* gas/hppa/more.parse/{defbug.s, stdreg.s}: New tests.
[deliverable/binutils-gdb.git] / gas / config / tc-hppa.c
CommitLineData
025b0302
ME
1/* tc-hppa.c -- Assemble for the PA
2 Copyright (C) 1989 Free Software Foundation, Inc.
3
8f78d0e9 4 This file is part of GAS, the GNU Assembler.
025b0302 5
8f78d0e9
KR
6 GAS is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 1, or (at your option)
9 any later version.
025b0302 10
8f78d0e9
KR
11 GAS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
025b0302 15
8f78d0e9
KR
16 You should have received a copy of the GNU General Public License
17 along with GAS; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
025b0302
ME
19
20
8f78d0e9
KR
21/* HP PA-RISC support was contributed by the Center for Software Science
22 at the University of Utah. */
025b0302
ME
23
24#include <stdio.h>
25#include <ctype.h>
26
27#include "as.h"
28#include "subsegs.h"
29
5cf4cd1b 30#include "../bfd/libhppa.h"
8f78d0e9 31#include "../bfd/libbfd.h"
5cf4cd1b 32
8f78d0e9
KR
33/* Be careful, this file includes data *declarations*. */
34#include "opcode/hppa.h"
35
36/* A "convient" place to put object file dependencies which do
37 not need to be seen outside of tc-hppa.c. */
5cf4cd1b 38#ifdef OBJ_ELF
8f78d0e9
KR
39/* Names of various debugging spaces/subspaces. */
40#define GDB_DEBUG_SPACE_NAME ".stab"
41#define GDB_STRINGS_SUBSPACE_NAME ".stabstr"
42#define GDB_SYMBOLS_SUBSPACE_NAME ".stab"
43#define UNWIND_SECTION_NAME ".hppa_unwind"
44/* Nonzero if CODE is a fixup code needing further processing. */
45
8f78d0e9
KR
46/* Object file formats specify relocation types. */
47typedef elf32_hppa_reloc_type reloc_type;
48
49/* Object file formats specify BFD symbol types. */
50typedef elf_symbol_type obj_symbol_type;
51
aa8b30ed
JL
52/* How to generate a relocation. */
53#define hppa_gen_reloc_type hppa_elf_gen_reloc_type
54
8f78d0e9
KR
55/* Who knows. */
56#define obj_version obj_elf_version
57
3b9a72c5
JL
58/* Use space aliases. */
59#define USE_ALIASES 1
60
8f78d0e9
KR
61/* Some local functions only used by ELF. */
62static void pa_build_symextn_section PARAMS ((void));
63static void hppa_tc_make_symextn_section PARAMS ((void));
64#endif
65
66#ifdef OBJ_SOM
67/* Names of various debugging spaces/subspaces. */
68#define GDB_DEBUG_SPACE_NAME "$GDB_DEBUG$"
69#define GDB_STRINGS_SUBSPACE_NAME "$GDB_STRINGS$"
70#define GDB_SYMBOLS_SUBSPACE_NAME "$GDB_SYMBOLS$"
71#define UNWIND_SECTION_NAME "$UNWIND$"
72
73/* Object file formats specify relocation types. */
74typedef int reloc_type;
75
76/* Who knows. */
77#define obj_version obj_som_version
78
3b9a72c5
JL
79/* Do not use space aliases. */
80#define USE_ALIASES 0
81
aa8b30ed
JL
82/* How to generate a relocation. */
83#define hppa_gen_reloc_type hppa_som_gen_reloc_type
8f78d0e9
KR
84
85/* Object file formats specify BFD symbol types. */
86typedef som_symbol_type obj_symbol_type;
5cf4cd1b
KR
87#endif
88
8f78d0e9
KR
89/* Various structures and types used internally in tc-hppa.c. */
90
91/* Unwind table and descriptor. FIXME: Sync this with GDB version. */
025b0302
ME
92
93struct unwind_desc
94 {
95 unsigned int cannot_unwind:1;
96 unsigned int millicode:1;
97 unsigned int millicode_save_rest:1;
98 unsigned int region_desc:2;
99 unsigned int save_sr:2;
8f78d0e9
KR
100 unsigned int entry_fr:4;
101 unsigned int entry_gr:5;
025b0302
ME
102 unsigned int args_stored:1;
103 unsigned int call_fr:5;
104 unsigned int call_gr:5;
105 unsigned int save_sp:1;
106 unsigned int save_rp:1;
107 unsigned int save_rp_in_frame:1;
108 unsigned int extn_ptr_defined:1;
109 unsigned int cleanup_defined:1;
110
111 unsigned int hpe_interrupt_marker:1;
112 unsigned int hpux_interrupt_marker:1;
113 unsigned int reserved:3;
114 unsigned int frame_size:27;
115 };
116
025b0302
ME
117struct unwind_table
118 {
8f78d0e9
KR
119 /* Starting and ending offsets of the region described by
120 descriptor. */
121 unsigned int start_offset;
122 unsigned int end_offset;
123 struct unwind_desc descriptor;
025b0302
ME
124 };
125
8f78d0e9
KR
126/* This structure is used by the .callinfo, .enter, .leave pseudo-ops to
127 control the entry and exit code they generate. It is also used in
128 creation of the correct stack unwind descriptors.
025b0302 129
8f78d0e9
KR
130 NOTE: GAS does not support .enter and .leave for the generation of
131 prologues and epilogues. FIXME.
132
133 The fields in structure roughly correspond to the arguments available on the
134 .callinfo pseudo-op. */
025b0302
ME
135
136struct call_info
137 {
8f78d0e9 138 /* Should sr3 be saved in the prologue? */
025b0302 139 int entry_sr;
8f78d0e9
KR
140
141 /* Does this function make calls? */
025b0302 142 int makes_calls;
025b0302 143
8f78d0e9
KR
144 /* The unwind descriptor being built. */
145 struct unwind_table ci_unwind;
146
147 /* Name of this function. */
148 symbolS *start_symbol;
149
150 /* (temporary) symbol used to mark the end of this function. */
151 symbolS *end_symbol;
152
153 /* frags associated with start and end of this function. */
154 fragS *start_frag;
155 fragS *end_frag;
156
157 /* frags for starting/ending offset of this descriptor. */
158 fragS *start_offset_frag;
159 fragS *end_offset_frag;
025b0302 160
8f78d0e9
KR
161 /* The location within {start,end}_offset_frag to find the
162 {start,end}_offset. */
163 int start_frag_where;
164 int end_frag_where;
025b0302 165
8f78d0e9
KR
166 /* Fixups (relocations) for start_offset and end_offset. */
167 fixS *start_fix;
168 fixS *end_fix;
025b0302 169
8f78d0e9
KR
170 /* Next entry in the chain. */
171 struct call_info *ci_next;
172 };
173
174/* Operand formats for FP instructions. Note not all FP instructions
175 allow all four formats to be used (for example fmpysub only allows
176 SGL and DBL). */
177typedef enum
178 {
179 SGL, DBL, ILLEGAL_FMT, QUAD
180 }
181fp_operand_format;
182
e75acd68
JL
183/* This fully describes the symbol types which may be attached to
184 an EXPORT or IMPORT directive. Only SOM uses this formation
185 (ELF has no need for it). */
186typedef enum
187{
188 SYMBOL_TYPE_UNKNOWN,
189 SYMBOL_TYPE_ABSOLUTE,
190 SYMBOL_TYPE_CODE,
191 SYMBOL_TYPE_DATA,
192 SYMBOL_TYPE_ENTRY,
193 SYMBOL_TYPE_MILLICODE,
194 SYMBOL_TYPE_PLABEL,
195 SYMBOL_TYPE_PRI_PROG,
196 SYMBOL_TYPE_SEC_PROG,
197} pa_symbol_type;
198
8f78d0e9
KR
199/* This structure contains information needed to assemble
200 individual instructions. */
025b0302
ME
201struct pa_it
202 {
8f78d0e9 203 /* Holds the opcode after parsing by pa_ip. */
025b0302 204 unsigned long opcode;
8f78d0e9
KR
205
206 /* Holds an expression associated with the current instruction. */
025b0302 207 expressionS exp;
8f78d0e9
KR
208
209 /* Does this instruction use PC-relative addressing. */
025b0302 210 int pcrel;
8f78d0e9
KR
211
212 /* Floating point formats for operand1 and operand2. */
213 fp_operand_format fpof1;
214 fp_operand_format fpof2;
215
216 /* Holds the field selector for this instruction
217 (for example L%, LR%, etc). */
025b0302 218 long field_selector;
8f78d0e9
KR
219
220 /* Holds any argument relocation bits associated with this
221 instruction. (instruction should be some sort of call). */
025b0302 222 long arg_reloc;
8f78d0e9
KR
223
224 /* The format specification for this instruction. */
025b0302 225 int format;
8f78d0e9
KR
226
227 /* The relocation (if any) associated with this instruction. */
228 reloc_type reloc;
025b0302
ME
229 };
230
8f78d0e9 231/* PA-89 floating point registers are arranged like this:
025b0302 232
025b0302 233
8f78d0e9
KR
234 +--------------+--------------+
235 | 0 or 16L | 16 or 16R |
236 +--------------+--------------+
237 | 1 or 17L | 17 or 17R |
238 +--------------+--------------+
239 | | |
240
241 . . .
242 . . .
243 . . .
244
245 | | |
246 +--------------+--------------+
247 | 14 or 30L | 30 or 30R |
248 +--------------+--------------+
249 | 15 or 31L | 31 or 31R |
250 +--------------+--------------+
251
252
253 The following is a version of pa_parse_number that
254 handles the L/R notation and returns the correct
255 value to put into the instruction register field.
256 The correct value to put into the instruction is
257 encoded in the structure 'pa_89_fp_reg_struct'. */
258
259struct pa_89_fp_reg_struct
260 {
261 /* The register number. */
262 char number_part;
263
264 /* L/R selector. */
265 char l_r_select;
266 };
267
268/* Additional information needed to build argument relocation stubs. */
269struct call_desc
270 {
271 /* The argument relocation specification. */
272 unsigned int arg_reloc;
273
274 /* Number of arguments. */
275 unsigned int arg_count;
276 };
277
278/* This structure defines an entry in the subspace dictionary
279 chain. */
280
281struct subspace_dictionary_chain
282 {
283 /* Index of containing space. */
284 unsigned long ssd_space_index;
285
47f45d66
JL
286 /* Nonzero if this space has been defined by the user code. */
287 unsigned int ssd_defined;
288
8f78d0e9
KR
289 /* Which quadrant within the space this subspace should be loaded into. */
290 unsigned char ssd_quadrant;
291
292 /* Alignment (in bytes) for this subspace. */
293 unsigned long ssd_alignment;
294
295 /* Access control bits to determine read/write/execute permissions
296 as well as gateway privilege promotions. */
297 unsigned char ssd_access_control_bits;
298
299 /* A sorting key so that it is possible to specify ordering of
300 subspaces within a space. */
301 unsigned char ssd_sort_key;
302
303 /* Nonzero of this space should be zero filled. */
304 unsigned long ssd_zero;
305
306 /* Nonzero if this is a common subspace. */
307 unsigned char ssd_common;
308
309 /* Nonzero if this is a common subspace which allows symbols to be
310 multiply defined. */
311 unsigned char ssd_dup_common;
312
313 /* Nonzero if this subspace is loadable. Note loadable subspaces
314 must be contained within loadable spaces; unloadable subspaces
315 must be contained in unloadable spaces. */
316 unsigned char ssd_loadable;
317
318 /* Nonzero if this subspace contains only code. */
319 unsigned char ssd_code_only;
320
321 /* Starting offset of this subspace. */
322 unsigned long ssd_subspace_start;
323
324 /* Length of this subspace. */
325 unsigned long ssd_subspace_length;
326
327 /* Name of this subspace. */
328 char *ssd_name;
329
330 /* GAS segment and subsegment associated with this subspace. */
331 asection *ssd_seg;
332 int ssd_subseg;
333
334 /* Index of this subspace within the subspace dictionary of the object
335 file. Not used until object file is written. */
336 int object_file_index;
337
338 /* The size of the last alignment request for this subspace. */
339 int ssd_last_align;
340
8f78d0e9
KR
341 /* Next space in the subspace dictionary chain. */
342 struct subspace_dictionary_chain *ssd_next;
343 };
344
345typedef struct subspace_dictionary_chain ssd_chain_struct;
346
347/* This structure defines an entry in the subspace dictionary
348 chain. */
349
350struct space_dictionary_chain
351 {
352
353 /* Holds the index into the string table of the name of this
354 space. */
355 unsigned int sd_name_index;
356
357 /* Nonzero if the space is loadable. */
358 unsigned int sd_loadable;
359
360 /* Nonzero if this space has been defined by the user code or
361 as a default space. */
362 unsigned int sd_defined;
363
364 /* Nonzero if this spaces has been defined by the user code. */
365 unsigned int sd_user_defined;
366
367 /* Nonzero if this space is not sharable. */
368 unsigned int sd_private;
369
370 /* The space number (or index). */
371 unsigned int sd_spnum;
372
373 /* The sort key for this space. May be used to determine how to lay
374 out the spaces within the object file. */
375 unsigned char sd_sort_key;
376
377 /* The name of this subspace. */
378 char *sd_name;
379
380 /* GAS segment to which this subspace corresponds. */
381 asection *sd_seg;
382
383 /* Current subsegment number being used. */
384 int sd_last_subseg;
385
386 /* The chain of subspaces contained within this space. */
387 ssd_chain_struct *sd_subspaces;
388
389 /* The next entry in the space dictionary chain. */
390 struct space_dictionary_chain *sd_next;
391 };
392
393typedef struct space_dictionary_chain sd_chain_struct;
394
395/* Structure for previous label tracking. Needed so that alignments,
396 callinfo declarations, etc can be easily attached to a particular
397 label. */
398typedef struct label_symbol_struct
399 {
400 struct symbol *lss_label;
401 sd_chain_struct *lss_space;
402 struct label_symbol_struct *lss_next;
403 }
404label_symbol_struct;
405
406/* This structure defines attributes of the default subspace
407 dictionary entries. */
408
409struct default_subspace_dict
410 {
411 /* Name of the subspace. */
412 char *name;
413
414 /* FIXME. Is this still needed? */
415 char defined;
416
417 /* Nonzero if this subspace is loadable. */
418 char loadable;
419
420 /* Nonzero if this subspace contains only code. */
421 char code_only;
422
423 /* Nonzero if this is a common subspace. */
424 char common;
425
426 /* Nonzero if this is a common subspace which allows symbols
427 to be multiply defined. */
428 char dup_common;
429
430 /* Nonzero if this subspace should be zero filled. */
431 char zero;
432
433 /* Sort key for this subspace. */
434 unsigned char sort;
435
436 /* Access control bits for this subspace. Can represent RWX access
437 as well as privilege level changes for gateways. */
438 int access;
439
440 /* Index of containing space. */
441 int space_index;
442
443 /* Alignment (in bytes) of this subspace. */
444 int alignment;
445
446 /* Quadrant within space where this subspace should be loaded. */
447 int quadrant;
448
449 /* An index into the default spaces array. */
450 int def_space_index;
451
452 /* An alias for this section (or NULL if no alias exists). */
453 char *alias;
454
455 /* Subsegment associated with this subspace. */
456 subsegT subsegment;
457 };
458
459/* This structure defines attributes of the default space
460 dictionary entries. */
461
462struct default_space_dict
463 {
464 /* Name of the space. */
465 char *name;
466
467 /* Space number. It is possible to identify spaces within
468 assembly code numerically! */
469 int spnum;
470
471 /* Nonzero if this space is loadable. */
472 char loadable;
473
474 /* Nonzero if this space is "defined". FIXME is still needed */
475 char defined;
476
477 /* Nonzero if this space can not be shared. */
478 char private;
479
480 /* Sort key for this space. */
481 unsigned char sort;
482
483 /* Segment associated with this space. */
484 asection *segment;
485
486 /* An alias for this section (or NULL if no alias exists). */
487 char *alias;
488 };
489
490/* Extra information needed to perform fixups (relocations) on the PA. */
491struct hppa_fix_struct
492{
8f78d0e9
KR
493 /* The field selector. */
494 int fx_r_field;
495
496 /* Type of fixup. */
497 int fx_r_type;
498
499 /* Format of fixup. */
500 int fx_r_format;
501
502 /* Argument relocation bits. */
503 long fx_arg_reloc;
504
505 /* The unwind descriptor associated with this fixup. */
506 char fx_unwind[8];
8f78d0e9
KR
507};
508
509/* Structure to hold information about predefined registers. */
510
511struct pd_reg
512{
513 char *name;
514 int value;
515};
516
517/* This structure defines the mapping from a FP condition string
518 to a condition number which can be recorded in an instruction. */
519struct fp_cond_map
520{
521 char *string;
522 int cond;
523};
524
525/* This structure defines a mapping from a field selector
526 string to a field selector type. */
527struct selector_entry
528{
529 char *prefix;
530 int field_selector;
531};
025b0302 532
8f78d0e9
KR
533/* Prototypes for functions local to tc-hppa.c. */
534
535static fp_operand_format pa_parse_fp_format PARAMS ((char **s));
8f78d0e9
KR
536static void pa_cons PARAMS ((int));
537static void pa_data PARAMS ((int));
538static void pa_desc PARAMS ((int));
539static void pa_float_cons PARAMS ((int));
540static void pa_fill PARAMS ((int));
541static void pa_lcomm PARAMS ((int));
542static void pa_lsym PARAMS ((int));
543static void pa_stringer PARAMS ((int));
544static void pa_text PARAMS ((int));
545static void pa_version PARAMS ((int));
546static int pa_parse_fp_cmp_cond PARAMS ((char **));
547static int get_expression PARAMS ((char *));
548static int pa_get_absolute_expression PARAMS ((char *));
549static int evaluate_absolute PARAMS ((expressionS, int));
550static unsigned int pa_build_arg_reloc PARAMS ((char *));
551static unsigned int pa_align_arg_reloc PARAMS ((unsigned int, unsigned int));
552static int pa_parse_nullif PARAMS ((char **));
553static int pa_parse_nonneg_cmpsub_cmpltr PARAMS ((char **, int));
554static int pa_parse_neg_cmpsub_cmpltr PARAMS ((char **, int));
555static int pa_parse_neg_add_cmpltr PARAMS ((char **, int));
556static int pa_parse_nonneg_add_cmpltr PARAMS ((char **, int));
557static void pa_block PARAMS ((int));
558static void pa_call PARAMS ((int));
559static void pa_call_args PARAMS ((struct call_desc *));
560static void pa_callinfo PARAMS ((int));
561static void pa_code PARAMS ((int));
562static void pa_comm PARAMS ((int));
563static void pa_copyright PARAMS ((int));
564static void pa_end PARAMS ((int));
565static void pa_enter PARAMS ((int));
566static void pa_entry PARAMS ((int));
567static void pa_equ PARAMS ((int));
568static void pa_exit PARAMS ((int));
569static void pa_export PARAMS ((int));
570static void pa_export_args PARAMS ((symbolS *));
571static void pa_import PARAMS ((int));
572static void pa_label PARAMS ((int));
573static void pa_leave PARAMS ((int));
574static void pa_origin PARAMS ((int));
575static void pa_proc PARAMS ((int));
576static void pa_procend PARAMS ((int));
577static void pa_space PARAMS ((int));
578static void pa_spnum PARAMS ((int));
579static void pa_subspace PARAMS ((int));
580static void pa_param PARAMS ((int));
581static void pa_undefine_label PARAMS ((void));
582static int need_89_opcode PARAMS ((struct pa_it *,
583 struct pa_89_fp_reg_struct *));
584static int pa_parse_number PARAMS ((char **, struct pa_89_fp_reg_struct *));
585static label_symbol_struct *pa_get_label PARAMS ((void));
586static sd_chain_struct *create_new_space PARAMS ((char *, int, char,
587 char, char, char,
588 asection *, int));
589static ssd_chain_struct * create_new_subspace PARAMS ((sd_chain_struct *,
590 char *, char, char,
591 char, char, char,
592 char, int, int, int,
593 int, asection *));
3b9a72c5
JL
594static ssd_chain_struct *update_subspace PARAMS ((sd_chain_struct *,
595 char *, char, char, char,
8f78d0e9
KR
596 char, char, char, int,
597 int, int, int, subsegT));
598static sd_chain_struct *is_defined_space PARAMS ((char *));
47f45d66 599static ssd_chain_struct *is_defined_subspace PARAMS ((char *));
8f78d0e9
KR
600static sd_chain_struct *pa_segment_to_space PARAMS ((asection *));
601static ssd_chain_struct * pa_subsegment_to_subspace PARAMS ((asection *,
602 subsegT));
603static sd_chain_struct *pa_find_space_by_number PARAMS ((int));
604static unsigned int pa_subspace_start PARAMS ((sd_chain_struct *, int));
8f78d0e9
KR
605static void pa_ip PARAMS ((char *));
606static void fix_new_hppa PARAMS ((fragS *, int, short int, symbolS *,
607 long, expressionS *, int,
608 bfd_reloc_code_real_type, long,
609 int, long, char *));
8f78d0e9
KR
610static void md_apply_fix_1 PARAMS ((fixS *, long));
611static int is_end_of_statement PARAMS ((void));
612static int reg_name_search PARAMS ((char *));
613static int pa_chk_field_selector PARAMS ((char **));
614static int is_same_frag PARAMS ((fragS *, fragS *));
615static void pa_build_unwind_subspace PARAMS ((struct call_info *));
616static void process_exit PARAMS ((void));
617static sd_chain_struct *pa_parse_space_stmt PARAMS ((char *, int));
618static void pa_align_subseg PARAMS ((asection *, subsegT));
aa8b30ed 619static int log2 PARAMS ((int));
8f78d0e9
KR
620static int pa_next_subseg PARAMS ((sd_chain_struct *));
621static unsigned int pa_stringer_aux PARAMS ((char *));
622static void pa_spaces_begin PARAMS ((void));
623
624
625/* File and gloally scoped variable declarations. */
626
627/* Root and final entry in the space chain. */
628static sd_chain_struct *space_dict_root;
629static sd_chain_struct *space_dict_last;
630
631/* The current space and subspace. */
632static sd_chain_struct *current_space;
633static ssd_chain_struct *current_subspace;
634
635/* Root of the call_info chain. */
636static struct call_info *call_info_root;
637
638/* The last call_info (for functions) structure
639 seen so it can be associated with fixups and
640 function labels. */
641static struct call_info *last_call_info;
642
643/* The last call description (for actual calls). */
644static struct call_desc last_call_desc;
645
646/* Relaxation isn't supported for the PA yet. */
5cf4cd1b 647const relax_typeS md_relax_table[] = {0};
025b0302 648
8f78d0e9 649/* Jumps are always the same size -- one instruction. */
025b0302
ME
650int md_short_jump_size = 4;
651int md_long_jump_size = 4;
652
8f78d0e9
KR
653/* handle of the OPCODE hash table */
654static struct hash_control *op_hash = NULL;
025b0302 655
8f78d0e9
KR
656/* This array holds the chars that always start a comment. If the
657 pre-processor is disabled, these aren't very useful. */
658const char comment_chars[] = ";";
659
660/* Table of pseudo ops for the PA. FIXME -- how many of these
661 are now redundant with the overall GAS and the object file
662 dependent tables? */
663const pseudo_typeS md_pseudo_table[] =
664{
665 /* align pseudo-ops on the PA specify the actual alignment requested,
666 not the log2 of the requested alignment. */
d33ace2e
JL
667 {"align", s_align_bytes, 8},
668 {"ALIGN", s_align_bytes, 8},
025b0302
ME
669 {"block", pa_block, 1},
670 {"BLOCK", pa_block, 1},
671 {"blockz", pa_block, 0},
672 {"BLOCKZ", pa_block, 0},
673 {"byte", pa_cons, 1},
674 {"BYTE", pa_cons, 1},
675 {"call", pa_call, 0},
676 {"CALL", pa_call, 0},
677 {"callinfo", pa_callinfo, 0},
678 {"CALLINFO", pa_callinfo, 0},
679 {"code", pa_code, 0},
680 {"CODE", pa_code, 0},
681 {"comm", pa_comm, 0},
682 {"COMM", pa_comm, 0},
683 {"copyright", pa_copyright, 0},
684 {"COPYRIGHT", pa_copyright, 0},
685 {"data", pa_data, 0},
686 {"DATA", pa_data, 0},
687 {"desc", pa_desc, 0},
688 {"DESC", pa_desc, 0},
689 {"double", pa_float_cons, 'd'},
690 {"DOUBLE", pa_float_cons, 'd'},
691 {"end", pa_end, 0},
692 {"END", pa_end, 0},
693 {"enter", pa_enter, 0},
694 {"ENTER", pa_enter, 0},
695 {"entry", pa_entry, 0},
696 {"ENTRY", pa_entry, 0},
697 {"equ", pa_equ, 0},
698 {"EQU", pa_equ, 0},
699 {"exit", pa_exit, 0},
700 {"EXIT", pa_exit, 0},
701 {"export", pa_export, 0},
702 {"EXPORT", pa_export, 0},
703 {"fill", pa_fill, 0},
704 {"FILL", pa_fill, 0},
705 {"float", pa_float_cons, 'f'},
706 {"FLOAT", pa_float_cons, 'f'},
707 {"half", pa_cons, 2},
708 {"HALF", pa_cons, 2},
709 {"import", pa_import, 0},
710 {"IMPORT", pa_import, 0},
711 {"int", pa_cons, 4},
712 {"INT", pa_cons, 4},
713 {"label", pa_label, 0},
714 {"LABEL", pa_label, 0},
715 {"lcomm", pa_lcomm, 0},
716 {"LCOMM", pa_lcomm, 0},
717 {"leave", pa_leave, 0},
718 {"LEAVE", pa_leave, 0},
719 {"long", pa_cons, 4},
720 {"LONG", pa_cons, 4},
721 {"lsym", pa_lsym, 0},
722 {"LSYM", pa_lsym, 0},
aa8b30ed
JL
723 {"octa", pa_cons, 16},
724 {"OCTA", pa_cons, 16},
025b0302
ME
725 {"org", pa_origin, 0},
726 {"ORG", pa_origin, 0},
727 {"origin", pa_origin, 0},
728 {"ORIGIN", pa_origin, 0},
5cf4cd1b
KR
729 {"param", pa_param, 0},
730 {"PARAM", pa_param, 0},
025b0302
ME
731 {"proc", pa_proc, 0},
732 {"PROC", pa_proc, 0},
733 {"procend", pa_procend, 0},
734 {"PROCEND", pa_procend, 0},
aa8b30ed
JL
735 {"quad", pa_cons, 8},
736 {"QUAD", pa_cons, 8},
8f78d0e9
KR
737 {"reg", pa_equ, 1},
738 {"REG", pa_equ, 1},
025b0302
ME
739 {"short", pa_cons, 2},
740 {"SHORT", pa_cons, 2},
741 {"single", pa_float_cons, 'f'},
742 {"SINGLE", pa_float_cons, 'f'},
743 {"space", pa_space, 0},
744 {"SPACE", pa_space, 0},
745 {"spnum", pa_spnum, 0},
746 {"SPNUM", pa_spnum, 0},
747 {"string", pa_stringer, 0},
748 {"STRING", pa_stringer, 0},
749 {"stringz", pa_stringer, 1},
750 {"STRINGZ", pa_stringer, 1},
751 {"subspa", pa_subspace, 0},
752 {"SUBSPA", pa_subspace, 0},
753 {"text", pa_text, 0},
754 {"TEXT", pa_text, 0},
755 {"version", pa_version, 0},
756 {"VERSION", pa_version, 0},
757 {"word", pa_cons, 4},
758 {"WORD", pa_cons, 4},
759 {NULL, 0, 0}
760};
761
762/* This array holds the chars that only start a comment at the beginning of
763 a line. If the line seems to have the form '# 123 filename'
8f78d0e9
KR
764 .line and .file directives will appear in the pre-processed output.
765
766 Note that input_file.c hand checks for '#' at the beginning of the
025b0302 767 first line of the input file. This is because the compiler outputs
8f78d0e9
KR
768 #NO_APP at the beginning of its output.
769
770 Also note that '/*' will always start a comment. */
025b0302
ME
771const char line_comment_chars[] = "#";
772
8f78d0e9 773/* This array holds the characters which act as line separators. */
025b0302
ME
774const char line_separator_chars[] = "!";
775
8f78d0e9 776/* Chars that can be used to separate mant from exp in floating point nums. */
025b0302
ME
777const char EXP_CHARS[] = "eE";
778
8f78d0e9
KR
779/* Chars that mean this number is a floating point constant.
780 As in 0f12.456 or 0d1.2345e12.
025b0302 781
8f78d0e9
KR
782 Be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
783 changed in read.c. Ideally it shouldn't hae to know abou it at
784 all, but nothing is ideal around here. */
785const char FLT_CHARS[] = "rRsSfFdDxXpP";
025b0302 786
8f78d0e9 787static struct pa_it the_insn;
025b0302 788
8f78d0e9
KR
789/* Points to the end of an expression just parsed by get_expressoin
790 and friends. FIXME. This shouldn't be handled with a file-global
791 variable. */
792static char *expr_end;
025b0302 793
8f78d0e9 794/* Nonzero if a .callinfo appeared within the current procedure. */
5cf4cd1b 795static int callinfo_found;
025b0302 796
8f78d0e9 797/* Nonzero if the assembler is currently within a .entry/.exit pair. */
5cf4cd1b 798static int within_entry_exit;
025b0302 799
8f78d0e9
KR
800/* Nonzero if the assembler has completed exit processing for the
801 current procedure. */
5cf4cd1b 802static int exit_processing_complete;
025b0302 803
8f78d0e9 804/* Nonzero if the assembler is currently within a procedure definition. */
5cf4cd1b 805static int within_procedure;
025b0302 806
8f78d0e9
KR
807/* Handle on strucutre which keep track of the last symbol
808 seen in each subspace. */
809static label_symbol_struct *label_symbols_rootp = NULL;
025b0302 810
8f78d0e9
KR
811/* Holds the last field selector. */
812static int hppa_field_selector;
025b0302 813
8f78d0e9
KR
814/* Nonzero if errors are to be printed. */
815static int print_errors = 1;
025b0302 816
8f78d0e9 817/* List of registers that are pre-defined:
025b0302 818
8f78d0e9
KR
819 Each general register has one predefined name of the form
820 %r<REGNUM> which has the value <REGNUM>.
025b0302 821
8f78d0e9
KR
822 Space and control registers are handled in a similar manner,
823 but use %sr<REGNUM> and %cr<REGNUM> as their predefined names.
025b0302 824
8f78d0e9
KR
825 Likewise for the floating point registers, but of the form
826 %fr<REGNUM>. Floating point registers have additional predefined
827 names with 'L' and 'R' suffixes (e.g. %fr19L, %fr19R) which
828 again have the value <REGNUM>.
025b0302 829
8f78d0e9 830 Many registers also have synonyms:
025b0302 831
8f78d0e9
KR
832 %r26 - %r23 have %arg0 - %arg3 as synonyms
833 %r28 - %r29 have %ret0 - %ret1 as synonyms
834 %r30 has %sp as a synonym
025b0302 835
8f78d0e9
KR
836 Almost every control register has a synonym; they are not listed
837 here for brevity.
025b0302 838
8f78d0e9 839 The table is sorted. Suitable for searching by a binary search. */
025b0302 840
8f78d0e9 841static const struct pd_reg pre_defined_registers[] =
025b0302 842{
8f78d0e9
KR
843 {"%arg0", 26},
844 {"%arg1", 25},
845 {"%arg2", 24},
846 {"%arg3", 23},
847 {"%cr0", 0},
848 {"%cr10", 10},
849 {"%cr11", 11},
850 {"%cr12", 12},
851 {"%cr13", 13},
852 {"%cr14", 14},
853 {"%cr15", 15},
854 {"%cr16", 16},
855 {"%cr17", 17},
856 {"%cr18", 18},
857 {"%cr19", 19},
858 {"%cr20", 20},
859 {"%cr21", 21},
860 {"%cr22", 22},
861 {"%cr23", 23},
862 {"%cr24", 24},
863 {"%cr25", 25},
864 {"%cr26", 26},
865 {"%cr27", 27},
866 {"%cr28", 28},
867 {"%cr29", 29},
868 {"%cr30", 30},
869 {"%cr31", 31},
870 {"%cr8", 8},
871 {"%cr9", 9},
872 {"%eiem", 15},
873 {"%eirr", 23},
874 {"%fr0", 0},
875 {"%fr0L", 0},
876 {"%fr0R", 0},
877 {"%fr1", 1},
878 {"%fr10", 10},
879 {"%fr10L", 10},
880 {"%fr10R", 10},
881 {"%fr11", 11},
882 {"%fr11L", 11},
883 {"%fr11R", 11},
884 {"%fr12", 12},
885 {"%fr12L", 12},
886 {"%fr12R", 12},
887 {"%fr13", 13},
888 {"%fr13L", 13},
889 {"%fr13R", 13},
890 {"%fr14", 14},
891 {"%fr14L", 14},
892 {"%fr14R", 14},
893 {"%fr15", 15},
894 {"%fr15L", 15},
895 {"%fr15R", 15},
896 {"%fr16", 16},
897 {"%fr16L", 16},
898 {"%fr16R", 16},
899 {"%fr17", 17},
900 {"%fr17L", 17},
901 {"%fr17R", 17},
902 {"%fr18", 18},
903 {"%fr18L", 18},
904 {"%fr18R", 18},
905 {"%fr19", 19},
906 {"%fr19L", 19},
907 {"%fr19R", 19},
908 {"%fr1L", 1},
909 {"%fr1R", 1},
910 {"%fr2", 2},
911 {"%fr20", 20},
912 {"%fr20L", 20},
913 {"%fr20R", 20},
914 {"%fr21", 21},
915 {"%fr21L", 21},
916 {"%fr21R", 21},
917 {"%fr22", 22},
918 {"%fr22L", 22},
919 {"%fr22R", 22},
920 {"%fr23", 23},
921 {"%fr23L", 23},
922 {"%fr23R", 23},
923 {"%fr24", 24},
924 {"%fr24L", 24},
925 {"%fr24R", 24},
926 {"%fr25", 25},
927 {"%fr25L", 25},
928 {"%fr25R", 25},
929 {"%fr26", 26},
930 {"%fr26L", 26},
931 {"%fr26R", 26},
932 {"%fr27", 27},
933 {"%fr27L", 27},
934 {"%fr27R", 27},
935 {"%fr28", 28},
936 {"%fr28L", 28},
937 {"%fr28R", 28},
938 {"%fr29", 29},
939 {"%fr29L", 29},
940 {"%fr29R", 29},
941 {"%fr2L", 2},
942 {"%fr2R", 2},
943 {"%fr3", 3},
944 {"%fr30", 30},
945 {"%fr30L", 30},
946 {"%fr30R", 30},
947 {"%fr31", 31},
948 {"%fr31L", 31},
949 {"%fr31R", 31},
950 {"%fr3L", 3},
951 {"%fr3R", 3},
952 {"%fr4", 4},
953 {"%fr4L", 4},
954 {"%fr4R", 4},
955 {"%fr5", 5},
956 {"%fr5L", 5},
957 {"%fr5R", 5},
958 {"%fr6", 6},
959 {"%fr6L", 6},
960 {"%fr6R", 6},
961 {"%fr7", 7},
962 {"%fr7L", 7},
963 {"%fr7R", 7},
964 {"%fr8", 8},
965 {"%fr8L", 8},
966 {"%fr8R", 8},
967 {"%fr9", 9},
968 {"%fr9L", 9},
969 {"%fr9R", 9},
970 {"%hta", 25},
971 {"%iir", 19},
972 {"%ior", 21},
973 {"%ipsw", 22},
974 {"%isr", 20},
975 {"%itmr", 16},
976 {"%iva", 14},
977 {"%pcoq", 18},
978 {"%pcsq", 17},
979 {"%pidr1", 8},
980 {"%pidr2", 9},
981 {"%pidr3", 12},
982 {"%pidr4", 13},
983 {"%ppda", 24},
984 {"%r0", 0},
985 {"%r1", 1},
986 {"%r10", 10},
987 {"%r11", 11},
988 {"%r12", 12},
989 {"%r13", 13},
990 {"%r14", 14},
991 {"%r15", 15},
992 {"%r16", 16},
993 {"%r17", 17},
994 {"%r18", 18},
995 {"%r19", 19},
996 {"%r2", 2},
997 {"%r20", 20},
998 {"%r21", 21},
999 {"%r22", 22},
1000 {"%r23", 23},
1001 {"%r24", 24},
1002 {"%r25", 25},
1003 {"%r26", 26},
1004 {"%r27", 27},
1005 {"%r28", 28},
1006 {"%r29", 29},
1007 {"%r3", 3},
1008 {"%r30", 30},
1009 {"%r31", 31},
1010 {"%r4", 4},
1011 {"%r4L", 4},
1012 {"%r4R", 4},
1013 {"%r5", 5},
1014 {"%r5L", 5},
1015 {"%r5R", 5},
1016 {"%r6", 6},
1017 {"%r6L", 6},
1018 {"%r6R", 6},
1019 {"%r7", 7},
1020 {"%r7L", 7},
1021 {"%r7R", 7},
1022 {"%r8", 8},
1023 {"%r8L", 8},
1024 {"%r8R", 8},
1025 {"%r9", 9},
1026 {"%r9L", 9},
1027 {"%r9R", 9},
1028 {"%rctr", 0},
1029 {"%ret0", 28},
1030 {"%ret1", 29},
1031 {"%sar", 11},
1032 {"%sp", 30},
1033 {"%sr0", 0},
1034 {"%sr1", 1},
1035 {"%sr2", 2},
1036 {"%sr3", 3},
1037 {"%sr4", 4},
1038 {"%sr5", 5},
1039 {"%sr6", 6},
1040 {"%sr7", 7},
1041 {"%tr0", 24},
1042 {"%tr1", 25},
1043 {"%tr2", 26},
1044 {"%tr3", 27},
1045 {"%tr4", 28},
1046 {"%tr5", 29},
1047 {"%tr6", 30},
1048 {"%tr7", 31}
1049};
025b0302 1050
8f78d0e9
KR
1051/* This table is sorted by order of the length of the string. This is
1052 so we check for <> before we check for <. If we had a <> and checked
1053 for < first, we would get a false match. */
1054static const struct fp_cond_map fp_cond_map [] =
1055{
1056 {"false?", 0},
1057 {"false", 1},
1058 {"true?", 30},
1059 {"true", 31},
1060 {"!<=>", 3},
1061 {"!?>=", 8},
1062 {"!?<=", 16},
1063 {"!<>", 7},
1064 {"!>=", 11},
1065 {"!?>", 12},
1066 {"?<=", 14},
1067 {"!<=", 19},
1068 {"!?<", 20},
1069 {"?>=", 22},
1070 {"!?=", 24},
1071 {"!=t", 27},
1072 {"<=>", 29},
1073 {"=t", 5},
1074 {"?=", 6},
1075 {"?<", 10},
1076 {"<=", 13},
1077 {"!>", 15},
1078 {"?>", 18},
1079 {">=", 21},
1080 {"!<", 23},
1081 {"<>", 25},
1082 {"!=", 26},
1083 {"!?", 28},
1084 {"?", 2},
1085 {"=", 4},
1086 {"<", 9},
1087 {">", 17}
1088};
025b0302 1089
8f78d0e9
KR
1090static const struct selector_entry selector_table[] =
1091{
1092 {"F'", e_fsel},
1093 {"F%", e_fsel},
1094 {"LS'", e_lssel},
1095 {"LS%", e_lssel},
1096 {"RS'", e_rssel},
1097 {"RS%", e_rssel},
1098 {"L'", e_lsel},
1099 {"L%", e_lsel},
1100 {"R'", e_rsel},
1101 {"R%", e_rsel},
1102 {"LD'", e_ldsel},
1103 {"LD%", e_ldsel},
1104 {"RD'", e_rdsel},
1105 {"RD%", e_rdsel},
1106 {"LR'", e_lrsel},
1107 {"LR%", e_lrsel},
1108 {"RR'", e_rrsel},
1109 {"RR%", e_rrsel},
1110 {"P'", e_psel},
1111 {"P%", e_psel},
1112 {"RP'", e_rpsel},
1113 {"RP%", e_rpsel},
1114 {"LP'", e_lpsel},
1115 {"LP%", e_lpsel},
1116 {"T'", e_tsel},
1117 {"T%", e_tsel},
1118 {"RT'", e_rtsel},
1119 {"RT%", e_rtsel},
1120 {"LT'", e_ltsel},
1121 {"LT%", e_ltsel},
1122 {NULL, e_fsel}
1123};
025b0302 1124
8f78d0e9 1125/* default space and subspace dictionaries */
025b0302 1126
8f78d0e9
KR
1127#define GDB_SYMBOLS GDB_SYMBOLS_SUBSPACE_NAME
1128#define GDB_STRINGS GDB_STRINGS_SUBSPACE_NAME
025b0302 1129
8f78d0e9
KR
1130/* pre-defined subsegments (subspaces) for the HPPA. */
1131#define SUBSEG_CODE 0
1132#define SUBSEG_DATA 0
1133#define SUBSEG_LIT 1
1134#define SUBSEG_BSS 2
1135#define SUBSEG_UNWIND 3
1136#define SUBSEG_GDB_STRINGS 0
1137#define SUBSEG_GDB_SYMBOLS 1
025b0302 1138
8f78d0e9 1139static struct default_subspace_dict pa_def_subspaces[] =
025b0302 1140{
aa8b30ed
JL
1141 {"$CODE$", 1, 1, 1, 0, 0, 0, 24, 0x2c, 0, 8, 0, 0, ".text", SUBSEG_CODE},
1142 {"$DATA$", 1, 1, 0, 0, 0, 0, 24, 0x1f, 1, 8, 1, 1, ".data", SUBSEG_DATA},
1143 {"$LIT$", 1, 1, 0, 0, 0, 0, 16, 0x2c, 0, 8, 0, 0, ".text", SUBSEG_LIT},
1144 {"$BSS$", 1, 1, 0, 0, 0, 1, 80, 0x1f, 1, 8, 1, 1, ".bss", SUBSEG_BSS},
1145 {"$UNWIND$", 1, 1, 0, 0, 0, 0, 64, 0x2c, 0, 4, 0, 0, ".hppa_unwind", SUBSEG_UNWIND},
8f78d0e9
KR
1146 {NULL, 0, 1, 0, 0, 0, 0, 255, 0x1f, 0, 4, 0, 0, 0}
1147};
025b0302 1148
8f78d0e9
KR
1149static struct default_space_dict pa_def_spaces[] =
1150{
aa8b30ed
JL
1151 {"$TEXT$", 0, 1, 1, 0, 8, ASEC_NULL, ".text"},
1152 {"$PRIVATE$", 1, 1, 1, 1, 16, ASEC_NULL, ".data"},
8f78d0e9
KR
1153 {NULL, 0, 0, 0, 0, 0, ASEC_NULL, NULL}
1154};
025b0302 1155
8f78d0e9
KR
1156/* Misc local definitions used by the assembler. */
1157
1158/* Return nonzero if the string pointed to by S potentially represents
1159 a right or left half of a FP register */
1160#define IS_R_SELECT(S) (*(S) == 'R' || *(S) == 'r')
1161#define IS_L_SELECT(S) (*(S) == 'L' || *(S) == 'l')
1162
1163/* These macros are used to maintain spaces/subspaces. */
1164#define SPACE_DEFINED(space_chain) (space_chain)->sd_defined
1165#define SPACE_USER_DEFINED(space_chain) (space_chain)->sd_user_defined
1166#define SPACE_PRIVATE(space_chain) (space_chain)->sd_private
1167#define SPACE_LOADABLE(space_chain) (space_chain)->sd_loadable
1168#define SPACE_SPNUM(space_chain) (space_chain)->sd_spnum
1169#define SPACE_SORT(space_chain) (space_chain)->sd_sort_key
1170#define SPACE_NAME(space_chain) (space_chain)->sd_name
1171#define SPACE_NAME_INDEX(space_chain) (space_chain)->sd_name_index
1172
1173#define SUBSPACE_SPACE_INDEX(ss_chain) (ss_chain)->ssd_space_index
47f45d66 1174#define SUBSPACE_DEFINED(ss_chain) (ss_chain)->ssd_defined
8f78d0e9
KR
1175#define SUBSPACE_QUADRANT(ss_chain) (ss_chain)->ssd_quadrant
1176#define SUBSPACE_ALIGN(ss_chain) (ss_chain)->ssd_alignment
1177#define SUBSPACE_ACCESS(ss_chain) (ss_chain)->ssd_access_control_bits
1178#define SUBSPACE_SORT(ss_chain) (ss_chain)->ssd_sort_key
1179#define SUBSPACE_COMMON(ss_chain) (ss_chain)->ssd_common
1180#define SUBSPACE_ZERO(ss_chain) (ss_chain)->ssd_zero
1181#define SUBSPACE_DUP_COMM(ss_chain) (ss_chain)->ssd_dup_common
1182#define SUBSPACE_CODE_ONLY(ss_chain) (ss_chain)->ssd_code_only
1183#define SUBSPACE_LOADABLE(ss_chain) (ss_chain)->ssd_loadable
1184#define SUBSPACE_SUBSPACE_START(ss_chain) (ss_chain)->ssd_subspace_start
1185#define SUBSPACE_SUBSPACE_LENGTH(ss_chain) (ss_chain)->ssd_subspace_length
1186#define SUBSPACE_NAME(ss_chain) (ss_chain)->ssd_name
1187
1188#define is_DP_relative(exp) \
1189 ((exp).X_op == O_subtract \
1190 && strcmp((exp).X_op_symbol->bsym->name, "$global$") == 0)
1191
1192#define is_PC_relative(exp) \
1193 ((exp).X_op == O_subtract \
1194 && strcmp((exp).X_op_symbol->bsym->name, "$PIC_pcrel$0") == 0)
1195
1196#define is_complex(exp) \
1197 ((exp).X_op != O_constant && (exp).X_op != O_symbol)
1198
1199/* Actual functions to implement the PA specific code for the assembler. */
1200
1201/* Returns a pointer to the label_symbol_struct for the current space.
1202 or NULL if no label_symbol_struct exists for the current space. */
1203
1204static label_symbol_struct *
1205pa_get_label ()
1206{
1207 label_symbol_struct *label_chain;
3b9a72c5 1208 sd_chain_struct *space_chain = current_space;
025b0302 1209
8f78d0e9
KR
1210 for (label_chain = label_symbols_rootp;
1211 label_chain;
1212 label_chain = label_chain->lss_next)
1213 if (space_chain == label_chain->lss_space && label_chain->lss_label)
1214 return label_chain;
025b0302 1215
8f78d0e9
KR
1216 return NULL;
1217}
025b0302 1218
8f78d0e9
KR
1219/* Defines a label for the current space. If one is already defined,
1220 this function will replace it with the new label. */
025b0302 1221
8f78d0e9
KR
1222void
1223pa_define_label (symbol)
1224 symbolS *symbol;
1225{
1226 label_symbol_struct *label_chain = pa_get_label ();
3b9a72c5 1227 sd_chain_struct *space_chain = current_space;
8f78d0e9
KR
1228
1229 if (label_chain)
1230 label_chain->lss_label = symbol;
1231 else
1232 {
1233 /* Create a new label entry and add it to the head of the chain. */
1234 label_chain
1235 = (label_symbol_struct *) xmalloc (sizeof (label_symbol_struct));
1236 label_chain->lss_label = symbol;
1237 label_chain->lss_space = space_chain;
1238 label_chain->lss_next = NULL;
1239
1240 if (label_symbols_rootp)
1241 label_chain->lss_next = label_symbols_rootp;
1242
1243 label_symbols_rootp = label_chain;
1244 }
1245}
1246
1247/* Removes a label definition for the current space.
1248 If there is no label_symbol_struct entry, then no action is taken. */
1249
1250static void
1251pa_undefine_label ()
1252{
1253 label_symbol_struct *label_chain;
1254 label_symbol_struct *prev_label_chain = NULL;
3b9a72c5 1255 sd_chain_struct *space_chain = current_space;
8f78d0e9
KR
1256
1257 for (label_chain = label_symbols_rootp;
1258 label_chain;
1259 label_chain = label_chain->lss_next)
1260 {
1261 if (space_chain == label_chain->lss_space && label_chain->lss_label)
1262 {
1263 /* Remove the label from the chain and free its memory. */
1264 if (prev_label_chain)
1265 prev_label_chain->lss_next = label_chain->lss_next;
1266 else
1267 label_symbols_rootp = label_chain->lss_next;
1268
1269 free (label_chain);
1270 break;
1271 }
1272 prev_label_chain = label_chain;
1273 }
1274}
1275
1276
1277/* An HPPA-specific version of fix_new. This is required because the HPPA
1278 code needs to keep track of some extra stuff. Each call to fix_new_hppa
1279 results in the creation of an instance of an hppa_fix_struct. An
1280 hppa_fix_struct stores the extra information along with a pointer to the
aa8b30ed
JL
1281 original fixS. This is attached to the original fixup via the
1282 tc_fix_data field. */
8f78d0e9
KR
1283
1284static void
1285fix_new_hppa (frag, where, size, add_symbol, offset, exp, pcrel,
1286 r_type, r_field, r_format, arg_reloc, unwind_desc)
1287 fragS *frag;
1288 int where;
1289 short int size;
1290 symbolS *add_symbol;
1291 long offset;
1292 expressionS *exp;
1293 int pcrel;
1294 bfd_reloc_code_real_type r_type;
1295 long r_field;
1296 int r_format;
1297 long arg_reloc;
1298 char *unwind_desc;
1299{
1300 fixS *new_fix;
1301
1302 struct hppa_fix_struct *hppa_fix = (struct hppa_fix_struct *)
1303 obstack_alloc (&notes, sizeof (struct hppa_fix_struct));
1304
1305 if (exp != NULL)
1306 new_fix = fix_new_exp (frag, where, size, exp, pcrel, r_type);
1307 else
1308 new_fix = fix_new (frag, where, size, add_symbol, offset, pcrel, r_type);
aa8b30ed 1309 new_fix->tc_fix_data = hppa_fix;
8f78d0e9
KR
1310 hppa_fix->fx_r_type = r_type;
1311 hppa_fix->fx_r_field = r_field;
1312 hppa_fix->fx_r_format = r_format;
1313 hppa_fix->fx_arg_reloc = arg_reloc;
8f78d0e9 1314 if (unwind_desc)
ff852e11
JL
1315 {
1316 bcopy (unwind_desc, hppa_fix->fx_unwind, 8);
025b0302 1317
ff852e11
JL
1318 /* If necessary call BFD backend function to attach the
1319 unwind bits to the target dependent parts of a BFD symbol.
1320 Yuk. */
1321#ifdef obj_attach_unwind_info
1322 obj_attach_unwind_info (add_symbol->bsym, unwind_desc);
1323#endif
1324 }
025b0302
ME
1325}
1326
1327/* Parse a .byte, .word, .long expression for the HPPA. Called by
1328 cons via the TC_PARSE_CONS_EXPRESSION macro. */
1329
025b0302
ME
1330void
1331parse_cons_expression_hppa (exp)
1332 expressionS *exp;
1333{
1334 hppa_field_selector = pa_chk_field_selector (&input_line_pointer);
5cf4cd1b 1335 expression (exp);
025b0302
ME
1336}
1337
1338/* This fix_new is called by cons via TC_CONS_FIX_NEW.
1339 hppa_field_selector is set by the parse_cons_expression_hppa. */
1340
1341void
1342cons_fix_new_hppa (frag, where, size, exp)
8f78d0e9
KR
1343 fragS *frag;
1344 int where;
1345 int size;
1346 expressionS *exp;
025b0302
ME
1347{
1348 unsigned int reloc_type;
1349
1350 if (is_DP_relative (*exp))
1351 reloc_type = R_HPPA_GOTOFF;
1352 else if (is_complex (*exp))
1353 reloc_type = R_HPPA_COMPLEX;
1354 else
1355 reloc_type = R_HPPA;
1356
1357 if (hppa_field_selector != e_psel && hppa_field_selector != e_fsel)
8f78d0e9 1358 as_warn ("Invalid field selector. Assuming F%%.");
025b0302 1359
5cf4cd1b
KR
1360 fix_new_hppa (frag, where, size,
1361 (symbolS *) NULL, (offsetT) 0, exp, 0, reloc_type,
025b0302 1362 hppa_field_selector, 32, 0, (char *) 0);
025b0302
ME
1363}
1364
1365/* This function is called once, at assembler startup time. It should
1366 set up all the tables, etc. that the MD part of the assembler will need. */
8f78d0e9 1367
025b0302
ME
1368void
1369md_begin ()
1370{
8f78d0e9 1371 char *retval = NULL;
025b0302 1372 int lose = 0;
8f78d0e9 1373 unsigned int i = 0;
025b0302
ME
1374
1375 last_call_info = NULL;
1376 call_info_root = NULL;
1377
13925cef
JL
1378 /* Folding of text and data segments fails miserably on the PA.
1379 Warn user and disable "-R" option. */
d56f45f5
JL
1380 if (flagseen['R'])
1381 {
1382 as_warn ("-R option not supported on this target.");
1383 flag_readonly_data_in_text = 0;
1384 flagseen['R'] = 0;
1385 }
13925cef 1386
025b0302
ME
1387 pa_spaces_begin ();
1388
1389 op_hash = hash_new ();
1390 if (op_hash == NULL)
1391 as_fatal ("Virtual memory exhausted");
1392
1393 while (i < NUMOPCODES)
1394 {
1395 const char *name = pa_opcodes[i].name;
1396 retval = hash_insert (op_hash, name, &pa_opcodes[i]);
8f78d0e9 1397 if (retval != NULL && *retval != '\0')
025b0302 1398 {
8f78d0e9 1399 as_fatal ("Internal error: can't hash `%s': %s\n", name, retval);
025b0302
ME
1400 lose = 1;
1401 }
1402 do
1403 {
8f78d0e9
KR
1404 if ((pa_opcodes[i].match & pa_opcodes[i].mask)
1405 != pa_opcodes[i].match)
025b0302
ME
1406 {
1407 fprintf (stderr, "internal error: losing opcode: `%s' \"%s\"\n",
1408 pa_opcodes[i].name, pa_opcodes[i].args);
1409 lose = 1;
1410 }
1411 ++i;
1412 }
8f78d0e9 1413 while (i < NUMOPCODES && !strcmp (pa_opcodes[i].name, name));
025b0302
ME
1414 }
1415
1416 if (lose)
1417 as_fatal ("Broken assembler. No assembly attempted.");
3b9a72c5
JL
1418
1419 /* SOM will change text_section. To make sure we never put
1420 anything into the old one switch to the new one now. */
1421 subseg_set (text_section, 0);
025b0302
ME
1422}
1423
8f78d0e9
KR
1424/* Called at the end of assembling a source file. Nothing to do
1425 at this point on the PA. */
1426
025b0302
ME
1427void
1428md_end ()
1429{
1430 return;
1431}
1432
8f78d0e9 1433/* Assemble a single instruction storing it into a frag. */
025b0302
ME
1434void
1435md_assemble (str)
1436 char *str;
1437{
8f78d0e9 1438 char *to;
025b0302 1439
8f78d0e9 1440 /* The had better be something to assemble. */
025b0302 1441 assert (str);
8f78d0e9
KR
1442
1443 /* Assemble the instruction. Results are saved into "the_insn". */
025b0302 1444 pa_ip (str);
025b0302 1445
8f78d0e9
KR
1446 /* Get somewhere to put the assembled instrution. */
1447 to = frag_more (4);
025b0302 1448
8f78d0e9
KR
1449 /* Output the opcode. */
1450 md_number_to_chars (to, the_insn.opcode, 4);
025b0302 1451
8f78d0e9 1452 /* If necessary output more stuff. */
aa8b30ed 1453 if (the_insn.reloc != R_HPPA_NONE)
8f78d0e9
KR
1454 fix_new_hppa (frag_now, (to - frag_now->fr_literal), 4, NULL,
1455 (offsetT) 0, &the_insn.exp, the_insn.pcrel,
1456 the_insn.reloc, the_insn.field_selector,
1457 the_insn.format, the_insn.arg_reloc, NULL);
025b0302 1458
8f78d0e9 1459}
025b0302 1460
8f78d0e9
KR
1461/* Do the real work for assembling a single instruction. Store results
1462 into the global "the_insn" variable.
025b0302 1463
8f78d0e9
KR
1464 FIXME: Should define and use some functions/macros to handle
1465 various common insertions of information into the opcode. */
025b0302
ME
1466
1467static void
1468pa_ip (str)
1469 char *str;
1470{
1471 char *error_message = "";
8f78d0e9 1472 char *s, c, *argstart, *name, *save_s;
025b0302 1473 const char *args;
025b0302
ME
1474 int match = FALSE;
1475 int comma = 0;
8f78d0e9 1476 int reg, s2, s3, m, a, uu, cmpltr, nullif, flag, sfu, cond;
025b0302 1477 unsigned int im21, im14, im11, im5;
8f78d0e9
KR
1478 unsigned long i, opcode;
1479 struct pa_opcode *insn;
025b0302 1480
8f78d0e9 1481 /* Skip to something interesting. */
025b0302
ME
1482 for (s = str; isupper (*s) || islower (*s) || (*s >= '0' && *s <= '3'); ++s)
1483 ;
8f78d0e9 1484
025b0302
ME
1485 switch (*s)
1486 {
1487
1488 case '\0':
1489 break;
1490
1491 case ',':
1492 comma = 1;
1493
8f78d0e9 1494 /*FALLTHROUGH */
025b0302
ME
1495
1496 case ' ':
1497 *s++ = '\0';
1498 break;
1499
1500 default:
1501 as_bad ("Unknown opcode: `%s'", str);
1502 exit (1);
1503 }
1504
1505 save_s = str;
1506
8f78d0e9 1507 /* Convert everything into lower case. */
025b0302
ME
1508 while (*save_s)
1509 {
1510 if (isupper (*save_s))
1511 *save_s = tolower (*save_s);
1512 save_s++;
1513 }
1514
8f78d0e9 1515 /* Look up the opcode in the has table. */
025b0302
ME
1516 if ((insn = (struct pa_opcode *) hash_find (op_hash, str)) == NULL)
1517 {
1518 as_bad ("Unknown opcode: `%s'", str);
1519 return;
1520 }
8f78d0e9 1521
025b0302
ME
1522 if (comma)
1523 {
1524 *--s = ',';
1525 }
8f78d0e9
KR
1526
1527 /* Mark the location where arguments for the instruction start, then
1528 start processing them. */
1529 argstart = s;
025b0302
ME
1530 for (;;)
1531 {
8f78d0e9 1532 /* Do some initialization. */
025b0302
ME
1533 opcode = insn->match;
1534 bzero (&the_insn, sizeof (the_insn));
8f78d0e9 1535
025b0302 1536 the_insn.reloc = R_HPPA_NONE;
8f78d0e9
KR
1537
1538 /* Build the opcode, checking as we go to make
1539 sure that the operands match. */
025b0302
ME
1540 for (args = insn->args;; ++args)
1541 {
025b0302
ME
1542 switch (*args)
1543 {
1544
8f78d0e9
KR
1545 /* End of arguments. */
1546 case '\0':
025b0302 1547 if (*s == '\0')
8f78d0e9 1548 match = TRUE;
025b0302
ME
1549 break;
1550
1551 case '+':
1552 if (*s == '+')
1553 {
1554 ++s;
1555 continue;
1556 }
1557 if (*s == '-')
8f78d0e9 1558 continue;
025b0302
ME
1559 break;
1560
8f78d0e9
KR
1561 /* These must match exactly. */
1562 case '(':
025b0302
ME
1563 case ')':
1564 case ',':
1565 case ' ':
1566 if (*s++ == *args)
1567 continue;
1568 break;
1569
8f78d0e9
KR
1570 /* Handle a 5 bit register or control register field at 10. */
1571 case 'b':
1572 case '^':
1573 reg = pa_parse_number (&s, 0);
025b0302
ME
1574 if (reg < 32 && reg >= 0)
1575 {
1576 opcode |= reg << 21;
1577 continue;
1578 }
1579 break;
8f78d0e9
KR
1580
1581 /* Handle a 5 bit register field at 15. */
1582 case 'x':
1583 reg = pa_parse_number (&s, 0);
025b0302
ME
1584 if (reg < 32 && reg >= 0)
1585 {
1586 opcode |= reg << 16;
1587 continue;
1588 }
1589 break;
5cf4cd1b 1590
8f78d0e9
KR
1591 /* Handle a 5 bit register field at 31. */
1592 case 'y':
1593 case 't':
1594 reg = pa_parse_number (&s, 0);
025b0302
ME
1595 if (reg < 32 && reg >= 0)
1596 {
1597 opcode |= reg;
1598 continue;
1599 }
1600 break;
8f78d0e9
KR
1601
1602 /* Handle a 5 bit field length at 31. */
1603 case 'T':
1604 pa_get_absolute_expression (s);
5cf4cd1b 1605 if (the_insn.exp.X_op == O_constant)
025b0302
ME
1606 {
1607 reg = the_insn.exp.X_add_number;
1608 if (reg <= 32 && reg > 0)
1609 {
1610 opcode |= 32 - reg;
1611 s = expr_end;
1612 continue;
1613 }
1614 }
1615 break;
8f78d0e9
KR
1616
1617 /* Handle a 5 bit immediate at 15. */
1618 case '5':
1619 pa_get_absolute_expression (s);
025b0302
ME
1620 if (the_insn.exp.X_add_number > 15)
1621 {
8f78d0e9 1622 as_bad ("5 bit immediate > 15. Set to 15");
025b0302
ME
1623 the_insn.exp.X_add_number = 15;
1624 }
1625 else if (the_insn.exp.X_add_number < -16)
1626 {
8f78d0e9 1627 as_bad ("5 bit immediate < -16. Set to -16");
025b0302
ME
1628 the_insn.exp.X_add_number = -16;
1629 }
1630
8f78d0e9
KR
1631 low_sign_unext (evaluate_absolute (the_insn.exp,
1632 the_insn.field_selector),
025b0302
ME
1633 5, &im5);
1634 opcode |= (im5 << 16);
1635 s = expr_end;
1636 continue;
1637
8f78d0e9
KR
1638 /* Handle a 2 bit space identifier at 17. */
1639 case 's':
1640 s2 = pa_parse_number (&s, 0);
025b0302
ME
1641 if (s2 < 4 && s2 >= 0)
1642 {
1643 opcode |= s2 << 14;
1644 continue;
1645 }
1646 break;
8f78d0e9
KR
1647
1648 /* Handle a 3 bit space identifier at 18. */
1649 case 'S':
1650 s3 = pa_parse_number (&s, 0);
025b0302
ME
1651 if (s3 < 8 && s3 >= 0)
1652 {
1653 dis_assemble_3 (s3, &s3);
1654 opcode |= s3 << 13;
1655 continue;
1656 }
1657 break;
8f78d0e9
KR
1658
1659 /* Handle a completer for an indexing load or store. */
1660 case 'c':
025b0302
ME
1661 uu = 0;
1662 m = 0;
1663 i = 0;
1664 while (*s == ',' && i < 2)
1665 {
1666 s++;
1667 if (strncasecmp (s, "sm", 2) == 0)
1668 {
1669 uu = 1;
1670 m = 1;
1671 s++;
1672 i++;
1673 }
1674 else if (strncasecmp (s, "m", 1) == 0)
1675 m = 1;
1676 else if (strncasecmp (s, "s", 1) == 0)
1677 uu = 1;
1678 else
8f78d0e9 1679 as_bad ("Invalid Indexed Load Completer.");
025b0302
ME
1680 s++;
1681 i++;
1682 }
1683 if (i > 2)
8f78d0e9 1684 as_bad ("Invalid Indexed Load Completer Syntax.");
025b0302
ME
1685 while (*s == ' ' || *s == '\t')
1686 s++;
1687
1688 opcode |= m << 5;
1689 opcode |= uu << 13;
1690 continue;
8f78d0e9
KR
1691
1692 /* Handle a short load/store completer. */
1693 case 'C':
025b0302
ME
1694 a = 0;
1695 m = 0;
1696 if (*s == ',')
1697 {
1698 s++;
1699 if (strncasecmp (s, "ma", 2) == 0)
1700 {
1701 a = 0;
1702 m = 1;
1703 }
1704 else if (strncasecmp (s, "mb", 2) == 0)
1705 {
1706 a = 1;
1707 m = 1;
1708 }
1709 else
8f78d0e9 1710 as_bad ("Invalid Short Load/Store Completer.");
025b0302
ME
1711 s += 2;
1712 }
025b0302
ME
1713 while (*s == ' ' || *s == '\t')
1714 s++;
1715 opcode |= m << 5;
1716 opcode |= a << 13;
1717 continue;
8f78d0e9
KR
1718
1719 /* Handle a stbys completer. */
1720 case 'Y':
025b0302
ME
1721 a = 0;
1722 m = 0;
1723 i = 0;
1724 while (*s == ',' && i < 2)
1725 {
1726 s++;
1727 if (strncasecmp (s, "m", 1) == 0)
1728 m = 1;
1729 else if (strncasecmp (s, "b", 1) == 0)
1730 a = 0;
1731 else if (strncasecmp (s, "e", 1) == 0)
1732 a = 1;
1733 else
8f78d0e9 1734 as_bad ("Invalid Store Bytes Short Completer");
025b0302
ME
1735 s++;
1736 i++;
1737 }
025b0302 1738 if (i > 2)
8f78d0e9
KR
1739 as_bad ("Invalid Store Bytes Short Completer");
1740 while (*s == ' ' || *s == '\t')
025b0302
ME
1741 s++;
1742 opcode |= m << 5;
1743 opcode |= a << 13;
1744 continue;
8f78d0e9
KR
1745
1746 /* Handle a non-negated compare/stubtract condition. */
1747 case '<':
5cf4cd1b 1748 cmpltr = pa_parse_nonneg_cmpsub_cmpltr (&s, 1);
025b0302
ME
1749 if (cmpltr < 0)
1750 {
8f78d0e9 1751 as_bad ("Invalid Compare/Subtract Condition: %c", *s);
025b0302
ME
1752 cmpltr = 0;
1753 }
1754 opcode |= cmpltr << 13;
1755 continue;
8f78d0e9
KR
1756
1757 /* Handle a negated or non-negated compare/subtract condition. */
1758 case '?':
025b0302 1759 save_s = s;
5cf4cd1b 1760 cmpltr = pa_parse_nonneg_cmpsub_cmpltr (&s, 1);
025b0302
ME
1761 if (cmpltr < 0)
1762 {
1763 s = save_s;
5cf4cd1b 1764 cmpltr = pa_parse_neg_cmpsub_cmpltr (&s, 1);
025b0302
ME
1765 if (cmpltr < 0)
1766 {
8f78d0e9 1767 as_bad ("Invalid Compare/Subtract Condition.");
025b0302
ME
1768 cmpltr = 0;
1769 }
1770 else
1771 {
8f78d0e9
KR
1772 /* Negated condition requires an opcode change. */
1773 opcode |= 1 << 27;
025b0302
ME
1774 }
1775 }
1776 opcode |= cmpltr << 13;
1777 continue;
8f78d0e9
KR
1778
1779 /* Handle a negated or non-negated add condition. */
1780 case '!':
025b0302 1781 save_s = s;
5cf4cd1b 1782 cmpltr = pa_parse_nonneg_add_cmpltr (&s, 1);
025b0302
ME
1783 if (cmpltr < 0)
1784 {
1785 s = save_s;
5cf4cd1b 1786 cmpltr = pa_parse_neg_add_cmpltr (&s, 1);
025b0302
ME
1787 if (cmpltr < 0)
1788 {
8f78d0e9 1789 as_bad ("Invalid Compare/Subtract Condition");
025b0302
ME
1790 cmpltr = 0;
1791 }
1792 else
1793 {
8f78d0e9
KR
1794 /* Negated condition requires an opcode change. */
1795 opcode |= 1 << 27;
025b0302
ME
1796 }
1797 }
1798 opcode |= cmpltr << 13;
1799 continue;
8f78d0e9
KR
1800
1801 /* Handle a compare/subtract condition. */
1802 case 'a':
025b0302 1803 cmpltr = 0;
8f78d0e9 1804 flag = 0;
025b0302
ME
1805 save_s = s;
1806 if (*s == ',')
1807 {
5cf4cd1b 1808 cmpltr = pa_parse_nonneg_cmpsub_cmpltr (&s, 0);
025b0302
ME
1809 if (cmpltr < 0)
1810 {
8f78d0e9 1811 flag = 1;
025b0302 1812 s = save_s;
5cf4cd1b 1813 cmpltr = pa_parse_neg_cmpsub_cmpltr (&s, 0);
025b0302
ME
1814 if (cmpltr < 0)
1815 {
8f78d0e9 1816 as_bad ("Invalid Compare/Subtract Condition");
025b0302
ME
1817 }
1818 }
1819 }
1820 opcode |= cmpltr << 13;
8f78d0e9 1821 opcode |= flag << 12;
025b0302 1822 continue;
8f78d0e9
KR
1823
1824 /* Handle a non-negated add condition. */
1825 case 'd':
025b0302
ME
1826 cmpltr = 0;
1827 nullif = 0;
1828 flag = 0;
1829 if (*s == ',')
1830 {
1831 s++;
1832 name = s;
1833 while (*s != ',' && *s != ' ' && *s != '\t')
1834 s += 1;
1835 c = *s;
1836 *s = 0x00;
1837 if (strcmp (name, "=") == 0)
8f78d0e9 1838 cmpltr = 1;
025b0302 1839 else if (strcmp (name, "<") == 0)
8f78d0e9 1840 cmpltr = 2;
025b0302 1841 else if (strcmp (name, "<=") == 0)
8f78d0e9 1842 cmpltr = 3;
025b0302 1843 else if (strcasecmp (name, "nuv") == 0)
8f78d0e9 1844 cmpltr = 4;
025b0302 1845 else if (strcasecmp (name, "znv") == 0)
8f78d0e9 1846 cmpltr = 5;
025b0302 1847 else if (strcasecmp (name, "sv") == 0)
8f78d0e9 1848 cmpltr = 6;
025b0302 1849 else if (strcasecmp (name, "od") == 0)
8f78d0e9 1850 cmpltr = 7;
025b0302 1851 else if (strcasecmp (name, "n") == 0)
8f78d0e9 1852 nullif = 1;
025b0302
ME
1853 else if (strcasecmp (name, "tr") == 0)
1854 {
1855 cmpltr = 0;
1856 flag = 1;
1857 }
1858 else if (strcasecmp (name, "<>") == 0)
1859 {
1860 cmpltr = 1;
1861 flag = 1;
1862 }
1863 else if (strcasecmp (name, ">=") == 0)
1864 {
1865 cmpltr = 2;
1866 flag = 1;
1867 }
1868 else if (strcasecmp (name, ">") == 0)
1869 {
1870 cmpltr = 3;
1871 flag = 1;
1872 }
1873 else if (strcasecmp (name, "uv") == 0)
1874 {
1875 cmpltr = 4;
1876 flag = 1;
1877 }
1878 else if (strcasecmp (name, "vnz") == 0)
1879 {
1880 cmpltr = 5;
1881 flag = 1;
1882 }
1883 else if (strcasecmp (name, "nsv") == 0)
1884 {
1885 cmpltr = 6;
1886 flag = 1;
1887 }
1888 else if (strcasecmp (name, "ev") == 0)
1889 {
1890 cmpltr = 7;
1891 flag = 1;
1892 }
1893 else
8f78d0e9 1894 as_bad ("Invalid Add Condition: %s", name);
025b0302
ME
1895 *s = c;
1896 }
1897 nullif = pa_parse_nullif (&s);
1898 opcode |= nullif << 1;
1899 opcode |= cmpltr << 13;
1900 opcode |= flag << 12;
1901 continue;
8f78d0e9
KR
1902
1903 /* Handle a logical instruction condition. */
1904 case '&':
025b0302 1905 cmpltr = 0;
8f78d0e9 1906 flag = 0;
025b0302
ME
1907 if (*s == ',')
1908 {
1909 s++;
1910 name = s;
1911 while (*s != ',' && *s != ' ' && *s != '\t')
1912 s += 1;
1913 c = *s;
1914 *s = 0x00;
1915 if (strcmp (name, "=") == 0)
8f78d0e9 1916 cmpltr = 1;
025b0302 1917 else if (strcmp (name, "<") == 0)
8f78d0e9 1918 cmpltr = 2;
025b0302 1919 else if (strcmp (name, "<=") == 0)
8f78d0e9 1920 cmpltr = 3;
025b0302 1921 else if (strcasecmp (name, "od") == 0)
8f78d0e9 1922 cmpltr = 7;
025b0302
ME
1923 else if (strcasecmp (name, "tr") == 0)
1924 {
1925 cmpltr = 0;
8f78d0e9 1926 flag = 1;
025b0302
ME
1927 }
1928 else if (strcmp (name, "<>") == 0)
1929 {
1930 cmpltr = 1;
8f78d0e9 1931 flag = 1;
025b0302
ME
1932 }
1933 else if (strcmp (name, ">=") == 0)
1934 {
1935 cmpltr = 2;
8f78d0e9 1936 flag = 1;
025b0302
ME
1937 }
1938 else if (strcmp (name, ">") == 0)
1939 {
1940 cmpltr = 3;
8f78d0e9 1941 flag = 1;
025b0302
ME
1942 }
1943 else if (strcasecmp (name, "ev") == 0)
1944 {
1945 cmpltr = 7;
8f78d0e9 1946 flag = 1;
025b0302
ME
1947 }
1948 else
8f78d0e9 1949 as_bad ("Invalid Logical Instruction Condition.");
025b0302
ME
1950 *s = c;
1951 }
1952 opcode |= cmpltr << 13;
8f78d0e9 1953 opcode |= flag << 12;
025b0302 1954 continue;
8f78d0e9
KR
1955
1956 /* Handle a unit instruction condition. */
1957 case 'U':
025b0302 1958 cmpltr = 0;
8f78d0e9 1959 flag = 0;
025b0302
ME
1960 if (*s == ',')
1961 {
1962 s++;
1963 if (strncasecmp (s, "sbz", 3) == 0)
1964 {
1965 cmpltr = 2;
1966 s += 3;
1967 }
1968 else if (strncasecmp (s, "shz", 3) == 0)
1969 {
1970 cmpltr = 3;
1971 s += 3;
1972 }
1973 else if (strncasecmp (s, "sdc", 3) == 0)
1974 {
1975 cmpltr = 4;
1976 s += 3;
1977 }
1978 else if (strncasecmp (s, "sbc", 3) == 0)
1979 {
1980 cmpltr = 6;
1981 s += 3;
1982 }
1983 else if (strncasecmp (s, "shc", 3) == 0)
1984 {
1985 cmpltr = 7;
1986 s += 3;
1987 }
1988 else if (strncasecmp (s, "tr", 2) == 0)
1989 {
1990 cmpltr = 0;
8f78d0e9 1991 flag = 1;
025b0302
ME
1992 s += 2;
1993 }
1994 else if (strncasecmp (s, "nbz", 3) == 0)
1995 {
1996 cmpltr = 2;
8f78d0e9 1997 flag = 1;
025b0302
ME
1998 s += 3;
1999 }
2000 else if (strncasecmp (s, "nhz", 3) == 0)
2001 {
2002 cmpltr = 3;
8f78d0e9 2003 flag = 1;
025b0302
ME
2004 s += 3;
2005 }
2006 else if (strncasecmp (s, "ndc", 3) == 0)
2007 {
2008 cmpltr = 4;
8f78d0e9 2009 flag = 1;
025b0302
ME
2010 s += 3;
2011 }
2012 else if (strncasecmp (s, "nbc", 3) == 0)
2013 {
2014 cmpltr = 6;
8f78d0e9 2015 flag = 1;
025b0302
ME
2016 s += 3;
2017 }
2018 else if (strncasecmp (s, "nhc", 3) == 0)
2019 {
2020 cmpltr = 7;
8f78d0e9 2021 flag = 1;
025b0302
ME
2022 s += 3;
2023 }
2024 else
8f78d0e9 2025 as_bad ("Invalid Logical Instruction Condition.");
025b0302
ME
2026 }
2027 opcode |= cmpltr << 13;
8f78d0e9 2028 opcode |= flag << 12;
025b0302 2029 continue;
8f78d0e9
KR
2030
2031 /* Handle a shift/extract/deposit condition. */
2032 case '|':
2033 case '>':
025b0302
ME
2034 cmpltr = 0;
2035 if (*s == ',')
2036 {
8f78d0e9 2037 save_s = s++;
025b0302
ME
2038 name = s;
2039 while (*s != ',' && *s != ' ' && *s != '\t')
2040 s += 1;
2041 c = *s;
2042 *s = 0x00;
2043 if (strcmp (name, "=") == 0)
8f78d0e9 2044 cmpltr = 1;
025b0302 2045 else if (strcmp (name, "<") == 0)
8f78d0e9 2046 cmpltr = 2;
025b0302 2047 else if (strcasecmp (name, "od") == 0)
8f78d0e9 2048 cmpltr = 3;
025b0302 2049 else if (strcasecmp (name, "tr") == 0)
8f78d0e9 2050 cmpltr = 4;
025b0302 2051 else if (strcmp (name, "<>") == 0)
8f78d0e9 2052 cmpltr = 5;
025b0302 2053 else if (strcmp (name, ">=") == 0)
8f78d0e9 2054 cmpltr = 6;
025b0302 2055 else if (strcasecmp (name, "ev") == 0)
8f78d0e9 2056 cmpltr = 7;
5cf4cd1b
KR
2057 /* Handle movb,n. Put things back the way they were.
2058 This includes moving s back to where it started. */
2059 else if (strcasecmp (name, "n") == 0 && *args == '|')
2060 {
2061 *s = c;
2062 s = save_s;
2063 continue;
2064 }
025b0302 2065 else
8f78d0e9 2066 as_bad ("Invalid Shift/Extract/Deposit Condition.");
025b0302
ME
2067 *s = c;
2068 }
2069 opcode |= cmpltr << 13;
2070 continue;
8f78d0e9
KR
2071
2072 /* Handle bvb and bb conditions. */
2073 case '~':
025b0302
ME
2074 cmpltr = 0;
2075 if (*s == ',')
2076 {
2077 s++;
2078 if (strncmp (s, "<", 1) == 0)
2079 {
2080 cmpltr = 2;
2081 s++;
2082 }
2083 else if (strncmp (s, ">=", 2) == 0)
2084 {
2085 cmpltr = 6;
2086 s += 2;
2087 }
2088 else
8f78d0e9 2089 as_bad ("Invalid Bit Branch Condition: %c", *s);
025b0302
ME
2090 }
2091 opcode |= cmpltr << 13;
2092 continue;
8f78d0e9
KR
2093
2094 /* Handle a 5 bit immediate at 31. */
2095 case 'V':
2096 get_expression (s);
2097 low_sign_unext (evaluate_absolute (the_insn.exp,
2098 the_insn.field_selector),
025b0302
ME
2099 5, &im5);
2100 opcode |= im5;
2101 s = expr_end;
2102 continue;
8f78d0e9
KR
2103
2104 /* Handle an unsigned 5 bit immediate at 31. */
2105 case 'r':
2106 get_expression (s);
2107 im5 = evaluate_absolute (the_insn.exp, the_insn.field_selector);
892a3ff1 2108 if (im5 > 31)
025b0302 2109 {
8f78d0e9
KR
2110 as_bad ("Operand out of range. Was: %d. Should be [0..31].",
2111 im5);
025b0302
ME
2112 im5 = im5 & 0x1f;
2113 }
2114 opcode |= im5;
2115 s = expr_end;
2116 continue;
8f78d0e9
KR
2117
2118 /* Handle an unsigned 5 bit immediate at 15. */
2119 case 'R':
2120 get_expression (s);
2121 im5 = evaluate_absolute (the_insn.exp, the_insn.field_selector);
892a3ff1 2122 if (im5 > 31)
025b0302 2123 {
8f78d0e9
KR
2124 as_bad ("Operand out of range. Was: %d. Should be [0..31].",
2125 im5);
025b0302
ME
2126 im5 = im5 & 0x1f;
2127 }
2128 opcode |= im5 << 16;
2129 s = expr_end;
2130 continue;
8f78d0e9
KR
2131
2132 /* Handle a 11 bit immediate at 31. */
2133 case 'i':
2134 the_insn.field_selector = pa_chk_field_selector (&s);
2135 get_expression (s);
5cf4cd1b 2136 if (the_insn.exp.X_op == O_constant)
025b0302 2137 {
8f78d0e9
KR
2138 low_sign_unext (evaluate_absolute (the_insn.exp,
2139 the_insn.field_selector),
025b0302
ME
2140 11, &im11);
2141 opcode |= im11;
2142 }
2143 else
2144 {
025b0302
ME
2145 if (is_DP_relative (the_insn.exp))
2146 the_insn.reloc = R_HPPA_GOTOFF;
2147 else if (is_PC_relative (the_insn.exp))
2148 the_insn.reloc = R_HPPA_PCREL_CALL;
2149 else if (is_complex (the_insn.exp))
2150 the_insn.reloc = R_HPPA_COMPLEX;
2151 else
2152 the_insn.reloc = R_HPPA;
2153 the_insn.format = 11;
025b0302
ME
2154 }
2155 s = expr_end;
2156 continue;
8f78d0e9
KR
2157
2158 /* Handle a 14 bit immediate at 31. */
2159 case 'j':
025b0302 2160 the_insn.field_selector = pa_chk_field_selector (&s);
8f78d0e9 2161 get_expression (s);
5cf4cd1b 2162 if (the_insn.exp.X_op == O_constant)
025b0302 2163 {
8f78d0e9
KR
2164 low_sign_unext (evaluate_absolute (the_insn.exp,
2165 the_insn.field_selector),
025b0302
ME
2166 14, &im14);
2167 if (the_insn.field_selector == e_rsel)
2168 opcode |= (im14 & 0xfff);
2169 else
2170 opcode |= im14;
2171 }
2172 else
2173 {
2174 if (is_DP_relative (the_insn.exp))
2175 the_insn.reloc = R_HPPA_GOTOFF;
2176 else if (is_PC_relative (the_insn.exp))
2177 the_insn.reloc = R_HPPA_PCREL_CALL;
2178 else if (is_complex (the_insn.exp))
2179 the_insn.reloc = R_HPPA_COMPLEX;
2180 else
2181 the_insn.reloc = R_HPPA;
2182 the_insn.format = 14;
2183 }
2184 s = expr_end;
2185 continue;
025b0302 2186
8f78d0e9
KR
2187 /* Handle a 21 bit immediate at 31. */
2188 case 'k':
2189 the_insn.field_selector = pa_chk_field_selector (&s);
2190 get_expression (s);
5cf4cd1b 2191 if (the_insn.exp.X_op == O_constant)
025b0302 2192 {
8f78d0e9
KR
2193 dis_assemble_21 (evaluate_absolute (the_insn.exp,
2194 the_insn.field_selector),
025b0302
ME
2195 &im21);
2196 opcode |= im21;
2197 }
2198 else
2199 {
025b0302
ME
2200 if (is_DP_relative (the_insn.exp))
2201 the_insn.reloc = R_HPPA_GOTOFF;
2202 else if (is_PC_relative (the_insn.exp))
2203 the_insn.reloc = R_HPPA_PCREL_CALL;
2204 else if (is_complex (the_insn.exp))
2205 the_insn.reloc = R_HPPA_COMPLEX;
2206 else
2207 the_insn.reloc = R_HPPA;
2208 the_insn.format = 21;
2209 }
2210 s = expr_end;
2211 continue;
025b0302 2212
8f78d0e9
KR
2213 /* Handle a nullification completer for branch instructions. */
2214 case 'n':
025b0302
ME
2215 nullif = pa_parse_nullif (&s);
2216 opcode |= nullif << 1;
2217 continue;
8f78d0e9
KR
2218
2219 /* Handle a 12 bit branch displacement. */
2220 case 'w':
2221 the_insn.field_selector = pa_chk_field_selector (&s);
2222 get_expression (s);
025b0302 2223 the_insn.pcrel = 1;
8f78d0e9 2224 if (!strcmp (S_GET_NAME (the_insn.exp.X_add_symbol), "L0\001"))
025b0302
ME
2225 {
2226 unsigned int w1, w, result;
2227
8f78d0e9
KR
2228 sign_unext ((the_insn.exp.X_add_number - 8) >> 2, 12,
2229 &result);
025b0302
ME
2230 dis_assemble_12 (result, &w1, &w);
2231 opcode |= ((w1 << 2) | w);
025b0302
ME
2232 }
2233 else
2234 {
025b0302
ME
2235 if (is_complex (the_insn.exp))
2236 the_insn.reloc = R_HPPA_COMPLEX_PCREL_CALL;
2237 else
2238 the_insn.reloc = R_HPPA_PCREL_CALL;
2239 the_insn.format = 12;
2240 the_insn.arg_reloc = last_call_desc.arg_reloc;
8f78d0e9 2241 bzero (&last_call_desc, sizeof (struct call_desc));
025b0302
ME
2242 }
2243 s = expr_end;
2244 continue;
8f78d0e9
KR
2245
2246 /* Handle a 17 bit branch displacement. */
2247 case 'W':
025b0302 2248 the_insn.field_selector = pa_chk_field_selector (&s);
8f78d0e9 2249 get_expression (s);
025b0302 2250 the_insn.pcrel = 1;
025b0302
ME
2251 if (the_insn.exp.X_add_symbol)
2252 {
8f78d0e9
KR
2253 if (!strcmp (S_GET_NAME (the_insn.exp.X_add_symbol),
2254 "L0\001"))
025b0302
ME
2255 {
2256 unsigned int w2, w1, w, result;
2257
8f78d0e9
KR
2258 sign_unext ((the_insn.exp.X_add_number - 8) >> 2, 17,
2259 &result);
025b0302
ME
2260 dis_assemble_17 (result, &w1, &w2, &w);
2261 opcode |= ((w2 << 2) | (w1 << 16) | w);
2262 }
2263 else
2264 {
2265 if (is_complex (the_insn.exp))
2266 the_insn.reloc = R_HPPA_COMPLEX_PCREL_CALL;
2267 else
2268 the_insn.reloc = R_HPPA_PCREL_CALL;
2269 the_insn.format = 17;
2270 the_insn.arg_reloc = last_call_desc.arg_reloc;
8f78d0e9 2271 bzero (&last_call_desc, sizeof (struct call_desc));
025b0302
ME
2272 }
2273 }
2274 else
2275 {
2276 unsigned int w2, w1, w, result;
2277
2278 sign_unext (the_insn.exp.X_add_number >> 2, 17, &result);
2279 dis_assemble_17 (result, &w1, &w2, &w);
2280 opcode |= ((w2 << 2) | (w1 << 16) | w);
2281 }
025b0302
ME
2282 s = expr_end;
2283 continue;
8f78d0e9
KR
2284
2285 /* Handle an absolute 17 bit branch target. */
2286 case 'z':
025b0302 2287 the_insn.field_selector = pa_chk_field_selector (&s);
8f78d0e9 2288 get_expression (s);
025b0302 2289 the_insn.pcrel = 0;
025b0302
ME
2290 if (the_insn.exp.X_add_symbol)
2291 {
8f78d0e9
KR
2292 if (!strcmp (S_GET_NAME (the_insn.exp.X_add_symbol),
2293 "L0\001"))
025b0302
ME
2294 {
2295 unsigned int w2, w1, w, result;
2296
8f78d0e9
KR
2297 sign_unext ((the_insn.exp.X_add_number - 8) >> 2, 17,
2298 &result);
025b0302
ME
2299 dis_assemble_17 (result, &w1, &w2, &w);
2300 opcode |= ((w2 << 2) | (w1 << 16) | w);
2301 }
2302 else
2303 {
2304 if (is_complex (the_insn.exp))
8f78d0e9 2305 the_insn.reloc = R_HPPA_COMPLEX_ABS_CALL;
025b0302 2306 else
8f78d0e9 2307 the_insn.reloc = R_HPPA_ABS_CALL;
025b0302 2308 the_insn.format = 17;
025b0302
ME
2309 }
2310 }
2311 else
2312 {
2313 unsigned int w2, w1, w, result;
2314
2315 sign_unext (the_insn.exp.X_add_number >> 2, 17, &result);
2316 dis_assemble_17 (result, &w1, &w2, &w);
2317 opcode |= ((w2 << 2) | (w1 << 16) | w);
2318 }
025b0302
ME
2319 s = expr_end;
2320 continue;
8f78d0e9
KR
2321
2322 /* Handle a 5 bit shift count at 26. */
2323 case 'p':
2324 get_expression (s);
5cf4cd1b 2325 if (the_insn.exp.X_op == O_constant)
8f78d0e9 2326 opcode |= (((31 - the_insn.exp.X_add_number) & 0x1f) << 5);
025b0302
ME
2327 s = expr_end;
2328 continue;
8f78d0e9
KR
2329
2330 /* Handle a 5 bit bit position at 26. */
2331 case 'P':
2332 get_expression (s);
5cf4cd1b 2333 if (the_insn.exp.X_op == O_constant)
8f78d0e9 2334 opcode |= (the_insn.exp.X_add_number & 0x1f) << 5;
025b0302
ME
2335 s = expr_end;
2336 continue;
8f78d0e9
KR
2337
2338 /* Handle a 5 bit immediate at 10. */
2339 case 'Q':
2340 get_expression (s);
2341 im5 = evaluate_absolute (the_insn.exp, the_insn.field_selector);
892a3ff1 2342 if (im5 > 31)
025b0302 2343 {
8f78d0e9
KR
2344 as_bad ("Operand out of range. Was: %d. Should be [0..31].",
2345 im5);
025b0302
ME
2346 im5 = im5 & 0x1f;
2347 }
2348 opcode |= im5 << 21;
2349 s = expr_end;
2350 continue;
8f78d0e9
KR
2351
2352 /* Handle a 13 bit immediate at 18. */
2353 case 'A':
2354 pa_get_absolute_expression (s);
5cf4cd1b 2355 if (the_insn.exp.X_op == O_constant)
025b0302
ME
2356 opcode |= (the_insn.exp.X_add_number & 0x1fff) << 13;
2357 s = expr_end;
2358 continue;
8f78d0e9
KR
2359
2360 /* Handle a system control completer. */
2361 case 'Z':
025b0302
ME
2362 if (*s == ',' && (*(s + 1) == 'm' || *(s + 1) == 'M'))
2363 {
2364 m = 1;
2365 s += 2;
2366 }
2367 else
2368 m = 0;
2369
2370 opcode |= m << 5;
8f78d0e9 2371 while (*s == ' ' || *s == '\t')
025b0302 2372 s++;
025b0302 2373 continue;
8f78d0e9
KR
2374
2375 /* Handle a 26 bit immediate at 31. */
2376 case 'D':
025b0302 2377 the_insn.field_selector = pa_chk_field_selector (&s);
8f78d0e9 2378 get_expression (s);
5cf4cd1b 2379 if (the_insn.exp.X_op == O_constant)
025b0302 2380 {
8f78d0e9
KR
2381 opcode |= ((evaluate_absolute (the_insn.exp,
2382 the_insn.field_selector)
2383 & 0x1ffffff) << 1);
025b0302
ME
2384 }
2385 else
8f78d0e9 2386 as_bad ("Invalid DIAG operand");
025b0302
ME
2387 s = expr_end;
2388 continue;
8f78d0e9
KR
2389
2390 /* Handle a 3 bit SFU identifier at 25. */
2391 case 'f':
2392 sfu = pa_parse_number (&s, 0);
025b0302 2393 if ((sfu > 7) || (sfu < 0))
8f78d0e9 2394 as_bad ("Invalid SFU identifier: %02x", sfu);
025b0302
ME
2395 opcode |= (sfu & 7) << 6;
2396 continue;
8f78d0e9
KR
2397
2398 /* We don't support any of these. FIXME. */
2399 case 'O':
2400 get_expression (s);
025b0302 2401 s = expr_end;
8f78d0e9 2402 abort ();
025b0302 2403 continue;
8f78d0e9
KR
2404
2405 /* Handle a source FP operand format completer. */
2406 case 'F':
2407 flag = pa_parse_fp_format (&s);
2408 opcode |= (int) flag << 11;
2409 the_insn.fpof1 = flag;
025b0302 2410 continue;
8f78d0e9
KR
2411
2412 /* Handle a destination FP operand format completer. */
2413 case 'G':
2414
2415 /* pa_parse_format needs the ',' prefix. */
2416 s--;
2417 flag = pa_parse_fp_format (&s);
2418 opcode |= (int) flag << 13;
2419 the_insn.fpof2 = flag;
025b0302 2420 continue;
8f78d0e9
KR
2421
2422 /* Handle FP compare conditions. */
2423 case 'M':
025b0302
ME
2424 cond = pa_parse_fp_cmp_cond (&s);
2425 opcode |= cond;
2426 continue;
2427
8f78d0e9
KR
2428 /* Handle L/R register halves like 't'. */
2429 case 'v':
025b0302
ME
2430 {
2431 struct pa_89_fp_reg_struct result;
025b0302 2432
8f78d0e9 2433 pa_parse_number (&s, &result);
025b0302
ME
2434 if (result.number_part < 32 && result.number_part >= 0)
2435 {
2436 opcode |= (result.number_part & 0x1f);
2437
8f78d0e9
KR
2438 /* 0x30 opcodes are FP arithmetic operation opcodes
2439 and need to be turned into 0x38 opcodes. This
2440 is not necessary for loads/stores. */
025b0302
ME
2441 if (need_89_opcode (&the_insn, &result))
2442 {
2443 if ((opcode & 0xfc000000) == 0x30000000)
2444 {
8f78d0e9 2445 opcode |= (result.l_r_select & 1) << 6;
025b0302
ME
2446 opcode |= 1 << 27;
2447 }
2448 else
2449 {
8f78d0e9 2450 opcode |= (result.l_r_select & 1) << 6;
025b0302
ME
2451 }
2452 }
2453 continue;
2454 }
2455 }
2456 break;
8f78d0e9
KR
2457
2458 /* Handle L/R register halves like 'b'. */
2459 case 'E':
025b0302
ME
2460 {
2461 struct pa_89_fp_reg_struct result;
025b0302 2462
8f78d0e9 2463 pa_parse_number (&s, &result);
025b0302
ME
2464 if (result.number_part < 32 && result.number_part >= 0)
2465 {
2466 opcode |= (result.number_part & 0x1f) << 21;
2467 if (need_89_opcode (&the_insn, &result))
2468 {
8f78d0e9 2469 opcode |= (result.l_r_select & 1) << 7;
025b0302
ME
2470 opcode |= 1 << 27;
2471 }
2472 continue;
2473 }
2474 }
2475 break;
2476
8f78d0e9
KR
2477 /* Handle L/R register halves like 'x'. */
2478 case 'X':
025b0302
ME
2479 {
2480 struct pa_89_fp_reg_struct result;
025b0302 2481
8f78d0e9 2482 pa_parse_number (&s, &result);
025b0302
ME
2483 if (result.number_part < 32 && result.number_part >= 0)
2484 {
2485 opcode |= (result.number_part & 0x1f) << 16;
2486 if (need_89_opcode (&the_insn, &result))
2487 {
8f78d0e9 2488 opcode |= (result.l_r_select & 1) << 12;
025b0302
ME
2489 opcode |= 1 << 27;
2490 }
2491 continue;
2492 }
2493 }
2494 break;
2495
8f78d0e9
KR
2496 /* Handle a 5 bit register field at 10. */
2497 case '4':
025b0302
ME
2498 {
2499 struct pa_89_fp_reg_struct result;
2500 int status;
2501
8f78d0e9 2502 status = pa_parse_number (&s, &result);
025b0302
ME
2503 if (result.number_part < 32 && result.number_part >= 0)
2504 {
2505 if (the_insn.fpof1 == SGL)
2506 {
2507 result.number_part &= 0xF;
8f78d0e9 2508 result.number_part |= (result.l_r_select & 1) << 4;
025b0302
ME
2509 }
2510 opcode |= result.number_part << 21;
2511 continue;
2512 }
2513 }
2514 break;
2515
8f78d0e9
KR
2516 /* Handle a 5 bit register field at 15. */
2517 case '6':
025b0302
ME
2518 {
2519 struct pa_89_fp_reg_struct result;
2520 int status;
2521
8f78d0e9 2522 status = pa_parse_number (&s, &result);
025b0302
ME
2523 if (result.number_part < 32 && result.number_part >= 0)
2524 {
2525 if (the_insn.fpof1 == SGL)
2526 {
2527 result.number_part &= 0xF;
8f78d0e9 2528 result.number_part |= (result.l_r_select & 1) << 4;
025b0302
ME
2529 }
2530 opcode |= result.number_part << 16;
2531 continue;
2532 }
2533 }
2534 break;
2535
8f78d0e9
KR
2536 /* Handle a 5 bit register field at 31. */
2537 case '7':
025b0302
ME
2538 {
2539 struct pa_89_fp_reg_struct result;
2540 int status;
2541
8f78d0e9 2542 status = pa_parse_number (&s, &result);
025b0302
ME
2543 if (result.number_part < 32 && result.number_part >= 0)
2544 {
2545 if (the_insn.fpof1 == SGL)
2546 {
2547 result.number_part &= 0xF;
8f78d0e9 2548 result.number_part |= (result.l_r_select & 1) << 4;
025b0302
ME
2549 }
2550 opcode |= result.number_part;
2551 continue;
2552 }
2553 }
2554 break;
2555
8f78d0e9
KR
2556 /* Handle a 5 bit register field at 20. */
2557 case '8':
025b0302
ME
2558 {
2559 struct pa_89_fp_reg_struct result;
2560 int status;
2561
8f78d0e9 2562 status = pa_parse_number (&s, &result);
025b0302
ME
2563 if (result.number_part < 32 && result.number_part >= 0)
2564 {
2565 if (the_insn.fpof1 == SGL)
2566 {
2567 result.number_part &= 0xF;
8f78d0e9 2568 result.number_part |= (result.l_r_select & 1) << 4;
025b0302
ME
2569 }
2570 opcode |= result.number_part << 11;
2571 continue;
2572 }
2573 }
2574 break;
2575
8f78d0e9
KR
2576 /* Handle a 5 bit register field at 25. */
2577 case '9':
025b0302
ME
2578 {
2579 struct pa_89_fp_reg_struct result;
2580 int status;
2581
8f78d0e9 2582 status = pa_parse_number (&s, &result);
025b0302
ME
2583 if (result.number_part < 32 && result.number_part >= 0)
2584 {
2585 if (the_insn.fpof1 == SGL)
2586 {
2587 result.number_part &= 0xF;
8f78d0e9 2588 result.number_part |= (result.l_r_select & 1) << 4;
025b0302
ME
2589 }
2590 opcode |= result.number_part << 6;
2591 continue;
2592 }
2593 }
2594 break;
2595
8f78d0e9
KR
2596 /* Handle a floating point operand format at 26.
2597 Only allows single and double precision. */
2598 case 'H':
2599 flag = pa_parse_fp_format (&s);
2600 switch (flag)
025b0302
ME
2601 {
2602 case SGL:
2603 opcode |= 0x20;
2604 case DBL:
8f78d0e9 2605 the_insn.fpof1 = flag;
025b0302
ME
2606 continue;
2607
2608 case QUAD:
2609 case ILLEGAL_FMT:
2610 default:
8f78d0e9 2611 as_bad ("Invalid Floating Point Operand Format.");
025b0302
ME
2612 }
2613 break;
2614
2615 default:
2616 abort ();
2617 }
2618 break;
2619 }
892a3ff1 2620
8f78d0e9 2621 /* Check if the args matched. */
025b0302
ME
2622 if (match == FALSE)
2623 {
025b0302
ME
2624 if (&insn[1] - pa_opcodes < NUMOPCODES
2625 && !strcmp (insn->name, insn[1].name))
2626 {
2627 ++insn;
8f78d0e9 2628 s = argstart;
025b0302
ME
2629 continue;
2630 }
2631 else
2632 {
8f78d0e9 2633 as_bad ("Invalid operands %s", error_message);
025b0302
ME
2634 return;
2635 }
2636 }
2637 break;
2638 }
2639
2640 the_insn.opcode = opcode;
025b0302
ME
2641 return;
2642}
2643
8f78d0e9 2644/* Turn a string in input_line_pointer into a floating point constant of type
025b0302 2645 type, and store the appropriate bytes in *litP. The number of LITTLENUMS
8f78d0e9 2646 emitted is stored in *sizeP . An error message or NULL is returned. */
025b0302 2647
025b0302
ME
2648#define MAX_LITTLENUMS 6
2649
2650char *
2651md_atof (type, litP, sizeP)
2652 char type;
2653 char *litP;
2654 int *sizeP;
2655{
2656 int prec;
2657 LITTLENUM_TYPE words[MAX_LITTLENUMS];
2658 LITTLENUM_TYPE *wordP;
2659 char *t;
025b0302
ME
2660
2661 switch (type)
2662 {
2663
2664 case 'f':
2665 case 'F':
2666 case 's':
2667 case 'S':
2668 prec = 2;
2669 break;
2670
2671 case 'd':
2672 case 'D':
2673 case 'r':
2674 case 'R':
2675 prec = 4;
2676 break;
2677
2678 case 'x':
2679 case 'X':
2680 prec = 6;
2681 break;
2682
2683 case 'p':
2684 case 'P':
2685 prec = 6;
2686 break;
2687
2688 default:
2689 *sizeP = 0;
2690 return "Bad call to MD_ATOF()";
2691 }
2692 t = atof_ieee (input_line_pointer, type, words);
2693 if (t)
2694 input_line_pointer = t;
2695 *sizeP = prec * sizeof (LITTLENUM_TYPE);
2696 for (wordP = words; prec--;)
2697 {
8f78d0e9 2698 md_number_to_chars (litP, (valueT) (*wordP++), sizeof (LITTLENUM_TYPE));
025b0302
ME
2699 litP += sizeof (LITTLENUM_TYPE);
2700 }
aa8b30ed 2701 return NULL;
025b0302
ME
2702}
2703
8f78d0e9
KR
2704/* Write out big-endian. */
2705
025b0302
ME
2706void
2707md_number_to_chars (buf, val, n)
2708 char *buf;
2709 valueT val;
2710 int n;
2711{
2712
2713 switch (n)
2714 {
025b0302
ME
2715 case 4:
2716 *buf++ = val >> 24;
2717 *buf++ = val >> 16;
2718 case 2:
2719 *buf++ = val >> 8;
2720 case 1:
2721 *buf = val;
2722 break;
025b0302
ME
2723 default:
2724 abort ();
2725 }
2726 return;
2727}
2728
025b0302 2729/* Translate internal representation of relocation info to BFD target
62f0841b 2730 format. */
8f78d0e9 2731
025b0302
ME
2732arelent **
2733tc_gen_reloc (section, fixp)
2734 asection *section;
2735 fixS *fixp;
2736{
2737 arelent *reloc;
aa8b30ed 2738 struct hppa_fix_struct *hppa_fixp = fixp->tc_fix_data;
025b0302
ME
2739 bfd_reloc_code_real_type code;
2740 static int unwind_reloc_fixp_cnt = 0;
2741 static arelent *unwind_reloc_entryP = NULL;
2742 static arelent *no_relocs = NULL;
2743 arelent **relocs;
2744 bfd_reloc_code_real_type **codes;
2745 int n_relocs;
2746 int i;
2747
2748 if (fixp->fx_addsy == 0)
2749 return &no_relocs;
2750 assert (hppa_fixp != 0);
2751 assert (section != 0);
2752
62f0841b
JL
2753#ifdef OBJ_ELF
2754 /* Yuk. I would really like to push all this ELF specific unwind
2755 crud into BFD and the linker. That's how SOM does it -- and
2756 if we could make ELF emulate that then we could share more code
2757 in GAS (and potentially a gnu-linker later).
2758
2759 Unwind section relocations are handled in a special way.
8f78d0e9
KR
2760 The relocations for the .unwind section are originally
2761 built in the usual way. That is, for each unwind table
2762 entry there are two relocations: one for the beginning of
2763 the function and one for the end.
2764
2765 The first time we enter this function we create a
2766 relocation of the type R_HPPA_UNWIND_ENTRIES. The addend
2767 of the relocation is initialized to 0. Each additional
2768 pair of times this function is called for the unwind
2769 section represents an additional unwind table entry. Thus,
2770 the addend of the relocation should end up to be the number
2771 of unwind table entries. */
025b0302
ME
2772 if (strcmp (UNWIND_SECTION_NAME, section->name) == 0)
2773 {
2774 if (unwind_reloc_entryP == NULL)
2775 {
8f78d0e9
KR
2776 reloc = (arelent *) bfd_alloc_by_size_t (stdoutput,
2777 sizeof (arelent));
025b0302
ME
2778 assert (reloc != 0);
2779 unwind_reloc_entryP = reloc;
2780 unwind_reloc_fixp_cnt++;
8f78d0e9
KR
2781 unwind_reloc_entryP->address
2782 = fixp->fx_frag->fr_address + fixp->fx_where;
2783 /* A pointer to any function will do. We only
2784 need one to tell us what section the unwind
2785 relocations are for. */
025b0302 2786 unwind_reloc_entryP->sym_ptr_ptr = &fixp->fx_addsy->bsym;
8f78d0e9
KR
2787 hppa_fixp->fx_r_type = code = R_HPPA_UNWIND_ENTRIES;
2788 fixp->fx_r_type = R_HPPA_UNWIND;
025b0302
ME
2789 unwind_reloc_entryP->howto = bfd_reloc_type_lookup (stdoutput, code);
2790 unwind_reloc_entryP->addend = unwind_reloc_fixp_cnt / 2;
8f78d0e9
KR
2791 relocs = (arelent **) bfd_alloc_by_size_t (stdoutput,
2792 sizeof (arelent *) * 2);
025b0302
ME
2793 assert (relocs != 0);
2794 relocs[0] = unwind_reloc_entryP;
2795 relocs[1] = NULL;
2796 return relocs;
2797 }
2798 unwind_reloc_fixp_cnt++;
2799 unwind_reloc_entryP->addend = unwind_reloc_fixp_cnt / 2;
2800
2801 return &no_relocs;
2802 }
62f0841b 2803#endif
025b0302
ME
2804
2805 reloc = (arelent *) bfd_alloc_by_size_t (stdoutput, sizeof (arelent));
2806 assert (reloc != 0);
2807
2808 reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym;
aa8b30ed
JL
2809 codes = hppa_gen_reloc_type (stdoutput,
2810 fixp->fx_r_type,
2811 hppa_fixp->fx_r_format,
2812 hppa_fixp->fx_r_field);
025b0302
ME
2813
2814 for (n_relocs = 0; codes[n_relocs]; n_relocs++)
2815 ;
2816
8f78d0e9
KR
2817 relocs = (arelent **)
2818 bfd_alloc_by_size_t (stdoutput, sizeof (arelent *) * n_relocs + 1);
025b0302
ME
2819 assert (relocs != 0);
2820
8f78d0e9
KR
2821 reloc = (arelent *) bfd_alloc_by_size_t (stdoutput,
2822 sizeof (arelent) * n_relocs);
025b0302
ME
2823 if (n_relocs > 0)
2824 assert (reloc != 0);
2825
2826 for (i = 0; i < n_relocs; i++)
2827 relocs[i] = &reloc[i];
2828
2829 relocs[n_relocs] = NULL;
2830
62f0841b 2831#ifdef OBJ_ELF
025b0302
ME
2832 switch (fixp->fx_r_type)
2833 {
2834 case R_HPPA_COMPLEX:
2835 case R_HPPA_COMPLEX_PCREL_CALL:
2836 case R_HPPA_COMPLEX_ABS_CALL:
2837 assert (n_relocs == 5);
2838
2839 for (i = 0; i < n_relocs; i++)
2840 {
2841 reloc[i].sym_ptr_ptr = NULL;
2842 reloc[i].address = 0;
2843 reloc[i].addend = 0;
2844 reloc[i].howto = bfd_reloc_type_lookup (stdoutput, *codes[i]);
2845 assert (reloc[i].howto && *codes[i] == reloc[i].howto->type);
2846 }
2847
2848 reloc[0].sym_ptr_ptr = &fixp->fx_addsy->bsym;
2849 reloc[1].sym_ptr_ptr = &fixp->fx_subsy->bsym;
2850 reloc[4].address = fixp->fx_frag->fr_address + fixp->fx_where;
2851
2852 if (fixp->fx_r_type == R_HPPA_COMPLEX)
2853 reloc[3].addend = fixp->fx_addnumber;
2854 else if (fixp->fx_r_type == R_HPPA_COMPLEX_PCREL_CALL ||
2855 fixp->fx_r_type == R_HPPA_COMPLEX_ABS_CALL)
2856 reloc[1].addend = fixp->fx_addnumber;
2857
2858 break;
2859
2860 default:
2861 assert (n_relocs == 1);
2862
2863 code = *codes[0];
2864
2865 reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym;
2866 reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
2867 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
2868 reloc->addend = 0; /* default */
2869
2870 assert (reloc->howto && code == reloc->howto->type);
2871
8f78d0e9 2872 /* Now, do any processing that is dependent on the relocation type. */
025b0302
ME
2873 switch (code)
2874 {
2875 case R_HPPA_PLABEL_32:
2876 case R_HPPA_PLABEL_11:
2877 case R_HPPA_PLABEL_14:
2878 case R_HPPA_PLABEL_L21:
2879 case R_HPPA_PLABEL_R11:
2880 case R_HPPA_PLABEL_R14:
8f78d0e9
KR
2881 /* For plabel relocations, the addend of the
2882 relocation should be either 0 (no static link) or 2
2883 (static link required).
2884
2885 FIXME: assume that fx_addnumber contains this
2886 information */
025b0302
ME
2887 reloc->addend = fixp->fx_addnumber;
2888 break;
2889
2890 case R_HPPA_ABS_CALL_11:
2891 case R_HPPA_ABS_CALL_14:
2892 case R_HPPA_ABS_CALL_17:
2893 case R_HPPA_ABS_CALL_L21:
2894 case R_HPPA_ABS_CALL_R11:
2895 case R_HPPA_ABS_CALL_R14:
2896 case R_HPPA_ABS_CALL_R17:
2897 case R_HPPA_ABS_CALL_LS21:
2898 case R_HPPA_ABS_CALL_RS11:
2899 case R_HPPA_ABS_CALL_RS14:
2900 case R_HPPA_ABS_CALL_RS17:
2901 case R_HPPA_ABS_CALL_LD21:
2902 case R_HPPA_ABS_CALL_RD11:
2903 case R_HPPA_ABS_CALL_RD14:
2904 case R_HPPA_ABS_CALL_RD17:
2905 case R_HPPA_ABS_CALL_LR21:
2906 case R_HPPA_ABS_CALL_RR14:
2907 case R_HPPA_ABS_CALL_RR17:
2908
2909 case R_HPPA_PCREL_CALL_11:
2910 case R_HPPA_PCREL_CALL_14:
2911 case R_HPPA_PCREL_CALL_17:
2912 case R_HPPA_PCREL_CALL_L21:
2913 case R_HPPA_PCREL_CALL_R11:
2914 case R_HPPA_PCREL_CALL_R14:
2915 case R_HPPA_PCREL_CALL_R17:
2916 case R_HPPA_PCREL_CALL_LS21:
2917 case R_HPPA_PCREL_CALL_RS11:
2918 case R_HPPA_PCREL_CALL_RS14:
2919 case R_HPPA_PCREL_CALL_RS17:
2920 case R_HPPA_PCREL_CALL_LD21:
2921 case R_HPPA_PCREL_CALL_RD11:
2922 case R_HPPA_PCREL_CALL_RD14:
2923 case R_HPPA_PCREL_CALL_RD17:
2924 case R_HPPA_PCREL_CALL_LR21:
2925 case R_HPPA_PCREL_CALL_RR14:
2926 case R_HPPA_PCREL_CALL_RR17:
8f78d0e9
KR
2927 /* The constant is stored in the instruction. */
2928 reloc->addend = HPPA_R_ADDEND (hppa_fixp->fx_arg_reloc, 0);
025b0302
ME
2929 break;
2930 default:
2931 reloc->addend = fixp->fx_addnumber;
2932 break;
2933 }
2934 break;
2935 }
62f0841b 2936#else /* OBJ_SOM */
025b0302 2937
62f0841b
JL
2938 /* Preliminary relocation handling for SOM. Needs to handle
2939 COMPLEX relocations (yes, I've seen them occur) and it will
2940 need to handle R_ENTRY/R_EXIT relocations in the very near future
2941 (for generating unwinds). */
2942 switch (fixp->fx_r_type)
2943 {
2944 case R_HPPA_COMPLEX:
2945 case R_HPPA_COMPLEX_PCREL_CALL:
2946 case R_HPPA_COMPLEX_ABS_CALL:
2947 abort();
2948 break;
2949 default:
2950 assert (n_relocs == 1);
2951
2952 code = *codes[0];
2953
2954 reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym;
2955 reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
2956 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where ;
2957 reloc->addend = 0;
025b0302 2958
62f0841b
JL
2959 switch (code)
2960 {
2961 case R_PCREL_CALL:
2962 case R_ABS_CALL:
2963 reloc->addend = HPPA_R_ADDEND (hppa_fixp->fx_arg_reloc, 0);
2964 break;
2965 default:
2966 reloc->addend = fixp->fx_addnumber;
2967 break;
2968 }
2969 break;
2970 }
025b0302
ME
2971#endif
2972
62f0841b
JL
2973 return relocs;
2974}
2975
8f78d0e9
KR
2976/* Process any machine dependent frag types. */
2977
025b0302
ME
2978void
2979md_convert_frag (abfd, sec, fragP)
2980 register bfd *abfd;
2981 register asection *sec;
2982 register fragS *fragP;
2983{
2984 unsigned int address;
2985
2986 if (fragP->fr_type == rs_machine_dependent)
2987 {
2988 switch ((int) fragP->fr_subtype)
2989 {
2990 case 0:
2991 fragP->fr_type = rs_fill;
2992 know (fragP->fr_var == 1);
2993 know (fragP->fr_next);
2994 address = fragP->fr_address + fragP->fr_fix;
2995 if (address % fragP->fr_offset)
2996 {
2997 fragP->fr_offset =
2998 fragP->fr_next->fr_address
2999 - fragP->fr_address
3000 - fragP->fr_fix;
3001 }
3002 else
3003 fragP->fr_offset = 0;
3004 break;
3005 }
8f78d0e9
KR
3006 }
3007}
025b0302 3008
8f78d0e9 3009/* Round up a section size to the appropriate boundary. */
025b0302 3010
8f78d0e9
KR
3011valueT
3012md_section_align (segment, size)
3013 asection *segment;
3014 valueT size;
025b0302 3015{
8f78d0e9
KR
3016 int align = bfd_get_section_alignment (stdoutput, segment);
3017 int align2 = (1 << align) - 1;
025b0302 3018
8f78d0e9 3019 return (size + align2) & ~align2;
025b0302 3020
8f78d0e9 3021}
025b0302 3022
8f78d0e9
KR
3023/* Create a short jump from FROM_ADDR to TO_ADDR. Not used on the PA. */
3024void
3025md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol)
3026 char *ptr;
3027 addressT from_addr, to_addr;
3028 fragS *frag;
3029 symbolS *to_symbol;
3030{
3031 fprintf (stderr, "pa_create_short_jmp\n");
3032 abort ();
3033}
025b0302 3034
8f78d0e9
KR
3035/* Create a long jump from FROM_ADDR to TO_ADDR. Not used on the PA. */
3036void
3037md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol)
3038 char *ptr;
3039 addressT from_addr, to_addr;
3040 fragS *frag;
3041 symbolS *to_symbol;
3042{
3043 fprintf (stderr, "pa_create_long_jump\n");
3044 abort ();
025b0302
ME
3045}
3046
8f78d0e9
KR
3047/* Return the approximate size of a frag before relaxation has occurred. */
3048int
3049md_estimate_size_before_relax (fragP, segment)
3050 register fragS *fragP;
3051 asection *segment;
025b0302 3052{
8f78d0e9
KR
3053 int size;
3054
3055 size = 0;
3056
3057 while ((fragP->fr_fix + size) % fragP->fr_offset)
3058 size++;
3059
3060 return size;
025b0302
ME
3061}
3062
8f78d0e9
KR
3063/* Parse machine dependent options. There are none on the PA. */
3064int
3065md_parse_option (argP, cntP, vecP)
3066 char **argP;
3067 int *cntP;
3068 char ***vecP;
025b0302 3069{
8f78d0e9
KR
3070 return 1;
3071}
025b0302 3072
8f78d0e9
KR
3073/* We have no need to default values of symbols. */
3074
3075symbolS *
3076md_undefined_symbol (name)
3077 char *name;
3078{
3079 return 0;
025b0302
ME
3080}
3081
8f78d0e9
KR
3082/* Parse an operand that is machine-specific.
3083 We just return without modifying the expression as we have nothing
3084 to do on the PA. */
3085
3086void
3087md_operand (expressionP)
3088 expressionS *expressionP;
025b0302 3089{
8f78d0e9 3090}
025b0302 3091
8f78d0e9
KR
3092/* Helper function for md_apply_fix. Actually determine if the fix
3093 can be applied, and if so, apply it.
3094
3095 If a fix is applied, then set fx_addsy to NULL which indicates
3096 the fix was applied and need not be emitted into the object file. */
3097
3098static void
3099md_apply_fix_1 (fixP, val)
3100 fixS *fixP;
3101 long val;
025b0302 3102{
8f78d0e9 3103 char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
aa8b30ed 3104 struct hppa_fix_struct *hppa_fixP = fixP->tc_fix_data;
8f78d0e9
KR
3105 long new_val, result;
3106 unsigned int w1, w2, w;
3107
ff852e11
JL
3108 /* SOM uses R_HPPA_ENTRY and R_HPPA_EXIT relocations which can
3109 never be "applied". They must always be emitted. */
3110#ifdef OBJ_SOM
3111 if (fixP->fx_r_type == R_HPPA_ENTRY
3112 || fixP->fx_r_type == R_HPPA_EXIT)
3113 return;
3114#endif
3115
8f78d0e9
KR
3116 /* There should have been an HPPA specific fixup associated
3117 with the GAS fixup. */
3118 if (hppa_fixP)
3119 {
3120 unsigned long buf_wd = bfd_get_32 (stdoutput, buf);
aa8b30ed 3121 unsigned char fmt = bfd_hppa_insn2fmt (buf_wd);
8f78d0e9
KR
3122
3123 /* Sanity check the fixup type. */
aa8b30ed
JL
3124 /* Is this really necessary? */
3125 if (fixP->fx_r_type == R_HPPA_NONE)
3126 fmt = 0;
8f78d0e9
KR
3127
3128 /* Remember this value for emit_reloc. FIXME, is this braindamage
3129 documented anywhere!?! */
3130 fixP->fx_addnumber = val;
3131
3132 /* Check if this is an undefined symbol. No relocation can
3133 possibly be performed in this case. */
3134 if ((fixP->fx_addsy && fixP->fx_addsy->bsym->section == &bfd_und_section)
3135 || (fixP->fx_subsy
3136 && fixP->fx_subsy->bsym->section == &bfd_und_section))
3137 return;
3138
3139 switch (fmt)
3140 {
3141 /* Handle all opcodes with the 'j' operand type. */
3142 case 14:
3143 new_val = hppa_field_adjust (val, 0, hppa_fixP->fx_r_field);
3144
3145 /* Mask off 14 bits to be changed. */
3146 bfd_put_32 (stdoutput,
3147 bfd_get_32 (stdoutput, buf) & 0xffffc000,
3148 buf);
3149 low_sign_unext (new_val, 14, &result);
3150 break;
3151
3152 /* Handle all opcodes with the 'k' operand type. */
3153 case 21:
3154 new_val = hppa_field_adjust (val, 0, hppa_fixP->fx_r_field);
3155
3156 /* Mask off 21 bits to be changed. */
3157 bfd_put_32 (stdoutput,
3158 bfd_get_32 (stdoutput, buf) & 0xffe00000,
3159 buf);
3160 dis_assemble_21 (new_val, &result);
3161 break;
3162
3163 /* Handle all the opcodes with the 'i' operand type. */
3164 case 11:
3165 new_val = hppa_field_adjust (val, 0, hppa_fixP->fx_r_field);
3166
3167 /* Mask off 11 bits to be changed. */
3168 bfd_put_32 (stdoutput,
3169 bfd_get_32 (stdoutput, buf) & 0xffff800,
3170 buf);
3171 low_sign_unext (new_val, 11, &result);
3172 break;
3173
3174 /* Handle all the opcodes with the 'w' operand type. */
3175 case 12:
3176 new_val = hppa_field_adjust (val, 0, hppa_fixP->fx_r_field);
3177
3178 /* Mask off 11 bits to be changed. */
3179 sign_unext ((new_val - 8) >> 2, 12, &result);
3180 bfd_put_32 (stdoutput,
3181 bfd_get_32 (stdoutput, buf) & 0xffffe002,
3182 buf);
3183
3184 dis_assemble_12 (result, &w1, &w);
3185 result = ((w1 << 2) | w);
3186 fixP->fx_addsy = NULL;
3187 break;
3188
3189#define too_far(VAL, NUM_BITS) \
3190 (((int)(VAL) > (1 << (NUM_BITS)) - 1) || ((int)(VAL) < (-1 << (NUM_BITS))))
3191
3192#define stub_needed(CALLER, CALLEE) \
3193 ((CALLEE) && (CALLER) && ((CALLEE) != (CALLER)))
3194
3195 /* Handle some of the opcodes with the 'W' operand type. */
3196 case 17:
3197 /* If a long-call stub or argument relocation stub is
3198 needed, then we can not apply this relocation, instead
3199 the linker must handle it. */
3200 if (too_far (val, 18)
aa8b30ed 3201 || stub_needed (((obj_symbol_type *)
8f78d0e9
KR
3202 fixP->fx_addsy->bsym)->tc_data.hppa_arg_reloc,
3203 hppa_fixP->fx_arg_reloc))
3204 return;
3205
3206 /* No stubs were needed, we can perform this relocation. */
3207 new_val = hppa_field_adjust (val, 0, hppa_fixP->fx_r_field);
3208
3209 /* Mask off 17 bits to be changed. */
3210 bfd_put_32 (stdoutput,
3211 bfd_get_32 (stdoutput, buf) & 0xffe0e002,
3212 buf);
3213 sign_unext ((new_val - 8) >> 2, 17, &result);
3214 dis_assemble_17 (result, &w1, &w2, &w);
3215 result = ((w2 << 2) | (w1 << 16) | w);
3216 fixP->fx_addsy = NULL;
3217 break;
3218
3219#undef too_far
3220#undef stub_needed
3221
3222 case 32:
aa8b30ed 3223#ifdef OBJ_ELF
ff852e11
JL
3224 /* These are ELF specific relocations. ELF unfortunately
3225 handles unwinds in a completely different manner. */
8f78d0e9
KR
3226 if (hppa_fixP->fx_r_type == R_HPPA_UNWIND_ENTRY
3227 || hppa_fixP->fx_r_type == R_HPPA_UNWIND_ENTRIES)
3228 result = fixP->fx_addnumber;
3229 else
aa8b30ed 3230#endif
8f78d0e9
KR
3231 {
3232 result = 0;
3233 fixP->fx_addnumber = fixP->fx_offset;
3234 bfd_put_32 (stdoutput, 0, buf);
3235 return;
3236 }
3237 break;
3238
3239 case 0:
3240 return;
3241
3242 default:
3243 as_bad ("bad relocation type/fmt: 0x%02x/0x%02x",
3244 fixP->fx_r_type, fmt);
3245 return;
3246 }
3247
3248 /* Insert the relocation. */
3249 buf[0] |= (result & 0xff000000) >> 24;
3250 buf[1] |= (result & 0x00ff0000) >> 16;
3251 buf[2] |= (result & 0x0000ff00) >> 8;
3252 buf[3] |= result & 0x000000ff;
3253 }
025b0302 3254 else
8f78d0e9
KR
3255 printf ("no hppa_fixup entry for this fixup (fixP = 0x%x, type = 0x%x)\n",
3256 (unsigned int) fixP, fixP->fx_r_type);
025b0302 3257}
8f78d0e9
KR
3258
3259/* Apply a fix into a frag's data (if possible). */
025b0302
ME
3260
3261int
8f78d0e9
KR
3262md_apply_fix (fixP, valp)
3263 fixS *fixP;
3264 valueT *valp;
3265{
3266 md_apply_fix_1 (fixP, (long) *valp);
3267 return 1;
3268}
3269
3270/* Exactly what point is a PC-relative offset relative TO?
3271 On the PA, they're relative to the address of the offset. */
3272
3273long
3274md_pcrel_from (fixP)
3275 fixS *fixP;
3276{
3277 return fixP->fx_where + fixP->fx_frag->fr_address;
3278}
3279
3280/* Return nonzero if the input line pointer is at the end of
3281 a statement. */
3282
3283static int
3284is_end_of_statement ()
3285{
3286 return ((*input_line_pointer == '\n')
3287 || (*input_line_pointer == ';')
3288 || (*input_line_pointer == '!'));
3289}
3290
3291/* Read a number from S. The number might come in one of many forms,
3292 the most common will be a hex or decimal constant, but it could be
3293 a pre-defined register (Yuk!), or an absolute symbol.
3294
3295 Return a number or -1 for failure.
3296
3297 When parsing PA-89 FP register numbers RESULT will be
3298 the address of a structure to return information about
3299 L/R half of FP registers, store results there as appropriate.
3300
3301 pa_parse_number can not handle negative constants and will fail
3302 horribly if it is passed such a constant. */
3303
3304static int
3305pa_parse_number (s, result)
025b0302
ME
3306 char **s;
3307 struct pa_89_fp_reg_struct *result;
3308{
3309 int num;
3310 char *name;
3311 char c;
3312 symbolS *sym;
3313 int status;
3314 char *p = *s;
3315
8f78d0e9 3316 /* Skip whitespace before the number. */
025b0302
ME
3317 while (*p == ' ' || *p == '\t')
3318 p = p + 1;
8f78d0e9
KR
3319
3320 /* Store info in RESULT if requested by caller. */
3321 if (result)
3322 {
3323 result->number_part = -1;
3324 result->l_r_select = -1;
3325 }
3326 num = -1;
025b0302
ME
3327
3328 if (isdigit (*p))
3329 {
8f78d0e9
KR
3330 /* Looks like a number. */
3331 num = 0;
025b0302
ME
3332
3333 if (*p == '0' && (*(p + 1) == 'x' || *(p + 1) == 'X'))
8f78d0e9
KR
3334 {
3335 /* The number is specified in hex. */
3336 p += 2;
025b0302
ME
3337 while (isdigit (*p) || ((*p >= 'a') && (*p <= 'f'))
3338 || ((*p >= 'A') && (*p <= 'F')))
3339 {
3340 if (isdigit (*p))
3341 num = num * 16 + *p - '0';
3342 else if (*p >= 'a' && *p <= 'f')
3343 num = num * 16 + *p - 'a' + 10;
3344 else
3345 num = num * 16 + *p - 'A' + 10;
3346 ++p;
3347 }
3348 }
3349 else
3350 {
8f78d0e9 3351 /* The number is specified in decimal. */
025b0302
ME
3352 while (isdigit (*p))
3353 {
3354 num = num * 10 + *p - '0';
3355 ++p;
3356 }
3357 }
3358
8f78d0e9
KR
3359 /* Store info in RESULT if requested by the caller. */
3360 if (result)
025b0302 3361 {
8f78d0e9 3362 result->number_part = num;
025b0302 3363
8f78d0e9
KR
3364 if (IS_R_SELECT (p))
3365 {
3366 result->l_r_select = 1;
3367 ++p;
3368 }
3369 else if (IS_L_SELECT (p))
3370 {
3371 result->l_r_select = 0;
3372 ++p;
3373 }
3374 else
3375 result->l_r_select = 0;
3376 }
025b0302
ME
3377 }
3378 else if (*p == '%')
8f78d0e9
KR
3379 {
3380 /* The number might be a predefined register. */
025b0302
ME
3381 num = 0;
3382 name = p;
3383 p++;
3384 c = *p;
8f78d0e9
KR
3385 /* Tege hack: Special case for general registers as the general
3386 code makes a binary search with case translation, and is VERY
3387 slow. */
025b0302
ME
3388 if (c == 'r')
3389 {
3390 p++;
8f78d0e9
KR
3391 if (*p == 'e' && *(p + 1) == 't'
3392 && (*(p + 2) == '0' || *(p + 2) == '1'))
025b0302
ME
3393 {
3394 p += 2;
8f78d0e9 3395 num = *p - '0' + 28;
025b0302
ME
3396 p++;
3397 }
3398 else if (!isdigit (*p))
3399 as_bad ("Undefined register: '%s'. ASSUMING 0", name);
3400 else
3401 {
3402 do
3403 num = num * 10 + *p++ - '0';
3404 while (isdigit (*p));
3405 }
3406 }
3407 else
3408 {
8f78d0e9 3409 /* Do a normal register search. */
025b0302
ME
3410 while (is_part_of_name (c))
3411 {
3412 p = p + 1;
3413 c = *p;
3414 }
3415 *p = 0;
3416 status = reg_name_search (name);
3417 if (status >= 0)
3418 num = status;
3419 else
3420 {
3421 if (print_errors)
3422 as_bad ("Undefined register: '%s'. ASSUMING 0", name);
3423 else
3424 num = -1;
3425 }
3426 *p = c;
3427 }
3428
8f78d0e9
KR
3429 /* Store info in RESULT if requested by caller. */
3430 if (result)
3431 {
3432 result->number_part = num;
3433 if (IS_R_SELECT (p - 1))
3434 result->l_r_select = 1;
3435 else if (IS_L_SELECT (p - 1))
3436 result->l_r_select = 0;
3437 else
3438 result->l_r_select = 0;
3439 }
025b0302
ME
3440 }
3441 else
3442 {
8f78d0e9
KR
3443 /* And finally, it could be a symbol in the absolute section which
3444 is effectively a constant. */
025b0302
ME
3445 num = 0;
3446 name = p;
3447 c = *p;
3448 while (is_part_of_name (c))
3449 {
3450 p = p + 1;
3451 c = *p;
3452 }
3453 *p = 0;
3454 if ((sym = symbol_find (name)) != NULL)
3455 {
025b0302 3456 if (S_GET_SEGMENT (sym) == &bfd_abs_section)
8f78d0e9 3457 num = S_GET_VALUE (sym);
025b0302
ME
3458 else
3459 {
3460 if (print_errors)
3461 as_bad ("Non-absolute constant: '%s'. ASSUMING 0", name);
3462 else
3463 num = -1;
3464 }
3465 }
3466 else
3467 {
3468 if (print_errors)
3469 as_bad ("Undefined absolute constant: '%s'. ASSUMING 0", name);
3470 else
3471 num = -1;
3472 }
3473 *p = c;
025b0302 3474
8f78d0e9
KR
3475 /* Store info in RESULT if requested by caller. */
3476 if (result)
3477 {
3478 result->number_part = num;
3479 if (IS_R_SELECT (p - 1))
3480 result->l_r_select = 1;
3481 else if (IS_L_SELECT (p - 1))
3482 result->l_r_select = 0;
3483 else
3484 result->l_r_select = 0;
3485 }
025b0302
ME
3486 }
3487
3488 *s = p;
3489 return num;
8f78d0e9
KR
3490}
3491
3492#define REG_NAME_CNT (sizeof(pre_defined_registers) / sizeof(struct pd_reg))
3493
3494/* Given NAME, find the register number associated with that name, return
3495 the integer value associated with the given name or -1 on failure. */
3496
3497static int
3498reg_name_search (name)
3499 char *name;
3500{
3501 int middle, low, high;
3502
3503 low = 0;
3504 high = REG_NAME_CNT - 1;
3505
3506 do
3507 {
3508 middle = (low + high) / 2;
3509 if (strcasecmp (name, pre_defined_registers[middle].name) < 0)
3510 high = middle - 1;
3511 else
3512 low = middle + 1;
3513 }
3514 while (!((strcasecmp (name, pre_defined_registers[middle].name) == 0) ||
3515 (low > high)));
3516
3517 if (strcasecmp (name, pre_defined_registers[middle].name) == 0)
3518 return (pre_defined_registers[middle].value);
3519 else
3520 return (-1);
3521}
3522
3523
3524/* Return nonzero if the given INSN and L/R information will require
3525 a new PA-89 opcode. */
025b0302 3526
8f78d0e9
KR
3527static int
3528need_89_opcode (insn, result)
3529 struct pa_it *insn;
3530 struct pa_89_fp_reg_struct *result;
3531{
3532 if (result->l_r_select == 1 && !(insn->fpof1 == DBL && insn->fpof2 == DBL))
3533 return TRUE;
3534 else
3535 return FALSE;
025b0302
ME
3536}
3537
8f78d0e9
KR
3538/* Parse a condition for a fcmp instruction. Return the numerical
3539 code associated with the condition. */
3540
3541static int
025b0302
ME
3542pa_parse_fp_cmp_cond (s)
3543 char **s;
3544{
3545 int cond, i;
025b0302
ME
3546
3547 cond = 0;
3548
3549 for (i = 0; i < 32; i++)
3550 {
8f78d0e9
KR
3551 if (strncasecmp (*s, fp_cond_map[i].string,
3552 strlen (fp_cond_map[i].string)) == 0)
025b0302 3553 {
8f78d0e9
KR
3554 cond = fp_cond_map[i].cond;
3555 *s += strlen (fp_cond_map[i].string);
025b0302
ME
3556 while (**s == ' ' || **s == '\t')
3557 *s = *s + 1;
3558 return cond;
3559 }
3560 }
3561
8f78d0e9 3562 as_bad ("Invalid FP Compare Condition: %c", **s);
025b0302
ME
3563 return 0;
3564}
3565
8f78d0e9
KR
3566/* Parse an FP operand format completer returning the completer
3567 type. */
3568
3569static fp_operand_format
025b0302
ME
3570pa_parse_fp_format (s)
3571 char **s;
3572{
8f78d0e9 3573 int format;
025b0302 3574
8f78d0e9 3575 format = SGL;
025b0302
ME
3576 if (**s == ',')
3577 {
3578 *s += 1;
3579 if (strncasecmp (*s, "sgl", 3) == 0)
3580 {
8f78d0e9 3581 format = SGL;
025b0302
ME
3582 *s += 4;
3583 }
3584 else if (strncasecmp (*s, "dbl", 3) == 0)
3585 {
8f78d0e9 3586 format = DBL;
025b0302
ME
3587 *s += 4;
3588 }
3589 else if (strncasecmp (*s, "quad", 4) == 0)
3590 {
8f78d0e9 3591 format = QUAD;
025b0302
ME
3592 *s += 5;
3593 }
3594 else
3595 {
8f78d0e9
KR
3596 format = ILLEGAL_FMT;
3597 as_bad ("Invalid FP Operand Format: %3s", *s);
025b0302
ME
3598 }
3599 }
3600 while (**s == ' ' || **s == '\t' || **s == 0)
3601 *s = *s + 1;
3602
8f78d0e9 3603 return format;
025b0302
ME
3604}
3605
8f78d0e9
KR
3606/* Convert from a selector string into a selector type. */
3607
3608static int
025b0302
ME
3609pa_chk_field_selector (str)
3610 char **str;
3611{
3612 int selector;
8f78d0e9 3613 struct selector_entry *tablep;
025b0302
ME
3614
3615 selector = e_fsel;
3616
8f78d0e9 3617 /* Read past any whitespace. */
025b0302 3618 while (**str == ' ' || **str == '\t' || **str == '\n' || **str == '\f')
8f78d0e9
KR
3619 *str = *str + 1;
3620
3621 /* Yuk. Looks like a linear search through the table. With the
3622 frequence of some selectors it might make sense to sort the
3623 table by usage. */
3624 for (tablep = selector_table; tablep->prefix; tablep++)
025b0302 3625 {
8f78d0e9 3626 if (strncasecmp (tablep->prefix, *str, strlen (tablep->prefix)) == 0)
025b0302 3627 {
8f78d0e9
KR
3628 *str += strlen (tablep->prefix);
3629 selector = tablep->field_selector;
025b0302
ME
3630 break;
3631 }
3632 }
3633 return selector;
3634}
3635
8f78d0e9 3636/* Mark (via expr_end) the end of an expression (I think). FIXME. */
025b0302 3637
8f78d0e9
KR
3638static int
3639get_expression (str)
025b0302
ME
3640 char *str;
3641{
3642 char *save_in;
8f78d0e9 3643 asection *seg;
025b0302
ME
3644
3645 save_in = input_line_pointer;
3646 input_line_pointer = str;
5cf4cd1b
KR
3647 seg = expression (&the_insn.exp);
3648 if (!(seg == absolute_section
3649 || seg == undefined_section
3650 || SEG_NORMAL (seg)))
025b0302 3651 {
8f78d0e9 3652 as_warn ("Bad segment in expression.");
025b0302
ME
3653 expr_end = input_line_pointer;
3654 input_line_pointer = save_in;
3655 return 1;
3656 }
3657 expr_end = input_line_pointer;
3658 input_line_pointer = save_in;
3659 return 0;
3660}
3661
8f78d0e9
KR
3662/* Mark (via expr_end) the end of an absolute expression. FIXME. */
3663static int
3664pa_get_absolute_expression (str)
025b0302
ME
3665 char *str;
3666{
3667 char *save_in;
025b0302
ME
3668
3669 save_in = input_line_pointer;
3670 input_line_pointer = str;
5cf4cd1b
KR
3671 expression (&the_insn.exp);
3672 if (the_insn.exp.X_op != O_constant)
025b0302 3673 {
8f78d0e9 3674 as_warn ("Bad segment (should be absolute).");
025b0302
ME
3675 expr_end = input_line_pointer;
3676 input_line_pointer = save_in;
3677 return 1;
3678 }
3679 expr_end = input_line_pointer;
3680 input_line_pointer = save_in;
3681 return 0;
3682}
3683
8f78d0e9
KR
3684/* Evaluate an absolute expression EXP which may be modified by
3685 the selector FIELD_SELECTOR. Return the value of the expression. */
3686static int
3687evaluate_absolute (exp, field_selector)
025b0302
ME
3688 expressionS exp;
3689 int field_selector;
3690{
3691 int value;
3692
3693 value = exp.X_add_number;
3694
025b0302
ME
3695 switch (field_selector)
3696 {
8f78d0e9
KR
3697 /* No change. */
3698 case e_fsel:
025b0302
ME
3699 break;
3700
8f78d0e9
KR
3701 /* If bit 21 is on then add 0x800 and arithmetic shift right 11 bits. */
3702 case e_lssel:
025b0302
ME
3703 if (value & 0x00000400)
3704 value += 0x800;
3705 value = (value & 0xfffff800) >> 11;
3706 break;
3707
8f78d0e9
KR
3708 /* Sign extend from bit 21. */
3709 case e_rssel:
025b0302
ME
3710 if (value & 0x00000400)
3711 value |= 0xfffff800;
3712 else
3713 value &= 0x7ff;
3714 break;
3715
8f78d0e9
KR
3716 /* Arithmetic shift right 11 bits. */
3717 case e_lsel:
025b0302
ME
3718 value = (value & 0xfffff800) >> 11;
3719 break;
3720
8f78d0e9
KR
3721 /* Set bits 0-20 to zero. */
3722 case e_rsel:
025b0302
ME
3723 value = value & 0x7ff;
3724 break;
3725
8f78d0e9
KR
3726 /* Add 0x800 and arithmetic shift right 11 bits. */
3727 case e_ldsel:
025b0302 3728 value += 0x800;
025b0302 3729
025b0302 3730
025b0302
ME
3731 value = (value & 0xfffff800) >> 11;
3732 break;
3733
8f78d0e9
KR
3734 /* Set bitgs 0-21 to one. */
3735 case e_rdsel:
3736 value |= 0xfffff800;
025b0302
ME
3737 break;
3738
8f78d0e9
KR
3739 /* This had better get fixed. It looks like we're quickly moving
3740 to LR/RR. FIXME. */
3741 case e_rrsel:
3742 case e_lrsel:
3743 abort ();
3744
025b0302
ME
3745 default:
3746 BAD_CASE (field_selector);
3747 break;
3748 }
3749 return value;
3750}
3751
8f78d0e9
KR
3752/* Given an argument location specification return the associated
3753 argument location number. */
3754
3755static unsigned int
025b0302
ME
3756pa_build_arg_reloc (type_name)
3757 char *type_name;
3758{
3759
3760 if (strncasecmp (type_name, "no", 2) == 0)
8f78d0e9 3761 return 0;
025b0302 3762 if (strncasecmp (type_name, "gr", 2) == 0)
8f78d0e9 3763 return 1;
025b0302 3764 else if (strncasecmp (type_name, "fr", 2) == 0)
8f78d0e9 3765 return 2;
025b0302 3766 else if (strncasecmp (type_name, "fu", 2) == 0)
8f78d0e9 3767 return 3;
025b0302 3768 else
8f78d0e9 3769 as_bad ("Invalid argument location: %s\n", type_name);
025b0302
ME
3770
3771 return 0;
3772}
3773
8f78d0e9
KR
3774/* Encode and return an argument relocation specification for
3775 the given register in the location specified by arg_reloc. */
3776
3777static unsigned int
025b0302
ME
3778pa_align_arg_reloc (reg, arg_reloc)
3779 unsigned int reg;
3780 unsigned int arg_reloc;
3781{
3782 unsigned int new_reloc;
3783
3784 new_reloc = arg_reloc;
3785 switch (reg)
3786 {
3787 case 0:
3788 new_reloc <<= 8;
3789 break;
3790 case 1:
3791 new_reloc <<= 6;
3792 break;
3793 case 2:
3794 new_reloc <<= 4;
3795 break;
3796 case 3:
3797 new_reloc <<= 2;
3798 break;
3799 default:
8f78d0e9 3800 as_bad ("Invalid argument description: %d", reg);
025b0302
ME
3801 }
3802
3803 return new_reloc;
3804}
3805
8f78d0e9
KR
3806/* Parse a PA nullification completer (,n). Return nonzero if the
3807 completer was found; return zero if no completer was found. */
3808
3809static int
025b0302
ME
3810pa_parse_nullif (s)
3811 char **s;
3812{
3813 int nullif;
3814
3815 nullif = 0;
3816 if (**s == ',')
3817 {
3818 *s = *s + 1;
3819 if (strncasecmp (*s, "n", 1) == 0)
3820 nullif = 1;
3821 else
3822 {
8f78d0e9 3823 as_bad ("Invalid Nullification: (%c)", **s);
025b0302
ME
3824 nullif = 0;
3825 }
3826 *s = *s + 1;
3827 }
3828 while (**s == ' ' || **s == '\t')
3829 *s = *s + 1;
3830
3831 return nullif;
3832}
3833
8f78d0e9
KR
3834/* Parse a non-negated compare/subtract completer returning the
3835 number (for encoding in instrutions) of the given completer.
3836
3837 ISBRANCH specifies whether or not this is parsing a condition
3838 completer for a branch (vs a nullification completer for a
3839 computational instruction. */
3840
3841static int
5cf4cd1b 3842pa_parse_nonneg_cmpsub_cmpltr (s, isbranch)
025b0302 3843 char **s;
5cf4cd1b 3844 int isbranch;
025b0302
ME
3845{
3846 int cmpltr;
5cf4cd1b 3847 char *name = *s + 1;
025b0302 3848 char c;
5cf4cd1b 3849 char *save_s = *s;
025b0302 3850
5cf4cd1b 3851 cmpltr = 0;
025b0302
ME
3852 if (**s == ',')
3853 {
3854 *s += 1;
025b0302
ME
3855 while (**s != ',' && **s != ' ' && **s != '\t')
3856 *s += 1;
3857 c = **s;
3858 **s = 0x00;
3859 if (strcmp (name, "=") == 0)
3860 {
3861 cmpltr = 1;
3862 }
3863 else if (strcmp (name, "<") == 0)
3864 {
3865 cmpltr = 2;
3866 }
3867 else if (strcmp (name, "<=") == 0)
3868 {
3869 cmpltr = 3;
3870 }
3871 else if (strcmp (name, "<<") == 0)
3872 {
3873 cmpltr = 4;
3874 }
3875 else if (strcmp (name, "<<=") == 0)
3876 {
3877 cmpltr = 5;
3878 }
3879 else if (strcasecmp (name, "sv") == 0)
3880 {
3881 cmpltr = 6;
3882 }
3883 else if (strcasecmp (name, "od") == 0)
3884 {
3885 cmpltr = 7;
3886 }
5cf4cd1b 3887 /* If we have something like addb,n then there is no condition
8f78d0e9 3888 completer. */
5cf4cd1b 3889 else if (strcasecmp (name, "n") == 0 && isbranch)
025b0302 3890 {
5cf4cd1b 3891 cmpltr = 0;
025b0302 3892 }
8f78d0e9 3893 else
025b0302 3894 {
5cf4cd1b 3895 cmpltr = -1;
025b0302 3896 }
025b0302
ME
3897 **s = c;
3898 }
3899 if (cmpltr >= 0)
3900 {
3901 while (**s == ' ' || **s == '\t')
3902 *s = *s + 1;
3903 }
3904
5cf4cd1b
KR
3905 /* Reset pointers if this was really a ,n for a branch instruction. */
3906 if (cmpltr == 0 && *name == 'n' && isbranch)
3907 *s = save_s;
3908
025b0302
ME
3909 return cmpltr;
3910}
3911
8f78d0e9
KR
3912/* Parse a negated compare/subtract completer returning the
3913 number (for encoding in instrutions) of the given completer.
3914
3915 ISBRANCH specifies whether or not this is parsing a condition
3916 completer for a branch (vs a nullification completer for a
3917 computational instruction. */
3918
3919static int
5cf4cd1b 3920pa_parse_neg_cmpsub_cmpltr (s, isbranch)
025b0302 3921 char **s;
5cf4cd1b 3922 int isbranch;
025b0302
ME
3923{
3924 int cmpltr;
5cf4cd1b 3925 char *name = *s + 1;
025b0302 3926 char c;
5cf4cd1b 3927 char *save_s = *s;
025b0302 3928
5cf4cd1b 3929 cmpltr = 0;
025b0302
ME
3930 if (**s == ',')
3931 {
3932 *s += 1;
025b0302
ME
3933 while (**s != ',' && **s != ' ' && **s != '\t')
3934 *s += 1;
3935 c = **s;
3936 **s = 0x00;
3937 if (strcasecmp (name, "tr") == 0)
3938 {
3939 cmpltr = 0;
3940 }
3941 else if (strcmp (name, "<>") == 0)
3942 {
3943 cmpltr = 1;
3944 }
3945 else if (strcmp (name, ">=") == 0)
3946 {
3947 cmpltr = 2;
3948 }
3949 else if (strcmp (name, ">") == 0)
3950 {
3951 cmpltr = 3;
3952 }
3953 else if (strcmp (name, ">>=") == 0)
3954 {
3955 cmpltr = 4;
3956 }
3957 else if (strcmp (name, ">>") == 0)
3958 {
3959 cmpltr = 5;
3960 }
3961 else if (strcasecmp (name, "nsv") == 0)
3962 {
3963 cmpltr = 6;
3964 }
3965 else if (strcasecmp (name, "ev") == 0)
3966 {
3967 cmpltr = 7;
3968 }
5cf4cd1b 3969 /* If we have something like addb,n then there is no condition
8f78d0e9 3970 completer. */
5cf4cd1b
KR
3971 else if (strcasecmp (name, "n") == 0 && isbranch)
3972 {
3973 cmpltr = 0;
3974 }
3975 else
3976 {
3977 cmpltr = -1;
3978 }
025b0302
ME
3979 **s = c;
3980 }
3981 if (cmpltr >= 0)
3982 {
3983 while (**s == ' ' || **s == '\t')
3984 *s = *s + 1;
3985 }
3986
5cf4cd1b
KR
3987 /* Reset pointers if this was really a ,n for a branch instruction. */
3988 if (cmpltr == 0 && *name == 'n' && isbranch)
3989 *s = save_s;
3990
025b0302
ME
3991 return cmpltr;
3992}
3993
8f78d0e9
KR
3994/* Parse a non-negated addition completer returning the number
3995 (for encoding in instrutions) of the given completer.
3996
3997 ISBRANCH specifies whether or not this is parsing a condition
3998 completer for a branch (vs a nullification completer for a
3999 computational instruction. */
4000
4001static int
5cf4cd1b 4002pa_parse_nonneg_add_cmpltr (s, isbranch)
025b0302 4003 char **s;
5cf4cd1b 4004 int isbranch;
025b0302
ME
4005{
4006 int cmpltr;
5cf4cd1b 4007 char *name = *s + 1;
025b0302 4008 char c;
5cf4cd1b 4009 char *save_s = *s;
025b0302 4010
5cf4cd1b 4011 cmpltr = 0;
025b0302
ME
4012 if (**s == ',')
4013 {
4014 *s += 1;
025b0302
ME
4015 while (**s != ',' && **s != ' ' && **s != '\t')
4016 *s += 1;
4017 c = **s;
4018 **s = 0x00;
4019 if (strcmp (name, "=") == 0)
4020 {
4021 cmpltr = 1;
4022 }
4023 else if (strcmp (name, "<") == 0)
4024 {
4025 cmpltr = 2;
4026 }
4027 else if (strcmp (name, "<=") == 0)
4028 {
4029 cmpltr = 3;
4030 }
4031 else if (strcasecmp (name, "nuv") == 0)
4032 {
4033 cmpltr = 4;
4034 }
4035 else if (strcasecmp (name, "znv") == 0)
4036 {
4037 cmpltr = 5;
4038 }
4039 else if (strcasecmp (name, "sv") == 0)
4040 {
4041 cmpltr = 6;
4042 }
4043 else if (strcasecmp (name, "od") == 0)
4044 {
4045 cmpltr = 7;
4046 }
5cf4cd1b 4047 /* If we have something like addb,n then there is no condition
8f78d0e9 4048 completer. */
5cf4cd1b
KR
4049 else if (strcasecmp (name, "n") == 0 && isbranch)
4050 {
4051 cmpltr = 0;
4052 }
4053 else
4054 {
4055 cmpltr = -1;
4056 }
025b0302
ME
4057 **s = c;
4058 }
4059 if (cmpltr >= 0)
4060 {
4061 while (**s == ' ' || **s == '\t')
4062 *s = *s + 1;
4063 }
4064
5cf4cd1b
KR
4065 /* Reset pointers if this was really a ,n for a branch instruction. */
4066 if (cmpltr == 0 && *name == 'n' && isbranch)
4067 *s = save_s;
4068
025b0302
ME
4069 return cmpltr;
4070}
4071
8f78d0e9
KR
4072/* Parse a negated addition completer returning the number
4073 (for encoding in instrutions) of the given completer.
4074
4075 ISBRANCH specifies whether or not this is parsing a condition
4076 completer for a branch (vs a nullification completer for a
4077 computational instruction. */
4078
4079static int
5cf4cd1b 4080pa_parse_neg_add_cmpltr (s, isbranch)
025b0302 4081 char **s;
5cf4cd1b 4082 int isbranch;
025b0302
ME
4083{
4084 int cmpltr;
5cf4cd1b 4085 char *name = *s + 1;
025b0302 4086 char c;
5cf4cd1b 4087 char *save_s = *s;
025b0302 4088
5cf4cd1b 4089 cmpltr = 0;
025b0302
ME
4090 if (**s == ',')
4091 {
4092 *s += 1;
025b0302
ME
4093 while (**s != ',' && **s != ' ' && **s != '\t')
4094 *s += 1;
4095 c = **s;
4096 **s = 0x00;
4097 if (strcasecmp (name, "tr") == 0)
4098 {
4099 cmpltr = 0;
4100 }
4101 else if (strcmp (name, "<>") == 0)
4102 {
4103 cmpltr = 1;
4104 }
4105 else if (strcmp (name, ">=") == 0)
4106 {
4107 cmpltr = 2;
4108 }
4109 else if (strcmp (name, ">") == 0)
4110 {
4111 cmpltr = 3;
4112 }
4113 else if (strcmp (name, "uv") == 0)
4114 {
4115 cmpltr = 4;
4116 }
4117 else if (strcmp (name, "vnz") == 0)
4118 {
4119 cmpltr = 5;
4120 }
4121 else if (strcasecmp (name, "nsv") == 0)
4122 {
4123 cmpltr = 6;
4124 }
4125 else if (strcasecmp (name, "ev") == 0)
4126 {
4127 cmpltr = 7;
4128 }
5cf4cd1b 4129 /* If we have something like addb,n then there is no condition
8f78d0e9 4130 completer. */
5cf4cd1b
KR
4131 else if (strcasecmp (name, "n") == 0 && isbranch)
4132 {
4133 cmpltr = 0;
4134 }
4135 else
4136 {
4137 cmpltr = -1;
4138 }
025b0302
ME
4139 **s = c;
4140 }
4141 if (cmpltr >= 0)
4142 {
4143 while (**s == ' ' || **s == '\t')
4144 *s = *s + 1;
4145 }
4146
5cf4cd1b
KR
4147 /* Reset pointers if this was really a ,n for a branch instruction. */
4148 if (cmpltr == 0 && *name == 'n' && isbranch)
4149 *s = save_s;
4150
025b0302
ME
4151 return cmpltr;
4152}
4153
8f78d0e9 4154/* Handle a .BLOCK type pseudo-op. */
025b0302 4155
8f78d0e9 4156static void
025b0302
ME
4157pa_block (z)
4158 int z;
4159{
8f78d0e9
KR
4160 char *p;
4161 long int temp_fill;
4162 unsigned int temp_size;
4163 int i;
025b0302
ME
4164
4165 temp_size = get_absolute_expression ();
4166
8f78d0e9
KR
4167 /* Always fill with zeros, that's what the HP assembler does. */
4168 temp_fill = 0;
025b0302 4169
8f78d0e9
KR
4170 p = frag_var (rs_fill, (int) temp_size, (int) temp_size,
4171 (relax_substateT) 0, (symbolS *) 0, 1, NULL);
4172 bzero (p, temp_size);
025b0302 4173
8f78d0e9 4174 /* Convert 2 bytes at a time. */
025b0302
ME
4175
4176 for (i = 0; i < temp_size; i += 2)
4177 {
4178 md_number_to_chars (p + i,
8f78d0e9 4179 (valueT) temp_fill,
025b0302
ME
4180 (int) ((temp_size - i) > 2 ? 2 : (temp_size - i)));
4181 }
4182
4183 pa_undefine_label ();
4184 demand_empty_rest_of_line ();
4185 return;
4186}
4187
8f78d0e9
KR
4188/* Handle a .CALL pseudo-op. This involves storing away information
4189 about where arguments are to be found so the linker can detect
4190 (and correct) argument location mismatches between caller and callee. */
025b0302 4191
8f78d0e9
KR
4192static void
4193pa_call (unused)
4194 int unused;
4195{
025b0302
ME
4196 pa_call_args (&last_call_desc);
4197 demand_empty_rest_of_line ();
4198 return;
4199}
4200
8f78d0e9
KR
4201/* Do the dirty work of building a call descriptor which describes
4202 where the caller placed arguments to a function call. */
4203
4204static void
025b0302 4205pa_call_args (call_desc)
8f78d0e9 4206 struct call_desc *call_desc;
025b0302 4207{
8f78d0e9
KR
4208 char *name, c, *p;
4209 unsigned int temp, arg_reloc;
025b0302
ME
4210
4211 while (!is_end_of_statement ())
4212 {
4213 name = input_line_pointer;
4214 c = get_symbol_end ();
8f78d0e9 4215 /* Process a source argument. */
025b0302
ME
4216 if ((strncasecmp (name, "argw", 4) == 0))
4217 {
4218 temp = atoi (name + 4);
4219 p = input_line_pointer;
4220 *p = c;
4221 input_line_pointer++;
4222 name = input_line_pointer;
4223 c = get_symbol_end ();
4224 arg_reloc = pa_build_arg_reloc (name);
4225 call_desc->arg_reloc |= pa_align_arg_reloc (temp, arg_reloc);
4226 }
8f78d0e9 4227 /* Process a return value. */
025b0302
ME
4228 else if ((strncasecmp (name, "rtnval", 6) == 0))
4229 {
4230 p = input_line_pointer;
4231 *p = c;
4232 input_line_pointer++;
4233 name = input_line_pointer;
4234 c = get_symbol_end ();
4235 arg_reloc = pa_build_arg_reloc (name);
4236 call_desc->arg_reloc |= (arg_reloc & 0x3);
4237 }
4238 else
4239 {
8f78d0e9 4240 as_bad ("Invalid .CALL argument: %s", name);
025b0302
ME
4241 }
4242 p = input_line_pointer;
4243 *p = c;
4244 if (!is_end_of_statement ())
4245 input_line_pointer++;
4246 }
4247}
4248
8f78d0e9
KR
4249/* Return TRUE if FRAG1 and FRAG2 are the same. */
4250
025b0302 4251static int
8f78d0e9
KR
4252is_same_frag (frag1, frag2)
4253 fragS *frag1;
4254 fragS *frag2;
025b0302
ME
4255{
4256
8f78d0e9 4257 if (frag1 == NULL)
025b0302 4258 return (FALSE);
8f78d0e9 4259 else if (frag2 == NULL)
025b0302 4260 return (FALSE);
8f78d0e9 4261 else if (frag1 == frag2)
025b0302 4262 return (TRUE);
8f78d0e9
KR
4263 else if (frag2->fr_type == rs_fill && frag2->fr_fix == 0)
4264 return (is_same_frag (frag1, frag2->fr_next));
025b0302
ME
4265 else
4266 return (FALSE);
4267}
4268
ff852e11
JL
4269#ifdef OBJ_ELF
4270/* Build an entry in the UNWIND subspace from the given function
4271 attributes in CALL_INFO. This is not needed for SOM as using
4272 R_ENTRY and R_EXIT relocations allow the linker to handle building
4273 of the unwind spaces. */
8f78d0e9 4274
025b0302
ME
4275static void
4276pa_build_unwind_subspace (call_info)
8f78d0e9 4277 struct call_info *call_info;
025b0302 4278{
8f78d0e9
KR
4279 char *unwind;
4280 asection *seg, *save_seg;
025b0302
ME
4281 subsegT subseg, save_subseg;
4282 int i;
8f78d0e9
KR
4283 char c, *p;
4284
4285 /* Get into the right seg/subseg. This may involve creating
4286 the seg the first time through. Make sure to have the
4287 old seg/subseg so that we can reset things when we are done. */
4288 subseg = SUBSEG_UNWIND;
4289 seg = bfd_get_section_by_name (stdoutput, UNWIND_SECTION_NAME);
4290 if (seg == ASEC_NULL)
025b0302 4291 {
8f78d0e9
KR
4292 seg = bfd_make_section_old_way (stdoutput, UNWIND_SECTION_NAME);
4293 bfd_set_section_flags (stdoutput, seg,
4294 SEC_READONLY | SEC_HAS_CONTENTS
4295 | SEC_LOAD | SEC_RELOC);
025b0302
ME
4296 }
4297
025b0302
ME
4298 save_seg = now_seg;
4299 save_subseg = now_subseg;
80aab579 4300 subseg_set (seg, subseg);
025b0302 4301
8f78d0e9
KR
4302
4303 /* Get some space to hold relocation information for the unwind
4304 descriptor. */
025b0302
ME
4305 p = frag_more (4);
4306 call_info->start_offset_frag = frag_now;
4307 call_info->start_frag_where = p - frag_now->fr_literal;
4308
8f78d0e9 4309 /* Relocation info. for start offset of the function. */
8f78d0e9
KR
4310 fix_new_hppa (frag_now, p - frag_now->fr_literal, 4,
4311 call_info->start_symbol, (offsetT) 0,
4312 (expressionS *) NULL, 0, R_HPPA_UNWIND, e_fsel, 32, 0,
4313 (char *) 0);
025b0302 4314
8f78d0e9
KR
4315 /* We need to search for the first relocation involving the start_symbol of
4316 this call_info descriptor. */
025b0302
ME
4317 {
4318 fixS *fixP;
4319
8f78d0e9 4320 call_info->start_fix = seg_info (now_seg)->fix_root;
025b0302
ME
4321 for (fixP = call_info->start_fix; fixP; fixP = fixP->fx_next)
4322 {
8f78d0e9
KR
4323 if (fixP->fx_addsy == call_info->start_symbol
4324 || fixP->fx_subsy == call_info->start_symbol)
025b0302
ME
4325 {
4326 call_info->start_fix = fixP;
4327 break;
4328 }
4329 }
4330 }
4331
4332 p = frag_more (4);
4333 call_info->end_offset_frag = frag_now;
4334 call_info->end_frag_where = p - frag_now->fr_literal;
4335
8f78d0e9 4336 /* Relocation info. for end offset of the function. */
8f78d0e9
KR
4337 fix_new_hppa (frag_now, p - frag_now->fr_literal, 4,
4338 call_info->end_symbol, (offsetT) 0,
4339 (expressionS *) NULL, 0, R_HPPA_UNWIND, e_fsel, 32, 0,
4340 (char *) 0);
025b0302 4341
8f78d0e9
KR
4342 /* We need to search for the first relocation involving the end_symbol of
4343 this call_info descriptor. */
025b0302
ME
4344 {
4345 fixS *fixP;
4346
4347 call_info->end_fix = seg_info (now_seg)->fix_root; /* the default */
4348 for (fixP = call_info->end_fix; fixP; fixP = fixP->fx_next)
4349 {
8f78d0e9
KR
4350 if (fixP->fx_addsy == call_info->end_symbol
4351 || fixP->fx_subsy == call_info->end_symbol)
025b0302
ME
4352 {
4353 call_info->end_fix = fixP;
4354 break;
4355 }
4356 }
4357 }
4358
8f78d0e9
KR
4359 /* Dump it. */
4360 unwind = (char *) &call_info->ci_unwind;
4361 for (i = 8; i < sizeof (struct unwind_table); i++)
025b0302 4362 {
8f78d0e9 4363 c = *(unwind + i);
025b0302
ME
4364 {
4365 FRAG_APPEND_1_CHAR (c);
4366 }
4367 }
4368
8f78d0e9 4369 /* Return back to the original segment/subsegment. */
80aab579 4370 subseg_set (save_seg, save_subseg);
025b0302 4371}
ff852e11 4372#endif
025b0302 4373
8f78d0e9
KR
4374/* Process a .CALLINFO pseudo-op. This information is used later
4375 to build unwind descriptors and maybe one day to support
4376 .ENTER and .LEAVE. */
025b0302 4377
8f78d0e9
KR
4378static void
4379pa_callinfo (unused)
4380 int unused;
025b0302 4381{
8f78d0e9
KR
4382 char *name, c, *p;
4383 int temp;
025b0302 4384
8f78d0e9 4385 /* .CALLINFO must appear within a procedure definition. */
025b0302
ME
4386 if (!within_procedure)
4387 as_bad (".callinfo is not within a procedure definition");
4388
8f78d0e9
KR
4389 /* Mark the fact that we found the .CALLINFO for the
4390 current procedure. */
025b0302
ME
4391 callinfo_found = TRUE;
4392
8f78d0e9 4393 /* Iterate over the .CALLINFO arguments. */
025b0302
ME
4394 while (!is_end_of_statement ())
4395 {
4396 name = input_line_pointer;
4397 c = get_symbol_end ();
8f78d0e9 4398 /* Frame size specification. */
025b0302
ME
4399 if ((strncasecmp (name, "frame", 5) == 0))
4400 {
4401 p = input_line_pointer;
4402 *p = c;
4403 input_line_pointer++;
4404 temp = get_absolute_expression ();
4405 if ((temp & 0x3) != 0)
4406 {
4407 as_bad ("FRAME parameter must be a multiple of 8: %d\n", temp);
4408 temp = 0;
4409 }
49fc68a1
JL
4410
4411 /* callinfo is in bytes and unwind_desc is in 8 byte units. */
4412 last_call_info->ci_unwind.descriptor.frame_size = temp / 8;
4413
025b0302 4414 }
8f78d0e9 4415 /* Entry register (GR, GR and SR) specifications. */
025b0302
ME
4416 else if ((strncasecmp (name, "entry_gr", 8) == 0))
4417 {
4418 p = input_line_pointer;
4419 *p = c;
4420 input_line_pointer++;
4421 temp = get_absolute_expression ();
aa8b30ed
JL
4422 /* The HP assembler accepts 19 as the high bound for ENTRY_GR
4423 even though %r19 is caller saved. I think this is a bug in
4424 the HP assembler, and we are not going to emulate it. */
4425 if (temp < 3 || temp > 18)
4426 as_bad ("Value for ENTRY_GR must be in the range 3..18\n");
4427 last_call_info->ci_unwind.descriptor.entry_gr = temp - 2;
025b0302
ME
4428 }
4429 else if ((strncasecmp (name, "entry_fr", 8) == 0))
4430 {
4431 p = input_line_pointer;
4432 *p = c;
4433 input_line_pointer++;
4434 temp = get_absolute_expression ();
aa8b30ed
JL
4435 /* Similarly the HP assembler takes 31 as the high bound even
4436 though %fr21 is the last callee saved floating point register. */
4437 if (temp < 12 || temp > 21)
4438 as_bad ("Value for ENTRY_FR must be in the range 12..21\n");
4439 last_call_info->ci_unwind.descriptor.entry_fr = temp - 11;
025b0302
ME
4440 }
4441 else if ((strncasecmp (name, "entry_sr", 8) == 0))
4442 {
4443 p = input_line_pointer;
4444 *p = c;
4445 input_line_pointer++;
4446 temp = get_absolute_expression ();
aa8b30ed
JL
4447 if (temp != 3)
4448 as_bad ("Value for ENTRY_SR must be 3\n");
4449 last_call_info->entry_sr = temp - 2;
025b0302 4450 }
8f78d0e9 4451 /* Note whether or not this function performs any calls. */
025b0302
ME
4452 else if ((strncasecmp (name, "calls", 5) == 0) ||
4453 (strncasecmp (name, "caller", 6) == 0))
4454 {
4455 p = input_line_pointer;
4456 *p = c;
4457 last_call_info->makes_calls = 1;
4458 }
4459 else if ((strncasecmp (name, "no_calls", 8) == 0))
4460 {
4461 p = input_line_pointer;
4462 *p = c;
4463 last_call_info->makes_calls = 0;
4464 }
8f78d0e9 4465 /* Should RP be saved into the stack. */
025b0302
ME
4466 else if ((strncasecmp (name, "save_rp", 7) == 0))
4467 {
4468 p = input_line_pointer;
4469 *p = c;
4470 last_call_info->ci_unwind.descriptor.save_rp = 1;
4471 }
8f78d0e9 4472 /* Likewise for SP. */
025b0302
ME
4473 else if ((strncasecmp (name, "save_sp", 7) == 0))
4474 {
4475 p = input_line_pointer;
4476 *p = c;
4477 last_call_info->ci_unwind.descriptor.save_sp = 1;
4478 }
8f78d0e9
KR
4479 /* Is this an unwindable procedure. If so mark it so
4480 in the unwind descriptor. */
025b0302
ME
4481 else if ((strncasecmp (name, "no_unwind", 9) == 0))
4482 {
4483 p = input_line_pointer;
4484 *p = c;
4485 last_call_info->ci_unwind.descriptor.cannot_unwind = 1;
4486 }
8f78d0e9
KR
4487 /* Is this an interrupt routine. If so mark it in the
4488 unwind descriptor. */
025b0302
ME
4489 else if ((strncasecmp (name, "hpux_int", 7) == 0))
4490 {
4491 p = input_line_pointer;
4492 *p = c;
8f78d0e9 4493 last_call_info->ci_unwind.descriptor.hpux_interrupt_marker = 1;
025b0302
ME
4494 }
4495 else
4496 {
8f78d0e9 4497 as_bad ("Invalid .CALLINFO argument: %s", name);
025b0302
ME
4498 }
4499 if (!is_end_of_statement ())
4500 input_line_pointer++;
4501 }
4502
4503 demand_empty_rest_of_line ();
4504 return;
4505}
4506
8f78d0e9
KR
4507/* Switch into the code subspace. */
4508
4509static void
4510pa_code (unused)
4511 int unused;
025b0302 4512{
8f78d0e9 4513 sd_chain_struct *sdchain;
025b0302 4514
8f78d0e9
KR
4515 /* First time through it might be necessary to create the
4516 $TEXT$ space. */
025b0302
ME
4517 if ((sdchain = is_defined_space ("$TEXT$")) == NULL)
4518 {
8f78d0e9
KR
4519 sdchain = create_new_space (pa_def_spaces[0].name,
4520 pa_def_spaces[0].spnum,
4521 pa_def_spaces[0].loadable,
4522 pa_def_spaces[0].defined,
4523 pa_def_spaces[0].private,
4524 pa_def_spaces[0].sort,
4525 pa_def_spaces[0].segment, 0);
025b0302
ME
4526 }
4527
4528 SPACE_DEFINED (sdchain) = 1;
80aab579 4529 subseg_set (text_section, SUBSEG_CODE);
025b0302
ME
4530 demand_empty_rest_of_line ();
4531 return;
4532}
4533
8f78d0e9
KR
4534/* This is different than the standard GAS s_comm(). On HP9000/800 machines,
4535 the .comm pseudo-op has the following symtax:
025b0302 4536
8f78d0e9
KR
4537 <label> .comm <length>
4538
4539 where <label> is optional and is a symbol whose address will be the start of
4540 a block of memory <length> bytes long. <length> must be an absolute
4541 expression. <length> bytes will be allocated in the current space
4542 and subspace. */
4543
4544static void
4545pa_comm (unused)
4546 int unused;
025b0302 4547{
8f78d0e9
KR
4548 unsigned int size;
4549 symbolS *symbol;
4550 label_symbol_struct *label_symbol = pa_get_label ();
025b0302 4551
8f78d0e9
KR
4552 if (label_symbol)
4553 symbol = label_symbol->lss_label;
025b0302 4554 else
8f78d0e9 4555 symbol = NULL;
025b0302
ME
4556
4557 SKIP_WHITESPACE ();
8f78d0e9 4558 size = get_absolute_expression ();
025b0302 4559
8f78d0e9 4560 if (symbol)
025b0302 4561 {
d56f45f5
JL
4562 /* It is incorrect to check S_IS_DEFINED at this point as
4563 the symbol will *always* be defined. FIXME. How to
4564 correctly determine when this label really as been
4565 defined before. */
8f78d0e9 4566 if (S_GET_VALUE (symbol))
025b0302 4567 {
8f78d0e9 4568 if (S_GET_VALUE (symbol) != size)
025b0302 4569 {
8f78d0e9
KR
4570 as_warn ("Length of .comm \"%s\" is already %d. Not changed.",
4571 S_GET_NAME (symbol), S_GET_VALUE (symbol));
025b0302
ME
4572 return;
4573 }
4574 }
4575 else
4576 {
8f78d0e9 4577 S_SET_VALUE (symbol, size);
aa8b30ed 4578 S_SET_SEGMENT (symbol, &bfd_und_section);
8f78d0e9 4579 S_SET_EXTERNAL (symbol);
025b0302 4580 }
025b0302 4581 }
025b0302
ME
4582 demand_empty_rest_of_line ();
4583}
4584
8f78d0e9
KR
4585/* Process a .COPYRIGHT pseudo-op. */
4586
4587static void
4588pa_copyright (unused)
4589 int unused;
025b0302 4590{
8f78d0e9
KR
4591 char *name;
4592 char c;
025b0302
ME
4593
4594 SKIP_WHITESPACE ();
4595 if (*input_line_pointer == '\"')
4596 {
8f78d0e9 4597 ++input_line_pointer;
025b0302
ME
4598 name = input_line_pointer;
4599 while ((c = next_char_of_string ()) >= 0)
4600 ;
4601 c = *input_line_pointer;
4602 *input_line_pointer = '\0';
4603 *(input_line_pointer - 1) = '\0';
4604 {
8f78d0e9
KR
4605 /* FIXME. Not supported */
4606 abort ();
025b0302
ME
4607 }
4608 *input_line_pointer = c;
4609 }
4610 else
4611 {
4612 as_bad ("Expected \"-ed string");
4613 }
4614 pa_undefine_label ();
4615 demand_empty_rest_of_line ();
4616}
4617
8f78d0e9 4618/* Process a .END pseudo-op. */
025b0302 4619
8f78d0e9
KR
4620static void
4621pa_end (unused)
4622 int unused;
4623{
025b0302
ME
4624 demand_empty_rest_of_line ();
4625 return;
4626}
4627
8f78d0e9
KR
4628/* Process a .ENTER pseudo-op. This is not supported. */
4629static void
4630pa_enter (unused)
4631 int unused;
025b0302 4632{
8f78d0e9 4633 abort();
025b0302
ME
4634 return;
4635}
4636
8f78d0e9
KR
4637/* Process a .ENTRY pseudo-op. .ENTRY marks the beginning of the
4638 procesure. */
4639static void
4640pa_entry (unused)
4641 int unused;
025b0302 4642{
025b0302
ME
4643 if (!within_procedure)
4644 as_bad ("Misplaced .entry. Ignored.");
4645 else
4646 {
4647 if (!callinfo_found)
4648 as_bad ("Missing .callinfo.");
4649
4650 last_call_info->start_frag = frag_now;
4651 }
4652 demand_empty_rest_of_line ();
4653 within_entry_exit = TRUE;
8f78d0e9
KR
4654
4655 /* Go back to the last symbol and turn on the BSF_FUNCTION flag.
4656 It will not be on if no .EXPORT pseudo-op exists (static function). */
4657 last_call_info->start_symbol->bsym->flags |= BSF_FUNCTION;
4658
ff852e11
JL
4659#ifdef OBJ_SOM
4660 /* SOM defers building of unwind descriptors until the link phase.
4661 The assembler is responsible for creating an R_ENTRY relocation
4662 to mark the beginning of a region and hold the unwind bits, and
4663 for creating an R_EXIT relocation to mark the end of the region.
4664
4665 FIXME. ELF should be using the same conventions! The problem
4666 is an unwind requires too much relocation space. Hmmm. Maybe
4667 if we split the unwind bits up between the relocations which
4668 denote the entry and exit points. */
4669 {
4670 char *where = frag_more (0);
4671
4672 fix_new_hppa (frag_now, where - frag_now->fr_literal, 0,
4673 last_call_info->start_symbol, (offsetT) 0, NULL,
4674 0, R_HPPA_ENTRY, e_fsel, 0, 0,
4675 &last_call_info->ci_unwind.descriptor);
4676 }
4677#endif
4678
025b0302
ME
4679 return;
4680}
4681
8f78d0e9
KR
4682/* Handle a .EQU pseudo-op. */
4683
4684static void
025b0302
ME
4685pa_equ (reg)
4686 int reg;
4687{
8f78d0e9
KR
4688 label_symbol_struct *label_symbol = pa_get_label ();
4689 symbolS *symbol;
025b0302 4690
8f78d0e9 4691 if (label_symbol)
025b0302 4692 {
8f78d0e9
KR
4693 symbol = label_symbol->lss_label;
4694 S_SET_VALUE (symbol, (unsigned int) get_absolute_expression ());
4695 S_SET_SEGMENT (symbol, &bfd_abs_section);
025b0302
ME
4696 }
4697 else
4698 {
4699 if (reg)
4700 as_bad (".REG must use a label");
4701 else
4702 as_bad (".EQU must use a label");
4703 }
4704
4705 pa_undefine_label ();
4706 demand_empty_rest_of_line ();
4707 return;
4708}
4709
8f78d0e9
KR
4710/* Helper function. Does processing for the end of a function. This
4711 usually involves creating some relocations or building special
4712 symbols to mark the end of the function. */
4713
4714static void
025b0302
ME
4715process_exit ()
4716{
4717 char *where;
4718
4719 where = frag_more (0);
aa8b30ed 4720
ff852e11 4721#ifdef OBJ_ELF
8f78d0e9
KR
4722 /* ELF does not have EXIT relocations. All we do is create a
4723 temporary symbol marking the end of the function. */
025b0302 4724 {
a50e9b55 4725 char *name = (char *) xmalloc (strlen ("L$\001end_") +
025b0302
ME
4726 strlen (S_GET_NAME (last_call_info->start_symbol)) + 1);
4727
4728 if (name)
4729 {
4730 symbolS *symbolP;
4731
a50e9b55 4732 strcpy (name, "L$\001end_");
025b0302
ME
4733 strcat (name, S_GET_NAME (last_call_info->start_symbol));
4734
4735 symbolP = symbol_find (name);
4736 if (symbolP)
4737 as_warn ("Symbol '%s' already defined.", name);
4738 else
4739 {
8f78d0e9
KR
4740 /* symbol value should be the offset of the
4741 last instruction of the function */
4742 symbolP = symbol_new (name, now_seg,
4743 (valueT) (obstack_next_free (&frags)
4744 - frag_now->fr_literal - 4),
025b0302
ME
4745 frag_now);
4746
4747 assert (symbolP);
5cf4cd1b 4748 symbolP->bsym->flags = BSF_LOCAL;
025b0302
ME
4749 symbol_table_insert (symbolP);
4750 }
4751 if (symbolP)
4752 last_call_info->end_symbol = symbolP;
4753 else
4754 as_bad ("Symbol '%s' could not be created.", name);
4755
4756 }
4757 else
4758 as_bad ("No memory for symbol name.");
4759 }
025b0302 4760
8f78d0e9
KR
4761 /* Stuff away the location of the frag for the end of the function,
4762 and call pa_build_unwind_subspace to add an entry in the unwind
4763 table. */
4764 last_call_info->end_frag = frag_now;
025b0302 4765 pa_build_unwind_subspace (last_call_info);
ff852e11
JL
4766#else
4767 /* SOM defers building of unwind descriptors until the link phase.
4768 The assembler is responsible for creating an R_ENTRY relocation
4769 to mark the beginning of a region and hold the unwind bits, and
4770 for creating an R_EXIT relocation to mark the end of the region.
4771
4772 FIXME. ELF should be using the same conventions! The problem
4773 is an unwind requires too much relocation space. Hmmm. Maybe
4774 if we split the unwind bits up between the relocations which
4775 denote the entry and exit points. */
4776 fix_new_hppa (frag_now, where - frag_now->fr_literal, 0,
4777 last_call_info->start_symbol, (offsetT) 0,
4778 NULL, 0, R_HPPA_EXIT, e_fsel, 0, 0, NULL);
4779#endif
4780
025b0302
ME
4781 exit_processing_complete = TRUE;
4782}
4783
8f78d0e9 4784/* Process a .EXIT pseudo-op. */
025b0302 4785
8f78d0e9
KR
4786static void
4787pa_exit (unused)
4788 int unused;
4789{
025b0302
ME
4790 if (!within_procedure)
4791 as_bad (".EXIT must appear within a procedure");
4792 else
4793 {
4794 if (!callinfo_found)
4795 as_bad ("Missing .callinfo");
4796 else
4797 {
4798 if (!within_entry_exit)
4799 as_bad ("No .ENTRY for this .EXIT");
4800 else
4801 {
4802 within_entry_exit = FALSE;
4803 process_exit ();
4804 }
4805 }
4806 }
4807 demand_empty_rest_of_line ();
4808 return;
4809}
4810
8f78d0e9
KR
4811/* Process a .EXPORT directive. This makes functions external
4812 and provides information such as argument relocation entries
4813 to callers. */
5cf4cd1b 4814
8f78d0e9
KR
4815static void
4816pa_export (unused)
4817 int unused;
025b0302 4818{
8f78d0e9
KR
4819 char *name, c, *p;
4820 symbolS *symbol;
025b0302
ME
4821
4822 name = input_line_pointer;
4823 c = get_symbol_end ();
8f78d0e9
KR
4824 /* Make sure the given symbol exists. */
4825 if ((symbol = symbol_find_or_make (name)) == NULL)
025b0302
ME
4826 {
4827 as_bad ("Cannot define export symbol: %s\n", name);
4828 p = input_line_pointer;
4829 *p = c;
4830 input_line_pointer++;
4831 }
4832 else
4833 {
8f78d0e9
KR
4834 /* OK. Set the external bits and process argument relocations. */
4835 S_SET_EXTERNAL (symbol);
025b0302
ME
4836 p = input_line_pointer;
4837 *p = c;
4838 if (!is_end_of_statement ())
4839 {
4840 input_line_pointer++;
8f78d0e9 4841 pa_export_args (symbol);
5cf4cd1b 4842#ifdef OBJ_ELF
8f78d0e9 4843 pa_build_symextn_section ();
5cf4cd1b 4844#endif
025b0302
ME
4845 }
4846 }
4847
4848 demand_empty_rest_of_line ();
4849 return;
4850}
4851
8f78d0e9
KR
4852/* Helper function to process arguments to a .EXPORT pseudo-op. */
4853
4854static void
025b0302 4855pa_export_args (symbolP)
8f78d0e9 4856 symbolS *symbolP;
025b0302 4857{
8f78d0e9
KR
4858 char *name, c, *p;
4859 unsigned int temp, arg_reloc;
e75acd68 4860 pa_symbol_type type = SYMBOL_TYPE_UNKNOWN;
8f78d0e9 4861 obj_symbol_type *symbol = (obj_symbol_type *) symbolP->bsym;
025b0302
ME
4862
4863 if (strncasecmp (input_line_pointer, "absolute", 8) == 0)
4864 {
4865 input_line_pointer += 8;
9a182533 4866 symbolP->bsym->flags &= ~BSF_FUNCTION;
025b0302 4867 S_SET_SEGMENT (symbolP, &bfd_abs_section);
e75acd68 4868 type = SYMBOL_TYPE_ABSOLUTE;
025b0302
ME
4869 }
4870 else if (strncasecmp (input_line_pointer, "code", 4) == 0)
9a182533
JL
4871 {
4872 input_line_pointer += 4;
4873 symbolP->bsym->flags &= ~BSF_FUNCTION;
e75acd68 4874 type = SYMBOL_TYPE_CODE;
9a182533 4875 }
025b0302 4876 else if (strncasecmp (input_line_pointer, "data", 4) == 0)
9a182533
JL
4877 {
4878 input_line_pointer += 4;
4879 symbolP->bsym->flags &= ~BSF_FUNCTION;
e75acd68 4880 type = SYMBOL_TYPE_DATA;
9a182533 4881 }
025b0302
ME
4882 else if ((strncasecmp (input_line_pointer, "entry", 5) == 0))
4883 {
4884 input_line_pointer += 5;
025b0302 4885 symbolP->bsym->flags |= BSF_FUNCTION;
e75acd68 4886 type = SYMBOL_TYPE_ENTRY;
025b0302
ME
4887 }
4888 else if (strncasecmp (input_line_pointer, "millicode", 9) == 0)
4889 {
4890 input_line_pointer += 9;
9a182533 4891 symbolP->bsym->flags |= BSF_FUNCTION;
e75acd68 4892 type = SYMBOL_TYPE_MILLICODE;
025b0302
ME
4893 }
4894 else if (strncasecmp (input_line_pointer, "plabel", 6) == 0)
4895 {
4896 input_line_pointer += 6;
9a182533 4897 symbolP->bsym->flags &= ~BSF_FUNCTION;
e75acd68 4898 type = SYMBOL_TYPE_PLABEL;
025b0302
ME
4899 }
4900 else if (strncasecmp (input_line_pointer, "pri_prog", 8) == 0)
4901 {
4902 input_line_pointer += 8;
9a182533 4903 symbolP->bsym->flags |= BSF_FUNCTION;
e75acd68 4904 type = SYMBOL_TYPE_PRI_PROG;
025b0302
ME
4905 }
4906 else if (strncasecmp (input_line_pointer, "sec_prog", 8) == 0)
4907 {
4908 input_line_pointer += 8;
9a182533 4909 symbolP->bsym->flags |= BSF_FUNCTION;
e75acd68 4910 type = SYMBOL_TYPE_SEC_PROG;
025b0302
ME
4911 }
4912
e75acd68
JL
4913 /* SOM requires much more information about symbol types
4914 than BFD understands. This is how we get this information
4915 to the SOM BFD backend. */
4916#ifdef obj_set_symbol_type
4917 obj_set_symbol_type (symbolP->bsym, (int) type);
4918#endif
4919
8f78d0e9
KR
4920 /* Now that the type of the exported symbol has been handled,
4921 handle any argument relocation information. */
025b0302
ME
4922 while (!is_end_of_statement ())
4923 {
4924 if (*input_line_pointer == ',')
4925 input_line_pointer++;
4926 name = input_line_pointer;
4927 c = get_symbol_end ();
8f78d0e9 4928 /* Argument sources. */
025b0302
ME
4929 if ((strncasecmp (name, "argw", 4) == 0))
4930 {
4931 p = input_line_pointer;
4932 *p = c;
4933 input_line_pointer++;
4934 temp = atoi (name + 4);
4935 name = input_line_pointer;
4936 c = get_symbol_end ();
4937 arg_reloc = pa_align_arg_reloc (temp, pa_build_arg_reloc (name));
8f78d0e9 4938 symbol->tc_data.hppa_arg_reloc |= arg_reloc;
025b0302
ME
4939 *input_line_pointer = c;
4940 }
8f78d0e9 4941 /* The return value. */
025b0302
ME
4942 else if ((strncasecmp (name, "rtnval", 6)) == 0)
4943 {
4944 p = input_line_pointer;
4945 *p = c;
4946 input_line_pointer++;
4947 name = input_line_pointer;
4948 c = get_symbol_end ();
4949 arg_reloc = pa_build_arg_reloc (name);
8f78d0e9 4950 symbol->tc_data.hppa_arg_reloc |= arg_reloc;
025b0302
ME
4951 *input_line_pointer = c;
4952 }
8f78d0e9 4953 /* Privelege level. */
025b0302
ME
4954 else if ((strncasecmp (name, "priv_lev", 8)) == 0)
4955 {
4956 p = input_line_pointer;
4957 *p = c;
4958 input_line_pointer++;
025b0302
ME
4959 temp = atoi (input_line_pointer);
4960 c = get_symbol_end ();
4961 *input_line_pointer = c;
025b0302
ME
4962 }
4963 else
4964 {
4965 as_bad ("Undefined .EXPORT/.IMPORT argument (ignored): %s", name);
4966 p = input_line_pointer;
4967 *p = c;
4968 }
4969 if (!is_end_of_statement ())
4970 input_line_pointer++;
4971 }
4972}
4973
8f78d0e9
KR
4974/* Handle an .IMPORT pseudo-op. Any symbol referenced in a given
4975 assembly file must either be defined in the assembly file, or
4976 explicitly IMPORTED from another. */
4977
4978static void
4979pa_import (unused)
4980 int unused;
025b0302 4981{
8f78d0e9
KR
4982 char *name, c, *p;
4983 symbolS *symbol;
025b0302
ME
4984
4985 name = input_line_pointer;
4986 c = get_symbol_end ();
025b0302 4987
8f78d0e9 4988 symbol = symbol_find_or_make (name);
025b0302
ME
4989 p = input_line_pointer;
4990 *p = c;
4991
4992 if (!is_end_of_statement ())
4993 {
4994 input_line_pointer++;
8f78d0e9 4995 pa_export_args (symbol);
025b0302
ME
4996 }
4997 else
4998 {
47f45d66
JL
4999 /* Sigh. To be compatable with the HP assembler and to help
5000 poorly written assembly code, we assign a type based on
5001 the the current segment. Note only BSF_FUNCTION really
5002 matters, we do not need to set the full SYMBOL_TYPE_* info here. */
5003 if (now_seg == text_section)
5004 symbol->bsym->flags |= BSF_FUNCTION;
5005
8f78d0e9
KR
5006 /* If the section is undefined, then the symbol is undefined
5007 Since this is an import, leave the section undefined. */
5008 S_SET_SEGMENT (symbol, &bfd_und_section);
025b0302
ME
5009 }
5010
025b0302
ME
5011 demand_empty_rest_of_line ();
5012 return;
5013}
5014
8f78d0e9
KR
5015/* Handle a .LABEL pseudo-op. */
5016
5017static void
5018pa_label (unused)
5019 int unused;
025b0302 5020{
8f78d0e9 5021 char *name, c, *p;
025b0302
ME
5022
5023 name = input_line_pointer;
5024 c = get_symbol_end ();
025b0302
ME
5025
5026 if (strlen (name) > 0)
5027 {
5028 colon (name);
5029 p = input_line_pointer;
5030 *p = c;
5031 }
5032 else
5033 {
5034 as_warn ("Missing label name on .LABEL");
5035 }
5036
5037 if (!is_end_of_statement ())
5038 {
5039 as_warn ("extra .LABEL arguments ignored.");
5040 ignore_rest_of_line ();
5041 }
5042 demand_empty_rest_of_line ();
5043 return;
5044}
5045
8f78d0e9 5046/* Handle a .LEAVE pseudo-op. This is not supported yet. */
025b0302 5047
8f78d0e9
KR
5048static void
5049pa_leave (unused)
5050 int unused;
5051{
5052 abort();
025b0302
ME
5053}
5054
8f78d0e9
KR
5055/* Handle a .ORIGIN pseudo-op. */
5056
5057static void
5058pa_origin (unused)
5059 int unused;
025b0302 5060{
8f78d0e9 5061 s_org (0);
025b0302
ME
5062 pa_undefine_label ();
5063 return;
5064}
5065
8f78d0e9
KR
5066/* Handle a .PARAM pseudo-op. This is much like a .EXPORT, except it
5067 is for static functions. FIXME. Should share more code with .EXPORT. */
5cf4cd1b 5068
8f78d0e9
KR
5069static void
5070pa_param (unused)
5071 int unused;
5cf4cd1b 5072{
8f78d0e9
KR
5073 char *name, c, *p;
5074 symbolS *symbol;
5cf4cd1b
KR
5075
5076 name = input_line_pointer;
5077 c = get_symbol_end ();
5cf4cd1b 5078
8f78d0e9 5079 if ((symbol = symbol_find_or_make (name)) == NULL)
5cf4cd1b
KR
5080 {
5081 as_bad ("Cannot define static symbol: %s\n", name);
5082 p = input_line_pointer;
5083 *p = c;
5084 input_line_pointer++;
5085 }
5086 else
5087 {
8f78d0e9 5088 S_CLEAR_EXTERNAL (symbol);
5cf4cd1b
KR
5089 p = input_line_pointer;
5090 *p = c;
5091 if (!is_end_of_statement ())
5092 {
5093 input_line_pointer++;
8f78d0e9 5094 pa_export_args (symbol);
5cf4cd1b
KR
5095 }
5096 }
5097
5098 demand_empty_rest_of_line ();
5099 return;
5100}
5101
8f78d0e9
KR
5102/* Handle a .PROC pseudo-op. It is used to mark the beginning
5103 of a procedure from a syntatical point of view. */
5104
5105static void
5106pa_proc (unused)
5107 int unused;
025b0302 5108{
8f78d0e9 5109 struct call_info *call_info;
025b0302
ME
5110
5111 if (within_procedure)
5112 as_fatal ("Nested procedures");
5113
8f78d0e9 5114 /* Reset global variables for new procedure. */
025b0302
ME
5115 callinfo_found = FALSE;
5116 within_procedure = TRUE;
5117 exit_processing_complete = FALSE;
5118
8f78d0e9
KR
5119 /* Create another call_info structure. */
5120 call_info = (struct call_info *) xmalloc (sizeof (struct call_info));
025b0302
ME
5121
5122 if (!call_info)
5123 as_fatal ("Cannot allocate unwind descriptor\n");
5124
8f78d0e9 5125 bzero (call_info, sizeof (struct call_info));
025b0302
ME
5126
5127 call_info->ci_next = NULL;
5128
5129 if (call_info_root == NULL)
5130 {
5131 call_info_root = call_info;
5132 last_call_info = call_info;
5133 }
5134 else
5135 {
5136 last_call_info->ci_next = call_info;
5137 last_call_info = call_info;
5138 }
5139
5140 /* set up defaults on call_info structure */
5141
5142 call_info->ci_unwind.descriptor.cannot_unwind = 0;
5143 call_info->ci_unwind.descriptor.region_desc = 1;
8f78d0e9 5144 call_info->ci_unwind.descriptor.hpux_interrupt_marker = 0;
025b0302
ME
5145 call_info->entry_sr = ~0;
5146 call_info->makes_calls = 1;
025b0302
ME
5147
5148 /* If we got a .PROC pseudo-op, we know that the function is defined
8f78d0e9 5149 locally. Make sure it gets into the symbol table. */
025b0302 5150 {
8f78d0e9 5151 label_symbol_struct *label_symbol = pa_get_label ();
025b0302 5152
8f78d0e9 5153 if (label_symbol)
025b0302 5154 {
8f78d0e9 5155 if (label_symbol->lss_label)
025b0302 5156 {
8f78d0e9
KR
5157 last_call_info->start_symbol = label_symbol->lss_label;
5158 label_symbol->lss_label->bsym->flags |= BSF_FUNCTION;
025b0302
ME
5159 }
5160 else
5161 as_bad ("Missing function name for .PROC (corrupted label)");
5162 }
5163 else
5164 as_bad ("Missing function name for .PROC");
5165 }
5166
5167 demand_empty_rest_of_line ();
5168 return;
5169}
5170
8f78d0e9
KR
5171/* Process the syntatical end of a procedure. Make sure all the
5172 appropriate pseudo-ops were found within the procedure. */
5173
5174static void
5175pa_procend (unused)
5176 int unused;
025b0302
ME
5177{
5178
5179 if (!within_procedure)
5180 as_bad ("misplaced .procend");
5181
5182 if (!callinfo_found)
5183 as_bad ("Missing .callinfo for this procedure");
5184
5185 if (within_entry_exit)
5186 as_bad ("Missing .EXIT for a .ENTRY");
5187
5188 if (!exit_processing_complete)
5189 process_exit ();
5190
5191 within_procedure = FALSE;
5192 demand_empty_rest_of_line ();
5193 return;
5194}
5195
8f78d0e9
KR
5196/* Parse the parameters to a .SPACE directive; if CREATE_FLAG is nonzero,
5197 then create a new space entry to hold the information specified
5198 by the parameters to the .SPACE directive. */
5199
5200static sd_chain_struct *
025b0302
ME
5201pa_parse_space_stmt (space_name, create_flag)
5202 char *space_name;
5203 int create_flag;
5204{
8f78d0e9
KR
5205 char *name, *ptemp, c;
5206 char loadable, defined, private, sort;
025b0302 5207 int spnum;
3b9a72c5 5208 asection *seg = NULL;
8f78d0e9 5209 sd_chain_struct *space;
025b0302
ME
5210
5211 /* load default values */
5212 spnum = 0;
3b9a72c5 5213 sort = 0;
025b0302
ME
5214 loadable = TRUE;
5215 defined = TRUE;
5216 private = FALSE;
5217 if (strcasecmp (space_name, "$TEXT$") == 0)
5218 {
0f3b419c
JL
5219 seg = pa_def_spaces[0].segment;
5220 sort = pa_def_spaces[0].sort;
025b0302 5221 }
0f3b419c 5222 else if (strcasecmp (space_name, "$PRIVATE$") == 0)
025b0302 5223 {
0f3b419c
JL
5224 seg = pa_def_spaces[1].segment;
5225 sort = pa_def_spaces[1].sort;
025b0302
ME
5226 }
5227
5228 if (!is_end_of_statement ())
5229 {
5230 print_errors = FALSE;
5231 ptemp = input_line_pointer + 1;
8f78d0e9
KR
5232 /* First see if the space was specified as a number rather than
5233 as a name. According to the PA assembly manual the rest of
5234 the line should be ignored. */
5235 if ((spnum = pa_parse_number (&ptemp, 0)) >= 0)
5236 input_line_pointer = ptemp;
025b0302
ME
5237 else
5238 {
5239 while (!is_end_of_statement ())
5240 {
5241 input_line_pointer++;
5242 name = input_line_pointer;
5243 c = get_symbol_end ();
5244 if ((strncasecmp (name, "SPNUM", 5) == 0))
5245 {
8f78d0e9 5246 *input_line_pointer = c;
025b0302 5247 input_line_pointer++;
8f78d0e9 5248 spnum = get_absolute_expression ();
025b0302
ME
5249 }
5250 else if ((strncasecmp (name, "SORT", 4) == 0))
5251 {
8f78d0e9 5252 *input_line_pointer = c;
025b0302 5253 input_line_pointer++;
8f78d0e9 5254 sort = get_absolute_expression ();
025b0302
ME
5255 }
5256 else if ((strncasecmp (name, "UNLOADABLE", 10) == 0))
5257 {
8f78d0e9 5258 *input_line_pointer = c;
025b0302
ME
5259 loadable = FALSE;
5260 }
5261 else if ((strncasecmp (name, "NOTDEFINED", 10) == 0))
5262 {
8f78d0e9 5263 *input_line_pointer = c;
025b0302
ME
5264 defined = FALSE;
5265 }
5266 else if ((strncasecmp (name, "PRIVATE", 7) == 0))
5267 {
8f78d0e9 5268 *input_line_pointer = c;
025b0302
ME
5269 private = TRUE;
5270 }
5271 else
3515a504
JL
5272 {
5273 as_bad ("Invalid .SPACE argument");
5274 *input_line_pointer = c;
5275 if (! is_end_of_statement ())
5276 input_line_pointer++;
5277 }
025b0302
ME
5278 }
5279 }
5280 print_errors = TRUE;
5281 }
8f78d0e9 5282
3b9a72c5
JL
5283 if (create_flag && seg == NULL)
5284 seg = subseg_new (space_name, 0);
5285
8f78d0e9
KR
5286 /* If create_flag is nonzero, then create the new space with
5287 the attributes computed above. Else set the values in
5288 an already existing space -- this can only happen for
5289 the first occurence of a built-in space. */
025b0302 5290 if (create_flag)
8f78d0e9
KR
5291 space = create_new_space (space_name, spnum, loadable, defined,
5292 private, sort, seg, 1);
025b0302 5293 else
8f78d0e9 5294 {
025b0302
ME
5295 space = is_defined_space (space_name);
5296 SPACE_SPNUM (space) = spnum;
5297 SPACE_LOADABLE (space) = loadable & 1;
5298 SPACE_DEFINED (space) = defined & 1;
8f78d0e9 5299 SPACE_USER_DEFINED (space) = 1;
025b0302
ME
5300 SPACE_PRIVATE (space) = private & 1;
5301 SPACE_SORT (space) = sort & 0xff;
025b0302
ME
5302 space->sd_seg = seg;
5303 }
548ea75b
JL
5304
5305#ifdef obj_set_section_attributes
5306 obj_set_section_attributes (seg, defined, private, sort, spnum);
5307#endif
5308
025b0302
ME
5309 return space;
5310}
5311
8f78d0e9
KR
5312/* Adjust the frag's alignment according to the alignment needs
5313 of the given subspace/subsegment. */
5314
5315static void
025b0302 5316pa_align_subseg (seg, subseg)
8f78d0e9 5317 asection *seg;
025b0302
ME
5318 subsegT subseg;
5319{
8f78d0e9 5320 ssd_chain_struct *now_subspace;
025b0302 5321 int alignment;
8f78d0e9 5322 int shift = 0;
025b0302
ME
5323
5324 now_subspace = pa_subsegment_to_subspace (seg, subseg);
8f78d0e9
KR
5325 if (now_subspace)
5326 {
5327 if (SUBSPACE_ALIGN (now_subspace) == 0)
5328 alignment = now_subspace->ssd_last_align;
5329 else if (now_subspace->ssd_last_align > SUBSPACE_ALIGN (now_subspace))
5330 alignment = now_subspace->ssd_last_align;
5331 else
5332 alignment = SUBSPACE_ALIGN (now_subspace);
5333
5334 while ((1 << shift) < alignment)
5335 shift++;
5336 }
025b0302 5337 else
8f78d0e9 5338 shift = bfd_get_section_alignment (stdoutput, seg);
025b0302
ME
5339
5340 frag_align (shift, 0);
5341}
5342
8f78d0e9
KR
5343/* Handle a .SPACE pseudo-op; this switches the current space to the
5344 given space, creating the new space if necessary. */
5345
5346static void
5347pa_space (unused)
5348 int unused;
025b0302 5349{
aa8b30ed 5350 char *name, c, *space_name, *save_s;
8f78d0e9
KR
5351 int temp;
5352 sd_chain_struct *sd_chain;
025b0302
ME
5353
5354 if (within_procedure)
5355 {
5356 as_bad ("Can\'t change spaces within a procedure definition. Ignored");
5357 ignore_rest_of_line ();
5358 }
5359 else
5360 {
8f78d0e9
KR
5361 /* Check for some of the predefined spaces. FIXME: most of the code
5362 below is repeated several times, can we extract the common parts
5363 and place them into a subroutine or something similar? */
025b0302
ME
5364 if (strncasecmp (input_line_pointer, "$text$", 6) == 0)
5365 {
5366 input_line_pointer += 6;
5367 sd_chain = is_defined_space ("$TEXT$");
5368 if (sd_chain == NULL)
5369 sd_chain = pa_parse_space_stmt ("$TEXT$", 1);
8f78d0e9 5370 else if (SPACE_USER_DEFINED (sd_chain) == 0)
025b0302
ME
5371 sd_chain = pa_parse_space_stmt ("$TEXT$", 0);
5372
5373 current_space = sd_chain;
8f78d0e9
KR
5374
5375 /* No need to align if we are already there. */
5376 if (now_seg != text_section)
025b0302
ME
5377 pa_align_subseg (now_seg, now_subseg);
5378
80aab579 5379 subseg_set (text_section, sd_chain->sd_last_subseg);
8f78d0e9
KR
5380
5381 current_subspace
5382 = pa_subsegment_to_subspace (text_section,
5383 sd_chain->sd_last_subseg);
025b0302
ME
5384 demand_empty_rest_of_line ();
5385 return;
5386 }
5387 if (strncasecmp (input_line_pointer, "$private$", 9) == 0)
5388 {
5389 input_line_pointer += 9;
5390 sd_chain = is_defined_space ("$PRIVATE$");
5391 if (sd_chain == NULL)
5392 sd_chain = pa_parse_space_stmt ("$PRIVATE$", 1);
8f78d0e9 5393 else if (SPACE_USER_DEFINED (sd_chain) == 0)
025b0302
ME
5394 sd_chain = pa_parse_space_stmt ("$PRIVATE$", 0);
5395
5396 current_space = sd_chain;
8f78d0e9
KR
5397
5398 /* No need to align if we are already there. */
5399 if (now_seg != data_section)
025b0302 5400 pa_align_subseg (now_seg, now_subseg);
8f78d0e9 5401
80aab579 5402 subseg_set (data_section, sd_chain->sd_last_subseg);
8f78d0e9
KR
5403 current_subspace
5404 = pa_subsegment_to_subspace (data_section,
5405 sd_chain->sd_last_subseg);
025b0302
ME
5406 demand_empty_rest_of_line ();
5407 return;
5408 }
8f78d0e9
KR
5409 if (!strncasecmp (input_line_pointer,
5410 GDB_DEBUG_SPACE_NAME,
5411 strlen (GDB_DEBUG_SPACE_NAME)))
025b0302
ME
5412 {
5413 input_line_pointer += strlen (GDB_DEBUG_SPACE_NAME);
5414 sd_chain = is_defined_space (GDB_DEBUG_SPACE_NAME);
5415 if (sd_chain == NULL)
5416 sd_chain = pa_parse_space_stmt (GDB_DEBUG_SPACE_NAME, 1);
8f78d0e9 5417 else if (SPACE_USER_DEFINED (sd_chain) == 0)
025b0302
ME
5418 sd_chain = pa_parse_space_stmt (GDB_DEBUG_SPACE_NAME, 0);
5419
5420 current_space = sd_chain;
80aab579 5421
5cf4cd1b 5422 {
8f78d0e9
KR
5423 asection *gdb_section
5424 = bfd_make_section_old_way (stdoutput, GDB_DEBUG_SPACE_NAME);
5425
5426 /* No need to align if we are already there. */
80aab579 5427 if (strcmp (segment_name (now_seg), GDB_DEBUG_SPACE_NAME) != 0)
5cf4cd1b 5428 pa_align_subseg (now_seg, now_subseg);
8f78d0e9
KR
5429
5430 subseg_set (gdb_section, sd_chain->sd_last_subseg);
5431 current_subspace
5432 = pa_subsegment_to_subspace (gdb_section,
5433 sd_chain->sd_last_subseg);
5cf4cd1b 5434 }
025b0302
ME
5435 demand_empty_rest_of_line ();
5436 return;
5437 }
5438
8f78d0e9 5439 /* It could be a space specified by number. */
aa8b30ed
JL
5440 print_errors = 0;
5441 save_s = input_line_pointer;
8f78d0e9 5442 if ((temp = pa_parse_number (&input_line_pointer, 0)) >= 0)
025b0302
ME
5443 {
5444 if (sd_chain = pa_find_space_by_number (temp))
5445 {
5446 current_space = sd_chain;
8f78d0e9
KR
5447
5448 if (now_seg != sd_chain->sd_seg)
025b0302 5449 pa_align_subseg (now_seg, now_subseg);
80aab579 5450 subseg_set (sd_chain->sd_seg, sd_chain->sd_last_subseg);
8f78d0e9
KR
5451 current_subspace
5452 = pa_subsegment_to_subspace (sd_chain->sd_seg,
5453 sd_chain->sd_last_subseg);
025b0302
ME
5454 demand_empty_rest_of_line ();
5455 return;
5456 }
5457 }
5458
8f78d0e9 5459 /* Not a number, attempt to create a new space. */
aa8b30ed
JL
5460 print_errors = 1;
5461 input_line_pointer = save_s;
025b0302
ME
5462 name = input_line_pointer;
5463 c = get_symbol_end ();
8f78d0e9 5464 space_name = xmalloc (strlen (name) + 1);
025b0302
ME
5465 strcpy (space_name, name);
5466 *input_line_pointer = c;
5467
5468 sd_chain = pa_parse_space_stmt (space_name, 1);
5469 current_space = sd_chain;
8f78d0e9
KR
5470
5471 if (now_seg != sd_chain->sd_seg)
025b0302 5472 pa_align_subseg (now_seg, now_subseg);
80aab579 5473 subseg_set (sd_chain->sd_seg, sd_chain->sd_last_subseg);
025b0302
ME
5474 current_subspace = pa_subsegment_to_subspace (sd_chain->sd_seg,
5475 sd_chain->sd_last_subseg);
5476 demand_empty_rest_of_line ();
5477 }
5478 return;
5479}
5480
8f78d0e9
KR
5481/* Switch to a new space. (I think). FIXME. */
5482
5483static void
5484pa_spnum (unused)
5485 int unused;
025b0302 5486{
8f78d0e9
KR
5487 char *name;
5488 char c;
5489 char *p;
5490 sd_chain_struct *space;
025b0302
ME
5491
5492 name = input_line_pointer;
5493 c = get_symbol_end ();
5494 space = is_defined_space (name);
5495 if (space)
5496 {
5497 p = frag_more (4);
025b0302
ME
5498 md_number_to_chars (p, SPACE_SPNUM (space), 4);
5499 }
5500 else
5501 as_warn ("Undefined space: '%s' Assuming space number = 0.", name);
5502
5503 *input_line_pointer = c;
5504 demand_empty_rest_of_line ();
5505 return;
5506}
5507
8f78d0e9 5508/* If VALUE is an exact power of two between zero and 2^31, then
aa8b30ed 5509 return log2 (VALUE). Else return -1. */
8f78d0e9
KR
5510
5511static int
aa8b30ed 5512log2 (value)
025b0302
ME
5513 int value;
5514{
8f78d0e9 5515 int shift = 0;
025b0302 5516
025b0302
ME
5517 while ((1 << shift) != value && shift < 32)
5518 shift++;
5519
5520 if (shift >= 32)
aa8b30ed 5521 return -1;
8f78d0e9 5522 else
aa8b30ed 5523 return shift;
025b0302
ME
5524}
5525
3b9a72c5 5526/* Handle a .SUBSPACE pseudo-op; this switches the current subspace to the
8f78d0e9
KR
5527 given subspace, creating the new subspace if necessary.
5528
5529 FIXME. Should mirror pa_space more closely, in particular how
5530 they're broken up into subroutines. */
5531
5532static void
5533pa_subspace (unused)
5534 int unused;
025b0302 5535{
3b9a72c5 5536 char *name, *ss_name, *alias, c;
8f78d0e9 5537 char loadable, code_only, common, dup_common, zero, sort;
3b9a72c5 5538 int i, access, space_index, alignment, quadrant, applicable, flags;
8f78d0e9
KR
5539 sd_chain_struct *space;
5540 ssd_chain_struct *ssd;
3b9a72c5 5541 asection *section;
025b0302
ME
5542
5543 if (within_procedure)
5544 {
5545 as_bad ("Can\'t change subspaces within a procedure definition. Ignored");
5546 ignore_rest_of_line ();
5547 }
5548 else
5549 {
5550 name = input_line_pointer;
5551 c = get_symbol_end ();
025b0302
ME
5552 ss_name = xmalloc (strlen (name) + 1);
5553 strcpy (ss_name, name);
025b0302
ME
5554 *input_line_pointer = c;
5555
8f78d0e9 5556 /* Load default values. */
025b0302
ME
5557 sort = 0;
5558 access = 0x7f;
5559 loadable = 1;
5560 common = 0;
5561 dup_common = 0;
5562 code_only = 0;
5563 zero = 0;
8f78d0e9
KR
5564 space_index = ~0;
5565 alignment = 0;
025b0302 5566 quadrant = 0;
3b9a72c5 5567 alias = NULL;
025b0302 5568
3b9a72c5 5569 space = current_space;
47f45d66
JL
5570 ssd = is_defined_subspace (ss_name);
5571 /* Allow user to override the builtin attributes of subspaces. But
5572 only allow the attributes to be changed once! */
5573 if (ssd && SUBSPACE_DEFINED (ssd))
025b0302 5574 {
8f78d0e9
KR
5575 subseg_set (ssd->ssd_seg, ssd->ssd_subseg);
5576 if (!is_end_of_statement ())
5577 as_warn ("Parameters of an existing subspace can\'t be modified");
5578 demand_empty_rest_of_line ();
5579 return;
025b0302
ME
5580 }
5581 else
5582 {
3b9a72c5
JL
5583 /* A new subspace. Load default values if it matches one of
5584 the builtin subspaces. */
025b0302
ME
5585 i = 0;
5586 while (pa_def_subspaces[i].name)
5587 {
5588 if (strcasecmp (pa_def_subspaces[i].name, ss_name) == 0)
5589 {
5590 loadable = pa_def_subspaces[i].loadable;
5591 common = pa_def_subspaces[i].common;
5592 dup_common = pa_def_subspaces[i].dup_common;
5593 code_only = pa_def_subspaces[i].code_only;
5594 zero = pa_def_subspaces[i].zero;
5595 space_index = pa_def_subspaces[i].space_index;
8f78d0e9 5596 alignment = pa_def_subspaces[i].alignment;
025b0302
ME
5597 quadrant = pa_def_subspaces[i].quadrant;
5598 access = pa_def_subspaces[i].access;
5599 sort = pa_def_subspaces[i].sort;
3b9a72c5
JL
5600 if (USE_ALIASES && pa_def_subspaces[i].alias)
5601 alias = pa_def_subspaces[i].alias;
025b0302
ME
5602 break;
5603 }
5604 i++;
5605 }
5606 }
5607
8f78d0e9
KR
5608 /* We should be working with a new subspace now. Fill in
5609 any information as specified by the user. */
025b0302
ME
5610 if (!is_end_of_statement ())
5611 {
5612 input_line_pointer++;
5613 while (!is_end_of_statement ())
5614 {
5615 name = input_line_pointer;
5616 c = get_symbol_end ();
5617 if ((strncasecmp (name, "QUAD", 4) == 0))
5618 {
5619 *input_line_pointer = c;
5620 input_line_pointer++;
8f78d0e9 5621 quadrant = get_absolute_expression ();
025b0302
ME
5622 }
5623 else if ((strncasecmp (name, "ALIGN", 5) == 0))
5624 {
5625 *input_line_pointer = c;
5626 input_line_pointer++;
8f78d0e9 5627 alignment = get_absolute_expression ();
aa8b30ed 5628 if (log2 (alignment) == -1)
025b0302
ME
5629 {
5630 as_bad ("Alignment must be a power of 2");
5631 alignment = 1;
5632 }
5633 }
5634 else if ((strncasecmp (name, "ACCESS", 6) == 0))
5635 {
5636 *input_line_pointer = c;
5637 input_line_pointer++;
8f78d0e9 5638 access = get_absolute_expression ();
025b0302
ME
5639 }
5640 else if ((strncasecmp (name, "SORT", 4) == 0))
5641 {
5642 *input_line_pointer = c;
5643 input_line_pointer++;
8f78d0e9 5644 sort = get_absolute_expression ();
025b0302
ME
5645 }
5646 else if ((strncasecmp (name, "CODE_ONLY", 9) == 0))
5647 {
5648 *input_line_pointer = c;
5649 code_only = 1;
5650 }
5651 else if ((strncasecmp (name, "UNLOADABLE", 10) == 0))
5652 {
5653 *input_line_pointer = c;
5654 loadable = 0;
5655 }
5656 else if ((strncasecmp (name, "COMMON", 6) == 0))
5657 {
5658 *input_line_pointer = c;
5659 common = 1;
5660 }
5661 else if ((strncasecmp (name, "DUP_COMM", 8) == 0))
5662 {
5663 *input_line_pointer = c;
5664 dup_common = 1;
5665 }
5666 else if ((strncasecmp (name, "ZERO", 4) == 0))
5667 {
5668 *input_line_pointer = c;
5669 zero = 1;
5670 }
8f78d0e9
KR
5671 else if ((strncasecmp (name, "FIRST", 5) == 0))
5672 as_bad ("FIRST not supported as a .SUBSPACE argument");
025b0302 5673 else
8f78d0e9 5674 as_bad ("Invalid .SUBSPACE argument");
025b0302
ME
5675 if (!is_end_of_statement ())
5676 input_line_pointer++;
5677 }
5678 }
8f78d0e9 5679
3b9a72c5
JL
5680 /* Compute a reasonable set of BFD flags based on the information
5681 in the .subspace directive. */
5682 applicable = bfd_applicable_section_flags (stdoutput);
5683 flags = 0;
5684 if (loadable)
5685 flags |= (SEC_ALLOC | SEC_LOAD);
5686 if (code_only)
5687 flags |= SEC_CODE;
5688 if (common || dup_common)
5689 flags |= SEC_IS_COMMON;
5690
5691 /* This is a zero-filled subspace (eg BSS). */
5692 if (zero)
5693 flags &= ~SEC_LOAD;
5694
5695 flags |= SEC_RELOC | SEC_HAS_CONTENTS;
5696 applicable &= flags;
5697
5698 /* If this is an existing subspace, then we want to use the
5699 segment already associated with the subspace.
5700
5701 FIXME NOW! ELF BFD doesn't appear to be ready to deal with
5702 lots of sections. It might be a problem in the PA ELF
5703 code, I do not know yet. For now avoid creating anything
5704 but the "standard" sections for ELF. */
5705 if (ssd)
5706 section = ssd->ssd_seg;
47f45d66 5707 else if (alias)
3b9a72c5
JL
5708 section = subseg_new (alias, 0);
5709 else if (! alias && USE_ALIASES)
5710 {
5711 as_warn ("Ignoring subspace decl due to ELF BFD bugs.");
5712 demand_empty_rest_of_line ();
5713 return;
5714 }
5715 else
5716 section = subseg_new (ss_name, 0);
5717
5718 /* Now set the flags. */
5719 bfd_set_section_flags (stdoutput, section, applicable);
5720
5721 /* Record any alignment request for this section. */
5722 record_alignment (section, log2 (alignment));
5723
5724 /* Set the starting offset for this section. */
5725 bfd_set_section_vma (stdoutput, section,
5726 pa_subspace_start (space, quadrant));
5727
8f78d0e9 5728 /* Now that all the flags are set, update an existing subspace,
3b9a72c5 5729 or create a new one. */
025b0302 5730 if (ssd)
3b9a72c5
JL
5731
5732 current_subspace = update_subspace (space, ss_name, loadable,
5733 code_only, common, dup_common,
5734 sort, zero, access, space_index,
5735 alignment, quadrant,
47f45d66 5736 section);
025b0302 5737 else
8f78d0e9
KR
5738 current_subspace = create_new_subspace (space, ss_name, loadable,
5739 code_only, common,
5740 dup_common, zero, sort,
5741 access, space_index,
3b9a72c5 5742 alignment, quadrant, section);
025b0302
ME
5743
5744 demand_empty_rest_of_line ();
3b9a72c5 5745 current_subspace->ssd_seg = section;
80aab579 5746 subseg_set (current_subspace->ssd_seg, current_subspace->ssd_subseg);
025b0302 5747 }
47f45d66 5748 SUBSPACE_DEFINED (current_subspace) = 1;
025b0302
ME
5749 return;
5750}
5751
025b0302 5752
8f78d0e9 5753/* Create default space and subspace dictionaries. */
025b0302 5754
8f78d0e9 5755static void
025b0302
ME
5756pa_spaces_begin ()
5757{
025b0302 5758 int i;
025b0302
ME
5759
5760 space_dict_root = NULL;
5761 space_dict_last = NULL;
5762
025b0302
ME
5763 i = 0;
5764 while (pa_def_spaces[i].name)
5765 {
3b9a72c5
JL
5766 char *name;
5767
5768 /* Pick the right name to use for the new section. */
5769 if (pa_def_spaces[i].alias && USE_ALIASES)
5770 name = pa_def_spaces[i].alias;
025b0302 5771 else
3b9a72c5 5772 name = pa_def_spaces[i].name;
025b0302 5773
3b9a72c5 5774 pa_def_spaces[i].segment = subseg_new (name, 0);
025b0302
ME
5775 create_new_space (pa_def_spaces[i].name, pa_def_spaces[i].spnum,
5776 pa_def_spaces[i].loadable, pa_def_spaces[i].defined,
8f78d0e9
KR
5777 pa_def_spaces[i].private, pa_def_spaces[i].sort,
5778 pa_def_spaces[i].segment, 0);
025b0302
ME
5779 i++;
5780 }
5781
5782 i = 0;
5783 while (pa_def_subspaces[i].name)
5784 {
3b9a72c5
JL
5785 char *name;
5786 int applicable, subsegment;
5787 asection *segment = NULL;
5788 sd_chain_struct *space;
5789
5790 /* Pick the right name for the new section and pick the right
5791 subsegment number. */
5792 if (pa_def_subspaces[i].alias && USE_ALIASES)
025b0302 5793 {
3b9a72c5
JL
5794 name = pa_def_subspaces[i].alias;
5795 subsegment = pa_def_subspaces[i].subsegment;
025b0302
ME
5796 }
5797 else
3b9a72c5
JL
5798 {
5799 name = pa_def_subspaces[i].name;
5800 subsegment = 0;
5801 }
5802
5803 /* Create the new section. */
5804 segment = subseg_new (name, subsegment);
5805
5806
5807 /* For SOM we want to replace the standard .text, .data, and .bss
5808 sections with our own. */
5809 if (! strcmp (pa_def_subspaces[i].name, "$CODE$") && ! USE_ALIASES)
5810 {
5811 text_section = segment;
5812 applicable = bfd_applicable_section_flags (stdoutput);
5813 bfd_set_section_flags (stdoutput, text_section,
5814 applicable & (SEC_ALLOC | SEC_LOAD
5815 | SEC_RELOC | SEC_CODE
5816 | SEC_READONLY
5817 | SEC_HAS_CONTENTS));
5818 }
5819 else if (! strcmp (pa_def_subspaces[i].name, "$DATA$") && ! USE_ALIASES)
5820 {
5821 data_section = segment;
5822 applicable = bfd_applicable_section_flags (stdoutput);
5823 bfd_set_section_flags (stdoutput, data_section,
5824 applicable & (SEC_ALLOC | SEC_LOAD
5825 | SEC_RELOC
5826 | SEC_HAS_CONTENTS));
5827
5828
5829 }
5830 else if (! strcmp (pa_def_subspaces[i].name, "$BSS$") && ! USE_ALIASES)
5831 {
5832 bss_section = segment;
5833 applicable = bfd_applicable_section_flags (stdoutput);
5834 bfd_set_section_flags (stdoutput, bss_section,
5835 applicable & SEC_ALLOC);
5836 }
5837
5838 /* Find the space associated with this subspace. */
5839 space = pa_segment_to_space (pa_def_spaces[pa_def_subspaces[i].
5840 def_space_index].segment);
5841 if (space == NULL)
5842 {
5843 as_fatal ("Internal error: Unable to find containing space for %s.",
5844 pa_def_subspaces[i].name);
5845 }
5846
5847 create_new_subspace (space, name,
5848 pa_def_subspaces[i].loadable,
5849 pa_def_subspaces[i].code_only,
5850 pa_def_subspaces[i].common,
5851 pa_def_subspaces[i].dup_common,
5852 pa_def_subspaces[i].zero,
5853 pa_def_subspaces[i].sort,
5854 pa_def_subspaces[i].access,
5855 pa_def_subspaces[i].space_index,
5856 pa_def_subspaces[i].alignment,
5857 pa_def_subspaces[i].quadrant,
5858 segment);
025b0302
ME
5859 i++;
5860 }
5861}
5862
8f78d0e9
KR
5863
5864
5865/* Create a new space NAME, with the appropriate flags as defined
5866 by the given parameters.
5867
5868 Add the new space to the space dictionary chain in numerical
5869 order as defined by the SORT entries. */
5870
5871static sd_chain_struct *
5872create_new_space (name, spnum, loadable, defined, private,
5873 sort, seg, user_defined)
025b0302
ME
5874 char *name;
5875 int spnum;
5876 char loadable;
5877 char defined;
5878 char private;
5879 char sort;
025b0302 5880 asection *seg;
8f78d0e9 5881 int user_defined;
025b0302 5882{
8f78d0e9
KR
5883 sd_chain_struct *chain_entry;
5884
5885 chain_entry = (sd_chain_struct *) xmalloc (sizeof (sd_chain_struct));
025b0302 5886 if (!chain_entry)
8f78d0e9
KR
5887 as_fatal ("Out of memory: could not allocate new space chain entry: %s\n",
5888 name);
025b0302
ME
5889
5890 SPACE_NAME (chain_entry) = (char *) xmalloc (strlen (name) + 1);
5891 strcpy (SPACE_NAME (chain_entry), name);
8f78d0e9
KR
5892 SPACE_NAME_INDEX (chain_entry) = 0;
5893 SPACE_LOADABLE (chain_entry) = loadable;
5894 SPACE_DEFINED (chain_entry) = defined;
5895 SPACE_USER_DEFINED (chain_entry) = user_defined;
5896 SPACE_PRIVATE (chain_entry) = private;
5897 SPACE_SPNUM (chain_entry) = spnum;
5898 SPACE_SORT (chain_entry) = sort;
025b0302 5899
025b0302
ME
5900 chain_entry->sd_seg = seg;
5901 chain_entry->sd_last_subseg = -1;
5902 chain_entry->sd_next = NULL;
5903
8f78d0e9 5904 /* Find spot for the new space based on its sort key. */
025b0302
ME
5905 if (!space_dict_last)
5906 space_dict_last = chain_entry;
5907
8f78d0e9 5908 if (space_dict_root == NULL)
025b0302
ME
5909 space_dict_root = chain_entry;
5910 else
5911 {
8f78d0e9
KR
5912 sd_chain_struct *chain_pointer;
5913 sd_chain_struct *prev_chain_pointer;
025b0302 5914
8f78d0e9
KR
5915 chain_pointer = space_dict_root;
5916 prev_chain_pointer = NULL;
025b0302 5917
8f78d0e9 5918 while (chain_pointer)
025b0302 5919 {
8f78d0e9 5920 if (SPACE_SORT (chain_pointer) <= SPACE_SORT (chain_entry))
025b0302 5921 {
8f78d0e9
KR
5922 prev_chain_pointer = chain_pointer;
5923 chain_pointer = chain_pointer->sd_next;
025b0302 5924 }
8f78d0e9
KR
5925 else
5926 break;
025b0302
ME
5927 }
5928
8f78d0e9
KR
5929 /* At this point we've found the correct place to add the new
5930 entry. So add it and update the linked lists as appropriate. */
5931 if (prev_chain_pointer)
025b0302 5932 {
8f78d0e9
KR
5933 chain_entry->sd_next = chain_pointer;
5934 prev_chain_pointer->sd_next = chain_entry;
025b0302
ME
5935 }
5936 else
5937 {
5938 space_dict_root = chain_entry;
8f78d0e9 5939 chain_entry->sd_next = chain_pointer;
025b0302
ME
5940 }
5941
5942 if (chain_entry->sd_next == NULL)
5943 space_dict_last = chain_entry;
5944 }
5945
548ea75b
JL
5946 /* This is here to catch predefined spaces which do not get
5947 modified by the user's input. Another call is found at
5948 the bottom of pa_parse_space_stmt to handle cases where
5949 the user modifies a predefined space. */
5950#ifdef obj_set_section_attributes
5951 obj_set_section_attributes (seg, defined, private, sort, spnum);
5952#endif
5953
025b0302
ME
5954 return chain_entry;
5955}
5956
8f78d0e9
KR
5957/* Create a new subspace NAME, with the appropriate flags as defined
5958 by the given parameters.
5959
5960 Add the new subspace to the subspace dictionary chain in numerical
5961 order as defined by the SORT entries. */
5962
5963static ssd_chain_struct *
5964create_new_subspace (space, name, loadable, code_only, common,
5965 dup_common, is_zero, sort, access, space_index,
5966 alignment, quadrant, seg)
5967 sd_chain_struct *space;
025b0302 5968 char *name;
8f78d0e9 5969 char loadable, code_only, common, dup_common, is_zero;
025b0302
ME
5970 char sort;
5971 int access;
5972 int space_index;
5973 int alignment;
5974 int quadrant;
5975 asection *seg;
5976{
8f78d0e9 5977 ssd_chain_struct *chain_entry;
025b0302 5978
8f78d0e9 5979 chain_entry = (ssd_chain_struct *) xmalloc (sizeof (ssd_chain_struct));
025b0302
ME
5980 if (!chain_entry)
5981 as_fatal ("Out of memory: could not allocate new subspace chain entry: %s\n", name);
5982
025b0302
ME
5983 SUBSPACE_NAME (chain_entry) = (char *) xmalloc (strlen (name) + 1);
5984 strcpy (SUBSPACE_NAME (chain_entry), name);
5985
8f78d0e9
KR
5986 SUBSPACE_ACCESS (chain_entry) = access;
5987 SUBSPACE_LOADABLE (chain_entry) = loadable;
5988 SUBSPACE_COMMON (chain_entry) = common;
5989 SUBSPACE_DUP_COMM (chain_entry) = dup_common;
5990 SUBSPACE_SORT (chain_entry) = sort;
5991 SUBSPACE_CODE_ONLY (chain_entry) = code_only;
5992 SUBSPACE_ALIGN (chain_entry) = alignment;
5993 SUBSPACE_QUADRANT (chain_entry) = quadrant;
025b0302 5994 SUBSPACE_SUBSPACE_START (chain_entry) = pa_subspace_start (space, quadrant);
8f78d0e9
KR
5995 SUBSPACE_SPACE_INDEX (chain_entry) = space_index;
5996 SUBSPACE_ZERO (chain_entry) = is_zero;
025b0302 5997
3b9a72c5 5998 chain_entry->ssd_subseg = USE_ALIASES ? pa_next_subseg (space) : 0;
025b0302 5999 chain_entry->ssd_seg = seg;
025b0302
ME
6000 chain_entry->ssd_last_align = 1;
6001 chain_entry->ssd_next = NULL;
6002
8f78d0e9
KR
6003 /* Find spot for the new subspace based on its sort key. */
6004 if (space->sd_subspaces == NULL)
025b0302
ME
6005 space->sd_subspaces = chain_entry;
6006 else
6007 {
8f78d0e9
KR
6008 ssd_chain_struct *chain_pointer;
6009 ssd_chain_struct *prev_chain_pointer;
025b0302 6010
8f78d0e9
KR
6011 chain_pointer = space->sd_subspaces;
6012 prev_chain_pointer = NULL;
025b0302 6013
8f78d0e9 6014 while (chain_pointer)
025b0302 6015 {
8f78d0e9 6016 if (SUBSPACE_SORT (chain_pointer) <= SUBSPACE_SORT (chain_entry))
025b0302 6017 {
8f78d0e9
KR
6018 prev_chain_pointer = chain_pointer;
6019 chain_pointer = chain_pointer->ssd_next;
025b0302 6020 }
8f78d0e9
KR
6021 else
6022 break;
6023
025b0302
ME
6024 }
6025
8f78d0e9
KR
6026 /* Now we have somewhere to put the new entry. Insert it and update
6027 the links. */
6028 if (prev_chain_pointer)
025b0302 6029 {
8f78d0e9
KR
6030 chain_entry->ssd_next = chain_pointer;
6031 prev_chain_pointer->ssd_next = chain_entry;
025b0302
ME
6032 }
6033 else
6034 {
6035 space->sd_subspaces = chain_entry;
8f78d0e9 6036 chain_entry->ssd_next = chain_pointer;
025b0302
ME
6037 }
6038 }
6039
548ea75b
JL
6040#ifdef obj_set_subsection_attributes
6041 obj_set_subsection_attributes (seg, space->sd_seg, access,
6042 sort, quadrant);
6043#endif
6044
025b0302
ME
6045 return chain_entry;
6046
6047}
6048
8f78d0e9
KR
6049/* Update the information for the given subspace based upon the
6050 various arguments. Return the modified subspace chain entry. */
6051
6052static ssd_chain_struct *
3b9a72c5 6053update_subspace (space, name, loadable, code_only, common, dup_common, sort,
8f78d0e9 6054 zero, access, space_index, alignment, quadrant, subseg)
3b9a72c5 6055 sd_chain_struct *space;
025b0302 6056 char *name;
8f78d0e9
KR
6057 char loadable;
6058 char code_only;
6059 char common;
6060 char dup_common;
6061 char zero;
025b0302
ME
6062 char sort;
6063 int access;
6064 int space_index;
6065 int alignment;
6066 int quadrant;
6067 subsegT subseg;
6068{
8f78d0e9 6069 ssd_chain_struct *chain_entry;
025b0302 6070
47f45d66 6071 if ((chain_entry = is_defined_subspace (name)))
025b0302 6072 {
8f78d0e9
KR
6073 SUBSPACE_ACCESS (chain_entry) = access;
6074 SUBSPACE_LOADABLE (chain_entry) = loadable;
6075 SUBSPACE_COMMON (chain_entry) = common;
6076 SUBSPACE_DUP_COMM (chain_entry) = dup_common;
6077 SUBSPACE_CODE_ONLY (chain_entry) = 1;
6078 SUBSPACE_SORT (chain_entry) = sort;
6079 SUBSPACE_ALIGN (chain_entry) = alignment;
6080 SUBSPACE_QUADRANT (chain_entry) = quadrant;
6081 SUBSPACE_SPACE_INDEX (chain_entry) = space_index;
025b0302
ME
6082 SUBSPACE_ZERO (chain_entry) = zero;
6083 }
6084 else
6085 chain_entry = NULL;
6086
548ea75b
JL
6087#ifdef obj_set_subsection_attributes
6088 obj_set_subsection_attributes (subseg, space->sd_seg, access,
6089 sort, quadrant);
6090#endif
6091
025b0302
ME
6092 return chain_entry;
6093
6094}
6095
8f78d0e9
KR
6096/* Return the space chain entry for the space with the name NAME or
6097 NULL if no such space exists. */
6098
6099static sd_chain_struct *
025b0302
ME
6100is_defined_space (name)
6101 char *name;
6102{
8f78d0e9 6103 sd_chain_struct *chain_pointer;
025b0302 6104
8f78d0e9
KR
6105 for (chain_pointer = space_dict_root;
6106 chain_pointer;
6107 chain_pointer = chain_pointer->sd_next)
025b0302 6108 {
8f78d0e9
KR
6109 if (strcmp (SPACE_NAME (chain_pointer), name) == 0)
6110 return chain_pointer;
025b0302
ME
6111 }
6112
8f78d0e9 6113 /* No mapping from segment to space was found. Return NULL. */
025b0302
ME
6114 return NULL;
6115}
6116
8f78d0e9
KR
6117/* Find and return the space associated with the given seg. If no mapping
6118 from the given seg to a space is found, then return NULL.
6119
6120 Unlike subspaces, the number of spaces is not expected to grow much,
6121 so a linear exhaustive search is OK here. */
6122
6123static sd_chain_struct *
025b0302
ME
6124pa_segment_to_space (seg)
6125 asection *seg;
6126{
8f78d0e9 6127 sd_chain_struct *space_chain;
025b0302 6128
8f78d0e9
KR
6129 /* Walk through each space looking for the correct mapping. */
6130 for (space_chain = space_dict_root;
6131 space_chain;
6132 space_chain = space_chain->sd_next)
025b0302 6133 {
8f78d0e9
KR
6134 if (space_chain->sd_seg == seg)
6135 return space_chain;
025b0302
ME
6136 }
6137
8f78d0e9 6138 /* Mapping was not found. Return NULL. */
025b0302
ME
6139 return NULL;
6140}
6141
8f78d0e9
KR
6142/* Return the space chain entry for the subspace with the name NAME or
6143 NULL if no such subspace exists.
6144
6145 Uses a linear search through all the spaces and subspaces, this may
6146 not be appropriate if we ever being placing each function in its
6147 own subspace. */
6148
6149static ssd_chain_struct *
47f45d66 6150is_defined_subspace (name)
025b0302 6151 char *name;
025b0302 6152{
8f78d0e9
KR
6153 sd_chain_struct*space_chain;
6154 ssd_chain_struct *subspace_chain;
025b0302 6155
8f78d0e9
KR
6156 /* Walk through each space. */
6157 for (space_chain = space_dict_root;
6158 space_chain;
6159 space_chain = space_chain->sd_next)
025b0302 6160 {
8f78d0e9
KR
6161 /* Walk through each subspace looking for a name which matches. */
6162 for (subspace_chain = space_chain->sd_subspaces;
6163 subspace_chain;
6164 subspace_chain = subspace_chain->ssd_next)
6165 if (strcmp (SUBSPACE_NAME (subspace_chain), name) == 0)
6166 return subspace_chain;
025b0302 6167 }
8f78d0e9
KR
6168
6169 /* Subspace wasn't found. Return NULL. */
025b0302
ME
6170 return NULL;
6171}
6172
8f78d0e9
KR
6173/* Find and return the subspace associated with the given seg. If no
6174 mapping from the given seg to a subspace is found, then return NULL.
6175
6176 If we ever put each procedure/function within its own subspace
6177 (to make life easier on the compiler and linker), then this will have
6178 to become more efficient. */
6179
6180static ssd_chain_struct *
025b0302
ME
6181pa_subsegment_to_subspace (seg, subseg)
6182 asection *seg;
6183 subsegT subseg;
6184{
8f78d0e9
KR
6185 sd_chain_struct *space_chain;
6186 ssd_chain_struct *subspace_chain;
025b0302 6187
8f78d0e9
KR
6188 /* Walk through each space. */
6189 for (space_chain = space_dict_root;
6190 space_chain;
6191 space_chain = space_chain->sd_next)
025b0302 6192 {
8f78d0e9 6193 if (space_chain->sd_seg == seg)
025b0302 6194 {
8f78d0e9
KR
6195 /* Walk through each subspace within each space looking for
6196 the correct mapping. */
6197 for (subspace_chain = space_chain->sd_subspaces;
6198 subspace_chain;
6199 subspace_chain = subspace_chain->ssd_next)
6200 if (subspace_chain->ssd_subseg == (int) subseg)
6201 return subspace_chain;
025b0302
ME
6202 }
6203 }
6204
8f78d0e9 6205 /* No mapping from subsegment to subspace found. Return NULL. */
025b0302
ME
6206 return NULL;
6207}
6208
8f78d0e9
KR
6209/* Given a number, try and find a space with the name number.
6210
6211 Return a pointer to a space dictionary chain entry for the space
6212 that was found or NULL on failure. */
6213
6214static sd_chain_struct *
025b0302
ME
6215pa_find_space_by_number (number)
6216 int number;
6217{
8f78d0e9 6218 sd_chain_struct *space_chain;
025b0302 6219
8f78d0e9
KR
6220 for (space_chain = space_dict_root;
6221 space_chain;
6222 space_chain = space_chain->sd_next)
025b0302 6223 {
8f78d0e9
KR
6224 if (SPACE_SPNUM (space_chain) == number)
6225 return space_chain;
025b0302
ME
6226 }
6227
8f78d0e9 6228 /* No appropriate space found. Return NULL. */
025b0302
ME
6229 return NULL;
6230}
6231
8f78d0e9
KR
6232/* Return the starting address for the given subspace. If the starting
6233 address is unknown then return zero. */
6234
6235static unsigned int
025b0302 6236pa_subspace_start (space, quadrant)
8f78d0e9 6237 sd_chain_struct *space;
025b0302
ME
6238 int quadrant;
6239{
8f78d0e9
KR
6240 /* FIXME. Assumes everyone puts read/write data at 0x4000000, this
6241 is not correct for the PA OSF1 port. */
6242 if ((strcasecmp (SPACE_NAME (space), "$PRIVATE$") == 0) && quadrant == 1)
6243 return 0x40000000;
025b0302 6244 else if (space->sd_seg == data_section && quadrant == 1)
8f78d0e9 6245 return 0x40000000;
025b0302
ME
6246 else
6247 return 0;
6248}
6249
8f78d0e9
KR
6250/* FIXME. Needs documentation. */
6251static int
025b0302 6252pa_next_subseg (space)
8f78d0e9 6253 sd_chain_struct *space;
025b0302
ME
6254{
6255
6256 space->sd_last_subseg++;
6257 return space->sd_last_subseg;
6258}
6259
8f78d0e9
KR
6260/* Helper function for pa_stringer. Used to find the end of
6261 a string. */
6262
025b0302
ME
6263static unsigned int
6264pa_stringer_aux (s)
6265 char *s;
6266{
6267 unsigned int c = *s & CHAR_MASK;
6268 switch (c)
6269 {
6270 case '\"':
6271 c = NOT_A_CHAR;
6272 break;
6273 default:
6274 break;
6275 }
6276 return c;
6277}
6278
8f78d0e9
KR
6279/* Handle a .STRING type pseudo-op. */
6280
6281static void
6282pa_stringer (append_zero)
6283 int append_zero;
025b0302 6284{
8f78d0e9 6285 char *s, num_buf[4];
025b0302 6286 unsigned int c;
025b0302
ME
6287 int i;
6288
8f78d0e9
KR
6289 /* Preprocess the string to handle PA-specific escape sequences.
6290 For example, \xDD where DD is a hexidecimal number should be
6291 changed to \OOO where OOO is an octal number. */
025b0302 6292
8f78d0e9
KR
6293 /* Skip the opening quote. */
6294 s = input_line_pointer + 1;
025b0302
ME
6295
6296 while (is_a_char (c = pa_stringer_aux (s++)))
6297 {
6298 if (c == '\\')
6299 {
6300 c = *s;
6301 switch (c)
6302 {
8f78d0e9 6303 /* Handle \x<num>. */
025b0302
ME
6304 case 'x':
6305 {
6306 unsigned int number;
6307 int num_digit;
6308 char dg;
6309 char *s_start = s;
6310
8f78d0e9
KR
6311 /* Get pas the 'x'. */
6312 s++;
025b0302
ME
6313 for (num_digit = 0, number = 0, dg = *s;
6314 num_digit < 2
6315 && (isdigit (dg) || (dg >= 'a' && dg <= 'f')
6316 || (dg >= 'A' && dg <= 'F'));
6317 num_digit++)
6318 {
6319 if (isdigit (dg))
6320 number = number * 16 + dg - '0';
6321 else if (dg >= 'a' && dg <= 'f')
6322 number = number * 16 + dg - 'a' + 10;
6323 else
6324 number = number * 16 + dg - 'A' + 10;
6325
6326 s++;
6327 dg = *s;
6328 }
6329 if (num_digit > 0)
6330 {
6331 switch (num_digit)
6332 {
6333 case 1:
6334 sprintf (num_buf, "%02o", number);
6335 break;
6336 case 2:
6337 sprintf (num_buf, "%03o", number);
6338 break;
6339 }
6340 for (i = 0; i <= num_digit; i++)
6341 s_start[i] = num_buf[i];
6342 }
5cf4cd1b 6343 break;
025b0302 6344 }
8f78d0e9 6345 /* This might be a "\"", skip over the escaped char. */
5cf4cd1b
KR
6346 default:
6347 s++;
025b0302
ME
6348 break;
6349 }
6350 }
6351 }
6352 stringer (append_zero);
6353 pa_undefine_label ();
6354}
6355
8f78d0e9
KR
6356/* Handle a .VERSION pseudo-op. */
6357
6358static void
6359pa_version (unused)
6360 int unused;
025b0302 6361{
8f78d0e9 6362 obj_version (0);
025b0302
ME
6363 pa_undefine_label ();
6364}
6365
8f78d0e9
KR
6366/* Just like a normal cons, but when finished we have to undefine
6367 the latest space label. */
6368
6369static void
025b0302 6370pa_cons (nbytes)
8f78d0e9 6371 int nbytes;
025b0302
ME
6372{
6373 cons (nbytes);
6374 pa_undefine_label ();
6375}
6376
8f78d0e9
KR
6377/* Switch to the data space. As usual delete our label. */
6378
6379static void
6380pa_data (unused)
6381 int unused;
025b0302 6382{
80aab579 6383 s_data (0);
025b0302
ME
6384 pa_undefine_label ();
6385}
6386
8f78d0e9 6387/* FIXME. What's the purpose of this pseudo-op? */
025b0302 6388
8f78d0e9
KR
6389static void
6390pa_desc (unused)
6391 int unused;
6392{
025b0302
ME
6393 pa_undefine_label ();
6394}
6395
8f78d0e9
KR
6396/* Like float_cons, but we need to undefine our label. */
6397
6398static void
025b0302 6399pa_float_cons (float_type)
8f78d0e9 6400 int float_type;
025b0302
ME
6401{
6402 float_cons (float_type);
6403 pa_undefine_label ();
6404}
6405
8f78d0e9
KR
6406/* Like s_fill, but delete our label when finished. */
6407
6408static void
6409pa_fill (unused)
6410 int unused;
025b0302 6411{
80aab579 6412 s_fill (0);
025b0302
ME
6413 pa_undefine_label ();
6414}
6415
8f78d0e9
KR
6416/* Like lcomm, but delete our label when finished. */
6417
6418static void
025b0302 6419pa_lcomm (needs_align)
025b0302
ME
6420 int needs_align;
6421{
6422 s_lcomm (needs_align);
6423 pa_undefine_label ();
6424}
6425
8f78d0e9
KR
6426/* Like lsym, but delete our label when finished. */
6427
6428static void
6429pa_lsym (unused)
6430 int unused;
025b0302 6431{
80aab579 6432 s_lsym (0);
025b0302
ME
6433 pa_undefine_label ();
6434}
6435
8f78d0e9
KR
6436/* Switch to the text space. Like s_text, but delete our
6437 label when finished. */
6438static void
6439pa_text (unused)
6440 int unused;
025b0302 6441{
80aab579 6442 s_text (0);
025b0302
ME
6443 pa_undefine_label ();
6444}
5cf4cd1b 6445
aa8b30ed
JL
6446/* On the PA relocations which involve function symbols must not be
6447 adjusted. This so that the linker can know when/how to create argument
6448 relocation stubs for indirect calls and calls to static functions.
6449
6450 FIXME. Also reject R_HPPA relocations which are 32 bits
6451 wide. Helps with code lables in arrays for SOM. (SOM BFD code
6452 needs to generate relocations to push the addend and symbol value
6453 onto the stack, add them, then pop the value off the stack and
6454 use it in a relocation -- yuk. */
6455
6456int
6457hppa_fix_adjustable (fixp)
6458 fixS *fixp;
6459{
6460 struct hppa_fix_struct *hppa_fix;
6461
6462 hppa_fix = fixp->tc_fix_data;
6463
6464 if (fixp->fx_r_type == R_HPPA && hppa_fix->fx_r_format == 32)
6465 return 0;
6466
6467 if (fixp->fx_addsy == 0
6468 || (fixp->fx_addsy->bsym->flags & BSF_FUNCTION) == 0)
6469 return 1;
6470
6471 return 0;
6472}
6473
8f78d0e9
KR
6474/* Now for some ELF specific code. FIXME. */
6475#ifdef OBJ_ELF
6476static symext_chainS *symext_rootP;
6477static symext_chainS *symext_lastP;
6478
6479/* Do any symbol processing requested by the target-cpu or target-format. */
5cf4cd1b
KR
6480
6481void
6482hppa_tc_symbol (abfd, symbolP, sym_idx)
8f78d0e9
KR
6483 bfd *abfd;
6484 elf_symbol_type *symbolP;
5cf4cd1b
KR
6485 int sym_idx;
6486{
6487 symext_chainS *symextP;
6488 unsigned int arg_reloc;
6489
8f78d0e9 6490 /* Only functions can have argument relocations. */
5cf4cd1b
KR
6491 if (!(symbolP->symbol.flags & BSF_FUNCTION))
6492 return;
6493
6494 arg_reloc = symbolP->tc_data.hppa_arg_reloc;
6495
8f78d0e9
KR
6496 /* If there are no argument relocation bits, then no relocation is
6497 necessary. Do not add this to the symextn section. */
6498 if (arg_reloc == 0)
6499 return;
6500
5cf4cd1b
KR
6501 symextP = (symext_chainS *) bfd_alloc (abfd, sizeof (symext_chainS) * 2);
6502
6503 symextP[0].entry = ELF32_HPPA_SX_WORD (HPPA_SXT_SYMNDX, sym_idx);
6504 symextP[0].next = &symextP[1];
6505
6506 symextP[1].entry = ELF32_HPPA_SX_WORD (HPPA_SXT_ARG_RELOC, arg_reloc);
6507 symextP[1].next = NULL;
6508
6509 if (symext_rootP == NULL)
6510 {
6511 symext_rootP = &symextP[0];
6512 symext_lastP = &symextP[1];
6513 }
6514 else
6515 {
6516 symext_lastP->next = &symextP[0];
6517 symext_lastP = &symextP[1];
6518 }
6519}
6520
8f78d0e9 6521/* Make sections needed by the target cpu and/or target format. */
5cf4cd1b
KR
6522void
6523hppa_tc_make_sections (abfd)
8f78d0e9 6524 bfd *abfd;
5cf4cd1b
KR
6525{
6526 symext_chainS *symextP;
8f78d0e9 6527 int size, n;
5cf4cd1b
KR
6528 asection *symextn_sec;
6529 segT save_seg = now_seg;
6530 subsegT save_subseg = now_subseg;
6531
8f78d0e9
KR
6532 /* Build the symbol extension section. */
6533 hppa_tc_make_symextn_section ();
5cf4cd1b 6534
8f78d0e9
KR
6535 /* Force some calculation to occur. */
6536 bfd_set_section_contents (stdoutput, stdoutput->sections, "", 0, 0);
5cf4cd1b
KR
6537
6538 hppa_elf_stub_finish (abfd);
6539
8f78d0e9 6540 /* If no symbols for the symbol extension section, then stop now. */
5cf4cd1b
KR
6541 if (symext_rootP == NULL)
6542 return;
6543
8f78d0e9 6544 /* Count the number of symbols for the symbol extension section. */
5cf4cd1b
KR
6545 for (n = 0, symextP = symext_rootP; symextP; symextP = symextP->next, ++n)
6546 ;
6547
6548 size = sizeof (symext_entryS) * n;
6549
8f78d0e9
KR
6550 /* Switch to the symbol extension section. */
6551 symextn_sec = subseg_new (SYMEXTN_SECTION_NAME, 0);
5cf4cd1b
KR
6552
6553 frag_wane (frag_now);
6554 frag_new (0);
6555
6556 for (symextP = symext_rootP; symextP; symextP = symextP->next)
6557 {
6558 char *ptr;
8f78d0e9 6559 int *symtab_map = elf_sym_extra (abfd);
5cf4cd1b
KR
6560 int idx;
6561
8f78d0e9
KR
6562 /* First, patch the symbol extension record to reflect the true
6563 symbol table index. */
5cf4cd1b 6564
8f78d0e9 6565 if (ELF32_HPPA_SX_TYPE (symextP->entry) == HPPA_SXT_SYMNDX)
5cf4cd1b 6566 {
8f78d0e9 6567 idx = ELF32_HPPA_SX_VAL (symextP->entry) - 1;
5cf4cd1b 6568 symextP->entry = ELF32_HPPA_SX_WORD (HPPA_SXT_SYMNDX,
8f78d0e9 6569 symtab_map[idx]);
5cf4cd1b
KR
6570 }
6571
8f78d0e9
KR
6572 ptr = frag_more (sizeof (symextP->entry));
6573 md_number_to_chars (ptr, symextP->entry, sizeof (symextP->entry));
5cf4cd1b
KR
6574 }
6575
6576 frag_now->fr_fix = obstack_next_free (&frags) - frag_now->fr_literal;
6577 frag_wane (frag_now);
6578
8f78d0e9
KR
6579 /* Switch back to the original segment. */
6580 subseg_set (save_seg, save_subseg);
5cf4cd1b
KR
6581
6582 return;
6583}
6584
8f78d0e9
KR
6585/* Make the symbol extension section. */
6586
5cf4cd1b 6587static void
8f78d0e9 6588hppa_tc_make_symextn_section ()
5cf4cd1b 6589{
5cf4cd1b
KR
6590 if (symext_rootP)
6591 {
6592 symext_chainS *symextP;
6593 int n;
8f78d0e9 6594 unsigned int size;
5cf4cd1b
KR
6595 segT symextn_sec;
6596 segT save_seg = now_seg;
6597 subsegT save_subseg = now_subseg;
6598
6599 for (n = 0, symextP = symext_rootP; symextP; symextP = symextP->next, ++n)
6600 ;
6601
6602 size = sizeof (symext_entryS) * n;
6603
8f78d0e9 6604 symextn_sec = subseg_new (SYMEXTN_SECTION_NAME, 0);
5cf4cd1b 6605
8f78d0e9
KR
6606 bfd_set_section_flags (stdoutput, symextn_sec,
6607 SEC_LOAD | SEC_HAS_CONTENTS | SEC_DATA);
5cf4cd1b
KR
6608 bfd_set_section_size (stdoutput, symextn_sec, size);
6609
8f78d0e9
KR
6610 /* Now, switch back to the original segment. */
6611 subseg_set (save_seg, save_subseg);
6612 }
6613}
6614
6615/* Build the symbol extension section. */
6616
6617static void
6618pa_build_symextn_section ()
6619{
6620 segT seg;
6621 asection *save_seg = now_seg;
6622 subsegT subseg = (subsegT) 0;
6623 subsegT save_subseg = now_subseg;
6624
6625 seg = subseg_new (".hppa_symextn", subseg);
6626 bfd_set_section_flags (stdoutput,
6627 seg,
6628 SEC_HAS_CONTENTS | SEC_READONLY
6629 | SEC_ALLOC | SEC_LOAD);
6630
6631 subseg_set (save_seg, save_subseg);
6632
6633}
6634
6635/* For ELF, this function serves one purpose: to setup the st_size
6636 field of STT_FUNC symbols. To do this, we need to scan the
6637 call_info structure list, determining st_size in one of two possible
6638 ways:
6639
6640 1. call_info->start_frag->fr_fix has the size of the fragment.
6641 This approach assumes that the function was built into a
6642 single fragment. This works for most cases, but might fail.
6643 For example, if there was a segment change in the middle of
6644 the function.
6645
6646 2. The st_size field is the difference in the addresses of the
6647 call_info->start_frag->fr_address field and the fr_address
6648 field of the next fragment with fr_type == rs_fill and
6649 fr_fix != 0. */
6650
6651void
6652elf_hppa_final_processing ()
6653{
6654 struct call_info *call_info_pointer;
6655
6656 for (call_info_pointer = call_info_root;
6657 call_info_pointer;
6658 call_info_pointer = call_info_pointer->ci_next)
6659 {
6660 elf_symbol_type *esym
6661 = (elf_symbol_type *) call_info_pointer->start_symbol->bsym;
6662 esym->internal_elf_sym.st_size =
6663 S_GET_VALUE (call_info_pointer->end_symbol)
6664 - S_GET_VALUE (call_info_pointer->start_symbol) + 4;
5cf4cd1b
KR
6665 }
6666}
8f78d0e9 6667#endif
This page took 0.359183 seconds and 4 git commands to generate.