more Utah changes, some cleanup of mine
[external/binutils.git] / gas / config / tc-hppa.h
1 /* tc-hppa.h -- Header file for the PA */
2
3 /* Copyright (C) 1989, 1993 Free Software Foundation, Inc.
4
5 This file is part of GAS, the GNU Assembler.
6
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)
10 any later version.
11
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.
16
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.  */
20
21
22 /*
23    HP PA-RISC support was contributed by the Center for Software Science
24    at the University of Utah.
25  */
26
27 #ifndef _TC_HPPA_H
28 #define _TC_HPPA_H
29
30 #ifndef TC_HPPA
31 #define TC_HPPA 1
32 #endif
33
34 #ifdef OBJ_ELF
35 #include "../bfd/elf32-hppa.h"
36 #endif
37
38 #define TARGET_ARCH bfd_arch_hppa
39 #define TARGET_FORMAT "elf32-hppa"
40
41 /* Local labels have an "L$" prefix.  */
42 #define LOCAL_LABEL(name) ((name)[0] == 'L' && (name)[1] == '$')
43 #define ASEC_NULL (asection *)0
44
45 /* We can do sym1 - sym2 as long as sym2 is $global$ */
46
47 #define SEG_DIFF_ALLOWED
48
49 typedef enum FPOF
50   {
51     SGL, DBL, ILLEGAL_FMT, QUAD
52   } FP_Operand_Format;
53
54 extern char *expr_end;
55
56 extern void s_globl (), s_long (), s_short (), s_space (), cons ();
57 extern void stringer ();
58 extern unsigned int next_char_of_string ();
59
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 ();
71
72 int pa_parse_number ();
73
74 int pa_parse_fp_cmp_cond ();
75
76 FP_Operand_Format pa_parse_fp_format ();
77
78 #ifdef __STDC__
79 int getExpression (char *str);
80 #else
81 int getExpression ();
82 #endif
83
84 int getAbsoluteExpression ();
85
86 int evaluateAbsolute ();
87
88 int pa_build_arg_reloc ();
89
90 unsigned int pa_align_arg_reloc ();
91
92 void pa_skip ();
93
94 int pa_parse_nullif ();
95
96 int pa_parse_nonneg_cmpsub_cmpltr ();
97
98 int pa_parse_neg_cmpsub_cmpltr ();
99
100 int pa_parse_nonneg_add_cmpltr ();
101
102 int pa_parse_neg_add_cmpltr ();
103
104 int pa_build_arg_reloc ();
105
106 void s_seg (), s_proc (), s_data1 ();
107
108 void pa_block (), pa_call (), pa_call_args (), pa_callinfo ();
109 void pa_code (), pa_comm (), pa_copyright (), pa_end ();
110 void pa_enter ();
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 ();
115 void pa_param();
116
117 extern const pseudo_typeS md_pseudo_table[];
118
119 /*
120   PA-89 floating point registers are arranged like this:
121
122
123   +--------------+--------------+
124   |   0 or 16L   |  16 or 16R   |
125   +--------------+--------------+
126   |   1 or 17L   |  17 or 17R   |
127   +--------------+--------------+
128   |              |              |
129
130   .              .              .
131   .              .              .
132   .              .              .
133
134   |              |              |
135   +--------------+--------------+
136   |  14 or 30L   |  30 or 30R   |
137   +--------------+--------------+
138   |  15 or 31L   |  31 or 31R   |
139   +--------------+--------------+
140
141
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'.
147
148  */
149
150 struct pa_89_fp_reg_struct
151   {
152     char number_part;
153     char L_R_select;
154   };
155
156 int need_89_opcode ();
157 int pa_89_parse_number ();
158
159
160 struct call_desc
161   {
162     unsigned int arg_reloc;
163     unsigned int arg_count;
164   };
165
166 typedef struct call_desc call_descS;
167
168 extern call_descS last_call_desc;
169
170 /* GDB debug support */
171
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$"
176 #else
177 #define GDB_DEBUG_SPACE_NAME ".stab"
178 #define GDB_STRINGS_SUBSPACE_NAME ".stabstr"
179 #define GDB_SYMBOLS_SUBSPACE_NAME ".stab"
180 #endif
181 /* pre-defined subsegments (subspaces) for the HP 9000 Series 800 */
182
183 #define SUBSEG_CODE   0
184 #define SUBSEG_DATA   0
185 #define SUBSEG_LIT    1
186 #define SUBSEG_BSS    2
187 #define SUBSEG_UNWIND 3
188 #define SUBSEG_GDB_STRINGS 0
189 #define SUBSEG_GDB_SYMBOLS 1
190
191 #define UNWIND_SECTION_NAME     ".hppa_unwind"
192 /* subspace dictionary chain entry structure */
193
194 struct subspace_dictionary_chain
195   {
196 #if defined(OBJ_OSFROSE) | defined(OBJ_ELF)
197 #ifdef OBJ_OSFROSE
198     region_command_t *ssd_entry;/* XXX: not sure this is what we need here */
199 #else
200     Elf_Internal_Shdr *ssd_entry;
201     unsigned long ssd_vm_addr;
202 #endif
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;
211 #else
212     subspace_dictS *ssd_entry;  /* this dictionary */
213 #endif
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 */
218     int ssd_zero;
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 */
228   };
229
230 typedef struct subspace_dictionary_chain subspace_dict_chainS;
231
232 /* space dictionary chain entry structure */
233
234 struct space_dictionary_chain
235   {
236 #ifdef OBJ_OSFROSE
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;
244 #else
245 #ifdef OBJ_ELF
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;
253 #else
254     space_dictS *sd_entry;      /* this dictionary */
255 #endif
256 #endif
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 */
262   };
263
264 typedef struct space_dictionary_chain space_dict_chainS;
265
266 /*
267     Macros to maintain spaces and subspaces
268  */
269
270 #ifdef OBJ_OSFROSE
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
277
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
292 #endif
293
294 #ifdef OBJ_ELF
295 #define RELOC_EXPANSION_POSSIBLE
296 #define MAX_RELOC_EXPANSION 5
297
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
304
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
321
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)         \
325                   {                                             \
326                      int i = S_GET_TYPE(symP) & N_TYPE;         \
327                      fix_new_hppa(frag,                         \
328                                   toptr-frag->fr_literal, /* where */   \
329                                   4,            /* size */      \
330                                   symP->sy_value.X_add_symbol,  /* addr of sym for this stab */ \
331                                   (offsetT) 0,                  \
332                                   (expressionS *) NULL,         \
333                                   i == N_UNDF || i == N_ABS,    /* 1 if internal reloc */       \
334                                   R_HPPA,       /* type */      \
335                                   e_fsel,       /* fixup fld = F% */    \
336                                   32,                           \
337                                   0,            /* arg_reloc */ \
338                                   (char *)0                     \
339                                   );                            \
340                   }                                             \
341                 else if ( stab_type == 'd' )                    \
342                   {                                             \
343                      fix_new_hppa (frag,                        \
344                                    toptr-frag->fr_literal, /* where */  \
345                                    4,           /* size */      \
346                                    symP,        /* addr of sym for this stab */ \
347                                    (offsetT) 0,                 \
348                                    (expressionS *) NULL,        \
349                                    0,                           \
350                                    R_HPPA,      /* type */      \
351                                    e_fsel,      /* fixup fld = F% */    \
352                                    32,                          \
353                                    0,           /* arg_reloc */ \
354                                    (char *)0                    \
355                                    );                           \
356                   }
357
358 #endif
359
360 #ifdef OBJ_SOM
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
367
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
380 #endif
381
382 extern space_dict_chainS *space_dict_root;
383 extern space_dict_chainS *space_dict_last;
384
385 extern space_dict_chainS *current_space;
386 extern subspace_dict_chainS *current_subspace;
387
388 extern space_dict_chainS *create_new_space ();
389
390 extern subspace_dict_chainS *create_new_subspace ();
391
392 extern subspace_dict_chainS *update_subspace ();
393
394 extern space_dict_chainS *is_defined_space ();
395
396 extern space_dict_chainS *pa_segment_to_space ();
397
398 extern subspace_dict_chainS *is_defined_subspace ();
399
400 extern subspace_dict_chainS *pa_subsegment_to_subspace ();
401
402 extern space_dict_chainS *pa_find_space_by_number ();
403
404 extern unsigned int pa_subspace_start ();
405
406 extern int is_last_defined_subspace ();
407
408 /* symbol support */
409
410 extern struct symbol *pa_get_start_symbol ();
411
412 extern struct symbol *pa_set_start_symbol ();
413
414 /* default space and subspace dictionaries */
415
416 struct default_subspace_dict
417   {
418     char *name;
419     char defined;
420     char loadable, code_only, common, dup_common, zero;
421     unsigned char sort;
422     int access, space_index, alignment, quadrant;
423 #ifdef OBJ_SOM
424     segT segment;
425 #else
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) */
428 #endif
429     subsegT subsegment;
430   };
431
432 extern struct default_subspace_dict pa_def_subspaces[];
433
434 struct default_space_dict
435   {
436     char *name;
437     int spnum;
438     char loadable;
439     char defined;
440     char private;
441     unsigned char sort;
442 #ifdef OBJ_SOM
443     segT segment;
444 #else
445     asection *segment;
446     /* an alias for this section (or NULL if there isn't one) */
447     char *alias;
448 #endif
449   };
450
451 extern struct default_space_dict pa_def_spaces[];
452
453 /*
454         Support for keeping track of the most recent label in each
455         space.
456  */
457
458 #define tc_frob_label(sym) pa_define_label (sym)
459
460 typedef struct label_symbol_struct
461   {
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;
468   } label_symbolS;
469
470 void pa_define_label ();
471
472 /* end of label symbol support. */
473
474 #define is_DP_relative(exp)                     \
475   ((exp).X_op == O_subtract                     \
476    && strcmp((exp).X_op_symbol->bsym->name, "$global$") == 0)
477
478 #define is_PC_relative(exp)                     \
479   ((exp).X_op == O_subtract                     \
480    && strcmp((exp).X_op_symbol->bsym->name, "$PIC_pcrel$0") == 0)
481
482 #define is_complex(exp)                         \
483   ((exp).X_op != O_constant && (exp).X_op != O_symbol)
484
485 #define tc_crawl_symbol_chain(headers) {;}      /* Not used. */
486
487 #define tc_headers_hook(headers) {;}    /* Not used. */
488
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
493
494 /* We need to parse field selectors in .byte, etc.  */
495
496 #define TC_PARSE_CONS_EXPRESSION(EXP, NBYTES) \
497   parse_cons_expression_hppa (EXP)
498 #define TC_CONS_FIX_NEW cons_fix_new_hppa
499
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 ();
504
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) == ',')
510
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] == ',')
515
516 #endif /* _TC_HPPA_H */