* NEWS: Note improvements in C++ support, preliminary thread
[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
3515a504
JL
5119 {
5120 as_bad ("Invalid .SPACE argument");
5121 *input_line_pointer = c;
5122 if (! is_end_of_statement ())
5123 input_line_pointer++;
5124 }
025b0302
ME
5125 }
5126 }
5127 print_errors = TRUE;
5128 }
8f78d0e9
KR
5129
5130 /* If create_flag is nonzero, then create the new space with
5131 the attributes computed above. Else set the values in
5132 an already existing space -- this can only happen for
5133 the first occurence of a built-in space. */
025b0302 5134 if (create_flag)
8f78d0e9
KR
5135 space = create_new_space (space_name, spnum, loadable, defined,
5136 private, sort, seg, 1);
025b0302 5137 else
8f78d0e9 5138 {
025b0302
ME
5139 space = is_defined_space (space_name);
5140 SPACE_SPNUM (space) = spnum;
5141 SPACE_LOADABLE (space) = loadable & 1;
5142 SPACE_DEFINED (space) = defined & 1;
8f78d0e9 5143 SPACE_USER_DEFINED (space) = 1;
025b0302
ME
5144 SPACE_PRIVATE (space) = private & 1;
5145 SPACE_SORT (space) = sort & 0xff;
025b0302
ME
5146 space->sd_seg = seg;
5147 }
5148 return space;
5149}
5150
8f78d0e9
KR
5151/* Adjust the frag's alignment according to the alignment needs
5152 of the given subspace/subsegment. */
5153
5154static void
025b0302 5155pa_align_subseg (seg, subseg)
8f78d0e9 5156 asection *seg;
025b0302
ME
5157 subsegT subseg;
5158{
8f78d0e9 5159 ssd_chain_struct *now_subspace;
025b0302 5160 int alignment;
8f78d0e9 5161 int shift = 0;
025b0302
ME
5162
5163 now_subspace = pa_subsegment_to_subspace (seg, subseg);
8f78d0e9
KR
5164 if (now_subspace)
5165 {
5166 if (SUBSPACE_ALIGN (now_subspace) == 0)
5167 alignment = now_subspace->ssd_last_align;
5168 else if (now_subspace->ssd_last_align > SUBSPACE_ALIGN (now_subspace))
5169 alignment = now_subspace->ssd_last_align;
5170 else
5171 alignment = SUBSPACE_ALIGN (now_subspace);
5172
5173 while ((1 << shift) < alignment)
5174 shift++;
5175 }
025b0302 5176 else
8f78d0e9 5177 shift = bfd_get_section_alignment (stdoutput, seg);
025b0302
ME
5178
5179 frag_align (shift, 0);
5180}
5181
8f78d0e9
KR
5182/* Handle a .SPACE pseudo-op; this switches the current space to the
5183 given space, creating the new space if necessary. */
5184
5185static void
5186pa_space (unused)
5187 int unused;
025b0302 5188{
aa8b30ed 5189 char *name, c, *space_name, *save_s;
8f78d0e9
KR
5190 int temp;
5191 sd_chain_struct *sd_chain;
025b0302
ME
5192
5193 if (within_procedure)
5194 {
5195 as_bad ("Can\'t change spaces within a procedure definition. Ignored");
5196 ignore_rest_of_line ();
5197 }
5198 else
5199 {
8f78d0e9
KR
5200 /* Check for some of the predefined spaces. FIXME: most of the code
5201 below is repeated several times, can we extract the common parts
5202 and place them into a subroutine or something similar? */
025b0302
ME
5203 if (strncasecmp (input_line_pointer, "$text$", 6) == 0)
5204 {
5205 input_line_pointer += 6;
5206 sd_chain = is_defined_space ("$TEXT$");
5207 if (sd_chain == NULL)
5208 sd_chain = pa_parse_space_stmt ("$TEXT$", 1);
8f78d0e9 5209 else if (SPACE_USER_DEFINED (sd_chain) == 0)
025b0302
ME
5210 sd_chain = pa_parse_space_stmt ("$TEXT$", 0);
5211
5212 current_space = sd_chain;
8f78d0e9
KR
5213
5214 /* No need to align if we are already there. */
5215 if (now_seg != text_section)
025b0302
ME
5216 pa_align_subseg (now_seg, now_subseg);
5217
80aab579 5218 subseg_set (text_section, sd_chain->sd_last_subseg);
8f78d0e9
KR
5219
5220 current_subspace
5221 = pa_subsegment_to_subspace (text_section,
5222 sd_chain->sd_last_subseg);
025b0302
ME
5223 demand_empty_rest_of_line ();
5224 return;
5225 }
5226 if (strncasecmp (input_line_pointer, "$private$", 9) == 0)
5227 {
5228 input_line_pointer += 9;
5229 sd_chain = is_defined_space ("$PRIVATE$");
5230 if (sd_chain == NULL)
5231 sd_chain = pa_parse_space_stmt ("$PRIVATE$", 1);
8f78d0e9 5232 else if (SPACE_USER_DEFINED (sd_chain) == 0)
025b0302
ME
5233 sd_chain = pa_parse_space_stmt ("$PRIVATE$", 0);
5234
5235 current_space = sd_chain;
8f78d0e9
KR
5236
5237 /* No need to align if we are already there. */
5238 if (now_seg != data_section)
025b0302 5239 pa_align_subseg (now_seg, now_subseg);
8f78d0e9 5240
80aab579 5241 subseg_set (data_section, sd_chain->sd_last_subseg);
8f78d0e9
KR
5242 current_subspace
5243 = pa_subsegment_to_subspace (data_section,
5244 sd_chain->sd_last_subseg);
025b0302
ME
5245 demand_empty_rest_of_line ();
5246 return;
5247 }
8f78d0e9
KR
5248 if (!strncasecmp (input_line_pointer,
5249 GDB_DEBUG_SPACE_NAME,
5250 strlen (GDB_DEBUG_SPACE_NAME)))
025b0302
ME
5251 {
5252 input_line_pointer += strlen (GDB_DEBUG_SPACE_NAME);
5253 sd_chain = is_defined_space (GDB_DEBUG_SPACE_NAME);
5254 if (sd_chain == NULL)
5255 sd_chain = pa_parse_space_stmt (GDB_DEBUG_SPACE_NAME, 1);
8f78d0e9 5256 else if (SPACE_USER_DEFINED (sd_chain) == 0)
025b0302
ME
5257 sd_chain = pa_parse_space_stmt (GDB_DEBUG_SPACE_NAME, 0);
5258
5259 current_space = sd_chain;
80aab579 5260
5cf4cd1b 5261 {
8f78d0e9
KR
5262 asection *gdb_section
5263 = bfd_make_section_old_way (stdoutput, GDB_DEBUG_SPACE_NAME);
5264
5265 /* No need to align if we are already there. */
80aab579 5266 if (strcmp (segment_name (now_seg), GDB_DEBUG_SPACE_NAME) != 0)
5cf4cd1b 5267 pa_align_subseg (now_seg, now_subseg);
8f78d0e9
KR
5268
5269 subseg_set (gdb_section, sd_chain->sd_last_subseg);
5270 current_subspace
5271 = pa_subsegment_to_subspace (gdb_section,
5272 sd_chain->sd_last_subseg);
5cf4cd1b 5273 }
025b0302
ME
5274 demand_empty_rest_of_line ();
5275 return;
5276 }
5277
8f78d0e9 5278 /* It could be a space specified by number. */
aa8b30ed
JL
5279 print_errors = 0;
5280 save_s = input_line_pointer;
8f78d0e9 5281 if ((temp = pa_parse_number (&input_line_pointer, 0)) >= 0)
025b0302
ME
5282 {
5283 if (sd_chain = pa_find_space_by_number (temp))
5284 {
5285 current_space = sd_chain;
8f78d0e9
KR
5286
5287 if (now_seg != sd_chain->sd_seg)
025b0302 5288 pa_align_subseg (now_seg, now_subseg);
80aab579 5289 subseg_set (sd_chain->sd_seg, sd_chain->sd_last_subseg);
8f78d0e9
KR
5290 current_subspace
5291 = pa_subsegment_to_subspace (sd_chain->sd_seg,
5292 sd_chain->sd_last_subseg);
025b0302
ME
5293 demand_empty_rest_of_line ();
5294 return;
5295 }
5296 }
5297
8f78d0e9 5298 /* Not a number, attempt to create a new space. */
aa8b30ed
JL
5299 print_errors = 1;
5300 input_line_pointer = save_s;
025b0302
ME
5301 name = input_line_pointer;
5302 c = get_symbol_end ();
8f78d0e9 5303 space_name = xmalloc (strlen (name) + 1);
025b0302
ME
5304 strcpy (space_name, name);
5305 *input_line_pointer = c;
5306
5307 sd_chain = pa_parse_space_stmt (space_name, 1);
5308 current_space = sd_chain;
8f78d0e9
KR
5309
5310 if (now_seg != sd_chain->sd_seg)
025b0302 5311 pa_align_subseg (now_seg, now_subseg);
80aab579 5312 subseg_set (sd_chain->sd_seg, sd_chain->sd_last_subseg);
025b0302
ME
5313 current_subspace = pa_subsegment_to_subspace (sd_chain->sd_seg,
5314 sd_chain->sd_last_subseg);
5315 demand_empty_rest_of_line ();
5316 }
5317 return;
5318}
5319
8f78d0e9
KR
5320/* Switch to a new space. (I think). FIXME. */
5321
5322static void
5323pa_spnum (unused)
5324 int unused;
025b0302 5325{
8f78d0e9
KR
5326 char *name;
5327 char c;
5328 char *p;
5329 sd_chain_struct *space;
025b0302
ME
5330
5331 name = input_line_pointer;
5332 c = get_symbol_end ();
5333 space = is_defined_space (name);
5334 if (space)
5335 {
5336 p = frag_more (4);
025b0302
ME
5337 md_number_to_chars (p, SPACE_SPNUM (space), 4);
5338 }
5339 else
5340 as_warn ("Undefined space: '%s' Assuming space number = 0.", name);
5341
5342 *input_line_pointer = c;
5343 demand_empty_rest_of_line ();
5344 return;
5345}
5346
8f78d0e9 5347/* If VALUE is an exact power of two between zero and 2^31, then
aa8b30ed 5348 return log2 (VALUE). Else return -1. */
8f78d0e9
KR
5349
5350static int
aa8b30ed 5351log2 (value)
025b0302
ME
5352 int value;
5353{
8f78d0e9 5354 int shift = 0;
025b0302 5355
025b0302
ME
5356 while ((1 << shift) != value && shift < 32)
5357 shift++;
5358
5359 if (shift >= 32)
aa8b30ed 5360 return -1;
8f78d0e9 5361 else
aa8b30ed 5362 return shift;
025b0302
ME
5363}
5364
8f78d0e9
KR
5365/* Handle a .SPACE pseudo-op; this switches the current subspace to the
5366 given subspace, creating the new subspace if necessary.
5367
5368 FIXME. Should mirror pa_space more closely, in particular how
5369 they're broken up into subroutines. */
5370
5371static void
5372pa_subspace (unused)
5373 int unused;
025b0302 5374{
8f78d0e9
KR
5375 char *name, *ss_name, c;
5376 char loadable, code_only, common, dup_common, zero, sort;
5377 int i, access, space_index, alignment, quadrant;
5378 sd_chain_struct *space;
5379 ssd_chain_struct *ssd;
025b0302
ME
5380
5381 if (within_procedure)
5382 {
5383 as_bad ("Can\'t change subspaces within a procedure definition. Ignored");
5384 ignore_rest_of_line ();
5385 }
5386 else
5387 {
5388 name = input_line_pointer;
5389 c = get_symbol_end ();
025b0302
ME
5390 ss_name = xmalloc (strlen (name) + 1);
5391 strcpy (ss_name, name);
025b0302
ME
5392 *input_line_pointer = c;
5393
8f78d0e9 5394 /* Load default values. */
025b0302
ME
5395 sort = 0;
5396 access = 0x7f;
5397 loadable = 1;
5398 common = 0;
5399 dup_common = 0;
5400 code_only = 0;
5401 zero = 0;
8f78d0e9
KR
5402 space_index = ~0;
5403 alignment = 0;
025b0302
ME
5404 quadrant = 0;
5405
8f78d0e9
KR
5406 space = pa_segment_to_space (now_seg);
5407 ssd = is_defined_subspace (name, space->sd_last_subseg);
025b0302
ME
5408 if (ssd)
5409 {
8f78d0e9
KR
5410 subseg_set (ssd->ssd_seg, ssd->ssd_subseg);
5411 if (!is_end_of_statement ())
5412 as_warn ("Parameters of an existing subspace can\'t be modified");
5413 demand_empty_rest_of_line ();
5414 return;
025b0302
ME
5415 }
5416 else
5417 {
8f78d0e9 5418 /* A new subspace. Load default values. */
025b0302
ME
5419 i = 0;
5420 while (pa_def_subspaces[i].name)
5421 {
5422 if (strcasecmp (pa_def_subspaces[i].name, ss_name) == 0)
5423 {
5424 loadable = pa_def_subspaces[i].loadable;
5425 common = pa_def_subspaces[i].common;
5426 dup_common = pa_def_subspaces[i].dup_common;
5427 code_only = pa_def_subspaces[i].code_only;
5428 zero = pa_def_subspaces[i].zero;
5429 space_index = pa_def_subspaces[i].space_index;
8f78d0e9 5430 alignment = pa_def_subspaces[i].alignment;
025b0302
ME
5431 quadrant = pa_def_subspaces[i].quadrant;
5432 access = pa_def_subspaces[i].access;
5433 sort = pa_def_subspaces[i].sort;
5434 break;
5435 }
5436 i++;
5437 }
5438 }
5439
8f78d0e9
KR
5440 /* We should be working with a new subspace now. Fill in
5441 any information as specified by the user. */
025b0302
ME
5442 if (!is_end_of_statement ())
5443 {
5444 input_line_pointer++;
5445 while (!is_end_of_statement ())
5446 {
5447 name = input_line_pointer;
5448 c = get_symbol_end ();
5449 if ((strncasecmp (name, "QUAD", 4) == 0))
5450 {
5451 *input_line_pointer = c;
5452 input_line_pointer++;
8f78d0e9 5453 quadrant = get_absolute_expression ();
025b0302
ME
5454 }
5455 else if ((strncasecmp (name, "ALIGN", 5) == 0))
5456 {
5457 *input_line_pointer = c;
5458 input_line_pointer++;
8f78d0e9 5459 alignment = get_absolute_expression ();
aa8b30ed 5460 if (log2 (alignment) == -1)
025b0302
ME
5461 {
5462 as_bad ("Alignment must be a power of 2");
5463 alignment = 1;
5464 }
5465 }
5466 else if ((strncasecmp (name, "ACCESS", 6) == 0))
5467 {
5468 *input_line_pointer = c;
5469 input_line_pointer++;
8f78d0e9 5470 access = get_absolute_expression ();
025b0302
ME
5471 }
5472 else if ((strncasecmp (name, "SORT", 4) == 0))
5473 {
5474 *input_line_pointer = c;
5475 input_line_pointer++;
8f78d0e9 5476 sort = get_absolute_expression ();
025b0302
ME
5477 }
5478 else if ((strncasecmp (name, "CODE_ONLY", 9) == 0))
5479 {
5480 *input_line_pointer = c;
5481 code_only = 1;
5482 }
5483 else if ((strncasecmp (name, "UNLOADABLE", 10) == 0))
5484 {
5485 *input_line_pointer = c;
5486 loadable = 0;
5487 }
5488 else if ((strncasecmp (name, "COMMON", 6) == 0))
5489 {
5490 *input_line_pointer = c;
5491 common = 1;
5492 }
5493 else if ((strncasecmp (name, "DUP_COMM", 8) == 0))
5494 {
5495 *input_line_pointer = c;
5496 dup_common = 1;
5497 }
5498 else if ((strncasecmp (name, "ZERO", 4) == 0))
5499 {
5500 *input_line_pointer = c;
5501 zero = 1;
5502 }
8f78d0e9
KR
5503 else if ((strncasecmp (name, "FIRST", 5) == 0))
5504 as_bad ("FIRST not supported as a .SUBSPACE argument");
025b0302 5505 else
8f78d0e9 5506 as_bad ("Invalid .SUBSPACE argument");
025b0302
ME
5507 if (!is_end_of_statement ())
5508 input_line_pointer++;
5509 }
5510 }
8f78d0e9
KR
5511
5512 /* Now that all the flags are set, update an existing subspace,
5513 or create a new one with the given flags if the subspace does
5514 not currently exist. */
025b0302
ME
5515 space = pa_segment_to_space (now_seg);
5516 if (ssd)
8f78d0e9
KR
5517 current_subspace = update_subspace (ss_name, loadable, code_only,
5518 common, dup_common, sort, zero,
5519 access, space_index, alignment,
5520 quadrant, ssd->ssd_subseg);
025b0302 5521 else
8f78d0e9
KR
5522 current_subspace = create_new_subspace (space, ss_name, loadable,
5523 code_only, common,
5524 dup_common, zero, sort,
5525 access, space_index,
5526 alignment, quadrant, now_seg);
5527 SUBSPACE_SUBSPACE_START (current_subspace) = pa_subspace_start (space,
5528 quadrant);
025b0302
ME
5529
5530 demand_empty_rest_of_line ();
80aab579 5531 subseg_set (current_subspace->ssd_seg, current_subspace->ssd_subseg);
025b0302
ME
5532 }
5533 return;
5534}
5535
025b0302 5536
8f78d0e9 5537/* Create default space and subspace dictionaries. */
025b0302 5538
8f78d0e9 5539static void
025b0302
ME
5540pa_spaces_begin ()
5541{
8f78d0e9 5542 sd_chain_struct *space;
025b0302 5543 int i;
025b0302
ME
5544
5545 space_dict_root = NULL;
5546 space_dict_last = NULL;
5547
025b0302
ME
5548 i = 0;
5549 while (pa_def_spaces[i].name)
5550 {
5551 if (pa_def_spaces[i].alias)
5552 pa_def_spaces[i].segment = subseg_new (pa_def_spaces[i].alias, 0);
5553 else
8f78d0e9
KR
5554 pa_def_spaces[i].segment
5555 = bfd_make_section_old_way (stdoutput, pa_def_spaces[i].name);
025b0302
ME
5556
5557 create_new_space (pa_def_spaces[i].name, pa_def_spaces[i].spnum,
5558 pa_def_spaces[i].loadable, pa_def_spaces[i].defined,
8f78d0e9
KR
5559 pa_def_spaces[i].private, pa_def_spaces[i].sort,
5560 pa_def_spaces[i].segment, 0);
025b0302
ME
5561 i++;
5562 }
5563
5564 i = 0;
5565 while (pa_def_subspaces[i].name)
5566 {
5567 space = pa_segment_to_space (pa_def_spaces[pa_def_subspaces[i].def_space_index].segment);
5568 if (space)
5569 {
5570 char *name = pa_def_subspaces[i].alias;
5571 if (!name)
5572 name = pa_def_subspaces[i].name;
5573 create_new_subspace (space, name,
025b0302 5574 pa_def_subspaces[i].loadable,
8f78d0e9
KR
5575 pa_def_subspaces[i].code_only,
5576 pa_def_subspaces[i].common,
5577 pa_def_subspaces[i].dup_common,
5578 pa_def_subspaces[i].zero,
5579 pa_def_subspaces[i].sort,
5580 pa_def_subspaces[i].access,
025b0302
ME
5581 pa_def_subspaces[i].space_index,
5582 pa_def_subspaces[i].alignment,
5583 pa_def_subspaces[i].quadrant,
8f78d0e9 5584 pa_def_spaces[pa_def_subspaces[i].def_space_index].segment);
025b0302
ME
5585 subseg_new (name, pa_def_subspaces[i].subsegment);
5586 }
5587 else
5588 as_fatal ("Internal error: space missing for subspace \"%s\"\n",
5589 pa_def_subspaces[i].name);
5590 i++;
5591 }
5592}
5593
8f78d0e9
KR
5594
5595
5596/* Create a new space NAME, with the appropriate flags as defined
5597 by the given parameters.
5598
5599 Add the new space to the space dictionary chain in numerical
5600 order as defined by the SORT entries. */
5601
5602static sd_chain_struct *
5603create_new_space (name, spnum, loadable, defined, private,
5604 sort, seg, user_defined)
025b0302
ME
5605 char *name;
5606 int spnum;
5607 char loadable;
5608 char defined;
5609 char private;
5610 char sort;
025b0302 5611 asection *seg;
8f78d0e9 5612 int user_defined;
025b0302 5613{
8f78d0e9
KR
5614 sd_chain_struct *chain_entry;
5615
5616 chain_entry = (sd_chain_struct *) xmalloc (sizeof (sd_chain_struct));
025b0302 5617 if (!chain_entry)
8f78d0e9
KR
5618 as_fatal ("Out of memory: could not allocate new space chain entry: %s\n",
5619 name);
025b0302
ME
5620
5621 SPACE_NAME (chain_entry) = (char *) xmalloc (strlen (name) + 1);
5622 strcpy (SPACE_NAME (chain_entry), name);
8f78d0e9
KR
5623 SPACE_NAME_INDEX (chain_entry) = 0;
5624 SPACE_LOADABLE (chain_entry) = loadable;
5625 SPACE_DEFINED (chain_entry) = defined;
5626 SPACE_USER_DEFINED (chain_entry) = user_defined;
5627 SPACE_PRIVATE (chain_entry) = private;
5628 SPACE_SPNUM (chain_entry) = spnum;
5629 SPACE_SORT (chain_entry) = sort;
025b0302 5630
025b0302
ME
5631 chain_entry->sd_seg = seg;
5632 chain_entry->sd_last_subseg = -1;
5633 chain_entry->sd_next = NULL;
5634
8f78d0e9 5635 /* Find spot for the new space based on its sort key. */
025b0302
ME
5636 if (!space_dict_last)
5637 space_dict_last = chain_entry;
5638
8f78d0e9 5639 if (space_dict_root == NULL)
025b0302
ME
5640 space_dict_root = chain_entry;
5641 else
5642 {
8f78d0e9
KR
5643 sd_chain_struct *chain_pointer;
5644 sd_chain_struct *prev_chain_pointer;
025b0302 5645
8f78d0e9
KR
5646 chain_pointer = space_dict_root;
5647 prev_chain_pointer = NULL;
025b0302 5648
8f78d0e9 5649 while (chain_pointer)
025b0302 5650 {
8f78d0e9 5651 if (SPACE_SORT (chain_pointer) <= SPACE_SORT (chain_entry))
025b0302 5652 {
8f78d0e9
KR
5653 prev_chain_pointer = chain_pointer;
5654 chain_pointer = chain_pointer->sd_next;
025b0302 5655 }
8f78d0e9
KR
5656 else
5657 break;
025b0302
ME
5658 }
5659
8f78d0e9
KR
5660 /* At this point we've found the correct place to add the new
5661 entry. So add it and update the linked lists as appropriate. */
5662 if (prev_chain_pointer)
025b0302 5663 {
8f78d0e9
KR
5664 chain_entry->sd_next = chain_pointer;
5665 prev_chain_pointer->sd_next = chain_entry;
025b0302
ME
5666 }
5667 else
5668 {
5669 space_dict_root = chain_entry;
8f78d0e9 5670 chain_entry->sd_next = chain_pointer;
025b0302
ME
5671 }
5672
5673 if (chain_entry->sd_next == NULL)
5674 space_dict_last = chain_entry;
5675 }
5676
5677 return chain_entry;
5678}
5679
8f78d0e9
KR
5680/* Create a new subspace NAME, with the appropriate flags as defined
5681 by the given parameters.
5682
5683 Add the new subspace to the subspace dictionary chain in numerical
5684 order as defined by the SORT entries. */
5685
5686static ssd_chain_struct *
5687create_new_subspace (space, name, loadable, code_only, common,
5688 dup_common, is_zero, sort, access, space_index,
5689 alignment, quadrant, seg)
5690 sd_chain_struct *space;
025b0302 5691 char *name;
8f78d0e9 5692 char loadable, code_only, common, dup_common, is_zero;
025b0302
ME
5693 char sort;
5694 int access;
5695 int space_index;
5696 int alignment;
5697 int quadrant;
5698 asection *seg;
5699{
8f78d0e9 5700 ssd_chain_struct *chain_entry;
025b0302
ME
5701 symbolS *start_symbol;
5702
8f78d0e9 5703 chain_entry = (ssd_chain_struct *) xmalloc (sizeof (ssd_chain_struct));
025b0302
ME
5704 if (!chain_entry)
5705 as_fatal ("Out of memory: could not allocate new subspace chain entry: %s\n", name);
5706
025b0302
ME
5707 SUBSPACE_NAME (chain_entry) = (char *) xmalloc (strlen (name) + 1);
5708 strcpy (SUBSPACE_NAME (chain_entry), name);
5709
8f78d0e9
KR
5710 SUBSPACE_ACCESS (chain_entry) = access;
5711 SUBSPACE_LOADABLE (chain_entry) = loadable;
5712 SUBSPACE_COMMON (chain_entry) = common;
5713 SUBSPACE_DUP_COMM (chain_entry) = dup_common;
5714 SUBSPACE_SORT (chain_entry) = sort;
5715 SUBSPACE_CODE_ONLY (chain_entry) = code_only;
5716 SUBSPACE_ALIGN (chain_entry) = alignment;
5717 SUBSPACE_QUADRANT (chain_entry) = quadrant;
025b0302 5718 SUBSPACE_SUBSPACE_START (chain_entry) = pa_subspace_start (space, quadrant);
8f78d0e9
KR
5719 SUBSPACE_SPACE_INDEX (chain_entry) = space_index;
5720 SUBSPACE_ZERO (chain_entry) = is_zero;
025b0302 5721
025b0302
ME
5722 chain_entry->ssd_subseg = pa_next_subseg (space);
5723 chain_entry->ssd_seg = seg;
025b0302
ME
5724 chain_entry->ssd_last_align = 1;
5725 chain_entry->ssd_next = NULL;
5726
8f78d0e9
KR
5727 /* Find spot for the new subspace based on its sort key. */
5728 if (space->sd_subspaces == NULL)
025b0302
ME
5729 space->sd_subspaces = chain_entry;
5730 else
5731 {
8f78d0e9
KR
5732 ssd_chain_struct *chain_pointer;
5733 ssd_chain_struct *prev_chain_pointer;
025b0302 5734
8f78d0e9
KR
5735 chain_pointer = space->sd_subspaces;
5736 prev_chain_pointer = NULL;
025b0302 5737
8f78d0e9 5738 while (chain_pointer)
025b0302 5739 {
8f78d0e9 5740 if (SUBSPACE_SORT (chain_pointer) <= SUBSPACE_SORT (chain_entry))
025b0302 5741 {
8f78d0e9
KR
5742 prev_chain_pointer = chain_pointer;
5743 chain_pointer = chain_pointer->ssd_next;
025b0302 5744 }
8f78d0e9
KR
5745 else
5746 break;
5747
025b0302
ME
5748 }
5749
8f78d0e9
KR
5750 /* Now we have somewhere to put the new entry. Insert it and update
5751 the links. */
5752 if (prev_chain_pointer)
025b0302 5753 {
8f78d0e9
KR
5754 chain_entry->ssd_next = chain_pointer;
5755 prev_chain_pointer->ssd_next = chain_entry;
025b0302
ME
5756 }
5757 else
5758 {
5759 space->sd_subspaces = chain_entry;
8f78d0e9 5760 chain_entry->ssd_next = chain_pointer;
025b0302
ME
5761 }
5762 }
5763
025b0302
ME
5764 return chain_entry;
5765
5766}
5767
8f78d0e9
KR
5768/* Update the information for the given subspace based upon the
5769 various arguments. Return the modified subspace chain entry. */
5770
5771static ssd_chain_struct *
5772update_subspace (name, loadable, code_only, common, dup_common, sort,
5773 zero, access, space_index, alignment, quadrant, subseg)
025b0302 5774 char *name;
8f78d0e9
KR
5775 char loadable;
5776 char code_only;
5777 char common;
5778 char dup_common;
5779 char zero;
025b0302
ME
5780 char sort;
5781 int access;
5782 int space_index;
5783 int alignment;
5784 int quadrant;
5785 subsegT subseg;
5786{
8f78d0e9 5787 ssd_chain_struct *chain_entry;
025b0302
ME
5788
5789 if ((chain_entry = is_defined_subspace (name, subseg)))
5790 {
8f78d0e9
KR
5791 SUBSPACE_ACCESS (chain_entry) = access;
5792 SUBSPACE_LOADABLE (chain_entry) = loadable;
5793 SUBSPACE_COMMON (chain_entry) = common;
5794 SUBSPACE_DUP_COMM (chain_entry) = dup_common;
5795 SUBSPACE_CODE_ONLY (chain_entry) = 1;
5796 SUBSPACE_SORT (chain_entry) = sort;
5797 SUBSPACE_ALIGN (chain_entry) = alignment;
5798 SUBSPACE_QUADRANT (chain_entry) = quadrant;
5799 SUBSPACE_SPACE_INDEX (chain_entry) = space_index;
025b0302
ME
5800 SUBSPACE_ZERO (chain_entry) = zero;
5801 }
5802 else
5803 chain_entry = NULL;
5804
5805 return chain_entry;
5806
5807}
5808
8f78d0e9
KR
5809/* Return the space chain entry for the space with the name NAME or
5810 NULL if no such space exists. */
5811
5812static sd_chain_struct *
025b0302
ME
5813is_defined_space (name)
5814 char *name;
5815{
8f78d0e9 5816 sd_chain_struct *chain_pointer;
025b0302 5817
8f78d0e9
KR
5818 for (chain_pointer = space_dict_root;
5819 chain_pointer;
5820 chain_pointer = chain_pointer->sd_next)
025b0302 5821 {
8f78d0e9
KR
5822 if (strcmp (SPACE_NAME (chain_pointer), name) == 0)
5823 return chain_pointer;
025b0302
ME
5824 }
5825
8f78d0e9 5826 /* No mapping from segment to space was found. Return NULL. */
025b0302
ME
5827 return NULL;
5828}
5829
8f78d0e9
KR
5830/* Find and return the space associated with the given seg. If no mapping
5831 from the given seg to a space is found, then return NULL.
5832
5833 Unlike subspaces, the number of spaces is not expected to grow much,
5834 so a linear exhaustive search is OK here. */
5835
5836static sd_chain_struct *
025b0302
ME
5837pa_segment_to_space (seg)
5838 asection *seg;
5839{
8f78d0e9 5840 sd_chain_struct *space_chain;
025b0302 5841
8f78d0e9
KR
5842 /* Walk through each space looking for the correct mapping. */
5843 for (space_chain = space_dict_root;
5844 space_chain;
5845 space_chain = space_chain->sd_next)
025b0302 5846 {
8f78d0e9
KR
5847 if (space_chain->sd_seg == seg)
5848 return space_chain;
025b0302
ME
5849 }
5850
8f78d0e9 5851 /* Mapping was not found. Return NULL. */
025b0302
ME
5852 return NULL;
5853}
5854
8f78d0e9
KR
5855/* Return the space chain entry for the subspace with the name NAME or
5856 NULL if no such subspace exists.
5857
5858 Uses a linear search through all the spaces and subspaces, this may
5859 not be appropriate if we ever being placing each function in its
5860 own subspace. */
5861
5862static ssd_chain_struct *
025b0302
ME
5863is_defined_subspace (name, subseg)
5864 char *name;
5865 subsegT subseg;
5866{
8f78d0e9
KR
5867 sd_chain_struct*space_chain;
5868 ssd_chain_struct *subspace_chain;
025b0302 5869
8f78d0e9
KR
5870 /* Walk through each space. */
5871 for (space_chain = space_dict_root;
5872 space_chain;
5873 space_chain = space_chain->sd_next)
025b0302 5874 {
8f78d0e9
KR
5875 /* Walk through each subspace looking for a name which matches. */
5876 for (subspace_chain = space_chain->sd_subspaces;
5877 subspace_chain;
5878 subspace_chain = subspace_chain->ssd_next)
5879 if (strcmp (SUBSPACE_NAME (subspace_chain), name) == 0)
5880 return subspace_chain;
025b0302 5881 }
8f78d0e9
KR
5882
5883 /* Subspace wasn't found. Return NULL. */
025b0302
ME
5884 return NULL;
5885}
5886
8f78d0e9
KR
5887/* Find and return the subspace associated with the given seg. If no
5888 mapping from the given seg to a subspace is found, then return NULL.
5889
5890 If we ever put each procedure/function within its own subspace
5891 (to make life easier on the compiler and linker), then this will have
5892 to become more efficient. */
5893
5894static ssd_chain_struct *
025b0302
ME
5895pa_subsegment_to_subspace (seg, subseg)
5896 asection *seg;
5897 subsegT subseg;
5898{
8f78d0e9
KR
5899 sd_chain_struct *space_chain;
5900 ssd_chain_struct *subspace_chain;
025b0302 5901
8f78d0e9
KR
5902 /* Walk through each space. */
5903 for (space_chain = space_dict_root;
5904 space_chain;
5905 space_chain = space_chain->sd_next)
025b0302 5906 {
8f78d0e9 5907 if (space_chain->sd_seg == seg)
025b0302 5908 {
8f78d0e9
KR
5909 /* Walk through each subspace within each space looking for
5910 the correct mapping. */
5911 for (subspace_chain = space_chain->sd_subspaces;
5912 subspace_chain;
5913 subspace_chain = subspace_chain->ssd_next)
5914 if (subspace_chain->ssd_subseg == (int) subseg)
5915 return subspace_chain;
025b0302
ME
5916 }
5917 }
5918
8f78d0e9 5919 /* No mapping from subsegment to subspace found. Return NULL. */
025b0302
ME
5920 return NULL;
5921}
5922
8f78d0e9
KR
5923/* Given a number, try and find a space with the name number.
5924
5925 Return a pointer to a space dictionary chain entry for the space
5926 that was found or NULL on failure. */
5927
5928static sd_chain_struct *
025b0302
ME
5929pa_find_space_by_number (number)
5930 int number;
5931{
8f78d0e9 5932 sd_chain_struct *space_chain;
025b0302 5933
8f78d0e9
KR
5934 for (space_chain = space_dict_root;
5935 space_chain;
5936 space_chain = space_chain->sd_next)
025b0302 5937 {
8f78d0e9
KR
5938 if (SPACE_SPNUM (space_chain) == number)
5939 return space_chain;
025b0302
ME
5940 }
5941
8f78d0e9 5942 /* No appropriate space found. Return NULL. */
025b0302
ME
5943 return NULL;
5944}
5945
8f78d0e9
KR
5946/* Return the starting address for the given subspace. If the starting
5947 address is unknown then return zero. */
5948
5949static unsigned int
025b0302 5950pa_subspace_start (space, quadrant)
8f78d0e9 5951 sd_chain_struct *space;
025b0302
ME
5952 int quadrant;
5953{
8f78d0e9
KR
5954 /* FIXME. Assumes everyone puts read/write data at 0x4000000, this
5955 is not correct for the PA OSF1 port. */
5956 if ((strcasecmp (SPACE_NAME (space), "$PRIVATE$") == 0) && quadrant == 1)
5957 return 0x40000000;
025b0302 5958 else if (space->sd_seg == data_section && quadrant == 1)
8f78d0e9 5959 return 0x40000000;
025b0302
ME
5960 else
5961 return 0;
5962}
5963
8f78d0e9
KR
5964/* FIXME. Needs documentation. */
5965static int
025b0302 5966pa_next_subseg (space)
8f78d0e9 5967 sd_chain_struct *space;
025b0302
ME
5968{
5969
5970 space->sd_last_subseg++;
5971 return space->sd_last_subseg;
5972}
5973
8f78d0e9
KR
5974/* Helper function for pa_stringer. Used to find the end of
5975 a string. */
5976
025b0302
ME
5977static unsigned int
5978pa_stringer_aux (s)
5979 char *s;
5980{
5981 unsigned int c = *s & CHAR_MASK;
5982 switch (c)
5983 {
5984 case '\"':
5985 c = NOT_A_CHAR;
5986 break;
5987 default:
5988 break;
5989 }
5990 return c;
5991}
5992
8f78d0e9
KR
5993/* Handle a .STRING type pseudo-op. */
5994
5995static void
5996pa_stringer (append_zero)
5997 int append_zero;
025b0302 5998{
8f78d0e9 5999 char *s, num_buf[4];
025b0302 6000 unsigned int c;
025b0302
ME
6001 int i;
6002
8f78d0e9
KR
6003 /* Preprocess the string to handle PA-specific escape sequences.
6004 For example, \xDD where DD is a hexidecimal number should be
6005 changed to \OOO where OOO is an octal number. */
025b0302 6006
8f78d0e9
KR
6007 /* Skip the opening quote. */
6008 s = input_line_pointer + 1;
025b0302
ME
6009
6010 while (is_a_char (c = pa_stringer_aux (s++)))
6011 {
6012 if (c == '\\')
6013 {
6014 c = *s;
6015 switch (c)
6016 {
8f78d0e9 6017 /* Handle \x<num>. */
025b0302
ME
6018 case 'x':
6019 {
6020 unsigned int number;
6021 int num_digit;
6022 char dg;
6023 char *s_start = s;
6024
8f78d0e9
KR
6025 /* Get pas the 'x'. */
6026 s++;
025b0302
ME
6027 for (num_digit = 0, number = 0, dg = *s;
6028 num_digit < 2
6029 && (isdigit (dg) || (dg >= 'a' && dg <= 'f')
6030 || (dg >= 'A' && dg <= 'F'));
6031 num_digit++)
6032 {
6033 if (isdigit (dg))
6034 number = number * 16 + dg - '0';
6035 else if (dg >= 'a' && dg <= 'f')
6036 number = number * 16 + dg - 'a' + 10;
6037 else
6038 number = number * 16 + dg - 'A' + 10;
6039
6040 s++;
6041 dg = *s;
6042 }
6043 if (num_digit > 0)
6044 {
6045 switch (num_digit)
6046 {
6047 case 1:
6048 sprintf (num_buf, "%02o", number);
6049 break;
6050 case 2:
6051 sprintf (num_buf, "%03o", number);
6052 break;
6053 }
6054 for (i = 0; i <= num_digit; i++)
6055 s_start[i] = num_buf[i];
6056 }
5cf4cd1b 6057 break;
025b0302 6058 }
8f78d0e9 6059 /* This might be a "\"", skip over the escaped char. */
5cf4cd1b
KR
6060 default:
6061 s++;
025b0302
ME
6062 break;
6063 }
6064 }
6065 }
6066 stringer (append_zero);
6067 pa_undefine_label ();
6068}
6069
8f78d0e9
KR
6070/* Handle a .VERSION pseudo-op. */
6071
6072static void
6073pa_version (unused)
6074 int unused;
025b0302 6075{
8f78d0e9 6076 obj_version (0);
025b0302
ME
6077 pa_undefine_label ();
6078}
6079
8f78d0e9
KR
6080/* Just like a normal cons, but when finished we have to undefine
6081 the latest space label. */
6082
6083static void
025b0302 6084pa_cons (nbytes)
8f78d0e9 6085 int nbytes;
025b0302
ME
6086{
6087 cons (nbytes);
6088 pa_undefine_label ();
6089}
6090
8f78d0e9
KR
6091/* Switch to the data space. As usual delete our label. */
6092
6093static void
6094pa_data (unused)
6095 int unused;
025b0302 6096{
80aab579 6097 s_data (0);
025b0302
ME
6098 pa_undefine_label ();
6099}
6100
8f78d0e9 6101/* FIXME. What's the purpose of this pseudo-op? */
025b0302 6102
8f78d0e9
KR
6103static void
6104pa_desc (unused)
6105 int unused;
6106{
025b0302
ME
6107 pa_undefine_label ();
6108}
6109
8f78d0e9
KR
6110/* Like float_cons, but we need to undefine our label. */
6111
6112static void
025b0302 6113pa_float_cons (float_type)
8f78d0e9 6114 int float_type;
025b0302
ME
6115{
6116 float_cons (float_type);
6117 pa_undefine_label ();
6118}
6119
8f78d0e9
KR
6120/* Like s_fill, but delete our label when finished. */
6121
6122static void
6123pa_fill (unused)
6124 int unused;
025b0302 6125{
80aab579 6126 s_fill (0);
025b0302
ME
6127 pa_undefine_label ();
6128}
6129
8f78d0e9
KR
6130/* Like lcomm, but delete our label when finished. */
6131
6132static void
025b0302 6133pa_lcomm (needs_align)
025b0302
ME
6134 int needs_align;
6135{
6136 s_lcomm (needs_align);
6137 pa_undefine_label ();
6138}
6139
8f78d0e9
KR
6140/* Like lsym, but delete our label when finished. */
6141
6142static void
6143pa_lsym (unused)
6144 int unused;
025b0302 6145{
80aab579 6146 s_lsym (0);
025b0302
ME
6147 pa_undefine_label ();
6148}
6149
8f78d0e9
KR
6150/* Switch to the text space. Like s_text, but delete our
6151 label when finished. */
6152static void
6153pa_text (unused)
6154 int unused;
025b0302 6155{
80aab579 6156 s_text (0);
025b0302
ME
6157 pa_undefine_label ();
6158}
5cf4cd1b 6159
aa8b30ed
JL
6160/* On the PA relocations which involve function symbols must not be
6161 adjusted. This so that the linker can know when/how to create argument
6162 relocation stubs for indirect calls and calls to static functions.
6163
6164 FIXME. Also reject R_HPPA relocations which are 32 bits
6165 wide. Helps with code lables in arrays for SOM. (SOM BFD code
6166 needs to generate relocations to push the addend and symbol value
6167 onto the stack, add them, then pop the value off the stack and
6168 use it in a relocation -- yuk. */
6169
6170int
6171hppa_fix_adjustable (fixp)
6172 fixS *fixp;
6173{
6174 struct hppa_fix_struct *hppa_fix;
6175
6176 hppa_fix = fixp->tc_fix_data;
6177
6178 if (fixp->fx_r_type == R_HPPA && hppa_fix->fx_r_format == 32)
6179 return 0;
6180
6181 if (fixp->fx_addsy == 0
6182 || (fixp->fx_addsy->bsym->flags & BSF_FUNCTION) == 0)
6183 return 1;
6184
6185 return 0;
6186}
6187
8f78d0e9
KR
6188/* Now for some ELF specific code. FIXME. */
6189#ifdef OBJ_ELF
6190static symext_chainS *symext_rootP;
6191static symext_chainS *symext_lastP;
6192
6193/* Do any symbol processing requested by the target-cpu or target-format. */
5cf4cd1b
KR
6194
6195void
6196hppa_tc_symbol (abfd, symbolP, sym_idx)
8f78d0e9
KR
6197 bfd *abfd;
6198 elf_symbol_type *symbolP;
5cf4cd1b
KR
6199 int sym_idx;
6200{
6201 symext_chainS *symextP;
6202 unsigned int arg_reloc;
6203
8f78d0e9 6204 /* Only functions can have argument relocations. */
5cf4cd1b
KR
6205 if (!(symbolP->symbol.flags & BSF_FUNCTION))
6206 return;
6207
6208 arg_reloc = symbolP->tc_data.hppa_arg_reloc;
6209
8f78d0e9
KR
6210 /* If there are no argument relocation bits, then no relocation is
6211 necessary. Do not add this to the symextn section. */
6212 if (arg_reloc == 0)
6213 return;
6214
5cf4cd1b
KR
6215 symextP = (symext_chainS *) bfd_alloc (abfd, sizeof (symext_chainS) * 2);
6216
6217 symextP[0].entry = ELF32_HPPA_SX_WORD (HPPA_SXT_SYMNDX, sym_idx);
6218 symextP[0].next = &symextP[1];
6219
6220 symextP[1].entry = ELF32_HPPA_SX_WORD (HPPA_SXT_ARG_RELOC, arg_reloc);
6221 symextP[1].next = NULL;
6222
6223 if (symext_rootP == NULL)
6224 {
6225 symext_rootP = &symextP[0];
6226 symext_lastP = &symextP[1];
6227 }
6228 else
6229 {
6230 symext_lastP->next = &symextP[0];
6231 symext_lastP = &symextP[1];
6232 }
6233}
6234
8f78d0e9 6235/* Make sections needed by the target cpu and/or target format. */
5cf4cd1b
KR
6236void
6237hppa_tc_make_sections (abfd)
8f78d0e9 6238 bfd *abfd;
5cf4cd1b
KR
6239{
6240 symext_chainS *symextP;
8f78d0e9 6241 int size, n;
5cf4cd1b
KR
6242 asection *symextn_sec;
6243 segT save_seg = now_seg;
6244 subsegT save_subseg = now_subseg;
6245
8f78d0e9
KR
6246 /* Build the symbol extension section. */
6247 hppa_tc_make_symextn_section ();
5cf4cd1b 6248
8f78d0e9
KR
6249 /* Force some calculation to occur. */
6250 bfd_set_section_contents (stdoutput, stdoutput->sections, "", 0, 0);
5cf4cd1b
KR
6251
6252 hppa_elf_stub_finish (abfd);
6253
8f78d0e9 6254 /* If no symbols for the symbol extension section, then stop now. */
5cf4cd1b
KR
6255 if (symext_rootP == NULL)
6256 return;
6257
8f78d0e9 6258 /* Count the number of symbols for the symbol extension section. */
5cf4cd1b
KR
6259 for (n = 0, symextP = symext_rootP; symextP; symextP = symextP->next, ++n)
6260 ;
6261
6262 size = sizeof (symext_entryS) * n;
6263
8f78d0e9
KR
6264 /* Switch to the symbol extension section. */
6265 symextn_sec = subseg_new (SYMEXTN_SECTION_NAME, 0);
5cf4cd1b
KR
6266
6267 frag_wane (frag_now);
6268 frag_new (0);
6269
6270 for (symextP = symext_rootP; symextP; symextP = symextP->next)
6271 {
6272 char *ptr;
8f78d0e9 6273 int *symtab_map = elf_sym_extra (abfd);
5cf4cd1b
KR
6274 int idx;
6275
8f78d0e9
KR
6276 /* First, patch the symbol extension record to reflect the true
6277 symbol table index. */
5cf4cd1b 6278
8f78d0e9 6279 if (ELF32_HPPA_SX_TYPE (symextP->entry) == HPPA_SXT_SYMNDX)
5cf4cd1b 6280 {
8f78d0e9 6281 idx = ELF32_HPPA_SX_VAL (symextP->entry) - 1;
5cf4cd1b 6282 symextP->entry = ELF32_HPPA_SX_WORD (HPPA_SXT_SYMNDX,
8f78d0e9 6283 symtab_map[idx]);
5cf4cd1b
KR
6284 }
6285
8f78d0e9
KR
6286 ptr = frag_more (sizeof (symextP->entry));
6287 md_number_to_chars (ptr, symextP->entry, sizeof (symextP->entry));
5cf4cd1b
KR
6288 }
6289
6290 frag_now->fr_fix = obstack_next_free (&frags) - frag_now->fr_literal;
6291 frag_wane (frag_now);
6292
8f78d0e9
KR
6293 /* Switch back to the original segment. */
6294 subseg_set (save_seg, save_subseg);
5cf4cd1b
KR
6295
6296 return;
6297}
6298
8f78d0e9
KR
6299/* Make the symbol extension section. */
6300
5cf4cd1b 6301static void
8f78d0e9 6302hppa_tc_make_symextn_section ()
5cf4cd1b 6303{
5cf4cd1b
KR
6304 if (symext_rootP)
6305 {
6306 symext_chainS *symextP;
6307 int n;
8f78d0e9 6308 unsigned int size;
5cf4cd1b
KR
6309 segT symextn_sec;
6310 segT save_seg = now_seg;
6311 subsegT save_subseg = now_subseg;
6312
6313 for (n = 0, symextP = symext_rootP; symextP; symextP = symextP->next, ++n)
6314 ;
6315
6316 size = sizeof (symext_entryS) * n;
6317
8f78d0e9 6318 symextn_sec = subseg_new (SYMEXTN_SECTION_NAME, 0);
5cf4cd1b 6319
8f78d0e9
KR
6320 bfd_set_section_flags (stdoutput, symextn_sec,
6321 SEC_LOAD | SEC_HAS_CONTENTS | SEC_DATA);
5cf4cd1b
KR
6322 bfd_set_section_size (stdoutput, symextn_sec, size);
6323
8f78d0e9
KR
6324 /* Now, switch back to the original segment. */
6325 subseg_set (save_seg, save_subseg);
6326 }
6327}
6328
6329/* Build the symbol extension section. */
6330
6331static void
6332pa_build_symextn_section ()
6333{
6334 segT seg;
6335 asection *save_seg = now_seg;
6336 subsegT subseg = (subsegT) 0;
6337 subsegT save_subseg = now_subseg;
6338
6339 seg = subseg_new (".hppa_symextn", subseg);
6340 bfd_set_section_flags (stdoutput,
6341 seg,
6342 SEC_HAS_CONTENTS | SEC_READONLY
6343 | SEC_ALLOC | SEC_LOAD);
6344
6345 subseg_set (save_seg, save_subseg);
6346
6347}
6348
6349/* For ELF, this function serves one purpose: to setup the st_size
6350 field of STT_FUNC symbols. To do this, we need to scan the
6351 call_info structure list, determining st_size in one of two possible
6352 ways:
6353
6354 1. call_info->start_frag->fr_fix has the size of the fragment.
6355 This approach assumes that the function was built into a
6356 single fragment. This works for most cases, but might fail.
6357 For example, if there was a segment change in the middle of
6358 the function.
6359
6360 2. The st_size field is the difference in the addresses of the
6361 call_info->start_frag->fr_address field and the fr_address
6362 field of the next fragment with fr_type == rs_fill and
6363 fr_fix != 0. */
6364
6365void
6366elf_hppa_final_processing ()
6367{
6368 struct call_info *call_info_pointer;
6369
6370 for (call_info_pointer = call_info_root;
6371 call_info_pointer;
6372 call_info_pointer = call_info_pointer->ci_next)
6373 {
6374 elf_symbol_type *esym
6375 = (elf_symbol_type *) call_info_pointer->start_symbol->bsym;
6376 esym->internal_elf_sym.st_size =
6377 S_GET_VALUE (call_info_pointer->end_symbol)
6378 - S_GET_VALUE (call_info_pointer->start_symbol) + 4;
5cf4cd1b
KR
6379 }
6380}
8f78d0e9 6381#endif
This page took 0.319962 seconds and 4 git commands to generate.