diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2019-12-12 11:56:06 -0800 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2019-12-12 12:03:45 -0800 |
commit | e379e5f385f874adb0b414f917adb1fc50e20de9 (patch) | |
tree | e9a1ad41c0582dd54bfebe9391afb382105f907c /gas/ChangeLog | |
parent | b65d68b8d60338a860e169aac3bac54e6bac60db (diff) | |
download | fsf-binutils-gdb-e379e5f385f874adb0b414f917adb1fc50e20de9.zip fsf-binutils-gdb-e379e5f385f874adb0b414f917adb1fc50e20de9.tar.gz fsf-binutils-gdb-e379e5f385f874adb0b414f917adb1fc50e20de9.tar.bz2 |
i386: Align branches within a fixed boundary
Add 3 command-line options to align branches within a fixed boundary
with segment prefixes or NOPs:
1. -malign-branch-boundary=NUM aligns branches within NUM byte boundary.
2. -malign-branch=TYPE[+TYPE...] specifies types of branches to align.
The supported branches are:
a. Conditional jump.
b. Fused conditional jump.
c. Unconditional jump.
d. Call.
e. Ret.
f. Indirect jump and call.
3. -malign-branch-prefix-size=NUM aligns branches with NUM segment
prefixes per instruction.
3 new rs_machine_dependent frag types are added:
1. BRANCH_PADDING. The variable size frag to insert NOP before branch.
2. BRANCH_PREFIX. The variable size frag to insert segment prefixes to
an instruction. The choices of prefixes are:
a. Use the existing segment prefix if there is one.
b. Use CS segment prefix in 64-bit mode.
c. In 32-bit mode, use SS segment prefix with ESP/EBP base register
and use DS segment prefix without ESP/EBP base register.
3. FUSED_JCC_PADDING. The variable size frag to insert NOP before fused
conditional jump.
The new rs_machine_dependent frags aren't inserted if the previous item
is a prefix or a constant directive, which may be used to hardcode an
instruction, since there is no clear instruction boundary. Segment
prefixes and NOP padding are disabled before relaxable TLS relocations
and tls_get_addr calls to keep TLS instruction sequence unchanged.
md_estimate_size_before_relax() and i386_generic_table_relax_frag() are
used to handled BRANCH_PADDING, BRANCH_PREFIX and FUSED_JCC_PADDING frags.
i386_generic_table_relax_frag() grows or shrinks sizes of segment prefix
and NOP to align the next branch frag:
1. First try to add segment prefixes to instructions before a branch.
2. If there is no sufficient room to add segment prefixes, NOP will be
inserted before a branch.
* config/tc-i386.c (_i386_insn): Add has_gotpc_tls_reloc.
(tls_get_addr): New.
(last_insn): New.
(align_branch_power): New.
(align_branch_kind): New.
(align_branch_bit): New.
(align_branch): New.
(MAX_FUSED_JCC_PADDING_SIZE): New.
(align_branch_prefix_size): New.
(BRANCH_PADDING): New.
(BRANCH_PREFIX): New.
(FUSED_JCC_PADDING): New.
(i386_generate_nops): Support BRANCH_PADDING and FUSED_JCC_PADDING.
(md_begin): Abort if align_branch_prefix_size <
MAX_FUSED_JCC_PADDING_SIZE.
(md_assemble): Set last_insn.
(maybe_fused_with_jcc_p): New.
(add_fused_jcc_padding_frag_p): New.
(add_branch_prefix_frag_p): New.
(add_branch_padding_frag_p): New.
(output_insn): Generate a BRANCH_PADDING, FUSED_JCC_PADDING or
BRANCH_PREFIX frag and terminate each frag to align branches.
(output_disp): Set i.has_gotpc_tls_reloc to TRUE for GOTPC and
relaxable TLS relocations.
(output_imm): Likewise.
(i386_next_non_empty_frag): New.
(i386_next_jcc_frag): New.
(i386_classify_machine_dependent_frag): New.
(i386_branch_padding_size): New.
(i386_generic_table_relax_frag): New.
(md_estimate_size_before_relax): Handle COND_JUMP_PADDING,
FUSED_JCC_PADDING and COND_JUMP_PREFIX frags.
(md_convert_frag): Handle BRANCH_PADDING, BRANCH_PREFIX and
FUSED_JCC_PADDING frags.
(OPTION_MALIGN_BRANCH_BOUNDARY): New.
(OPTION_MALIGN_BRANCH_PREFIX_SIZE): New.
(OPTION_MALIGN_BRANCH): New.
(md_longopts): Add -malign-branch-boundary=,
-malign-branch-prefix-size= and -malign-branch=.
(md_parse_option): Handle -malign-branch-boundary=,
-malign-branch-prefix-size= and -malign-branch=.
(md_show_usage): Display -malign-branch-boundary=,
-malign-branch-prefix-size= and -malign-branch=.
(i386_target_format): Set tls_get_addr.
(i386_cons_align): New.
* config/tc-i386.h (i386_cons_align): New.
(md_cons_align): New.
(i386_generic_table_relax_frag): New.
(md_generic_table_relax_frag): New.
(i386_tc_frag_data): Add u, padding_address, length,
max_prefix_length, prefix_length, default_prefix, cmp_size,
classified and branch_type.
(TC_FRAG_INIT): Initialize u, padding_address, length,
max_prefix_length, prefix_length, default_prefix, cmp_size,
classified and branch_type.
* doc/c-i386.texi: Document -malign-branch-boundary=,
-malign-branch= and -malign-branch-prefix-size=.
Diffstat (limited to 'gas/ChangeLog')
-rw-r--r-- | gas/ChangeLog | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index ef7369c..7b83a0a 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,5 +1,65 @@ 2019-12-12 H.J. Lu <hongjiu.lu@intel.com> + * config/tc-i386.c (_i386_insn): Add has_gotpc_tls_reloc. + (tls_get_addr): New. + (last_insn): New. + (align_branch_power): New. + (align_branch_kind): New. + (align_branch_bit): New. + (align_branch): New. + (MAX_FUSED_JCC_PADDING_SIZE): New. + (align_branch_prefix_size): New. + (BRANCH_PADDING): New. + (BRANCH_PREFIX): New. + (FUSED_JCC_PADDING): New. + (i386_generate_nops): Support BRANCH_PADDING and FUSED_JCC_PADDING. + (md_begin): Abort if align_branch_prefix_size < + MAX_FUSED_JCC_PADDING_SIZE. + (md_assemble): Set last_insn. + (maybe_fused_with_jcc_p): New. + (add_fused_jcc_padding_frag_p): New. + (add_branch_prefix_frag_p): New. + (add_branch_padding_frag_p): New. + (output_insn): Generate a BRANCH_PADDING, FUSED_JCC_PADDING or + BRANCH_PREFIX frag and terminate each frag to align branches. + (output_disp): Set i.has_gotpc_tls_reloc to TRUE for GOTPC and + relaxable TLS relocations. + (output_imm): Likewise. + (i386_next_non_empty_frag): New. + (i386_next_jcc_frag): New. + (i386_classify_machine_dependent_frag): New. + (i386_branch_padding_size): New. + (i386_generic_table_relax_frag): New. + (md_estimate_size_before_relax): Handle COND_JUMP_PADDING, + FUSED_JCC_PADDING and COND_JUMP_PREFIX frags. + (md_convert_frag): Handle BRANCH_PADDING, BRANCH_PREFIX and + FUSED_JCC_PADDING frags. + (OPTION_MALIGN_BRANCH_BOUNDARY): New. + (OPTION_MALIGN_BRANCH_PREFIX_SIZE): New. + (OPTION_MALIGN_BRANCH): New. + (md_longopts): Add -malign-branch-boundary=, + -malign-branch-prefix-size= and -malign-branch=. + (md_parse_option): Handle -malign-branch-boundary=, + -malign-branch-prefix-size= and -malign-branch=. + (md_show_usage): Display -malign-branch-boundary=, + -malign-branch-prefix-size= and -malign-branch=. + (i386_target_format): Set tls_get_addr. + (i386_cons_align): New. + * config/tc-i386.h (i386_cons_align): New. + (md_cons_align): New. + (i386_generic_table_relax_frag): New. + (md_generic_table_relax_frag): New. + (i386_tc_frag_data): Add u, padding_address, length, + max_prefix_length, prefix_length, default_prefix, cmp_size, + classified and branch_type. + (TC_FRAG_INIT): Initialize u, padding_address, length, + max_prefix_length, prefix_length, default_prefix, cmp_size, + classified and branch_type. + * doc/c-i386.texi: Document -malign-branch-boundary=, + -malign-branch= and -malign-branch-prefix-size=. + +2019-12-12 H.J. Lu <hongjiu.lu@intel.com> + * write.c (md_generic_table_relax_frag): New. Defined to relax_frag if not defined. (relax_segment): Call md_generic_table_relax_frag instead of |