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