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