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