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" */
34 * Unwind table and descriptor.
39 unsigned int cannot_unwind
:1;
40 unsigned int millicode
:1;
41 unsigned int millicode_save_rest
:1;
42 unsigned int region_desc
:2;
43 unsigned int save_sr
:2;
44 unsigned int entry_fr
:4; /* number saved */
45 unsigned int entry_gr
:5; /* number saved */
46 unsigned int args_stored
:1;
47 unsigned int call_fr
:5;
48 unsigned int call_gr
:5;
49 unsigned int save_sp
:1;
50 unsigned int save_rp
:1;
51 unsigned int save_rp_in_frame
:1;
52 unsigned int extn_ptr_defined
:1;
53 unsigned int cleanup_defined
:1;
55 unsigned int hpe_interrupt_marker
:1;
56 unsigned int hpux_interrupt_marker
:1;
57 unsigned int reserved
:3;
58 unsigned int frame_size
:27;
61 typedef struct unwind_desc unwind_descS
;
65 unsigned int start_offset
; /* starting offset (from SR4) of applicable region */
66 unsigned int end_offset
; /* ending offset (from SR4) of applicable region */
67 unwind_descS descriptor
;
70 typedef struct unwind_table unwind_tableS
;
73 * This structure is used by the .callinfo, .enter, .leave pseudo-ops to
74 * control the entry and exit code they generate. It is also used in
75 * creation of the correct stack unwind descriptors.
77 * The fields in structure roughly correspond to the arguments available on the
78 * .callinfo pseudo-op.
87 unwind_tableS ci_unwind
; /* the unwind descriptor we are building */
88 symbolS
*start_symbol
; /* name of function (used in relocation info) */
89 symbolS
*end_symbol
; /* temporary symbol used to mark the */
90 /* end of the function (used in */
91 /* relocation info) */
92 fragS
*start_frag
; /* frag associated w/ start of this function */
93 fragS
*end_frag
; /* frag associated w/ end of this function */
94 fragS
*start_offset_frag
; /* frag for start offset of this descriptor */
95 int start_frag_where
; /* where in start_offset_frag is start_offset */
96 fixS
*start_fix
; /* fixup for the start_offset */
97 fragS
*end_offset_frag
; /* frag for start offset of this descriptor */
98 int end_frag_where
; /* where in end_offset_frag is end_offset */
99 fixS
*end_fix
; /* fixup for the end_offset */
100 struct call_info
*ci_next
; /* the next call_info structure */
103 typedef struct call_info call_infoS
;
105 call_infoS
*last_call_info
;
106 call_infoS
*call_info_root
;
107 call_descS last_call_desc
;
109 /* A structure used during assembly of individual instructions */
114 unsigned long opcode
;
115 /* symbol_dictS *nlistp; *//*** used to be: struct nlist *nlistp; */
119 FP_Operand_Format fpof1
; /* Floating Point Operand Format, operand 1 */
120 FP_Operand_Format fpof2
; /* Floating Point Operand Format, operand 2 */
121 /* (used only for class 1 instructions -- */
122 /* the conversion instructions) */
131 elf32_hppa_reloc_type reloc
;
139 extern struct pa_it the_insn
;
141 /* careful, this file includes data *declarations* */
142 #include "opcode/hppa.h"
146 void md_number_to_chars ();
149 void md_convert_frag ();
150 void md_create_short_jump ();
151 void md_create_long_jump ();
152 int md_estimate_size_before_relax ();
153 void md_number_to_imm ();
154 void md_number_to_disp ();
155 void md_number_to_field ();
156 void md_ri_to_chars ();
157 void emit_relocations ();
158 static void pa_ip ();
160 const relax_typeS md_relax_table
[] =
162 /* handle of the OPCODE hash table */
163 static struct hash_control
*op_hash
= NULL
;
165 int md_short_jump_size
= 4;
166 int md_long_jump_size
= 4;
168 /* This array holds the chars that always start a comment. If the
169 pre-processor is disabled, these aren't very useful */
170 const char comment_chars
[] = ";"; /* JF removed '|' from comment_chars */
175 {"align", s_align_bytes
, 0}, /* .align 4 means .align to 4-byte boundary */
176 {"ALIGN", s_align_bytes
, 0}, /* .align 4 means .align to 4-byte boundary */
177 {"block", pa_block
, 1},
178 {"BLOCK", pa_block
, 1},
179 {"blockz", pa_block
, 0},
180 {"BLOCKZ", pa_block
, 0},
181 {"byte", pa_cons
, 1},
182 {"BYTE", pa_cons
, 1},
183 {"call", pa_call
, 0},
184 {"CALL", pa_call
, 0},
185 {"callinfo", pa_callinfo
, 0},
186 {"CALLINFO", pa_callinfo
, 0},
187 {"code", pa_code
, 0},
188 {"CODE", pa_code
, 0},
189 {"comm", pa_comm
, 0},
190 {"COMM", pa_comm
, 0},
191 {"copyright", pa_copyright
, 0},
192 {"COPYRIGHT", pa_copyright
, 0},
193 {"data", pa_data
, 0},
194 {"DATA", pa_data
, 0},
195 {"desc", pa_desc
, 0},
196 {"DESC", pa_desc
, 0},
197 {"double", pa_float_cons
, 'd'},
198 {"DOUBLE", pa_float_cons
, 'd'},
201 {"enter", pa_enter
, 0},
202 {"ENTER", pa_enter
, 0},
203 {"entry", pa_entry
, 0},
204 {"ENTRY", pa_entry
, 0},
207 {"exit", pa_exit
, 0},
208 {"EXIT", pa_exit
, 0},
209 {"export", pa_export
, 0},
210 {"EXPORT", pa_export
, 0},
211 {"fill", pa_fill
, 0},
212 {"FILL", pa_fill
, 0},
213 {"float", pa_float_cons
, 'f'},
214 {"FLOAT", pa_float_cons
, 'f'},
215 {"half", pa_cons
, 2},
216 {"HALF", pa_cons
, 2},
217 {"import", pa_import
, 0},
218 {"IMPORT", pa_import
, 0},
221 {"label", pa_label
, 0},
222 {"LABEL", pa_label
, 0},
223 {"lcomm", pa_lcomm
, 0},
224 {"LCOMM", pa_lcomm
, 0},
225 {"leave", pa_leave
, 0},
226 {"LEAVE", pa_leave
, 0},
227 {"long", pa_cons
, 4},
228 {"LONG", pa_cons
, 4},
229 {"lsym", pa_lsym
, 0},
230 {"LSYM", pa_lsym
, 0},
231 {"octa", pa_big_cons
, 16},
232 {"OCTA", pa_big_cons
, 16},
233 {"org", pa_origin
, 0},
234 {"ORG", pa_origin
, 0},
235 {"origin", pa_origin
, 0},
236 {"ORIGIN", pa_origin
, 0},
237 {"proc", pa_proc
, 0},
238 {"PROC", pa_proc
, 0},
239 {"procend", pa_procend
, 0},
240 {"PROCEND", pa_procend
, 0},
241 {"quad", pa_big_cons
, 8},
242 {"QUAD", pa_big_cons
, 8},
243 {"reg", pa_equ
, 1}, /* very similar to .equ */
244 {"REG", pa_equ
, 1}, /* very similar to .equ */
245 {"short", pa_cons
, 2},
246 {"SHORT", pa_cons
, 2},
247 {"single", pa_float_cons
, 'f'},
248 {"SINGLE", pa_float_cons
, 'f'},
249 {"space", pa_space
, 0},
250 {"SPACE", pa_space
, 0},
251 {"spnum", pa_spnum
, 0},
252 {"SPNUM", pa_spnum
, 0},
253 {"string", pa_stringer
, 0},
254 {"STRING", pa_stringer
, 0},
255 {"stringz", pa_stringer
, 1},
256 {"STRINGZ", pa_stringer
, 1},
257 {"subspa", pa_subspace
, 0},
258 {"SUBSPA", pa_subspace
, 0},
259 {"text", pa_text
, 0},
260 {"TEXT", pa_text
, 0},
261 {"version", pa_version
, 0},
262 {"VERSION", pa_version
, 0},
263 {"word", pa_cons
, 4},
264 {"WORD", pa_cons
, 4},
268 /* This array holds the chars that only start a comment at the beginning of
269 a line. If the line seems to have the form '# 123 filename'
270 .line and .file directives will appear in the pre-processed output */
271 /* Note that input_file.c hand checks for '#' at the beginning of the
272 first line of the input file. This is because the compiler outputs
273 #NO_APP at the beginning of its output. */
274 /* Also note that '/*' will always start a comment */
275 const char line_comment_chars
[] = "#";
277 const char line_separator_chars
[] = "!";
279 /* Chars that can be used to separate mant from exp in floating point nums */
280 const char EXP_CHARS
[] = "eE";
282 /* Chars that mean this number is a floating point constant */
285 const char FLT_CHARS
[] = "rRsSfFdDxXpP";
287 /* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
288 changed in read.c . Ideally it shouldn't have to know about it at all,
289 but nothing is ideal around here.
292 static unsigned char octal
[256];
294 #define isoctal(c) octal[c]
296 static unsigned char toHex
[256];
298 struct pa_it set_insn
; /* this structure is defined above */
300 /* SKV 12/22/92. Added prev_insn, prev_fix, and initialized the_insn
301 so that we can recognize instruction sequences such as (ldil, ble)
302 and generate the appropriate fixups. */
304 struct pa_it the_insn
=
310 NULL
, /* exp.X_add_symbol */
311 NULL
, /* exp.X_subtract_symbol */
312 0, /* exp.X_add_number */
313 NULL
/* exp.asection */
319 0, /* field_selector */
323 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
329 struct pa_it prev_insn
;
330 char prev_str
[10] = "";
331 fixS
*prev_fix
= NULL
;
332 fixS
*curr_fix
= NULL
;
337 void print_insn (struct pa_it
*insn
);
343 symbolS
*label_symbolP
; /* the last label symbol encountered */
344 /* saved here in case a .equ is encountered */
345 int label_symbol_defined
;
347 int callinfo_found
; /* T if a .callinfo appeared within the current */
348 /* procedure definition and F otherwise */
350 int within_entry_exit
; /* T if the assembler is currently within a */
351 /* .entry/.exit pair and F otherwise */
353 int exit_processing_complete
; /* T is the assembler has completed exit */
354 /* processing for the current procedure */
355 /* and F otherwise */
357 int within_procedure
; /* T if the assembler is currently within a */
358 /* a procedure definition and F otherwise */
360 void ignore_rest_of_line (); /* a useful function in read.c */
362 /* default space and subspace dictionaries */
364 #define GDB_SYMBOLS GDB_SYMBOLS_SUBSPACE_NAME
365 #define GDB_STRINGS GDB_STRINGS_SUBSPACE_NAME
368 struct default_subspace_dict pa_def_subspaces
[] =
370 {"$CODE$", 0, 1, 0, 0, 0, 0, 24, 0x2c, 0, 8, 0, 0, ".text", SUBSEG_CODE
},
371 {"$DATA$", 0, 1, 0, 0, 0, 0, 24, 0x1f, 0, 8, 1, 1, ".data", SUBSEG_DATA
},
372 {"$LIT$", 0, 1, 0, 0, 0, 0, 16, 0x2c, 0, 8, 0, 0, ".text", SUBSEG_LIT
},
373 {"$BSS$", 0, 1, 0, 0, 0, 1, 80, 0x1f, 0, 8, 1, 1, ".bss", SUBSEG_BSS
},
374 {"$UNWIND$", 0, 1, 0, 0, 0, 0, 64, 0x2c, 0, 4, 0, 0, ".hppa_unwind", SUBSEG_UNWIND
},
375 {GDB_STRINGS
, 0, 0, 0, 0, 0, 0, 254, 0x1f, 0, 4, 0, 2, ".stabstr", SUBSEG_GDB_STRINGS
},
376 {GDB_SYMBOLS
, 0, 0, 0, 0, 0, 0, 255, 0x1f, 0, 4, 0, 2, ".stab", SUBSEG_GDB_SYMBOLS
},
377 {NULL
, 0, 1, 0, 0, 0, 0, 255, 0x1f, 0, 4, 0, 0, 0}
380 struct default_space_dict pa_def_spaces
[] =
382 {"$TEXT$", 0, 1, 0, 0, 8, ASEC_NULL
, ".text"},
383 {"$PRIVATE$", 0, 1, 0, 0, 16, ASEC_NULL
, ".data"},
384 {GDB_DEBUG_SPACE_NAME
, 0, 0, 0, 0, 255, ASEC_NULL
, ".stab"},
385 {NULL
, 0, 0, 0, 0, 0, ASEC_NULL
, NULL
}
388 struct default_subspace_dict pa_def_subspaces
[] =
390 {"$CODE$", 0, 1, 0, 0, 0, 0, 24, 0x2c, 0, 8, 0, SEG_TEXT
, SUBSEG_CODE
},
391 {"$DATA$", 0, 1, 0, 0, 0, 0, 24, 0x1f, 0, 8, 1, SEG_DATA
, SUBSEG_DATA
},
392 {"$LIT$", 0, 1, 0, 0, 0, 0, 16, 0x2c, 0, 8, 0, SEG_TEXT
, SUBSEG_LIT
},
393 {"$BSS$", 0, 1, 0, 0, 0, 1, 80, 0x1f, 0, 8, 1, SEG_DATA
, SUBSEG_BSS
},
394 {"$UNWIND$", 0, 1, 0, 0, 0, 0, 64, 0x2c, 0, 4, 0, SEG_TEXT
, SUBSEG_UNWIND
},
395 {GDB_STRINGS
, 0, 0, 0, 0, 0, 0, 254, 0x1f, 0, 4, 0, SEG_GDB
, SUBSEG_GDB_STRINGS
397 {GDB_SYMBOLS
, 0, 0, 0, 0, 0, 0, 255, 0x1f, 0, 4, 0, SEG_GDB
, SUBSEG_GDB_SYMBOLS
399 {NULL
, 0, 1, 0, 0, 0, 0, 255, 0x1f, 0, 4, 0, SEG_GOOF
, 0}
402 struct default_space_dict pa_def_spaces
[] =
404 {"$TEXT$", 0, 1, 0, 0, 8, SEG_TEXT
},
405 {"$PRIVATE$", 0, 1, 0, 0, 16, SEG_DATA
},
406 {GDB_DEBUG_SPACE_NAME
, 0, 0, 0, 0, 255, SEG_GDB
},
407 {NULL
, 0, 0, 0, 0, 0, SEG_GOOF
}
412 #define bcmp(b1,b2,n) memcmp((b1),(b2),(n))
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 *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)
478 Support for keeping track of the most recent label in each
482 /* XXX: NOTE: label_symbolS is defined in pa.h */
484 label_symbolS
*label_symbols_rootP
= NULL
;
489 Returns a pointer to the label_symbolS for the current space.
496 space_dict_chainS
*now_sdcP
= pa_segment_to_space (now_seg
);
498 for (lssP
= label_symbols_rootP
; lssP
; lssP
= lssP
->lss_next
)
500 if (now_sdcP
== lssP
->lss_space
&& lssP
->lss_label
)
504 return (label_symbolS
*) NULL
;
510 A predicate to determine whether a useable label is defined in
515 pa_label_is_defined ()
517 return (int) pa_get_label ();
523 Defines a label for the current space. If one is already defined,
524 this function will replace it with the new label.
528 pa_define_label (symbolP
)
531 label_symbolS
*lssP
= pa_get_label ();
532 space_dict_chainS
*now_sdcP
= pa_segment_to_space (now_seg
);
536 lssP
->lss_label
= symbolP
;
540 lssP
= (label_symbolS
*) xmalloc (sizeof (label_symbolS
));
541 lssP
->lss_label
= symbolP
;
542 lssP
->lss_space
= now_sdcP
;
543 lssP
->lss_next
= (label_symbolS
*) NULL
;
545 if (label_symbols_rootP
)
547 lssP
->lss_next
= label_symbols_rootP
;
549 label_symbols_rootP
= lssP
;
556 Removes a label definition for the current space.
557 If there is no label_symbolS entry, then no action is taken.
564 label_symbolS
*prevP
= (label_symbolS
*) NULL
;
565 space_dict_chainS
*now_sdcP
= pa_segment_to_space (now_seg
);
567 for (lssP
= label_symbols_rootP
; lssP
; lssP
= lssP
->lss_next
)
569 if (now_sdcP
== lssP
->lss_space
&& lssP
->lss_label
)
572 prevP
->lss_next
= lssP
->lss_next
;
574 label_symbols_rootP
= lssP
->lss_next
;
583 /* end of label symbol support. */
586 /* An HPPA-specific version of fix_new. This is required because the HPPA */
587 /* code needs to keep track of some extra stuff. Each call to fix_new_hppa */
588 /* results in the creation of an instance of an hppa_fixS. An hppa_fixS */
589 /* stores the extra information along with a pointer to the original fixS. */
591 typedef struct hppa_fix_struct
598 call_infoS
*fx_call_infop
;
600 struct hppa_fix_struct
*fx_next
;
603 hppa_fixS
*hppa_fix_root
= NULL
;
606 fix_new_hppa (frag
, where
, size
, add_symbol
, sub_symbol
, offset
, pcrel
,
607 r_type
, r_field
, r_format
, arg_reloc
, unwind_desc
)
608 fragS
*frag
; /* Which frag? */
609 int where
; /* Where in that frag? */
610 short int size
; /* 1, 2 or 4 usually. */
611 symbolS
*add_symbol
; /* X_add_symbol. */
612 symbolS
*sub_symbol
; /* X_subtract_symbol. */
613 long offset
; /* X_add_number. */
614 int pcrel
; /* TRUE if PC-relative relocation. */
616 bfd_reloc_code_real_type r_type
; /* Relocation type */
618 int r_type
; /* Relocation type */
620 long r_field
; /* F, R, L, etc */
621 int r_format
; /* 11,12,14,17,21,32, etc */
625 fixS
*new_fix
= fix_new (frag
, where
, size
,
626 add_symbol
, sub_symbol
,
627 offset
, pcrel
, r_type
);
629 hppa_fixS
*hppa_fix
= (hppa_fixS
*) obstack_alloc (¬es
, sizeof (hppa_fixS
));
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
693 exp
->X_subtract_symbol
,
694 exp
->X_add_number
, 0, reloc_type
,
695 hppa_field_selector
, 32, 0, (char *) 0);
698 /* Given a FixS, find the hppa_fixS associated with it. */
700 hppa_find_hppa_fix (fix
)
705 for (hfP
= hppa_fix_root
; hfP
; hfP
= hfP
->fx_next
)
707 if (hfP
->fx_fixP
== fix
)
711 return (hppa_fixS
*) 0;
714 /* This function is called once, at assembler startup time. It should
715 set up all the tables, etc. that the MD part of the assembler will need. */
719 register char *retval
= NULL
;
721 register unsigned int i
= 0;
722 void pa_spaces_begin (); /* forward declaration */
724 last_call_info
= NULL
;
725 call_info_root
= NULL
;
729 op_hash
= hash_new ();
731 as_fatal ("Virtual memory exhausted");
733 while (i
< NUMOPCODES
)
735 const char *name
= pa_opcodes
[i
].name
;
736 retval
= hash_insert (op_hash
, name
, &pa_opcodes
[i
]);
737 if (retval
!= NULL
&& *retval
!= '\0')
739 as_fatal ("Internal error: can't hash `%s': %s\n",
740 pa_opcodes
[i
].name
, retval
);
745 if ((pa_opcodes
[i
].match
& pa_opcodes
[i
].mask
) != pa_opcodes
[i
].match
)
747 fprintf (stderr
, "internal error: losing opcode: `%s' \"%s\"\n",
748 pa_opcodes
[i
].name
, pa_opcodes
[i
].args
);
753 while (i
< NUMOPCODES
754 && !strcmp (pa_opcodes
[i
].name
, name
));
758 as_fatal ("Broken assembler. No assembly attempted.");
760 for (i
= '0'; i
< '8'; ++i
)
762 for (i
= '0'; i
<= '9'; ++i
)
764 for (i
= 'a'; i
<= 'f'; ++i
)
765 toHex
[i
] = i
+ 10 - 'a';
766 for (i
= 'A'; i
<= 'F'; ++i
)
767 toHex
[i
] = i
+ 10 - 'A';
786 /* put out the opcode */
787 md_number_to_chars (toP
, the_insn
.opcode
, 4);
789 /* put out the symbol-dependent stuff */
790 #if defined ( OBJ_SOM )
791 if (the_insn
.reloc
!= R_NO_RELOCATION
)
794 #if defined ( OBJ_ELF )
795 if (the_insn
.reloc
!= R_HPPA_NONE
)
801 fix_new_hppa (frag_now
, /* which frag */
802 (toP
- frag_now
->fr_literal
), /* where */
804 the_insn
.exp
.X_add_symbol
,
805 the_insn
.exp
.X_subtract_symbol
,
806 the_insn
.exp
.X_add_number
,
809 the_insn
.field_selector
,
815 fix_new (frag_now
, /* which frag */
816 (toP
- frag_now
->fr_literal
), /* where */
818 the_insn
.exp
.X_add_symbol
,
819 the_insn
.exp
.X_subtract_symbol
,
820 the_insn
.exp
.X_add_number
,
823 the_insn
.field_selector
,
830 /* SKV 12/22/92. Added prev_insn, prev_fix, and initialized the_insn
831 so that we can recognize instruction sequences such as (ldil, ble)
832 and generate the appropriate fixups. */
836 prev_insn
= the_insn
;
837 strncpy (prev_str
, str
, 10);
838 if (prev_insn
.reloc
= R_HPPA_NONE
)
854 char *error_message
= "";
859 struct pa_opcode
*insn
;
861 unsigned long opcode
;
866 int reg
, reg1
, reg2
, s2
, s3
;
867 unsigned int im21
, im14
, im11
, im5
;
869 int cmpltr
, nullif
, flag
;
875 fprintf (stderr
, "STATEMENT: \"%s\"\n", str
);
877 for (s
= str
; isupper (*s
) || islower (*s
) || (*s
>= '0' && *s
<= '3'); ++s
)
895 as_bad ("Unknown opcode: `%s'", str
);
903 if (isupper (*save_s
))
904 *save_s
= tolower (*save_s
);
908 if ((insn
= (struct pa_opcode
*) hash_find (op_hash
, str
)) == NULL
)
910 as_bad ("Unknown opcode: `%s'", str
);
920 opcode
= insn
->match
;
921 bzero (&the_insn
, sizeof (the_insn
));
922 #if defined( OBJ_SOM )
923 the_insn
.reloc
= R_NO_RELOCATION
;
925 #if defined ( OBJ_ELF )
926 the_insn
.reloc
= R_HPPA_NONE
;
930 * Build the opcode, checking as we go to make
931 * sure that the operands match
933 for (args
= insn
->args
;; ++args
)
939 case '\0': /* end of args */
958 case '(': /* these must match exactly */
966 case 'b': /* 5 bit register field at 10 */
967 case '^': /* 5 bit control register field at 10 */
968 reg
= pa_parse_number (&s
);
969 if (reg
< 32 && reg
>= 0)
975 case 'x': /* 5 bit register field at 15 */
976 reg
= pa_parse_number (&s
);
977 if (reg
< 32 && reg
>= 0)
983 case 't': /* 5 bit register field at 31 */
984 reg
= pa_parse_number (&s
);
985 if (reg
< 32 && reg
>= 0)
991 case 'T': /* 5 bit field length at 31 (encoded as 32-T) */
993 reg = pa_parse_number(&s);
995 getAbsoluteExpression (s
);
996 if (the_insn
.exp
.X_seg
== &bfd_abs_section
)
998 reg
= the_insn
.exp
.X_add_number
;
999 if (reg
<= 32 && reg
> 0)
1007 case '5': /* 5 bit immediate at 15 */
1008 getAbsoluteExpression (s
);
1009 /** PJH: The following 2 calls to as_bad() might eventually **/
1010 /** want to end up as as_warn(). **/
1011 if (the_insn
.exp
.X_add_number
> 15)
1013 as_bad ("5 bit immediate > 15. Set to 15",
1014 the_insn
.exp
.X_add_number
);
1015 the_insn
.exp
.X_add_number
= 15;
1017 else if (the_insn
.exp
.X_add_number
< -16)
1019 as_bad ("5 bit immediate < -16. Set to -16",
1020 the_insn
.exp
.X_add_number
);
1021 the_insn
.exp
.X_add_number
= -16;
1024 low_sign_unext (evaluateAbsolute (the_insn
.exp
, the_insn
.field_selector
),
1026 opcode
|= (im5
<< 16);
1030 case 's': /* 2 bit space identifier at 17 */
1031 s2
= pa_parse_number (&s
);
1032 if (s2
< 4 && s2
>= 0)
1038 case 'S': /* 3 bit space identifier at 18 */
1039 s3
= pa_parse_number (&s
);
1040 if (s3
< 8 && s3
>= 0)
1042 dis_assemble_3 (s3
, &s3
);
1047 case 'c': /* indexed load completer. */
1051 while (*s
== ',' && i
< 2)
1054 if (strncasecmp (s
, "sm", 2) == 0)
1061 else if (strncasecmp (s
, "m", 1) == 0)
1063 else if (strncasecmp (s
, "s", 1) == 0)
1066 as_bad ("Unrecognized Indexed Load Completer...assuming 0");
1071 as_bad ("Illegal Indexed Load Completer Syntax...extras ignored");
1073 while (*s
== ' ' || *s
== '\t')
1079 case 'C': /* short load and store completer */
1085 if (strncasecmp (s
, "ma", 2) == 0)
1090 else if (strncasecmp (s
, "mb", 2) == 0)
1096 as_bad ("Unrecognized Indexed Load Completer...assuming 0");
1100 while (*s
== ' ' || *s
== '\t')
1105 case 'Y': /* Store Bytes Short completer */
1109 while (*s
== ',' && i
< 2)
1112 if (strncasecmp (s
, "m", 1) == 0)
1114 else if (strncasecmp (s
, "b", 1) == 0)
1116 else if (strncasecmp (s
, "e", 1) == 0)
1119 as_bad ("Unrecognized Store Bytes Short Completer...assuming 0");
1123 /** if ( i >= 2 ) **/
1125 as_bad ("Illegal Store Bytes Short Completer...extras ignored");
1126 while (*s
== ' ' || *s
== '\t') /* skip to next operand */
1131 case '<': /* non-negated compare/subtract conditions. */
1132 cmpltr
= pa_parse_nonneg_cmpsub_cmpltr (&s
);
1135 as_bad ("Unrecognized Compare/Subtract Condition: %c", *s
);
1138 opcode
|= cmpltr
<< 13;
1140 case '?': /* negated or non-negated cmp/sub conditions. */
1141 /* used only by ``comb'' and ``comib'' pseudo-ops */
1143 cmpltr
= pa_parse_nonneg_cmpsub_cmpltr (&s
);
1147 cmpltr
= pa_parse_neg_cmpsub_cmpltr (&s
);
1150 as_bad ("Unrecognized Compare/Subtract Condition: %c", *s
);
1155 opcode
|= 1 << 27; /* required opcode change to make
1156 COMIBT into a COMIBF or a
1157 COMBT into a COMBF or a
1158 ADDBT into a ADDBF or a
1159 ADDIBT into a ADDIBF */
1162 opcode
|= cmpltr
<< 13;
1164 case '!': /* negated or non-negated add conditions. */
1165 /* used only by ``addb'' and ``addib'' pseudo-ops */
1167 cmpltr
= pa_parse_nonneg_add_cmpltr (&s
);
1171 cmpltr
= pa_parse_neg_add_cmpltr (&s
);
1174 as_bad ("Unrecognized Compare/Subtract Condition: %c", *s
);
1179 opcode
|= 1 << 27; /* required opcode change to make
1180 COMIBT into a COMIBF or a
1181 COMBT into a COMBF or a
1182 ADDBT into a ADDBF or a
1183 ADDIBT into a ADDIBF */
1186 opcode
|= cmpltr
<< 13;
1188 case 'a': /* compare/subtract conditions */
1194 cmpltr
= pa_parse_nonneg_cmpsub_cmpltr (&s
);
1199 cmpltr
= pa_parse_neg_cmpsub_cmpltr (&s
);
1202 as_bad ("Unrecognized Compare/Subtract Condition");
1206 opcode
|= cmpltr
<< 13;
1209 case 'd': /* non-negated add conditions */
1217 while (*s
!= ',' && *s
!= ' ' && *s
!= '\t')
1221 if (strcmp (name
, "=") == 0)
1225 else if (strcmp (name
, "<") == 0)
1229 else if (strcmp (name
, "<=") == 0)
1233 else if (strcasecmp (name
, "nuv") == 0)
1237 else if (strcasecmp (name
, "znv") == 0)
1241 else if (strcasecmp (name
, "sv") == 0)
1245 else if (strcasecmp (name
, "od") == 0)
1249 else if (strcasecmp (name
, "n") == 0)
1253 else if (strcasecmp (name
, "tr") == 0)
1258 else if (strcasecmp (name
, "<>") == 0)
1263 else if (strcasecmp (name
, ">=") == 0)
1268 else if (strcasecmp (name
, ">") == 0)
1273 else if (strcasecmp (name
, "uv") == 0)
1278 else if (strcasecmp (name
, "vnz") == 0)
1283 else if (strcasecmp (name
, "nsv") == 0)
1288 else if (strcasecmp (name
, "ev") == 0)
1294 as_bad ("Unrecognized Add Condition: %s", name
);
1297 nullif
= pa_parse_nullif (&s
);
1298 opcode
|= nullif
<< 1;
1299 opcode
|= cmpltr
<< 13;
1300 opcode
|= flag
<< 12;
1302 case '&': /* logical instruction conditions */
1309 while (*s
!= ',' && *s
!= ' ' && *s
!= '\t')
1313 if (strcmp (name
, "=") == 0)
1317 else if (strcmp (name
, "<") == 0)
1321 else if (strcmp (name
, "<=") == 0)
1325 else if (strcasecmp (name
, "od") == 0)
1329 else if (strcasecmp (name
, "tr") == 0)
1334 else if (strcmp (name
, "<>") == 0)
1339 else if (strcmp (name
, ">=") == 0)
1344 else if (strcmp (name
, ">") == 0)
1349 else if (strcasecmp (name
, "ev") == 0)
1355 as_bad ("Unrecognized Logical Instruction Condition: %s", name
);
1358 opcode
|= cmpltr
<< 13;
1361 case 'U': /* unit instruction conditions */
1367 if (strncasecmp (s
, "sbz", 3) == 0)
1372 else if (strncasecmp (s
, "shz", 3) == 0)
1377 else if (strncasecmp (s
, "sdc", 3) == 0)
1382 else if (strncasecmp (s
, "sbc", 3) == 0)
1387 else if (strncasecmp (s
, "shc", 3) == 0)
1392 else if (strncasecmp (s
, "tr", 2) == 0)
1398 else if (strncasecmp (s
, "nbz", 3) == 0)
1404 else if (strncasecmp (s
, "nhz", 3) == 0)
1410 else if (strncasecmp (s
, "ndc", 3) == 0)
1416 else if (strncasecmp (s
, "nbc", 3) == 0)
1422 else if (strncasecmp (s
, "nhc", 3) == 0)
1429 as_bad ("Unrecognized Logical Instruction Condition: %c", *s
);
1431 opcode
|= cmpltr
<< 13;
1434 case '>': /* shift/extract/deposit conditions. */
1440 while (*s
!= ',' && *s
!= ' ' && *s
!= '\t')
1444 if (strcmp (name
, "=") == 0)
1448 else if (strcmp (name
, "<") == 0)
1452 else if (strcasecmp (name
, "od") == 0)
1456 else if (strcasecmp (name
, "tr") == 0)
1460 else if (strcmp (name
, "<>") == 0)
1464 else if (strcmp (name
, ">=") == 0)
1468 else if (strcasecmp (name
, "ev") == 0)
1473 as_bad ("Unrecognized Shift/Extract/Deposit Condition: %s", name
);
1476 opcode
|= cmpltr
<< 13;
1478 case '~': /* bvb,bb conditions */
1483 if (strncmp (s
, "<", 1) == 0)
1488 else if (strncmp (s
, ">=", 2) == 0)
1494 as_bad ("Unrecognized Bit Branch Condition: %c", *s
);
1496 opcode
|= cmpltr
<< 13;
1498 case 'V': /* 5 bit immediate at 31 */
1500 low_sign_unext (evaluateAbsolute (the_insn
.exp
, the_insn
.field_selector
),
1505 case 'r': /* 5 bit immediate at 31 */
1506 /* (unsigned value for the break instruction) */
1508 im5
= evaluateAbsolute (the_insn
.exp
, the_insn
.field_selector
);
1509 if (im5
> 31 || im5
< 0)
1511 as_bad ("Operand out of range. Was: %d. Should be [0..31]. Assuming %d.\n", im5
, im5
& 0x1f);
1517 case 'R': /* 5 bit immediate at 15 */
1518 /* (unsigned value for the ssm and rsm instruction) */
1520 im5
= evaluateAbsolute (the_insn
.exp
, the_insn
.field_selector
);
1521 if (im5
> 31 || im5
< 0)
1523 as_bad ("Operand out of range. Was: %d. Should be [0..31]. Assuming %d.\n", im5
, im5
& 0x1f);
1526 opcode
|= im5
<< 16;
1529 case 'i': /* 11 bit immediate at 31 */
1532 if (the_insn
.exp
.X_seg
== &bfd_abs_section
)
1534 low_sign_unext (evaluateAbsolute (the_insn
.exp
, the_insn
.field_selector
),
1540 the_insn
.reloc
= R_CODE_ONE_SYMBOL
;
1541 the_insn
.code
= 'i';
1542 the_insn
.field_selector
= the_insn
.exp
.field_selector
;
1547 the_insn
.field_selector
= pa_chk_field_selector (&s
);
1549 if (the_insn
.exp
.X_seg
== &bfd_abs_section
)
1551 low_sign_unext (evaluateAbsolute (the_insn
.exp
, the_insn
.field_selector
),
1557 if (is_DP_relative (the_insn
.exp
))
1558 the_insn
.reloc
= R_HPPA_GOTOFF
;
1559 else if (is_PC_relative (the_insn
.exp
))
1560 the_insn
.reloc
= R_HPPA_PCREL_CALL
;
1561 else if (is_complex (the_insn
.exp
))
1562 the_insn
.reloc
= R_HPPA_COMPLEX
;
1564 the_insn
.reloc
= R_HPPA
;
1565 the_insn
.format
= 11;
1570 case 'j': /* 14 bit immediate at 31 */
1573 if (the_insn
.exp
.X_seg
== &bfd_abs_section
)
1575 low_sign_unext (evaluateAbsolute (the_insn
.exp
, field_selector
),
1577 if (the_insn
.exp
.field_selector
== e_rsel
)
1578 opcode
|= (im14
& 0xfff);
1584 the_insn
.reloc
= R_CODE_ONE_SYMBOL
;
1585 the_insn
.code
= 'j';
1586 the_insn
.field_selector
= the_insn
.exp
.field_selector
;
1591 the_insn
.field_selector
= pa_chk_field_selector (&s
);
1593 if (the_insn
.exp
.X_seg
== &bfd_abs_section
)
1595 low_sign_unext (evaluateAbsolute (the_insn
.exp
, the_insn
.field_selector
),
1597 if (the_insn
.field_selector
== e_rsel
)
1598 opcode
|= (im14
& 0xfff);
1604 if (is_DP_relative (the_insn
.exp
))
1605 the_insn
.reloc
= R_HPPA_GOTOFF
;
1606 else if (is_PC_relative (the_insn
.exp
))
1607 the_insn
.reloc
= R_HPPA_PCREL_CALL
;
1608 else if (is_complex (the_insn
.exp
))
1609 the_insn
.reloc
= R_HPPA_COMPLEX
;
1611 the_insn
.reloc
= R_HPPA
;
1612 the_insn
.format
= 14;
1618 case 'k': /* 21 bit immediate at 31 */
1621 if (the_insn
.exp
.X_seg
== &bfd_abs_section
)
1623 dis_assemble_21 (evaluateAbsolute (the_insn
.exp
, the_insn
.field_selector
),
1629 the_insn
.reloc
= R_CODE_ONE_SYMBOL
;
1630 the_insn
.code
= 'k';
1631 the_insn
.field_selector
= the_insn
.exp
.field_selector
;
1636 the_insn
.field_selector
= pa_chk_field_selector (&s
);
1638 if (the_insn
.exp
.X_seg
== &bfd_abs_section
)
1640 dis_assemble_21 (evaluateAbsolute (the_insn
.exp
, the_insn
.field_selector
),
1646 if (is_DP_relative (the_insn
.exp
))
1647 the_insn
.reloc
= R_HPPA_GOTOFF
;
1648 else if (is_PC_relative (the_insn
.exp
))
1649 the_insn
.reloc
= R_HPPA_PCREL_CALL
;
1650 else if (is_complex (the_insn
.exp
))
1651 the_insn
.reloc
= R_HPPA_COMPLEX
;
1653 the_insn
.reloc
= R_HPPA
;
1654 the_insn
.format
= 21;
1660 case 'n': /* nullification for branch instructions */
1661 nullif
= pa_parse_nullif (&s
);
1662 opcode
|= nullif
<< 1;
1664 case 'w': /* 12 bit branch displacement */
1668 if (strcmp (the_insn
.exp
.X_add_symbol
->sy_nlist
.n_un
.n_name
, "L0\001") == 0)
1670 unsigned int w1
, w
, result
;
1672 sign_unext ((the_insn
.exp
.X_add_number
- 8) >> 2, 12, &result
);
1673 dis_assemble_12 (result
, &w1
, &w
);
1674 opcode
|= ((w1
<< 2) | w
);
1675 the_insn
.exp
.X_add_symbol
->sy_ref
= FALSE
;
1679 /* this has to be wrong -- dont know what is right! */
1680 the_insn
.reloc
= R_PCREL_CALL
;
1681 the_insn
.code
= 'w';
1682 the_insn
.field_selector
= the_insn
.exp
.field_selector
;
1683 the_insn
.arg_reloc
= last_call_desc
.arg_reloc
;
1684 bzero (&last_call_desc
, sizeof (call_descS
));
1689 the_insn
.field_selector
= pa_chk_field_selector (&s
);
1692 if (strcmp (S_GET_NAME (the_insn
.exp
.X_add_symbol
), "L0\001") == 0)
1694 unsigned int w1
, w
, result
;
1696 sign_unext ((the_insn
.exp
.X_add_number
- 8) >> 2, 12, &result
);
1697 dis_assemble_12 (result
, &w1
, &w
);
1698 opcode
|= ((w1
<< 2) | w
);
1699 /* the_insn.exp.X_add_symbol->sy_ref = FALSE; *//* XXX: not sure how to do this in BFD */
1703 if (is_complex (the_insn
.exp
))
1704 the_insn
.reloc
= R_HPPA_COMPLEX_PCREL_CALL
;
1706 the_insn
.reloc
= R_HPPA_PCREL_CALL
;
1707 the_insn
.format
= 12;
1708 the_insn
.arg_reloc
= last_call_desc
.arg_reloc
;
1709 bzero (&last_call_desc
, sizeof (call_descS
));
1714 case 'W': /* 17 bit branch displacement */
1715 #if defined(OBJ_ELF)
1716 the_insn
.field_selector
= pa_chk_field_selector (&s
);
1721 if (strcmp (the_insn
.exp
.X_add_symbol
->sy_nlist
.n_un
.n_name
, "L0\001") == 0)
1723 unsigned int w2
, w1
, w
, result
;
1725 sign_unext ((the_insn
.exp
.X_add_number
- 8) >> 2, 17, &result
);
1726 dis_assemble_17 (result
, &w1
, &w2
, &w
);
1727 opcode
|= ((w2
<< 2) | (w1
<< 16) | w
);
1728 the_insn
.exp
.X_add_symbol
->sy_ref
= FALSE
;
1732 /* this has to be wrong -- dont know what is right! */
1733 the_insn
.reloc
= R_PCREL_CALL
;
1734 the_insn
.code
= 'W';
1735 the_insn
.field_selector
= the_insn
.exp
.field_selector
;
1736 the_insn
.arg_reloc
= last_call_desc
.arg_reloc
;
1737 bzero (&last_call_desc
, sizeof (call_descS
));
1740 if (the_insn
.exp
.X_add_symbol
)
1742 if (strcmp (S_GET_NAME (the_insn
.exp
.X_add_symbol
), "L0\001") == 0)
1744 unsigned int w2
, w1
, w
, result
;
1746 sign_unext ((the_insn
.exp
.X_add_number
- 8) >> 2, 17, &result
);
1747 dis_assemble_17 (result
, &w1
, &w2
, &w
);
1748 opcode
|= ((w2
<< 2) | (w1
<< 16) | w
);
1752 if (is_complex (the_insn
.exp
))
1753 the_insn
.reloc
= R_HPPA_COMPLEX_PCREL_CALL
;
1755 the_insn
.reloc
= R_HPPA_PCREL_CALL
;
1756 the_insn
.format
= 17;
1757 the_insn
.arg_reloc
= last_call_desc
.arg_reloc
;
1758 bzero (&last_call_desc
, sizeof (call_descS
));
1763 unsigned int w2
, w1
, w
, result
;
1765 sign_unext (the_insn
.exp
.X_add_number
>> 2, 17, &result
);
1766 dis_assemble_17 (result
, &w1
, &w2
, &w
);
1767 opcode
|= ((w2
<< 2) | (w1
<< 16) | w
);
1772 case 'z': /* 17 bit branch displacement (not pc-relative) */
1773 #if defined(OBJ_ELF)
1774 the_insn
.field_selector
= pa_chk_field_selector (&s
);
1779 if (strcmp (the_insn
.exp
.X_add_symbol
->sy_nlist
.n_un
.n_name
, "L0\001") == 0)
1781 unsigned int w2
, w1
, w
, result
;
1783 sign_unext ((the_insn
.exp
.X_add_number
- 8) >> 2, 17, &result
);
1784 dis_assemble_17 (result
, &w1
, &w2
, &w
);
1785 opcode
|= ((w2
<< 2) | (w1
<< 16) | w
);
1786 the_insn
.exp
.X_add_symbol
->sy_ref
= FALSE
;
1790 /* this has to be wrong -- dont know what is right! */
1791 the_insn
.reloc
= R_PCREL_CALL
;
1792 the_insn
.code
= 'W';
1793 the_insn
.field_selector
= the_insn
.exp
.field_selector
;
1794 the_insn
.arg_reloc
= last_call_desc
.arg_reloc
;
1795 bzero (&last_call_desc
, sizeof (call_descS
));
1798 if (the_insn
.exp
.X_add_symbol
)
1800 if (strcmp (S_GET_NAME (the_insn
.exp
.X_add_symbol
), "L0\001") == 0)
1802 unsigned int w2
, w1
, w
, result
;
1804 sign_unext ((the_insn
.exp
.X_add_number
- 8) >> 2, 17, &result
);
1805 dis_assemble_17 (result
, &w1
, &w2
, &w
);
1806 opcode
|= ((w2
<< 2) | (w1
<< 16) | w
);
1810 if (is_complex (the_insn
.exp
))
1812 the_insn
.reloc
= R_HPPA_COMPLEX_ABS_CALL
;
1816 the_insn
.reloc
= R_HPPA_ABS_CALL
;
1818 /* This could also be part of an instruction sequence of
1819 interest. If so, check to make sure that the previous
1820 instruction's fixup is appropriate. (ble, be instructions
1821 affect the reloc of immediately preceding ldil
1823 if (strcasecmp (prev_str
, "ldil") == 0 &&
1824 prev_insn
.exp
.X_add_symbol
== the_insn
.exp
.X_add_symbol
&&
1825 prev_insn
.exp
.X_subtract_symbol
== the_insn
.exp
.X_subtract_symbol
&&
1826 prev_insn
.exp
.X_seg
== the_insn
.exp
.X_seg
&&
1827 prev_insn
.exp
.X_add_number
== the_insn
.exp
.X_add_number
&&
1829 prev_fix
->fx_r_type
= the_insn
.reloc
;
1831 the_insn
.format
= 17;
1832 the_insn
.arg_reloc
= last_call_desc
.arg_reloc
;
1833 bzero (&last_call_desc
, sizeof (call_descS
));
1838 unsigned int w2
, w1
, w
, result
;
1840 sign_unext (the_insn
.exp
.X_add_number
>> 2, 17, &result
);
1841 dis_assemble_17 (result
, &w1
, &w2
, &w
);
1842 opcode
|= ((w2
<< 2) | (w1
<< 16) | w
);
1847 case 'p': /* 5 bit shift count at 26 (to support SHD instr.) */
1848 /* value is encoded in instr. as 31-p where p is */
1849 /* the value scanned here */
1851 if (the_insn
.exp
.X_seg
== &bfd_abs_section
)
1853 opcode
|= (((31 - the_insn
.exp
.X_add_number
) & 0x1f) << 5);
1857 case 'P': /* 5-bit bit position at 26 */
1859 if (the_insn
.exp
.X_seg
== &bfd_abs_section
)
1861 opcode
|= (the_insn
.exp
.X_add_number
& 0x1f) << 5;
1865 case 'Q': /* 5 bit immediate at 10 */
1866 /* (unsigned bit position value for the bb instruction) */
1868 im5
= evaluateAbsolute (the_insn
.exp
, the_insn
.field_selector
);
1869 if (im5
> 31 || im5
< 0)
1871 as_bad ("Operand out of range. Was: %d. Should be [0..31]. Assuming %d.\n", im5
, im5
& 0x1f);
1874 opcode
|= im5
<< 21;
1877 case 'A': /* 13 bit immediate at 18 (to support BREAK instr.) */
1878 getAbsoluteExpression (s
);
1879 if (the_insn
.exp
.X_seg
== &bfd_abs_section
)
1880 opcode
|= (the_insn
.exp
.X_add_number
& 0x1fff) << 13;
1883 case 'Z': /* System Control Completer(for LDA, LHA, etc.) */
1884 if (*s
== ',' && (*(s
+ 1) == 'm' || *(s
+ 1) == 'M'))
1893 while (*s
== ' ' || *s
== '\t') /* skip to next operand */
1897 case 'D': /* 26 bit immediate at 31 (to support DIAG instr.) */
1898 /* the action (and interpretation of this operand is
1899 implementation dependent) */
1900 #if defined(OBJ_ELF)
1901 the_insn
.field_selector
= pa_chk_field_selector (&s
);
1904 if (the_insn
.exp
.X_seg
== &bfd_abs_section
)
1906 opcode
|= ((evaluateAbsolute (the_insn
.exp
, the_insn
.field_selector
) & 0x1ffffff) << 1);
1907 #ifdef NEW_SOM /* XXX what replaces this? */
1908 /* PJH: VERY unsure about the following */
1909 the_insn
.field_selector
= the_insn
.exp
.field_selector
;
1913 as_bad ("Illegal DIAG operand");
1916 case 'f': /* 3 bit Special Function Unit (SFU) identifier at 25 */
1917 sfu
= pa_parse_number (&s
);
1918 if ((sfu
> 7) || (sfu
< 0))
1919 as_bad ("Illegal SFU identifier: %02x", sfu
);
1920 opcode
|= (sfu
& 7) << 6;
1922 case 'O': /* 20 bit SFU op. split between 15 bits at 20
1927 case 'o': /* 15 bit Special Function Unit operation at 20 */
1931 case '2': /* 22 bit SFU op. split between 17 bits at 20
1936 case '1': /* 15 bit SFU op. split between 10 bits at 20
1941 case '0': /* 10 bit SFU op. split between 5 bits at 20
1946 case 'u': /* 3 bit coprocessor unit identifier at 25 */
1950 case 'F': /* Source FP Operand Format Completer (2 bits at 20) */
1951 f
= pa_parse_fp_format (&s
);
1952 opcode
|= (int) f
<< 11;
1955 case 'G': /* Destination FP Operand Format Completer (2 bits at 18) */
1956 s
--; /* need to pass the previous comma to pa_parse_fp_format */
1957 f
= pa_parse_fp_format (&s
);
1958 opcode
|= (int) f
<< 13;
1961 case 'M': /* FP Compare Conditions (encoded as 5 bits at 31) */
1962 cond
= pa_parse_fp_cmp_cond (&s
);
1966 case 'v': /* a 't' type extended to handle L/R register halves. */
1968 struct pa_89_fp_reg_struct result
;
1971 pa_89_parse_number (&s
, &result
);
1972 if (result
.number_part
< 32 && result
.number_part
>= 0)
1974 opcode
|= (result
.number_part
& 0x1f);
1976 /* 0x30 opcodes are FP arithmetic operation opcodes */
1977 /* load/store FP opcodes do not get converted to 0x38 */
1978 /* opcodes like the 0x30 opcodes do */
1979 if (need_89_opcode (&the_insn
, &result
))
1981 if ((opcode
& 0xfc000000) == 0x30000000)
1983 opcode
|= (result
.L_R_select
& 1) << 6;
1988 opcode
|= (result
.L_R_select
& 1) << 6;
1995 case 'E': /* a 'b' type extended to handle L/R register halves. */
1997 struct pa_89_fp_reg_struct result
;
2000 pa_89_parse_number (&s
, &result
);
2001 if (result
.number_part
< 32 && result
.number_part
>= 0)
2003 opcode
|= (result
.number_part
& 0x1f) << 21;
2004 if (need_89_opcode (&the_insn
, &result
))
2006 opcode
|= (result
.L_R_select
& 1) << 7;
2014 case 'X': /* an 'x' type extended to handle L/R register halves. */
2016 struct pa_89_fp_reg_struct result
;
2020 pa_89_parse_number (&s
, &result
);
2021 if (result
.number_part
< 32 && result
.number_part
>= 0)
2023 opcode
|= (result
.number_part
& 0x1f) << 16;
2024 if (need_89_opcode (&the_insn
, &result
))
2026 opcode
|= (result
.L_R_select
& 1) << 12;
2034 case '4': /* 5 bit register field at 10
2035 (used in 'fmpyadd' and 'fmpysub') */
2037 struct pa_89_fp_reg_struct result
;
2040 status
= pa_89_parse_number (&s
, &result
);
2041 if (result
.number_part
< 32 && result
.number_part
>= 0)
2043 if (the_insn
.fpof1
== SGL
)
2045 result
.number_part
&= 0xF;
2046 result
.number_part
|= (result
.L_R_select
& 1) << 4;
2048 opcode
|= result
.number_part
<< 21;
2054 case '6': /* 5 bit register field at 15
2055 (used in 'fmpyadd' and 'fmpysub') */
2057 struct pa_89_fp_reg_struct result
;
2060 status
= pa_89_parse_number (&s
, &result
);
2061 if (result
.number_part
< 32 && result
.number_part
>= 0)
2063 if (the_insn
.fpof1
== SGL
)
2065 result
.number_part
&= 0xF;
2066 result
.number_part
|= (result
.L_R_select
& 1) << 4;
2068 opcode
|= result
.number_part
<< 16;
2074 case '7': /* 5 bit register field at 31
2075 (used in 'fmpyadd' and 'fmpysub') */
2077 struct pa_89_fp_reg_struct result
;
2080 status
= pa_89_parse_number (&s
, &result
);
2081 if (result
.number_part
< 32 && result
.number_part
>= 0)
2083 if (the_insn
.fpof1
== SGL
)
2085 result
.number_part
&= 0xF;
2086 result
.number_part
|= (result
.L_R_select
& 1) << 4;
2088 opcode
|= result
.number_part
;
2094 case '8': /* 5 bit register field at 20
2095 (used in 'fmpyadd' and 'fmpysub') */
2097 struct pa_89_fp_reg_struct result
;
2100 status
= pa_89_parse_number (&s
, &result
);
2101 if (result
.number_part
< 32 && result
.number_part
>= 0)
2103 if (the_insn
.fpof1
== SGL
)
2105 result
.number_part
&= 0xF;
2106 result
.number_part
|= (result
.L_R_select
& 1) << 4;
2108 opcode
|= result
.number_part
<< 11;
2114 case '9': /* 5 bit register field at 25
2115 (used in 'fmpyadd' and 'fmpysub') */
2117 struct pa_89_fp_reg_struct result
;
2120 status
= pa_89_parse_number (&s
, &result
);
2121 if (result
.number_part
< 32 && result
.number_part
>= 0)
2123 if (the_insn
.fpof1
== SGL
)
2125 result
.number_part
&= 0xF;
2126 result
.number_part
|= (result
.L_R_select
& 1) << 4;
2128 opcode
|= result
.number_part
<< 6;
2134 case 'H': /* Floating Point Operand Format at 26 for */
2135 /* 'fmpyadd' and 'fmpysub' (very similar to 'F') */
2136 /* bits are switched from other FP Operand */
2137 /* formats. 1=SGL, 1=<none>, 0=DBL */
2138 f
= pa_parse_fp_format (&s
);
2150 as_bad ("Illegal Floating Point Operand Format for this instruction: '%s'", *s
);
2162 /* Args don't match. */
2163 if (&insn
[1] - pa_opcodes
< NUMOPCODES
2164 && !strcmp (insn
->name
, insn
[1].name
))
2172 as_bad ("Illegal operands %s", error_message
);
2179 the_insn
.opcode
= opcode
;
2182 if (the_insn
.exp
.X_add_symbol
&& the_insn
.exp
.X_subtract_symbol
)
2183 print_insn_short (&the_insn
);
2184 fprintf (stderr
, "*********** END OF STATEMENT\n");
2191 This is identical to the md_atof in m68k.c. I think this is right,
2194 Turn a string in input_line_pointer into a floating point constant of type
2195 type, and store the appropriate bytes in *litP. The number of LITTLENUMS
2196 emitted is stored in *sizeP . An error message is returned, or NULL on OK.
2199 /* Equal to MAX_PRECISION in atof-ieee.c */
2200 #define MAX_LITTLENUMS 6
2203 md_atof (type
, litP
, sizeP
)
2209 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
2210 LITTLENUM_TYPE
*wordP
;
2243 return "Bad call to MD_ATOF()";
2245 t
= atof_ieee (input_line_pointer
, type
, words
);
2247 input_line_pointer
= t
;
2248 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
2249 for (wordP
= words
; prec
--;)
2251 md_number_to_chars (litP
, (long) (*wordP
++), sizeof (LITTLENUM_TYPE
));
2252 litP
+= sizeof (LITTLENUM_TYPE
);
2254 return ""; /* Someone should teach Dean about null pointers */
2258 * Write out big-endian.
2261 md_number_to_chars (buf
, val
, n
)
2286 md_create_short_jump (ptr
, from_addr
, to_addr
, frag
, to_symbol
)
2288 addressT from_addr
, to_addr
;
2292 fprintf (stderr
, "pa_create_short_jmp\n");
2297 md_number_to_disp (buf
, val
, n
)
2302 fprintf (stderr
, "md_number_to_disp\n");
2307 md_number_to_field (buf
, val
, fix
)
2312 fprintf (stderr
, "pa_number_to_field\n");
2316 /* the bit-field entries in the relocation_info struct plays hell
2317 with the byte-order problems of cross-assembly. So as a hack,
2318 I added this mach. dependent ri twiddler. Ugly, but it gets
2320 /* on sparc: first 4 bytes are normal unsigned long address, next three
2321 bytes are index, most sig. byte first. Byte 7 is broken up with
2322 bit 7 as external, bits 6 & 5 unused, and the lower
2323 five bits as relocation type. Next 4 bytes are long int addend. */
2324 /* Thanx and a tip of the hat to Michael Bloom, mb@ttidca.tti.com */
2328 md_ri_to_chars (ri_p
, ri
)
2329 struct reloc_info_pa
*ri_p
, ri
;
2331 unsigned char the_bytes
[sizeof (*ri_p
)];
2332 #if defined(OBJ_SOM) | defined(OBJ_OSFROSE) | defined(OBJ_ELF)
2333 /* not sure what, if any, changes are required for new-style cross-assembly */
2335 the_bytes
[0] = ((ri
.need_data_ref
<< 7) & 0x80) | ((ri
.arg_reloc
& 0x03f8) >> 3);
2336 the_bytes
[1] = ((ri
.arg_reloc
& 0x07) << 5) | ri
.expression_type
;
2337 the_bytes
[2] = ((ri
.exec_level
<< 6) & 0xc0) | ri
.fixup_format
;
2338 the_bytes
[3] = ri
.fixup_field
& 0xff;
2339 md_number_to_chars (&the_bytes
[4], ri
.subspace_offset
, sizeof (ri
.subspace_offset
));
2340 md_number_to_chars (&the_bytes
[8], ri
.symbol_index_one
, sizeof (ri
.symbol_index_one
));
2341 md_number_to_chars (&the_bytes
[12], ri
.symbol_index_two
, sizeof (ri
.symbol_index_two
));
2342 md_number_to_chars (&the_bytes
[16], ri
.fixup_constant
, sizeof (ri
.fixup_constant
));
2344 /* now put it back where you found it, Junior... */
2345 bcopy (the_bytes
, (char *) ri_p
, sizeof (*ri_p
));
2353 /* Translate internal representation of relocation info to BFD target
2355 /* This may need additional work to make sure that SOM support is complete. */
2358 tc_gen_reloc (section
, fixp
)
2363 hppa_fixS
*hppa_fixp
= hppa_find_hppa_fix (fixp
);
2364 bfd_reloc_code_real_type code
;
2365 static int unwind_reloc_fixp_cnt
= 0;
2366 static arelent
*unwind_reloc_entryP
= NULL
;
2367 static arelent
*no_relocs
= NULL
;
2369 bfd_reloc_code_real_type
**codes
;
2373 if (fixp
->fx_addsy
== 0)
2375 assert (hppa_fixp
!= 0);
2376 assert (section
!= 0);
2378 /* unwind section relocations are handled in a special way. */
2379 /* The relocations for the .unwind section are originally */
2380 /* built in the usual way. That is, for each unwind table */
2381 /* entry there are two relocations: one for the beginning of */
2382 /* the function and one for the end. */
2384 /* The first time we enter this function we create a */
2385 /* relocation of the type R_HPPA_UNWIND_ENTRIES. The addend */
2386 /* of the relocation is initialized to 0. Each additional */
2387 /* pair of times this function is called for the unwind */
2388 /* section represents an additional unwind table entry. Thus, */
2389 /* the addend of the relocation should end up to be the number */
2390 /* of unwind table entries. */
2391 if (strcmp (UNWIND_SECTION_NAME
, section
->name
) == 0)
2393 if (unwind_reloc_entryP
== NULL
)
2395 reloc
= (arelent
*) bfd_alloc_by_size_t (stdoutput
, sizeof (arelent
));
2396 assert (reloc
!= 0);
2397 unwind_reloc_entryP
= reloc
;
2398 unwind_reloc_fixp_cnt
++;
2399 unwind_reloc_entryP
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
2400 /* a pointer any function will do. We only */
2401 /* need one to tell us what section the unwind */
2402 /* relocations are for. */
2403 unwind_reloc_entryP
->sym_ptr_ptr
= &fixp
->fx_addsy
->bsym
;
2404 code
= R_HPPA_UNWIND_ENTRIES
;
2405 unwind_reloc_entryP
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
2406 unwind_reloc_entryP
->addend
= unwind_reloc_fixp_cnt
/ 2;
2407 relocs
= (arelent
**) bfd_alloc_by_size_t (stdoutput
, sizeof (arelent
*) * 2);
2408 assert (relocs
!= 0);
2409 relocs
[0] = unwind_reloc_entryP
;
2413 unwind_reloc_fixp_cnt
++;
2414 unwind_reloc_entryP
->addend
= unwind_reloc_fixp_cnt
/ 2;
2419 reloc
= (arelent
*) bfd_alloc_by_size_t (stdoutput
, sizeof (arelent
));
2420 assert (reloc
!= 0);
2422 reloc
->sym_ptr_ptr
= &fixp
->fx_addsy
->bsym
;
2423 /* XXX: might need additional processing here */
2424 /* hppa_elf_gen_reloc_type() is defined in the */
2425 /* ELF/PA BFD back-end */
2426 codes
= hppa_elf_gen_reloc_type (stdoutput
,
2428 hppa_fixp
->fx_r_format
,
2429 hppa_fixp
->fx_r_field
);
2431 for (n_relocs
= 0; codes
[n_relocs
]; n_relocs
++)
2434 relocs
= (arelent
**) bfd_alloc_by_size_t (stdoutput
, sizeof (arelent
*) * n_relocs
+ 1);
2435 assert (relocs
!= 0);
2437 reloc
= (arelent
*) bfd_alloc_by_size_t (stdoutput
, sizeof (arelent
) * n_relocs
);
2439 assert (reloc
!= 0);
2441 for (i
= 0; i
< n_relocs
; i
++)
2442 relocs
[i
] = &reloc
[i
];
2444 relocs
[n_relocs
] = NULL
;
2446 switch (fixp
->fx_r_type
)
2448 case R_HPPA_COMPLEX
:
2449 case R_HPPA_COMPLEX_PCREL_CALL
:
2450 case R_HPPA_COMPLEX_ABS_CALL
:
2451 assert (n_relocs
== 5);
2453 for (i
= 0; i
< n_relocs
; i
++)
2455 reloc
[i
].sym_ptr_ptr
= NULL
;
2456 reloc
[i
].address
= 0;
2457 reloc
[i
].addend
= 0;
2458 reloc
[i
].howto
= bfd_reloc_type_lookup (stdoutput
, *codes
[i
]);
2459 assert (reloc
[i
].howto
&& *codes
[i
] == reloc
[i
].howto
->type
);
2462 reloc
[0].sym_ptr_ptr
= &fixp
->fx_addsy
->bsym
;
2463 reloc
[1].sym_ptr_ptr
= &fixp
->fx_subsy
->bsym
;
2464 reloc
[4].address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
2466 if (fixp
->fx_r_type
== R_HPPA_COMPLEX
)
2467 reloc
[3].addend
= fixp
->fx_addnumber
;
2468 else if (fixp
->fx_r_type
== R_HPPA_COMPLEX_PCREL_CALL
||
2469 fixp
->fx_r_type
== R_HPPA_COMPLEX_ABS_CALL
)
2470 reloc
[1].addend
= fixp
->fx_addnumber
;
2475 assert (n_relocs
== 1);
2479 reloc
->sym_ptr_ptr
= &fixp
->fx_addsy
->bsym
;
2480 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
2481 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
2482 reloc
->addend
= 0; /* default */
2484 assert (reloc
->howto
&& code
== reloc
->howto
->type
);
2486 /* Now, do any processing that is dependent on the relocation */
2490 case R_HPPA_PLABEL_32
:
2491 case R_HPPA_PLABEL_11
:
2492 case R_HPPA_PLABEL_14
:
2493 case R_HPPA_PLABEL_L21
:
2494 case R_HPPA_PLABEL_R11
:
2495 case R_HPPA_PLABEL_R14
:
2496 /* For plabel relocations, the addend of the */
2497 /* relocation should be either 0 (no static link) or 2 */
2498 /* (static link required). */
2499 /* XXX: assume that fx_addnumber contains this */
2501 reloc
->addend
= fixp
->fx_addnumber
;
2504 case R_HPPA_ABS_CALL_11
:
2505 case R_HPPA_ABS_CALL_14
:
2506 case R_HPPA_ABS_CALL_17
:
2507 case R_HPPA_ABS_CALL_L21
:
2508 case R_HPPA_ABS_CALL_R11
:
2509 case R_HPPA_ABS_CALL_R14
:
2510 case R_HPPA_ABS_CALL_R17
:
2511 case R_HPPA_ABS_CALL_LS21
:
2512 case R_HPPA_ABS_CALL_RS11
:
2513 case R_HPPA_ABS_CALL_RS14
:
2514 case R_HPPA_ABS_CALL_RS17
:
2515 case R_HPPA_ABS_CALL_LD21
:
2516 case R_HPPA_ABS_CALL_RD11
:
2517 case R_HPPA_ABS_CALL_RD14
:
2518 case R_HPPA_ABS_CALL_RD17
:
2519 case R_HPPA_ABS_CALL_LR21
:
2520 case R_HPPA_ABS_CALL_RR14
:
2521 case R_HPPA_ABS_CALL_RR17
:
2523 case R_HPPA_PCREL_CALL_11
:
2524 case R_HPPA_PCREL_CALL_14
:
2525 case R_HPPA_PCREL_CALL_17
:
2526 case R_HPPA_PCREL_CALL_L21
:
2527 case R_HPPA_PCREL_CALL_R11
:
2528 case R_HPPA_PCREL_CALL_R14
:
2529 case R_HPPA_PCREL_CALL_R17
:
2530 case R_HPPA_PCREL_CALL_LS21
:
2531 case R_HPPA_PCREL_CALL_RS11
:
2532 case R_HPPA_PCREL_CALL_RS14
:
2533 case R_HPPA_PCREL_CALL_RS17
:
2534 case R_HPPA_PCREL_CALL_LD21
:
2535 case R_HPPA_PCREL_CALL_RD11
:
2536 case R_HPPA_PCREL_CALL_RD14
:
2537 case R_HPPA_PCREL_CALL_RD17
:
2538 case R_HPPA_PCREL_CALL_LR21
:
2539 case R_HPPA_PCREL_CALL_RR14
:
2540 case R_HPPA_PCREL_CALL_RR17
:
2541 /* constant is stored in the instruction */
2542 reloc
->addend
= ELF32_HPPA_R_ADDEND (hppa_fixp
->fx_arg_reloc
, 0);
2545 reloc
->addend
= fixp
->fx_addnumber
;
2556 tc_gen_reloc (section
, fixp
)
2561 hppa_fixS
*hppa_fixp
= hppa_find_hppa_fix (fixp
);
2562 bfd_reloc_code_real_type code
;
2564 if (fixp
->fx_addsy
== 0)
2566 assert (hppa_fixp
!= 0);
2567 assert (section
!= 0);
2569 reloc
= (arelent
*) bfd_alloc_by_size_t (stdoutput
, sizeof (arelent
));
2570 assert (reloc
!= 0);
2572 reloc
->sym_ptr_ptr
= &fixp
->fx_addsy
->bsym
;
2573 /* XXX: might need additional processing here */
2574 /* hppa_elf_gen_reloc_type() is defined in the */
2575 /* ELF/PA BFD back-end */
2576 code
= hppa_elf_gen_reloc_type (stdoutput
,
2578 hppa_fixp
->fx_r_format
,
2579 hppa_fixp
->fx_r_field
);
2580 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
2582 assert (code
== reloc
->howto
->type
);
2584 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
2585 reloc
->addend
= 0; /* default */
2587 /* Now, do any processing that is dependent on the relocation */
2588 /* type. (Is there any?) */
2592 reloc
->addend
= fixp
->fx_addnumber
;
2602 md_convert_frag (abfd
, sec
, fragP
)
2604 register asection
*sec
;
2605 register fragS
*fragP
;
2607 unsigned int address
;
2609 if (fragP
->fr_type
== rs_machine_dependent
)
2611 switch ((int) fragP
->fr_subtype
)
2614 fragP
->fr_type
= rs_fill
;
2615 know (fragP
->fr_var
== 1);
2616 know (fragP
->fr_next
);
2617 address
= fragP
->fr_address
+ fragP
->fr_fix
;
2618 if (address
% fragP
->fr_offset
)
2621 fragP
->fr_next
->fr_address
2626 fragP
->fr_offset
= 0;
2632 /* Round up a section size to the appropriate boundary. */
2634 md_section_align (segment
, size
)
2638 return (size
+ 7) & ~7; /* Round all sects to multiple of 8 */
2639 } /* md_section_align() */
2642 md_create_long_jump (ptr
, from_addr
, to_addr
, frag
, to_symbol
)
2644 addressT from_addr
, to_addr
;
2648 fprintf (stderr
, "pa_create_long_jump\n");
2653 /* md_estimate_size_before_relax(fragP, segtype) */
2654 md_estimate_size_before_relax (fragP
, segment
)
2655 register fragS
*fragP
;
2662 while ((fragP
->fr_fix
+ size
) % fragP
->fr_offset
)
2669 md_parse_option (argP
, cntP
, vecP
)
2677 /* We have no need to default values of symbols. */
2681 md_undefined_symbol (name
)
2685 } /*md_undefined_symbol() */
2687 /* Parse an operand that is machine-specific.
2688 We just return without modifying the expression if we have nothing
2693 md_operand (expressionP
)
2694 expressionS
*expressionP
;
2698 /* Apply a fixS to the frags, now that we know the value it ought to
2702 apply_field_selector (value
, constant
, field_selector
)
2707 /* hppa_field_adjust() is defined in the HPPA target */
2708 return hppa_field_adjust (value
, constant
, field_selector
);
2712 md_apply_fix_1 (fixP
, val
)
2716 char *buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
2717 hppa_fixS
*hppa_fixP
= hppa_find_hppa_fix (fixP
);
2720 unsigned int w1
, w2
, w
;
2721 /* The following routine is defined in the ELF/PA back-end */
2722 extern unsigned char hppa_elf_insn2fmt ();
2726 unsigned long buf_wd
= bfd_get_32 (stdoutput
, buf
);
2727 unsigned char fmt
= hppa_elf_insn2fmt (fixP
->fx_r_type
, buf_wd
);
2729 assert (fixP
->fx_r_type
< R_HPPA_UNIMPLEMENTED
);
2730 assert (fixP
->fx_r_type
>= R_HPPA_NONE
);
2732 fixP
->fx_addnumber
= val
; /* Remember value for emit_reloc */
2734 /* Check if this is an undefined symbol. No relocation can */
2735 /* possibly be performed in this case. */
2737 if ((fixP
->fx_addsy
&& fixP
->fx_addsy
->bsym
->section
== &bfd_und_section
)
2738 || (fixP
->fx_subsy
&& fixP
->fx_subsy
->bsym
->section
== &bfd_und_section
))
2741 /* Perform some processing particular to unwind */
2744 if (hppa_fixP
->fx_call_infop
2745 && (((fixP
== hppa_fixP
->fx_call_infop
->start_fix
)
2746 && (fixP
->fx_addsy
==
2747 hppa_fixP
->fx_call_infop
->start_symbol
))
2748 || ((fixP
== hppa_fixP
->fx_call_infop
->end_fix
)
2749 && (fixP
->fx_addsy
==
2750 hppa_fixP
->fx_call_infop
->end_symbol
))
2752 val
+= fixP
->fx_addsy
->sy_frag
->fr_address
;
2757 case 14: /* all the opcodes with the 'j' operand type */
2758 new_val
= apply_field_selector (val
, 0, hppa_fixP
->fx_r_field
);
2759 /* need to check for overflow here */
2761 /* mask off 14 bits to be changed */
2762 /* *(long *)buf = *(long *)buf & 0xffffc000; */
2763 bfd_put_32 (stdoutput
,
2764 bfd_get_32 (stdoutput
, buf
) & 0xffffc000,
2766 low_sign_unext (new_val
, 14, &result
);
2769 case 21: /* all the opcodes with the 'k' 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 21 bits to be changed */
2774 /* *(long *)buf = *(long *)buf & 0xffe00000; */
2775 bfd_put_32 (stdoutput
,
2776 bfd_get_32 (stdoutput
, buf
) & 0xffe00000,
2778 dis_assemble_21 (new_val
, &result
);
2781 case 11: /* all the opcodes with the 'i' operand type */
2782 new_val
= apply_field_selector (val
, 0, hppa_fixP
->fx_r_field
);
2783 /* need to check for overflow here */
2785 /* mask off 11 bits to be changed */
2786 /* *(long *)buf = *(long *)buf & 0xffff800; */
2787 bfd_put_32 (stdoutput
,
2788 bfd_get_32 (stdoutput
, buf
) & 0xffff800,
2790 low_sign_unext (new_val
, 11, &result
);
2793 case 12: /* all the opcodes with the 'w' operand type */
2794 new_val
= apply_field_selector (val
, 0, hppa_fixP
->fx_r_field
);
2796 /* mask off 11 bits to be changed */
2797 sign_unext ((new_val
- 8) >> 2, 12, &result
);
2798 /* *(long *)buf = *(long *)buf & 0xffffe002; */
2799 bfd_put_32 (stdoutput
,
2800 bfd_get_32 (stdoutput
, buf
) & 0xffffe002,
2803 dis_assemble_12 (result
, &w1
, &w
);
2804 result
= ((w1
<< 2) | w
);
2807 case 17: /* some of the opcodes with the 'W' operand type */
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 /* *(long *)buf = *(long *)buf & 0xffe0e002; */
2813 bfd_put_32 (stdoutput
,
2814 bfd_get_32 (stdoutput
, buf
) & 0xffe0e002,
2816 sign_unext ((new_val
- 8) >> 2, 17, &result
);
2817 dis_assemble_17 (result
, &w1
, &w2
, &w
);
2818 result
= ((w2
<< 2) | (w1
<< 16) | w
);
2822 new_val
= apply_field_selector (val
, 0, hppa_fixP
->fx_r_field
);
2823 result
= new_val
; /* no transformation on result */
2824 /* *(long *)buf = 0; *//* clear out everything */
2825 bfd_put_32 (stdoutput
, 0, buf
); /* clear out everything */
2832 as_bad ("bad relocation type/fmt: 0x%02x/0x%02x",
2833 fixP
->fx_r_type
, fmt
);
2836 buf
[0] |= (result
& 0xff000000) >> 24;
2837 buf
[1] |= (result
& 0x00ff0000) >> 16;
2838 buf
[2] |= (result
& 0x0000ff00) >> 8;
2839 buf
[3] |= result
& 0x000000ff;
2840 /* We've now adjusted for fx_addnumber, we can */
2841 /* forget it now. */
2842 fixP
->fx_addnumber
= 0;
2846 printf ("no hppa_fixup entry for this fixup (fixP = 0x%x, type = 0x%x)\n",
2847 fixP
, fixP
->fx_r_type
);
2849 } /* md_apply_fix_1() */
2851 #ifdef BFD_ASSEMBLER
2853 md_apply_fix (fixP
, valp
)
2857 md_apply_fix_1 (fixP
, *valp
);
2863 md_apply_fix (fixP
, val
)
2867 md_apply_fix_1 (fixP
, val
);
2872 /* Exactly what point is a PC-relative offset relative TO?
2873 On the PA, they're relative to the address of the offset.
2874 (??? Is this right? FIXME-SOON) */
2876 md_pcrel_from (fixP
)
2879 return fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
2880 } /* md_pcrel_from() */
2883 is_end_of_statement ()
2885 return ((*input_line_pointer
== '\n')
2886 || (*input_line_pointer
== ';')
2887 || (*input_line_pointer
== '!'));
2890 /* pa-aux.c -- Assembler for the PA - PA-RISC specific support routines */
2892 struct aux_hdr_list
*aux_hdr_root
= NULL
;
2894 int print_errors
= 1;
2900 while (**s
== ' ' || **s
== '\t')
2915 while (*p
== ' ' || *p
== '\t')
2917 num
= -1; /* assume invalid number to begin with */
2920 num
= 0; /* now we know it is a number */
2922 if (*p
== '0' && (*(p
+ 1) == 'x' || *(p
+ 1) == 'X'))
2925 while (isdigit (*p
) || ((*p
>= 'a') && (*p
<= 'f'))
2926 || ((*p
>= 'A') && (*p
<= 'F')))
2929 num
= num
* 16 + *p
- '0';
2930 else if (*p
>= 'a' && *p
<= 'f')
2931 num
= num
* 16 + *p
- 'a' + 10;
2933 num
= num
* 16 + *p
- 'A' + 10;
2939 while (isdigit (*p
))
2941 num
= num
* 10 + *p
- '0';
2947 { /* could be a pre-defined register */
2952 /* tege hack: Special case for general registers
2953 as the general code makes a binary search with case translation,
2954 and is VERY slow. */
2958 if (*p
== 'e' && *(p
+ 1) == 't' && (*(p
+ 2) == '0' || *(p
+ 2) == '1'))
2961 num
= *p
- '0' + 28; /* r28 is ret0 */
2964 else if (!isdigit (*p
))
2965 as_bad ("Undefined register: '%s'. ASSUMING 0", name
);
2969 num
= num
* 10 + *p
++ - '0';
2970 while (isdigit (*p
));
2975 while (is_part_of_name (c
))
2981 status
= reg_name_search (name
);
2987 as_bad ("Undefined register: '%s'. ASSUMING 0", name
);
2999 while (is_part_of_name (c
))
3005 if ((sym
= symbol_find (name
)) != NULL
)
3008 if (sym
->pa_sy_type
== ST_ABSOLUTE
)
3010 num
= sym
->pa_sy_value
;
3012 if (S_GET_SEGMENT (sym
) == &bfd_abs_section
)
3014 num
= S_GET_VALUE (sym
);
3020 as_bad ("Non-absolute constant: '%s'. ASSUMING 0", name
);
3028 as_bad ("Undefined absolute constant: '%s'. ASSUMING 0", name
);
3045 /* List of registers that are pre-defined:
3049 Name Value Name Value
3067 Floating-point Registers:
3068 [NOTE: Also includes L and R versions of these (e.g. %fr19L, %fr19R)]
3070 Name Value Name Value
3090 Name Value Name Value
3096 Control registers and their synonyms:
3125 Miscellaneous registers and their synonyms:
3137 /* This table is sorted. Suitable for searching by a binary search. */
3139 static struct pd_reg pre_defined_registers
[] =
3349 #define REG_NAME_CNT (sizeof(pre_defined_registers) / sizeof(struct pd_reg))
3352 reg_name_search (name
)
3358 r
= REG_NAME_CNT
- 1;
3363 if (strcasecmp (name
, pre_defined_registers
[x
].name
) < 0)
3368 while (!((strcasecmp (name
, pre_defined_registers
[x
].name
) == 0) ||
3371 if (strcasecmp (name
, pre_defined_registers
[x
].name
) == 0)
3372 return (pre_defined_registers
[x
].value
);
3379 is_pre_defined_register (s
)
3382 if (reg_name_search (s
) >= 0)
3393 if (*s
== 'R' || *s
== 'r')
3404 if (*s
== 'L' || *s
== 'l')
3411 need_89_opcode (insn
, result
)
3413 struct pa_89_fp_reg_struct
*result
;
3415 /* if ( result->L_R_select == 1 || insn->fpof1 == DBL || insn->fpof2 == DBL ) */
3416 /* if (result->L_R_select == 1 && !(insn->fpof1 == DBL || insn->fpof2 == DBL) ) */
3417 if (result
->L_R_select
== 1 && !(insn
->fpof1
== DBL
&& insn
->fpof2
== DBL
))
3418 /* if ( insn->fpof1 == DBL || insn->fpof2 == DBL ) */
3425 pa_89_parse_number (s
, result
)
3427 struct pa_89_fp_reg_struct
*result
;
3436 while (*p
== ' ' || *p
== '\t')
3438 num
= -1; /* assume invalid number to begin with */
3439 result
->number_part
= -1;
3440 result
->L_R_select
= -1;
3444 num
= 0; /* now we know it is a number */
3446 if (*p
== '0' && (*(p
+ 1) == 'x' || *(p
+ 1) == 'X'))
3449 while (isdigit (*p
) || ((*p
>= 'a') && (*p
<= 'f'))
3450 || ((*p
>= 'A') && (*p
<= 'F')))
3453 num
= num
* 16 + *p
- '0';
3454 else if (*p
>= 'a' && *p
<= 'f')
3455 num
= num
* 16 + *p
- 'a' + 10;
3457 num
= num
* 16 + *p
- 'A' + 10;
3463 while (isdigit (*p
))
3465 num
= num
* 10 + *p
- '0';
3470 result
->number_part
= num
;
3472 if (is_R_select (p
))
3474 result
->L_R_select
= 1;
3477 else if (is_L_select (p
))
3479 result
->L_R_select
= 0;
3483 result
->L_R_select
= 0;
3487 { /* could be a pre-defined register */
3492 /* tege hack: Special case for general registers
3493 as the general code makes a binary search with case translation,
3494 and is VERY slow. */
3498 if (*p
== 'e' && *(p
+ 1) == 't' && (*(p
+ 2) == '0' || *(p
+ 2) == '1'))
3501 num
= *p
- '0' + 28; /* r28 is ret0 */
3504 else if (!isdigit (*p
))
3505 as_bad ("Undefined register: '%s'. ASSUMING 0", name
);
3509 num
= num
* 10 + *p
++ - '0';
3510 while (isdigit (*p
));
3515 while (is_part_of_name (c
))
3521 status
= reg_name_search (name
);
3527 as_bad ("Undefined register: '%s'. ASSUMING 0", name
);
3534 result
->number_part
= num
;
3536 if (is_R_select (p
- 1))
3537 result
->L_R_select
= 1;
3538 else if (is_L_select (p
- 1))
3539 result
->L_R_select
= 0;
3541 result
->L_R_select
= 0;
3549 while (is_part_of_name (c
))
3555 if ((sym
= symbol_find (name
)) != NULL
)
3558 if (sym
->pa_sy_type
== ST_ABSOLUTE
)
3560 num
= sym
->pa_sy_value
;
3562 if (S_GET_SEGMENT (sym
) == &bfd_abs_section
)
3564 num
= S_GET_VALUE (sym
);
3570 as_bad ("Non-absolute constant: '%s'. ASSUMING 0", name
);
3578 as_bad ("Undefined absolute constant: '%s'. ASSUMING 0", name
);
3583 result
->number_part
= num
;
3585 if (is_R_select (p
- 1))
3586 result
->L_R_select
= 1;
3587 else if (is_L_select (p
- 1))
3588 result
->L_R_select
= 0;
3590 result
->L_R_select
= 0;
3600 pa_parse_fp_cmp_cond (s
)
3611 This table is sorted by order of the length of the string. This is so we
3612 check for <> before we check for <. If we had a <> and checked for < first,
3613 we would get a false match.
3615 static struct possibleS poss
[] =
3653 for (i
= 0; i
< 32; i
++)
3655 if (strncasecmp (*s
, poss
[i
].string
, strlen (poss
[i
].string
)) == 0)
3657 cond
= poss
[i
].cond
;
3658 *s
+= strlen (poss
[i
].string
);
3659 while (**s
== ' ' || **s
== '\t')
3665 as_bad ("Illegal FP Compare Condition: %c", **s
);
3670 pa_parse_fp_format (s
)
3679 if (strncasecmp (*s
, "sgl", 3) == 0)
3684 else if (strncasecmp (*s
, "dbl", 3) == 0)
3689 else if (strncasecmp (*s
, "quad", 4) == 0)
3697 as_bad ("Unrecognized FP Operand Format: %3s", *s
);
3700 while (**s
== ' ' || **s
== '\t' || **s
== 0)
3706 #if defined(OBJ_ELF)
3708 pa_chk_field_selector (str
)
3712 struct selector_entry
3717 static struct selector_entry selector_table
[] =
3751 struct selector_entry
*tableP
;
3755 while (**str
== ' ' || **str
== '\t' || **str
== '\n' || **str
== '\f')
3759 for (tableP
= selector_table
; tableP
->prefix
; tableP
++)
3761 if (strncasecmp (tableP
->prefix
, *str
, strlen (tableP
->prefix
)) == 0)
3763 *str
+= strlen (tableP
->prefix
);
3764 selector
= tableP
->field_selector
;
3778 save_in
= input_line_pointer
;
3779 input_line_pointer
= str
;
3780 seg
= expression (&the_insn
.exp
);
3782 if (!(seg
== &bfd_abs_section
3783 || seg
== &bfd_und_section
3784 || seg
== text_section
3785 || seg
== data_section
3786 || seg
== bss_section
3787 || seg
== diff_section
3788 || seg
== big_section
3789 || seg
== absent_section
))
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
;
3802 getAbsoluteExpression (str
)
3808 save_in
= input_line_pointer
;
3809 input_line_pointer
= str
;
3810 seg
= expression (&the_insn
.exp
);
3812 if (seg
!= &bfd_abs_section
)
3814 the_insn
.error
= "segment should be ABSOLUTE";
3815 expr_end
= input_line_pointer
;
3816 input_line_pointer
= save_in
;
3819 expr_end
= input_line_pointer
;
3820 input_line_pointer
= save_in
;
3832 save_in
= input_line_pointer
;
3833 input_line_pointer
= str
;
3834 switch (seg
= expression (&the_insn
.exp
))
3842 case SEG_DIFFERENCE
:
3850 the_insn
.error
= "illegal segment";
3851 expr_end
= input_line_pointer
;
3852 input_line_pointer
= save_in
;
3855 expr_end
= input_line_pointer
;
3856 input_line_pointer
= save_in
;
3861 getAbsoluteExpression (str
)
3867 save_in
= input_line_pointer
;
3868 input_line_pointer
= str
;
3869 switch (seg
= expression (&the_insn
.exp
))
3876 the_insn
.error
= "segment should be ABSOLUTE";
3877 expr_end
= input_line_pointer
;
3878 input_line_pointer
= save_in
;
3881 expr_end
= input_line_pointer
;
3882 input_line_pointer
= save_in
;
3889 evaluateAbsolute (exp
, field_selector
)
3895 value
= exp
.X_add_number
;
3897 if (exp
.X_add_symbol
)
3899 value
+= S_GET_VALUE (exp
.X_add_symbol
);
3901 if (exp
.X_subtract_symbol
)
3903 value
-= S_GET_VALUE (exp
.X_subtract_symbol
);
3906 switch (field_selector
)
3908 case e_fsel
: /* F : no change */
3911 case e_lssel
: /* LS : if (bit 21) then add 0x800
3912 arithmetic shift right 11 bits */
3913 if (value
& 0x00000400)
3915 value
= (value
& 0xfffff800) >> 11;
3918 case e_rssel
: /* RS : Sign extend from bit 21 */
3919 if (value
& 0x00000400)
3920 value
|= 0xfffff800;
3925 case e_lsel
: /* L : Arithmetic shift right 11 bits */
3926 value
= (value
& 0xfffff800) >> 11;
3929 case e_rsel
: /* R : Set bits 0-20 to zero */
3930 value
= value
& 0x7ff;
3933 case e_ldsel
: /* LD : Add 0x800, arithmetic shift
3936 value
= (value
& 0xfffff800) >> 11;
3939 case e_rdsel
: /* RD : Set bits 0-20 to one */
3940 value
|= 0xfffff800;
3943 case e_lrsel
: /* LR : L with "rounded" constant */
3944 /* XXX: this isn't right. Need to add a "rounded" constant */
3945 /* XXX: (presumably from X_add_number) */
3946 value
= (value
& 0xfffff800) >> 11;
3949 case e_rrsel
: /* RR : R with "rounded" constant */
3950 /* XXX: this isn't right. Need to add a "rounded" constant */
3951 /* XXX: (presumably from X_add_number) */
3952 value
= value
& 0x7ff;
3956 BAD_CASE (field_selector
);
3963 pa_build_arg_reloc (type_name
)
3967 if (strncasecmp (type_name
, "no", 2) == 0)
3971 if (strncasecmp (type_name
, "gr", 2) == 0)
3975 else if (strncasecmp (type_name
, "fr", 2) == 0)
3979 else if (strncasecmp (type_name
, "fu", 2) == 0)
3984 as_bad ("Unrecognized argument location: %s\n", type_name
);
3990 pa_align_arg_reloc (reg
, arg_reloc
)
3992 unsigned int arg_reloc
;
3994 unsigned int new_reloc
;
3996 new_reloc
= arg_reloc
;
4012 as_bad ("Illegal argument description: %d", reg
);
4028 if (strncasecmp (*s
, "n", 1) == 0)
4032 as_bad ("Unrecognized Nullification: (%c)", **s
);
4037 while (**s
== ' ' || **s
== '\t')
4045 pa_parse_nonneg_cmpsub_cmpltr (s
)
4058 while (**s
!= ',' && **s
!= ' ' && **s
!= '\t')
4062 if (strcmp (name
, "=") == 0)
4066 else if (strcmp (name
, "<") == 0)
4070 else if (strcmp (name
, "<=") == 0)
4074 else if (strcmp (name
, "<<") == 0)
4078 else if (strcmp (name
, "<<=") == 0)
4082 else if (strcasecmp (name
, "sv") == 0)
4086 else if (strcasecmp (name
, "od") == 0)
4098 while (**s
== ' ' || **s
== '\t')
4107 pa_parse_nonneg_cmpsub_cmpltr (s
)
4119 while (**s
!= ',' && **s
!= ' ' && **s
!= '\t')
4123 if (strcmp (name
, "=") == 0)
4127 else if (strcmp (name
, "<") == 0)
4131 else if (strcmp (name
, "<=") == 0)
4135 else if (strcmp (name
, "<<") == 0)
4139 else if (strcmp (name
, "<<=") == 0)
4143 else if (strcasecmp (name
, "sv") == 0)
4147 else if (strcasecmp (name
, "od") == 0)
4157 while (**s
== ' ' || **s
== '\t')
4165 pa_parse_neg_cmpsub_cmpltr (s
)
4177 while (**s
!= ',' && **s
!= ' ' && **s
!= '\t')
4181 if (strcasecmp (name
, "tr") == 0)
4185 else if (strcmp (name
, "<>") == 0)
4189 else if (strcmp (name
, ">=") == 0)
4193 else if (strcmp (name
, ">") == 0)
4197 else if (strcmp (name
, ">>=") == 0)
4201 else if (strcmp (name
, ">>") == 0)
4205 else if (strcasecmp (name
, "nsv") == 0)
4209 else if (strcasecmp (name
, "ev") == 0)
4217 while (**s
== ' ' || **s
== '\t')
4225 pa_parse_nonneg_add_cmpltr (s
)
4237 while (**s
!= ',' && **s
!= ' ' && **s
!= '\t')
4241 if (strcmp (name
, "=") == 0)
4245 else if (strcmp (name
, "<") == 0)
4249 else if (strcmp (name
, "<=") == 0)
4253 else if (strcasecmp (name
, "nuv") == 0)
4257 else if (strcasecmp (name
, "znv") == 0)
4261 else if (strcasecmp (name
, "sv") == 0)
4265 else if (strcasecmp (name
, "od") == 0)
4273 while (**s
== ' ' || **s
== '\t')
4281 pa_parse_neg_add_cmpltr (s
)
4293 while (**s
!= ',' && **s
!= ' ' && **s
!= '\t')
4297 if (strcasecmp (name
, "tr") == 0)
4301 else if (strcmp (name
, "<>") == 0)
4305 else if (strcmp (name
, ">=") == 0)
4309 else if (strcmp (name
, ">") == 0)
4313 else if (strcmp (name
, "uv") == 0)
4317 else if (strcmp (name
, "vnz") == 0)
4321 else if (strcasecmp (name
, "nsv") == 0)
4325 else if (strcasecmp (name
, "ev") == 0)
4333 while (**s
== ' ' || **s
== '\t')
4344 if (strncmp (input_line_pointer
, "\"text\"", 6) == 0)
4346 input_line_pointer
+= 6;
4350 if (strncmp (input_line_pointer
, "\"data\"", 6) == 0)
4352 input_line_pointer
+= 6;
4356 if (strncmp (input_line_pointer
, "\"data1\"", 7) == 0)
4358 input_line_pointer
+= 7;
4362 as_bad ("Unknown segment type");
4363 demand_empty_rest_of_line ();
4372 temp
= get_absolute_expression ();
4374 subseg_new (SEG_DATA
, (subsegT
) temp
);
4376 subseg_new (".data", (subsegT
) temp
);
4378 demand_empty_rest_of_line ();
4385 subseg_new (SEG_DATA
, 1);
4387 subseg_new (".data", 1);
4389 demand_empty_rest_of_line ();
4396 extern char is_end_of_line
[];
4398 while (!is_end_of_line
[*input_line_pointer
])
4400 ++input_line_pointer
;
4402 ++input_line_pointer
;
4411 register long int temp_fill
;
4412 register long int temp_size
;
4415 temp_size
= get_absolute_expression ();
4418 { /* fill with zeroes even if not requested to do so. */
4419 temp_fill
= 0; /* HP assembler does this too. */
4428 as_bad ("size < 0, .block ignored");
4431 p
= frag_var (rs_fill
,
4433 (int) temp_size
, (relax_substateT
) 0, (symbolS
*) 0, 1, (char *) 0);
4434 bzero (p
, (int) temp_size
);
4436 /* convert 2 bytes at a time */
4438 for (i
= 0; i
< temp_size
; i
+= 2)
4440 md_number_to_chars (p
+ i
,
4442 (int) ((temp_size
- i
) > 2 ? 2 : (temp_size
- i
)));
4445 pa_undefine_label ();
4446 demand_empty_rest_of_line ();
4454 pa_call_args (&last_call_desc
);
4455 demand_empty_rest_of_line ();
4460 pa_call_args (call_desc
)
4461 register call_descS
*call_desc
;
4463 register char *name
;
4467 register unsigned int arg_reloc
;
4469 while (!is_end_of_statement ())
4471 name
= input_line_pointer
;
4472 c
= get_symbol_end ();
4473 if ((strncasecmp (name
, "argw", 4) == 0))
4475 temp
= atoi (name
+ 4);
4476 p
= input_line_pointer
;
4478 input_line_pointer
++;
4479 name
= input_line_pointer
;
4480 c
= get_symbol_end ();
4481 arg_reloc
= pa_build_arg_reloc (name
);
4482 call_desc
->arg_reloc
|= pa_align_arg_reloc (temp
, arg_reloc
);
4484 else if ((strncasecmp (name
, "rtnval", 6) == 0))
4486 p
= input_line_pointer
;
4488 input_line_pointer
++;
4489 name
= input_line_pointer
;
4490 c
= get_symbol_end ();
4491 arg_reloc
= pa_build_arg_reloc (name
);
4492 call_desc
->arg_reloc
|= (arg_reloc
& 0x3);
4496 as_bad ("Unrecognized .CALL argument: %s", name
);
4498 p
= input_line_pointer
;
4500 if (!is_end_of_statement ())
4501 input_line_pointer
++;
4506 is_same_frag (frag1P
, frag2P
)
4513 else if (frag2P
== NULL
)
4515 else if (frag1P
== frag2P
)
4517 else if (frag2P
->fr_type
== rs_fill
&& frag2P
->fr_fix
== 0)
4518 is_same_frag (frag1P
, frag2P
->fr_next
);
4525 pa_build_unwind_subspace (call_info
)
4526 call_infoS
*call_info
;
4531 subsegT subseg
, save_subseg
;
4536 subseg
= SUBSEG_UNWIND
;
4537 seg
= bfd_get_section_by_name (stdoutput
, UNWIND_SECTION_NAME
);
4538 if (seg
== ASEC_NULL
)
4540 seg
= bfd_make_section_old_way (stdoutput
, UNWIND_SECTION_NAME
);
4542 bfd_set_section_flags (stdoutput
,
4544 SEC_READONLY
| SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
);
4546 /* callinfo.frame is in bytes and unwind_desc is in 8 byte units */
4547 call_info
->ci_unwind
.descriptor
.frame_size
= call_info
->frame
/ 8;
4549 /* Now, dump the unwind descriptor to the $UNWIND$ subspace. This
4550 creates a couple of relocations */
4553 save_subseg
= now_subseg
;
4554 subseg_new ((char *) seg
->name
, subseg
);
4555 unwindP
= (char *) &call_info
->ci_unwind
;
4558 call_info
->start_offset_frag
= frag_now
;
4559 call_info
->start_frag_where
= p
- frag_now
->fr_literal
;
4561 /* relocation info. for start offset of the function */
4563 fix_new_hppa (frag_now
, p
- frag_now
->fr_literal
, 4,
4564 call_info
->start_symbol
, (symbolS
*) NULL
,
4565 0, 0, R_HPPA
, e_fsel
, 32, 0, (char *) 0);
4567 /** we need to search for the first relocation involving the start_symbol of **/
4568 /** this call_info descriptor **/
4573 call_info
->start_fix
= seg_info (now_seg
)->fix_root
; /* the default */
4574 for (fixP
= call_info
->start_fix
; fixP
; fixP
= fixP
->fx_next
)
4576 if (fixP
->fx_addsy
== call_info
->start_symbol
4577 || fixP
->fx_subsy
== call_info
->start_symbol
)
4579 call_info
->start_fix
= fixP
;
4586 call_info
->end_offset_frag
= frag_now
;
4587 call_info
->end_frag_where
= p
- frag_now
->fr_literal
;
4589 /* relocation info. for end offset of the function */
4591 fix_new_hppa (frag_now
, p
- frag_now
->fr_literal
, 4,
4592 call_info
->end_symbol
, (symbolS
*) NULL
,
4593 0, 0, R_HPPA
, e_fsel
, 32, 0, (char *) 0);
4595 /** we need to search for the first relocation involving the start_symbol of **/
4596 /** this call_info descriptor **/
4601 call_info
->end_fix
= seg_info (now_seg
)->fix_root
; /* the default */
4602 for (fixP
= call_info
->end_fix
; fixP
; fixP
= fixP
->fx_next
)
4604 if (fixP
->fx_addsy
== call_info
->end_symbol
4605 || fixP
->fx_subsy
== call_info
->end_symbol
)
4607 call_info
->end_fix
= fixP
;
4613 for (i
= 8; i
< sizeof (unwind_tableS
); i
++)
4617 FRAG_APPEND_1_CHAR (c
);
4621 subseg_new ((char *) save_seg
->name
, save_subseg
);
4627 pa_build_unwind_subspace (call_info
)
4628 call_infoS
*call_info
;
4630 space_dict_chainS
*spaceP
;
4631 subspace_dict_chainS
*subspaceP
;
4633 char defined
, loadable
, code_only
, common
, dup_common
, is_zero
, sort
;
4634 int access
, space_index
, alignment
, quadrant
;
4636 subsegT subseg
, save_subseg
;
4652 subseg
= SUBSEG_UNWIND
;
4655 spaceP
= pa_segment_to_space (seg
);
4657 if ((subspaceP
= is_defined_subspace ("$UNWIND$", SUBSEG_UNWIND
)))
4659 update_subspace ("$UNWIND$", defined
, loadable
, code_only
, common
, dup_common
,
4660 sort
, is_zero
, access
, space_index
, alignment
, quadrant
,
4665 subspaceP
= create_new_subspace (spaceP
, "$UNWIND$", defined
, loadable
, code_only
,
4666 common
, dup_common
, is_zero
, sort
, access
,
4667 space_index
, alignment
, quadrant
, seg
);
4671 /* callinfo.frame is in bytes and unwind_desc is in 8 byte units */
4672 call_info
->ci_unwind
.descriptor
.frame_size
= call_info
->frame
/ 8;
4674 /* Now, dump the unwind descriptor to the $UNWIND$ subspace. This
4675 creates a couple of relocations */
4678 save_subseg
= now_subseg
;
4679 subseg_new (seg
, subseg
);
4680 unwindP
= (char *) &call_info
->ci_unwind
;
4683 call_info
->start_offset_frag
= frag_now
;
4684 call_info
->start_frag_where
= p
- frag_now
->fr_literal
;
4686 /* relocation info. for start offset of the function */
4688 fix_new (frag_now
, p
- frag_now
->fr_literal
, 4,
4689 call_info
->start_symbol
, (symbolS
*) NULL
,
4690 0, 0, R_DATA_ONE_SYMBOL
, e_fsel
, 0, 0, (char *) 0);
4692 /** we need to search for the first relocation involving the start_symbol of **/
4693 /** this call_info descriptor **/
4698 call_info
->start_fix
= seg_info (now_seg
)->fix_root
; /* the default */
4699 for (fixP
= call_info
->start_fix
; fixP
; fixP
= fixP
->fx_next
)
4702 if ( ( fixP->fx_addsy == call_info->start_symbol ||
4703 fixP->fx_subsy == call_info->start_symbol )
4705 ( fixP->fx_frag == call_info->start_symbol->sy_frag ) ) {
4707 if ((fixP
->fx_addsy
== call_info
->start_symbol
||
4708 fixP
->fx_subsy
== call_info
->start_symbol
)
4710 (is_same_frag (fixP
->fx_frag
, call_info
->start_symbol
->sy_frag
)))
4712 call_info
->start_fix
= fixP
;
4719 call_info
->end_offset_frag
= frag_now
;
4720 call_info
->end_frag_where
= p
- frag_now
->fr_literal
;
4722 /* relocation info. for end offset of the function */
4724 fix_new (frag_now
, p
- frag_now
->fr_literal
, 4,
4725 call_info
->start_symbol
, (symbolS
*) NULL
,
4726 0, 0, R_DATA_ONE_SYMBOL
, e_fsel
, 0, 0, (char *) 0);
4728 /** we need to search for the first relocation involving the start_symbol of **/
4729 /** this call_info descriptor **/
4734 call_info
->end_fix
= seg_info (now_seg
)->fix_root
; /* the default */
4735 for (fixP
= call_info
->end_fix
; fixP
; fixP
= fixP
->fx_next
)
4738 if ( ( fixP->fx_addsy == call_info->start_symbol ||
4739 fixP->fx_subsy == call_info->start_symbol )
4741 ( fixP->fx_frag == call_info->start_symbol->sy_frag ) ) {
4743 if ((fixP
->fx_addsy
== call_info
->start_symbol
||
4744 fixP
->fx_subsy
== call_info
->start_symbol
)
4746 (is_same_frag (fixP
->fx_frag
, call_info
->start_symbol
->sy_frag
)))
4748 call_info
->end_fix
= fixP
;
4754 for (i
= 8; i
< sizeof (unwind_tableS
); i
++)
4758 FRAG_APPEND_1_CHAR (c
);
4762 subseg_new (save_seg
, save_subseg
);
4772 register char *name
;
4776 register symbolS
*symbolP
;
4778 if (!within_procedure
)
4779 as_bad (".callinfo is not within a procedure definition");
4781 callinfo_found
= TRUE
;
4783 while (!is_end_of_statement ())
4785 name
= input_line_pointer
;
4786 c
= get_symbol_end ();
4787 if ((strncasecmp (name
, "frame", 5) == 0))
4789 p
= input_line_pointer
;
4791 input_line_pointer
++;
4792 temp
= get_absolute_expression ();
4793 if ((temp
& 0x3) != 0)
4795 as_bad ("FRAME parameter must be a multiple of 8: %d\n", temp
);
4798 last_call_info
->frame
= temp
;
4800 else if ((strncasecmp (name
, "entry_gr", 8) == 0))
4802 p
= input_line_pointer
;
4804 input_line_pointer
++;
4805 temp
= get_absolute_expression ();
4806 last_call_info
->ci_unwind
.descriptor
.entry_gr
= temp
;
4808 else if ((strncasecmp (name
, "entry_fr", 8) == 0))
4810 p
= input_line_pointer
;
4812 input_line_pointer
++;
4813 temp
= get_absolute_expression ();
4814 last_call_info
->ci_unwind
.descriptor
.entry_fr
= temp
;
4816 else if ((strncasecmp (name
, "entry_sr", 8) == 0))
4818 p
= input_line_pointer
;
4820 input_line_pointer
++;
4821 temp
= get_absolute_expression ();
4822 last_call_info
->entry_sr
= temp
;
4824 else if ((strncasecmp (name
, "calls", 5) == 0) ||
4825 (strncasecmp (name
, "caller", 6) == 0))
4827 p
= input_line_pointer
;
4829 last_call_info
->makes_calls
= 1;
4831 else if ((strncasecmp (name
, "no_calls", 8) == 0))
4833 p
= input_line_pointer
;
4835 last_call_info
->makes_calls
= 0;
4837 else if ((strncasecmp (name
, "save_rp", 7) == 0))
4839 p
= input_line_pointer
;
4841 last_call_info
->ci_unwind
.descriptor
.save_rp
= 1;
4843 else if ((strncasecmp (name
, "save_sp", 7) == 0))
4845 p
= input_line_pointer
;
4847 last_call_info
->ci_unwind
.descriptor
.save_sp
= 1;
4849 else if ((strncasecmp (name
, "no_unwind", 9) == 0))
4851 p
= input_line_pointer
;
4853 last_call_info
->ci_unwind
.descriptor
.cannot_unwind
= 1;
4855 else if ((strncasecmp (name
, "hpux_int", 7) == 0))
4857 p
= input_line_pointer
;
4859 last_call_info
->hpux_int
= 1;
4863 as_bad ("Unrecognized .CALLINFO argument: %s", name
);
4865 if (!is_end_of_statement ())
4866 input_line_pointer
++;
4869 demand_empty_rest_of_line ();
4876 space_dict_chainS
*sdchain
;
4878 if ((sdchain
= is_defined_space ("$TEXT$")) == NULL
)
4880 sdchain
= create_new_space (pa_def_spaces
[0].name
, pa_def_spaces
[0].spnum
,
4881 pa_def_spaces
[0].loadable
, pa_def_spaces
[0].defined
,
4882 pa_def_spaces
[0].private, pa_def_spaces
[0].sort
,
4883 1, pa_def_spaces
[0].segment
);
4886 SPACE_DEFINED (sdchain
) = 1;
4889 subseg_new (SEG_TEXT
, SUBSEG_CODE
);
4892 subseg_new (".text", SUBSEG_CODE
);
4895 demand_empty_rest_of_line ();
4900 * This is different than the standard GAS s_comm(). On HP9000/800 machines,
4901 * the .comm pseudo-op has the following symtax:
4903 * <label> .comm <length>
4905 * where <label> is optional and is a symbol whose address will be the start of
4906 * a block of memory <length> bytes long. <length> must be an absolute expressio
4908 * <length> bytes will be allocated in the current space and subspace.
4916 register int size
, i
;
4917 register symbolS
*symbolP
;
4918 register label_symbolS
*label_symbolP
= pa_get_label ();
4921 symbolP
= label_symbolP
->lss_label
;
4926 if ((size
= get_absolute_expression ()) < 0)
4928 as_warn (".COMMon length (%d.) <0! Ignored.", size
);
4929 ignore_rest_of_line ();
4936 if (symbolP
->pa_sy_type
== ST_STORAGE
&&
4937 symbolP
->pa_sy_scope
== SS_UNSAT
)
4939 if (symbolP
->pa_sy_value
!= size
)
4941 as_warn ("Length of .comm \"%s\" is already %d. Not changed to %d.",
4942 symbolP
->pa_sy_name
, symbolP
->pa_sy_value
, size
);
4948 symbolP
->pa_sy_value
= size
;
4949 symbolP
->pa_sy_scope
= SS_UNSAT
;
4950 symbolP
->pa_sy_type
= ST_STORAGE
;
4951 symbolP
->sy_ref
= sym_def
;
4955 if (S_IS_DEFINED (symbolP
) && S_GET_SEGMENT (symbolP
) == bss_section
)
4957 as_bad ("Ignoring attempt to re-define symbol");
4958 ignore_rest_of_line ();
4961 if (S_GET_VALUE (symbolP
))
4963 if (S_GET_VALUE (symbolP
) != size
)
4965 as_warn ("Length of .comm \"%s\" is already %d. Not changed to %d.",
4966 S_GET_NAME (symbolP
), S_GET_VALUE (symbolP
), size
);
4972 S_SET_VALUE (symbolP
, size
);
4973 S_SET_SEGMENT (symbolP
, bss_section
);
4974 S_SET_EXTERNAL (symbolP
);
4980 demand_empty_rest_of_line ();
4986 register char *name
;
4990 register symbolS
*symbolP
;
4993 if (*input_line_pointer
== '\"')
4995 ++input_line_pointer
; /* -> 1st char of string. */
4996 name
= input_line_pointer
;
4997 while ((c
= next_char_of_string ()) >= 0)
4999 c
= *input_line_pointer
;
5000 *input_line_pointer
= '\0';
5001 *(input_line_pointer
- 1) = '\0';
5004 #define PREFIX "Copyright "
5005 #define MIDFIX ". All rights reserved. No part of this program may be photocopied, reproduced, or transmitted without prior written consent of "
5008 struct aux_hdr_list
*aux_hdr_entry
;
5010 char *company_name
= name
;
5013 date_part
= (char *) index (name
, ',');
5028 len
+= strlen (date_part
) + strlen (",");
5031 aux_hdr_entry
= (struct aux_hdr_list
*) malloc (sizeof (struct aux_hdr_list
));
5034 aux_hdr_entry
->ahl_next
= aux_hdr_root
;
5035 aux_hdr_root
= aux_hdr_entry
;
5039 aux_hdr_entry
->ahl_next
= NULL
;
5040 aux_hdr_root
= aux_hdr_entry
;
5042 aux_hdr_entry
->type
= COPYRIGHT_AUX_ID
;
5043 aux_hdr_entry
->contents
.cpy
.header_id
.append
= 1;
5044 aux_hdr_entry
->contents
.cpy
.header_id
.type
= COPYRIGHT_AUX_ID
;
5045 aux_hdr_entry
->contents
.cpy
.header_id
.length
= len
+ sizeof (unsigned int);
5046 while (aux_hdr_entry
->contents
.usr_str
.header_id
.length
% 4)
5047 aux_hdr_entry
->contents
.usr_str
.header_id
.length
+= 1;
5049 aux_hdr_entry
->contents
.cpy
.string_length
= len
;
5050 aux_hdr_entry
->contents
.cpy
.copyright
= (char *) (malloc (len
+ 1));
5051 strcpy (aux_hdr_entry
->contents
.cpy
.copyright
, PREFIX
);
5052 strcat (aux_hdr_entry
->contents
.cpy
.copyright
, name
);
5055 strcat (aux_hdr_entry
->contents
.cpy
.copyright
, ",");
5056 strcat (aux_hdr_entry
->contents
.cpy
.copyright
, date_part
);
5058 strcat (aux_hdr_entry
->contents
.cpy
.copyright
, MIDFIX
);
5059 strcat (aux_hdr_entry
->contents
.cpy
.copyright
, name
);
5060 strcat (aux_hdr_entry
->contents
.cpy
.copyright
, SUFFIX
);
5061 aux_hdr_entry
->contents
.cpy
.copyright
[len
] = NULL
;
5065 #endif /* OBJ_SOM */
5067 *input_line_pointer
= c
;
5071 as_bad ("Expected \"-ed string");
5073 pa_undefine_label ();
5074 demand_empty_rest_of_line ();
5081 demand_empty_rest_of_line ();
5089 as_bad (".ENTER encountered. gas doesn't generate entry code sequences.");
5099 if (!within_procedure
)
5100 as_bad ("Misplaced .entry. Ignored.");
5103 if (!callinfo_found
)
5104 as_bad ("Missing .callinfo.");
5106 last_call_info
->start_frag
= frag_now
;
5108 demand_empty_rest_of_line ();
5109 within_entry_exit
= TRUE
;
5110 where
= frag_more (0);
5112 fix_new (frag_now
, where
- frag_now
->fr_literal
, 0,
5113 last_call_info
->start_symbol
, (symbolS
*) NULL
, 0, 0,
5114 R_ENTRY
, e_fsel
, 0, 0, (char *) &last_call_info
->ci_unwind
.descriptor
);
5117 /* XXX: no ENTRY relocation for PA ELF. What do we do instead? */
5119 fix_new_hppa (frag_now
, where
- frag_now
->fr_literal
, 0,
5120 last_call_info
->start_symbol
, (symbolS
*) NULL
, 0, 0,
5121 R_HPPA_ENTRY
, 0, 0, 0,
5122 (char *) &last_call_info
->ci_unwind
.descriptor
);
5132 register label_symbolS
*label_symbolP
= pa_get_label ();
5133 register symbolS
*symbolP
;
5137 symbolP
= label_symbolP
->lss_label
;
5139 symbolP
->pa_sy_value
= get_absolute_expression ();
5140 symbolP
->pa_sy_type
= ST_ABSOLUTE
;
5141 symbolP
->sy_ref
= sym_unref
;
5142 symbolP
->sy_equ
= 1;
5144 S_SET_VALUE (symbolP
, get_absolute_expression ());
5145 S_SET_SEGMENT (symbolP
, &bfd_abs_section
);
5151 as_bad (".REG must use a label");
5153 as_bad (".EQU must use a label");
5156 pa_undefine_label ();
5157 demand_empty_rest_of_line ();
5166 where
= frag_more (0);
5168 fix_new (frag_now
, where
- frag_now
->fr_literal
, 0,
5169 last_call_info
->start_symbol
, (symbolS
*) NULL
, 0,
5170 0, R_EXIT
, e_fsel
, 0, 0, (char *) NULL
);
5173 /* XXX: no EXIT relocation for PA ELF. All we do is create a */
5174 /* temporary symbol marking the end of the function. */
5176 char *name
= (char *) xmalloc (strlen ("L\001end_") +
5177 strlen (S_GET_NAME (last_call_info
->start_symbol
)) + 1);
5183 strcpy (name
, "L\001end_");
5184 strcat (name
, S_GET_NAME (last_call_info
->start_symbol
));
5186 symbolP
= symbol_find (name
);
5188 as_warn ("Symbol '%s' already defined.", name
);
5191 /* symbol value should be the offset of the */
5192 /* last instruction of the function */
5193 symbolP
= symbol_new (name
,
5195 (valueT
) (obstack_next_free (&frags
) - frag_now
->fr_literal
- 4),
5200 symbolP
->bsym
->flags
= last_call_info
->start_symbol
->bsym
->flags
;
5201 symbol_table_insert (symbolP
);
5204 last_call_info
->end_symbol
= symbolP
;
5206 as_bad ("Symbol '%s' could not be created.", name
);
5210 as_bad ("No memory for symbol name.");
5213 fix_new_hppa (frag_now
, where
- frag_now
->fr_literal
, 0,
5214 last_call_info
->start_symbol
, (symbolS
*) NULL
, 0,
5215 0, R_HPPA_EXIT
, 0, 0, 0, (char *) NULL
);
5217 last_call_info
->end_frag
= frag_now
;
5219 pa_build_unwind_subspace (last_call_info
);
5221 exit_processing_complete
= TRUE
;
5228 if (!within_procedure
)
5229 as_bad (".EXIT must appear within a procedure");
5232 if (!callinfo_found
)
5233 as_bad ("Missing .callinfo");
5236 if (!within_entry_exit
)
5237 as_bad ("No .ENTRY for this .EXIT");
5240 within_entry_exit
= FALSE
;
5245 demand_empty_rest_of_line ();
5252 register char *name
;
5257 register symbolS
*symbolP
;
5259 name
= input_line_pointer
;
5260 c
= get_symbol_end ();
5261 /* just after name is now '\0' */
5263 if ((symbolP
= symbol_find_or_make (name
)) == NULL
)
5265 as_bad ("Cannot define export symbol: %s\n", name
);
5266 p
= input_line_pointer
;
5268 input_line_pointer
++;
5273 symbolP
->pa_sy_dict
.symbol_scope
= SS_UNIVERSAL
;
5274 /* determination of the symbol_type field will have to wait until
5275 we know the subspace index (within the object file) of the subspace
5276 containing this symbol */
5278 /* S_SET_SEGMENT(symbolP,&bfd_und_section); */
5279 S_SET_EXTERNAL (symbolP
);
5280 /* symbolP->sy_frag = frag_now; */
5283 p
= input_line_pointer
;
5285 if (!is_end_of_statement ())
5287 input_line_pointer
++;
5288 pa_export_args (symbolP
);
5292 demand_empty_rest_of_line ();
5297 pa_export_args (symbolP
)
5298 register symbolS
*symbolP
;
5300 register char *name
;
5304 register unsigned int arg_reloc
;
5306 elf_symbol_type
*esymbolP
= (elf_symbol_type
*) (symbolP
->bsym
);
5309 if (strncasecmp (input_line_pointer
, "absolute", 8) == 0)
5311 input_line_pointer
+= 8;
5313 symbolP
->pa_sy_dict
.symbol_type
= ST_ABSOLUTE
;
5315 S_SET_SEGMENT (symbolP
, &bfd_abs_section
);
5318 else if (strncasecmp (input_line_pointer
, "code", 4) == 0)
5320 input_line_pointer
+= 4;
5322 symbolP
->pa_sy_dict
.symbol_type
= ST_CODE
;
5324 /* S_SET_SEGMENT(symbolP,text_section); */
5327 else if (strncasecmp (input_line_pointer
, "data", 4) == 0)
5329 input_line_pointer
+= 4;
5331 symbolP
->pa_sy_dict
.symbol_type
= ST_DATA
;
5333 /* S_SET_SEGMENT(symbolP,data_section); */
5336 else if ((strncasecmp (input_line_pointer
, "entry", 5) == 0))
5338 input_line_pointer
+= 5;
5340 symbolP
->pa_sy_dict
.symbol_type
= ST_ENTRY
;
5342 symbolP
->bsym
->flags
|= BSF_FUNCTION
;
5345 else if (strncasecmp (input_line_pointer
, "millicode", 9) == 0)
5347 input_line_pointer
+= 9;
5349 symbolP
->pa_sy_dict
.symbol_type
= ST_MILLICODE
;
5352 else if (strncasecmp (input_line_pointer
, "plabel", 6) == 0)
5354 input_line_pointer
+= 6;
5356 symbolP
->pa_sy_dict
.symbol_type
= ST_PLABEL
;
5359 else if (strncasecmp (input_line_pointer
, "pri_prog", 8) == 0)
5361 input_line_pointer
+= 8;
5363 symbolP
->pa_sy_dict
.symbol_type
= ST_PRI_PROG
;
5366 else if (strncasecmp (input_line_pointer
, "sec_prog", 8) == 0)
5368 input_line_pointer
+= 8;
5370 symbolP
->pa_sy_dict
.symbol_type
= ST_SEC_PROG
;
5374 while (!is_end_of_statement ())
5376 if (*input_line_pointer
== ',')
5377 input_line_pointer
++;
5378 name
= input_line_pointer
;
5379 c
= get_symbol_end ();
5380 if ((strncasecmp (name
, "argw", 4) == 0))
5382 p
= input_line_pointer
;
5384 input_line_pointer
++;
5385 temp
= atoi (name
+ 4);
5386 name
= input_line_pointer
;
5387 c
= get_symbol_end ();
5388 arg_reloc
= pa_align_arg_reloc (temp
, pa_build_arg_reloc (name
));
5390 symbolP
->pa_sy_dict
.arg_reloc
|= arg_reloc
;
5392 esymbolP
->tc_data
.hppa_arg_reloc
|= arg_reloc
;
5394 *input_line_pointer
= c
;
5396 else if ((strncasecmp (name
, "rtnval", 6)) == 0)
5398 p
= input_line_pointer
;
5400 input_line_pointer
++;
5401 name
= input_line_pointer
;
5402 c
= get_symbol_end ();
5403 arg_reloc
= pa_build_arg_reloc (name
);
5405 symbolP
->pa_sy_dict
.arg_reloc
|= arg_reloc
;
5407 esymbolP
->tc_data
.hppa_arg_reloc
|= arg_reloc
;
5409 *input_line_pointer
= c
;
5411 else if ((strncasecmp (name
, "priv_lev", 8)) == 0)
5413 p
= input_line_pointer
;
5415 input_line_pointer
++;
5416 /*** temp = get_absolute_expression (); ***/
5417 temp
= atoi (input_line_pointer
);
5418 c
= get_symbol_end ();
5419 *input_line_pointer
= c
;
5421 symbolP
->sy_priv_lev
= temp
& 3; /* this is stored in symbol_value later */
5426 as_bad ("Undefined .EXPORT/.IMPORT argument (ignored): %s", name
);
5427 p
= input_line_pointer
;
5430 if (!is_end_of_statement ())
5431 input_line_pointer
++;
5438 register char *name
;
5441 register symbolS
*symbolP
;
5442 register expressionS resultP
; /* Deliver result here. */
5444 name
= input_line_pointer
;
5445 c
= get_symbol_end ();
5446 /* just after name is now '\0' */
5448 symbolP
= symbol_find_or_make (name
);
5449 #if defined(OBJ_ELF)
5450 /* symbolP->bsym->flags |= BSF_IMPORT; *//* XXX BSF_IMPORT is obsolete */
5452 /* Check to see if this symbol has already been exported (this means its */
5453 /* defined locally and the import statement is redundant). */
5454 /* If it has not been exported, go ahead and mark this symbol as SS_UNSAT */
5455 /* (an unsatisfied external symbol) */
5457 /* But, if the symbol has already been referenced (sy_ref == TRUE),
5460 if (!symbolP
->sy_ref
)
5462 if (symbolP
->pa_sy_dict
.symbol_scope
!= SS_UNIVERSAL
)
5464 symbolP
->pa_sy_dict
.symbol_scope
= SS_UNSAT
;
5465 symbolP
->sy_ref
= FALSE
;
5470 p
= input_line_pointer
;
5473 if (!is_end_of_statement ())
5475 input_line_pointer
++;
5477 pa_export_args (symbolP
);
5479 /* In ELF, since this is an import, leave the section undefined. */
5480 /* S_SET_SEGMENT(symbolP,&bfd_und_section); */
5486 /* no further arguments, assign a default type according
5487 to the current subspace (CODE or DATA) */
5491 symbolP
->pa_sy_dict
.symbol_type
= ST_CODE
;
5494 symbolP
->pa_sy_dict
.symbol_type
= ST_ABSOLUTE
;
5497 symbolP
->pa_sy_dict
.symbol_type
= ST_DATA
;
5500 /* In ELF, if the section is undefined, then the symbol is undefined */
5501 /* Since this is an import, leave the section undefined. */
5502 S_SET_SEGMENT (symbolP
, &bfd_und_section
);
5507 demand_empty_rest_of_line ();
5514 register char *name
;
5518 name
= input_line_pointer
;
5519 c
= get_symbol_end ();
5520 /* just after name is now '\0' */
5522 if (strlen (name
) > 0)
5525 p
= input_line_pointer
;
5530 as_warn ("Missing label name on .LABEL");
5533 if (!is_end_of_statement ())
5535 as_warn ("extra .LABEL arguments ignored.");
5536 ignore_rest_of_line ();
5538 demand_empty_rest_of_line ();
5546 as_bad (".LEAVE encountered. gas doesn't generate exit code sequences.");
5554 s_org (); /* ORG actually allows another argument (the fill value)
5555 but maybe this is OK? */
5556 pa_undefine_label ();
5563 call_infoS
*call_info
;
5565 if (within_procedure
)
5566 as_fatal ("Nested procedures");
5568 callinfo_found
= FALSE
;
5569 within_procedure
= TRUE
;
5570 exit_processing_complete
= FALSE
;
5572 /* create another call_info structure */
5574 call_info
= (call_infoS
*) xmalloc (sizeof (call_infoS
));
5577 as_fatal ("Cannot allocate unwind descriptor\n");
5579 bzero (call_info
, sizeof (call_infoS
));
5581 call_info
->ci_next
= NULL
;
5583 if (call_info_root
== NULL
)
5585 call_info_root
= call_info
;
5586 last_call_info
= call_info
;
5590 last_call_info
->ci_next
= call_info
;
5591 last_call_info
= call_info
;
5594 /* set up defaults on call_info structure */
5596 call_info
->ci_unwind
.descriptor
.cannot_unwind
= 0;
5597 call_info
->ci_unwind
.descriptor
.region_desc
= 1;
5598 call_info
->entry_sr
= ~0;
5599 call_info
->makes_calls
= 1;
5600 call_info
->hpux_int
= 0;
5602 /* If we got a .PROC pseudo-op, we know that the function is defined
5603 locally. Make sure it gets into the symbol table */
5605 label_symbolS
*label_symbolP
= pa_get_label ();
5609 if (label_symbolP
->lss_label
)
5612 label_symbolP
->lss_label
->sy_ref
|= sym_def
;
5614 last_call_info
->start_symbol
= label_symbolP
->lss_label
;
5615 label_symbolP
->lss_label
->bsym
->flags
|= BSF_FUNCTION
;
5618 as_bad ("Missing function name for .PROC (corrupted label)");
5621 as_bad ("Missing function name for .PROC");
5624 demand_empty_rest_of_line ();
5632 if (!within_procedure
)
5633 as_bad ("misplaced .procend");
5635 if (!callinfo_found
)
5636 as_bad ("Missing .callinfo for this procedure");
5638 if (within_entry_exit
)
5639 as_bad ("Missing .EXIT for a .ENTRY");
5641 if (!exit_processing_complete
)
5644 within_procedure
= FALSE
;
5645 demand_empty_rest_of_line ();
5650 pa_parse_space_stmt (space_name
, create_flag
)
5654 register char *name
;
5670 space_dict_chainS
*space
;
5672 /* load default values */
5677 if (strcasecmp (space_name
, "$TEXT$") == 0)
5696 if (!is_end_of_statement ())
5698 print_errors
= FALSE
;
5699 ptemp
= input_line_pointer
+ 1;
5700 if ((temp
= pa_parse_number (&ptemp
)) >= 0)
5703 input_line_pointer
= ptemp
;
5707 while (!is_end_of_statement ())
5709 input_line_pointer
++;
5710 name
= input_line_pointer
;
5711 c
= get_symbol_end ();
5712 if ((strncasecmp (name
, "SPNUM", 5) == 0))
5714 p
= input_line_pointer
;
5716 input_line_pointer
++;
5717 temp
= get_absolute_expression ();
5720 else if ((strncasecmp (name
, "SORT", 4) == 0))
5722 p
= input_line_pointer
;
5724 input_line_pointer
++;
5725 temp
= get_absolute_expression ();
5728 else if ((strncasecmp (name
, "UNLOADABLE", 10) == 0))
5730 p
= input_line_pointer
;
5734 else if ((strncasecmp (name
, "NOTDEFINED", 10) == 0))
5736 p
= input_line_pointer
;
5740 else if ((strncasecmp (name
, "PRIVATE", 7) == 0))
5742 p
= input_line_pointer
;
5748 as_bad ("Unrecognized .SPACE argument");
5749 p
= input_line_pointer
;
5754 print_errors
= TRUE
;
5757 space
= create_new_space (space_name
, spnum
, loadable
, defined
, private, sort
, 1, seg
);
5759 { /* if no creation of new space, this must be the first */
5760 /* occurrence of a built-in space */
5761 space
= is_defined_space (space_name
);
5762 SPACE_SPNUM (space
) = spnum
;
5763 SPACE_LOADABLE (space
) = loadable
& 1;
5764 SPACE_DEFINED (space
) = defined
& 1;
5765 SPACE_PRIVATE (space
) = private & 1;
5766 SPACE_SORT (space
) = sort
& 0xff;
5767 space
->sd_defined
= 1;
5768 space
->sd_seg
= seg
;
5774 pa_align_subseg (seg
, subseg
)
5782 subspace_dict_chainS
*now_subspace
;
5786 now_subspace
= pa_subsegment_to_subspace (seg
, subseg
);
5787 if (SUBSPACE_ALIGN (now_subspace
) == 0)
5788 alignment
= now_subspace
->ssd_last_align
;
5789 else if (now_subspace
->ssd_last_align
> SUBSPACE_ALIGN (now_subspace
))
5790 alignment
= now_subspace
->ssd_last_align
;
5792 alignment
= SUBSPACE_ALIGN (now_subspace
);
5795 while ((1 << shift
) < alignment
)
5798 frag_align (shift
, 0);
5804 register char *name
;
5808 register symbolS
*symbolP
;
5809 register space_dict_chainS
*sd_chain
;
5810 char space_name
[40];
5812 if (within_procedure
)
5814 as_bad ("Can\'t change spaces within a procedure definition. Ignored");
5815 ignore_rest_of_line ();
5819 if (strncasecmp (input_line_pointer
, "$text$", 6) == 0)
5821 input_line_pointer
+= 6;
5822 sd_chain
= is_defined_space ("$TEXT$");
5823 if (sd_chain
== NULL
)
5824 sd_chain
= pa_parse_space_stmt ("$TEXT$", 1);
5825 else if (sd_chain
->sd_defined
== 0)
5826 sd_chain
= pa_parse_space_stmt ("$TEXT$", 0);
5828 current_space
= sd_chain
;
5829 SPACE_DEFINED (current_space
) = 1;
5830 current_space
->sd_defined
= 1;
5832 if (now_seg
!= SEG_TEXT
) /* no need to align if we are already there */
5834 if (now_seg
!= text_section
) /* no need to align if we are already there */
5836 pa_align_subseg (now_seg
, now_subseg
);
5839 subseg_new (SEG_TEXT
, sd_chain
->sd_last_subseg
);
5840 current_subspace
= pa_subsegment_to_subspace (SEG_TEXT
,
5841 sd_chain
->sd_last_subseg
);
5843 subseg_new ((char *) text_section
->name
, sd_chain
->sd_last_subseg
);
5844 current_subspace
= pa_subsegment_to_subspace (text_section
,
5845 sd_chain
->sd_last_subseg
);
5847 demand_empty_rest_of_line ();
5850 if (strncasecmp (input_line_pointer
, "$private$", 9) == 0)
5852 input_line_pointer
+= 9;
5853 sd_chain
= is_defined_space ("$PRIVATE$");
5854 if (sd_chain
== NULL
)
5855 sd_chain
= pa_parse_space_stmt ("$PRIVATE$", 1);
5856 else if (sd_chain
->sd_defined
== 0)
5857 sd_chain
= pa_parse_space_stmt ("$PRIVATE$", 0);
5859 current_space
= sd_chain
;
5860 SPACE_DEFINED (current_space
) = 1;
5861 current_space
->sd_defined
= 1;
5863 if (now_seg
!= SEG_DATA
) /* no need to align if we are already there */
5865 if (now_seg
!= data_section
) /* no need to align if we are already there */
5867 pa_align_subseg (now_seg
, now_subseg
);
5869 subseg_new (SEG_DATA
, sd_chain
->sd_last_subseg
);
5870 current_subspace
= pa_subsegment_to_subspace (SEG_DATA
,
5871 sd_chain
->sd_last_subseg
);
5873 subseg_new ((char *) data_section
->name
, sd_chain
->sd_last_subseg
);
5874 current_subspace
= pa_subsegment_to_subspace (data_section
,
5875 sd_chain
->sd_last_subseg
);
5877 demand_empty_rest_of_line ();
5880 if (strncasecmp (input_line_pointer
,
5881 GDB_DEBUG_SPACE_NAME
, strlen (GDB_DEBUG_SPACE_NAME
)) == 0)
5883 input_line_pointer
+= strlen (GDB_DEBUG_SPACE_NAME
);
5884 sd_chain
= is_defined_space (GDB_DEBUG_SPACE_NAME
);
5885 if (sd_chain
== NULL
)
5886 sd_chain
= pa_parse_space_stmt (GDB_DEBUG_SPACE_NAME
, 1);
5887 else if (sd_chain
->sd_defined
== 0)
5888 sd_chain
= pa_parse_space_stmt (GDB_DEBUG_SPACE_NAME
, 0);
5890 current_space
= sd_chain
;
5891 SPACE_DEFINED (current_space
) = 1;
5892 current_space
->sd_defined
= 1;
5894 if (now_seg
!= SEG_GDB
) /* no need to align if we are already there */
5895 pa_align_subseg (now_seg
, now_subseg
);
5896 subseg_new (SEG_GDB
, sd_chain
->sd_last_subseg
);
5897 current_subspace
= pa_subsegment_to_subspace (SEG_GDB
,
5898 sd_chain
->sd_last_subseg
);
5900 if (now_seg
!= gdb_section
) /* no need to align if we are already there */
5901 pa_align_subseg (now_seg
, now_subseg
);
5902 subseg_new ((char *) gdb_section
->name
, sd_chain
->sd_last_subseg
);
5903 current_subspace
= pa_subsegment_to_subspace (gdb_section
,
5904 sd_chain
->sd_last_subseg
);
5906 demand_empty_rest_of_line ();
5910 /* it could be a space specified by number */
5912 if ((temp
= pa_parse_number (&input_line_pointer
)) >= 0)
5914 if (sd_chain
= pa_find_space_by_number (temp
))
5916 current_space
= sd_chain
;
5917 SPACE_DEFINED (current_space
) = 1;
5918 current_space
->sd_defined
= 1;
5919 if (now_seg
!= sd_chain
->sd_seg
) /* don't align if we're already there */
5920 pa_align_subseg (now_seg
, now_subseg
);
5922 subseg_new (sd_chain
->sd_seg
, sd_chain
->sd_last_subseg
);
5924 subseg_new ((char *) sd_chain
->sd_seg
->name
, sd_chain
->sd_last_subseg
);
5926 current_subspace
= pa_subsegment_to_subspace (sd_chain
->sd_seg
,
5927 sd_chain
->sd_last_subseg
);
5928 demand_empty_rest_of_line ();
5933 /* not a number, attempt to create a new space */
5935 name
= input_line_pointer
;
5936 c
= get_symbol_end ();
5937 space_name
[0] = 0x00;
5938 strcpy (space_name
, name
);
5939 *input_line_pointer
= c
;
5941 sd_chain
= pa_parse_space_stmt (space_name
, 1);
5942 current_space
= sd_chain
;
5943 SPACE_DEFINED (current_space
) = 1;
5944 current_space
->sd_defined
= 1;
5945 if (now_seg
!= sd_chain
->sd_seg
) /* don't align if we're already there */
5946 pa_align_subseg (now_seg
, now_subseg
);
5948 subseg_new (sd_chain
->sd_seg
, sd_chain
->sd_last_subseg
);
5950 subseg_new ((char *) sd_chain
->sd_seg
->name
, sd_chain
->sd_last_subseg
);
5952 current_subspace
= pa_subsegment_to_subspace (sd_chain
->sd_seg
,
5953 sd_chain
->sd_last_subseg
);
5954 demand_empty_rest_of_line ();
5962 register char *name
;
5965 space_dict_chainS
*space
;
5967 name
= input_line_pointer
;
5968 c
= get_symbol_end ();
5969 space
= is_defined_space (name
);
5973 /* put bytes in right order. */
5974 md_number_to_chars (p
, SPACE_SPNUM (space
), 4);
5977 as_warn ("Undefined space: '%s' Assuming space number = 0.", name
);
5979 *input_line_pointer
= c
;
5980 demand_empty_rest_of_line ();
5986 is_power_of_2 (value
)
5992 while ((1 << shift
) != value
&& shift
< 32)
6003 register char *name
;
6007 register symbolS
*symbolP
;
6009 char loadable
, code_only
, common
, dup_common
, zero
;
6018 space_dict_chainS
*space
;
6019 subspace_dict_chainS
*ssd
;
6020 subspace_dict_chainS
*ssdCh
;
6022 int is_power_of_2 ();
6024 if (within_procedure
)
6026 as_bad ("Can\'t change subspaces within a procedure definition. Ignored");
6027 ignore_rest_of_line ();
6031 name
= input_line_pointer
;
6032 c
= get_symbol_end ();
6033 space
= pa_segment_to_space (now_seg
);
6034 ssd
= is_defined_subspace (name
, space
->sd_last_subseg
);
6036 ss_name
= xmalloc (strlen (name
) + 1);
6037 strcpy (ss_name
, name
);
6039 *input_line_pointer
= c
;
6041 /* load default values */
6049 space_index
= ~0; /* filled in when the .o file is written */
6050 alignment
= 0; /* alignment=0 means no ALIGN= appeared on the .SUBSPA */
6051 /* pseudo-op. The default will be the largest .ALIGN */
6052 /* encountered (or 1 if no .ALIGN is encountered) */
6057 if (ssd
->ssd_defined
)
6060 subseg_new (now_seg
, ssd
->ssd_subseg
);
6062 /* subseg_new(now_seg->name,ssd->ssd_subseg); */
6063 subseg_new ((char *) ssd
->ssd_seg
->name
, ssd
->ssd_subseg
);
6065 if (!is_end_of_statement ())
6067 as_warn ("Parameters of an existing subspace can\'t be modified");
6069 demand_empty_rest_of_line ();
6074 ssd
->ssd_defined
= 1;
6079 /* a new subspace */
6080 /* load default values */
6082 while (pa_def_subspaces
[i
].name
)
6084 if (strcasecmp (pa_def_subspaces
[i
].name
, ss_name
) == 0)
6086 loadable
= pa_def_subspaces
[i
].loadable
;
6087 common
= pa_def_subspaces
[i
].common
;
6088 dup_common
= pa_def_subspaces
[i
].dup_common
;
6089 code_only
= pa_def_subspaces
[i
].code_only
;
6090 zero
= pa_def_subspaces
[i
].zero
;
6091 space_index
= pa_def_subspaces
[i
].space_index
;
6092 /* alignment = pa_def_subspaces[i].alignment; */
6094 quadrant
= pa_def_subspaces
[i
].quadrant
;
6095 access
= pa_def_subspaces
[i
].access
;
6096 sort
= pa_def_subspaces
[i
].sort
;
6103 if (!is_end_of_statement ())
6105 input_line_pointer
++;
6106 while (!is_end_of_statement ())
6108 name
= input_line_pointer
;
6109 c
= get_symbol_end ();
6110 if ((strncasecmp (name
, "QUAD", 4) == 0))
6112 *input_line_pointer
= c
;
6113 input_line_pointer
++;
6114 temp
= get_absolute_expression ();
6117 else if ((strncasecmp (name
, "ALIGN", 5) == 0))
6119 *input_line_pointer
= c
;
6120 input_line_pointer
++;
6121 temp
= get_absolute_expression ();
6123 if (!is_power_of_2 (alignment
))
6125 as_bad ("Alignment must be a power of 2");
6129 else if ((strncasecmp (name
, "ACCESS", 6) == 0))
6131 *input_line_pointer
= c
;
6132 input_line_pointer
++;
6133 temp
= get_absolute_expression ();
6136 else if ((strncasecmp (name
, "SORT", 4) == 0))
6138 *input_line_pointer
= c
;
6139 input_line_pointer
++;
6140 temp
= get_absolute_expression ();
6143 else if ((strncasecmp (name
, "CODE_ONLY", 9) == 0))
6145 *input_line_pointer
= c
;
6148 else if ((strncasecmp (name
, "UNLOADABLE", 10) == 0))
6150 *input_line_pointer
= c
;
6153 else if ((strncasecmp (name
, "COMMON", 6) == 0))
6155 *input_line_pointer
= c
;
6158 else if ((strncasecmp (name
, "DUP_COMM", 8) == 0))
6160 *input_line_pointer
= c
;
6163 else if ((strncasecmp (name
, "ZERO", 4) == 0))
6165 *input_line_pointer
= c
;
6170 as_bad ("Unrecognized .SUBSPACE argument");
6172 if (!is_end_of_statement ())
6173 input_line_pointer
++;
6176 space
= pa_segment_to_space (now_seg
);
6179 current_subspace
= update_subspace (ss_name
, 1, loadable
, code_only
,
6180 common
, dup_common
, sort
, zero
, access
,
6181 space_index
, alignment
, quadrant
,
6186 current_subspace
= create_new_subspace (space
, ss_name
, 1, loadable
, code_only
,
6187 common
, dup_common
, zero
, sort
,
6188 access
, space_index
, alignment
,
6191 SUBSPACE_SUBSPACE_START (current_subspace
) = pa_subspace_start (space
, quadrant
);
6193 demand_empty_rest_of_line ();
6195 subseg_new (current_subspace
->ssd_seg
, current_subspace
->ssd_subseg
);
6197 subseg_new ((char *) current_subspace
->ssd_seg
->name
, current_subspace
->ssd_subseg
);
6203 /* For ELF, this function serves one purpose: to setup the st_size */
6204 /* field of STT_FUNC symbols. To do this, we need to scan the */
6205 /* call_info structure list, determining st_size in one of two possible */
6208 /* 1. call_info->start_frag->fr_fix has the size of the fragment. */
6209 /* This approach assumes that the function was built into a */
6210 /* single fragment. This works for most cases, but might fail. */
6211 /* For example, if there was a segment change in the middle of */
6214 /* 2. The st_size field is the difference in the addresses of the */
6215 /* call_info->start_frag->fr_address field and the fr_address */
6216 /* field of the next fragment with fr_type == rs_fill and */
6220 elf_hppa_final_processing_hook ()
6222 extern call_infoS
*call_info_root
;
6226 for (ciP
= call_info_root
; ciP
; ciP
= ciP
->ci_next
)
6228 elf_symbol_type
*esym
= (elf_symbol_type
*) ciP
->start_symbol
->bsym
;
6229 esym
->internal_elf_sym
.st_size
=
6230 ciP
->end_symbol
->bsym
->value
6231 - ciP
->start_symbol
->bsym
->value
+ 4;
6235 /* pa-spaces.c -- Space/subspace support for the HP PA-RISC version of GAS */
6237 /* for space, subspace, and symbol maintenance on HP 9000 Series 800 */
6239 space_dict_chainS
*space_dict_root
;
6240 space_dict_chainS
*space_dict_last
;
6242 space_dict_chainS
*current_space
;
6243 subspace_dict_chainS
*current_subspace
;
6245 extern symbolS
*start_symbol_root
;
6246 extern symbolS
*start_symbol_last
;
6251 space_dict_chainS
*space
;
6253 subsegT now_subseg
= now_subseg
;
6255 space_dict_root
= NULL
;
6256 space_dict_last
= NULL
;
6258 start_symbol_root
= NULL
;
6259 start_symbol_last
= NULL
;
6261 /* create default space and subspace dictionaries */
6264 while (pa_def_spaces
[i
].name
)
6266 if (pa_def_spaces
[i
].alias
)
6267 pa_def_spaces
[i
].segment
= subseg_new (pa_def_spaces
[i
].alias
, 0);
6269 pa_def_spaces
[i
].segment
= bfd_make_section_old_way (stdoutput
, pa_def_spaces
[i
].name
);
6271 create_new_space (pa_def_spaces
[i
].name
, pa_def_spaces
[i
].spnum
,
6272 pa_def_spaces
[i
].loadable
, pa_def_spaces
[i
].defined
,
6273 pa_def_spaces
[i
].private, pa_def_spaces
[i
].sort
, 0,
6274 pa_def_spaces
[i
].segment
);
6279 while (pa_def_subspaces
[i
].name
)
6281 space
= pa_segment_to_space (pa_def_spaces
[pa_def_subspaces
[i
].def_space_index
].segment
);
6284 char *name
= pa_def_subspaces
[i
].alias
;
6286 name
= pa_def_subspaces
[i
].name
;
6287 create_new_subspace (space
, name
,
6288 pa_def_subspaces
[i
].defined
,
6289 pa_def_subspaces
[i
].loadable
,
6290 pa_def_subspaces
[i
].code_only
, pa_def_subspaces
[i
].common
,
6291 pa_def_subspaces
[i
].dup_common
, pa_def_subspaces
[i
].zero
,
6292 pa_def_subspaces
[i
].sort
, pa_def_subspaces
[i
].access
,
6293 pa_def_subspaces
[i
].space_index
,
6294 pa_def_subspaces
[i
].alignment
,
6295 pa_def_subspaces
[i
].quadrant
,
6296 pa_def_spaces
[pa_def_subspaces
[i
].def_space_index
].segment
);
6297 subseg_new (name
, pa_def_subspaces
[i
].subsegment
);
6300 as_fatal ("Internal error: space missing for subspace \"%s\"\n",
6301 pa_def_subspaces
[i
].name
);
6307 create_new_space (name
, spnum
, loadable
, defined
, private, sort
, defined_in_file
, seg
)
6314 char defined_in_file
;
6318 Elf_Internal_Shdr
*new_space
;
6319 space_dict_chainS
*chain_entry
;
6321 new_space
= (Elf_Internal_Shdr
*) xmalloc (sizeof (Elf_Internal_Shdr
));
6323 as_fatal ("Out of memory: could not allocate new Elf_Internal_Shdr: %s\n", name
);
6326 new_space->space_number = spnum;
6327 new_space->is_loadable = loadable & 1;
6328 new_space->is_defined = defined & 1;
6329 new_space->is_private = private & 1;
6330 new_space->sort_key = sort & 0xff;
6332 new_space->loader_fix_index = ~0;
6333 new_space->loader_fix_quantity = 0;
6334 new_space->init_pointer_index = ~0;
6335 new_space->init_pointer_quantity = 0;
6336 new_space->subspace_quantity = 0;
6339 chain_entry
= (space_dict_chainS
*) xmalloc (sizeof (space_dict_chainS
));
6341 as_fatal ("Out of memory: could not allocate new space chain entry: %s\n", name
);
6343 SPACE_NAME (chain_entry
) = (char *) xmalloc (strlen (name
) + 1);
6344 strcpy (SPACE_NAME (chain_entry
), name
);
6346 chain_entry
->sd_entry
= new_space
;
6347 chain_entry
->sd_defined
= defined_in_file
;
6348 chain_entry
->sd_seg
= seg
;
6349 chain_entry
->sd_last_subseg
= -1;
6350 chain_entry
->sd_next
= NULL
;
6352 SPACE_SPNUM (chain_entry
) = spnum
;
6353 SPACE_LOADABLE (chain_entry
) = loadable
& 1;
6354 SPACE_DEFINED (chain_entry
) = defined
& 1;
6355 SPACE_PRIVATE (chain_entry
) = private & 1;
6356 SPACE_SORT (chain_entry
) = sort
& 0xff;
6358 /* find spot for the new space based on its sort key */
6360 if (!space_dict_last
)
6361 space_dict_last
= chain_entry
;
6363 if (space_dict_root
== NULL
) /* if root is null, it is very easy */
6364 space_dict_root
= chain_entry
;
6367 space_dict_chainS
*sdcP
;
6368 space_dict_chainS
*last_sdcP
;
6370 sdcP
= space_dict_root
;
6375 if (SPACE_SORT (sdcP
) < SPACE_SORT (chain_entry
))
6378 sdcP
= sdcP
->sd_next
;
6380 else if (SPACE_SORT (sdcP
) == SPACE_SORT (chain_entry
))
6383 sdcP
= sdcP
->sd_next
;
6385 else if (SPACE_SORT (sdcP
) > SPACE_SORT (chain_entry
))
6393 chain_entry
->sd_next
= sdcP
;
6394 last_sdcP
->sd_next
= chain_entry
;
6398 space_dict_root
= chain_entry
;
6399 chain_entry
->sd_next
= sdcP
;
6402 if (chain_entry
->sd_next
== NULL
)
6403 space_dict_last
= chain_entry
;
6409 subspace_dict_chainS
6410 * create_new_subspace (space
, name
, defined
, loadable
, code_only
, common
, dup_common
,
6411 is_zero
, sort
, access
, space_index
, alignment
, quadrant
, seg
)
6412 space_dict_chainS
*space
;
6414 char defined
, loadable
, code_only
, common
, dup_common
, is_zero
;
6422 Elf_Internal_Shdr
*new_subspace
;
6423 subspace_dict_chainS
*chain_entry
;
6424 symbolS
*start_symbol
;
6426 new_subspace
= (Elf_Internal_Shdr
*) xmalloc (sizeof (Elf_Internal_Shdr
));
6428 as_fatal ("Out of memory: could not allocate new Elf_Internal_Shdr: %s\n",
6432 new_subspace->space_index = space_index;
6433 new_subspace->fixup_request_index = ~0;
6436 chain_entry
= (subspace_dict_chainS
*) xmalloc (sizeof (subspace_dict_chainS
));
6438 as_fatal ("Out of memory: could not allocate new subspace chain entry: %s\n", name
);
6440 chain_entry
->ssd_entry
= new_subspace
;
6441 SUBSPACE_NAME (chain_entry
) = (char *) xmalloc (strlen (name
) + 1);
6442 strcpy (SUBSPACE_NAME (chain_entry
), name
);
6444 SUBSPACE_ACCESS (chain_entry
) = access
& 0x7f;
6445 SUBSPACE_LOADABLE (chain_entry
) = loadable
& 1;
6446 SUBSPACE_COMMON (chain_entry
) = common
& 1;
6447 SUBSPACE_DUP_COMM (chain_entry
) = dup_common
& 1;
6448 SUBSPACE_SORT (chain_entry
) = sort
& 0xff;
6449 SET_SUBSPACE_CODE_ONLY (chain_entry
, code_only
& 1);
6450 SUBSPACE_ALIGN (chain_entry
) = alignment
& 0xffff;
6451 SUBSPACE_QUADRANT (chain_entry
) = quadrant
& 0x3;
6452 SUBSPACE_SUBSPACE_START (chain_entry
) = pa_subspace_start (space
, quadrant
);
6454 chain_entry
->ssd_defined
= defined
;
6455 chain_entry
->ssd_space_number
= space_index
;
6456 chain_entry
->ssd_subseg
= pa_next_subseg (space
);
6457 chain_entry
->ssd_seg
= seg
;
6458 SUBSPACE_ZERO (chain_entry
) = is_zero
;
6459 chain_entry
->ssd_last_align
= 1;
6460 chain_entry
->ssd_next
= NULL
;
6462 /* find spot for the new subspace based on its sort key */
6464 if (space
->sd_subspaces
== NULL
) /* if root is null, it is very easy */
6465 space
->sd_subspaces
= chain_entry
;
6468 subspace_dict_chainS
*ssdcP
;
6469 subspace_dict_chainS
*last_ssdcP
;
6471 ssdcP
= space
->sd_subspaces
;
6476 if (SUBSPACE_SORT (ssdcP
) < SUBSPACE_SORT (chain_entry
))
6479 ssdcP
= ssdcP
->ssd_next
;
6481 else if (SUBSPACE_SORT (ssdcP
) == SUBSPACE_SORT (chain_entry
))
6484 ssdcP
= ssdcP
->ssd_next
;
6486 else if (SUBSPACE_SORT (ssdcP
) > SUBSPACE_SORT (chain_entry
))
6494 chain_entry
->ssd_next
= ssdcP
;
6495 last_ssdcP
->ssd_next
= chain_entry
;
6499 space
->sd_subspaces
= chain_entry
;
6500 chain_entry
->ssd_next
= ssdcP
;
6504 start_symbol
= pa_set_start_symbol (seg
, space
->sd_last_subseg
);
6505 chain_entry
->ssd_start_sym
= start_symbol
;
6510 subspace_dict_chainS
6511 * update_subspace (name
, defined
, loadable
, code_only
, common
, dup_common
, sort
, zero
,
6512 access
, space_index
, alignment
, quadrant
, subseg
)
6514 char defined
, loadable
, code_only
, common
, dup_common
, zero
;
6522 subspace_dict_chainS
*chain_entry
;
6523 subspace_dict_chainS
*is_defined_subspace ();
6525 if ((chain_entry
= is_defined_subspace (name
, subseg
)))
6528 SUBSPACE_ACCESS (chain_entry
) = access
& 0x7f;
6529 SUBSPACE_LOADABLE (chain_entry
) = loadable
& 1;
6530 SUBSPACE_COMMON (chain_entry
) = common
& 1;
6531 SUBSPACE_DUP_COMM (chain_entry
) = dup_common
& 1;
6532 SET_SUBSPACE_CODE_ONLY (chain_entry
, code_only
& 1);
6533 SUBSPACE_SORT (chain_entry
) = sort
& 0xff;
6534 /* chain_entry->ssd_entry->space_index = space_index; */
6535 SUBSPACE_ALIGN (chain_entry
) = alignment
& 0xffff;
6536 SUBSPACE_QUADRANT (chain_entry
) = quadrant
& 0x3;
6538 chain_entry
->ssd_defined
= defined
;
6539 chain_entry
->ssd_space_number
= space_index
;
6540 SUBSPACE_ZERO (chain_entry
) = zero
;
6550 is_defined_space (name
)
6553 space_dict_chainS
*spaceCh
;
6555 for (spaceCh
= space_dict_root
; spaceCh
; spaceCh
= spaceCh
->sd_next
)
6557 if (strcmp (SPACE_NAME (spaceCh
), name
) == 0)
6567 pa_segment_to_space (seg
)
6570 space_dict_chainS
*spaceCh
;
6572 for (spaceCh
= space_dict_root
; spaceCh
; spaceCh
= spaceCh
->sd_next
)
6574 if (spaceCh
->sd_seg
== seg
)
6583 subspace_dict_chainS
*
6584 is_defined_subspace (name
, subseg
)
6588 space_dict_chainS
*spaceCh
;
6589 subspace_dict_chainS
*subspCh
;
6591 for (spaceCh
= space_dict_root
; spaceCh
; spaceCh
= spaceCh
->sd_next
)
6593 for (subspCh
= spaceCh
->sd_subspaces
; subspCh
; subspCh
= subspCh
->ssd_next
)
6596 if ( strcmp(SUBSPACE_NAME(subspCh),name) == 0 &&
6597 subspCh->ssd_subseg == subseg ) {
6599 if (strcmp (SUBSPACE_NAME (subspCh
), name
) == 0)
6608 subspace_dict_chainS
*
6609 pa_subsegment_to_subspace (seg
, subseg
)
6613 space_dict_chainS
*spaceCh
;
6614 subspace_dict_chainS
*subspCh
;
6616 for (spaceCh
= space_dict_root
; spaceCh
; spaceCh
= spaceCh
->sd_next
)
6618 if (spaceCh
->sd_seg
== seg
)
6620 for (subspCh
= spaceCh
->sd_subspaces
; subspCh
; subspCh
= subspCh
->ssd_next
)
6622 if (subspCh
->ssd_subseg
== (int) subseg
)
6634 pa_find_space_by_number (number
)
6637 space_dict_chainS
*spaceCh
;
6639 for (spaceCh
= space_dict_root
; spaceCh
; spaceCh
= spaceCh
->sd_next
)
6641 if (SPACE_SPNUM (spaceCh
) == number
)
6651 pa_subspace_start (space
, quadrant
)
6652 space_dict_chainS
*space
;
6655 if ((strcasecmp (SPACE_NAME (space
), "$PRIVATE$") == 0) &&
6660 else if (space
->sd_seg
== data_section
&& quadrant
== 1)
6661 { /* in case name is */
6662 /* already converted */
6663 /* to a space dict- */
6672 pa_next_subseg (space
)
6673 space_dict_chainS
*space
;
6676 space
->sd_last_subseg
++;
6677 return space
->sd_last_subseg
;
6681 is_last_defined_subspace (ssd
)
6682 subspace_dict_chainS
*ssd
;
6685 for (; ssd
; ssd
= ssd
->ssd_next
)
6687 if (ssd
->ssd_defined
)
6695 pa_get_start_symbol (seg
, subseg
)
6699 symbolS
*start_symbol
;
6700 subspace_dict_chainS
*ssd
;
6702 start_symbol
= NULL
;
6704 /* each time a new space is created, build a symbol called LS$START_seg_subseg$ */
6705 /* where <space-name> is the name of the space */
6706 /* the start symbol will be SS_LOCAL and ST_CODE */
6708 if (seg
== bfd_make_section_old_way (stdoutput
, ".text") ||
6709 seg
== bfd_make_section_old_way (stdoutput
, ".data") ||
6710 seg
== bfd_make_section_old_way (stdoutput
, GDB_DEBUG_SPACE_NAME
))
6712 ssd
= pa_subsegment_to_subspace (seg
, subseg
);
6715 start_symbol
= ssd
->ssd_start_sym
;
6718 as_fatal ("Internal error: missing subspace for (seg,subseg)=('%s',%d)",
6722 as_fatal ("Internal error: attempt to find start symbol for unloadable segment: '%s'",
6725 return start_symbol
;
6729 Function to define a symbol whose address is the beginning of a subspace.
6730 This function assumes the symbol is to be defined for the current subspace.
6734 pa_set_start_symbol (seg
, subseg
)
6738 symbolS
*start_symbol
;
6739 subspace_dict_chainS
*ssd
;
6742 symbol_name
= (char *) xmalloc (strlen ("LS$START__000000$") + strlen (seg
->name
) + 1);
6744 sprintf (symbol_name
, "LS$START_%s_%03d$", seg
->name
, subseg
);
6747 = symbol_new (symbol_name
, seg
, 0, frag_now
); /* XXX: not sure if value s.b. 0 or frag s.b. NULL */
6749 start_symbol
->bsym
->flags
= BSF_LOCAL
; /* XXX: isn't there a macro defined for this? */
6751 /* each time a new space is created, build a symbol called LS$START_seg_subseg$ */
6752 /* where <space-name> is the name of the space */
6753 /* the start symbol will be SS_LOCAL and ST_CODE */
6754 /* This function assumes that (seg,subseg) is a new subsegment(subspace) */
6756 if (seg
== bfd_make_section_old_way (stdoutput
, ".text") ||
6757 seg
== bfd_make_section_old_way (stdoutput
, ".data") ||
6758 seg
== bfd_make_section_old_way (stdoutput
, GDB_DEBUG_SPACE_NAME
))
6760 ssd
= pa_subsegment_to_subspace (seg
, subseg
);
6763 ssd
->ssd_start_sym
= start_symbol
;
6766 as_fatal ("Internal error: missing subspace for (seg,subseg)=('%s',%d)",
6770 as_fatal ("Internal error: attempt to define start symbol for unloadable segment: '%s'",
6773 return start_symbol
;
6780 unsigned int c
= *s
& CHAR_MASK
;
6793 pa_stringer (append_zero
) /* Worker to do .ascii etc statements. */
6794 /* Checks end-of-line. */
6795 register int append_zero
; /* 0: don't append '\0', else 1 */
6802 /* Preprocess the string to handle PA-specific escape sequences. */
6803 /* For example, \xDD where DD is a hexidecimal number should be */
6804 /* changed to \OOO where OOO is an octal number. */
6806 s
= input_line_pointer
+ 1; /* skip the opening quote */
6808 while (is_a_char (c
= pa_stringer_aux (s
++)))
6817 unsigned int number
;
6822 s
++; /* get past the 'x' */
6823 for (num_digit
= 0, number
= 0, dg
= *s
;
6825 && (isdigit (dg
) || (dg
>= 'a' && dg
<= 'f')
6826 || (dg
>= 'A' && dg
<= 'F'));
6830 number
= number
* 16 + dg
- '0';
6831 else if (dg
>= 'a' && dg
<= 'f')
6832 number
= number
* 16 + dg
- 'a' + 10;
6834 number
= number
* 16 + dg
- 'A' + 10;
6844 sprintf (num_buf
, "%02o", number
);
6847 sprintf (num_buf
, "%03o", number
);
6850 for (i
= 0; i
<= num_digit
; i
++)
6851 s_start
[i
] = num_buf
[i
];
6858 stringer (append_zero
);
6859 pa_undefine_label ();
6868 pa_undefine_label ();
6873 register unsigned int nbytes
; /* 1=.byte, 2=.word, 4=.long */
6876 pa_undefine_label ();
6883 pa_undefine_label ();
6893 pa_undefine_label ();
6897 pa_float_cons (float_type
)
6898 register int float_type
; /* 'f':.ffloat ... 'F':.float ... */
6900 float_cons (float_type
);
6901 pa_undefine_label ();
6908 pa_undefine_label ();
6912 pa_lcomm (needs_align
)
6913 /* 1 if this was a ".bss" directive, which may require a 3rd argument
6914 (alignment); 0 if it was an ".lcomm" (2 args only) */
6917 s_lcomm (needs_align
);
6918 pa_undefine_label ();
6925 pa_undefine_label ();
6929 pa_big_cons (nbytes
)
6930 register int nbytes
;
6933 pa_undefine_label ();
6940 pa_undefine_label ();