1 /* tc-alpha.c - Processor-specific code for the DEC Alpha AXP CPU.
2 Copyright 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 2001, 2002 Free Software Foundation, Inc.
4 Contributed by Carnegie Mellon University, 1993.
5 Written by Alessandro Forin, based on earlier gas-1.38 target CPU files.
6 Modified by Ken Raeburn for gas-2.x and ECOFF support.
7 Modified by Richard Henderson for ELF support.
8 Modified by Klaus K"ampf for EVAX (OpenVMS/Alpha) support.
10 This file is part of GAS, the GNU Assembler.
12 GAS is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2, or (at your option)
17 GAS is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
22 You should have received a copy of the GNU General Public License
23 along with GAS; see the file COPYING. If not, write to the Free
24 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
28 * Mach Operating System
29 * Copyright (c) 1993 Carnegie Mellon University
30 * All Rights Reserved.
32 * Permission to use, copy, modify and distribute this software and its
33 * documentation is hereby granted, provided that both the copyright
34 * notice and this permission notice appear in all copies of the
35 * software, derivative works or modified versions, and any portions
36 * thereof, and that both notices appear in supporting documentation.
38 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
39 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
40 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
42 * Carnegie Mellon requests users of this software to return to
44 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
45 * School of Computer Science
46 * Carnegie Mellon University
47 * Pittsburgh PA 15213-3890
49 * any improvements or extensions that they make and grant Carnegie the
50 * rights to redistribute these changes.
55 #include "struc-symbol.h"
58 #include "opcode/alpha.h"
61 #include "elf/alpha.h"
62 #include "dwarf2dbg.h"
65 #include "safe-ctype.h"
69 #define TOKENIZE_ERROR -1
70 #define TOKENIZE_ERROR_REPORT -2
72 #define MAX_INSN_FIXUPS 2
73 #define MAX_INSN_ARGS 5
77 bfd_reloc_code_real_type reloc
;
83 struct alpha_fixup fixups
[MAX_INSN_FIXUPS
];
87 enum alpha_macro_arg
{
99 void (*emit
) PARAMS ((const expressionS
*, int, const PTR
));
101 enum alpha_macro_arg argsets
[16];
104 /* Extra expression types. */
106 #define O_pregister O_md1 /* O_register, in parentheses */
107 #define O_cpregister O_md2 /* + a leading comma */
109 /* The alpha_reloc_op table below depends on the ordering of these. */
110 #define O_literal O_md3 /* !literal relocation */
111 #define O_lituse_addr O_md4 /* !lituse_addr relocation */
112 #define O_lituse_base O_md5 /* !lituse_base relocation */
113 #define O_lituse_bytoff O_md6 /* !lituse_bytoff relocation */
114 #define O_lituse_jsr O_md7 /* !lituse_jsr relocation */
115 #define O_lituse_tlsgd O_md8 /* !lituse_tlsgd relocation */
116 #define O_lituse_tlsldm O_md9 /* !lituse_tlsldm relocation */
117 #define O_gpdisp O_md10 /* !gpdisp relocation */
118 #define O_gprelhigh O_md11 /* !gprelhigh relocation */
119 #define O_gprellow O_md12 /* !gprellow relocation */
120 #define O_gprel O_md13 /* !gprel relocation */
121 #define O_samegp O_md14 /* !samegp relocation */
122 #define O_tlsgd O_md15 /* !tlsgd relocation */
123 #define O_tlsldm O_md16 /* !tlsldm relocation */
124 #define O_gotdtprel O_md17 /* !gotdtprel relocation */
125 #define O_dtprelhi O_md18 /* !dtprelhi relocation */
126 #define O_dtprello O_md19 /* !dtprello relocation */
127 #define O_dtprel O_md20 /* !dtprel relocation */
128 #define O_gottprel O_md21 /* !gottprel relocation */
129 #define O_tprelhi O_md22 /* !tprelhi relocation */
130 #define O_tprello O_md23 /* !tprello relocation */
131 #define O_tprel O_md24 /* !tprel relocation */
133 #define DUMMY_RELOC_LITUSE_ADDR (BFD_RELOC_UNUSED + 1)
134 #define DUMMY_RELOC_LITUSE_BASE (BFD_RELOC_UNUSED + 2)
135 #define DUMMY_RELOC_LITUSE_BYTOFF (BFD_RELOC_UNUSED + 3)
136 #define DUMMY_RELOC_LITUSE_JSR (BFD_RELOC_UNUSED + 4)
137 #define DUMMY_RELOC_LITUSE_TLSGD (BFD_RELOC_UNUSED + 5)
138 #define DUMMY_RELOC_LITUSE_TLSLDM (BFD_RELOC_UNUSED + 6)
140 #define USER_RELOC_P(R) ((R) >= O_literal && (R) <= O_tprel)
142 /* Macros for extracting the type and number of encoded register tokens */
144 #define is_ir_num(x) (((x) & 32) == 0)
145 #define is_fpr_num(x) (((x) & 32) != 0)
146 #define regno(x) ((x) & 31)
148 /* Something odd inherited from the old assembler */
150 #define note_gpreg(R) (alpha_gprmask |= (1 << (R)))
151 #define note_fpreg(R) (alpha_fprmask |= (1 << (R)))
153 /* Predicates for 16- and 32-bit ranges */
154 /* XXX: The non-shift version appears to trigger a compiler bug when
155 cross-assembling from x86 w/ gcc 2.7.2. */
158 #define range_signed_16(x) \
159 (((offsetT) (x) >> 15) == 0 || ((offsetT) (x) >> 15) == -1)
160 #define range_signed_32(x) \
161 (((offsetT) (x) >> 31) == 0 || ((offsetT) (x) >> 31) == -1)
163 #define range_signed_16(x) ((offsetT) (x) >= -(offsetT) 0x8000 && \
164 (offsetT) (x) <= (offsetT) 0x7FFF)
165 #define range_signed_32(x) ((offsetT) (x) >= -(offsetT) 0x80000000 && \
166 (offsetT) (x) <= (offsetT) 0x7FFFFFFF)
169 /* Macros for sign extending from 16- and 32-bits. */
170 /* XXX: The cast macros will work on all the systems that I care about,
171 but really a predicate should be found to use the non-cast forms. */
174 #define sign_extend_16(x) ((short) (x))
175 #define sign_extend_32(x) ((int) (x))
177 #define sign_extend_16(x) ((offsetT) (((x) & 0xFFFF) ^ 0x8000) - 0x8000)
178 #define sign_extend_32(x) ((offsetT) (((x) & 0xFFFFFFFF) \
179 ^ 0x80000000) - 0x80000000)
182 /* Macros to build tokens */
184 #define set_tok_reg(t, r) (memset (&(t), 0, sizeof (t)), \
185 (t).X_op = O_register, \
186 (t).X_add_number = (r))
187 #define set_tok_preg(t, r) (memset (&(t), 0, sizeof (t)), \
188 (t).X_op = O_pregister, \
189 (t).X_add_number = (r))
190 #define set_tok_cpreg(t, r) (memset (&(t), 0, sizeof (t)), \
191 (t).X_op = O_cpregister, \
192 (t).X_add_number = (r))
193 #define set_tok_freg(t, r) (memset (&(t), 0, sizeof (t)), \
194 (t).X_op = O_register, \
195 (t).X_add_number = (r) + 32)
196 #define set_tok_sym(t, s, a) (memset (&(t), 0, sizeof (t)), \
197 (t).X_op = O_symbol, \
198 (t).X_add_symbol = (s), \
199 (t).X_add_number = (a))
200 #define set_tok_const(t, n) (memset (&(t), 0, sizeof (t)), \
201 (t).X_op = O_constant, \
202 (t).X_add_number = (n))
204 /* Prototypes for all local functions */
206 static struct alpha_reloc_tag
*get_alpha_reloc_tag
PARAMS ((long));
207 static void alpha_adjust_symtab_relocs
PARAMS ((bfd
*, asection
*, PTR
));
209 static int tokenize_arguments
PARAMS ((char *, expressionS
*, int));
210 static const struct alpha_opcode
*find_opcode_match
211 PARAMS ((const struct alpha_opcode
*, const expressionS
*, int *, int *));
212 static const struct alpha_macro
*find_macro_match
213 PARAMS ((const struct alpha_macro
*, const expressionS
*, int *));
214 static unsigned insert_operand
215 PARAMS ((unsigned, const struct alpha_operand
*, offsetT
, char *, unsigned));
216 static void assemble_insn
217 PARAMS ((const struct alpha_opcode
*, const expressionS
*, int,
218 struct alpha_insn
*, bfd_reloc_code_real_type
));
219 static void emit_insn
PARAMS ((struct alpha_insn
*));
220 static void assemble_tokens_to_insn
221 PARAMS ((const char *, const expressionS
*, int, struct alpha_insn
*));
222 static void assemble_tokens
223 PARAMS ((const char *, const expressionS
*, int, int));
225 static long load_expression
226 PARAMS ((int, const expressionS
*, int *, expressionS
*));
228 static void emit_ldgp
PARAMS ((const expressionS
*, int, const PTR
));
229 static void emit_division
PARAMS ((const expressionS
*, int, const PTR
));
230 static void emit_lda
PARAMS ((const expressionS
*, int, const PTR
));
231 static void emit_ldah
PARAMS ((const expressionS
*, int, const PTR
));
232 static void emit_ir_load
PARAMS ((const expressionS
*, int, const PTR
));
233 static void emit_loadstore
PARAMS ((const expressionS
*, int, const PTR
));
234 static void emit_jsrjmp
PARAMS ((const expressionS
*, int, const PTR
));
235 static void emit_ldX
PARAMS ((const expressionS
*, int, const PTR
));
236 static void emit_ldXu
PARAMS ((const expressionS
*, int, const PTR
));
237 static void emit_uldX
PARAMS ((const expressionS
*, int, const PTR
));
238 static void emit_uldXu
PARAMS ((const expressionS
*, int, const PTR
));
239 static void emit_ldil
PARAMS ((const expressionS
*, int, const PTR
));
240 static void emit_stX
PARAMS ((const expressionS
*, int, const PTR
));
241 static void emit_ustX
PARAMS ((const expressionS
*, int, const PTR
));
242 static void emit_sextX
PARAMS ((const expressionS
*, int, const PTR
));
243 static void emit_retjcr
PARAMS ((const expressionS
*, int, const PTR
));
245 static void s_alpha_text
PARAMS ((int));
246 static void s_alpha_data
PARAMS ((int));
248 static void s_alpha_comm
PARAMS ((int));
249 static void s_alpha_rdata
PARAMS ((int));
252 static void s_alpha_sdata
PARAMS ((int));
255 static void s_alpha_section
PARAMS ((int));
256 static void s_alpha_ent
PARAMS ((int));
257 static void s_alpha_end
PARAMS ((int));
258 static void s_alpha_mask
PARAMS ((int));
259 static void s_alpha_frame
PARAMS ((int));
260 static void s_alpha_prologue
PARAMS ((int));
261 static void s_alpha_file
PARAMS ((int));
262 static void s_alpha_loc
PARAMS ((int));
263 static void s_alpha_stab
PARAMS ((int));
264 static void s_alpha_coff_wrapper
PARAMS ((int));
267 static void s_alpha_section
PARAMS ((int));
269 static void s_alpha_gprel32
PARAMS ((int));
270 static void s_alpha_float_cons
PARAMS ((int));
271 static void s_alpha_proc
PARAMS ((int));
272 static void s_alpha_set
PARAMS ((int));
273 static void s_alpha_base
PARAMS ((int));
274 static void s_alpha_align
PARAMS ((int));
275 static void s_alpha_stringer
PARAMS ((int));
276 static void s_alpha_space
PARAMS ((int));
277 static void s_alpha_ucons
PARAMS ((int));
278 static void s_alpha_arch
PARAMS ((int));
280 static void create_literal_section
PARAMS ((const char *, segT
*, symbolS
**));
282 static void select_gp_value
PARAMS ((void));
284 static void alpha_align
PARAMS ((int, char *, symbolS
*, int));
286 /* Generic assembler global variables which must be defined by all
289 /* Characters which always start a comment. */
290 const char comment_chars
[] = "#";
292 /* Characters which start a comment at the beginning of a line. */
293 const char line_comment_chars
[] = "#";
295 /* Characters which may be used to separate multiple commands on a
297 const char line_separator_chars
[] = ";";
299 /* Characters which are used to indicate an exponent in a floating
301 const char EXP_CHARS
[] = "eE";
303 /* Characters which mean that a number is a floating point constant,
306 const char FLT_CHARS
[] = "dD";
308 /* XXX: Do all of these really get used on the alpha?? */
309 char FLT_CHARS
[] = "rRsSfFdDxXpP";
313 const char *md_shortopts
= "Fm:g+1h:HG:";
315 const char *md_shortopts
= "Fm:gG:";
318 struct option md_longopts
[] = {
319 #define OPTION_32ADDR (OPTION_MD_BASE)
320 { "32addr", no_argument
, NULL
, OPTION_32ADDR
},
321 #define OPTION_RELAX (OPTION_32ADDR + 1)
322 { "relax", no_argument
, NULL
, OPTION_RELAX
},
324 #define OPTION_MDEBUG (OPTION_RELAX + 1)
325 #define OPTION_NO_MDEBUG (OPTION_MDEBUG + 1)
326 { "mdebug", no_argument
, NULL
, OPTION_MDEBUG
},
327 { "no-mdebug", no_argument
, NULL
, OPTION_NO_MDEBUG
},
329 { NULL
, no_argument
, NULL
, 0 }
332 size_t md_longopts_size
= sizeof (md_longopts
);
336 #define AXP_REG_R16 16
337 #define AXP_REG_R17 17
339 #define AXP_REG_T9 22
341 #define AXP_REG_T10 23
343 #define AXP_REG_T11 24
345 #define AXP_REG_T12 25
346 #define AXP_REG_AI 25
348 #define AXP_REG_FP 29
351 #define AXP_REG_GP AXP_REG_PV
352 #endif /* OBJ_EVAX */
354 /* The cpu for which we are generating code */
355 static unsigned alpha_target
= AXP_OPCODE_BASE
;
356 static const char *alpha_target_name
= "<all>";
358 /* The hash table of instruction opcodes */
359 static struct hash_control
*alpha_opcode_hash
;
361 /* The hash table of macro opcodes */
362 static struct hash_control
*alpha_macro_hash
;
365 /* The $gp relocation symbol */
366 static symbolS
*alpha_gp_symbol
;
368 /* XXX: what is this, and why is it exported? */
369 valueT alpha_gp_value
;
372 /* The current $gp register */
373 static int alpha_gp_register
= AXP_REG_GP
;
375 /* A table of the register symbols */
376 static symbolS
*alpha_register_table
[64];
378 /* Constant sections, or sections of constants */
380 static segT alpha_lita_section
;
381 static segT alpha_lit4_section
;
384 static segT alpha_link_section
;
385 static segT alpha_ctors_section
;
386 static segT alpha_dtors_section
;
388 static segT alpha_lit8_section
;
390 /* Symbols referring to said sections. */
392 static symbolS
*alpha_lita_symbol
;
393 static symbolS
*alpha_lit4_symbol
;
396 static symbolS
*alpha_link_symbol
;
397 static symbolS
*alpha_ctors_symbol
;
398 static symbolS
*alpha_dtors_symbol
;
400 static symbolS
*alpha_lit8_symbol
;
402 /* Literal for .litX+0x8000 within .lita */
404 static offsetT alpha_lit4_literal
;
405 static offsetT alpha_lit8_literal
;
409 /* The active .ent symbol. */
410 static symbolS
*alpha_cur_ent_sym
;
413 /* Is the assembler not allowed to use $at? */
414 static int alpha_noat_on
= 0;
416 /* Are macros enabled? */
417 static int alpha_macros_on
= 1;
419 /* Are floats disabled? */
420 static int alpha_nofloats_on
= 0;
422 /* Are addresses 32 bit? */
423 static int alpha_addr32_on
= 0;
425 /* Symbol labelling the current insn. When the Alpha gas sees
428 and the section happens to not be on an eight byte boundary, it
429 will align both the symbol and the .quad to an eight byte boundary. */
430 static symbolS
*alpha_insn_label
;
432 /* Whether we should automatically align data generation pseudo-ops.
433 .align 0 will turn this off. */
434 static int alpha_auto_align_on
= 1;
436 /* The known current alignment of the current section. */
437 static int alpha_current_align
;
439 /* These are exported to ECOFF code. */
440 unsigned long alpha_gprmask
, alpha_fprmask
;
442 /* Whether the debugging option was seen. */
443 static int alpha_debug
;
446 /* Whether we are emitting an mdebug section. */
447 int alpha_flag_mdebug
= -1;
450 /* Don't fully resolve relocations, allowing code movement in the linker. */
451 static int alpha_flag_relax
;
453 /* What value to give to bfd_set_gp_size. */
454 static int g_switch_value
= 8;
457 /* Collect information about current procedure here. */
459 symbolS
*symbol
; /* proc pdesc symbol */
461 int framereg
; /* register for frame pointer */
462 int framesize
; /* size of frame */
472 static int alpha_flag_hash_long_names
= 0; /* -+ */
473 static int alpha_flag_show_after_trunc
= 0; /* -H */
475 /* If the -+ switch is given, then a hash is appended to any name that is
476 * longer than 64 characters, else longer symbol names are truncated.
482 /* A table to map the spelling of a relocation operand into an appropriate
483 bfd_reloc_code_real_type type. The table is assumed to be ordered such
484 that op-O_literal indexes into it. */
486 #define ALPHA_RELOC_TABLE(op) \
487 (&alpha_reloc_op[ ((!USER_RELOC_P (op)) \
489 : (int) (op) - (int) O_literal) ])
491 #define DEF(NAME, RELOC, REQ, ALLOW) \
492 { #NAME, sizeof(#NAME)-1, O_##NAME, RELOC, REQ, ALLOW}
494 static const struct alpha_reloc_op_tag
{
495 const char *name
; /* string to lookup */
496 size_t length
; /* size of the string */
497 operatorT op
; /* which operator to use */
498 bfd_reloc_code_real_type reloc
; /* relocation before frob */
499 unsigned int require_seq
: 1; /* require a sequence number */
500 unsigned int allow_seq
: 1; /* allow a sequence number */
501 } alpha_reloc_op
[] = {
502 DEF(literal
, BFD_RELOC_ALPHA_ELF_LITERAL
, 0, 1),
503 DEF(lituse_addr
, DUMMY_RELOC_LITUSE_ADDR
, 1, 1),
504 DEF(lituse_base
, DUMMY_RELOC_LITUSE_BASE
, 1, 1),
505 DEF(lituse_bytoff
, DUMMY_RELOC_LITUSE_BYTOFF
, 1, 1),
506 DEF(lituse_jsr
, DUMMY_RELOC_LITUSE_JSR
, 1, 1),
507 DEF(lituse_tlsgd
, DUMMY_RELOC_LITUSE_TLSGD
, 1, 1),
508 DEF(lituse_tlsldm
, DUMMY_RELOC_LITUSE_TLSLDM
, 1, 1),
509 DEF(gpdisp
, BFD_RELOC_ALPHA_GPDISP
, 1, 1),
510 DEF(gprelhigh
, BFD_RELOC_ALPHA_GPREL_HI16
, 0, 0),
511 DEF(gprellow
, BFD_RELOC_ALPHA_GPREL_LO16
, 0, 0),
512 DEF(gprel
, BFD_RELOC_GPREL16
, 0, 0),
513 DEF(samegp
, BFD_RELOC_ALPHA_BRSGP
, 0, 0),
514 DEF(tlsgd
, BFD_RELOC_ALPHA_TLSGD
, 0, 1),
515 DEF(tlsldm
, BFD_RELOC_ALPHA_TLSLDM
, 0, 1),
516 DEF(gotdtprel
, BFD_RELOC_ALPHA_GOTDTPREL16
, 0, 0),
517 DEF(dtprelhi
, BFD_RELOC_ALPHA_DTPREL_HI16
, 0, 0),
518 DEF(dtprello
, BFD_RELOC_ALPHA_DTPREL_LO16
, 0, 0),
519 DEF(dtprel
, BFD_RELOC_ALPHA_DTPREL16
, 0, 0),
520 DEF(gottprel
, BFD_RELOC_ALPHA_GOTTPREL16
, 0, 0),
521 DEF(tprelhi
, BFD_RELOC_ALPHA_TPREL_HI16
, 0, 0),
522 DEF(tprello
, BFD_RELOC_ALPHA_TPREL_LO16
, 0, 0),
523 DEF(tprel
, BFD_RELOC_ALPHA_TPREL16
, 0, 0),
528 static const int alpha_num_reloc_op
529 = sizeof (alpha_reloc_op
) / sizeof (*alpha_reloc_op
);
530 #endif /* RELOC_OP_P */
532 /* Maximum # digits needed to hold the largest sequence # */
533 #define ALPHA_RELOC_DIGITS 25
535 /* Structure to hold explict sequence information. */
536 struct alpha_reloc_tag
538 fixS
*master
; /* the literal reloc */
539 fixS
*slaves
; /* head of linked list of lituses */
540 segT segment
; /* segment relocs are in or undefined_section*/
541 long sequence
; /* sequence # */
542 unsigned n_master
; /* # of literals */
543 unsigned n_slaves
; /* # of lituses */
544 unsigned saw_tlsgd
: 1; /* true if ... */
545 unsigned saw_tlsldm
: 1;
546 unsigned saw_lu_tlsgd
: 1;
547 unsigned saw_lu_tlsldm
: 1;
548 unsigned multi_section_p
: 1; /* true if more than one section was used */
549 char string
[1]; /* printable form of sequence to hash with */
552 /* Hash table to link up literals with the appropriate lituse */
553 static struct hash_control
*alpha_literal_hash
;
555 /* Sequence numbers for internal use by macros. */
556 static long next_sequence_num
= -1;
558 /* A table of CPU names and opcode sets. */
560 static const struct cpu_type
{
564 /* Ad hoc convention: cpu number gets palcode, process code doesn't.
565 This supports usage under DU 4.0b that does ".arch ev4", and
566 usage in MILO that does -m21064. Probably something more
567 specific like -m21064-pal should be used, but oh well. */
569 { "21064", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
570 { "21064a", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
571 { "21066", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
572 { "21068", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
573 { "21164", AXP_OPCODE_BASE
|AXP_OPCODE_EV5
},
574 { "21164a", AXP_OPCODE_BASE
|AXP_OPCODE_EV5
|AXP_OPCODE_BWX
},
575 { "21164pc", (AXP_OPCODE_BASE
|AXP_OPCODE_EV5
|AXP_OPCODE_BWX
577 { "21264", (AXP_OPCODE_BASE
|AXP_OPCODE_EV6
|AXP_OPCODE_BWX
578 |AXP_OPCODE_MAX
|AXP_OPCODE_CIX
) },
579 { "21264a", (AXP_OPCODE_BASE
|AXP_OPCODE_EV6
|AXP_OPCODE_BWX
580 |AXP_OPCODE_MAX
|AXP_OPCODE_CIX
) },
581 { "21264b", (AXP_OPCODE_BASE
|AXP_OPCODE_EV6
|AXP_OPCODE_BWX
582 |AXP_OPCODE_MAX
|AXP_OPCODE_CIX
) },
584 { "ev4", AXP_OPCODE_BASE
},
585 { "ev45", AXP_OPCODE_BASE
},
586 { "lca45", AXP_OPCODE_BASE
},
587 { "ev5", AXP_OPCODE_BASE
},
588 { "ev56", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
},
589 { "pca56", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
|AXP_OPCODE_MAX
},
590 { "ev6", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
|AXP_OPCODE_MAX
|AXP_OPCODE_CIX
},
591 { "ev67", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
|AXP_OPCODE_MAX
|AXP_OPCODE_CIX
},
592 { "ev68", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
|AXP_OPCODE_MAX
|AXP_OPCODE_CIX
},
594 { "all", AXP_OPCODE_BASE
},
598 /* The macro table */
600 static const struct alpha_macro alpha_macros
[] = {
601 /* Load/Store macros */
602 { "lda", emit_lda
, NULL
,
603 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
604 { "ldah", emit_ldah
, NULL
,
605 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
607 { "ldl", emit_ir_load
, "ldl",
608 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
609 { "ldl_l", emit_ir_load
, "ldl_l",
610 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
611 { "ldq", emit_ir_load
, "ldq",
612 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
613 { "ldq_l", emit_ir_load
, "ldq_l",
614 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
615 { "ldq_u", emit_ir_load
, "ldq_u",
616 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
617 { "ldf", emit_loadstore
, "ldf",
618 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
619 { "ldg", emit_loadstore
, "ldg",
620 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
621 { "lds", emit_loadstore
, "lds",
622 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
623 { "ldt", emit_loadstore
, "ldt",
624 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
626 { "ldb", emit_ldX
, (PTR
) 0,
627 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
628 { "ldbu", emit_ldXu
, (PTR
) 0,
629 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
630 { "ldw", emit_ldX
, (PTR
) 1,
631 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
632 { "ldwu", emit_ldXu
, (PTR
) 1,
633 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
635 { "uldw", emit_uldX
, (PTR
) 1,
636 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
637 { "uldwu", emit_uldXu
, (PTR
) 1,
638 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
639 { "uldl", emit_uldX
, (PTR
) 2,
640 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
641 { "uldlu", emit_uldXu
, (PTR
) 2,
642 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
643 { "uldq", emit_uldXu
, (PTR
) 3,
644 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
646 { "ldgp", emit_ldgp
, NULL
,
647 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
} },
649 { "ldi", emit_lda
, NULL
,
650 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
651 { "ldil", emit_ldil
, NULL
,
652 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
653 { "ldiq", emit_lda
, NULL
,
654 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
656 { "ldif" emit_ldiq
, NULL
,
657 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
658 { "ldid" emit_ldiq
, NULL
,
659 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
660 { "ldig" emit_ldiq
, NULL
,
661 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
662 { "ldis" emit_ldiq
, NULL
,
663 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
664 { "ldit" emit_ldiq
, NULL
,
665 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
668 { "stl", emit_loadstore
, "stl",
669 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
670 { "stl_c", emit_loadstore
, "stl_c",
671 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
672 { "stq", emit_loadstore
, "stq",
673 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
674 { "stq_c", emit_loadstore
, "stq_c",
675 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
676 { "stq_u", emit_loadstore
, "stq_u",
677 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
678 { "stf", emit_loadstore
, "stf",
679 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
680 { "stg", emit_loadstore
, "stg",
681 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
682 { "sts", emit_loadstore
, "sts",
683 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
684 { "stt", emit_loadstore
, "stt",
685 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
687 { "stb", emit_stX
, (PTR
) 0,
688 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
689 { "stw", emit_stX
, (PTR
) 1,
690 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
691 { "ustw", emit_ustX
, (PTR
) 1,
692 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
693 { "ustl", emit_ustX
, (PTR
) 2,
694 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
695 { "ustq", emit_ustX
, (PTR
) 3,
696 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
698 /* Arithmetic macros */
700 { "absl" emit_absl
, 1, { IR
} },
701 { "absl" emit_absl
, 2, { IR
, IR
} },
702 { "absl" emit_absl
, 2, { EXP
, IR
} },
703 { "absq" emit_absq
, 1, { IR
} },
704 { "absq" emit_absq
, 2, { IR
, IR
} },
705 { "absq" emit_absq
, 2, { EXP
, IR
} },
708 { "sextb", emit_sextX
, (PTR
) 0,
709 { MACRO_IR
, MACRO_IR
, MACRO_EOA
,
711 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
712 { "sextw", emit_sextX
, (PTR
) 1,
713 { MACRO_IR
, MACRO_IR
, MACRO_EOA
,
715 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
717 { "divl", emit_division
, "__divl",
718 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
719 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
720 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
721 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
722 { "divlu", emit_division
, "__divlu",
723 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
724 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
725 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
726 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
727 { "divq", emit_division
, "__divq",
728 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
729 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
730 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
731 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
732 { "divqu", emit_division
, "__divqu",
733 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
734 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
735 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
736 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
737 { "reml", emit_division
, "__reml",
738 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
739 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
740 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
741 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
742 { "remlu", emit_division
, "__remlu",
743 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
744 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
745 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
746 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
747 { "remq", emit_division
, "__remq",
748 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
749 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
750 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
751 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
752 { "remqu", emit_division
, "__remqu",
753 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
754 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
755 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
756 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
758 { "jsr", emit_jsrjmp
, "jsr",
759 { MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
760 MACRO_PIR
, MACRO_EOA
,
761 MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
762 MACRO_EXP
, MACRO_EOA
} },
763 { "jmp", emit_jsrjmp
, "jmp",
764 { MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
765 MACRO_PIR
, MACRO_EOA
,
766 MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
767 MACRO_EXP
, MACRO_EOA
} },
768 { "ret", emit_retjcr
, "ret",
769 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
771 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
772 MACRO_PIR
, MACRO_EOA
,
773 MACRO_EXP
, MACRO_EOA
,
775 { "jcr", emit_retjcr
, "jcr",
776 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
778 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
779 MACRO_PIR
, MACRO_EOA
,
780 MACRO_EXP
, MACRO_EOA
,
782 { "jsr_coroutine", emit_retjcr
, "jcr",
783 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
785 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
786 MACRO_PIR
, MACRO_EOA
,
787 MACRO_EXP
, MACRO_EOA
,
791 static const unsigned int alpha_num_macros
792 = sizeof (alpha_macros
) / sizeof (*alpha_macros
);
794 /* Public interface functions */
796 /* This function is called once, at assembler startup time. It sets
797 up all the tables, etc. that the MD part of the assembler will
798 need, that can be determined before arguments are parsed. */
805 /* Verify that X_op field is wide enough. */
809 assert (e
.X_op
== O_max
);
812 /* Create the opcode hash table */
814 alpha_opcode_hash
= hash_new ();
815 for (i
= 0; i
< alpha_num_opcodes
;)
817 const char *name
, *retval
, *slash
;
819 name
= alpha_opcodes
[i
].name
;
820 retval
= hash_insert (alpha_opcode_hash
, name
, (PTR
) &alpha_opcodes
[i
]);
822 as_fatal (_("internal error: can't hash opcode `%s': %s"),
825 /* Some opcodes include modifiers of various sorts with a "/mod"
826 syntax, like the architecture manual suggests. However, for
827 use with gcc at least, we also need access to those same opcodes
830 if ((slash
= strchr (name
, '/')) != NULL
)
832 char *p
= xmalloc (strlen (name
));
833 memcpy (p
, name
, slash
- name
);
834 strcpy (p
+ (slash
- name
), slash
+ 1);
836 (void) hash_insert (alpha_opcode_hash
, p
, (PTR
) &alpha_opcodes
[i
]);
837 /* Ignore failures -- the opcode table does duplicate some
838 variants in different forms, like "hw_stq" and "hw_st/q". */
841 while (++i
< alpha_num_opcodes
842 && (alpha_opcodes
[i
].name
== name
843 || !strcmp (alpha_opcodes
[i
].name
, name
)))
847 /* Create the macro hash table */
849 alpha_macro_hash
= hash_new ();
850 for (i
= 0; i
< alpha_num_macros
;)
852 const char *name
, *retval
;
854 name
= alpha_macros
[i
].name
;
855 retval
= hash_insert (alpha_macro_hash
, name
, (PTR
) &alpha_macros
[i
]);
857 as_fatal (_("internal error: can't hash macro `%s': %s"),
860 while (++i
< alpha_num_macros
861 && (alpha_macros
[i
].name
== name
862 || !strcmp (alpha_macros
[i
].name
, name
)))
866 /* Construct symbols for each of the registers */
868 for (i
= 0; i
< 32; ++i
)
871 sprintf (name
, "$%d", i
);
872 alpha_register_table
[i
] = symbol_create (name
, reg_section
, i
,
878 sprintf (name
, "$f%d", i
- 32);
879 alpha_register_table
[i
] = symbol_create (name
, reg_section
, i
,
883 /* Create the special symbols and sections we'll be using */
885 /* So .sbss will get used for tiny objects. */
886 bfd_set_gp_size (stdoutput
, g_switch_value
);
889 create_literal_section (".lita", &alpha_lita_section
, &alpha_lita_symbol
);
891 /* For handling the GP, create a symbol that won't be output in the
892 symbol table. We'll edit it out of relocs later. */
893 alpha_gp_symbol
= symbol_create ("<GP value>", alpha_lita_section
, 0x8000,
898 create_literal_section (".link", &alpha_link_section
, &alpha_link_symbol
);
904 segT sec
= subseg_new (".mdebug", (subsegT
) 0);
905 bfd_set_section_flags (stdoutput
, sec
, SEC_HAS_CONTENTS
| SEC_READONLY
);
906 bfd_set_section_alignment (stdoutput
, sec
, 3);
910 /* Create literal lookup hash table. */
911 alpha_literal_hash
= hash_new ();
913 subseg_set (text_section
, 0);
916 /* The public interface to the instruction assembler. */
922 char opname
[32]; /* current maximum is 13 */
923 expressionS tok
[MAX_INSN_ARGS
];
927 /* split off the opcode */
928 opnamelen
= strspn (str
, "abcdefghijklmnopqrstuvwxyz_/46819");
929 trunclen
= (opnamelen
< sizeof (opname
) - 1
931 : sizeof (opname
) - 1);
932 memcpy (opname
, str
, trunclen
);
933 opname
[trunclen
] = '\0';
935 /* tokenize the rest of the line */
936 if ((ntok
= tokenize_arguments (str
+ opnamelen
, tok
, MAX_INSN_ARGS
)) < 0)
938 if (ntok
!= TOKENIZE_ERROR_REPORT
)
939 as_bad (_("syntax error"));
945 assemble_tokens (opname
, tok
, ntok
, alpha_macros_on
);
948 /* Round up a section's size to the appropriate boundary. */
951 md_section_align (seg
, size
)
955 int align
= bfd_get_section_alignment (stdoutput
, seg
);
956 valueT mask
= ((valueT
) 1 << align
) - 1;
958 return (size
+ mask
) & ~mask
;
961 /* Turn a string in input_line_pointer into a floating point constant
962 of type TYPE, and store the appropriate bytes in *LITP. The number
963 of LITTLENUMS emitted is stored in *SIZEP. An error message is
964 returned, or NULL on OK. */
966 /* Equal to MAX_PRECISION in atof-ieee.c */
967 #define MAX_LITTLENUMS 6
969 extern char *vax_md_atof
PARAMS ((int, char *, int *));
972 md_atof (type
, litP
, sizeP
)
978 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
979 LITTLENUM_TYPE
*wordP
;
986 /* VAX md_atof doesn't like "G" for some reason. */
990 return vax_md_atof (type
, litP
, sizeP
);
1013 return _("Bad call to MD_ATOF()");
1015 t
= atof_ieee (input_line_pointer
, type
, words
);
1017 input_line_pointer
= t
;
1018 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
1020 for (wordP
= words
+ prec
- 1; prec
--;)
1022 md_number_to_chars (litP
, (long) (*wordP
--), sizeof (LITTLENUM_TYPE
));
1023 litP
+= sizeof (LITTLENUM_TYPE
);
1029 /* Take care of the target-specific command-line options. */
1032 md_parse_option (c
, arg
)
1039 alpha_nofloats_on
= 1;
1043 alpha_addr32_on
= 1;
1051 g_switch_value
= atoi (arg
);
1056 const struct cpu_type
*p
;
1057 for (p
= cpu_types
; p
->name
; ++p
)
1058 if (strcmp (arg
, p
->name
) == 0)
1060 alpha_target_name
= p
->name
, alpha_target
= p
->flags
;
1063 as_warn (_("Unknown CPU identifier `%s'"), arg
);
1069 case '+': /* For g++. Hash any name > 63 chars long. */
1070 alpha_flag_hash_long_names
= 1;
1073 case 'H': /* Show new symbol after hash truncation */
1074 alpha_flag_show_after_trunc
= 1;
1077 case 'h': /* for gnu-c/vax compatibility. */
1082 alpha_flag_relax
= 1;
1087 alpha_flag_mdebug
= 1;
1089 case OPTION_NO_MDEBUG
:
1090 alpha_flag_mdebug
= 0;
1101 /* Print a description of the command-line options that we accept. */
1104 md_show_usage (stream
)
1109 -32addr treat addresses as 32-bit values\n\
1110 -F lack floating point instructions support\n\
1111 -mev4 | -mev45 | -mev5 | -mev56 | -mpca56 | -mev6 | -mev67 | -mev68 | -mall\n\
1112 specify variant of Alpha architecture\n\
1113 -m21064 | -m21066 | -m21164 | -m21164a | -m21164pc | -m21264 | -m21264a | -m21264b\n\
1114 these variants include PALcode opcodes\n"),
1119 -+ hash encode (don't truncate) names longer than 64 characters\n\
1120 -H show new symbol after hash truncation\n"),
1125 /* Decide from what point a pc-relative relocation is relative to,
1126 relative to the pc-relative fixup. Er, relatively speaking. */
1129 md_pcrel_from (fixP
)
1132 valueT addr
= fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
1133 switch (fixP
->fx_r_type
)
1135 case BFD_RELOC_ALPHA_GPDISP
:
1136 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1137 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1140 return fixP
->fx_size
+ addr
;
1144 /* Attempt to simplify or even eliminate a fixup. The return value is
1145 ignored; perhaps it was once meaningful, but now it is historical.
1146 To indicate that a fixup has been eliminated, set fixP->fx_done.
1148 For ELF, here it is that we transform the GPDISP_HI16 reloc we used
1149 internally into the GPDISP reloc used externally. We had to do
1150 this so that we'd have the GPDISP_LO16 reloc as a tag to compute
1151 the distance to the "lda" instruction for setting the addend to
1155 md_apply_fix3 (fixP
, valP
, seg
)
1160 char * const fixpos
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
1161 valueT value
= * valP
;
1162 unsigned image
, size
;
1164 switch (fixP
->fx_r_type
)
1166 /* The GPDISP relocations are processed internally with a symbol
1167 referring to the current function; we need to drop in a value
1168 which, when added to the address of the start of the function,
1169 gives the desired GP. */
1170 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1172 fixS
*next
= fixP
->fx_next
;
1174 /* With user-specified !gpdisp relocations, we can be missing
1175 the matching LO16 reloc. We will have already issued an
1178 fixP
->fx_offset
= (next
->fx_frag
->fr_address
+ next
->fx_where
1179 - fixP
->fx_frag
->fr_address
- fixP
->fx_where
);
1181 value
= (value
- sign_extend_16 (value
)) >> 16;
1184 fixP
->fx_r_type
= BFD_RELOC_ALPHA_GPDISP
;
1188 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1189 value
= sign_extend_16 (value
);
1190 fixP
->fx_offset
= 0;
1196 fixP
->fx_addsy
= section_symbol (seg
);
1197 md_number_to_chars (fixpos
, value
, 2);
1202 fixP
->fx_r_type
= BFD_RELOC_16_PCREL
;
1207 fixP
->fx_r_type
= BFD_RELOC_32_PCREL
;
1212 fixP
->fx_r_type
= BFD_RELOC_64_PCREL
;
1215 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
1217 md_number_to_chars (fixpos
, value
, size
);
1223 case BFD_RELOC_GPREL32
:
1224 assert (fixP
->fx_subsy
== alpha_gp_symbol
);
1226 /* FIXME: inherited this obliviousness of `value' -- why? */
1227 md_number_to_chars (fixpos
, -alpha_gp_value
, 4);
1230 case BFD_RELOC_GPREL32
:
1232 case BFD_RELOC_GPREL16
:
1233 case BFD_RELOC_ALPHA_GPREL_HI16
:
1234 case BFD_RELOC_ALPHA_GPREL_LO16
:
1237 case BFD_RELOC_23_PCREL_S2
:
1238 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
1240 image
= bfd_getl32 (fixpos
);
1241 image
= (image
& ~0x1FFFFF) | ((value
>> 2) & 0x1FFFFF);
1246 case BFD_RELOC_ALPHA_HINT
:
1247 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
1249 image
= bfd_getl32 (fixpos
);
1250 image
= (image
& ~0x3FFF) | ((value
>> 2) & 0x3FFF);
1256 case BFD_RELOC_ALPHA_BRSGP
:
1257 case BFD_RELOC_ALPHA_TLSGD
:
1258 case BFD_RELOC_ALPHA_TLSLDM
:
1259 case BFD_RELOC_ALPHA_GOTDTPREL16
:
1260 case BFD_RELOC_ALPHA_DTPREL_HI16
:
1261 case BFD_RELOC_ALPHA_DTPREL_LO16
:
1262 case BFD_RELOC_ALPHA_DTPREL16
:
1263 case BFD_RELOC_ALPHA_GOTTPREL16
:
1264 case BFD_RELOC_ALPHA_TPREL_HI16
:
1265 case BFD_RELOC_ALPHA_TPREL_LO16
:
1266 case BFD_RELOC_ALPHA_TPREL16
:
1271 case BFD_RELOC_ALPHA_LITERAL
:
1272 md_number_to_chars (fixpos
, value
, 2);
1275 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1276 case BFD_RELOC_ALPHA_LITUSE
:
1277 case BFD_RELOC_ALPHA_LINKAGE
:
1278 case BFD_RELOC_ALPHA_CODEADDR
:
1281 case BFD_RELOC_VTABLE_INHERIT
:
1282 case BFD_RELOC_VTABLE_ENTRY
:
1287 const struct alpha_operand
*operand
;
1289 if ((int) fixP
->fx_r_type
>= 0)
1290 as_fatal (_("unhandled relocation type %s"),
1291 bfd_get_reloc_code_name (fixP
->fx_r_type
));
1293 assert (-(int) fixP
->fx_r_type
< (int) alpha_num_operands
);
1294 operand
= &alpha_operands
[-(int) fixP
->fx_r_type
];
1296 /* The rest of these fixups only exist internally during symbol
1297 resolution and have no representation in the object file.
1298 Therefore they must be completely resolved as constants. */
1300 if (fixP
->fx_addsy
!= 0
1301 && S_GET_SEGMENT (fixP
->fx_addsy
) != absolute_section
)
1302 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
1303 _("non-absolute expression in constant field"));
1305 image
= bfd_getl32 (fixpos
);
1306 image
= insert_operand (image
, operand
, (offsetT
) value
,
1307 fixP
->fx_file
, fixP
->fx_line
);
1312 if (fixP
->fx_addsy
!= 0 || fixP
->fx_pcrel
!= 0)
1316 as_warn_where (fixP
->fx_file
, fixP
->fx_line
,
1317 _("type %d reloc done?\n"), (int) fixP
->fx_r_type
);
1322 md_number_to_chars (fixpos
, image
, 4);
1328 /* Look for a register name in the given symbol. */
1331 md_undefined_symbol (name
)
1336 int is_float
= 0, num
;
1341 if (name
[1] == 'p' && name
[2] == '\0')
1342 return alpha_register_table
[AXP_REG_FP
];
1347 if (!ISDIGIT (*++name
))
1351 case '0': case '1': case '2': case '3': case '4':
1352 case '5': case '6': case '7': case '8': case '9':
1353 if (name
[1] == '\0')
1354 num
= name
[0] - '0';
1355 else if (name
[0] != '0' && ISDIGIT (name
[1]) && name
[2] == '\0')
1357 num
= (name
[0] - '0') * 10 + name
[1] - '0';
1364 if (!alpha_noat_on
&& (num
+ is_float
) == AXP_REG_AT
)
1365 as_warn (_("Used $at without \".set noat\""));
1366 return alpha_register_table
[num
+ is_float
];
1369 if (name
[1] == 't' && name
[2] == '\0')
1372 as_warn (_("Used $at without \".set noat\""));
1373 return alpha_register_table
[AXP_REG_AT
];
1378 if (name
[1] == 'p' && name
[2] == '\0')
1379 return alpha_register_table
[alpha_gp_register
];
1383 if (name
[1] == 'p' && name
[2] == '\0')
1384 return alpha_register_table
[AXP_REG_SP
];
1392 /* @@@ Magic ECOFF bits. */
1395 alpha_frob_ecoff_data ()
1398 /* $zero and $f31 are read-only */
1399 alpha_gprmask
&= ~1;
1400 alpha_fprmask
&= ~1;
1404 /* Hook to remember a recently defined label so that the auto-align
1405 code can adjust the symbol after we know what alignment will be
1409 alpha_define_label (sym
)
1412 alpha_insn_label
= sym
;
1415 /* If we have a BRSGP reloc to a local symbol, adjust it to BRADDR and
1416 let it get resolved at assembly time. */
1419 alpha_validate_fix (f
)
1426 if (f
->fx_r_type
!= BFD_RELOC_ALPHA_BRSGP
)
1429 if (! S_IS_DEFINED (f
->fx_addsy
))
1432 switch (S_GET_OTHER (f
->fx_addsy
) & STO_ALPHA_STD_GPLOAD
)
1434 case STO_ALPHA_NOPV
:
1436 case STO_ALPHA_STD_GPLOAD
:
1440 if (S_IS_LOCAL (f
->fx_addsy
))
1443 name
= S_GET_NAME (f
->fx_addsy
);
1444 as_bad_where (f
->fx_file
, f
->fx_line
,
1445 _("!samegp reloc against symbol without .prologue: %s"),
1450 if (! (S_IS_EXTERN (f
->fx_addsy
) || S_IS_WEAK (f
->fx_addsy
)))
1452 f
->fx_r_type
= BFD_RELOC_23_PCREL_S2
;
1453 f
->fx_offset
+= offset
;
1458 /* Return true if we must always emit a reloc for a type and false if
1459 there is some hope of resolving it at assembly time. */
1462 alpha_force_relocation (f
)
1465 if (alpha_flag_relax
)
1468 switch (f
->fx_r_type
)
1470 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1471 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1472 case BFD_RELOC_ALPHA_GPDISP
:
1473 case BFD_RELOC_ALPHA_LITERAL
:
1474 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1475 case BFD_RELOC_ALPHA_LITUSE
:
1476 case BFD_RELOC_GPREL16
:
1477 case BFD_RELOC_GPREL32
:
1478 case BFD_RELOC_ALPHA_GPREL_HI16
:
1479 case BFD_RELOC_ALPHA_GPREL_LO16
:
1480 case BFD_RELOC_ALPHA_LINKAGE
:
1481 case BFD_RELOC_ALPHA_CODEADDR
:
1482 case BFD_RELOC_ALPHA_BRSGP
:
1483 case BFD_RELOC_VTABLE_INHERIT
:
1484 case BFD_RELOC_VTABLE_ENTRY
:
1485 case BFD_RELOC_ALPHA_TLSGD
:
1486 case BFD_RELOC_ALPHA_TLSLDM
:
1487 case BFD_RELOC_ALPHA_GOTDTPREL16
:
1488 case BFD_RELOC_ALPHA_DTPREL_HI16
:
1489 case BFD_RELOC_ALPHA_DTPREL_LO16
:
1490 case BFD_RELOC_ALPHA_DTPREL16
:
1491 case BFD_RELOC_ALPHA_GOTTPREL16
:
1492 case BFD_RELOC_ALPHA_TPREL_HI16
:
1493 case BFD_RELOC_ALPHA_TPREL_LO16
:
1494 case BFD_RELOC_ALPHA_TPREL16
:
1497 case BFD_RELOC_23_PCREL_S2
:
1500 case BFD_RELOC_ALPHA_HINT
:
1508 /* Return true if we can partially resolve a relocation now. */
1511 alpha_fix_adjustable (f
)
1515 /* Prevent all adjustments to global symbols */
1516 if (S_IS_EXTERN (f
->fx_addsy
) || S_IS_WEAK (f
->fx_addsy
))
1520 /* Are there any relocation types for which we must generate a reloc
1521 but we can adjust the values contained within it? */
1522 switch (f
->fx_r_type
)
1524 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1525 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1526 case BFD_RELOC_ALPHA_GPDISP
:
1527 case BFD_RELOC_ALPHA_BRSGP
:
1530 case BFD_RELOC_ALPHA_LITERAL
:
1531 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1532 case BFD_RELOC_ALPHA_LITUSE
:
1533 case BFD_RELOC_ALPHA_LINKAGE
:
1534 case BFD_RELOC_ALPHA_CODEADDR
:
1537 case BFD_RELOC_VTABLE_ENTRY
:
1538 case BFD_RELOC_VTABLE_INHERIT
:
1541 case BFD_RELOC_GPREL16
:
1542 case BFD_RELOC_GPREL32
:
1543 case BFD_RELOC_ALPHA_GPREL_HI16
:
1544 case BFD_RELOC_ALPHA_GPREL_LO16
:
1545 case BFD_RELOC_23_PCREL_S2
:
1548 case BFD_RELOC_ALPHA_HINT
:
1551 case BFD_RELOC_ALPHA_TLSGD
:
1552 case BFD_RELOC_ALPHA_TLSLDM
:
1553 case BFD_RELOC_ALPHA_GOTDTPREL16
:
1554 case BFD_RELOC_ALPHA_DTPREL_HI16
:
1555 case BFD_RELOC_ALPHA_DTPREL_LO16
:
1556 case BFD_RELOC_ALPHA_DTPREL16
:
1557 case BFD_RELOC_ALPHA_GOTTPREL16
:
1558 case BFD_RELOC_ALPHA_TPREL_HI16
:
1559 case BFD_RELOC_ALPHA_TPREL_LO16
:
1560 case BFD_RELOC_ALPHA_TPREL16
:
1561 /* ??? No idea why we can't return a reference to .tbss+10, but
1562 we're preventing this in the other assemblers. Follow for now. */
1571 /* Generate the BFD reloc to be stuck in the object file from the
1572 fixup used internally in the assembler. */
1575 tc_gen_reloc (sec
, fixp
)
1576 asection
*sec ATTRIBUTE_UNUSED
;
1581 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
1582 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
1583 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
1584 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
1586 /* Make sure none of our internal relocations make it this far.
1587 They'd better have been fully resolved by this point. */
1588 assert ((int) fixp
->fx_r_type
> 0);
1590 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
1591 if (reloc
->howto
== NULL
)
1593 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1594 _("cannot represent `%s' relocation in object file"),
1595 bfd_get_reloc_code_name (fixp
->fx_r_type
));
1599 if (!fixp
->fx_pcrel
!= !reloc
->howto
->pc_relative
)
1601 as_fatal (_("internal error? cannot generate `%s' relocation"),
1602 bfd_get_reloc_code_name (fixp
->fx_r_type
));
1604 assert (!fixp
->fx_pcrel
== !reloc
->howto
->pc_relative
);
1607 if (fixp
->fx_r_type
== BFD_RELOC_ALPHA_LITERAL
)
1609 /* fake out bfd_perform_relocation. sigh */
1610 reloc
->addend
= -alpha_gp_value
;
1615 reloc
->addend
= fixp
->fx_offset
;
1618 * Ohhh, this is ugly. The problem is that if this is a local global
1619 * symbol, the relocation will entirely be performed at link time, not
1620 * at assembly time. bfd_perform_reloc doesn't know about this sort
1621 * of thing, and as a result we need to fake it out here.
1623 if ((S_IS_EXTERN (fixp
->fx_addsy
) || S_IS_WEAK (fixp
->fx_addsy
)
1624 || (S_GET_SEGMENT (fixp
->fx_addsy
)->flags
& SEC_MERGE
)
1625 || (S_GET_SEGMENT (fixp
->fx_addsy
)->flags
& SEC_THREAD_LOCAL
))
1626 && !S_IS_COMMON (fixp
->fx_addsy
))
1627 reloc
->addend
-= symbol_get_bfdsym (fixp
->fx_addsy
)->value
;
1634 /* Parse a register name off of the input_line and return a register
1635 number. Gets md_undefined_symbol above to do the register name
1638 Only called as a part of processing the ECOFF .frame directive. */
1641 tc_get_register (frame
)
1642 int frame ATTRIBUTE_UNUSED
;
1644 int framereg
= AXP_REG_SP
;
1647 if (*input_line_pointer
== '$')
1649 char *s
= input_line_pointer
;
1650 char c
= get_symbol_end ();
1651 symbolS
*sym
= md_undefined_symbol (s
);
1653 *strchr (s
, '\0') = c
;
1654 if (sym
&& (framereg
= S_GET_VALUE (sym
)) <= 31)
1657 as_warn (_("frame reg expected, using $%d."), framereg
);
1660 note_gpreg (framereg
);
1664 /* This is called before the symbol table is processed. In order to
1665 work with gcc when using mips-tfile, we must keep all local labels.
1666 However, in other cases, we want to discard them. If we were
1667 called with -g, but we didn't see any debugging information, it may
1668 mean that gcc is smuggling debugging information through to
1669 mips-tfile, in which case we must generate all local labels. */
1674 alpha_frob_file_before_adjust ()
1676 if (alpha_debug
!= 0
1677 && ! ecoff_debugging_seen
)
1678 flag_keep_locals
= 1;
1681 #endif /* OBJ_ECOFF */
1683 static struct alpha_reloc_tag
*
1684 get_alpha_reloc_tag (sequence
)
1687 char buffer
[ALPHA_RELOC_DIGITS
];
1688 struct alpha_reloc_tag
*info
;
1690 sprintf (buffer
, "!%ld", sequence
);
1692 info
= (struct alpha_reloc_tag
*) hash_find (alpha_literal_hash
, buffer
);
1695 size_t len
= strlen (buffer
);
1698 info
= (struct alpha_reloc_tag
*)
1699 xcalloc (sizeof (struct alpha_reloc_tag
) + len
, 1);
1701 info
->segment
= now_seg
;
1702 info
->sequence
= sequence
;
1703 strcpy (info
->string
, buffer
);
1704 errmsg
= hash_insert (alpha_literal_hash
, info
->string
, (PTR
) info
);
1712 /* Before the relocations are written, reorder them, so that user
1713 supplied !lituse relocations follow the appropriate !literal
1714 relocations, and similarly for !gpdisp relocations. */
1717 alpha_adjust_symtab ()
1719 if (alpha_literal_hash
)
1720 bfd_map_over_sections (stdoutput
, alpha_adjust_symtab_relocs
, NULL
);
1724 alpha_adjust_symtab_relocs (abfd
, sec
, ptr
)
1725 bfd
*abfd ATTRIBUTE_UNUSED
;
1727 PTR ptr ATTRIBUTE_UNUSED
;
1729 segment_info_type
*seginfo
= seg_info (sec
);
1735 /* If seginfo is NULL, we did not create this section; don't do
1736 anything with it. By using a pointer to a pointer, we can update
1737 the links in place. */
1738 if (seginfo
== NULL
)
1741 /* If there are no relocations, skip the section. */
1742 if (! seginfo
->fix_root
)
1745 /* First rebuild the fixup chain without the expicit lituse and
1746 gpdisp_lo16 relocs. */
1747 prevP
= &seginfo
->fix_root
;
1748 for (fixp
= seginfo
->fix_root
; fixp
; fixp
= next
)
1750 next
= fixp
->fx_next
;
1751 fixp
->fx_next
= (fixS
*) 0;
1753 switch (fixp
->fx_r_type
)
1755 case BFD_RELOC_ALPHA_LITUSE
:
1756 if (fixp
->tc_fix_data
.info
->n_master
== 0)
1757 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1758 _("No !literal!%ld was found"),
1759 fixp
->tc_fix_data
.info
->sequence
);
1760 if (fixp
->fx_offset
== LITUSE_ALPHA_TLSGD
)
1762 if (! fixp
->tc_fix_data
.info
->saw_tlsgd
)
1763 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1764 _("No !tlsgd!%ld was found"),
1765 fixp
->tc_fix_data
.info
->sequence
);
1767 else if (fixp
->fx_offset
== LITUSE_ALPHA_TLSLDM
)
1769 if (! fixp
->tc_fix_data
.info
->saw_tlsldm
)
1770 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1771 _("No !tlsldm!%ld was found"),
1772 fixp
->tc_fix_data
.info
->sequence
);
1776 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1777 if (fixp
->tc_fix_data
.info
->n_master
== 0)
1778 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1779 _("No ldah !gpdisp!%ld was found"),
1780 fixp
->tc_fix_data
.info
->sequence
);
1783 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1784 if (fixp
->tc_fix_data
.info
1785 && (fixp
->tc_fix_data
.info
->saw_tlsgd
1786 || fixp
->tc_fix_data
.info
->saw_tlsldm
))
1792 prevP
= &fixp
->fx_next
;
1797 /* Go back and re-chain dependent relocations. They are currently
1798 linked through the next_reloc field in reverse order, so as we
1799 go through the next_reloc chain, we effectively reverse the chain
1802 Except if there is more than one !literal for a given sequence
1803 number. In that case, the programmer and/or compiler is not sure
1804 how control flows from literal to lituse, and we can't be sure to
1805 get the relaxation correct.
1807 ??? Well, actually we could, if there are enough lituses such that
1808 we can make each literal have at least one of each lituse type
1809 present. Not implemented.
1811 Also suppress the optimization if the !literals/!lituses are spread
1812 in different segments. This can happen with "intersting" uses of
1813 inline assembly; examples are present in the Linux kernel semaphores. */
1815 for (fixp
= seginfo
->fix_root
; fixp
; fixp
= next
)
1817 next
= fixp
->fx_next
;
1818 switch (fixp
->fx_r_type
)
1820 case BFD_RELOC_ALPHA_TLSGD
:
1821 case BFD_RELOC_ALPHA_TLSLDM
:
1822 if (!fixp
->tc_fix_data
.info
)
1824 if (fixp
->tc_fix_data
.info
->n_master
== 0)
1826 else if (fixp
->tc_fix_data
.info
->n_master
> 1)
1828 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1829 _("too many !literal!%ld for %s"),
1830 fixp
->tc_fix_data
.info
->sequence
,
1831 (fixp
->fx_r_type
== BFD_RELOC_ALPHA_TLSGD
1832 ? "!tlsgd" : "!tlsldm"));
1836 fixp
->tc_fix_data
.info
->master
->fx_next
= fixp
->fx_next
;
1837 fixp
->fx_next
= fixp
->tc_fix_data
.info
->master
;
1838 fixp
= fixp
->fx_next
;
1841 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1842 if (fixp
->tc_fix_data
.info
1843 && fixp
->tc_fix_data
.info
->n_master
== 1
1844 && ! fixp
->tc_fix_data
.info
->multi_section_p
)
1846 for (slave
= fixp
->tc_fix_data
.info
->slaves
;
1847 slave
!= (fixS
*) 0;
1848 slave
= slave
->tc_fix_data
.next_reloc
)
1850 slave
->fx_next
= fixp
->fx_next
;
1851 fixp
->fx_next
= slave
;
1856 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1857 if (fixp
->tc_fix_data
.info
->n_slaves
== 0)
1858 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1859 _("No lda !gpdisp!%ld was found"),
1860 fixp
->tc_fix_data
.info
->sequence
);
1863 slave
= fixp
->tc_fix_data
.info
->slaves
;
1864 slave
->fx_next
= next
;
1865 fixp
->fx_next
= slave
;
1877 debug_exp (tok
, ntok
)
1883 fprintf (stderr
, "debug_exp: %d tokens", ntok
);
1884 for (i
= 0; i
< ntok
; i
++)
1886 expressionS
*t
= &tok
[i
];
1890 default: name
= "unknown"; break;
1891 case O_illegal
: name
= "O_illegal"; break;
1892 case O_absent
: name
= "O_absent"; break;
1893 case O_constant
: name
= "O_constant"; break;
1894 case O_symbol
: name
= "O_symbol"; break;
1895 case O_symbol_rva
: name
= "O_symbol_rva"; break;
1896 case O_register
: name
= "O_register"; break;
1897 case O_big
: name
= "O_big"; break;
1898 case O_uminus
: name
= "O_uminus"; break;
1899 case O_bit_not
: name
= "O_bit_not"; break;
1900 case O_logical_not
: name
= "O_logical_not"; break;
1901 case O_multiply
: name
= "O_multiply"; break;
1902 case O_divide
: name
= "O_divide"; break;
1903 case O_modulus
: name
= "O_modulus"; break;
1904 case O_left_shift
: name
= "O_left_shift"; break;
1905 case O_right_shift
: name
= "O_right_shift"; break;
1906 case O_bit_inclusive_or
: name
= "O_bit_inclusive_or"; break;
1907 case O_bit_or_not
: name
= "O_bit_or_not"; break;
1908 case O_bit_exclusive_or
: name
= "O_bit_exclusive_or"; break;
1909 case O_bit_and
: name
= "O_bit_and"; break;
1910 case O_add
: name
= "O_add"; break;
1911 case O_subtract
: name
= "O_subtract"; break;
1912 case O_eq
: name
= "O_eq"; break;
1913 case O_ne
: name
= "O_ne"; break;
1914 case O_lt
: name
= "O_lt"; break;
1915 case O_le
: name
= "O_le"; break;
1916 case O_ge
: name
= "O_ge"; break;
1917 case O_gt
: name
= "O_gt"; break;
1918 case O_logical_and
: name
= "O_logical_and"; break;
1919 case O_logical_or
: name
= "O_logical_or"; break;
1920 case O_index
: name
= "O_index"; break;
1921 case O_pregister
: name
= "O_pregister"; break;
1922 case O_cpregister
: name
= "O_cpregister"; break;
1923 case O_literal
: name
= "O_literal"; break;
1924 case O_lituse_addr
: name
= "O_lituse_addr"; break;
1925 case O_lituse_base
: name
= "O_lituse_base"; break;
1926 case O_lituse_bytoff
: name
= "O_lituse_bytoff"; break;
1927 case O_lituse_jsr
: name
= "O_lituse_jsr"; break;
1928 case O_lituse_tlsgd
: name
= "O_lituse_tlsgd"; break;
1929 case O_lituse_tlsldm
: name
= "O_lituse_tlsldm"; break;
1930 case O_gpdisp
: name
= "O_gpdisp"; break;
1931 case O_gprelhigh
: name
= "O_gprelhigh"; break;
1932 case O_gprellow
: name
= "O_gprellow"; break;
1933 case O_gprel
: name
= "O_gprel"; break;
1934 case O_samegp
: name
= "O_samegp"; break;
1935 case O_tlsgd
: name
= "O_tlsgd"; break;
1936 case O_tlsldm
: name
= "O_tlsldm"; break;
1937 case O_gotdtprel
: name
= "O_gotdtprel"; break;
1938 case O_dtprelhi
: name
= "O_dtprelhi"; break;
1939 case O_dtprello
: name
= "O_dtprello"; break;
1940 case O_dtprel
: name
= "O_dtprel"; break;
1941 case O_gottprel
: name
= "O_gottprel"; break;
1942 case O_tprelhi
: name
= "O_tprelhi"; break;
1943 case O_tprello
: name
= "O_tprello"; break;
1944 case O_tprel
: name
= "O_tprel"; break;
1947 fprintf (stderr
, ", %s(%s, %s, %d)", name
,
1948 (t
->X_add_symbol
) ? S_GET_NAME (t
->X_add_symbol
) : "--",
1949 (t
->X_op_symbol
) ? S_GET_NAME (t
->X_op_symbol
) : "--",
1950 (int) t
->X_add_number
);
1952 fprintf (stderr
, "\n");
1957 /* Parse the arguments to an opcode. */
1960 tokenize_arguments (str
, tok
, ntok
)
1965 expressionS
*end_tok
= tok
+ ntok
;
1966 char *old_input_line_pointer
;
1967 int saw_comma
= 0, saw_arg
= 0;
1969 expressionS
*orig_tok
= tok
;
1972 const struct alpha_reloc_op_tag
*r
;
1975 int reloc_found_p
= 0;
1977 memset (tok
, 0, sizeof (*tok
) * ntok
);
1979 /* Save and restore input_line_pointer around this function */
1980 old_input_line_pointer
= input_line_pointer
;
1981 input_line_pointer
= str
;
1984 /* ??? Wrest control of ! away from the regular expression parser. */
1985 is_end_of_line
[(unsigned char) '!'] = 1;
1988 while (tok
< end_tok
&& *input_line_pointer
)
1991 switch (*input_line_pointer
)
1998 /* A relocation operand can be placed after the normal operand on an
1999 assembly language statement, and has the following form:
2000 !relocation_type!sequence_number. */
2002 { /* only support one relocation op per insn */
2003 as_bad (_("More than one relocation op per insn"));
2010 ++input_line_pointer
;
2012 p
= input_line_pointer
;
2013 c
= get_symbol_end ();
2015 /* Parse !relocation_type */
2016 len
= input_line_pointer
- p
;
2019 as_bad (_("No relocation operand"));
2023 r
= &alpha_reloc_op
[0];
2024 for (i
= alpha_num_reloc_op
- 1; i
>= 0; i
--, r
++)
2025 if (len
== r
->length
&& memcmp (p
, r
->name
, len
) == 0)
2029 as_bad (_("Unknown relocation operand: !%s"), p
);
2033 *input_line_pointer
= c
;
2035 if (*input_line_pointer
!= '!')
2039 as_bad (_("no sequence number after !%s"), p
);
2043 tok
->X_add_number
= 0;
2049 as_bad (_("!%s does not use a sequence number"), p
);
2053 input_line_pointer
++;
2055 /* Parse !sequence_number */
2057 if (tok
->X_op
!= O_constant
|| tok
->X_add_number
<= 0)
2059 as_bad (_("Bad sequence number: !%s!%s"),
2060 r
->name
, input_line_pointer
);
2069 #endif /* RELOC_OP_P */
2072 ++input_line_pointer
;
2073 if (saw_comma
|| !saw_arg
)
2080 char *hold
= input_line_pointer
++;
2082 /* First try for parenthesized register ... */
2084 if (*input_line_pointer
== ')' && tok
->X_op
== O_register
)
2086 tok
->X_op
= (saw_comma
? O_cpregister
: O_pregister
);
2089 ++input_line_pointer
;
2094 /* ... then fall through to plain expression */
2095 input_line_pointer
= hold
;
2099 if (saw_arg
&& !saw_comma
)
2103 if (tok
->X_op
== O_illegal
|| tok
->X_op
== O_absent
)
2116 input_line_pointer
= old_input_line_pointer
;
2119 debug_exp (orig_tok
, ntok
- (end_tok
- tok
));
2122 is_end_of_line
[(unsigned char) '!'] = 0;
2125 return ntok
- (end_tok
- tok
);
2129 is_end_of_line
[(unsigned char) '!'] = 0;
2131 input_line_pointer
= old_input_line_pointer
;
2132 return TOKENIZE_ERROR
;
2136 is_end_of_line
[(unsigned char) '!'] = 0;
2138 input_line_pointer
= old_input_line_pointer
;
2139 return TOKENIZE_ERROR_REPORT
;
2142 /* Search forward through all variants of an opcode looking for a
2145 static const struct alpha_opcode
*
2146 find_opcode_match (first_opcode
, tok
, pntok
, pcpumatch
)
2147 const struct alpha_opcode
*first_opcode
;
2148 const expressionS
*tok
;
2152 const struct alpha_opcode
*opcode
= first_opcode
;
2154 int got_cpu_match
= 0;
2158 const unsigned char *opidx
;
2161 /* Don't match opcodes that don't exist on this architecture */
2162 if (!(opcode
->flags
& alpha_target
))
2167 for (opidx
= opcode
->operands
; *opidx
; ++opidx
)
2169 const struct alpha_operand
*operand
= &alpha_operands
[*opidx
];
2171 /* only take input from real operands */
2172 if (operand
->flags
& AXP_OPERAND_FAKE
)
2175 /* when we expect input, make sure we have it */
2178 if ((operand
->flags
& AXP_OPERAND_OPTIONAL_MASK
) == 0)
2183 /* match operand type with expression type */
2184 switch (operand
->flags
& AXP_OPERAND_TYPECHECK_MASK
)
2186 case AXP_OPERAND_IR
:
2187 if (tok
[tokidx
].X_op
!= O_register
2188 || !is_ir_num (tok
[tokidx
].X_add_number
))
2191 case AXP_OPERAND_FPR
:
2192 if (tok
[tokidx
].X_op
!= O_register
2193 || !is_fpr_num (tok
[tokidx
].X_add_number
))
2196 case AXP_OPERAND_IR
| AXP_OPERAND_PARENS
:
2197 if (tok
[tokidx
].X_op
!= O_pregister
2198 || !is_ir_num (tok
[tokidx
].X_add_number
))
2201 case AXP_OPERAND_IR
| AXP_OPERAND_PARENS
| AXP_OPERAND_COMMA
:
2202 if (tok
[tokidx
].X_op
!= O_cpregister
2203 || !is_ir_num (tok
[tokidx
].X_add_number
))
2207 case AXP_OPERAND_RELATIVE
:
2208 case AXP_OPERAND_SIGNED
:
2209 case AXP_OPERAND_UNSIGNED
:
2210 switch (tok
[tokidx
].X_op
)
2225 /* everything else should have been fake */
2231 /* possible match -- did we use all of our input? */
2240 while (++opcode
- alpha_opcodes
< alpha_num_opcodes
2241 && !strcmp (opcode
->name
, first_opcode
->name
));
2244 *pcpumatch
= got_cpu_match
;
2249 /* Search forward through all variants of a macro looking for a syntax
2252 static const struct alpha_macro
*
2253 find_macro_match (first_macro
, tok
, pntok
)
2254 const struct alpha_macro
*first_macro
;
2255 const expressionS
*tok
;
2258 const struct alpha_macro
*macro
= first_macro
;
2263 const enum alpha_macro_arg
*arg
= macro
->argsets
;
2277 /* index register */
2279 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_register
2280 || !is_ir_num (tok
[tokidx
].X_add_number
))
2285 /* parenthesized index register */
2287 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_pregister
2288 || !is_ir_num (tok
[tokidx
].X_add_number
))
2293 /* optional parenthesized index register */
2295 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_pregister
2296 && is_ir_num (tok
[tokidx
].X_add_number
))
2300 /* leading comma with a parenthesized index register */
2302 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_cpregister
2303 || !is_ir_num (tok
[tokidx
].X_add_number
))
2308 /* floating point register */
2310 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_register
2311 || !is_fpr_num (tok
[tokidx
].X_add_number
))
2316 /* normal expression */
2320 switch (tok
[tokidx
].X_op
)
2329 case O_lituse_bytoff
:
2345 while (*arg
!= MACRO_EOA
)
2353 while (++macro
- alpha_macros
< alpha_num_macros
2354 && !strcmp (macro
->name
, first_macro
->name
));
2359 /* Insert an operand value into an instruction. */
2362 insert_operand (insn
, operand
, val
, file
, line
)
2364 const struct alpha_operand
*operand
;
2369 if (operand
->bits
!= 32 && !(operand
->flags
& AXP_OPERAND_NOOVERFLOW
))
2373 if (operand
->flags
& AXP_OPERAND_SIGNED
)
2375 max
= (1 << (operand
->bits
- 1)) - 1;
2376 min
= -(1 << (operand
->bits
- 1));
2380 max
= (1 << operand
->bits
) - 1;
2384 if (val
< min
|| val
> max
)
2387 _("operand out of range (%s not between %d and %d)");
2388 char buf
[sizeof (val
) * 3 + 2];
2390 sprint_value (buf
, val
);
2392 as_warn_where (file
, line
, err
, buf
, min
, max
);
2394 as_warn (err
, buf
, min
, max
);
2398 if (operand
->insert
)
2400 const char *errmsg
= NULL
;
2402 insn
= (*operand
->insert
) (insn
, val
, &errmsg
);
2407 insn
|= ((val
& ((1 << operand
->bits
) - 1)) << operand
->shift
);
2413 * Turn an opcode description and a set of arguments into
2414 * an instruction and a fixup.
2418 assemble_insn (opcode
, tok
, ntok
, insn
, reloc
)
2419 const struct alpha_opcode
*opcode
;
2420 const expressionS
*tok
;
2422 struct alpha_insn
*insn
;
2423 bfd_reloc_code_real_type reloc
;
2425 const struct alpha_operand
*reloc_operand
= NULL
;
2426 const expressionS
*reloc_exp
= NULL
;
2427 const unsigned char *argidx
;
2431 memset (insn
, 0, sizeof (*insn
));
2432 image
= opcode
->opcode
;
2434 for (argidx
= opcode
->operands
; *argidx
; ++argidx
)
2436 const struct alpha_operand
*operand
= &alpha_operands
[*argidx
];
2437 const expressionS
*t
= (const expressionS
*) 0;
2439 if (operand
->flags
& AXP_OPERAND_FAKE
)
2441 /* fake operands take no value and generate no fixup */
2442 image
= insert_operand (image
, operand
, 0, NULL
, 0);
2448 switch (operand
->flags
& AXP_OPERAND_OPTIONAL_MASK
)
2450 case AXP_OPERAND_DEFAULT_FIRST
:
2453 case AXP_OPERAND_DEFAULT_SECOND
:
2456 case AXP_OPERAND_DEFAULT_ZERO
:
2458 static expressionS zero_exp
;
2460 zero_exp
.X_op
= O_constant
;
2461 zero_exp
.X_unsigned
= 1;
2476 image
= insert_operand (image
, operand
, regno (t
->X_add_number
),
2481 image
= insert_operand (image
, operand
, t
->X_add_number
, NULL
, 0);
2482 assert (reloc_operand
== NULL
);
2483 reloc_operand
= operand
;
2488 /* This is only 0 for fields that should contain registers,
2489 which means this pattern shouldn't have matched. */
2490 if (operand
->default_reloc
== 0)
2493 /* There is one special case for which an insn receives two
2494 relocations, and thus the user-supplied reloc does not
2495 override the operand reloc. */
2496 if (operand
->default_reloc
== BFD_RELOC_ALPHA_HINT
)
2498 struct alpha_fixup
*fixup
;
2500 if (insn
->nfixups
>= MAX_INSN_FIXUPS
)
2501 as_fatal (_("too many fixups"));
2503 fixup
= &insn
->fixups
[insn
->nfixups
++];
2505 fixup
->reloc
= BFD_RELOC_ALPHA_HINT
;
2509 if (reloc
== BFD_RELOC_UNUSED
)
2510 reloc
= operand
->default_reloc
;
2512 assert (reloc_operand
== NULL
);
2513 reloc_operand
= operand
;
2520 if (reloc
!= BFD_RELOC_UNUSED
)
2522 struct alpha_fixup
*fixup
;
2524 if (insn
->nfixups
>= MAX_INSN_FIXUPS
)
2525 as_fatal (_("too many fixups"));
2527 /* ??? My but this is hacky. But the OSF/1 assembler uses the same
2528 relocation tag for both ldah and lda with gpdisp. Choose the
2529 correct internal relocation based on the opcode. */
2530 if (reloc
== BFD_RELOC_ALPHA_GPDISP
)
2532 if (strcmp (opcode
->name
, "ldah") == 0)
2533 reloc
= BFD_RELOC_ALPHA_GPDISP_HI16
;
2534 else if (strcmp (opcode
->name
, "lda") == 0)
2535 reloc
= BFD_RELOC_ALPHA_GPDISP_LO16
;
2537 as_bad (_("invalid relocation for instruction"));
2540 /* If this is a real relocation (as opposed to a lituse hint), then
2541 the relocation width should match the operand width. */
2542 else if (reloc
< BFD_RELOC_UNUSED
)
2544 reloc_howto_type
*reloc_howto
2545 = bfd_reloc_type_lookup (stdoutput
, reloc
);
2546 if (reloc_howto
->bitsize
!= reloc_operand
->bits
)
2548 as_bad (_("invalid relocation for field"));
2553 fixup
= &insn
->fixups
[insn
->nfixups
++];
2555 fixup
->exp
= *reloc_exp
;
2557 fixup
->exp
.X_op
= O_absent
;
2558 fixup
->reloc
= reloc
;
2565 * Actually output an instruction with its fixup.
2570 struct alpha_insn
*insn
;
2575 /* Take care of alignment duties. */
2576 if (alpha_auto_align_on
&& alpha_current_align
< 2)
2577 alpha_align (2, (char *) NULL
, alpha_insn_label
, 0);
2578 if (alpha_current_align
> 2)
2579 alpha_current_align
= 2;
2580 alpha_insn_label
= NULL
;
2582 /* Write out the instruction. */
2584 md_number_to_chars (f
, insn
->insn
, 4);
2587 dwarf2_emit_insn (4);
2590 /* Apply the fixups in order */
2591 for (i
= 0; i
< insn
->nfixups
; ++i
)
2593 const struct alpha_operand
*operand
= (const struct alpha_operand
*) 0;
2594 struct alpha_fixup
*fixup
= &insn
->fixups
[i
];
2595 struct alpha_reloc_tag
*info
= NULL
;
2599 /* Some fixups are only used internally and so have no howto */
2600 if ((int) fixup
->reloc
< 0)
2602 operand
= &alpha_operands
[-(int) fixup
->reloc
];
2604 pcrel
= ((operand
->flags
& AXP_OPERAND_RELATIVE
) != 0);
2606 else if (fixup
->reloc
> BFD_RELOC_UNUSED
2607 || fixup
->reloc
== BFD_RELOC_ALPHA_GPDISP_HI16
2608 || fixup
->reloc
== BFD_RELOC_ALPHA_GPDISP_LO16
)
2615 reloc_howto_type
*reloc_howto
2616 = bfd_reloc_type_lookup (stdoutput
, fixup
->reloc
);
2617 assert (reloc_howto
);
2619 size
= bfd_get_reloc_size (reloc_howto
);
2620 assert (size
>= 1 && size
<= 4);
2622 pcrel
= reloc_howto
->pc_relative
;
2625 fixP
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, size
,
2626 &fixup
->exp
, pcrel
, fixup
->reloc
);
2628 /* Turn off complaints that the addend is too large for some fixups,
2629 and copy in the sequence number for the explicit relocations. */
2630 switch (fixup
->reloc
)
2632 case BFD_RELOC_ALPHA_HINT
:
2633 case BFD_RELOC_GPREL32
:
2634 case BFD_RELOC_GPREL16
:
2635 case BFD_RELOC_ALPHA_GPREL_HI16
:
2636 case BFD_RELOC_ALPHA_GPREL_LO16
:
2637 case BFD_RELOC_ALPHA_GOTDTPREL16
:
2638 case BFD_RELOC_ALPHA_DTPREL_HI16
:
2639 case BFD_RELOC_ALPHA_DTPREL_LO16
:
2640 case BFD_RELOC_ALPHA_DTPREL16
:
2641 case BFD_RELOC_ALPHA_GOTTPREL16
:
2642 case BFD_RELOC_ALPHA_TPREL_HI16
:
2643 case BFD_RELOC_ALPHA_TPREL_LO16
:
2644 case BFD_RELOC_ALPHA_TPREL16
:
2645 fixP
->fx_no_overflow
= 1;
2648 case BFD_RELOC_ALPHA_GPDISP_HI16
:
2649 fixP
->fx_no_overflow
= 1;
2650 fixP
->fx_addsy
= section_symbol (now_seg
);
2651 fixP
->fx_offset
= 0;
2653 info
= get_alpha_reloc_tag (insn
->sequence
);
2654 if (++info
->n_master
> 1)
2655 as_bad (_("too many ldah insns for !gpdisp!%ld"), insn
->sequence
);
2656 if (info
->segment
!= now_seg
)
2657 as_bad (_("both insns for !gpdisp!%ld must be in the same section"),
2659 fixP
->tc_fix_data
.info
= info
;
2662 case BFD_RELOC_ALPHA_GPDISP_LO16
:
2663 fixP
->fx_no_overflow
= 1;
2665 info
= get_alpha_reloc_tag (insn
->sequence
);
2666 if (++info
->n_slaves
> 1)
2667 as_bad (_("too many lda insns for !gpdisp!%ld"), insn
->sequence
);
2668 if (info
->segment
!= now_seg
)
2669 as_bad (_("both insns for !gpdisp!%ld must be in the same section"),
2671 fixP
->tc_fix_data
.info
= info
;
2672 info
->slaves
= fixP
;
2675 case BFD_RELOC_ALPHA_LITERAL
:
2676 case BFD_RELOC_ALPHA_ELF_LITERAL
:
2677 fixP
->fx_no_overflow
= 1;
2679 if (insn
->sequence
== 0)
2681 info
= get_alpha_reloc_tag (insn
->sequence
);
2682 info
->master
= fixP
;
2684 if (info
->segment
!= now_seg
)
2685 info
->multi_section_p
= 1;
2686 fixP
->tc_fix_data
.info
= info
;
2689 case DUMMY_RELOC_LITUSE_ADDR
:
2690 fixP
->fx_offset
= LITUSE_ALPHA_ADDR
;
2692 case DUMMY_RELOC_LITUSE_BASE
:
2693 fixP
->fx_offset
= LITUSE_ALPHA_BASE
;
2695 case DUMMY_RELOC_LITUSE_BYTOFF
:
2696 fixP
->fx_offset
= LITUSE_ALPHA_BYTOFF
;
2698 case DUMMY_RELOC_LITUSE_JSR
:
2699 fixP
->fx_offset
= LITUSE_ALPHA_JSR
;
2701 case DUMMY_RELOC_LITUSE_TLSGD
:
2702 fixP
->fx_offset
= LITUSE_ALPHA_TLSGD
;
2704 case DUMMY_RELOC_LITUSE_TLSLDM
:
2705 fixP
->fx_offset
= LITUSE_ALPHA_TLSLDM
;
2708 fixP
->fx_addsy
= section_symbol (now_seg
);
2709 fixP
->fx_r_type
= BFD_RELOC_ALPHA_LITUSE
;
2711 info
= get_alpha_reloc_tag (insn
->sequence
);
2712 if (fixup
->reloc
== DUMMY_RELOC_LITUSE_TLSGD
)
2713 info
->saw_lu_tlsgd
= 1;
2714 else if (fixup
->reloc
== DUMMY_RELOC_LITUSE_TLSLDM
)
2715 info
->saw_lu_tlsldm
= 1;
2716 if (++info
->n_slaves
> 1)
2718 if (info
->saw_lu_tlsgd
)
2719 as_bad (_("too many lituse insns for !lituse_tlsgd!%ld"),
2721 else if (info
->saw_lu_tlsldm
)
2722 as_bad (_("too many lituse insns for !lituse_tlsldm!%ld"),
2725 fixP
->tc_fix_data
.info
= info
;
2726 fixP
->tc_fix_data
.next_reloc
= info
->slaves
;
2727 info
->slaves
= fixP
;
2728 if (info
->segment
!= now_seg
)
2729 info
->multi_section_p
= 1;
2732 case BFD_RELOC_ALPHA_TLSGD
:
2733 fixP
->fx_no_overflow
= 1;
2735 if (insn
->sequence
== 0)
2737 info
= get_alpha_reloc_tag (insn
->sequence
);
2738 if (info
->saw_tlsgd
)
2739 as_bad (_("duplicate !tlsgd!%ld"), insn
->sequence
);
2740 else if (info
->saw_tlsldm
)
2741 as_bad (_("sequence number in use for !tlsldm!%ld"),
2744 info
->saw_tlsgd
= 1;
2745 fixP
->tc_fix_data
.info
= info
;
2748 case BFD_RELOC_ALPHA_TLSLDM
:
2749 fixP
->fx_no_overflow
= 1;
2751 if (insn
->sequence
== 0)
2753 info
= get_alpha_reloc_tag (insn
->sequence
);
2754 if (info
->saw_tlsldm
)
2755 as_bad (_("duplicate !tlsldm!%ld"), insn
->sequence
);
2756 else if (info
->saw_tlsgd
)
2757 as_bad (_("sequence number in use for !tlsgd!%ld"),
2760 info
->saw_tlsldm
= 1;
2761 fixP
->tc_fix_data
.info
= info
;
2765 if ((int) fixup
->reloc
< 0)
2767 if (operand
->flags
& AXP_OPERAND_NOOVERFLOW
)
2768 fixP
->fx_no_overflow
= 1;
2775 /* Given an opcode name and a pre-tokenized set of arguments, assemble
2776 the insn, but do not emit it.
2778 Note that this implies no macros allowed, since we can't store more
2779 than one insn in an insn structure. */
2782 assemble_tokens_to_insn (opname
, tok
, ntok
, insn
)
2784 const expressionS
*tok
;
2786 struct alpha_insn
*insn
;
2788 const struct alpha_opcode
*opcode
;
2790 /* search opcodes */
2791 opcode
= (const struct alpha_opcode
*) hash_find (alpha_opcode_hash
, opname
);
2795 opcode
= find_opcode_match (opcode
, tok
, &ntok
, &cpumatch
);
2798 assemble_insn (opcode
, tok
, ntok
, insn
, BFD_RELOC_UNUSED
);
2802 as_bad (_("inappropriate arguments for opcode `%s'"), opname
);
2804 as_bad (_("opcode `%s' not supported for target %s"), opname
,
2808 as_bad (_("unknown opcode `%s'"), opname
);
2811 /* Given an opcode name and a pre-tokenized set of arguments, take the
2812 opcode all the way through emission. */
2815 assemble_tokens (opname
, tok
, ntok
, local_macros_on
)
2817 const expressionS
*tok
;
2819 int local_macros_on
;
2821 int found_something
= 0;
2822 const struct alpha_opcode
*opcode
;
2823 const struct alpha_macro
*macro
;
2825 bfd_reloc_code_real_type reloc
= BFD_RELOC_UNUSED
;
2828 /* If a user-specified relocation is present, this is not a macro. */
2829 if (ntok
&& USER_RELOC_P (tok
[ntok
- 1].X_op
))
2831 reloc
= ALPHA_RELOC_TABLE (tok
[ntok
- 1].X_op
)->reloc
;
2836 if (local_macros_on
)
2838 macro
= ((const struct alpha_macro
*)
2839 hash_find (alpha_macro_hash
, opname
));
2842 found_something
= 1;
2843 macro
= find_macro_match (macro
, tok
, &ntok
);
2846 (*macro
->emit
) (tok
, ntok
, macro
->arg
);
2852 /* search opcodes */
2853 opcode
= (const struct alpha_opcode
*) hash_find (alpha_opcode_hash
, opname
);
2856 found_something
= 1;
2857 opcode
= find_opcode_match (opcode
, tok
, &ntok
, &cpumatch
);
2860 struct alpha_insn insn
;
2861 assemble_insn (opcode
, tok
, ntok
, &insn
, reloc
);
2863 /* Copy the sequence number for the reloc from the reloc token. */
2864 if (reloc
!= BFD_RELOC_UNUSED
)
2865 insn
.sequence
= tok
[ntok
].X_add_number
;
2872 if (found_something
)
2875 as_bad (_("inappropriate arguments for opcode `%s'"), opname
);
2877 as_bad (_("opcode `%s' not supported for target %s"), opname
,
2881 as_bad (_("unknown opcode `%s'"), opname
);
2884 /* Some instruction sets indexed by lg(size) */
2885 static const char * const sextX_op
[] = { "sextb", "sextw", "sextl", NULL
};
2886 static const char * const insXl_op
[] = { "insbl", "inswl", "insll", "insql" };
2887 static const char * const insXh_op
[] = { NULL
, "inswh", "inslh", "insqh" };
2888 static const char * const extXl_op
[] = { "extbl", "extwl", "extll", "extql" };
2889 static const char * const extXh_op
[] = { NULL
, "extwh", "extlh", "extqh" };
2890 static const char * const mskXl_op
[] = { "mskbl", "mskwl", "mskll", "mskql" };
2891 static const char * const mskXh_op
[] = { NULL
, "mskwh", "msklh", "mskqh" };
2892 static const char * const stX_op
[] = { "stb", "stw", "stl", "stq" };
2893 static const char * const ldXu_op
[] = { "ldbu", "ldwu", NULL
, NULL
};
2895 /* Implement the ldgp macro. */
2898 emit_ldgp (tok
, ntok
, unused
)
2899 const expressionS
*tok
;
2900 int ntok ATTRIBUTE_UNUSED
;
2901 const PTR unused ATTRIBUTE_UNUSED
;
2906 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
2907 /* from "ldgp r1,n(r2)", generate "ldah r1,X(R2); lda r1,Y(r1)"
2908 with appropriate constants and relocations. */
2909 struct alpha_insn insn
;
2910 expressionS newtok
[3];
2914 if (regno (tok
[2].X_add_number
) == AXP_REG_PV
)
2915 ecoff_set_gp_prolog_size (0);
2919 set_tok_const (newtok
[1], 0);
2922 assemble_tokens_to_insn ("ldah", newtok
, 3, &insn
);
2927 if (addend
.X_op
!= O_constant
)
2928 as_bad (_("can not resolve expression"));
2929 addend
.X_op
= O_symbol
;
2930 addend
.X_add_symbol
= alpha_gp_symbol
;
2934 insn
.fixups
[0].exp
= addend
;
2935 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_GPDISP_HI16
;
2936 insn
.sequence
= next_sequence_num
;
2940 set_tok_preg (newtok
[2], tok
[0].X_add_number
);
2942 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
2945 addend
.X_add_number
+= 4;
2949 insn
.fixups
[0].exp
= addend
;
2950 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_GPDISP_LO16
;
2951 insn
.sequence
= next_sequence_num
--;
2954 #endif /* OBJ_ECOFF || OBJ_ELF */
2959 /* Add symbol+addend to link pool.
2960 Return offset from basesym to entry in link pool.
2962 Add new fixup only if offset isn't 16bit. */
2965 add_to_link_pool (basesym
, sym
, addend
)
2970 segT current_section
= now_seg
;
2971 int current_subsec
= now_subseg
;
2973 bfd_reloc_code_real_type reloc_type
;
2975 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
2978 offset
= - *symbol_get_obj (basesym
);
2980 /* @@ This assumes all entries in a given section will be of the same
2981 size... Probably correct, but unwise to rely on. */
2982 /* This must always be called with the same subsegment. */
2984 if (seginfo
->frchainP
)
2985 for (fixp
= seginfo
->frchainP
->fix_root
;
2986 fixp
!= (fixS
*) NULL
;
2987 fixp
= fixp
->fx_next
, offset
+= 8)
2989 if (fixp
->fx_addsy
== sym
&& fixp
->fx_offset
== addend
)
2991 if (range_signed_16 (offset
))
2998 /* Not found in 16bit signed range. */
3000 subseg_set (alpha_link_section
, 0);
3004 fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, sym
, addend
, 0,
3007 subseg_set (current_section
, current_subsec
);
3008 seginfo
->literal_pool_size
+= 8;
3012 #endif /* OBJ_EVAX */
3014 /* Load a (partial) expression into a target register.
3016 If poffset is not null, after the call it will either contain
3017 O_constant 0, or a 16-bit offset appropriate for any MEM format
3018 instruction. In addition, pbasereg will be modified to point to
3019 the base register to use in that MEM format instruction.
3021 In any case, *pbasereg should contain a base register to add to the
3022 expression. This will normally be either AXP_REG_ZERO or
3023 alpha_gp_register. Symbol addresses will always be loaded via $gp,
3024 so "foo($0)" is interpreted as adding the address of foo to $0;
3025 i.e. "ldq $targ, LIT($gp); addq $targ, $0, $targ". Odd, perhaps,
3026 but this is what OSF/1 does.
3028 If explicit relocations of the form !literal!<number> are allowed,
3029 and used, then explict_reloc with be an expression pointer.
3031 Finally, the return value is nonzero if the calling macro may emit
3032 a LITUSE reloc if otherwise appropriate; the return value is the
3033 sequence number to use. */
3036 load_expression (targreg
, exp
, pbasereg
, poffset
)
3038 const expressionS
*exp
;
3040 expressionS
*poffset
;
3042 long emit_lituse
= 0;
3043 offsetT addend
= exp
->X_add_number
;
3044 int basereg
= *pbasereg
;
3045 struct alpha_insn insn
;
3046 expressionS newtok
[3];
3055 /* attempt to reduce .lit load by splitting the offset from
3056 its symbol when possible, but don't create a situation in
3058 if (!range_signed_32 (addend
) &&
3059 (alpha_noat_on
|| targreg
== AXP_REG_AT
))
3061 lit
= add_to_literal_pool (exp
->X_add_symbol
, addend
,
3062 alpha_lita_section
, 8);
3067 lit
= add_to_literal_pool (exp
->X_add_symbol
, 0,
3068 alpha_lita_section
, 8);
3072 as_fatal (_("overflow in literal (.lita) table"));
3074 /* emit "ldq r, lit(gp)" */
3076 if (basereg
!= alpha_gp_register
&& targreg
== basereg
)
3079 as_bad (_("macro requires $at register while noat in effect"));
3080 if (targreg
== AXP_REG_AT
)
3081 as_bad (_("macro requires $at while $at in use"));
3083 set_tok_reg (newtok
[0], AXP_REG_AT
);
3086 set_tok_reg (newtok
[0], targreg
);
3087 set_tok_sym (newtok
[1], alpha_lita_symbol
, lit
);
3088 set_tok_preg (newtok
[2], alpha_gp_register
);
3090 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
3092 assert (insn
.nfixups
== 1);
3093 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITERAL
;
3094 insn
.sequence
= emit_lituse
= next_sequence_num
--;
3095 #endif /* OBJ_ECOFF */
3097 /* emit "ldq r, gotoff(gp)" */
3099 if (basereg
!= alpha_gp_register
&& targreg
== basereg
)
3102 as_bad (_("macro requires $at register while noat in effect"));
3103 if (targreg
== AXP_REG_AT
)
3104 as_bad (_("macro requires $at while $at in use"));
3106 set_tok_reg (newtok
[0], AXP_REG_AT
);
3109 set_tok_reg (newtok
[0], targreg
);
3111 /* XXX: Disable this .got minimizing optimization so that we can get
3112 better instruction offset knowledge in the compiler. This happens
3113 very infrequently anyway. */
3115 || (!range_signed_32 (addend
)
3116 && (alpha_noat_on
|| targreg
== AXP_REG_AT
)))
3123 set_tok_sym (newtok
[1], exp
->X_add_symbol
, 0);
3126 set_tok_preg (newtok
[2], alpha_gp_register
);
3128 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
3130 assert (insn
.nfixups
== 1);
3131 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_ELF_LITERAL
;
3132 insn
.sequence
= emit_lituse
= next_sequence_num
--;
3133 #endif /* OBJ_ELF */
3137 /* Find symbol or symbol pointer in link section. */
3139 if (exp
->X_add_symbol
== alpha_evax_proc
.symbol
)
3141 if (range_signed_16 (addend
))
3143 set_tok_reg (newtok
[0], targreg
);
3144 set_tok_const (newtok
[1], addend
);
3145 set_tok_preg (newtok
[2], basereg
);
3146 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
3151 set_tok_reg (newtok
[0], targreg
);
3152 set_tok_const (newtok
[1], 0);
3153 set_tok_preg (newtok
[2], basereg
);
3154 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
3159 if (!range_signed_32 (addend
))
3161 link
= add_to_link_pool (alpha_evax_proc
.symbol
,
3162 exp
->X_add_symbol
, addend
);
3167 link
= add_to_link_pool (alpha_evax_proc
.symbol
,
3168 exp
->X_add_symbol
, 0);
3170 set_tok_reg (newtok
[0], targreg
);
3171 set_tok_const (newtok
[1], link
);
3172 set_tok_preg (newtok
[2], basereg
);
3173 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
3175 #endif /* OBJ_EVAX */
3180 if (basereg
!= alpha_gp_register
&& basereg
!= AXP_REG_ZERO
)
3182 /* emit "addq r, base, r" */
3184 set_tok_reg (newtok
[1], basereg
);
3185 set_tok_reg (newtok
[2], targreg
);
3186 assemble_tokens ("addq", newtok
, 3, 0);
3198 /* Assume that this difference expression will be resolved to an
3199 absolute value and that that value will fit in 16 bits. */
3201 set_tok_reg (newtok
[0], targreg
);
3203 set_tok_preg (newtok
[2], basereg
);
3204 assemble_tokens ("lda", newtok
, 3, 0);
3207 set_tok_const (*poffset
, 0);
3211 if (exp
->X_add_number
> 0)
3212 as_bad (_("bignum invalid; zero assumed"));
3214 as_bad (_("floating point number invalid; zero assumed"));
3219 as_bad (_("can't handle expression"));
3224 if (!range_signed_32 (addend
))
3227 long seq_num
= next_sequence_num
--;
3229 /* For 64-bit addends, just put it in the literal pool. */
3232 /* emit "ldq targreg, lit(basereg)" */
3233 lit
= add_to_link_pool (alpha_evax_proc
.symbol
,
3234 section_symbol (absolute_section
), addend
);
3235 set_tok_reg (newtok
[0], targreg
);
3236 set_tok_const (newtok
[1], lit
);
3237 set_tok_preg (newtok
[2], alpha_gp_register
);
3238 assemble_tokens ("ldq", newtok
, 3, 0);
3241 if (alpha_lit8_section
== NULL
)
3243 create_literal_section (".lit8",
3244 &alpha_lit8_section
,
3245 &alpha_lit8_symbol
);
3248 alpha_lit8_literal
= add_to_literal_pool (alpha_lit8_symbol
, 0x8000,
3249 alpha_lita_section
, 8);
3250 if (alpha_lit8_literal
>= 0x8000)
3251 as_fatal (_("overflow in literal (.lita) table"));
3255 lit
= add_to_literal_pool (NULL
, addend
, alpha_lit8_section
, 8) - 0x8000;
3257 as_fatal (_("overflow in literal (.lit8) table"));
3259 /* emit "lda litreg, .lit8+0x8000" */
3261 if (targreg
== basereg
)
3264 as_bad (_("macro requires $at register while noat in effect"));
3265 if (targreg
== AXP_REG_AT
)
3266 as_bad (_("macro requires $at while $at in use"));
3268 set_tok_reg (newtok
[0], AXP_REG_AT
);
3271 set_tok_reg (newtok
[0], targreg
);
3273 set_tok_sym (newtok
[1], alpha_lita_symbol
, alpha_lit8_literal
);
3276 set_tok_sym (newtok
[1], alpha_lit8_symbol
, 0x8000);
3278 set_tok_preg (newtok
[2], alpha_gp_register
);
3280 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
3282 assert (insn
.nfixups
== 1);
3284 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITERAL
;
3287 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_ELF_LITERAL
;
3289 insn
.sequence
= seq_num
;
3293 /* emit "ldq litreg, lit(litreg)" */
3295 set_tok_const (newtok
[1], lit
);
3296 set_tok_preg (newtok
[2], newtok
[0].X_add_number
);
3298 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
3300 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3301 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BASE
;
3302 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3304 insn
.sequence
= seq_num
;
3309 /* emit "addq litreg, base, target" */
3311 if (basereg
!= AXP_REG_ZERO
)
3313 set_tok_reg (newtok
[1], basereg
);
3314 set_tok_reg (newtok
[2], targreg
);
3315 assemble_tokens ("addq", newtok
, 3, 0);
3317 #endif /* !OBJ_EVAX */
3320 set_tok_const (*poffset
, 0);
3321 *pbasereg
= targreg
;
3325 offsetT low
, high
, extra
, tmp
;
3327 /* for 32-bit operands, break up the addend */
3329 low
= sign_extend_16 (addend
);
3331 high
= sign_extend_16 (tmp
>> 16);
3333 if (tmp
- (high
<< 16))
3337 high
= sign_extend_16 (tmp
>> 16);
3342 set_tok_reg (newtok
[0], targreg
);
3343 set_tok_preg (newtok
[2], basereg
);
3347 /* emit "ldah r, extra(r) */
3348 set_tok_const (newtok
[1], extra
);
3349 assemble_tokens ("ldah", newtok
, 3, 0);
3350 set_tok_preg (newtok
[2], basereg
= targreg
);
3355 /* emit "ldah r, high(r) */
3356 set_tok_const (newtok
[1], high
);
3357 assemble_tokens ("ldah", newtok
, 3, 0);
3359 set_tok_preg (newtok
[2], basereg
);
3362 if ((low
&& !poffset
) || (!poffset
&& basereg
!= targreg
))
3364 /* emit "lda r, low(base)" */
3365 set_tok_const (newtok
[1], low
);
3366 assemble_tokens ("lda", newtok
, 3, 0);
3372 set_tok_const (*poffset
, low
);
3373 *pbasereg
= basereg
;
3379 /* The lda macro differs from the lda instruction in that it handles
3380 most simple expressions, particualrly symbol address loads and
3384 emit_lda (tok
, ntok
, unused
)
3385 const expressionS
*tok
;
3387 const PTR unused ATTRIBUTE_UNUSED
;
3392 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
3394 basereg
= tok
[2].X_add_number
;
3396 (void) load_expression (tok
[0].X_add_number
, &tok
[1], &basereg
, NULL
);
3399 /* The ldah macro differs from the ldah instruction in that it has $31
3400 as an implied base register. */
3403 emit_ldah (tok
, ntok
, unused
)
3404 const expressionS
*tok
;
3405 int ntok ATTRIBUTE_UNUSED
;
3406 const PTR unused ATTRIBUTE_UNUSED
;
3408 expressionS newtok
[3];
3412 set_tok_preg (newtok
[2], AXP_REG_ZERO
);
3414 assemble_tokens ("ldah", newtok
, 3, 0);
3417 /* Handle all "simple" integer register loads -- ldq, ldq_l, ldq_u,
3418 etc. They differ from the real instructions in that they do simple
3419 expressions like the lda macro. */
3422 emit_ir_load (tok
, ntok
, opname
)
3423 const expressionS
*tok
;
3429 expressionS newtok
[3];
3430 struct alpha_insn insn
;
3433 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
3435 basereg
= tok
[2].X_add_number
;
3437 lituse
= load_expression (tok
[0].X_add_number
, &tok
[1], &basereg
,
3441 set_tok_preg (newtok
[2], basereg
);
3443 assemble_tokens_to_insn ((const char *) opname
, newtok
, 3, &insn
);
3447 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3448 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BASE
;
3449 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3451 insn
.sequence
= lituse
;
3457 /* Handle fp register loads, and both integer and fp register stores.
3458 Again, we handle simple expressions. */
3461 emit_loadstore (tok
, ntok
, opname
)
3462 const expressionS
*tok
;
3468 expressionS newtok
[3];
3469 struct alpha_insn insn
;
3472 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
3474 basereg
= tok
[2].X_add_number
;
3476 if (tok
[1].X_op
!= O_constant
|| !range_signed_16 (tok
[1].X_add_number
))
3479 as_bad (_("macro requires $at register while noat in effect"));
3481 lituse
= load_expression (AXP_REG_AT
, &tok
[1], &basereg
, &newtok
[1]);
3490 set_tok_preg (newtok
[2], basereg
);
3492 assemble_tokens_to_insn ((const char *) opname
, newtok
, 3, &insn
);
3496 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3497 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BASE
;
3498 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3500 insn
.sequence
= lituse
;
3506 /* Load a half-word or byte as an unsigned value. */
3509 emit_ldXu (tok
, ntok
, vlgsize
)
3510 const expressionS
*tok
;
3514 if (alpha_target
& AXP_OPCODE_BWX
)
3515 emit_ir_load (tok
, ntok
, ldXu_op
[(long) vlgsize
]);
3518 expressionS newtok
[3];
3519 struct alpha_insn insn
;
3524 as_bad (_("macro requires $at register while noat in effect"));
3527 basereg
= (tok
[1].X_op
== O_constant
3528 ? AXP_REG_ZERO
: alpha_gp_register
);
3530 basereg
= tok
[2].X_add_number
;
3532 /* emit "lda $at, exp" */
3534 lituse
= load_expression (AXP_REG_AT
, &tok
[1], &basereg
, NULL
);
3536 /* emit "ldq_u targ, 0($at)" */
3539 set_tok_const (newtok
[1], 0);
3540 set_tok_preg (newtok
[2], basereg
);
3541 assemble_tokens_to_insn ("ldq_u", newtok
, 3, &insn
);
3545 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3546 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BASE
;
3547 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3549 insn
.sequence
= lituse
;
3554 /* emit "extXl targ, $at, targ" */
3556 set_tok_reg (newtok
[1], basereg
);
3557 newtok
[2] = newtok
[0];
3558 assemble_tokens_to_insn (extXl_op
[(long) vlgsize
], newtok
, 3, &insn
);
3562 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3563 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BYTOFF
;
3564 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3566 insn
.sequence
= lituse
;
3573 /* Load a half-word or byte as a signed value. */
3576 emit_ldX (tok
, ntok
, vlgsize
)
3577 const expressionS
*tok
;
3581 emit_ldXu (tok
, ntok
, vlgsize
);
3582 assemble_tokens (sextX_op
[(long) vlgsize
], tok
, 1, 1);
3585 /* Load an integral value from an unaligned address as an unsigned
3589 emit_uldXu (tok
, ntok
, vlgsize
)
3590 const expressionS
*tok
;
3594 long lgsize
= (long) vlgsize
;
3595 expressionS newtok
[3];
3598 as_bad (_("macro requires $at register while noat in effect"));
3600 /* emit "lda $at, exp" */
3602 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
3603 newtok
[0].X_add_number
= AXP_REG_AT
;
3604 assemble_tokens ("lda", newtok
, ntok
, 1);
3606 /* emit "ldq_u $t9, 0($at)" */
3608 set_tok_reg (newtok
[0], AXP_REG_T9
);
3609 set_tok_const (newtok
[1], 0);
3610 set_tok_preg (newtok
[2], AXP_REG_AT
);
3611 assemble_tokens ("ldq_u", newtok
, 3, 1);
3613 /* emit "ldq_u $t10, size-1($at)" */
3615 set_tok_reg (newtok
[0], AXP_REG_T10
);
3616 set_tok_const (newtok
[1], (1 << lgsize
) - 1);
3617 assemble_tokens ("ldq_u", newtok
, 3, 1);
3619 /* emit "extXl $t9, $at, $t9" */
3621 set_tok_reg (newtok
[0], AXP_REG_T9
);
3622 set_tok_reg (newtok
[1], AXP_REG_AT
);
3623 set_tok_reg (newtok
[2], AXP_REG_T9
);
3624 assemble_tokens (extXl_op
[lgsize
], newtok
, 3, 1);
3626 /* emit "extXh $t10, $at, $t10" */
3628 set_tok_reg (newtok
[0], AXP_REG_T10
);
3629 set_tok_reg (newtok
[2], AXP_REG_T10
);
3630 assemble_tokens (extXh_op
[lgsize
], newtok
, 3, 1);
3632 /* emit "or $t9, $t10, targ" */
3634 set_tok_reg (newtok
[0], AXP_REG_T9
);
3635 set_tok_reg (newtok
[1], AXP_REG_T10
);
3637 assemble_tokens ("or", newtok
, 3, 1);
3640 /* Load an integral value from an unaligned address as a signed value.
3641 Note that quads should get funneled to the unsigned load since we
3642 don't have to do the sign extension. */
3645 emit_uldX (tok
, ntok
, vlgsize
)
3646 const expressionS
*tok
;
3650 emit_uldXu (tok
, ntok
, vlgsize
);
3651 assemble_tokens (sextX_op
[(long) vlgsize
], tok
, 1, 1);
3654 /* Implement the ldil macro. */
3657 emit_ldil (tok
, ntok
, unused
)
3658 const expressionS
*tok
;
3660 const PTR unused ATTRIBUTE_UNUSED
;
3662 expressionS newtok
[2];
3664 memcpy (newtok
, tok
, sizeof (newtok
));
3665 newtok
[1].X_add_number
= sign_extend_32 (tok
[1].X_add_number
);
3667 assemble_tokens ("lda", newtok
, ntok
, 1);
3670 /* Store a half-word or byte. */
3673 emit_stX (tok
, ntok
, vlgsize
)
3674 const expressionS
*tok
;
3678 int lgsize
= (int) (long) vlgsize
;
3680 if (alpha_target
& AXP_OPCODE_BWX
)
3681 emit_loadstore (tok
, ntok
, stX_op
[lgsize
]);
3684 expressionS newtok
[3];
3685 struct alpha_insn insn
;
3690 as_bad (_("macro requires $at register while noat in effect"));
3693 basereg
= (tok
[1].X_op
== O_constant
3694 ? AXP_REG_ZERO
: alpha_gp_register
);
3696 basereg
= tok
[2].X_add_number
;
3698 /* emit "lda $at, exp" */
3700 lituse
= load_expression (AXP_REG_AT
, &tok
[1], &basereg
, NULL
);
3702 /* emit "ldq_u $t9, 0($at)" */
3704 set_tok_reg (newtok
[0], AXP_REG_T9
);
3705 set_tok_const (newtok
[1], 0);
3706 set_tok_preg (newtok
[2], basereg
);
3707 assemble_tokens_to_insn ("ldq_u", newtok
, 3, &insn
);
3711 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3712 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BASE
;
3713 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3715 insn
.sequence
= lituse
;
3720 /* emit "insXl src, $at, $t10" */
3723 set_tok_reg (newtok
[1], basereg
);
3724 set_tok_reg (newtok
[2], AXP_REG_T10
);
3725 assemble_tokens_to_insn (insXl_op
[lgsize
], newtok
, 3, &insn
);
3729 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3730 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BYTOFF
;
3731 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3733 insn
.sequence
= lituse
;
3738 /* emit "mskXl $t9, $at, $t9" */
3740 set_tok_reg (newtok
[0], AXP_REG_T9
);
3741 newtok
[2] = newtok
[0];
3742 assemble_tokens_to_insn (mskXl_op
[lgsize
], newtok
, 3, &insn
);
3746 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3747 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BYTOFF
;
3748 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3750 insn
.sequence
= lituse
;
3755 /* emit "or $t9, $t10, $t9" */
3757 set_tok_reg (newtok
[1], AXP_REG_T10
);
3758 assemble_tokens ("or", newtok
, 3, 1);
3760 /* emit "stq_u $t9, 0($at) */
3762 set_tok_const(newtok
[1], 0);
3763 set_tok_preg (newtok
[2], AXP_REG_AT
);
3764 assemble_tokens_to_insn ("stq_u", newtok
, 3, &insn
);
3768 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3769 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BASE
;
3770 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3772 insn
.sequence
= lituse
;
3779 /* Store an integer to an unaligned address. */
3782 emit_ustX (tok
, ntok
, vlgsize
)
3783 const expressionS
*tok
;
3787 int lgsize
= (int) (long) vlgsize
;
3788 expressionS newtok
[3];
3790 /* emit "lda $at, exp" */
3792 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
3793 newtok
[0].X_add_number
= AXP_REG_AT
;
3794 assemble_tokens ("lda", newtok
, ntok
, 1);
3796 /* emit "ldq_u $9, 0($at)" */
3798 set_tok_reg (newtok
[0], AXP_REG_T9
);
3799 set_tok_const (newtok
[1], 0);
3800 set_tok_preg (newtok
[2], AXP_REG_AT
);
3801 assemble_tokens ("ldq_u", newtok
, 3, 1);
3803 /* emit "ldq_u $10, size-1($at)" */
3805 set_tok_reg (newtok
[0], AXP_REG_T10
);
3806 set_tok_const (newtok
[1], (1 << lgsize
) - 1);
3807 assemble_tokens ("ldq_u", newtok
, 3, 1);
3809 /* emit "insXl src, $at, $t11" */
3812 set_tok_reg (newtok
[1], AXP_REG_AT
);
3813 set_tok_reg (newtok
[2], AXP_REG_T11
);
3814 assemble_tokens (insXl_op
[lgsize
], newtok
, 3, 1);
3816 /* emit "insXh src, $at, $t12" */
3818 set_tok_reg (newtok
[2], AXP_REG_T12
);
3819 assemble_tokens (insXh_op
[lgsize
], newtok
, 3, 1);
3821 /* emit "mskXl $t9, $at, $t9" */
3823 set_tok_reg (newtok
[0], AXP_REG_T9
);
3824 newtok
[2] = newtok
[0];
3825 assemble_tokens (mskXl_op
[lgsize
], newtok
, 3, 1);
3827 /* emit "mskXh $t10, $at, $t10" */
3829 set_tok_reg (newtok
[0], AXP_REG_T10
);
3830 newtok
[2] = newtok
[0];
3831 assemble_tokens (mskXh_op
[lgsize
], newtok
, 3, 1);
3833 /* emit "or $t9, $t11, $t9" */
3835 set_tok_reg (newtok
[0], AXP_REG_T9
);
3836 set_tok_reg (newtok
[1], AXP_REG_T11
);
3837 newtok
[2] = newtok
[0];
3838 assemble_tokens ("or", newtok
, 3, 1);
3840 /* emit "or $t10, $t12, $t10" */
3842 set_tok_reg (newtok
[0], AXP_REG_T10
);
3843 set_tok_reg (newtok
[1], AXP_REG_T12
);
3844 newtok
[2] = newtok
[0];
3845 assemble_tokens ("or", newtok
, 3, 1);
3847 /* emit "stq_u $t9, 0($at)" */
3849 set_tok_reg (newtok
[0], AXP_REG_T9
);
3850 set_tok_const (newtok
[1], 0);
3851 set_tok_preg (newtok
[2], AXP_REG_AT
);
3852 assemble_tokens ("stq_u", newtok
, 3, 1);
3854 /* emit "stq_u $t10, size-1($at)" */
3856 set_tok_reg (newtok
[0], AXP_REG_T10
);
3857 set_tok_const (newtok
[1], (1 << lgsize
) - 1);
3858 assemble_tokens ("stq_u", newtok
, 3, 1);
3861 /* Sign extend a half-word or byte. The 32-bit sign extend is
3862 implemented as "addl $31, $r, $t" in the opcode table. */
3865 emit_sextX (tok
, ntok
, vlgsize
)
3866 const expressionS
*tok
;
3870 long lgsize
= (long) vlgsize
;
3872 if (alpha_target
& AXP_OPCODE_BWX
)
3873 assemble_tokens (sextX_op
[lgsize
], tok
, ntok
, 0);
3876 int bitshift
= 64 - 8 * (1 << lgsize
);
3877 expressionS newtok
[3];
3879 /* emit "sll src,bits,dst" */
3882 set_tok_const (newtok
[1], bitshift
);
3883 newtok
[2] = tok
[ntok
- 1];
3884 assemble_tokens ("sll", newtok
, 3, 1);
3886 /* emit "sra dst,bits,dst" */
3888 newtok
[0] = newtok
[2];
3889 assemble_tokens ("sra", newtok
, 3, 1);
3893 /* Implement the division and modulus macros. */
3897 /* Make register usage like in normal procedure call.
3898 Don't clobber PV and RA. */
3901 emit_division (tok
, ntok
, symname
)
3902 const expressionS
*tok
;
3906 /* DIVISION and MODULUS. Yech.
3911 * mov x,R16 # if x != R16
3912 * mov y,R17 # if y != R17
3917 * with appropriate optimizations if R0,R16,R17 are the registers
3918 * specified by the compiler.
3923 expressionS newtok
[3];
3925 xr
= regno (tok
[0].X_add_number
);
3926 yr
= regno (tok
[1].X_add_number
);
3931 rr
= regno (tok
[2].X_add_number
);
3933 /* Move the operands into the right place */
3934 if (yr
== AXP_REG_R16
&& xr
== AXP_REG_R17
)
3936 /* They are in exactly the wrong order -- swap through AT */
3939 as_bad (_("macro requires $at register while noat in effect"));
3941 set_tok_reg (newtok
[0], AXP_REG_R16
);
3942 set_tok_reg (newtok
[1], AXP_REG_AT
);
3943 assemble_tokens ("mov", newtok
, 2, 1);
3945 set_tok_reg (newtok
[0], AXP_REG_R17
);
3946 set_tok_reg (newtok
[1], AXP_REG_R16
);
3947 assemble_tokens ("mov", newtok
, 2, 1);
3949 set_tok_reg (newtok
[0], AXP_REG_AT
);
3950 set_tok_reg (newtok
[1], AXP_REG_R17
);
3951 assemble_tokens ("mov", newtok
, 2, 1);
3955 if (yr
== AXP_REG_R16
)
3957 set_tok_reg (newtok
[0], AXP_REG_R16
);
3958 set_tok_reg (newtok
[1], AXP_REG_R17
);
3959 assemble_tokens ("mov", newtok
, 2, 1);
3962 if (xr
!= AXP_REG_R16
)
3964 set_tok_reg (newtok
[0], xr
);
3965 set_tok_reg (newtok
[1], AXP_REG_R16
);
3966 assemble_tokens ("mov", newtok
, 2, 1);
3969 if (yr
!= AXP_REG_R16
&& yr
!= AXP_REG_R17
)
3971 set_tok_reg (newtok
[0], yr
);
3972 set_tok_reg (newtok
[1], AXP_REG_R17
);
3973 assemble_tokens ("mov", newtok
, 2, 1);
3977 sym
= symbol_find_or_make ((const char *) symname
);
3979 set_tok_reg (newtok
[0], AXP_REG_AT
);
3980 set_tok_sym (newtok
[1], sym
, 0);
3981 assemble_tokens ("lda", newtok
, 2, 1);
3983 /* Call the division routine */
3984 set_tok_reg (newtok
[0], AXP_REG_AT
);
3985 set_tok_cpreg (newtok
[1], AXP_REG_AT
);
3986 set_tok_const (newtok
[2], 0);
3987 assemble_tokens ("jsr", newtok
, 3, 1);
3989 /* Move the result to the right place */
3990 if (rr
!= AXP_REG_R0
)
3992 set_tok_reg (newtok
[0], AXP_REG_R0
);
3993 set_tok_reg (newtok
[1], rr
);
3994 assemble_tokens ("mov", newtok
, 2, 1);
3998 #else /* !OBJ_EVAX */
4001 emit_division (tok
, ntok
, symname
)
4002 const expressionS
*tok
;
4006 /* DIVISION and MODULUS. Yech.
4016 * with appropriate optimizations if t10,t11,t12 are the registers
4017 * specified by the compiler.
4022 expressionS newtok
[3];
4024 xr
= regno (tok
[0].X_add_number
);
4025 yr
= regno (tok
[1].X_add_number
);
4030 rr
= regno (tok
[2].X_add_number
);
4032 sym
= symbol_find_or_make ((const char *) symname
);
4034 /* Move the operands into the right place */
4035 if (yr
== AXP_REG_T10
&& xr
== AXP_REG_T11
)
4037 /* They are in exactly the wrong order -- swap through AT */
4040 as_bad (_("macro requires $at register while noat in effect"));
4042 set_tok_reg (newtok
[0], AXP_REG_T10
);
4043 set_tok_reg (newtok
[1], AXP_REG_AT
);
4044 assemble_tokens ("mov", newtok
, 2, 1);
4046 set_tok_reg (newtok
[0], AXP_REG_T11
);
4047 set_tok_reg (newtok
[1], AXP_REG_T10
);
4048 assemble_tokens ("mov", newtok
, 2, 1);
4050 set_tok_reg (newtok
[0], AXP_REG_AT
);
4051 set_tok_reg (newtok
[1], AXP_REG_T11
);
4052 assemble_tokens ("mov", newtok
, 2, 1);
4056 if (yr
== AXP_REG_T10
)
4058 set_tok_reg (newtok
[0], AXP_REG_T10
);
4059 set_tok_reg (newtok
[1], AXP_REG_T11
);
4060 assemble_tokens ("mov", newtok
, 2, 1);
4063 if (xr
!= AXP_REG_T10
)
4065 set_tok_reg (newtok
[0], xr
);
4066 set_tok_reg (newtok
[1], AXP_REG_T10
);
4067 assemble_tokens ("mov", newtok
, 2, 1);
4070 if (yr
!= AXP_REG_T10
&& yr
!= AXP_REG_T11
)
4072 set_tok_reg (newtok
[0], yr
);
4073 set_tok_reg (newtok
[1], AXP_REG_T11
);
4074 assemble_tokens ("mov", newtok
, 2, 1);
4078 /* Call the division routine */
4079 set_tok_reg (newtok
[0], AXP_REG_T9
);
4080 set_tok_sym (newtok
[1], sym
, 0);
4081 assemble_tokens ("jsr", newtok
, 2, 1);
4083 /* Reload the GP register */
4087 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
4088 set_tok_reg (newtok
[0], alpha_gp_register
);
4089 set_tok_const (newtok
[1], 0);
4090 set_tok_preg (newtok
[2], AXP_REG_T9
);
4091 assemble_tokens ("ldgp", newtok
, 3, 1);
4094 /* Move the result to the right place */
4095 if (rr
!= AXP_REG_T12
)
4097 set_tok_reg (newtok
[0], AXP_REG_T12
);
4098 set_tok_reg (newtok
[1], rr
);
4099 assemble_tokens ("mov", newtok
, 2, 1);
4103 #endif /* !OBJ_EVAX */
4105 /* The jsr and jmp macros differ from their instruction counterparts
4106 in that they can load the target address and default most
4110 emit_jsrjmp (tok
, ntok
, vopname
)
4111 const expressionS
*tok
;
4115 const char *opname
= (const char *) vopname
;
4116 struct alpha_insn insn
;
4117 expressionS newtok
[3];
4121 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_register
)
4122 r
= regno (tok
[tokidx
++].X_add_number
);
4124 r
= strcmp (opname
, "jmp") == 0 ? AXP_REG_ZERO
: AXP_REG_RA
;
4126 set_tok_reg (newtok
[0], r
);
4128 if (tokidx
< ntok
&&
4129 (tok
[tokidx
].X_op
== O_pregister
|| tok
[tokidx
].X_op
== O_cpregister
))
4130 r
= regno (tok
[tokidx
++].X_add_number
);
4132 /* keep register if jsr $n.<sym> */
4136 int basereg
= alpha_gp_register
;
4137 lituse
= load_expression (r
= AXP_REG_PV
, &tok
[tokidx
], &basereg
, NULL
);
4141 set_tok_cpreg (newtok
[1], r
);
4144 /* FIXME: Add hint relocs to BFD for evax. */
4147 newtok
[2] = tok
[tokidx
];
4150 set_tok_const (newtok
[2], 0);
4152 assemble_tokens_to_insn (opname
, newtok
, 3, &insn
);
4156 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
4157 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_JSR
;
4158 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
4160 insn
.sequence
= lituse
;
4166 /* The ret and jcr instructions differ from their instruction
4167 counterparts in that everything can be defaulted. */
4170 emit_retjcr (tok
, ntok
, vopname
)
4171 const expressionS
*tok
;
4175 const char *opname
= (const char *) vopname
;
4176 expressionS newtok
[3];
4179 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_register
)
4180 r
= regno (tok
[tokidx
++].X_add_number
);
4184 set_tok_reg (newtok
[0], r
);
4186 if (tokidx
< ntok
&&
4187 (tok
[tokidx
].X_op
== O_pregister
|| tok
[tokidx
].X_op
== O_cpregister
))
4188 r
= regno (tok
[tokidx
++].X_add_number
);
4192 set_tok_cpreg (newtok
[1], r
);
4195 newtok
[2] = tok
[tokidx
];
4197 set_tok_const (newtok
[2], strcmp (opname
, "ret") == 0);
4199 assemble_tokens (opname
, newtok
, 3, 0);
4202 /* Assembler directives */
4204 /* Handle the .text pseudo-op. This is like the usual one, but it
4205 clears alpha_insn_label and restores auto alignment. */
4217 alpha_insn_label
= NULL
;
4218 alpha_auto_align_on
= 1;
4219 alpha_current_align
= 0;
4222 /* Handle the .data pseudo-op. This is like the usual one, but it
4223 clears alpha_insn_label and restores auto alignment. */
4234 alpha_insn_label
= NULL
;
4235 alpha_auto_align_on
= 1;
4236 alpha_current_align
= 0;
4239 #if defined (OBJ_ECOFF) || defined (OBJ_EVAX)
4241 /* Handle the OSF/1 and openVMS .comm pseudo quirks.
4242 openVMS constructs a section for every common symbol. */
4245 s_alpha_comm (ignore
)
4248 register char *name
;
4252 register symbolS
*symbolP
;
4255 segT current_section
= now_seg
;
4256 int current_subsec
= now_subseg
;
4260 name
= input_line_pointer
;
4261 c
= get_symbol_end ();
4263 /* just after name is now '\0' */
4264 p
= input_line_pointer
;
4269 /* Alpha OSF/1 compiler doesn't provide the comma, gcc does. */
4270 if (*input_line_pointer
== ',')
4272 input_line_pointer
++;
4275 if ((temp
= get_absolute_expression ()) < 0)
4277 as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) temp
);
4278 ignore_rest_of_line ();
4283 symbolP
= symbol_find_or_make (name
);
4286 /* Make a section for the common symbol. */
4287 new_seg
= subseg_new (xstrdup (name
), 0);
4293 /* alignment might follow */
4294 if (*input_line_pointer
== ',')
4298 input_line_pointer
++;
4299 align
= get_absolute_expression ();
4300 bfd_set_section_alignment (stdoutput
, new_seg
, align
);
4304 if (S_IS_DEFINED (symbolP
) && ! S_IS_COMMON (symbolP
))
4306 as_bad (_("Ignoring attempt to re-define symbol"));
4307 ignore_rest_of_line ();
4312 if (bfd_section_size (stdoutput
, new_seg
) > 0)
4314 if (bfd_section_size (stdoutput
, new_seg
) != temp
)
4315 as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
4316 S_GET_NAME (symbolP
),
4317 (long) bfd_section_size (stdoutput
, new_seg
),
4321 if (S_GET_VALUE (symbolP
))
4323 if (S_GET_VALUE (symbolP
) != (valueT
) temp
)
4324 as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
4325 S_GET_NAME (symbolP
),
4326 (long) S_GET_VALUE (symbolP
),
4333 subseg_set (new_seg
, 0);
4334 p
= frag_more (temp
);
4335 new_seg
->flags
|= SEC_IS_COMMON
;
4336 if (! S_IS_DEFINED (symbolP
))
4337 S_SET_SEGMENT (symbolP
, new_seg
);
4339 S_SET_VALUE (symbolP
, (valueT
) temp
);
4341 S_SET_EXTERNAL (symbolP
);
4345 subseg_set (current_section
, current_subsec
);
4348 know (symbol_get_frag (symbolP
) == &zero_address_frag
);
4350 demand_empty_rest_of_line ();
4353 #endif /* ! OBJ_ELF */
4357 /* Handle the .rdata pseudo-op. This is like the usual one, but it
4358 clears alpha_insn_label and restores auto alignment. */
4361 s_alpha_rdata (ignore
)
4366 temp
= get_absolute_expression ();
4367 subseg_new (".rdata", 0);
4368 demand_empty_rest_of_line ();
4369 alpha_insn_label
= NULL
;
4370 alpha_auto_align_on
= 1;
4371 alpha_current_align
= 0;
4378 /* Handle the .sdata pseudo-op. This is like the usual one, but it
4379 clears alpha_insn_label and restores auto alignment. */
4382 s_alpha_sdata (ignore
)
4387 temp
= get_absolute_expression ();
4388 subseg_new (".sdata", 0);
4389 demand_empty_rest_of_line ();
4390 alpha_insn_label
= NULL
;
4391 alpha_auto_align_on
= 1;
4392 alpha_current_align
= 0;
4398 /* Handle the .section pseudo-op. This is like the usual one, but it
4399 clears alpha_insn_label and restores auto alignment. */
4402 s_alpha_section (ignore
)
4405 obj_elf_section (ignore
);
4407 alpha_insn_label
= NULL
;
4408 alpha_auto_align_on
= 1;
4409 alpha_current_align
= 0;
4414 int dummy ATTRIBUTE_UNUSED
;
4416 if (ECOFF_DEBUGGING
)
4417 ecoff_directive_ent (0);
4420 char *name
, name_end
;
4421 name
= input_line_pointer
;
4422 name_end
= get_symbol_end ();
4424 if (! is_name_beginner (*name
))
4426 as_warn (_(".ent directive has no name"));
4427 *input_line_pointer
= name_end
;
4433 if (alpha_cur_ent_sym
)
4434 as_warn (_("nested .ent directives"));
4436 sym
= symbol_find_or_make (name
);
4437 symbol_get_bfdsym (sym
)->flags
|= BSF_FUNCTION
;
4438 alpha_cur_ent_sym
= sym
;
4440 /* The .ent directive is sometimes followed by a number. Not sure
4441 what it really means, but ignore it. */
4442 *input_line_pointer
= name_end
;
4444 if (*input_line_pointer
== ',')
4446 input_line_pointer
++;
4449 if (ISDIGIT (*input_line_pointer
) || *input_line_pointer
== '-')
4450 (void) get_absolute_expression ();
4452 demand_empty_rest_of_line ();
4458 int dummy ATTRIBUTE_UNUSED
;
4460 if (ECOFF_DEBUGGING
)
4461 ecoff_directive_end (0);
4464 char *name
, name_end
;
4465 name
= input_line_pointer
;
4466 name_end
= get_symbol_end ();
4468 if (! is_name_beginner (*name
))
4470 as_warn (_(".end directive has no name"));
4471 *input_line_pointer
= name_end
;
4477 sym
= symbol_find (name
);
4478 if (sym
!= alpha_cur_ent_sym
)
4479 as_warn (_(".end directive names different symbol than .ent"));
4481 /* Create an expression to calculate the size of the function. */
4484 symbol_get_obj (sym
)->size
=
4485 (expressionS
*) xmalloc (sizeof (expressionS
));
4486 symbol_get_obj (sym
)->size
->X_op
= O_subtract
;
4487 symbol_get_obj (sym
)->size
->X_add_symbol
4488 = symbol_new ("L0\001", now_seg
, frag_now_fix (), frag_now
);
4489 symbol_get_obj (sym
)->size
->X_op_symbol
= sym
;
4490 symbol_get_obj (sym
)->size
->X_add_number
= 0;
4493 alpha_cur_ent_sym
= NULL
;
4495 *input_line_pointer
= name_end
;
4497 demand_empty_rest_of_line ();
4505 if (ECOFF_DEBUGGING
)
4508 ecoff_directive_fmask (0);
4510 ecoff_directive_mask (0);
4513 discard_rest_of_line ();
4517 s_alpha_frame (dummy
)
4518 int dummy ATTRIBUTE_UNUSED
;
4520 if (ECOFF_DEBUGGING
)
4521 ecoff_directive_frame (0);
4523 discard_rest_of_line ();
4527 s_alpha_prologue (ignore
)
4528 int ignore ATTRIBUTE_UNUSED
;
4533 arg
= get_absolute_expression ();
4534 demand_empty_rest_of_line ();
4536 if (ECOFF_DEBUGGING
)
4537 sym
= ecoff_get_cur_proc_sym ();
4539 sym
= alpha_cur_ent_sym
;
4544 case 0: /* No PV required. */
4545 S_SET_OTHER (sym
, STO_ALPHA_NOPV
4546 | (S_GET_OTHER (sym
) & ~STO_ALPHA_STD_GPLOAD
));
4548 case 1: /* Std GP load. */
4549 S_SET_OTHER (sym
, STO_ALPHA_STD_GPLOAD
4550 | (S_GET_OTHER (sym
) & ~STO_ALPHA_STD_GPLOAD
));
4552 case 2: /* Non-std use of PV. */
4556 as_bad (_("Invalid argument %d to .prologue."), arg
);
4561 static char *first_file_directive
;
4564 s_alpha_file (ignore
)
4565 int ignore ATTRIBUTE_UNUSED
;
4567 /* Save the first .file directive we see, so that we can change our
4568 minds about whether ecoff debugging should or shouldn't be enabled. */
4569 if (alpha_flag_mdebug
< 0 && ! first_file_directive
)
4571 char *start
= input_line_pointer
;
4574 discard_rest_of_line ();
4576 len
= input_line_pointer
- start
;
4577 first_file_directive
= xmalloc (len
+ 1);
4578 memcpy (first_file_directive
, start
, len
);
4579 first_file_directive
[len
] = '\0';
4581 input_line_pointer
= start
;
4584 if (ECOFF_DEBUGGING
)
4585 ecoff_directive_file (0);
4587 dwarf2_directive_file (0);
4591 s_alpha_loc (ignore
)
4592 int ignore ATTRIBUTE_UNUSED
;
4594 if (ECOFF_DEBUGGING
)
4595 ecoff_directive_loc (0);
4597 dwarf2_directive_loc (0);
4604 /* If we've been undecided about mdebug, make up our minds in favour. */
4605 if (alpha_flag_mdebug
< 0)
4607 segT sec
= subseg_new (".mdebug", 0);
4608 bfd_set_section_flags (stdoutput
, sec
, SEC_HAS_CONTENTS
| SEC_READONLY
);
4609 bfd_set_section_alignment (stdoutput
, sec
, 3);
4611 ecoff_read_begin_hook ();
4613 if (first_file_directive
)
4615 char *save_ilp
= input_line_pointer
;
4616 input_line_pointer
= first_file_directive
;
4617 ecoff_directive_file (0);
4618 input_line_pointer
= save_ilp
;
4619 free (first_file_directive
);
4622 alpha_flag_mdebug
= 1;
4628 s_alpha_coff_wrapper (which
)
4631 static void (* const fns
[]) PARAMS ((int)) = {
4632 ecoff_directive_begin
,
4633 ecoff_directive_bend
,
4634 ecoff_directive_def
,
4635 ecoff_directive_dim
,
4636 ecoff_directive_endef
,
4637 ecoff_directive_scl
,
4638 ecoff_directive_tag
,
4639 ecoff_directive_val
,
4642 assert (which
>= 0 && which
< (int) (sizeof (fns
)/sizeof (*fns
)));
4644 if (ECOFF_DEBUGGING
)
4648 as_bad (_("ECOFF debugging is disabled."));
4649 ignore_rest_of_line ();
4652 #endif /* OBJ_ELF */
4656 /* Handle the section specific pseudo-op. */
4659 s_alpha_section (secid
)
4663 #define EVAX_SECTION_COUNT 5
4664 static char *section_name
[EVAX_SECTION_COUNT
+ 1] =
4665 { "NULL", ".rdata", ".comm", ".link", ".ctors", ".dtors" };
4667 if ((secid
<= 0) || (secid
> EVAX_SECTION_COUNT
))
4669 as_fatal (_("Unknown section directive"));
4670 demand_empty_rest_of_line ();
4673 temp
= get_absolute_expression ();
4674 subseg_new (section_name
[secid
], 0);
4675 demand_empty_rest_of_line ();
4676 alpha_insn_label
= NULL
;
4677 alpha_auto_align_on
= 1;
4678 alpha_current_align
= 0;
4681 /* Parse .ent directives. */
4684 s_alpha_ent (ignore
)
4688 expressionS symexpr
;
4690 alpha_evax_proc
.pdsckind
= 0;
4691 alpha_evax_proc
.framereg
= -1;
4692 alpha_evax_proc
.framesize
= 0;
4693 alpha_evax_proc
.rsa_offset
= 0;
4694 alpha_evax_proc
.ra_save
= AXP_REG_RA
;
4695 alpha_evax_proc
.fp_save
= -1;
4696 alpha_evax_proc
.imask
= 0;
4697 alpha_evax_proc
.fmask
= 0;
4698 alpha_evax_proc
.prologue
= 0;
4699 alpha_evax_proc
.type
= 0;
4701 expression (&symexpr
);
4703 if (symexpr
.X_op
!= O_symbol
)
4705 as_fatal (_(".ent directive has no symbol"));
4706 demand_empty_rest_of_line ();
4710 symbol
= make_expr_symbol (&symexpr
);
4711 symbol_get_bfdsym (symbol
)->flags
|= BSF_FUNCTION
;
4712 alpha_evax_proc
.symbol
= symbol
;
4714 demand_empty_rest_of_line ();
4718 /* Parse .frame <framreg>,<framesize>,RA,<rsa_offset> directives. */
4721 s_alpha_frame (ignore
)
4726 alpha_evax_proc
.framereg
= tc_get_register (1);
4729 if (*input_line_pointer
++ != ','
4730 || get_absolute_expression_and_terminator (&val
) != ',')
4732 as_warn (_("Bad .frame directive 1./2. param"));
4733 --input_line_pointer
;
4734 demand_empty_rest_of_line ();
4738 alpha_evax_proc
.framesize
= val
;
4740 (void) tc_get_register (1);
4742 if (*input_line_pointer
++ != ',')
4744 as_warn (_("Bad .frame directive 3./4. param"));
4745 --input_line_pointer
;
4746 demand_empty_rest_of_line ();
4749 alpha_evax_proc
.rsa_offset
= get_absolute_expression ();
4755 s_alpha_pdesc (ignore
)
4765 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
4767 if (now_seg
!= alpha_link_section
)
4769 as_bad (_(".pdesc directive not in link (.link) section"));
4770 demand_empty_rest_of_line ();
4774 if ((alpha_evax_proc
.symbol
== 0)
4775 || (!S_IS_DEFINED (alpha_evax_proc
.symbol
)))
4777 as_fatal (_(".pdesc has no matching .ent"));
4778 demand_empty_rest_of_line ();
4782 *symbol_get_obj (alpha_evax_proc
.symbol
) =
4783 (valueT
) seginfo
->literal_pool_size
;
4786 if (exp
.X_op
!= O_symbol
)
4788 as_warn (_(".pdesc directive has no entry symbol"));
4789 demand_empty_rest_of_line ();
4793 entry_sym
= make_expr_symbol (&exp
);
4794 /* Save bfd symbol of proc desc in function symbol. */
4795 symbol_get_bfdsym (alpha_evax_proc
.symbol
)->udata
.p
4796 = symbol_get_bfdsym (entry_sym
);
4799 if (*input_line_pointer
++ != ',')
4801 as_warn (_("No comma after .pdesc <entryname>"));
4802 demand_empty_rest_of_line ();
4807 name
= input_line_pointer
;
4808 name_end
= get_symbol_end ();
4810 if (strncmp (name
, "stack", 5) == 0)
4812 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_FP_STACK
;
4814 else if (strncmp (name
, "reg", 3) == 0)
4816 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_FP_REGISTER
;
4818 else if (strncmp (name
, "null", 4) == 0)
4820 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_NULL
;
4824 as_fatal (_("unknown procedure kind"));
4825 demand_empty_rest_of_line ();
4829 *input_line_pointer
= name_end
;
4830 demand_empty_rest_of_line ();
4832 #ifdef md_flush_pending_output
4833 md_flush_pending_output ();
4836 frag_align (3, 0, 0);
4838 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
4840 seginfo
->literal_pool_size
+= 16;
4842 *p
= alpha_evax_proc
.pdsckind
4843 | ((alpha_evax_proc
.framereg
== 29) ? PDSC_S_M_BASE_REG_IS_FP
: 0);
4844 *(p
+ 1) = PDSC_S_M_NATIVE
| PDSC_S_M_NO_JACKET
;
4846 switch (alpha_evax_proc
.pdsckind
)
4848 case PDSC_S_K_KIND_NULL
:
4852 case PDSC_S_K_KIND_FP_REGISTER
:
4853 *(p
+ 2) = alpha_evax_proc
.fp_save
;
4854 *(p
+ 3) = alpha_evax_proc
.ra_save
;
4856 case PDSC_S_K_KIND_FP_STACK
:
4857 md_number_to_chars (p
+ 2, (valueT
) alpha_evax_proc
.rsa_offset
, 2);
4859 default: /* impossible */
4864 *(p
+ 5) = alpha_evax_proc
.type
& 0x0f;
4866 /* Signature offset. */
4867 md_number_to_chars (p
+ 6, (valueT
) 0, 2);
4869 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
+8, 8, &exp
, 0, BFD_RELOC_64
);
4871 if (alpha_evax_proc
.pdsckind
== PDSC_S_K_KIND_NULL
)
4874 /* Add dummy fix to make add_to_link_pool work. */
4876 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
4878 seginfo
->literal_pool_size
+= 8;
4880 /* pdesc+16: Size. */
4881 md_number_to_chars (p
, (valueT
) alpha_evax_proc
.framesize
, 4);
4883 md_number_to_chars (p
+ 4, (valueT
) 0, 2);
4886 md_number_to_chars (p
+ 6, alpha_evax_proc
.prologue
, 2);
4888 if (alpha_evax_proc
.pdsckind
== PDSC_S_K_KIND_FP_REGISTER
)
4891 /* Add dummy fix to make add_to_link_pool work. */
4893 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
4895 seginfo
->literal_pool_size
+= 8;
4897 /* pdesc+24: register masks. */
4899 md_number_to_chars (p
, alpha_evax_proc
.imask
, 4);
4900 md_number_to_chars (p
+ 4, alpha_evax_proc
.fmask
, 4);
4905 /* Support for crash debug on vms. */
4908 s_alpha_name (ignore
)
4913 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
4915 if (now_seg
!= alpha_link_section
)
4917 as_bad (_(".name directive not in link (.link) section"));
4918 demand_empty_rest_of_line ();
4923 if (exp
.X_op
!= O_symbol
)
4925 as_warn (_(".name directive has no symbol"));
4926 demand_empty_rest_of_line ();
4930 demand_empty_rest_of_line ();
4932 #ifdef md_flush_pending_output
4933 md_flush_pending_output ();
4936 frag_align (3, 0, 0);
4938 seginfo
->literal_pool_size
+= 8;
4940 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 8, &exp
, 0, BFD_RELOC_64
);
4946 s_alpha_linkage (ignore
)
4952 #ifdef md_flush_pending_output
4953 md_flush_pending_output ();
4957 if (exp
.X_op
!= O_symbol
)
4959 as_fatal (_("No symbol after .linkage"));
4963 p
= frag_more (LKP_S_K_SIZE
);
4964 memset (p
, 0, LKP_S_K_SIZE
);
4965 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, LKP_S_K_SIZE
, &exp
, 0,\
4966 BFD_RELOC_ALPHA_LINKAGE
);
4968 demand_empty_rest_of_line ();
4974 s_alpha_code_address (ignore
)
4980 #ifdef md_flush_pending_output
4981 md_flush_pending_output ();
4985 if (exp
.X_op
!= O_symbol
)
4987 as_fatal (_("No symbol after .code_address"));
4993 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 8, &exp
, 0,\
4994 BFD_RELOC_ALPHA_CODEADDR
);
4996 demand_empty_rest_of_line ();
5002 s_alpha_fp_save (ignore
)
5006 alpha_evax_proc
.fp_save
= tc_get_register (1);
5008 demand_empty_rest_of_line ();
5013 s_alpha_mask (ignore
)
5018 if (get_absolute_expression_and_terminator (&val
) != ',')
5020 as_warn (_("Bad .mask directive"));
5021 --input_line_pointer
;
5025 alpha_evax_proc
.imask
= val
;
5026 (void) get_absolute_expression ();
5028 demand_empty_rest_of_line ();
5034 s_alpha_fmask (ignore
)
5039 if (get_absolute_expression_and_terminator (&val
) != ',')
5041 as_warn (_("Bad .fmask directive"));
5042 --input_line_pointer
;
5046 alpha_evax_proc
.fmask
= val
;
5047 (void) get_absolute_expression ();
5049 demand_empty_rest_of_line ();
5055 s_alpha_end (ignore
)
5060 c
= get_symbol_end ();
5061 *input_line_pointer
= c
;
5062 demand_empty_rest_of_line ();
5063 alpha_evax_proc
.symbol
= 0;
5069 s_alpha_file (ignore
)
5074 static char case_hack
[32];
5076 extern char *demand_copy_string
PARAMS ((int *lenP
));
5078 sprintf (case_hack
, "<CASE:%01d%01d>",
5079 alpha_flag_hash_long_names
, alpha_flag_show_after_trunc
);
5081 s
= symbol_find_or_make (case_hack
);
5082 symbol_get_bfdsym (s
)->flags
|= BSF_FILE
;
5084 get_absolute_expression ();
5085 s
= symbol_find_or_make (demand_copy_string (&length
));
5086 symbol_get_bfdsym (s
)->flags
|= BSF_FILE
;
5087 demand_empty_rest_of_line ();
5091 #endif /* OBJ_EVAX */
5093 /* Handle the .gprel32 pseudo op. */
5096 s_alpha_gprel32 (ignore
)
5097 int ignore ATTRIBUTE_UNUSED
;
5109 e
.X_add_symbol
= section_symbol (absolute_section
);
5122 e
.X_add_symbol
= section_symbol (absolute_section
);
5125 e
.X_op
= O_subtract
;
5126 e
.X_op_symbol
= alpha_gp_symbol
;
5134 if (alpha_auto_align_on
&& alpha_current_align
< 2)
5135 alpha_align (2, (char *) NULL
, alpha_insn_label
, 0);
5136 if (alpha_current_align
> 2)
5137 alpha_current_align
= 2;
5138 alpha_insn_label
= NULL
;
5142 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 4,
5143 &e
, 0, BFD_RELOC_GPREL32
);
5146 /* Handle floating point allocation pseudo-ops. This is like the
5147 generic vresion, but it makes sure the current label, if any, is
5148 correctly aligned. */
5151 s_alpha_float_cons (type
)
5178 if (alpha_auto_align_on
&& alpha_current_align
< log_size
)
5179 alpha_align (log_size
, (char *) NULL
, alpha_insn_label
, 0);
5180 if (alpha_current_align
> log_size
)
5181 alpha_current_align
= log_size
;
5182 alpha_insn_label
= NULL
;
5187 /* Handle the .proc pseudo op. We don't really do much with it except
5191 s_alpha_proc (is_static
)
5192 int is_static ATTRIBUTE_UNUSED
;
5200 /* Takes ".proc name,nargs" */
5202 name
= input_line_pointer
;
5203 c
= get_symbol_end ();
5204 p
= input_line_pointer
;
5205 symbolP
= symbol_find_or_make (name
);
5208 if (*input_line_pointer
!= ',')
5211 as_warn (_("Expected comma after name \"%s\""), name
);
5214 ignore_rest_of_line ();
5218 input_line_pointer
++;
5219 temp
= get_absolute_expression ();
5221 /* *symbol_get_obj (symbolP) = (signed char) temp; */
5222 as_warn (_("unhandled: .proc %s,%d"), name
, temp
);
5223 demand_empty_rest_of_line ();
5226 /* Handle the .set pseudo op. This is used to turn on and off most of
5227 the assembler features. */
5231 int x ATTRIBUTE_UNUSED
;
5237 name
= input_line_pointer
;
5238 ch
= get_symbol_end ();
5241 if (s
[0] == 'n' && s
[1] == 'o')
5246 if (!strcmp ("reorder", s
))
5248 else if (!strcmp ("at", s
))
5249 alpha_noat_on
= !yesno
;
5250 else if (!strcmp ("macro", s
))
5251 alpha_macros_on
= yesno
;
5252 else if (!strcmp ("move", s
))
5254 else if (!strcmp ("volatile", s
))
5257 as_warn (_("Tried to .set unrecognized mode `%s'"), name
);
5259 *input_line_pointer
= ch
;
5260 demand_empty_rest_of_line ();
5263 /* Handle the .base pseudo op. This changes the assembler's notion of
5264 the $gp register. */
5267 s_alpha_base (ignore
)
5268 int ignore ATTRIBUTE_UNUSED
;
5271 if (first_32bit_quadrant
)
5273 /* not fatal, but it might not work in the end */
5274 as_warn (_("File overrides no-base-register option."));
5275 first_32bit_quadrant
= 0;
5280 if (*input_line_pointer
== '$')
5282 input_line_pointer
++;
5283 if (*input_line_pointer
== 'r')
5284 input_line_pointer
++;
5287 alpha_gp_register
= get_absolute_expression ();
5288 if (alpha_gp_register
< 0 || alpha_gp_register
> 31)
5290 alpha_gp_register
= AXP_REG_GP
;
5291 as_warn (_("Bad base register, using $%d."), alpha_gp_register
);
5294 demand_empty_rest_of_line ();
5297 /* Handle the .align pseudo-op. This aligns to a power of two. It
5298 also adjusts any current instruction label. We treat this the same
5299 way the MIPS port does: .align 0 turns off auto alignment. */
5302 s_alpha_align (ignore
)
5303 int ignore ATTRIBUTE_UNUSED
;
5307 long max_alignment
= 15;
5309 align
= get_absolute_expression ();
5310 if (align
> max_alignment
)
5312 align
= max_alignment
;
5313 as_bad (_("Alignment too large: %d. assumed"), align
);
5317 as_warn (_("Alignment negative: 0 assumed"));
5321 if (*input_line_pointer
== ',')
5323 input_line_pointer
++;
5324 fill
= get_absolute_expression ();
5332 alpha_auto_align_on
= 1;
5333 alpha_align (align
, pfill
, alpha_insn_label
, 1);
5337 alpha_auto_align_on
= 0;
5340 demand_empty_rest_of_line ();
5343 /* Hook the normal string processor to reset known alignment. */
5346 s_alpha_stringer (terminate
)
5349 alpha_current_align
= 0;
5350 alpha_insn_label
= NULL
;
5351 stringer (terminate
);
5354 /* Hook the normal space processing to reset known alignment. */
5357 s_alpha_space (ignore
)
5360 alpha_current_align
= 0;
5361 alpha_insn_label
= NULL
;
5365 /* Hook into cons for auto-alignment. */
5368 alpha_cons_align (size
)
5374 while ((size
>>= 1) != 0)
5377 if (alpha_auto_align_on
&& alpha_current_align
< log_size
)
5378 alpha_align (log_size
, (char *) NULL
, alpha_insn_label
, 0);
5379 if (alpha_current_align
> log_size
)
5380 alpha_current_align
= log_size
;
5381 alpha_insn_label
= NULL
;
5384 /* Here come the .uword, .ulong, and .uquad explicitly unaligned
5385 pseudos. We just turn off auto-alignment and call down to cons. */
5388 s_alpha_ucons (bytes
)
5391 int hold
= alpha_auto_align_on
;
5392 alpha_auto_align_on
= 0;
5394 alpha_auto_align_on
= hold
;
5397 /* Switch the working cpu type. */
5400 s_alpha_arch (ignored
)
5401 int ignored ATTRIBUTE_UNUSED
;
5404 const struct cpu_type
*p
;
5407 name
= input_line_pointer
;
5408 ch
= get_symbol_end ();
5410 for (p
= cpu_types
; p
->name
; ++p
)
5411 if (strcmp (name
, p
->name
) == 0)
5413 alpha_target_name
= p
->name
, alpha_target
= p
->flags
;
5416 as_warn ("Unknown CPU identifier `%s'", name
);
5419 *input_line_pointer
= ch
;
5420 demand_empty_rest_of_line ();
5424 /* print token expression with alpha specific extension. */
5427 alpha_print_token (f
, exp
)
5429 const expressionS
*exp
;
5439 expressionS nexp
= *exp
;
5440 nexp
.X_op
= O_register
;
5441 print_expr (f
, &nexp
);
5446 print_expr (f
, exp
);
5453 /* The target specific pseudo-ops which we support. */
5455 const pseudo_typeS md_pseudo_table
[] = {
5457 {"comm", s_alpha_comm
, 0}, /* osf1 compiler does this */
5458 {"rdata", s_alpha_rdata
, 0},
5460 {"text", s_alpha_text
, 0},
5461 {"data", s_alpha_data
, 0},
5463 {"sdata", s_alpha_sdata
, 0},
5466 {"section", s_alpha_section
, 0},
5467 {"section.s", s_alpha_section
, 0},
5468 {"sect", s_alpha_section
, 0},
5469 {"sect.s", s_alpha_section
, 0},
5472 { "pdesc", s_alpha_pdesc
, 0},
5473 { "name", s_alpha_name
, 0},
5474 { "linkage", s_alpha_linkage
, 0},
5475 { "code_address", s_alpha_code_address
, 0},
5476 { "ent", s_alpha_ent
, 0},
5477 { "frame", s_alpha_frame
, 0},
5478 { "fp_save", s_alpha_fp_save
, 0},
5479 { "mask", s_alpha_mask
, 0},
5480 { "fmask", s_alpha_fmask
, 0},
5481 { "end", s_alpha_end
, 0},
5482 { "file", s_alpha_file
, 0},
5483 { "rdata", s_alpha_section
, 1},
5484 { "comm", s_alpha_comm
, 0},
5485 { "link", s_alpha_section
, 3},
5486 { "ctors", s_alpha_section
, 4},
5487 { "dtors", s_alpha_section
, 5},
5490 /* Frame related pseudos. */
5491 {"ent", s_alpha_ent
, 0},
5492 {"end", s_alpha_end
, 0},
5493 {"mask", s_alpha_mask
, 0},
5494 {"fmask", s_alpha_mask
, 1},
5495 {"frame", s_alpha_frame
, 0},
5496 {"prologue", s_alpha_prologue
, 0},
5497 {"file", s_alpha_file
, 5},
5498 {"loc", s_alpha_loc
, 9},
5499 {"stabs", s_alpha_stab
, 's'},
5500 {"stabn", s_alpha_stab
, 'n'},
5501 /* COFF debugging related pseudos. */
5502 {"begin", s_alpha_coff_wrapper
, 0},
5503 {"bend", s_alpha_coff_wrapper
, 1},
5504 {"def", s_alpha_coff_wrapper
, 2},
5505 {"dim", s_alpha_coff_wrapper
, 3},
5506 {"endef", s_alpha_coff_wrapper
, 4},
5507 {"scl", s_alpha_coff_wrapper
, 5},
5508 {"tag", s_alpha_coff_wrapper
, 6},
5509 {"val", s_alpha_coff_wrapper
, 7},
5511 {"prologue", s_ignore
, 0},
5513 {"gprel32", s_alpha_gprel32
, 0},
5514 {"t_floating", s_alpha_float_cons
, 'd'},
5515 {"s_floating", s_alpha_float_cons
, 'f'},
5516 {"f_floating", s_alpha_float_cons
, 'F'},
5517 {"g_floating", s_alpha_float_cons
, 'G'},
5518 {"d_floating", s_alpha_float_cons
, 'D'},
5520 {"proc", s_alpha_proc
, 0},
5521 {"aproc", s_alpha_proc
, 1},
5522 {"set", s_alpha_set
, 0},
5523 {"reguse", s_ignore
, 0},
5524 {"livereg", s_ignore
, 0},
5525 {"base", s_alpha_base
, 0}, /*??*/
5526 {"option", s_ignore
, 0},
5527 {"aent", s_ignore
, 0},
5528 {"ugen", s_ignore
, 0},
5529 {"eflag", s_ignore
, 0},
5531 {"align", s_alpha_align
, 0},
5532 {"double", s_alpha_float_cons
, 'd'},
5533 {"float", s_alpha_float_cons
, 'f'},
5534 {"single", s_alpha_float_cons
, 'f'},
5535 {"ascii", s_alpha_stringer
, 0},
5536 {"asciz", s_alpha_stringer
, 1},
5537 {"string", s_alpha_stringer
, 1},
5538 {"space", s_alpha_space
, 0},
5539 {"skip", s_alpha_space
, 0},
5540 {"zero", s_alpha_space
, 0},
5542 /* Unaligned data pseudos. */
5543 {"uword", s_alpha_ucons
, 2},
5544 {"ulong", s_alpha_ucons
, 4},
5545 {"uquad", s_alpha_ucons
, 8},
5548 /* Dwarf wants these versions of unaligned. */
5549 {"2byte", s_alpha_ucons
, 2},
5550 {"4byte", s_alpha_ucons
, 4},
5551 {"8byte", s_alpha_ucons
, 8},
5554 /* We don't do any optimizing, so we can safely ignore these. */
5555 {"noalias", s_ignore
, 0},
5556 {"alias", s_ignore
, 0},
5558 {"arch", s_alpha_arch
, 0},
5563 /* Build a BFD section with its flags set appropriately for the .lita,
5564 .lit8, or .lit4 sections. */
5567 create_literal_section (name
, secp
, symp
)
5572 segT current_section
= now_seg
;
5573 int current_subsec
= now_subseg
;
5576 *secp
= new_sec
= subseg_new (name
, 0);
5577 subseg_set (current_section
, current_subsec
);
5578 bfd_set_section_alignment (stdoutput
, new_sec
, 4);
5579 bfd_set_section_flags (stdoutput
, new_sec
,
5580 SEC_RELOC
| SEC_ALLOC
| SEC_LOAD
| SEC_READONLY
5583 S_CLEAR_EXTERNAL (*symp
= section_symbol (new_sec
));
5588 /* @@@ GP selection voodoo. All of this seems overly complicated and
5589 unnecessary; which is the primary reason it's for ECOFF only. */
5598 vma
= bfd_get_section_vma (foo
, sec
);
5599 if (vma
&& vma
< alpha_gp_value
)
5600 alpha_gp_value
= vma
;
5606 assert (alpha_gp_value
== 0);
5608 /* Get minus-one in whatever width... */
5612 /* Select the smallest VMA of these existing sections. */
5613 maybe_set_gp (alpha_lita_section
);
5615 /* These were disabled before -- should we use them? */
5616 maybe_set_gp (sdata
);
5617 maybe_set_gp (lit8_sec
);
5618 maybe_set_gp (lit4_sec
);
5621 /* @@ Will a simple 0x8000 work here? If not, why not? */
5622 #define GP_ADJUSTMENT (0x8000 - 0x10)
5624 alpha_gp_value
+= GP_ADJUSTMENT
;
5626 S_SET_VALUE (alpha_gp_symbol
, alpha_gp_value
);
5629 printf (_("Chose GP value of %lx\n"), alpha_gp_value
);
5632 #endif /* OBJ_ECOFF */
5635 /* Map 's' to SHF_ALPHA_GPREL. */
5638 alpha_elf_section_letter (letter
, ptr_msg
)
5643 return SHF_ALPHA_GPREL
;
5645 *ptr_msg
= _("Bad .section directive: want a,s,w,x,M,S,G,T in string");
5649 /* Map SHF_ALPHA_GPREL to SEC_SMALL_DATA. */
5652 alpha_elf_section_flags (flags
, attr
, type
)
5654 int attr
, type ATTRIBUTE_UNUSED
;
5656 if (attr
& SHF_ALPHA_GPREL
)
5657 flags
|= SEC_SMALL_DATA
;
5660 #endif /* OBJ_ELF */
5662 /* Called internally to handle all alignment needs. This takes care
5663 of eliding calls to frag_align if'n the cached current alignment
5664 says we've already got it, as well as taking care of the auto-align
5665 feature wrt labels. */
5668 alpha_align (n
, pfill
, label
, force
)
5672 int force ATTRIBUTE_UNUSED
;
5674 if (alpha_current_align
>= n
)
5679 if (subseg_text_p (now_seg
))
5680 frag_align_code (n
, 0);
5682 frag_align (n
, 0, 0);
5685 frag_align (n
, *pfill
, 0);
5687 alpha_current_align
= n
;
5689 if (label
!= NULL
&& S_GET_SEGMENT (label
) == now_seg
)
5691 symbol_set_frag (label
, frag_now
);
5692 S_SET_VALUE (label
, (valueT
) frag_now_fix ());
5695 record_alignment (now_seg
, n
);
5697 /* ??? If alpha_flag_relax && force && elf, record the requested alignment
5698 in a reloc for the linker to see. */
5701 /* This is called from HANDLE_ALIGN in write.c. Fill in the contents
5702 of an rs_align_code fragment. */
5705 alpha_handle_align (fragp
)
5708 static char const unop
[4] = { 0x00, 0x00, 0xfe, 0x2f };
5709 static char const nopunop
[8] = {
5710 0x1f, 0x04, 0xff, 0x47,
5711 0x00, 0x00, 0xfe, 0x2f
5717 if (fragp
->fr_type
!= rs_align_code
)
5720 bytes
= fragp
->fr_next
->fr_address
- fragp
->fr_address
- fragp
->fr_fix
;
5721 p
= fragp
->fr_literal
+ fragp
->fr_fix
;
5734 memcpy (p
, unop
, 4);
5740 memcpy (p
, nopunop
, 8);
5742 fragp
->fr_fix
+= fix
;
5746 /* The Alpha has support for some VAX floating point types, as well as for
5747 IEEE floating point. We consider IEEE to be the primary floating point
5748 format, and sneak in the VAX floating point support here. */
5749 #define md_atof vax_md_atof
5750 #include "config/atof-vax.c"