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