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