1 /* tc-hppa.c -- Assemble for the PA
2 Copyright (C) 1989 Free Software Foundation, Inc.
4 This file is part of GAS, the GNU Assembler.
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)
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.
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. */
22 HP PA-RISC support was contributed by the Center for Software Science
23 at the University of Utah.
32 #include "../bfd/libhppa.h"
35 #include "../bfd/elf32-hppa.h"
39 * Unwind table and descriptor.
44 unsigned int cannot_unwind
:1;
45 unsigned int millicode
:1;
46 unsigned int millicode_save_rest
:1;
47 unsigned int region_desc
:2;
48 unsigned int save_sr
:2;
49 unsigned int entry_fr
:4; /* number saved */
50 unsigned int entry_gr
:5; /* number saved */
51 unsigned int args_stored
:1;
52 unsigned int call_fr
:5;
53 unsigned int call_gr
:5;
54 unsigned int save_sp
:1;
55 unsigned int save_rp
:1;
56 unsigned int save_rp_in_frame
:1;
57 unsigned int extn_ptr_defined
:1;
58 unsigned int cleanup_defined
:1;
60 unsigned int hpe_interrupt_marker
:1;
61 unsigned int hpux_interrupt_marker
:1;
62 unsigned int reserved
:3;
63 unsigned int frame_size
:27;
66 typedef struct unwind_desc unwind_descS
;
70 unsigned int start_offset
; /* starting offset (from SR4) of applicable region */
71 unsigned int end_offset
; /* ending offset (from SR4) of applicable region */
72 unwind_descS descriptor
;
75 typedef struct unwind_table unwind_tableS
;
78 * This structure is used by the .callinfo, .enter, .leave pseudo-ops to
79 * control the entry and exit code they generate. It is also used in
80 * creation of the correct stack unwind descriptors.
82 * The fields in structure roughly correspond to the arguments available on the
83 * .callinfo pseudo-op.
92 unwind_tableS ci_unwind
; /* the unwind descriptor we are building */
93 symbolS
*start_symbol
; /* name of function (used in relocation info) */
94 symbolS
*end_symbol
; /* temporary symbol used to mark the */
95 /* end of the function (used in */
96 /* relocation info) */
97 fragS
*start_frag
; /* frag associated w/ start of this function */
98 fragS
*end_frag
; /* frag associated w/ end of this function */
99 fragS
*start_offset_frag
; /* frag for start offset of this descriptor */
100 int start_frag_where
; /* where in start_offset_frag is start_offset */
101 fixS
*start_fix
; /* fixup for the start_offset */
102 fragS
*end_offset_frag
; /* frag for start offset of this descriptor */
103 int end_frag_where
; /* where in end_offset_frag is end_offset */
104 fixS
*end_fix
; /* fixup for the end_offset */
105 struct call_info
*ci_next
; /* the next call_info structure */
108 typedef struct call_info call_infoS
;
110 call_infoS
*last_call_info
;
111 call_infoS
*call_info_root
;
112 call_descS last_call_desc
;
114 /* A structure used during assembly of individual instructions */
119 unsigned long opcode
;
120 /* symbol_dictS *nlistp; *//*** used to be: struct nlist *nlistp; */
124 FP_Operand_Format fpof1
; /* Floating Point Operand Format, operand 1 */
125 FP_Operand_Format fpof2
; /* Floating Point Operand Format, operand 2 */
126 /* (used only for class 1 instructions -- */
127 /* the conversion instructions) */
136 elf32_hppa_reloc_type reloc
;
144 extern struct pa_it the_insn
;
146 /* careful, this file includes data *declarations* */
147 #include "opcode/hppa.h"
151 void md_number_to_chars ();
154 void md_convert_frag ();
155 void md_create_short_jump ();
156 void md_create_long_jump ();
157 int md_estimate_size_before_relax ();
158 void md_number_to_imm ();
159 void md_number_to_disp ();
160 void md_number_to_field ();
161 void md_ri_to_chars ();
162 void emit_relocations ();
163 static void pa_ip ();
164 static void hppa_tc_make_symextn_section ();
166 const relax_typeS md_relax_table
[] = {0};
167 /* handle of the OPCODE hash table */
168 static struct hash_control
*op_hash
= NULL
;
170 int md_short_jump_size
= 4;
171 int md_long_jump_size
= 4;
173 /* This array holds the chars that always start a comment. If the
174 pre-processor is disabled, these aren't very useful */
175 const char comment_chars
[] = ";"; /* JF removed '|' from comment_chars */
180 {"align", s_align_bytes
, 0}, /* .align 4 means .align to 4-byte boundary */
181 {"ALIGN", s_align_bytes
, 0}, /* .align 4 means .align to 4-byte boundary */
182 {"block", pa_block
, 1},
183 {"BLOCK", pa_block
, 1},
184 {"blockz", pa_block
, 0},
185 {"BLOCKZ", pa_block
, 0},
186 {"byte", pa_cons
, 1},
187 {"BYTE", pa_cons
, 1},
188 {"call", pa_call
, 0},
189 {"CALL", pa_call
, 0},
190 {"callinfo", pa_callinfo
, 0},
191 {"CALLINFO", pa_callinfo
, 0},
192 {"code", pa_code
, 0},
193 {"CODE", pa_code
, 0},
194 {"comm", pa_comm
, 0},
195 {"COMM", pa_comm
, 0},
196 {"copyright", pa_copyright
, 0},
197 {"COPYRIGHT", pa_copyright
, 0},
198 {"data", pa_data
, 0},
199 {"DATA", pa_data
, 0},
200 {"desc", pa_desc
, 0},
201 {"DESC", pa_desc
, 0},
202 {"double", pa_float_cons
, 'd'},
203 {"DOUBLE", pa_float_cons
, 'd'},
206 {"enter", pa_enter
, 0},
207 {"ENTER", pa_enter
, 0},
208 {"entry", pa_entry
, 0},
209 {"ENTRY", pa_entry
, 0},
212 {"exit", pa_exit
, 0},
213 {"EXIT", pa_exit
, 0},
214 {"export", pa_export
, 0},
215 {"EXPORT", pa_export
, 0},
216 {"fill", pa_fill
, 0},
217 {"FILL", pa_fill
, 0},
218 {"float", pa_float_cons
, 'f'},
219 {"FLOAT", pa_float_cons
, 'f'},
220 {"half", pa_cons
, 2},
221 {"HALF", pa_cons
, 2},
222 {"import", pa_import
, 0},
223 {"IMPORT", pa_import
, 0},
226 {"label", pa_label
, 0},
227 {"LABEL", pa_label
, 0},
228 {"lcomm", pa_lcomm
, 0},
229 {"LCOMM", pa_lcomm
, 0},
230 {"leave", pa_leave
, 0},
231 {"LEAVE", pa_leave
, 0},
232 {"long", pa_cons
, 4},
233 {"LONG", pa_cons
, 4},
234 {"lsym", pa_lsym
, 0},
235 {"LSYM", pa_lsym
, 0},
236 {"octa", pa_cons
, 16},
237 {"OCTA", pa_cons
, 16},
238 {"org", pa_origin
, 0},
239 {"ORG", pa_origin
, 0},
240 {"origin", pa_origin
, 0},
241 {"ORIGIN", pa_origin
, 0},
242 {"param", pa_param
, 0},
243 {"PARAM", pa_param
, 0},
244 {"proc", pa_proc
, 0},
245 {"PROC", pa_proc
, 0},
246 {"procend", pa_procend
, 0},
247 {"PROCEND", pa_procend
, 0},
248 {"quad", pa_cons
, 8},
249 {"QUAD", pa_cons
, 8},
250 {"reg", pa_equ
, 1}, /* very similar to .equ */
251 {"REG", pa_equ
, 1}, /* very similar to .equ */
252 {"short", pa_cons
, 2},
253 {"SHORT", pa_cons
, 2},
254 {"single", pa_float_cons
, 'f'},
255 {"SINGLE", pa_float_cons
, 'f'},
256 {"space", pa_space
, 0},
257 {"SPACE", pa_space
, 0},
258 {"spnum", pa_spnum
, 0},
259 {"SPNUM", pa_spnum
, 0},
260 {"string", pa_stringer
, 0},
261 {"STRING", pa_stringer
, 0},
262 {"stringz", pa_stringer
, 1},
263 {"STRINGZ", pa_stringer
, 1},
264 {"subspa", pa_subspace
, 0},
265 {"SUBSPA", pa_subspace
, 0},
266 {"text", pa_text
, 0},
267 {"TEXT", pa_text
, 0},
268 {"version", pa_version
, 0},
269 {"VERSION", pa_version
, 0},
270 {"word", pa_cons
, 4},
271 {"WORD", pa_cons
, 4},
275 /* This array holds the chars that only start a comment at the beginning of
276 a line. If the line seems to have the form '# 123 filename'
277 .line and .file directives will appear in the pre-processed output */
278 /* Note that input_file.c hand checks for '#' at the beginning of the
279 first line of the input file. This is because the compiler outputs
280 #NO_APP at the beginning of its output. */
281 /* Also note that '/*' will always start a comment */
282 const char line_comment_chars
[] = "#";
284 const char line_separator_chars
[] = "!";
286 /* Chars that can be used to separate mant from exp in floating point nums */
287 const char EXP_CHARS
[] = "eE";
289 /* Chars that mean this number is a floating point constant */
292 const char FLT_CHARS
[] = "rRsSfFdDxXpP";
294 /* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
295 changed in read.c . Ideally it shouldn't have to know about it at all,
296 but nothing is ideal around here.
299 static unsigned char octal
[256];
301 #define isoctal(c) octal[c]
303 static unsigned char toHex
[256];
305 struct pa_it set_insn
; /* this structure is defined above */
307 /* SKV 12/22/92. Added prev_insn, prev_fix, and initialized the_insn
308 so that we can recognize instruction sequences such as (ldil, ble)
309 and generate the appropriate fixups. */
311 struct pa_it the_insn
=
317 O_illegal
, /* exp.X_op */
318 NULL
, /* exp.X_add_symbol */
319 NULL
, /* exp.X_op_symbol */
320 0, /* exp.X_add_number */
326 0, /* field_selector */
330 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
336 struct pa_it prev_insn
;
337 char prev_str
[10] = "";
338 fixS
*prev_fix
= NULL
;
339 fixS
*curr_fix
= NULL
;
344 void print_insn (struct pa_it
*insn
);
350 static symbolS
*label_symbolP
; /* the last label symbol encountered */
351 /* saved here in case a .equ is encountered */
352 static int label_symbol_defined
;
354 /* T if a .callinfo appeared within the current procedure definition
356 static int callinfo_found
;
358 /* T if the assembler is currently within a .entry/.exit pair and F
360 static int within_entry_exit
;
362 /* T is the assembler has completed exit processing for the current
363 procedure and F otherwise. */
364 static int exit_processing_complete
;
366 /* T if the assembler is currently within a procedure definition and
368 static int within_procedure
;
370 void ignore_rest_of_line (); /* a useful function in read.c */
372 /* default space and subspace dictionaries */
374 #define GDB_SYMBOLS GDB_SYMBOLS_SUBSPACE_NAME
375 #define GDB_STRINGS GDB_STRINGS_SUBSPACE_NAME
378 static struct default_subspace_dict pa_def_subspaces
[] =
380 {"$CODE$", 0, 1, 0, 0, 0, 0, 24, 0x2c, 0, 8, 0, 0, ".text", SUBSEG_CODE
},
381 {"$DATA$", 0, 1, 0, 0, 0, 0, 24, 0x1f, 0, 8, 1, 1, ".data", SUBSEG_DATA
},
382 {"$LIT$", 0, 1, 0, 0, 0, 0, 16, 0x2c, 0, 8, 0, 0, ".text", SUBSEG_LIT
},
383 {"$BSS$", 0, 1, 0, 0, 0, 1, 80, 0x1f, 0, 8, 1, 1, ".bss", SUBSEG_BSS
},
384 {"$UNWIND$", 0, 1, 0, 0, 0, 0, 64, 0x2c, 0, 4, 0, 0, ".hppa_unwind", SUBSEG_UNWIND
},
385 {NULL
, 0, 1, 0, 0, 0, 0, 255, 0x1f, 0, 4, 0, 0, 0, 0}
388 static struct default_space_dict pa_def_spaces
[] =
390 {"$TEXT$", 0, 1, 0, 0, 8, ASEC_NULL
, ".text"},
391 {"$PRIVATE$", 0, 1, 0, 0, 16, ASEC_NULL
, ".data"},
392 {NULL
, 0, 0, 0, 0, 0, ASEC_NULL
, NULL
}
395 static struct default_subspace_dict pa_def_subspaces
[] =
397 {"$CODE$", 0, 1, 0, 0, 0, 0, 24, 0x2c, 0, 8, 0, SEG_TEXT
, SUBSEG_CODE
},
398 {"$DATA$", 0, 1, 0, 0, 0, 0, 24, 0x1f, 0, 8, 1, SEG_DATA
, SUBSEG_DATA
},
399 {"$LIT$", 0, 1, 0, 0, 0, 0, 16, 0x2c, 0, 8, 0, SEG_TEXT
, SUBSEG_LIT
},
400 {"$BSS$", 0, 1, 0, 0, 0, 1, 80, 0x1f, 0, 8, 1, SEG_DATA
, SUBSEG_BSS
},
401 {"$UNWIND$", 0, 1, 0, 0, 0, 0, 64, 0x2c, 0, 4, 0, SEG_TEXT
, SUBSEG_UNWIND
},
402 {GDB_STRINGS
, 0, 0, 0, 0, 0, 0, 254, 0x1f, 0, 4, 0, SEG_GDB
, SUBSEG_GDB_STRINGS
},
403 {GDB_SYMBOLS
, 0, 0, 0, 0, 0, 0, 255, 0x1f, 0, 4, 0, SEG_GDB
, SUBSEG_GDB_SYMBOLS
},
404 {NULL
, 0, 1, 0, 0, 0, 0, 255, 0x1f, 0, 4, 0, SEG_GOOF
, 0}
407 static struct default_space_dict pa_def_spaces
[] =
409 {"$TEXT$", 0, 1, 0, 0, 8, SEG_TEXT
},
410 {"$PRIVATE$", 0, 1, 0, 0, 16, SEG_DATA
},
411 {GDB_DEBUG_SPACE_NAME
, 0, 0, 0, 0, 255, SEG_GDB
},
412 {NULL
, 0, 0, 0, 0, 0, SEG_GOOF
}
418 #define TRUE (!FALSE)
419 #endif /* no FALSE yet */
422 Support for keeping track of the most recent label in each
427 PA_PSEUDO_OP_MOVES_PC
429 A predicate that returns true if the pseudo-operation or
430 assembly directive results in a movement in the current
431 location. All instructions cause movement in the current
435 static const char *const movers
[] =
437 /* these entries from 'static pseudo_typeS potable[]' in pa-read.c */
441 "data", "desc", "double",
446 "lcomm", "long", "lsym",
452 /* these entries from 'pseudo_typeS md_pseudo_table[]' in pa-aux.c */
457 "reg", /* very similar to .equ */
460 NULL
/* end sentinel */
464 pa_pseudo_op_moves_pc (name
)
470 if (strcmp (name
, movers
[i
++]) == 0)
477 /* Support for keeping track of the most recent label in each
480 /* XXX: NOTE: label_symbolS is defined in pa.h */
482 static label_symbolS
*label_symbols_rootP
;
487 Returns a pointer to the label_symbolS for the current space.
490 static label_symbolS
*
494 space_dict_chainS
*now_sdcP
= pa_segment_to_space (now_seg
);
496 for (lssP
= label_symbols_rootP
; lssP
; lssP
= lssP
->lss_next
)
498 if (now_sdcP
== lssP
->lss_space
&& lssP
->lss_label
)
502 return (label_symbolS
*) NULL
;
508 A predicate to determine whether a useable label is defined in
513 pa_label_is_defined ()
515 return (int) pa_get_label ();
521 Defines a label for the current space. If one is already defined,
522 this function will replace it with the new label.
526 pa_define_label (symbolP
)
529 label_symbolS
*lssP
= pa_get_label ();
530 space_dict_chainS
*now_sdcP
= pa_segment_to_space (now_seg
);
534 lssP
->lss_label
= symbolP
;
538 lssP
= (label_symbolS
*) xmalloc (sizeof (label_symbolS
));
539 lssP
->lss_label
= symbolP
;
540 lssP
->lss_space
= now_sdcP
;
541 lssP
->lss_next
= (label_symbolS
*) NULL
;
543 if (label_symbols_rootP
)
545 lssP
->lss_next
= label_symbols_rootP
;
547 label_symbols_rootP
= lssP
;
554 Removes a label definition for the current space.
555 If there is no label_symbolS entry, then no action is taken.
562 label_symbolS
*prevP
= (label_symbolS
*) NULL
;
563 space_dict_chainS
*now_sdcP
= pa_segment_to_space (now_seg
);
565 for (lssP
= label_symbols_rootP
; lssP
; lssP
= lssP
->lss_next
)
567 if (now_sdcP
== lssP
->lss_space
&& lssP
->lss_label
)
570 prevP
->lss_next
= lssP
->lss_next
;
572 label_symbols_rootP
= lssP
->lss_next
;
581 /* end of label symbol support. */
584 /* An HPPA-specific version of fix_new. This is required because the HPPA
585 code needs to keep track of some extra stuff. Each call to fix_new_hppa
586 results in the creation of an instance of an hppa_fixS. An hppa_fixS
587 stores the extra information along with a pointer to the original fixS. */
589 typedef struct hppa_fix_struct
596 call_infoS
*fx_call_infop
;
598 struct hppa_fix_struct
*fx_next
;
601 static hppa_fixS
*hppa_fix_root
;
604 fix_new_hppa (frag
, where
, size
, add_symbol
, offset
, exp
, pcrel
,
605 r_type
, r_field
, r_format
, arg_reloc
, unwind_desc
)
606 fragS
*frag
; /* Which frag? */
607 int where
; /* Where in that frag? */
608 short int size
; /* 1, 2 or 4 usually. */
609 symbolS
*add_symbol
; /* X_add_symbol. */
610 long offset
; /* X_add_number. */
611 expressionS
*exp
; /* expression (if non-null) */
612 int pcrel
; /* TRUE if PC-relative relocation. */
614 bfd_reloc_code_real_type r_type
; /* Relocation type */
616 int r_type
; /* Relocation type */
618 long r_field
; /* F, R, L, etc */
619 int r_format
; /* 11,12,14,17,21,32, etc */
625 hppa_fixS
*hppa_fix
= (hppa_fixS
*) obstack_alloc (¬es
, sizeof (hppa_fixS
));
628 new_fix
= fix_new_exp (frag
, where
, size
, exp
, pcrel
, r_type
);
630 new_fix
= fix_new (frag
, where
, size
, add_symbol
, offset
, pcrel
, r_type
);
631 hppa_fix
->fx_fixP
= new_fix
;
632 hppa_fix
->fx_r_field
= r_field
;
633 hppa_fix
->fx_r_format
= r_format
;
634 hppa_fix
->fx_arg_reloc
= arg_reloc
;
635 hppa_fix
->fx_next
= (hppa_fixS
*) 0;
636 hppa_fix
->fx_call_infop
= last_call_info
;
638 bcopy (unwind_desc
, hppa_fix
->fx_unwind
, 8);
641 hppa_fix
->fx_next
= hppa_fix_root
;
643 hppa_fix_root
= hppa_fix
;
645 /* SKV 12/22/92. Added prev_insn, prev_fix, and initialized the_insn
646 so that we can recognize instruction sequences such as (ldil, ble)
647 and generate the appropriate fixups. */
656 /* Parse a .byte, .word, .long expression for the HPPA. Called by
657 cons via the TC_PARSE_CONS_EXPRESSION macro. */
659 static int hppa_field_selector
;
662 parse_cons_expression_hppa (exp
)
665 hppa_field_selector
= pa_chk_field_selector (&input_line_pointer
);
669 /* This fix_new is called by cons via TC_CONS_FIX_NEW.
670 hppa_field_selector is set by the parse_cons_expression_hppa. */
673 cons_fix_new_hppa (frag
, where
, size
, exp
)
674 fragS
*frag
; /* Which frag? */
675 int where
; /* Where in that frag? */
676 int size
; /* 1, 2 or 4 usually. */
677 expressionS
*exp
; /* Expression. */
679 unsigned int reloc_type
;
681 if (is_DP_relative (*exp
))
682 reloc_type
= R_HPPA_GOTOFF
;
683 else if (is_complex (*exp
))
684 reloc_type
= R_HPPA_COMPLEX
;
688 if (hppa_field_selector
!= e_psel
&& hppa_field_selector
!= e_fsel
)
689 as_warn("Invalid field selector. Assuming F%%.");
691 fix_new_hppa (frag
, where
, size
,
692 (symbolS
*) NULL
, (offsetT
) 0, exp
, 0, reloc_type
,
693 hppa_field_selector
, 32, 0, (char *) 0);
696 /* Given a FixS, find the hppa_fixS associated with it. */
698 hppa_find_hppa_fix (fix
)
703 for (hfP
= hppa_fix_root
; hfP
; hfP
= hfP
->fx_next
)
705 if (hfP
->fx_fixP
== fix
)
709 return (hppa_fixS
*) 0;
712 /* This function is called once, at assembler startup time. It should
713 set up all the tables, etc. that the MD part of the assembler will need. */
717 register char *retval
= NULL
;
719 register unsigned int i
= 0;
720 void pa_spaces_begin (); /* forward declaration */
722 last_call_info
= NULL
;
723 call_info_root
= NULL
;
727 op_hash
= hash_new ();
729 as_fatal ("Virtual memory exhausted");
731 while (i
< NUMOPCODES
)
733 const char *name
= pa_opcodes
[i
].name
;
734 retval
= hash_insert (op_hash
, name
, &pa_opcodes
[i
]);
737 as_fatal ("Internal error: can't hash `%s': %s\n",
738 pa_opcodes
[i
].name
, retval
);
743 if ((pa_opcodes
[i
].match
& pa_opcodes
[i
].mask
) != pa_opcodes
[i
].match
)
745 fprintf (stderr
, "internal error: losing opcode: `%s' \"%s\"\n",
746 pa_opcodes
[i
].name
, pa_opcodes
[i
].args
);
751 while (i
< NUMOPCODES
752 && !strcmp (pa_opcodes
[i
].name
, name
));
756 as_fatal ("Broken assembler. No assembly attempted.");
758 for (i
= '0'; i
< '8'; ++i
)
760 for (i
= '0'; i
<= '9'; ++i
)
762 for (i
= 'a'; i
<= 'f'; ++i
)
763 toHex
[i
] = i
+ 10 - 'a';
764 for (i
= 'A'; i
<= 'F'; ++i
)
765 toHex
[i
] = i
+ 10 - 'A';
784 /* put out the opcode */
785 md_number_to_chars (toP
, the_insn
.opcode
, 4);
787 /* put out the symbol-dependent stuff */
788 #if defined ( OBJ_SOM )
789 if (the_insn
.reloc
!= R_NO_RELOCATION
)
792 #if defined ( OBJ_ELF )
793 if (the_insn
.reloc
!= R_HPPA_NONE
)
799 fix_new_hppa (frag_now
, /* which frag */
800 (toP
- frag_now
->fr_literal
), /* where */
807 the_insn
.field_selector
,
813 fix_new (frag_now
, /* which frag */
814 (toP
- frag_now
->fr_literal
), /* where */
821 the_insn
.field_selector
,
828 /* SKV 12/22/92. Added prev_insn, prev_fix, and initialized the_insn
829 so that we can recognize instruction sequences such as (ldil, ble)
830 and generate the appropriate fixups. */
834 prev_insn
= the_insn
;
835 strncpy (prev_str
, str
, 10);
836 if (prev_insn
.reloc
== R_HPPA_NONE
)
852 char *error_message
= "";
857 struct pa_opcode
*insn
;
859 unsigned long opcode
;
863 unsigned int im21
, im14
, im11
, im5
;
865 int cmpltr
, nullif
, flag
;
871 fprintf (stderr
, "STATEMENT: \"%s\"\n", str
);
873 for (s
= str
; isupper (*s
) || islower (*s
) || (*s
>= '0' && *s
<= '3'); ++s
)
891 as_bad ("Unknown opcode: `%s'", str
);
899 if (isupper (*save_s
))
900 *save_s
= tolower (*save_s
);
904 if ((insn
= (struct pa_opcode
*) hash_find (op_hash
, str
)) == NULL
)
906 as_bad ("Unknown opcode: `%s'", str
);
916 opcode
= insn
->match
;
917 bzero (&the_insn
, sizeof (the_insn
));
918 #if defined( OBJ_SOM )
919 the_insn
.reloc
= R_NO_RELOCATION
;
921 #if defined ( OBJ_ELF )
922 the_insn
.reloc
= R_HPPA_NONE
;
926 * Build the opcode, checking as we go to make
927 * sure that the operands match
929 for (args
= insn
->args
;; ++args
)
935 case '\0': /* end of args */
954 case '(': /* these must match exactly */
962 case 'b': /* 5 bit register field at 10 */
963 case '^': /* 5 bit control register field at 10 */
964 reg
= pa_parse_number (&s
);
965 if (reg
< 32 && reg
>= 0)
971 case 'x': /* 5 bit register field at 15 */
972 reg
= pa_parse_number (&s
);
973 if (reg
< 32 && reg
>= 0)
980 case 'y': /* Same as 't'. */
981 case 't': /* 5 bit register field at 31 */
982 reg
= pa_parse_number (&s
);
983 if (reg
< 32 && reg
>= 0)
989 case 'T': /* 5 bit field length at 31 (encoded as 32-T) */
991 reg = pa_parse_number(&s);
993 getAbsoluteExpression (s
);
994 if (the_insn
.exp
.X_op
== O_constant
)
996 reg
= the_insn
.exp
.X_add_number
;
997 if (reg
<= 32 && reg
> 0)
1005 case '5': /* 5 bit immediate at 15 */
1006 getAbsoluteExpression (s
);
1007 /** PJH: The following 2 calls to as_bad() might eventually **/
1008 /** want to end up as as_warn(). **/
1009 if (the_insn
.exp
.X_add_number
> 15)
1011 as_bad ("5 bit immediate > 15. Set to 15",
1012 the_insn
.exp
.X_add_number
);
1013 the_insn
.exp
.X_add_number
= 15;
1015 else if (the_insn
.exp
.X_add_number
< -16)
1017 as_bad ("5 bit immediate < -16. Set to -16",
1018 the_insn
.exp
.X_add_number
);
1019 the_insn
.exp
.X_add_number
= -16;
1022 low_sign_unext (evaluateAbsolute (the_insn
.exp
, the_insn
.field_selector
),
1024 opcode
|= (im5
<< 16);
1028 case 's': /* 2 bit space identifier at 17 */
1029 s2
= pa_parse_number (&s
);
1030 if (s2
< 4 && s2
>= 0)
1036 case 'S': /* 3 bit space identifier at 18 */
1037 s3
= pa_parse_number (&s
);
1038 if (s3
< 8 && s3
>= 0)
1040 dis_assemble_3 (s3
, &s3
);
1045 case 'c': /* indexed load completer. */
1049 while (*s
== ',' && i
< 2)
1052 if (strncasecmp (s
, "sm", 2) == 0)
1059 else if (strncasecmp (s
, "m", 1) == 0)
1061 else if (strncasecmp (s
, "s", 1) == 0)
1064 as_bad ("Unrecognized Indexed Load Completer...assuming 0");
1069 as_bad ("Illegal Indexed Load Completer Syntax...extras ignored");
1071 while (*s
== ' ' || *s
== '\t')
1077 case 'C': /* short load and store completer */
1083 if (strncasecmp (s
, "ma", 2) == 0)
1088 else if (strncasecmp (s
, "mb", 2) == 0)
1094 as_bad ("Unrecognized Indexed Load Completer...assuming 0");
1098 while (*s
== ' ' || *s
== '\t')
1103 case 'Y': /* Store Bytes Short completer */
1107 while (*s
== ',' && i
< 2)
1110 if (strncasecmp (s
, "m", 1) == 0)
1112 else if (strncasecmp (s
, "b", 1) == 0)
1114 else if (strncasecmp (s
, "e", 1) == 0)
1117 as_bad ("Unrecognized Store Bytes Short Completer...assuming 0");
1121 /** if ( i >= 2 ) **/
1123 as_bad ("Illegal Store Bytes Short Completer...extras ignored");
1124 while (*s
== ' ' || *s
== '\t') /* skip to next operand */
1129 case '<': /* non-negated compare/subtract conditions. */
1130 cmpltr
= pa_parse_nonneg_cmpsub_cmpltr (&s
, 1);
1133 as_bad ("Unrecognized Compare/Subtract Condition: %c", *s
);
1136 opcode
|= cmpltr
<< 13;
1138 case '?': /* negated or non-negated cmp/sub conditions. */
1139 /* used only by ``comb'' and ``comib'' pseudo-ops */
1141 cmpltr
= pa_parse_nonneg_cmpsub_cmpltr (&s
, 1);
1145 cmpltr
= pa_parse_neg_cmpsub_cmpltr (&s
, 1);
1148 as_bad ("Unrecognized Compare/Subtract Condition: %c", *s
);
1153 opcode
|= 1 << 27; /* required opcode change to make
1154 COMIBT into a COMIBF or a
1155 COMBT into a COMBF or a
1156 ADDBT into a ADDBF or a
1157 ADDIBT into a ADDIBF */
1160 opcode
|= cmpltr
<< 13;
1162 case '!': /* negated or non-negated add conditions. */
1163 /* used only by ``addb'' and ``addib'' pseudo-ops */
1165 cmpltr
= pa_parse_nonneg_add_cmpltr (&s
, 1);
1169 cmpltr
= pa_parse_neg_add_cmpltr (&s
, 1);
1172 as_bad ("Unrecognized Compare/Subtract Condition: %c", *s
);
1177 opcode
|= 1 << 27; /* required opcode change to make
1178 COMIBT into a COMIBF or a
1179 COMBT into a COMBF or a
1180 ADDBT into a ADDBF or a
1181 ADDIBT into a ADDIBF */
1184 opcode
|= cmpltr
<< 13;
1186 case 'a': /* compare/subtract conditions */
1192 cmpltr
= pa_parse_nonneg_cmpsub_cmpltr (&s
, 0);
1197 cmpltr
= pa_parse_neg_cmpsub_cmpltr (&s
, 0);
1200 as_bad ("Unrecognized Compare/Subtract Condition");
1204 opcode
|= cmpltr
<< 13;
1207 case 'd': /* non-negated add conditions */
1215 while (*s
!= ',' && *s
!= ' ' && *s
!= '\t')
1219 if (strcmp (name
, "=") == 0)
1223 else if (strcmp (name
, "<") == 0)
1227 else if (strcmp (name
, "<=") == 0)
1231 else if (strcasecmp (name
, "nuv") == 0)
1235 else if (strcasecmp (name
, "znv") == 0)
1239 else if (strcasecmp (name
, "sv") == 0)
1243 else if (strcasecmp (name
, "od") == 0)
1247 else if (strcasecmp (name
, "n") == 0)
1251 else if (strcasecmp (name
, "tr") == 0)
1256 else if (strcasecmp (name
, "<>") == 0)
1261 else if (strcasecmp (name
, ">=") == 0)
1266 else if (strcasecmp (name
, ">") == 0)
1271 else if (strcasecmp (name
, "uv") == 0)
1276 else if (strcasecmp (name
, "vnz") == 0)
1281 else if (strcasecmp (name
, "nsv") == 0)
1286 else if (strcasecmp (name
, "ev") == 0)
1292 as_bad ("Unrecognized Add Condition: %s", name
);
1295 nullif
= pa_parse_nullif (&s
);
1296 opcode
|= nullif
<< 1;
1297 opcode
|= cmpltr
<< 13;
1298 opcode
|= flag
<< 12;
1300 case '&': /* logical instruction conditions */
1307 while (*s
!= ',' && *s
!= ' ' && *s
!= '\t')
1311 if (strcmp (name
, "=") == 0)
1315 else if (strcmp (name
, "<") == 0)
1319 else if (strcmp (name
, "<=") == 0)
1323 else if (strcasecmp (name
, "od") == 0)
1327 else if (strcasecmp (name
, "tr") == 0)
1332 else if (strcmp (name
, "<>") == 0)
1337 else if (strcmp (name
, ">=") == 0)
1342 else if (strcmp (name
, ">") == 0)
1347 else if (strcasecmp (name
, "ev") == 0)
1353 as_bad ("Unrecognized Logical Instruction Condition: %s", name
);
1356 opcode
|= cmpltr
<< 13;
1359 case 'U': /* unit instruction conditions */
1365 if (strncasecmp (s
, "sbz", 3) == 0)
1370 else if (strncasecmp (s
, "shz", 3) == 0)
1375 else if (strncasecmp (s
, "sdc", 3) == 0)
1380 else if (strncasecmp (s
, "sbc", 3) == 0)
1385 else if (strncasecmp (s
, "shc", 3) == 0)
1390 else if (strncasecmp (s
, "tr", 2) == 0)
1396 else if (strncasecmp (s
, "nbz", 3) == 0)
1402 else if (strncasecmp (s
, "nhz", 3) == 0)
1408 else if (strncasecmp (s
, "ndc", 3) == 0)
1414 else if (strncasecmp (s
, "nbc", 3) == 0)
1420 else if (strncasecmp (s
, "nhc", 3) == 0)
1427 as_bad ("Unrecognized Logical Instruction Condition: %c", *s
);
1429 opcode
|= cmpltr
<< 13;
1432 case '|': /* shift/extract/deposit in conditional. */
1433 case '>': /* shift/extract/deposit conditions. */
1439 while (*s
!= ',' && *s
!= ' ' && *s
!= '\t')
1443 if (strcmp (name
, "=") == 0)
1447 else if (strcmp (name
, "<") == 0)
1451 else if (strcasecmp (name
, "od") == 0)
1455 else if (strcasecmp (name
, "tr") == 0)
1459 else if (strcmp (name
, "<>") == 0)
1463 else if (strcmp (name
, ">=") == 0)
1467 else if (strcasecmp (name
, "ev") == 0)
1471 /* Handle movb,n. Put things back the way they were.
1472 This includes moving s back to where it started. */
1473 else if (strcasecmp (name
, "n") == 0 && *args
== '|')
1480 as_bad ("Unrecognized Shift/Extract/Deposit Condition: %s", name
);
1483 opcode
|= cmpltr
<< 13;
1485 case '~': /* bvb,bb conditions */
1490 if (strncmp (s
, "<", 1) == 0)
1495 else if (strncmp (s
, ">=", 2) == 0)
1501 as_bad ("Unrecognized Bit Branch Condition: %c", *s
);
1503 opcode
|= cmpltr
<< 13;
1505 case 'V': /* 5 bit immediate at 31 */
1507 low_sign_unext (evaluateAbsolute (the_insn
.exp
, the_insn
.field_selector
),
1512 case 'r': /* 5 bit immediate at 31 */
1513 /* (unsigned value for the break instruction) */
1515 im5
= evaluateAbsolute (the_insn
.exp
, the_insn
.field_selector
);
1518 as_bad ("Operand out of range. Was: %d. Should be [0..31]. Assuming %d.\n", im5
, im5
& 0x1f);
1524 case 'R': /* 5 bit immediate at 15 */
1525 /* (unsigned value for the ssm and rsm instruction) */
1527 im5
= evaluateAbsolute (the_insn
.exp
, the_insn
.field_selector
);
1530 as_bad ("Operand out of range. Was: %d. Should be [0..31]. Assuming %d.\n", im5
, im5
& 0x1f);
1533 opcode
|= im5
<< 16;
1536 case 'i': /* 11 bit immediate at 31 */
1539 if (the_insn
.exp
.X_op
== O_constant
)
1541 low_sign_unext (evaluateAbsolute (the_insn
.exp
, the_insn
.field_selector
),
1547 the_insn
.reloc
= R_CODE_ONE_SYMBOL
;
1548 the_insn
.code
= 'i';
1549 the_insn
.field_selector
= the_insn
.exp
.field_selector
;
1554 the_insn
.field_selector
= pa_chk_field_selector (&s
);
1556 if (the_insn
.exp
.X_op
== O_constant
)
1558 low_sign_unext (evaluateAbsolute (the_insn
.exp
, the_insn
.field_selector
),
1564 if (is_DP_relative (the_insn
.exp
))
1565 the_insn
.reloc
= R_HPPA_GOTOFF
;
1566 else if (is_PC_relative (the_insn
.exp
))
1567 the_insn
.reloc
= R_HPPA_PCREL_CALL
;
1568 else if (is_complex (the_insn
.exp
))
1569 the_insn
.reloc
= R_HPPA_COMPLEX
;
1571 the_insn
.reloc
= R_HPPA
;
1572 the_insn
.format
= 11;
1577 case 'j': /* 14 bit immediate at 31 */
1580 if (the_insn
.exp
.X_op
== O_constant
)
1582 low_sign_unext (evaluateAbsolute (the_insn
.exp
, field_selector
),
1584 if (the_insn
.exp
.field_selector
== e_rsel
)
1585 opcode
|= (im14
& 0xfff);
1591 the_insn
.reloc
= R_CODE_ONE_SYMBOL
;
1592 the_insn
.code
= 'j';
1593 the_insn
.field_selector
= the_insn
.exp
.field_selector
;
1598 the_insn
.field_selector
= pa_chk_field_selector (&s
);
1600 if (the_insn
.exp
.X_op
== O_constant
)
1602 low_sign_unext (evaluateAbsolute (the_insn
.exp
, the_insn
.field_selector
),
1604 if (the_insn
.field_selector
== e_rsel
)
1605 opcode
|= (im14
& 0xfff);
1611 if (is_DP_relative (the_insn
.exp
))
1612 the_insn
.reloc
= R_HPPA_GOTOFF
;
1613 else if (is_PC_relative (the_insn
.exp
))
1614 the_insn
.reloc
= R_HPPA_PCREL_CALL
;
1615 else if (is_complex (the_insn
.exp
))
1616 the_insn
.reloc
= R_HPPA_COMPLEX
;
1618 the_insn
.reloc
= R_HPPA
;
1619 the_insn
.format
= 14;
1625 case 'k': /* 21 bit immediate at 31 */
1628 if (the_insn
.exp
.X_op
== O_constant
)
1630 dis_assemble_21 (evaluateAbsolute (the_insn
.exp
, the_insn
.field_selector
),
1636 the_insn
.reloc
= R_CODE_ONE_SYMBOL
;
1637 the_insn
.code
= 'k';
1638 the_insn
.field_selector
= the_insn
.exp
.field_selector
;
1643 the_insn
.field_selector
= pa_chk_field_selector (&s
);
1645 if (the_insn
.exp
.X_op
== O_constant
)
1647 dis_assemble_21 (evaluateAbsolute (the_insn
.exp
, the_insn
.field_selector
),
1653 if (is_DP_relative (the_insn
.exp
))
1654 the_insn
.reloc
= R_HPPA_GOTOFF
;
1655 else if (is_PC_relative (the_insn
.exp
))
1656 the_insn
.reloc
= R_HPPA_PCREL_CALL
;
1657 else if (is_complex (the_insn
.exp
))
1658 the_insn
.reloc
= R_HPPA_COMPLEX
;
1660 the_insn
.reloc
= R_HPPA
;
1661 the_insn
.format
= 21;
1667 case 'n': /* nullification for branch instructions */
1668 nullif
= pa_parse_nullif (&s
);
1669 opcode
|= nullif
<< 1;
1671 case 'w': /* 12 bit branch displacement */
1675 if (strcmp (the_insn
.exp
.X_add_symbol
->sy_nlist
.n_un
.n_name
, "L0\001") == 0)
1677 unsigned int w1
, w
, result
;
1679 sign_unext ((the_insn
.exp
.X_add_number
- 8) >> 2, 12, &result
);
1680 dis_assemble_12 (result
, &w1
, &w
);
1681 opcode
|= ((w1
<< 2) | w
);
1682 the_insn
.exp
.X_add_symbol
->sy_ref
= FALSE
;
1686 /* this has to be wrong -- dont know what is right! */
1687 the_insn
.reloc
= R_PCREL_CALL
;
1688 the_insn
.code
= 'w';
1689 the_insn
.field_selector
= the_insn
.exp
.field_selector
;
1690 the_insn
.arg_reloc
= last_call_desc
.arg_reloc
;
1691 bzero (&last_call_desc
, sizeof (call_descS
));
1696 the_insn
.field_selector
= pa_chk_field_selector (&s
);
1699 if (strcmp (S_GET_NAME (the_insn
.exp
.X_add_symbol
), "L0\001") == 0)
1701 unsigned int w1
, w
, result
;
1703 sign_unext ((the_insn
.exp
.X_add_number
- 8) >> 2, 12, &result
);
1704 dis_assemble_12 (result
, &w1
, &w
);
1705 opcode
|= ((w1
<< 2) | w
);
1706 /* the_insn.exp.X_add_symbol->sy_ref = FALSE; *//* XXX: not sure how to do this in BFD */
1710 if (is_complex (the_insn
.exp
))
1711 the_insn
.reloc
= R_HPPA_COMPLEX_PCREL_CALL
;
1713 the_insn
.reloc
= R_HPPA_PCREL_CALL
;
1714 the_insn
.format
= 12;
1715 the_insn
.arg_reloc
= last_call_desc
.arg_reloc
;
1716 bzero (&last_call_desc
, sizeof (call_descS
));
1721 case 'W': /* 17 bit branch displacement */
1722 #if defined(OBJ_ELF)
1723 the_insn
.field_selector
= pa_chk_field_selector (&s
);
1728 if (strcmp (the_insn
.exp
.X_add_symbol
->sy_nlist
.n_un
.n_name
, "L0\001") == 0)
1730 unsigned int w2
, w1
, w
, result
;
1732 sign_unext ((the_insn
.exp
.X_add_number
- 8) >> 2, 17, &result
);
1733 dis_assemble_17 (result
, &w1
, &w2
, &w
);
1734 opcode
|= ((w2
<< 2) | (w1
<< 16) | w
);
1735 the_insn
.exp
.X_add_symbol
->sy_ref
= FALSE
;
1739 /* this has to be wrong -- dont know what is right! */
1740 the_insn
.reloc
= R_PCREL_CALL
;
1741 the_insn
.code
= 'W';
1742 the_insn
.field_selector
= the_insn
.exp
.field_selector
;
1743 the_insn
.arg_reloc
= last_call_desc
.arg_reloc
;
1744 bzero (&last_call_desc
, sizeof (call_descS
));
1747 if (the_insn
.exp
.X_add_symbol
)
1749 if (strcmp (S_GET_NAME (the_insn
.exp
.X_add_symbol
), "L0\001") == 0)
1751 unsigned int w2
, w1
, w
, result
;
1753 sign_unext ((the_insn
.exp
.X_add_number
- 8) >> 2, 17, &result
);
1754 dis_assemble_17 (result
, &w1
, &w2
, &w
);
1755 opcode
|= ((w2
<< 2) | (w1
<< 16) | w
);
1759 if (is_complex (the_insn
.exp
))
1760 the_insn
.reloc
= R_HPPA_COMPLEX_PCREL_CALL
;
1762 the_insn
.reloc
= R_HPPA_PCREL_CALL
;
1763 the_insn
.format
= 17;
1764 the_insn
.arg_reloc
= last_call_desc
.arg_reloc
;
1765 bzero (&last_call_desc
, sizeof (call_descS
));
1770 unsigned int w2
, w1
, w
, result
;
1772 sign_unext (the_insn
.exp
.X_add_number
>> 2, 17, &result
);
1773 dis_assemble_17 (result
, &w1
, &w2
, &w
);
1774 opcode
|= ((w2
<< 2) | (w1
<< 16) | w
);
1779 case 'z': /* 17 bit branch displacement (not pc-relative) */
1780 #if defined(OBJ_ELF)
1781 the_insn
.field_selector
= pa_chk_field_selector (&s
);
1786 if (strcmp (the_insn
.exp
.X_add_symbol
->sy_nlist
.n_un
.n_name
, "L0\001") == 0)
1788 unsigned int w2
, w1
, w
, result
;
1790 sign_unext ((the_insn
.exp
.X_add_number
- 8) >> 2, 17, &result
);
1791 dis_assemble_17 (result
, &w1
, &w2
, &w
);
1792 opcode
|= ((w2
<< 2) | (w1
<< 16) | w
);
1793 the_insn
.exp
.X_add_symbol
->sy_ref
= FALSE
;
1797 /* this has to be wrong -- dont know what is right! */
1798 the_insn
.reloc
= R_PCREL_CALL
;
1799 the_insn
.code
= 'W';
1800 the_insn
.field_selector
= the_insn
.exp
.field_selector
;
1801 the_insn
.arg_reloc
= last_call_desc
.arg_reloc
;
1802 bzero (&last_call_desc
, sizeof (call_descS
));
1805 if (the_insn
.exp
.X_add_symbol
)
1807 if (strcmp (S_GET_NAME (the_insn
.exp
.X_add_symbol
), "L0\001") == 0)
1809 unsigned int w2
, w1
, w
, result
;
1811 sign_unext ((the_insn
.exp
.X_add_number
- 8) >> 2, 17, &result
);
1812 dis_assemble_17 (result
, &w1
, &w2
, &w
);
1813 opcode
|= ((w2
<< 2) | (w1
<< 16) | w
);
1817 if (is_complex (the_insn
.exp
))
1819 the_insn
.reloc
= R_HPPA_COMPLEX_ABS_CALL
;
1823 the_insn
.reloc
= R_HPPA_ABS_CALL
;
1825 /* This could also be part of an instruction sequence of
1826 interest. If so, check to make sure that the previous
1827 instruction's fixup is appropriate. (ble, be instructions
1828 affect the reloc of immediately preceding ldil
1830 if (strcasecmp (prev_str
, "ldil") == 0 &&
1831 prev_insn
.exp
.X_add_symbol
== the_insn
.exp
.X_add_symbol
&&
1832 prev_insn
.exp
.X_op
== the_insn
.exp
.X_op
&&
1833 prev_insn
.exp
.X_op_symbol
== the_insn
.exp
.X_op_symbol
&&
1834 prev_insn
.exp
.X_add_number
== the_insn
.exp
.X_add_number
&&
1836 prev_fix
->fx_r_type
= the_insn
.reloc
;
1838 the_insn
.format
= 17;
1839 the_insn
.arg_reloc
= last_call_desc
.arg_reloc
;
1840 bzero (&last_call_desc
, sizeof (call_descS
));
1845 unsigned int w2
, w1
, w
, result
;
1847 sign_unext (the_insn
.exp
.X_add_number
>> 2, 17, &result
);
1848 dis_assemble_17 (result
, &w1
, &w2
, &w
);
1849 opcode
|= ((w2
<< 2) | (w1
<< 16) | w
);
1854 case 'p': /* 5 bit shift count at 26 (to support SHD instr.) */
1855 /* value is encoded in instr. as 31-p where p is */
1856 /* the value scanned here */
1858 if (the_insn
.exp
.X_op
== O_constant
)
1860 opcode
|= (((31 - the_insn
.exp
.X_add_number
) & 0x1f) << 5);
1864 case 'P': /* 5-bit bit position at 26 */
1866 if (the_insn
.exp
.X_op
== O_constant
)
1868 opcode
|= (the_insn
.exp
.X_add_number
& 0x1f) << 5;
1872 case 'Q': /* 5 bit immediate at 10 */
1873 /* (unsigned bit position value for the bb instruction) */
1875 im5
= evaluateAbsolute (the_insn
.exp
, the_insn
.field_selector
);
1878 as_bad ("Operand out of range. Was: %d. Should be [0..31]. Assuming %d.\n", im5
, im5
& 0x1f);
1881 opcode
|= im5
<< 21;
1884 case 'A': /* 13 bit immediate at 18 (to support BREAK instr.) */
1885 getAbsoluteExpression (s
);
1886 if (the_insn
.exp
.X_op
== O_constant
)
1887 opcode
|= (the_insn
.exp
.X_add_number
& 0x1fff) << 13;
1890 case 'Z': /* System Control Completer(for LDA, LHA, etc.) */
1891 if (*s
== ',' && (*(s
+ 1) == 'm' || *(s
+ 1) == 'M'))
1900 while (*s
== ' ' || *s
== '\t') /* skip to next operand */
1904 case 'D': /* 26 bit immediate at 31 (to support DIAG instr.) */
1905 /* the action (and interpretation of this operand is
1906 implementation dependent) */
1907 #if defined(OBJ_ELF)
1908 the_insn
.field_selector
= pa_chk_field_selector (&s
);
1911 if (the_insn
.exp
.X_op
== O_constant
)
1913 opcode
|= ((evaluateAbsolute (the_insn
.exp
, the_insn
.field_selector
) & 0x1ffffff) << 1);
1914 #ifdef NEW_SOM /* XXX what replaces this? */
1915 /* PJH: VERY unsure about the following */
1916 the_insn
.field_selector
= the_insn
.exp
.field_selector
;
1920 as_bad ("Illegal DIAG operand");
1923 case 'f': /* 3 bit Special Function Unit (SFU) identifier at 25 */
1924 sfu
= pa_parse_number (&s
);
1925 if ((sfu
> 7) || (sfu
< 0))
1926 as_bad ("Illegal SFU identifier: %02x", sfu
);
1927 opcode
|= (sfu
& 7) << 6;
1929 case 'O': /* 20 bit SFU op. split between 15 bits at 20
1934 case 'o': /* 15 bit Special Function Unit operation at 20 */
1938 case '2': /* 22 bit SFU op. split between 17 bits at 20
1943 case '1': /* 15 bit SFU op. split between 10 bits at 20
1948 case '0': /* 10 bit SFU op. split between 5 bits at 20
1953 case 'u': /* 3 bit coprocessor unit identifier at 25 */
1957 case 'F': /* Source FP Operand Format Completer (2 bits at 20) */
1958 f
= pa_parse_fp_format (&s
);
1959 opcode
|= (int) f
<< 11;
1962 case 'G': /* Destination FP Operand Format Completer (2 bits at 18) */
1963 s
--; /* need to pass the previous comma to pa_parse_fp_format */
1964 f
= pa_parse_fp_format (&s
);
1965 opcode
|= (int) f
<< 13;
1968 case 'M': /* FP Compare Conditions (encoded as 5 bits at 31) */
1969 cond
= pa_parse_fp_cmp_cond (&s
);
1973 case 'v': /* a 't' type extended to handle L/R register halves. */
1975 struct pa_89_fp_reg_struct result
;
1977 pa_89_parse_number (&s
, &result
);
1978 if (result
.number_part
< 32 && result
.number_part
>= 0)
1980 opcode
|= (result
.number_part
& 0x1f);
1982 /* 0x30 opcodes are FP arithmetic operation opcodes */
1983 /* load/store FP opcodes do not get converted to 0x38 */
1984 /* opcodes like the 0x30 opcodes do */
1985 if (need_89_opcode (&the_insn
, &result
))
1987 if ((opcode
& 0xfc000000) == 0x30000000)
1989 opcode
|= (result
.L_R_select
& 1) << 6;
1994 opcode
|= (result
.L_R_select
& 1) << 6;
2001 case 'E': /* a 'b' type extended to handle L/R register halves. */
2003 struct pa_89_fp_reg_struct result
;
2005 pa_89_parse_number (&s
, &result
);
2006 if (result
.number_part
< 32 && result
.number_part
>= 0)
2008 opcode
|= (result
.number_part
& 0x1f) << 21;
2009 if (need_89_opcode (&the_insn
, &result
))
2011 opcode
|= (result
.L_R_select
& 1) << 7;
2019 case 'X': /* an 'x' type extended to handle L/R register halves. */
2021 struct pa_89_fp_reg_struct result
;
2023 pa_89_parse_number (&s
, &result
);
2024 if (result
.number_part
< 32 && result
.number_part
>= 0)
2026 opcode
|= (result
.number_part
& 0x1f) << 16;
2027 if (need_89_opcode (&the_insn
, &result
))
2029 opcode
|= (result
.L_R_select
& 1) << 12;
2037 case '4': /* 5 bit register field at 10
2038 (used in 'fmpyadd' and 'fmpysub') */
2040 struct pa_89_fp_reg_struct result
;
2043 status
= pa_89_parse_number (&s
, &result
);
2044 if (result
.number_part
< 32 && result
.number_part
>= 0)
2046 if (the_insn
.fpof1
== SGL
)
2048 result
.number_part
&= 0xF;
2049 result
.number_part
|= (result
.L_R_select
& 1) << 4;
2051 opcode
|= result
.number_part
<< 21;
2057 case '6': /* 5 bit register field at 15
2058 (used in 'fmpyadd' and 'fmpysub') */
2060 struct pa_89_fp_reg_struct result
;
2063 status
= pa_89_parse_number (&s
, &result
);
2064 if (result
.number_part
< 32 && result
.number_part
>= 0)
2066 if (the_insn
.fpof1
== SGL
)
2068 result
.number_part
&= 0xF;
2069 result
.number_part
|= (result
.L_R_select
& 1) << 4;
2071 opcode
|= result
.number_part
<< 16;
2077 case '7': /* 5 bit register field at 31
2078 (used in 'fmpyadd' and 'fmpysub') */
2080 struct pa_89_fp_reg_struct result
;
2083 status
= pa_89_parse_number (&s
, &result
);
2084 if (result
.number_part
< 32 && result
.number_part
>= 0)
2086 if (the_insn
.fpof1
== SGL
)
2088 result
.number_part
&= 0xF;
2089 result
.number_part
|= (result
.L_R_select
& 1) << 4;
2091 opcode
|= result
.number_part
;
2097 case '8': /* 5 bit register field at 20
2098 (used in 'fmpyadd' and 'fmpysub') */
2100 struct pa_89_fp_reg_struct result
;
2103 status
= pa_89_parse_number (&s
, &result
);
2104 if (result
.number_part
< 32 && result
.number_part
>= 0)
2106 if (the_insn
.fpof1
== SGL
)
2108 result
.number_part
&= 0xF;
2109 result
.number_part
|= (result
.L_R_select
& 1) << 4;
2111 opcode
|= result
.number_part
<< 11;
2117 case '9': /* 5 bit register field at 25
2118 (used in 'fmpyadd' and 'fmpysub') */
2120 struct pa_89_fp_reg_struct result
;
2123 status
= pa_89_parse_number (&s
, &result
);
2124 if (result
.number_part
< 32 && result
.number_part
>= 0)
2126 if (the_insn
.fpof1
== SGL
)
2128 result
.number_part
&= 0xF;
2129 result
.number_part
|= (result
.L_R_select
& 1) << 4;
2131 opcode
|= result
.number_part
<< 6;
2137 case 'H': /* Floating Point Operand Format at 26 for */
2138 /* 'fmpyadd' and 'fmpysub' (very similar to 'F') */
2139 /* bits are switched from other FP Operand */
2140 /* formats. 1=SGL, 1=<none>, 0=DBL */
2141 f
= pa_parse_fp_format (&s
);
2153 as_bad ("Illegal Floating Point Operand Format for this instruction: '%s'", *s
);
2165 /* Args don't match. */
2166 if (&insn
[1] - pa_opcodes
< NUMOPCODES
2167 && !strcmp (insn
->name
, insn
[1].name
))
2175 as_bad ("Illegal operands %s", error_message
);
2182 the_insn
.opcode
= opcode
;
2185 if (the_insn
.exp
.X_add_symbol
&& the_insn
.exp
.X_op_symbol
)
2186 print_insn_short (&the_insn
);
2187 fprintf (stderr
, "*********** END OF STATEMENT\n");
2194 This is identical to the md_atof in m68k.c. I think this is right,
2197 Turn a string in input_line_pointer into a floating point constant of type
2198 type, and store the appropriate bytes in *litP. The number of LITTLENUMS
2199 emitted is stored in *sizeP . An error message is returned, or NULL on OK.
2202 /* Equal to MAX_PRECISION in atof-ieee.c */
2203 #define MAX_LITTLENUMS 6
2206 md_atof (type
, litP
, sizeP
)
2212 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
2213 LITTLENUM_TYPE
*wordP
;
2246 return "Bad call to MD_ATOF()";
2248 t
= atof_ieee (input_line_pointer
, type
, words
);
2250 input_line_pointer
= t
;
2251 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
2252 for (wordP
= words
; prec
--;)
2254 md_number_to_chars (litP
, (long) (*wordP
++), sizeof (LITTLENUM_TYPE
));
2255 litP
+= sizeof (LITTLENUM_TYPE
);
2257 return ""; /* Someone should teach Dean about null pointers */
2261 * Write out big-endian.
2264 md_number_to_chars (buf
, val
, n
)
2289 md_create_short_jump (ptr
, from_addr
, to_addr
, frag
, to_symbol
)
2291 addressT from_addr
, to_addr
;
2295 fprintf (stderr
, "pa_create_short_jmp\n");
2300 md_number_to_disp (buf
, val
, n
)
2305 fprintf (stderr
, "md_number_to_disp\n");
2310 md_number_to_field (buf
, val
, fix
)
2315 fprintf (stderr
, "pa_number_to_field\n");
2319 /* the bit-field entries in the relocation_info struct plays hell
2320 with the byte-order problems of cross-assembly. So as a hack,
2321 I added this mach. dependent ri twiddler. Ugly, but it gets
2323 /* on sparc: first 4 bytes are normal unsigned long address, next three
2324 bytes are index, most sig. byte first. Byte 7 is broken up with
2325 bit 7 as external, bits 6 & 5 unused, and the lower
2326 five bits as relocation type. Next 4 bytes are long int addend. */
2327 /* Thanx and a tip of the hat to Michael Bloom, mb@ttidca.tti.com */
2331 md_ri_to_chars (ri_p
, ri
)
2332 struct reloc_info_pa
*ri_p
, ri
;
2334 unsigned char the_bytes
[sizeof (*ri_p
)];
2335 #if defined(OBJ_SOM) | defined(OBJ_OSFROSE) | defined(OBJ_ELF)
2336 /* not sure what, if any, changes are required for new-style cross-assembly */
2338 the_bytes
[0] = ((ri
.need_data_ref
<< 7) & 0x80) | ((ri
.arg_reloc
& 0x03f8) >> 3);
2339 the_bytes
[1] = ((ri
.arg_reloc
& 0x07) << 5) | ri
.expression_type
;
2340 the_bytes
[2] = ((ri
.exec_level
<< 6) & 0xc0) | ri
.fixup_format
;
2341 the_bytes
[3] = ri
.fixup_field
& 0xff;
2342 md_number_to_chars (&the_bytes
[4], ri
.subspace_offset
, sizeof (ri
.subspace_offset
));
2343 md_number_to_chars (&the_bytes
[8], ri
.symbol_index_one
, sizeof (ri
.symbol_index_one
));
2344 md_number_to_chars (&the_bytes
[12], ri
.symbol_index_two
, sizeof (ri
.symbol_index_two
));
2345 md_number_to_chars (&the_bytes
[16], ri
.fixup_constant
, sizeof (ri
.fixup_constant
));
2347 /* now put it back where you found it, Junior... */
2348 bcopy (the_bytes
, (char *) ri_p
, sizeof (*ri_p
));
2356 /* Translate internal representation of relocation info to BFD target
2358 /* This may need additional work to make sure that SOM support is complete. */
2361 tc_gen_reloc (section
, fixp
)
2366 hppa_fixS
*hppa_fixp
= hppa_find_hppa_fix (fixp
);
2367 bfd_reloc_code_real_type code
;
2368 static int unwind_reloc_fixp_cnt
= 0;
2369 static arelent
*unwind_reloc_entryP
= NULL
;
2370 static arelent
*no_relocs
= NULL
;
2372 bfd_reloc_code_real_type
**codes
;
2376 if (fixp
->fx_addsy
== 0)
2378 assert (hppa_fixp
!= 0);
2379 assert (section
!= 0);
2381 /* unwind section relocations are handled in a special way. */
2382 /* The relocations for the .unwind section are originally */
2383 /* built in the usual way. That is, for each unwind table */
2384 /* entry there are two relocations: one for the beginning of */
2385 /* the function and one for the end. */
2387 /* The first time we enter this function we create a */
2388 /* relocation of the type R_HPPA_UNWIND_ENTRIES. The addend */
2389 /* of the relocation is initialized to 0. Each additional */
2390 /* pair of times this function is called for the unwind */
2391 /* section represents an additional unwind table entry. Thus, */
2392 /* the addend of the relocation should end up to be the number */
2393 /* of unwind table entries. */
2394 if (strcmp (UNWIND_SECTION_NAME
, section
->name
) == 0)
2396 if (unwind_reloc_entryP
== NULL
)
2398 reloc
= (arelent
*) bfd_alloc_by_size_t (stdoutput
, sizeof (arelent
));
2399 assert (reloc
!= 0);
2400 unwind_reloc_entryP
= reloc
;
2401 unwind_reloc_fixp_cnt
++;
2402 unwind_reloc_entryP
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
2403 /* a pointer any function will do. We only */
2404 /* need one to tell us what section the unwind */
2405 /* relocations are for. */
2406 unwind_reloc_entryP
->sym_ptr_ptr
= &fixp
->fx_addsy
->bsym
;
2407 code
= R_HPPA_UNWIND_ENTRIES
;
2408 unwind_reloc_entryP
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
2409 unwind_reloc_entryP
->addend
= unwind_reloc_fixp_cnt
/ 2;
2410 relocs
= (arelent
**) bfd_alloc_by_size_t (stdoutput
, sizeof (arelent
*) * 2);
2411 assert (relocs
!= 0);
2412 relocs
[0] = unwind_reloc_entryP
;
2416 unwind_reloc_fixp_cnt
++;
2417 unwind_reloc_entryP
->addend
= unwind_reloc_fixp_cnt
/ 2;
2422 reloc
= (arelent
*) bfd_alloc_by_size_t (stdoutput
, sizeof (arelent
));
2423 assert (reloc
!= 0);
2425 reloc
->sym_ptr_ptr
= &fixp
->fx_addsy
->bsym
;
2426 /* XXX: might need additional processing here */
2427 /* hppa_elf_gen_reloc_type() is defined in the */
2428 /* ELF/PA BFD back-end */
2429 codes
= hppa_elf_gen_reloc_type (stdoutput
,
2431 hppa_fixp
->fx_r_format
,
2432 hppa_fixp
->fx_r_field
);
2434 for (n_relocs
= 0; codes
[n_relocs
]; n_relocs
++)
2437 relocs
= (arelent
**) bfd_alloc_by_size_t (stdoutput
, sizeof (arelent
*) * n_relocs
+ 1);
2438 assert (relocs
!= 0);
2440 reloc
= (arelent
*) bfd_alloc_by_size_t (stdoutput
, sizeof (arelent
) * n_relocs
);
2442 assert (reloc
!= 0);
2444 for (i
= 0; i
< n_relocs
; i
++)
2445 relocs
[i
] = &reloc
[i
];
2447 relocs
[n_relocs
] = NULL
;
2449 switch (fixp
->fx_r_type
)
2451 case R_HPPA_COMPLEX
:
2452 case R_HPPA_COMPLEX_PCREL_CALL
:
2453 case R_HPPA_COMPLEX_ABS_CALL
:
2454 assert (n_relocs
== 5);
2456 for (i
= 0; i
< n_relocs
; i
++)
2458 reloc
[i
].sym_ptr_ptr
= NULL
;
2459 reloc
[i
].address
= 0;
2460 reloc
[i
].addend
= 0;
2461 reloc
[i
].howto
= bfd_reloc_type_lookup (stdoutput
, *codes
[i
]);
2462 assert (reloc
[i
].howto
&& *codes
[i
] == reloc
[i
].howto
->type
);
2465 reloc
[0].sym_ptr_ptr
= &fixp
->fx_addsy
->bsym
;
2466 reloc
[1].sym_ptr_ptr
= &fixp
->fx_subsy
->bsym
;
2467 reloc
[4].address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
2469 if (fixp
->fx_r_type
== R_HPPA_COMPLEX
)
2470 reloc
[3].addend
= fixp
->fx_addnumber
;
2471 else if (fixp
->fx_r_type
== R_HPPA_COMPLEX_PCREL_CALL
||
2472 fixp
->fx_r_type
== R_HPPA_COMPLEX_ABS_CALL
)
2473 reloc
[1].addend
= fixp
->fx_addnumber
;
2478 assert (n_relocs
== 1);
2482 reloc
->sym_ptr_ptr
= &fixp
->fx_addsy
->bsym
;
2483 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
2484 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
2485 reloc
->addend
= 0; /* default */
2487 assert (reloc
->howto
&& code
== reloc
->howto
->type
);
2489 /* Now, do any processing that is dependent on the relocation */
2493 case R_HPPA_PLABEL_32
:
2494 case R_HPPA_PLABEL_11
:
2495 case R_HPPA_PLABEL_14
:
2496 case R_HPPA_PLABEL_L21
:
2497 case R_HPPA_PLABEL_R11
:
2498 case R_HPPA_PLABEL_R14
:
2499 /* For plabel relocations, the addend of the */
2500 /* relocation should be either 0 (no static link) or 2 */
2501 /* (static link required). */
2502 /* XXX: assume that fx_addnumber contains this */
2504 reloc
->addend
= fixp
->fx_addnumber
;
2507 case R_HPPA_ABS_CALL_11
:
2508 case R_HPPA_ABS_CALL_14
:
2509 case R_HPPA_ABS_CALL_17
:
2510 case R_HPPA_ABS_CALL_L21
:
2511 case R_HPPA_ABS_CALL_R11
:
2512 case R_HPPA_ABS_CALL_R14
:
2513 case R_HPPA_ABS_CALL_R17
:
2514 case R_HPPA_ABS_CALL_LS21
:
2515 case R_HPPA_ABS_CALL_RS11
:
2516 case R_HPPA_ABS_CALL_RS14
:
2517 case R_HPPA_ABS_CALL_RS17
:
2518 case R_HPPA_ABS_CALL_LD21
:
2519 case R_HPPA_ABS_CALL_RD11
:
2520 case R_HPPA_ABS_CALL_RD14
:
2521 case R_HPPA_ABS_CALL_RD17
:
2522 case R_HPPA_ABS_CALL_LR21
:
2523 case R_HPPA_ABS_CALL_RR14
:
2524 case R_HPPA_ABS_CALL_RR17
:
2526 case R_HPPA_PCREL_CALL_11
:
2527 case R_HPPA_PCREL_CALL_14
:
2528 case R_HPPA_PCREL_CALL_17
:
2529 case R_HPPA_PCREL_CALL_L21
:
2530 case R_HPPA_PCREL_CALL_R11
:
2531 case R_HPPA_PCREL_CALL_R14
:
2532 case R_HPPA_PCREL_CALL_R17
:
2533 case R_HPPA_PCREL_CALL_LS21
:
2534 case R_HPPA_PCREL_CALL_RS11
:
2535 case R_HPPA_PCREL_CALL_RS14
:
2536 case R_HPPA_PCREL_CALL_RS17
:
2537 case R_HPPA_PCREL_CALL_LD21
:
2538 case R_HPPA_PCREL_CALL_RD11
:
2539 case R_HPPA_PCREL_CALL_RD14
:
2540 case R_HPPA_PCREL_CALL_RD17
:
2541 case R_HPPA_PCREL_CALL_LR21
:
2542 case R_HPPA_PCREL_CALL_RR14
:
2543 case R_HPPA_PCREL_CALL_RR17
:
2544 /* constant is stored in the instruction */
2545 reloc
->addend
= ELF32_HPPA_R_ADDEND (hppa_fixp
->fx_arg_reloc
, 0);
2548 reloc
->addend
= fixp
->fx_addnumber
;
2559 tc_gen_reloc (section
, fixp
)
2564 hppa_fixS
*hppa_fixp
= hppa_find_hppa_fix (fixp
);
2565 bfd_reloc_code_real_type code
;
2567 if (fixp
->fx_addsy
== 0)
2569 assert (hppa_fixp
!= 0);
2570 assert (section
!= 0);
2572 reloc
= (arelent
*) bfd_alloc_by_size_t (stdoutput
, sizeof (arelent
));
2573 assert (reloc
!= 0);
2575 reloc
->sym_ptr_ptr
= &fixp
->fx_addsy
->bsym
;
2576 /* XXX: might need additional processing here */
2577 /* hppa_elf_gen_reloc_type() is defined in the */
2578 /* ELF/PA BFD back-end */
2579 code
= hppa_elf_gen_reloc_type (stdoutput
,
2581 hppa_fixp
->fx_r_format
,
2582 hppa_fixp
->fx_r_field
);
2583 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
2585 assert (code
== reloc
->howto
->type
);
2587 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
2588 reloc
->addend
= 0; /* default */
2590 /* Now, do any processing that is dependent on the relocation */
2591 /* type. (Is there any?) */
2595 reloc
->addend
= fixp
->fx_addnumber
;
2605 md_convert_frag (abfd
, sec
, fragP
)
2607 register asection
*sec
;
2608 register fragS
*fragP
;
2610 unsigned int address
;
2612 if (fragP
->fr_type
== rs_machine_dependent
)
2614 switch ((int) fragP
->fr_subtype
)
2617 fragP
->fr_type
= rs_fill
;
2618 know (fragP
->fr_var
== 1);
2619 know (fragP
->fr_next
);
2620 address
= fragP
->fr_address
+ fragP
->fr_fix
;
2621 if (address
% fragP
->fr_offset
)
2624 fragP
->fr_next
->fr_address
2629 fragP
->fr_offset
= 0;
2635 /* Round up a section size to the appropriate boundary. */
2637 md_section_align (segment
, size
)
2641 return (size
+ 7) & ~7; /* Round all sects to multiple of 8 */
2642 } /* md_section_align() */
2645 md_create_long_jump (ptr
, from_addr
, to_addr
, frag
, to_symbol
)
2647 addressT from_addr
, to_addr
;
2651 fprintf (stderr
, "pa_create_long_jump\n");
2656 /* md_estimate_size_before_relax(fragP, segtype) */
2657 md_estimate_size_before_relax (fragP
, segment
)
2658 register fragS
*fragP
;
2665 while ((fragP
->fr_fix
+ size
) % fragP
->fr_offset
)
2672 md_parse_option (argP
, cntP
, vecP
)
2680 /* We have no need to default values of symbols. */
2684 md_undefined_symbol (name
)
2688 } /*md_undefined_symbol() */
2690 /* Parse an operand that is machine-specific.
2691 We just return without modifying the expression if we have nothing
2696 md_operand (expressionP
)
2697 expressionS
*expressionP
;
2701 /* Apply a fixS to the frags, now that we know the value it ought to
2705 apply_field_selector (value
, constant
, field_selector
)
2710 /* hppa_field_adjust() is defined in the HPPA target */
2711 return hppa_field_adjust (value
, constant
, field_selector
);
2715 md_apply_fix_1 (fixP
, val
)
2719 char *buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
2720 hppa_fixS
*hppa_fixP
= hppa_find_hppa_fix (fixP
);
2723 unsigned int w1
, w2
, w
;
2724 /* The following routine is defined in the ELF/PA back-end */
2725 extern unsigned char hppa_elf_insn2fmt ();
2729 unsigned long buf_wd
= bfd_get_32 (stdoutput
, buf
);
2730 unsigned char fmt
= hppa_elf_insn2fmt (fixP
->fx_r_type
, buf_wd
);
2732 assert (fixP
->fx_r_type
< R_HPPA_UNIMPLEMENTED
);
2733 assert (fixP
->fx_r_type
>= R_HPPA_NONE
);
2735 fixP
->fx_addnumber
= val
; /* Remember value for emit_reloc */
2737 /* Check if this is an undefined symbol. No relocation can */
2738 /* possibly be performed in this case. */
2740 if ((fixP
->fx_addsy
&& fixP
->fx_addsy
->bsym
->section
== &bfd_und_section
)
2741 || (fixP
->fx_subsy
&& fixP
->fx_subsy
->bsym
->section
== &bfd_und_section
))
2747 case 14: /* all the opcodes with the 'j' operand type */
2748 new_val
= apply_field_selector (val
, 0, hppa_fixP
->fx_r_field
);
2749 /* need to check for overflow here */
2751 /* mask off 14 bits to be changed */
2752 bfd_put_32 (stdoutput
,
2753 bfd_get_32 (stdoutput
, buf
) & 0xffffc000,
2755 low_sign_unext (new_val
, 14, &result
);
2758 case 21: /* all the opcodes with the 'k' operand type */
2759 new_val
= apply_field_selector (val
, 0, hppa_fixP
->fx_r_field
);
2760 /* need to check for overflow here */
2762 /* mask off 21 bits to be changed */
2763 bfd_put_32 (stdoutput
,
2764 bfd_get_32 (stdoutput
, buf
) & 0xffe00000,
2766 dis_assemble_21 (new_val
, &result
);
2769 case 11: /* all the opcodes with the 'i' operand type */
2770 new_val
= apply_field_selector (val
, 0, hppa_fixP
->fx_r_field
);
2771 /* need to check for overflow here */
2773 /* mask off 11 bits to be changed */
2774 bfd_put_32 (stdoutput
,
2775 bfd_get_32 (stdoutput
, buf
) & 0xffff800,
2777 low_sign_unext (new_val
, 11, &result
);
2780 case 12: /* all the opcodes with the 'w' operand type */
2781 new_val
= apply_field_selector (val
, 0, hppa_fixP
->fx_r_field
);
2783 /* mask off 11 bits to be changed */
2784 sign_unext ((new_val
- 8) >> 2, 12, &result
);
2785 bfd_put_32 (stdoutput
,
2786 bfd_get_32 (stdoutput
, buf
) & 0xffffe002,
2789 dis_assemble_12 (result
, &w1
, &w
);
2790 result
= ((w1
<< 2) | w
);
2791 fixP
->fx_addsy
= NULL
; /* No relocations please. */
2794 #define too_far(VAL, NUM_BITS) \
2795 (((int)(VAL) > (1 << (NUM_BITS)) - 1) || ((int)(VAL) < (-1 << (NUM_BITS))))
2797 #define stub_needed(CALLER, CALLEE) \
2798 ((CALLEE) && (CALLER) && ((CALLEE) != (CALLER)))
2800 case 17: /* some of the opcodes with the 'W' operand type */
2801 if (too_far (val
, 18)
2802 || stub_needed (((elf32_symbol_type
*) fixP
->fx_addsy
->bsym
)->tc_data
.hppa_arg_reloc
,
2803 hppa_fixP
->fx_arg_reloc
))
2804 /* Keep the relocation because we can't reach the target with
2805 a short call, or if an argument relocation stub is needed. */
2808 new_val
= apply_field_selector (val
, 0, hppa_fixP
->fx_r_field
);
2809 /* need to check for overflow here */
2811 /* mask off 17 bits to be changed */
2812 bfd_put_32 (stdoutput
,
2813 bfd_get_32 (stdoutput
, buf
) & 0xffe0e002,
2815 sign_unext ((new_val
- 8) >> 2, 17, &result
);
2816 dis_assemble_17 (result
, &w1
, &w2
, &w
);
2817 result
= ((w2
<< 2) | (w1
<< 16) | w
);
2818 fixP
->fx_addsy
= NULL
; /* No relocations please. */
2822 if (hppa_fixP
->fx_r_type
== R_HPPA_UNWIND_ENTRY
2823 || hppa_fixP
->fx_r_type
== R_HPPA_UNWIND_ENTRIES
)
2824 result
= fixP
->fx_addnumber
;
2828 fixP
->fx_addnumber
= fixP
->fx_offset
;
2829 bfd_put_32 (stdoutput
, 0, buf
); /* clear out everything */
2830 return; /* still need the relocation */
2838 as_bad ("bad relocation type/fmt: 0x%02x/0x%02x",
2839 fixP
->fx_r_type
, fmt
);
2842 buf
[0] |= (result
& 0xff000000) >> 24;
2843 buf
[1] |= (result
& 0x00ff0000) >> 16;
2844 buf
[2] |= (result
& 0x0000ff00) >> 8;
2845 buf
[3] |= result
& 0x000000ff;
2846 /* We've now adjusted for fx_addnumber, we can */
2847 /* forget it now. */
2848 fixP
->fx_addnumber
= 0;
2852 printf ("no hppa_fixup entry for this fixup (fixP = 0x%x, type = 0x%x)\n",
2853 fixP
, fixP
->fx_r_type
);
2855 } /* md_apply_fix_1() */
2857 #ifdef BFD_ASSEMBLER
2859 md_apply_fix (fixP
, valp
)
2863 md_apply_fix_1 (fixP
, *valp
);
2869 md_apply_fix (fixP
, val
)
2873 md_apply_fix_1 (fixP
, val
);
2878 /* Exactly what point is a PC-relative offset relative TO?
2879 On the PA, they're relative to the address of the offset.
2880 (??? Is this right? FIXME-SOON) */
2882 md_pcrel_from (fixP
)
2885 return fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
2886 } /* md_pcrel_from() */
2889 is_end_of_statement ()
2891 return ((*input_line_pointer
== '\n')
2892 || (*input_line_pointer
== ';')
2893 || (*input_line_pointer
== '!'));
2896 /* pa-aux.c -- Assembler for the PA - PA-RISC specific support routines */
2898 struct aux_hdr_list
*aux_hdr_root
= NULL
;
2900 int print_errors
= 1;
2906 while (**s
== ' ' || **s
== '\t')
2921 while (*p
== ' ' || *p
== '\t')
2923 num
= -1; /* assume invalid number to begin with */
2926 num
= 0; /* now we know it is a number */
2928 if (*p
== '0' && (*(p
+ 1) == 'x' || *(p
+ 1) == 'X'))
2931 while (isdigit (*p
) || ((*p
>= 'a') && (*p
<= 'f'))
2932 || ((*p
>= 'A') && (*p
<= 'F')))
2935 num
= num
* 16 + *p
- '0';
2936 else if (*p
>= 'a' && *p
<= 'f')
2937 num
= num
* 16 + *p
- 'a' + 10;
2939 num
= num
* 16 + *p
- 'A' + 10;
2945 while (isdigit (*p
))
2947 num
= num
* 10 + *p
- '0';
2953 { /* could be a pre-defined register */
2958 /* tege hack: Special case for general registers
2959 as the general code makes a binary search with case translation,
2960 and is VERY slow. */
2964 if (*p
== 'e' && *(p
+ 1) == 't' && (*(p
+ 2) == '0' || *(p
+ 2) == '1'))
2967 num
= *p
- '0' + 28; /* r28 is ret0 */
2970 else if (!isdigit (*p
))
2971 as_bad ("Undefined register: '%s'. ASSUMING 0", name
);
2975 num
= num
* 10 + *p
++ - '0';
2976 while (isdigit (*p
));
2981 while (is_part_of_name (c
))
2987 status
= reg_name_search (name
);
2993 as_bad ("Undefined register: '%s'. ASSUMING 0", name
);
3005 while (is_part_of_name (c
))
3011 if ((sym
= symbol_find (name
)) != NULL
)
3014 if (sym
->pa_sy_type
== ST_ABSOLUTE
)
3016 num
= sym
->pa_sy_value
;
3018 if (S_GET_SEGMENT (sym
) == &bfd_abs_section
)
3020 num
= S_GET_VALUE (sym
);
3026 as_bad ("Non-absolute constant: '%s'. ASSUMING 0", name
);
3034 as_bad ("Undefined absolute constant: '%s'. ASSUMING 0", name
);
3051 /* List of registers that are pre-defined:
3055 Name Value Name Value
3073 Floating-point Registers:
3074 [NOTE: Also includes L and R versions of these (e.g. %fr19L, %fr19R)]
3076 Name Value Name Value
3096 Name Value Name Value
3102 Control registers and their synonyms:
3131 Miscellaneous registers and their synonyms:
3143 /* This table is sorted. Suitable for searching by a binary search. */
3145 static struct pd_reg pre_defined_registers
[] =
3355 #define REG_NAME_CNT (sizeof(pre_defined_registers) / sizeof(struct pd_reg))
3358 reg_name_search (name
)
3364 r
= REG_NAME_CNT
- 1;
3369 if (strcasecmp (name
, pre_defined_registers
[x
].name
) < 0)
3374 while (!((strcasecmp (name
, pre_defined_registers
[x
].name
) == 0) ||
3377 if (strcasecmp (name
, pre_defined_registers
[x
].name
) == 0)
3378 return (pre_defined_registers
[x
].value
);
3385 is_pre_defined_register (s
)
3388 if (reg_name_search (s
) >= 0)
3399 if (*s
== 'R' || *s
== 'r')
3410 if (*s
== 'L' || *s
== 'l')
3417 need_89_opcode (insn
, result
)
3419 struct pa_89_fp_reg_struct
*result
;
3421 /* if ( result->L_R_select == 1 || insn->fpof1 == DBL || insn->fpof2 == DBL ) */
3422 /* if (result->L_R_select == 1 && !(insn->fpof1 == DBL || insn->fpof2 == DBL) ) */
3423 if (result
->L_R_select
== 1 && !(insn
->fpof1
== DBL
&& insn
->fpof2
== DBL
))
3424 /* if ( insn->fpof1 == DBL || insn->fpof2 == DBL ) */
3431 pa_89_parse_number (s
, result
)
3433 struct pa_89_fp_reg_struct
*result
;
3442 while (*p
== ' ' || *p
== '\t')
3444 num
= -1; /* assume invalid number to begin with */
3445 result
->number_part
= -1;
3446 result
->L_R_select
= -1;
3450 num
= 0; /* now we know it is a number */
3452 if (*p
== '0' && (*(p
+ 1) == 'x' || *(p
+ 1) == 'X'))
3455 while (isdigit (*p
) || ((*p
>= 'a') && (*p
<= 'f'))
3456 || ((*p
>= 'A') && (*p
<= 'F')))
3459 num
= num
* 16 + *p
- '0';
3460 else if (*p
>= 'a' && *p
<= 'f')
3461 num
= num
* 16 + *p
- 'a' + 10;
3463 num
= num
* 16 + *p
- 'A' + 10;
3469 while (isdigit (*p
))
3471 num
= num
* 10 + *p
- '0';
3476 result
->number_part
= num
;
3478 if (is_R_select (p
))
3480 result
->L_R_select
= 1;
3483 else if (is_L_select (p
))
3485 result
->L_R_select
= 0;
3489 result
->L_R_select
= 0;
3493 { /* could be a pre-defined register */
3498 /* tege hack: Special case for general registers
3499 as the general code makes a binary search with case translation,
3500 and is VERY slow. */
3504 if (*p
== 'e' && *(p
+ 1) == 't' && (*(p
+ 2) == '0' || *(p
+ 2) == '1'))
3507 num
= *p
- '0' + 28; /* r28 is ret0 */
3510 else if (!isdigit (*p
))
3511 as_bad ("Undefined register: '%s'. ASSUMING 0", name
);
3515 num
= num
* 10 + *p
++ - '0';
3516 while (isdigit (*p
));
3521 while (is_part_of_name (c
))
3527 status
= reg_name_search (name
);
3533 as_bad ("Undefined register: '%s'. ASSUMING 0", name
);
3540 result
->number_part
= num
;
3542 if (is_R_select (p
- 1))
3543 result
->L_R_select
= 1;
3544 else if (is_L_select (p
- 1))
3545 result
->L_R_select
= 0;
3547 result
->L_R_select
= 0;
3555 while (is_part_of_name (c
))
3561 if ((sym
= symbol_find (name
)) != NULL
)
3564 if (sym
->pa_sy_type
== ST_ABSOLUTE
)
3566 num
= sym
->pa_sy_value
;
3568 if (S_GET_SEGMENT (sym
) == &bfd_abs_section
)
3570 num
= S_GET_VALUE (sym
);
3576 as_bad ("Non-absolute constant: '%s'. ASSUMING 0", name
);
3584 as_bad ("Undefined absolute constant: '%s'. ASSUMING 0", name
);
3589 result
->number_part
= num
;
3591 if (is_R_select (p
- 1))
3592 result
->L_R_select
= 1;
3593 else if (is_L_select (p
- 1))
3594 result
->L_R_select
= 0;
3596 result
->L_R_select
= 0;
3606 pa_parse_fp_cmp_cond (s
)
3617 This table is sorted by order of the length of the string. This is so we
3618 check for <> before we check for <. If we had a <> and checked for < first,
3619 we would get a false match.
3621 static struct possibleS poss
[] =
3659 for (i
= 0; i
< 32; i
++)
3661 if (strncasecmp (*s
, poss
[i
].string
, strlen (poss
[i
].string
)) == 0)
3663 cond
= poss
[i
].cond
;
3664 *s
+= strlen (poss
[i
].string
);
3665 while (**s
== ' ' || **s
== '\t')
3671 as_bad ("Illegal FP Compare Condition: %c", **s
);
3676 pa_parse_fp_format (s
)
3685 if (strncasecmp (*s
, "sgl", 3) == 0)
3690 else if (strncasecmp (*s
, "dbl", 3) == 0)
3695 else if (strncasecmp (*s
, "quad", 4) == 0)
3703 as_bad ("Unrecognized FP Operand Format: %3s", *s
);
3706 while (**s
== ' ' || **s
== '\t' || **s
== 0)
3712 #if defined(OBJ_ELF)
3714 pa_chk_field_selector (str
)
3718 struct selector_entry
3723 static struct selector_entry selector_table
[] =
3757 struct selector_entry
*tableP
;
3761 while (**str
== ' ' || **str
== '\t' || **str
== '\n' || **str
== '\f')
3765 for (tableP
= selector_table
; tableP
->prefix
; tableP
++)
3767 if (strncasecmp (tableP
->prefix
, *str
, strlen (tableP
->prefix
)) == 0)
3769 *str
+= strlen (tableP
->prefix
);
3770 selector
= tableP
->field_selector
;
3784 save_in
= input_line_pointer
;
3785 input_line_pointer
= str
;
3786 seg
= expression (&the_insn
.exp
);
3787 if (!(seg
== absolute_section
3788 || seg
== undefined_section
3789 || SEG_NORMAL (seg
)))
3791 the_insn
.error
= "bad segment";
3792 expr_end
= input_line_pointer
;
3793 input_line_pointer
= save_in
;
3796 expr_end
= input_line_pointer
;
3797 input_line_pointer
= save_in
;
3809 save_in
= input_line_pointer
;
3810 input_line_pointer
= str
;
3811 seg
= expression (&the_insn
.exp
);
3812 if (!(seg
== absolute_section
3813 || seg
== undefined_section
3814 || SEG_NORMAL (seg
)))
3816 the_insn
.error
= "illegal segment";
3817 expr_end
= input_line_pointer
;
3818 input_line_pointer
= save_in
;
3821 expr_end
= input_line_pointer
;
3822 input_line_pointer
= save_in
;
3829 getAbsoluteExpression (str
)
3834 save_in
= input_line_pointer
;
3835 input_line_pointer
= str
;
3836 expression (&the_insn
.exp
);
3837 if (the_insn
.exp
.X_op
!= O_constant
)
3839 the_insn
.error
= "segment should be ABSOLUTE";
3840 expr_end
= input_line_pointer
;
3841 input_line_pointer
= save_in
;
3844 expr_end
= input_line_pointer
;
3845 input_line_pointer
= save_in
;
3850 evaluateAbsolute (exp
, field_selector
)
3856 value
= exp
.X_add_number
;
3858 switch (field_selector
)
3860 case e_fsel
: /* F : no change */
3863 case e_lssel
: /* LS : if (bit 21) then add 0x800
3864 arithmetic shift right 11 bits */
3865 if (value
& 0x00000400)
3867 value
= (value
& 0xfffff800) >> 11;
3870 case e_rssel
: /* RS : Sign extend from bit 21 */
3871 if (value
& 0x00000400)
3872 value
|= 0xfffff800;
3877 case e_lsel
: /* L : Arithmetic shift right 11 bits */
3878 value
= (value
& 0xfffff800) >> 11;
3881 case e_rsel
: /* R : Set bits 0-20 to zero */
3882 value
= value
& 0x7ff;
3885 case e_ldsel
: /* LD : Add 0x800, arithmetic shift
3888 value
= (value
& 0xfffff800) >> 11;
3891 case e_rdsel
: /* RD : Set bits 0-20 to one */
3892 value
|= 0xfffff800;
3895 case e_lrsel
: /* LR : L with "rounded" constant */
3896 /* XXX: this isn't right. Need to add a "rounded" constant */
3897 /* XXX: (presumably from X_add_number) */
3898 value
= (value
& 0xfffff800) >> 11;
3901 case e_rrsel
: /* RR : R with "rounded" constant */
3902 /* XXX: this isn't right. Need to add a "rounded" constant */
3903 /* XXX: (presumably from X_add_number) */
3904 value
= value
& 0x7ff;
3908 BAD_CASE (field_selector
);
3915 pa_build_arg_reloc (type_name
)
3919 if (strncasecmp (type_name
, "no", 2) == 0)
3923 if (strncasecmp (type_name
, "gr", 2) == 0)
3927 else if (strncasecmp (type_name
, "fr", 2) == 0)
3931 else if (strncasecmp (type_name
, "fu", 2) == 0)
3936 as_bad ("Unrecognized argument location: %s\n", type_name
);
3942 pa_align_arg_reloc (reg
, arg_reloc
)
3944 unsigned int arg_reloc
;
3946 unsigned int new_reloc
;
3948 new_reloc
= arg_reloc
;
3964 as_bad ("Illegal argument description: %d", reg
);
3980 if (strncasecmp (*s
, "n", 1) == 0)
3984 as_bad ("Unrecognized Nullification: (%c)", **s
);
3989 while (**s
== ' ' || **s
== '\t')
3996 pa_parse_nonneg_cmpsub_cmpltr (s
, isbranch
)
4001 char *name
= *s
+ 1;
4009 while (**s
!= ',' && **s
!= ' ' && **s
!= '\t')
4013 if (strcmp (name
, "=") == 0)
4017 else if (strcmp (name
, "<") == 0)
4021 else if (strcmp (name
, "<=") == 0)
4025 else if (strcmp (name
, "<<") == 0)
4029 else if (strcmp (name
, "<<=") == 0)
4033 else if (strcasecmp (name
, "sv") == 0)
4037 else if (strcasecmp (name
, "od") == 0)
4041 /* If we have something like addb,n then there is no condition
4043 else if (strcasecmp (name
, "n") == 0 && isbranch
)
4055 while (**s
== ' ' || **s
== '\t')
4059 /* Reset pointers if this was really a ,n for a branch instruction. */
4060 if (cmpltr
== 0 && *name
== 'n' && isbranch
)
4067 pa_parse_neg_cmpsub_cmpltr (s
, isbranch
)
4072 char *name
= *s
+ 1;
4080 while (**s
!= ',' && **s
!= ' ' && **s
!= '\t')
4084 if (strcasecmp (name
, "tr") == 0)
4088 else if (strcmp (name
, "<>") == 0)
4092 else if (strcmp (name
, ">=") == 0)
4096 else if (strcmp (name
, ">") == 0)
4100 else if (strcmp (name
, ">>=") == 0)
4104 else if (strcmp (name
, ">>") == 0)
4108 else if (strcasecmp (name
, "nsv") == 0)
4112 else if (strcasecmp (name
, "ev") == 0)
4116 /* If we have something like addb,n then there is no condition
4118 else if (strcasecmp (name
, "n") == 0 && isbranch
)
4130 while (**s
== ' ' || **s
== '\t')
4134 /* Reset pointers if this was really a ,n for a branch instruction. */
4135 if (cmpltr
== 0 && *name
== 'n' && isbranch
)
4142 pa_parse_nonneg_add_cmpltr (s
, isbranch
)
4147 char *name
= *s
+ 1;
4155 while (**s
!= ',' && **s
!= ' ' && **s
!= '\t')
4159 if (strcmp (name
, "=") == 0)
4163 else if (strcmp (name
, "<") == 0)
4167 else if (strcmp (name
, "<=") == 0)
4171 else if (strcasecmp (name
, "nuv") == 0)
4175 else if (strcasecmp (name
, "znv") == 0)
4179 else if (strcasecmp (name
, "sv") == 0)
4183 else if (strcasecmp (name
, "od") == 0)
4187 /* If we have something like addb,n then there is no condition
4189 else if (strcasecmp (name
, "n") == 0 && isbranch
)
4201 while (**s
== ' ' || **s
== '\t')
4205 /* Reset pointers if this was really a ,n for a branch instruction. */
4206 if (cmpltr
== 0 && *name
== 'n' && isbranch
)
4213 pa_parse_neg_add_cmpltr (s
, isbranch
)
4218 char *name
= *s
+ 1;
4226 while (**s
!= ',' && **s
!= ' ' && **s
!= '\t')
4230 if (strcasecmp (name
, "tr") == 0)
4234 else if (strcmp (name
, "<>") == 0)
4238 else if (strcmp (name
, ">=") == 0)
4242 else if (strcmp (name
, ">") == 0)
4246 else if (strcmp (name
, "uv") == 0)
4250 else if (strcmp (name
, "vnz") == 0)
4254 else if (strcasecmp (name
, "nsv") == 0)
4258 else if (strcasecmp (name
, "ev") == 0)
4262 /* If we have something like addb,n then there is no condition
4264 else if (strcasecmp (name
, "n") == 0 && isbranch
)
4276 while (**s
== ' ' || **s
== '\t')
4280 /* Reset pointers if this was really a ,n for a branch instruction. */
4281 if (cmpltr
== 0 && *name
== 'n' && isbranch
)
4291 if (strncmp (input_line_pointer
, "\"text\"", 6) == 0)
4293 input_line_pointer
+= 6;
4297 if (strncmp (input_line_pointer
, "\"data\"", 6) == 0)
4299 input_line_pointer
+= 6;
4303 if (strncmp (input_line_pointer
, "\"data1\"", 7) == 0)
4305 input_line_pointer
+= 7;
4309 as_bad ("Unknown segment type");
4310 demand_empty_rest_of_line ();
4319 temp
= get_absolute_expression ();
4320 subseg_set (data_section
, (subsegT
) temp
);
4321 demand_empty_rest_of_line ();
4327 subseg_set (data_section
, 1);
4328 demand_empty_rest_of_line ();
4335 extern char is_end_of_line
[];
4337 while (!is_end_of_line
[*input_line_pointer
])
4339 ++input_line_pointer
;
4341 ++input_line_pointer
;
4350 register long int temp_fill
;
4351 register long int temp_size
;
4354 temp_size
= get_absolute_expression ();
4357 { /* fill with zeroes even if not requested to do so. */
4358 temp_fill
= 0; /* HP assembler does this too. */
4367 as_bad ("size < 0, .block ignored");
4370 p
= frag_var (rs_fill
,
4372 (int) temp_size
, (relax_substateT
) 0, (symbolS
*) 0, 1, (char *) 0);
4373 bzero (p
, (int) temp_size
);
4375 /* convert 2 bytes at a time */
4377 for (i
= 0; i
< temp_size
; i
+= 2)
4379 md_number_to_chars (p
+ i
,
4381 (int) ((temp_size
- i
) > 2 ? 2 : (temp_size
- i
)));
4384 pa_undefine_label ();
4385 demand_empty_rest_of_line ();
4393 pa_call_args (&last_call_desc
);
4394 demand_empty_rest_of_line ();
4399 pa_call_args (call_desc
)
4400 register call_descS
*call_desc
;
4402 register char *name
;
4406 register unsigned int arg_reloc
;
4408 while (!is_end_of_statement ())
4410 name
= input_line_pointer
;
4411 c
= get_symbol_end ();
4412 if ((strncasecmp (name
, "argw", 4) == 0))
4414 temp
= atoi (name
+ 4);
4415 p
= input_line_pointer
;
4417 input_line_pointer
++;
4418 name
= input_line_pointer
;
4419 c
= get_symbol_end ();
4420 arg_reloc
= pa_build_arg_reloc (name
);
4421 call_desc
->arg_reloc
|= pa_align_arg_reloc (temp
, arg_reloc
);
4423 else if ((strncasecmp (name
, "rtnval", 6) == 0))
4425 p
= input_line_pointer
;
4427 input_line_pointer
++;
4428 name
= input_line_pointer
;
4429 c
= get_symbol_end ();
4430 arg_reloc
= pa_build_arg_reloc (name
);
4431 call_desc
->arg_reloc
|= (arg_reloc
& 0x3);
4435 as_bad ("Unrecognized .CALL argument: %s", name
);
4437 p
= input_line_pointer
;
4439 if (!is_end_of_statement ())
4440 input_line_pointer
++;
4445 is_same_frag (frag1P
, frag2P
)
4452 else if (frag2P
== NULL
)
4454 else if (frag1P
== frag2P
)
4456 else if (frag2P
->fr_type
== rs_fill
&& frag2P
->fr_fix
== 0)
4457 return (is_same_frag (frag1P
, frag2P
->fr_next
));
4464 pa_build_unwind_subspace (call_info
)
4465 call_infoS
*call_info
;
4470 subsegT subseg
, save_subseg
;
4475 subseg
= SUBSEG_UNWIND
;
4476 seg
= bfd_get_section_by_name (stdoutput
, UNWIND_SECTION_NAME
);
4477 if (seg
== ASEC_NULL
)
4479 seg
= bfd_make_section_old_way (stdoutput
, UNWIND_SECTION_NAME
);
4481 bfd_set_section_flags (stdoutput
, seg
,
4482 (SEC_READONLY
| SEC_HAS_CONTENTS
4483 | SEC_LOAD
| SEC_RELOC
));
4485 /* callinfo.frame is in bytes and unwind_desc is in 8 byte units */
4486 call_info
->ci_unwind
.descriptor
.frame_size
= call_info
->frame
/ 8;
4488 /* Now, dump the unwind descriptor to the $UNWIND$ subspace. This
4489 creates a couple of relocations */
4492 save_subseg
= now_subseg
;
4493 subseg_set (seg
, subseg
);
4494 unwindP
= (char *) &call_info
->ci_unwind
;
4497 call_info
->start_offset_frag
= frag_now
;
4498 call_info
->start_frag_where
= p
- frag_now
->fr_literal
;
4500 /* relocation info. for start offset of the function */
4502 fix_new_hppa (frag_now
, p
- frag_now
->fr_literal
, 4,
4503 call_info
->start_symbol
, (offsetT
) 0,
4504 (expressionS
*) NULL
, 0, R_HPPA_UNWIND
, e_fsel
, 32, 0,
4507 /** we need to search for the first relocation involving the start_symbol of **/
4508 /** this call_info descriptor **/
4513 call_info
->start_fix
= seg_info (now_seg
)->fix_root
; /* the default */
4514 for (fixP
= call_info
->start_fix
; fixP
; fixP
= fixP
->fx_next
)
4516 if (fixP
->fx_addsy
== call_info
->start_symbol
4517 || fixP
->fx_subsy
== call_info
->start_symbol
)
4519 call_info
->start_fix
= fixP
;
4526 call_info
->end_offset_frag
= frag_now
;
4527 call_info
->end_frag_where
= p
- frag_now
->fr_literal
;
4529 /* relocation info. for end offset of the function */
4531 fix_new_hppa (frag_now
, p
- frag_now
->fr_literal
, 4,
4532 call_info
->end_symbol
, (offsetT
) 0,
4533 (expressionS
*) NULL
, 0, R_HPPA_UNWIND
, e_fsel
, 32, 0,
4536 /** we need to search for the first relocation involving the start_symbol of **/
4537 /** this call_info descriptor **/
4542 call_info
->end_fix
= seg_info (now_seg
)->fix_root
; /* the default */
4543 for (fixP
= call_info
->end_fix
; fixP
; fixP
= fixP
->fx_next
)
4545 if (fixP
->fx_addsy
== call_info
->end_symbol
4546 || fixP
->fx_subsy
== call_info
->end_symbol
)
4548 call_info
->end_fix
= fixP
;
4554 for (i
= 8; i
< sizeof (unwind_tableS
); i
++)
4558 FRAG_APPEND_1_CHAR (c
);
4562 subseg_set (save_seg
, save_subseg
);
4568 pa_build_unwind_subspace (call_info
)
4569 call_infoS
*call_info
;
4571 space_dict_chainS
*spaceP
;
4572 subspace_dict_chainS
*subspaceP
;
4574 char defined
, loadable
, code_only
, common
, dup_common
, is_zero
, sort
;
4575 int access
, space_index
, alignment
, quadrant
;
4577 subsegT subseg
, save_subseg
;
4593 subseg
= SUBSEG_UNWIND
;
4596 spaceP
= pa_segment_to_space (seg
);
4598 if ((subspaceP
= is_defined_subspace ("$UNWIND$", SUBSEG_UNWIND
)))
4600 update_subspace ("$UNWIND$", defined
, loadable
, code_only
, common
, dup_common
,
4601 sort
, is_zero
, access
, space_index
, alignment
, quadrant
,
4606 subspaceP
= create_new_subspace (spaceP
, "$UNWIND$", defined
, loadable
, code_only
,
4607 common
, dup_common
, is_zero
, sort
, access
,
4608 space_index
, alignment
, quadrant
, seg
);
4612 /* callinfo.frame is in bytes and unwind_desc is in 8 byte units */
4613 call_info
->ci_unwind
.descriptor
.frame_size
= call_info
->frame
/ 8;
4615 /* Now, dump the unwind descriptor to the $UNWIND$ subspace. This
4616 creates a couple of relocations */
4619 save_subseg
= now_subseg
;
4620 subseg_set (seg
, subseg
);
4621 unwindP
= (char *) &call_info
->ci_unwind
;
4624 call_info
->start_offset_frag
= frag_now
;
4625 call_info
->start_frag_where
= p
- frag_now
->fr_literal
;
4627 /* relocation info. for start offset of the function */
4629 fix_new (frag_now
, p
- frag_now
->fr_literal
, 4,
4630 call_info
->start_symbol
, (offsetT
) 0,
4631 (expressionS
*) NULL
, 0, R_DATA_ONE_SYMBOL
, e_fsel
, 0, 0,
4634 /** we need to search for the first relocation involving the start_symbol of **/
4635 /** this call_info descriptor **/
4640 call_info
->start_fix
= seg_info (now_seg
)->fix_root
; /* the default */
4641 for (fixP
= call_info
->start_fix
; fixP
; fixP
= fixP
->fx_next
)
4644 if ( ( fixP->fx_addsy == call_info->start_symbol ||
4645 fixP->fx_subsy == call_info->start_symbol )
4647 ( fixP->fx_frag == call_info->start_symbol->sy_frag ) ) {
4649 if ((fixP
->fx_addsy
== call_info
->start_symbol
||
4650 fixP
->fx_subsy
== call_info
->start_symbol
)
4652 (is_same_frag (fixP
->fx_frag
, call_info
->start_symbol
->sy_frag
)))
4654 call_info
->start_fix
= fixP
;
4661 call_info
->end_offset_frag
= frag_now
;
4662 call_info
->end_frag_where
= p
- frag_now
->fr_literal
;
4664 /* relocation info. for end offset of the function */
4666 fix_new (frag_now
, p
- frag_now
->fr_literal
, 4,
4667 call_info
->start_symbol
, (offsetT
) 0,
4668 (expressionS
*) NULL
, 0, R_DATA_ONE_SYMBOL
, e_fsel
, 0, 0,
4671 /** we need to search for the first relocation involving the start_symbol of **/
4672 /** this call_info descriptor **/
4677 call_info
->end_fix
= seg_info (now_seg
)->fix_root
; /* the default */
4678 for (fixP
= call_info
->end_fix
; fixP
; fixP
= fixP
->fx_next
)
4681 if ( ( fixP->fx_addsy == call_info->start_symbol ||
4682 fixP->fx_subsy == call_info->start_symbol )
4684 ( fixP->fx_frag == call_info->start_symbol->sy_frag ) ) {
4686 if ((fixP
->fx_addsy
== call_info
->start_symbol
||
4687 fixP
->fx_subsy
== call_info
->start_symbol
)
4689 (is_same_frag (fixP
->fx_frag
, call_info
->start_symbol
->sy_frag
)))
4691 call_info
->end_fix
= fixP
;
4697 for (i
= 8; i
< sizeof (unwind_tableS
); i
++)
4701 FRAG_APPEND_1_CHAR (c
);
4705 subseg_set (save_seg
, save_subseg
);
4715 register char *name
;
4720 if (!within_procedure
)
4721 as_bad (".callinfo is not within a procedure definition");
4723 callinfo_found
= TRUE
;
4725 while (!is_end_of_statement ())
4727 name
= input_line_pointer
;
4728 c
= get_symbol_end ();
4729 if ((strncasecmp (name
, "frame", 5) == 0))
4731 p
= input_line_pointer
;
4733 input_line_pointer
++;
4734 temp
= get_absolute_expression ();
4735 if ((temp
& 0x3) != 0)
4737 as_bad ("FRAME parameter must be a multiple of 8: %d\n", temp
);
4740 last_call_info
->frame
= temp
;
4742 else if ((strncasecmp (name
, "entry_gr", 8) == 0))
4744 p
= input_line_pointer
;
4746 input_line_pointer
++;
4747 temp
= get_absolute_expression ();
4748 last_call_info
->ci_unwind
.descriptor
.entry_gr
= temp
;
4750 else if ((strncasecmp (name
, "entry_fr", 8) == 0))
4752 p
= input_line_pointer
;
4754 input_line_pointer
++;
4755 temp
= get_absolute_expression ();
4756 last_call_info
->ci_unwind
.descriptor
.entry_fr
= temp
;
4758 else if ((strncasecmp (name
, "entry_sr", 8) == 0))
4760 p
= input_line_pointer
;
4762 input_line_pointer
++;
4763 temp
= get_absolute_expression ();
4764 last_call_info
->entry_sr
= temp
;
4766 else if ((strncasecmp (name
, "calls", 5) == 0) ||
4767 (strncasecmp (name
, "caller", 6) == 0))
4769 p
= input_line_pointer
;
4771 last_call_info
->makes_calls
= 1;
4773 else if ((strncasecmp (name
, "no_calls", 8) == 0))
4775 p
= input_line_pointer
;
4777 last_call_info
->makes_calls
= 0;
4779 else if ((strncasecmp (name
, "save_rp", 7) == 0))
4781 p
= input_line_pointer
;
4783 last_call_info
->ci_unwind
.descriptor
.save_rp
= 1;
4785 else if ((strncasecmp (name
, "save_sp", 7) == 0))
4787 p
= input_line_pointer
;
4789 last_call_info
->ci_unwind
.descriptor
.save_sp
= 1;
4791 else if ((strncasecmp (name
, "no_unwind", 9) == 0))
4793 p
= input_line_pointer
;
4795 last_call_info
->ci_unwind
.descriptor
.cannot_unwind
= 1;
4797 else if ((strncasecmp (name
, "hpux_int", 7) == 0))
4799 p
= input_line_pointer
;
4801 last_call_info
->hpux_int
= 1;
4805 as_bad ("Unrecognized .CALLINFO argument: %s", name
);
4807 if (!is_end_of_statement ())
4808 input_line_pointer
++;
4811 demand_empty_rest_of_line ();
4818 space_dict_chainS
*sdchain
;
4820 if ((sdchain
= is_defined_space ("$TEXT$")) == NULL
)
4822 sdchain
= create_new_space (pa_def_spaces
[0].name
, pa_def_spaces
[0].spnum
,
4823 pa_def_spaces
[0].loadable
, pa_def_spaces
[0].defined
,
4824 pa_def_spaces
[0].private, pa_def_spaces
[0].sort
,
4825 1, pa_def_spaces
[0].segment
);
4828 SPACE_DEFINED (sdchain
) = 1;
4830 subseg_set (text_section
, SUBSEG_CODE
);
4832 demand_empty_rest_of_line ();
4837 * This is different than the standard GAS s_comm(). On HP9000/800 machines,
4838 * the .comm pseudo-op has the following symtax:
4840 * <label> .comm <length>
4842 * where <label> is optional and is a symbol whose address will be the start of
4843 * a block of memory <length> bytes long. <length> must be an absolute expressio
4845 * <length> bytes will be allocated in the current space and subspace.
4853 register symbolS
*symbolP
;
4854 register label_symbolS
*label_symbolP
= pa_get_label ();
4857 symbolP
= label_symbolP
->lss_label
;
4862 if ((size
= get_absolute_expression ()) < 0)
4864 as_warn (".COMMon length (%d.) <0! Ignored.", size
);
4865 ignore_rest_of_line ();
4872 if (symbolP
->pa_sy_type
== ST_STORAGE
&&
4873 symbolP
->pa_sy_scope
== SS_UNSAT
)
4875 if (symbolP
->pa_sy_value
!= size
)
4877 as_warn ("Length of .comm \"%s\" is already %d. Not changed to %d.",
4878 symbolP
->pa_sy_name
, symbolP
->pa_sy_value
, size
);
4884 symbolP
->pa_sy_value
= size
;
4885 symbolP
->pa_sy_scope
= SS_UNSAT
;
4886 symbolP
->pa_sy_type
= ST_STORAGE
;
4887 symbolP
->sy_ref
= sym_def
;
4891 if (S_IS_DEFINED (symbolP
) && S_GET_SEGMENT (symbolP
) == bss_section
)
4893 as_bad ("Ignoring attempt to re-define symbol");
4894 ignore_rest_of_line ();
4897 if (S_GET_VALUE (symbolP
))
4899 if (S_GET_VALUE (symbolP
) != size
)
4901 as_warn ("Length of .comm \"%s\" is already %d. Not changed to %d.",
4902 S_GET_NAME (symbolP
), S_GET_VALUE (symbolP
), size
);
4908 S_SET_VALUE (symbolP
, size
);
4909 S_SET_SEGMENT (symbolP
, bss_section
);
4910 S_SET_EXTERNAL (symbolP
);
4916 demand_empty_rest_of_line ();
4922 register char *name
;
4926 if (*input_line_pointer
== '\"')
4928 ++input_line_pointer
; /* -> 1st char of string. */
4929 name
= input_line_pointer
;
4930 while ((c
= next_char_of_string ()) >= 0)
4932 c
= *input_line_pointer
;
4933 *input_line_pointer
= '\0';
4934 *(input_line_pointer
- 1) = '\0';
4937 #define PREFIX "Copyright "
4938 #define MIDFIX ". All rights reserved. No part of this program may be photocopied, reproduced, or transmitted without prior written consent of "
4941 struct aux_hdr_list
*aux_hdr_entry
;
4943 char *company_name
= name
;
4946 date_part
= (char *) strchr (name
, ',');
4961 len
+= strlen (date_part
) + strlen (",");
4964 aux_hdr_entry
= (struct aux_hdr_list
*) malloc (sizeof (struct aux_hdr_list
));
4967 aux_hdr_entry
->ahl_next
= aux_hdr_root
;
4968 aux_hdr_root
= aux_hdr_entry
;
4972 aux_hdr_entry
->ahl_next
= NULL
;
4973 aux_hdr_root
= aux_hdr_entry
;
4975 aux_hdr_entry
->type
= COPYRIGHT_AUX_ID
;
4976 aux_hdr_entry
->contents
.cpy
.header_id
.append
= 1;
4977 aux_hdr_entry
->contents
.cpy
.header_id
.type
= COPYRIGHT_AUX_ID
;
4978 aux_hdr_entry
->contents
.cpy
.header_id
.length
= len
+ sizeof (unsigned int);
4979 while (aux_hdr_entry
->contents
.usr_str
.header_id
.length
% 4)
4980 aux_hdr_entry
->contents
.usr_str
.header_id
.length
+= 1;
4982 aux_hdr_entry
->contents
.cpy
.string_length
= len
;
4983 aux_hdr_entry
->contents
.cpy
.copyright
= (char *) (malloc (len
+ 1));
4984 strcpy (aux_hdr_entry
->contents
.cpy
.copyright
, PREFIX
);
4985 strcat (aux_hdr_entry
->contents
.cpy
.copyright
, name
);
4988 strcat (aux_hdr_entry
->contents
.cpy
.copyright
, ",");
4989 strcat (aux_hdr_entry
->contents
.cpy
.copyright
, date_part
);
4991 strcat (aux_hdr_entry
->contents
.cpy
.copyright
, MIDFIX
);
4992 strcat (aux_hdr_entry
->contents
.cpy
.copyright
, name
);
4993 strcat (aux_hdr_entry
->contents
.cpy
.copyright
, SUFFIX
);
4994 aux_hdr_entry
->contents
.cpy
.copyright
[len
] = NULL
;
4998 #endif /* OBJ_SOM */
5000 *input_line_pointer
= c
;
5004 as_bad ("Expected \"-ed string");
5006 pa_undefine_label ();
5007 demand_empty_rest_of_line ();
5014 demand_empty_rest_of_line ();
5022 as_bad (".ENTER encountered. gas doesn't generate entry code sequences.");
5032 if (!within_procedure
)
5033 as_bad ("Misplaced .entry. Ignored.");
5036 if (!callinfo_found
)
5037 as_bad ("Missing .callinfo.");
5039 last_call_info
->start_frag
= frag_now
;
5041 demand_empty_rest_of_line ();
5042 within_entry_exit
= TRUE
;
5043 where
= frag_more (0);
5045 fix_new_hppa (frag_now
, where
- frag_now
->fr_literal
, 0,
5046 last_call_info
->start_symbol
, (offsetT
) 0,
5047 (expressionS
*) NULL
, 0, R_ENTRY
, e_fsel
, 0, 0,
5048 (char *) &last_call_info
->ci_unwind
.descriptor
);
5051 /* XXX: no ENTRY relocation for PA ELF. What do we do instead? */
5053 fix_new_hppa (frag_now
, where
- frag_now
->fr_literal
, 0,
5054 last_call_info
->start_symbol
, (offsetT
) 0,
5055 (expressionS
*) NULL
, 0,
5056 R_HPPA_ENTRY
, 0, 0, 0,
5057 (char *) &last_call_info
->ci_unwind
.descriptor
);
5067 register label_symbolS
*label_symbolP
= pa_get_label ();
5068 register symbolS
*symbolP
;
5072 symbolP
= label_symbolP
->lss_label
;
5074 symbolP
->pa_sy_value
= get_absolute_expression ();
5075 symbolP
->pa_sy_type
= ST_ABSOLUTE
;
5076 symbolP
->sy_ref
= sym_unref
;
5077 symbolP
->sy_equ
= 1;
5079 S_SET_VALUE (symbolP
, get_absolute_expression ());
5080 S_SET_SEGMENT (symbolP
, &bfd_abs_section
);
5086 as_bad (".REG must use a label");
5088 as_bad (".EQU must use a label");
5091 pa_undefine_label ();
5092 demand_empty_rest_of_line ();
5101 where
= frag_more (0);
5103 fix_new_hppa (frag_now
, where
- frag_now
->fr_literal
, 0,
5104 last_call_info
->start_symbol
, (offsetT
) 0,
5105 (expressionS
*) NULL
, 0, R_EXIT
, e_fsel
, 0, 0,
5109 /* XXX: no EXIT relocation for PA ELF. All we do is create a */
5110 /* temporary symbol marking the end of the function. */
5112 char *name
= (char *) xmalloc (strlen ("L\001end_") +
5113 strlen (S_GET_NAME (last_call_info
->start_symbol
)) + 1);
5119 strcpy (name
, "L\001end_");
5120 strcat (name
, S_GET_NAME (last_call_info
->start_symbol
));
5122 symbolP
= symbol_find (name
);
5124 as_warn ("Symbol '%s' already defined.", name
);
5127 /* symbol value should be the offset of the */
5128 /* last instruction of the function */
5129 symbolP
= symbol_new (name
,
5131 (valueT
) (obstack_next_free (&frags
) - frag_now
->fr_literal
- 4),
5136 symbolP
->bsym
->flags
= BSF_LOCAL
;
5137 symbol_table_insert (symbolP
);
5140 last_call_info
->end_symbol
= symbolP
;
5142 as_bad ("Symbol '%s' could not be created.", name
);
5146 as_bad ("No memory for symbol name.");
5149 fix_new_hppa (frag_now
, where
- frag_now
->fr_literal
, 0,
5150 last_call_info
->start_symbol
, (offsetT
) 0,
5151 (expressionS
*) NULL
, 0, R_HPPA_EXIT
, 0, 0, 0,
5154 last_call_info
->end_frag
= frag_now
;
5156 pa_build_unwind_subspace (last_call_info
);
5158 exit_processing_complete
= TRUE
;
5165 if (!within_procedure
)
5166 as_bad (".EXIT must appear within a procedure");
5169 if (!callinfo_found
)
5170 as_bad ("Missing .callinfo");
5173 if (!within_entry_exit
)
5174 as_bad ("No .ENTRY for this .EXIT");
5177 within_entry_exit
= FALSE
;
5182 demand_empty_rest_of_line ();
5188 pa_build_symextn_section()
5191 asection
*save_seg
= now_seg
;
5192 subsegT subseg
= (subsegT
)0;
5193 subsegT save_subseg
= now_subseg
;
5195 seg
= subseg_new(".hppa_symextn", subseg
);
5196 bfd_set_section_flags (stdoutput
,
5198 SEC_HAS_CONTENTS
| SEC_READONLY
| SEC_ALLOC
| SEC_LOAD
);
5200 subseg_set(save_seg
, save_subseg
);
5208 register char *name
;
5211 register symbolS
*symbolP
;
5213 name
= input_line_pointer
;
5214 c
= get_symbol_end ();
5215 /* just after name is now '\0' */
5217 if ((symbolP
= symbol_find_or_make (name
)) == NULL
)
5219 as_bad ("Cannot define export symbol: %s\n", name
);
5220 p
= input_line_pointer
;
5222 input_line_pointer
++;
5227 symbolP
->pa_sy_dict
.symbol_scope
= SS_UNIVERSAL
;
5228 /* determination of the symbol_type field will have to wait until
5229 we know the subspace index (within the object file) of the subspace
5230 containing this symbol */
5232 /* S_SET_SEGMENT(symbolP,&bfd_und_section); */
5233 S_SET_EXTERNAL (symbolP
);
5234 /* symbolP->sy_frag = frag_now; */
5237 p
= input_line_pointer
;
5239 if (!is_end_of_statement ())
5241 input_line_pointer
++;
5242 pa_export_args (symbolP
);
5244 pa_build_symextn_section();
5249 demand_empty_rest_of_line ();
5254 pa_export_args (symbolP
)
5255 register symbolS
*symbolP
;
5257 register char *name
;
5261 register unsigned int arg_reloc
;
5263 elf32_symbol_type
*esymbolP
= (elf32_symbol_type
*) (symbolP
->bsym
);
5266 if (strncasecmp (input_line_pointer
, "absolute", 8) == 0)
5268 input_line_pointer
+= 8;
5270 symbolP
->pa_sy_dict
.symbol_type
= ST_ABSOLUTE
;
5272 S_SET_SEGMENT (symbolP
, &bfd_abs_section
);
5275 else if (strncasecmp (input_line_pointer
, "code", 4) == 0)
5277 input_line_pointer
+= 4;
5279 symbolP
->pa_sy_dict
.symbol_type
= ST_CODE
;
5281 /* S_SET_SEGMENT(symbolP,text_section); */
5284 else if (strncasecmp (input_line_pointer
, "data", 4) == 0)
5286 input_line_pointer
+= 4;
5288 symbolP
->pa_sy_dict
.symbol_type
= ST_DATA
;
5290 /* S_SET_SEGMENT(symbolP,data_section); */
5293 else if ((strncasecmp (input_line_pointer
, "entry", 5) == 0))
5295 input_line_pointer
+= 5;
5297 symbolP
->pa_sy_dict
.symbol_type
= ST_ENTRY
;
5299 symbolP
->bsym
->flags
|= BSF_FUNCTION
;
5302 else if (strncasecmp (input_line_pointer
, "millicode", 9) == 0)
5304 input_line_pointer
+= 9;
5306 symbolP
->pa_sy_dict
.symbol_type
= ST_MILLICODE
;
5309 else if (strncasecmp (input_line_pointer
, "plabel", 6) == 0)
5311 input_line_pointer
+= 6;
5313 symbolP
->pa_sy_dict
.symbol_type
= ST_PLABEL
;
5316 else if (strncasecmp (input_line_pointer
, "pri_prog", 8) == 0)
5318 input_line_pointer
+= 8;
5320 symbolP
->pa_sy_dict
.symbol_type
= ST_PRI_PROG
;
5323 else if (strncasecmp (input_line_pointer
, "sec_prog", 8) == 0)
5325 input_line_pointer
+= 8;
5327 symbolP
->pa_sy_dict
.symbol_type
= ST_SEC_PROG
;
5331 while (!is_end_of_statement ())
5333 if (*input_line_pointer
== ',')
5334 input_line_pointer
++;
5335 name
= input_line_pointer
;
5336 c
= get_symbol_end ();
5337 if ((strncasecmp (name
, "argw", 4) == 0))
5339 p
= input_line_pointer
;
5341 input_line_pointer
++;
5342 temp
= atoi (name
+ 4);
5343 name
= input_line_pointer
;
5344 c
= get_symbol_end ();
5345 arg_reloc
= pa_align_arg_reloc (temp
, pa_build_arg_reloc (name
));
5347 symbolP
->pa_sy_dict
.arg_reloc
|= arg_reloc
;
5349 esymbolP
->tc_data
.hppa_arg_reloc
|= arg_reloc
;
5351 *input_line_pointer
= c
;
5353 else if ((strncasecmp (name
, "rtnval", 6)) == 0)
5355 p
= input_line_pointer
;
5357 input_line_pointer
++;
5358 name
= input_line_pointer
;
5359 c
= get_symbol_end ();
5360 arg_reloc
= pa_build_arg_reloc (name
);
5362 symbolP
->pa_sy_dict
.arg_reloc
|= arg_reloc
;
5364 esymbolP
->tc_data
.hppa_arg_reloc
|= arg_reloc
;
5366 *input_line_pointer
= c
;
5368 else if ((strncasecmp (name
, "priv_lev", 8)) == 0)
5370 p
= input_line_pointer
;
5372 input_line_pointer
++;
5373 /*** temp = get_absolute_expression (); ***/
5374 temp
= atoi (input_line_pointer
);
5375 c
= get_symbol_end ();
5376 *input_line_pointer
= c
;
5378 symbolP
->sy_priv_lev
= temp
& 3; /* this is stored in symbol_value later */
5383 as_bad ("Undefined .EXPORT/.IMPORT argument (ignored): %s", name
);
5384 p
= input_line_pointer
;
5387 if (!is_end_of_statement ())
5388 input_line_pointer
++;
5395 register char *name
;
5398 register symbolS
*symbolP
;
5400 name
= input_line_pointer
;
5401 c
= get_symbol_end ();
5402 /* just after name is now '\0' */
5404 symbolP
= symbol_find_or_make (name
);
5405 #if defined(OBJ_ELF)
5406 /* symbolP->bsym->flags |= BSF_IMPORT; *//* XXX BSF_IMPORT is obsolete */
5408 /* Check to see if this symbol has already been exported (this means its */
5409 /* defined locally and the import statement is redundant). */
5410 /* If it has not been exported, go ahead and mark this symbol as SS_UNSAT */
5411 /* (an unsatisfied external symbol) */
5413 /* But, if the symbol has already been referenced (sy_ref == TRUE),
5416 if (!symbolP
->sy_ref
)
5418 if (symbolP
->pa_sy_dict
.symbol_scope
!= SS_UNIVERSAL
)
5420 symbolP
->pa_sy_dict
.symbol_scope
= SS_UNSAT
;
5421 symbolP
->sy_ref
= FALSE
;
5426 p
= input_line_pointer
;
5429 if (!is_end_of_statement ())
5431 input_line_pointer
++;
5433 pa_export_args (symbolP
);
5435 /* In ELF, since this is an import, leave the section undefined. */
5436 /* S_SET_SEGMENT(symbolP,&bfd_und_section); */
5442 /* no further arguments, assign a default type according
5443 to the current subspace (CODE or DATA) */
5447 symbolP
->pa_sy_dict
.symbol_type
= ST_CODE
;
5450 symbolP
->pa_sy_dict
.symbol_type
= ST_ABSOLUTE
;
5453 symbolP
->pa_sy_dict
.symbol_type
= ST_DATA
;
5456 /* In ELF, if the section is undefined, then the symbol is undefined */
5457 /* Since this is an import, leave the section undefined. */
5458 S_SET_SEGMENT (symbolP
, &bfd_und_section
);
5463 demand_empty_rest_of_line ();
5470 register char *name
;
5474 name
= input_line_pointer
;
5475 c
= get_symbol_end ();
5476 /* just after name is now '\0' */
5478 if (strlen (name
) > 0)
5481 p
= input_line_pointer
;
5486 as_warn ("Missing label name on .LABEL");
5489 if (!is_end_of_statement ())
5491 as_warn ("extra .LABEL arguments ignored.");
5492 ignore_rest_of_line ();
5494 demand_empty_rest_of_line ();
5502 as_bad (".LEAVE encountered. gas doesn't generate exit code sequences.");
5510 s_org (0); /* ORG actually allows another argument
5511 (the fill value) but maybe this is OK? */
5512 pa_undefine_label ();
5525 name
= input_line_pointer
;
5526 c
= get_symbol_end ();
5527 /* just after name is now '\0' */
5529 if ((symbolP
= symbol_find_or_make (name
)) == NULL
)
5531 as_bad ("Cannot define static symbol: %s\n", name
);
5532 p
= input_line_pointer
;
5534 input_line_pointer
++;
5539 symbolP
->pa_sy_dict
.symbol_scope
= SS_LOCAL
;
5540 /* determination of the symbol_type field will have to wait until
5541 we know the subspace index (within the object file) of the subspace
5542 containing this symbol */
5544 /* S_SET_SEGMENT(symbolP,&bfd_und_section); */
5545 S_CLEAR_EXTERNAL (symbolP
);
5546 /* symbolP->sy_frag = frag_now; */
5549 p
= input_line_pointer
;
5551 if (!is_end_of_statement ())
5553 input_line_pointer
++;
5554 pa_export_args (symbolP
);
5558 demand_empty_rest_of_line ();
5565 call_infoS
*call_info
;
5567 if (within_procedure
)
5568 as_fatal ("Nested procedures");
5570 callinfo_found
= FALSE
;
5571 within_procedure
= TRUE
;
5572 exit_processing_complete
= FALSE
;
5574 /* create another call_info structure */
5576 call_info
= (call_infoS
*) xmalloc (sizeof (call_infoS
));
5579 as_fatal ("Cannot allocate unwind descriptor\n");
5581 bzero (call_info
, sizeof (call_infoS
));
5583 call_info
->ci_next
= NULL
;
5585 if (call_info_root
== NULL
)
5587 call_info_root
= call_info
;
5588 last_call_info
= call_info
;
5592 last_call_info
->ci_next
= call_info
;
5593 last_call_info
= call_info
;
5596 /* set up defaults on call_info structure */
5598 call_info
->ci_unwind
.descriptor
.cannot_unwind
= 0;
5599 call_info
->ci_unwind
.descriptor
.region_desc
= 1;
5600 call_info
->entry_sr
= ~0;
5601 call_info
->makes_calls
= 1;
5602 call_info
->hpux_int
= 0;
5604 /* If we got a .PROC pseudo-op, we know that the function is defined
5605 locally. Make sure it gets into the symbol table */
5607 label_symbolS
*label_symbolP
= pa_get_label ();
5611 if (label_symbolP
->lss_label
)
5614 label_symbolP
->lss_label
->sy_ref
|= sym_def
;
5616 last_call_info
->start_symbol
= label_symbolP
->lss_label
;
5617 label_symbolP
->lss_label
->bsym
->flags
|= BSF_FUNCTION
;
5620 as_bad ("Missing function name for .PROC (corrupted label)");
5623 as_bad ("Missing function name for .PROC");
5626 demand_empty_rest_of_line ();
5634 if (!within_procedure
)
5635 as_bad ("misplaced .procend");
5637 if (!callinfo_found
)
5638 as_bad ("Missing .callinfo for this procedure");
5640 if (within_entry_exit
)
5641 as_bad ("Missing .EXIT for a .ENTRY");
5643 if (!exit_processing_complete
)
5646 within_procedure
= FALSE
;
5647 demand_empty_rest_of_line ();
5652 pa_parse_space_stmt (space_name
, create_flag
)
5656 register char *name
;
5672 space_dict_chainS
*space
;
5674 /* load default values */
5679 if (strcasecmp (space_name
, "$TEXT$") == 0)
5698 if (!is_end_of_statement ())
5700 print_errors
= FALSE
;
5701 ptemp
= input_line_pointer
+ 1;
5702 if ((temp
= pa_parse_number (&ptemp
)) >= 0)
5705 input_line_pointer
= ptemp
;
5709 while (!is_end_of_statement ())
5711 input_line_pointer
++;
5712 name
= input_line_pointer
;
5713 c
= get_symbol_end ();
5714 if ((strncasecmp (name
, "SPNUM", 5) == 0))
5716 p
= input_line_pointer
;
5718 input_line_pointer
++;
5719 temp
= get_absolute_expression ();
5722 else if ((strncasecmp (name
, "SORT", 4) == 0))
5724 p
= input_line_pointer
;
5726 input_line_pointer
++;
5727 temp
= get_absolute_expression ();
5730 else if ((strncasecmp (name
, "UNLOADABLE", 10) == 0))
5732 p
= input_line_pointer
;
5736 else if ((strncasecmp (name
, "NOTDEFINED", 10) == 0))
5738 p
= input_line_pointer
;
5742 else if ((strncasecmp (name
, "PRIVATE", 7) == 0))
5744 p
= input_line_pointer
;
5750 as_bad ("Unrecognized .SPACE argument");
5751 p
= input_line_pointer
;
5756 print_errors
= TRUE
;
5759 space
= create_new_space (space_name
, spnum
, loadable
, defined
, private, sort
, 1, seg
);
5761 { /* if no creation of new space, this must be the first */
5762 /* occurrence of a built-in space */
5763 space
= is_defined_space (space_name
);
5764 SPACE_SPNUM (space
) = spnum
;
5765 SPACE_LOADABLE (space
) = loadable
& 1;
5766 SPACE_DEFINED (space
) = defined
& 1;
5767 SPACE_PRIVATE (space
) = private & 1;
5768 SPACE_SORT (space
) = sort
& 0xff;
5769 space
->sd_defined
= 1;
5770 space
->sd_seg
= seg
;
5776 pa_align_subseg (seg
, subseg
)
5780 subspace_dict_chainS
*now_subspace
;
5784 now_subspace
= pa_subsegment_to_subspace (seg
, subseg
);
5785 if (SUBSPACE_ALIGN (now_subspace
) == 0)
5786 alignment
= now_subspace
->ssd_last_align
;
5787 else if (now_subspace
->ssd_last_align
> SUBSPACE_ALIGN (now_subspace
))
5788 alignment
= now_subspace
->ssd_last_align
;
5790 alignment
= SUBSPACE_ALIGN (now_subspace
);
5793 while ((1 << shift
) < alignment
)
5796 frag_align (shift
, 0);
5802 register char *name
;
5805 register space_dict_chainS
*sd_chain
;
5806 char space_name
[40];
5808 if (within_procedure
)
5810 as_bad ("Can\'t change spaces within a procedure definition. Ignored");
5811 ignore_rest_of_line ();
5815 if (strncasecmp (input_line_pointer
, "$text$", 6) == 0)
5817 input_line_pointer
+= 6;
5818 sd_chain
= is_defined_space ("$TEXT$");
5819 if (sd_chain
== NULL
)
5820 sd_chain
= pa_parse_space_stmt ("$TEXT$", 1);
5821 else if (sd_chain
->sd_defined
== 0)
5822 sd_chain
= pa_parse_space_stmt ("$TEXT$", 0);
5824 current_space
= sd_chain
;
5825 SPACE_DEFINED (current_space
) = 1;
5826 current_space
->sd_defined
= 1;
5827 if (now_seg
!= text_section
) /* no need to align if we are already there */
5828 pa_align_subseg (now_seg
, now_subseg
);
5830 subseg_set (text_section
, sd_chain
->sd_last_subseg
);
5831 current_subspace
= pa_subsegment_to_subspace (text_section
,
5832 sd_chain
->sd_last_subseg
);
5833 demand_empty_rest_of_line ();
5836 if (strncasecmp (input_line_pointer
, "$private$", 9) == 0)
5838 input_line_pointer
+= 9;
5839 sd_chain
= is_defined_space ("$PRIVATE$");
5840 if (sd_chain
== NULL
)
5841 sd_chain
= pa_parse_space_stmt ("$PRIVATE$", 1);
5842 else if (sd_chain
->sd_defined
== 0)
5843 sd_chain
= pa_parse_space_stmt ("$PRIVATE$", 0);
5845 current_space
= sd_chain
;
5846 SPACE_DEFINED (current_space
) = 1;
5847 current_space
->sd_defined
= 1;
5848 if (now_seg
!= data_section
) /* no need to align if we are already there */
5849 pa_align_subseg (now_seg
, now_subseg
);
5850 subseg_set (data_section
, sd_chain
->sd_last_subseg
);
5851 current_subspace
= pa_subsegment_to_subspace (data_section
,
5852 sd_chain
->sd_last_subseg
);
5853 demand_empty_rest_of_line ();
5856 if (strncasecmp (input_line_pointer
,
5857 GDB_DEBUG_SPACE_NAME
, strlen (GDB_DEBUG_SPACE_NAME
)) == 0)
5859 input_line_pointer
+= strlen (GDB_DEBUG_SPACE_NAME
);
5860 sd_chain
= is_defined_space (GDB_DEBUG_SPACE_NAME
);
5861 if (sd_chain
== NULL
)
5862 sd_chain
= pa_parse_space_stmt (GDB_DEBUG_SPACE_NAME
, 1);
5863 else if (sd_chain
->sd_defined
== 0)
5864 sd_chain
= pa_parse_space_stmt (GDB_DEBUG_SPACE_NAME
, 0);
5866 current_space
= sd_chain
;
5867 SPACE_DEFINED (current_space
) = 1;
5868 current_space
->sd_defined
= 1;
5871 if (now_seg
!= SEG_GDB
) /* no need to align if we are already there */
5873 pa_align_subseg (now_seg
, now_subseg
);
5874 subseg_set (SEG_GDB
, sd_chain
->sd_last_subseg
);
5875 current_subspace
= pa_subsegment_to_subspace (SEG_GDB
,
5876 sd_chain
->sd_last_subseg
);
5880 /* no need to align if we are already there */
5881 if (strcmp (segment_name (now_seg
), GDB_DEBUG_SPACE_NAME
) != 0)
5882 pa_align_subseg (now_seg
, now_subseg
);
5883 gdb_section
= subseg_new (GDB_DEBUG_SPACE_NAME
,
5884 sd_chain
->sd_last_subseg
);
5885 current_subspace
= pa_subsegment_to_subspace (gdb_section
,
5886 sd_chain
->sd_last_subseg
);
5889 demand_empty_rest_of_line ();
5893 /* it could be a space specified by number */
5895 if ((temp
= pa_parse_number (&input_line_pointer
)) >= 0)
5897 if (sd_chain
= pa_find_space_by_number (temp
))
5899 current_space
= sd_chain
;
5900 SPACE_DEFINED (current_space
) = 1;
5901 current_space
->sd_defined
= 1;
5902 if (now_seg
!= sd_chain
->sd_seg
) /* don't align if we're already there */
5903 pa_align_subseg (now_seg
, now_subseg
);
5904 subseg_set (sd_chain
->sd_seg
, sd_chain
->sd_last_subseg
);
5905 current_subspace
= pa_subsegment_to_subspace (sd_chain
->sd_seg
,
5906 sd_chain
->sd_last_subseg
);
5907 demand_empty_rest_of_line ();
5912 /* not a number, attempt to create a new space */
5914 name
= input_line_pointer
;
5915 c
= get_symbol_end ();
5916 space_name
[0] = 0x00;
5917 strcpy (space_name
, name
);
5918 *input_line_pointer
= c
;
5920 sd_chain
= pa_parse_space_stmt (space_name
, 1);
5921 current_space
= sd_chain
;
5922 SPACE_DEFINED (current_space
) = 1;
5923 current_space
->sd_defined
= 1;
5924 if (now_seg
!= sd_chain
->sd_seg
) /* don't align if we're already there */
5925 pa_align_subseg (now_seg
, now_subseg
);
5926 subseg_set (sd_chain
->sd_seg
, sd_chain
->sd_last_subseg
);
5927 current_subspace
= pa_subsegment_to_subspace (sd_chain
->sd_seg
,
5928 sd_chain
->sd_last_subseg
);
5929 demand_empty_rest_of_line ();
5937 register char *name
;
5940 space_dict_chainS
*space
;
5942 name
= input_line_pointer
;
5943 c
= get_symbol_end ();
5944 space
= is_defined_space (name
);
5948 /* put bytes in right order. */
5949 md_number_to_chars (p
, SPACE_SPNUM (space
), 4);
5952 as_warn ("Undefined space: '%s' Assuming space number = 0.", name
);
5954 *input_line_pointer
= c
;
5955 demand_empty_rest_of_line ();
5961 is_power_of_2 (value
)
5967 while ((1 << shift
) != value
&& shift
< 32)
5978 register char *name
;
5981 char loadable
, code_only
, common
, dup_common
, zero
;
5988 space_dict_chainS
*space
;
5989 subspace_dict_chainS
*ssd
;
5991 int is_power_of_2 ();
5993 if (within_procedure
)
5995 as_bad ("Can\'t change subspaces within a procedure definition. Ignored");
5996 ignore_rest_of_line ();
6000 name
= input_line_pointer
;
6001 c
= get_symbol_end ();
6002 space
= pa_segment_to_space (now_seg
);
6003 ssd
= is_defined_subspace (name
, space
->sd_last_subseg
);
6005 ss_name
= xmalloc (strlen (name
) + 1);
6006 strcpy (ss_name
, name
);
6008 *input_line_pointer
= c
;
6010 /* load default values */
6018 space_index
= ~0; /* filled in when the .o file is written */
6019 alignment
= 0; /* alignment=0 means no ALIGN= appeared on the .SUBSPA */
6020 /* pseudo-op. The default will be the largest .ALIGN */
6021 /* encountered (or 1 if no .ALIGN is encountered) */
6026 if (ssd
->ssd_defined
)
6029 subseg_set (now_seg
, ssd
->ssd_subseg
);
6031 /* subseg_new(now_seg->name,ssd->ssd_subseg); */
6032 subseg_new ((char *) ssd
->ssd_seg
->name
, ssd
->ssd_subseg
);
6034 if (!is_end_of_statement ())
6036 as_warn ("Parameters of an existing subspace can\'t be modified");
6038 demand_empty_rest_of_line ();
6043 ssd
->ssd_defined
= 1;
6048 /* a new subspace */
6049 /* load default values */
6051 while (pa_def_subspaces
[i
].name
)
6053 if (strcasecmp (pa_def_subspaces
[i
].name
, ss_name
) == 0)
6055 loadable
= pa_def_subspaces
[i
].loadable
;
6056 common
= pa_def_subspaces
[i
].common
;
6057 dup_common
= pa_def_subspaces
[i
].dup_common
;
6058 code_only
= pa_def_subspaces
[i
].code_only
;
6059 zero
= pa_def_subspaces
[i
].zero
;
6060 space_index
= pa_def_subspaces
[i
].space_index
;
6061 /* alignment = pa_def_subspaces[i].alignment; */
6063 quadrant
= pa_def_subspaces
[i
].quadrant
;
6064 access
= pa_def_subspaces
[i
].access
;
6065 sort
= pa_def_subspaces
[i
].sort
;
6072 if (!is_end_of_statement ())
6074 input_line_pointer
++;
6075 while (!is_end_of_statement ())
6077 name
= input_line_pointer
;
6078 c
= get_symbol_end ();
6079 if ((strncasecmp (name
, "QUAD", 4) == 0))
6081 *input_line_pointer
= c
;
6082 input_line_pointer
++;
6083 temp
= get_absolute_expression ();
6086 else if ((strncasecmp (name
, "ALIGN", 5) == 0))
6088 *input_line_pointer
= c
;
6089 input_line_pointer
++;
6090 temp
= get_absolute_expression ();
6092 if (!is_power_of_2 (alignment
))
6094 as_bad ("Alignment must be a power of 2");
6098 else if ((strncasecmp (name
, "ACCESS", 6) == 0))
6100 *input_line_pointer
= c
;
6101 input_line_pointer
++;
6102 temp
= get_absolute_expression ();
6105 else if ((strncasecmp (name
, "SORT", 4) == 0))
6107 *input_line_pointer
= c
;
6108 input_line_pointer
++;
6109 temp
= get_absolute_expression ();
6112 else if ((strncasecmp (name
, "CODE_ONLY", 9) == 0))
6114 *input_line_pointer
= c
;
6117 else if ((strncasecmp (name
, "UNLOADABLE", 10) == 0))
6119 *input_line_pointer
= c
;
6122 else if ((strncasecmp (name
, "COMMON", 6) == 0))
6124 *input_line_pointer
= c
;
6127 else if ((strncasecmp (name
, "DUP_COMM", 8) == 0))
6129 *input_line_pointer
= c
;
6132 else if ((strncasecmp (name
, "ZERO", 4) == 0))
6134 *input_line_pointer
= c
;
6139 as_bad ("Unrecognized .SUBSPACE argument");
6141 if (!is_end_of_statement ())
6142 input_line_pointer
++;
6145 space
= pa_segment_to_space (now_seg
);
6148 current_subspace
= update_subspace (ss_name
, 1, loadable
, code_only
,
6149 common
, dup_common
, sort
, zero
, access
,
6150 space_index
, alignment
, quadrant
,
6155 current_subspace
= create_new_subspace (space
, ss_name
, 1, loadable
, code_only
,
6156 common
, dup_common
, zero
, sort
,
6157 access
, space_index
, alignment
,
6160 SUBSPACE_SUBSPACE_START (current_subspace
) = pa_subspace_start (space
, quadrant
);
6162 demand_empty_rest_of_line ();
6163 subseg_set (current_subspace
->ssd_seg
, current_subspace
->ssd_subseg
);
6168 /* For ELF, this function serves one purpose: to setup the st_size */
6169 /* field of STT_FUNC symbols. To do this, we need to scan the */
6170 /* call_info structure list, determining st_size in one of two possible */
6173 /* 1. call_info->start_frag->fr_fix has the size of the fragment. */
6174 /* This approach assumes that the function was built into a */
6175 /* single fragment. This works for most cases, but might fail. */
6176 /* For example, if there was a segment change in the middle of */
6179 /* 2. The st_size field is the difference in the addresses of the */
6180 /* call_info->start_frag->fr_address field and the fr_address */
6181 /* field of the next fragment with fr_type == rs_fill and */
6185 elf_hppa_final_processing ()
6187 extern call_infoS
*call_info_root
;
6191 for (ciP
= call_info_root
; ciP
; ciP
= ciP
->ci_next
)
6193 elf32_symbol_type
*esym
= (elf32_symbol_type
*) ciP
->start_symbol
->bsym
;
6194 esym
->internal_elf_sym
.st_size
=
6195 S_GET_VALUE (ciP
->end_symbol
) - S_GET_VALUE (ciP
->start_symbol
) + 4;
6199 /* pa-spaces.c -- Space/subspace support for the HP PA-RISC version of GAS */
6201 /* for space, subspace, and symbol maintenance on HP 9000 Series 800 */
6203 space_dict_chainS
*space_dict_root
;
6204 space_dict_chainS
*space_dict_last
;
6206 space_dict_chainS
*current_space
;
6207 subspace_dict_chainS
*current_subspace
;
6212 space_dict_chainS
*space
;
6214 subsegT now_subseg
= now_subseg
;
6216 space_dict_root
= NULL
;
6217 space_dict_last
= NULL
;
6219 /* create default space and subspace dictionaries */
6222 while (pa_def_spaces
[i
].name
)
6224 if (pa_def_spaces
[i
].alias
)
6225 pa_def_spaces
[i
].segment
= subseg_new (pa_def_spaces
[i
].alias
, 0);
6227 pa_def_spaces
[i
].segment
= bfd_make_section_old_way (stdoutput
, pa_def_spaces
[i
].name
);
6229 create_new_space (pa_def_spaces
[i
].name
, pa_def_spaces
[i
].spnum
,
6230 pa_def_spaces
[i
].loadable
, pa_def_spaces
[i
].defined
,
6231 pa_def_spaces
[i
].private, pa_def_spaces
[i
].sort
, 0,
6232 pa_def_spaces
[i
].segment
);
6237 while (pa_def_subspaces
[i
].name
)
6239 space
= pa_segment_to_space (pa_def_spaces
[pa_def_subspaces
[i
].def_space_index
].segment
);
6242 char *name
= pa_def_subspaces
[i
].alias
;
6244 name
= pa_def_subspaces
[i
].name
;
6245 create_new_subspace (space
, name
,
6246 pa_def_subspaces
[i
].defined
,
6247 pa_def_subspaces
[i
].loadable
,
6248 pa_def_subspaces
[i
].code_only
, pa_def_subspaces
[i
].common
,
6249 pa_def_subspaces
[i
].dup_common
, pa_def_subspaces
[i
].zero
,
6250 pa_def_subspaces
[i
].sort
, pa_def_subspaces
[i
].access
,
6251 pa_def_subspaces
[i
].space_index
,
6252 pa_def_subspaces
[i
].alignment
,
6253 pa_def_subspaces
[i
].quadrant
,
6254 pa_def_spaces
[pa_def_subspaces
[i
].def_space_index
].segment
);
6255 subseg_new (name
, pa_def_subspaces
[i
].subsegment
);
6258 as_fatal ("Internal error: space missing for subspace \"%s\"\n",
6259 pa_def_subspaces
[i
].name
);
6265 create_new_space (name
, spnum
, loadable
, defined
, private, sort
, defined_in_file
, seg
)
6272 char defined_in_file
;
6276 Elf_Internal_Shdr
*new_space
;
6277 space_dict_chainS
*chain_entry
;
6279 new_space
= (Elf_Internal_Shdr
*) xmalloc (sizeof (Elf_Internal_Shdr
));
6281 as_fatal ("Out of memory: could not allocate new Elf_Internal_Shdr: %s\n", name
);
6284 new_space->space_number = spnum;
6285 new_space->is_loadable = loadable & 1;
6286 new_space->is_defined = defined & 1;
6287 new_space->is_private = private & 1;
6288 new_space->sort_key = sort & 0xff;
6290 new_space->loader_fix_index = ~0;
6291 new_space->loader_fix_quantity = 0;
6292 new_space->init_pointer_index = ~0;
6293 new_space->init_pointer_quantity = 0;
6294 new_space->subspace_quantity = 0;
6297 chain_entry
= (space_dict_chainS
*) xmalloc (sizeof (space_dict_chainS
));
6299 as_fatal ("Out of memory: could not allocate new space chain entry: %s\n", name
);
6301 SPACE_NAME (chain_entry
) = (char *) xmalloc (strlen (name
) + 1);
6302 strcpy (SPACE_NAME (chain_entry
), name
);
6304 chain_entry
->sd_entry
= new_space
;
6305 chain_entry
->sd_defined
= defined_in_file
;
6306 chain_entry
->sd_seg
= seg
;
6307 chain_entry
->sd_last_subseg
= -1;
6308 chain_entry
->sd_next
= NULL
;
6310 SPACE_SPNUM (chain_entry
) = spnum
;
6311 SPACE_LOADABLE (chain_entry
) = loadable
& 1;
6312 SPACE_DEFINED (chain_entry
) = defined
& 1;
6313 SPACE_PRIVATE (chain_entry
) = private & 1;
6314 SPACE_SORT (chain_entry
) = sort
& 0xff;
6316 /* find spot for the new space based on its sort key */
6318 if (!space_dict_last
)
6319 space_dict_last
= chain_entry
;
6321 if (space_dict_root
== NULL
) /* if root is null, it is very easy */
6322 space_dict_root
= chain_entry
;
6325 space_dict_chainS
*sdcP
;
6326 space_dict_chainS
*last_sdcP
;
6328 sdcP
= space_dict_root
;
6333 if (SPACE_SORT (sdcP
) < SPACE_SORT (chain_entry
))
6336 sdcP
= sdcP
->sd_next
;
6338 else if (SPACE_SORT (sdcP
) == SPACE_SORT (chain_entry
))
6341 sdcP
= sdcP
->sd_next
;
6343 else if (SPACE_SORT (sdcP
) > SPACE_SORT (chain_entry
))
6351 chain_entry
->sd_next
= sdcP
;
6352 last_sdcP
->sd_next
= chain_entry
;
6356 space_dict_root
= chain_entry
;
6357 chain_entry
->sd_next
= sdcP
;
6360 if (chain_entry
->sd_next
== NULL
)
6361 space_dict_last
= chain_entry
;
6367 subspace_dict_chainS
6368 * create_new_subspace (space
, name
, defined
, loadable
, code_only
, common
, dup_common
,
6369 is_zero
, sort
, access
, space_index
, alignment
, quadrant
, seg
)
6370 space_dict_chainS
*space
;
6372 char defined
, loadable
, code_only
, common
, dup_common
, is_zero
;
6380 Elf_Internal_Shdr
*new_subspace
;
6381 subspace_dict_chainS
*chain_entry
;
6382 symbolS
*start_symbol
;
6384 new_subspace
= (Elf_Internal_Shdr
*) xmalloc (sizeof (Elf_Internal_Shdr
));
6386 as_fatal ("Out of memory: could not allocate new Elf_Internal_Shdr: %s\n",
6390 new_subspace->space_index = space_index;
6391 new_subspace->fixup_request_index = ~0;
6394 chain_entry
= (subspace_dict_chainS
*) xmalloc (sizeof (subspace_dict_chainS
));
6396 as_fatal ("Out of memory: could not allocate new subspace chain entry: %s\n", name
);
6398 chain_entry
->ssd_entry
= new_subspace
;
6399 SUBSPACE_NAME (chain_entry
) = (char *) xmalloc (strlen (name
) + 1);
6400 strcpy (SUBSPACE_NAME (chain_entry
), name
);
6402 SUBSPACE_ACCESS (chain_entry
) = access
& 0x7f;
6403 SUBSPACE_LOADABLE (chain_entry
) = loadable
& 1;
6404 SUBSPACE_COMMON (chain_entry
) = common
& 1;
6405 SUBSPACE_DUP_COMM (chain_entry
) = dup_common
& 1;
6406 SUBSPACE_SORT (chain_entry
) = sort
& 0xff;
6407 SET_SUBSPACE_CODE_ONLY (chain_entry
, code_only
& 1);
6408 SUBSPACE_ALIGN (chain_entry
) = alignment
& 0xffff;
6409 SUBSPACE_QUADRANT (chain_entry
) = quadrant
& 0x3;
6410 SUBSPACE_SUBSPACE_START (chain_entry
) = pa_subspace_start (space
, quadrant
);
6412 chain_entry
->ssd_defined
= defined
;
6413 chain_entry
->ssd_space_number
= space_index
;
6414 chain_entry
->ssd_subseg
= pa_next_subseg (space
);
6415 chain_entry
->ssd_seg
= seg
;
6416 SUBSPACE_ZERO (chain_entry
) = is_zero
;
6417 chain_entry
->ssd_last_align
= 1;
6418 chain_entry
->ssd_next
= NULL
;
6420 /* find spot for the new subspace based on its sort key */
6422 if (space
->sd_subspaces
== NULL
) /* if root is null, it is very easy */
6423 space
->sd_subspaces
= chain_entry
;
6426 subspace_dict_chainS
*ssdcP
;
6427 subspace_dict_chainS
*last_ssdcP
;
6429 ssdcP
= space
->sd_subspaces
;
6434 if (SUBSPACE_SORT (ssdcP
) < SUBSPACE_SORT (chain_entry
))
6437 ssdcP
= ssdcP
->ssd_next
;
6439 else if (SUBSPACE_SORT (ssdcP
) == SUBSPACE_SORT (chain_entry
))
6442 ssdcP
= ssdcP
->ssd_next
;
6444 else if (SUBSPACE_SORT (ssdcP
) > SUBSPACE_SORT (chain_entry
))
6452 chain_entry
->ssd_next
= ssdcP
;
6453 last_ssdcP
->ssd_next
= chain_entry
;
6457 space
->sd_subspaces
= chain_entry
;
6458 chain_entry
->ssd_next
= ssdcP
;
6462 start_symbol
= pa_set_start_symbol (seg
, space
->sd_last_subseg
);
6463 chain_entry
->ssd_start_sym
= start_symbol
;
6468 subspace_dict_chainS
6469 * update_subspace (name
, defined
, loadable
, code_only
, common
, dup_common
, sort
, zero
,
6470 access
, space_index
, alignment
, quadrant
, subseg
)
6472 char defined
, loadable
, code_only
, common
, dup_common
, zero
;
6480 subspace_dict_chainS
*chain_entry
;
6481 subspace_dict_chainS
*is_defined_subspace ();
6483 if ((chain_entry
= is_defined_subspace (name
, subseg
)))
6486 SUBSPACE_ACCESS (chain_entry
) = access
& 0x7f;
6487 SUBSPACE_LOADABLE (chain_entry
) = loadable
& 1;
6488 SUBSPACE_COMMON (chain_entry
) = common
& 1;
6489 SUBSPACE_DUP_COMM (chain_entry
) = dup_common
& 1;
6490 SET_SUBSPACE_CODE_ONLY (chain_entry
, code_only
& 1);
6491 SUBSPACE_SORT (chain_entry
) = sort
& 0xff;
6492 /* chain_entry->ssd_entry->space_index = space_index; */
6493 SUBSPACE_ALIGN (chain_entry
) = alignment
& 0xffff;
6494 SUBSPACE_QUADRANT (chain_entry
) = quadrant
& 0x3;
6496 chain_entry
->ssd_defined
= defined
;
6497 chain_entry
->ssd_space_number
= space_index
;
6498 SUBSPACE_ZERO (chain_entry
) = zero
;
6508 is_defined_space (name
)
6511 space_dict_chainS
*spaceCh
;
6513 for (spaceCh
= space_dict_root
; spaceCh
; spaceCh
= spaceCh
->sd_next
)
6515 if (strcmp (SPACE_NAME (spaceCh
), name
) == 0)
6525 pa_segment_to_space (seg
)
6528 space_dict_chainS
*spaceCh
;
6530 for (spaceCh
= space_dict_root
; spaceCh
; spaceCh
= spaceCh
->sd_next
)
6532 if (spaceCh
->sd_seg
== seg
)
6541 subspace_dict_chainS
*
6542 is_defined_subspace (name
, subseg
)
6546 space_dict_chainS
*spaceCh
;
6547 subspace_dict_chainS
*subspCh
;
6549 for (spaceCh
= space_dict_root
; spaceCh
; spaceCh
= spaceCh
->sd_next
)
6551 for (subspCh
= spaceCh
->sd_subspaces
; subspCh
; subspCh
= subspCh
->ssd_next
)
6554 if ( strcmp(SUBSPACE_NAME(subspCh),name) == 0 &&
6555 subspCh->ssd_subseg == subseg ) {
6557 if (strcmp (SUBSPACE_NAME (subspCh
), name
) == 0)
6566 subspace_dict_chainS
*
6567 pa_subsegment_to_subspace (seg
, subseg
)
6571 space_dict_chainS
*spaceCh
;
6572 subspace_dict_chainS
*subspCh
;
6574 for (spaceCh
= space_dict_root
; spaceCh
; spaceCh
= spaceCh
->sd_next
)
6576 if (spaceCh
->sd_seg
== seg
)
6578 for (subspCh
= spaceCh
->sd_subspaces
; subspCh
; subspCh
= subspCh
->ssd_next
)
6580 if (subspCh
->ssd_subseg
== (int) subseg
)
6592 pa_find_space_by_number (number
)
6595 space_dict_chainS
*spaceCh
;
6597 for (spaceCh
= space_dict_root
; spaceCh
; spaceCh
= spaceCh
->sd_next
)
6599 if (SPACE_SPNUM (spaceCh
) == number
)
6609 pa_subspace_start (space
, quadrant
)
6610 space_dict_chainS
*space
;
6613 if ((strcasecmp (SPACE_NAME (space
), "$PRIVATE$") == 0) &&
6618 else if (space
->sd_seg
== data_section
&& quadrant
== 1)
6619 { /* in case name is */
6620 /* already converted */
6621 /* to a space dict- */
6630 pa_next_subseg (space
)
6631 space_dict_chainS
*space
;
6634 space
->sd_last_subseg
++;
6635 return space
->sd_last_subseg
;
6639 is_last_defined_subspace (ssd
)
6640 subspace_dict_chainS
*ssd
;
6643 for (; ssd
; ssd
= ssd
->ssd_next
)
6645 if (ssd
->ssd_defined
)
6653 pa_get_start_symbol (seg
, subseg
)
6657 symbolS
*start_symbol
;
6658 subspace_dict_chainS
*ssd
;
6660 start_symbol
= NULL
;
6662 /* each time a new space is created, build a symbol called LS$START_seg_subseg$ */
6663 /* where <space-name> is the name of the space */
6664 /* the start symbol will be SS_LOCAL and ST_CODE */
6666 if (seg
== bfd_make_section_old_way (stdoutput
, ".text") ||
6667 seg
== bfd_make_section_old_way (stdoutput
, ".data") ||
6668 seg
== bfd_make_section_old_way (stdoutput
, GDB_DEBUG_SPACE_NAME
))
6670 ssd
= pa_subsegment_to_subspace (seg
, subseg
);
6673 start_symbol
= ssd
->ssd_start_sym
;
6676 as_fatal ("Internal error: missing subspace for (seg,subseg)=('%s',%d)",
6680 as_fatal ("Internal error: attempt to find start symbol for unloadable segment: '%s'",
6683 return start_symbol
;
6687 Function to define a symbol whose address is the beginning of a subspace.
6688 This function assumes the symbol is to be defined for the current subspace.
6692 pa_set_start_symbol (seg
, subseg
)
6696 symbolS
*start_symbol
;
6697 subspace_dict_chainS
*ssd
;
6700 symbol_name
= (char *) xmalloc (strlen ("LS$START__000000$") + strlen (seg
->name
) + 1);
6702 sprintf (symbol_name
, "LS$START_%s_%03d$", seg
->name
, subseg
);
6705 = symbol_new (symbol_name
, seg
, 0, frag_now
); /* XXX: not sure if value s.b. 0 or frag s.b. NULL */
6707 start_symbol
->bsym
->flags
= BSF_LOCAL
; /* XXX: isn't there a macro defined for this? */
6709 /* each time a new space is created, build a symbol called LS$START_seg_subseg$ */
6710 /* where <space-name> is the name of the space */
6711 /* the start symbol will be SS_LOCAL and ST_CODE */
6712 /* This function assumes that (seg,subseg) is a new subsegment(subspace) */
6714 if (seg
== bfd_make_section_old_way (stdoutput
, ".text") ||
6715 seg
== bfd_make_section_old_way (stdoutput
, ".data") ||
6716 seg
== bfd_make_section_old_way (stdoutput
, GDB_DEBUG_SPACE_NAME
))
6718 ssd
= pa_subsegment_to_subspace (seg
, subseg
);
6721 ssd
->ssd_start_sym
= start_symbol
;
6724 as_fatal ("Internal error: missing subspace for (seg,subseg)=('%s',%d)",
6728 as_fatal ("Internal error: attempt to define start symbol for unloadable segment: '%s'",
6731 return start_symbol
;
6738 unsigned int c
= *s
& CHAR_MASK
;
6751 pa_stringer (append_zero
) /* Worker to do .ascii etc statements. */
6752 /* Checks end-of-line. */
6753 register int append_zero
; /* 0: don't append '\0', else 1 */
6760 /* Preprocess the string to handle PA-specific escape sequences. */
6761 /* For example, \xDD where DD is a hexidecimal number should be */
6762 /* changed to \OOO where OOO is an octal number. */
6764 s
= input_line_pointer
+ 1; /* skip the opening quote */
6766 while (is_a_char (c
= pa_stringer_aux (s
++)))
6775 unsigned int number
;
6780 s
++; /* get past the 'x' */
6781 for (num_digit
= 0, number
= 0, dg
= *s
;
6783 && (isdigit (dg
) || (dg
>= 'a' && dg
<= 'f')
6784 || (dg
>= 'A' && dg
<= 'F'));
6788 number
= number
* 16 + dg
- '0';
6789 else if (dg
>= 'a' && dg
<= 'f')
6790 number
= number
* 16 + dg
- 'a' + 10;
6792 number
= number
* 16 + dg
- 'A' + 10;
6802 sprintf (num_buf
, "%02o", number
);
6805 sprintf (num_buf
, "%03o", number
);
6808 for (i
= 0; i
<= num_digit
; i
++)
6809 s_start
[i
] = num_buf
[i
];
6813 /* This might be a "\"", skip over the escaped char. */
6820 stringer (append_zero
);
6821 pa_undefine_label ();
6830 pa_undefine_label ();
6835 register unsigned int nbytes
; /* 1=.byte, 2=.word, 4=.long */
6838 pa_undefine_label ();
6845 pa_undefine_label ();
6855 pa_undefine_label ();
6859 pa_float_cons (float_type
)
6860 register int float_type
; /* 'f':.ffloat ... 'F':.float ... */
6862 float_cons (float_type
);
6863 pa_undefine_label ();
6870 pa_undefine_label ();
6874 pa_lcomm (needs_align
)
6875 /* 1 if this was a ".bss" directive, which may require a 3rd argument
6876 (alignment); 0 if it was an ".lcomm" (2 args only) */
6879 s_lcomm (needs_align
);
6880 pa_undefine_label ();
6887 pa_undefine_label ();
6894 pa_undefine_label ();
6897 static symext_chainS
*symext_rootP
= NULL
;
6898 static symext_chainS
*symext_lastP
= NULL
;
6901 hppa_tc_symbol (abfd
, symbolP
, sym_idx
)
6903 elf_symbol_type
* symbolP
;
6906 symext_chainS
*symextP
;
6907 unsigned int arg_reloc
;
6909 if (!(symbolP
->symbol
.flags
& BSF_FUNCTION
))
6912 arg_reloc
= symbolP
->tc_data
.hppa_arg_reloc
;
6914 symextP
= (symext_chainS
*) bfd_alloc (abfd
, sizeof (symext_chainS
) * 2);
6916 symextP
[0].entry
= ELF32_HPPA_SX_WORD (HPPA_SXT_SYMNDX
, sym_idx
);
6917 symextP
[0].next
= &symextP
[1];
6919 symextP
[1].entry
= ELF32_HPPA_SX_WORD (HPPA_SXT_ARG_RELOC
, arg_reloc
);
6920 symextP
[1].next
= NULL
;
6922 if (symext_rootP
== NULL
)
6924 symext_rootP
= &symextP
[0];
6925 symext_lastP
= &symextP
[1];
6929 symext_lastP
->next
= &symextP
[0];
6930 symext_lastP
= &symextP
[1];
6935 hppa_tc_make_sections (abfd
)
6938 symext_chainS
*symextP
;
6939 symext_entryS
*outbound_symexts
;
6942 extern void hppa_elf_stub_finish (); /* forward declaration */
6943 asection
*symextn_sec
;
6944 segT save_seg
= now_seg
;
6945 subsegT save_subseg
= now_subseg
;
6947 hppa_tc_make_symextn_section();
6949 bfd_set_section_contents(stdoutput
, stdoutput
->sections
, "", 0, 0); /* force some calculations */
6951 hppa_elf_stub_finish (abfd
);
6953 if (symext_rootP
== NULL
)
6956 for (n
= 0, symextP
= symext_rootP
; symextP
; symextP
= symextP
->next
, ++n
)
6959 size
= sizeof (symext_entryS
) * n
;
6961 symextn_sec
= subseg_new(SYMEXTN_SECTION_NAME
, 0);
6963 frag_wane (frag_now
);
6966 for (symextP
= symext_rootP
; symextP
; symextP
= symextP
->next
)
6969 extern int *elf_get_symtab_map();
6970 Elf_Sym_Extra
*symextra
= elf_sym_extra (abfd
);
6973 /* First, patch the symbol extension record to reflect the true */
6974 /* symbol table index */
6976 if (ELF32_HPPA_SX_TYPE(symextP
->entry
) == HPPA_SXT_SYMNDX
)
6978 idx
= ELF32_HPPA_SX_VAL(symextP
->entry
) - 1;
6979 symextP
->entry
= ELF32_HPPA_SX_WORD (HPPA_SXT_SYMNDX
,
6980 symextra
[idx
].elf_sym_num
);
6983 ptr
= frag_more(sizeof(symextP
->entry
));
6984 md_number_to_chars(ptr
,symextP
->entry
,sizeof(symextP
->entry
));
6987 frag_now
->fr_fix
= obstack_next_free (&frags
) - frag_now
->fr_literal
;
6988 frag_wane (frag_now
);
6990 /* now, switch back to the original segment */
6992 subseg_set(save_seg
, save_subseg
);
6998 hppa_tc_make_symextn_section()
7000 extern symext_chainS
*elf32_hppa_get_symextn_chain();
7004 symext_chainS
*symextP
;
7008 segT save_seg
= now_seg
;
7009 subsegT save_subseg
= now_subseg
;
7011 for (n
= 0, symextP
= symext_rootP
; symextP
; symextP
= symextP
->next
, ++n
)
7014 size
= sizeof (symext_entryS
) * n
;
7016 symextn_sec
= subseg_new(SYMEXTN_SECTION_NAME
, 0);
7018 bfd_set_section_flags(stdoutput
, symextn_sec
, SEC_LOAD
| SEC_HAS_CONTENTS
| SEC_DATA
);
7019 bfd_set_section_size (stdoutput
, symextn_sec
, size
);
7021 /* now, switch back to the original segment */
7022 subseg_set(save_seg
, save_subseg
);