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