2000-09-12 Kazu Hirata <kazu@hxi.com>
[deliverable/binutils-gdb.git] / gas / config / tc-hppa.c
CommitLineData
252b5132 1/* tc-hppa.c -- Assemble for the PA
ad1079af 2 Copyright (C) 1989, 93, 94, 95, 96, 97, 98, 99, 2000
49309057 3 Free Software Foundation, Inc.
252b5132
RH
4
5 This file is part of GAS, the GNU Assembler.
6
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GAS is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GAS; see the file COPYING. If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA. */
21
252b5132
RH
22/* HP PA-RISC support was contributed by the Center for Software Science
23 at the University of Utah. */
24
25#include <stdio.h>
26#include <ctype.h>
27
28#include "as.h"
29#include "subsegs.h"
30
31#include "bfd/libhppa.h"
252b5132
RH
32
33/* Be careful, this file includes data *declarations*. */
34#include "opcode/hppa.h"
35
49863f82
JL
36#if defined (OBJ_ELF) && defined (OBJ_SOM)
37error only one of OBJ_ELF and OBJ_SOM can be defined
38#endif
39
2d93dcc4
JL
40/* If we are using ELF, then we probably can support dwarf2 debug
41 records. Furthermore, if we are supporting dwarf2 debug records,
42 then we want to use the assembler support for compact line numbers. */
43#ifdef OBJ_ELF
44#include "dwarf2dbg.h"
45struct dwarf2_line_info debug_line;
2d93dcc4 46
252b5132
RH
47/* A "convient" place to put object file dependencies which do
48 not need to be seen outside of tc-hppa.c. */
ad1079af 49
252b5132 50/* Object file formats specify relocation types. */
ad1079af 51typedef enum elf_hppa_reloc_type reloc_type;
252b5132
RH
52
53/* Object file formats specify BFD symbol types. */
54typedef elf_symbol_type obj_symbol_type;
ad1079af
AM
55#define symbol_arg_reloc_info(sym)\
56 (((obj_symbol_type *) symbol_get_bfdsym (sym))->tc_data.hppa_arg_reloc)
252b5132 57
ad1079af 58#if TARGET_ARCH_SIZE == 64
252b5132 59/* How to generate a relocation. */
b388df87
JL
60#define hppa_gen_reloc_type _bfd_elf64_hppa_gen_reloc_type
61#else
62#define hppa_gen_reloc_type _bfd_elf32_hppa_gen_reloc_type
63#endif
252b5132
RH
64
65/* ELF objects can have versions, but apparently do not have anywhere
66 to store a copyright string. */
67#define obj_version obj_elf_version
68#define obj_copyright obj_elf_version
46031ca9
JL
69
70#define UNWIND_SECTION_NAME ".PARISC.unwind"
ad1079af 71#endif /* OBJ_ELF */
252b5132
RH
72
73#ifdef OBJ_SOM
74/* Names of various debugging spaces/subspaces. */
75#define GDB_DEBUG_SPACE_NAME "$GDB_DEBUG$"
76#define GDB_STRINGS_SUBSPACE_NAME "$GDB_STRINGS$"
77#define GDB_SYMBOLS_SUBSPACE_NAME "$GDB_SYMBOLS$"
78#define UNWIND_SECTION_NAME "$UNWIND$"
79
80/* Object file formats specify relocation types. */
81typedef int reloc_type;
82
83/* SOM objects can have both a version string and a copyright string. */
84#define obj_version obj_som_version
85#define obj_copyright obj_som_copyright
86
252b5132
RH
87/* How to generate a relocation. */
88#define hppa_gen_reloc_type hppa_som_gen_reloc_type
89
90/* Object file formats specify BFD symbol types. */
91typedef som_symbol_type obj_symbol_type;
ad1079af
AM
92#define symbol_arg_reloc_info(sym)\
93 (((obj_symbol_type *) symbol_get_bfdsym (sym))->tc_data.ap.hppa_arg_reloc)
252b5132
RH
94
95/* This apparently isn't in older versions of hpux reloc.h. */
96#ifndef R_DLT_REL
97#define R_DLT_REL 0x78
98#endif
252b5132
RH
99
100#ifndef R_N0SEL
101#define R_N0SEL 0xd8
102#endif
103
104#ifndef R_N1SEL
105#define R_N1SEL 0xd9
106#endif
ad1079af 107#endif /* OBJ_SOM */
252b5132
RH
108
109/* Various structures and types used internally in tc-hppa.c. */
110
111/* Unwind table and descriptor. FIXME: Sync this with GDB version. */
112
113struct unwind_desc
114 {
115 unsigned int cannot_unwind:1;
116 unsigned int millicode:1;
117 unsigned int millicode_save_rest:1;
118 unsigned int region_desc:2;
119 unsigned int save_sr:2;
120 unsigned int entry_fr:4;
121 unsigned int entry_gr:5;
122 unsigned int args_stored:1;
123 unsigned int call_fr:5;
124 unsigned int call_gr:5;
125 unsigned int save_sp:1;
126 unsigned int save_rp:1;
127 unsigned int save_rp_in_frame:1;
128 unsigned int extn_ptr_defined:1;
129 unsigned int cleanup_defined:1;
130
131 unsigned int hpe_interrupt_marker:1;
132 unsigned int hpux_interrupt_marker:1;
133 unsigned int reserved:3;
134 unsigned int frame_size:27;
135 };
136
137struct unwind_table
138 {
139 /* Starting and ending offsets of the region described by
140 descriptor. */
141 unsigned int start_offset;
142 unsigned int end_offset;
143 struct unwind_desc descriptor;
144 };
145
146/* This structure is used by the .callinfo, .enter, .leave pseudo-ops to
147 control the entry and exit code they generate. It is also used in
148 creation of the correct stack unwind descriptors.
149
150 NOTE: GAS does not support .enter and .leave for the generation of
151 prologues and epilogues. FIXME.
152
153 The fields in structure roughly correspond to the arguments available on the
154 .callinfo pseudo-op. */
155
156struct call_info
157 {
158 /* The unwind descriptor being built. */
159 struct unwind_table ci_unwind;
160
161 /* Name of this function. */
162 symbolS *start_symbol;
163
164 /* (temporary) symbol used to mark the end of this function. */
165 symbolS *end_symbol;
166
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, W, UW, DW, UDW, QW, UQW
177 }
178fp_operand_format;
179
180/* This fully describes the symbol types which may be attached to
181 an EXPORT or IMPORT directive. Only SOM uses this formation
182 (ELF has no need for it). */
183typedef enum
184 {
185 SYMBOL_TYPE_UNKNOWN,
186 SYMBOL_TYPE_ABSOLUTE,
187 SYMBOL_TYPE_CODE,
188 SYMBOL_TYPE_DATA,
189 SYMBOL_TYPE_ENTRY,
190 SYMBOL_TYPE_MILLICODE,
191 SYMBOL_TYPE_PLABEL,
192 SYMBOL_TYPE_PRI_PROG,
193 SYMBOL_TYPE_SEC_PROG,
194 }
195pa_symbol_type;
196
197/* This structure contains information needed to assemble
198 individual instructions. */
199struct pa_it
200 {
201 /* Holds the opcode after parsing by pa_ip. */
202 unsigned long opcode;
203
204 /* Holds an expression associated with the current instruction. */
205 expressionS exp;
206
207 /* Does this instruction use PC-relative addressing. */
208 int pcrel;
209
210 /* Floating point formats for operand1 and operand2. */
211 fp_operand_format fpof1;
212 fp_operand_format fpof2;
213
1cf6ae67
JL
214 /* Whether or not we saw a truncation request on an fcnv insn. */
215 int trunc;
252b5132
RH
216
217 /* Holds the field selector for this instruction
218 (for example L%, LR%, etc). */
219 long field_selector;
220
221 /* Holds any argument relocation bits associated with this
222 instruction. (instruction should be some sort of call). */
ad1079af 223 unsigned int arg_reloc;
252b5132
RH
224
225 /* The format specification for this instruction. */
226 int format;
227
228 /* The relocation (if any) associated with this instruction. */
229 reloc_type reloc;
230 };
231
232/* PA-89 floating point registers are arranged like this:
233
252b5132
RH
234 +--------------+--------------+
235 | 0 or 16L | 16 or 16R |
236 +--------------+--------------+
237 | 1 or 17L | 17 or 17R |
238 +--------------+--------------+
239 | | |
240
241 . . .
242 . . .
243 . . .
244
245 | | |
246 +--------------+--------------+
247 | 14 or 30L | 30 or 30R |
248 +--------------+--------------+
249 | 15 or 31L | 31 or 31R |
ecacdc7a 250 +--------------+--------------+ */
252b5132
RH
251
252/* Additional information needed to build argument relocation stubs. */
253struct call_desc
254 {
255 /* The argument relocation specification. */
256 unsigned int arg_reloc;
257
258 /* Number of arguments. */
259 unsigned int arg_count;
260 };
261
49863f82 262#ifdef OBJ_SOM
252b5132
RH
263/* This structure defines an entry in the subspace dictionary
264 chain. */
265
266struct subspace_dictionary_chain
267 {
268 /* Nonzero if this space has been defined by the user code. */
269 unsigned int ssd_defined;
270
271 /* Name of this subspace. */
272 char *ssd_name;
273
274 /* GAS segment and subsegment associated with this subspace. */
275 asection *ssd_seg;
276 int ssd_subseg;
277
278 /* Next space in the subspace dictionary chain. */
279 struct subspace_dictionary_chain *ssd_next;
280 };
281
282typedef struct subspace_dictionary_chain ssd_chain_struct;
283
284/* This structure defines an entry in the subspace dictionary
285 chain. */
286
287struct space_dictionary_chain
288 {
289 /* Nonzero if this space has been defined by the user code or
290 as a default space. */
291 unsigned int sd_defined;
292
293 /* Nonzero if this spaces has been defined by the user code. */
294 unsigned int sd_user_defined;
295
296 /* The space number (or index). */
297 unsigned int sd_spnum;
298
299 /* The name of this subspace. */
300 char *sd_name;
301
302 /* GAS segment to which this subspace corresponds. */
303 asection *sd_seg;
304
305 /* Current subsegment number being used. */
306 int sd_last_subseg;
307
308 /* The chain of subspaces contained within this space. */
309 ssd_chain_struct *sd_subspaces;
310
311 /* The next entry in the space dictionary chain. */
312 struct space_dictionary_chain *sd_next;
313 };
314
315typedef struct space_dictionary_chain sd_chain_struct;
316
252b5132
RH
317/* This structure defines attributes of the default subspace
318 dictionary entries. */
319
320struct default_subspace_dict
321 {
322 /* Name of the subspace. */
323 char *name;
324
325 /* FIXME. Is this still needed? */
326 char defined;
327
328 /* Nonzero if this subspace is loadable. */
329 char loadable;
330
331 /* Nonzero if this subspace contains only code. */
332 char code_only;
333
334 /* Nonzero if this is a common subspace. */
335 char common;
336
337 /* Nonzero if this is a common subspace which allows symbols
338 to be multiply defined. */
339 char dup_common;
340
341 /* Nonzero if this subspace should be zero filled. */
342 char zero;
343
344 /* Sort key for this subspace. */
345 unsigned char sort;
346
347 /* Access control bits for this subspace. Can represent RWX access
348 as well as privilege level changes for gateways. */
349 int access;
350
351 /* Index of containing space. */
352 int space_index;
353
354 /* Alignment (in bytes) of this subspace. */
355 int alignment;
356
357 /* Quadrant within space where this subspace should be loaded. */
358 int quadrant;
359
360 /* An index into the default spaces array. */
361 int def_space_index;
362
252b5132
RH
363 /* Subsegment associated with this subspace. */
364 subsegT subsegment;
365 };
366
367/* This structure defines attributes of the default space
368 dictionary entries. */
369
370struct default_space_dict
371 {
372 /* Name of the space. */
373 char *name;
374
375 /* Space number. It is possible to identify spaces within
376 assembly code numerically! */
377 int spnum;
378
379 /* Nonzero if this space is loadable. */
380 char loadable;
381
382 /* Nonzero if this space is "defined". FIXME is still needed */
383 char defined;
384
385 /* Nonzero if this space can not be shared. */
386 char private;
387
388 /* Sort key for this space. */
389 unsigned char sort;
390
391 /* Segment associated with this space. */
392 asection *segment;
252b5132 393 };
49863f82
JL
394#endif
395
396/* Structure for previous label tracking. Needed so that alignments,
397 callinfo declarations, etc can be easily attached to a particular
398 label. */
399typedef struct label_symbol_struct
400 {
401 struct symbol *lss_label;
402#ifdef OBJ_SOM
403 sd_chain_struct *lss_space;
404#endif
405#ifdef OBJ_ELF
406 segT lss_segment;
407#endif
408 struct label_symbol_struct *lss_next;
409 }
410label_symbol_struct;
252b5132
RH
411
412/* Extra information needed to perform fixups (relocations) on the PA. */
413struct hppa_fix_struct
414 {
415 /* The field selector. */
416 enum hppa_reloc_field_selector_type_alt fx_r_field;
417
418 /* Type of fixup. */
419 int fx_r_type;
420
421 /* Format of fixup. */
422 int fx_r_format;
423
424 /* Argument relocation bits. */
ad1079af 425 unsigned int fx_arg_reloc;
252b5132
RH
426
427 /* The segment this fixup appears in. */
428 segT segment;
429 };
430
431/* Structure to hold information about predefined registers. */
432
433struct pd_reg
434 {
435 char *name;
436 int value;
437 };
438
439/* This structure defines the mapping from a FP condition string
440 to a condition number which can be recorded in an instruction. */
441struct fp_cond_map
442 {
443 char *string;
444 int cond;
445 };
446
447/* This structure defines a mapping from a field selector
448 string to a field selector type. */
449struct selector_entry
450 {
451 char *prefix;
452 int field_selector;
453 };
454
455/* Prototypes for functions local to tc-hppa.c. */
456
49863f82 457#ifdef OBJ_SOM
252b5132 458static void pa_check_current_space_and_subspace PARAMS ((void));
49863f82
JL
459#endif
460
ad1079af
AM
461#if !(defined (OBJ_ELF) && defined (TE_LINUX))
462static void pa_text PARAMS ((int));
463static void pa_data PARAMS ((int));
464static void pa_comm PARAMS ((int));
465#endif
252b5132
RH
466static fp_operand_format pa_parse_fp_format PARAMS ((char **s));
467static void pa_cons PARAMS ((int));
252b5132
RH
468static void pa_float_cons PARAMS ((int));
469static void pa_fill PARAMS ((int));
470static void pa_lcomm PARAMS ((int));
471static void pa_lsym PARAMS ((int));
472static void pa_stringer PARAMS ((int));
252b5132
RH
473static void pa_version PARAMS ((int));
474static int pa_parse_fp_cmp_cond PARAMS ((char **));
475static int get_expression PARAMS ((char *));
476static int pa_get_absolute_expression PARAMS ((struct pa_it *, char **));
477static int evaluate_absolute PARAMS ((struct pa_it *));
478static unsigned int pa_build_arg_reloc PARAMS ((char *));
479static unsigned int pa_align_arg_reloc PARAMS ((unsigned int, unsigned int));
480static int pa_parse_nullif PARAMS ((char **));
481static int pa_parse_nonneg_cmpsub_cmpltr PARAMS ((char **, int));
482static int pa_parse_neg_cmpsub_cmpltr PARAMS ((char **, int));
483static int pa_parse_neg_add_cmpltr PARAMS ((char **, int));
484static int pa_parse_nonneg_add_cmpltr PARAMS ((char **, int));
d53d2751
JL
485static int pa_parse_cmpb_64_cmpltr PARAMS ((char **));
486static int pa_parse_cmpib_64_cmpltr PARAMS ((char **));
487static int pa_parse_addb_64_cmpltr PARAMS ((char **));
252b5132
RH
488static void pa_block PARAMS ((int));
489static void pa_brtab PARAMS ((int));
490static void pa_try PARAMS ((int));
491static void pa_call PARAMS ((int));
492static void pa_call_args PARAMS ((struct call_desc *));
493static void pa_callinfo PARAMS ((int));
252b5132
RH
494static void pa_copyright PARAMS ((int));
495static void pa_end PARAMS ((int));
496static void pa_enter PARAMS ((int));
497static void pa_entry PARAMS ((int));
498static void pa_equ PARAMS ((int));
499static void pa_exit PARAMS ((int));
500static void pa_export PARAMS ((int));
501static void pa_type_args PARAMS ((symbolS *, int));
502static void pa_import PARAMS ((int));
503static void pa_label PARAMS ((int));
504static void pa_leave PARAMS ((int));
505static void pa_level PARAMS ((int));
506static void pa_origin PARAMS ((int));
507static void pa_proc PARAMS ((int));
508static void pa_procend PARAMS ((int));
252b5132
RH
509static void pa_param PARAMS ((int));
510static void pa_undefine_label PARAMS ((void));
ecacdc7a
AM
511static int need_pa11_opcode PARAMS ((void));
512static int pa_parse_number PARAMS ((char **, int));
252b5132 513static label_symbol_struct *pa_get_label PARAMS ((void));
49863f82 514#ifdef OBJ_SOM
3f9b03b5 515static int log2 PARAMS ((int));
49863f82
JL
516static void pa_compiler PARAMS ((int));
517static void pa_align PARAMS ((int));
518static void pa_space PARAMS ((int));
519static void pa_spnum PARAMS ((int));
520static void pa_subspace PARAMS ((int));
252b5132
RH
521static sd_chain_struct *create_new_space PARAMS ((char *, int, int,
522 int, int, int,
523 asection *, int));
524static ssd_chain_struct *create_new_subspace PARAMS ((sd_chain_struct *,
525 char *, int, int,
526 int, int, int,
527 int, int, int, int,
528 int, asection *));
529static ssd_chain_struct *update_subspace PARAMS ((sd_chain_struct *,
530 char *, int, int, int,
531 int, int, int, int,
532 int, int, int,
533 asection *));
534static sd_chain_struct *is_defined_space PARAMS ((char *));
535static ssd_chain_struct *is_defined_subspace PARAMS ((char *));
536static sd_chain_struct *pa_segment_to_space PARAMS ((asection *));
537static ssd_chain_struct *pa_subsegment_to_subspace PARAMS ((asection *,
538 subsegT));
539static sd_chain_struct *pa_find_space_by_number PARAMS ((int));
540static unsigned int pa_subspace_start PARAMS ((sd_chain_struct *, int));
49863f82
JL
541static sd_chain_struct *pa_parse_space_stmt PARAMS ((char *, int));
542static int pa_next_subseg PARAMS ((sd_chain_struct *));
543static void pa_spaces_begin PARAMS ((void));
544#endif
252b5132
RH
545static void pa_ip PARAMS ((char *));
546static void fix_new_hppa PARAMS ((fragS *, int, int, symbolS *,
ad1079af 547 offsetT, expressionS *, int,
252b5132
RH
548 bfd_reloc_code_real_type,
549 enum hppa_reloc_field_selector_type_alt,
ad1079af 550 int, unsigned int, int *));
252b5132
RH
551static int is_end_of_statement PARAMS ((void));
552static int reg_name_search PARAMS ((char *));
553static int pa_chk_field_selector PARAMS ((char **));
554static int is_same_frag PARAMS ((fragS *, fragS *));
555static void process_exit PARAMS ((void));
252b5132 556static unsigned int pa_stringer_aux PARAMS ((char *));
1cf6ae67
JL
557static fp_operand_format pa_parse_fp_cnv_format PARAMS ((char **s));
558static int pa_parse_ftest_gfx_completer PARAMS ((char **));
252b5132
RH
559
560#ifdef OBJ_ELF
561static void hppa_elf_mark_end_of_function PARAMS ((void));
562static void pa_build_unwind_subspace PARAMS ((struct call_info *));
904a31bf
AM
563static void pa_vtable_entry PARAMS ((int));
564static void pa_vtable_inherit PARAMS ((int));
252b5132
RH
565#endif
566
567/* File and gloally scoped variable declarations. */
568
49863f82 569#ifdef OBJ_SOM
252b5132
RH
570/* Root and final entry in the space chain. */
571static sd_chain_struct *space_dict_root;
572static sd_chain_struct *space_dict_last;
573
574/* The current space and subspace. */
575static sd_chain_struct *current_space;
576static ssd_chain_struct *current_subspace;
49863f82 577#endif
252b5132
RH
578
579/* Root of the call_info chain. */
580static struct call_info *call_info_root;
581
582/* The last call_info (for functions) structure
583 seen so it can be associated with fixups and
584 function labels. */
585static struct call_info *last_call_info;
586
587/* The last call description (for actual calls). */
588static struct call_desc last_call_desc;
589
590/* handle of the OPCODE hash table */
591static struct hash_control *op_hash = NULL;
592
252b5132
RH
593/* Table of pseudo ops for the PA. FIXME -- how many of these
594 are now redundant with the overall GAS and the object file
595 dependent tables? */
596const pseudo_typeS md_pseudo_table[] =
597{
598 /* align pseudo-ops on the PA specify the actual alignment requested,
599 not the log2 of the requested alignment. */
49863f82 600#ifdef OBJ_SOM
252b5132 601 {"align", pa_align, 8},
49863f82
JL
602#endif
603#ifdef OBJ_ELF
604 {"align", s_align_bytes, 8},
605#endif
252b5132
RH
606 {"begin_brtab", pa_brtab, 1},
607 {"begin_try", pa_try, 1},
608 {"block", pa_block, 1},
609 {"blockz", pa_block, 0},
610 {"byte", pa_cons, 1},
611 {"call", pa_call, 0},
612 {"callinfo", pa_callinfo, 0},
ad1079af
AM
613#if defined (OBJ_ELF) && defined (TE_LINUX)
614 {"code", obj_elf_text, 0},
615#else
616 {"code", pa_text, 0},
252b5132 617 {"comm", pa_comm, 0},
ad1079af 618#endif
252b5132
RH
619#ifdef OBJ_SOM
620 {"compiler", pa_compiler, 0},
621#endif
622 {"copyright", pa_copyright, 0},
ad1079af 623#if !(defined (OBJ_ELF) && defined (TE_LINUX))
252b5132 624 {"data", pa_data, 0},
ad1079af 625#endif
252b5132 626 {"double", pa_float_cons, 'd'},
077db52a 627 {"dword", pa_cons, 8},
252b5132
RH
628 {"end", pa_end, 0},
629 {"end_brtab", pa_brtab, 0},
ad1079af 630#if !(defined (OBJ_ELF) && defined (TE_LINUX))
252b5132 631 {"end_try", pa_try, 0},
ad1079af 632#endif
252b5132
RH
633 {"enter", pa_enter, 0},
634 {"entry", pa_entry, 0},
635 {"equ", pa_equ, 0},
636 {"exit", pa_exit, 0},
637 {"export", pa_export, 0},
2d93dcc4 638#ifdef OBJ_ELF
ad1079af 639 {"file", dwarf2_directive_file, 0 },
2d93dcc4 640#endif
252b5132
RH
641 {"fill", pa_fill, 0},
642 {"float", pa_float_cons, 'f'},
643 {"half", pa_cons, 2},
644 {"import", pa_import, 0},
645 {"int", pa_cons, 4},
646 {"label", pa_label, 0},
647 {"lcomm", pa_lcomm, 0},
648 {"leave", pa_leave, 0},
649 {"level", pa_level, 0},
2d93dcc4 650#ifdef OBJ_ELF
ad1079af 651 {"loc", dwarf2_directive_loc, 0 },
2d93dcc4 652#endif
252b5132
RH
653 {"long", pa_cons, 4},
654 {"lsym", pa_lsym, 0},
49863f82 655#ifdef OBJ_SOM
252b5132 656 {"nsubspa", pa_subspace, 1},
49863f82 657#endif
252b5132
RH
658 {"octa", pa_cons, 16},
659 {"org", pa_origin, 0},
660 {"origin", pa_origin, 0},
661 {"param", pa_param, 0},
662 {"proc", pa_proc, 0},
663 {"procend", pa_procend, 0},
664 {"quad", pa_cons, 8},
665 {"reg", pa_equ, 1},
666 {"short", pa_cons, 2},
667 {"single", pa_float_cons, 'f'},
49863f82 668#ifdef OBJ_SOM
252b5132
RH
669 {"space", pa_space, 0},
670 {"spnum", pa_spnum, 0},
49863f82 671#endif
252b5132
RH
672 {"string", pa_stringer, 0},
673 {"stringz", pa_stringer, 1},
49863f82 674#ifdef OBJ_SOM
252b5132 675 {"subspa", pa_subspace, 0},
49863f82 676#endif
ad1079af 677#if !(defined (OBJ_ELF) && defined (TE_LINUX))
252b5132 678 {"text", pa_text, 0},
ad1079af 679#endif
252b5132 680 {"version", pa_version, 0},
904a31bf
AM
681#ifdef OBJ_ELF
682 {"vtable_entry", pa_vtable_entry, 0},
683 {"vtable_inherit", pa_vtable_inherit, 0},
684#endif
252b5132
RH
685 {"word", pa_cons, 4},
686 {NULL, 0, 0}
687};
688
689/* This array holds the chars that only start a comment at the beginning of
690 a line. If the line seems to have the form '# 123 filename'
691 .line and .file directives will appear in the pre-processed output.
692
693 Note that input_file.c hand checks for '#' at the beginning of the
694 first line of the input file. This is because the compiler outputs
695 #NO_APP at the beginning of its output.
696
a28a3ccf 697 Also note that C style comments will always work. */
252b5132
RH
698const char line_comment_chars[] = "#";
699
ad1079af
AM
700/* This array holds the chars that always start a comment. If the
701 pre-processor is disabled, these aren't very useful. */
702const char comment_chars[] = ";";
703
252b5132
RH
704/* This array holds the characters which act as line separators. */
705const char line_separator_chars[] = "!";
706
707/* Chars that can be used to separate mant from exp in floating point nums. */
708const char EXP_CHARS[] = "eE";
709
710/* Chars that mean this number is a floating point constant.
711 As in 0f12.456 or 0d1.2345e12.
712
713 Be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
714 changed in read.c. Ideally it shouldn't hae to know abou it at
715 all, but nothing is ideal around here. */
716const char FLT_CHARS[] = "rRsSfFdDxXpP";
717
718static struct pa_it the_insn;
719
720/* Points to the end of an expression just parsed by get_expressoin
721 and friends. FIXME. This shouldn't be handled with a file-global
722 variable. */
723static char *expr_end;
724
725/* Nonzero if a .callinfo appeared within the current procedure. */
726static int callinfo_found;
727
728/* Nonzero if the assembler is currently within a .entry/.exit pair. */
729static int within_entry_exit;
730
731/* Nonzero if the assembler is currently within a procedure definition. */
732static int within_procedure;
733
ad1079af 734/* Handle on structure which keep track of the last symbol
252b5132
RH
735 seen in each subspace. */
736static label_symbol_struct *label_symbols_rootp = NULL;
737
738/* Holds the last field selector. */
739static int hppa_field_selector;
740
0f4f8b56
JL
741/* Nonzero when strict syntax checking is enabled. Zero otherwise.
742
743 Each opcode in the table has a flag which indicates whether or not
744 strict syntax checking should be enabled for that instruction. */
745static int strict = 0;
746
ecacdc7a
AM
747/* pa_parse_number returns values in `pa_number'. Mostly
748 pa_parse_number is used to return a register number, with floating
749 point registers being numbered from FP_REG_BASE upwards.
750 The bit specified with FP_REG_RSEL is set if the floating point
751 register has a `r' suffix. */
752#define FP_REG_BASE 64
753#define FP_REG_RSEL 128
754static int pa_number;
755
993142d5 756#ifdef OBJ_SOM
252b5132
RH
757/* A dummy bfd symbol so that all relocations have symbols of some kind. */
758static symbolS *dummy_symbol;
993142d5 759#endif
252b5132
RH
760
761/* Nonzero if errors are to be printed. */
762static int print_errors = 1;
763
764/* List of registers that are pre-defined:
765
766 Each general register has one predefined name of the form
767 %r<REGNUM> which has the value <REGNUM>.
768
769 Space and control registers are handled in a similar manner,
770 but use %sr<REGNUM> and %cr<REGNUM> as their predefined names.
771
772 Likewise for the floating point registers, but of the form
773 %fr<REGNUM>. Floating point registers have additional predefined
774 names with 'L' and 'R' suffixes (e.g. %fr19L, %fr19R) which
775 again have the value <REGNUM>.
776
777 Many registers also have synonyms:
778
779 %r26 - %r23 have %arg0 - %arg3 as synonyms
780 %r28 - %r29 have %ret0 - %ret1 as synonyms
781 %r30 has %sp as a synonym
782 %r27 has %dp as a synonym
783 %r2 has %rp as a synonym
784
785 Almost every control register has a synonym; they are not listed
786 here for brevity.
787
a28a3ccf 788 The table is sorted. Suitable for searching by a binary search. */
252b5132
RH
789
790static const struct pd_reg pre_defined_registers[] =
791{
ecacdc7a
AM
792 {"%arg0", 26},
793 {"%arg1", 25},
794 {"%arg2", 24},
795 {"%arg3", 23},
796 {"%cr0", 0},
797 {"%cr10", 10},
798 {"%cr11", 11},
799 {"%cr12", 12},
800 {"%cr13", 13},
801 {"%cr14", 14},
802 {"%cr15", 15},
803 {"%cr16", 16},
804 {"%cr17", 17},
805 {"%cr18", 18},
806 {"%cr19", 19},
807 {"%cr20", 20},
808 {"%cr21", 21},
809 {"%cr22", 22},
810 {"%cr23", 23},
811 {"%cr24", 24},
812 {"%cr25", 25},
813 {"%cr26", 26},
814 {"%cr27", 27},
815 {"%cr28", 28},
816 {"%cr29", 29},
817 {"%cr30", 30},
818 {"%cr31", 31},
819 {"%cr8", 8},
820 {"%cr9", 9},
821 {"%dp", 27},
822 {"%eiem", 15},
823 {"%eirr", 23},
824 {"%fr0", 0 + FP_REG_BASE},
825 {"%fr0l", 0 + FP_REG_BASE},
826 {"%fr0r", 0 + FP_REG_BASE + FP_REG_RSEL},
827 {"%fr1", 1 + FP_REG_BASE},
828 {"%fr10", 10 + FP_REG_BASE},
829 {"%fr10l", 10 + FP_REG_BASE},
830 {"%fr10r", 10 + FP_REG_BASE + FP_REG_RSEL},
831 {"%fr11", 11 + FP_REG_BASE},
832 {"%fr11l", 11 + FP_REG_BASE},
833 {"%fr11r", 11 + FP_REG_BASE + FP_REG_RSEL},
834 {"%fr12", 12 + FP_REG_BASE},
835 {"%fr12l", 12 + FP_REG_BASE},
836 {"%fr12r", 12 + FP_REG_BASE + FP_REG_RSEL},
837 {"%fr13", 13 + FP_REG_BASE},
838 {"%fr13l", 13 + FP_REG_BASE},
839 {"%fr13r", 13 + FP_REG_BASE + FP_REG_RSEL},
840 {"%fr14", 14 + FP_REG_BASE},
841 {"%fr14l", 14 + FP_REG_BASE},
842 {"%fr14r", 14 + FP_REG_BASE + FP_REG_RSEL},
843 {"%fr15", 15 + FP_REG_BASE},
844 {"%fr15l", 15 + FP_REG_BASE},
845 {"%fr15r", 15 + FP_REG_BASE + FP_REG_RSEL},
846 {"%fr16", 16 + FP_REG_BASE},
847 {"%fr16l", 16 + FP_REG_BASE},
848 {"%fr16r", 16 + FP_REG_BASE + FP_REG_RSEL},
849 {"%fr17", 17 + FP_REG_BASE},
850 {"%fr17l", 17 + FP_REG_BASE},
851 {"%fr17r", 17 + FP_REG_BASE + FP_REG_RSEL},
852 {"%fr18", 18 + FP_REG_BASE},
853 {"%fr18l", 18 + FP_REG_BASE},
854 {"%fr18r", 18 + FP_REG_BASE + FP_REG_RSEL},
855 {"%fr19", 19 + FP_REG_BASE},
856 {"%fr19l", 19 + FP_REG_BASE},
857 {"%fr19r", 19 + FP_REG_BASE + FP_REG_RSEL},
858 {"%fr1l", 1 + FP_REG_BASE},
859 {"%fr1r", 1 + FP_REG_BASE + FP_REG_RSEL},
860 {"%fr2", 2 + FP_REG_BASE},
861 {"%fr20", 20 + FP_REG_BASE},
862 {"%fr20l", 20 + FP_REG_BASE},
863 {"%fr20r", 20 + FP_REG_BASE + FP_REG_RSEL},
864 {"%fr21", 21 + FP_REG_BASE},
865 {"%fr21l", 21 + FP_REG_BASE},
866 {"%fr21r", 21 + FP_REG_BASE + FP_REG_RSEL},
867 {"%fr22", 22 + FP_REG_BASE},
868 {"%fr22l", 22 + FP_REG_BASE},
869 {"%fr22r", 22 + FP_REG_BASE + FP_REG_RSEL},
870 {"%fr23", 23 + FP_REG_BASE},
871 {"%fr23l", 23 + FP_REG_BASE},
872 {"%fr23r", 23 + FP_REG_BASE + FP_REG_RSEL},
873 {"%fr24", 24 + FP_REG_BASE},
874 {"%fr24l", 24 + FP_REG_BASE},
875 {"%fr24r", 24 + FP_REG_BASE + FP_REG_RSEL},
876 {"%fr25", 25 + FP_REG_BASE},
877 {"%fr25l", 25 + FP_REG_BASE},
878 {"%fr25r", 25 + FP_REG_BASE + FP_REG_RSEL},
879 {"%fr26", 26 + FP_REG_BASE},
880 {"%fr26l", 26 + FP_REG_BASE},
881 {"%fr26r", 26 + FP_REG_BASE + FP_REG_RSEL},
882 {"%fr27", 27 + FP_REG_BASE},
883 {"%fr27l", 27 + FP_REG_BASE},
884 {"%fr27r", 27 + FP_REG_BASE + FP_REG_RSEL},
885 {"%fr28", 28 + FP_REG_BASE},
886 {"%fr28l", 28 + FP_REG_BASE},
887 {"%fr28r", 28 + FP_REG_BASE + FP_REG_RSEL},
888 {"%fr29", 29 + FP_REG_BASE},
889 {"%fr29l", 29 + FP_REG_BASE},
890 {"%fr29r", 29 + FP_REG_BASE + FP_REG_RSEL},
891 {"%fr2l", 2 + FP_REG_BASE},
892 {"%fr2r", 2 + FP_REG_BASE + FP_REG_RSEL},
893 {"%fr3", 3 + FP_REG_BASE},
894 {"%fr30", 30 + FP_REG_BASE},
895 {"%fr30l", 30 + FP_REG_BASE},
896 {"%fr30r", 30 + FP_REG_BASE + FP_REG_RSEL},
897 {"%fr31", 31 + FP_REG_BASE},
898 {"%fr31l", 31 + FP_REG_BASE},
899 {"%fr31r", 31 + FP_REG_BASE + FP_REG_RSEL},
900 {"%fr3l", 3 + FP_REG_BASE},
901 {"%fr3r", 3 + FP_REG_BASE + FP_REG_RSEL},
902 {"%fr4", 4 + FP_REG_BASE},
903 {"%fr4l", 4 + FP_REG_BASE},
904 {"%fr4r", 4 + FP_REG_BASE + FP_REG_RSEL},
905 {"%fr5", 5 + FP_REG_BASE},
906 {"%fr5l", 5 + FP_REG_BASE},
907 {"%fr5r", 5 + FP_REG_BASE + FP_REG_RSEL},
908 {"%fr6", 6 + FP_REG_BASE},
909 {"%fr6l", 6 + FP_REG_BASE},
910 {"%fr6r", 6 + FP_REG_BASE + FP_REG_RSEL},
911 {"%fr7", 7 + FP_REG_BASE},
912 {"%fr7l", 7 + FP_REG_BASE},
913 {"%fr7r", 7 + FP_REG_BASE + FP_REG_RSEL},
914 {"%fr8", 8 + FP_REG_BASE},
915 {"%fr8l", 8 + FP_REG_BASE},
916 {"%fr8r", 8 + FP_REG_BASE + FP_REG_RSEL},
917 {"%fr9", 9 + FP_REG_BASE},
918 {"%fr9l", 9 + FP_REG_BASE},
919 {"%fr9r", 9 + FP_REG_BASE + FP_REG_RSEL},
920 {"%hta", 25},
921 {"%iir", 19},
922 {"%ior", 21},
923 {"%ipsw", 22},
924 {"%isr", 20},
925 {"%itmr", 16},
926 {"%iva", 14},
927 {"%pcoq", 18},
928 {"%pcsq", 17},
929 {"%pidr1", 8},
930 {"%pidr2", 9},
252b5132
RH
931 {"%pidr3", 12},
932 {"%pidr4", 13},
ecacdc7a
AM
933 {"%ppda", 24},
934 {"%r0", 0},
935 {"%r1", 1},
936 {"%r10", 10},
937 {"%r11", 11},
938 {"%r12", 12},
939 {"%r13", 13},
940 {"%r14", 14},
941 {"%r15", 15},
942 {"%r16", 16},
943 {"%r17", 17},
944 {"%r18", 18},
945 {"%r19", 19},
946 {"%r2", 2},
947 {"%r20", 20},
948 {"%r21", 21},
949 {"%r22", 22},
950 {"%r23", 23},
951 {"%r24", 24},
952 {"%r25", 25},
953 {"%r26", 26},
954 {"%r27", 27},
955 {"%r28", 28},
956 {"%r29", 29},
957 {"%r3", 3},
958 {"%r30", 30},
959 {"%r31", 31},
960 {"%r4", 4},
961 {"%r5", 5},
962 {"%r6", 6},
963 {"%r7", 7},
964 {"%r8", 8},
965 {"%r9", 9},
966 {"%rctr", 0},
967 {"%ret0", 28},
968 {"%ret1", 29},
969 {"%rp", 2},
970 {"%sar", 11},
971 {"%sp", 30},
972 {"%sr0", 0},
973 {"%sr1", 1},
974 {"%sr2", 2},
975 {"%sr3", 3},
976 {"%sr4", 4},
977 {"%sr5", 5},
978 {"%sr6", 6},
979 {"%sr7", 7},
980 {"%tr0", 24},
981 {"%tr1", 25},
982 {"%tr2", 26},
983 {"%tr3", 27},
984 {"%tr4", 28},
985 {"%tr5", 29},
986 {"%tr6", 30},
987 {"%tr7", 31}
252b5132
RH
988};
989
990/* This table is sorted by order of the length of the string. This is
991 so we check for <> before we check for <. If we had a <> and checked
992 for < first, we would get a false match. */
993static const struct fp_cond_map fp_cond_map[] =
994{
995 {"false?", 0},
996 {"false", 1},
997 {"true?", 30},
998 {"true", 31},
999 {"!<=>", 3},
1000 {"!?>=", 8},
1001 {"!?<=", 16},
1002 {"!<>", 7},
1003 {"!>=", 11},
1004 {"!?>", 12},
1005 {"?<=", 14},
1006 {"!<=", 19},
1007 {"!?<", 20},
1008 {"?>=", 22},
1009 {"!?=", 24},
1010 {"!=t", 27},
1011 {"<=>", 29},
1012 {"=t", 5},
1013 {"?=", 6},
1014 {"?<", 10},
1015 {"<=", 13},
1016 {"!>", 15},
1017 {"?>", 18},
1018 {">=", 21},
1019 {"!<", 23},
1020 {"<>", 25},
1021 {"!=", 26},
1022 {"!?", 28},
1023 {"?", 2},
1024 {"=", 4},
1025 {"<", 9},
1026 {">", 17}
1027};
1028
1029static const struct selector_entry selector_table[] =
1030{
1031 {"f", e_fsel},
1032 {"l", e_lsel},
1033 {"ld", e_ldsel},
1034 {"lp", e_lpsel},
1035 {"lr", e_lrsel},
1036 {"ls", e_lssel},
1037 {"lt", e_ltsel},
39ba5561 1038 {"ltp", e_ltpsel},
252b5132
RH
1039 {"n", e_nsel},
1040 {"nl", e_nlsel},
1041 {"nlr", e_nlrsel},
1042 {"p", e_psel},
1043 {"r", e_rsel},
1044 {"rd", e_rdsel},
1045 {"rp", e_rpsel},
1046 {"rr", e_rrsel},
1047 {"rs", e_rssel},
1048 {"rt", e_rtsel},
39ba5561 1049 {"rtp", e_rtpsel},
252b5132
RH
1050 {"t", e_tsel},
1051};
1052
49863f82 1053#ifdef OBJ_SOM
252b5132
RH
1054/* default space and subspace dictionaries */
1055
1056#define GDB_SYMBOLS GDB_SYMBOLS_SUBSPACE_NAME
1057#define GDB_STRINGS GDB_STRINGS_SUBSPACE_NAME
1058
1059/* pre-defined subsegments (subspaces) for the HPPA. */
1060#define SUBSEG_CODE 0
1061#define SUBSEG_LIT 1
1062#define SUBSEG_MILLI 2
1063#define SUBSEG_DATA 0
1064#define SUBSEG_BSS 2
1065#define SUBSEG_UNWIND 3
1066#define SUBSEG_GDB_STRINGS 0
1067#define SUBSEG_GDB_SYMBOLS 1
1068
1069static struct default_subspace_dict pa_def_subspaces[] =
1070{
49863f82
JL
1071 {"$CODE$", 1, 1, 1, 0, 0, 0, 24, 0x2c, 0, 8, 0, 0, SUBSEG_CODE},
1072 {"$DATA$", 1, 1, 0, 0, 0, 0, 24, 0x1f, 1, 8, 1, 1, SUBSEG_DATA},
1073 {"$LIT$", 1, 1, 0, 0, 0, 0, 16, 0x2c, 0, 8, 0, 0, SUBSEG_LIT},
1074 {"$MILLICODE$", 1, 1, 0, 0, 0, 0, 8, 0x2c, 0, 8, 0, 0, SUBSEG_MILLI},
1075 {"$BSS$", 1, 1, 0, 0, 0, 1, 80, 0x1f, 1, 8, 1, 1, SUBSEG_BSS},
252b5132
RH
1076 {NULL, 0, 1, 0, 0, 0, 0, 255, 0x1f, 0, 4, 0, 0, 0}
1077};
1078
1079static struct default_space_dict pa_def_spaces[] =
1080{
49863f82
JL
1081 {"$TEXT$", 0, 1, 1, 0, 8, ASEC_NULL},
1082 {"$PRIVATE$", 1, 1, 1, 1, 16, ASEC_NULL},
1083 {NULL, 0, 0, 0, 0, 0, ASEC_NULL}
252b5132
RH
1084};
1085
1086/* Misc local definitions used by the assembler. */
1087
252b5132
RH
1088/* These macros are used to maintain spaces/subspaces. */
1089#define SPACE_DEFINED(space_chain) (space_chain)->sd_defined
1090#define SPACE_USER_DEFINED(space_chain) (space_chain)->sd_user_defined
1091#define SPACE_SPNUM(space_chain) (space_chain)->sd_spnum
1092#define SPACE_NAME(space_chain) (space_chain)->sd_name
1093
1094#define SUBSPACE_DEFINED(ss_chain) (ss_chain)->ssd_defined
1095#define SUBSPACE_NAME(ss_chain) (ss_chain)->ssd_name
49863f82
JL
1096#endif
1097
1098/* Return nonzero if the string pointed to by S potentially represents
1099 a right or left half of a FP register */
1100#define IS_R_SELECT(S) (*(S) == 'R' || *(S) == 'r')
1101#define IS_L_SELECT(S) (*(S) == 'L' || *(S) == 'l')
252b5132
RH
1102
1103/* Insert FIELD into OPCODE starting at bit START. Continue pa_ip
1104 main loop after insertion. */
1105
1106#define INSERT_FIELD_AND_CONTINUE(OPCODE, FIELD, START) \
1107 { \
1108 ((OPCODE) |= (FIELD) << (START)); \
1109 continue; \
1110 }
1111
1112/* Simple range checking for FIELD againt HIGH and LOW bounds.
1113 IGNORE is used to suppress the error message. */
1114
1115#define CHECK_FIELD(FIELD, HIGH, LOW, IGNORE) \
1116 { \
1117 if ((FIELD) > (HIGH) || (FIELD) < (LOW)) \
1118 { \
1119 if (! IGNORE) \
1120 as_bad (_("Field out of range [%d..%d] (%d)."), (LOW), (HIGH), \
1121 (int) (FIELD));\
1122 break; \
1123 } \
1124 }
1125
a02fab7e
JL
1126/* Simple alignment checking for FIELD againt ALIGN (a power of two).
1127 IGNORE is used to suppress the error message. */
1128
1129#define CHECK_ALIGN(FIELD, ALIGN, IGNORE) \
1130 { \
1131 if ((FIELD) & ((ALIGN) - 1)) \
1132 { \
1133 if (! IGNORE) \
1134 as_bad (_("Field not properly aligned [%d] (%d)."), (ALIGN), \
1135 (int) (FIELD));\
1136 break; \
1137 } \
1138 }
1139
252b5132
RH
1140#define is_DP_relative(exp) \
1141 ((exp).X_op == O_subtract \
a0f75b47 1142 && strcmp (S_GET_NAME ((exp).X_op_symbol), "$global$") == 0)
252b5132
RH
1143
1144#define is_PC_relative(exp) \
1145 ((exp).X_op == O_subtract \
a0f75b47 1146 && strcmp (S_GET_NAME ((exp).X_op_symbol), "$PIC_pcrel$0") == 0)
252b5132
RH
1147
1148/* We need some complex handling for stabs (sym1 - sym2). Luckily, we'll
1149 always be able to reduce the expression to a constant, so we don't
1150 need real complex handling yet. */
1151#define is_complex(exp) \
1152 ((exp).X_op != O_constant && (exp).X_op != O_symbol)
1153
1154/* Actual functions to implement the PA specific code for the assembler. */
1155
1156/* Called before writing the object file. Make sure entry/exit and
1157 proc/procend pairs match. */
1158
1159void
1160pa_check_eof ()
1161{
1162 if (within_entry_exit)
1163 as_fatal (_("Missing .exit\n"));
1164
1165 if (within_procedure)
1166 as_fatal (_("Missing .procend\n"));
1167}
1168
252b5132
RH
1169/* Returns a pointer to the label_symbol_struct for the current space.
1170 or NULL if no label_symbol_struct exists for the current space. */
1171
1172static label_symbol_struct *
1173pa_get_label ()
1174{
1175 label_symbol_struct *label_chain;
252b5132
RH
1176
1177 for (label_chain = label_symbols_rootp;
1178 label_chain;
1179 label_chain = label_chain->lss_next)
49863f82
JL
1180 {
1181#ifdef OBJ_SOM
1182 if (current_space == label_chain->lss_space && label_chain->lss_label)
1183 return label_chain;
1184#endif
1185#ifdef OBJ_ELF
1186 if (now_seg == label_chain->lss_segment && label_chain->lss_label)
252b5132 1187 return label_chain;
49863f82
JL
1188#endif
1189 }
252b5132
RH
1190
1191 return NULL;
1192}
1193
1194/* Defines a label for the current space. If one is already defined,
1195 this function will replace it with the new label. */
1196
1197void
1198pa_define_label (symbol)
1199 symbolS *symbol;
1200{
1201 label_symbol_struct *label_chain = pa_get_label ();
252b5132
RH
1202
1203 if (label_chain)
1204 label_chain->lss_label = symbol;
1205 else
1206 {
1207 /* Create a new label entry and add it to the head of the chain. */
1208 label_chain
1209 = (label_symbol_struct *) xmalloc (sizeof (label_symbol_struct));
1210 label_chain->lss_label = symbol;
49863f82
JL
1211#ifdef OBJ_SOM
1212 label_chain->lss_space = current_space;
1213#endif
1214#ifdef OBJ_ELF
1215 label_chain->lss_segment = now_seg;
1216#endif
252b5132
RH
1217 label_chain->lss_next = NULL;
1218
1219 if (label_symbols_rootp)
1220 label_chain->lss_next = label_symbols_rootp;
1221
1222 label_symbols_rootp = label_chain;
1223 }
1224}
1225
1226/* Removes a label definition for the current space.
1227 If there is no label_symbol_struct entry, then no action is taken. */
1228
1229static void
1230pa_undefine_label ()
1231{
1232 label_symbol_struct *label_chain;
1233 label_symbol_struct *prev_label_chain = NULL;
252b5132
RH
1234
1235 for (label_chain = label_symbols_rootp;
1236 label_chain;
1237 label_chain = label_chain->lss_next)
1238 {
49863f82
JL
1239 if (1
1240#ifdef OBJ_SOM
1241 && current_space == label_chain->lss_space && label_chain->lss_label
1242#endif
1243#ifdef OBJ_ELF
1244 && now_seg == label_chain->lss_segment && label_chain->lss_label
1245#endif
1246 )
252b5132
RH
1247 {
1248 /* Remove the label from the chain and free its memory. */
1249 if (prev_label_chain)
1250 prev_label_chain->lss_next = label_chain->lss_next;
1251 else
1252 label_symbols_rootp = label_chain->lss_next;
1253
1254 free (label_chain);
1255 break;
1256 }
1257 prev_label_chain = label_chain;
1258 }
1259}
1260
252b5132
RH
1261/* An HPPA-specific version of fix_new. This is required because the HPPA
1262 code needs to keep track of some extra stuff. Each call to fix_new_hppa
1263 results in the creation of an instance of an hppa_fix_struct. An
1264 hppa_fix_struct stores the extra information along with a pointer to the
1265 original fixS. This is attached to the original fixup via the
1266 tc_fix_data field. */
1267
1268static void
1269fix_new_hppa (frag, where, size, add_symbol, offset, exp, pcrel,
1270 r_type, r_field, r_format, arg_reloc, unwind_bits)
1271 fragS *frag;
1272 int where;
1273 int size;
1274 symbolS *add_symbol;
ad1079af 1275 offsetT offset;
252b5132
RH
1276 expressionS *exp;
1277 int pcrel;
1278 bfd_reloc_code_real_type r_type;
1279 enum hppa_reloc_field_selector_type_alt r_field;
1280 int r_format;
ad1079af 1281 unsigned int arg_reloc;
3f9b03b5 1282 int* unwind_bits ATTRIBUTE_UNUSED;
252b5132
RH
1283{
1284 fixS *new_fix;
1285
1286 struct hppa_fix_struct *hppa_fix = (struct hppa_fix_struct *)
1287 obstack_alloc (&notes, sizeof (struct hppa_fix_struct));
1288
1289 if (exp != NULL)
1290 new_fix = fix_new_exp (frag, where, size, exp, pcrel, r_type);
1291 else
1292 new_fix = fix_new (frag, where, size, add_symbol, offset, pcrel, r_type);
1293 new_fix->tc_fix_data = (void *) hppa_fix;
1294 hppa_fix->fx_r_type = r_type;
1295 hppa_fix->fx_r_field = r_field;
1296 hppa_fix->fx_r_format = r_format;
1297 hppa_fix->fx_arg_reloc = arg_reloc;
1298 hppa_fix->segment = now_seg;
1299#ifdef OBJ_SOM
1300 if (r_type == R_ENTRY || r_type == R_EXIT)
1301 new_fix->fx_offset = *unwind_bits;
1302#endif
1303
1304 /* foo-$global$ is used to access non-automatic storage. $global$
1305 is really just a marker and has served its purpose, so eliminate
904a31bf 1306 it now so as not to confuse write.c. Ditto for $PIC_pcrel$0. */
252b5132 1307 if (new_fix->fx_subsy
904a31bf
AM
1308 && (strcmp (S_GET_NAME (new_fix->fx_subsy), "$global$") == 0
1309 || strcmp (S_GET_NAME (new_fix->fx_subsy), "$PIC_pcrel$0") == 0))
252b5132
RH
1310 new_fix->fx_subsy = NULL;
1311}
1312
1313/* Parse a .byte, .word, .long expression for the HPPA. Called by
1314 cons via the TC_PARSE_CONS_EXPRESSION macro. */
1315
1316void
1317parse_cons_expression_hppa (exp)
1318 expressionS *exp;
1319{
1320 hppa_field_selector = pa_chk_field_selector (&input_line_pointer);
1321 expression (exp);
1322}
1323
1324/* This fix_new is called by cons via TC_CONS_FIX_NEW.
1325 hppa_field_selector is set by the parse_cons_expression_hppa. */
1326
1327void
1328cons_fix_new_hppa (frag, where, size, exp)
1329 fragS *frag;
1330 int where;
1331 int size;
1332 expressionS *exp;
1333{
1334 unsigned int rel_type;
1335
1336 /* Get a base relocation type. */
1337 if (is_DP_relative (*exp))
1338 rel_type = R_HPPA_GOTOFF;
1339 else if (is_complex (*exp))
1340 rel_type = R_HPPA_COMPLEX;
1341 else
1342 rel_type = R_HPPA;
1343
1344 if (hppa_field_selector != e_psel && hppa_field_selector != e_fsel)
ad1079af
AM
1345 {
1346 as_warn (_("Invalid field selector. Assuming F%%."));
1347 hppa_field_selector = e_fsel;
1348 }
252b5132
RH
1349
1350 fix_new_hppa (frag, where, size,
1351 (symbolS *) NULL, (offsetT) 0, exp, 0, rel_type,
077db52a 1352 hppa_field_selector, size * 8, 0, NULL);
252b5132
RH
1353
1354 /* Reset field selector to its default state. */
1355 hppa_field_selector = 0;
1356}
1357
1358/* This function is called once, at assembler startup time. It should
1359 set up all the tables, etc. that the MD part of the assembler will need. */
1360
1361void
1362md_begin ()
1363{
1364 const char *retval = NULL;
1365 int lose = 0;
1366 unsigned int i = 0;
1367
1368 last_call_info = NULL;
1369 call_info_root = NULL;
1370
1371 /* Set the default machine type. */
1372 if (!bfd_set_arch_mach (stdoutput, bfd_arch_hppa, 10))
1373 as_warn (_("could not set architecture and machine"));
1374
1375 /* Folding of text and data segments fails miserably on the PA.
1376 Warn user and disable "-R" option. */
1377 if (flag_readonly_data_in_text)
1378 {
1379 as_warn (_("-R option not supported on this target."));
1380 flag_readonly_data_in_text = 0;
1381 }
1382
49863f82 1383#ifdef OBJ_SOM
252b5132 1384 pa_spaces_begin ();
49863f82 1385#endif
252b5132
RH
1386
1387 op_hash = hash_new ();
1388
1389 while (i < NUMOPCODES)
1390 {
1391 const char *name = pa_opcodes[i].name;
1392 retval = hash_insert (op_hash, name, (struct pa_opcode *) &pa_opcodes[i]);
1393 if (retval != NULL && *retval != '\0')
1394 {
1395 as_fatal (_("Internal error: can't hash `%s': %s\n"), name, retval);
1396 lose = 1;
1397 }
1398 do
1399 {
1400 if ((pa_opcodes[i].match & pa_opcodes[i].mask)
1401 != pa_opcodes[i].match)
1402 {
1403 fprintf (stderr, _("internal error: losing opcode: `%s' \"%s\"\n"),
1404 pa_opcodes[i].name, pa_opcodes[i].args);
1405 lose = 1;
1406 }
1407 ++i;
1408 }
1409 while (i < NUMOPCODES && !strcmp (pa_opcodes[i].name, name));
1410 }
1411
1412 if (lose)
1413 as_fatal (_("Broken assembler. No assembly attempted."));
1414
49863f82 1415#ifdef OBJ_SOM
252b5132
RH
1416 /* SOM will change text_section. To make sure we never put
1417 anything into the old one switch to the new one now. */
1418 subseg_set (text_section, 0);
49863f82 1419#endif
252b5132 1420
993142d5 1421#ifdef OBJ_SOM
252b5132
RH
1422 dummy_symbol = symbol_find_or_make ("L$dummy");
1423 S_SET_SEGMENT (dummy_symbol, text_section);
a28a3ccf 1424 /* Force the symbol to be converted to a real symbol. */
d53d2751 1425 (void) symbol_get_bfdsym (dummy_symbol);
993142d5 1426#endif
252b5132
RH
1427}
1428
1429/* Assemble a single instruction storing it into a frag. */
1430void
1431md_assemble (str)
1432 char *str;
1433{
1434 char *to;
1435
1436 /* The had better be something to assemble. */
1437 assert (str);
1438
1439 /* If we are within a procedure definition, make sure we've
1440 defined a label for the procedure; handle case where the
1441 label was defined after the .PROC directive.
1442
1443 Note there's not need to diddle with the segment or fragment
1444 for the label symbol in this case. We have already switched
1445 into the new $CODE$ subspace at this point. */
1446 if (within_procedure && last_call_info->start_symbol == NULL)
1447 {
1448 label_symbol_struct *label_symbol = pa_get_label ();
1449
1450 if (label_symbol)
1451 {
1452 if (label_symbol->lss_label)
1453 {
1454 last_call_info->start_symbol = label_symbol->lss_label;
a0f75b47
ILT
1455 symbol_get_bfdsym (label_symbol->lss_label)->flags
1456 |= BSF_FUNCTION;
252b5132
RH
1457#ifdef OBJ_SOM
1458 /* Also handle allocation of a fixup to hold the unwind
1459 information when the label appears after the proc/procend. */
1460 if (within_entry_exit)
1461 {
1462 char *where = frag_more (0);
1463
1464 fix_new_hppa (frag_now, where - frag_now->fr_literal, 0,
1465 NULL, (offsetT) 0, NULL,
1466 0, R_HPPA_ENTRY, e_fsel, 0, 0,
1467 (int *)&last_call_info->ci_unwind.descriptor);
1468 }
1469#endif
1470 }
1471 else
1472 as_bad (_("Missing function name for .PROC (corrupted label chain)"));
1473 }
1474 else
1475 as_bad (_("Missing function name for .PROC"));
1476 }
1477
1478 /* Assemble the instruction. Results are saved into "the_insn". */
1479 pa_ip (str);
1480
1481 /* Get somewhere to put the assembled instrution. */
1482 to = frag_more (4);
1483
a28a3ccf 1484 /* Output the opcode. */
252b5132
RH
1485 md_number_to_chars (to, the_insn.opcode, 4);
1486
1487 /* If necessary output more stuff. */
1488 if (the_insn.reloc != R_HPPA_NONE)
1489 fix_new_hppa (frag_now, (to - frag_now->fr_literal), 4, NULL,
1490 (offsetT) 0, &the_insn.exp, the_insn.pcrel,
1491 the_insn.reloc, the_insn.field_selector,
1492 the_insn.format, the_insn.arg_reloc, NULL);
2d93dcc4
JL
1493
1494#ifdef OBJ_ELF
1495 if (debug_type == DEBUG_DWARF2)
b52c78b8
JL
1496 {
1497 bfd_vma addr;
1498
e061d86f
JL
1499 /* First update the notion of the current source line. */
1500 dwarf2_where (&debug_line);
1501
1502 /* We want the offset of the start of this instruction within the
1503 the current frag. */
1504 addr = frag_now->fr_address + frag_now_fix () - 4;
2d93dcc4 1505
e061d86f 1506 /* And record the information. */
b52c78b8 1507 dwarf2_gen_line_info (addr, &debug_line);
b52c78b8
JL
1508 }
1509#endif
252b5132
RH
1510}
1511
1512/* Do the real work for assembling a single instruction. Store results
1513 into the global "the_insn" variable. */
1514
1515static void
1516pa_ip (str)
1517 char *str;
1518{
1519 char *error_message = "";
1520 char *s, c, *argstart, *name, *save_s;
1521 const char *args;
1522 int match = FALSE;
1523 int comma = 0;
1524 int cmpltr, nullif, flag, cond, num;
1525 unsigned long opcode;
1526 struct pa_opcode *insn;
1527
49863f82 1528#ifdef OBJ_SOM
252b5132
RH
1529 /* We must have a valid space and subspace. */
1530 pa_check_current_space_and_subspace ();
49863f82 1531#endif
252b5132 1532
b1c5e0ee
JL
1533 /* Convert everything up to the first whitespace character into lower
1534 case. */
1535 for (s = str; *s != ' ' && *s != '\t' && *s != '\n' && *s != '\0'; s++)
1536 if (isupper (*s))
1537 *s = tolower (*s);
1538
252b5132
RH
1539 /* Skip to something interesting. */
1540 for (s = str; isupper (*s) || islower (*s) || (*s >= '0' && *s <= '3'); ++s)
1541 ;
1542
1543 switch (*s)
1544 {
1545
1546 case '\0':
1547 break;
1548
1549 case ',':
1550 comma = 1;
1551
1552 /*FALLTHROUGH */
1553
1554 case ' ':
1555 *s++ = '\0';
1556 break;
1557
1558 default:
1559 as_fatal (_("Unknown opcode: `%s'"), str);
1560 }
1561
1562 save_s = str;
1563
252b5132
RH
1564 /* Look up the opcode in the has table. */
1565 if ((insn = (struct pa_opcode *) hash_find (op_hash, str)) == NULL)
1566 {
1567 as_bad ("Unknown opcode: `%s'", str);
1568 return;
1569 }
1570
1571 if (comma)
1572 {
1573 *--s = ',';
1574 }
1575
1576 /* Mark the location where arguments for the instruction start, then
1577 start processing them. */
1578 argstart = s;
1579 for (;;)
1580 {
1581 /* Do some initialization. */
1582 opcode = insn->match;
0f4f8b56 1583 strict = (insn->flags & FLAG_STRICT);
252b5132
RH
1584 memset (&the_insn, 0, sizeof (the_insn));
1585
1586 the_insn.reloc = R_HPPA_NONE;
1587
1588 /* If this instruction is specific to a particular architecture,
1589 then set a new architecture. */
1590 /* But do not automatically promote to pa2.0. The automatic promotion
1591 crud is for compatability with HP's old assemblers only. */
1592 if (insn->arch < 20
1593 && bfd_get_mach (stdoutput) < insn->arch)
1594 {
1595 if (!bfd_set_arch_mach (stdoutput, bfd_arch_hppa, insn->arch))
1596 as_warn (_("could not update architecture and machine"));
1597 }
1598 else if (bfd_get_mach (stdoutput) < insn->arch)
1599 {
1600 match = FALSE;
1601 goto failed;
1602 }
1603
1604 /* Build the opcode, checking as we go to make
1605 sure that the operands match. */
1606 for (args = insn->args;; ++args)
1607 {
680ef6de
JL
1608 /* Absorb white space in instruction. */
1609 while (*s == ' ' || *s == '\t')
1610 s++;
1611
252b5132
RH
1612 switch (*args)
1613 {
1614
1615 /* End of arguments. */
1616 case '\0':
1617 if (*s == '\0')
1618 match = TRUE;
1619 break;
1620
1621 case '+':
1622 if (*s == '+')
1623 {
1624 ++s;
1625 continue;
1626 }
1627 if (*s == '-')
1628 continue;
1629 break;
1630
1631 /* These must match exactly. */
1632 case '(':
1633 case ')':
1634 case ',':
1635 case ' ':
1636 if (*s++ == *args)
1637 continue;
1638 break;
1639
1640 /* Handle a 5 bit register or control register field at 10. */
1641 case 'b':
1642 case '^':
ecacdc7a 1643 if (!pa_parse_number (&s, 0))
0f4f8b56 1644 break;
ecacdc7a 1645 num = pa_number;
252b5132
RH
1646 CHECK_FIELD (num, 31, 0, 0);
1647 INSERT_FIELD_AND_CONTINUE (opcode, num, 21);
1648
a97685e9
JL
1649 /* Handle %sar or %cr11. No bits get set, we just verify that it
1650 is there. */
1651 case '!':
1652 /* Skip whitespace before register. */
1653 while (*s == ' ' || *s == '\t')
1654 s = s + 1;
1655
1656 if (!strncasecmp(s, "%sar", 4))
1657 {
1658 s += 4;
1659 continue;
1660 }
1661 else if (!strncasecmp(s, "%cr11", 5))
1662 {
1663 s += 5;
1664 continue;
1665 }
1666 break;
1667
252b5132
RH
1668 /* Handle a 5 bit register field at 15. */
1669 case 'x':
ecacdc7a 1670 if (!pa_parse_number (&s, 0))
0f4f8b56 1671 break;
ecacdc7a 1672 num = pa_number;
252b5132
RH
1673 CHECK_FIELD (num, 31, 0, 0);
1674 INSERT_FIELD_AND_CONTINUE (opcode, num, 16);
1675
1676 /* Handle a 5 bit register field at 31. */
252b5132 1677 case 't':
ecacdc7a 1678 if (!pa_parse_number (&s, 0))
0f4f8b56 1679 break;
ecacdc7a 1680 num = pa_number;
252b5132
RH
1681 CHECK_FIELD (num, 31, 0, 0);
1682 INSERT_FIELD_AND_CONTINUE (opcode, num, 0);
1683
413c94ba
JL
1684 /* Handle a 5 bit register field at 10 and 15. */
1685 case 'a':
ecacdc7a 1686 if (!pa_parse_number (&s, 0))
0f4f8b56 1687 break;
ecacdc7a 1688 num = pa_number;
413c94ba
JL
1689 CHECK_FIELD (num, 31, 0, 0);
1690 opcode |= num << 16;
1691 INSERT_FIELD_AND_CONTINUE (opcode, num, 21);
1692
252b5132
RH
1693 /* Handle a 5 bit field length at 31. */
1694 case 'T':
1695 num = pa_get_absolute_expression (&the_insn, &s);
0f4f8b56
JL
1696 if (strict && the_insn.exp.X_op != O_constant)
1697 break;
252b5132
RH
1698 s = expr_end;
1699 CHECK_FIELD (num, 32, 1, 0);
1700 INSERT_FIELD_AND_CONTINUE (opcode, 32 - num, 0);
1701
1702 /* Handle a 5 bit immediate at 15. */
1703 case '5':
1704 num = pa_get_absolute_expression (&the_insn, &s);
0f4f8b56
JL
1705 if (strict && the_insn.exp.X_op != O_constant)
1706 break;
252b5132 1707 s = expr_end;
0f4f8b56
JL
1708 /* When in strict mode, we want to just reject this
1709 match instead of giving an out of range error. */
1710 CHECK_FIELD (num, 15, -16, strict);
3f9b03b5 1711 num = low_sign_unext (num, 5);
252b5132
RH
1712 INSERT_FIELD_AND_CONTINUE (opcode, num, 16);
1713
1714 /* Handle a 5 bit immediate at 31. */
1715 case 'V':
1716 num = pa_get_absolute_expression (&the_insn, &s);
0f4f8b56
JL
1717 if (strict && the_insn.exp.X_op != O_constant)
1718 break;
252b5132 1719 s = expr_end;
0f4f8b56
JL
1720 /* When in strict mode, we want to just reject this
1721 match instead of giving an out of range error. */
ad1079af 1722 CHECK_FIELD (num, 15, -16, strict);
3f9b03b5 1723 num = low_sign_unext (num, 5);
252b5132
RH
1724 INSERT_FIELD_AND_CONTINUE (opcode, num, 0);
1725
1726 /* Handle an unsigned 5 bit immediate at 31. */
1727 case 'r':
1728 num = pa_get_absolute_expression (&the_insn, &s);
0f4f8b56
JL
1729 if (strict && the_insn.exp.X_op != O_constant)
1730 break;
252b5132 1731 s = expr_end;
ad1079af
AM
1732 CHECK_FIELD (num, 31, 0, strict);
1733 INSERT_FIELD_AND_CONTINUE (opcode, num, 0);
252b5132
RH
1734
1735 /* Handle an unsigned 5 bit immediate at 15. */
1736 case 'R':
1737 num = pa_get_absolute_expression (&the_insn, &s);
0f4f8b56
JL
1738 if (strict && the_insn.exp.X_op != O_constant)
1739 break;
252b5132 1740 s = expr_end;
0f4f8b56 1741 CHECK_FIELD (num, 31, 0, strict);
252b5132
RH
1742 INSERT_FIELD_AND_CONTINUE (opcode, num, 16);
1743
680ef6de
JL
1744 /* Handle an unsigned 10 bit immediate at 15. */
1745 case 'U':
1746 num = pa_get_absolute_expression (&the_insn, &s);
0f4f8b56
JL
1747 if (strict && the_insn.exp.X_op != O_constant)
1748 break;
680ef6de 1749 s = expr_end;
0f4f8b56 1750 CHECK_FIELD (num, 1023, 0, strict);
680ef6de
JL
1751 INSERT_FIELD_AND_CONTINUE (opcode, num, 16);
1752
252b5132
RH
1753 /* Handle a 2 bit space identifier at 17. */
1754 case 's':
ecacdc7a 1755 if (!pa_parse_number (&s, 0))
0f4f8b56 1756 break;
ecacdc7a 1757 num = pa_number;
252b5132
RH
1758 CHECK_FIELD (num, 3, 0, 1);
1759 INSERT_FIELD_AND_CONTINUE (opcode, num, 14);
1760
1761 /* Handle a 3 bit space identifier at 18. */
1762 case 'S':
ecacdc7a 1763 if (!pa_parse_number (&s, 0))
0f4f8b56 1764 break;
ecacdc7a 1765 num = pa_number;
252b5132 1766 CHECK_FIELD (num, 7, 0, 1);
ad1079af 1767 opcode |= re_assemble_3 (num);
3f9b03b5 1768 continue;
252b5132 1769
28252e61 1770 /* Handle all completers. */
252b5132 1771 case 'c':
28252e61
JL
1772 switch (*++args)
1773 {
1774
1775 /* Handle a completer for an indexing load or store. */
1776 case 'x':
252b5132 1777 {
28252e61
JL
1778 int uu = 0;
1779 int m = 0;
1780 int i = 0;
1781 while (*s == ',' && i < 2)
252b5132 1782 {
28252e61
JL
1783 s++;
1784 if (strncasecmp (s, "sm", 2) == 0)
1785 {
1786 uu = 1;
1787 m = 1;
1788 s++;
1789 i++;
1790 }
1791 else if (strncasecmp (s, "m", 1) == 0)
1792 m = 1;
d53d2751
JL
1793 else if ((strncasecmp (s, "s ", 2) == 0)
1794 || (strncasecmp (s, "s,", 2) == 0))
28252e61 1795 uu = 1;
0f4f8b56
JL
1796 /* When in strict mode this is a match failure. */
1797 else if (strict)
d53d2751
JL
1798 {
1799 s--;
1800 break;
1801 }
28252e61
JL
1802 else
1803 as_bad (_("Invalid Indexed Load Completer."));
252b5132
RH
1804 s++;
1805 i++;
1806 }
28252e61
JL
1807 if (i > 2)
1808 as_bad (_("Invalid Indexed Load Completer Syntax."));
1809 opcode |= m << 5;
1810 INSERT_FIELD_AND_CONTINUE (opcode, uu, 13);
252b5132 1811 }
252b5132 1812
28252e61
JL
1813 /* Handle a short load/store completer. */
1814 case 'm':
61dd1d31 1815 case 'q':
71823da4 1816 case 'J':
d53d2751 1817 case 'e':
252b5132 1818 {
28252e61
JL
1819 int a = 0;
1820 int m = 0;
1821 if (*s == ',')
252b5132 1822 {
d53d2751 1823 int found = 0;
28252e61
JL
1824 s++;
1825 if (strncasecmp (s, "ma", 2) == 0)
1826 {
1827 a = 0;
1828 m = 1;
d53d2751 1829 found = 1;
28252e61
JL
1830 }
1831 else if (strncasecmp (s, "mb", 2) == 0)
1832 {
1833 a = 1;
1834 m = 1;
d53d2751 1835 found = 1;
28252e61 1836 }
d53d2751
JL
1837
1838 /* When in strict mode, pass through for cache op. */
1839 if (!found && strict)
1840 s--;
28252e61 1841 else
d53d2751
JL
1842 {
1843 if (!found)
1844 as_bad (_("Invalid Short Load/Store Completer."));
1845 s += 2;
1846 }
252b5132 1847 }
65fab780 1848 /* If we did not get a ma/mb completer, then we do not
d53d2751
JL
1849 consider this a positive match for 'ce'. */
1850 else if (*args == 'e')
65fab780 1851 break;
252b5132 1852
71823da4
JL
1853 /* 'J', 'm' and 'q' are the same, except for where they
1854 encode the before/after field. */
61dd1d31
JL
1855 if (*args == 'm')
1856 {
1857 opcode |= m << 5;
1858 INSERT_FIELD_AND_CONTINUE (opcode, a, 13);
1859 }
1860 else if (*args == 'q')
1861 {
1862 opcode |= m << 3;
1863 INSERT_FIELD_AND_CONTINUE (opcode, a, 2);
1864 }
71823da4
JL
1865 else if (*args == 'J')
1866 {
1867 /* M bit is explicit in the major opcode. */
1868 INSERT_FIELD_AND_CONTINUE (opcode, a, 2);
1869 }
d53d2751 1870 else if (*args == 'e')
65fab780
JL
1871 {
1872 /* Gross! Hide these values in the immediate field
1873 of the instruction, then pull them out later. */
1874 opcode |= m << 8;
1875 opcode |= a << 9;
1876 continue;
1877 }
252b5132 1878 }
252b5132 1879
28252e61
JL
1880 /* Handle a stbys completer. */
1881 case 's':
252b5132 1882 {
28252e61
JL
1883 int a = 0;
1884 int m = 0;
1885 int i = 0;
1886 while (*s == ',' && i < 2)
1887 {
1888 s++;
1889 if (strncasecmp (s, "m", 1) == 0)
1890 m = 1;
d53d2751
JL
1891 else if ((strncasecmp (s, "b ", 2) == 0)
1892 || (strncasecmp (s, "b,", 2) == 0))
28252e61
JL
1893 a = 0;
1894 else if (strncasecmp (s, "e", 1) == 0)
1895 a = 1;
0f4f8b56
JL
1896 /* When in strict mode this is a match failure. */
1897 else if (strict)
d53d2751
JL
1898 {
1899 s--;
1900 break;
1901 }
28252e61
JL
1902 else
1903 as_bad (_("Invalid Store Bytes Short Completer"));
1904 s++;
1905 i++;
1906 }
1907 if (i > 2)
252b5132 1908 as_bad (_("Invalid Store Bytes Short Completer"));
28252e61
JL
1909 opcode |= m << 5;
1910 INSERT_FIELD_AND_CONTINUE (opcode, a, 13);
252b5132 1911 }
28252e61 1912
d53d2751
JL
1913 /* Handle load cache hint completer. */
1914 case 'c':
1915 cmpltr = 0;
1916 if (!strncmp(s, ",sl", 3))
1917 {
1918 s += 3;
1919 cmpltr = 2;
1920 }
1921 INSERT_FIELD_AND_CONTINUE (opcode, cmpltr, 10);
1922
1923 /* Handle store cache hint completer. */
1924 case 'C':
1925 cmpltr = 0;
1926 if (!strncmp(s, ",sl", 3))
1927 {
1928 s += 3;
1929 cmpltr = 2;
1930 }
1931 else if (!strncmp(s, ",bc", 3))
1932 {
1933 s += 3;
1934 cmpltr = 1;
1935 }
1936 INSERT_FIELD_AND_CONTINUE (opcode, cmpltr, 10);
1937
1938 /* Handle load and clear cache hint completer. */
1939 case 'd':
1940 cmpltr = 0;
1941 if (!strncmp(s, ",co", 3))
1942 {
1943 s += 3;
1944 cmpltr = 1;
1945 }
1946 INSERT_FIELD_AND_CONTINUE (opcode, cmpltr, 10);
1947
a28a3ccf 1948 /* Handle load ordering completer. */
d53d2751
JL
1949 case 'o':
1950 if (strncmp(s, ",o", 2) != 0)
1951 break;
1952 s += 2;
1953 continue;
1954
ce674324
JL
1955 /* Handle a branch gate completer. */
1956 case 'g':
1957 if (strncasecmp (s, ",gate", 5) != 0)
1958 break;
1959 s += 5;
1960 continue;
1961
1962 /* Handle a branch link and push completer. */
1963 case 'p':
1964 if (strncasecmp (s, ",l,push", 7) != 0)
1965 break;
1966 s += 7;
1967 continue;
1968
1969 /* Handle a branch link completer. */
1970 case 'l':
1971 if (strncasecmp (s, ",l", 2) != 0)
1972 break;
1973 s += 2;
1974 continue;
1975
1976 /* Handle a branch pop completer. */
1977 case 'P':
1978 if (strncasecmp (s, ",pop", 4) != 0)
1979 break;
1980 s += 4;
1981 continue;
1982
680ef6de
JL
1983 /* Handle a local processor completer. */
1984 case 'L':
1985 if (strncasecmp (s, ",l", 2) != 0)
1986 break;
1987 s += 2;
1988 continue;
1989
1990 /* Handle a PROBE read/write completer. */
1991 case 'w':
1992 flag = 0;
1993 if (!strncasecmp (s, ",w", 2))
1994 {
1995 flag = 1;
1996 s += 2;
1997 }
1998 else if (!strncasecmp (s, ",r", 2))
1999 {
2000 flag = 0;
2001 s += 2;
2002 }
2003
2004 INSERT_FIELD_AND_CONTINUE (opcode, flag, 6);
2005
2006 /* Handle MFCTL wide completer. */
d53d2751 2007 case 'W':
680ef6de
JL
2008 if (strncasecmp (s, ",w", 2) != 0)
2009 break;
2010 s += 2;
2011 continue;
2012
2013 /* Handle an RFI restore completer. */
2014 case 'r':
2015 flag = 0;
2016 if (!strncasecmp (s, ",r", 2))
2017 {
2018 flag = 5;
2019 s += 2;
2020 }
2021
2022 INSERT_FIELD_AND_CONTINUE (opcode, flag, 5);
2023
28252e61
JL
2024 /* Handle a system control completer. */
2025 case 'Z':
2026 if (*s == ',' && (*(s + 1) == 'm' || *(s + 1) == 'M'))
2027 {
2028 flag = 1;
2029 s += 2;
2030 }
2031 else
2032 flag = 0;
2033
2034 INSERT_FIELD_AND_CONTINUE (opcode, flag, 5);
2035
680ef6de
JL
2036 /* Handle intermediate/final completer for DCOR. */
2037 case 'i':
2038 flag = 0;
2039 if (!strncasecmp (s, ",i", 2))
2040 {
2041 flag = 1;
2042 s += 2;
2043 }
2044
2045 INSERT_FIELD_AND_CONTINUE (opcode, flag, 6);
2046
9e4f2d3a
JL
2047 /* Handle zero/sign extension completer. */
2048 case 'z':
2049 flag = 1;
2050 if (!strncasecmp (s, ",z", 2))
2051 {
2052 flag = 0;
2053 s += 2;
2054 }
2055
2056 INSERT_FIELD_AND_CONTINUE (opcode, flag, 10);
2057
680ef6de
JL
2058 /* Handle add completer. */
2059 case 'a':
2060 flag = 1;
2061 if (!strncasecmp (s, ",l", 2))
2062 {
2063 flag = 2;
2064 s += 2;
2065 }
2066 else if (!strncasecmp (s, ",tsv", 4))
2067 {
2068 flag = 3;
2069 s += 4;
2070 }
d53d2751 2071
680ef6de
JL
2072 INSERT_FIELD_AND_CONTINUE (opcode, flag, 10);
2073
2074 /* Handle 64 bit carry for ADD. */
2075 case 'Y':
2076 flag = 0;
2077 if (!strncasecmp (s, ",dc,tsv", 7) ||
2078 !strncasecmp (s, ",tsv,dc", 7))
2079 {
2080 flag = 1;
2081 s += 7;
2082 }
2083 else if (!strncasecmp (s, ",dc", 3))
2084 {
2085 flag = 0;
2086 s += 3;
2087 }
2088 else
2089 break;
2090
2091 INSERT_FIELD_AND_CONTINUE (opcode, flag, 11);
2092
2093 /* Handle 32 bit carry for ADD. */
2094 case 'y':
2095 flag = 0;
2096 if (!strncasecmp (s, ",c,tsv", 6) ||
2097 !strncasecmp (s, ",tsv,c", 6))
2098 {
2099 flag = 1;
2100 s += 6;
2101 }
2102 else if (!strncasecmp (s, ",c", 2))
2103 {
2104 flag = 0;
2105 s += 2;
2106 }
2107 else
2108 break;
2109
2110 INSERT_FIELD_AND_CONTINUE (opcode, flag, 11);
2111
2112 /* Handle trap on signed overflow. */
2113 case 'v':
2114 flag = 0;
2115 if (!strncasecmp (s, ",tsv", 4))
2116 {
2117 flag = 1;
2118 s += 4;
2119 }
2120
2121 INSERT_FIELD_AND_CONTINUE (opcode, flag, 11);
2122
2123 /* Handle trap on condition and overflow. */
2124 case 't':
2125 flag = 0;
2126 if (!strncasecmp (s, ",tc,tsv", 7) ||
2127 !strncasecmp (s, ",tsv,tc", 7))
2128 {
2129 flag = 1;
2130 s += 7;
2131 }
2132 else if (!strncasecmp (s, ",tc", 3))
2133 {
2134 flag = 0;
2135 s += 3;
2136 }
2137 else
2138 break;
2139
2140 INSERT_FIELD_AND_CONTINUE (opcode, flag, 11);
2141
2142 /* Handle 64 bit borrow for SUB. */
2143 case 'B':
2144 flag = 0;
2145 if (!strncasecmp (s, ",db,tsv", 7) ||
2146 !strncasecmp (s, ",tsv,db", 7))
2147 {
2148 flag = 1;
2149 s += 7;
2150 }
2151 else if (!strncasecmp (s, ",db", 3))
2152 {
2153 flag = 0;
2154 s += 3;
2155 }
2156 else
2157 break;
2158
2159 INSERT_FIELD_AND_CONTINUE (opcode, flag, 11);
2160
2161 /* Handle 32 bit borrow for SUB. */
2162 case 'b':
2163 flag = 0;
2164 if (!strncasecmp (s, ",b,tsv", 6) ||
2165 !strncasecmp (s, ",tsv,b", 6))
2166 {
2167 flag = 1;
2168 s += 6;
2169 }
2170 else if (!strncasecmp (s, ",b", 2))
2171 {
2172 flag = 0;
2173 s += 2;
2174 }
2175 else
2176 break;
2177
2178 INSERT_FIELD_AND_CONTINUE (opcode, flag, 11);
2179
2180 /* Handle trap condition completer for UADDCM. */
2181 case 'T':
2182 flag = 0;
2183 if (!strncasecmp (s, ",tc", 3))
2184 {
2185 flag = 1;
2186 s += 3;
2187 }
2188
2189 INSERT_FIELD_AND_CONTINUE (opcode, flag, 6);
2190
413c94ba
JL
2191 /* Handle signed/unsigned at 21. */
2192 case 'S':
2193 {
2194 int sign = 1;
2195 if (strncasecmp (s, ",s", 2) == 0)
2196 {
2197 sign = 1;
2198 s += 2;
2199 }
2200 else if (strncasecmp (s, ",u", 2) == 0)
2201 {
2202 sign = 0;
2203 s += 2;
2204 }
2205
2206 INSERT_FIELD_AND_CONTINUE (opcode, sign, 10);
2207 }
2208
2209 /* Handle left/right combination at 17:18. */
2210 case 'h':
2211 if (*s++ == ',')
2212 {
2213 int lr = 0;
2214 if (*s == 'r')
2215 lr = 2;
2216 else if (*s == 'l')
2217 lr = 0;
2218 else
2219 as_bad(_("Invalid left/right combination completer"));
2220
2221 s++;
2222 INSERT_FIELD_AND_CONTINUE (opcode, lr, 13);
2223 }
2224 else
2225 as_bad(_("Invalid left/right combination completer"));
2226 break;
2227
2228 /* Handle saturation at 24:25. */
2229 case 'H':
2230 {
2231 int sat = 3;
2232 if (strncasecmp (s, ",ss", 3) == 0)
2233 {
2234 sat = 1;
2235 s += 3;
2236 }
2237 else if (strncasecmp (s, ",us", 3) == 0)
2238 {
2239 sat = 0;
2240 s += 3;
2241 }
2242
2243 INSERT_FIELD_AND_CONTINUE (opcode, sat, 6);
2244 }
2245
2246 /* Handle permutation completer. */
2247 case '*':
2248 if (*s++ == ',')
2249 {
b1039fc4 2250 int permloc[4];
413c94ba
JL
2251 int perm = 0;
2252 int i = 0;
b1039fc4
JL
2253 permloc[0] = 13;
2254 permloc[1] = 10;
2255 permloc[2] = 8;
2256 permloc[3] = 6;
413c94ba
JL
2257 for (; i < 4; i++)
2258 {
2259 switch (*s++)
2260 {
2261 case '0':
2262 perm = 0;
2263 break;
2264 case '1':
2265 perm = 1;
2266 break;
2267 case '2':
2268 perm = 2;
2269 break;
2270 case '3':
2271 perm = 3;
2272 break;
2273 default:
2274 as_bad(_("Invalid permutation completer"));
2275 }
2276 opcode |= perm << permloc[i];
2277 }
2278 continue;
2279 }
2280 else
2281 as_bad(_("Invalid permutation completer"));
2282 break;
2283
28252e61
JL
2284 default:
2285 abort ();
2286 }
2287 break;
252b5132 2288
55a914bc 2289 /* Handle all conditions. */
252b5132 2290 case '?':
55a914bc
JL
2291 {
2292 args++;
2293 switch (*args)
2294 {
2295 /* Handle FP compare conditions. */
2296 case 'f':
2297 cond = pa_parse_fp_cmp_cond (&s);
2298 INSERT_FIELD_AND_CONTINUE (opcode, cond, 0);
2299
2300 /* Handle an add condition. */
9a913dfb 2301 case 'A':
55a914bc
JL
2302 case 'a':
2303 cmpltr = 0;
2304 flag = 0;
2305 if (*s == ',')
2306 {
2307 s++;
9a913dfb
JL
2308
2309 /* 64 bit conditions. */
2310 if (*args == 'A')
2311 {
2312 if (*s == '*')
2313 s++;
2314 else
2315 break;
2316 }
17d9105c
JL
2317 else if (*s == '*')
2318 break;
55a914bc 2319 name = s;
9a913dfb 2320
680ef6de 2321 name = s;
55a914bc
JL
2322 while (*s != ',' && *s != ' ' && *s != '\t')
2323 s += 1;
2324 c = *s;
2325 *s = 0x00;
2326 if (strcmp (name, "=") == 0)
2327 cmpltr = 1;
2328 else if (strcmp (name, "<") == 0)
2329 cmpltr = 2;
2330 else if (strcmp (name, "<=") == 0)
2331 cmpltr = 3;
2332 else if (strcasecmp (name, "nuv") == 0)
2333 cmpltr = 4;
2334 else if (strcasecmp (name, "znv") == 0)
2335 cmpltr = 5;
2336 else if (strcasecmp (name, "sv") == 0)
2337 cmpltr = 6;
2338 else if (strcasecmp (name, "od") == 0)
2339 cmpltr = 7;
2340 else if (strcasecmp (name, "tr") == 0)
2341 {
2342 cmpltr = 0;
2343 flag = 1;
2344 }
2345 else if (strcmp (name, "<>") == 0)
2346 {
2347 cmpltr = 1;
2348 flag = 1;
2349 }
2350 else if (strcmp (name, ">=") == 0)
2351 {
2352 cmpltr = 2;
2353 flag = 1;
2354 }
2355 else if (strcmp (name, ">") == 0)
2356 {
2357 cmpltr = 3;
2358 flag = 1;
2359 }
2360 else if (strcasecmp (name, "uv") == 0)
2361 {
2362 cmpltr = 4;
2363 flag = 1;
2364 }
2365 else if (strcasecmp (name, "vnz") == 0)
2366 {
2367 cmpltr = 5;
2368 flag = 1;
2369 }
2370 else if (strcasecmp (name, "nsv") == 0)
2371 {
2372 cmpltr = 6;
2373 flag = 1;
2374 }
2375 else if (strcasecmp (name, "ev") == 0)
2376 {
2377 cmpltr = 7;
2378 flag = 1;
2379 }
9a913dfb
JL
2380 /* ",*" is a valid condition. */
2381 else if (*args == 'a')
55a914bc
JL
2382 as_bad (_("Invalid Add Condition: %s"), name);
2383 *s = c;
2384 }
2385 opcode |= cmpltr << 13;
2386 INSERT_FIELD_AND_CONTINUE (opcode, flag, 12);
252b5132 2387
55a914bc
JL
2388 /* Handle non-negated add and branch condition. */
2389 case 'd':
2390 cmpltr = pa_parse_nonneg_add_cmpltr (&s, 1);
2391 if (cmpltr < 0)
2392 {
d53d2751 2393 as_bad (_("Invalid Add and Branch Condition: %c"), *s);
55a914bc
JL
2394 cmpltr = 0;
2395 }
2396 INSERT_FIELD_AND_CONTINUE (opcode, cmpltr, 13);
2397
d53d2751 2398 /* Handle 64 bit wide-mode add and branch condition. */
9a913dfb 2399 case 'W':
d53d2751
JL
2400 cmpltr = pa_parse_addb_64_cmpltr (&s);
2401 if (cmpltr < 0)
2402 {
2403 as_bad (_("Invalid Add and Branch Condition: %c"), *s);
2404 cmpltr = 0;
2405 }
2406 else
2407 {
a28a3ccf 2408 /* Negated condition requires an opcode change. */
d53d2751
JL
2409 opcode |= (cmpltr & 8) << 24;
2410 }
2411 INSERT_FIELD_AND_CONTINUE (opcode, cmpltr & 7, 13);
9a913dfb 2412
d53d2751 2413 /* Handle a negated or non-negated add and branch
55a914bc
JL
2414 condition. */
2415 case '@':
2416 save_s = s;
2417 cmpltr = pa_parse_nonneg_add_cmpltr (&s, 1);
2418 if (cmpltr < 0)
2419 {
2420 s = save_s;
2421 cmpltr = pa_parse_neg_add_cmpltr (&s, 1);
2422 if (cmpltr < 0)
2423 {
2424 as_bad (_("Invalid Compare/Subtract Condition"));
2425 cmpltr = 0;
2426 }
2427 else
2428 {
a28a3ccf 2429 /* Negated condition requires an opcode change. */
55a914bc
JL
2430 opcode |= 1 << 27;
2431 }
2432 }
2433 INSERT_FIELD_AND_CONTINUE (opcode, cmpltr, 13);
252b5132 2434
55a914bc 2435 /* Handle branch on bit conditions. */
9a913dfb 2436 case 'B':
55a914bc
JL
2437 case 'b':
2438 cmpltr = 0;
2439 if (*s == ',')
2440 {
2441 s++;
9a913dfb
JL
2442
2443 if (*args == 'B')
2444 {
2445 if (*s == '*')
2446 s++;
2447 else
2448 break;
2449 }
17d9105c
JL
2450 else if (*s == '*')
2451 break;
9a913dfb 2452
55a914bc
JL
2453 if (strncmp (s, "<", 1) == 0)
2454 {
2455 cmpltr = 0;
2456 s++;
2457 }
2458 else if (strncmp (s, ">=", 2) == 0)
2459 {
2460 cmpltr = 1;
2461 s += 2;
2462 }
2463 else
2464 as_bad (_("Invalid Bit Branch Condition: %c"), *s);
2465 }
2466 INSERT_FIELD_AND_CONTINUE (opcode, cmpltr, 15);
252b5132 2467
55a914bc 2468 /* Handle a compare/subtract condition. */
9a913dfb 2469 case 'S':
55a914bc
JL
2470 case 's':
2471 cmpltr = 0;
2472 flag = 0;
2473 if (*s == ',')
2474 {
2475 s++;
9a913dfb
JL
2476
2477 /* 64 bit conditions. */
2478 if (*args == 'S')
d53d2751 2479 {
9a913dfb
JL
2480 if (*s == '*')
2481 s++;
2482 else
2483 break;
d53d2751 2484 }
17d9105c
JL
2485 else if (*s == '*')
2486 break;
55a914bc 2487 name = s;
d53d2751 2488
680ef6de 2489 name = s;
55a914bc
JL
2490 while (*s != ',' && *s != ' ' && *s != '\t')
2491 s += 1;
2492 c = *s;
2493 *s = 0x00;
2494 if (strcmp (name, "=") == 0)
2495 cmpltr = 1;
2496 else if (strcmp (name, "<") == 0)
2497 cmpltr = 2;
2498 else if (strcmp (name, "<=") == 0)
2499 cmpltr = 3;
2500 else if (strcasecmp (name, "<<") == 0)
2501 cmpltr = 4;
2502 else if (strcasecmp (name, "<<=") == 0)
2503 cmpltr = 5;
2504 else if (strcasecmp (name, "sv") == 0)
2505 cmpltr = 6;
2506 else if (strcasecmp (name, "od") == 0)
2507 cmpltr = 7;
2508 else if (strcasecmp (name, "tr") == 0)
2509 {
2510 cmpltr = 0;
2511 flag = 1;
2512 }
2513 else if (strcmp (name, "<>") == 0)
2514 {
2515 cmpltr = 1;
2516 flag = 1;
2517 }
2518 else if (strcmp (name, ">=") == 0)
2519 {
2520 cmpltr = 2;
2521 flag = 1;
2522 }
2523 else if (strcmp (name, ">") == 0)
2524 {
2525 cmpltr = 3;
2526 flag = 1;
2527 }
2528 else if (strcasecmp (name, ">>=") == 0)
2529 {
2530 cmpltr = 4;
2531 flag = 1;
2532 }
2533 else if (strcasecmp (name, ">>") == 0)
2534 {
2535 cmpltr = 5;
2536 flag = 1;
2537 }
2538 else if (strcasecmp (name, "nsv") == 0)
2539 {
2540 cmpltr = 6;
2541 flag = 1;
2542 }
2543 else if (strcasecmp (name, "ev") == 0)
2544 {
2545 cmpltr = 7;
2546 flag = 1;
2547 }
9a913dfb
JL
2548 /* ",*" is a valid condition. */
2549 else if (*args != 'S')
55a914bc
JL
2550 as_bad (_("Invalid Compare/Subtract Condition: %s"),
2551 name);
2552 *s = c;
2553 }
2554 opcode |= cmpltr << 13;
2555 INSERT_FIELD_AND_CONTINUE (opcode, flag, 12);
252b5132 2556
55a914bc
JL
2557 /* Handle a non-negated compare condition. */
2558 case 't':
2559 cmpltr = pa_parse_nonneg_cmpsub_cmpltr (&s, 1);
2560 if (cmpltr < 0)
2561 {
2562 as_bad (_("Invalid Compare/Subtract Condition: %c"), *s);
2563 cmpltr = 0;
2564 }
2565 INSERT_FIELD_AND_CONTINUE (opcode, cmpltr, 13);
9a913dfb 2566
d53d2751 2567 /* Handle a 32 bit compare and branch condition. */
55a914bc
JL
2568 case 'n':
2569 save_s = s;
2570 cmpltr = pa_parse_nonneg_cmpsub_cmpltr (&s, 1);
2571 if (cmpltr < 0)
2572 {
2573 s = save_s;
2574 cmpltr = pa_parse_neg_cmpsub_cmpltr (&s, 1);
2575 if (cmpltr < 0)
2576 {
d53d2751 2577 as_bad (_("Invalid Compare and Branch Condition."));
55a914bc
JL
2578 cmpltr = 0;
2579 }
2580 else
2581 {
a28a3ccf 2582 /* Negated condition requires an opcode change. */
55a914bc
JL
2583 opcode |= 1 << 27;
2584 }
2585 }
d53d2751
JL
2586
2587 INSERT_FIELD_AND_CONTINUE (opcode, cmpltr, 13);
2588
2589 /* Handle a 64 bit compare and branch condition. */
2590 case 'N':
2591 cmpltr = pa_parse_cmpb_64_cmpltr (&s);
2592 if (cmpltr >= 0)
2593 {
a28a3ccf 2594 /* Negated condition requires an opcode change. */
d53d2751
JL
2595 opcode |= (cmpltr & 8) << 26;
2596 }
2597 else
a28a3ccf 2598 /* Not a 64 bit cond. Give 32 bit a chance. */
d53d2751
JL
2599 break;
2600
2601 INSERT_FIELD_AND_CONTINUE (opcode, cmpltr & 7, 13);
2602
2603 /* Handle a 64 bit cmpib condition. */
2604 case 'Q':
2605 cmpltr = pa_parse_cmpib_64_cmpltr (&s);
2606 if (cmpltr < 0)
a28a3ccf 2607 /* Not a 64 bit cond. Give 32 bit a chance. */
d53d2751
JL
2608 break;
2609
55a914bc
JL
2610 INSERT_FIELD_AND_CONTINUE (opcode, cmpltr, 13);
2611
2612 /* Handle a logical instruction condition. */
9a913dfb 2613 case 'L':
55a914bc
JL
2614 case 'l':
2615 cmpltr = 0;
2616 flag = 0;
2617 if (*s == ',')
2618 {
2619 s++;
9a913dfb
JL
2620
2621 /* 64 bit conditions. */
2622 if (*args == 'L')
2623 {
2624 if (*s == '*')
2625 s++;
2626 else
2627 break;
2628 }
17d9105c
JL
2629 else if (*s == '*')
2630 break;
d53d2751 2631
680ef6de 2632 name = s;
55a914bc
JL
2633 while (*s != ',' && *s != ' ' && *s != '\t')
2634 s += 1;
2635 c = *s;
2636 *s = 0x00;
d53d2751 2637
55a914bc
JL
2638 if (strcmp (name, "=") == 0)
2639 cmpltr = 1;
2640 else if (strcmp (name, "<") == 0)
2641 cmpltr = 2;
2642 else if (strcmp (name, "<=") == 0)
2643 cmpltr = 3;
2644 else if (strcasecmp (name, "od") == 0)
2645 cmpltr = 7;
2646 else if (strcasecmp (name, "tr") == 0)
2647 {
2648 cmpltr = 0;
2649 flag = 1;
2650 }
2651 else if (strcmp (name, "<>") == 0)
2652 {
2653 cmpltr = 1;
2654 flag = 1;
2655 }
2656 else if (strcmp (name, ">=") == 0)
2657 {
2658 cmpltr = 2;
2659 flag = 1;
2660 }
2661 else if (strcmp (name, ">") == 0)
2662 {
2663 cmpltr = 3;
2664 flag = 1;
2665 }
2666 else if (strcasecmp (name, "ev") == 0)
2667 {
2668 cmpltr = 7;
2669 flag = 1;
2670 }
9a913dfb
JL
2671 /* ",*" is a valid condition. */
2672 else if (*args != 'L')
55a914bc
JL
2673 as_bad (_("Invalid Logical Instruction Condition."));
2674 *s = c;
2675 }
2676 opcode |= cmpltr << 13;
2677 INSERT_FIELD_AND_CONTINUE (opcode, flag, 12);
2678
2679 /* Handle a shift/extract/deposit condition. */
9a913dfb 2680 case 'X':
55a914bc
JL
2681 case 'x':
2682 case 'y':
2683 cmpltr = 0;
2684 if (*s == ',')
2685 {
2686 save_s = s++;
2687
9a913dfb
JL
2688 /* 64 bit conditions. */
2689 if (*args == 'X')
2690 {
2691 if (*s == '*')
2692 s++;
2693 else
2694 break;
2695 }
17d9105c
JL
2696 else if (*s == '*')
2697 break;
d53d2751 2698
680ef6de 2699 name = s;
55a914bc
JL
2700 while (*s != ',' && *s != ' ' && *s != '\t')
2701 s += 1;
2702 c = *s;
2703 *s = 0x00;
2704 if (strcmp (name, "=") == 0)
2705 cmpltr = 1;
2706 else if (strcmp (name, "<") == 0)
2707 cmpltr = 2;
2708 else if (strcasecmp (name, "od") == 0)
2709 cmpltr = 3;
2710 else if (strcasecmp (name, "tr") == 0)
2711 cmpltr = 4;
2712 else if (strcmp (name, "<>") == 0)
2713 cmpltr = 5;
2714 else if (strcmp (name, ">=") == 0)
2715 cmpltr = 6;
2716 else if (strcasecmp (name, "ev") == 0)
2717 cmpltr = 7;
2718 /* Handle movb,n. Put things back the way they were.
2719 This includes moving s back to where it started. */
2720 else if (strcasecmp (name, "n") == 0 && *args == 'y')
2721 {
2722 *s = c;
2723 s = save_s;
2724 continue;
2725 }
9a913dfb
JL
2726 /* ",*" is a valid condition. */
2727 else if (*args != 'X')
55a914bc
JL
2728 as_bad (_("Invalid Shift/Extract/Deposit Condition."));
2729 *s = c;
2730 }
2731 INSERT_FIELD_AND_CONTINUE (opcode, cmpltr, 13);
252b5132 2732
55a914bc 2733 /* Handle a unit instruction condition. */
9a913dfb
JL
2734 case 'U':
2735 case 'u':
55a914bc
JL
2736 cmpltr = 0;
2737 flag = 0;
2738 if (*s == ',')
2739 {
2740 s++;
d53d2751 2741
9a913dfb
JL
2742 /* 64 bit conditions. */
2743 if (*args == 'U')
2744 {
2745 if (*s == '*')
2746 s++;
2747 else
2748 break;
2749 }
17d9105c
JL
2750 else if (*s == '*')
2751 break;
d53d2751 2752
55a914bc
JL
2753 if (strncasecmp (s, "sbz", 3) == 0)
2754 {
2755 cmpltr = 2;
2756 s += 3;
2757 }
2758 else if (strncasecmp (s, "shz", 3) == 0)
2759 {
2760 cmpltr = 3;
2761 s += 3;
2762 }
2763 else if (strncasecmp (s, "sdc", 3) == 0)
2764 {
2765 cmpltr = 4;
2766 s += 3;
2767 }
2768 else if (strncasecmp (s, "sbc", 3) == 0)
2769 {
2770 cmpltr = 6;
2771 s += 3;
2772 }
2773 else if (strncasecmp (s, "shc", 3) == 0)
2774 {
2775 cmpltr = 7;
2776 s += 3;
2777 }
2778 else if (strncasecmp (s, "tr", 2) == 0)
2779 {
2780 cmpltr = 0;
2781 flag = 1;
2782 s += 2;
2783 }
2784 else if (strncasecmp (s, "nbz", 3) == 0)
2785 {
2786 cmpltr = 2;
2787 flag = 1;
2788 s += 3;
2789 }
2790 else if (strncasecmp (s, "nhz", 3) == 0)
2791 {
2792 cmpltr = 3;
2793 flag = 1;
2794 s += 3;
2795 }
2796 else if (strncasecmp (s, "ndc", 3) == 0)
2797 {
2798 cmpltr = 4;
2799 flag = 1;
2800 s += 3;
2801 }
2802 else if (strncasecmp (s, "nbc", 3) == 0)
2803 {
2804 cmpltr = 6;
2805 flag = 1;
2806 s += 3;
2807 }
2808 else if (strncasecmp (s, "nhc", 3) == 0)
2809 {
2810 cmpltr = 7;
2811 flag = 1;
2812 s += 3;
2813 }
afbf211f
JL
2814 else if (strncasecmp (s, "swz", 3) == 0)
2815 {
2816 cmpltr = 1;
2817 flag = 0;
2818 s += 3;
2819 }
2820 else if (strncasecmp (s, "swc", 3) == 0)
2821 {
2822 cmpltr = 5;
2823 flag = 0;
2824 s += 3;
2825 }
2826 else if (strncasecmp (s, "nwz", 3) == 0)
2827 {
2828 cmpltr = 1;
2829 flag = 1;
2830 s += 3;
2831 }
2832 else if (strncasecmp (s, "nwc", 3) == 0)
2833 {
2834 cmpltr = 5;
2835 flag = 1;
2836 s += 3;
2837 }
9a913dfb
JL
2838 /* ",*" is a valid condition. */
2839 else if (*args != 'U')
55a914bc
JL
2840 as_bad (_("Invalid Unit Instruction Condition."));
2841 }
2842 opcode |= cmpltr << 13;
2843 INSERT_FIELD_AND_CONTINUE (opcode, flag, 12);
252b5132 2844
55a914bc
JL
2845 default:
2846 abort ();
2847 }
0741736b 2848 break;
55a914bc 2849 }
252b5132 2850
252b5132
RH
2851 /* Handle a nullification completer for branch instructions. */
2852 case 'n':
2853 nullif = pa_parse_nullif (&s);
2854 INSERT_FIELD_AND_CONTINUE (opcode, nullif, 1);
2855
2856 /* Handle a nullification completer for copr and spop insns. */
2857 case 'N':
2858 nullif = pa_parse_nullif (&s);
2859 INSERT_FIELD_AND_CONTINUE (opcode, nullif, 5);
2860
dbe2f9ee
JL
2861 /* Handle ,%r2 completer for new syntax branches. */
2862 case 'L':
54af6ff6 2863 if (*s == ',' && strncasecmp (s + 1, "%r2", 3) == 0)
dbe2f9ee 2864 s += 4;
54af6ff6 2865 else if (*s == ',' && strncasecmp (s + 1, "%rp", 3) == 0)
dbe2f9ee
JL
2866 s += 4;
2867 else
2868 break;
2869 continue;
2870
1cf6ae67
JL
2871 /* Handle 3 bit entry into the fp compare array. Valid values
2872 are 0..6 inclusive. */
2873 case 'h':
2874 get_expression (s);
2875 s = expr_end;
2876 if (the_insn.exp.X_op == O_constant)
2877 {
2878 num = evaluate_absolute (&the_insn);
2879 CHECK_FIELD (num, 6, 0, 0);
2880 num++;
2881 INSERT_FIELD_AND_CONTINUE (opcode, num, 13);
2882 }
2883 else
2884 break;
2885
2886 /* Handle 3 bit entry into the fp compare array. Valid values
2887 are 0..6 inclusive. */
2888 case 'm':
2889 get_expression (s);
1cf6ae67
JL
2890 if (the_insn.exp.X_op == O_constant)
2891 {
b1039fc4 2892 s = expr_end;
1cf6ae67
JL
2893 num = evaluate_absolute (&the_insn);
2894 CHECK_FIELD (num, 6, 0, 0);
2895 num = (num + 1) ^ 1;
2896 INSERT_FIELD_AND_CONTINUE (opcode, num, 13);
2897 }
2898 else
b1039fc4 2899 break;
1cf6ae67
JL
2900
2901 /* Handle graphics test completers for ftest */
2902 case '=':
2903 {
2904 num = pa_parse_ftest_gfx_completer (&s);
2905 INSERT_FIELD_AND_CONTINUE (opcode, num, 0);
2906 }
2907
252b5132
RH
2908 /* Handle a 11 bit immediate at 31. */
2909 case 'i':
2910 the_insn.field_selector = pa_chk_field_selector (&s);
2911 get_expression (s);
2912 s = expr_end;
2913 if (the_insn.exp.X_op == O_constant)
2914 {
2915 num = evaluate_absolute (&the_insn);
2916 CHECK_FIELD (num, 1023, -1024, 0);
3f9b03b5 2917 num = low_sign_unext (num, 11);
252b5132
RH
2918 INSERT_FIELD_AND_CONTINUE (opcode, num, 0);
2919 }
2920 else
2921 {
2922 if (is_DP_relative (the_insn.exp))
2923 the_insn.reloc = R_HPPA_GOTOFF;
2924 else if (is_PC_relative (the_insn.exp))
2925 the_insn.reloc = R_HPPA_PCREL_CALL;
2926 else
2927 the_insn.reloc = R_HPPA;
2928 the_insn.format = 11;
2929 continue;
2930 }
2931
65fab780
JL
2932 /* Handle a 14 bit immediate at 31. */
2933 case 'J':
2934 the_insn.field_selector = pa_chk_field_selector (&s);
2935 get_expression (s);
2936 s = expr_end;
2937 if (the_insn.exp.X_op == O_constant)
2938 {
2939 int a, m;
2940
2941 /* XXX the completer stored away tibits of information
2942 for us to extract. We need a cleaner way to do this.
2943 Now that we have lots of letters again, it would be
2944 good to rethink this. */
2945 m = (opcode & (1 << 8)) != 0;
2946 a = (opcode & (1 << 9)) != 0;
2947 opcode &= ~ (3 << 8);
2948 num = evaluate_absolute (&the_insn);
fd232ac8 2949 if ((a == 1 && num >= 0) || (a == 0 && num < 0))
65fab780
JL
2950 break;
2951 CHECK_FIELD (num, 8191, -8192, 0);
3f9b03b5 2952 num = low_sign_unext (num, 14);
65fab780
JL
2953 INSERT_FIELD_AND_CONTINUE (opcode, num, 0);
2954 }
2955 else
2956 {
2957 break;
2958 }
2959
2960 /* Handle a 14 bit immediate at 31. */
2961 case 'K':
2962 the_insn.field_selector = pa_chk_field_selector (&s);
2963 get_expression (s);
2964 s = expr_end;
2965 if (the_insn.exp.X_op == O_constant)
2966 {
2967 int a, m;
2968
2969 /* XXX the completer stored away tibits of information
2970 for us to extract. We need a cleaner way to do this.
2971 Now that we have lots of letters again, it would be
2972 good to rethink this. */
2973 m = (opcode & (1 << 8)) != 0;
2974 a = (opcode & (1 << 9)) != 0;
2975 opcode &= ~ (3 << 8);
2976 num = evaluate_absolute (&the_insn);
fd232ac8 2977 if ((a == 1 && num < 0) || (a == 0 && num > 0))
65fab780
JL
2978 break;
2979 if (num % 4)
2980 break;
2981 CHECK_FIELD (num, 8191, -8192, 0);
2982 if (num < 0)
2983 opcode |= 1;
2984 num &= 0x1fff;
2985 num >>= 2;
2986 INSERT_FIELD_AND_CONTINUE (opcode, num, 3);
2987 }
2988 else
2989 {
2990 break;
2991 }
2992
ad1079af 2993 /* Handle 14 bit immediate, shifted left three times. */
61dd1d31
JL
2994 case '#':
2995 the_insn.field_selector = pa_chk_field_selector (&s);
2996 get_expression (s);
2997 s = expr_end;
2998 if (the_insn.exp.X_op == O_constant)
2999 {
3000 num = evaluate_absolute (&the_insn);
3001 if (num & 0x7)
3002 break;
3003 CHECK_FIELD (num, 8191, -8192, 0);
3004 if (num < 0)
3005 opcode |= 1;
3006 num &= 0x1fff;
3007 num >>= 3;
3008 INSERT_FIELD_AND_CONTINUE (opcode, num, 4);
3009 }
3010 else
3011 {
3012 if (is_DP_relative (the_insn.exp))
3013 the_insn.reloc = R_HPPA_GOTOFF;
3014 else if (is_PC_relative (the_insn.exp))
3015 the_insn.reloc = R_HPPA_PCREL_CALL;
3016 else
3017 the_insn.reloc = R_HPPA;
3018 the_insn.format = 14;
3019 continue;
3020 }
3021 break;
3022
3023 /* Handle 14 bit immediate, shifted left twice. */
3024 case 'd':
3025 the_insn.field_selector = pa_chk_field_selector (&s);
3026 get_expression (s);
3027 s = expr_end;
3028 if (the_insn.exp.X_op == O_constant)
3029 {
3030 num = evaluate_absolute (&the_insn);
3031 if (num & 0x3)
3032 break;
3033 CHECK_FIELD (num, 8191, -8192, 0);
3034 if (num < 0)
3035 opcode |= 1;
3036 num &= 0x1fff;
3037 num >>= 2;
3038 INSERT_FIELD_AND_CONTINUE (opcode, num, 3);
3039 }
3040 else
3041 {
3042 if (is_DP_relative (the_insn.exp))
3043 the_insn.reloc = R_HPPA_GOTOFF;
3044 else if (is_PC_relative (the_insn.exp))
3045 the_insn.reloc = R_HPPA_PCREL_CALL;
3046 else
3047 the_insn.reloc = R_HPPA;
3048 the_insn.format = 14;
3049 continue;
3050 }
252b5132
RH
3051
3052 /* Handle a 14 bit immediate at 31. */
3053 case 'j':
3054 the_insn.field_selector = pa_chk_field_selector (&s);
3055 get_expression (s);
3056 s = expr_end;
3057 if (the_insn.exp.X_op == O_constant)
3058 {
3059 num = evaluate_absolute (&the_insn);
3060 CHECK_FIELD (num, 8191, -8192, 0);
3f9b03b5 3061 num = low_sign_unext (num, 14);
252b5132
RH
3062 INSERT_FIELD_AND_CONTINUE (opcode, num, 0);
3063 }
3064 else
3065 {
3066 if (is_DP_relative (the_insn.exp))
3067 the_insn.reloc = R_HPPA_GOTOFF;
3068 else if (is_PC_relative (the_insn.exp))
3069 the_insn.reloc = R_HPPA_PCREL_CALL;
3070 else
3071 the_insn.reloc = R_HPPA;
3072 the_insn.format = 14;
3073 continue;
3074 }
3075
3076 /* Handle a 21 bit immediate at 31. */
3077 case 'k':
3078 the_insn.field_selector = pa_chk_field_selector (&s);
3079 get_expression (s);
3080 s = expr_end;
3081 if (the_insn.exp.X_op == O_constant)
3082 {
3083 num = evaluate_absolute (&the_insn);
3084 CHECK_FIELD (num >> 11, 1048575, -1048576, 0);
ad1079af 3085 opcode |= re_assemble_21 (num);
3f9b03b5 3086 continue;
252b5132
RH
3087 }
3088 else
3089 {
3090 if (is_DP_relative (the_insn.exp))
3091 the_insn.reloc = R_HPPA_GOTOFF;
3092 else if (is_PC_relative (the_insn.exp))
3093 the_insn.reloc = R_HPPA_PCREL_CALL;
3094 else
3095 the_insn.reloc = R_HPPA;
3096 the_insn.format = 21;
3097 continue;
3098 }
3099
a02fab7e
JL
3100 /* Handle a 16 bit immediate at 31 (PA 2.0 wide mode only). */
3101 case 'l':
3102 the_insn.field_selector = pa_chk_field_selector (&s);
3103 get_expression (s);
3104 s = expr_end;
3105 if (the_insn.exp.X_op == O_constant)
3106 {
a02fab7e
JL
3107 num = evaluate_absolute (&the_insn);
3108 CHECK_FIELD (num, 32767, -32768, 0);
ad1079af 3109 opcode |= re_assemble_16 (num);
3f9b03b5 3110 continue;
a02fab7e
JL
3111 }
3112 else
3113 {
3114 /* ??? Is this valid for wide mode? */
3115 if (is_DP_relative (the_insn.exp))
3116 the_insn.reloc = R_HPPA_GOTOFF;
3117 else if (is_PC_relative (the_insn.exp))
3118 the_insn.reloc = R_HPPA_PCREL_CALL;
3119 else
3120 the_insn.reloc = R_HPPA;
3121 the_insn.format = 14;
3122 continue;
3123 }
3124
3125 /* Handle a word-aligned 16-bit imm. at 31 (PA2.0 wide). */
3126 case 'y':
3127 the_insn.field_selector = pa_chk_field_selector (&s);
3128 get_expression (s);
3129 s = expr_end;
3130 if (the_insn.exp.X_op == O_constant)
3131 {
a02fab7e
JL
3132 num = evaluate_absolute (&the_insn);
3133 CHECK_FIELD (num, 32767, -32768, 0);
3134 CHECK_ALIGN (num, 4, 0);
ad1079af 3135 opcode |= re_assemble_16 (num);
3f9b03b5 3136 continue;
a02fab7e
JL
3137 }
3138 else
3139 {
3140 /* ??? Is this valid for wide mode? */
3141 if (is_DP_relative (the_insn.exp))
3142 the_insn.reloc = R_HPPA_GOTOFF;
3143 else if (is_PC_relative (the_insn.exp))
3144 the_insn.reloc = R_HPPA_PCREL_CALL;
3145 else
3146 the_insn.reloc = R_HPPA;
3147 the_insn.format = 14;
3148 continue;
3149 }
3150
3151 /* Handle a dword-aligned 16-bit imm. at 31 (PA2.0 wide). */
3152 case '&':
3153 the_insn.field_selector = pa_chk_field_selector (&s);
3154 get_expression (s);
3155 s = expr_end;
3156 if (the_insn.exp.X_op == O_constant)
3157 {
a02fab7e
JL
3158 num = evaluate_absolute (&the_insn);
3159 CHECK_FIELD (num, 32767, -32768, 0);
3160 CHECK_ALIGN (num, 8, 0);
ad1079af 3161 opcode |= re_assemble_16 (num);
3f9b03b5 3162 continue;
a02fab7e
JL
3163 }
3164 else
3165 {
3166 /* ??? Is this valid for wide mode? */
3167 if (is_DP_relative (the_insn.exp))
3168 the_insn.reloc = R_HPPA_GOTOFF;
3169 else if (is_PC_relative (the_insn.exp))
3170 the_insn.reloc = R_HPPA_PCREL_CALL;
3171 else
3172 the_insn.reloc = R_HPPA;
3173 the_insn.format = 14;
3174 continue;
3175 }
3176
252b5132
RH
3177 /* Handle a 12 bit branch displacement. */
3178 case 'w':
3179 the_insn.field_selector = pa_chk_field_selector (&s);
3180 get_expression (s);
3181 s = expr_end;
3182 the_insn.pcrel = 1;
3183 if (!strcmp (S_GET_NAME (the_insn.exp.X_add_symbol), "L$0\001"))
3184 {
252b5132
RH
3185 num = evaluate_absolute (&the_insn);
3186 if (num % 4)
3187 {
3188 as_bad (_("Branch to unaligned address"));
3189 break;
3190 }
3191 CHECK_FIELD (num, 8199, -8184, 0);
a28a3ccf 3192
ad1079af 3193 opcode |= re_assemble_12 ((num - 8) >> 2);
3f9b03b5 3194 continue;
252b5132
RH
3195 }
3196 else
3197 {
3198 the_insn.reloc = R_HPPA_PCREL_CALL;
3199 the_insn.format = 12;
3200 the_insn.arg_reloc = last_call_desc.arg_reloc;
3201 memset (&last_call_desc, 0, sizeof (struct call_desc));
3202 s = expr_end;
3203 continue;
3204 }
3205
3206 /* Handle a 17 bit branch displacement. */
3207 case 'W':
3208 the_insn.field_selector = pa_chk_field_selector (&s);
3209 get_expression (s);
3210 s = expr_end;
3211 the_insn.pcrel = 1;
3212 if (!the_insn.exp.X_add_symbol
3213 || !strcmp (S_GET_NAME (the_insn.exp.X_add_symbol),
3214 "L$0\001"))
3215 {
252b5132
RH
3216 num = evaluate_absolute (&the_insn);
3217 if (num % 4)
3218 {
3219 as_bad (_("Branch to unaligned address"));
3220 break;
3221 }
3222 CHECK_FIELD (num, 262143, -262144, 0);
3223
3224 if (the_insn.exp.X_add_symbol)
3225 num -= 8;
3226
ad1079af 3227 opcode |= re_assemble_17 (num >> 2);
3f9b03b5 3228 continue;
252b5132
RH
3229 }
3230 else
3231 {
3232 the_insn.reloc = R_HPPA_PCREL_CALL;
3233 the_insn.format = 17;
3234 the_insn.arg_reloc = last_call_desc.arg_reloc;
3235 memset (&last_call_desc, 0, sizeof (struct call_desc));
3236 continue;
3237 }
3238
77c02e18
JL
3239 /* Handle a 22 bit branch displacement. */
3240 case 'X':
3241 the_insn.field_selector = pa_chk_field_selector (&s);
3242 get_expression (s);
3243 s = expr_end;
3244 the_insn.pcrel = 1;
3245 if (!the_insn.exp.X_add_symbol
3246 || !strcmp (S_GET_NAME (the_insn.exp.X_add_symbol),
3247 "L$0\001"))
3248 {
77c02e18
JL
3249 num = evaluate_absolute (&the_insn);
3250 if (num % 4)
3251 {
3252 as_bad (_("Branch to unaligned address"));
3253 break;
3254 }
3255 CHECK_FIELD (num, 8388607, -8388608, 0);
3256
3257 if (the_insn.exp.X_add_symbol)
3258 num -= 8;
3259
ad1079af 3260 opcode |= re_assemble_22 (num >> 2);
77c02e18
JL
3261 }
3262 else
3263 {
3264 the_insn.reloc = R_HPPA_PCREL_CALL;
3265 the_insn.format = 22;
3266 the_insn.arg_reloc = last_call_desc.arg_reloc;
3267 memset (&last_call_desc, 0, sizeof (struct call_desc));
3268 continue;
3269 }
3270
252b5132
RH
3271 /* Handle an absolute 17 bit branch target. */
3272 case 'z':
3273 the_insn.field_selector = pa_chk_field_selector (&s);
3274 get_expression (s);
3275 s = expr_end;
3276 the_insn.pcrel = 0;
3277 if (!the_insn.exp.X_add_symbol
3278 || !strcmp (S_GET_NAME (the_insn.exp.X_add_symbol),
3279 "L$0\001"))
3280 {
252b5132
RH
3281 num = evaluate_absolute (&the_insn);
3282 if (num % 4)
3283 {
3284 as_bad (_("Branch to unaligned address"));
3285 break;
3286 }
3287 CHECK_FIELD (num, 262143, -262144, 0);
3288
3289 if (the_insn.exp.X_add_symbol)
3290 num -= 8;
3291
ad1079af 3292 opcode |= re_assemble_17 (num >> 2);
3f9b03b5 3293 continue;
252b5132
RH
3294 }
3295 else
3296 {
3297 the_insn.reloc = R_HPPA_ABS_CALL;
3298 the_insn.format = 17;
3299 the_insn.arg_reloc = last_call_desc.arg_reloc;
3300 memset (&last_call_desc, 0, sizeof (struct call_desc));
3301 continue;
3302 }
3303
4964086a
JL
3304 /* Handle '%r1' implicit operand of addil instruction. */
3305 case 'Z':
3306 if (*s == ',' && *(s + 1) == '%' && *(s + 3) == '1'
3307 && (*(s + 2) == 'r' || *(s + 2) == 'R'))
3308 {
3309 s += 4;
3310 continue;
3311 }
3312 else
3313 break;
3314
ce674324
JL
3315 /* Handle '%sr0,%r31' implicit operand of be,l instruction. */
3316 case 'Y':
3317 if (strncasecmp (s, "%sr0,%r31", 9) != 0)
3318 break;
3319 s += 9;
3320 continue;
3321
d53d2751
JL
3322 /* Handle immediate value of 0 for ordered load/store instructions. */
3323 case '@':
3324 if (*s != '0')
3325 break;
3326 s++;
3327 continue;
3328
a97685e9
JL
3329 /* Handle a 2 bit shift count at 25. */
3330 case '.':
3331 num = pa_get_absolute_expression (&the_insn, &s);
0f4f8b56
JL
3332 if (strict && the_insn.exp.X_op != O_constant)
3333 break;
a97685e9 3334 s = expr_end;
0f4f8b56 3335 CHECK_FIELD (num, 3, 1, strict);
a97685e9
JL
3336 INSERT_FIELD_AND_CONTINUE (opcode, num, 6);
3337
413c94ba
JL
3338 /* Handle a 4 bit shift count at 25. */
3339 case '*':
3340 num = pa_get_absolute_expression (&the_insn, &s);
0f4f8b56
JL
3341 if (strict && the_insn.exp.X_op != O_constant)
3342 break;
413c94ba 3343 s = expr_end;
0f4f8b56 3344 CHECK_FIELD (num, 15, 0, strict);
413c94ba
JL
3345 INSERT_FIELD_AND_CONTINUE (opcode, num, 6);
3346
252b5132
RH
3347 /* Handle a 5 bit shift count at 26. */
3348 case 'p':
3349 num = pa_get_absolute_expression (&the_insn, &s);
0f4f8b56
JL
3350 if (strict && the_insn.exp.X_op != O_constant)
3351 break;
252b5132 3352 s = expr_end;
0f4f8b56 3353 CHECK_FIELD (num, 31, 0, strict);
252b5132
RH
3354 INSERT_FIELD_AND_CONTINUE (opcode, 31 - num, 5);
3355
a97685e9
JL
3356 /* Handle a 6 bit shift count at 20,22:26. */
3357 case '~':
3358 num = pa_get_absolute_expression (&the_insn, &s);
0f4f8b56
JL
3359 if (strict && the_insn.exp.X_op != O_constant)
3360 break;
a97685e9 3361 s = expr_end;
0f4f8b56 3362 CHECK_FIELD (num, 63, 0, strict);
a97685e9
JL
3363 num = 63 - num;
3364 opcode |= (num & 0x20) << 6;
3365 INSERT_FIELD_AND_CONTINUE (opcode, num & 0x1f, 5);
3366
9e4f2d3a
JL
3367 /* Handle a 6 bit field length at 23,27:31. */
3368 case '%':
3369 flag = 0;
3370 num = pa_get_absolute_expression (&the_insn, &s);
0f4f8b56
JL
3371 if (strict && the_insn.exp.X_op != O_constant)
3372 break;
9e4f2d3a 3373 s = expr_end;
0f4f8b56 3374 CHECK_FIELD (num, 64, 1, strict);
9e4f2d3a
JL
3375 num--;
3376 opcode |= (num & 0x20) << 3;
3377 num = 31 - (num & 0x1f);
3378 INSERT_FIELD_AND_CONTINUE (opcode, num, 0);
3379
3380 /* Handle a 6 bit field length at 19,27:31. */
3381 case '|':
3382 num = pa_get_absolute_expression (&the_insn, &s);
0f4f8b56
JL
3383 if (strict && the_insn.exp.X_op != O_constant)
3384 break;
9e4f2d3a 3385 s = expr_end;
0f4f8b56 3386 CHECK_FIELD (num, 64, 1, strict);
9e4f2d3a
JL
3387 num--;
3388 opcode |= (num & 0x20) << 7;
3389 num = 31 - (num & 0x1f);
3390 INSERT_FIELD_AND_CONTINUE (opcode, num, 0);
3391
252b5132
RH
3392 /* Handle a 5 bit bit position at 26. */
3393 case 'P':
3394 num = pa_get_absolute_expression (&the_insn, &s);
0f4f8b56
JL
3395 if (strict && the_insn.exp.X_op != O_constant)
3396 break;
252b5132 3397 s = expr_end;
0f4f8b56 3398 CHECK_FIELD (num, 31, 0, strict);
252b5132
RH
3399 INSERT_FIELD_AND_CONTINUE (opcode, num, 5);
3400
9e4f2d3a
JL
3401 /* Handle a 6 bit bit position at 20,22:26. */
3402 case 'q':
3403 num = pa_get_absolute_expression (&the_insn, &s);
0f4f8b56
JL
3404 if (strict && the_insn.exp.X_op != O_constant)
3405 break;
9e4f2d3a 3406 s = expr_end;
0f4f8b56 3407 CHECK_FIELD (num, 63, 0, strict);
9e4f2d3a
JL
3408 opcode |= (num & 0x20) << 6;
3409 INSERT_FIELD_AND_CONTINUE (opcode, num & 0x1f, 5);
3410
afbf211f
JL
3411 /* Handle a 5 bit immediate at 10 with 'd' as the complement
3412 of the high bit of the immediate. */
3413 case 'B':
3414 num = pa_get_absolute_expression (&the_insn, &s);
3415 if (strict && the_insn.exp.X_op != O_constant)
3416 break;
3417 s = expr_end;
3418 CHECK_FIELD (num, 63, 0, strict);
3419 if (num & 0x20)
3420 ;
3421 else
3422 opcode |= (1 << 13);
3423 INSERT_FIELD_AND_CONTINUE (opcode, num & 0x1f, 21);
3424
252b5132
RH
3425 /* Handle a 5 bit immediate at 10. */
3426 case 'Q':
252b5132 3427 num = pa_get_absolute_expression (&the_insn, &s);
0f4f8b56
JL
3428 if (strict && the_insn.exp.X_op != O_constant)
3429 break;
252b5132 3430 s = expr_end;
0f4f8b56 3431 CHECK_FIELD (num, 31, 0, strict);
252b5132
RH
3432 INSERT_FIELD_AND_CONTINUE (opcode, num, 21);
3433
a97685e9
JL
3434 /* Handle a 9 bit immediate at 28. */
3435 case '$':
3436 num = pa_get_absolute_expression (&the_insn, &s);
0f4f8b56
JL
3437 if (strict && the_insn.exp.X_op != O_constant)
3438 break;
a97685e9 3439 s = expr_end;
0f4f8b56 3440 CHECK_FIELD (num, 511, 1, strict);
a97685e9 3441 INSERT_FIELD_AND_CONTINUE (opcode, num, 3);
d53d2751 3442
252b5132
RH
3443 /* Handle a 13 bit immediate at 18. */
3444 case 'A':
3445 num = pa_get_absolute_expression (&the_insn, &s);
0f4f8b56
JL
3446 if (strict && the_insn.exp.X_op != O_constant)
3447 break;
252b5132 3448 s = expr_end;
0f4f8b56 3449 CHECK_FIELD (num, 8191, 0, strict);
252b5132
RH
3450 INSERT_FIELD_AND_CONTINUE (opcode, num, 13);
3451
3452 /* Handle a 26 bit immediate at 31. */
3453 case 'D':
3454 num = pa_get_absolute_expression (&the_insn, &s);
0f4f8b56
JL
3455 if (strict && the_insn.exp.X_op != O_constant)
3456 break;
252b5132 3457 s = expr_end;
0f4f8b56 3458 CHECK_FIELD (num, 671108864, 0, strict);
252b5132
RH
3459 INSERT_FIELD_AND_CONTINUE (opcode, num, 0);
3460
3461 /* Handle a 3 bit SFU identifier at 25. */
97e1581b 3462 case 'v':
252b5132
RH
3463 if (*s++ != ',')
3464 as_bad (_("Invalid SFU identifier"));
3465 num = pa_get_absolute_expression (&the_insn, &s);
0f4f8b56
JL
3466 if (strict && the_insn.exp.X_op != O_constant)
3467 break;
252b5132 3468 s = expr_end;
0f4f8b56 3469 CHECK_FIELD (num, 7, 0, strict);
252b5132
RH
3470 INSERT_FIELD_AND_CONTINUE (opcode, num, 6);
3471
3472 /* Handle a 20 bit SOP field for spop0. */
3473 case 'O':
3474 num = pa_get_absolute_expression (&the_insn, &s);
0f4f8b56
JL
3475 if (strict && the_insn.exp.X_op != O_constant)
3476 break;
252b5132 3477 s = expr_end;
0f4f8b56 3478 CHECK_FIELD (num, 1048575, 0, strict);
252b5132
RH
3479 num = (num & 0x1f) | ((num & 0x000fffe0) << 6);
3480 INSERT_FIELD_AND_CONTINUE (opcode, num, 0);
3481
3482 /* Handle a 15bit SOP field for spop1. */
3483 case 'o':
3484 num = pa_get_absolute_expression (&the_insn, &s);
0f4f8b56
JL
3485 if (strict && the_insn.exp.X_op != O_constant)
3486 break;
252b5132 3487 s = expr_end;
0f4f8b56 3488 CHECK_FIELD (num, 32767, 0, strict);
252b5132
RH
3489 INSERT_FIELD_AND_CONTINUE (opcode, num, 11);
3490
3491 /* Handle a 10bit SOP field for spop3. */
3492 case '0':
3493 num = pa_get_absolute_expression (&the_insn, &s);
0f4f8b56
JL
3494 if (strict && the_insn.exp.X_op != O_constant)
3495 break;
252b5132 3496 s = expr_end;
0f4f8b56 3497 CHECK_FIELD (num, 1023, 0, strict);
252b5132
RH
3498 num = (num & 0x1f) | ((num & 0x000003e0) << 6);
3499 INSERT_FIELD_AND_CONTINUE (opcode, num, 0);
3500
3501 /* Handle a 15 bit SOP field for spop2. */
3502 case '1':
3503 num = pa_get_absolute_expression (&the_insn, &s);
0f4f8b56
JL
3504 if (strict && the_insn.exp.X_op != O_constant)
3505 break;
252b5132 3506 s = expr_end;
0f4f8b56 3507 CHECK_FIELD (num, 32767, 0, strict);
252b5132
RH
3508 num = (num & 0x1f) | ((num & 0x00007fe0) << 6);
3509 INSERT_FIELD_AND_CONTINUE (opcode, num, 0);
3510
3511 /* Handle a 3-bit co-processor ID field. */
3512 case 'u':
3513 if (*s++ != ',')
3514 as_bad (_("Invalid COPR identifier"));
3515 num = pa_get_absolute_expression (&the_insn, &s);
0f4f8b56
JL
3516 if (strict && the_insn.exp.X_op != O_constant)
3517 break;
252b5132 3518 s = expr_end;
0f4f8b56 3519 CHECK_FIELD (num, 7, 0, strict);
252b5132
RH
3520 INSERT_FIELD_AND_CONTINUE (opcode, num, 6);
3521
3522 /* Handle a 22bit SOP field for copr. */
3523 case '2':
3524 num = pa_get_absolute_expression (&the_insn, &s);
0f4f8b56
JL
3525 if (strict && the_insn.exp.X_op != O_constant)
3526 break;
252b5132 3527 s = expr_end;
0f4f8b56 3528 CHECK_FIELD (num, 4194303, 0, strict);
252b5132
RH
3529 num = (num & 0x1f) | ((num & 0x003fffe0) << 4);
3530 INSERT_FIELD_AND_CONTINUE (opcode, num, 0);
3531
1cf6ae67
JL
3532 /* Handle a source FP operand format completer. */
3533 case '{':
3534 if (*s == ',' && *(s+1) == 't')
3535 {
3536 the_insn.trunc = 1;
3537 s += 2;
3538 }
3539 else
3540 the_insn.trunc = 0;
3541 flag = pa_parse_fp_cnv_format (&s);
3542 the_insn.fpof1 = flag;
3543 if (flag == W || flag == UW)
3544 flag = SGL;
3545 if (flag == DW || flag == UDW)
3546 flag = DBL;
3547 if (flag == QW || flag == UQW)
3548 flag = QUAD;
3549 INSERT_FIELD_AND_CONTINUE (opcode, flag, 11);
3550
3551 /* Handle a destination FP operand format completer. */
3552 case '_':
3553 /* pa_parse_format needs the ',' prefix. */
3554 s--;
3555 flag = pa_parse_fp_cnv_format (&s);
3556 the_insn.fpof2 = flag;
3557 if (flag == W || flag == UW)
3558 flag = SGL;
3559 if (flag == DW || flag == UDW)
3560 flag = DBL;
3561 if (flag == QW || flag == UQW)
3562 flag = QUAD;
3563 opcode |= flag << 13;
3564 if (the_insn.fpof1 == SGL
d53d2751 3565 || the_insn.fpof1 == DBL
1cf6ae67
JL
3566 || the_insn.fpof1 == QUAD)
3567 {
3568 if (the_insn.fpof2 == SGL
3569 || the_insn.fpof2 == DBL
3570 || the_insn.fpof2 == QUAD)
3571 flag = 0;
3572 else if (the_insn.fpof2 == W
3573 || the_insn.fpof2 == DW
3574 || the_insn.fpof2 == QW)
3575 flag = 2;
3576 else if (the_insn.fpof2 == UW
3577 || the_insn.fpof2 == UDW
3578 || the_insn.fpof2 == UQW)
3579 flag = 6;
3580 else
3581 abort ();
3582 }
3583 else if (the_insn.fpof1 == W
d53d2751 3584 || the_insn.fpof1 == DW
1cf6ae67
JL
3585 || the_insn.fpof1 == QW)
3586 {
3587 if (the_insn.fpof2 == SGL
3588 || the_insn.fpof2 == DBL
3589 || the_insn.fpof2 == QUAD)
3590 flag = 1;
3591 else
3592 abort ();
3593 }
3594 else if (the_insn.fpof1 == UW
d53d2751 3595 || the_insn.fpof1 == UDW
1cf6ae67
JL
3596 || the_insn.fpof1 == UQW)
3597 {
3598 if (the_insn.fpof2 == SGL
3599 || the_insn.fpof2 == DBL
3600 || the_insn.fpof2 == QUAD)
3601 flag = 5;
3602 else
3603 abort ();
3604 }
3605 flag |= the_insn.trunc;
3606 INSERT_FIELD_AND_CONTINUE (opcode, flag, 15);
252b5132
RH
3607
3608 /* Handle a source FP operand format completer. */
3609 case 'F':
3610 flag = pa_parse_fp_format (&s);
3611 the_insn.fpof1 = flag;
3612 INSERT_FIELD_AND_CONTINUE (opcode, flag, 11);
3613
3614 /* Handle a destination FP operand format completer. */
3615 case 'G':
3616 /* pa_parse_format needs the ',' prefix. */
3617 s--;
3618 flag = pa_parse_fp_format (&s);
3619 the_insn.fpof2 = flag;
3620 INSERT_FIELD_AND_CONTINUE (opcode, flag, 13);
3621
9ecc05f0
JL
3622 /* Handle a source FP operand format completer at 20. */
3623 case 'I':
3624 flag = pa_parse_fp_format (&s);
3625 the_insn.fpof1 = flag;
3626 INSERT_FIELD_AND_CONTINUE (opcode, flag, 11);
3627
97e1581b
JL
3628 /* Handle a floating point operand format at 26.
3629 Only allows single and double precision. */
3630 case 'H':
3631 flag = pa_parse_fp_format (&s);
3632 switch (flag)
3633 {
3634 case SGL:
3635 opcode |= 0x20;
3636 case DBL:
3637 the_insn.fpof1 = flag;
3638 continue;
252b5132 3639
97e1581b
JL
3640 case QUAD:
3641 case ILLEGAL_FMT:
3642 default:
3643 as_bad (_("Invalid Floating Point Operand Format."));
3644 }
3645 break;
252b5132 3646
97e1581b
JL
3647 /* Handle all floating point registers. */
3648 case 'f':
3649 switch (*++args)
3650 {
3651 /* Float target register. */
3652 case 't':
ecacdc7a 3653 if (!pa_parse_number (&s, 3))
0f4f8b56 3654 break;
ecacdc7a 3655 num = (pa_number & ~FP_REG_RSEL) - FP_REG_BASE;
97e1581b
JL
3656 CHECK_FIELD (num, 31, 0, 0);
3657 INSERT_FIELD_AND_CONTINUE (opcode, num, 0);
252b5132 3658
97e1581b
JL
3659 /* Float target register with L/R selection. */
3660 case 'T':
252b5132 3661 {
ecacdc7a 3662 if (!pa_parse_number (&s, 1))
0f4f8b56 3663 break;
ecacdc7a
AM
3664 num = (pa_number & ~FP_REG_RSEL) - FP_REG_BASE;
3665 CHECK_FIELD (num, 31, 0, 0);
3666 opcode |= num;
b53fcc20 3667
97e1581b
JL
3668 /* 0x30 opcodes are FP arithmetic operation opcodes
3669 and need to be turned into 0x38 opcodes. This
3670 is not necessary for loads/stores. */
ecacdc7a 3671 if (need_pa11_opcode ()
97e1581b
JL
3672 && ((opcode & 0xfc000000) == 0x30000000))
3673 opcode |= 1 << 27;
b53fcc20 3674
ecacdc7a
AM
3675 opcode |= (pa_number & FP_REG_RSEL ? 1 << 6 : 0);
3676 continue;
97e1581b 3677 }
252b5132 3678
97e1581b
JL
3679 /* Float operand 1. */
3680 case 'a':
3681 {
ecacdc7a 3682 if (!pa_parse_number (&s, 1))
0f4f8b56 3683 break;
ecacdc7a
AM
3684 num = (pa_number & ~FP_REG_RSEL) - FP_REG_BASE;
3685 CHECK_FIELD (num, 31, 0, 0);
3686 opcode |= num << 21;
3687 if (need_pa11_opcode ())
97e1581b 3688 {
ecacdc7a 3689 opcode |= (pa_number & FP_REG_RSEL ? 1 << 7 : 0);
97e1581b
JL
3690 opcode |= 1 << 27;
3691 }
3692 continue;
3693 }
252b5132 3694
97e1581b 3695 /* Float operand 1 with L/R selection. */
e061d86f 3696 case 'X':
97e1581b 3697 case 'A':
252b5132 3698 {
ecacdc7a 3699 if (!pa_parse_number (&s, 1))
0f4f8b56 3700 break;
ecacdc7a
AM
3701 num = (pa_number & ~FP_REG_RSEL) - FP_REG_BASE;
3702 CHECK_FIELD (num, 31, 0, 0);
3703 opcode |= num << 21;
3704 opcode |= (pa_number & FP_REG_RSEL ? 1 << 7 : 0);
97e1581b 3705 continue;
252b5132 3706 }
252b5132 3707
97e1581b
JL
3708 /* Float operand 2. */
3709 case 'b':
3710 {
ecacdc7a 3711 if (!pa_parse_number (&s, 1))
0f4f8b56 3712 break;
ecacdc7a
AM
3713 num = (pa_number & ~FP_REG_RSEL) - FP_REG_BASE;
3714 CHECK_FIELD (num, 31, 0, 0);
3715 opcode |= num << 16;
3716 if (need_pa11_opcode ())
97e1581b 3717 {
ecacdc7a 3718 opcode |= (pa_number & FP_REG_RSEL ? 1 << 12 : 0);
97e1581b
JL
3719 opcode |= 1 << 27;
3720 }
3721 continue;
3722 }
3723
3724 /* Float operand 2 with L/R selection. */
3725 case 'B':
252b5132 3726 {
ecacdc7a 3727 if (!pa_parse_number (&s, 1))
0f4f8b56 3728 break;
ecacdc7a
AM
3729 num = (pa_number & ~FP_REG_RSEL) - FP_REG_BASE;
3730 CHECK_FIELD (num, 31, 0, 0);
3731 opcode |= num << 16;
3732 opcode |= (pa_number & FP_REG_RSEL ? 1 << 12 : 0);
97e1581b 3733 continue;
252b5132 3734 }
252b5132 3735
97e1581b
JL
3736 /* Float operand 3 for fmpyfadd, fmpynfadd. */
3737 case 'C':
3738 {
ecacdc7a 3739 if (!pa_parse_number (&s, 1))
0f4f8b56 3740 break;
ecacdc7a
AM
3741 num = (pa_number & ~FP_REG_RSEL) - FP_REG_BASE;
3742 CHECK_FIELD (num, 31, 0, 0);
3743 opcode |= (num & 0x1c) << 11;
3744 opcode |= (num & 0x03) << 9;
3745 opcode |= (pa_number & FP_REG_RSEL ? 1 << 8 : 0);
97e1581b
JL
3746 continue;
3747 }
b53fcc20 3748
97e1581b
JL
3749 /* Float mult operand 1 for fmpyadd, fmpysub */
3750 case 'i':
3751 {
ecacdc7a 3752 if (!pa_parse_number (&s, 1))
0f4f8b56 3753 break;
ecacdc7a
AM
3754 num = (pa_number & ~FP_REG_RSEL) - FP_REG_BASE;
3755 CHECK_FIELD (num, 31, 0, 0);
97e1581b
JL
3756 if (the_insn.fpof1 == SGL)
3757 {
ecacdc7a 3758 if (num < 16)
97e1581b
JL
3759 {
3760 as_bad (_("Invalid register for single precision fmpyadd or fmpysub"));
3761 break;
3762 }
ecacdc7a
AM
3763 num &= 0xF;
3764 num |= (pa_number & FP_REG_RSEL ? 1 << 4 : 0);
97e1581b 3765 }
ecacdc7a 3766 INSERT_FIELD_AND_CONTINUE (opcode, num, 21);
97e1581b
JL
3767 }
3768
3769 /* Float mult operand 2 for fmpyadd, fmpysub */
3770 case 'j':
252b5132 3771 {
ecacdc7a 3772 if (!pa_parse_number (&s, 1))
0f4f8b56 3773 break;
ecacdc7a
AM
3774 num = (pa_number & ~FP_REG_RSEL) - FP_REG_BASE;
3775 CHECK_FIELD (num, 31, 0, 0);
97e1581b 3776 if (the_insn.fpof1 == SGL)
252b5132 3777 {
ecacdc7a 3778 if (num < 16)
97e1581b 3779 {
ecacdc7a
AM
3780 as_bad (_("Invalid register for single precision fmpyadd or fmpysub"));
3781 break;
97e1581b 3782 }
ecacdc7a
AM
3783 num &= 0xF;
3784 num |= (pa_number & FP_REG_RSEL ? 1 << 4 : 0);
252b5132 3785 }
ecacdc7a 3786 INSERT_FIELD_AND_CONTINUE (opcode, num, 16);
252b5132 3787 }
252b5132 3788
97e1581b
JL
3789 /* Float mult target for fmpyadd, fmpysub */
3790 case 'k':
252b5132 3791 {
ecacdc7a 3792 if (!pa_parse_number (&s, 1))
0f4f8b56 3793 break;
ecacdc7a
AM
3794 num = (pa_number & ~FP_REG_RSEL) - FP_REG_BASE;
3795 CHECK_FIELD (num, 31, 0, 0);
97e1581b 3796 if (the_insn.fpof1 == SGL)
252b5132 3797 {
ecacdc7a 3798 if (num < 16)
97e1581b 3799 {
ecacdc7a
AM
3800 as_bad (_("Invalid register for single precision fmpyadd or fmpysub"));
3801 break;
97e1581b 3802 }
ecacdc7a
AM
3803 num &= 0xF;
3804 num |= (pa_number & FP_REG_RSEL ? 1 << 4 : 0);
252b5132 3805 }
ecacdc7a 3806 INSERT_FIELD_AND_CONTINUE (opcode, num, 0);
252b5132 3807 }
252b5132 3808
97e1581b
JL
3809 /* Float add operand 1 for fmpyadd, fmpysub */
3810 case 'l':
252b5132 3811 {
ecacdc7a 3812 if (!pa_parse_number (&s, 1))
0f4f8b56 3813 break;
ecacdc7a
AM
3814 num = (pa_number & ~FP_REG_RSEL) - FP_REG_BASE;
3815 CHECK_FIELD (num, 31, 0, 0);
97e1581b 3816 if (the_insn.fpof1 == SGL)
252b5132 3817 {
ecacdc7a 3818 if (num < 16)
97e1581b 3819 {
ecacdc7a
AM
3820 as_bad (_("Invalid register for single precision fmpyadd or fmpysub"));
3821 break;
97e1581b 3822 }
ecacdc7a
AM
3823 num &= 0xF;
3824 num |= (pa_number & FP_REG_RSEL ? 1 << 4 : 0);
252b5132 3825 }
ecacdc7a 3826 INSERT_FIELD_AND_CONTINUE (opcode, num, 6);
252b5132 3827 }
252b5132 3828
97e1581b
JL
3829 /* Float add target for fmpyadd, fmpysub */
3830 case 'm':
252b5132 3831 {
ecacdc7a 3832 if (!pa_parse_number (&s, 1))
0f4f8b56 3833 break;
ecacdc7a
AM
3834 num = (pa_number & ~FP_REG_RSEL) - FP_REG_BASE;
3835 CHECK_FIELD (num, 31, 0, 0);
97e1581b 3836 if (the_insn.fpof1 == SGL)
252b5132 3837 {
ecacdc7a 3838 if (num < 16)
97e1581b 3839 {
ecacdc7a
AM
3840 as_bad (_("Invalid register for single precision fmpyadd or fmpysub"));
3841 break;
97e1581b 3842 }
ecacdc7a
AM
3843 num &= 0xF;
3844 num |= (pa_number & FP_REG_RSEL ? 1 << 4 : 0);
252b5132 3845 }
ecacdc7a 3846 INSERT_FIELD_AND_CONTINUE (opcode, num, 11);
252b5132 3847 }
252b5132 3848
71823da4 3849 /* Handle L/R register halves like 'x'. */
a02fab7e 3850 case 'E':
71823da4
JL
3851 case 'e':
3852 {
ecacdc7a 3853 if (!pa_parse_number (&s, 1))
71823da4 3854 break;
ecacdc7a
AM
3855 num = (pa_number & ~FP_REG_RSEL) - FP_REG_BASE;
3856 CHECK_FIELD (num, 31, 0, 0);
3857 opcode |= num << 16;
3858 if (need_pa11_opcode ())
71823da4 3859 {
ecacdc7a 3860 opcode |= (pa_number & FP_REG_RSEL ? 1 << 1 : 0);
71823da4
JL
3861 }
3862 continue;
d3426803 3863 }
a02fab7e
JL
3864
3865 /* Float target register (PA 2.0 wide). */
3866 case 'x':
ecacdc7a 3867 if (!pa_parse_number (&s, 3))
a02fab7e 3868 break;
ecacdc7a 3869 num = (pa_number & ~FP_REG_RSEL) - FP_REG_BASE;
a02fab7e
JL
3870 CHECK_FIELD (num, 31, 0, 0);
3871 INSERT_FIELD_AND_CONTINUE (opcode, num, 16);
3872
97e1581b
JL
3873 default:
3874 abort ();
3875 }
3876 break;
3877
252b5132
RH
3878 default:
3879 abort ();
3880 }
3881 break;
3882 }
3883
3884 failed:
3885 /* Check if the args matched. */
3886 if (match == FALSE)
3887 {
3888 if (&insn[1] - pa_opcodes < (int) NUMOPCODES
3889 && !strcmp (insn->name, insn[1].name))
3890 {
3891 ++insn;
3892 s = argstart;
3893 continue;
3894 }
3895 else
3896 {
3897 as_bad (_("Invalid operands %s"), error_message);
3898 return;
3899 }
3900 }
3901 break;
3902 }
3903
3904 the_insn.opcode = opcode;
3905}
3906
3907/* Turn a string in input_line_pointer into a floating point constant of type
3908 type, and store the appropriate bytes in *litP. The number of LITTLENUMS
3909 emitted is stored in *sizeP . An error message or NULL is returned. */
3910
3911#define MAX_LITTLENUMS 6
3912
3913char *
3914md_atof (type, litP, sizeP)
3915 char type;
3916 char *litP;
3917 int *sizeP;
3918{
3919 int prec;
3920 LITTLENUM_TYPE words[MAX_LITTLENUMS];
3921 LITTLENUM_TYPE *wordP;
3922 char *t;
3923
3924 switch (type)
3925 {
3926
3927 case 'f':
3928 case 'F':
3929 case 's':
3930 case 'S':
3931 prec = 2;
3932 break;
3933
3934 case 'd':
3935 case 'D':
3936 case 'r':
3937 case 'R':
3938 prec = 4;
3939 break;
3940
3941 case 'x':
3942 case 'X':
3943 prec = 6;
3944 break;
3945
3946 case 'p':
3947 case 'P':
3948 prec = 6;
3949 break;
3950
3951 default:
3952 *sizeP = 0;
3953 return _("Bad call to MD_ATOF()");
3954 }
3955 t = atof_ieee (input_line_pointer, type, words);
3956 if (t)
3957 input_line_pointer = t;
3958 *sizeP = prec * sizeof (LITTLENUM_TYPE);
3959 for (wordP = words; prec--;)
3960 {
3961 md_number_to_chars (litP, (valueT) (*wordP++), sizeof (LITTLENUM_TYPE));
3962 litP += sizeof (LITTLENUM_TYPE);
3963 }
3964 return NULL;
3965}
3966
3967/* Write out big-endian. */
3968
3969void
3970md_number_to_chars (buf, val, n)
3971 char *buf;
3972 valueT val;
3973 int n;
3974{
3975 number_to_chars_bigendian (buf, val, n);
3976}
3977
3978/* Translate internal representation of relocation info to BFD target
3979 format. */
3980
3981arelent **
3982tc_gen_reloc (section, fixp)
3983 asection *section;
3984 fixS *fixp;
3985{
3986 arelent *reloc;
3987 struct hppa_fix_struct *hppa_fixp;
252b5132
RH
3988 static arelent *no_relocs = NULL;
3989 arelent **relocs;
ad1079af
AM
3990 reloc_type **codes;
3991 reloc_type code;
252b5132
RH
3992 int n_relocs;
3993 int i;
3994
3995 hppa_fixp = (struct hppa_fix_struct *) fixp->tc_fix_data;
3996 if (fixp->fx_addsy == 0)
3997 return &no_relocs;
ad1079af 3998
252b5132
RH
3999 assert (hppa_fixp != 0);
4000 assert (section != 0);
4001
4002 reloc = (arelent *) xmalloc (sizeof (arelent));
4003
a0f75b47
ILT
4004 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
4005 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
ad1079af 4006 codes = hppa_gen_reloc_type (stdoutput,
252b5132
RH
4007 fixp->fx_r_type,
4008 hppa_fixp->fx_r_format,
4009 hppa_fixp->fx_r_field,
4010 fixp->fx_subsy != NULL,
a0f75b47 4011 symbol_get_bfdsym (fixp->fx_addsy));
252b5132
RH
4012
4013 if (codes == NULL)
4014 abort ();
4015
4016 for (n_relocs = 0; codes[n_relocs]; n_relocs++)
4017 ;
4018
4019 relocs = (arelent **) xmalloc (sizeof (arelent *) * n_relocs + 1);
4020 reloc = (arelent *) xmalloc (sizeof (arelent) * n_relocs);
4021 for (i = 0; i < n_relocs; i++)
4022 relocs[i] = &reloc[i];
4023
4024 relocs[n_relocs] = NULL;
4025
4026#ifdef OBJ_ELF
4027 switch (fixp->fx_r_type)
4028 {
4029 default:
4030 assert (n_relocs == 1);
4031
4032 code = *codes[0];
4033
a0f75b47
ILT
4034 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
4035 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
ad1079af
AM
4036 reloc->howto = bfd_reloc_type_lookup (stdoutput,
4037 (bfd_reloc_code_real_type) code);
252b5132 4038 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
252b5132 4039
ad1079af 4040 assert (reloc->howto && (unsigned int) code == reloc->howto->type);
252b5132
RH
4041
4042 /* Now, do any processing that is dependent on the relocation type. */
4043 switch (code)
4044 {
4045 case R_PARISC_DLTREL21L:
4046 case R_PARISC_DLTREL14R:
4047 case R_PARISC_DLTREL14F:
4048 case R_PARISC_PLABEL32:
4049 case R_PARISC_PLABEL21L:
4050 case R_PARISC_PLABEL14R:
4051 /* For plabel relocations, the addend of the
4052 relocation should be either 0 (no static link) or 2
904a31bf
AM
4053 (static link required). This adjustment is done in
4054 bfd/elf32-hppa.c:elf32_hppa_relocate_section.
252b5132
RH
4055
4056 We also slam a zero addend into the DLT relative relocs;
4057 it doesn't make a lot of sense to use any addend since
4058 it gets you a different (eg unknown) DLT entry. */
4059 reloc->addend = 0;
4060 break;
4061
ad1079af 4062#ifdef ELF_ARG_RELOC
252b5132
RH
4063 case R_PARISC_PCREL17R:
4064 case R_PARISC_PCREL17F:
4065 case R_PARISC_PCREL17C:
ad1079af
AM
4066 case R_PARISC_DIR17R:
4067 case R_PARISC_DIR17F:
ad1079af
AM
4068 case R_PARISC_PCREL21L:
4069 case R_PARISC_DIR21L:
904a31bf
AM
4070 reloc->addend = HPPA_R_ADDEND (hppa_fixp->fx_arg_reloc,
4071 fixp->fx_offset);
ad1079af
AM
4072 break;
4073#endif
4074
252b5132
RH
4075 default:
4076 reloc->addend = fixp->fx_offset;
4077 break;
4078 }
4079 break;
4080 }
4081#else /* OBJ_SOM */
4082
4083 /* Walk over reach relocation returned by the BFD backend. */
4084 for (i = 0; i < n_relocs; i++)
4085 {
4086 code = *codes[i];
4087
398e8c25
ILT
4088 relocs[i]->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
4089 *relocs[i]->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
ad1079af
AM
4090 relocs[i]->howto =
4091 bfd_reloc_type_lookup (stdoutput,
4092 (bfd_reloc_code_real_type) code);
252b5132
RH
4093 relocs[i]->address = fixp->fx_frag->fr_address + fixp->fx_where;
4094
4095 switch (code)
4096 {
4097 case R_COMP2:
4098 /* The only time we ever use a R_COMP2 fixup is for the difference
4099 of two symbols. With that in mind we fill in all four
4100 relocs now and break out of the loop. */
4101 assert (i == 1);
993142d5 4102 relocs[0]->sym_ptr_ptr = (asymbol **) &(bfd_abs_symbol);
ad1079af
AM
4103 relocs[0]->howto =
4104 bfd_reloc_type_lookup (stdoutput,
4105 (bfd_reloc_code_real_type) *codes[0]);
252b5132
RH
4106 relocs[0]->address = fixp->fx_frag->fr_address + fixp->fx_where;
4107 relocs[0]->addend = 0;
993142d5
ILT
4108 relocs[1]->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
4109 *relocs[1]->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
ad1079af
AM
4110 relocs[1]->howto =
4111 bfd_reloc_type_lookup (stdoutput,
4112 (bfd_reloc_code_real_type) *codes[1]);
252b5132
RH
4113 relocs[1]->address = fixp->fx_frag->fr_address + fixp->fx_where;
4114 relocs[1]->addend = 0;
993142d5
ILT
4115 relocs[2]->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
4116 *relocs[2]->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_subsy);
ad1079af
AM
4117 relocs[2]->howto =
4118 bfd_reloc_type_lookup (stdoutput,
4119 (bfd_reloc_code_real_type) *codes[2]);
252b5132
RH
4120 relocs[2]->address = fixp->fx_frag->fr_address + fixp->fx_where;
4121 relocs[2]->addend = 0;
993142d5 4122 relocs[3]->sym_ptr_ptr = (asymbol **) &(bfd_abs_symbol);
ad1079af
AM
4123 relocs[3]->howto =
4124 bfd_reloc_type_lookup (stdoutput,
4125 (bfd_reloc_code_real_type) *codes[3]);
252b5132
RH
4126 relocs[3]->address = fixp->fx_frag->fr_address + fixp->fx_where;
4127 relocs[3]->addend = 0;
993142d5 4128 relocs[4]->sym_ptr_ptr = (asymbol **) &(bfd_abs_symbol);
ad1079af
AM
4129 relocs[4]->howto =
4130 bfd_reloc_type_lookup (stdoutput,
4131 (bfd_reloc_code_real_type) *codes[4]);
252b5132
RH
4132 relocs[4]->address = fixp->fx_frag->fr_address + fixp->fx_where;
4133 relocs[4]->addend = 0;
4134 goto done;
4135 case R_PCREL_CALL:
4136 case R_ABS_CALL:
4137 relocs[i]->addend = HPPA_R_ADDEND (hppa_fixp->fx_arg_reloc, 0);
4138 break;
4139
4140 case R_DLT_REL:
4141 case R_DATA_PLABEL:
4142 case R_CODE_PLABEL:
4143 /* For plabel relocations, the addend of the
4144 relocation should be either 0 (no static link) or 2
4145 (static link required).
4146
4147 FIXME: We always assume no static link!
4148
4149 We also slam a zero addend into the DLT relative relocs;
4150 it doesn't make a lot of sense to use any addend since
4151 it gets you a different (eg unknown) DLT entry. */
4152 relocs[i]->addend = 0;
4153 break;
4154
4155 case R_N_MODE:
4156 case R_S_MODE:
4157 case R_D_MODE:
4158 case R_R_MODE:
4159 case R_FSEL:
4160 case R_LSEL:
4161 case R_RSEL:
4162 case R_BEGIN_BRTAB:
4163 case R_END_BRTAB:
4164 case R_BEGIN_TRY:
4165 case R_N0SEL:
4166 case R_N1SEL:
4167 /* There is no symbol or addend associated with these fixups. */
993142d5
ILT
4168 relocs[i]->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
4169 *relocs[i]->sym_ptr_ptr = symbol_get_bfdsym (dummy_symbol);
252b5132
RH
4170 relocs[i]->addend = 0;
4171 break;
4172
4173 case R_END_TRY:
4174 case R_ENTRY:
4175 case R_EXIT:
4176 /* There is no symbol associated with these fixups. */
993142d5
ILT
4177 relocs[i]->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
4178 *relocs[i]->sym_ptr_ptr = symbol_get_bfdsym (dummy_symbol);
252b5132
RH
4179 relocs[i]->addend = fixp->fx_offset;
4180 break;
4181
4182 default:
4183 relocs[i]->addend = fixp->fx_offset;
4184 }
4185 }
4186
4187 done:
4188#endif
4189
4190 return relocs;
4191}
4192
4193/* Process any machine dependent frag types. */
4194
4195void
4196md_convert_frag (abfd, sec, fragP)
3f9b03b5
AM
4197 register bfd *abfd ATTRIBUTE_UNUSED;
4198 register asection *sec ATTRIBUTE_UNUSED;
252b5132
RH
4199 register fragS *fragP;
4200{
4201 unsigned int address;
4202
4203 if (fragP->fr_type == rs_machine_dependent)
4204 {
4205 switch ((int) fragP->fr_subtype)
4206 {
4207 case 0:
4208 fragP->fr_type = rs_fill;
4209 know (fragP->fr_var == 1);
4210 know (fragP->fr_next);
4211 address = fragP->fr_address + fragP->fr_fix;
4212 if (address % fragP->fr_offset)
4213 {
4214 fragP->fr_offset =
4215 fragP->fr_next->fr_address
4216 - fragP->fr_address
4217 - fragP->fr_fix;
4218 }
4219 else
4220 fragP->fr_offset = 0;
4221 break;
4222 }
4223 }
4224}
4225
a28a3ccf 4226/* Round up a section size to the appropriate boundary. */
252b5132
RH
4227
4228valueT
4229md_section_align (segment, size)
4230 asection *segment;
4231 valueT size;
4232{
4233 int align = bfd_get_section_alignment (stdoutput, segment);
4234 int align2 = (1 << align) - 1;
4235
4236 return (size + align2) & ~align2;
4237}
4238
4239/* Return the approximate size of a frag before relaxation has occurred. */
4240int
4241md_estimate_size_before_relax (fragP, segment)
4242 register fragS *fragP;
3f9b03b5 4243 asection *segment ATTRIBUTE_UNUSED;
252b5132
RH
4244{
4245 int size;
4246
4247 size = 0;
4248
4249 while ((fragP->fr_fix + size) % fragP->fr_offset)
4250 size++;
4251
4252 return size;
4253}
4254\f
ad1079af 4255#ifdef OBJ_ELF
4c400d5e
AM
4256# ifdef WARN_COMMENTS
4257const char *md_shortopts = "Vc";
4258# else
ad1079af 4259const char *md_shortopts = "V";
4c400d5e 4260# endif
ad1079af 4261#else
4c400d5e
AM
4262# ifdef WARN_COMMENTS
4263const char *md_shortopts = "c";
4264# else
ad1079af 4265const char *md_shortopts = "";
4c400d5e 4266# endif
ad1079af
AM
4267#endif
4268
252b5132 4269struct option md_longopts[] = {
4c400d5e
AM
4270#ifdef WARN_COMMENTS
4271 {"warn-comment", no_argument, NULL, 'c'},
4272#endif
252b5132
RH
4273 {NULL, no_argument, NULL, 0}
4274};
4275size_t md_longopts_size = sizeof(md_longopts);
4276
4277int
4278md_parse_option (c, arg)
3f9b03b5
AM
4279 int c ATTRIBUTE_UNUSED;
4280 char *arg ATTRIBUTE_UNUSED;
252b5132 4281{
ad1079af
AM
4282 switch (c)
4283 {
4284 default:
4285 return 0;
4286
4287#ifdef OBJ_ELF
4288 case 'V':
4289 print_version_id ();
4290 break;
4c400d5e
AM
4291#endif
4292#ifdef WARN_COMMENTS
4293 case 'c':
4294 warn_comment = 1;
4295 break;
ad1079af
AM
4296#endif
4297 }
4298
4299 return 1;
252b5132
RH
4300}
4301
4302void
4303md_show_usage (stream)
3f9b03b5 4304 FILE *stream ATTRIBUTE_UNUSED;
252b5132 4305{
4c400d5e
AM
4306#ifdef OBJ_ELF
4307 fprintf (stream, _("\
4308 -Q ignored\n"));
4309#endif
4310#ifdef WARN_COMMENTS
4311 fprintf (stream, _("\
4312 -c print a warning if a comment is found\n"));
4313#endif
252b5132
RH
4314}
4315\f
4316/* We have no need to default values of symbols. */
4317
4318symbolS *
4319md_undefined_symbol (name)
3f9b03b5 4320 char *name ATTRIBUTE_UNUSED;
252b5132
RH
4321{
4322 return 0;
4323}
4324
25a8b250 4325#if defined (OBJ_SOM) || defined (ELF_ARG_RELOC)
ad1079af
AM
4326#define arg_reloc_stub_needed(CALLER, CALLEE) \
4327 ((CALLEE) && (CALLER) && ((CALLEE) != (CALLER)))
4328#else
4329#define arg_reloc_stub_needed(CALLER, CALLEE) 0
4330#endif
4331
252b5132
RH
4332/* Apply a fixup to an instruction. */
4333
4334int
4335md_apply_fix (fixP, valp)
4336 fixS *fixP;
4337 valueT *valp;
4338{
4339 char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
4340 struct hppa_fix_struct *hppa_fixP;
3f9b03b5 4341 offsetT new_val;
ad1079af 4342 int insn, val;
252b5132
RH
4343
4344 hppa_fixP = (struct hppa_fix_struct *) fixP->tc_fix_data;
4345 /* SOM uses R_HPPA_ENTRY and R_HPPA_EXIT relocations which can
4346 never be "applied" (they are just markers). Likewise for
4347 R_HPPA_BEGIN_BRTAB and R_HPPA_END_BRTAB. */
4348#ifdef OBJ_SOM
4349 if (fixP->fx_r_type == R_HPPA_ENTRY
4350 || fixP->fx_r_type == R_HPPA_EXIT
4351 || fixP->fx_r_type == R_HPPA_BEGIN_BRTAB
4352 || fixP->fx_r_type == R_HPPA_END_BRTAB
4353 || fixP->fx_r_type == R_HPPA_BEGIN_TRY)
4354 return 1;
4355
4356 /* Disgusting. We must set fx_offset ourselves -- R_HPPA_END_TRY
4357 fixups are considered not adjustable, which in turn causes
4358 adjust_reloc_syms to not set fx_offset. Ugh. */
4359 if (fixP->fx_r_type == R_HPPA_END_TRY)
4360 {
4361 fixP->fx_offset = *valp;
4362 return 1;
4363 }
4364#endif
904a31bf
AM
4365#ifdef OBJ_ELF
4366 if (fixP->fx_r_type == (int) R_PARISC_GNU_VTENTRY
4367 || fixP->fx_r_type == (int) R_PARISC_GNU_VTINHERIT)
4368 return 1;
4369#endif
252b5132 4370
1cd1c99b 4371 insn = bfd_get_32 (stdoutput, (unsigned char *) buf);
252b5132
RH
4372 /* There should have been an HPPA specific fixup associated
4373 with the GAS fixup. */
4374 if (hppa_fixP)
4375 {
ad1079af 4376 int fmt = bfd_hppa_insn2fmt (stdoutput, insn);
252b5132
RH
4377
4378 /* If there is a symbol associated with this fixup, then it's something
4379 which will need a SOM relocation (except for some PC-relative relocs).
4380 In such cases we should treat the "val" or "addend" as zero since it
4381 will be added in as needed from fx_offset in tc_gen_reloc. */
4382 if ((fixP->fx_addsy != NULL
ad1079af 4383 || fixP->fx_r_type == (int) R_HPPA_NONE)
252b5132
RH
4384#ifdef OBJ_SOM
4385 && fmt != 32
4386#endif
4387 )
90700a53 4388 new_val = ((fmt == 12 || fmt == 17 || fmt == 22) ? 8 : 0);
252b5132
RH
4389#ifdef OBJ_SOM
4390 /* These field selectors imply that we do not want an addend. */
4391 else if (hppa_fixP->fx_r_field == e_psel
4392 || hppa_fixP->fx_r_field == e_rpsel
4393 || hppa_fixP->fx_r_field == e_lpsel
4394 || hppa_fixP->fx_r_field == e_tsel
4395 || hppa_fixP->fx_r_field == e_rtsel
4396 || hppa_fixP->fx_r_field == e_ltsel)
90700a53 4397 new_val = ((fmt == 12 || fmt == 17 || fmt == 22) ? 8 : 0);
252b5132
RH
4398 /* This is truely disgusting. The machine independent code blindly
4399 adds in the value of the symbol being relocated against. Damn! */
4400 else if (fmt == 32
4401 && fixP->fx_addsy != NULL
4402 && S_GET_SEGMENT (fixP->fx_addsy) != bfd_com_section_ptr)
4403 new_val = hppa_field_adjust (*valp - S_GET_VALUE (fixP->fx_addsy),
4404 0, hppa_fixP->fx_r_field);
4405#endif
4406 else
4407 new_val = hppa_field_adjust (*valp, 0, hppa_fixP->fx_r_field);
4408
4409 /* Handle pc-relative exceptions from above. */
90700a53 4410 if ((fmt == 12 || fmt == 17 || fmt == 22)
252b5132
RH
4411 && fixP->fx_addsy
4412 && fixP->fx_pcrel
ad1079af
AM
4413 && !arg_reloc_stub_needed (symbol_arg_reloc_info (fixP->fx_addsy),
4414 hppa_fixP->fx_arg_reloc)
46b85d42
AM
4415 && ((*valp + 8192) < 16384
4416 || (fmt == 17 && (*valp + 262144) < 524288)
4417 || (fmt == 22 && (*valp + 8388608) < 16777216))
252b5132
RH
4418 && S_GET_SEGMENT (fixP->fx_addsy) == hppa_fixP->segment
4419 && !(fixP->fx_subsy
4420 && S_GET_SEGMENT (fixP->fx_subsy) != hppa_fixP->segment))
ad1079af
AM
4421 {
4422 new_val = hppa_field_adjust (*valp, 0, hppa_fixP->fx_r_field);
4423 }
3f9b03b5 4424
252b5132
RH
4425 switch (fmt)
4426 {
a02fab7e
JL
4427 case 10:
4428 CHECK_FIELD (new_val, 8191, -8192, 0);
3f9b03b5 4429 val = new_val;
a02fab7e 4430
3f9b03b5
AM
4431 insn = (insn & ~ 0x3ff1) | (((val & 0x1ff8) << 1)
4432 | ((val & 0x2000) >> 13));
a02fab7e
JL
4433 break;
4434 case -11:
4435 CHECK_FIELD (new_val, 8191, -8192, 0);
3f9b03b5 4436 val = new_val;
a02fab7e 4437
3f9b03b5
AM
4438 insn = (insn & ~ 0x3ff9) | (((val & 0x1ffc) << 1)
4439 | ((val & 0x2000) >> 13));
a02fab7e 4440 break;
252b5132
RH
4441 /* Handle all opcodes with the 'j' operand type. */
4442 case 14:
4443 CHECK_FIELD (new_val, 8191, -8192, 0);
3f9b03b5 4444 val = new_val;
252b5132 4445
3f9b03b5 4446 insn = ((insn & ~ 0x3fff) | low_sign_unext (val, 14));
252b5132
RH
4447 break;
4448
4449 /* Handle all opcodes with the 'k' operand type. */
4450 case 21:
ad1079af 4451 CHECK_FIELD (new_val, 1048575, -1048576, 0);
3f9b03b5
AM
4452 val = new_val;
4453
ad1079af 4454 insn = (insn & ~ 0x1fffff) | re_assemble_21 (val);
252b5132
RH
4455 break;
4456
4457 /* Handle all the opcodes with the 'i' operand type. */
4458 case 11:
4459 CHECK_FIELD (new_val, 1023, -1023, 0);
3f9b03b5 4460 val = new_val;
252b5132 4461
3f9b03b5 4462 insn = (insn & ~ 0x7ff) | low_sign_unext (val, 11);
252b5132
RH
4463 break;
4464
4465 /* Handle all the opcodes with the 'w' operand type. */
4466 case 12:
4467 CHECK_FIELD (new_val, 8199, -8184, 0);
3f9b03b5 4468 val = new_val;
252b5132 4469
ad1079af 4470 insn = (insn & ~ 0x1ffd) | re_assemble_12 ((val - 8) >> 2);
252b5132
RH
4471 break;
4472
4473 /* Handle some of the opcodes with the 'W' operand type. */
4474 case 17:
4475 {
3f9b03b5 4476 offsetT distance = *valp;
252b5132
RH
4477
4478 /* If this is an absolute branch (ie no link) with an out of
4479 range target, then we want to complain. */
ad1079af 4480 if (fixP->fx_r_type == (int) R_HPPA_PCREL_CALL
3f9b03b5 4481 && (insn & 0xffe00000) == 0xe8000000)
252b5132
RH
4482 CHECK_FIELD (distance, 262143, -262144, 0);
4483
3f9b03b5
AM
4484 CHECK_FIELD (new_val, 262143, -262144, 0);
4485 val = new_val;
4486
ad1079af 4487 insn = (insn & ~ 0x1f1ffd) | re_assemble_17 ((val - 8) >> 2);
252b5132
RH
4488 break;
4489 }
4490
77c02e18
JL
4491 case 22:
4492 {
3f9b03b5 4493 offsetT distance = *valp;
77c02e18
JL
4494
4495 /* If this is an absolute branch (ie no link) with an out of
4496 range target, then we want to complain. */
ad1079af 4497 if (fixP->fx_r_type == (int) R_HPPA_PCREL_CALL
3f9b03b5 4498 && (insn & 0xffe00000) == 0xe8000000)
77c02e18
JL
4499 CHECK_FIELD (distance, 8388607, -8388608, 0);
4500
3f9b03b5
AM
4501 CHECK_FIELD (new_val, 8388607, -8388608, 0);
4502 val = new_val;
4503
ad1079af 4504 insn = (insn & ~ 0x3ff1ffd) | re_assemble_22 ((val - 8) >> 2);
77c02e18
JL
4505 break;
4506 }
4507
ad1079af
AM
4508 case -10:
4509 val = new_val;
4510 insn = (insn & ~ 0xfff1) | re_assemble_16 (val & -8);
4511 break;
4512
4513 case -16:
4514 val = new_val;
4515 insn = (insn & ~ 0xfff9) | re_assemble_16 (val & -4);
4516 break;
4517
4518 case 16:
4519 val = new_val;
4520 insn = (insn & ~ 0xffff) | re_assemble_16 (val);
4521 break;
4522
252b5132 4523 case 32:
3f9b03b5 4524 insn = new_val;
252b5132
RH
4525 break;
4526
4527 default:
4528 as_bad (_("Unknown relocation encountered in md_apply_fix."));
4529 return 0;
4530 }
4531
4532 /* Insert the relocation. */
ad1079af 4533 bfd_put_32 (stdoutput, insn, (unsigned char *) buf);
252b5132
RH
4534 return 1;
4535 }
4536 else
4537 {
4538 printf (_("no hppa_fixup entry for this fixup (fixP = 0x%x, type = 0x%x)\n"),
4539 (unsigned int) fixP, fixP->fx_r_type);
4540 return 0;
4541 }
4542}
4543
4544/* Exactly what point is a PC-relative offset relative TO?
4545 On the PA, they're relative to the address of the offset. */
4546
4547long
4548md_pcrel_from (fixP)
4549 fixS *fixP;
4550{
4551 return fixP->fx_where + fixP->fx_frag->fr_address;
4552}
4553
4554/* Return nonzero if the input line pointer is at the end of
4555 a statement. */
4556
4557static int
4558is_end_of_statement ()
4559{
4560 return ((*input_line_pointer == '\n')
4561 || (*input_line_pointer == ';')
4562 || (*input_line_pointer == '!'));
4563}
4564
4565/* Read a number from S. The number might come in one of many forms,
4566 the most common will be a hex or decimal constant, but it could be
4567 a pre-defined register (Yuk!), or an absolute symbol.
4568
ecacdc7a
AM
4569 Return 1 on success or 0 on failure. If STRICT, then a missing
4570 register prefix will cause a failure. The number itself is
4571 returned in `pa_number'.
252b5132 4572
ecacdc7a
AM
4573 IS_FLOAT indicates that a PA-89 FP register number should be
4574 parsed; A `l' or `r' suffix is checked for if but 2 of IS_FLOAT is
4575 not set.
252b5132
RH
4576
4577 pa_parse_number can not handle negative constants and will fail
4578 horribly if it is passed such a constant. */
4579
4580static int
ecacdc7a 4581pa_parse_number (s, is_float)
252b5132 4582 char **s;
ecacdc7a 4583 int is_float;
252b5132
RH
4584{
4585 int num;
4586 char *name;
4587 char c;
4588 symbolS *sym;
4589 int status;
4590 char *p = *s;
ecacdc7a 4591 boolean have_prefix;
252b5132
RH
4592
4593 /* Skip whitespace before the number. */
4594 while (*p == ' ' || *p == '\t')
4595 p = p + 1;
4596
ecacdc7a
AM
4597 pa_number = -1;
4598 have_prefix = 0;
4599 num = 0;
4600 if (!strict && isdigit (*p))
252b5132
RH
4601 {
4602 /* Looks like a number. */
252b5132
RH
4603
4604 if (*p == '0' && (*(p + 1) == 'x' || *(p + 1) == 'X'))
4605 {
4606 /* The number is specified in hex. */
4607 p += 2;
4608 while (isdigit (*p) || ((*p >= 'a') && (*p <= 'f'))
4609 || ((*p >= 'A') && (*p <= 'F')))
4610 {
4611 if (isdigit (*p))
4612 num = num * 16 + *p - '0';
4613 else if (*p >= 'a' && *p <= 'f')
4614 num = num * 16 + *p - 'a' + 10;
4615 else
4616 num = num * 16 + *p - 'A' + 10;
4617 ++p;
4618 }
4619 }
4620 else
4621 {
4622 /* The number is specified in decimal. */
4623 while (isdigit (*p))
4624 {
4625 num = num * 10 + *p - '0';
4626 ++p;
4627 }
4628 }
4629
ecacdc7a 4630 pa_number = num;
252b5132 4631
ecacdc7a
AM
4632 /* Check for a `l' or `r' suffix. */
4633 if (is_float)
4634 {
4635 pa_number += FP_REG_BASE;
4636 if (! (is_float & 2))
252b5132 4637 {
ecacdc7a
AM
4638 if (IS_R_SELECT (p))
4639 {
4640 pa_number += FP_REG_RSEL;
4641 ++p;
4642 }
4643 else if (IS_L_SELECT (p))
4644 {
4645 ++p;
4646 }
252b5132 4647 }
252b5132
RH
4648 }
4649 }
4650 else if (*p == '%')
4651 {
4652 /* The number might be a predefined register. */
ecacdc7a 4653 have_prefix = 1;
252b5132
RH
4654 name = p;
4655 p++;
4656 c = *p;
4657 /* Tege hack: Special case for general registers as the general
4658 code makes a binary search with case translation, and is VERY
a28a3ccf 4659 slow. */
252b5132
RH
4660 if (c == 'r')
4661 {
4662 p++;
4663 if (*p == 'e' && *(p + 1) == 't'
4664 && (*(p + 2) == '0' || *(p + 2) == '1'))
4665 {
4666 p += 2;
4667 num = *p - '0' + 28;
4668 p++;
4669 }
4670 else if (*p == 'p')
4671 {
4672 num = 2;
4673 p++;
4674 }
4675 else if (!isdigit (*p))
4676 {
4677 if (print_errors)
4678 as_bad (_("Undefined register: '%s'."), name);
4679 num = -1;
4680 }
4681 else
4682 {
4683 do
4684 num = num * 10 + *p++ - '0';
4685 while (isdigit (*p));
4686 }
4687 }
4688 else
4689 {
4690 /* Do a normal register search. */
4691 while (is_part_of_name (c))
4692 {
4693 p = p + 1;
4694 c = *p;
4695 }
4696 *p = 0;
4697 status = reg_name_search (name);
4698 if (status >= 0)
4699 num = status;
4700 else
4701 {
4702 if (print_errors)
4703 as_bad (_("Undefined register: '%s'."), name);
4704 num = -1;
4705 }
4706 *p = c;
4707 }
4708
ecacdc7a 4709 pa_number = num;
252b5132
RH
4710 }
4711 else
4712 {
4713 /* And finally, it could be a symbol in the absolute section which
ecacdc7a 4714 is effectively a constant, or a register alias symbol. */
252b5132
RH
4715 name = p;
4716 c = *p;
4717 while (is_part_of_name (c))
4718 {
4719 p = p + 1;
4720 c = *p;
4721 }
4722 *p = 0;
4723 if ((sym = symbol_find (name)) != NULL)
4724 {
ecacdc7a
AM
4725 if (S_GET_SEGMENT (sym) == reg_section)
4726 {
4727 num = S_GET_VALUE (sym);
4728 /* Well, we don't really have one, but we do have a
4729 register, so... */
4730 have_prefix = true;
4731 }
4732 else if (S_GET_SEGMENT (sym) == &bfd_abs_section)
252b5132 4733 num = S_GET_VALUE (sym);
ecacdc7a 4734 else if (!strict)
252b5132
RH
4735 {
4736 if (print_errors)
4737 as_bad (_("Non-absolute symbol: '%s'."), name);
4738 num = -1;
4739 }
4740 }
ecacdc7a 4741 else if (!strict)
252b5132
RH
4742 {
4743 /* There is where we'd come for an undefined symbol
4744 or for an empty string. For an empty string we
4745 will return zero. That's a concession made for
4746 compatability with the braindamaged HP assemblers. */
4747 if (*name == 0)
4748 num = 0;
4749 else
4750 {
4751 if (print_errors)
4752 as_bad (_("Undefined absolute constant: '%s'."), name);
4753 num = -1;
4754 }
4755 }
4756 *p = c;
4757
ecacdc7a 4758 pa_number = num;
252b5132
RH
4759 }
4760
ecacdc7a
AM
4761 if (!strict || have_prefix)
4762 {
4763 *s = p;
4764 return 1;
4765 }
4766 return 0;
252b5132
RH
4767}
4768
4769#define REG_NAME_CNT (sizeof(pre_defined_registers) / sizeof(struct pd_reg))
4770
4771/* Given NAME, find the register number associated with that name, return
4772 the integer value associated with the given name or -1 on failure. */
4773
4774static int
4775reg_name_search (name)
4776 char *name;
4777{
4778 int middle, low, high;
4779 int cmp;
4780
4781 low = 0;
4782 high = REG_NAME_CNT - 1;
4783
4784 do
4785 {
4786 middle = (low + high) / 2;
4787 cmp = strcasecmp (name, pre_defined_registers[middle].name);
4788 if (cmp < 0)
4789 high = middle - 1;
4790 else if (cmp > 0)
4791 low = middle + 1;
4792 else
4793 return pre_defined_registers[middle].value;
4794 }
4795 while (low <= high);
4796
4797 return -1;
4798}
4799
252b5132
RH
4800/* Return nonzero if the given INSN and L/R information will require
4801 a new PA-1.1 opcode. */
4802
4803static int
ecacdc7a 4804need_pa11_opcode ()
252b5132 4805{
ecacdc7a
AM
4806 if ((pa_number & FP_REG_RSEL) != 0
4807 && !(the_insn.fpof1 == DBL && the_insn.fpof2 == DBL))
252b5132
RH
4808 {
4809 /* If this instruction is specific to a particular architecture,
4810 then set a new architecture. */
4811 if (bfd_get_mach (stdoutput) < pa11)
4812 {
4813 if (!bfd_set_arch_mach (stdoutput, bfd_arch_hppa, pa11))
4814 as_warn (_("could not update architecture and machine"));
4815 }
4816 return TRUE;
4817 }
4818 else
4819 return FALSE;
4820}
4821
4822/* Parse a condition for a fcmp instruction. Return the numerical
4823 code associated with the condition. */
4824
4825static int
4826pa_parse_fp_cmp_cond (s)
4827 char **s;
4828{
4829 int cond, i;
4830
4831 cond = 0;
4832
4833 for (i = 0; i < 32; i++)
4834 {
4835 if (strncasecmp (*s, fp_cond_map[i].string,
4836 strlen (fp_cond_map[i].string)) == 0)
4837 {
4838 cond = fp_cond_map[i].cond;
4839 *s += strlen (fp_cond_map[i].string);
4840 /* If not a complete match, back up the input string and
4841 report an error. */
4842 if (**s != ' ' && **s != '\t')
4843 {
4844 *s -= strlen (fp_cond_map[i].string);
4845 break;
4846 }
4847 while (**s == ' ' || **s == '\t')
4848 *s = *s + 1;
4849 return cond;
4850 }
4851 }
4852
4853 as_bad (_("Invalid FP Compare Condition: %s"), *s);
4854
4855 /* Advance over the bogus completer. */
4856 while (**s != ',' && **s != ' ' && **s != '\t')
4857 *s += 1;
4858
4859 return 0;
4860}
4861
1cf6ae67
JL
4862/* Parse a graphics test complete for ftest. */
4863
4864static int
4865pa_parse_ftest_gfx_completer (s)
4866 char **s;
4867{
4868 int value;
4869
4870 value = 0;
4871 if (strncasecmp (*s, "acc8", 4) == 0)
4872 {
4873 value = 5;
4874 *s += 4;
4875 }
4876 else if (strncasecmp (*s, "acc6", 4) == 0)
4877 {
4878 value = 9;
4879 *s += 4;
4880 }
4881 else if (strncasecmp (*s, "acc4", 4) == 0)
4882 {
4883 value = 13;
4884 *s += 4;
4885 }
4886 else if (strncasecmp (*s, "acc2", 4) == 0)
4887 {
4888 value = 17;
4889 *s += 4;
4890 }
4891 else if (strncasecmp (*s, "acc", 3) == 0)
4892 {
4893 value = 1;
4894 *s += 3;
4895 }
4896 else if (strncasecmp (*s, "rej8", 4) == 0)
4897 {
4898 value = 6;
4899 *s += 4;
4900 }
4901 else if (strncasecmp (*s, "rej", 3) == 0)
4902 {
4903 value = 2;
4904 *s += 3;
4905 }
4906 else
4907 {
4908 value = 0;
4909 as_bad (_("Invalid FTEST completer: %s"), *s);
4910 }
4911
4912 return value;
4913}
4914
4915/* Parse an FP operand format completer returning the completer
4916 type. */
4917
4918static fp_operand_format
4919pa_parse_fp_cnv_format (s)
4920 char **s;
4921{
4922 int format;
4923
4924 format = SGL;
4925 if (**s == ',')
4926 {
4927 *s += 1;
4928 if (strncasecmp (*s, "sgl", 3) == 0)
4929 {
4930 format = SGL;
4931 *s += 4;
4932 }
4933 else if (strncasecmp (*s, "dbl", 3) == 0)
4934 {
4935 format = DBL;
4936 *s += 4;
4937 }
4938 else if (strncasecmp (*s, "quad", 4) == 0)
4939 {
4940 format = QUAD;
4941 *s += 5;
4942 }
4943 else if (strncasecmp (*s, "w", 1) == 0)
4944 {
4945 format = W;
4946 *s += 2;
4947 }
4948 else if (strncasecmp (*s, "uw", 2) == 0)
4949 {
4950 format = UW;
4951 *s += 3;
4952 }
4953 else if (strncasecmp (*s, "dw", 2) == 0)
4954 {
4955 format = DW;
4956 *s += 3;
4957 }
4958 else if (strncasecmp (*s, "udw", 3) == 0)
4959 {
4960 format = UDW;
4961 *s += 4;
4962 }
4963 else if (strncasecmp (*s, "qw", 2) == 0)
4964 {
4965 format = QW;
4966 *s += 3;
4967 }
4968 else if (strncasecmp (*s, "uqw", 3) == 0)
4969 {
4970 format = UQW;
4971 *s += 4;
4972 }
4973 else
4974 {
4975 format = ILLEGAL_FMT;
4976 as_bad (_("Invalid FP Operand Format: %3s"), *s);
4977 }
4978 }
4979
4980 return format;
4981}
252b5132
RH
4982
4983/* Parse an FP operand format completer returning the completer
4984 type. */
4985
4986static fp_operand_format
4987pa_parse_fp_format (s)
4988 char **s;
4989{
4990 int format;
4991
4992 format = SGL;
4993 if (**s == ',')
4994 {
4995 *s += 1;
4996 if (strncasecmp (*s, "sgl", 3) == 0)
4997 {
4998 format = SGL;
4999 *s += 4;
5000 }
5001 else if (strncasecmp (*s, "dbl", 3) == 0)
5002 {
5003 format = DBL;
5004 *s += 4;
5005 }
5006 else if (strncasecmp (*s, "quad", 4) == 0)
5007 {
5008 format = QUAD;
5009 *s += 5;
5010 }
5011 else
5012 {
5013 format = ILLEGAL_FMT;
5014 as_bad (_("Invalid FP Operand Format: %3s"), *s);
5015 }
5016 }
5017
5018 return format;
5019}
5020
5021/* Convert from a selector string into a selector type. */
5022
5023static int
5024pa_chk_field_selector (str)
5025 char **str;
5026{
5027 int middle, low, high;
5028 int cmp;
5029 char name[4];
5030
5031 /* Read past any whitespace. */
5032 /* FIXME: should we read past newlines and formfeeds??? */
5033 while (**str == ' ' || **str == '\t' || **str == '\n' || **str == '\f')
5034 *str = *str + 1;
5035
5036 if ((*str)[1] == '\'' || (*str)[1] == '%')
5037 name[0] = tolower ((*str)[0]),
5038 name[1] = 0;
5039 else if ((*str)[2] == '\'' || (*str)[2] == '%')
5040 name[0] = tolower ((*str)[0]),
5041 name[1] = tolower ((*str)[1]),
5042 name[2] = 0;
252b5132
RH
5043 else if ((*str)[3] == '\'' || (*str)[3] == '%')
5044 name[0] = tolower ((*str)[0]),
5045 name[1] = tolower ((*str)[1]),
5046 name[2] = tolower ((*str)[2]),
5047 name[3] = 0;
252b5132
RH
5048 else
5049 return e_fsel;
5050
5051 low = 0;
5052 high = sizeof (selector_table) / sizeof (struct selector_entry) - 1;
5053
5054 do
5055 {
5056 middle = (low + high) / 2;
5057 cmp = strcmp (name, selector_table[middle].prefix);
5058 if (cmp < 0)
5059 high = middle - 1;
5060 else if (cmp > 0)
5061 low = middle + 1;
5062 else
5063 {
5064 *str += strlen (name) + 1;
5065#ifndef OBJ_SOM
5066 if (selector_table[middle].field_selector == e_nsel)
5067 return e_fsel;
5068#endif
5069 return selector_table[middle].field_selector;
5070 }
5071 }
5072 while (low <= high);
5073
5074 return e_fsel;
5075}
5076
5077/* Mark (via expr_end) the end of an expression (I think). FIXME. */
5078
5079static int
5080get_expression (str)
5081 char *str;
5082{
5083 char *save_in;
5084 asection *seg;
5085
5086 save_in = input_line_pointer;
5087 input_line_pointer = str;
5088 seg = expression (&the_insn.exp);
5089 if (!(seg == absolute_section
5090 || seg == undefined_section
5091 || SEG_NORMAL (seg)))
5092 {
5093 as_warn (_("Bad segment in expression."));
5094 expr_end = input_line_pointer;
5095 input_line_pointer = save_in;
5096 return 1;
5097 }
5098 expr_end = input_line_pointer;
5099 input_line_pointer = save_in;
5100 return 0;
5101}
5102
a28a3ccf 5103/* Mark (via expr_end) the end of an absolute expression. FIXME. */
252b5132
RH
5104static int
5105pa_get_absolute_expression (insn, strp)
5106 struct pa_it *insn;
5107 char **strp;
5108{
5109 char *save_in;
5110
5111 insn->field_selector = pa_chk_field_selector (strp);
5112 save_in = input_line_pointer;
5113 input_line_pointer = *strp;
5114 expression (&insn->exp);
5115 /* This is not perfect, but is a huge improvement over doing nothing.
5116
5117 The PA assembly syntax is ambigious in a variety of ways. Consider
5118 this string "4 %r5" Is that the number 4 followed by the register
ecacdc7a 5119 r5, or is that 4 MOD r5?
252b5132
RH
5120
5121 If we get a modulo expresion When looking for an absolute, we try
5122 again cutting off the input string at the first whitespace character. */
5123 if (insn->exp.X_op == O_modulus)
5124 {
5125 char *s, c;
5126 int retval;
5127
5128 input_line_pointer = *strp;
5129 s = *strp;
5130 while (*s != ',' && *s != ' ' && *s != '\t')
5131 s++;
5132
5133 c = *s;
5134 *s = 0;
5135
5136 retval = pa_get_absolute_expression (insn, strp);
5137
5138 input_line_pointer = save_in;
5139 *s = c;
5140 return evaluate_absolute (insn);
5141 }
0f4f8b56
JL
5142 /* When in strict mode we have a non-match, fix up the pointers
5143 and return to our caller. */
5144 if (insn->exp.X_op != O_constant && strict)
5145 {
5146 expr_end = input_line_pointer;
5147 input_line_pointer = save_in;
5148 return 0;
5149 }
252b5132
RH
5150 if (insn->exp.X_op != O_constant)
5151 {
5152 as_bad (_("Bad segment (should be absolute)."));
5153 expr_end = input_line_pointer;
5154 input_line_pointer = save_in;
5155 return 0;
5156 }
5157 expr_end = input_line_pointer;
5158 input_line_pointer = save_in;
5159 return evaluate_absolute (insn);
5160}
5161
5162/* Evaluate an absolute expression EXP which may be modified by
5163 the selector FIELD_SELECTOR. Return the value of the expression. */
5164static int
5165evaluate_absolute (insn)
5166 struct pa_it *insn;
5167{
3f9b03b5 5168 offsetT value;
252b5132
RH
5169 expressionS exp;
5170 int field_selector = insn->field_selector;
5171
5172 exp = insn->exp;
5173 value = exp.X_add_number;
5174
3f9b03b5 5175 return hppa_field_adjust (0, value, field_selector);
252b5132
RH
5176}
5177
5178/* Given an argument location specification return the associated
5179 argument location number. */
5180
5181static unsigned int
5182pa_build_arg_reloc (type_name)
5183 char *type_name;
5184{
5185
5186 if (strncasecmp (type_name, "no", 2) == 0)
5187 return 0;
5188 if (strncasecmp (type_name, "gr", 2) == 0)
5189 return 1;
5190 else if (strncasecmp (type_name, "fr", 2) == 0)
5191 return 2;
5192 else if (strncasecmp (type_name, "fu", 2) == 0)
5193 return 3;
5194 else
5195 as_bad (_("Invalid argument location: %s\n"), type_name);
5196
5197 return 0;
5198}
5199
5200/* Encode and return an argument relocation specification for
5201 the given register in the location specified by arg_reloc. */
5202
5203static unsigned int
5204pa_align_arg_reloc (reg, arg_reloc)
5205 unsigned int reg;
5206 unsigned int arg_reloc;
5207{
5208 unsigned int new_reloc;
5209
5210 new_reloc = arg_reloc;
5211 switch (reg)
5212 {
5213 case 0:
5214 new_reloc <<= 8;
5215 break;
5216 case 1:
5217 new_reloc <<= 6;
5218 break;
5219 case 2:
5220 new_reloc <<= 4;
5221 break;
5222 case 3:
5223 new_reloc <<= 2;
5224 break;
5225 default:
5226 as_bad (_("Invalid argument description: %d"), reg);
5227 }
5228
5229 return new_reloc;
5230}
5231
5232/* Parse a PA nullification completer (,n). Return nonzero if the
5233 completer was found; return zero if no completer was found. */
5234
5235static int
5236pa_parse_nullif (s)
5237 char **s;
5238{
5239 int nullif;
5240
5241 nullif = 0;
5242 if (**s == ',')
5243 {
5244 *s = *s + 1;
5245 if (strncasecmp (*s, "n", 1) == 0)
5246 nullif = 1;
5247 else
5248 {
5249 as_bad (_("Invalid Nullification: (%c)"), **s);
5250 nullif = 0;
5251 }
5252 *s = *s + 1;
5253 }
5254
5255 return nullif;
5256}
5257
5258/* Parse a non-negated compare/subtract completer returning the
5259 number (for encoding in instrutions) of the given completer.
5260
5261 ISBRANCH specifies whether or not this is parsing a condition
5262 completer for a branch (vs a nullification completer for a
5263 computational instruction. */
5264
5265static int
5266pa_parse_nonneg_cmpsub_cmpltr (s, isbranch)
5267 char **s;
5268 int isbranch;
5269{
5270 int cmpltr;
5271 char *name = *s + 1;
5272 char c;
5273 char *save_s = *s;
5274 int nullify = 0;
5275
5276 cmpltr = 0;
5277 if (**s == ',')
5278 {
5279 *s += 1;
5280 while (**s != ',' && **s != ' ' && **s != '\t')
5281 *s += 1;
5282 c = **s;
5283 **s = 0x00;
5284
252b5132
RH
5285 if (strcmp (name, "=") == 0)
5286 {
5287 cmpltr = 1;
5288 }
5289 else if (strcmp (name, "<") == 0)
5290 {
5291 cmpltr = 2;
5292 }
5293 else if (strcmp (name, "<=") == 0)
5294 {
5295 cmpltr = 3;
5296 }
5297 else if (strcmp (name, "<<") == 0)
5298 {
5299 cmpltr = 4;
5300 }
5301 else if (strcmp (name, "<<=") == 0)
5302 {
5303 cmpltr = 5;
5304 }
5305 else if (strcasecmp (name, "sv") == 0)
5306 {
5307 cmpltr = 6;
5308 }
5309 else if (strcasecmp (name, "od") == 0)
5310 {
5311 cmpltr = 7;
5312 }
5313 /* If we have something like addb,n then there is no condition
5314 completer. */
5315 else if (strcasecmp (name, "n") == 0 && isbranch)
5316 {
5317 cmpltr = 0;
5318 nullify = 1;
5319 }
5320 else
5321 {
5322 cmpltr = -1;
5323 }
5324 **s = c;
5325 }
5326
5327 /* Reset pointers if this was really a ,n for a branch instruction. */
5328 if (nullify)
5329 *s = save_s;
5330
252b5132
RH
5331 return cmpltr;
5332}
5333
5334/* Parse a negated compare/subtract completer returning the
5335 number (for encoding in instrutions) of the given completer.
5336
5337 ISBRANCH specifies whether or not this is parsing a condition
5338 completer for a branch (vs a nullification completer for a
5339 computational instruction. */
5340
5341static int
5342pa_parse_neg_cmpsub_cmpltr (s, isbranch)
5343 char **s;
5344 int isbranch;
5345{
5346 int cmpltr;
5347 char *name = *s + 1;
5348 char c;
5349 char *save_s = *s;
5350 int nullify = 0;
5351
5352 cmpltr = 0;
5353 if (**s == ',')
5354 {
5355 *s += 1;
5356 while (**s != ',' && **s != ' ' && **s != '\t')
5357 *s += 1;
5358 c = **s;
5359 **s = 0x00;
5360
252b5132
RH
5361 if (strcasecmp (name, "tr") == 0)
5362 {
5363 cmpltr = 0;
5364 }
5365 else if (strcmp (name, "<>") == 0)
5366 {
5367 cmpltr = 1;
5368 }
5369 else if (strcmp (name, ">=") == 0)
5370 {
5371 cmpltr = 2;
5372 }
5373 else if (strcmp (name, ">") == 0)
5374 {
5375 cmpltr = 3;
5376 }
5377 else if (strcmp (name, ">>=") == 0)
5378 {
5379 cmpltr = 4;
5380 }
5381 else if (strcmp (name, ">>") == 0)
5382 {
5383 cmpltr = 5;
5384 }
5385 else if (strcasecmp (name, "nsv") == 0)
5386 {
5387 cmpltr = 6;
5388 }
5389 else if (strcasecmp (name, "ev") == 0)
5390 {
5391 cmpltr = 7;
5392 }
5393 /* If we have something like addb,n then there is no condition
5394 completer. */
5395 else if (strcasecmp (name, "n") == 0 && isbranch)
5396 {
5397 cmpltr = 0;
5398 nullify = 1;
5399 }
5400 else
5401 {
5402 cmpltr = -1;
5403 }
5404 **s = c;
5405 }
5406
5407 /* Reset pointers if this was really a ,n for a branch instruction. */
5408 if (nullify)
5409 *s = save_s;
5410
252b5132
RH
5411 return cmpltr;
5412}
5413
d53d2751
JL
5414/* Parse a 64 bit compare and branch completer returning the number (for
5415 encoding in instrutions) of the given completer.
5416
5417 Nonnegated comparisons are returned as 0-7, negated comparisons are
5418 returned as 8-15. */
5419
5420static int
5421pa_parse_cmpb_64_cmpltr (s)
5422 char **s;
5423{
5424 int cmpltr;
5425 char *name = *s + 1;
5426 char c;
d53d2751
JL
5427
5428 cmpltr = -1;
5429 if (**s == ',')
5430 {
5431 *s += 1;
5432 while (**s != ',' && **s != ' ' && **s != '\t')
5433 *s += 1;
5434 c = **s;
5435 **s = 0x00;
5436
5437 if (strcmp (name, "*") == 0)
5438 {
5439 cmpltr = 0;
5440 }
5441 else if (strcmp (name, "*=") == 0)
5442 {
5443 cmpltr = 1;
5444 }
5445 else if (strcmp (name, "*<") == 0)
5446 {
5447 cmpltr = 2;
5448 }
5449 else if (strcmp (name, "*<=") == 0)
5450 {
5451 cmpltr = 3;
5452 }
5453 else if (strcmp (name, "*<<") == 0)
5454 {
5455 cmpltr = 4;
5456 }
5457 else if (strcmp (name, "*<<=") == 0)
5458 {
5459 cmpltr = 5;
5460 }
5461 else if (strcasecmp (name, "*sv") == 0)
5462 {
5463 cmpltr = 6;
5464 }
5465 else if (strcasecmp (name, "*od") == 0)
5466 {
5467 cmpltr = 7;
5468 }
5469 else if (strcasecmp (name, "*tr") == 0)
5470 {
5471 cmpltr = 8;
5472 }
5473 else if (strcmp (name, "*<>") == 0)
5474 {
5475 cmpltr = 9;
5476 }
5477 else if (strcmp (name, "*>=") == 0)
5478 {
5479 cmpltr = 10;
5480 }
5481 else if (strcmp (name, "*>") == 0)
5482 {
5483 cmpltr = 11;
5484 }
5485 else if (strcmp (name, "*>>=") == 0)
5486 {
5487 cmpltr = 12;
5488 }
5489 else if (strcmp (name, "*>>") == 0)
5490 {
5491 cmpltr = 13;
5492 }
5493 else if (strcasecmp (name, "*nsv") == 0)
5494 {
5495 cmpltr = 14;
5496 }
5497 else if (strcasecmp (name, "*ev") == 0)
5498 {
5499 cmpltr = 15;
5500 }
5501 else
5502 {
5503 cmpltr = -1;
5504 }
5505 **s = c;
5506 }
5507
d53d2751
JL
5508 return cmpltr;
5509}
5510
5511/* Parse a 64 bit compare immediate and branch completer returning the number
5512 (for encoding in instrutions) of the given completer. */
5513
5514static int
5515pa_parse_cmpib_64_cmpltr (s)
5516 char **s;
5517{
5518 int cmpltr;
5519 char *name = *s + 1;
5520 char c;
d53d2751
JL
5521
5522 cmpltr = -1;
5523 if (**s == ',')
5524 {
5525 *s += 1;
5526 while (**s != ',' && **s != ' ' && **s != '\t')
5527 *s += 1;
5528 c = **s;
5529 **s = 0x00;
5530
5531 if (strcmp (name, "*<<") == 0)
5532 {
5533 cmpltr = 0;
5534 }
5535 else if (strcmp (name, "*=") == 0)
5536 {
5537 cmpltr = 1;
5538 }
5539 else if (strcmp (name, "*<") == 0)
5540 {
5541 cmpltr = 2;
5542 }
5543 else if (strcmp (name, "*<=") == 0)
5544 {
5545 cmpltr = 3;
5546 }
5547 else if (strcmp (name, "*>>=") == 0)
5548 {
5549 cmpltr = 4;
5550 }
5551 else if (strcmp (name, "*<>") == 0)
5552 {
5553 cmpltr = 5;
5554 }
5555 else if (strcasecmp (name, "*>=") == 0)
5556 {
5557 cmpltr = 6;
5558 }
5559 else if (strcasecmp (name, "*>") == 0)
5560 {
5561 cmpltr = 7;
5562 }
5563 else
5564 {
5565 cmpltr = -1;
5566 }
5567 **s = c;
5568 }
5569
d53d2751
JL
5570 return cmpltr;
5571}
5572
252b5132
RH
5573/* Parse a non-negated addition completer returning the number
5574 (for encoding in instrutions) of the given completer.
5575
5576 ISBRANCH specifies whether or not this is parsing a condition
5577 completer for a branch (vs a nullification completer for a
5578 computational instruction. */
5579
5580static int
5581pa_parse_nonneg_add_cmpltr (s, isbranch)
5582 char **s;
5583 int isbranch;
5584{
5585 int cmpltr;
5586 char *name = *s + 1;
5587 char c;
5588 char *save_s = *s;
5589
5590 cmpltr = 0;
5591 if (**s == ',')
5592 {
5593 *s += 1;
5594 while (**s != ',' && **s != ' ' && **s != '\t')
5595 *s += 1;
5596 c = **s;
5597 **s = 0x00;
5598 if (strcmp (name, "=") == 0)
5599 {
5600 cmpltr = 1;
5601 }
5602 else if (strcmp (name, "<") == 0)
5603 {
5604 cmpltr = 2;
5605 }
5606 else if (strcmp (name, "<=") == 0)
5607 {
5608 cmpltr = 3;
5609 }
5610 else if (strcasecmp (name, "nuv") == 0)
5611 {
5612 cmpltr = 4;
5613 }
5614 else if (strcasecmp (name, "znv") == 0)
5615 {
5616 cmpltr = 5;
5617 }
5618 else if (strcasecmp (name, "sv") == 0)
5619 {
5620 cmpltr = 6;
5621 }
5622 else if (strcasecmp (name, "od") == 0)
5623 {
5624 cmpltr = 7;
5625 }
5626 /* If we have something like addb,n then there is no condition
5627 completer. */
5628 else if (strcasecmp (name, "n") == 0 && isbranch)
5629 {
5630 cmpltr = 0;
5631 }
5632 else
5633 {
5634 cmpltr = -1;
5635 }
5636 **s = c;
5637 }
5638
5639 /* Reset pointers if this was really a ,n for a branch instruction. */
5640 if (cmpltr == 0 && *name == 'n' && isbranch)
5641 *s = save_s;
5642
5643 return cmpltr;
5644}
5645
5646/* Parse a negated addition completer returning the number
5647 (for encoding in instrutions) of the given completer.
5648
5649 ISBRANCH specifies whether or not this is parsing a condition
5650 completer for a branch (vs a nullification completer for a
5651 computational instruction). */
5652
5653static int
5654pa_parse_neg_add_cmpltr (s, isbranch)
5655 char **s;
5656 int isbranch;
5657{
5658 int cmpltr;
5659 char *name = *s + 1;
5660 char c;
5661 char *save_s = *s;
5662
5663 cmpltr = 0;
5664 if (**s == ',')
5665 {
5666 *s += 1;
5667 while (**s != ',' && **s != ' ' && **s != '\t')
5668 *s += 1;
5669 c = **s;
5670 **s = 0x00;
5671 if (strcasecmp (name, "tr") == 0)
5672 {
5673 cmpltr = 0;
5674 }
5675 else if (strcmp (name, "<>") == 0)
5676 {
5677 cmpltr = 1;
5678 }
5679 else if (strcmp (name, ">=") == 0)
5680 {
5681 cmpltr = 2;
5682 }
5683 else if (strcmp (name, ">") == 0)
5684 {
5685 cmpltr = 3;
5686 }
5687 else if (strcasecmp (name, "uv") == 0)
5688 {
5689 cmpltr = 4;
5690 }
5691 else if (strcasecmp (name, "vnz") == 0)
5692 {
5693 cmpltr = 5;
5694 }
5695 else if (strcasecmp (name, "nsv") == 0)
5696 {
5697 cmpltr = 6;
5698 }
5699 else if (strcasecmp (name, "ev") == 0)
5700 {
5701 cmpltr = 7;
5702 }
5703 /* If we have something like addb,n then there is no condition
5704 completer. */
5705 else if (strcasecmp (name, "n") == 0 && isbranch)
5706 {
5707 cmpltr = 0;
5708 }
5709 else
5710 {
5711 cmpltr = -1;
5712 }
5713 **s = c;
5714 }
5715
5716 /* Reset pointers if this was really a ,n for a branch instruction. */
5717 if (cmpltr == 0 && *name == 'n' && isbranch)
5718 *s = save_s;
5719
5720 return cmpltr;
5721}
5722
d53d2751
JL
5723/* Parse a 64 bit wide mode add and branch completer returning the number (for
5724 encoding in instrutions) of the given completer. */
5725
5726static int
5727pa_parse_addb_64_cmpltr (s)
5728 char **s;
5729{
5730 int cmpltr;
5731 char *name = *s + 1;
5732 char c;
5733 char *save_s = *s;
5734 int nullify = 0;
5735
5736 cmpltr = 0;
5737 if (**s == ',')
5738 {
5739 *s += 1;
5740 while (**s != ',' && **s != ' ' && **s != '\t')
5741 *s += 1;
5742 c = **s;
5743 **s = 0x00;
5744 if (strcmp (name, "=") == 0)
5745 {
5746 cmpltr = 1;
5747 }
5748 else if (strcmp (name, "<") == 0)
5749 {
5750 cmpltr = 2;
5751 }
5752 else if (strcmp (name, "<=") == 0)
5753 {
5754 cmpltr = 3;
5755 }
5756 else if (strcasecmp (name, "nuv") == 0)
5757 {
5758 cmpltr = 4;
5759 }
5760 else if (strcasecmp (name, "*=") == 0)
5761 {
5762 cmpltr = 5;
5763 }
5764 else if (strcasecmp (name, "*<") == 0)
5765 {
5766 cmpltr = 6;
5767 }
5768 else if (strcasecmp (name, "*<=") == 0)
5769 {
5770 cmpltr = 7;
5771 }
5772 else if (strcmp (name, "tr") == 0)
5773 {
5774 cmpltr = 8;
5775 }
5776 else if (strcmp (name, "<>") == 0)
5777 {
5778 cmpltr = 9;
5779 }
5780 else if (strcmp (name, ">=") == 0)
5781 {
5782 cmpltr = 10;
5783 }
5784 else if (strcmp (name, ">") == 0)
5785 {
5786 cmpltr = 11;
5787 }
5788 else if (strcasecmp (name, "uv") == 0)
5789 {
5790 cmpltr = 12;
5791 }
5792 else if (strcasecmp (name, "*<>") == 0)
5793 {
5794 cmpltr = 13;
5795 }
5796 else if (strcasecmp (name, "*>=") == 0)
5797 {
5798 cmpltr = 14;
5799 }
5800 else if (strcasecmp (name, "*>") == 0)
5801 {
5802 cmpltr = 15;
5803 }
5804 /* If we have something like addb,n then there is no condition
5805 completer. */
5806 else if (strcasecmp (name, "n") == 0)
5807 {
5808 cmpltr = 0;
5809 nullify = 1;
5810 }
5811 else
5812 {
5813 cmpltr = -1;
5814 }
5815 **s = c;
5816 }
5817
5818 /* Reset pointers if this was really a ,n for a branch instruction. */
5819 if (nullify)
5820 *s = save_s;
5821
5822 return cmpltr;
5823}
5824
49863f82 5825#ifdef OBJ_SOM
252b5132
RH
5826/* Handle an alignment directive. Special so that we can update the
5827 alignment of the subspace if necessary. */
5828static void
5829pa_align (bytes)
5830{
5831 /* We must have a valid space and subspace. */
5832 pa_check_current_space_and_subspace ();
5833
5834 /* Let the generic gas code do most of the work. */
5835 s_align_bytes (bytes);
5836
5837 /* If bytes is a power of 2, then update the current subspace's
5838 alignment if necessary. */
5839 if (log2 (bytes) != -1)
5840 record_alignment (current_subspace->ssd_seg, log2 (bytes));
5841}
49863f82 5842#endif
252b5132
RH
5843
5844/* Handle a .BLOCK type pseudo-op. */
5845
5846static void
5847pa_block (z)
3f9b03b5 5848 int z ATTRIBUTE_UNUSED;
252b5132
RH
5849{
5850 char *p;
5851 long int temp_fill;
5852 unsigned int temp_size;
5853 unsigned int i;
5854
49863f82 5855#ifdef OBJ_SOM
252b5132
RH
5856 /* We must have a valid space and subspace. */
5857 pa_check_current_space_and_subspace ();
49863f82 5858#endif
252b5132
RH
5859
5860 temp_size = get_absolute_expression ();
5861
5862 /* Always fill with zeros, that's what the HP assembler does. */
5863 temp_fill = 0;
5864
5865 p = frag_var (rs_fill, (int) temp_size, (int) temp_size,
5866 (relax_substateT) 0, (symbolS *) 0, (offsetT) 1, NULL);
5867 memset (p, 0, temp_size);
5868
5869 /* Convert 2 bytes at a time. */
5870
5871 for (i = 0; i < temp_size; i += 2)
5872 {
5873 md_number_to_chars (p + i,
5874 (valueT) temp_fill,
5875 (int) ((temp_size - i) > 2 ? 2 : (temp_size - i)));
5876 }
5877
5878 pa_undefine_label ();
5879 demand_empty_rest_of_line ();
5880}
5881
5882/* Handle a .begin_brtab and .end_brtab pseudo-op. */
5883
5884static void
5885pa_brtab (begin)
3f9b03b5 5886 int begin ATTRIBUTE_UNUSED;
252b5132
RH
5887{
5888
5889#ifdef OBJ_SOM
5890 /* The BRTAB relocations are only availble in SOM (to denote
5891 the beginning and end of branch tables). */
5892 char *where = frag_more (0);
5893
5894 fix_new_hppa (frag_now, where - frag_now->fr_literal, 0,
5895 NULL, (offsetT) 0, NULL,
5896 0, begin ? R_HPPA_BEGIN_BRTAB : R_HPPA_END_BRTAB,
5897 e_fsel, 0, 0, NULL);
5898#endif
5899
5900 demand_empty_rest_of_line ();
5901}
5902
5903/* Handle a .begin_try and .end_try pseudo-op. */
5904
5905static void
5906pa_try (begin)
3f9b03b5 5907 int begin ATTRIBUTE_UNUSED;
252b5132
RH
5908{
5909#ifdef OBJ_SOM
5910 expressionS exp;
5911 char *where = frag_more (0);
5912
5913 if (! begin)
5914 expression (&exp);
5915
5916 /* The TRY relocations are only availble in SOM (to denote
5917 the beginning and end of exception handling regions). */
5918
5919 fix_new_hppa (frag_now, where - frag_now->fr_literal, 0,
5920 NULL, (offsetT) 0, begin ? NULL : &exp,
5921 0, begin ? R_HPPA_BEGIN_TRY : R_HPPA_END_TRY,
5922 e_fsel, 0, 0, NULL);
5923#endif
5924
5925 demand_empty_rest_of_line ();
5926}
5927
5928/* Handle a .CALL pseudo-op. This involves storing away information
5929 about where arguments are to be found so the linker can detect
5930 (and correct) argument location mismatches between caller and callee. */
5931
5932static void
5933pa_call (unused)
3f9b03b5 5934 int unused ATTRIBUTE_UNUSED;
252b5132 5935{
49863f82 5936#ifdef OBJ_SOM
252b5132
RH
5937 /* We must have a valid space and subspace. */
5938 pa_check_current_space_and_subspace ();
49863f82 5939#endif
252b5132
RH
5940
5941 pa_call_args (&last_call_desc);
5942 demand_empty_rest_of_line ();
5943}
5944
5945/* Do the dirty work of building a call descriptor which describes
5946 where the caller placed arguments to a function call. */
5947
5948static void
5949pa_call_args (call_desc)
5950 struct call_desc *call_desc;
5951{
5952 char *name, c, *p;
5953 unsigned int temp, arg_reloc;
5954
5955 while (!is_end_of_statement ())
5956 {
5957 name = input_line_pointer;
5958 c = get_symbol_end ();
5959 /* Process a source argument. */
5960 if ((strncasecmp (name, "argw", 4) == 0))
5961 {
5962 temp = atoi (name + 4);
5963 p = input_line_pointer;
5964 *p = c;
5965 input_line_pointer++;
5966 name = input_line_pointer;
5967 c = get_symbol_end ();
5968 arg_reloc = pa_build_arg_reloc (name);
5969 call_desc->arg_reloc |= pa_align_arg_reloc (temp, arg_reloc);
5970 }
5971 /* Process a return value. */
5972 else if ((strncasecmp (name, "rtnval", 6) == 0))
5973 {
5974 p = input_line_pointer;
5975 *p = c;
5976 input_line_pointer++;
5977 name = input_line_pointer;
5978 c = get_symbol_end ();
5979 arg_reloc = pa_build_arg_reloc (name);
5980 call_desc->arg_reloc |= (arg_reloc & 0x3);
5981 }
5982 else
5983 {
5984 as_bad (_("Invalid .CALL argument: %s"), name);
5985 }
5986 p = input_line_pointer;
5987 *p = c;
5988 if (!is_end_of_statement ())
5989 input_line_pointer++;
5990 }
5991}
5992
5993/* Return TRUE if FRAG1 and FRAG2 are the same. */
5994
5995static int
5996is_same_frag (frag1, frag2)
5997 fragS *frag1;
5998 fragS *frag2;
5999{
6000
6001 if (frag1 == NULL)
6002 return (FALSE);
6003 else if (frag2 == NULL)
6004 return (FALSE);
6005 else if (frag1 == frag2)
6006 return (TRUE);
6007 else if (frag2->fr_type == rs_fill && frag2->fr_fix == 0)
6008 return (is_same_frag (frag1, frag2->fr_next));
6009 else
6010 return (FALSE);
6011}
6012
6013#ifdef OBJ_ELF
6014/* Build an entry in the UNWIND subspace from the given function
6015 attributes in CALL_INFO. This is not needed for SOM as using
6016 R_ENTRY and R_EXIT relocations allow the linker to handle building
6017 of the unwind spaces. */
6018
6019static void
6020pa_build_unwind_subspace (call_info)
6021 struct call_info *call_info;
6022{
6023 char *unwind;
6024 asection *seg, *save_seg;
3f9b03b5
AM
6025 subsegT save_subseg;
6026 unsigned int i;
6027 int reloc;
252b5132
RH
6028 char c, *p;
6029
f1a1312b 6030 if (now_seg != text_section)
7acbfc6b
JL
6031 return;
6032
9100134c
JL
6033 if (bfd_get_arch_info (stdoutput)->bits_per_address == 32)
6034 reloc = R_PARISC_DIR32;
46031ca9 6035 else
9100134c 6036 reloc = R_PARISC_SEGREL32;
d53d2751 6037
c97305a1
JL
6038 save_seg = now_seg;
6039 save_subseg = now_subseg;
252b5132
RH
6040 /* Get into the right seg/subseg. This may involve creating
6041 the seg the first time through. Make sure to have the
6042 old seg/subseg so that we can reset things when we are done. */
252b5132
RH
6043 seg = bfd_get_section_by_name (stdoutput, UNWIND_SECTION_NAME);
6044 if (seg == ASEC_NULL)
6045 {
c97305a1 6046 seg = subseg_new (UNWIND_SECTION_NAME, 0);
252b5132
RH
6047 bfd_set_section_flags (stdoutput, seg,
6048 SEC_READONLY | SEC_HAS_CONTENTS
b100be66
JL
6049 | SEC_LOAD | SEC_RELOC | SEC_ALLOC | SEC_DATA);
6050 bfd_set_section_alignment (stdoutput, seg, 2);
252b5132
RH
6051 }
6052
46031ca9 6053 subseg_set (seg, 0);
252b5132 6054
252b5132
RH
6055 /* Get some space to hold relocation information for the unwind
6056 descriptor. */
6057 p = frag_more (4);
6058 md_number_to_chars (p, 0, 4);
6059
6060 /* Relocation info. for start offset of the function. */
6061 fix_new_hppa (frag_now, p - frag_now->fr_literal, 4,
6062 call_info->start_symbol, (offsetT) 0,
46031ca9
JL
6063 (expressionS *) NULL, 0, reloc,
6064 e_fsel, 32, 0, NULL);
252b5132
RH
6065
6066 p = frag_more (4);
6067 md_number_to_chars (p, 0, 4);
6068
6069 /* Relocation info. for end offset of the function.
6070
6071 Because we allow reductions of 32bit relocations for ELF, this will be
6072 reduced to section_sym + offset which avoids putting the temporary
6073 symbol into the symbol table. It (should) end up giving the same
6074 value as call_info->start_symbol + function size once the linker is
6075 finished with its work. */
6076
6077 fix_new_hppa (frag_now, p - frag_now->fr_literal, 4,
6078 call_info->end_symbol, (offsetT) 0,
46031ca9
JL
6079 (expressionS *) NULL, 0, reloc,
6080 e_fsel, 32, 0, NULL);
252b5132 6081
a28a3ccf 6082 /* Dump it. */
252b5132
RH
6083 unwind = (char *) &call_info->ci_unwind;
6084 for (i = 8; i < sizeof (struct unwind_table); i++)
6085 {
6086 c = *(unwind + i);
6087 {
6088 FRAG_APPEND_1_CHAR (c);
6089 }
6090 }
6091
6092 /* Return back to the original segment/subsegment. */
6093 subseg_set (save_seg, save_subseg);
6094}
6095#endif
6096
6097/* Process a .CALLINFO pseudo-op. This information is used later
6098 to build unwind descriptors and maybe one day to support
6099 .ENTER and .LEAVE. */
6100
6101static void
6102pa_callinfo (unused)
3f9b03b5 6103 int unused ATTRIBUTE_UNUSED;
252b5132
RH
6104{
6105 char *name, c, *p;
6106 int temp;
6107
49863f82 6108#ifdef OBJ_SOM
252b5132
RH
6109 /* We must have a valid space and subspace. */
6110 pa_check_current_space_and_subspace ();
49863f82 6111#endif
252b5132
RH
6112
6113 /* .CALLINFO must appear within a procedure definition. */
6114 if (!within_procedure)
6115 as_bad (_(".callinfo is not within a procedure definition"));
6116
6117 /* Mark the fact that we found the .CALLINFO for the
6118 current procedure. */
6119 callinfo_found = TRUE;
6120
6121 /* Iterate over the .CALLINFO arguments. */
6122 while (!is_end_of_statement ())
6123 {
6124 name = input_line_pointer;
6125 c = get_symbol_end ();
6126 /* Frame size specification. */
6127 if ((strncasecmp (name, "frame", 5) == 0))
6128 {
6129 p = input_line_pointer;
6130 *p = c;
6131 input_line_pointer++;
6132 temp = get_absolute_expression ();
6133 if ((temp & 0x3) != 0)
6134 {
6135 as_bad (_("FRAME parameter must be a multiple of 8: %d\n"), temp);
6136 temp = 0;
6137 }
6138
6139 /* callinfo is in bytes and unwind_desc is in 8 byte units. */
6140 last_call_info->ci_unwind.descriptor.frame_size = temp / 8;
6141
6142 }
6143 /* Entry register (GR, GR and SR) specifications. */
6144 else if ((strncasecmp (name, "entry_gr", 8) == 0))
6145 {
6146 p = input_line_pointer;
6147 *p = c;
6148 input_line_pointer++;
6149 temp = get_absolute_expression ();
6150 /* The HP assembler accepts 19 as the high bound for ENTRY_GR
6151 even though %r19 is caller saved. I think this is a bug in
6152 the HP assembler, and we are not going to emulate it. */
6153 if (temp < 3 || temp > 18)
6154 as_bad (_("Value for ENTRY_GR must be in the range 3..18\n"));
6155 last_call_info->ci_unwind.descriptor.entry_gr = temp - 2;
6156 }
6157 else if ((strncasecmp (name, "entry_fr", 8) == 0))
6158 {
6159 p = input_line_pointer;
6160 *p = c;
6161 input_line_pointer++;
6162 temp = get_absolute_expression ();
6163 /* Similarly the HP assembler takes 31 as the high bound even
6164 though %fr21 is the last callee saved floating point register. */
6165 if (temp < 12 || temp > 21)
6166 as_bad (_("Value for ENTRY_FR must be in the range 12..21\n"));
6167 last_call_info->ci_unwind.descriptor.entry_fr = temp - 11;
6168 }
6169 else if ((strncasecmp (name, "entry_sr", 8) == 0))
6170 {
6171 p = input_line_pointer;
6172 *p = c;
6173 input_line_pointer++;
6174 temp = get_absolute_expression ();
6175 if (temp != 3)
6176 as_bad (_("Value for ENTRY_SR must be 3\n"));
6177 }
6178 /* Note whether or not this function performs any calls. */
6179 else if ((strncasecmp (name, "calls", 5) == 0) ||
6180 (strncasecmp (name, "caller", 6) == 0))
6181 {
6182 p = input_line_pointer;
6183 *p = c;
6184 }
6185 else if ((strncasecmp (name, "no_calls", 8) == 0))
6186 {
6187 p = input_line_pointer;
6188 *p = c;
6189 }
6190 /* Should RP be saved into the stack. */
6191 else if ((strncasecmp (name, "save_rp", 7) == 0))
6192 {
6193 p = input_line_pointer;
6194 *p = c;
6195 last_call_info->ci_unwind.descriptor.save_rp = 1;
6196 }
6197 /* Likewise for SP. */
6198 else if ((strncasecmp (name, "save_sp", 7) == 0))
6199 {
6200 p = input_line_pointer;
6201 *p = c;
6202 last_call_info->ci_unwind.descriptor.save_sp = 1;
6203 }
6204 /* Is this an unwindable procedure. If so mark it so
6205 in the unwind descriptor. */
6206 else if ((strncasecmp (name, "no_unwind", 9) == 0))
6207 {
6208 p = input_line_pointer;
6209 *p = c;
6210 last_call_info->ci_unwind.descriptor.cannot_unwind = 1;
6211 }
6212 /* Is this an interrupt routine. If so mark it in the
6213 unwind descriptor. */
6214 else if ((strncasecmp (name, "hpux_int", 7) == 0))
6215 {
6216 p = input_line_pointer;
6217 *p = c;
6218 last_call_info->ci_unwind.descriptor.hpux_interrupt_marker = 1;
6219 }
6220 /* Is this a millicode routine. "millicode" isn't in my
6221 assembler manual, but my copy is old. The HP assembler
6222 accepts it, and there's a place in the unwind descriptor
6223 to drop the information, so we'll accept it too. */
6224 else if ((strncasecmp (name, "millicode", 9) == 0))
6225 {
6226 p = input_line_pointer;
6227 *p = c;
6228 last_call_info->ci_unwind.descriptor.millicode = 1;
6229 }
6230 else
6231 {
6232 as_bad (_("Invalid .CALLINFO argument: %s"), name);
6233 *input_line_pointer = c;
6234 }
6235 if (!is_end_of_statement ())
6236 input_line_pointer++;
6237 }
6238
6239 demand_empty_rest_of_line ();
6240}
6241
ad1079af
AM
6242#if !(defined (OBJ_ELF) && defined (TE_LINUX))
6243/* Switch to the text space. Like s_text, but delete our
6244 label when finished. */
252b5132 6245static void
ad1079af 6246pa_text (unused)
3f9b03b5 6247 int unused ATTRIBUTE_UNUSED;
252b5132 6248{
49863f82 6249#ifdef OBJ_SOM
252b5132
RH
6250 current_space = is_defined_space ("$TEXT$");
6251 current_subspace
6252 = pa_subsegment_to_subspace (current_space->sd_seg, 0);
49863f82 6253#endif
ad1079af 6254
252b5132
RH
6255 s_text (0);
6256 pa_undefine_label ();
6257}
6258
ad1079af
AM
6259/* Switch to the data space. As usual delete our label. */
6260static void
6261pa_data (unused)
6262 int unused ATTRIBUTE_UNUSED;
6263{
6264#ifdef OBJ_SOM
6265 current_space = is_defined_space ("$PRIVATE$");
6266 current_subspace
6267 = pa_subsegment_to_subspace (current_space->sd_seg, 0);
6268#endif
6269 s_data (0);
6270 pa_undefine_label ();
6271}
6272
252b5132
RH
6273/* This is different than the standard GAS s_comm(). On HP9000/800 machines,
6274 the .comm pseudo-op has the following symtax:
6275
6276 <label> .comm <length>
6277
6278 where <label> is optional and is a symbol whose address will be the start of
6279 a block of memory <length> bytes long. <length> must be an absolute
6280 expression. <length> bytes will be allocated in the current space
6281 and subspace.
6282
6283 Also note the label may not even be on the same line as the .comm.
6284
6285 This difference in syntax means the colon function will be called
6286 on the symbol before we arrive in pa_comm. colon will set a number
6287 of attributes of the symbol that need to be fixed here. In particular
6288 the value, section pointer, fragment pointer, flags, etc. What
6289 a pain.
6290
6291 This also makes error detection all but impossible. */
6292
6293static void
6294pa_comm (unused)
3f9b03b5 6295 int unused ATTRIBUTE_UNUSED;
252b5132
RH
6296{
6297 unsigned int size;
6298 symbolS *symbol;
6299 label_symbol_struct *label_symbol = pa_get_label ();
6300
6301 if (label_symbol)
6302 symbol = label_symbol->lss_label;
6303 else
6304 symbol = NULL;
6305
6306 SKIP_WHITESPACE ();
6307 size = get_absolute_expression ();
6308
6309 if (symbol)
6310 {
6311 S_SET_VALUE (symbol, size);
6312 S_SET_SEGMENT (symbol, bfd_und_section_ptr);
6313 S_SET_EXTERNAL (symbol);
6314
6315 /* colon() has already set the frag to the current location in the
6316 current subspace; we need to reset the fragment to the zero address
6317 fragment. We also need to reset the segment pointer. */
a0f75b47 6318 symbol_set_frag (symbol, &zero_address_frag);
252b5132
RH
6319 }
6320 demand_empty_rest_of_line ();
6321}
ad1079af 6322#endif /* !(defined (OBJ_ELF) && defined (TE_LINUX)) */
252b5132
RH
6323
6324/* Process a .END pseudo-op. */
6325
6326static void
6327pa_end (unused)
3f9b03b5 6328 int unused ATTRIBUTE_UNUSED;
252b5132
RH
6329{
6330 demand_empty_rest_of_line ();
6331}
6332
6333/* Process a .ENTER pseudo-op. This is not supported. */
6334static void
6335pa_enter (unused)
3f9b03b5 6336 int unused ATTRIBUTE_UNUSED;
252b5132 6337{
49863f82 6338#ifdef OBJ_SOM
252b5132
RH
6339 /* We must have a valid space and subspace. */
6340 pa_check_current_space_and_subspace ();
49863f82 6341#endif
252b5132
RH
6342
6343 as_bad (_("The .ENTER pseudo-op is not supported"));
6344 demand_empty_rest_of_line ();
6345}
6346
6347/* Process a .ENTRY pseudo-op. .ENTRY marks the beginning of the
6348 procesure. */
6349static void
6350pa_entry (unused)
3f9b03b5 6351 int unused ATTRIBUTE_UNUSED;
252b5132 6352{
49863f82 6353#ifdef OBJ_SOM
252b5132
RH
6354 /* We must have a valid space and subspace. */
6355 pa_check_current_space_and_subspace ();
49863f82 6356#endif
252b5132
RH
6357
6358 if (!within_procedure)
6359 as_bad (_("Misplaced .entry. Ignored."));
6360 else
6361 {
6362 if (!callinfo_found)
6363 as_bad (_("Missing .callinfo."));
6364 }
6365 demand_empty_rest_of_line ();
6366 within_entry_exit = TRUE;
6367
6368#ifdef OBJ_SOM
6369 /* SOM defers building of unwind descriptors until the link phase.
6370 The assembler is responsible for creating an R_ENTRY relocation
6371 to mark the beginning of a region and hold the unwind bits, and
6372 for creating an R_EXIT relocation to mark the end of the region.
6373
6374 FIXME. ELF should be using the same conventions! The problem
6375 is an unwind requires too much relocation space. Hmmm. Maybe
6376 if we split the unwind bits up between the relocations which
6377 denote the entry and exit points. */
6378 if (last_call_info->start_symbol != NULL)
6379 {
6380 char *where = frag_more (0);
6381
6382 fix_new_hppa (frag_now, where - frag_now->fr_literal, 0,
6383 NULL, (offsetT) 0, NULL,
6384 0, R_HPPA_ENTRY, e_fsel, 0, 0,
6385 (int *) &last_call_info->ci_unwind.descriptor);
6386 }
6387#endif
6388}
6389
ecacdc7a
AM
6390/* Silly nonsense for pa_equ. The only half-sensible use for this is
6391 being able to subtract two register symbols that specify a range of
6392 registers, to get the size of the range. */
6393static int fudge_reg_expressions;
6394
6395int
6396hppa_force_reg_syms_absolute (resultP, op, rightP)
6397 expressionS *resultP;
6398 operatorT op ATTRIBUTE_UNUSED;
6399 expressionS *rightP;
6400{
6401 if (fudge_reg_expressions
6402 && rightP->X_op == O_register
6403 && resultP->X_op == O_register)
6404 {
6405 rightP->X_op = O_constant;
6406 resultP->X_op = O_constant;
6407 }
6408 return 0; /* Continue normal expr handling. */
6409}
6410
252b5132
RH
6411/* Handle a .EQU pseudo-op. */
6412
6413static void
6414pa_equ (reg)
6415 int reg;
6416{
6417 label_symbol_struct *label_symbol = pa_get_label ();
6418 symbolS *symbol;
6419
6420 if (label_symbol)
6421 {
6422 symbol = label_symbol->lss_label;
6423 if (reg)
ecacdc7a
AM
6424 {
6425 strict = 1;
6426 if (!pa_parse_number (&input_line_pointer, 0))
6427 as_bad (_(".REG expression must be a register"));
6428 S_SET_VALUE (symbol, pa_number);
6429 S_SET_SEGMENT (symbol, reg_section);
6430 }
252b5132 6431 else
ecacdc7a
AM
6432 {
6433 expressionS exp;
6434 segT seg;
6435
6436 fudge_reg_expressions = 1;
6437 seg = expression (&exp);
6438 fudge_reg_expressions = 0;
6439 if (exp.X_op != O_constant
6440 && exp.X_op != O_register)
6441 {
6442 if (exp.X_op != O_absent)
6443 as_bad (_("bad or irreducible absolute expression; zero assumed"));
6444 exp.X_add_number = 0;
6445 seg = absolute_section;
6446 }
6447 S_SET_VALUE (symbol, (unsigned int) exp.X_add_number);
6448 S_SET_SEGMENT (symbol, seg);
6449 }
252b5132
RH
6450 }
6451 else
6452 {
6453 if (reg)
6454 as_bad (_(".REG must use a label"));
6455 else
6456 as_bad (_(".EQU must use a label"));
6457 }
6458
6459 pa_undefine_label ();
6460 demand_empty_rest_of_line ();
6461}
6462
6463/* Helper function. Does processing for the end of a function. This
6464 usually involves creating some relocations or building special
6465 symbols to mark the end of the function. */
6466
6467static void
6468process_exit ()
6469{
6470 char *where;
6471
6472 where = frag_more (0);
6473
6474#ifdef OBJ_ELF
6475 /* Mark the end of the function, stuff away the location of the frag
6476 for the end of the function, and finally call pa_build_unwind_subspace
6477 to add an entry in the unwind table. */
6478 hppa_elf_mark_end_of_function ();
6479 pa_build_unwind_subspace (last_call_info);
6480#else
6481 /* SOM defers building of unwind descriptors until the link phase.
6482 The assembler is responsible for creating an R_ENTRY relocation
6483 to mark the beginning of a region and hold the unwind bits, and
6484 for creating an R_EXIT relocation to mark the end of the region.
6485
6486 FIXME. ELF should be using the same conventions! The problem
6487 is an unwind requires too much relocation space. Hmmm. Maybe
6488 if we split the unwind bits up between the relocations which
6489 denote the entry and exit points. */
6490 fix_new_hppa (frag_now, where - frag_now->fr_literal, 0,
6491 NULL, (offsetT) 0,
6492 NULL, 0, R_HPPA_EXIT, e_fsel, 0, 0,
6493 (int *) &last_call_info->ci_unwind.descriptor + 1);
6494#endif
6495}
6496
6497/* Process a .EXIT pseudo-op. */
6498
6499static void
6500pa_exit (unused)
3f9b03b5 6501 int unused ATTRIBUTE_UNUSED;
252b5132 6502{
49863f82 6503#ifdef OBJ_SOM
252b5132
RH
6504 /* We must have a valid space and subspace. */
6505 pa_check_current_space_and_subspace ();
49863f82 6506#endif
252b5132
RH
6507
6508 if (!within_procedure)
6509 as_bad (_(".EXIT must appear within a procedure"));
6510 else
6511 {
6512 if (!callinfo_found)
6513 as_bad (_("Missing .callinfo"));
6514 else
6515 {
6516 if (!within_entry_exit)
6517 as_bad (_("No .ENTRY for this .EXIT"));
6518 else
6519 {
6520 within_entry_exit = FALSE;
6521 process_exit ();
6522 }
6523 }
6524 }
6525 demand_empty_rest_of_line ();
6526}
6527
6528/* Process a .EXPORT directive. This makes functions external
6529 and provides information such as argument relocation entries
6530 to callers. */
6531
6532static void
6533pa_export (unused)
3f9b03b5 6534 int unused ATTRIBUTE_UNUSED;
252b5132
RH
6535{
6536 char *name, c, *p;
6537 symbolS *symbol;
6538
6539 name = input_line_pointer;
6540 c = get_symbol_end ();
6541 /* Make sure the given symbol exists. */
6542 if ((symbol = symbol_find_or_make (name)) == NULL)
6543 {
6544 as_bad (_("Cannot define export symbol: %s\n"), name);
6545 p = input_line_pointer;
6546 *p = c;
6547 input_line_pointer++;
6548 }
6549 else
6550 {
20348649 6551 /* OK. Set the external bits and process argument relocations.
a28a3ccf 6552 For the HP, weak and global are not mutually exclusive.
20348649
JL
6553 S_SET_EXTERNAL will not set BSF_GLOBAL if WEAK is set.
6554 Call S_SET_EXTERNAL to get the other processing. Manually
6555 set BSF_GLOBAL when we get back. */
252b5132 6556 S_SET_EXTERNAL (symbol);
20348649 6557 symbol_get_bfdsym (symbol)->flags |= BSF_GLOBAL;
252b5132
RH
6558 p = input_line_pointer;
6559 *p = c;
6560 if (!is_end_of_statement ())
6561 {
6562 input_line_pointer++;
6563 pa_type_args (symbol, 1);
6564 }
6565 }
6566
6567 demand_empty_rest_of_line ();
6568}
6569
6570/* Helper function to process arguments to a .EXPORT pseudo-op. */
6571
6572static void
6573pa_type_args (symbolP, is_export)
6574 symbolS *symbolP;
6575 int is_export;
6576{
6577 char *name, c, *p;
6578 unsigned int temp, arg_reloc;
6579 pa_symbol_type type = SYMBOL_TYPE_UNKNOWN;
904a31bf 6580 asymbol *bfdsym = symbol_get_bfdsym (symbolP);
252b5132
RH
6581
6582 if (strncasecmp (input_line_pointer, "absolute", 8) == 0)
6583
6584 {
6585 input_line_pointer += 8;
904a31bf 6586 bfdsym->flags &= ~BSF_FUNCTION;
252b5132
RH
6587 S_SET_SEGMENT (symbolP, bfd_abs_section_ptr);
6588 type = SYMBOL_TYPE_ABSOLUTE;
6589 }
6590 else if (strncasecmp (input_line_pointer, "code", 4) == 0)
6591 {
6592 input_line_pointer += 4;
6593 /* IMPORTing/EXPORTing CODE types for functions is meaningless for SOM,
6594 instead one should be IMPORTing/EXPORTing ENTRY types.
6595
6596 Complain if one tries to EXPORT a CODE type since that's never
6597 done. Both GCC and HP C still try to IMPORT CODE types, so
6598 silently fix them to be ENTRY types. */
a0f75b47 6599 if (S_IS_FUNCTION (symbolP))
252b5132
RH
6600 {
6601 if (is_export)
a0f75b47
ILT
6602 as_tsktsk (_("Using ENTRY rather than CODE in export directive for %s"),
6603 S_GET_NAME (symbolP));
252b5132 6604
904a31bf 6605 bfdsym->flags |= BSF_FUNCTION;
252b5132
RH
6606 type = SYMBOL_TYPE_ENTRY;
6607 }
6608 else
6609 {
904a31bf 6610 bfdsym->flags &= ~BSF_FUNCTION;
252b5132
RH
6611 type = SYMBOL_TYPE_CODE;
6612 }
6613 }
6614 else if (strncasecmp (input_line_pointer, "data", 4) == 0)
6615 {
6616 input_line_pointer += 4;
904a31bf
AM
6617 bfdsym->flags &= ~BSF_FUNCTION;
6618 bfdsym->flags |= BSF_OBJECT;
252b5132
RH
6619 type = SYMBOL_TYPE_DATA;
6620 }
6621 else if ((strncasecmp (input_line_pointer, "entry", 5) == 0))
6622 {
6623 input_line_pointer += 5;
904a31bf 6624 bfdsym->flags |= BSF_FUNCTION;
252b5132
RH
6625 type = SYMBOL_TYPE_ENTRY;
6626 }
6627 else if (strncasecmp (input_line_pointer, "millicode", 9) == 0)
6628 {
6629 input_line_pointer += 9;
904a31bf
AM
6630 bfdsym->flags |= BSF_FUNCTION;
6631#ifdef OBJ_ELF
6632 {
6633 elf_symbol_type *elfsym = (elf_symbol_type *) bfdsym;
6634 elfsym->internal_elf_sym.st_info =
6635 ELF_ST_INFO (ELF_ST_BIND (elfsym->internal_elf_sym.st_info),
6636 STT_PARISC_MILLI);
6637 }
6638#endif
252b5132
RH
6639 type = SYMBOL_TYPE_MILLICODE;
6640 }
6641 else if (strncasecmp (input_line_pointer, "plabel", 6) == 0)
6642 {
6643 input_line_pointer += 6;
904a31bf 6644 bfdsym->flags &= ~BSF_FUNCTION;
252b5132
RH
6645 type = SYMBOL_TYPE_PLABEL;
6646 }
6647 else if (strncasecmp (input_line_pointer, "pri_prog", 8) == 0)
6648 {
6649 input_line_pointer += 8;
904a31bf 6650 bfdsym->flags |= BSF_FUNCTION;
252b5132
RH
6651 type = SYMBOL_TYPE_PRI_PROG;
6652 }
6653 else if (strncasecmp (input_line_pointer, "sec_prog", 8) == 0)
6654 {
6655 input_line_pointer += 8;
904a31bf 6656 bfdsym->flags |= BSF_FUNCTION;
252b5132
RH
6657 type = SYMBOL_TYPE_SEC_PROG;
6658 }
6659
6660 /* SOM requires much more information about symbol types
6661 than BFD understands. This is how we get this information
6662 to the SOM BFD backend. */
6663#ifdef obj_set_symbol_type
904a31bf 6664 obj_set_symbol_type (bfdsym, (int) type);
252b5132
RH
6665#endif
6666
6667 /* Now that the type of the exported symbol has been handled,
6668 handle any argument relocation information. */
6669 while (!is_end_of_statement ())
6670 {
6671 if (*input_line_pointer == ',')
6672 input_line_pointer++;
6673 name = input_line_pointer;
6674 c = get_symbol_end ();
6675 /* Argument sources. */
6676 if ((strncasecmp (name, "argw", 4) == 0))
6677 {
6678 p = input_line_pointer;
6679 *p = c;
6680 input_line_pointer++;
6681 temp = atoi (name + 4);
6682 name = input_line_pointer;
6683 c = get_symbol_end ();
6684 arg_reloc = pa_align_arg_reloc (temp, pa_build_arg_reloc (name));
25a8b250 6685#if defined (OBJ_SOM) || defined (ELF_ARG_RELOC)
ad1079af 6686 symbol_arg_reloc_info (symbolP) |= arg_reloc;
49863f82 6687#endif
252b5132
RH
6688 *input_line_pointer = c;
6689 }
6690 /* The return value. */
6691 else if ((strncasecmp (name, "rtnval", 6)) == 0)
6692 {
6693 p = input_line_pointer;
6694 *p = c;
6695 input_line_pointer++;
6696 name = input_line_pointer;
6697 c = get_symbol_end ();
6698 arg_reloc = pa_build_arg_reloc (name);
25a8b250 6699#if defined (OBJ_SOM) || defined (ELF_ARG_RELOC)
ad1079af 6700 symbol_arg_reloc_info (symbolP) |= arg_reloc;
49863f82 6701#endif
252b5132
RH
6702 *input_line_pointer = c;
6703 }
6704 /* Privelege level. */
6705 else if ((strncasecmp (name, "priv_lev", 8)) == 0)
6706 {
6707 p = input_line_pointer;
6708 *p = c;
6709 input_line_pointer++;
6710 temp = atoi (input_line_pointer);
49863f82 6711#ifdef OBJ_SOM
904a31bf 6712 ((obj_symbol_type *) bfdsym)->tc_data.ap.hppa_priv_level = temp;
49863f82 6713#endif
252b5132
RH
6714 c = get_symbol_end ();
6715 *input_line_pointer = c;
6716 }
6717 else
6718 {
6719 as_bad (_("Undefined .EXPORT/.IMPORT argument (ignored): %s"), name);
6720 p = input_line_pointer;
6721 *p = c;
6722 }
6723 if (!is_end_of_statement ())
6724 input_line_pointer++;
6725 }
6726}
6727
6728/* Handle an .IMPORT pseudo-op. Any symbol referenced in a given
6729 assembly file must either be defined in the assembly file, or
6730 explicitly IMPORTED from another. */
6731
6732static void
6733pa_import (unused)
3f9b03b5 6734 int unused ATTRIBUTE_UNUSED;
252b5132
RH
6735{
6736 char *name, c, *p;
6737 symbolS *symbol;
6738
6739 name = input_line_pointer;
6740 c = get_symbol_end ();
6741
6742 symbol = symbol_find (name);
6743 /* Ugh. We might be importing a symbol defined earlier in the file,
6744 in which case all the code below will really screw things up
6745 (set the wrong segment, symbol flags & type, etc). */
6746 if (symbol == NULL || !S_IS_DEFINED (symbol))
6747 {
6748 symbol = symbol_find_or_make (name);
6749 p = input_line_pointer;
6750 *p = c;
6751
6752 if (!is_end_of_statement ())
6753 {
6754 input_line_pointer++;
6755 pa_type_args (symbol, 0);
6756 }
6757 else
6758 {
6759 /* Sigh. To be compatable with the HP assembler and to help
6760 poorly written assembly code, we assign a type based on
6761 the the current segment. Note only BSF_FUNCTION really
6762 matters, we do not need to set the full SYMBOL_TYPE_* info. */
6763 if (now_seg == text_section)
a0f75b47 6764 symbol_get_bfdsym (symbol)->flags |= BSF_FUNCTION;
252b5132
RH
6765
6766 /* If the section is undefined, then the symbol is undefined
6767 Since this is an import, leave the section undefined. */
6768 S_SET_SEGMENT (symbol, bfd_und_section_ptr);
6769 }
6770 }
6771 else
6772 {
6773 /* The symbol was already defined. Just eat everything up to
6774 the end of the current statement. */
6775 while (!is_end_of_statement ())
6776 input_line_pointer++;
6777 }
6778
6779 demand_empty_rest_of_line ();
6780}
6781
6782/* Handle a .LABEL pseudo-op. */
6783
6784static void
6785pa_label (unused)
3f9b03b5 6786 int unused ATTRIBUTE_UNUSED;
252b5132
RH
6787{
6788 char *name, c, *p;
6789
6790 name = input_line_pointer;
6791 c = get_symbol_end ();
6792
6793 if (strlen (name) > 0)
6794 {
6795 colon (name);
6796 p = input_line_pointer;
6797 *p = c;
6798 }
6799 else
6800 {
6801 as_warn (_("Missing label name on .LABEL"));
6802 }
6803
6804 if (!is_end_of_statement ())
6805 {
6806 as_warn (_("extra .LABEL arguments ignored."));
6807 ignore_rest_of_line ();
6808 }
6809 demand_empty_rest_of_line ();
6810}
6811
6812/* Handle a .LEAVE pseudo-op. This is not supported yet. */
6813
6814static void
6815pa_leave (unused)
3f9b03b5 6816 int unused ATTRIBUTE_UNUSED;
252b5132 6817{
49863f82 6818#ifdef OBJ_SOM
252b5132
RH
6819 /* We must have a valid space and subspace. */
6820 pa_check_current_space_and_subspace ();
49863f82 6821#endif
252b5132
RH
6822
6823 as_bad (_("The .LEAVE pseudo-op is not supported"));
6824 demand_empty_rest_of_line ();
6825}
6826
6827/* Handle a .LEVEL pseudo-op. */
6828
6829static void
6830pa_level (unused)
3f9b03b5 6831 int unused ATTRIBUTE_UNUSED;
252b5132
RH
6832{
6833 char *level;
6834
6835 level = input_line_pointer;
6836 if (strncmp (level, "1.0", 3) == 0)
6837 {
6838 input_line_pointer += 3;
6839 if (!bfd_set_arch_mach (stdoutput, bfd_arch_hppa, 10))
6840 as_warn (_("could not set architecture and machine"));
6841 }
6842 else if (strncmp (level, "1.1", 3) == 0)
6843 {
6844 input_line_pointer += 3;
6845 if (!bfd_set_arch_mach (stdoutput, bfd_arch_hppa, 11))
6846 as_warn (_("could not set architecture and machine"));
6847 }
46031ca9
JL
6848 else if (strncmp (level, "2.0w", 4) == 0)
6849 {
6850 input_line_pointer += 4;
6851 if (!bfd_set_arch_mach (stdoutput, bfd_arch_hppa, 25))
6852 as_warn (_("could not set architecture and machine"));
6853 }
252b5132
RH
6854 else if (strncmp (level, "2.0", 3) == 0)
6855 {
6856 input_line_pointer += 3;
6857 if (!bfd_set_arch_mach (stdoutput, bfd_arch_hppa, 20))
6858 as_warn (_("could not set architecture and machine"));
6859 }
6860 else
6861 {
6862 as_bad (_("Unrecognized .LEVEL argument\n"));
6863 ignore_rest_of_line ();
6864 }
6865 demand_empty_rest_of_line ();
6866}
6867
6868/* Handle a .ORIGIN pseudo-op. */
6869
6870static void
6871pa_origin (unused)
3f9b03b5 6872 int unused ATTRIBUTE_UNUSED;
252b5132 6873{
49863f82 6874#ifdef OBJ_SOM
252b5132
RH
6875 /* We must have a valid space and subspace. */
6876 pa_check_current_space_and_subspace ();
49863f82 6877#endif
252b5132
RH
6878
6879 s_org (0);
6880 pa_undefine_label ();
6881}
6882
6883/* Handle a .PARAM pseudo-op. This is much like a .EXPORT, except it
6884 is for static functions. FIXME. Should share more code with .EXPORT. */
6885
6886static void
6887pa_param (unused)
3f9b03b5 6888 int unused ATTRIBUTE_UNUSED;
252b5132
RH
6889{
6890 char *name, c, *p;
6891 symbolS *symbol;
6892
6893 name = input_line_pointer;
6894 c = get_symbol_end ();
6895
6896 if ((symbol = symbol_find_or_make (name)) == NULL)
6897 {
6898 as_bad (_("Cannot define static symbol: %s\n"), name);
6899 p = input_line_pointer;
6900 *p = c;
6901 input_line_pointer++;
6902 }
6903 else
6904 {
6905 S_CLEAR_EXTERNAL (symbol);
6906 p = input_line_pointer;
6907 *p = c;
6908 if (!is_end_of_statement ())
6909 {
6910 input_line_pointer++;
6911 pa_type_args (symbol, 0);
6912 }
6913 }
6914
6915 demand_empty_rest_of_line ();
6916}
6917
6918/* Handle a .PROC pseudo-op. It is used to mark the beginning
ad1079af 6919 of a procedure from a syntactical point of view. */
252b5132
RH
6920
6921static void
6922pa_proc (unused)
3f9b03b5 6923 int unused ATTRIBUTE_UNUSED;
252b5132
RH
6924{
6925 struct call_info *call_info;
6926
49863f82 6927#ifdef OBJ_SOM
252b5132
RH
6928 /* We must have a valid space and subspace. */
6929 pa_check_current_space_and_subspace ();
49863f82 6930#endif
252b5132
RH
6931
6932 if (within_procedure)
6933 as_fatal (_("Nested procedures"));
6934
6935 /* Reset global variables for new procedure. */
6936 callinfo_found = FALSE;
6937 within_procedure = TRUE;
6938
6939 /* Create another call_info structure. */
6940 call_info = (struct call_info *) xmalloc (sizeof (struct call_info));
6941
6942 if (!call_info)
6943 as_fatal (_("Cannot allocate unwind descriptor\n"));
6944
6945 memset (call_info, 0, sizeof (struct call_info));
6946
6947 call_info->ci_next = NULL;
6948
6949 if (call_info_root == NULL)
6950 {
6951 call_info_root = call_info;
6952 last_call_info = call_info;
6953 }
6954 else
6955 {
6956 last_call_info->ci_next = call_info;
6957 last_call_info = call_info;
6958 }
6959
6960 /* set up defaults on call_info structure */
6961
6962 call_info->ci_unwind.descriptor.cannot_unwind = 0;
6963 call_info->ci_unwind.descriptor.region_desc = 1;
6964 call_info->ci_unwind.descriptor.hpux_interrupt_marker = 0;
6965
6966 /* If we got a .PROC pseudo-op, we know that the function is defined
6967 locally. Make sure it gets into the symbol table. */
6968 {
6969 label_symbol_struct *label_symbol = pa_get_label ();
6970
6971 if (label_symbol)
6972 {
6973 if (label_symbol->lss_label)
6974 {
6975 last_call_info->start_symbol = label_symbol->lss_label;
a0f75b47 6976 symbol_get_bfdsym (label_symbol->lss_label)->flags |= BSF_FUNCTION;
252b5132
RH
6977 }
6978 else
6979 as_bad (_("Missing function name for .PROC (corrupted label chain)"));
6980 }
6981 else
6982 last_call_info->start_symbol = NULL;
6983 }
6984
6985 demand_empty_rest_of_line ();
6986}
6987
6988/* Process the syntatical end of a procedure. Make sure all the
6989 appropriate pseudo-ops were found within the procedure. */
6990
6991static void
6992pa_procend (unused)
3f9b03b5 6993 int unused ATTRIBUTE_UNUSED;
252b5132
RH
6994{
6995
49863f82 6996#ifdef OBJ_SOM
252b5132
RH
6997 /* We must have a valid space and subspace. */
6998 pa_check_current_space_and_subspace ();
49863f82 6999#endif
252b5132
RH
7000
7001 /* If we are within a procedure definition, make sure we've
7002 defined a label for the procedure; handle case where the
7003 label was defined after the .PROC directive.
7004
7005 Note there's not need to diddle with the segment or fragment
7006 for the label symbol in this case. We have already switched
7007 into the new $CODE$ subspace at this point. */
7008 if (within_procedure && last_call_info->start_symbol == NULL)
7009 {
7010 label_symbol_struct *label_symbol = pa_get_label ();
7011
7012 if (label_symbol)
7013 {
7014 if (label_symbol->lss_label)
7015 {
7016 last_call_info->start_symbol = label_symbol->lss_label;
a0f75b47
ILT
7017 symbol_get_bfdsym (label_symbol->lss_label)->flags
7018 |= BSF_FUNCTION;
252b5132
RH
7019#ifdef OBJ_SOM
7020 /* Also handle allocation of a fixup to hold the unwind
7021 information when the label appears after the proc/procend. */
7022 if (within_entry_exit)
7023 {
7024 char *where = frag_more (0);
7025
7026 fix_new_hppa (frag_now, where - frag_now->fr_literal, 0,
7027 NULL, (offsetT) 0, NULL,
7028 0, R_HPPA_ENTRY, e_fsel, 0, 0,
7029 (int *) &last_call_info->ci_unwind.descriptor);
7030 }
7031#endif
7032 }
7033 else
7034 as_bad (_("Missing function name for .PROC (corrupted label chain)"));
7035 }
7036 else
7037 as_bad (_("Missing function name for .PROC"));
7038 }
7039
7040 if (!within_procedure)
7041 as_bad (_("misplaced .procend"));
7042
7043 if (!callinfo_found)
7044 as_bad (_("Missing .callinfo for this procedure"));
7045
7046 if (within_entry_exit)
7047 as_bad (_("Missing .EXIT for a .ENTRY"));
7048
7049#ifdef OBJ_ELF
7050 /* ELF needs to mark the end of each function so that it can compute
7051 the size of the function (apparently its needed in the symbol table). */
7052 hppa_elf_mark_end_of_function ();
7053#endif
7054
7055 within_procedure = FALSE;
7056 demand_empty_rest_of_line ();
7057 pa_undefine_label ();
7058}
7059
3f9b03b5 7060#ifdef OBJ_SOM
49863f82
JL
7061/* If VALUE is an exact power of two between zero and 2^31, then
7062 return log2 (VALUE). Else return -1. */
7063
7064static int
7065log2 (value)
7066 int value;
7067{
7068 int shift = 0;
7069
7070 while ((1 << shift) != value && shift < 32)
7071 shift++;
7072
7073 if (shift >= 32)
7074 return -1;
7075 else
7076 return shift;
7077}
7078
49863f82
JL
7079/* Check to make sure we have a valid space and subspace. */
7080
7081static void
7082pa_check_current_space_and_subspace ()
7083{
7084 if (current_space == NULL)
7085 as_fatal (_("Not in a space.\n"));
7086
7087 if (current_subspace == NULL)
7088 as_fatal (_("Not in a subspace.\n"));
7089}
7090
252b5132
RH
7091/* Parse the parameters to a .SPACE directive; if CREATE_FLAG is nonzero,
7092 then create a new space entry to hold the information specified
7093 by the parameters to the .SPACE directive. */
7094
7095static sd_chain_struct *
7096pa_parse_space_stmt (space_name, create_flag)
7097 char *space_name;
7098 int create_flag;
7099{
7100 char *name, *ptemp, c;
7101 char loadable, defined, private, sort;
ecacdc7a 7102 int spnum;
252b5132
RH
7103 asection *seg = NULL;
7104 sd_chain_struct *space;
7105
7106 /* load default values */
7107 spnum = 0;
7108 sort = 0;
7109 loadable = TRUE;
7110 defined = TRUE;
7111 private = FALSE;
7112 if (strcmp (space_name, "$TEXT$") == 0)
7113 {
7114 seg = pa_def_spaces[0].segment;
7115 defined = pa_def_spaces[0].defined;
7116 private = pa_def_spaces[0].private;
7117 sort = pa_def_spaces[0].sort;
7118 spnum = pa_def_spaces[0].spnum;
7119 }
7120 else if (strcmp (space_name, "$PRIVATE$") == 0)
7121 {
7122 seg = pa_def_spaces[1].segment;
7123 defined = pa_def_spaces[1].defined;
7124 private = pa_def_spaces[1].private;
7125 sort = pa_def_spaces[1].sort;
7126 spnum = pa_def_spaces[1].spnum;
7127 }
7128
7129 if (!is_end_of_statement ())
7130 {
7131 print_errors = FALSE;
7132 ptemp = input_line_pointer + 1;
7133 /* First see if the space was specified as a number rather than
7134 as a name. According to the PA assembly manual the rest of
7135 the line should be ignored. */
ecacdc7a
AM
7136 strict = 0;
7137 pa_parse_number (&ptemp, 0);
7138 if (pa_number >= 0)
252b5132 7139 {
ecacdc7a 7140 spnum = pa_number;
252b5132
RH
7141 input_line_pointer = ptemp;
7142 }
7143 else
7144 {
7145 while (!is_end_of_statement ())
7146 {
7147 input_line_pointer++;
7148 name = input_line_pointer;
7149 c = get_symbol_end ();
7150 if ((strncasecmp (name, "spnum", 5) == 0))
7151 {
7152 *input_line_pointer = c;
7153 input_line_pointer++;
7154 spnum = get_absolute_expression ();
7155 }
7156 else if ((strncasecmp (name, "sort", 4) == 0))
7157 {
7158 *input_line_pointer = c;
7159 input_line_pointer++;
7160 sort = get_absolute_expression ();
7161 }
7162 else if ((strncasecmp (name, "unloadable", 10) == 0))
7163 {
7164 *input_line_pointer = c;
7165 loadable = FALSE;
7166 }
7167 else if ((strncasecmp (name, "notdefined", 10) == 0))
7168 {
7169 *input_line_pointer = c;
7170 defined = FALSE;
7171 }
7172 else if ((strncasecmp (name, "private", 7) == 0))
7173 {
7174 *input_line_pointer = c;
7175 private = TRUE;
7176 }
7177 else
7178 {
7179 as_bad (_("Invalid .SPACE argument"));
7180 *input_line_pointer = c;
7181 if (!is_end_of_statement ())
7182 input_line_pointer++;
7183 }
7184 }
7185 }
7186 print_errors = TRUE;
7187 }
7188
7189 if (create_flag && seg == NULL)
7190 seg = subseg_new (space_name, 0);
7191
7192 /* If create_flag is nonzero, then create the new space with
7193 the attributes computed above. Else set the values in
7194 an already existing space -- this can only happen for
7195 the first occurence of a built-in space. */
7196 if (create_flag)
7197 space = create_new_space (space_name, spnum, loadable, defined,
7198 private, sort, seg, 1);
7199 else
7200 {
7201 space = is_defined_space (space_name);
7202 SPACE_SPNUM (space) = spnum;
7203 SPACE_DEFINED (space) = defined & 1;
7204 SPACE_USER_DEFINED (space) = 1;
7205 }
7206
7207#ifdef obj_set_section_attributes
7208 obj_set_section_attributes (seg, defined, private, sort, spnum);
7209#endif
7210
7211 return space;
7212}
7213
7214/* Handle a .SPACE pseudo-op; this switches the current space to the
7215 given space, creating the new space if necessary. */
7216
7217static void
7218pa_space (unused)
3f9b03b5 7219 int unused ATTRIBUTE_UNUSED;
252b5132
RH
7220{
7221 char *name, c, *space_name, *save_s;
252b5132
RH
7222 sd_chain_struct *sd_chain;
7223
7224 if (within_procedure)
7225 {
7226 as_bad (_("Can\'t change spaces within a procedure definition. Ignored"));
7227 ignore_rest_of_line ();
7228 }
7229 else
7230 {
7231 /* Check for some of the predefined spaces. FIXME: most of the code
7232 below is repeated several times, can we extract the common parts
7233 and place them into a subroutine or something similar? */
7234 /* FIXME Is this (and the next IF stmt) really right?
7235 What if INPUT_LINE_POINTER points to "$TEXT$FOO"? */
7236 if (strncmp (input_line_pointer, "$TEXT$", 6) == 0)
7237 {
7238 input_line_pointer += 6;
7239 sd_chain = is_defined_space ("$TEXT$");
7240 if (sd_chain == NULL)
7241 sd_chain = pa_parse_space_stmt ("$TEXT$", 1);
7242 else if (SPACE_USER_DEFINED (sd_chain) == 0)
7243 sd_chain = pa_parse_space_stmt ("$TEXT$", 0);
7244
7245 current_space = sd_chain;
7246 subseg_set (text_section, sd_chain->sd_last_subseg);
7247 current_subspace
7248 = pa_subsegment_to_subspace (text_section,
7249 sd_chain->sd_last_subseg);
7250 demand_empty_rest_of_line ();
7251 return;
7252 }
7253 if (strncmp (input_line_pointer, "$PRIVATE$", 9) == 0)
7254 {
7255 input_line_pointer += 9;
7256 sd_chain = is_defined_space ("$PRIVATE$");
7257 if (sd_chain == NULL)
7258 sd_chain = pa_parse_space_stmt ("$PRIVATE$", 1);
7259 else if (SPACE_USER_DEFINED (sd_chain) == 0)
7260 sd_chain = pa_parse_space_stmt ("$PRIVATE$", 0);
7261
7262 current_space = sd_chain;
7263 subseg_set (data_section, sd_chain->sd_last_subseg);
7264 current_subspace
7265 = pa_subsegment_to_subspace (data_section,
7266 sd_chain->sd_last_subseg);
7267 demand_empty_rest_of_line ();
7268 return;
7269 }
7270 if (!strncasecmp (input_line_pointer,
7271 GDB_DEBUG_SPACE_NAME,
7272 strlen (GDB_DEBUG_SPACE_NAME)))
7273 {
7274 input_line_pointer += strlen (GDB_DEBUG_SPACE_NAME);
7275 sd_chain = is_defined_space (GDB_DEBUG_SPACE_NAME);
7276 if (sd_chain == NULL)
7277 sd_chain = pa_parse_space_stmt (GDB_DEBUG_SPACE_NAME, 1);
7278 else if (SPACE_USER_DEFINED (sd_chain) == 0)
7279 sd_chain = pa_parse_space_stmt (GDB_DEBUG_SPACE_NAME, 0);
7280
7281 current_space = sd_chain;
7282
7283 {
7284 asection *gdb_section
7285 = bfd_make_section_old_way (stdoutput, GDB_DEBUG_SPACE_NAME);
7286
7287 subseg_set (gdb_section, sd_chain->sd_last_subseg);
7288 current_subspace
7289 = pa_subsegment_to_subspace (gdb_section,
7290 sd_chain->sd_last_subseg);
7291 }
7292 demand_empty_rest_of_line ();
7293 return;
7294 }
7295
7296 /* It could be a space specified by number. */
7297 print_errors = 0;
7298 save_s = input_line_pointer;
ecacdc7a
AM
7299 strict = 0;
7300 pa_parse_number (&input_line_pointer, 0);
7301 if (pa_number >= 0)
252b5132 7302 {
ecacdc7a 7303 if ((sd_chain = pa_find_space_by_number (pa_number)))
252b5132
RH
7304 {
7305 current_space = sd_chain;
7306
7307 subseg_set (sd_chain->sd_seg, sd_chain->sd_last_subseg);
7308 current_subspace
7309 = pa_subsegment_to_subspace (sd_chain->sd_seg,
7310 sd_chain->sd_last_subseg);
7311 demand_empty_rest_of_line ();
7312 return;
7313 }
7314 }
7315
7316 /* Not a number, attempt to create a new space. */
7317 print_errors = 1;
7318 input_line_pointer = save_s;
7319 name = input_line_pointer;
7320 c = get_symbol_end ();
7321 space_name = xmalloc (strlen (name) + 1);
7322 strcpy (space_name, name);
7323 *input_line_pointer = c;
7324
7325 sd_chain = pa_parse_space_stmt (space_name, 1);
7326 current_space = sd_chain;
7327
7328 subseg_set (sd_chain->sd_seg, sd_chain->sd_last_subseg);
7329 current_subspace = pa_subsegment_to_subspace (sd_chain->sd_seg,
7330 sd_chain->sd_last_subseg);
7331 demand_empty_rest_of_line ();
7332 }
7333}
7334
7335/* Switch to a new space. (I think). FIXME. */
7336
7337static void
7338pa_spnum (unused)
3f9b03b5 7339 int unused ATTRIBUTE_UNUSED;
252b5132
RH
7340{
7341 char *name;
7342 char c;
7343 char *p;
7344 sd_chain_struct *space;
7345
7346 name = input_line_pointer;
7347 c = get_symbol_end ();
7348 space = is_defined_space (name);
7349 if (space)
7350 {
7351 p = frag_more (4);
7352 md_number_to_chars (p, SPACE_SPNUM (space), 4);
7353 }
7354 else
7355 as_warn (_("Undefined space: '%s' Assuming space number = 0."), name);
7356
7357 *input_line_pointer = c;
7358 demand_empty_rest_of_line ();
7359}
7360
252b5132
RH
7361/* Handle a .SUBSPACE pseudo-op; this switches the current subspace to the
7362 given subspace, creating the new subspace if necessary.
7363
7364 FIXME. Should mirror pa_space more closely, in particular how
7365 they're broken up into subroutines. */
7366
7367static void
7368pa_subspace (create_new)
7369 int create_new;
7370{
49863f82 7371 char *name, *ss_name, c;
252b5132
RH
7372 char loadable, code_only, common, dup_common, zero, sort;
7373 int i, access, space_index, alignment, quadrant, applicable, flags;
7374 sd_chain_struct *space;
7375 ssd_chain_struct *ssd;
7376 asection *section;
7377
7378 if (current_space == NULL)
7379 as_fatal (_("Must be in a space before changing or declaring subspaces.\n"));
7380
7381 if (within_procedure)
7382 {
7383 as_bad (_("Can\'t change subspaces within a procedure definition. Ignored"));
7384 ignore_rest_of_line ();
7385 }
7386 else
7387 {
7388 name = input_line_pointer;
7389 c = get_symbol_end ();
7390 ss_name = xmalloc (strlen (name) + 1);
7391 strcpy (ss_name, name);
7392 *input_line_pointer = c;
7393
7394 /* Load default values. */
7395 sort = 0;
7396 access = 0x7f;
7397 loadable = 1;
7398 common = 0;
7399 dup_common = 0;
7400 code_only = 0;
7401 zero = 0;
7402 space_index = ~0;
7403 alignment = 1;
7404 quadrant = 0;
252b5132
RH
7405
7406 space = current_space;
7407 if (create_new)
7408 ssd = NULL;
7409 else
7410 ssd = is_defined_subspace (ss_name);
7411 /* Allow user to override the builtin attributes of subspaces. But
7412 only allow the attributes to be changed once! */
7413 if (ssd && SUBSPACE_DEFINED (ssd))
7414 {
7415 subseg_set (ssd->ssd_seg, ssd->ssd_subseg);
7416 current_subspace = ssd;
7417 if (!is_end_of_statement ())
7418 as_warn (_("Parameters of an existing subspace can\'t be modified"));
7419 demand_empty_rest_of_line ();
7420 return;
7421 }
7422 else
7423 {
7424 /* A new subspace. Load default values if it matches one of
7425 the builtin subspaces. */
7426 i = 0;
7427 while (pa_def_subspaces[i].name)
7428 {
7429 if (strcasecmp (pa_def_subspaces[i].name, ss_name) == 0)
7430 {
7431 loadable = pa_def_subspaces[i].loadable;
7432 common = pa_def_subspaces[i].common;
7433 dup_common = pa_def_subspaces[i].dup_common;
7434 code_only = pa_def_subspaces[i].code_only;
7435 zero = pa_def_subspaces[i].zero;
7436 space_index = pa_def_subspaces[i].space_index;
7437 alignment = pa_def_subspaces[i].alignment;
7438 quadrant = pa_def_subspaces[i].quadrant;
7439 access = pa_def_subspaces[i].access;
7440 sort = pa_def_subspaces[i].sort;
252b5132
RH
7441 break;
7442 }
7443 i++;
7444 }
7445 }
7446
7447 /* We should be working with a new subspace now. Fill in
7448 any information as specified by the user. */
7449 if (!is_end_of_statement ())
7450 {
7451 input_line_pointer++;
7452 while (!is_end_of_statement ())
7453 {
7454 name = input_line_pointer;
7455 c = get_symbol_end ();
7456 if ((strncasecmp (name, "quad", 4) == 0))
7457 {
7458 *input_line_pointer = c;
7459 input_line_pointer++;
7460 quadrant = get_absolute_expression ();
7461 }
7462 else if ((strncasecmp (name, "align", 5) == 0))
7463 {
7464 *input_line_pointer = c;
7465 input_line_pointer++;
7466 alignment = get_absolute_expression ();
7467 if (log2 (alignment) == -1)
7468 {
7469 as_bad (_("Alignment must be a power of 2"));
7470 alignment = 1;
7471 }
7472 }
7473 else if ((strncasecmp (name, "access", 6) == 0))
7474 {
7475 *input_line_pointer = c;
7476 input_line_pointer++;
7477 access = get_absolute_expression ();
7478 }
7479 else if ((strncasecmp (name, "sort", 4) == 0))
7480 {
7481 *input_line_pointer = c;
7482 input_line_pointer++;
7483 sort = get_absolute_expression ();
7484 }
7485 else if ((strncasecmp (name, "code_only", 9) == 0))
7486 {
7487 *input_line_pointer = c;
7488 code_only = 1;
7489 }
7490 else if ((strncasecmp (name, "unloadable", 10) == 0))
7491 {
7492 *input_line_pointer = c;
7493 loadable = 0;
7494 }
7495 else if ((strncasecmp (name, "common", 6) == 0))
7496 {
7497 *input_line_pointer = c;
7498 common = 1;
7499 }
7500 else if ((strncasecmp (name, "dup_comm", 8) == 0))
7501 {
7502 *input_line_pointer = c;
7503 dup_common = 1;
7504 }
7505 else if ((strncasecmp (name, "zero", 4) == 0))
7506 {
7507 *input_line_pointer = c;
7508 zero = 1;
7509 }
7510 else if ((strncasecmp (name, "first", 5) == 0))
7511 as_bad (_("FIRST not supported as a .SUBSPACE argument"));
7512 else
7513 as_bad (_("Invalid .SUBSPACE argument"));
7514 if (!is_end_of_statement ())
7515 input_line_pointer++;
7516 }
7517 }
7518
7519 /* Compute a reasonable set of BFD flags based on the information
7520 in the .subspace directive. */
7521 applicable = bfd_applicable_section_flags (stdoutput);
7522 flags = 0;
7523 if (loadable)
7524 flags |= (SEC_ALLOC | SEC_LOAD);
7525 if (code_only)
7526 flags |= SEC_CODE;
7527 if (common || dup_common)
7528 flags |= SEC_IS_COMMON;
7529
7530 flags |= SEC_RELOC | SEC_HAS_CONTENTS;
7531
7532 /* This is a zero-filled subspace (eg BSS). */
7533 if (zero)
7534 flags &= ~(SEC_LOAD | SEC_HAS_CONTENTS);
7535
7536 applicable &= flags;
7537
7538 /* If this is an existing subspace, then we want to use the
7539 segment already associated with the subspace.
7540
7541 FIXME NOW! ELF BFD doesn't appear to be ready to deal with
7542 lots of sections. It might be a problem in the PA ELF
7543 code, I do not know yet. For now avoid creating anything
7544 but the "standard" sections for ELF. */
7545 if (create_new)
7546 section = subseg_force_new (ss_name, 0);
7547 else if (ssd)
7548 section = ssd->ssd_seg;
252b5132
RH
7549 else
7550 section = subseg_new (ss_name, 0);
7551
7552 if (zero)
7553 seg_info (section)->bss = 1;
7554
7555 /* Now set the flags. */
7556 bfd_set_section_flags (stdoutput, section, applicable);
7557
7558 /* Record any alignment request for this section. */
7559 record_alignment (section, log2 (alignment));
7560
7561 /* Set the starting offset for this section. */
7562 bfd_set_section_vma (stdoutput, section,
7563 pa_subspace_start (space, quadrant));
7564
7565 /* Now that all the flags are set, update an existing subspace,
7566 or create a new one. */
7567 if (ssd)
7568
7569 current_subspace = update_subspace (space, ss_name, loadable,
7570 code_only, common, dup_common,
7571 sort, zero, access, space_index,
7572 alignment, quadrant,
7573 section);
7574 else
7575 current_subspace = create_new_subspace (space, ss_name, loadable,
7576 code_only, common,
7577 dup_common, zero, sort,
7578 access, space_index,
7579 alignment, quadrant, section);
7580
7581 demand_empty_rest_of_line ();
7582 current_subspace->ssd_seg = section;
7583 subseg_set (current_subspace->ssd_seg, current_subspace->ssd_subseg);
7584 }
7585 SUBSPACE_DEFINED (current_subspace) = 1;
7586}
7587
252b5132
RH
7588/* Create default space and subspace dictionaries. */
7589
7590static void
7591pa_spaces_begin ()
7592{
7593 int i;
7594
7595 space_dict_root = NULL;
7596 space_dict_last = NULL;
7597
7598 i = 0;
7599 while (pa_def_spaces[i].name)
7600 {
7601 char *name;
7602
7603 /* Pick the right name to use for the new section. */
49863f82 7604 name = pa_def_spaces[i].name;
252b5132
RH
7605
7606 pa_def_spaces[i].segment = subseg_new (name, 0);
7607 create_new_space (pa_def_spaces[i].name, pa_def_spaces[i].spnum,
7608 pa_def_spaces[i].loadable, pa_def_spaces[i].defined,
7609 pa_def_spaces[i].private, pa_def_spaces[i].sort,
7610 pa_def_spaces[i].segment, 0);
7611 i++;
7612 }
7613
7614 i = 0;
7615 while (pa_def_subspaces[i].name)
7616 {
7617 char *name;
7618 int applicable, subsegment;
7619 asection *segment = NULL;
7620 sd_chain_struct *space;
7621
7622 /* Pick the right name for the new section and pick the right
7623 subsegment number. */
49863f82
JL
7624 name = pa_def_subspaces[i].name;
7625 subsegment = 0;
252b5132
RH
7626
7627 /* Create the new section. */
7628 segment = subseg_new (name, subsegment);
7629
252b5132
RH
7630 /* For SOM we want to replace the standard .text, .data, and .bss
7631 sections with our own. We also want to set BFD flags for
7632 all the built-in subspaces. */
49863f82 7633 if (!strcmp (pa_def_subspaces[i].name, "$CODE$"))
252b5132
RH
7634 {
7635 text_section = segment;
7636 applicable = bfd_applicable_section_flags (stdoutput);
7637 bfd_set_section_flags (stdoutput, segment,
7638 applicable & (SEC_ALLOC | SEC_LOAD
7639 | SEC_RELOC | SEC_CODE
7640 | SEC_READONLY
7641 | SEC_HAS_CONTENTS));
7642 }
49863f82 7643 else if (!strcmp (pa_def_subspaces[i].name, "$DATA$"))
252b5132
RH
7644 {
7645 data_section = segment;
7646 applicable = bfd_applicable_section_flags (stdoutput);
7647 bfd_set_section_flags (stdoutput, segment,
7648 applicable & (SEC_ALLOC | SEC_LOAD
7649 | SEC_RELOC
7650 | SEC_HAS_CONTENTS));
7651
252b5132 7652 }
49863f82 7653 else if (!strcmp (pa_def_subspaces[i].name, "$BSS$"))
252b5132
RH
7654 {
7655 bss_section = segment;
7656 applicable = bfd_applicable_section_flags (stdoutput);
7657 bfd_set_section_flags (stdoutput, segment,
7658 applicable & SEC_ALLOC);
7659 }
49863f82 7660 else if (!strcmp (pa_def_subspaces[i].name, "$LIT$"))
252b5132
RH
7661 {
7662 applicable = bfd_applicable_section_flags (stdoutput);
7663 bfd_set_section_flags (stdoutput, segment,
7664 applicable & (SEC_ALLOC | SEC_LOAD
7665 | SEC_RELOC
7666 | SEC_READONLY
7667 | SEC_HAS_CONTENTS));
7668 }
49863f82 7669 else if (!strcmp (pa_def_subspaces[i].name, "$MILLICODE$"))
252b5132
RH
7670 {
7671 applicable = bfd_applicable_section_flags (stdoutput);
7672 bfd_set_section_flags (stdoutput, segment,
7673 applicable & (SEC_ALLOC | SEC_LOAD
7674 | SEC_RELOC
7675 | SEC_READONLY
7676 | SEC_HAS_CONTENTS));
7677 }
49863f82 7678 else if (!strcmp (pa_def_subspaces[i].name, "$UNWIND$"))
252b5132
RH
7679 {
7680 applicable = bfd_applicable_section_flags (stdoutput);
7681 bfd_set_section_flags (stdoutput, segment,
7682 applicable & (SEC_ALLOC | SEC_LOAD
7683 | SEC_RELOC
7684 | SEC_READONLY
7685 | SEC_HAS_CONTENTS));
7686 }
7687
7688 /* Find the space associated with this subspace. */
7689 space = pa_segment_to_space (pa_def_spaces[pa_def_subspaces[i].
7690 def_space_index].segment);
7691 if (space == NULL)
7692 {
7693 as_fatal (_("Internal error: Unable to find containing space for %s."),
7694 pa_def_subspaces[i].name);
7695 }
7696
7697 create_new_subspace (space, name,
7698 pa_def_subspaces[i].loadable,
7699 pa_def_subspaces[i].code_only,
7700 pa_def_subspaces[i].common,
7701 pa_def_subspaces[i].dup_common,
7702 pa_def_subspaces[i].zero,
7703 pa_def_subspaces[i].sort,
7704 pa_def_subspaces[i].access,
7705 pa_def_subspaces[i].space_index,
7706 pa_def_subspaces[i].alignment,
7707 pa_def_subspaces[i].quadrant,
7708 segment);
7709 i++;
7710 }
7711}
7712
252b5132
RH
7713/* Create a new space NAME, with the appropriate flags as defined
7714 by the given parameters. */
7715
7716static sd_chain_struct *
7717create_new_space (name, spnum, loadable, defined, private,
7718 sort, seg, user_defined)
7719 char *name;
7720 int spnum;
7721 int loadable;
7722 int defined;
7723 int private;
7724 int sort;
7725 asection *seg;
7726 int user_defined;
7727{
7728 sd_chain_struct *chain_entry;
7729
7730 chain_entry = (sd_chain_struct *) xmalloc (sizeof (sd_chain_struct));
7731 if (!chain_entry)
7732 as_fatal (_("Out of memory: could not allocate new space chain entry: %s\n"),
7733 name);
7734
7735 SPACE_NAME (chain_entry) = (char *) xmalloc (strlen (name) + 1);
7736 strcpy (SPACE_NAME (chain_entry), name);
7737 SPACE_DEFINED (chain_entry) = defined;
7738 SPACE_USER_DEFINED (chain_entry) = user_defined;
7739 SPACE_SPNUM (chain_entry) = spnum;
7740
7741 chain_entry->sd_seg = seg;
7742 chain_entry->sd_last_subseg = -1;
7743 chain_entry->sd_subspaces = NULL;
7744 chain_entry->sd_next = NULL;
7745
7746 /* Find spot for the new space based on its sort key. */
7747 if (!space_dict_last)
7748 space_dict_last = chain_entry;
7749
7750 if (space_dict_root == NULL)
7751 space_dict_root = chain_entry;
7752 else
7753 {
7754 sd_chain_struct *chain_pointer;
7755 sd_chain_struct *prev_chain_pointer;
7756
7757 chain_pointer = space_dict_root;
7758 prev_chain_pointer = NULL;
7759
7760 while (chain_pointer)
7761 {
7762 prev_chain_pointer = chain_pointer;
7763 chain_pointer = chain_pointer->sd_next;
7764 }
7765
7766 /* At this point we've found the correct place to add the new
7767 entry. So add it and update the linked lists as appropriate. */
7768 if (prev_chain_pointer)
7769 {
7770 chain_entry->sd_next = chain_pointer;
7771 prev_chain_pointer->sd_next = chain_entry;
7772 }
7773 else
7774 {
7775 space_dict_root = chain_entry;
7776 chain_entry->sd_next = chain_pointer;
7777 }
7778
7779 if (chain_entry->sd_next == NULL)
7780 space_dict_last = chain_entry;
7781 }
7782
7783 /* This is here to catch predefined spaces which do not get
7784 modified by the user's input. Another call is found at
7785 the bottom of pa_parse_space_stmt to handle cases where
7786 the user modifies a predefined space. */
7787#ifdef obj_set_section_attributes
7788 obj_set_section_attributes (seg, defined, private, sort, spnum);
7789#endif
7790
7791 return chain_entry;
7792}
7793
7794/* Create a new subspace NAME, with the appropriate flags as defined
7795 by the given parameters.
7796
7797 Add the new subspace to the subspace dictionary chain in numerical
7798 order as defined by the SORT entries. */
7799
7800static ssd_chain_struct *
7801create_new_subspace (space, name, loadable, code_only, common,
7802 dup_common, is_zero, sort, access, space_index,
7803 alignment, quadrant, seg)
7804 sd_chain_struct *space;
7805 char *name;
7806 int loadable, code_only, common, dup_common, is_zero;
7807 int sort;
7808 int access;
7809 int space_index;
7810 int alignment;
7811 int quadrant;
7812 asection *seg;
7813{
7814 ssd_chain_struct *chain_entry;
7815
7816 chain_entry = (ssd_chain_struct *) xmalloc (sizeof (ssd_chain_struct));
7817 if (!chain_entry)
7818 as_fatal (_("Out of memory: could not allocate new subspace chain entry: %s\n"), name);
7819
7820 SUBSPACE_NAME (chain_entry) = (char *) xmalloc (strlen (name) + 1);
7821 strcpy (SUBSPACE_NAME (chain_entry), name);
7822
7823 /* Initialize subspace_defined. When we hit a .subspace directive
7824 we'll set it to 1 which "locks-in" the subspace attributes. */
7825 SUBSPACE_DEFINED (chain_entry) = 0;
7826
49863f82 7827 chain_entry->ssd_subseg = 0;
252b5132
RH
7828 chain_entry->ssd_seg = seg;
7829 chain_entry->ssd_next = NULL;
7830
7831 /* Find spot for the new subspace based on its sort key. */
7832 if (space->sd_subspaces == NULL)
7833 space->sd_subspaces = chain_entry;
7834 else
7835 {
7836 ssd_chain_struct *chain_pointer;
7837 ssd_chain_struct *prev_chain_pointer;
7838
7839 chain_pointer = space->sd_subspaces;
7840 prev_chain_pointer = NULL;
7841
7842 while (chain_pointer)
7843 {
7844 prev_chain_pointer = chain_pointer;
7845 chain_pointer = chain_pointer->ssd_next;
7846 }
7847
7848 /* Now we have somewhere to put the new entry. Insert it and update
7849 the links. */
7850 if (prev_chain_pointer)
7851 {
7852 chain_entry->ssd_next = chain_pointer;
7853 prev_chain_pointer->ssd_next = chain_entry;
7854 }
7855 else
7856 {
7857 space->sd_subspaces = chain_entry;
7858 chain_entry->ssd_next = chain_pointer;
7859 }
7860 }
7861
7862#ifdef obj_set_subsection_attributes
7863 obj_set_subsection_attributes (seg, space->sd_seg, access,
7864 sort, quadrant);
7865#endif
7866
7867 return chain_entry;
7868}
7869
7870/* Update the information for the given subspace based upon the
7871 various arguments. Return the modified subspace chain entry. */
7872
7873static ssd_chain_struct *
7874update_subspace (space, name, loadable, code_only, common, dup_common, sort,
7875 zero, access, space_index, alignment, quadrant, section)
7876 sd_chain_struct *space;
7877 char *name;
7878 int loadable;
7879 int code_only;
7880 int common;
7881 int dup_common;
7882 int zero;
7883 int sort;
7884 int access;
7885 int space_index;
7886 int alignment;
7887 int quadrant;
7888 asection *section;
7889{
7890 ssd_chain_struct *chain_entry;
7891
7892 chain_entry = is_defined_subspace (name);
7893
7894#ifdef obj_set_subsection_attributes
7895 obj_set_subsection_attributes (section, space->sd_seg, access,
7896 sort, quadrant);
7897#endif
7898
7899 return chain_entry;
7900}
7901
7902/* Return the space chain entry for the space with the name NAME or
7903 NULL if no such space exists. */
7904
7905static sd_chain_struct *
7906is_defined_space (name)
7907 char *name;
7908{
7909 sd_chain_struct *chain_pointer;
7910
7911 for (chain_pointer = space_dict_root;
7912 chain_pointer;
7913 chain_pointer = chain_pointer->sd_next)
7914 {
7915 if (strcmp (SPACE_NAME (chain_pointer), name) == 0)
7916 return chain_pointer;
7917 }
7918
7919 /* No mapping from segment to space was found. Return NULL. */
7920 return NULL;
7921}
7922
7923/* Find and return the space associated with the given seg. If no mapping
7924 from the given seg to a space is found, then return NULL.
7925
7926 Unlike subspaces, the number of spaces is not expected to grow much,
7927 so a linear exhaustive search is OK here. */
7928
7929static sd_chain_struct *
7930pa_segment_to_space (seg)
7931 asection *seg;
7932{
7933 sd_chain_struct *space_chain;
7934
7935 /* Walk through each space looking for the correct mapping. */
7936 for (space_chain = space_dict_root;
7937 space_chain;
7938 space_chain = space_chain->sd_next)
7939 {
7940 if (space_chain->sd_seg == seg)
7941 return space_chain;
7942 }
7943
7944 /* Mapping was not found. Return NULL. */
7945 return NULL;
7946}
7947
7948/* Return the space chain entry for the subspace with the name NAME or
7949 NULL if no such subspace exists.
7950
7951 Uses a linear search through all the spaces and subspaces, this may
7952 not be appropriate if we ever being placing each function in its
7953 own subspace. */
7954
7955static ssd_chain_struct *
7956is_defined_subspace (name)
7957 char *name;
7958{
7959 sd_chain_struct *space_chain;
7960 ssd_chain_struct *subspace_chain;
7961
7962 /* Walk through each space. */
7963 for (space_chain = space_dict_root;
7964 space_chain;
7965 space_chain = space_chain->sd_next)
7966 {
7967 /* Walk through each subspace looking for a name which matches. */
7968 for (subspace_chain = space_chain->sd_subspaces;
7969 subspace_chain;
7970 subspace_chain = subspace_chain->ssd_next)
7971 if (strcmp (SUBSPACE_NAME (subspace_chain), name) == 0)
7972 return subspace_chain;
7973 }
7974
7975 /* Subspace wasn't found. Return NULL. */
7976 return NULL;
7977}
7978
7979/* Find and return the subspace associated with the given seg. If no
7980 mapping from the given seg to a subspace is found, then return NULL.
7981
7982 If we ever put each procedure/function within its own subspace
7983 (to make life easier on the compiler and linker), then this will have
7984 to become more efficient. */
7985
7986static ssd_chain_struct *
7987pa_subsegment_to_subspace (seg, subseg)
7988 asection *seg;
7989 subsegT subseg;
7990{
7991 sd_chain_struct *space_chain;
7992 ssd_chain_struct *subspace_chain;
7993
7994 /* Walk through each space. */
7995 for (space_chain = space_dict_root;
7996 space_chain;
7997 space_chain = space_chain->sd_next)
7998 {
7999 if (space_chain->sd_seg == seg)
8000 {
8001 /* Walk through each subspace within each space looking for
8002 the correct mapping. */
8003 for (subspace_chain = space_chain->sd_subspaces;
8004 subspace_chain;
8005 subspace_chain = subspace_chain->ssd_next)
8006 if (subspace_chain->ssd_subseg == (int) subseg)
8007 return subspace_chain;
8008 }
8009 }
8010
8011 /* No mapping from subsegment to subspace found. Return NULL. */
8012 return NULL;
8013}
8014
8015/* Given a number, try and find a space with the name number.
8016
8017 Return a pointer to a space dictionary chain entry for the space
8018 that was found or NULL on failure. */
8019
8020static sd_chain_struct *
8021pa_find_space_by_number (number)
8022 int number;
8023{
8024 sd_chain_struct *space_chain;
8025
8026 for (space_chain = space_dict_root;
8027 space_chain;
8028 space_chain = space_chain->sd_next)
8029 {
8030 if (SPACE_SPNUM (space_chain) == (unsigned int) number)
8031 return space_chain;
8032 }
8033
8034 /* No appropriate space found. Return NULL. */
8035 return NULL;
8036}
8037
8038/* Return the starting address for the given subspace. If the starting
8039 address is unknown then return zero. */
8040
8041static unsigned int
8042pa_subspace_start (space, quadrant)
8043 sd_chain_struct *space;
8044 int quadrant;
8045{
252b5132
RH
8046 /* FIXME. Assumes everyone puts read/write data at 0x4000000, this
8047 is not correct for the PA OSF1 port. */
8048 if ((strcmp (SPACE_NAME (space), "$PRIVATE$") == 0) && quadrant == 1)
8049 return 0x40000000;
8050 else if (space->sd_seg == data_section && quadrant == 1)
8051 return 0x40000000;
8052 else
8053 return 0;
252b5132
RH
8054 return 0;
8055}
8056
8057/* FIXME. Needs documentation. */
8058static int
8059pa_next_subseg (space)
8060 sd_chain_struct *space;
8061{
8062
8063 space->sd_last_subseg++;
8064 return space->sd_last_subseg;
8065}
49863f82 8066#endif
252b5132
RH
8067
8068/* Helper function for pa_stringer. Used to find the end of
8069 a string. */
8070
8071static unsigned int
8072pa_stringer_aux (s)
8073 char *s;
8074{
8075 unsigned int c = *s & CHAR_MASK;
8076
252b5132
RH
8077 switch (c)
8078 {
8079 case '\"':
8080 c = NOT_A_CHAR;
8081 break;
8082 default:
8083 break;
8084 }
8085 return c;
8086}
8087
8088/* Handle a .STRING type pseudo-op. */
8089
8090static void
8091pa_stringer (append_zero)
8092 int append_zero;
8093{
8094 char *s, num_buf[4];
8095 unsigned int c;
8096 int i;
8097
8098 /* Preprocess the string to handle PA-specific escape sequences.
ad1079af 8099 For example, \xDD where DD is a hexadecimal number should be
252b5132
RH
8100 changed to \OOO where OOO is an octal number. */
8101
ad1079af
AM
8102#ifdef OBJ_SOM
8103 /* We must have a valid space and subspace. */
8104 pa_check_current_space_and_subspace ();
8105#endif
8106
252b5132
RH
8107 /* Skip the opening quote. */
8108 s = input_line_pointer + 1;
8109
8110 while (is_a_char (c = pa_stringer_aux (s++)))
8111 {
8112 if (c == '\\')
8113 {
8114 c = *s;
8115 switch (c)
8116 {
8117 /* Handle \x<num>. */
8118 case 'x':
8119 {
8120 unsigned int number;
8121 int num_digit;
8122 char dg;
8123 char *s_start = s;
8124
ad1079af 8125 /* Get past the 'x'. */
252b5132
RH
8126 s++;
8127 for (num_digit = 0, number = 0, dg = *s;
8128 num_digit < 2
8129 && (isdigit (dg) || (dg >= 'a' && dg <= 'f')
8130 || (dg >= 'A' && dg <= 'F'));
8131 num_digit++)
8132 {
8133 if (isdigit (dg))
8134 number = number * 16 + dg - '0';
8135 else if (dg >= 'a' && dg <= 'f')
8136 number = number * 16 + dg - 'a' + 10;
8137 else
8138 number = number * 16 + dg - 'A' + 10;
8139
8140 s++;
8141 dg = *s;
8142 }
8143 if (num_digit > 0)
8144 {
8145 switch (num_digit)
8146 {
8147 case 1:
8148 sprintf (num_buf, "%02o", number);
8149 break;
8150 case 2:
8151 sprintf (num_buf, "%03o", number);
8152 break;
8153 }
8154 for (i = 0; i <= num_digit; i++)
8155 s_start[i] = num_buf[i];
8156 }
8157 break;
8158 }
8159 /* This might be a "\"", skip over the escaped char. */
8160 default:
8161 s++;
8162 break;
8163 }
8164 }
8165 }
8166 stringer (append_zero);
8167 pa_undefine_label ();
8168}
8169
8170/* Handle a .VERSION pseudo-op. */
8171
8172static void
8173pa_version (unused)
3f9b03b5 8174 int unused ATTRIBUTE_UNUSED;
252b5132
RH
8175{
8176 obj_version (0);
8177 pa_undefine_label ();
8178}
8179
8180#ifdef OBJ_SOM
8181
8182/* Handle a .COMPILER pseudo-op. */
8183
8184static void
8185pa_compiler (unused)
3f9b03b5 8186 int unused ATTRIBUTE_UNUSED;
252b5132
RH
8187{
8188 obj_som_compiler (0);
8189 pa_undefine_label ();
8190}
8191
8192#endif
8193
8194/* Handle a .COPYRIGHT pseudo-op. */
8195
8196static void
8197pa_copyright (unused)
3f9b03b5 8198 int unused ATTRIBUTE_UNUSED;
252b5132
RH
8199{
8200 obj_copyright (0);
8201 pa_undefine_label ();
8202}
8203
8204/* Just like a normal cons, but when finished we have to undefine
8205 the latest space label. */
8206
8207static void
8208pa_cons (nbytes)
8209 int nbytes;
8210{
8211 cons (nbytes);
8212 pa_undefine_label ();
8213}
8214
252b5132
RH
8215/* Like float_cons, but we need to undefine our label. */
8216
8217static void
8218pa_float_cons (float_type)
8219 int float_type;
8220{
8221 float_cons (float_type);
8222 pa_undefine_label ();
8223}
8224
8225/* Like s_fill, but delete our label when finished. */
8226
8227static void
8228pa_fill (unused)
3f9b03b5 8229 int unused ATTRIBUTE_UNUSED;
252b5132 8230{
49863f82 8231#ifdef OBJ_SOM
252b5132
RH
8232 /* We must have a valid space and subspace. */
8233 pa_check_current_space_and_subspace ();
49863f82 8234#endif
252b5132
RH
8235
8236 s_fill (0);
8237 pa_undefine_label ();
8238}
8239
8240/* Like lcomm, but delete our label when finished. */
8241
8242static void
8243pa_lcomm (needs_align)
8244 int needs_align;
8245{
49863f82 8246#ifdef OBJ_SOM
252b5132
RH
8247 /* We must have a valid space and subspace. */
8248 pa_check_current_space_and_subspace ();
49863f82 8249#endif
252b5132
RH
8250
8251 s_lcomm (needs_align);
8252 pa_undefine_label ();
8253}
8254
8255/* Like lsym, but delete our label when finished. */
8256
8257static void
8258pa_lsym (unused)
3f9b03b5 8259 int unused ATTRIBUTE_UNUSED;
252b5132 8260{
49863f82 8261#ifdef OBJ_SOM
252b5132
RH
8262 /* We must have a valid space and subspace. */
8263 pa_check_current_space_and_subspace ();
49863f82 8264#endif
252b5132
RH
8265
8266 s_lsym (0);
8267 pa_undefine_label ();
8268}
8269
252b5132
RH
8270/* On the PA relocations which involve function symbols must not be
8271 adjusted. This so that the linker can know when/how to create argument
8272 relocation stubs for indirect calls and calls to static functions.
8273
8274 "T" field selectors create DLT relative fixups for accessing
8275 globals and statics in PIC code; each DLT relative fixup creates
8276 an entry in the DLT table. The entries contain the address of
8277 the final target (eg accessing "foo" would create a DLT entry
8278 with the address of "foo").
8279
8280 Unfortunately, the HP linker doesn't take into account any addend
8281 when generating the DLT; so accessing $LIT$+8 puts the address of
8282 $LIT$ into the DLT rather than the address of $LIT$+8.
8283
8284 The end result is we can't perform relocation symbol reductions for
8285 any fixup which creates entries in the DLT (eg they use "T" field
8286 selectors).
8287
8288 Reject reductions involving symbols with external scope; such
d53d2751 8289 reductions make life a living hell for object file editors.
252b5132
RH
8290
8291 FIXME. Also reject R_HPPA relocations which are 32bits wide in
8292 the code space. The SOM BFD backend doesn't know how to pull the
8293 right bits out of an instruction. */
8294
8295int
8296hppa_fix_adjustable (fixp)
8297 fixS *fixp;
8298{
8299 struct hppa_fix_struct *hppa_fix;
8300
8301 hppa_fix = (struct hppa_fix_struct *) fixp->tc_fix_data;
8302
8303#ifdef OBJ_SOM
8304 /* Reject reductions of symbols in 32bit relocs. */
8305 if (fixp->fx_r_type == R_HPPA && hppa_fix->fx_r_format == 32)
8306 return 0;
1cd1c99b 8307#endif
252b5132 8308
904a31bf
AM
8309#ifdef OBJ_ELF
8310 if (fixp->fx_r_type == (int) R_PARISC_GNU_VTINHERIT
8311 || fixp->fx_r_type == (int) R_PARISC_GNU_VTENTRY)
8312 return 0;
8313#endif
8314
252b5132 8315 /* Reject reductions of symbols in sym1-sym2 expressions when
d53d2751 8316 the fixup will occur in a CODE subspace.
252b5132
RH
8317
8318 XXX FIXME: Long term we probably want to reject all of these;
8319 for example reducing in the debug section would lose if we ever
8320 supported using the optimizing hp linker. */
8321 if (fixp->fx_addsy
8322 && fixp->fx_subsy
8323 && (hppa_fix->segment->flags & SEC_CODE))
8324 {
8325 /* Apparently sy_used_in_reloc never gets set for sub symbols. */
398e8c25 8326 symbol_mark_used_in_reloc (fixp->fx_subsy);
252b5132
RH
8327 return 0;
8328 }
8329
8330 /* We can't adjust any relocs that use LR% and RR% field selectors.
1cd1c99b
AM
8331
8332 If a symbol is reduced to a section symbol, the assembler will
8333 adjust the addend unless the symbol happens to reside right at
8334 the start of the section. Additionally, the linker has no choice
8335 but to manipulate the addends when coalescing input sections for
8336 "ld -r". Since an LR% field selector is defined to round the
8337 addend, we can't change the addend without risking that a LR% and
8338 it's corresponding (possible multiple) RR% field will no longer
8339 sum to the right value.
8340
8341 eg. Suppose we have
8342 . ldil LR%foo+0,%r21
8343 . ldw RR%foo+0(%r21),%r26
25a8b250
AM
8344 . ldw RR%foo+4(%r21),%r25
8345
8346 If foo is at address 4092 (decimal) in section `sect', then after
8347 reducing to the section symbol we get
8348 . LR%sect+4092 == (L%sect)+0
8349 . RR%sect+4092 == (R%sect)+4092
8350 . RR%sect+4096 == (R%sect)-4096
8351 and the last address loses because rounding the addend to 8k
8352 mutiples takes us up to 8192 with an offset of -4096.
8353
8354 In cases where the LR% expression is identical to the RR% one we
8355 will never have a problem, but is so happens that gcc rounds
8356 addends involved in LR% field selectors to work around a HP
8357 linker bug. ie. We often have addresses like the last case
1cd1c99b
AM
8358 above where the LR% expression is offset from the RR% one. */
8359
252b5132
RH
8360 if (hppa_fix->fx_r_field == e_lrsel
8361 || hppa_fix->fx_r_field == e_rrsel
8362 || hppa_fix->fx_r_field == e_nlrsel)
8363 return 0;
252b5132
RH
8364
8365 /* Reject reductions of symbols in DLT relative relocs,
8366 relocations with plabels. */
8367 if (hppa_fix->fx_r_field == e_tsel
8368 || hppa_fix->fx_r_field == e_ltsel
8369 || hppa_fix->fx_r_field == e_rtsel
8370 || hppa_fix->fx_r_field == e_psel
8371 || hppa_fix->fx_r_field == e_rpsel
8372 || hppa_fix->fx_r_field == e_lpsel)
8373 return 0;
8374
904a31bf
AM
8375 if (fixp->fx_addsy && (S_IS_EXTERNAL (fixp->fx_addsy)
8376 || S_IS_WEAK (fixp->fx_addsy)))
252b5132
RH
8377 return 0;
8378
8379 /* Reject absolute calls (jumps). */
8380 if (hppa_fix->fx_r_type == R_HPPA_ABS_CALL)
8381 return 0;
8382
8383 /* Reject reductions of function symbols. */
a0f75b47 8384 if (fixp->fx_addsy == 0 || ! S_IS_FUNCTION (fixp->fx_addsy))
252b5132
RH
8385 return 1;
8386
8387 return 0;
8388}
8389
8390/* Return nonzero if the fixup in FIXP will require a relocation,
8391 even it if appears that the fixup could be completely handled
8392 within GAS. */
8393
8394int
8395hppa_force_relocation (fixp)
ad1079af 8396 struct fix *fixp;
252b5132
RH
8397{
8398 struct hppa_fix_struct *hppa_fixp;
8399 int distance;
8400
8401 hppa_fixp = (struct hppa_fix_struct *) fixp->tc_fix_data;
8402#ifdef OBJ_SOM
ad1079af
AM
8403 if (fixp->fx_r_type == (int) R_HPPA_ENTRY
8404 || fixp->fx_r_type == (int) R_HPPA_EXIT
8405 || fixp->fx_r_type == (int) R_HPPA_BEGIN_BRTAB
8406 || fixp->fx_r_type == (int) R_HPPA_END_BRTAB
8407 || fixp->fx_r_type == (int) R_HPPA_BEGIN_TRY
8408 || fixp->fx_r_type == (int) R_HPPA_END_TRY
252b5132
RH
8409 || (fixp->fx_addsy != NULL && fixp->fx_subsy != NULL
8410 && (hppa_fixp->segment->flags & SEC_CODE) != 0))
8411 return 1;
8412#endif
904a31bf
AM
8413#ifdef OBJ_ELF
8414 if (fixp->fx_r_type == (int) R_PARISC_GNU_VTINHERIT
8415 || fixp->fx_r_type == (int) R_PARISC_GNU_VTENTRY)
8416 return 1;
8417#endif
252b5132 8418
252b5132
RH
8419 /* It is necessary to force PC-relative calls/jumps to have a relocation
8420 entry if they're going to need either a argument relocation or long
8421 call stub. FIXME. Can't we need the same for absolute calls? */
8422 if (fixp->fx_pcrel && fixp->fx_addsy
ad1079af
AM
8423 && (arg_reloc_stub_needed (symbol_arg_reloc_info (fixp->fx_addsy),
8424 hppa_fixp->fx_arg_reloc)))
252b5132 8425 return 1;
ad1079af 8426
252b5132
RH
8427 distance = (fixp->fx_offset + S_GET_VALUE (fixp->fx_addsy)
8428 - md_pcrel_from (fixp));
8429 /* Now check and see if we're going to need a long-branch stub. */
ad1079af 8430 if (fixp->fx_r_type == (int) R_HPPA_PCREL_CALL
252b5132
RH
8431 && (distance > 262143 || distance < -262144))
8432 return 1;
8433
ad1079af 8434 if (fixp->fx_r_type == (int) R_HPPA_ABS_CALL)
252b5132 8435 return 1;
252b5132
RH
8436
8437 /* No need (yet) to force another relocations to be emitted. */
8438 return 0;
8439}
8440
8441/* Now for some ELF specific code. FIXME. */
8442#ifdef OBJ_ELF
8443/* Mark the end of a function so that it's possible to compute
8444 the size of the function in hppa_elf_final_processing. */
8445
8446static void
8447hppa_elf_mark_end_of_function ()
8448{
8449 /* ELF does not have EXIT relocations. All we do is create a
8450 temporary symbol marking the end of the function. */
ad1079af
AM
8451 char *name;
8452
8453 if (last_call_info == NULL || last_call_info->start_symbol == NULL)
8454 {
8455 /* We have already warned about a missing label,
8456 or other problems. */
8457 return;
8458 }
252b5132 8459
ad1079af
AM
8460 name = (char *) xmalloc (strlen ("L$\001end_")
8461 + strlen (S_GET_NAME (last_call_info->start_symbol))
8462 + 1);
252b5132
RH
8463 if (name)
8464 {
8465 symbolS *symbolP;
8466
8467 strcpy (name, "L$\001end_");
8468 strcat (name, S_GET_NAME (last_call_info->start_symbol));
8469
8470 /* If we have a .exit followed by a .procend, then the
8471 symbol will have already been defined. */
8472 symbolP = symbol_find (name);
8473 if (symbolP)
8474 {
8475 /* The symbol has already been defined! This can
8476 happen if we have a .exit followed by a .procend.
8477
8478 This is *not* an error. All we want to do is free
8479 the memory we just allocated for the name and continue. */
8480 xfree (name);
8481 }
8482 else
8483 {
8484 /* symbol value should be the offset of the
8485 last instruction of the function */
8486 symbolP = symbol_new (name, now_seg, (valueT) (frag_now_fix () - 4),
8487 frag_now);
8488
8489 assert (symbolP);
a0f75b47 8490 S_CLEAR_EXTERNAL (symbolP);
252b5132
RH
8491 symbol_table_insert (symbolP);
8492 }
8493
8494 if (symbolP)
8495 last_call_info->end_symbol = symbolP;
8496 else
8497 as_bad (_("Symbol '%s' could not be created."), name);
8498
8499 }
8500 else
8501 as_bad (_("No memory for symbol name."));
8502
8503}
8504
8505/* For ELF, this function serves one purpose: to setup the st_size
8506 field of STT_FUNC symbols. To do this, we need to scan the
8507 call_info structure list, determining st_size in by taking the
8508 difference in the address of the beginning/end marker symbols. */
8509
8510void
8511elf_hppa_final_processing ()
8512{
8513 struct call_info *call_info_pointer;
8514
8515 for (call_info_pointer = call_info_root;
8516 call_info_pointer;
8517 call_info_pointer = call_info_pointer->ci_next)
8518 {
8519 elf_symbol_type *esym
a0f75b47
ILT
8520 = ((elf_symbol_type *)
8521 symbol_get_bfdsym (call_info_pointer->start_symbol));
252b5132
RH
8522 esym->internal_elf_sym.st_size =
8523 S_GET_VALUE (call_info_pointer->end_symbol)
8524 - S_GET_VALUE (call_info_pointer->start_symbol) + 4;
8525 }
8526}
2d93dcc4 8527
ad1079af
AM
8528void
8529pa_end_of_source ()
2d93dcc4
JL
8530{
8531 if (debug_type == DEBUG_DWARF2)
8532 dwarf2_finish ();
8533}
904a31bf
AM
8534
8535static void
8536pa_vtable_entry (ignore)
8537 int ignore ATTRIBUTE_UNUSED;
8538{
8539 struct fix *new_fix;
8540
8541 new_fix = obj_elf_vtable_entry (0);
8542
8543 if (new_fix)
8544 {
8545 struct hppa_fix_struct *hppa_fix = (struct hppa_fix_struct *)
8546 obstack_alloc (&notes, sizeof (struct hppa_fix_struct));
8547 hppa_fix->fx_r_type = R_HPPA;
8548 hppa_fix->fx_r_field = e_fsel;
8549 hppa_fix->fx_r_format = 32;
8550 hppa_fix->fx_arg_reloc = 0;
8551 hppa_fix->segment = now_seg;
8552 new_fix->tc_fix_data = (void *) hppa_fix;
8553 new_fix->fx_r_type = (int) R_PARISC_GNU_VTENTRY;
8554 }
8555}
8556
8557static void
8558pa_vtable_inherit (ignore)
8559 int ignore ATTRIBUTE_UNUSED;
8560{
8561 struct fix *new_fix;
8562
8563 new_fix = obj_elf_vtable_inherit (0);
8564
8565 if (new_fix)
8566 {
8567 struct hppa_fix_struct *hppa_fix = (struct hppa_fix_struct *)
8568 obstack_alloc (&notes, sizeof (struct hppa_fix_struct));
8569 hppa_fix->fx_r_type = R_HPPA;
8570 hppa_fix->fx_r_field = e_fsel;
8571 hppa_fix->fx_r_format = 32;
8572 hppa_fix->fx_arg_reloc = 0;
8573 hppa_fix->segment = now_seg;
8574 new_fix->tc_fix_data = (void *) hppa_fix;
8575 new_fix->fx_r_type = (int) R_PARISC_GNU_VTINHERIT;
8576 }
8577}
2d93dcc4 8578#endif
This page took 0.648689 seconds and 4 git commands to generate.