1 /* tc-hppa.h -- Header file for the PA */
3 /* Copyright (C) 1989, 1993 Free Software Foundation, Inc.
5 This file is part of GAS, the GNU Assembler.
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 1, or (at your option)
12 GAS is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GAS; see the file COPYING. If not, write to
19 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
23 HP PA-RISC support was contributed by the Center for Software Science
24 at the University of Utah.
35 #include "../bfd/elf32-hppa.h"
38 #define TARGET_ARCH bfd_arch_hppa
39 #define TARGET_FORMAT "elf32-hppa"
41 /* Local labels have an "L$" prefix. */
42 #define LOCAL_LABEL(name) ((name)[0] == 'L' && (name)[1] == '$')
43 #define ASEC_NULL (asection *)0
45 /* We can do sym1 - sym2 as long as sym2 is $global$ */
47 #define SEG_DIFF_ALLOWED
51 SGL
, DBL
, ILLEGAL_FMT
, QUAD
54 extern char *expr_end
;
56 extern void s_globl (), s_long (), s_short (), s_space (), cons ();
57 extern void stringer ();
58 extern unsigned int next_char_of_string ();
60 extern void pa_big_cons ();
61 extern void pa_cons ();
62 extern void pa_data ();
63 extern void pa_desc ();
64 extern void pa_float_cons ();
65 extern void pa_fill ();
66 extern void pa_lcomm ();
67 extern void pa_lsym ();
68 extern void pa_stringer ();
69 extern void pa_text ();
70 extern void pa_version ();
72 int pa_parse_number ();
74 int pa_parse_fp_cmp_cond ();
76 FP_Operand_Format
pa_parse_fp_format ();
79 int getExpression (char *str
);
84 int getAbsoluteExpression ();
86 int evaluateAbsolute ();
88 int pa_build_arg_reloc ();
90 unsigned int pa_align_arg_reloc ();
94 int pa_parse_nullif ();
96 int pa_parse_nonneg_cmpsub_cmpltr ();
98 int pa_parse_neg_cmpsub_cmpltr ();
100 int pa_parse_nonneg_add_cmpltr ();
102 int pa_parse_neg_add_cmpltr ();
104 int pa_build_arg_reloc ();
106 void s_seg (), s_proc (), s_data1 ();
108 void pa_block (), pa_call (), pa_call_args (), pa_callinfo ();
109 void pa_code (), pa_comm (), pa_copyright (), pa_end ();
111 void pa_entry (), pa_equ (), pa_exit (), pa_export ();
112 void pa_export_args (), pa_import (), pa_label (), pa_leave ();
113 void pa_origin (), pa_proc (), pa_procend (), pa_space ();
114 void pa_spnum (), pa_subspace (), pa_version ();
117 extern const pseudo_typeS md_pseudo_table
[];
120 PA-89 floating point registers are arranged like this:
123 +--------------+--------------+
124 | 0 or 16L | 16 or 16R |
125 +--------------+--------------+
126 | 1 or 17L | 17 or 17R |
127 +--------------+--------------+
135 +--------------+--------------+
136 | 14 or 30L | 30 or 30R |
137 +--------------+--------------+
138 | 15 or 31L | 31 or 31R |
139 +--------------+--------------+
142 The following is a version of pa_parse_number that
143 handles the L/R notation and returns the correct
144 value to put into the instruction register field.
145 The correct value to put into the instruction is
146 encoded in the structure 'pa_89_fp_reg_struct'.
150 struct pa_89_fp_reg_struct
156 int need_89_opcode ();
157 int pa_89_parse_number ();
162 unsigned int arg_reloc
;
163 unsigned int arg_count
;
166 typedef struct call_desc call_descS
;
168 extern call_descS last_call_desc
;
170 /* GDB debug support */
172 #if defined(OBJ_SOME)
173 #define GDB_DEBUG_SPACE_NAME "$GDB_DEBUG$"
174 #define GDB_STRINGS_SUBSPACE_NAME "$GDB_STRINGS$"
175 #define GDB_SYMBOLS_SUBSPACE_NAME "$GDB_SYMBOLS$"
177 #define GDB_DEBUG_SPACE_NAME ".stab"
178 #define GDB_STRINGS_SUBSPACE_NAME ".stabstr"
179 #define GDB_SYMBOLS_SUBSPACE_NAME ".stab"
181 /* pre-defined subsegments (subspaces) for the HP 9000 Series 800 */
183 #define SUBSEG_CODE 0
184 #define SUBSEG_DATA 0
187 #define SUBSEG_UNWIND 3
188 #define SUBSEG_GDB_STRINGS 0
189 #define SUBSEG_GDB_SYMBOLS 1
191 #define UNWIND_SECTION_NAME ".hppa_unwind"
192 /* subspace dictionary chain entry structure */
194 struct subspace_dictionary_chain
196 #if defined(OBJ_OSFROSE) | defined(OBJ_ELF)
198 region_command_t
*ssd_entry
;/* XXX: not sure this is what we need here */
200 Elf_Internal_Shdr
*ssd_entry
;
201 unsigned long ssd_vm_addr
;
203 char *ssd_name
; /* used until time of writing object file */
204 /* then we use ssd_entry->regc_region_name */
205 unsigned char ssd_quadrant
;
206 unsigned char ssd_sort_key
;
207 unsigned char ssd_common
;
208 unsigned char ssd_dup_common
;
209 unsigned char ssd_loadable
;
210 unsigned char ssd_code_only
;
212 subspace_dictS
*ssd_entry
; /* this dictionary */
214 int ssd_defined
; /* this subspace has been used */
215 int ssd_space_number
; /* space # this subspace is in */
216 asection
*ssd_seg
; /* this subspace = this seg */
217 int ssd_subseg
; /* and subseg */
219 int object_file_index
; /* index of this entry within
220 the subspace dictionary of
221 the object file (not used until
222 the object file is written */
223 int ssd_last_align
; /* the size of the last alignment
224 request for this subspace */
225 struct symbol
*ssd_start_sym
; /* a symbol whose value is the
226 start of this subspace */
227 struct subspace_dictionary_chain
*ssd_next
; /* next subspace dict. entry */
230 typedef struct subspace_dictionary_chain subspace_dict_chainS
;
232 /* space dictionary chain entry structure */
234 struct space_dictionary_chain
237 region_command_t
*sd_entry
; /* XXX: not sure this is what we need here */
238 char *sd_name
; /* used until time of writing object file */
239 /* then we use sd_entry->regc_region_name */
240 unsigned int sd_loadable
;
241 unsigned int sd_private
;
242 unsigned int sd_spnum
;
243 unsigned char sd_sort_key
;
246 Elf_Internal_Shdr
*sd_entry
;
247 char *sd_name
; /* used until time of writing object file */
248 /* then we use sd_entry->sh_name */
249 unsigned int sd_loadable
;
250 unsigned int sd_private
;
251 unsigned int sd_spnum
;
252 unsigned char sd_sort_key
;
254 space_dictS
*sd_entry
; /* this dictionary */
257 int sd_defined
; /* this space has been used */
258 asection
*sd_seg
; /* GAS segment to which this space corresponds */
259 int sd_last_subseg
; /* current subsegment number we are using */
260 subspace_dict_chainS
*sd_subspaces
; /* all subspaces in this space */
261 struct space_dictionary_chain
*sd_next
; /* the next space dict. entry */
264 typedef struct space_dictionary_chain space_dict_chainS
;
267 Macros to maintain spaces and subspaces
271 #define SPACE_DEFINED(space_chain) (space_chain)->sd_defined
272 #define SPACE_PRIVATE(space_chain) (space_chain)->sd_private
273 #define SPACE_LOADABLE(space_chain) (space_chain)->sd_loadable
274 #define SPACE_SPNUM(space_chain) (space_chain)->sd_spnum
275 #define SPACE_SORT(space_chain) (space_chain)->sd_sort_key
276 #define SPACE_NAME(space_chain) (space_chain)->sd_name
278 #define SUBSPACE_QUADRANT(ss_chain) (ss_chain)->ssd_quadrant
279 #define SUBSPACE_ALIGN(ss_chain) (ss_chain)->ssd_entry->regc_addralign
280 #define SUBSPACE_ACCESS(ss_chain) (ss_chain)->ssd_entry->regc_initprot
281 #define SUBSPACE_SORT(ss_chain) (ss_chain)->ssd_sort_key
282 #define SUBSPACE_COMMON(ss_chain) (ss_chain)->ssd_common
283 #define SUBSPACE_ZERO(ss_chain) (ss_chain)->ssd_zero
284 #define SUBSPACE_DUP_COMM(ss_chain) (ss_chain)->ssd_dup_common
285 #define SUBSPACE_CODE_ONLY(ssch) ((ssch)->ssd_entry->regc_flags & REG_TEXT_T)
286 #define SET_SUBSPACE_CODE_ONLY(ssch,val) (ssch)->ssd_entry->regc_flags |= ((val) ? REG_TEXT_T : 0)
287 #define SUBSPACE_LOADABLE(ss_chain) (ss_chain)->ssd_loadable
288 #define SUBSPACE_SUBSPACE_START(ss_chain) (ss_chain)->ssd_entry->regc_addr.vm_addr
289 #define SUBSPACE_SUBSPACE_LENGTH(ss_chain) (ss_chain)->ssd_entry->regc_vm_size
290 #define SUBSPACE_REGION_NAME(ss_chain) (ss_chain)->ssd_entry->regc_region_name
291 #define SUBSPACE_NAME(ss_chain) (ss_chain)->ssd_name
295 #define RELOC_EXPANSION_POSSIBLE
296 #define MAX_RELOC_EXPANSION 5
298 #define SPACE_DEFINED(space_chain) (space_chain)->sd_defined
299 #define SPACE_PRIVATE(space_chain) (space_chain)->sd_private
300 #define SPACE_LOADABLE(space_chain) (space_chain)->sd_loadable
301 #define SPACE_SPNUM(space_chain) (space_chain)->sd_spnum
302 #define SPACE_SORT(space_chain) (space_chain)->sd_sort_key
303 #define SPACE_NAME(space_chain) (space_chain)->sd_name
305 #define SUBSPACE_QUADRANT(ss_chain) (ss_chain)->ssd_quadrant
306 #define SUBSPACE_ALIGN(ss_chain) (ss_chain)->ssd_entry->sh_addralign
307 #define SUBSPACE_ACCESS(ss_chain) (ss_chain)->ssd_entry->sh_flags
308 #define SUBSPACE_SORT(ss_chain) (ss_chain)->ssd_sort_key
309 #define SUBSPACE_COMMON(ss_chain) (ss_chain)->ssd_common
310 #define SUBSPACE_ZERO(ss_chain) (ss_chain)->ssd_zero
311 #define SUBSPACE_DUP_COMM(ss_chain) (ss_chain)->ssd_dup_common
312 #define SUBSPACE_CODE_ONLY(ssch) \
313 (((ssch)->ssd_entry->sh_flags & (SHF_ALLOC | SHF_EXECINSTR | SHF_WRITE)) \
314 == (SHF_ALLOC | SHF_EXECINSTR))
315 #define SET_SUBSPACE_CODE_ONLY(ssch,val) \
316 (ssch)->ssd_entry->sh_flags &= ((val) ? ~SHF_WRITE : 0xffffffff)
317 #define SUBSPACE_LOADABLE(ss_chain) (ss_chain)->ssd_loadable
318 #define SUBSPACE_SUBSPACE_START(ss_chain) (ss_chain)->ssd_vm_addr
319 #define SUBSPACE_SUBSPACE_LENGTH(ss_chain) (ss_chain)->ssd_entry->sh_size
320 #define SUBSPACE_NAME(ss_chain) (ss_chain)->ssd_name
322 #define STAB_FIXUP(frag,toptr,symP,stab_type) \
323 if ( (stab_type == 's' || stab_type == 'n') \
324 && symP->sy_value.X_op == O_symbol) \
326 int i = S_GET_TYPE(symP) & N_TYPE; \
328 toptr-frag->fr_literal, /* where */ \
330 symP->sy_value.X_add_symbol, /* addr of sym for this stab */ \
332 (expressionS *) NULL, \
333 i == N_UNDF || i == N_ABS, /* 1 if internal reloc */ \
335 e_fsel, /* fixup fld = F% */ \
341 else if ( stab_type == 'd' ) \
343 fix_new_hppa (frag, \
344 toptr-frag->fr_literal, /* where */ \
346 symP, /* addr of sym for this stab */ \
348 (expressionS *) NULL, \
351 e_fsel, /* fixup fld = F% */ \
361 #define SPACE_DEFINED(space_chain) (space_chain)->sd_entry->is_defined
362 #define SPACE_PRIVATE(space_chain) (space_chain)->sd_entry->is_private
363 #define SPACE_LOADABLE(space_chain) (space_chain)->sd_entry->is_loadable
364 #define SPACE_SPNUM(space_chain) (space_chain)->sd_entry->space_number
365 #define SPACE_SORT(space_chain) (space_chain)->sd_entry->sort_key
366 #define SPACE_NAME(space_chain) (space_chain)->sd_entry->name
368 #define SUBSPACE_QUADRANT(ss_chain) (ss_chain)->ssd_entry->quadrant
369 #define SUBSPACE_ALIGN(ss_chain) (ss_chain)->ssd_entry->alignment
370 #define SUBSPACE_ACCESS(ss_chain) (ss_chain)->ssd_entry->access_control_bits
371 #define SUBSPACE_SORT(ss_chain) (ss_chain)->ssd_entry->sort_key
372 #define SUBSPACE_COMMON(ss_chain) (ss_chain)->ssd_entry->is_common
373 #define SUBSPACE_ZERO(ss_chain) (ss_chain)->ssd_zero
374 #define SUBSPACE_DUP_COMM(ss_chain) (ss_chain)->ssd_entry->dup_common
375 #define SUBSPACE_CODE_ONLY(ss_chain) (ss_chain)->ssd_entry->code_only
376 #define SUBSPACE_LOADABLE(ss_chain) (ss_chain)->ssd_entry->is_loadable
377 #define SUBSPACE_SUBSPACE_START(ss_chain) (ss_chain)->ssd_entry->subspace_start
378 #define SUBSPACE_SUBSPACE_LENGTH(ss_chain) (ss_chain)->ssd_entry->subspace_length
379 #define SUBSPACE_NAME(ss_chain) (ss_chain)->ssd_entry->name
382 extern space_dict_chainS
*space_dict_root
;
383 extern space_dict_chainS
*space_dict_last
;
385 extern space_dict_chainS
*current_space
;
386 extern subspace_dict_chainS
*current_subspace
;
388 extern space_dict_chainS
*create_new_space ();
390 extern subspace_dict_chainS
*create_new_subspace ();
392 extern subspace_dict_chainS
*update_subspace ();
394 extern space_dict_chainS
*is_defined_space ();
396 extern space_dict_chainS
*pa_segment_to_space ();
398 extern subspace_dict_chainS
*is_defined_subspace ();
400 extern subspace_dict_chainS
*pa_subsegment_to_subspace ();
402 extern space_dict_chainS
*pa_find_space_by_number ();
404 extern unsigned int pa_subspace_start ();
406 extern int is_last_defined_subspace ();
410 extern struct symbol
*pa_get_start_symbol ();
412 extern struct symbol
*pa_set_start_symbol ();
414 /* default space and subspace dictionaries */
416 struct default_subspace_dict
420 char loadable
, code_only
, common
, dup_common
, zero
;
422 int access
, space_index
, alignment
, quadrant
;
426 int def_space_index
; /* this is an index in the default spaces array */
427 char *alias
; /* an alias for this section (or NULL if there isn't one) */
432 extern struct default_subspace_dict pa_def_subspaces
[];
434 struct default_space_dict
446 /* an alias for this section (or NULL if there isn't one) */
451 extern struct default_space_dict pa_def_spaces
[];
454 Support for keeping track of the most recent label in each
458 #define tc_frob_label(sym) pa_define_label (sym)
460 typedef struct label_symbol_struct
462 /* the label symbol */
463 struct symbol
*lss_label
;
464 /* the space to which it applies */
465 space_dict_chainS
*lss_space
;
466 /* the next label symbol */
467 struct label_symbol_struct
*lss_next
;
470 void pa_define_label ();
472 /* end of label symbol support. */
474 #define is_DP_relative(exp) \
475 ((exp).X_op == O_subtract \
476 && strcmp((exp).X_op_symbol->bsym->name, "$global$") == 0)
478 #define is_PC_relative(exp) \
479 ((exp).X_op == O_subtract \
480 && strcmp((exp).X_op_symbol->bsym->name, "$PIC_pcrel$0") == 0)
482 #define is_complex(exp) \
483 ((exp).X_op != O_constant && (exp).X_op != O_symbol)
485 #define tc_crawl_symbol_chain(headers) {;} /* Not used. */
487 #define tc_headers_hook(headers) {;} /* Not used. */
489 #define elf_tc_symbol hppa_tc_symbol
490 #define elf_tc_make_sections hppa_tc_make_sections
491 extern void elf_hppa_final_processing ();
492 #define elf_tc_final_processing elf_hppa_final_processing
494 /* We need to parse field selectors in .byte, etc. */
496 #define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) \
497 parse_cons_expression_hppa (EXP)
498 #define TC_CONS_FIX_NEW cons_fix_new_hppa
500 /* FIXME these used to be prototypes, but both want an expressionS which
501 is not defined when this file is included. */
502 extern void parse_cons_expression_hppa ();
503 extern void cons_fix_new_hppa ();
505 /* On the PA, an equal sign often appears as a condition or nullification
506 completer in an instruction. This can be detected by checking the
507 previous character, if the character is a comma, then the equal is
508 being used as part of an instruction. */
509 #define TC_EQUAL_IN_INSN(C, PTR) ((C) == ',')
511 /* Similarly for an exclamation point. It is used in FP comparison
512 instructions and as an end of line marker. When used in an instruction
513 it will always follow a comma. */
514 #define TC_EOL_IN_INSN(PTR) (is_end_of_line[*(PTR)] && (PTR)[-1] == ',')
516 #endif /* _TC_HPPA_H */