tc-ia64.h revision 104834
184865Sobrien/* tc-ia64.h -- Header file for tc-ia64.c.
289857Sobrien   Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
384865Sobrien   Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
484865Sobrien
584865Sobrien   This file is part of GAS, the GNU Assembler.
684865Sobrien
784865Sobrien   GAS is free software; you can redistribute it and/or modify
884865Sobrien   it under the terms of the GNU General Public License as published by
984865Sobrien   the Free Software Foundation; either version 2, or (at your option)
1084865Sobrien   any later version.
1184865Sobrien
1284865Sobrien   GAS is distributed in the hope that it will be useful,
1384865Sobrien   but WITHOUT ANY WARRANTY; without even the implied warranty of
1484865Sobrien   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1584865Sobrien   GNU General Public License for more details.
1684865Sobrien
1784865Sobrien   You should have received a copy of the GNU General Public License
1884865Sobrien   along with GAS; see the file COPYING.  If not, write to
1984865Sobrien   the Free Software Foundation, 59 Temple Place - Suite 330,
2084865Sobrien   Boston, MA 02111-1307, USA.  */
2184865Sobrien
22104834Sobrien#include "opcode/ia64.h"
23104834Sobrien#include "elf/ia64.h"
2484865Sobrien
2584865Sobrien#define TC_IA64
2684865Sobrien
2784865Sobrien/* Linux is little endian by default.  HPUX is big endian by default.  */
2884865Sobrien#ifdef TE_HPUX
2984865Sobrien#define md_number_to_chars		number_to_chars_bigendian
3084865Sobrien#define TARGET_BYTES_BIG_ENDIAN		1
3189857Sobrien#define MD_FLAGS_DEFAULT		EF_IA_64_BE
3284865Sobrien#else
3384865Sobrien#define md_number_to_chars		number_to_chars_littleendian
3484865Sobrien#define TARGET_BYTES_BIG_ENDIAN		0
3589857Sobrien#define MD_FLAGS_DEFAULT		EF_IA_64_ABI64
3684865Sobrien#endif /* TE_HPUX */
3784865Sobrien
3884865Sobrien/* We need to set the default object file format in ia64_init and not in
3984865Sobrien   md_begin.  This is because parse_args is called before md_begin, and we
4084865Sobrien   do not want md_begin to wipe out the flag settings set by options parsed in
4184865Sobrien   md_parse_args.  */
4284865Sobrien
4384865Sobrien#define HOST_SPECIAL_INIT ia64_init
4484865Sobrienextern void ia64_init PARAMS ((int, char **));
4584865Sobrien
4684865Sobrien#define TARGET_FORMAT ia64_target_format()
4784865Sobrienextern const char *ia64_target_format PARAMS ((void));
4884865Sobrien
4984865Sobrien#define TARGET_ARCH			bfd_arch_ia64
5084865Sobrien#define DOUBLESLASH_LINE_COMMENTS	/* allow //-style comments */
5184865Sobrien
5284865Sobrien#define NEED_LITERAL_POOL		/* need gp literal pool */
5384865Sobrien#define RELOC_REQUIRES_SYMBOL
5484865Sobrien#define DIFF_EXPR_OK   /* foo-. gets turned into PC relative relocs */
5584865Sobrien#define NEED_INDEX_OPERATOR		/* [ ] is index operator */
5684865Sobrien
5784865Sobrien#define QUOTES_IN_INSN			/* allow `string "foo;bar"' */
5884865Sobrien#define LEX_AT		LEX_NAME	/* allow `@' inside name */
5984865Sobrien#define LEX_QM		LEX_NAME	/* allow `?' inside name */
6084865Sobrien#define LEX_HASH	LEX_END_NAME	/* allow `#' ending a name */
6184865Sobrien
6284865Sobrienstruct ia64_fix
6384865Sobrien  {
6484865Sobrien    int bigendian;			/* byte order at fix location */
6584865Sobrien    enum ia64_opnd opnd;
6684865Sobrien  };
6784865Sobrien
6884865Sobrienextern void ia64_do_align PARAMS((int n));
6984865Sobrienextern void ia64_end_of_source PARAMS((void));
7084865Sobrienextern void ia64_start_line PARAMS((void));
7184865Sobrienextern int ia64_unrecognized_line PARAMS((int ch));
7284865Sobrienextern void ia64_frob_label PARAMS((struct symbol *sym));
7384865Sobrienextern void ia64_flush_pending_output PARAMS((void));
7484865Sobrienextern int ia64_parse_name (char *name, expressionS *e);
7584865Sobrienextern int ia64_optimize_expr PARAMS((expressionS *l, operatorT op,
7684865Sobrien				      expressionS *r));
7784865Sobrienextern void ia64_cons_align PARAMS((int));
7884865Sobrienextern void ia64_flush_insns PARAMS((void));
7984865Sobrienextern int ia64_fix_adjustable PARAMS((struct fix *fix));
8084865Sobrienextern int ia64_force_relocation PARAMS((struct fix *));
8184865Sobrienextern void ia64_cons_fix_new PARAMS ((fragS *f, int where, int nbytes,
8284865Sobrien				       expressionS *exp));
8384865Sobrienextern void ia64_validate_fix PARAMS ((struct fix *fix));
8484865Sobrienextern char * ia64_canonicalize_symbol_name PARAMS ((char *));
8589857Sobrienextern int ia64_elf_section_letter PARAMS ((int, char **));
8684865Sobrienextern flagword ia64_elf_section_flags PARAMS ((flagword, int, int));
8784865Sobrienextern int ia64_elf_section_type PARAMS ((const char *, size_t len));
8884865Sobrienextern long ia64_pcrel_from_section PARAMS ((struct fix *fix, segT sec));
8984865Sobrienextern void ia64_md_do_align PARAMS ((int, const char *, int, int));
9084865Sobrienextern void ia64_handle_align PARAMS ((fragS *f));
9189857Sobrienextern void ia64_after_parse_args PARAMS ((void));
9284865Sobrien
9384865Sobrien#define md_end()       			ia64_end_of_source ()
9484865Sobrien#define md_start_line_hook()		ia64_start_line ()
9584865Sobrien#define tc_unrecognized_line(ch)	ia64_unrecognized_line (ch)
9684865Sobrien#define tc_frob_label(s)		ia64_frob_label (s)
9784865Sobrien#define md_flush_pending_output()	ia64_flush_pending_output ()
9889857Sobrien#define md_parse_name(s,e,c)		ia64_parse_name (s, e)
9984865Sobrien#define tc_canonicalize_symbol_name(s)	ia64_canonicalize_symbol_name (s)
10084865Sobrien#define md_optimize_expr(l,o,r)		ia64_optimize_expr (l, o, r)
10184865Sobrien#define md_cons_align(n)		ia64_cons_align (n)
10284865Sobrien#define TC_FORCE_RELOCATION(f)		ia64_force_relocation (f)
10384865Sobrien#define tc_fix_adjustable(f)		ia64_fix_adjustable (f)
10484865Sobrien#define md_convert_frag(b,s,f)		as_fatal ("ia64_convert_frag")
10589857Sobrien#define md_create_long_jump(p,f,t,fr,s)	as_fatal ("ia64_create_long_jump")
10684865Sobrien#define md_create_short_jump(p,f,t,fr,s) \
10789857Sobrien					as_fatal ("ia64_create_short_jump")
10884865Sobrien#define md_estimate_size_before_relax(f,s) \
10984865Sobrien			(as_fatal ("ia64_estimate_size_before_relax"), 1)
11089857Sobrien#define md_elf_section_letter		ia64_elf_section_letter
11184865Sobrien#define md_elf_section_flags		ia64_elf_section_flags
11284865Sobrien#define TC_FIX_TYPE			struct ia64_fix
11384865Sobrien#define TC_INIT_FIX_DATA(f)		{ f->tc_fix_data.opnd = 0; }
11484865Sobrien#define TC_CONS_FIX_NEW(f,o,l,e)	ia64_cons_fix_new (f, o, l, e)
11584865Sobrien#define TC_VALIDATE_FIX(fix,seg,skip)	ia64_validate_fix (fix)
11684865Sobrien#define MD_PCREL_FROM_SECTION(fix,sec)	ia64_pcrel_from_section (fix, sec)
11784865Sobrien#define md_do_align(n,f,l,m,j)		ia64_md_do_align (n,f,l,m)
11884865Sobrien#define HANDLE_ALIGN(f)			ia64_handle_align (f)
11984865Sobrien#define md_elf_section_type(str,len)	ia64_elf_section_type (str, len)
12089857Sobrien#define md_after_parse_args()		ia64_after_parse_args ()
12184865Sobrien
12284865Sobrien#define MAX_MEM_FOR_RS_ALIGN_CODE  (15 + 16)
12384865Sobrien
12484865Sobrien#define WORKING_DOT_WORD	/* don't do broken word processing for now */
12584865Sobrien
12684865Sobrien#define ELF_TC_SPECIAL_SECTIONS						   \
12784865Sobrien{ ".sbss",	SHT_NOBITS,	SHF_ALLOC + SHF_WRITE + SHF_IA_64_SHORT }, \
12884865Sobrien{ ".sdata",	SHT_PROGBITS,	SHF_ALLOC + SHF_WRITE + SHF_IA_64_SHORT },
12984865Sobrien
13084865Sobrien#define DWARF2_LINE_MIN_INSN_LENGTH 1	/* so slot-multipliers can be 1 */
13184865Sobrien
13284865Sobrien/* This is the information required for unwind records in an ia64
13384865Sobrien   object file. This is required by GAS and the compiler runtime.  */
13484865Sobrien
13584865Sobrien/* These are the starting point masks for the various types of
13684865Sobrien   unwind records. To create a record of type R3 for instance, one
13784865Sobrien   starts by using the value UNW_R3 and or-ing in any other required values.
13884865Sobrien   These values are also unique (in context), so they can be used to identify
13984865Sobrien   the various record types as well. UNW_Bx and some UNW_Px do have the
14084865Sobrien   same value, but Px can only occur in a prologue context, and Bx in
14184865Sobrien   a body context.  */
14284865Sobrien
14384865Sobrien#define UNW_R1	0x00
14484865Sobrien#define UNW_R2	0x40
14584865Sobrien#define UNW_R3	0x60
14684865Sobrien#define UNW_P1	0x80
14784865Sobrien#define UNW_P2	0xA0
14884865Sobrien#define UNW_P3	0xB0
14984865Sobrien#define UNW_P4	0xB8
15084865Sobrien#define UNW_P5	0xB9
15184865Sobrien#define UNW_P6	0xC0
15284865Sobrien#define UNW_P7	0xE0
15384865Sobrien#define UNW_P8	0xF0
15484865Sobrien#define UNW_P9	0xF1
15584865Sobrien#define UNW_P10	0xFF
15684865Sobrien#define UNW_X1	0xF9
15784865Sobrien#define UNW_X2	0xFA
15884865Sobrien#define UNW_X3	0xFB
15984865Sobrien#define UNW_X4	0xFC
16084865Sobrien#define UNW_B1	0x80
16184865Sobrien#define UNW_B2	0xC0
16284865Sobrien#define UNW_B3	0xE0
16384865Sobrien#define UNW_B4	0xF0
16484865Sobrien
16584865Sobrien/* These are all the various types of unwind records.  */
16684865Sobrien
16784865Sobrientypedef enum
16884865Sobrien{
16984865Sobrien  prologue, prologue_gr, body, mem_stack_f, mem_stack_v, psp_gr, psp_sprel,
17084865Sobrien  rp_when, rp_gr, rp_br, rp_psprel, rp_sprel, pfs_when, pfs_gr, pfs_psprel,
17184865Sobrien  pfs_sprel, preds_when, preds_gr, preds_psprel, preds_sprel,
17284865Sobrien  fr_mem, frgr_mem, gr_gr, gr_mem, br_mem, br_gr, spill_base, spill_mask,
17384865Sobrien  unat_when, unat_gr, unat_psprel, unat_sprel, lc_when, lc_gr, lc_psprel,
17484865Sobrien  lc_sprel, fpsr_when, fpsr_gr, fpsr_psprel, fpsr_sprel,
17584865Sobrien  priunat_when_gr, priunat_when_mem, priunat_gr, priunat_psprel,
17684865Sobrien  priunat_sprel, bsp_when, bsp_gr, bsp_psprel, bsp_sprel, bspstore_when,
17784865Sobrien  bspstore_gr, bspstore_psprel, bspstore_sprel, rnat_when, rnat_gr,
17884865Sobrien  rnat_psprel, rnat_sprel, epilogue, label_state, copy_state,
17984865Sobrien  spill_psprel, spill_sprel, spill_reg, spill_psprel_p, spill_sprel_p,
18084865Sobrien  spill_reg_p, unwabi
18184865Sobrien} unw_record_type;
18284865Sobrien
18384865Sobrien/* These structures declare the fields that can be used in each of the
18484865Sobrien   4 record formats, R, P, B and X.  */
18584865Sobrien
18684865Sobrientypedef struct unw_r_record
18784865Sobrien{
18884865Sobrien  unsigned long rlen;
18984865Sobrien  unsigned short grmask;
19084865Sobrien  unsigned short grsave;
19184865Sobrien  /* masks to represent the union of save.g, save.f, save.b, and
19284865Sobrien     save.gf: */
19384865Sobrien  unsigned long imask_size;
19484865Sobrien  struct
19584865Sobrien  {
19684865Sobrien    unsigned char *i;
19784865Sobrien    unsigned long fr_mem;
19884865Sobrien    unsigned char gr_mem;
19984865Sobrien    unsigned char br_mem;
20084865Sobrien  } mask;
20184865Sobrien} unw_r_record;
20284865Sobrien
20384865Sobrientypedef struct unw_p_record
20484865Sobrien{
20584865Sobrien  void *imask;
20684865Sobrien  unsigned long t;
20784865Sobrien  unsigned long size;
20884865Sobrien  unsigned long spoff;
20984865Sobrien  unsigned long br;
21084865Sobrien  unsigned long pspoff;
21184865Sobrien  unsigned short gr;
21284865Sobrien  unsigned short rmask;
21384865Sobrien  unsigned short grmask;
21484865Sobrien  unsigned long frmask;
21584865Sobrien  unsigned short brmask;
21684865Sobrien  unsigned char abi;
21784865Sobrien  unsigned char context;
21884865Sobrien} unw_p_record;
21984865Sobrien
22084865Sobrientypedef struct unw_b_record
22184865Sobrien{
22284865Sobrien  unsigned long t;
22384865Sobrien  unsigned long label;
22484865Sobrien  unsigned short ecount;
22584865Sobrien} unw_b_record;
22684865Sobrien
22784865Sobrientypedef struct unw_x_record
22884865Sobrien{
22984865Sobrien  unsigned long t;
23084865Sobrien  unsigned long spoff;
23184865Sobrien  unsigned long pspoff;
23284865Sobrien  unsigned short reg;
23384865Sobrien  unsigned short treg;
23484865Sobrien  unsigned short qp;
23584865Sobrien  unsigned short ab;	/* Value of the AB field..  */
23684865Sobrien  unsigned short xy;	/* Value of the XY field..  */
23784865Sobrien} unw_x_record;
23884865Sobrien
23984865Sobrien/* This structure is used to determine the specific record type and
24084865Sobrien   its fields.  */
24184865Sobrientypedef struct unwind_record
24284865Sobrien{
24384865Sobrien  unw_record_type type;
24484865Sobrien  union {
24584865Sobrien    unw_r_record r;
24684865Sobrien    unw_p_record p;
24784865Sobrien    unw_b_record b;
24884865Sobrien    unw_x_record x;
24984865Sobrien  } record;
25084865Sobrien} unwind_record;
25184865Sobrien
252104834Sobrien/* This expression evaluates to false if the relocation is for a local
25384865Sobrien   object for which we still want to do the relocation at runtime.
25484865Sobrien   True if we are willing to perform this relocation while building
25584865Sobrien   the .o file.  This is only used for pcrel relocations.  */
25684865Sobrien
25789857Sobrien/* If the reloc type is BFD_RELOC_UNUSED, then this is for a TAG13/TAG13b field
25889857Sobrien   which has no external reloc, so we must resolve the value now.  */
25989857Sobrien
26084865Sobrien#define TC_RELOC_RTSYM_LOC_FIXUP(FIX)				\
26184865Sobrien  ((FIX)->fx_addsy == NULL					\
26289857Sobrien   || (FIX)->fx_r_type == BFD_RELOC_UNUSED			\
26384865Sobrien   || (! S_IS_EXTERNAL ((FIX)->fx_addsy)			\
26484865Sobrien       && ! S_IS_WEAK ((FIX)->fx_addsy)				\
26584865Sobrien       && S_IS_DEFINED ((FIX)->fx_addsy)			\
26684865Sobrien       && ! S_IS_COMMON ((FIX)->fx_addsy)))
267