This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH 3/5] i386: Align branches within a fixed boundary


On Tue, Dec 3, 2019 at 11:02 AM H.J. Lu <hjl.tools@gmail.com> wrote:
>
> 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.  NOP padding
> is disabled before 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_reloc.
>         (tls_get_addr): New.
>         (last_insn): New.
>         (align_branch_power): New.
>         (align_branch_kind): 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_reloc to TRUE for GOTPC
>         relocation.
>         (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_worker): New.
>         * config/tc-i386.h (i386_cons_worker): New.
>         (md_cons_worker): 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, base_opcode,
>         length, max_prefix_length, prefix_length, default_prefix,
>         cmp_size and classified.
>         * doc/c-i386.texi: Document -malign-branch-boundary=,
>         -malign-branch-prefix-size= and -malign-branch=.

Please ignore this one.

-- 
H.J.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]