i386: Align branches within a fixed boundary
[deliverable/binutils-gdb.git] / gas / config / tc-i386.h
index 51638b080337605b108b1f982b129656f993d6b7..28f03cf2dbe21d64621489a136710e2db1717a9a 100644 (file)
@@ -1,13 +1,11 @@
 /* tc-i386.h -- Header file for tc-i386.c
-   Copyright 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-   2001, 2002, 2003, 2004, 2005, 2006, 2007
-   Free Software Foundation, Inc.
+   Copyright (C) 1989-2019 Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
 
    GAS is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2, or (at your option)
+   the Free Software Foundation; either version 3, or (at your option)
    any later version.
 
    GAS is distributed in the hope that it will be useful,
@@ -29,8 +27,9 @@ struct fix;
 
 #define TARGET_BYTES_BIG_ENDIAN        0
 
-#define TARGET_ARCH            bfd_arch_i386
+#define TARGET_ARCH            (i386_arch ())
 #define TARGET_MACH            (i386_mach ())
+extern enum bfd_architecture i386_arch (void);
 extern unsigned long i386_mach (void);
 
 #ifdef TE_FreeBSD
@@ -60,6 +59,17 @@ extern unsigned long i386_mach (void);
 #define ELF_TARGET_FORMAT64    "elf64-x86-64-freebsd"
 #elif defined (TE_VXWORKS)
 #define ELF_TARGET_FORMAT      "elf32-i386-vxworks"
+#elif defined (TE_NACL)
+#define ELF_TARGET_FORMAT      "elf32-i386-nacl"
+#define ELF_TARGET_FORMAT32    "elf32-x86-64-nacl"
+#define ELF_TARGET_FORMAT64    "elf64-x86-64-nacl"
+#elif defined TE_CLOUDABI
+#define ELF_TARGET_FORMAT64    "elf64-x86-64-cloudabi"
+#endif
+
+#ifdef TE_SOLARIS
+#define ELF_TARGET_FORMAT      "elf32-i386-sol2"
+#define ELF_TARGET_FORMAT64    "elf64-x86-64-sol2"
 #endif
 
 #ifndef ELF_TARGET_FORMAT
@@ -70,26 +80,42 @@ extern unsigned long i386_mach (void);
 #define ELF_TARGET_FORMAT64    "elf64-x86-64"
 #endif
 
+#ifndef ELF_TARGET_FORMAT32
+#define ELF_TARGET_FORMAT32    "elf32-x86-64"
+#endif
+
+#ifndef ELF_TARGET_L1OM_FORMAT
+#define ELF_TARGET_L1OM_FORMAT "elf64-l1om"
+#endif
+
+#ifndef ELF_TARGET_K1OM_FORMAT
+#define ELF_TARGET_K1OM_FORMAT "elf64-k1om"
+#endif
+
+#ifndef ELF_TARGET_IAMCU_FORMAT
+#define ELF_TARGET_IAMCU_FORMAT        "elf32-iamcu"
+#endif
+
 #if ((defined (OBJ_MAYBE_COFF) && defined (OBJ_MAYBE_AOUT)) \
-     || defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF))
+     || defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) \
+     || defined (TE_PE) || defined (TE_PEP) || defined (OBJ_MACH_O))
 extern const char *i386_target_format (void);
 #define TARGET_FORMAT i386_target_format ()
 #else
-#ifdef OBJ_ELF
-#define TARGET_FORMAT          ELF_TARGET_FORMAT
+#ifdef TE_GO32
+#define TARGET_FORMAT          "coff-go32"
 #endif
 #ifdef OBJ_AOUT
 #define TARGET_FORMAT          AOUT_TARGET_FORMAT
 #endif
 #endif
 
-#if (defined (OBJ_MAYBE_ELF) || defined (OBJ_ELF))
-#define md_end i386_elf_emit_arch_note
-extern void i386_elf_emit_arch_note (void);
-#endif
-
 #define SUB_SEGMENT_ALIGN(SEG, FRCHAIN) 0
 
+/* '$' may be used as immediate prefix.  */
+#undef LOCAL_LABELS_DOLLAR
+#define LOCAL_LABELS_DOLLAR 0
+#undef LOCAL_LABELS_FB
 #define LOCAL_LABELS_FB 1
 
 extern const char extra_symbol_chars[];
@@ -98,97 +124,6 @@ extern const char extra_symbol_chars[];
 extern const char *i386_comment_chars;
 #define tc_comment_chars i386_comment_chars
 
-/* Prefixes will be emitted in the order defined below.
-   WAIT_PREFIX must be the first prefix since FWAIT is really is an
-   instruction, and so must come before any prefixes.
-   The preferred prefix order is SEG_PREFIX, ADDR_PREFIX, DATA_PREFIX,
-   LOCKREP_PREFIX.  */
-#define WAIT_PREFIX    0
-#define SEG_PREFIX     1
-#define ADDR_PREFIX    2
-#define DATA_PREFIX    3
-#define LOCKREP_PREFIX 4
-#define REX_PREFIX     5       /* must come last.  */
-#define MAX_PREFIXES   6       /* max prefixes per opcode */
-
-/* we define the syntax here (modulo base,index,scale syntax) */
-#define REGISTER_PREFIX '%'
-#define IMMEDIATE_PREFIX '$'
-#define ABSOLUTE_PREFIX '*'
-
-/* these are the instruction mnemonic suffixes.  */
-#define WORD_MNEM_SUFFIX  'w'
-#define BYTE_MNEM_SUFFIX  'b'
-#define SHORT_MNEM_SUFFIX 's'
-#define LONG_MNEM_SUFFIX  'l'
-#define QWORD_MNEM_SUFFIX  'q'
-/* Intel Syntax */
-#define LONG_DOUBLE_MNEM_SUFFIX 'x'
-
-#define END_OF_INSN '\0'
-
-/*
-  'templates' is for grouping together 'template' structures for opcodes
-  of the same name.  This is only used for storing the insns in the grand
-  ole hash table of insns.
-  The templates themselves start at START and range up to (but not including)
-  END.
-  */
-typedef struct
-{
-  const template *start;
-  const template *end;
-}
-templates;
-
-/* 386 operand encoding bytes:  see 386 book for details of this.  */
-typedef struct
-{
-  unsigned int regmem; /* codes register or memory operand */
-  unsigned int reg;    /* codes register operand (or extended opcode) */
-  unsigned int mode;   /* how to interpret regmem & reg */
-}
-modrm_byte;
-
-/* x86-64 extension prefix.  */
-typedef int rex_byte;
-
-/* 386 opcode byte to code indirect addressing.  */
-typedef struct
-{
-  unsigned base;
-  unsigned index;
-  unsigned scale;
-}
-sib_byte;
-
-enum processor_type
-{
-  PROCESSOR_UNKNOWN,
-  PROCESSOR_I486,
-  PROCESSOR_PENTIUM,
-  PROCESSOR_PENTIUMPRO,
-  PROCESSOR_PENTIUM4,
-  PROCESSOR_NOCONA,
-  PROCESSOR_CORE,
-  PROCESSOR_CORE2,
-  PROCESSOR_K6,
-  PROCESSOR_ATHLON,
-  PROCESSOR_K8,
-  PROCESSOR_GENERIC32,
-  PROCESSOR_GENERIC64,
-  PROCESSOR_AMDFAM10
-};
-
-/* x86 arch names, types and features */
-typedef struct
-{
-  const char *name;            /* arch name */
-  enum processor_type type;    /* arch type */
-  unsigned int flags;          /* cpu feature flags */
-}
-arch_entry;
-
 /* The name of the global offset table generated by the compiler. Allow
    this to be overridden if need be.  */
 #ifndef GLOBAL_OFFSET_TABLE_NAME
@@ -197,12 +132,16 @@ arch_entry;
 
 #if (defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)) && !defined (LEX_AT)
 #define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) x86_cons (EXP, NBYTES)
-extern void x86_cons (expressionS *, int);
 #endif
+extern bfd_reloc_code_real_type x86_cons (expressionS *, int);
 
-#define TC_CONS_FIX_NEW(FRAG,OFF,LEN,EXP) x86_cons_fix_new(FRAG, OFF, LEN, EXP)
+#define TC_CONS_FIX_NEW(FRAG, OFF, LEN, EXP, RELOC)    \
+  x86_cons_fix_new(FRAG, OFF, LEN, EXP, RELOC)
 extern void x86_cons_fix_new
-  (fragS *, unsigned int, unsigned int, expressionS *);
+(fragS *, unsigned int, unsigned int, expressionS *, bfd_reloc_code_real_type);
+
+#define TC_ADDRESS_BYTES x86_address_bytes
+extern int x86_address_bytes (void);
 
 #define DIFF_EXPR_OK    /* foo-. gets turned into PC relative relocs */
 
@@ -230,20 +169,28 @@ extern int tc_i386_fix_adjustable (struct fix *);
 /* This expression evaluates to true if the relocation is for a local
    object for which we still want to do the relocation at runtime.
    False if we are willing to perform this relocation while building
-   the .o file.  GOTOFF does not need to be checked here because it is
-   not pcrel.  I am not sure if some of the others are ever used with
-   pcrel, but it is easier to be safe than sorry.  */
+   the .o file.  GOTOFF and GOT32 do not need to be checked here because
+   they are not pcrel.  .*/
 
-#define TC_FORCE_RELOCATION_LOCAL(FIX)                 \
-  (!(FIX)->fx_pcrel                                    \
-   || (FIX)->fx_r_type == BFD_RELOC_386_PLT32          \
-   || (FIX)->fx_r_type == BFD_RELOC_386_GOT32          \
-   || (FIX)->fx_r_type == BFD_RELOC_386_GOTPC          \
-   || TC_FORCE_RELOCATION (FIX))
+#define TC_FORCE_RELOCATION_LOCAL(FIX)                         \
+  (GENERIC_FORCE_RELOCATION_LOCAL (FIX)                                \
+   || (FIX)->fx_r_type == BFD_RELOC_386_PLT32                  \
+   || (FIX)->fx_r_type == BFD_RELOC_386_GOTPC                  \
+   || (FIX)->fx_r_type == BFD_RELOC_X86_64_GOTPCREL            \
+   || (FIX)->fx_r_type == BFD_RELOC_X86_64_GOTPCRELX           \
+   || (FIX)->fx_r_type == BFD_RELOC_X86_64_REX_GOTPCRELX)
 
 extern int i386_parse_name (char *, expressionS *, char *);
 #define md_parse_name(s, e, m, c) i386_parse_name (s, e, c)
 
+extern operatorT i386_operator (const char *name, unsigned int operands, char *);
+#define md_operator i386_operator
+
+extern int i386_need_index_operator (void);
+#define md_need_index_operator i386_need_index_operator
+
+#define md_register_arithmetic 0
+
 extern const struct relax_type md_relax_table[];
 #define TC_GENERIC_RELAX_TABLE md_relax_table
 
@@ -261,28 +208,119 @@ if ((n)                                                                  \
     goto around;                                                       \
   }
 
-#define MAX_MEM_FOR_RS_ALIGN_CODE  15
+#define MAX_MEM_FOR_RS_ALIGN_CODE  (alignment ? ((1 << alignment) - 1) : 1)
 
-extern void i386_align_code (fragS *, int);
-
-#define HANDLE_ALIGN(fragP)                                            \
-if (fragP->fr_type == rs_align_code)                                   \
-  i386_align_code (fragP, (fragP->fr_next->fr_address                  \
-                          - fragP->fr_address                          \
-                          - fragP->fr_fix));
+extern void i386_cons_align (int);
+#define md_cons_align(nbytes) i386_cons_align (nbytes)
 
 void i386_print_statistics (FILE *);
 #define tc_print_statistics i386_print_statistics
 
+extern unsigned int i386_frag_max_var (fragS *);
+#define md_frag_max_var i386_frag_max_var
+
+extern long i386_generic_table_relax_frag (segT, fragS *, long);
+#define md_generic_table_relax_frag(segment, fragP, stretch) \
+  i386_generic_table_relax_frag (segment, fragP, stretch)
+
 #define md_number_to_chars number_to_chars_littleendian
 
-#ifdef SCO_ELF
-#define tc_init_after_args() sco_id ()
-extern void sco_id (void);
-#endif
+enum processor_type
+{
+  PROCESSOR_UNKNOWN,
+  PROCESSOR_I386,
+  PROCESSOR_I486,
+  PROCESSOR_PENTIUM,
+  PROCESSOR_PENTIUMPRO,
+  PROCESSOR_PENTIUM4,
+  PROCESSOR_NOCONA,
+  PROCESSOR_CORE,
+  PROCESSOR_CORE2,
+  PROCESSOR_COREI7,
+  PROCESSOR_L1OM,
+  PROCESSOR_K1OM,
+  PROCESSOR_IAMCU,
+  PROCESSOR_K6,
+  PROCESSOR_ATHLON,
+  PROCESSOR_K8,
+  PROCESSOR_GENERIC32,
+  PROCESSOR_GENERIC64,
+  PROCESSOR_AMDFAM10,
+  PROCESSOR_BD,
+  PROCESSOR_ZNVER,
+  PROCESSOR_BT
+};
+
+extern enum processor_type cpu_arch_tune;
+extern enum processor_type cpu_arch_isa;
+extern i386_cpu_flags cpu_arch_isa_flags;
+
+struct i386_tc_frag_data
+{
+  union
+    {
+      fragS *padding_fragP;
+      fragS *branch_fragP;
+    } u;
+  addressT padding_address;
+  enum processor_type isa;
+  i386_cpu_flags isa_flags;
+  enum processor_type tune;
+  unsigned int max_bytes;
+  unsigned char length;
+  unsigned char last_length;
+  unsigned char max_prefix_length;
+  unsigned char prefix_length;
+  unsigned char default_prefix;
+  unsigned char cmp_size;
+  unsigned int classified : 1;
+  unsigned int branch_type : 3;
+};
+
+/* We need to emit the right NOP pattern in .align frags.  This is
+   done after the text-to-bits assembly pass, so we need to mark it with
+   the isa/tune settings at the time the .align was assembled.  */
+#define TC_FRAG_TYPE struct i386_tc_frag_data
+
+#define TC_FRAG_INIT(FRAGP, MAX_BYTES)                         \
+ do                                                            \
+   {                                                           \
+     (FRAGP)->tc_frag_data.u.padding_fragP = NULL;             \
+     (FRAGP)->tc_frag_data.padding_address = 0;                        \
+     (FRAGP)->tc_frag_data.isa = cpu_arch_isa;                 \
+     (FRAGP)->tc_frag_data.isa_flags = cpu_arch_isa_flags;     \
+     (FRAGP)->tc_frag_data.tune = cpu_arch_tune;               \
+     (FRAGP)->tc_frag_data.max_bytes = (MAX_BYTES);            \
+     (FRAGP)->tc_frag_data.length = 0;                         \
+     (FRAGP)->tc_frag_data.last_length = 0;                    \
+     (FRAGP)->tc_frag_data.max_prefix_length = 0;              \
+     (FRAGP)->tc_frag_data.prefix_length = 0;                  \
+     (FRAGP)->tc_frag_data.default_prefix = 0;                 \
+     (FRAGP)->tc_frag_data.cmp_size = 0;                       \
+     (FRAGP)->tc_frag_data.classified = 0;                     \
+     (FRAGP)->tc_frag_data.branch_type = 0;                    \
+   }                                                           \
+ while (0)
 
 #define WORKING_DOT_WORD 1
 
+/* How to generate NOPs for .nop direct directive.  */
+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(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);                                    \
+  }
+
 /* We want .cfi_* pseudo-ops for generating unwind info.  */
 #define TARGET_USE_CFIPOP 1
 
@@ -292,8 +330,11 @@ extern unsigned int x86_dwarf2_return_column;
 extern int x86_cie_data_alignment;
 #define DWARF2_CIE_DATA_ALIGNMENT x86_cie_data_alignment
 
-#define tc_regname_to_dw2regnum tc_x86_regname_to_dw2regnum
-extern int tc_x86_regname_to_dw2regnum (char *);
+extern int x86_dwarf2_addr_size (void);
+#define DWARF2_ADDR_SIZE(bfd) x86_dwarf2_addr_size ()
+
+#define tc_parse_to_dw2regnum tc_x86_parse_to_dw2regnum
+extern void tc_x86_parse_to_dw2regnum (expressionS *);
 
 #define tc_cfi_frame_initial_instructions tc_x86_frame_initial_instructions
 extern void tc_x86_frame_initial_instructions (void);
@@ -301,12 +342,22 @@ extern void tc_x86_frame_initial_instructions (void);
 #define md_elf_section_type(str,len) i386_elf_section_type (str, len)
 extern int i386_elf_section_type (const char *, size_t);
 
+#ifdef TE_SOLARIS
+#define md_fix_up_eh_frame(sec) i386_solaris_fix_up_eh_frame (sec)
+extern void i386_solaris_fix_up_eh_frame (segT);
+#endif
+
 /* Support for SHF_X86_64_LARGE */
-extern int x86_64_section_word (char *, size_t);
-extern int x86_64_section_letter (int, char **);
+extern bfd_vma x86_64_section_word (char *, size_t);
+extern bfd_vma x86_64_section_letter (int, const char **);
 #define md_elf_section_letter(LETTER, PTR_MSG) x86_64_section_letter (LETTER, PTR_MSG)
 #define md_elf_section_word(STR, LEN)          x86_64_section_word (STR, LEN)
 
+#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
+extern void x86_cleanup (void);
+#define md_cleanup() x86_cleanup ()
+#endif
+
 #ifdef TE_PE
 
 #define O_secrel O_md1
@@ -316,4 +367,21 @@ void tc_pe_dwarf2_emit_offset (symbolS *, unsigned int);
 
 #endif /* TE_PE */
 
+/* X_add_symbol:X_op_symbol (Intel mode only) */
+#define O_full_ptr O_md2
+
+#ifdef OBJ_MACH_O
+
+#define TC_FORCE_RELOCATION(FIX) (obj_mach_o_force_reloc (FIX))
+
+#define TC_FORCE_RELOCATION_SUB_SAME(FIX,SEG) \
+         (obj_mach_o_force_reloc_sub_same (FIX, SEG))
+
+#define TC_FORCE_RELOCATION_SUB_LOCAL(FIX,SEG) \
+       (obj_mach_o_force_reloc_sub_local (FIX, SEG))
+
+#define TC_VALIDATE_FIX_SUB(FIX, SEG) 1
+
+#endif /* OBJ_MACH_O */
+
 #endif /* TC_I386 */
This page took 0.029322 seconds and 4 git commands to generate.