diff options
Diffstat (limited to 'gas/config/tc-i386.h')
-rw-r--r-- | gas/config/tc-i386.h | 54 |
1 files changed, 43 insertions, 11 deletions
diff --git a/gas/config/tc-i386.h b/gas/config/tc-i386.h index 3fb7920..641596d 100644 --- a/gas/config/tc-i386.h +++ b/gas/config/tc-i386.h @@ -230,9 +230,6 @@ if ((n) \ goto around; \ } -#define MAX_MEM_FOR_RS_ALIGN_CODE \ - (alignment ? ((size_t) 1 << alignment) - 1 : (size_t) 1) - extern void i386_cons_align (int); #define md_cons_align(nbytes) i386_cons_align (nbytes) @@ -379,17 +376,43 @@ extern void i386_generate_nops (fragS *, char *, offsetT, int); #define md_generate_nops(frag, where, amount, control) \ i386_generate_nops ((frag), (where), (amount), (control)) -#define HANDLE_ALIGN(sec, fragP) \ +#define HANDLE_ALIGN(sec, fragP) \ if (fragP->fr_type == rs_align_code) \ { \ offsetT __count = (fragP->fr_next->fr_address \ - fragP->fr_address \ - fragP->fr_fix); \ - if (__count > 0 \ - && (unsigned int) __count <= fragP->tc_frag_data.max_bytes) \ - md_generate_nops (fragP, fragP->fr_literal + fragP->fr_fix, \ - __count, 0); \ + if (__count > 0) \ + { \ + know (fragP->tc_frag_data.max_bytes >= (valueT) __count \ + || (fragP->tc_frag_data.max_bytes \ + >= MAX_MEM_FOR_RS_ALIGN_CODE (fragP->fr_offset, \ + fragP->fr_subtype))); \ + md_generate_nops (fragP, fragP->fr_literal + fragP->fr_fix, \ + __count, 0); \ + } \ } +/* Possible plain nop, branch, twice largest nop less 1. + Yes, the branch might be one byte longer in CODE_16BIT but then the + largest nop is smaller. */ +#define MAX_MEM_FOR_RS_SPACE_NOP (1 + 5 + 2 * 15 - 1) + +static inline unsigned int +max_mem_for_rs_align_code (unsigned int p2align, unsigned int max) +{ + unsigned int bytes = 1; + if (p2align != 0) + { + bytes = MAX_MEM_FOR_RS_SPACE_NOP; + if (bytes > (1ull << p2align) - 1) + bytes = (1ull << p2align) - 1; + if (max != 0 && bytes > max) + bytes = max; + } + return bytes; +} +#define MAX_MEM_FOR_RS_ALIGN_CODE(p2align, max) \ + max_mem_for_rs_align_code (p2align, max) /* We want .cfi_* pseudo-ops for generating unwind info. */ #define TARGET_USE_CFIPOP 1 @@ -413,6 +436,9 @@ extern void tc_x86_frame_initial_instructions (void); #define REG_FP 6 /* DWARF register number of the stack-pointer register in 64-bit mode. */ #define REG_SP 7 +/* DWARF register number of the (pseudo) return address register in 64-bit + mode. This is the same as reg RIP in i386-reg.tbl. */ +#define REG_RA 16 #define md_elf_section_type(str,len) i386_elf_section_type (str, len) extern int i386_elf_section_type (const char *, size_t); @@ -455,13 +481,19 @@ extern bool x86_support_sframe_p (void); #define support_sframe_p x86_support_sframe_p /* The stack pointer DWARF register number for SFrame CFA tracking. */ -extern unsigned int x86_sframe_cfa_sp_reg; +extern const unsigned int x86_sframe_cfa_sp_reg; #define SFRAME_CFA_SP_REG x86_sframe_cfa_sp_reg /* The frame pointer DWARF register number for SFrame CFA and FP tracking. */ -extern unsigned int x86_sframe_cfa_fp_reg; +extern const unsigned int x86_sframe_cfa_fp_reg; #define SFRAME_CFA_FP_REG x86_sframe_cfa_fp_reg +/* The return address DWARF register number for SFrame purposes. Although for + AMD64, RA tracking is disabled, specific constructs, like for indicating + the _start function, may use it. */ +extern const unsigned int x86_sframe_cfa_ra_reg; +#define SFRAME_CFA_RA_REG x86_sframe_cfa_ra_reg + /* Whether SFrame return address tracking is needed. */ extern bool x86_sframe_ra_tracking_p (void); #define sframe_ra_tracking_p x86_sframe_ra_tracking_p @@ -471,7 +503,7 @@ extern bool x86_sframe_ra_tracking_p (void); extern offsetT x86_sframe_cfa_ra_offset (void); #define sframe_cfa_ra_offset x86_sframe_cfa_ra_offset -/* The abi/arch indentifier for SFrame. */ +/* The abi/arch identifier for SFrame. */ extern unsigned char x86_sframe_get_abi_arch (void); #define sframe_get_abi_arch x86_sframe_get_abi_arch |