133965Sjdp/* tc-i386.h -- Header file for tc-i386.c
278838Sobrien   Copyright 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3218822Sdim   2001, 2002, 2003, 2004, 2005, 2006, 2007
478838Sobrien   Free Software Foundation, Inc.
533965Sjdp
633965Sjdp   This file is part of GAS, the GNU Assembler.
733965Sjdp
833965Sjdp   GAS is free software; you can redistribute it and/or modify
933965Sjdp   it under the terms of the GNU General Public License as published by
1033965Sjdp   the Free Software Foundation; either version 2, or (at your option)
1133965Sjdp   any later version.
1233965Sjdp
1333965Sjdp   GAS is distributed in the hope that it will be useful,
1433965Sjdp   but WITHOUT ANY WARRANTY; without even the implied warranty of
1533965Sjdp   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1633965Sjdp   GNU General Public License for more details.
1733965Sjdp
1833965Sjdp   You should have received a copy of the GNU General Public License
1933965Sjdp   along with GAS; see the file COPYING.  If not, write to the Free
20218822Sdim   Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
21218822Sdim   02110-1301, USA.  */
2233965Sjdp
2333965Sjdp#ifndef TC_I386
2433965Sjdp#define TC_I386 1
2533965Sjdp
26218822Sdim#include "opcodes/i386-opc.h"
27130570Sobrien
2833965Sjdpstruct fix;
2933965Sjdp
3033965Sjdp#define TARGET_BYTES_BIG_ENDIAN	0
3133965Sjdp
3233965Sjdp#define TARGET_ARCH		bfd_arch_i386
3377312Sobrien#define TARGET_MACH		(i386_mach ())
34218822Sdimextern unsigned long i386_mach (void);
3533965Sjdp
3633973Sjdp#ifdef TE_FreeBSD
3760518Sobrien#define AOUT_TARGET_FORMAT	"a.out-i386-freebsd"
3833973Sjdp#endif
3933965Sjdp#ifdef TE_NetBSD
4060518Sobrien#define AOUT_TARGET_FORMAT	"a.out-i386-netbsd"
4133965Sjdp#endif
4233965Sjdp#ifdef TE_386BSD
4360518Sobrien#define AOUT_TARGET_FORMAT	"a.out-i386-bsd"
4433965Sjdp#endif
4533965Sjdp#ifdef TE_LINUX
4660518Sobrien#define AOUT_TARGET_FORMAT	"a.out-i386-linux"
4733965Sjdp#endif
4833965Sjdp#ifdef TE_Mach
4960518Sobrien#define AOUT_TARGET_FORMAT	"a.out-mach3"
5033965Sjdp#endif
5133965Sjdp#ifdef TE_DYNIX
5260518Sobrien#define AOUT_TARGET_FORMAT	"a.out-i386-dynix"
5333965Sjdp#endif
5460518Sobrien#ifndef AOUT_TARGET_FORMAT
5560518Sobrien#define AOUT_TARGET_FORMAT	"a.out-i386"
5633965Sjdp#endif
5733965Sjdp
58104848Sobrien#ifdef TE_FreeBSD
59104848Sobrien#define ELF_TARGET_FORMAT	"elf32-i386-freebsd"
60218822Sdim#define ELF_TARGET_FORMAT64	"elf64-x86-64-freebsd"
61218822Sdim#elif defined (TE_VXWORKS)
62218822Sdim#define ELF_TARGET_FORMAT	"elf32-i386-vxworks"
63104848Sobrien#endif
64218822Sdim
65104848Sobrien#ifndef ELF_TARGET_FORMAT
66104848Sobrien#define ELF_TARGET_FORMAT	"elf32-i386"
67104848Sobrien#endif
68104848Sobrien
69218822Sdim#ifndef ELF_TARGET_FORMAT64
70218822Sdim#define ELF_TARGET_FORMAT64	"elf64-x86-64"
71218822Sdim#endif
72218822Sdim
7377312Sobrien#if ((defined (OBJ_MAYBE_COFF) && defined (OBJ_MAYBE_AOUT)) \
7477312Sobrien     || defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF))
75218822Sdimextern const char *i386_target_format (void);
7660518Sobrien#define TARGET_FORMAT i386_target_format ()
7760518Sobrien#else
7833965Sjdp#ifdef OBJ_ELF
79104848Sobrien#define TARGET_FORMAT		ELF_TARGET_FORMAT
8033965Sjdp#endif
8160518Sobrien#ifdef OBJ_AOUT
8260518Sobrien#define TARGET_FORMAT		AOUT_TARGET_FORMAT
8333965Sjdp#endif
8433965Sjdp#endif
8533965Sjdp
8689868Sobrien#if (defined (OBJ_MAYBE_ELF) || defined (OBJ_ELF))
8789868Sobrien#define md_end i386_elf_emit_arch_note
88218822Sdimextern void i386_elf_emit_arch_note (void);
8989868Sobrien#endif
9089868Sobrien
91104848Sobrien#define SUB_SEGMENT_ALIGN(SEG, FRCHAIN) 0
92104848Sobrien
9333965Sjdp#define LOCAL_LABELS_FB 1
9433965Sjdp
9560518Sobrienextern const char extra_symbol_chars[];
9660518Sobrien#define tc_symbol_chars extra_symbol_chars
9760518Sobrien
98218822Sdimextern const char *i386_comment_chars;
99218822Sdim#define tc_comment_chars i386_comment_chars
10033965Sjdp
10160518Sobrien/* Prefixes will be emitted in the order defined below.
10260518Sobrien   WAIT_PREFIX must be the first prefix since FWAIT is really is an
103218822Sdim   instruction, and so must come before any prefixes.
104218822Sdim   The preferred prefix order is SEG_PREFIX, ADDR_PREFIX, DATA_PREFIX,
105218822Sdim   LOCKREP_PREFIX.  */
10660518Sobrien#define WAIT_PREFIX	0
107218822Sdim#define SEG_PREFIX	1
10860518Sobrien#define ADDR_PREFIX	2
10960518Sobrien#define DATA_PREFIX	3
110218822Sdim#define LOCKREP_PREFIX	4
11177312Sobrien#define REX_PREFIX	5       /* must come last.  */
11277312Sobrien#define MAX_PREFIXES	6	/* max prefixes per opcode */
11360518Sobrien
11433965Sjdp/* we define the syntax here (modulo base,index,scale syntax) */
11533965Sjdp#define REGISTER_PREFIX '%'
11633965Sjdp#define IMMEDIATE_PREFIX '$'
11733965Sjdp#define ABSOLUTE_PREFIX '*'
11833965Sjdp
11960518Sobrien/* these are the instruction mnemonic suffixes.  */
12060518Sobrien#define WORD_MNEM_SUFFIX  'w'
12160518Sobrien#define BYTE_MNEM_SUFFIX  'b'
12260518Sobrien#define SHORT_MNEM_SUFFIX 's'
12360518Sobrien#define LONG_MNEM_SUFFIX  'l'
12477312Sobrien#define QWORD_MNEM_SUFFIX  'q'
12560518Sobrien/* Intel Syntax */
12660518Sobrien#define LONG_DOUBLE_MNEM_SUFFIX 'x'
12733965Sjdp
12833965Sjdp#define END_OF_INSN '\0'
12933965Sjdp
13033965Sjdp/*
13133965Sjdp  'templates' is for grouping together 'template' structures for opcodes
13233965Sjdp  of the same name.  This is only used for storing the insns in the grand
13333965Sjdp  ole hash table of insns.
13433965Sjdp  The templates themselves start at START and range up to (but not including)
13533965Sjdp  END.
13633965Sjdp  */
13733965Sjdptypedef struct
13877312Sobrien{
13977312Sobrien  const template *start;
14077312Sobrien  const template *end;
14177312Sobrien}
14277312Sobrientemplates;
14333965Sjdp
14477312Sobrien/* 386 operand encoding bytes:  see 386 book for details of this.  */
14533965Sjdptypedef struct
14677312Sobrien{
14777312Sobrien  unsigned int regmem;	/* codes register or memory operand */
14877312Sobrien  unsigned int reg;	/* codes register operand (or extended opcode) */
14977312Sobrien  unsigned int mode;	/* how to interpret regmem & reg */
15077312Sobrien}
15133965Sjdpmodrm_byte;
15233965Sjdp
15377312Sobrien/* x86-64 extension prefix.  */
15494546Sobrientypedef int rex_byte;
15577312Sobrien
15677312Sobrien/* 386 opcode byte to code indirect addressing.  */
15777312Sobrientypedef struct
15877312Sobrien{
15977312Sobrien  unsigned base;
16077312Sobrien  unsigned index;
16177312Sobrien  unsigned scale;
16277312Sobrien}
16360518Sobriensib_byte;
16433965Sjdp
165218822Sdimenum processor_type
166218822Sdim{
167218822Sdim  PROCESSOR_UNKNOWN,
168218822Sdim  PROCESSOR_I486,
169218822Sdim  PROCESSOR_PENTIUM,
170218822Sdim  PROCESSOR_PENTIUMPRO,
171218822Sdim  PROCESSOR_PENTIUM4,
172218822Sdim  PROCESSOR_NOCONA,
173218822Sdim  PROCESSOR_CORE,
174218822Sdim  PROCESSOR_CORE2,
175218822Sdim  PROCESSOR_K6,
176218822Sdim  PROCESSOR_ATHLON,
177218822Sdim  PROCESSOR_K8,
178218822Sdim  PROCESSOR_GENERIC32,
179218822Sdim  PROCESSOR_GENERIC64,
180218822Sdim  PROCESSOR_AMDFAM10
181218822Sdim};
182218822Sdim
183218822Sdim/* x86 arch names, types and features */
18477312Sobrientypedef struct
18577312Sobrien{
186218822Sdim  const char *name;		/* arch name */
187218822Sdim  enum processor_type type;	/* arch type */
188218822Sdim  unsigned int flags;		/* cpu feature flags */
18977312Sobrien}
19077312Sobrienarch_entry;
19177312Sobrien
19233965Sjdp/* The name of the global offset table generated by the compiler. Allow
19377312Sobrien   this to be overridden if need be.  */
19433965Sjdp#ifndef GLOBAL_OFFSET_TABLE_NAME
19533965Sjdp#define GLOBAL_OFFSET_TABLE_NAME "_GLOBAL_OFFSET_TABLE_"
19633965Sjdp#endif
19733965Sjdp
198218822Sdim#if (defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)) && !defined (LEX_AT)
199130570Sobrien#define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) x86_cons (EXP, NBYTES)
200218822Sdimextern void x86_cons (expressionS *, int);
201218822Sdim#endif
202130570Sobrien
203130570Sobrien#define TC_CONS_FIX_NEW(FRAG,OFF,LEN,EXP) x86_cons_fix_new(FRAG, OFF, LEN, EXP)
204130570Sobrienextern void x86_cons_fix_new
205218822Sdim  (fragS *, unsigned int, unsigned int, expressionS *);
206130570Sobrien
207130570Sobrien#define DIFF_EXPR_OK    /* foo-. gets turned into PC relative relocs */
208130570Sobrien
209130570Sobrien#define NO_RELOC BFD_RELOC_NONE
210130570Sobrien
211218822Sdimvoid i386_validate_fix (struct fix *);
212130570Sobrien#define TC_VALIDATE_FIX(FIX,SEGTYPE,SKIP) i386_validate_fix(FIX)
213130570Sobrien
214130570Sobrien#define tc_fix_adjustable(X)  tc_i386_fix_adjustable(X)
215218822Sdimextern int tc_i386_fix_adjustable (struct fix *);
216130570Sobrien
217218822Sdim/* Values passed to md_apply_fix don't include the symbol value.  */
218130570Sobrien#define MD_APPLY_SYM_VALUE(FIX) 0
219130570Sobrien
220130570Sobrien/* ELF wants external syms kept, as does PE COFF.  */
221130570Sobrien#if defined (TE_PE) && defined (STRICT_PE_FORMAT)
222130570Sobrien#define EXTERN_FORCE_RELOC				\
223130570Sobrien  (OUTPUT_FLAVOR == bfd_target_elf_flavour		\
224130570Sobrien   || OUTPUT_FLAVOR == bfd_target_coff_flavour)
225130570Sobrien#else
226130570Sobrien#define EXTERN_FORCE_RELOC				\
227130570Sobrien  (OUTPUT_FLAVOR == bfd_target_elf_flavour)
22833965Sjdp#endif
22933965Sjdp
230130570Sobrien/* This expression evaluates to true if the relocation is for a local
231130570Sobrien   object for which we still want to do the relocation at runtime.
232130570Sobrien   False if we are willing to perform this relocation while building
233130570Sobrien   the .o file.  GOTOFF does not need to be checked here because it is
234130570Sobrien   not pcrel.  I am not sure if some of the others are ever used with
235130570Sobrien   pcrel, but it is easier to be safe than sorry.  */
23633965Sjdp
237130570Sobrien#define TC_FORCE_RELOCATION_LOCAL(FIX)			\
238130570Sobrien  (!(FIX)->fx_pcrel					\
239130570Sobrien   || (FIX)->fx_r_type == BFD_RELOC_386_PLT32		\
240130570Sobrien   || (FIX)->fx_r_type == BFD_RELOC_386_GOT32		\
241130570Sobrien   || (FIX)->fx_r_type == BFD_RELOC_386_GOTPC		\
242130570Sobrien   || TC_FORCE_RELOCATION (FIX))
243130570Sobrien
244218822Sdimextern int i386_parse_name (char *, expressionS *, char *);
245218822Sdim#define md_parse_name(s, e, m, c) i386_parse_name (s, e, c)
24633965Sjdp
24733965Sjdpextern const struct relax_type md_relax_table[];
24833965Sjdp#define TC_GENERIC_RELAX_TABLE md_relax_table
24933965Sjdp
250130570Sobrienextern int optimize_align_code;
251130570Sobrien
25233965Sjdp#define md_do_align(n, fill, len, max, around)				\
253130570Sobrienif ((n)									\
254130570Sobrien    && !need_pass_2							\
255130570Sobrien    && optimize_align_code						\
256130570Sobrien    && (!(fill)								\
257130570Sobrien	|| ((char)*(fill) == (char)0x90 && (len) == 1))			\
25860518Sobrien    && subseg_text_p (now_seg))						\
25933965Sjdp  {									\
26077312Sobrien    frag_align_code ((n), (max));					\
26133965Sjdp    goto around;							\
26233965Sjdp  }
26333965Sjdp
26477312Sobrien#define MAX_MEM_FOR_RS_ALIGN_CODE  15
26577312Sobrien
266218822Sdimextern void i386_align_code (fragS *, int);
26733965Sjdp
26833965Sjdp#define HANDLE_ALIGN(fragP)						\
26933965Sjdpif (fragP->fr_type == rs_align_code) 					\
27033965Sjdp  i386_align_code (fragP, (fragP->fr_next->fr_address			\
27133965Sjdp			   - fragP->fr_address				\
27233965Sjdp			   - fragP->fr_fix));
27333965Sjdp
274218822Sdimvoid i386_print_statistics (FILE *);
27533965Sjdp#define tc_print_statistics i386_print_statistics
27633965Sjdp
27733965Sjdp#define md_number_to_chars number_to_chars_littleendian
27833965Sjdp
27933965Sjdp#ifdef SCO_ELF
28033965Sjdp#define tc_init_after_args() sco_id ()
281218822Sdimextern void sco_id (void);
28233965Sjdp#endif
28333965Sjdp
284218822Sdim#define WORKING_DOT_WORD 1
285218822Sdim
286130570Sobrien/* We want .cfi_* pseudo-ops for generating unwind info.  */
287130570Sobrien#define TARGET_USE_CFIPOP 1
288130570Sobrien
289130570Sobrienextern unsigned int x86_dwarf2_return_column;
290130570Sobrien#define DWARF2_DEFAULT_RETURN_COLUMN x86_dwarf2_return_column
291130570Sobrien
292130570Sobrienextern int x86_cie_data_alignment;
293130570Sobrien#define DWARF2_CIE_DATA_ALIGNMENT x86_cie_data_alignment
294130570Sobrien
295130570Sobrien#define tc_regname_to_dw2regnum tc_x86_regname_to_dw2regnum
296218822Sdimextern int tc_x86_regname_to_dw2regnum (char *);
297130570Sobrien
298130570Sobrien#define tc_cfi_frame_initial_instructions tc_x86_frame_initial_instructions
299218822Sdimextern void tc_x86_frame_initial_instructions (void);
300130570Sobrien
301218822Sdim#define md_elf_section_type(str,len) i386_elf_section_type (str, len)
302218822Sdimextern int i386_elf_section_type (const char *, size_t);
303218822Sdim
304218822Sdim/* Support for SHF_X86_64_LARGE */
305218822Sdimextern int x86_64_section_word (char *, size_t);
306218822Sdimextern int x86_64_section_letter (int, char **);
307218822Sdim#define md_elf_section_letter(LETTER, PTR_MSG)	x86_64_section_letter (LETTER, PTR_MSG)
308218822Sdim#define md_elf_section_word(STR, LEN)		x86_64_section_word (STR, LEN)
309218822Sdim
310218822Sdim#ifdef TE_PE
311218822Sdim
312218822Sdim#define O_secrel O_md1
313218822Sdim
314218822Sdim#define TC_DWARF2_EMIT_OFFSET  tc_pe_dwarf2_emit_offset
315218822Sdimvoid tc_pe_dwarf2_emit_offset (symbolS *, unsigned int);
316218822Sdim
317218822Sdim#endif /* TE_PE */
318218822Sdim
319130570Sobrien#endif /* TC_I386 */
320