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_big_cons
, 16},
237 {"OCTA", pa_big_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_big_cons
, 8},
249 {"QUAD", pa_big_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
]);
735 if (retval
!= NULL
&& *retval
!= '\0')
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 ();
4321 subseg_new (SEG_DATA
, (subsegT
) temp
);
4323 subseg_new (".data", (subsegT
) temp
);
4325 demand_empty_rest_of_line ();
4332 subseg_new (SEG_DATA
, 1);
4334 subseg_new (".data", 1);
4336 demand_empty_rest_of_line ();
4343 extern char is_end_of_line
[];
4345 while (!is_end_of_line
[*input_line_pointer
])
4347 ++input_line_pointer
;
4349 ++input_line_pointer
;
4358 register long int temp_fill
;
4359 register long int temp_size
;
4362 temp_size
= get_absolute_expression ();
4365 { /* fill with zeroes even if not requested to do so. */
4366 temp_fill
= 0; /* HP assembler does this too. */
4375 as_bad ("size < 0, .block ignored");
4378 p
= frag_var (rs_fill
,
4380 (int) temp_size
, (relax_substateT
) 0, (symbolS
*) 0, 1, (char *) 0);
4381 bzero (p
, (int) temp_size
);
4383 /* convert 2 bytes at a time */
4385 for (i
= 0; i
< temp_size
; i
+= 2)
4387 md_number_to_chars (p
+ i
,
4389 (int) ((temp_size
- i
) > 2 ? 2 : (temp_size
- i
)));
4392 pa_undefine_label ();
4393 demand_empty_rest_of_line ();
4401 pa_call_args (&last_call_desc
);
4402 demand_empty_rest_of_line ();
4407 pa_call_args (call_desc
)
4408 register call_descS
*call_desc
;
4410 register char *name
;
4414 register unsigned int arg_reloc
;
4416 while (!is_end_of_statement ())
4418 name
= input_line_pointer
;
4419 c
= get_symbol_end ();
4420 if ((strncasecmp (name
, "argw", 4) == 0))
4422 temp
= atoi (name
+ 4);
4423 p
= input_line_pointer
;
4425 input_line_pointer
++;
4426 name
= input_line_pointer
;
4427 c
= get_symbol_end ();
4428 arg_reloc
= pa_build_arg_reloc (name
);
4429 call_desc
->arg_reloc
|= pa_align_arg_reloc (temp
, arg_reloc
);
4431 else if ((strncasecmp (name
, "rtnval", 6) == 0))
4433 p
= input_line_pointer
;
4435 input_line_pointer
++;
4436 name
= input_line_pointer
;
4437 c
= get_symbol_end ();
4438 arg_reloc
= pa_build_arg_reloc (name
);
4439 call_desc
->arg_reloc
|= (arg_reloc
& 0x3);
4443 as_bad ("Unrecognized .CALL argument: %s", name
);
4445 p
= input_line_pointer
;
4447 if (!is_end_of_statement ())
4448 input_line_pointer
++;
4453 is_same_frag (frag1P
, frag2P
)
4460 else if (frag2P
== NULL
)
4462 else if (frag1P
== frag2P
)
4464 else if (frag2P
->fr_type
== rs_fill
&& frag2P
->fr_fix
== 0)
4465 return (is_same_frag (frag1P
, frag2P
->fr_next
));
4472 pa_build_unwind_subspace (call_info
)
4473 call_infoS
*call_info
;
4478 subsegT subseg
, save_subseg
;
4483 subseg
= SUBSEG_UNWIND
;
4484 seg
= bfd_get_section_by_name (stdoutput
, UNWIND_SECTION_NAME
);
4485 if (seg
== ASEC_NULL
)
4487 seg
= bfd_make_section_old_way (stdoutput
, UNWIND_SECTION_NAME
);
4489 bfd_set_section_flags (stdoutput
, seg
,
4490 (SEC_READONLY
| SEC_HAS_CONTENTS
4491 | SEC_LOAD
| SEC_RELOC
));
4493 /* callinfo.frame is in bytes and unwind_desc is in 8 byte units */
4494 call_info
->ci_unwind
.descriptor
.frame_size
= call_info
->frame
/ 8;
4496 /* Now, dump the unwind descriptor to the $UNWIND$ subspace. This
4497 creates a couple of relocations */
4500 save_subseg
= now_subseg
;
4501 subseg_new ((char *) seg
->name
, subseg
);
4502 unwindP
= (char *) &call_info
->ci_unwind
;
4505 call_info
->start_offset_frag
= frag_now
;
4506 call_info
->start_frag_where
= p
- frag_now
->fr_literal
;
4508 /* relocation info. for start offset of the function */
4510 fix_new_hppa (frag_now
, p
- frag_now
->fr_literal
, 4,
4511 call_info
->start_symbol
, (offsetT
) 0,
4512 (expressionS
*) NULL
, 0, R_HPPA_UNWIND
, e_fsel
, 32, 0,
4515 /** we need to search for the first relocation involving the start_symbol of **/
4516 /** this call_info descriptor **/
4521 call_info
->start_fix
= seg_info (now_seg
)->fix_root
; /* the default */
4522 for (fixP
= call_info
->start_fix
; fixP
; fixP
= fixP
->fx_next
)
4524 if (fixP
->fx_addsy
== call_info
->start_symbol
4525 || fixP
->fx_subsy
== call_info
->start_symbol
)
4527 call_info
->start_fix
= fixP
;
4534 call_info
->end_offset_frag
= frag_now
;
4535 call_info
->end_frag_where
= p
- frag_now
->fr_literal
;
4537 /* relocation info. for end offset of the function */
4539 fix_new_hppa (frag_now
, p
- frag_now
->fr_literal
, 4,
4540 call_info
->end_symbol
, (offsetT
) 0,
4541 (expressionS
*) NULL
, 0, R_HPPA_UNWIND
, e_fsel
, 32, 0,
4544 /** we need to search for the first relocation involving the start_symbol of **/
4545 /** this call_info descriptor **/
4550 call_info
->end_fix
= seg_info (now_seg
)->fix_root
; /* the default */
4551 for (fixP
= call_info
->end_fix
; fixP
; fixP
= fixP
->fx_next
)
4553 if (fixP
->fx_addsy
== call_info
->end_symbol
4554 || fixP
->fx_subsy
== call_info
->end_symbol
)
4556 call_info
->end_fix
= fixP
;
4562 for (i
= 8; i
< sizeof (unwind_tableS
); i
++)
4566 FRAG_APPEND_1_CHAR (c
);
4570 subseg_new ((char *) save_seg
->name
, save_subseg
);
4576 pa_build_unwind_subspace (call_info
)
4577 call_infoS
*call_info
;
4579 space_dict_chainS
*spaceP
;
4580 subspace_dict_chainS
*subspaceP
;
4582 char defined
, loadable
, code_only
, common
, dup_common
, is_zero
, sort
;
4583 int access
, space_index
, alignment
, quadrant
;
4585 subsegT subseg
, save_subseg
;
4601 subseg
= SUBSEG_UNWIND
;
4604 spaceP
= pa_segment_to_space (seg
);
4606 if ((subspaceP
= is_defined_subspace ("$UNWIND$", SUBSEG_UNWIND
)))
4608 update_subspace ("$UNWIND$", defined
, loadable
, code_only
, common
, dup_common
,
4609 sort
, is_zero
, access
, space_index
, alignment
, quadrant
,
4614 subspaceP
= create_new_subspace (spaceP
, "$UNWIND$", defined
, loadable
, code_only
,
4615 common
, dup_common
, is_zero
, sort
, access
,
4616 space_index
, alignment
, quadrant
, seg
);
4620 /* callinfo.frame is in bytes and unwind_desc is in 8 byte units */
4621 call_info
->ci_unwind
.descriptor
.frame_size
= call_info
->frame
/ 8;
4623 /* Now, dump the unwind descriptor to the $UNWIND$ subspace. This
4624 creates a couple of relocations */
4627 save_subseg
= now_subseg
;
4628 subseg_new (seg
, subseg
);
4629 unwindP
= (char *) &call_info
->ci_unwind
;
4632 call_info
->start_offset_frag
= frag_now
;
4633 call_info
->start_frag_where
= p
- frag_now
->fr_literal
;
4635 /* relocation info. for start offset of the function */
4637 fix_new (frag_now
, p
- frag_now
->fr_literal
, 4,
4638 call_info
->start_symbol
, (offsetT
) 0,
4639 (expressionS
*) NULL
, 0, R_DATA_ONE_SYMBOL
, e_fsel
, 0, 0,
4642 /** we need to search for the first relocation involving the start_symbol of **/
4643 /** this call_info descriptor **/
4648 call_info
->start_fix
= seg_info (now_seg
)->fix_root
; /* the default */
4649 for (fixP
= call_info
->start_fix
; fixP
; fixP
= fixP
->fx_next
)
4652 if ( ( fixP->fx_addsy == call_info->start_symbol ||
4653 fixP->fx_subsy == call_info->start_symbol )
4655 ( fixP->fx_frag == call_info->start_symbol->sy_frag ) ) {
4657 if ((fixP
->fx_addsy
== call_info
->start_symbol
||
4658 fixP
->fx_subsy
== call_info
->start_symbol
)
4660 (is_same_frag (fixP
->fx_frag
, call_info
->start_symbol
->sy_frag
)))
4662 call_info
->start_fix
= fixP
;
4669 call_info
->end_offset_frag
= frag_now
;
4670 call_info
->end_frag_where
= p
- frag_now
->fr_literal
;
4672 /* relocation info. for end offset of the function */
4674 fix_new (frag_now
, p
- frag_now
->fr_literal
, 4,
4675 call_info
->start_symbol
, (offsetT
) 0,
4676 (expressionS
*) NULL
, 0, R_DATA_ONE_SYMBOL
, e_fsel
, 0, 0,
4679 /** we need to search for the first relocation involving the start_symbol of **/
4680 /** this call_info descriptor **/
4685 call_info
->end_fix
= seg_info (now_seg
)->fix_root
; /* the default */
4686 for (fixP
= call_info
->end_fix
; fixP
; fixP
= fixP
->fx_next
)
4689 if ( ( fixP->fx_addsy == call_info->start_symbol ||
4690 fixP->fx_subsy == call_info->start_symbol )
4692 ( fixP->fx_frag == call_info->start_symbol->sy_frag ) ) {
4694 if ((fixP
->fx_addsy
== call_info
->start_symbol
||
4695 fixP
->fx_subsy
== call_info
->start_symbol
)
4697 (is_same_frag (fixP
->fx_frag
, call_info
->start_symbol
->sy_frag
)))
4699 call_info
->end_fix
= fixP
;
4705 for (i
= 8; i
< sizeof (unwind_tableS
); i
++)
4709 FRAG_APPEND_1_CHAR (c
);
4713 subseg_new (save_seg
, save_subseg
);
4723 register char *name
;
4728 if (!within_procedure
)
4729 as_bad (".callinfo is not within a procedure definition");
4731 callinfo_found
= TRUE
;
4733 while (!is_end_of_statement ())
4735 name
= input_line_pointer
;
4736 c
= get_symbol_end ();
4737 if ((strncasecmp (name
, "frame", 5) == 0))
4739 p
= input_line_pointer
;
4741 input_line_pointer
++;
4742 temp
= get_absolute_expression ();
4743 if ((temp
& 0x3) != 0)
4745 as_bad ("FRAME parameter must be a multiple of 8: %d\n", temp
);
4748 last_call_info
->frame
= temp
;
4750 else if ((strncasecmp (name
, "entry_gr", 8) == 0))
4752 p
= input_line_pointer
;
4754 input_line_pointer
++;
4755 temp
= get_absolute_expression ();
4756 last_call_info
->ci_unwind
.descriptor
.entry_gr
= temp
;
4758 else if ((strncasecmp (name
, "entry_fr", 8) == 0))
4760 p
= input_line_pointer
;
4762 input_line_pointer
++;
4763 temp
= get_absolute_expression ();
4764 last_call_info
->ci_unwind
.descriptor
.entry_fr
= temp
;
4766 else if ((strncasecmp (name
, "entry_sr", 8) == 0))
4768 p
= input_line_pointer
;
4770 input_line_pointer
++;
4771 temp
= get_absolute_expression ();
4772 last_call_info
->entry_sr
= temp
;
4774 else if ((strncasecmp (name
, "calls", 5) == 0) ||
4775 (strncasecmp (name
, "caller", 6) == 0))
4777 p
= input_line_pointer
;
4779 last_call_info
->makes_calls
= 1;
4781 else if ((strncasecmp (name
, "no_calls", 8) == 0))
4783 p
= input_line_pointer
;
4785 last_call_info
->makes_calls
= 0;
4787 else if ((strncasecmp (name
, "save_rp", 7) == 0))
4789 p
= input_line_pointer
;
4791 last_call_info
->ci_unwind
.descriptor
.save_rp
= 1;
4793 else if ((strncasecmp (name
, "save_sp", 7) == 0))
4795 p
= input_line_pointer
;
4797 last_call_info
->ci_unwind
.descriptor
.save_sp
= 1;
4799 else if ((strncasecmp (name
, "no_unwind", 9) == 0))
4801 p
= input_line_pointer
;
4803 last_call_info
->ci_unwind
.descriptor
.cannot_unwind
= 1;
4805 else if ((strncasecmp (name
, "hpux_int", 7) == 0))
4807 p
= input_line_pointer
;
4809 last_call_info
->hpux_int
= 1;
4813 as_bad ("Unrecognized .CALLINFO argument: %s", name
);
4815 if (!is_end_of_statement ())
4816 input_line_pointer
++;
4819 demand_empty_rest_of_line ();
4826 space_dict_chainS
*sdchain
;
4828 if ((sdchain
= is_defined_space ("$TEXT$")) == NULL
)
4830 sdchain
= create_new_space (pa_def_spaces
[0].name
, pa_def_spaces
[0].spnum
,
4831 pa_def_spaces
[0].loadable
, pa_def_spaces
[0].defined
,
4832 pa_def_spaces
[0].private, pa_def_spaces
[0].sort
,
4833 1, pa_def_spaces
[0].segment
);
4836 SPACE_DEFINED (sdchain
) = 1;
4839 subseg_new (SEG_TEXT
, SUBSEG_CODE
);
4842 subseg_new (".text", SUBSEG_CODE
);
4845 demand_empty_rest_of_line ();
4850 * This is different than the standard GAS s_comm(). On HP9000/800 machines,
4851 * the .comm pseudo-op has the following symtax:
4853 * <label> .comm <length>
4855 * where <label> is optional and is a symbol whose address will be the start of
4856 * a block of memory <length> bytes long. <length> must be an absolute expressio
4858 * <length> bytes will be allocated in the current space and subspace.
4866 register symbolS
*symbolP
;
4867 register label_symbolS
*label_symbolP
= pa_get_label ();
4870 symbolP
= label_symbolP
->lss_label
;
4875 if ((size
= get_absolute_expression ()) < 0)
4877 as_warn (".COMMon length (%d.) <0! Ignored.", size
);
4878 ignore_rest_of_line ();
4885 if (symbolP
->pa_sy_type
== ST_STORAGE
&&
4886 symbolP
->pa_sy_scope
== SS_UNSAT
)
4888 if (symbolP
->pa_sy_value
!= size
)
4890 as_warn ("Length of .comm \"%s\" is already %d. Not changed to %d.",
4891 symbolP
->pa_sy_name
, symbolP
->pa_sy_value
, size
);
4897 symbolP
->pa_sy_value
= size
;
4898 symbolP
->pa_sy_scope
= SS_UNSAT
;
4899 symbolP
->pa_sy_type
= ST_STORAGE
;
4900 symbolP
->sy_ref
= sym_def
;
4904 if (S_IS_DEFINED (symbolP
) && S_GET_SEGMENT (symbolP
) == bss_section
)
4906 as_bad ("Ignoring attempt to re-define symbol");
4907 ignore_rest_of_line ();
4910 if (S_GET_VALUE (symbolP
))
4912 if (S_GET_VALUE (symbolP
) != size
)
4914 as_warn ("Length of .comm \"%s\" is already %d. Not changed to %d.",
4915 S_GET_NAME (symbolP
), S_GET_VALUE (symbolP
), size
);
4921 S_SET_VALUE (symbolP
, size
);
4922 S_SET_SEGMENT (symbolP
, bss_section
);
4923 S_SET_EXTERNAL (symbolP
);
4929 demand_empty_rest_of_line ();
4935 register char *name
;
4939 if (*input_line_pointer
== '\"')
4941 ++input_line_pointer
; /* -> 1st char of string. */
4942 name
= input_line_pointer
;
4943 while ((c
= next_char_of_string ()) >= 0)
4945 c
= *input_line_pointer
;
4946 *input_line_pointer
= '\0';
4947 *(input_line_pointer
- 1) = '\0';
4950 #define PREFIX "Copyright "
4951 #define MIDFIX ". All rights reserved. No part of this program may be photocopied, reproduced, or transmitted without prior written consent of "
4954 struct aux_hdr_list
*aux_hdr_entry
;
4956 char *company_name
= name
;
4959 date_part
= (char *) strchr (name
, ',');
4974 len
+= strlen (date_part
) + strlen (",");
4977 aux_hdr_entry
= (struct aux_hdr_list
*) malloc (sizeof (struct aux_hdr_list
));
4980 aux_hdr_entry
->ahl_next
= aux_hdr_root
;
4981 aux_hdr_root
= aux_hdr_entry
;
4985 aux_hdr_entry
->ahl_next
= NULL
;
4986 aux_hdr_root
= aux_hdr_entry
;
4988 aux_hdr_entry
->type
= COPYRIGHT_AUX_ID
;
4989 aux_hdr_entry
->contents
.cpy
.header_id
.append
= 1;
4990 aux_hdr_entry
->contents
.cpy
.header_id
.type
= COPYRIGHT_AUX_ID
;
4991 aux_hdr_entry
->contents
.cpy
.header_id
.length
= len
+ sizeof (unsigned int);
4992 while (aux_hdr_entry
->contents
.usr_str
.header_id
.length
% 4)
4993 aux_hdr_entry
->contents
.usr_str
.header_id
.length
+= 1;
4995 aux_hdr_entry
->contents
.cpy
.string_length
= len
;
4996 aux_hdr_entry
->contents
.cpy
.copyright
= (char *) (malloc (len
+ 1));
4997 strcpy (aux_hdr_entry
->contents
.cpy
.copyright
, PREFIX
);
4998 strcat (aux_hdr_entry
->contents
.cpy
.copyright
, name
);
5001 strcat (aux_hdr_entry
->contents
.cpy
.copyright
, ",");
5002 strcat (aux_hdr_entry
->contents
.cpy
.copyright
, date_part
);
5004 strcat (aux_hdr_entry
->contents
.cpy
.copyright
, MIDFIX
);
5005 strcat (aux_hdr_entry
->contents
.cpy
.copyright
, name
);
5006 strcat (aux_hdr_entry
->contents
.cpy
.copyright
, SUFFIX
);
5007 aux_hdr_entry
->contents
.cpy
.copyright
[len
] = NULL
;
5011 #endif /* OBJ_SOM */
5013 *input_line_pointer
= c
;
5017 as_bad ("Expected \"-ed string");
5019 pa_undefine_label ();
5020 demand_empty_rest_of_line ();
5027 demand_empty_rest_of_line ();
5035 as_bad (".ENTER encountered. gas doesn't generate entry code sequences.");
5045 if (!within_procedure
)
5046 as_bad ("Misplaced .entry. Ignored.");
5049 if (!callinfo_found
)
5050 as_bad ("Missing .callinfo.");
5052 last_call_info
->start_frag
= frag_now
;
5054 demand_empty_rest_of_line ();
5055 within_entry_exit
= TRUE
;
5056 where
= frag_more (0);
5058 fix_new_hppa (frag_now
, where
- frag_now
->fr_literal
, 0,
5059 last_call_info
->start_symbol
, (offsetT
) 0,
5060 (expressionS
*) NULL
, 0, R_ENTRY
, e_fsel
, 0, 0,
5061 (char *) &last_call_info
->ci_unwind
.descriptor
);
5064 /* XXX: no ENTRY relocation for PA ELF. What do we do instead? */
5066 fix_new_hppa (frag_now
, where
- frag_now
->fr_literal
, 0,
5067 last_call_info
->start_symbol
, (offsetT
) 0,
5068 (expressionS
*) NULL
, 0,
5069 R_HPPA_ENTRY
, 0, 0, 0,
5070 (char *) &last_call_info
->ci_unwind
.descriptor
);
5080 register label_symbolS
*label_symbolP
= pa_get_label ();
5081 register symbolS
*symbolP
;
5085 symbolP
= label_symbolP
->lss_label
;
5087 symbolP
->pa_sy_value
= get_absolute_expression ();
5088 symbolP
->pa_sy_type
= ST_ABSOLUTE
;
5089 symbolP
->sy_ref
= sym_unref
;
5090 symbolP
->sy_equ
= 1;
5092 S_SET_VALUE (symbolP
, get_absolute_expression ());
5093 S_SET_SEGMENT (symbolP
, &bfd_abs_section
);
5099 as_bad (".REG must use a label");
5101 as_bad (".EQU must use a label");
5104 pa_undefine_label ();
5105 demand_empty_rest_of_line ();
5114 where
= frag_more (0);
5116 fix_new_hppa (frag_now
, where
- frag_now
->fr_literal
, 0,
5117 last_call_info
->start_symbol
, (offsetT
) 0,
5118 (expressionS
*) NULL
, 0, R_EXIT
, e_fsel
, 0, 0,
5122 /* XXX: no EXIT relocation for PA ELF. All we do is create a */
5123 /* temporary symbol marking the end of the function. */
5125 char *name
= (char *) xmalloc (strlen ("L\001end_") +
5126 strlen (S_GET_NAME (last_call_info
->start_symbol
)) + 1);
5132 strcpy (name
, "L\001end_");
5133 strcat (name
, S_GET_NAME (last_call_info
->start_symbol
));
5135 symbolP
= symbol_find (name
);
5137 as_warn ("Symbol '%s' already defined.", name
);
5140 /* symbol value should be the offset of the */
5141 /* last instruction of the function */
5142 symbolP
= symbol_new (name
,
5144 (valueT
) (obstack_next_free (&frags
) - frag_now
->fr_literal
- 4),
5149 symbolP
->bsym
->flags
= BSF_LOCAL
;
5150 symbol_table_insert (symbolP
);
5153 last_call_info
->end_symbol
= symbolP
;
5155 as_bad ("Symbol '%s' could not be created.", name
);
5159 as_bad ("No memory for symbol name.");
5162 fix_new_hppa (frag_now
, where
- frag_now
->fr_literal
, 0,
5163 last_call_info
->start_symbol
, (offsetT
) 0,
5164 (expressionS
*) NULL
, 0, R_HPPA_EXIT
, 0, 0, 0,
5167 last_call_info
->end_frag
= frag_now
;
5169 pa_build_unwind_subspace (last_call_info
);
5171 exit_processing_complete
= TRUE
;
5178 if (!within_procedure
)
5179 as_bad (".EXIT must appear within a procedure");
5182 if (!callinfo_found
)
5183 as_bad ("Missing .callinfo");
5186 if (!within_entry_exit
)
5187 as_bad ("No .ENTRY for this .EXIT");
5190 within_entry_exit
= FALSE
;
5195 demand_empty_rest_of_line ();
5201 pa_build_symextn_section()
5204 asection
*save_seg
= now_seg
;
5205 subsegT subseg
= (subsegT
)0;
5206 subsegT save_subseg
= now_subseg
;
5208 seg
= subseg_new(".hppa_symextn", subseg
);
5209 bfd_set_section_flags (stdoutput
,
5211 SEC_HAS_CONTENTS
| SEC_READONLY
| SEC_ALLOC
| SEC_LOAD
);
5213 subseg_new(save_seg
->name
, save_subseg
);
5221 register char *name
;
5224 register symbolS
*symbolP
;
5226 name
= input_line_pointer
;
5227 c
= get_symbol_end ();
5228 /* just after name is now '\0' */
5230 if ((symbolP
= symbol_find_or_make (name
)) == NULL
)
5232 as_bad ("Cannot define export symbol: %s\n", name
);
5233 p
= input_line_pointer
;
5235 input_line_pointer
++;
5240 symbolP
->pa_sy_dict
.symbol_scope
= SS_UNIVERSAL
;
5241 /* determination of the symbol_type field will have to wait until
5242 we know the subspace index (within the object file) of the subspace
5243 containing this symbol */
5245 /* S_SET_SEGMENT(symbolP,&bfd_und_section); */
5246 S_SET_EXTERNAL (symbolP
);
5247 /* symbolP->sy_frag = frag_now; */
5250 p
= input_line_pointer
;
5252 if (!is_end_of_statement ())
5254 input_line_pointer
++;
5255 pa_export_args (symbolP
);
5257 pa_build_symextn_section();
5262 demand_empty_rest_of_line ();
5267 pa_export_args (symbolP
)
5268 register symbolS
*symbolP
;
5270 register char *name
;
5274 register unsigned int arg_reloc
;
5276 elf32_symbol_type
*esymbolP
= (elf32_symbol_type
*) (symbolP
->bsym
);
5279 if (strncasecmp (input_line_pointer
, "absolute", 8) == 0)
5281 input_line_pointer
+= 8;
5283 symbolP
->pa_sy_dict
.symbol_type
= ST_ABSOLUTE
;
5285 S_SET_SEGMENT (symbolP
, &bfd_abs_section
);
5288 else if (strncasecmp (input_line_pointer
, "code", 4) == 0)
5290 input_line_pointer
+= 4;
5292 symbolP
->pa_sy_dict
.symbol_type
= ST_CODE
;
5294 /* S_SET_SEGMENT(symbolP,text_section); */
5297 else if (strncasecmp (input_line_pointer
, "data", 4) == 0)
5299 input_line_pointer
+= 4;
5301 symbolP
->pa_sy_dict
.symbol_type
= ST_DATA
;
5303 /* S_SET_SEGMENT(symbolP,data_section); */
5306 else if ((strncasecmp (input_line_pointer
, "entry", 5) == 0))
5308 input_line_pointer
+= 5;
5310 symbolP
->pa_sy_dict
.symbol_type
= ST_ENTRY
;
5312 symbolP
->bsym
->flags
|= BSF_FUNCTION
;
5315 else if (strncasecmp (input_line_pointer
, "millicode", 9) == 0)
5317 input_line_pointer
+= 9;
5319 symbolP
->pa_sy_dict
.symbol_type
= ST_MILLICODE
;
5322 else if (strncasecmp (input_line_pointer
, "plabel", 6) == 0)
5324 input_line_pointer
+= 6;
5326 symbolP
->pa_sy_dict
.symbol_type
= ST_PLABEL
;
5329 else if (strncasecmp (input_line_pointer
, "pri_prog", 8) == 0)
5331 input_line_pointer
+= 8;
5333 symbolP
->pa_sy_dict
.symbol_type
= ST_PRI_PROG
;
5336 else if (strncasecmp (input_line_pointer
, "sec_prog", 8) == 0)
5338 input_line_pointer
+= 8;
5340 symbolP
->pa_sy_dict
.symbol_type
= ST_SEC_PROG
;
5344 while (!is_end_of_statement ())
5346 if (*input_line_pointer
== ',')
5347 input_line_pointer
++;
5348 name
= input_line_pointer
;
5349 c
= get_symbol_end ();
5350 if ((strncasecmp (name
, "argw", 4) == 0))
5352 p
= input_line_pointer
;
5354 input_line_pointer
++;
5355 temp
= atoi (name
+ 4);
5356 name
= input_line_pointer
;
5357 c
= get_symbol_end ();
5358 arg_reloc
= pa_align_arg_reloc (temp
, pa_build_arg_reloc (name
));
5360 symbolP
->pa_sy_dict
.arg_reloc
|= arg_reloc
;
5362 esymbolP
->tc_data
.hppa_arg_reloc
|= arg_reloc
;
5364 *input_line_pointer
= c
;
5366 else if ((strncasecmp (name
, "rtnval", 6)) == 0)
5368 p
= input_line_pointer
;
5370 input_line_pointer
++;
5371 name
= input_line_pointer
;
5372 c
= get_symbol_end ();
5373 arg_reloc
= pa_build_arg_reloc (name
);
5375 symbolP
->pa_sy_dict
.arg_reloc
|= arg_reloc
;
5377 esymbolP
->tc_data
.hppa_arg_reloc
|= arg_reloc
;
5379 *input_line_pointer
= c
;
5381 else if ((strncasecmp (name
, "priv_lev", 8)) == 0)
5383 p
= input_line_pointer
;
5385 input_line_pointer
++;
5386 /*** temp = get_absolute_expression (); ***/
5387 temp
= atoi (input_line_pointer
);
5388 c
= get_symbol_end ();
5389 *input_line_pointer
= c
;
5391 symbolP
->sy_priv_lev
= temp
& 3; /* this is stored in symbol_value later */
5396 as_bad ("Undefined .EXPORT/.IMPORT argument (ignored): %s", name
);
5397 p
= input_line_pointer
;
5400 if (!is_end_of_statement ())
5401 input_line_pointer
++;
5408 register char *name
;
5411 register symbolS
*symbolP
;
5413 name
= input_line_pointer
;
5414 c
= get_symbol_end ();
5415 /* just after name is now '\0' */
5417 symbolP
= symbol_find_or_make (name
);
5418 #if defined(OBJ_ELF)
5419 /* symbolP->bsym->flags |= BSF_IMPORT; *//* XXX BSF_IMPORT is obsolete */
5421 /* Check to see if this symbol has already been exported (this means its */
5422 /* defined locally and the import statement is redundant). */
5423 /* If it has not been exported, go ahead and mark this symbol as SS_UNSAT */
5424 /* (an unsatisfied external symbol) */
5426 /* But, if the symbol has already been referenced (sy_ref == TRUE),
5429 if (!symbolP
->sy_ref
)
5431 if (symbolP
->pa_sy_dict
.symbol_scope
!= SS_UNIVERSAL
)
5433 symbolP
->pa_sy_dict
.symbol_scope
= SS_UNSAT
;
5434 symbolP
->sy_ref
= FALSE
;
5439 p
= input_line_pointer
;
5442 if (!is_end_of_statement ())
5444 input_line_pointer
++;
5446 pa_export_args (symbolP
);
5448 /* In ELF, since this is an import, leave the section undefined. */
5449 /* S_SET_SEGMENT(symbolP,&bfd_und_section); */
5455 /* no further arguments, assign a default type according
5456 to the current subspace (CODE or DATA) */
5460 symbolP
->pa_sy_dict
.symbol_type
= ST_CODE
;
5463 symbolP
->pa_sy_dict
.symbol_type
= ST_ABSOLUTE
;
5466 symbolP
->pa_sy_dict
.symbol_type
= ST_DATA
;
5469 /* In ELF, if the section is undefined, then the symbol is undefined */
5470 /* Since this is an import, leave the section undefined. */
5471 S_SET_SEGMENT (symbolP
, &bfd_und_section
);
5476 demand_empty_rest_of_line ();
5483 register char *name
;
5487 name
= input_line_pointer
;
5488 c
= get_symbol_end ();
5489 /* just after name is now '\0' */
5491 if (strlen (name
) > 0)
5494 p
= input_line_pointer
;
5499 as_warn ("Missing label name on .LABEL");
5502 if (!is_end_of_statement ())
5504 as_warn ("extra .LABEL arguments ignored.");
5505 ignore_rest_of_line ();
5507 demand_empty_rest_of_line ();
5515 as_bad (".LEAVE encountered. gas doesn't generate exit code sequences.");
5523 s_org (); /* ORG actually allows another argument
5524 (the fill value) but maybe this is OK? */
5525 pa_undefine_label ();
5538 name
= input_line_pointer
;
5539 c
= get_symbol_end ();
5540 /* just after name is now '\0' */
5542 if ((symbolP
= symbol_find_or_make (name
)) == NULL
)
5544 as_bad ("Cannot define static symbol: %s\n", name
);
5545 p
= input_line_pointer
;
5547 input_line_pointer
++;
5552 symbolP
->pa_sy_dict
.symbol_scope
= SS_LOCAL
;
5553 /* determination of the symbol_type field will have to wait until
5554 we know the subspace index (within the object file) of the subspace
5555 containing this symbol */
5557 /* S_SET_SEGMENT(symbolP,&bfd_und_section); */
5558 S_CLEAR_EXTERNAL (symbolP
);
5559 /* symbolP->sy_frag = frag_now; */
5562 p
= input_line_pointer
;
5564 if (!is_end_of_statement ())
5566 input_line_pointer
++;
5567 pa_export_args (symbolP
);
5571 demand_empty_rest_of_line ();
5578 call_infoS
*call_info
;
5580 if (within_procedure
)
5581 as_fatal ("Nested procedures");
5583 callinfo_found
= FALSE
;
5584 within_procedure
= TRUE
;
5585 exit_processing_complete
= FALSE
;
5587 /* create another call_info structure */
5589 call_info
= (call_infoS
*) xmalloc (sizeof (call_infoS
));
5592 as_fatal ("Cannot allocate unwind descriptor\n");
5594 bzero (call_info
, sizeof (call_infoS
));
5596 call_info
->ci_next
= NULL
;
5598 if (call_info_root
== NULL
)
5600 call_info_root
= call_info
;
5601 last_call_info
= call_info
;
5605 last_call_info
->ci_next
= call_info
;
5606 last_call_info
= call_info
;
5609 /* set up defaults on call_info structure */
5611 call_info
->ci_unwind
.descriptor
.cannot_unwind
= 0;
5612 call_info
->ci_unwind
.descriptor
.region_desc
= 1;
5613 call_info
->entry_sr
= ~0;
5614 call_info
->makes_calls
= 1;
5615 call_info
->hpux_int
= 0;
5617 /* If we got a .PROC pseudo-op, we know that the function is defined
5618 locally. Make sure it gets into the symbol table */
5620 label_symbolS
*label_symbolP
= pa_get_label ();
5624 if (label_symbolP
->lss_label
)
5627 label_symbolP
->lss_label
->sy_ref
|= sym_def
;
5629 last_call_info
->start_symbol
= label_symbolP
->lss_label
;
5630 label_symbolP
->lss_label
->bsym
->flags
|= BSF_FUNCTION
;
5633 as_bad ("Missing function name for .PROC (corrupted label)");
5636 as_bad ("Missing function name for .PROC");
5639 demand_empty_rest_of_line ();
5647 if (!within_procedure
)
5648 as_bad ("misplaced .procend");
5650 if (!callinfo_found
)
5651 as_bad ("Missing .callinfo for this procedure");
5653 if (within_entry_exit
)
5654 as_bad ("Missing .EXIT for a .ENTRY");
5656 if (!exit_processing_complete
)
5659 within_procedure
= FALSE
;
5660 demand_empty_rest_of_line ();
5665 pa_parse_space_stmt (space_name
, create_flag
)
5669 register char *name
;
5685 space_dict_chainS
*space
;
5687 /* load default values */
5692 if (strcasecmp (space_name
, "$TEXT$") == 0)
5711 if (!is_end_of_statement ())
5713 print_errors
= FALSE
;
5714 ptemp
= input_line_pointer
+ 1;
5715 if ((temp
= pa_parse_number (&ptemp
)) >= 0)
5718 input_line_pointer
= ptemp
;
5722 while (!is_end_of_statement ())
5724 input_line_pointer
++;
5725 name
= input_line_pointer
;
5726 c
= get_symbol_end ();
5727 if ((strncasecmp (name
, "SPNUM", 5) == 0))
5729 p
= input_line_pointer
;
5731 input_line_pointer
++;
5732 temp
= get_absolute_expression ();
5735 else if ((strncasecmp (name
, "SORT", 4) == 0))
5737 p
= input_line_pointer
;
5739 input_line_pointer
++;
5740 temp
= get_absolute_expression ();
5743 else if ((strncasecmp (name
, "UNLOADABLE", 10) == 0))
5745 p
= input_line_pointer
;
5749 else if ((strncasecmp (name
, "NOTDEFINED", 10) == 0))
5751 p
= input_line_pointer
;
5755 else if ((strncasecmp (name
, "PRIVATE", 7) == 0))
5757 p
= input_line_pointer
;
5763 as_bad ("Unrecognized .SPACE argument");
5764 p
= input_line_pointer
;
5769 print_errors
= TRUE
;
5772 space
= create_new_space (space_name
, spnum
, loadable
, defined
, private, sort
, 1, seg
);
5774 { /* if no creation of new space, this must be the first */
5775 /* occurrence of a built-in space */
5776 space
= is_defined_space (space_name
);
5777 SPACE_SPNUM (space
) = spnum
;
5778 SPACE_LOADABLE (space
) = loadable
& 1;
5779 SPACE_DEFINED (space
) = defined
& 1;
5780 SPACE_PRIVATE (space
) = private & 1;
5781 SPACE_SORT (space
) = sort
& 0xff;
5782 space
->sd_defined
= 1;
5783 space
->sd_seg
= seg
;
5789 pa_align_subseg (seg
, subseg
)
5797 subspace_dict_chainS
*now_subspace
;
5801 now_subspace
= pa_subsegment_to_subspace (seg
, subseg
);
5802 if (SUBSPACE_ALIGN (now_subspace
) == 0)
5803 alignment
= now_subspace
->ssd_last_align
;
5804 else if (now_subspace
->ssd_last_align
> SUBSPACE_ALIGN (now_subspace
))
5805 alignment
= now_subspace
->ssd_last_align
;
5807 alignment
= SUBSPACE_ALIGN (now_subspace
);
5810 while ((1 << shift
) < alignment
)
5813 frag_align (shift
, 0);
5819 register char *name
;
5822 register space_dict_chainS
*sd_chain
;
5823 char space_name
[40];
5825 if (within_procedure
)
5827 as_bad ("Can\'t change spaces within a procedure definition. Ignored");
5828 ignore_rest_of_line ();
5832 if (strncasecmp (input_line_pointer
, "$text$", 6) == 0)
5834 input_line_pointer
+= 6;
5835 sd_chain
= is_defined_space ("$TEXT$");
5836 if (sd_chain
== NULL
)
5837 sd_chain
= pa_parse_space_stmt ("$TEXT$", 1);
5838 else if (sd_chain
->sd_defined
== 0)
5839 sd_chain
= pa_parse_space_stmt ("$TEXT$", 0);
5841 current_space
= sd_chain
;
5842 SPACE_DEFINED (current_space
) = 1;
5843 current_space
->sd_defined
= 1;
5845 if (now_seg
!= SEG_TEXT
) /* no need to align if we are already there */
5847 if (now_seg
!= text_section
) /* no need to align if we are already there */
5849 pa_align_subseg (now_seg
, now_subseg
);
5852 subseg_new (SEG_TEXT
, sd_chain
->sd_last_subseg
);
5853 current_subspace
= pa_subsegment_to_subspace (SEG_TEXT
,
5854 sd_chain
->sd_last_subseg
);
5856 subseg_new ((char *) text_section
->name
, sd_chain
->sd_last_subseg
);
5857 current_subspace
= pa_subsegment_to_subspace (text_section
,
5858 sd_chain
->sd_last_subseg
);
5860 demand_empty_rest_of_line ();
5863 if (strncasecmp (input_line_pointer
, "$private$", 9) == 0)
5865 input_line_pointer
+= 9;
5866 sd_chain
= is_defined_space ("$PRIVATE$");
5867 if (sd_chain
== NULL
)
5868 sd_chain
= pa_parse_space_stmt ("$PRIVATE$", 1);
5869 else if (sd_chain
->sd_defined
== 0)
5870 sd_chain
= pa_parse_space_stmt ("$PRIVATE$", 0);
5872 current_space
= sd_chain
;
5873 SPACE_DEFINED (current_space
) = 1;
5874 current_space
->sd_defined
= 1;
5876 if (now_seg
!= SEG_DATA
) /* no need to align if we are already there */
5878 if (now_seg
!= data_section
) /* no need to align if we are already there */
5880 pa_align_subseg (now_seg
, now_subseg
);
5882 subseg_new (SEG_DATA
, sd_chain
->sd_last_subseg
);
5883 current_subspace
= pa_subsegment_to_subspace (SEG_DATA
,
5884 sd_chain
->sd_last_subseg
);
5886 subseg_new ((char *) data_section
->name
, sd_chain
->sd_last_subseg
);
5887 current_subspace
= pa_subsegment_to_subspace (data_section
,
5888 sd_chain
->sd_last_subseg
);
5890 demand_empty_rest_of_line ();
5893 if (strncasecmp (input_line_pointer
,
5894 GDB_DEBUG_SPACE_NAME
, strlen (GDB_DEBUG_SPACE_NAME
)) == 0)
5896 input_line_pointer
+= strlen (GDB_DEBUG_SPACE_NAME
);
5897 sd_chain
= is_defined_space (GDB_DEBUG_SPACE_NAME
);
5898 if (sd_chain
== NULL
)
5899 sd_chain
= pa_parse_space_stmt (GDB_DEBUG_SPACE_NAME
, 1);
5900 else if (sd_chain
->sd_defined
== 0)
5901 sd_chain
= pa_parse_space_stmt (GDB_DEBUG_SPACE_NAME
, 0);
5903 current_space
= sd_chain
;
5904 SPACE_DEFINED (current_space
) = 1;
5905 current_space
->sd_defined
= 1;
5907 if (now_seg
!= SEG_GDB
) /* no need to align if we are already there */
5908 pa_align_subseg (now_seg
, now_subseg
);
5909 subseg_new (SEG_GDB
, sd_chain
->sd_last_subseg
);
5910 current_subspace
= pa_subsegment_to_subspace (SEG_GDB
,
5911 sd_chain
->sd_last_subseg
);
5914 asection
*gdb_section
5915 = bfd_make_section_old_way (stdoutput
, GDB_DEBUG_SPACE_NAME
);
5916 if (now_seg
!= gdb_section
) /* no need to align if we are already there */
5917 pa_align_subseg (now_seg
, now_subseg
);
5918 subseg_new ((char *) gdb_section
->name
, sd_chain
->sd_last_subseg
);
5919 current_subspace
= pa_subsegment_to_subspace (gdb_section
,
5920 sd_chain
->sd_last_subseg
);
5923 demand_empty_rest_of_line ();
5927 /* it could be a space specified by number */
5929 if ((temp
= pa_parse_number (&input_line_pointer
)) >= 0)
5931 if (sd_chain
= pa_find_space_by_number (temp
))
5933 current_space
= sd_chain
;
5934 SPACE_DEFINED (current_space
) = 1;
5935 current_space
->sd_defined
= 1;
5936 if (now_seg
!= sd_chain
->sd_seg
) /* don't align if we're already there */
5937 pa_align_subseg (now_seg
, now_subseg
);
5939 subseg_new (sd_chain
->sd_seg
, sd_chain
->sd_last_subseg
);
5941 subseg_new ((char *) sd_chain
->sd_seg
->name
, sd_chain
->sd_last_subseg
);
5943 current_subspace
= pa_subsegment_to_subspace (sd_chain
->sd_seg
,
5944 sd_chain
->sd_last_subseg
);
5945 demand_empty_rest_of_line ();
5950 /* not a number, attempt to create a new space */
5952 name
= input_line_pointer
;
5953 c
= get_symbol_end ();
5954 space_name
[0] = 0x00;
5955 strcpy (space_name
, name
);
5956 *input_line_pointer
= c
;
5958 sd_chain
= pa_parse_space_stmt (space_name
, 1);
5959 current_space
= sd_chain
;
5960 SPACE_DEFINED (current_space
) = 1;
5961 current_space
->sd_defined
= 1;
5962 if (now_seg
!= sd_chain
->sd_seg
) /* don't align if we're already there */
5963 pa_align_subseg (now_seg
, now_subseg
);
5965 subseg_new (sd_chain
->sd_seg
, sd_chain
->sd_last_subseg
);
5967 subseg_new ((char *) sd_chain
->sd_seg
->name
, sd_chain
->sd_last_subseg
);
5969 current_subspace
= pa_subsegment_to_subspace (sd_chain
->sd_seg
,
5970 sd_chain
->sd_last_subseg
);
5971 demand_empty_rest_of_line ();
5979 register char *name
;
5982 space_dict_chainS
*space
;
5984 name
= input_line_pointer
;
5985 c
= get_symbol_end ();
5986 space
= is_defined_space (name
);
5990 /* put bytes in right order. */
5991 md_number_to_chars (p
, SPACE_SPNUM (space
), 4);
5994 as_warn ("Undefined space: '%s' Assuming space number = 0.", name
);
5996 *input_line_pointer
= c
;
5997 demand_empty_rest_of_line ();
6003 is_power_of_2 (value
)
6009 while ((1 << shift
) != value
&& shift
< 32)
6020 register char *name
;
6023 char loadable
, code_only
, common
, dup_common
, zero
;
6030 space_dict_chainS
*space
;
6031 subspace_dict_chainS
*ssd
;
6033 int is_power_of_2 ();
6035 if (within_procedure
)
6037 as_bad ("Can\'t change subspaces within a procedure definition. Ignored");
6038 ignore_rest_of_line ();
6042 name
= input_line_pointer
;
6043 c
= get_symbol_end ();
6044 space
= pa_segment_to_space (now_seg
);
6045 ssd
= is_defined_subspace (name
, space
->sd_last_subseg
);
6047 ss_name
= xmalloc (strlen (name
) + 1);
6048 strcpy (ss_name
, name
);
6050 *input_line_pointer
= c
;
6052 /* load default values */
6060 space_index
= ~0; /* filled in when the .o file is written */
6061 alignment
= 0; /* alignment=0 means no ALIGN= appeared on the .SUBSPA */
6062 /* pseudo-op. The default will be the largest .ALIGN */
6063 /* encountered (or 1 if no .ALIGN is encountered) */
6068 if (ssd
->ssd_defined
)
6071 subseg_new (now_seg
, ssd
->ssd_subseg
);
6073 /* subseg_new(now_seg->name,ssd->ssd_subseg); */
6074 subseg_new ((char *) ssd
->ssd_seg
->name
, ssd
->ssd_subseg
);
6076 if (!is_end_of_statement ())
6078 as_warn ("Parameters of an existing subspace can\'t be modified");
6080 demand_empty_rest_of_line ();
6085 ssd
->ssd_defined
= 1;
6090 /* a new subspace */
6091 /* load default values */
6093 while (pa_def_subspaces
[i
].name
)
6095 if (strcasecmp (pa_def_subspaces
[i
].name
, ss_name
) == 0)
6097 loadable
= pa_def_subspaces
[i
].loadable
;
6098 common
= pa_def_subspaces
[i
].common
;
6099 dup_common
= pa_def_subspaces
[i
].dup_common
;
6100 code_only
= pa_def_subspaces
[i
].code_only
;
6101 zero
= pa_def_subspaces
[i
].zero
;
6102 space_index
= pa_def_subspaces
[i
].space_index
;
6103 /* alignment = pa_def_subspaces[i].alignment; */
6105 quadrant
= pa_def_subspaces
[i
].quadrant
;
6106 access
= pa_def_subspaces
[i
].access
;
6107 sort
= pa_def_subspaces
[i
].sort
;
6114 if (!is_end_of_statement ())
6116 input_line_pointer
++;
6117 while (!is_end_of_statement ())
6119 name
= input_line_pointer
;
6120 c
= get_symbol_end ();
6121 if ((strncasecmp (name
, "QUAD", 4) == 0))
6123 *input_line_pointer
= c
;
6124 input_line_pointer
++;
6125 temp
= get_absolute_expression ();
6128 else if ((strncasecmp (name
, "ALIGN", 5) == 0))
6130 *input_line_pointer
= c
;
6131 input_line_pointer
++;
6132 temp
= get_absolute_expression ();
6134 if (!is_power_of_2 (alignment
))
6136 as_bad ("Alignment must be a power of 2");
6140 else if ((strncasecmp (name
, "ACCESS", 6) == 0))
6142 *input_line_pointer
= c
;
6143 input_line_pointer
++;
6144 temp
= get_absolute_expression ();
6147 else if ((strncasecmp (name
, "SORT", 4) == 0))
6149 *input_line_pointer
= c
;
6150 input_line_pointer
++;
6151 temp
= get_absolute_expression ();
6154 else if ((strncasecmp (name
, "CODE_ONLY", 9) == 0))
6156 *input_line_pointer
= c
;
6159 else if ((strncasecmp (name
, "UNLOADABLE", 10) == 0))
6161 *input_line_pointer
= c
;
6164 else if ((strncasecmp (name
, "COMMON", 6) == 0))
6166 *input_line_pointer
= c
;
6169 else if ((strncasecmp (name
, "DUP_COMM", 8) == 0))
6171 *input_line_pointer
= c
;
6174 else if ((strncasecmp (name
, "ZERO", 4) == 0))
6176 *input_line_pointer
= c
;
6181 as_bad ("Unrecognized .SUBSPACE argument");
6183 if (!is_end_of_statement ())
6184 input_line_pointer
++;
6187 space
= pa_segment_to_space (now_seg
);
6190 current_subspace
= update_subspace (ss_name
, 1, loadable
, code_only
,
6191 common
, dup_common
, sort
, zero
, access
,
6192 space_index
, alignment
, quadrant
,
6197 current_subspace
= create_new_subspace (space
, ss_name
, 1, loadable
, code_only
,
6198 common
, dup_common
, zero
, sort
,
6199 access
, space_index
, alignment
,
6202 SUBSPACE_SUBSPACE_START (current_subspace
) = pa_subspace_start (space
, quadrant
);
6204 demand_empty_rest_of_line ();
6206 subseg_new (current_subspace
->ssd_seg
, current_subspace
->ssd_subseg
);
6208 subseg_new ((char *) current_subspace
->ssd_seg
->name
, current_subspace
->ssd_subseg
);
6214 /* For ELF, this function serves one purpose: to setup the st_size */
6215 /* field of STT_FUNC symbols. To do this, we need to scan the */
6216 /* call_info structure list, determining st_size in one of two possible */
6219 /* 1. call_info->start_frag->fr_fix has the size of the fragment. */
6220 /* This approach assumes that the function was built into a */
6221 /* single fragment. This works for most cases, but might fail. */
6222 /* For example, if there was a segment change in the middle of */
6225 /* 2. The st_size field is the difference in the addresses of the */
6226 /* call_info->start_frag->fr_address field and the fr_address */
6227 /* field of the next fragment with fr_type == rs_fill and */
6231 elf_hppa_final_processing ()
6233 extern call_infoS
*call_info_root
;
6237 for (ciP
= call_info_root
; ciP
; ciP
= ciP
->ci_next
)
6239 elf32_symbol_type
*esym
= (elf32_symbol_type
*) ciP
->start_symbol
->bsym
;
6240 esym
->internal_elf_sym
.st_size
=
6241 S_GET_VALUE (ciP
->end_symbol
) - S_GET_VALUE (ciP
->start_symbol
) + 4;
6245 /* pa-spaces.c -- Space/subspace support for the HP PA-RISC version of GAS */
6247 /* for space, subspace, and symbol maintenance on HP 9000 Series 800 */
6249 space_dict_chainS
*space_dict_root
;
6250 space_dict_chainS
*space_dict_last
;
6252 space_dict_chainS
*current_space
;
6253 subspace_dict_chainS
*current_subspace
;
6258 space_dict_chainS
*space
;
6260 subsegT now_subseg
= now_subseg
;
6262 space_dict_root
= NULL
;
6263 space_dict_last
= NULL
;
6265 /* create default space and subspace dictionaries */
6268 while (pa_def_spaces
[i
].name
)
6270 if (pa_def_spaces
[i
].alias
)
6271 pa_def_spaces
[i
].segment
= subseg_new (pa_def_spaces
[i
].alias
, 0);
6273 pa_def_spaces
[i
].segment
= bfd_make_section_old_way (stdoutput
, pa_def_spaces
[i
].name
);
6275 create_new_space (pa_def_spaces
[i
].name
, pa_def_spaces
[i
].spnum
,
6276 pa_def_spaces
[i
].loadable
, pa_def_spaces
[i
].defined
,
6277 pa_def_spaces
[i
].private, pa_def_spaces
[i
].sort
, 0,
6278 pa_def_spaces
[i
].segment
);
6283 while (pa_def_subspaces
[i
].name
)
6285 space
= pa_segment_to_space (pa_def_spaces
[pa_def_subspaces
[i
].def_space_index
].segment
);
6288 char *name
= pa_def_subspaces
[i
].alias
;
6290 name
= pa_def_subspaces
[i
].name
;
6291 create_new_subspace (space
, name
,
6292 pa_def_subspaces
[i
].defined
,
6293 pa_def_subspaces
[i
].loadable
,
6294 pa_def_subspaces
[i
].code_only
, pa_def_subspaces
[i
].common
,
6295 pa_def_subspaces
[i
].dup_common
, pa_def_subspaces
[i
].zero
,
6296 pa_def_subspaces
[i
].sort
, pa_def_subspaces
[i
].access
,
6297 pa_def_subspaces
[i
].space_index
,
6298 pa_def_subspaces
[i
].alignment
,
6299 pa_def_subspaces
[i
].quadrant
,
6300 pa_def_spaces
[pa_def_subspaces
[i
].def_space_index
].segment
);
6301 subseg_new (name
, pa_def_subspaces
[i
].subsegment
);
6304 as_fatal ("Internal error: space missing for subspace \"%s\"\n",
6305 pa_def_subspaces
[i
].name
);
6311 create_new_space (name
, spnum
, loadable
, defined
, private, sort
, defined_in_file
, seg
)
6318 char defined_in_file
;
6322 Elf_Internal_Shdr
*new_space
;
6323 space_dict_chainS
*chain_entry
;
6325 new_space
= (Elf_Internal_Shdr
*) xmalloc (sizeof (Elf_Internal_Shdr
));
6327 as_fatal ("Out of memory: could not allocate new Elf_Internal_Shdr: %s\n", name
);
6330 new_space->space_number = spnum;
6331 new_space->is_loadable = loadable & 1;
6332 new_space->is_defined = defined & 1;
6333 new_space->is_private = private & 1;
6334 new_space->sort_key = sort & 0xff;
6336 new_space->loader_fix_index = ~0;
6337 new_space->loader_fix_quantity = 0;
6338 new_space->init_pointer_index = ~0;
6339 new_space->init_pointer_quantity = 0;
6340 new_space->subspace_quantity = 0;
6343 chain_entry
= (space_dict_chainS
*) xmalloc (sizeof (space_dict_chainS
));
6345 as_fatal ("Out of memory: could not allocate new space chain entry: %s\n", name
);
6347 SPACE_NAME (chain_entry
) = (char *) xmalloc (strlen (name
) + 1);
6348 strcpy (SPACE_NAME (chain_entry
), name
);
6350 chain_entry
->sd_entry
= new_space
;
6351 chain_entry
->sd_defined
= defined_in_file
;
6352 chain_entry
->sd_seg
= seg
;
6353 chain_entry
->sd_last_subseg
= -1;
6354 chain_entry
->sd_next
= NULL
;
6356 SPACE_SPNUM (chain_entry
) = spnum
;
6357 SPACE_LOADABLE (chain_entry
) = loadable
& 1;
6358 SPACE_DEFINED (chain_entry
) = defined
& 1;
6359 SPACE_PRIVATE (chain_entry
) = private & 1;
6360 SPACE_SORT (chain_entry
) = sort
& 0xff;
6362 /* find spot for the new space based on its sort key */
6364 if (!space_dict_last
)
6365 space_dict_last
= chain_entry
;
6367 if (space_dict_root
== NULL
) /* if root is null, it is very easy */
6368 space_dict_root
= chain_entry
;
6371 space_dict_chainS
*sdcP
;
6372 space_dict_chainS
*last_sdcP
;
6374 sdcP
= space_dict_root
;
6379 if (SPACE_SORT (sdcP
) < SPACE_SORT (chain_entry
))
6382 sdcP
= sdcP
->sd_next
;
6384 else if (SPACE_SORT (sdcP
) == SPACE_SORT (chain_entry
))
6387 sdcP
= sdcP
->sd_next
;
6389 else if (SPACE_SORT (sdcP
) > SPACE_SORT (chain_entry
))
6397 chain_entry
->sd_next
= sdcP
;
6398 last_sdcP
->sd_next
= chain_entry
;
6402 space_dict_root
= chain_entry
;
6403 chain_entry
->sd_next
= sdcP
;
6406 if (chain_entry
->sd_next
== NULL
)
6407 space_dict_last
= chain_entry
;
6413 subspace_dict_chainS
6414 * create_new_subspace (space
, name
, defined
, loadable
, code_only
, common
, dup_common
,
6415 is_zero
, sort
, access
, space_index
, alignment
, quadrant
, seg
)
6416 space_dict_chainS
*space
;
6418 char defined
, loadable
, code_only
, common
, dup_common
, is_zero
;
6426 Elf_Internal_Shdr
*new_subspace
;
6427 subspace_dict_chainS
*chain_entry
;
6428 symbolS
*start_symbol
;
6430 new_subspace
= (Elf_Internal_Shdr
*) xmalloc (sizeof (Elf_Internal_Shdr
));
6432 as_fatal ("Out of memory: could not allocate new Elf_Internal_Shdr: %s\n",
6436 new_subspace->space_index = space_index;
6437 new_subspace->fixup_request_index = ~0;
6440 chain_entry
= (subspace_dict_chainS
*) xmalloc (sizeof (subspace_dict_chainS
));
6442 as_fatal ("Out of memory: could not allocate new subspace chain entry: %s\n", name
);
6444 chain_entry
->ssd_entry
= new_subspace
;
6445 SUBSPACE_NAME (chain_entry
) = (char *) xmalloc (strlen (name
) + 1);
6446 strcpy (SUBSPACE_NAME (chain_entry
), name
);
6448 SUBSPACE_ACCESS (chain_entry
) = access
& 0x7f;
6449 SUBSPACE_LOADABLE (chain_entry
) = loadable
& 1;
6450 SUBSPACE_COMMON (chain_entry
) = common
& 1;
6451 SUBSPACE_DUP_COMM (chain_entry
) = dup_common
& 1;
6452 SUBSPACE_SORT (chain_entry
) = sort
& 0xff;
6453 SET_SUBSPACE_CODE_ONLY (chain_entry
, code_only
& 1);
6454 SUBSPACE_ALIGN (chain_entry
) = alignment
& 0xffff;
6455 SUBSPACE_QUADRANT (chain_entry
) = quadrant
& 0x3;
6456 SUBSPACE_SUBSPACE_START (chain_entry
) = pa_subspace_start (space
, quadrant
);
6458 chain_entry
->ssd_defined
= defined
;
6459 chain_entry
->ssd_space_number
= space_index
;
6460 chain_entry
->ssd_subseg
= pa_next_subseg (space
);
6461 chain_entry
->ssd_seg
= seg
;
6462 SUBSPACE_ZERO (chain_entry
) = is_zero
;
6463 chain_entry
->ssd_last_align
= 1;
6464 chain_entry
->ssd_next
= NULL
;
6466 /* find spot for the new subspace based on its sort key */
6468 if (space
->sd_subspaces
== NULL
) /* if root is null, it is very easy */
6469 space
->sd_subspaces
= chain_entry
;
6472 subspace_dict_chainS
*ssdcP
;
6473 subspace_dict_chainS
*last_ssdcP
;
6475 ssdcP
= space
->sd_subspaces
;
6480 if (SUBSPACE_SORT (ssdcP
) < SUBSPACE_SORT (chain_entry
))
6483 ssdcP
= ssdcP
->ssd_next
;
6485 else if (SUBSPACE_SORT (ssdcP
) == SUBSPACE_SORT (chain_entry
))
6488 ssdcP
= ssdcP
->ssd_next
;
6490 else if (SUBSPACE_SORT (ssdcP
) > SUBSPACE_SORT (chain_entry
))
6498 chain_entry
->ssd_next
= ssdcP
;
6499 last_ssdcP
->ssd_next
= chain_entry
;
6503 space
->sd_subspaces
= chain_entry
;
6504 chain_entry
->ssd_next
= ssdcP
;
6508 start_symbol
= pa_set_start_symbol (seg
, space
->sd_last_subseg
);
6509 chain_entry
->ssd_start_sym
= start_symbol
;
6514 subspace_dict_chainS
6515 * update_subspace (name
, defined
, loadable
, code_only
, common
, dup_common
, sort
, zero
,
6516 access
, space_index
, alignment
, quadrant
, subseg
)
6518 char defined
, loadable
, code_only
, common
, dup_common
, zero
;
6526 subspace_dict_chainS
*chain_entry
;
6527 subspace_dict_chainS
*is_defined_subspace ();
6529 if ((chain_entry
= is_defined_subspace (name
, subseg
)))
6532 SUBSPACE_ACCESS (chain_entry
) = access
& 0x7f;
6533 SUBSPACE_LOADABLE (chain_entry
) = loadable
& 1;
6534 SUBSPACE_COMMON (chain_entry
) = common
& 1;
6535 SUBSPACE_DUP_COMM (chain_entry
) = dup_common
& 1;
6536 SET_SUBSPACE_CODE_ONLY (chain_entry
, code_only
& 1);
6537 SUBSPACE_SORT (chain_entry
) = sort
& 0xff;
6538 /* chain_entry->ssd_entry->space_index = space_index; */
6539 SUBSPACE_ALIGN (chain_entry
) = alignment
& 0xffff;
6540 SUBSPACE_QUADRANT (chain_entry
) = quadrant
& 0x3;
6542 chain_entry
->ssd_defined
= defined
;
6543 chain_entry
->ssd_space_number
= space_index
;
6544 SUBSPACE_ZERO (chain_entry
) = zero
;
6554 is_defined_space (name
)
6557 space_dict_chainS
*spaceCh
;
6559 for (spaceCh
= space_dict_root
; spaceCh
; spaceCh
= spaceCh
->sd_next
)
6561 if (strcmp (SPACE_NAME (spaceCh
), name
) == 0)
6571 pa_segment_to_space (seg
)
6574 space_dict_chainS
*spaceCh
;
6576 for (spaceCh
= space_dict_root
; spaceCh
; spaceCh
= spaceCh
->sd_next
)
6578 if (spaceCh
->sd_seg
== seg
)
6587 subspace_dict_chainS
*
6588 is_defined_subspace (name
, subseg
)
6592 space_dict_chainS
*spaceCh
;
6593 subspace_dict_chainS
*subspCh
;
6595 for (spaceCh
= space_dict_root
; spaceCh
; spaceCh
= spaceCh
->sd_next
)
6597 for (subspCh
= spaceCh
->sd_subspaces
; subspCh
; subspCh
= subspCh
->ssd_next
)
6600 if ( strcmp(SUBSPACE_NAME(subspCh),name) == 0 &&
6601 subspCh->ssd_subseg == subseg ) {
6603 if (strcmp (SUBSPACE_NAME (subspCh
), name
) == 0)
6612 subspace_dict_chainS
*
6613 pa_subsegment_to_subspace (seg
, subseg
)
6617 space_dict_chainS
*spaceCh
;
6618 subspace_dict_chainS
*subspCh
;
6620 for (spaceCh
= space_dict_root
; spaceCh
; spaceCh
= spaceCh
->sd_next
)
6622 if (spaceCh
->sd_seg
== seg
)
6624 for (subspCh
= spaceCh
->sd_subspaces
; subspCh
; subspCh
= subspCh
->ssd_next
)
6626 if (subspCh
->ssd_subseg
== (int) subseg
)
6638 pa_find_space_by_number (number
)
6641 space_dict_chainS
*spaceCh
;
6643 for (spaceCh
= space_dict_root
; spaceCh
; spaceCh
= spaceCh
->sd_next
)
6645 if (SPACE_SPNUM (spaceCh
) == number
)
6655 pa_subspace_start (space
, quadrant
)
6656 space_dict_chainS
*space
;
6659 if ((strcasecmp (SPACE_NAME (space
), "$PRIVATE$") == 0) &&
6664 else if (space
->sd_seg
== data_section
&& quadrant
== 1)
6665 { /* in case name is */
6666 /* already converted */
6667 /* to a space dict- */
6676 pa_next_subseg (space
)
6677 space_dict_chainS
*space
;
6680 space
->sd_last_subseg
++;
6681 return space
->sd_last_subseg
;
6685 is_last_defined_subspace (ssd
)
6686 subspace_dict_chainS
*ssd
;
6689 for (; ssd
; ssd
= ssd
->ssd_next
)
6691 if (ssd
->ssd_defined
)
6699 pa_get_start_symbol (seg
, subseg
)
6703 symbolS
*start_symbol
;
6704 subspace_dict_chainS
*ssd
;
6706 start_symbol
= NULL
;
6708 /* each time a new space is created, build a symbol called LS$START_seg_subseg$ */
6709 /* where <space-name> is the name of the space */
6710 /* the start symbol will be SS_LOCAL and ST_CODE */
6712 if (seg
== bfd_make_section_old_way (stdoutput
, ".text") ||
6713 seg
== bfd_make_section_old_way (stdoutput
, ".data") ||
6714 seg
== bfd_make_section_old_way (stdoutput
, GDB_DEBUG_SPACE_NAME
))
6716 ssd
= pa_subsegment_to_subspace (seg
, subseg
);
6719 start_symbol
= ssd
->ssd_start_sym
;
6722 as_fatal ("Internal error: missing subspace for (seg,subseg)=('%s',%d)",
6726 as_fatal ("Internal error: attempt to find start symbol for unloadable segment: '%s'",
6729 return start_symbol
;
6733 Function to define a symbol whose address is the beginning of a subspace.
6734 This function assumes the symbol is to be defined for the current subspace.
6738 pa_set_start_symbol (seg
, subseg
)
6742 symbolS
*start_symbol
;
6743 subspace_dict_chainS
*ssd
;
6746 symbol_name
= (char *) xmalloc (strlen ("LS$START__000000$") + strlen (seg
->name
) + 1);
6748 sprintf (symbol_name
, "LS$START_%s_%03d$", seg
->name
, subseg
);
6751 = symbol_new (symbol_name
, seg
, 0, frag_now
); /* XXX: not sure if value s.b. 0 or frag s.b. NULL */
6753 start_symbol
->bsym
->flags
= BSF_LOCAL
; /* XXX: isn't there a macro defined for this? */
6755 /* each time a new space is created, build a symbol called LS$START_seg_subseg$ */
6756 /* where <space-name> is the name of the space */
6757 /* the start symbol will be SS_LOCAL and ST_CODE */
6758 /* This function assumes that (seg,subseg) is a new subsegment(subspace) */
6760 if (seg
== bfd_make_section_old_way (stdoutput
, ".text") ||
6761 seg
== bfd_make_section_old_way (stdoutput
, ".data") ||
6762 seg
== bfd_make_section_old_way (stdoutput
, GDB_DEBUG_SPACE_NAME
))
6764 ssd
= pa_subsegment_to_subspace (seg
, subseg
);
6767 ssd
->ssd_start_sym
= start_symbol
;
6770 as_fatal ("Internal error: missing subspace for (seg,subseg)=('%s',%d)",
6774 as_fatal ("Internal error: attempt to define start symbol for unloadable segment: '%s'",
6777 return start_symbol
;
6784 unsigned int c
= *s
& CHAR_MASK
;
6797 pa_stringer (append_zero
) /* Worker to do .ascii etc statements. */
6798 /* Checks end-of-line. */
6799 register int append_zero
; /* 0: don't append '\0', else 1 */
6806 /* Preprocess the string to handle PA-specific escape sequences. */
6807 /* For example, \xDD where DD is a hexidecimal number should be */
6808 /* changed to \OOO where OOO is an octal number. */
6810 s
= input_line_pointer
+ 1; /* skip the opening quote */
6812 while (is_a_char (c
= pa_stringer_aux (s
++)))
6821 unsigned int number
;
6826 s
++; /* get past the 'x' */
6827 for (num_digit
= 0, number
= 0, dg
= *s
;
6829 && (isdigit (dg
) || (dg
>= 'a' && dg
<= 'f')
6830 || (dg
>= 'A' && dg
<= 'F'));
6834 number
= number
* 16 + dg
- '0';
6835 else if (dg
>= 'a' && dg
<= 'f')
6836 number
= number
* 16 + dg
- 'a' + 10;
6838 number
= number
* 16 + dg
- 'A' + 10;
6848 sprintf (num_buf
, "%02o", number
);
6851 sprintf (num_buf
, "%03o", number
);
6854 for (i
= 0; i
<= num_digit
; i
++)
6855 s_start
[i
] = num_buf
[i
];
6859 /* This might be a "\"", skip over the escaped char. */
6866 stringer (append_zero
);
6867 pa_undefine_label ();
6876 pa_undefine_label ();
6881 register unsigned int nbytes
; /* 1=.byte, 2=.word, 4=.long */
6884 pa_undefine_label ();
6891 pa_undefine_label ();
6901 pa_undefine_label ();
6905 pa_float_cons (float_type
)
6906 register int float_type
; /* 'f':.ffloat ... 'F':.float ... */
6908 float_cons (float_type
);
6909 pa_undefine_label ();
6916 pa_undefine_label ();
6920 pa_lcomm (needs_align
)
6921 /* 1 if this was a ".bss" directive, which may require a 3rd argument
6922 (alignment); 0 if it was an ".lcomm" (2 args only) */
6925 s_lcomm (needs_align
);
6926 pa_undefine_label ();
6933 pa_undefine_label ();
6937 pa_big_cons (nbytes
)
6938 register int nbytes
;
6941 pa_undefine_label ();
6948 pa_undefine_label ();
6951 static symext_chainS
*symext_rootP
= NULL
;
6952 static symext_chainS
*symext_lastP
= NULL
;
6955 hppa_tc_symbol (abfd
, symbolP
, sym_idx
)
6957 elf_symbol_type
* symbolP
;
6960 symext_chainS
*symextP
;
6961 unsigned int arg_reloc
;
6963 if (!(symbolP
->symbol
.flags
& BSF_FUNCTION
))
6966 arg_reloc
= symbolP
->tc_data
.hppa_arg_reloc
;
6968 symextP
= (symext_chainS
*) bfd_alloc (abfd
, sizeof (symext_chainS
) * 2);
6970 symextP
[0].entry
= ELF32_HPPA_SX_WORD (HPPA_SXT_SYMNDX
, sym_idx
);
6971 symextP
[0].next
= &symextP
[1];
6973 symextP
[1].entry
= ELF32_HPPA_SX_WORD (HPPA_SXT_ARG_RELOC
, arg_reloc
);
6974 symextP
[1].next
= NULL
;
6976 if (symext_rootP
== NULL
)
6978 symext_rootP
= &symextP
[0];
6979 symext_lastP
= &symextP
[1];
6983 symext_lastP
->next
= &symextP
[0];
6984 symext_lastP
= &symextP
[1];
6989 hppa_tc_make_sections (abfd
)
6992 symext_chainS
*symextP
;
6993 symext_entryS
*outbound_symexts
;
6996 extern void hppa_elf_stub_finish (); /* forward declaration */
6997 asection
*symextn_sec
;
6998 segT save_seg
= now_seg
;
6999 subsegT save_subseg
= now_subseg
;
7001 hppa_tc_make_symextn_section();
7003 bfd_set_section_contents(stdoutput
, stdoutput
->sections
, "", 0, 0); /* force some calculations */
7005 hppa_elf_stub_finish (abfd
);
7007 if (symext_rootP
== NULL
)
7010 for (n
= 0, symextP
= symext_rootP
; symextP
; symextP
= symextP
->next
, ++n
)
7013 size
= sizeof (symext_entryS
) * n
;
7015 symextn_sec
= subseg_new(SYMEXTN_SECTION_NAME
, 0);
7017 frag_wane (frag_now
);
7020 for (symextP
= symext_rootP
; symextP
; symextP
= symextP
->next
)
7023 extern int *elf_get_symtab_map();
7024 Elf_Sym_Extra
*symextra
= elf_sym_extra (abfd
);
7027 /* First, patch the symbol extension record to reflect the true */
7028 /* symbol table index */
7030 if (ELF32_HPPA_SX_TYPE(symextP
->entry
) == HPPA_SXT_SYMNDX
)
7032 idx
= ELF32_HPPA_SX_VAL(symextP
->entry
) - 1;
7033 symextP
->entry
= ELF32_HPPA_SX_WORD (HPPA_SXT_SYMNDX
,
7034 symextra
[idx
].elf_sym_num
);
7037 ptr
= frag_more(sizeof(symextP
->entry
));
7038 md_number_to_chars(ptr
,symextP
->entry
,sizeof(symextP
->entry
));
7041 frag_now
->fr_fix
= obstack_next_free (&frags
) - frag_now
->fr_literal
;
7042 frag_wane (frag_now
);
7044 /* now, switch back to the original segment */
7046 subseg_new(save_seg
->name
, save_subseg
);
7052 hppa_tc_make_symextn_section()
7054 extern symext_chainS
*elf32_hppa_get_symextn_chain();
7058 symext_chainS
*symextP
;
7062 segT save_seg
= now_seg
;
7063 subsegT save_subseg
= now_subseg
;
7065 for (n
= 0, symextP
= symext_rootP
; symextP
; symextP
= symextP
->next
, ++n
)
7068 size
= sizeof (symext_entryS
) * n
;
7070 symextn_sec
= subseg_new(SYMEXTN_SECTION_NAME
, 0);
7072 bfd_set_section_flags(stdoutput
, symextn_sec
, SEC_LOAD
| SEC_HAS_CONTENTS
| SEC_DATA
);
7073 bfd_set_section_size (stdoutput
, symextn_sec
, size
);
7075 /* now, switch back to the original segment */
7076 subseg_new(save_seg
->name
, save_subseg
);