aboutsummaryrefslogtreecommitdiff
path: root/gas/config/tc-ia64.h
blob: db8d7a4d10c296075180972da59fd401fdf03b13 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
/* tc-ia64.h -- Header file for tc-ia64.c.
   Copyright (C) 1998, 1999 Free Software Foundation, Inc.
   Contributed by David Mosberger-Tang <davidm@hpl.hp.com>

   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)
   any later version.

   GAS is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with GAS; see the file COPYING.  If not, write to
   the Free Software Foundation, 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA. */

#include <opcode/ia64.h>
#include <elf/ia64.h>

#define TC_IA64

#define TARGET_FORMAT (OUTPUT_FLAVOR == bfd_target_elf_flavour		\
		       ? "elf64-ia64-little"				\
		       : "unknown-format")

#define TARGET_ARCH			bfd_arch_ia64
#define TARGET_BYTES_BIG_ENDIAN		0
#define DOUBLESLASH_LINE_COMMENTS	/* allow //-style comments */
#define md_number_to_chars		number_to_chars_littleendian
#define TC_HANDLES_FX_DONE

#define NEED_LITERAL_POOL		/* need gp literal pool */
#define RELOC_REQUIRES_SYMBOL
#define DIFF_EXPR_OK   /* foo-. gets turned into PC relative relocs */
#define NEED_INDEX_OPERATOR		/* [ ] is index operator */

#define QUOTES_IN_INSN			/* allow `string "foo;bar"' */
#define LEX_AT		LEX_NAME	/* allow `@' inside name */
#define LEX_QM		LEX_NAME	/* allow `?' inside name */
#define LEX_HASH	LEX_END_NAME	/* allow `#' ending a name */

struct ia64_fix
  {
    int bigendian;			/* byte order at fix location */
    enum ia64_opnd opnd;
  };

extern void ia64_do_align PARAMS((int n));
extern void ia64_end_of_source PARAMS((void));
extern void ia64_start_line PARAMS((void));
extern int ia64_unrecognized_line PARAMS((int ch));
extern void ia64_frob_label PARAMS((struct symbol *sym));
extern void ia64_flush_pending_output PARAMS((void));
extern int ia64_parse_name (char *name, expressionS *e);
extern int ia64_optimize_expr PARAMS((expressionS *l, operatorT op,
				      expressionS *r));
extern void ia64_cons_align PARAMS((int));
extern void ia64_flush_insns PARAMS((void));
extern int ia64_fix_adjustable PARAMS((struct fix *fix));
extern int ia64_force_relocation PARAMS((struct fix *));
extern void ia64_cons_fix_new PARAMS ((fragS *f, int where, int nbytes,
				       expressionS *exp));
extern void ia64_validate_fix PARAMS ((struct fix *fix));
extern char * ia64_canonicalize_symbol_name PARAMS ((char *));
extern flagword ia64_elf_section_flags PARAMS ((flagword, int, int));
extern long ia64_pcrel_from_section PARAMS ((struct fix *fix, segT sec));
extern int ia64_md_do_align PARAMS ((int, const char *, int, int));

#define md_end()       			ia64_end_of_source ()
#define md_start_line_hook()		ia64_start_line ()
#define tc_unrecognized_line(ch)	ia64_unrecognized_line (ch)
#define tc_frob_label(s)		ia64_frob_label (s)
#define md_flush_pending_output()	ia64_flush_pending_output ()
#define md_parse_name(s,e)		ia64_parse_name (s, e)
#define tc_canonicalize_symbol_name(s)	ia64_canonicalize_symbol_name (s)
#define md_optimize_expr(l,o,r)		ia64_optimize_expr (l, o, r)
#define md_cons_align(n)		ia64_cons_align (n)
#define TC_FORCE_RELOCATION(f)		ia64_force_relocation (f)
#define tc_fix_adjustable(f)		ia64_fix_adjustable (f)
#define md_convert_frag(b,s,f)		as_fatal ("ia64_convert_frag")
#define md_create_long_jump(p,f,t,fr,s)	as_fatal("ia64_create_long_jump")
#define md_create_short_jump(p,f,t,fr,s) \
					as_fatal("ia64_create_short_jump")
#define md_estimate_size_before_relax(f,s) \
			(as_fatal ("ia64_estimate_size_before_relax"), 1)
#define md_elf_section_flags		ia64_elf_section_flags
#define TC_FIX_TYPE			struct ia64_fix
#define TC_INIT_FIX_DATA(f)		{ f->tc_fix_data.opnd = 0; }
#define TC_CONS_FIX_NEW(f,o,l,e)	ia64_cons_fix_new (f, o, l, e)
#define TC_VALIDATE_FIX(fix,seg,skip)	ia64_validate_fix (fix)
#define MD_PCREL_FROM_SECTION(fix,sec)	ia64_pcrel_from_section (fix, sec)
#define md_do_align(n,f,l,m,j)		if (ia64_md_do_align (n,f,l,m)) goto j

/* Call md_apply_fix3 with segment instead of md_apply_fix.  */
#define MD_APPLY_FIX3

#define WORKING_DOT_WORD	/* don't do broken word processing for now */

#define ELF_TC_SPECIAL_SECTIONS						   \
{ ".sbss",	SHT_NOBITS,	SHF_ALLOC + SHF_WRITE + SHF_IA_64_SHORT }, \
{ ".sdata",	SHT_PROGBITS,	SHF_ALLOC + SHF_WRITE + SHF_IA_64_SHORT }, \
{ ".IA_64.unwind",	SHT_IA_64_UNWIND,	SHF_ALLOC }, \
{ ".IA_64.unwind_info",	SHT_PROGBITS,		SHF_ALLOC },

#define DWARF2_LINE_MIN_INSN_LENGTH 1	/* so slot-multipliers can be 1 */

/* This is the information required for unwind records in an ia64
   object file. This is required by GAS and the compiler runtime. */

/* These are the starting point masks for the various types of
   unwind records. To create a record of type R3 for instance, one
   starts by using the value UNW_R3 and or-ing in any other required values. 
   These values are also unique (in context), so they can be used to identify 
   the various record types as well. UNW_Bx and some UNW_Px do have the
   same value, but Px can only occur in a prologue context, and Bx in
   a body context.  */

#define UNW_R1	0x00
#define UNW_R2	0x40
#define UNW_R3	0x60
#define UNW_P1	0x80
#define UNW_P2	0xA0
#define UNW_P3	0xB0
#define UNW_P4	0xB8
#define UNW_P5	0xB9
#define UNW_P6	0xC0
#define UNW_P7	0xE0
#define UNW_P8	0xF0
#define UNW_P9	0xF1
#define UNW_P10	0xFF
#define UNW_X1	0xF9
#define UNW_X2	0xFA
#define UNW_X3	0xFB
#define UNW_X4	0xFC
#define UNW_B1	0x80
#define UNW_B2	0xC0
#define UNW_B3	0xE0
#define UNW_B4	0xF0

/* These are all the various types of unwind records.  */

typedef enum
{
  prologue, prologue_gr, body, mem_stack_f, mem_stack_v, psp_gr, psp_sprel,
  rp_when, rp_gr, rp_br, rp_psprel, rp_sprel, pfs_when, pfs_gr, pfs_psprel,
  pfs_sprel, preds_when, preds_gr, preds_psprel, preds_sprel,
  fr_mem, frgr_mem, gr_gr, gr_mem, br_mem, br_gr, spill_base, spill_mask,
  unat_when, unat_gr, unat_psprel, unat_sprel, lc_when, lc_gr, lc_psprel,
  lc_sprel, fpsr_when, fpsr_gr, fpsr_psprel, fpsr_sprel, 
  priunat_when_gr, priunat_when_mem, priunat_gr, priunat_psprel, 
  priunat_sprel, bsp_when, bsp_gr, bsp_psprel, bsp_sprel, bspstore_when,
  bspstore_gr, bspstore_psprel, bspstore_sprel, rnat_when, rnat_gr,
  rnat_psprel, rnat_sprel, epilogue, label_state, copy_state,
  spill_psprel, spill_sprel, spill_reg, spill_psprel_p, spill_sprel_p,
  spill_reg_p
} unw_record_type;


/* These structures declare the fields that can be used in each of the 
   4 record formats, R, P, B and X.  */

typedef struct unw_r_record
{
  unsigned long rlen;
  unsigned short mask;
  unsigned short grsave;
} unw_r_record;

typedef struct unw_p_record
{
  void *imask;
  unsigned long t;
  unsigned long size;
  unsigned long spoff;
  unsigned long br;
  unsigned long pspoff;
  unsigned short gr;
  unsigned short rmask;
  unsigned short grmask;
  unsigned long frmask;
  unsigned short brmask;
} unw_p_record;

typedef struct unw_b_record
{
  unsigned long t;
  unsigned long label;
  unsigned short ecount;
} unw_b_record;

typedef struct unw_x_record
{
  unsigned long t;
  unsigned long spoff;
  unsigned long pspoff;
  unsigned short reg;
  unsigned short treg;
  unsigned short qp;
  unsigned short xy;   /* Value of the XY field..  */
} unw_x_record;

/* This structure is used to determine the specific record type and 
   its fields.  */
typedef struct unwind_record
{
  unw_record_type type;
  union {
    unw_r_record r;
    unw_p_record p;
    unw_b_record b;
    unw_x_record x;
  } record;
} unwind_record;