tc-arm.h revision 77298
160484Sobrien/* This file is tc-arm.h
277298Sobrien   Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000
360484Sobrien   Free Software Foundation, Inc.
460484Sobrien   Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
560484Sobrien	Modified by David Taylor (dtaylor@armltd.co.uk)
660484Sobrien
760484Sobrien   This file is part of GAS, the GNU Assembler.
860484Sobrien
960484Sobrien   GAS is free software; you can redistribute it and/or modify
1060484Sobrien   it under the terms of the GNU General Public License as published by
1160484Sobrien   the Free Software Foundation; either version 2, or (at your option)
1260484Sobrien   any later version.
1360484Sobrien
1460484Sobrien   GAS is distributed in the hope that it will be useful,
1560484Sobrien   but WITHOUT ANY WARRANTY; without even the implied warranty of
1660484Sobrien   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1760484Sobrien   GNU General Public License for more details.
1860484Sobrien
1960484Sobrien   You should have received a copy of the GNU General Public License
2060484Sobrien   along with GAS; see the file COPYING.  If not, write to the Free
2160484Sobrien   Software Foundation, 59 Temple Place - Suite 330, Boston, MA
2260484Sobrien   02111-1307, USA.  */
2360484Sobrien
2460484Sobrien#define TC_ARM 1
2560484Sobrien
2660484Sobrien#ifndef TARGET_BYTES_BIG_ENDIAN
2760484Sobrien#define TARGET_BYTES_BIG_ENDIAN 0
2860484Sobrien#endif
2960484Sobrien
3060484Sobrien#define WORKING_DOT_WORD
3160484Sobrien
3260484Sobrien#define COFF_MAGIC 	ARMMAGIC
3360484Sobrien#define TARGET_ARCH 	bfd_arch_arm
3460484Sobrien
3560484Sobrien#define AOUT_MACHTYPE 	0
3660484Sobrien
3760484Sobrien#define DIFF_EXPR_OK
3860484Sobrien
3960484Sobrien#ifdef  LITTLE_ENDIAN
4060484Sobrien#undef  LITTLE_ENDIAN
4160484Sobrien#endif
4260484Sobrien
4360484Sobrien#ifdef  BIG_ENDIAN
4460484Sobrien#undef  BIG_ENDIAN
4560484Sobrien#endif
4660484Sobrien
4760484Sobrien#define LITTLE_ENDIAN 	1234
4860484Sobrien#define BIG_ENDIAN 	4321
4960484Sobrien
5060484Sobrien#if defined OBJ_AOUT
5160484Sobrien#if defined TE_RISCIX
5260484Sobrien# define TARGET_FORMAT "a.out-riscix"
5360484Sobrien#elif defined TE_LINUX
5460484Sobrien# define ARM_BI_ENDIAN
5560484Sobrien# define TARGET_FORMAT "a.out-arm-linux"
5660484Sobrien#elif defined TE_NetBSD
5760484Sobrien# define TARGET_FORMAT "a.out-arm-netbsd"
5860484Sobrien#else
5960484Sobrien# define ARM_BI_ENDIAN
6060484Sobrien# define TARGET_FORMAT \
6160484Sobrien  (target_big_endian ? "a.out-arm-big" : "a.out-arm-little")
6260484Sobrien#endif
6360484Sobrien#endif /* OBJ_AOUT */
6460484Sobrien
6560484Sobrien#ifdef OBJ_AIF
6660484Sobrien#define TARGET_FORMAT "aif"
6760484Sobrien#endif
6860484Sobrien
6960484Sobrien#if defined OBJ_COFF || defined OBJ_ELF
7060484Sobrien# define ARM_BI_ENDIAN
7177298Sobrien
7260484Sobrien# define TC_VALIDATE_FIX(fixP, segType, Label) \
7360484Sobrien     if (arm_validate_fix (fixP)) add_symbolP = fixP->fx_addsy
7460484Sobrien  extern boolean arm_validate_fix PARAMS ((struct fix *));
7560484Sobrien#endif
7677298Sobrien
7760484Sobrien#ifdef OBJ_COFF
7860484Sobrien# if defined TE_PE
7960484Sobrien#  define TC_FORCE_RELOCATION(x) ((x)->fx_r_type == BFD_RELOC_RVA)
8060484Sobrien#   ifdef TE_EPOC
8160484Sobrien#    define TARGET_FORMAT (target_big_endian ? "epoc-pe-arm-big" : "epoc-pe-arm-little")
8260484Sobrien#   else
8360484Sobrien#    define TARGET_FORMAT (target_big_endian ? "pe-arm-big" : "pe-arm-little")
8460484Sobrien#   endif
8560484Sobrien# else
8660484Sobrien#  define TARGET_FORMAT (target_big_endian ? "coff-arm-big" : "coff-arm-little")
8760484Sobrien# endif
8860484Sobrien#endif
8960484Sobrien
9060484Sobrien#ifdef OBJ_ELF
9160484Sobrien# define TARGET_FORMAT elf32_arm_target_format()
9260484Sobrien  extern const char * elf32_arm_target_format PARAMS ((void));
9377298Sobrien
9460484Sobrien# define TC_FORCE_RELOCATION(fixp) arm_force_relocation (fixp)
9560484Sobrien  extern int arm_force_relocation PARAMS ((struct fix *));
9660484Sobrien#endif
9760484Sobrien
9860484Sobrien#define md_convert_frag(b, s, f) {as_fatal (_("arm convert_frag\n"));}
9960484Sobrien
10060484Sobrien#define md_cleanup() arm_cleanup ()
10160484Sobrien extern void arm_cleanup PARAMS ((void));
10260484Sobrien
10360484Sobrien#define md_start_line_hook() arm_start_line_hook ()
10460484Sobrien extern void arm_start_line_hook PARAMS ((void));
10560484Sobrien
10660484Sobrien#define tc_frob_label(S) arm_frob_label (S)
10760484Sobrien extern void arm_frob_label PARAMS ((symbolS *));
10860484Sobrien
10960484Sobrien/* We also need to mark assembler created symbols:  */
11060484Sobrien#define tc_frob_fake_label(S) arm_frob_label (S)
11160484Sobrien
11260484Sobrien/* NOTE: The fake label creation in stabs.c:s_stab_generic() has
11360484Sobrien   deliberately not been updated to mark assembler created stabs
11460484Sobrien   symbols as Thumb.  */
11560484Sobrien
11660484Sobrien#define TC_FIX_TYPE PTR
11760484Sobrien#define TC_INIT_FIX_DATA(FIXP) ((FIXP)->tc_fix_data = NULL)
11860484Sobrien
11977298Sobrien#if defined OBJ_ELF || defined OBJ_COFF
12060484Sobrien#include "write.h"        /* For definition of fixS */
12160484Sobrien#define obj_fix_adjustable(fixP) arm_fix_adjustable (fixP)
12260484Sobrienboolean arm_fix_adjustable PARAMS ((fixS *));
12377298Sobrien
12477298Sobrien/* This arranges for gas/write.c to not apply a relocation if
12577298Sobrien   obj_fix_adjustable() says it is not adjustable.  */
12677298Sobrien#define TC_FIX_ADJUSTABLE(fixP) obj_fix_adjustable (fixP)
12760484Sobrien#else
12860484Sobrien#define obj_fix_adjustable(fixP) 0
12960484Sobrien#endif
13060484Sobrien
13160484Sobrien/* We need to keep some local information on symbols.  */
13260484Sobrien
13360484Sobrien#define TC_SYMFIELD_TYPE unsigned int
13460484Sobrien#define ARM_GET_FLAG(s)   	(*symbol_get_tc (s))
13560484Sobrien#define ARM_SET_FLAG(s,v) 	(*symbol_get_tc (s) |= (v))
13660484Sobrien#define ARM_RESET_FLAG(s,v) 	(*symbol_get_tc (s) &= ~(v))
13760484Sobrien
13860484Sobrien#define ARM_FLAG_THUMB 		(1 << 0)	/* The symbol is a Thumb symbol rather than an Arm symbol.  */
13960484Sobrien#define ARM_FLAG_INTERWORK 	(1 << 1)	/* The symbol is attached to code that suppports interworking.  */
14060484Sobrien#define THUMB_FLAG_FUNC		(1 << 2)	/* The symbol is attached to the start of a Thumb function.  */
14160484Sobrien
14260484Sobrien#define ARM_IS_THUMB(s)		(ARM_GET_FLAG (s) & ARM_FLAG_THUMB)
14360484Sobrien#define ARM_IS_INTERWORK(s)	(ARM_GET_FLAG (s) & ARM_FLAG_INTERWORK)
14460484Sobrien#define THUMB_IS_FUNC(s)	(ARM_GET_FLAG (s) & THUMB_FLAG_FUNC)
14560484Sobrien
14660484Sobrien#define ARM_SET_THUMB(s,t)      ((t) ? ARM_SET_FLAG (s, ARM_FLAG_THUMB)     : ARM_RESET_FLAG (s, ARM_FLAG_THUMB))
14760484Sobrien#define ARM_SET_INTERWORK(s,t)  ((t) ? ARM_SET_FLAG (s, ARM_FLAG_INTERWORK) : ARM_RESET_FLAG (s, ARM_FLAG_INTERWORK))
14860484Sobrien#define THUMB_SET_FUNC(s,t)     ((t) ? ARM_SET_FLAG (s, THUMB_FLAG_FUNC)    : ARM_RESET_FLAG (s, THUMB_FLAG_FUNC))
14960484Sobrien
15060484Sobrien#define TC_START_LABEL(C,STR) \
15160484Sobrien  (c == ':' || (c == '/' && arm_data_in_code ()))
15260484Sobrienint arm_data_in_code PARAMS ((void));
15360484Sobrien
15460484Sobrien#define tc_canonicalize_symbol_name(str) \
15560484Sobrien arm_canonicalize_symbol_name (str);
15660484Sobrienchar * arm_canonicalize_symbol_name PARAMS ((char *));
15760484Sobrien
15860484Sobrien#define obj_adjust_symtab() arm_adjust_symtab ()
15960484Sobrien extern void arm_adjust_symtab PARAMS ((void));
16060484Sobrien
16160484Sobrien#ifdef OBJ_ELF
16260484Sobrien#define obj_frob_symbol(sym, punt)  armelf_frob_symbol ((sym), & (punt))
16360484Sobrienvoid armelf_frob_symbol PARAMS ((symbolS *, int *));
16460484Sobrien#endif
16560484Sobrien
16660484Sobrien#define tc_aout_pre_write_hook(x)	{;}	/* not used */
16760484Sobrien
16860484Sobrien#define LISTING_HEADER "ARM GAS "
16960484Sobrien
17060484Sobrien#define OPTIONAL_REGISTER_PREFIX '%'
17160484Sobrien
17260484Sobrien#define md_operand(x)
17360484Sobrien
17460484Sobrien#define TC_HANDLES_FX_DONE
17560484Sobrien
17660484Sobrien#define MD_APPLY_FIX3
17760484Sobrien
17860484Sobrien#define LOCAL_LABEL(name) (name[0] == '.' && (name[1] == 'L'))
17960484Sobrien#define LOCAL_LABELS_FB   1
18060484Sobrien#ifdef OBJ_ELF
18160484Sobrien#define LOCAL_LABEL_PREFIX '.'
18260484Sobrien#endif
18360484Sobrien
18460484Sobrien/* This expression evaluates to false if the relocation is for a local object
18560484Sobrien   for which we still want to do the relocation at runtime.  True if we
18660484Sobrien   are willing to perform this relocation while building the .o file.
18760484Sobrien   This is only used for pcrel relocations, so GOTOFF does not need to be
18860484Sobrien   checked here.  I am not sure if some of the others are ever used with
18960484Sobrien   pcrel, but it is easier to be safe than sorry.  */
19060484Sobrien
19160484Sobrien#define TC_RELOC_RTSYM_LOC_FIXUP(FIX)  \
19260484Sobrien   (  (FIX)->fx_r_type != BFD_RELOC_ARM_GOT12 \
19360484Sobrien   && (FIX)->fx_r_type != BFD_RELOC_ARM_GOT32 \
19460484Sobrien   && (FIX)->fx_r_type != BFD_RELOC_32)
19560484Sobrien
19660484Sobrien#define TC_CONS_FIX_NEW cons_fix_new_arm
19760484Sobrien extern void cons_fix_new_arm PARAMS ((fragS *, int, int, expressionS *));
19860484Sobrien
19960484Sobrien/* Don't allow symbols to be discarded on GOT related relocs,
20077298Sobrien   nor on globals.  */
20160484Sobrien#define tc_fix_adjustable(x) (\
20260484Sobrien     ((x)->fx_r_type == BFD_RELOC_ARM_PLT32 \
20360484Sobrien   || (x)->fx_r_type == BFD_RELOC_ARM_GOT32 \
20460484Sobrien   || (x)->fx_r_type == BFD_RELOC_ARM_GOTOFF \
20560484Sobrien   || S_IS_EXTERN ((x)->fx_addsy) \
20660484Sobrien   || S_IS_WEAK ((x)->fx_addsy)) ? 0 : 1)
20777298Sobrien
20860484Sobrien#ifdef OBJ_ELF
20960484Sobrien#define GLOBAL_OFFSET_TABLE_NAME "_GLOBAL_OFFSET_TABLE_"
21060484Sobrien#else
21160484Sobrien#define GLOBAL_OFFSET_TABLE_NAME "__GLOBAL_OFFSET_TABLE_"
21260484Sobrien#endif
21377298Sobrien
21477298Sobrien#ifdef OBJ_ELF
21577298Sobrien#define DWARF2_LINE_MIN_INSN_LENGTH 2
21677298Sobrien#endif
217