1 /* tc-alpha.c - Processor-specific code for the DEC Alpha AXP CPU.
2 Copyright 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
3 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"
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 /* Note, the alpha_reloc_op table below depends on the ordering
110 of O_literal .. O_gpre16. */
111 #define O_literal O_md3 /* !literal relocation */
112 #define O_lituse_addr O_md4 /* !lituse_addr relocation */
113 #define O_lituse_base O_md5 /* !lituse_base relocation */
114 #define O_lituse_bytoff O_md6 /* !lituse_bytoff relocation */
115 #define O_lituse_jsr O_md7 /* !lituse_jsr relocation */
116 #define O_gpdisp O_md8 /* !gpdisp relocation */
117 #define O_gprelhigh O_md9 /* !gprelhigh relocation */
118 #define O_gprellow O_md10 /* !gprellow relocation */
119 #define O_gprel O_md11 /* !gprel relocation */
121 #define DUMMY_RELOC_LITUSE_ADDR (BFD_RELOC_UNUSED + 1)
122 #define DUMMY_RELOC_LITUSE_BASE (BFD_RELOC_UNUSED + 2)
123 #define DUMMY_RELOC_LITUSE_BYTOFF (BFD_RELOC_UNUSED + 3)
124 #define DUMMY_RELOC_LITUSE_JSR (BFD_RELOC_UNUSED + 4)
126 #define LITUSE_ADDR 0
127 #define LITUSE_BASE 1
128 #define LITUSE_BYTOFF 2
131 #define USER_RELOC_P(R) ((R) >= O_literal && (R) <= O_gprel)
133 /* Macros for extracting the type and number of encoded register tokens */
135 #define is_ir_num(x) (((x) & 32) == 0)
136 #define is_fpr_num(x) (((x) & 32) != 0)
137 #define regno(x) ((x) & 31)
139 /* Something odd inherited from the old assembler */
141 #define note_gpreg(R) (alpha_gprmask |= (1 << (R)))
142 #define note_fpreg(R) (alpha_fprmask |= (1 << (R)))
144 /* Predicates for 16- and 32-bit ranges */
145 /* XXX: The non-shift version appears to trigger a compiler bug when
146 cross-assembling from x86 w/ gcc 2.7.2. */
149 #define range_signed_16(x) \
150 (((offsetT) (x) >> 15) == 0 || ((offsetT) (x) >> 15) == -1)
151 #define range_signed_32(x) \
152 (((offsetT) (x) >> 31) == 0 || ((offsetT) (x) >> 31) == -1)
154 #define range_signed_16(x) ((offsetT) (x) >= -(offsetT) 0x8000 && \
155 (offsetT) (x) <= (offsetT) 0x7FFF)
156 #define range_signed_32(x) ((offsetT) (x) >= -(offsetT) 0x80000000 && \
157 (offsetT) (x) <= (offsetT) 0x7FFFFFFF)
160 /* Macros for sign extending from 16- and 32-bits. */
161 /* XXX: The cast macros will work on all the systems that I care about,
162 but really a predicate should be found to use the non-cast forms. */
165 #define sign_extend_16(x) ((short) (x))
166 #define sign_extend_32(x) ((int) (x))
168 #define sign_extend_16(x) ((offsetT) (((x) & 0xFFFF) ^ 0x8000) - 0x8000)
169 #define sign_extend_32(x) ((offsetT) (((x) & 0xFFFFFFFF) \
170 ^ 0x80000000) - 0x80000000)
173 /* Macros to build tokens */
175 #define set_tok_reg(t, r) (memset (&(t), 0, sizeof (t)), \
176 (t).X_op = O_register, \
177 (t).X_add_number = (r))
178 #define set_tok_preg(t, r) (memset (&(t), 0, sizeof (t)), \
179 (t).X_op = O_pregister, \
180 (t).X_add_number = (r))
181 #define set_tok_cpreg(t, r) (memset (&(t), 0, sizeof (t)), \
182 (t).X_op = O_cpregister, \
183 (t).X_add_number = (r))
184 #define set_tok_freg(t, r) (memset (&(t), 0, sizeof (t)), \
185 (t).X_op = O_register, \
186 (t).X_add_number = (r) + 32)
187 #define set_tok_sym(t, s, a) (memset (&(t), 0, sizeof (t)), \
188 (t).X_op = O_symbol, \
189 (t).X_add_symbol = (s), \
190 (t).X_add_number = (a))
191 #define set_tok_const(t, n) (memset (&(t), 0, sizeof (t)), \
192 (t).X_op = O_constant, \
193 (t).X_add_number = (n))
195 /* Prototypes for all local functions */
197 static struct alpha_reloc_tag *get_alpha_reloc_tag PARAMS ((long));
198 static void alpha_adjust_symtab_relocs PARAMS ((bfd *, asection *, PTR));
200 static int tokenize_arguments PARAMS ((char *, expressionS *, int));
201 static const struct alpha_opcode *find_opcode_match
202 PARAMS ((const struct alpha_opcode *, const expressionS *, int *, int *));
203 static const struct alpha_macro *find_macro_match
204 PARAMS ((const struct alpha_macro *, const expressionS *, int *));
205 static unsigned insert_operand
206 PARAMS ((unsigned, const struct alpha_operand *, offsetT, char *, unsigned));
207 static void assemble_insn
208 PARAMS ((const struct alpha_opcode *, const expressionS *, int,
209 struct alpha_insn *, bfd_reloc_code_real_type));
210 static void emit_insn PARAMS ((struct alpha_insn *));
211 static void assemble_tokens_to_insn
212 PARAMS ((const char *, const expressionS *, int, struct alpha_insn *));
213 static void assemble_tokens
214 PARAMS ((const char *, const expressionS *, int, int));
216 static long load_expression
217 PARAMS ((int, const expressionS *, int *, expressionS *));
219 static void emit_ldgp PARAMS ((const expressionS *, int, const PTR));
220 static void emit_division PARAMS ((const expressionS *, int, const PTR));
221 static void emit_lda PARAMS ((const expressionS *, int, const PTR));
222 static void emit_ldah PARAMS ((const expressionS *, int, const PTR));
223 static void emit_ir_load PARAMS ((const expressionS *, int, const PTR));
224 static void emit_loadstore PARAMS ((const expressionS *, int, const PTR));
225 static void emit_jsrjmp PARAMS ((const expressionS *, int, const PTR));
226 static void emit_ldX PARAMS ((const expressionS *, int, const PTR));
227 static void emit_ldXu PARAMS ((const expressionS *, int, const PTR));
228 static void emit_uldX PARAMS ((const expressionS *, int, const PTR));
229 static void emit_uldXu PARAMS ((const expressionS *, int, const PTR));
230 static void emit_ldil PARAMS ((const expressionS *, int, const PTR));
231 static void emit_stX PARAMS ((const expressionS *, int, const PTR));
232 static void emit_ustX PARAMS ((const expressionS *, int, const PTR));
233 static void emit_sextX PARAMS ((const expressionS *, int, const PTR));
234 static void emit_retjcr PARAMS ((const expressionS *, int, const PTR));
236 static void s_alpha_text PARAMS ((int));
237 static void s_alpha_data PARAMS ((int));
239 static void s_alpha_comm PARAMS ((int));
240 static void s_alpha_rdata PARAMS ((int));
243 static void s_alpha_sdata PARAMS ((int));
246 static void s_alpha_section PARAMS ((int));
247 static void s_alpha_ent PARAMS ((int));
248 static void s_alpha_end PARAMS ((int));
249 static void s_alpha_mask PARAMS ((int));
250 static void s_alpha_frame PARAMS ((int));
251 static void s_alpha_prologue PARAMS ((int));
252 static void s_alpha_file PARAMS ((int));
253 static void s_alpha_loc PARAMS ((int));
254 static void s_alpha_stab PARAMS ((int));
255 static void s_alpha_coff_wrapper PARAMS ((int));
258 static void s_alpha_section PARAMS ((int));
260 static void s_alpha_gprel32 PARAMS ((int));
261 static void s_alpha_float_cons PARAMS ((int));
262 static void s_alpha_proc PARAMS ((int));
263 static void s_alpha_set PARAMS ((int));
264 static void s_alpha_base PARAMS ((int));
265 static void s_alpha_align PARAMS ((int));
266 static void s_alpha_stringer PARAMS ((int));
267 static void s_alpha_space PARAMS ((int));
268 static void s_alpha_ucons PARAMS ((int));
269 static void s_alpha_arch PARAMS ((int));
271 static void create_literal_section PARAMS ((const char *, segT *, symbolS **));
273 static void select_gp_value PARAMS ((void));
275 static void alpha_align PARAMS ((int, char *, symbolS *, int));
277 /* Generic assembler global variables which must be defined by all
280 /* Characters which always start a comment. */
281 const char comment_chars[] = "#";
283 /* Characters which start a comment at the beginning of a line. */
284 const char line_comment_chars[] = "#";
286 /* Characters which may be used to separate multiple commands on a
288 const char line_separator_chars[] = ";";
290 /* Characters which are used to indicate an exponent in a floating
292 const char EXP_CHARS[] = "eE";
294 /* Characters which mean that a number is a floating point constant,
297 const char FLT_CHARS[] = "dD";
299 /* XXX: Do all of these really get used on the alpha?? */
300 char FLT_CHARS[] = "rRsSfFdDxXpP";
304 const char *md_shortopts = "Fm:g+1h:HG:";
306 const char *md_shortopts = "Fm:gG:";
309 struct option md_longopts[] = {
310 #define OPTION_32ADDR (OPTION_MD_BASE)
311 { "32addr", no_argument, NULL, OPTION_32ADDR },
312 #define OPTION_RELAX (OPTION_32ADDR + 1)
313 { "relax", no_argument, NULL, OPTION_RELAX },
315 #define OPTION_MDEBUG (OPTION_RELAX + 1)
316 #define OPTION_NO_MDEBUG (OPTION_MDEBUG + 1)
317 { "mdebug", no_argument, NULL, OPTION_MDEBUG },
318 { "no-mdebug", no_argument, NULL, OPTION_NO_MDEBUG },
320 { NULL, no_argument, NULL, 0 }
323 size_t md_longopts_size = sizeof (md_longopts);
327 #define AXP_REG_R16 16
328 #define AXP_REG_R17 17
330 #define AXP_REG_T9 22
332 #define AXP_REG_T10 23
334 #define AXP_REG_T11 24
336 #define AXP_REG_T12 25
337 #define AXP_REG_AI 25
339 #define AXP_REG_FP 29
342 #define AXP_REG_GP AXP_REG_PV
343 #endif /* OBJ_EVAX */
345 /* The cpu for which we are generating code */
346 static unsigned alpha_target = AXP_OPCODE_BASE;
347 static const char *alpha_target_name = "<all>";
349 /* The hash table of instruction opcodes */
350 static struct hash_control *alpha_opcode_hash;
352 /* The hash table of macro opcodes */
353 static struct hash_control *alpha_macro_hash;
356 /* The $gp relocation symbol */
357 static symbolS *alpha_gp_symbol;
359 /* XXX: what is this, and why is it exported? */
360 valueT alpha_gp_value;
363 /* The current $gp register */
364 static int alpha_gp_register = AXP_REG_GP;
366 /* A table of the register symbols */
367 static symbolS *alpha_register_table[64];
369 /* Constant sections, or sections of constants */
371 static segT alpha_lita_section;
372 static segT alpha_lit4_section;
375 static segT alpha_link_section;
376 static segT alpha_ctors_section;
377 static segT alpha_dtors_section;
379 static segT alpha_lit8_section;
381 /* Symbols referring to said sections. */
383 static symbolS *alpha_lita_symbol;
384 static symbolS *alpha_lit4_symbol;
387 static symbolS *alpha_link_symbol;
388 static symbolS *alpha_ctors_symbol;
389 static symbolS *alpha_dtors_symbol;
391 static symbolS *alpha_lit8_symbol;
393 /* Literal for .litX+0x8000 within .lita */
395 static offsetT alpha_lit4_literal;
396 static offsetT alpha_lit8_literal;
400 /* The active .ent symbol. */
401 static symbolS *alpha_cur_ent_sym;
404 /* Is the assembler not allowed to use $at? */
405 static int alpha_noat_on = 0;
407 /* Are macros enabled? */
408 static int alpha_macros_on = 1;
410 /* Are floats disabled? */
411 static int alpha_nofloats_on = 0;
413 /* Are addresses 32 bit? */
414 static int alpha_addr32_on = 0;
416 /* Symbol labelling the current insn. When the Alpha gas sees
419 and the section happens to not be on an eight byte boundary, it
420 will align both the symbol and the .quad to an eight byte boundary. */
421 static symbolS *alpha_insn_label;
423 /* Whether we should automatically align data generation pseudo-ops.
424 .align 0 will turn this off. */
425 static int alpha_auto_align_on = 1;
427 /* The known current alignment of the current section. */
428 static int alpha_current_align;
430 /* These are exported to ECOFF code. */
431 unsigned long alpha_gprmask, alpha_fprmask;
433 /* Whether the debugging option was seen. */
434 static int alpha_debug;
437 /* Whether we are emitting an mdebug section. */
438 int alpha_flag_mdebug = -1;
441 /* Don't fully resolve relocations, allowing code movement in the linker. */
442 static int alpha_flag_relax;
444 /* What value to give to bfd_set_gp_size. */
445 static int g_switch_value = 8;
448 /* Collect information about current procedure here. */
450 symbolS *symbol; /* proc pdesc symbol */
452 int framereg; /* register for frame pointer */
453 int framesize; /* size of frame */
463 static int alpha_flag_hash_long_names = 0; /* -+ */
464 static int alpha_flag_show_after_trunc = 0; /* -H */
466 /* If the -+ switch is given, then a hash is appended to any name that is
467 * longer than 64 characters, else longer symbol names are truncated.
473 /* A table to map the spelling of a relocation operand into an appropriate
474 bfd_reloc_code_real_type type. The table is assumed to be ordered such
475 that op-O_literal indexes into it. */
477 #define ALPHA_RELOC_TABLE(op) \
478 (&alpha_reloc_op[ ((!USER_RELOC_P (op)) \
480 : (int) (op) - (int) O_literal) ])
482 #define DEF(NAME, RELOC, REQ, ALLOW) \
483 { #NAME, sizeof(#NAME)-1, O_##NAME, RELOC, REQ, ALLOW}
485 static const struct alpha_reloc_op_tag {
486 const char *name; /* string to lookup */
487 size_t length; /* size of the string */
488 operatorT op; /* which operator to use */
489 bfd_reloc_code_real_type reloc; /* relocation before frob */
490 unsigned int require_seq : 1; /* require a sequence number */
491 unsigned int allow_seq : 1; /* allow a sequence number */
492 } alpha_reloc_op[] = {
493 DEF(literal, BFD_RELOC_ALPHA_ELF_LITERAL, 0, 1),
494 DEF(lituse_addr, DUMMY_RELOC_LITUSE_ADDR, 1, 1),
495 DEF(lituse_base, DUMMY_RELOC_LITUSE_BASE, 1, 1),
496 DEF(lituse_bytoff, DUMMY_RELOC_LITUSE_BYTOFF, 1, 1),
497 DEF(lituse_jsr, DUMMY_RELOC_LITUSE_JSR, 1, 1),
498 DEF(gpdisp, BFD_RELOC_ALPHA_GPDISP, 1, 1),
499 DEF(gprelhigh, BFD_RELOC_ALPHA_GPREL_HI16, 0, 0),
500 DEF(gprellow, BFD_RELOC_ALPHA_GPREL_LO16, 0, 0),
501 DEF(gprel, BFD_RELOC_GPREL16, 0, 0)
506 static const int alpha_num_reloc_op
507 = sizeof (alpha_reloc_op) / sizeof (*alpha_reloc_op);
508 #endif /* RELOC_OP_P */
510 /* Maximum # digits needed to hold the largest sequence # */
511 #define ALPHA_RELOC_DIGITS 25
513 /* Structure to hold explict sequence information. */
514 struct alpha_reloc_tag
516 fixS *slaves; /* head of linked list of !literals */
517 segT segment; /* segment relocs are in or undefined_section*/
518 long sequence; /* sequence # */
519 unsigned n_master; /* # of literals */
520 unsigned n_slaves; /* # of lituses */
521 char multi_section_p; /* True if more than one section was used */
522 char string[1]; /* printable form of sequence to hash with */
525 /* Hash table to link up literals with the appropriate lituse */
526 static struct hash_control *alpha_literal_hash;
528 /* Sequence numbers for internal use by macros. */
529 static long next_sequence_num = -1;
531 /* A table of CPU names and opcode sets. */
533 static const struct cpu_type {
537 /* Ad hoc convention: cpu number gets palcode, process code doesn't.
538 This supports usage under DU 4.0b that does ".arch ev4", and
539 usage in MILO that does -m21064. Probably something more
540 specific like -m21064-pal should be used, but oh well. */
542 { "21064", AXP_OPCODE_BASE|AXP_OPCODE_EV4 },
543 { "21064a", AXP_OPCODE_BASE|AXP_OPCODE_EV4 },
544 { "21066", AXP_OPCODE_BASE|AXP_OPCODE_EV4 },
545 { "21068", AXP_OPCODE_BASE|AXP_OPCODE_EV4 },
546 { "21164", AXP_OPCODE_BASE|AXP_OPCODE_EV5 },
547 { "21164a", AXP_OPCODE_BASE|AXP_OPCODE_EV5|AXP_OPCODE_BWX },
548 { "21164pc", (AXP_OPCODE_BASE|AXP_OPCODE_EV5|AXP_OPCODE_BWX
550 { "21264", (AXP_OPCODE_BASE|AXP_OPCODE_EV6|AXP_OPCODE_BWX
551 |AXP_OPCODE_MAX|AXP_OPCODE_CIX) },
553 { "ev4", AXP_OPCODE_BASE },
554 { "ev45", AXP_OPCODE_BASE },
555 { "lca45", AXP_OPCODE_BASE },
556 { "ev5", AXP_OPCODE_BASE },
557 { "ev56", AXP_OPCODE_BASE|AXP_OPCODE_BWX },
558 { "pca56", AXP_OPCODE_BASE|AXP_OPCODE_BWX|AXP_OPCODE_MAX },
559 { "ev6", AXP_OPCODE_BASE|AXP_OPCODE_BWX|AXP_OPCODE_MAX|AXP_OPCODE_CIX },
561 { "all", AXP_OPCODE_BASE },
565 /* The macro table */
567 static const struct alpha_macro alpha_macros[] = {
568 /* Load/Store macros */
569 { "lda", emit_lda, NULL,
570 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
571 { "ldah", emit_ldah, NULL,
572 { MACRO_IR, MACRO_EXP, MACRO_EOA } },
574 { "ldl", emit_ir_load, "ldl",
575 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
576 { "ldl_l", emit_ir_load, "ldl_l",
577 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
578 { "ldq", emit_ir_load, "ldq",
579 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
580 { "ldq_l", emit_ir_load, "ldq_l",
581 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
582 { "ldq_u", emit_ir_load, "ldq_u",
583 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
584 { "ldf", emit_loadstore, "ldf",
585 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
586 { "ldg", emit_loadstore, "ldg",
587 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
588 { "lds", emit_loadstore, "lds",
589 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
590 { "ldt", emit_loadstore, "ldt",
591 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
593 { "ldb", emit_ldX, (PTR) 0,
594 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
595 { "ldbu", emit_ldXu, (PTR) 0,
596 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
597 { "ldw", emit_ldX, (PTR) 1,
598 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
599 { "ldwu", emit_ldXu, (PTR) 1,
600 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
602 { "uldw", emit_uldX, (PTR) 1,
603 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
604 { "uldwu", emit_uldXu, (PTR) 1,
605 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
606 { "uldl", emit_uldX, (PTR) 2,
607 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
608 { "uldlu", emit_uldXu, (PTR) 2,
609 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
610 { "uldq", emit_uldXu, (PTR) 3,
611 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
613 { "ldgp", emit_ldgp, NULL,
614 { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA } },
616 { "ldi", emit_lda, NULL,
617 { MACRO_IR, MACRO_EXP, MACRO_EOA } },
618 { "ldil", emit_ldil, NULL,
619 { MACRO_IR, MACRO_EXP, MACRO_EOA } },
620 { "ldiq", emit_lda, NULL,
621 { MACRO_IR, MACRO_EXP, MACRO_EOA } },
623 { "ldif" emit_ldiq, NULL,
624 { MACRO_FPR, MACRO_EXP, MACRO_EOA } },
625 { "ldid" emit_ldiq, NULL,
626 { MACRO_FPR, MACRO_EXP, MACRO_EOA } },
627 { "ldig" emit_ldiq, NULL,
628 { MACRO_FPR, MACRO_EXP, MACRO_EOA } },
629 { "ldis" emit_ldiq, NULL,
630 { MACRO_FPR, MACRO_EXP, MACRO_EOA } },
631 { "ldit" emit_ldiq, NULL,
632 { MACRO_FPR, MACRO_EXP, MACRO_EOA } },
635 { "stl", emit_loadstore, "stl",
636 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
637 { "stl_c", emit_loadstore, "stl_c",
638 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
639 { "stq", emit_loadstore, "stq",
640 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
641 { "stq_c", emit_loadstore, "stq_c",
642 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
643 { "stq_u", emit_loadstore, "stq_u",
644 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
645 { "stf", emit_loadstore, "stf",
646 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
647 { "stg", emit_loadstore, "stg",
648 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
649 { "sts", emit_loadstore, "sts",
650 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
651 { "stt", emit_loadstore, "stt",
652 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
654 { "stb", emit_stX, (PTR) 0,
655 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
656 { "stw", emit_stX, (PTR) 1,
657 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
658 { "ustw", emit_ustX, (PTR) 1,
659 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
660 { "ustl", emit_ustX, (PTR) 2,
661 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
662 { "ustq", emit_ustX, (PTR) 3,
663 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
665 /* Arithmetic macros */
667 { "absl" emit_absl, 1, { IR } },
668 { "absl" emit_absl, 2, { IR, IR } },
669 { "absl" emit_absl, 2, { EXP, IR } },
670 { "absq" emit_absq, 1, { IR } },
671 { "absq" emit_absq, 2, { IR, IR } },
672 { "absq" emit_absq, 2, { EXP, IR } },
675 { "sextb", emit_sextX, (PTR) 0,
676 { MACRO_IR, MACRO_IR, MACRO_EOA,
678 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
679 { "sextw", emit_sextX, (PTR) 1,
680 { MACRO_IR, MACRO_IR, MACRO_EOA,
682 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
684 { "divl", emit_division, "__divl",
685 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
686 MACRO_IR, MACRO_IR, MACRO_EOA,
687 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
688 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
689 { "divlu", emit_division, "__divlu",
690 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
691 MACRO_IR, MACRO_IR, MACRO_EOA,
692 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
693 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
694 { "divq", emit_division, "__divq",
695 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
696 MACRO_IR, MACRO_IR, MACRO_EOA,
697 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
698 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
699 { "divqu", emit_division, "__divqu",
700 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
701 MACRO_IR, MACRO_IR, MACRO_EOA,
702 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
703 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
704 { "reml", emit_division, "__reml",
705 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
706 MACRO_IR, MACRO_IR, MACRO_EOA,
707 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
708 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
709 { "remlu", emit_division, "__remlu",
710 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
711 MACRO_IR, MACRO_IR, MACRO_EOA,
712 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
713 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
714 { "remq", emit_division, "__remq",
715 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
716 MACRO_IR, MACRO_IR, MACRO_EOA,
717 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
718 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
719 { "remqu", emit_division, "__remqu",
720 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
721 MACRO_IR, MACRO_IR, MACRO_EOA,
722 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
723 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
725 { "jsr", emit_jsrjmp, "jsr",
726 { MACRO_PIR, MACRO_EXP, MACRO_EOA,
727 MACRO_PIR, MACRO_EOA,
728 MACRO_IR, MACRO_EXP, MACRO_EOA,
729 MACRO_EXP, MACRO_EOA } },
730 { "jmp", emit_jsrjmp, "jmp",
731 { MACRO_PIR, MACRO_EXP, MACRO_EOA,
732 MACRO_PIR, MACRO_EOA,
733 MACRO_IR, MACRO_EXP, MACRO_EOA,
734 MACRO_EXP, MACRO_EOA } },
735 { "ret", emit_retjcr, "ret",
736 { MACRO_IR, MACRO_EXP, MACRO_EOA,
738 MACRO_PIR, MACRO_EXP, MACRO_EOA,
739 MACRO_PIR, MACRO_EOA,
740 MACRO_EXP, MACRO_EOA,
742 { "jcr", emit_retjcr, "jcr",
743 { MACRO_IR, MACRO_EXP, MACRO_EOA,
745 MACRO_PIR, MACRO_EXP, MACRO_EOA,
746 MACRO_PIR, MACRO_EOA,
747 MACRO_EXP, MACRO_EOA,
749 { "jsr_coroutine", emit_retjcr, "jcr",
750 { MACRO_IR, MACRO_EXP, MACRO_EOA,
752 MACRO_PIR, MACRO_EXP, MACRO_EOA,
753 MACRO_PIR, MACRO_EOA,
754 MACRO_EXP, MACRO_EOA,
758 static const unsigned int alpha_num_macros
759 = sizeof (alpha_macros) / sizeof (*alpha_macros);
761 /* Public interface functions */
763 /* This function is called once, at assembler startup time. It sets
764 up all the tables, etc. that the MD part of the assembler will
765 need, that can be determined before arguments are parsed. */
772 /* Verify that X_op field is wide enough. */
776 assert (e.X_op == O_max);
779 /* Create the opcode hash table */
781 alpha_opcode_hash = hash_new ();
782 for (i = 0; i < alpha_num_opcodes;)
784 const char *name, *retval, *slash;
786 name = alpha_opcodes[i].name;
787 retval = hash_insert (alpha_opcode_hash, name, (PTR) &alpha_opcodes[i]);
789 as_fatal (_("internal error: can't hash opcode `%s': %s"),
792 /* Some opcodes include modifiers of various sorts with a "/mod"
793 syntax, like the architecture manual suggests. However, for
794 use with gcc at least, we also need access to those same opcodes
797 if ((slash = strchr (name, '/')) != NULL)
799 char *p = xmalloc (strlen (name));
800 memcpy (p, name, slash - name);
801 strcpy (p + (slash - name), slash + 1);
803 (void) hash_insert (alpha_opcode_hash, p, (PTR) &alpha_opcodes[i]);
804 /* Ignore failures -- the opcode table does duplicate some
805 variants in different forms, like "hw_stq" and "hw_st/q". */
808 while (++i < alpha_num_opcodes
809 && (alpha_opcodes[i].name == name
810 || !strcmp (alpha_opcodes[i].name, name)))
814 /* Create the macro hash table */
816 alpha_macro_hash = hash_new ();
817 for (i = 0; i < alpha_num_macros;)
819 const char *name, *retval;
821 name = alpha_macros[i].name;
822 retval = hash_insert (alpha_macro_hash, name, (PTR) &alpha_macros[i]);
824 as_fatal (_("internal error: can't hash macro `%s': %s"),
827 while (++i < alpha_num_macros
828 && (alpha_macros[i].name == name
829 || !strcmp (alpha_macros[i].name, name)))
833 /* Construct symbols for each of the registers */
835 for (i = 0; i < 32; ++i)
838 sprintf (name, "$%d", i);
839 alpha_register_table[i] = symbol_create (name, reg_section, i,
845 sprintf (name, "$f%d", i - 32);
846 alpha_register_table[i] = symbol_create (name, reg_section, i,
850 /* Create the special symbols and sections we'll be using */
852 /* So .sbss will get used for tiny objects. */
853 bfd_set_gp_size (stdoutput, g_switch_value);
856 create_literal_section (".lita", &alpha_lita_section, &alpha_lita_symbol);
858 /* For handling the GP, create a symbol that won't be output in the
859 symbol table. We'll edit it out of relocs later. */
860 alpha_gp_symbol = symbol_create ("<GP value>", alpha_lita_section, 0x8000,
865 create_literal_section (".link", &alpha_link_section, &alpha_link_symbol);
871 segT sec = subseg_new (".mdebug", (subsegT) 0);
872 bfd_set_section_flags (stdoutput, sec, SEC_HAS_CONTENTS | SEC_READONLY);
873 bfd_set_section_alignment (stdoutput, sec, 3);
877 /* Create literal lookup hash table. */
878 alpha_literal_hash = hash_new ();
880 subseg_set (text_section, 0);
883 /* The public interface to the instruction assembler. */
889 char opname[32]; /* current maximum is 13 */
890 expressionS tok[MAX_INSN_ARGS];
894 /* split off the opcode */
895 opnamelen = strspn (str, "abcdefghijklmnopqrstuvwxyz_/46819");
896 trunclen = (opnamelen < sizeof (opname) - 1
898 : sizeof (opname) - 1);
899 memcpy (opname, str, trunclen);
900 opname[trunclen] = '\0';
902 /* tokenize the rest of the line */
903 if ((ntok = tokenize_arguments (str + opnamelen, tok, MAX_INSN_ARGS)) < 0)
905 if (ntok != TOKENIZE_ERROR_REPORT)
906 as_bad (_("syntax error"));
912 assemble_tokens (opname, tok, ntok, alpha_macros_on);
915 /* Round up a section's size to the appropriate boundary. */
918 md_section_align (seg, size)
922 int align = bfd_get_section_alignment (stdoutput, seg);
923 valueT mask = ((valueT) 1 << align) - 1;
925 return (size + mask) & ~mask;
928 /* Turn a string in input_line_pointer into a floating point constant
929 of type TYPE, and store the appropriate bytes in *LITP. The number
930 of LITTLENUMS emitted is stored in *SIZEP. An error message is
931 returned, or NULL on OK. */
933 /* Equal to MAX_PRECISION in atof-ieee.c */
934 #define MAX_LITTLENUMS 6
936 extern char *vax_md_atof PARAMS ((int, char *, int *));
939 md_atof (type, litP, sizeP)
945 LITTLENUM_TYPE words[MAX_LITTLENUMS];
946 LITTLENUM_TYPE *wordP;
953 /* VAX md_atof doesn't like "G" for some reason. */
957 return vax_md_atof (type, litP, sizeP);
980 return _("Bad call to MD_ATOF()");
982 t = atof_ieee (input_line_pointer, type, words);
984 input_line_pointer = t;
985 *sizeP = prec * sizeof (LITTLENUM_TYPE);
987 for (wordP = words + prec - 1; prec--;)
989 md_number_to_chars (litP, (long) (*wordP--), sizeof (LITTLENUM_TYPE));
990 litP += sizeof (LITTLENUM_TYPE);
996 /* Take care of the target-specific command-line options. */
999 md_parse_option (c, arg)
1006 alpha_nofloats_on = 1;
1010 alpha_addr32_on = 1;
1018 g_switch_value = atoi (arg);
1023 const struct cpu_type *p;
1024 for (p = cpu_types; p->name; ++p)
1025 if (strcmp (arg, p->name) == 0)
1027 alpha_target_name = p->name, alpha_target = p->flags;
1030 as_warn (_("Unknown CPU identifier `%s'"), arg);
1036 case '+': /* For g++. Hash any name > 63 chars long. */
1037 alpha_flag_hash_long_names = 1;
1040 case 'H': /* Show new symbol after hash truncation */
1041 alpha_flag_show_after_trunc = 1;
1044 case 'h': /* for gnu-c/vax compatibility. */
1049 alpha_flag_relax = 1;
1054 alpha_flag_mdebug = 1;
1056 case OPTION_NO_MDEBUG:
1057 alpha_flag_mdebug = 0;
1068 /* Print a description of the command-line options that we accept. */
1071 md_show_usage (stream)
1076 -32addr treat addresses as 32-bit values\n\
1077 -F lack floating point instructions support\n\
1078 -mev4 | -mev45 | -mev5 | -mev56 | -mpca56 | -mev6 | -mall\n\
1079 specify variant of Alpha architecture\n\
1080 -m21064 | -m21066 | -m21164 | -m21164a | -m21164pc | -m21264\n\
1081 these variants include PALcode opcodes\n"),
1086 -+ hash encode (don't truncate) names longer than 64 characters\n\
1087 -H show new symbol after hash truncation\n"),
1092 /* Decide from what point a pc-relative relocation is relative to,
1093 relative to the pc-relative fixup. Er, relatively speaking. */
1096 md_pcrel_from (fixP)
1099 valueT addr = fixP->fx_where + fixP->fx_frag->fr_address;
1100 switch (fixP->fx_r_type)
1102 case BFD_RELOC_ALPHA_GPDISP:
1103 case BFD_RELOC_ALPHA_GPDISP_HI16:
1104 case BFD_RELOC_ALPHA_GPDISP_LO16:
1107 return fixP->fx_size + addr;
1111 /* Attempt to simplify or even eliminate a fixup. The return value is
1112 ignored; perhaps it was once meaningful, but now it is historical.
1113 To indicate that a fixup has been eliminated, set fixP->fx_done.
1115 For ELF, here it is that we transform the GPDISP_HI16 reloc we used
1116 internally into the GPDISP reloc used externally. We had to do
1117 this so that we'd have the GPDISP_LO16 reloc as a tag to compute
1118 the distance to the "lda" instruction for setting the addend to
1122 md_apply_fix3 (fixP, valueP, seg)
1127 char * const fixpos = fixP->fx_frag->fr_literal + fixP->fx_where;
1128 valueT value = *valueP;
1129 unsigned image, size;
1131 switch (fixP->fx_r_type)
1133 /* The GPDISP relocations are processed internally with a symbol
1134 referring to the current function; we need to drop in a value
1135 which, when added to the address of the start of the function,
1136 gives the desired GP. */
1137 case BFD_RELOC_ALPHA_GPDISP_HI16:
1139 fixS *next = fixP->fx_next;
1141 /* With user-specified !gpdisp relocations, we can be missing
1142 the matching LO16 reloc. We will have already issued an
1145 fixP->fx_offset = (next->fx_frag->fr_address + next->fx_where
1146 - fixP->fx_frag->fr_address - fixP->fx_where);
1148 value = (value - sign_extend_16 (value)) >> 16;
1151 fixP->fx_r_type = BFD_RELOC_ALPHA_GPDISP;
1155 case BFD_RELOC_ALPHA_GPDISP_LO16:
1156 value = sign_extend_16 (value);
1157 fixP->fx_offset = 0;
1163 fixP->fx_addsy = section_symbol (seg);
1164 md_number_to_chars (fixpos, value, 2);
1169 fixP->fx_r_type = BFD_RELOC_16_PCREL;
1174 fixP->fx_r_type = BFD_RELOC_32_PCREL;
1179 fixP->fx_r_type = BFD_RELOC_64_PCREL;
1182 if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0)
1184 md_number_to_chars (fixpos, value, size);
1190 case BFD_RELOC_GPREL32:
1191 assert (fixP->fx_subsy == alpha_gp_symbol);
1193 /* FIXME: inherited this obliviousness of `value' -- why? */
1194 md_number_to_chars (fixpos, -alpha_gp_value, 4);
1197 case BFD_RELOC_GPREL32:
1199 case BFD_RELOC_GPREL16:
1200 case BFD_RELOC_ALPHA_GPREL_HI16:
1201 case BFD_RELOC_ALPHA_GPREL_LO16:
1204 case BFD_RELOC_23_PCREL_S2:
1205 if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0)
1207 image = bfd_getl32 (fixpos);
1208 image = (image & ~0x1FFFFF) | ((value >> 2) & 0x1FFFFF);
1213 case BFD_RELOC_ALPHA_HINT:
1214 if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0)
1216 image = bfd_getl32 (fixpos);
1217 image = (image & ~0x3FFF) | ((value >> 2) & 0x3FFF);
1223 case BFD_RELOC_ALPHA_LITERAL:
1224 md_number_to_chars (fixpos, value, 2);
1227 case BFD_RELOC_ALPHA_ELF_LITERAL:
1228 case BFD_RELOC_ALPHA_LITUSE:
1229 case BFD_RELOC_ALPHA_LINKAGE:
1230 case BFD_RELOC_ALPHA_CODEADDR:
1233 case BFD_RELOC_VTABLE_INHERIT:
1234 case BFD_RELOC_VTABLE_ENTRY:
1239 const struct alpha_operand *operand;
1241 if ((int) fixP->fx_r_type >= 0)
1242 as_fatal (_("unhandled relocation type %s"),
1243 bfd_get_reloc_code_name (fixP->fx_r_type));
1245 assert (-(int) fixP->fx_r_type < (int) alpha_num_operands);
1246 operand = &alpha_operands[-(int) fixP->fx_r_type];
1248 /* The rest of these fixups only exist internally during symbol
1249 resolution and have no representation in the object file.
1250 Therefore they must be completely resolved as constants. */
1252 if (fixP->fx_addsy != 0
1253 && S_GET_SEGMENT (fixP->fx_addsy) != absolute_section)
1254 as_bad_where (fixP->fx_file, fixP->fx_line,
1255 _("non-absolute expression in constant field"));
1257 image = bfd_getl32 (fixpos);
1258 image = insert_operand (image, operand, (offsetT) value,
1259 fixP->fx_file, fixP->fx_line);
1264 if (fixP->fx_addsy != 0 || fixP->fx_pcrel != 0)
1268 as_warn_where (fixP->fx_file, fixP->fx_line,
1269 _("type %d reloc done?\n"), (int) fixP->fx_r_type);
1274 md_number_to_chars (fixpos, image, 4);
1282 * Look for a register name in the given symbol.
1286 md_undefined_symbol (name)
1291 int is_float = 0, num;
1296 if (name[1] == 'p' && name[2] == '\0')
1297 return alpha_register_table[AXP_REG_FP];
1302 if (!isdigit (*++name))
1306 case '0': case '1': case '2': case '3': case '4':
1307 case '5': case '6': case '7': case '8': case '9':
1308 if (name[1] == '\0')
1309 num = name[0] - '0';
1310 else if (name[0] != '0' && isdigit (name[1]) && name[2] == '\0')
1312 num = (name[0] - '0') * 10 + name[1] - '0';
1319 if (!alpha_noat_on && (num + is_float) == AXP_REG_AT)
1320 as_warn (_("Used $at without \".set noat\""));
1321 return alpha_register_table[num + is_float];
1324 if (name[1] == 't' && name[2] == '\0')
1327 as_warn (_("Used $at without \".set noat\""));
1328 return alpha_register_table[AXP_REG_AT];
1333 if (name[1] == 'p' && name[2] == '\0')
1334 return alpha_register_table[alpha_gp_register];
1338 if (name[1] == 'p' && name[2] == '\0')
1339 return alpha_register_table[AXP_REG_SP];
1347 /* @@@ Magic ECOFF bits. */
1350 alpha_frob_ecoff_data ()
1353 /* $zero and $f31 are read-only */
1354 alpha_gprmask &= ~1;
1355 alpha_fprmask &= ~1;
1359 /* Hook to remember a recently defined label so that the auto-align
1360 code can adjust the symbol after we know what alignment will be
1364 alpha_define_label (sym)
1367 alpha_insn_label = sym;
1370 /* Return true if we must always emit a reloc for a type and false if
1371 there is some hope of resolving it a assembly time. */
1374 alpha_force_relocation (f)
1377 if (alpha_flag_relax)
1380 switch (f->fx_r_type)
1382 case BFD_RELOC_ALPHA_GPDISP_HI16:
1383 case BFD_RELOC_ALPHA_GPDISP_LO16:
1384 case BFD_RELOC_ALPHA_GPDISP:
1385 case BFD_RELOC_ALPHA_LITERAL:
1386 case BFD_RELOC_ALPHA_ELF_LITERAL:
1387 case BFD_RELOC_ALPHA_LITUSE:
1388 case BFD_RELOC_GPREL16:
1389 case BFD_RELOC_GPREL32:
1390 case BFD_RELOC_ALPHA_GPREL_HI16:
1391 case BFD_RELOC_ALPHA_GPREL_LO16:
1392 case BFD_RELOC_ALPHA_LINKAGE:
1393 case BFD_RELOC_ALPHA_CODEADDR:
1394 case BFD_RELOC_VTABLE_INHERIT:
1395 case BFD_RELOC_VTABLE_ENTRY:
1398 case BFD_RELOC_23_PCREL_S2:
1401 case BFD_RELOC_ALPHA_HINT:
1405 assert ((int) f->fx_r_type < 0
1406 && -(int) f->fx_r_type < (int) alpha_num_operands);
1411 /* Return true if we can partially resolve a relocation now. */
1414 alpha_fix_adjustable (f)
1418 /* Prevent all adjustments to global symbols */
1419 if (S_IS_EXTERN (f->fx_addsy) || S_IS_WEAK (f->fx_addsy))
1423 /* Are there any relocation types for which we must generate a reloc
1424 but we can adjust the values contained within it? */
1425 switch (f->fx_r_type)
1427 case BFD_RELOC_ALPHA_GPDISP_HI16:
1428 case BFD_RELOC_ALPHA_GPDISP_LO16:
1429 case BFD_RELOC_ALPHA_GPDISP:
1432 case BFD_RELOC_ALPHA_LITERAL:
1433 case BFD_RELOC_ALPHA_ELF_LITERAL:
1434 case BFD_RELOC_ALPHA_LITUSE:
1435 case BFD_RELOC_ALPHA_LINKAGE:
1436 case BFD_RELOC_ALPHA_CODEADDR:
1439 case BFD_RELOC_VTABLE_ENTRY:
1440 case BFD_RELOC_VTABLE_INHERIT:
1443 case BFD_RELOC_GPREL16:
1444 case BFD_RELOC_GPREL32:
1445 case BFD_RELOC_ALPHA_GPREL_HI16:
1446 case BFD_RELOC_ALPHA_GPREL_LO16:
1447 case BFD_RELOC_23_PCREL_S2:
1450 case BFD_RELOC_ALPHA_HINT:
1454 assert ((int) f->fx_r_type < 0
1455 && - (int) f->fx_r_type < (int) alpha_num_operands);
1461 /* Generate the BFD reloc to be stuck in the object file from the
1462 fixup used internally in the assembler. */
1465 tc_gen_reloc (sec, fixp)
1466 asection *sec ATTRIBUTE_UNUSED;
1471 reloc = (arelent *) xmalloc (sizeof (arelent));
1472 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
1473 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
1474 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
1476 /* Make sure none of our internal relocations make it this far.
1477 They'd better have been fully resolved by this point. */
1478 assert ((int) fixp->fx_r_type > 0);
1480 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
1481 if (reloc->howto == NULL)
1483 as_bad_where (fixp->fx_file, fixp->fx_line,
1484 _("cannot represent `%s' relocation in object file"),
1485 bfd_get_reloc_code_name (fixp->fx_r_type));
1489 if (!fixp->fx_pcrel != !reloc->howto->pc_relative)
1491 as_fatal (_("internal error? cannot generate `%s' relocation"),
1492 bfd_get_reloc_code_name (fixp->fx_r_type));
1494 assert (!fixp->fx_pcrel == !reloc->howto->pc_relative);
1497 if (fixp->fx_r_type == BFD_RELOC_ALPHA_LITERAL)
1499 /* fake out bfd_perform_relocation. sigh */
1500 reloc->addend = -alpha_gp_value;
1505 reloc->addend = fixp->fx_offset;
1508 * Ohhh, this is ugly. The problem is that if this is a local global
1509 * symbol, the relocation will entirely be performed at link time, not
1510 * at assembly time. bfd_perform_reloc doesn't know about this sort
1511 * of thing, and as a result we need to fake it out here.
1513 if ((S_IS_EXTERN (fixp->fx_addsy) || S_IS_WEAK (fixp->fx_addsy)
1514 || (S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_MERGE))
1515 && !S_IS_COMMON (fixp->fx_addsy))
1516 reloc->addend -= symbol_get_bfdsym (fixp->fx_addsy)->value;
1523 /* Parse a register name off of the input_line and return a register
1524 number. Gets md_undefined_symbol above to do the register name
1527 Only called as a part of processing the ECOFF .frame directive. */
1530 tc_get_register (frame)
1531 int frame ATTRIBUTE_UNUSED;
1533 int framereg = AXP_REG_SP;
1536 if (*input_line_pointer == '$')
1538 char *s = input_line_pointer;
1539 char c = get_symbol_end ();
1540 symbolS *sym = md_undefined_symbol (s);
1542 *strchr (s, '\0') = c;
1543 if (sym && (framereg = S_GET_VALUE (sym)) <= 31)
1546 as_warn (_("frame reg expected, using $%d."), framereg);
1549 note_gpreg (framereg);
1553 /* This is called before the symbol table is processed. In order to
1554 work with gcc when using mips-tfile, we must keep all local labels.
1555 However, in other cases, we want to discard them. If we were
1556 called with -g, but we didn't see any debugging information, it may
1557 mean that gcc is smuggling debugging information through to
1558 mips-tfile, in which case we must generate all local labels. */
1563 alpha_frob_file_before_adjust ()
1565 if (alpha_debug != 0
1566 && ! ecoff_debugging_seen)
1567 flag_keep_locals = 1;
1570 #endif /* OBJ_ECOFF */
1572 static struct alpha_reloc_tag *
1573 get_alpha_reloc_tag (sequence)
1576 char buffer[ALPHA_RELOC_DIGITS];
1577 struct alpha_reloc_tag *info;
1579 sprintf (buffer, "!%ld", sequence);
1581 info = (struct alpha_reloc_tag *) hash_find (alpha_literal_hash, buffer);
1584 size_t len = strlen (buffer);
1587 info = (struct alpha_reloc_tag *)
1588 xcalloc (sizeof (struct alpha_reloc_tag) + len, 1);
1590 info->segment = now_seg;
1591 info->sequence = sequence;
1592 strcpy (info->string, buffer);
1593 errmsg = hash_insert (alpha_literal_hash, info->string, (PTR) info);
1601 /* Before the relocations are written, reorder them, so that user
1602 supplied !lituse relocations follow the appropriate !literal
1603 relocations, and similarly for !gpdisp relocations. */
1606 alpha_adjust_symtab ()
1608 if (alpha_literal_hash)
1609 bfd_map_over_sections (stdoutput, alpha_adjust_symtab_relocs, NULL);
1613 alpha_adjust_symtab_relocs (abfd, sec, ptr)
1614 bfd *abfd ATTRIBUTE_UNUSED;
1616 PTR ptr ATTRIBUTE_UNUSED;
1618 segment_info_type *seginfo = seg_info (sec);
1623 unsigned long n_slaves = 0;
1625 /* If seginfo is NULL, we did not create this section; don't do
1626 anything with it. By using a pointer to a pointer, we can update
1627 the links in place. */
1628 if (seginfo == NULL)
1631 /* If there are no relocations, skip the section. */
1632 if (! seginfo->fix_root)
1635 /* First rebuild the fixup chain without the expicit lituse and
1636 gpdisp_lo16 relocs. */
1637 prevP = &seginfo->fix_root;
1638 for (fixp = seginfo->fix_root; fixp; fixp = next)
1640 next = fixp->fx_next;
1641 fixp->fx_next = (fixS *) 0;
1643 switch (fixp->fx_r_type)
1645 case BFD_RELOC_ALPHA_LITUSE:
1647 if (fixp->tc_fix_data.info->n_master == 0)
1648 as_bad_where (fixp->fx_file, fixp->fx_line,
1649 _("No !literal!%ld was found"),
1650 fixp->tc_fix_data.info->sequence);
1653 case BFD_RELOC_ALPHA_GPDISP_LO16:
1655 if (fixp->tc_fix_data.info->n_master == 0)
1656 as_bad_where (fixp->fx_file, fixp->fx_line,
1657 _("No ldah !gpdisp!%ld was found"),
1658 fixp->tc_fix_data.info->sequence);
1663 prevP = &fixp->fx_next;
1668 /* If there were any dependent relocations, go and add them back to
1669 the chain. They are linked through the next_reloc field in
1670 reverse order, so as we go through the next_reloc chain, we
1671 effectively reverse the chain once again.
1673 Except if there is more than one !literal for a given sequence
1674 number. In that case, the programmer and/or compiler is not sure
1675 how control flows from literal to lituse, and we can't be sure to
1676 get the relaxation correct.
1678 ??? Well, actually we could, if there are enough lituses such that
1679 we can make each literal have at least one of each lituse type
1680 present. Not implemented.
1682 Also suppress the optimization if the !literals/!lituses are spread
1683 in different segments. This can happen with "intersting" uses of
1684 inline assembly; examples are present in the Linux kernel semaphores. */
1686 for (fixp = seginfo->fix_root; fixp; fixp = next)
1688 next = fixp->fx_next;
1689 switch (fixp->fx_r_type)
1691 case BFD_RELOC_ALPHA_ELF_LITERAL:
1692 if (fixp->tc_fix_data.info->n_master == 1
1693 && ! fixp->tc_fix_data.info->multi_section_p)
1695 for (slave = fixp->tc_fix_data.info->slaves;
1696 slave != (fixS *) 0;
1697 slave = slave->tc_fix_data.next_reloc)
1699 slave->fx_next = fixp->fx_next;
1700 fixp->fx_next = slave;
1705 case BFD_RELOC_ALPHA_GPDISP_HI16:
1706 if (fixp->tc_fix_data.info->n_slaves == 0)
1707 as_bad_where (fixp->fx_file, fixp->fx_line,
1708 _("No lda !gpdisp!%ld was found"),
1709 fixp->tc_fix_data.info->sequence);
1712 slave = fixp->tc_fix_data.info->slaves;
1713 slave->fx_next = next;
1714 fixp->fx_next = slave;
1726 debug_exp (tok, ntok)
1732 fprintf (stderr, "debug_exp: %d tokens", ntok);
1733 for (i = 0; i < ntok; i++)
1735 expressionS *t = &tok[i];
1739 default: name = "unknown"; break;
1740 case O_illegal: name = "O_illegal"; break;
1741 case O_absent: name = "O_absent"; break;
1742 case O_constant: name = "O_constant"; break;
1743 case O_symbol: name = "O_symbol"; break;
1744 case O_symbol_rva: name = "O_symbol_rva"; break;
1745 case O_register: name = "O_register"; break;
1746 case O_big: name = "O_big"; break;
1747 case O_uminus: name = "O_uminus"; break;
1748 case O_bit_not: name = "O_bit_not"; break;
1749 case O_logical_not: name = "O_logical_not"; break;
1750 case O_multiply: name = "O_multiply"; break;
1751 case O_divide: name = "O_divide"; break;
1752 case O_modulus: name = "O_modulus"; break;
1753 case O_left_shift: name = "O_left_shift"; break;
1754 case O_right_shift: name = "O_right_shift"; break;
1755 case O_bit_inclusive_or: name = "O_bit_inclusive_or"; break;
1756 case O_bit_or_not: name = "O_bit_or_not"; break;
1757 case O_bit_exclusive_or: name = "O_bit_exclusive_or"; break;
1758 case O_bit_and: name = "O_bit_and"; break;
1759 case O_add: name = "O_add"; break;
1760 case O_subtract: name = "O_subtract"; break;
1761 case O_eq: name = "O_eq"; break;
1762 case O_ne: name = "O_ne"; break;
1763 case O_lt: name = "O_lt"; break;
1764 case O_le: name = "O_le"; break;
1765 case O_ge: name = "O_ge"; break;
1766 case O_gt: name = "O_gt"; break;
1767 case O_logical_and: name = "O_logical_and"; break;
1768 case O_logical_or: name = "O_logical_or"; break;
1769 case O_index: name = "O_index"; break;
1770 case O_pregister: name = "O_pregister"; break;
1771 case O_cpregister: name = "O_cpregister"; break;
1772 case O_literal: name = "O_literal"; break;
1773 case O_lituse_base: name = "O_lituse_base"; break;
1774 case O_lituse_bytoff: name = "O_lituse_bytoff"; break;
1775 case O_lituse_jsr: name = "O_lituse_jsr"; break;
1776 case O_gpdisp: name = "O_gpdisp"; break;
1777 case O_gprelhigh: name = "O_gprelhigh"; break;
1778 case O_gprellow: name = "O_gprellow"; break;
1779 case O_gprel: name = "O_gprel"; break;
1780 case O_md11: name = "O_md11"; break;
1781 case O_md12: name = "O_md12"; break;
1782 case O_md13: name = "O_md13"; break;
1783 case O_md14: name = "O_md14"; break;
1784 case O_md15: name = "O_md15"; break;
1785 case O_md16: name = "O_md16"; break;
1788 fprintf (stderr, ", %s(%s, %s, %d)", name,
1789 (t->X_add_symbol) ? S_GET_NAME (t->X_add_symbol) : "--",
1790 (t->X_op_symbol) ? S_GET_NAME (t->X_op_symbol) : "--",
1791 (int) t->X_add_number);
1793 fprintf (stderr, "\n");
1798 /* Parse the arguments to an opcode. */
1801 tokenize_arguments (str, tok, ntok)
1806 expressionS *end_tok = tok + ntok;
1807 char *old_input_line_pointer;
1808 int saw_comma = 0, saw_arg = 0;
1810 expressionS *orig_tok = tok;
1813 const struct alpha_reloc_op_tag *r;
1816 int reloc_found_p = 0;
1818 memset (tok, 0, sizeof (*tok) * ntok);
1820 /* Save and restore input_line_pointer around this function */
1821 old_input_line_pointer = input_line_pointer;
1822 input_line_pointer = str;
1825 /* ??? Wrest control of ! away from the regular expression parser. */
1826 is_end_of_line[(unsigned char) '!'] = 1;
1829 while (tok < end_tok && *input_line_pointer)
1832 switch (*input_line_pointer)
1839 /* A relocation operand can be placed after the normal operand on an
1840 assembly language statement, and has the following form:
1841 !relocation_type!sequence_number. */
1843 { /* only support one relocation op per insn */
1844 as_bad (_("More than one relocation op per insn"));
1851 ++input_line_pointer;
1853 p = input_line_pointer;
1854 c = get_symbol_end ();
1856 /* Parse !relocation_type */
1857 len = input_line_pointer - p;
1860 as_bad (_("No relocation operand"));
1864 r = &alpha_reloc_op[0];
1865 for (i = alpha_num_reloc_op - 1; i >= 0; i--, r++)
1866 if (len == r->length && memcmp (p, r->name, len) == 0)
1870 as_bad (_("Unknown relocation operand: !%s"), p);
1874 *input_line_pointer = c;
1876 if (*input_line_pointer != '!')
1880 as_bad (_("no sequence number after !%s"), p);
1884 tok->X_add_number = 0;
1890 as_bad (_("!%s does not use a sequence number"), p);
1894 input_line_pointer++;
1896 /* Parse !sequence_number */
1898 if (tok->X_op != O_constant || tok->X_add_number <= 0)
1900 as_bad (_("Bad sequence number: !%s!%s"),
1901 r->name, input_line_pointer);
1910 #endif /* RELOC_OP_P */
1913 ++input_line_pointer;
1914 if (saw_comma || !saw_arg)
1921 char *hold = input_line_pointer++;
1923 /* First try for parenthesized register ... */
1925 if (*input_line_pointer == ')' && tok->X_op == O_register)
1927 tok->X_op = (saw_comma ? O_cpregister : O_pregister);
1930 ++input_line_pointer;
1935 /* ... then fall through to plain expression */
1936 input_line_pointer = hold;
1940 if (saw_arg && !saw_comma)
1944 if (tok->X_op == O_illegal || tok->X_op == O_absent)
1957 input_line_pointer = old_input_line_pointer;
1960 debug_exp (orig_tok, ntok - (end_tok - tok));
1963 is_end_of_line[(unsigned char) '!'] = 0;
1966 return ntok - (end_tok - tok);
1970 is_end_of_line[(unsigned char) '!'] = 0;
1972 input_line_pointer = old_input_line_pointer;
1973 return TOKENIZE_ERROR;
1977 is_end_of_line[(unsigned char) '!'] = 0;
1979 input_line_pointer = old_input_line_pointer;
1980 return TOKENIZE_ERROR_REPORT;
1983 /* Search forward through all variants of an opcode looking for a
1986 static const struct alpha_opcode *
1987 find_opcode_match (first_opcode, tok, pntok, pcpumatch)
1988 const struct alpha_opcode *first_opcode;
1989 const expressionS *tok;
1993 const struct alpha_opcode *opcode = first_opcode;
1995 int got_cpu_match = 0;
1999 const unsigned char *opidx;
2002 /* Don't match opcodes that don't exist on this architecture */
2003 if (!(opcode->flags & alpha_target))
2008 for (opidx = opcode->operands; *opidx; ++opidx)
2010 const struct alpha_operand *operand = &alpha_operands[*opidx];
2012 /* only take input from real operands */
2013 if (operand->flags & AXP_OPERAND_FAKE)
2016 /* when we expect input, make sure we have it */
2019 if ((operand->flags & AXP_OPERAND_OPTIONAL_MASK) == 0)
2024 /* match operand type with expression type */
2025 switch (operand->flags & AXP_OPERAND_TYPECHECK_MASK)
2027 case AXP_OPERAND_IR:
2028 if (tok[tokidx].X_op != O_register
2029 || !is_ir_num (tok[tokidx].X_add_number))
2032 case AXP_OPERAND_FPR:
2033 if (tok[tokidx].X_op != O_register
2034 || !is_fpr_num (tok[tokidx].X_add_number))
2037 case AXP_OPERAND_IR | AXP_OPERAND_PARENS:
2038 if (tok[tokidx].X_op != O_pregister
2039 || !is_ir_num (tok[tokidx].X_add_number))
2042 case AXP_OPERAND_IR | AXP_OPERAND_PARENS | AXP_OPERAND_COMMA:
2043 if (tok[tokidx].X_op != O_cpregister
2044 || !is_ir_num (tok[tokidx].X_add_number))
2048 case AXP_OPERAND_RELATIVE:
2049 case AXP_OPERAND_SIGNED:
2050 case AXP_OPERAND_UNSIGNED:
2051 switch (tok[tokidx].X_op)
2066 /* everything else should have been fake */
2072 /* possible match -- did we use all of our input? */
2081 while (++opcode - alpha_opcodes < alpha_num_opcodes
2082 && !strcmp (opcode->name, first_opcode->name));
2085 *pcpumatch = got_cpu_match;
2090 /* Search forward through all variants of a macro looking for a syntax
2093 static const struct alpha_macro *
2094 find_macro_match (first_macro, tok, pntok)
2095 const struct alpha_macro *first_macro;
2096 const expressionS *tok;
2099 const struct alpha_macro *macro = first_macro;
2104 const enum alpha_macro_arg *arg = macro->argsets;
2118 /* index register */
2120 if (tokidx >= ntok || tok[tokidx].X_op != O_register
2121 || !is_ir_num (tok[tokidx].X_add_number))
2126 /* parenthesized index register */
2128 if (tokidx >= ntok || tok[tokidx].X_op != O_pregister
2129 || !is_ir_num (tok[tokidx].X_add_number))
2134 /* optional parenthesized index register */
2136 if (tokidx < ntok && tok[tokidx].X_op == O_pregister
2137 && is_ir_num (tok[tokidx].X_add_number))
2141 /* leading comma with a parenthesized index register */
2143 if (tokidx >= ntok || tok[tokidx].X_op != O_cpregister
2144 || !is_ir_num (tok[tokidx].X_add_number))
2149 /* floating point register */
2151 if (tokidx >= ntok || tok[tokidx].X_op != O_register
2152 || !is_fpr_num (tok[tokidx].X_add_number))
2157 /* normal expression */
2161 switch (tok[tokidx].X_op)
2170 case O_lituse_bytoff:
2185 while (*arg != MACRO_EOA)
2193 while (++macro - alpha_macros < alpha_num_macros
2194 && !strcmp (macro->name, first_macro->name));
2199 /* Insert an operand value into an instruction. */
2202 insert_operand (insn, operand, val, file, line)
2204 const struct alpha_operand *operand;
2209 if (operand->bits != 32 && !(operand->flags & AXP_OPERAND_NOOVERFLOW))
2213 if (operand->flags & AXP_OPERAND_SIGNED)
2215 max = (1 << (operand->bits - 1)) - 1;
2216 min = -(1 << (operand->bits - 1));
2220 max = (1 << operand->bits) - 1;
2224 if (val < min || val > max)
2227 _("operand out of range (%s not between %d and %d)");
2228 char buf[sizeof (val) * 3 + 2];
2230 sprint_value (buf, val);
2232 as_warn_where (file, line, err, buf, min, max);
2234 as_warn (err, buf, min, max);
2238 if (operand->insert)
2240 const char *errmsg = NULL;
2242 insn = (*operand->insert) (insn, val, &errmsg);
2247 insn |= ((val & ((1 << operand->bits) - 1)) << operand->shift);
2253 * Turn an opcode description and a set of arguments into
2254 * an instruction and a fixup.
2258 assemble_insn (opcode, tok, ntok, insn, reloc)
2259 const struct alpha_opcode *opcode;
2260 const expressionS *tok;
2262 struct alpha_insn *insn;
2263 bfd_reloc_code_real_type reloc;
2265 const struct alpha_operand *reloc_operand = NULL;
2266 const expressionS *reloc_exp = NULL;
2267 const unsigned char *argidx;
2271 memset (insn, 0, sizeof (*insn));
2272 image = opcode->opcode;
2274 for (argidx = opcode->operands; *argidx; ++argidx)
2276 const struct alpha_operand *operand = &alpha_operands[*argidx];
2277 const expressionS *t = (const expressionS *) 0;
2279 if (operand->flags & AXP_OPERAND_FAKE)
2281 /* fake operands take no value and generate no fixup */
2282 image = insert_operand (image, operand, 0, NULL, 0);
2288 switch (operand->flags & AXP_OPERAND_OPTIONAL_MASK)
2290 case AXP_OPERAND_DEFAULT_FIRST:
2293 case AXP_OPERAND_DEFAULT_SECOND:
2296 case AXP_OPERAND_DEFAULT_ZERO:
2298 static expressionS zero_exp;
2300 zero_exp.X_op = O_constant;
2301 zero_exp.X_unsigned = 1;
2316 image = insert_operand (image, operand, regno (t->X_add_number),
2321 image = insert_operand (image, operand, t->X_add_number, NULL, 0);
2322 assert (reloc_operand == NULL);
2323 reloc_operand = operand;
2328 /* This is only 0 for fields that should contain registers,
2329 which means this pattern shouldn't have matched. */
2330 if (operand->default_reloc == 0)
2333 /* There is one special case for which an insn receives two
2334 relocations, and thus the user-supplied reloc does not
2335 override the operand reloc. */
2336 if (operand->default_reloc == BFD_RELOC_ALPHA_HINT)
2338 struct alpha_fixup *fixup;
2340 if (insn->nfixups >= MAX_INSN_FIXUPS)
2341 as_fatal (_("too many fixups"));
2343 fixup = &insn->fixups[insn->nfixups++];
2345 fixup->reloc = BFD_RELOC_ALPHA_HINT;
2349 if (reloc == BFD_RELOC_UNUSED)
2350 reloc = operand->default_reloc;
2352 assert (reloc_operand == NULL);
2353 reloc_operand = operand;
2360 if (reloc != BFD_RELOC_UNUSED)
2362 struct alpha_fixup *fixup;
2364 if (insn->nfixups >= MAX_INSN_FIXUPS)
2365 as_fatal (_("too many fixups"));
2367 /* ??? My but this is hacky. But the OSF/1 assembler uses the same
2368 relocation tag for both ldah and lda with gpdisp. Choose the
2369 correct internal relocation based on the opcode. */
2370 if (reloc == BFD_RELOC_ALPHA_GPDISP)
2372 if (strcmp (opcode->name, "ldah") == 0)
2373 reloc = BFD_RELOC_ALPHA_GPDISP_HI16;
2374 else if (strcmp (opcode->name, "lda") == 0)
2375 reloc = BFD_RELOC_ALPHA_GPDISP_LO16;
2377 as_bad (_("invalid relocation for instruction"));
2380 /* If this is a real relocation (as opposed to a lituse hint), then
2381 the relocation width should match the operand width. */
2382 else if (reloc < BFD_RELOC_UNUSED)
2384 reloc_howto_type *reloc_howto
2385 = bfd_reloc_type_lookup (stdoutput, reloc);
2386 if (reloc_howto->bitsize != reloc_operand->bits)
2388 as_bad (_("invalid relocation for field"));
2393 fixup = &insn->fixups[insn->nfixups++];
2395 fixup->exp = *reloc_exp;
2397 fixup->exp.X_op = O_absent;
2398 fixup->reloc = reloc;
2405 * Actually output an instruction with its fixup.
2410 struct alpha_insn *insn;
2415 /* Take care of alignment duties. */
2416 if (alpha_auto_align_on && alpha_current_align < 2)
2417 alpha_align (2, (char *) NULL, alpha_insn_label, 0);
2418 if (alpha_current_align > 2)
2419 alpha_current_align = 2;
2420 alpha_insn_label = NULL;
2422 /* Write out the instruction. */
2424 md_number_to_chars (f, insn->insn, 4);
2427 dwarf2_emit_insn (4);
2430 /* Apply the fixups in order */
2431 for (i = 0; i < insn->nfixups; ++i)
2433 const struct alpha_operand *operand = (const struct alpha_operand *) 0;
2434 struct alpha_fixup *fixup = &insn->fixups[i];
2435 struct alpha_reloc_tag *info;
2439 /* Some fixups are only used internally and so have no howto */
2440 if ((int) fixup->reloc < 0)
2442 operand = &alpha_operands[-(int) fixup->reloc];
2444 pcrel = ((operand->flags & AXP_OPERAND_RELATIVE) != 0);
2446 else if (fixup->reloc > BFD_RELOC_UNUSED
2447 || fixup->reloc == BFD_RELOC_ALPHA_GPDISP_HI16
2448 || fixup->reloc == BFD_RELOC_ALPHA_GPDISP_LO16)
2455 reloc_howto_type *reloc_howto
2456 = bfd_reloc_type_lookup (stdoutput, fixup->reloc);
2457 assert (reloc_howto);
2459 size = bfd_get_reloc_size (reloc_howto);
2460 assert (size >= 1 && size <= 4);
2462 pcrel = reloc_howto->pc_relative;
2465 fixP = fix_new_exp (frag_now, f - frag_now->fr_literal, size,
2466 &fixup->exp, pcrel, fixup->reloc);
2468 /* Turn off complaints that the addend is too large for some fixups,
2469 and copy in the sequence number for the explicit relocations. */
2470 switch (fixup->reloc)
2472 case BFD_RELOC_ALPHA_HINT:
2473 case BFD_RELOC_GPREL32:
2474 case BFD_RELOC_GPREL16:
2475 case BFD_RELOC_ALPHA_GPREL_HI16:
2476 case BFD_RELOC_ALPHA_GPREL_LO16:
2477 fixP->fx_no_overflow = 1;
2480 case BFD_RELOC_ALPHA_GPDISP_HI16:
2481 fixP->fx_no_overflow = 1;
2482 fixP->fx_addsy = section_symbol (now_seg);
2483 fixP->fx_offset = 0;
2485 info = get_alpha_reloc_tag (insn->sequence);
2486 if (++info->n_master > 1)
2487 as_bad (_("too many ldah insns for !gpdisp!%ld"), insn->sequence);
2488 if (info->segment != now_seg)
2489 as_bad (_("both insns for !gpdisp!%ld must be in the same section"),
2491 fixP->tc_fix_data.info = info;
2494 case BFD_RELOC_ALPHA_GPDISP_LO16:
2495 fixP->fx_no_overflow = 1;
2497 info = get_alpha_reloc_tag (insn->sequence);
2498 if (++info->n_slaves > 1)
2499 as_bad (_("too many lda insns for !gpdisp!%ld"), insn->sequence);
2500 if (info->segment != now_seg)
2501 as_bad (_("both insns for !gpdisp!%ld must be in the same section"),
2503 fixP->tc_fix_data.info = info;
2504 info->slaves = fixP;
2507 case BFD_RELOC_ALPHA_LITERAL:
2508 case BFD_RELOC_ALPHA_ELF_LITERAL:
2509 fixP->fx_no_overflow = 1;
2511 info = get_alpha_reloc_tag (insn->sequence);
2513 if (info->segment != now_seg)
2514 info->multi_section_p = 1;
2515 fixP->tc_fix_data.info = info;
2518 case DUMMY_RELOC_LITUSE_ADDR:
2519 fixP->fx_offset = LITUSE_ADDR;
2521 case DUMMY_RELOC_LITUSE_BASE:
2522 fixP->fx_offset = LITUSE_BASE;
2524 case DUMMY_RELOC_LITUSE_BYTOFF:
2525 fixP->fx_offset = LITUSE_BYTOFF;
2527 case DUMMY_RELOC_LITUSE_JSR:
2528 fixP->fx_offset = LITUSE_JSR;
2530 fixP->fx_addsy = section_symbol (now_seg);
2531 fixP->fx_r_type = BFD_RELOC_ALPHA_LITUSE;
2533 info = get_alpha_reloc_tag (insn->sequence);
2535 fixP->tc_fix_data.info = info;
2536 fixP->tc_fix_data.next_reloc = info->slaves;
2537 info->slaves = fixP;
2538 if (info->segment != now_seg)
2539 info->multi_section_p = 1;
2543 if ((int) fixup->reloc < 0)
2545 if (operand->flags & AXP_OPERAND_NOOVERFLOW)
2546 fixP->fx_no_overflow = 1;
2553 /* Given an opcode name and a pre-tokenized set of arguments, assemble
2554 the insn, but do not emit it.
2556 Note that this implies no macros allowed, since we can't store more
2557 than one insn in an insn structure. */
2560 assemble_tokens_to_insn (opname, tok, ntok, insn)
2562 const expressionS *tok;
2564 struct alpha_insn *insn;
2566 const struct alpha_opcode *opcode;
2568 /* search opcodes */
2569 opcode = (const struct alpha_opcode *) hash_find (alpha_opcode_hash, opname);
2573 opcode = find_opcode_match (opcode, tok, &ntok, &cpumatch);
2576 assemble_insn (opcode, tok, ntok, insn, BFD_RELOC_UNUSED);
2580 as_bad (_("inappropriate arguments for opcode `%s'"), opname);
2582 as_bad (_("opcode `%s' not supported for target %s"), opname,
2586 as_bad (_("unknown opcode `%s'"), opname);
2589 /* Given an opcode name and a pre-tokenized set of arguments, take the
2590 opcode all the way through emission. */
2593 assemble_tokens (opname, tok, ntok, local_macros_on)
2595 const expressionS *tok;
2597 int local_macros_on;
2599 int found_something = 0;
2600 const struct alpha_opcode *opcode;
2601 const struct alpha_macro *macro;
2603 bfd_reloc_code_real_type reloc = BFD_RELOC_UNUSED;
2605 /* If a user-specified relocation is present, this is not a macro. */
2606 if (ntok && USER_RELOC_P (tok[ntok - 1].X_op))
2608 reloc = ALPHA_RELOC_TABLE (tok[ntok - 1].X_op)->reloc;
2611 else if (local_macros_on)
2613 macro = ((const struct alpha_macro *)
2614 hash_find (alpha_macro_hash, opname));
2617 found_something = 1;
2618 macro = find_macro_match (macro, tok, &ntok);
2621 (*macro->emit) (tok, ntok, macro->arg);
2627 /* search opcodes */
2628 opcode = (const struct alpha_opcode *) hash_find (alpha_opcode_hash, opname);
2631 found_something = 1;
2632 opcode = find_opcode_match (opcode, tok, &ntok, &cpumatch);
2635 struct alpha_insn insn;
2636 assemble_insn (opcode, tok, ntok, &insn, reloc);
2638 /* Copy the sequence number for the reloc from the reloc token. */
2639 if (reloc != BFD_RELOC_UNUSED)
2640 insn.sequence = tok[ntok].X_add_number;
2647 if (found_something)
2650 as_bad (_("inappropriate arguments for opcode `%s'"), opname);
2652 as_bad (_("opcode `%s' not supported for target %s"), opname,
2656 as_bad (_("unknown opcode `%s'"), opname);
2659 /* Some instruction sets indexed by lg(size) */
2660 static const char * const sextX_op[] = { "sextb", "sextw", "sextl", NULL };
2661 static const char * const insXl_op[] = { "insbl", "inswl", "insll", "insql" };
2662 static const char * const insXh_op[] = { NULL, "inswh", "inslh", "insqh" };
2663 static const char * const extXl_op[] = { "extbl", "extwl", "extll", "extql" };
2664 static const char * const extXh_op[] = { NULL, "extwh", "extlh", "extqh" };
2665 static const char * const mskXl_op[] = { "mskbl", "mskwl", "mskll", "mskql" };
2666 static const char * const mskXh_op[] = { NULL, "mskwh", "msklh", "mskqh" };
2667 static const char * const stX_op[] = { "stb", "stw", "stl", "stq" };
2668 static const char * const ldX_op[] = { "ldb", "ldw", "ldll", "ldq" };
2669 static const char * const ldXu_op[] = { "ldbu", "ldwu", NULL, NULL };
2671 /* Implement the ldgp macro. */
2674 emit_ldgp (tok, ntok, unused)
2675 const expressionS *tok;
2676 int ntok ATTRIBUTE_UNUSED;
2677 const PTR unused ATTRIBUTE_UNUSED;
2682 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
2683 /* from "ldgp r1,n(r2)", generate "ldah r1,X(R2); lda r1,Y(r1)"
2684 with appropriate constants and relocations. */
2685 struct alpha_insn insn;
2686 expressionS newtok[3];
2690 if (regno (tok[2].X_add_number) == AXP_REG_PV)
2691 ecoff_set_gp_prolog_size (0);
2695 set_tok_const (newtok[1], 0);
2698 assemble_tokens_to_insn ("ldah", newtok, 3, &insn);
2703 if (addend.X_op != O_constant)
2704 as_bad (_("can not resolve expression"));
2705 addend.X_op = O_symbol;
2706 addend.X_add_symbol = alpha_gp_symbol;
2710 insn.fixups[0].exp = addend;
2711 insn.fixups[0].reloc = BFD_RELOC_ALPHA_GPDISP_HI16;
2712 insn.sequence = next_sequence_num;
2716 set_tok_preg (newtok[2], tok[0].X_add_number);
2718 assemble_tokens_to_insn ("lda", newtok, 3, &insn);
2721 addend.X_add_number += 4;
2725 insn.fixups[0].exp = addend;
2726 insn.fixups[0].reloc = BFD_RELOC_ALPHA_GPDISP_LO16;
2727 insn.sequence = next_sequence_num--;
2730 #endif /* OBJ_ECOFF || OBJ_ELF */
2735 /* Add symbol+addend to link pool.
2736 Return offset from basesym to entry in link pool.
2738 Add new fixup only if offset isn't 16bit. */
2741 add_to_link_pool (basesym, sym, addend)
2746 segT current_section = now_seg;
2747 int current_subsec = now_subseg;
2749 bfd_reloc_code_real_type reloc_type;
2751 segment_info_type *seginfo = seg_info (alpha_link_section);
2754 offset = - *symbol_get_obj (basesym);
2756 /* @@ This assumes all entries in a given section will be of the same
2757 size... Probably correct, but unwise to rely on. */
2758 /* This must always be called with the same subsegment. */
2760 if (seginfo->frchainP)
2761 for (fixp = seginfo->frchainP->fix_root;
2762 fixp != (fixS *) NULL;
2763 fixp = fixp->fx_next, offset += 8)
2765 if (fixp->fx_addsy == sym && fixp->fx_offset == addend)
2767 if (range_signed_16 (offset))
2774 /* Not found in 16bit signed range. */
2776 subseg_set (alpha_link_section, 0);
2780 fix_new (frag_now, p - frag_now->fr_literal, 8, sym, addend, 0,
2783 subseg_set (current_section, current_subsec);
2784 seginfo->literal_pool_size += 8;
2788 #endif /* OBJ_EVAX */
2790 /* Load a (partial) expression into a target register.
2792 If poffset is not null, after the call it will either contain
2793 O_constant 0, or a 16-bit offset appropriate for any MEM format
2794 instruction. In addition, pbasereg will be modified to point to
2795 the base register to use in that MEM format instruction.
2797 In any case, *pbasereg should contain a base register to add to the
2798 expression. This will normally be either AXP_REG_ZERO or
2799 alpha_gp_register. Symbol addresses will always be loaded via $gp,
2800 so "foo($0)" is interpreted as adding the address of foo to $0;
2801 i.e. "ldq $targ, LIT($gp); addq $targ, $0, $targ". Odd, perhaps,
2802 but this is what OSF/1 does.
2804 If explicit relocations of the form !literal!<number> are allowed,
2805 and used, then explict_reloc with be an expression pointer.
2807 Finally, the return value is nonzero if the calling macro may emit
2808 a LITUSE reloc if otherwise appropriate; the return value is the
2809 sequence number to use. */
2812 load_expression (targreg, exp, pbasereg, poffset)
2814 const expressionS *exp;
2816 expressionS *poffset;
2818 long emit_lituse = 0;
2819 offsetT addend = exp->X_add_number;
2820 int basereg = *pbasereg;
2821 struct alpha_insn insn;
2822 expressionS newtok[3];
2831 /* attempt to reduce .lit load by splitting the offset from
2832 its symbol when possible, but don't create a situation in
2834 if (!range_signed_32 (addend) &&
2835 (alpha_noat_on || targreg == AXP_REG_AT))
2837 lit = add_to_literal_pool (exp->X_add_symbol, addend,
2838 alpha_lita_section, 8);
2843 lit = add_to_literal_pool (exp->X_add_symbol, 0,
2844 alpha_lita_section, 8);
2848 as_fatal (_("overflow in literal (.lita) table"));
2850 /* emit "ldq r, lit(gp)" */
2852 if (basereg != alpha_gp_register && targreg == basereg)
2855 as_bad (_("macro requires $at register while noat in effect"));
2856 if (targreg == AXP_REG_AT)
2857 as_bad (_("macro requires $at while $at in use"));
2859 set_tok_reg (newtok[0], AXP_REG_AT);
2862 set_tok_reg (newtok[0], targreg);
2863 set_tok_sym (newtok[1], alpha_lita_symbol, lit);
2864 set_tok_preg (newtok[2], alpha_gp_register);
2866 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
2868 assert (insn.nfixups == 1);
2869 insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITERAL;
2870 insn.sequence = emit_lituse = next_sequence_num--;
2871 #endif /* OBJ_ECOFF */
2873 /* emit "ldq r, gotoff(gp)" */
2875 if (basereg != alpha_gp_register && targreg == basereg)
2878 as_bad (_("macro requires $at register while noat in effect"));
2879 if (targreg == AXP_REG_AT)
2880 as_bad (_("macro requires $at while $at in use"));
2882 set_tok_reg (newtok[0], AXP_REG_AT);
2885 set_tok_reg (newtok[0], targreg);
2887 /* XXX: Disable this .got minimizing optimization so that we can get
2888 better instruction offset knowledge in the compiler. This happens
2889 very infrequently anyway. */
2891 || (!range_signed_32 (addend)
2892 && (alpha_noat_on || targreg == AXP_REG_AT)))
2899 set_tok_sym (newtok[1], exp->X_add_symbol, 0);
2902 set_tok_preg (newtok[2], alpha_gp_register);
2904 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
2906 assert (insn.nfixups == 1);
2907 insn.fixups[0].reloc = BFD_RELOC_ALPHA_ELF_LITERAL;
2908 insn.sequence = emit_lituse = next_sequence_num--;
2909 #endif /* OBJ_ELF */
2913 /* Find symbol or symbol pointer in link section. */
2915 if (exp->X_add_symbol == alpha_evax_proc.symbol)
2917 if (range_signed_16 (addend))
2919 set_tok_reg (newtok[0], targreg);
2920 set_tok_const (newtok[1], addend);
2921 set_tok_preg (newtok[2], basereg);
2922 assemble_tokens_to_insn ("lda", newtok, 3, &insn);
2927 set_tok_reg (newtok[0], targreg);
2928 set_tok_const (newtok[1], 0);
2929 set_tok_preg (newtok[2], basereg);
2930 assemble_tokens_to_insn ("lda", newtok, 3, &insn);
2935 if (!range_signed_32 (addend))
2937 link = add_to_link_pool (alpha_evax_proc.symbol,
2938 exp->X_add_symbol, addend);
2943 link = add_to_link_pool (alpha_evax_proc.symbol,
2944 exp->X_add_symbol, 0);
2946 set_tok_reg (newtok[0], targreg);
2947 set_tok_const (newtok[1], link);
2948 set_tok_preg (newtok[2], basereg);
2949 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
2951 #endif /* OBJ_EVAX */
2956 if (basereg != alpha_gp_register && basereg != AXP_REG_ZERO)
2958 /* emit "addq r, base, r" */
2960 set_tok_reg (newtok[1], basereg);
2961 set_tok_reg (newtok[2], targreg);
2962 assemble_tokens ("addq", newtok, 3, 0);
2974 /* Assume that this difference expression will be resolved to an
2975 absolute value and that that value will fit in 16 bits. */
2977 set_tok_reg (newtok[0], targreg);
2979 set_tok_preg (newtok[2], basereg);
2980 assemble_tokens ("lda", newtok, 3, 0);
2983 set_tok_const (*poffset, 0);
2987 if (exp->X_add_number > 0)
2988 as_bad (_("bignum invalid; zero assumed"));
2990 as_bad (_("floating point number invalid; zero assumed"));
2995 as_bad (_("can't handle expression"));
3000 if (!range_signed_32 (addend))
3003 long seq_num = next_sequence_num--;
3005 /* For 64-bit addends, just put it in the literal pool. */
3008 /* emit "ldq targreg, lit(basereg)" */
3009 lit = add_to_link_pool (alpha_evax_proc.symbol,
3010 section_symbol (absolute_section), addend);
3011 set_tok_reg (newtok[0], targreg);
3012 set_tok_const (newtok[1], lit);
3013 set_tok_preg (newtok[2], alpha_gp_register);
3014 assemble_tokens ("ldq", newtok, 3, 0);
3017 if (alpha_lit8_section == NULL)
3019 create_literal_section (".lit8",
3020 &alpha_lit8_section,
3021 &alpha_lit8_symbol);
3024 alpha_lit8_literal = add_to_literal_pool (alpha_lit8_symbol, 0x8000,
3025 alpha_lita_section, 8);
3026 if (alpha_lit8_literal >= 0x8000)
3027 as_fatal (_("overflow in literal (.lita) table"));
3031 lit = add_to_literal_pool (NULL, addend, alpha_lit8_section, 8) - 0x8000;
3033 as_fatal (_("overflow in literal (.lit8) table"));
3035 /* emit "lda litreg, .lit8+0x8000" */
3037 if (targreg == basereg)
3040 as_bad (_("macro requires $at register while noat in effect"));
3041 if (targreg == AXP_REG_AT)
3042 as_bad (_("macro requires $at while $at in use"));
3044 set_tok_reg (newtok[0], AXP_REG_AT);
3047 set_tok_reg (newtok[0], targreg);
3049 set_tok_sym (newtok[1], alpha_lita_symbol, alpha_lit8_literal);
3052 set_tok_sym (newtok[1], alpha_lit8_symbol, 0x8000);
3054 set_tok_preg (newtok[2], alpha_gp_register);
3056 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
3058 assert (insn.nfixups == 1);
3060 insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITERAL;
3063 insn.fixups[0].reloc = BFD_RELOC_ALPHA_ELF_LITERAL;
3065 insn.sequence = seq_num;
3069 /* emit "ldq litreg, lit(litreg)" */
3071 set_tok_const (newtok[1], lit);
3072 set_tok_preg (newtok[2], newtok[0].X_add_number);
3074 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
3076 assert (insn.nfixups < MAX_INSN_FIXUPS);
3077 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
3078 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3080 insn.sequence = seq_num;
3085 /* emit "addq litreg, base, target" */
3087 if (basereg != AXP_REG_ZERO)
3089 set_tok_reg (newtok[1], basereg);
3090 set_tok_reg (newtok[2], targreg);
3091 assemble_tokens ("addq", newtok, 3, 0);
3093 #endif /* !OBJ_EVAX */
3096 set_tok_const (*poffset, 0);
3097 *pbasereg = targreg;
3101 offsetT low, high, extra, tmp;
3103 /* for 32-bit operands, break up the addend */
3105 low = sign_extend_16 (addend);
3107 high = sign_extend_16 (tmp >> 16);
3109 if (tmp - (high << 16))
3113 high = sign_extend_16 (tmp >> 16);
3118 set_tok_reg (newtok[0], targreg);
3119 set_tok_preg (newtok[2], basereg);
3123 /* emit "ldah r, extra(r) */
3124 set_tok_const (newtok[1], extra);
3125 assemble_tokens ("ldah", newtok, 3, 0);
3126 set_tok_preg (newtok[2], basereg = targreg);
3131 /* emit "ldah r, high(r) */
3132 set_tok_const (newtok[1], high);
3133 assemble_tokens ("ldah", newtok, 3, 0);
3135 set_tok_preg (newtok[2], basereg);
3138 if ((low && !poffset) || (!poffset && basereg != targreg))
3140 /* emit "lda r, low(base)" */
3141 set_tok_const (newtok[1], low);
3142 assemble_tokens ("lda", newtok, 3, 0);
3148 set_tok_const (*poffset, low);
3149 *pbasereg = basereg;
3155 /* The lda macro differs from the lda instruction in that it handles
3156 most simple expressions, particualrly symbol address loads and
3160 emit_lda (tok, ntok, unused)
3161 const expressionS *tok;
3163 const PTR unused ATTRIBUTE_UNUSED;
3168 basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
3170 basereg = tok[2].X_add_number;
3172 (void) load_expression (tok[0].X_add_number, &tok[1], &basereg, NULL);
3175 /* The ldah macro differs from the ldah instruction in that it has $31
3176 as an implied base register. */
3179 emit_ldah (tok, ntok, unused)
3180 const expressionS *tok;
3181 int ntok ATTRIBUTE_UNUSED;
3182 const PTR unused ATTRIBUTE_UNUSED;
3184 expressionS newtok[3];
3188 set_tok_preg (newtok[2], AXP_REG_ZERO);
3190 assemble_tokens ("ldah", newtok, 3, 0);
3193 /* Handle all "simple" integer register loads -- ldq, ldq_l, ldq_u,
3194 etc. They differ from the real instructions in that they do simple
3195 expressions like the lda macro. */
3198 emit_ir_load (tok, ntok, opname)
3199 const expressionS *tok;
3205 expressionS newtok[3];
3206 struct alpha_insn insn;
3209 basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
3211 basereg = tok[2].X_add_number;
3213 lituse = load_expression (tok[0].X_add_number, &tok[1], &basereg,
3217 set_tok_preg (newtok[2], basereg);
3219 assemble_tokens_to_insn ((const char *) opname, newtok, 3, &insn);
3223 assert (insn.nfixups < MAX_INSN_FIXUPS);
3224 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
3225 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3227 insn.sequence = lituse;
3233 /* Handle fp register loads, and both integer and fp register stores.
3234 Again, we handle simple expressions. */
3237 emit_loadstore (tok, ntok, opname)
3238 const expressionS *tok;
3244 expressionS newtok[3];
3245 struct alpha_insn insn;
3248 basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
3250 basereg = tok[2].X_add_number;
3252 if (tok[1].X_op != O_constant || !range_signed_16 (tok[1].X_add_number))
3255 as_bad (_("macro requires $at register while noat in effect"));
3257 lituse = load_expression (AXP_REG_AT, &tok[1], &basereg, &newtok[1]);
3266 set_tok_preg (newtok[2], basereg);
3268 assemble_tokens_to_insn ((const char *) opname, newtok, 3, &insn);
3272 assert (insn.nfixups < MAX_INSN_FIXUPS);
3273 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
3274 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3276 insn.sequence = lituse;
3282 /* Load a half-word or byte as an unsigned value. */
3285 emit_ldXu (tok, ntok, vlgsize)
3286 const expressionS *tok;
3290 if (alpha_target & AXP_OPCODE_BWX)
3291 emit_ir_load (tok, ntok, ldXu_op[(long) vlgsize]);
3294 expressionS newtok[3];
3295 struct alpha_insn insn;
3300 as_bad (_("macro requires $at register while noat in effect"));
3303 basereg = (tok[1].X_op == O_constant
3304 ? AXP_REG_ZERO : alpha_gp_register);
3306 basereg = tok[2].X_add_number;
3308 /* emit "lda $at, exp" */
3310 lituse = load_expression (AXP_REG_AT, &tok[1], &basereg, NULL);
3312 /* emit "ldq_u targ, 0($at)" */
3315 set_tok_const (newtok[1], 0);
3316 set_tok_preg (newtok[2], basereg);
3317 assemble_tokens_to_insn ("ldq_u", newtok, 3, &insn);
3321 assert (insn.nfixups < MAX_INSN_FIXUPS);
3322 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
3323 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3325 insn.sequence = lituse;
3330 /* emit "extXl targ, $at, targ" */
3332 set_tok_reg (newtok[1], basereg);
3333 newtok[2] = newtok[0];
3334 assemble_tokens_to_insn (extXl_op[(long) vlgsize], newtok, 3, &insn);
3338 assert (insn.nfixups < MAX_INSN_FIXUPS);
3339 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF;
3340 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3342 insn.sequence = lituse;
3349 /* Load a half-word or byte as a signed value. */
3352 emit_ldX (tok, ntok, vlgsize)
3353 const expressionS *tok;
3357 emit_ldXu (tok, ntok, vlgsize);
3358 assemble_tokens (sextX_op[(long) vlgsize], tok, 1, 1);
3361 /* Load an integral value from an unaligned address as an unsigned
3365 emit_uldXu (tok, ntok, vlgsize)
3366 const expressionS *tok;
3370 long lgsize = (long) vlgsize;
3371 expressionS newtok[3];
3374 as_bad (_("macro requires $at register while noat in effect"));
3376 /* emit "lda $at, exp" */
3378 memcpy (newtok, tok, sizeof (expressionS) * ntok);
3379 newtok[0].X_add_number = AXP_REG_AT;
3380 assemble_tokens ("lda", newtok, ntok, 1);
3382 /* emit "ldq_u $t9, 0($at)" */
3384 set_tok_reg (newtok[0], AXP_REG_T9);
3385 set_tok_const (newtok[1], 0);
3386 set_tok_preg (newtok[2], AXP_REG_AT);
3387 assemble_tokens ("ldq_u", newtok, 3, 1);
3389 /* emit "ldq_u $t10, size-1($at)" */
3391 set_tok_reg (newtok[0], AXP_REG_T10);
3392 set_tok_const (newtok[1], (1 << lgsize) - 1);
3393 assemble_tokens ("ldq_u", newtok, 3, 1);
3395 /* emit "extXl $t9, $at, $t9" */
3397 set_tok_reg (newtok[0], AXP_REG_T9);
3398 set_tok_reg (newtok[1], AXP_REG_AT);
3399 set_tok_reg (newtok[2], AXP_REG_T9);
3400 assemble_tokens (extXl_op[lgsize], newtok, 3, 1);
3402 /* emit "extXh $t10, $at, $t10" */
3404 set_tok_reg (newtok[0], AXP_REG_T10);
3405 set_tok_reg (newtok[2], AXP_REG_T10);
3406 assemble_tokens (extXh_op[lgsize], newtok, 3, 1);
3408 /* emit "or $t9, $t10, targ" */
3410 set_tok_reg (newtok[0], AXP_REG_T9);
3411 set_tok_reg (newtok[1], AXP_REG_T10);
3413 assemble_tokens ("or", newtok, 3, 1);
3416 /* Load an integral value from an unaligned address as a signed value.
3417 Note that quads should get funneled to the unsigned load since we
3418 don't have to do the sign extension. */
3421 emit_uldX (tok, ntok, vlgsize)
3422 const expressionS *tok;
3426 emit_uldXu (tok, ntok, vlgsize);
3427 assemble_tokens (sextX_op[(long) vlgsize], tok, 1, 1);
3430 /* Implement the ldil macro. */
3433 emit_ldil (tok, ntok, unused)
3434 const expressionS *tok;
3436 const PTR unused ATTRIBUTE_UNUSED;
3438 expressionS newtok[2];
3440 memcpy (newtok, tok, sizeof (newtok));
3441 newtok[1].X_add_number = sign_extend_32 (tok[1].X_add_number);
3443 assemble_tokens ("lda", newtok, ntok, 1);
3446 /* Store a half-word or byte. */
3449 emit_stX (tok, ntok, vlgsize)
3450 const expressionS *tok;
3454 int lgsize = (int) (long) vlgsize;
3456 if (alpha_target & AXP_OPCODE_BWX)
3457 emit_loadstore (tok, ntok, stX_op[lgsize]);
3460 expressionS newtok[3];
3461 struct alpha_insn insn;
3466 as_bad (_("macro requires $at register while noat in effect"));
3469 basereg = (tok[1].X_op == O_constant
3470 ? AXP_REG_ZERO : alpha_gp_register);
3472 basereg = tok[2].X_add_number;
3474 /* emit "lda $at, exp" */
3476 lituse = load_expression (AXP_REG_AT, &tok[1], &basereg, NULL);
3478 /* emit "ldq_u $t9, 0($at)" */
3480 set_tok_reg (newtok[0], AXP_REG_T9);
3481 set_tok_const (newtok[1], 0);
3482 set_tok_preg (newtok[2], basereg);
3483 assemble_tokens_to_insn ("ldq_u", newtok, 3, &insn);
3487 assert (insn.nfixups < MAX_INSN_FIXUPS);
3488 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
3489 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3491 insn.sequence = lituse;
3496 /* emit "insXl src, $at, $t10" */
3499 set_tok_reg (newtok[1], basereg);
3500 set_tok_reg (newtok[2], AXP_REG_T10);
3501 assemble_tokens_to_insn (insXl_op[lgsize], newtok, 3, &insn);
3505 assert (insn.nfixups < MAX_INSN_FIXUPS);
3506 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF;
3507 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3509 insn.sequence = lituse;
3514 /* emit "mskXl $t9, $at, $t9" */
3516 set_tok_reg (newtok[0], AXP_REG_T9);
3517 newtok[2] = newtok[0];
3518 assemble_tokens_to_insn (mskXl_op[lgsize], newtok, 3, &insn);
3522 assert (insn.nfixups < MAX_INSN_FIXUPS);
3523 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF;
3524 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3526 insn.sequence = lituse;
3531 /* emit "or $t9, $t10, $t9" */
3533 set_tok_reg (newtok[1], AXP_REG_T10);
3534 assemble_tokens ("or", newtok, 3, 1);
3536 /* emit "stq_u $t9, 0($at) */
3538 set_tok_const(newtok[1], 0);
3539 set_tok_preg (newtok[2], AXP_REG_AT);
3540 assemble_tokens_to_insn ("stq_u", newtok, 3, &insn);
3544 assert (insn.nfixups < MAX_INSN_FIXUPS);
3545 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
3546 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3548 insn.sequence = lituse;
3555 /* Store an integer to an unaligned address. */
3558 emit_ustX (tok, ntok, vlgsize)
3559 const expressionS *tok;
3563 int lgsize = (int) (long) vlgsize;
3564 expressionS newtok[3];
3566 /* emit "lda $at, exp" */
3568 memcpy (newtok, tok, sizeof (expressionS) * ntok);
3569 newtok[0].X_add_number = AXP_REG_AT;
3570 assemble_tokens ("lda", newtok, ntok, 1);
3572 /* emit "ldq_u $9, 0($at)" */
3574 set_tok_reg (newtok[0], AXP_REG_T9);
3575 set_tok_const (newtok[1], 0);
3576 set_tok_preg (newtok[2], AXP_REG_AT);
3577 assemble_tokens ("ldq_u", newtok, 3, 1);
3579 /* emit "ldq_u $10, size-1($at)" */
3581 set_tok_reg (newtok[0], AXP_REG_T10);
3582 set_tok_const (newtok[1], (1 << lgsize) - 1);
3583 assemble_tokens ("ldq_u", newtok, 3, 1);
3585 /* emit "insXl src, $at, $t11" */
3588 set_tok_reg (newtok[1], AXP_REG_AT);
3589 set_tok_reg (newtok[2], AXP_REG_T11);
3590 assemble_tokens (insXl_op[lgsize], newtok, 3, 1);
3592 /* emit "insXh src, $at, $t12" */
3594 set_tok_reg (newtok[2], AXP_REG_T12);
3595 assemble_tokens (insXh_op[lgsize], newtok, 3, 1);
3597 /* emit "mskXl $t9, $at, $t9" */
3599 set_tok_reg (newtok[0], AXP_REG_T9);
3600 newtok[2] = newtok[0];
3601 assemble_tokens (mskXl_op[lgsize], newtok, 3, 1);
3603 /* emit "mskXh $t10, $at, $t10" */
3605 set_tok_reg (newtok[0], AXP_REG_T10);
3606 newtok[2] = newtok[0];
3607 assemble_tokens (mskXh_op[lgsize], newtok, 3, 1);
3609 /* emit "or $t9, $t11, $t9" */
3611 set_tok_reg (newtok[0], AXP_REG_T9);
3612 set_tok_reg (newtok[1], AXP_REG_T11);
3613 newtok[2] = newtok[0];
3614 assemble_tokens ("or", newtok, 3, 1);
3616 /* emit "or $t10, $t12, $t10" */
3618 set_tok_reg (newtok[0], AXP_REG_T10);
3619 set_tok_reg (newtok[1], AXP_REG_T12);
3620 newtok[2] = newtok[0];
3621 assemble_tokens ("or", newtok, 3, 1);
3623 /* emit "stq_u $t9, 0($at)" */
3625 set_tok_reg (newtok[0], AXP_REG_T9);
3626 set_tok_const (newtok[1], 0);
3627 set_tok_preg (newtok[2], AXP_REG_AT);
3628 assemble_tokens ("stq_u", newtok, 3, 1);
3630 /* emit "stq_u $t10, size-1($at)" */
3632 set_tok_reg (newtok[0], AXP_REG_T10);
3633 set_tok_const (newtok[1], (1 << lgsize) - 1);
3634 assemble_tokens ("stq_u", newtok, 3, 1);
3637 /* Sign extend a half-word or byte. The 32-bit sign extend is
3638 implemented as "addl $31, $r, $t" in the opcode table. */
3641 emit_sextX (tok, ntok, vlgsize)
3642 const expressionS *tok;
3646 long lgsize = (long) vlgsize;
3648 if (alpha_target & AXP_OPCODE_BWX)
3649 assemble_tokens (sextX_op[lgsize], tok, ntok, 0);
3652 int bitshift = 64 - 8 * (1 << lgsize);
3653 expressionS newtok[3];
3655 /* emit "sll src,bits,dst" */
3658 set_tok_const (newtok[1], bitshift);
3659 newtok[2] = tok[ntok - 1];
3660 assemble_tokens ("sll", newtok, 3, 1);
3662 /* emit "sra dst,bits,dst" */
3664 newtok[0] = newtok[2];
3665 assemble_tokens ("sra", newtok, 3, 1);
3669 /* Implement the division and modulus macros. */
3673 /* Make register usage like in normal procedure call.
3674 Don't clobber PV and RA. */
3677 emit_division (tok, ntok, symname)
3678 const expressionS *tok;
3682 /* DIVISION and MODULUS. Yech.
3687 * mov x,R16 # if x != R16
3688 * mov y,R17 # if y != R17
3693 * with appropriate optimizations if R0,R16,R17 are the registers
3694 * specified by the compiler.
3699 expressionS newtok[3];
3701 xr = regno (tok[0].X_add_number);
3702 yr = regno (tok[1].X_add_number);
3707 rr = regno (tok[2].X_add_number);
3709 /* Move the operands into the right place */
3710 if (yr == AXP_REG_R16 && xr == AXP_REG_R17)
3712 /* They are in exactly the wrong order -- swap through AT */
3715 as_bad (_("macro requires $at register while noat in effect"));
3717 set_tok_reg (newtok[0], AXP_REG_R16);
3718 set_tok_reg (newtok[1], AXP_REG_AT);
3719 assemble_tokens ("mov", newtok, 2, 1);
3721 set_tok_reg (newtok[0], AXP_REG_R17);
3722 set_tok_reg (newtok[1], AXP_REG_R16);
3723 assemble_tokens ("mov", newtok, 2, 1);
3725 set_tok_reg (newtok[0], AXP_REG_AT);
3726 set_tok_reg (newtok[1], AXP_REG_R17);
3727 assemble_tokens ("mov", newtok, 2, 1);
3731 if (yr == AXP_REG_R16)
3733 set_tok_reg (newtok[0], AXP_REG_R16);
3734 set_tok_reg (newtok[1], AXP_REG_R17);
3735 assemble_tokens ("mov", newtok, 2, 1);
3738 if (xr != AXP_REG_R16)
3740 set_tok_reg (newtok[0], xr);
3741 set_tok_reg (newtok[1], AXP_REG_R16);
3742 assemble_tokens ("mov", newtok, 2, 1);
3745 if (yr != AXP_REG_R16 && yr != AXP_REG_R17)
3747 set_tok_reg (newtok[0], yr);
3748 set_tok_reg (newtok[1], AXP_REG_R17);
3749 assemble_tokens ("mov", newtok, 2, 1);
3753 sym = symbol_find_or_make ((const char *) symname);
3755 set_tok_reg (newtok[0], AXP_REG_AT);
3756 set_tok_sym (newtok[1], sym, 0);
3757 assemble_tokens ("lda", newtok, 2, 1);
3759 /* Call the division routine */
3760 set_tok_reg (newtok[0], AXP_REG_AT);
3761 set_tok_cpreg (newtok[1], AXP_REG_AT);
3762 set_tok_const (newtok[2], 0);
3763 assemble_tokens ("jsr", newtok, 3, 1);
3765 /* Move the result to the right place */
3766 if (rr != AXP_REG_R0)
3768 set_tok_reg (newtok[0], AXP_REG_R0);
3769 set_tok_reg (newtok[1], rr);
3770 assemble_tokens ("mov", newtok, 2, 1);
3774 #else /* !OBJ_EVAX */
3777 emit_division (tok, ntok, symname)
3778 const expressionS *tok;
3782 /* DIVISION and MODULUS. Yech.
3792 * with appropriate optimizations if t10,t11,t12 are the registers
3793 * specified by the compiler.
3798 expressionS newtok[3];
3800 xr = regno (tok[0].X_add_number);
3801 yr = regno (tok[1].X_add_number);
3806 rr = regno (tok[2].X_add_number);
3808 sym = symbol_find_or_make ((const char *) symname);
3810 /* Move the operands into the right place */
3811 if (yr == AXP_REG_T10 && xr == AXP_REG_T11)
3813 /* They are in exactly the wrong order -- swap through AT */
3816 as_bad (_("macro requires $at register while noat in effect"));
3818 set_tok_reg (newtok[0], AXP_REG_T10);
3819 set_tok_reg (newtok[1], AXP_REG_AT);
3820 assemble_tokens ("mov", newtok, 2, 1);
3822 set_tok_reg (newtok[0], AXP_REG_T11);
3823 set_tok_reg (newtok[1], AXP_REG_T10);
3824 assemble_tokens ("mov", newtok, 2, 1);
3826 set_tok_reg (newtok[0], AXP_REG_AT);
3827 set_tok_reg (newtok[1], AXP_REG_T11);
3828 assemble_tokens ("mov", newtok, 2, 1);
3832 if (yr == AXP_REG_T10)
3834 set_tok_reg (newtok[0], AXP_REG_T10);
3835 set_tok_reg (newtok[1], AXP_REG_T11);
3836 assemble_tokens ("mov", newtok, 2, 1);
3839 if (xr != AXP_REG_T10)
3841 set_tok_reg (newtok[0], xr);
3842 set_tok_reg (newtok[1], AXP_REG_T10);
3843 assemble_tokens ("mov", newtok, 2, 1);
3846 if (yr != AXP_REG_T10 && yr != AXP_REG_T11)
3848 set_tok_reg (newtok[0], yr);
3849 set_tok_reg (newtok[1], AXP_REG_T11);
3850 assemble_tokens ("mov", newtok, 2, 1);
3854 /* Call the division routine */
3855 set_tok_reg (newtok[0], AXP_REG_T9);
3856 set_tok_sym (newtok[1], sym, 0);
3857 assemble_tokens ("jsr", newtok, 2, 1);
3859 /* Reload the GP register */
3863 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
3864 set_tok_reg (newtok[0], alpha_gp_register);
3865 set_tok_const (newtok[1], 0);
3866 set_tok_preg (newtok[2], AXP_REG_T9);
3867 assemble_tokens ("ldgp", newtok, 3, 1);
3870 /* Move the result to the right place */
3871 if (rr != AXP_REG_T12)
3873 set_tok_reg (newtok[0], AXP_REG_T12);
3874 set_tok_reg (newtok[1], rr);
3875 assemble_tokens ("mov", newtok, 2, 1);
3879 #endif /* !OBJ_EVAX */
3881 /* The jsr and jmp macros differ from their instruction counterparts
3882 in that they can load the target address and default most
3886 emit_jsrjmp (tok, ntok, vopname)
3887 const expressionS *tok;
3891 const char *opname = (const char *) vopname;
3892 struct alpha_insn insn;
3893 expressionS newtok[3];
3897 if (tokidx < ntok && tok[tokidx].X_op == O_register)
3898 r = regno (tok[tokidx++].X_add_number);
3900 r = strcmp (opname, "jmp") == 0 ? AXP_REG_ZERO : AXP_REG_RA;
3902 set_tok_reg (newtok[0], r);
3904 if (tokidx < ntok &&
3905 (tok[tokidx].X_op == O_pregister || tok[tokidx].X_op == O_cpregister))
3906 r = regno (tok[tokidx++].X_add_number);
3908 /* keep register if jsr $n.<sym> */
3912 int basereg = alpha_gp_register;
3913 lituse = load_expression (r = AXP_REG_PV, &tok[tokidx], &basereg, NULL);
3917 set_tok_cpreg (newtok[1], r);
3920 /* FIXME: Add hint relocs to BFD for evax. */
3923 newtok[2] = tok[tokidx];
3926 set_tok_const (newtok[2], 0);
3928 assemble_tokens_to_insn (opname, newtok, 3, &insn);
3932 assert (insn.nfixups < MAX_INSN_FIXUPS);
3933 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_JSR;
3934 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3936 insn.sequence = lituse;
3942 /* The ret and jcr instructions differ from their instruction
3943 counterparts in that everything can be defaulted. */
3946 emit_retjcr (tok, ntok, vopname)
3947 const expressionS *tok;
3951 const char *opname = (const char *) vopname;
3952 expressionS newtok[3];
3955 if (tokidx < ntok && tok[tokidx].X_op == O_register)
3956 r = regno (tok[tokidx++].X_add_number);
3960 set_tok_reg (newtok[0], r);
3962 if (tokidx < ntok &&
3963 (tok[tokidx].X_op == O_pregister || tok[tokidx].X_op == O_cpregister))
3964 r = regno (tok[tokidx++].X_add_number);
3968 set_tok_cpreg (newtok[1], r);
3971 newtok[2] = tok[tokidx];
3973 set_tok_const (newtok[2], strcmp (opname, "ret") == 0);
3975 assemble_tokens (opname, newtok, 3, 0);
3978 /* Assembler directives */
3980 /* Handle the .text pseudo-op. This is like the usual one, but it
3981 clears alpha_insn_label and restores auto alignment. */
3989 alpha_insn_label = NULL;
3990 alpha_auto_align_on = 1;
3991 alpha_current_align = 0;
3994 /* Handle the .data pseudo-op. This is like the usual one, but it
3995 clears alpha_insn_label and restores auto alignment. */
4002 alpha_insn_label = NULL;
4003 alpha_auto_align_on = 1;
4004 alpha_current_align = 0;
4007 #if defined (OBJ_ECOFF) || defined (OBJ_EVAX)
4009 /* Handle the OSF/1 and openVMS .comm pseudo quirks.
4010 openVMS constructs a section for every common symbol. */
4013 s_alpha_comm (ignore)
4016 register char *name;
4020 register symbolS *symbolP;
4023 segT current_section = now_seg;
4024 int current_subsec = now_subseg;
4028 name = input_line_pointer;
4029 c = get_symbol_end ();
4031 /* just after name is now '\0' */
4032 p = input_line_pointer;
4037 /* Alpha OSF/1 compiler doesn't provide the comma, gcc does. */
4038 if (*input_line_pointer == ',')
4040 input_line_pointer++;
4043 if ((temp = get_absolute_expression ()) < 0)
4045 as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) temp);
4046 ignore_rest_of_line ();
4051 symbolP = symbol_find_or_make (name);
4054 /* Make a section for the common symbol. */
4055 new_seg = subseg_new (xstrdup (name), 0);
4061 /* alignment might follow */
4062 if (*input_line_pointer == ',')
4066 input_line_pointer++;
4067 align = get_absolute_expression ();
4068 bfd_set_section_alignment (stdoutput, new_seg, align);
4072 if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
4074 as_bad (_("Ignoring attempt to re-define symbol"));
4075 ignore_rest_of_line ();
4080 if (bfd_section_size (stdoutput, new_seg) > 0)
4082 if (bfd_section_size (stdoutput, new_seg) != temp)
4083 as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
4084 S_GET_NAME (symbolP),
4085 (long) bfd_section_size (stdoutput, new_seg),
4089 if (S_GET_VALUE (symbolP))
4091 if (S_GET_VALUE (symbolP) != (valueT) temp)
4092 as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
4093 S_GET_NAME (symbolP),
4094 (long) S_GET_VALUE (symbolP),
4101 subseg_set (new_seg, 0);
4102 p = frag_more (temp);
4103 new_seg->flags |= SEC_IS_COMMON;
4104 if (! S_IS_DEFINED (symbolP))
4105 S_SET_SEGMENT (symbolP, new_seg);
4107 S_SET_VALUE (symbolP, (valueT) temp);
4109 S_SET_EXTERNAL (symbolP);
4113 subseg_set (current_section, current_subsec);
4116 know (symbol_get_frag (symbolP) == &zero_address_frag);
4118 demand_empty_rest_of_line ();
4121 #endif /* ! OBJ_ELF */
4125 /* Handle the .rdata pseudo-op. This is like the usual one, but it
4126 clears alpha_insn_label and restores auto alignment. */
4129 s_alpha_rdata (ignore)
4134 temp = get_absolute_expression ();
4135 subseg_new (".rdata", 0);
4136 demand_empty_rest_of_line ();
4137 alpha_insn_label = NULL;
4138 alpha_auto_align_on = 1;
4139 alpha_current_align = 0;
4146 /* Handle the .sdata pseudo-op. This is like the usual one, but it
4147 clears alpha_insn_label and restores auto alignment. */
4150 s_alpha_sdata (ignore)
4155 temp = get_absolute_expression ();
4156 subseg_new (".sdata", 0);
4157 demand_empty_rest_of_line ();
4158 alpha_insn_label = NULL;
4159 alpha_auto_align_on = 1;
4160 alpha_current_align = 0;
4166 /* Handle the .section pseudo-op. This is like the usual one, but it
4167 clears alpha_insn_label and restores auto alignment. */
4170 s_alpha_section (ignore)
4173 obj_elf_section (ignore);
4175 alpha_insn_label = NULL;
4176 alpha_auto_align_on = 1;
4177 alpha_current_align = 0;
4182 int dummy ATTRIBUTE_UNUSED;
4184 if (ECOFF_DEBUGGING)
4185 ecoff_directive_ent (0);
4188 char *name, name_end;
4189 name = input_line_pointer;
4190 name_end = get_symbol_end ();
4192 if (! is_name_beginner (*name))
4194 as_warn (_(".ent directive has no name"));
4195 *input_line_pointer = name_end;
4201 if (alpha_cur_ent_sym)
4202 as_warn (_("nested .ent directives"));
4204 sym = symbol_find_or_make (name);
4205 symbol_get_bfdsym (sym)->flags |= BSF_FUNCTION;
4206 alpha_cur_ent_sym = sym;
4208 /* The .ent directive is sometimes followed by a number. Not sure
4209 what it really means, but ignore it. */
4210 *input_line_pointer = name_end;
4212 if (*input_line_pointer == ',')
4214 input_line_pointer++;
4217 if (isdigit (*input_line_pointer) || *input_line_pointer == '-')
4218 (void) get_absolute_expression ();
4220 demand_empty_rest_of_line ();
4226 int dummy ATTRIBUTE_UNUSED;
4228 if (ECOFF_DEBUGGING)
4229 ecoff_directive_end (0);
4232 char *name, name_end;
4233 name = input_line_pointer;
4234 name_end = get_symbol_end ();
4236 if (! is_name_beginner (*name))
4238 as_warn (_(".end directive has no name"));
4239 *input_line_pointer = name_end;
4245 sym = symbol_find (name);
4246 if (sym != alpha_cur_ent_sym)
4247 as_warn (_(".end directive names different symbol than .ent"));
4249 /* Create an expression to calculate the size of the function. */
4252 symbol_get_obj (sym)->size =
4253 (expressionS *) xmalloc (sizeof (expressionS));
4254 symbol_get_obj (sym)->size->X_op = O_subtract;
4255 symbol_get_obj (sym)->size->X_add_symbol
4256 = symbol_new ("L0\001", now_seg, frag_now_fix (), frag_now);
4257 symbol_get_obj (sym)->size->X_op_symbol = sym;
4258 symbol_get_obj (sym)->size->X_add_number = 0;
4261 alpha_cur_ent_sym = NULL;
4263 *input_line_pointer = name_end;
4265 demand_empty_rest_of_line ();
4273 if (ECOFF_DEBUGGING)
4276 ecoff_directive_fmask (0);
4278 ecoff_directive_mask (0);
4281 discard_rest_of_line ();
4285 s_alpha_frame (dummy)
4286 int dummy ATTRIBUTE_UNUSED;
4288 if (ECOFF_DEBUGGING)
4289 ecoff_directive_frame (0);
4291 discard_rest_of_line ();
4295 s_alpha_prologue (ignore)
4296 int ignore ATTRIBUTE_UNUSED;
4301 arg = get_absolute_expression ();
4302 demand_empty_rest_of_line ();
4304 if (ECOFF_DEBUGGING)
4305 sym = ecoff_get_cur_proc_sym ();
4307 sym = alpha_cur_ent_sym;
4312 case 0: /* No PV required. */
4313 S_SET_OTHER (sym, STO_ALPHA_NOPV
4314 | (S_GET_OTHER (sym) & ~STO_ALPHA_STD_GPLOAD));
4316 case 1: /* Std GP load. */
4317 S_SET_OTHER (sym, STO_ALPHA_STD_GPLOAD
4318 | (S_GET_OTHER (sym) & ~STO_ALPHA_STD_GPLOAD));
4320 case 2: /* Non-std use of PV. */
4324 as_bad (_("Invalid argument %d to .prologue."), arg);
4329 static char *first_file_directive;
4332 s_alpha_file (ignore)
4333 int ignore ATTRIBUTE_UNUSED;
4335 /* Save the first .file directive we see, so that we can change our
4336 minds about whether ecoff debugging should or shouldn't be enabled. */
4337 if (alpha_flag_mdebug < 0 && ! first_file_directive)
4339 char *start = input_line_pointer;
4342 discard_rest_of_line ();
4344 len = input_line_pointer - start;
4345 first_file_directive = xmalloc (len + 1);
4346 memcpy (first_file_directive, start, len);
4347 first_file_directive[len] = '\0';
4349 input_line_pointer = start;
4352 if (ECOFF_DEBUGGING)
4353 ecoff_directive_file (0);
4355 dwarf2_directive_file (0);
4359 s_alpha_loc (ignore)
4360 int ignore ATTRIBUTE_UNUSED;
4362 if (ECOFF_DEBUGGING)
4363 ecoff_directive_loc (0);
4365 dwarf2_directive_loc (0);
4372 /* If we've been undecided about mdebug, make up our minds in favour. */
4373 if (alpha_flag_mdebug < 0)
4375 segT sec = subseg_new (".mdebug", 0);
4376 bfd_set_section_flags (stdoutput, sec, SEC_HAS_CONTENTS | SEC_READONLY);
4377 bfd_set_section_alignment (stdoutput, sec, 3);
4379 ecoff_read_begin_hook ();
4381 if (first_file_directive)
4383 char *save_ilp = input_line_pointer;
4384 input_line_pointer = first_file_directive;
4385 ecoff_directive_file (0);
4386 input_line_pointer = save_ilp;
4387 free (first_file_directive);
4390 alpha_flag_mdebug = 1;
4396 s_alpha_coff_wrapper (which)
4399 static void (* const fns[]) PARAMS ((int)) = {
4400 ecoff_directive_begin,
4401 ecoff_directive_bend,
4402 ecoff_directive_def,
4403 ecoff_directive_dim,
4404 ecoff_directive_endef,
4405 ecoff_directive_scl,
4406 ecoff_directive_tag,
4407 ecoff_directive_val,
4410 assert (which >= 0 && which < (int) (sizeof (fns)/sizeof (*fns)));
4412 if (ECOFF_DEBUGGING)
4416 as_bad (_("ECOFF debugging is disabled."));
4417 ignore_rest_of_line ();
4420 #endif /* OBJ_ELF */
4424 /* Handle the section specific pseudo-op. */
4427 s_alpha_section (secid)
4431 #define EVAX_SECTION_COUNT 5
4432 static char *section_name[EVAX_SECTION_COUNT + 1] =
4433 { "NULL", ".rdata", ".comm", ".link", ".ctors", ".dtors" };
4435 if ((secid <= 0) || (secid > EVAX_SECTION_COUNT))
4437 as_fatal (_("Unknown section directive"));
4438 demand_empty_rest_of_line ();
4441 temp = get_absolute_expression ();
4442 subseg_new (section_name[secid], 0);
4443 demand_empty_rest_of_line ();
4444 alpha_insn_label = NULL;
4445 alpha_auto_align_on = 1;
4446 alpha_current_align = 0;
4449 /* Parse .ent directives. */
4452 s_alpha_ent (ignore)
4456 expressionS symexpr;
4458 alpha_evax_proc.pdsckind = 0;
4459 alpha_evax_proc.framereg = -1;
4460 alpha_evax_proc.framesize = 0;
4461 alpha_evax_proc.rsa_offset = 0;
4462 alpha_evax_proc.ra_save = AXP_REG_RA;
4463 alpha_evax_proc.fp_save = -1;
4464 alpha_evax_proc.imask = 0;
4465 alpha_evax_proc.fmask = 0;
4466 alpha_evax_proc.prologue = 0;
4467 alpha_evax_proc.type = 0;
4469 expression (&symexpr);
4471 if (symexpr.X_op != O_symbol)
4473 as_fatal (_(".ent directive has no symbol"));
4474 demand_empty_rest_of_line ();
4478 symbol = make_expr_symbol (&symexpr);
4479 symbol_get_bfdsym (symbol)->flags |= BSF_FUNCTION;
4480 alpha_evax_proc.symbol = symbol;
4482 demand_empty_rest_of_line ();
4486 /* Parse .frame <framreg>,<framesize>,RA,<rsa_offset> directives. */
4489 s_alpha_frame (ignore)
4494 alpha_evax_proc.framereg = tc_get_register (1);
4497 if (*input_line_pointer++ != ','
4498 || get_absolute_expression_and_terminator (&val) != ',')
4500 as_warn (_("Bad .frame directive 1./2. param"));
4501 --input_line_pointer;
4502 demand_empty_rest_of_line ();
4506 alpha_evax_proc.framesize = val;
4508 (void) tc_get_register (1);
4510 if (*input_line_pointer++ != ',')
4512 as_warn (_("Bad .frame directive 3./4. param"));
4513 --input_line_pointer;
4514 demand_empty_rest_of_line ();
4517 alpha_evax_proc.rsa_offset = get_absolute_expression ();
4523 s_alpha_pdesc (ignore)
4533 segment_info_type *seginfo = seg_info (alpha_link_section);
4535 if (now_seg != alpha_link_section)
4537 as_bad (_(".pdesc directive not in link (.link) section"));
4538 demand_empty_rest_of_line ();
4542 if ((alpha_evax_proc.symbol == 0)
4543 || (!S_IS_DEFINED (alpha_evax_proc.symbol)))
4545 as_fatal (_(".pdesc has no matching .ent"));
4546 demand_empty_rest_of_line ();
4550 *symbol_get_obj (alpha_evax_proc.symbol) =
4551 (valueT) seginfo->literal_pool_size;
4554 if (exp.X_op != O_symbol)
4556 as_warn (_(".pdesc directive has no entry symbol"));
4557 demand_empty_rest_of_line ();
4561 entry_sym = make_expr_symbol (&exp);
4562 /* Save bfd symbol of proc desc in function symbol. */
4563 symbol_get_bfdsym (alpha_evax_proc.symbol)->udata.p
4564 = symbol_get_bfdsym (entry_sym);
4567 if (*input_line_pointer++ != ',')
4569 as_warn (_("No comma after .pdesc <entryname>"));
4570 demand_empty_rest_of_line ();
4575 name = input_line_pointer;
4576 name_end = get_symbol_end ();
4578 if (strncmp (name, "stack", 5) == 0)
4580 alpha_evax_proc.pdsckind = PDSC_S_K_KIND_FP_STACK;
4582 else if (strncmp (name, "reg", 3) == 0)
4584 alpha_evax_proc.pdsckind = PDSC_S_K_KIND_FP_REGISTER;
4586 else if (strncmp (name, "null", 4) == 0)
4588 alpha_evax_proc.pdsckind = PDSC_S_K_KIND_NULL;
4592 as_fatal (_("unknown procedure kind"));
4593 demand_empty_rest_of_line ();
4597 *input_line_pointer = name_end;
4598 demand_empty_rest_of_line ();
4600 #ifdef md_flush_pending_output
4601 md_flush_pending_output ();
4604 frag_align (3, 0, 0);
4606 fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
4608 seginfo->literal_pool_size += 16;
4610 *p = alpha_evax_proc.pdsckind
4611 | ((alpha_evax_proc.framereg == 29) ? PDSC_S_M_BASE_REG_IS_FP : 0);
4612 *(p + 1) = PDSC_S_M_NATIVE | PDSC_S_M_NO_JACKET;
4614 switch (alpha_evax_proc.pdsckind)
4616 case PDSC_S_K_KIND_NULL:
4620 case PDSC_S_K_KIND_FP_REGISTER:
4621 *(p + 2) = alpha_evax_proc.fp_save;
4622 *(p + 3) = alpha_evax_proc.ra_save;
4624 case PDSC_S_K_KIND_FP_STACK:
4625 md_number_to_chars (p + 2, (valueT) alpha_evax_proc.rsa_offset, 2);
4627 default: /* impossible */
4632 *(p + 5) = alpha_evax_proc.type & 0x0f;
4634 /* Signature offset. */
4635 md_number_to_chars (p + 6, (valueT) 0, 2);
4637 fix_new_exp (frag_now, p - frag_now->fr_literal+8, 8, &exp, 0, BFD_RELOC_64);
4639 if (alpha_evax_proc.pdsckind == PDSC_S_K_KIND_NULL)
4642 /* Add dummy fix to make add_to_link_pool work. */
4644 fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
4646 seginfo->literal_pool_size += 8;
4648 /* pdesc+16: Size. */
4649 md_number_to_chars (p, (valueT) alpha_evax_proc.framesize, 4);
4651 md_number_to_chars (p + 4, (valueT) 0, 2);
4654 md_number_to_chars (p + 6, alpha_evax_proc.prologue, 2);
4656 if (alpha_evax_proc.pdsckind == PDSC_S_K_KIND_FP_REGISTER)
4659 /* Add dummy fix to make add_to_link_pool work. */
4661 fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
4663 seginfo->literal_pool_size += 8;
4665 /* pdesc+24: register masks. */
4667 md_number_to_chars (p, alpha_evax_proc.imask, 4);
4668 md_number_to_chars (p + 4, alpha_evax_proc.fmask, 4);
4673 /* Support for crash debug on vms. */
4676 s_alpha_name (ignore)
4681 segment_info_type *seginfo = seg_info (alpha_link_section);
4683 if (now_seg != alpha_link_section)
4685 as_bad (_(".name directive not in link (.link) section"));
4686 demand_empty_rest_of_line ();
4691 if (exp.X_op != O_symbol)
4693 as_warn (_(".name directive has no symbol"));
4694 demand_empty_rest_of_line ();
4698 demand_empty_rest_of_line ();
4700 #ifdef md_flush_pending_output
4701 md_flush_pending_output ();
4704 frag_align (3, 0, 0);
4706 seginfo->literal_pool_size += 8;
4708 fix_new_exp (frag_now, p - frag_now->fr_literal, 8, &exp, 0, BFD_RELOC_64);
4714 s_alpha_linkage (ignore)
4720 #ifdef md_flush_pending_output
4721 md_flush_pending_output ();
4725 if (exp.X_op != O_symbol)
4727 as_fatal (_("No symbol after .linkage"));
4731 p = frag_more (LKP_S_K_SIZE);
4732 memset (p, 0, LKP_S_K_SIZE);
4733 fix_new_exp (frag_now, p - frag_now->fr_literal, LKP_S_K_SIZE, &exp, 0,\
4734 BFD_RELOC_ALPHA_LINKAGE);
4736 demand_empty_rest_of_line ();
4742 s_alpha_code_address (ignore)
4748 #ifdef md_flush_pending_output
4749 md_flush_pending_output ();
4753 if (exp.X_op != O_symbol)
4755 as_fatal (_("No symbol after .code_address"));
4761 fix_new_exp (frag_now, p - frag_now->fr_literal, 8, &exp, 0,\
4762 BFD_RELOC_ALPHA_CODEADDR);
4764 demand_empty_rest_of_line ();
4770 s_alpha_fp_save (ignore)
4774 alpha_evax_proc.fp_save = tc_get_register (1);
4776 demand_empty_rest_of_line ();
4781 s_alpha_mask (ignore)
4786 if (get_absolute_expression_and_terminator (&val) != ',')
4788 as_warn (_("Bad .mask directive"));
4789 --input_line_pointer;
4793 alpha_evax_proc.imask = val;
4794 (void) get_absolute_expression ();
4796 demand_empty_rest_of_line ();
4802 s_alpha_fmask (ignore)
4807 if (get_absolute_expression_and_terminator (&val) != ',')
4809 as_warn (_("Bad .fmask directive"));
4810 --input_line_pointer;
4814 alpha_evax_proc.fmask = val;
4815 (void) get_absolute_expression ();
4817 demand_empty_rest_of_line ();
4823 s_alpha_end (ignore)
4828 c = get_symbol_end ();
4829 *input_line_pointer = c;
4830 demand_empty_rest_of_line ();
4831 alpha_evax_proc.symbol = 0;
4837 s_alpha_file (ignore)
4842 static char case_hack[32];
4844 extern char *demand_copy_string PARAMS ((int *lenP));
4846 sprintf (case_hack, "<CASE:%01d%01d>",
4847 alpha_flag_hash_long_names, alpha_flag_show_after_trunc);
4849 s = symbol_find_or_make (case_hack);
4850 symbol_get_bfdsym (s)->flags |= BSF_FILE;
4852 get_absolute_expression ();
4853 s = symbol_find_or_make (demand_copy_string (&length));
4854 symbol_get_bfdsym (s)->flags |= BSF_FILE;
4855 demand_empty_rest_of_line ();
4859 #endif /* OBJ_EVAX */
4861 /* Handle the .gprel32 pseudo op. */
4864 s_alpha_gprel32 (ignore)
4865 int ignore ATTRIBUTE_UNUSED;
4877 e.X_add_symbol = section_symbol (absolute_section);
4890 e.X_add_symbol = section_symbol (absolute_section);
4893 e.X_op = O_subtract;
4894 e.X_op_symbol = alpha_gp_symbol;
4902 if (alpha_auto_align_on && alpha_current_align < 2)
4903 alpha_align (2, (char *) NULL, alpha_insn_label, 0);
4904 if (alpha_current_align > 2)
4905 alpha_current_align = 2;
4906 alpha_insn_label = NULL;
4910 fix_new_exp (frag_now, p - frag_now->fr_literal, 4,
4911 &e, 0, BFD_RELOC_GPREL32);
4914 /* Handle floating point allocation pseudo-ops. This is like the
4915 generic vresion, but it makes sure the current label, if any, is
4916 correctly aligned. */
4919 s_alpha_float_cons (type)
4946 if (alpha_auto_align_on && alpha_current_align < log_size)
4947 alpha_align (log_size, (char *) NULL, alpha_insn_label, 0);
4948 if (alpha_current_align > log_size)
4949 alpha_current_align = log_size;
4950 alpha_insn_label = NULL;
4955 /* Handle the .proc pseudo op. We don't really do much with it except
4959 s_alpha_proc (is_static)
4960 int is_static ATTRIBUTE_UNUSED;
4968 /* Takes ".proc name,nargs" */
4970 name = input_line_pointer;
4971 c = get_symbol_end ();
4972 p = input_line_pointer;
4973 symbolP = symbol_find_or_make (name);
4976 if (*input_line_pointer != ',')
4979 as_warn (_("Expected comma after name \"%s\""), name);
4982 ignore_rest_of_line ();
4986 input_line_pointer++;
4987 temp = get_absolute_expression ();
4989 /* *symbol_get_obj (symbolP) = (signed char) temp; */
4990 as_warn (_("unhandled: .proc %s,%d"), name, temp);
4991 demand_empty_rest_of_line ();
4994 /* Handle the .set pseudo op. This is used to turn on and off most of
4995 the assembler features. */
4999 int x ATTRIBUTE_UNUSED;
5005 name = input_line_pointer;
5006 ch = get_symbol_end ();
5009 if (s[0] == 'n' && s[1] == 'o')
5014 if (!strcmp ("reorder", s))
5016 else if (!strcmp ("at", s))
5017 alpha_noat_on = !yesno;
5018 else if (!strcmp ("macro", s))
5019 alpha_macros_on = yesno;
5020 else if (!strcmp ("move", s))
5022 else if (!strcmp ("volatile", s))
5025 as_warn (_("Tried to .set unrecognized mode `%s'"), name);
5027 *input_line_pointer = ch;
5028 demand_empty_rest_of_line ();
5031 /* Handle the .base pseudo op. This changes the assembler's notion of
5032 the $gp register. */
5035 s_alpha_base (ignore)
5036 int ignore ATTRIBUTE_UNUSED;
5039 if (first_32bit_quadrant)
5041 /* not fatal, but it might not work in the end */
5042 as_warn (_("File overrides no-base-register option."));
5043 first_32bit_quadrant = 0;
5048 if (*input_line_pointer == '$')
5050 input_line_pointer++;
5051 if (*input_line_pointer == 'r')
5052 input_line_pointer++;
5055 alpha_gp_register = get_absolute_expression ();
5056 if (alpha_gp_register < 0 || alpha_gp_register > 31)
5058 alpha_gp_register = AXP_REG_GP;
5059 as_warn (_("Bad base register, using $%d."), alpha_gp_register);
5062 demand_empty_rest_of_line ();
5065 /* Handle the .align pseudo-op. This aligns to a power of two. It
5066 also adjusts any current instruction label. We treat this the same
5067 way the MIPS port does: .align 0 turns off auto alignment. */
5070 s_alpha_align (ignore)
5071 int ignore ATTRIBUTE_UNUSED;
5075 long max_alignment = 15;
5077 align = get_absolute_expression ();
5078 if (align > max_alignment)
5080 align = max_alignment;
5081 as_bad (_("Alignment too large: %d. assumed"), align);
5085 as_warn (_("Alignment negative: 0 assumed"));
5089 if (*input_line_pointer == ',')
5091 input_line_pointer++;
5092 fill = get_absolute_expression ();
5100 alpha_auto_align_on = 1;
5101 alpha_align (align, pfill, alpha_insn_label, 1);
5105 alpha_auto_align_on = 0;
5108 demand_empty_rest_of_line ();
5111 /* Hook the normal string processor to reset known alignment. */
5114 s_alpha_stringer (terminate)
5117 alpha_current_align = 0;
5118 alpha_insn_label = NULL;
5119 stringer (terminate);
5122 /* Hook the normal space processing to reset known alignment. */
5125 s_alpha_space (ignore)
5128 alpha_current_align = 0;
5129 alpha_insn_label = NULL;
5133 /* Hook into cons for auto-alignment. */
5136 alpha_cons_align (size)
5142 while ((size >>= 1) != 0)
5145 if (alpha_auto_align_on && alpha_current_align < log_size)
5146 alpha_align (log_size, (char *) NULL, alpha_insn_label, 0);
5147 if (alpha_current_align > log_size)
5148 alpha_current_align = log_size;
5149 alpha_insn_label = NULL;
5152 /* Here come the .uword, .ulong, and .uquad explicitly unaligned
5153 pseudos. We just turn off auto-alignment and call down to cons. */
5156 s_alpha_ucons (bytes)
5159 int hold = alpha_auto_align_on;
5160 alpha_auto_align_on = 0;
5162 alpha_auto_align_on = hold;
5165 /* Switch the working cpu type. */
5168 s_alpha_arch (ignored)
5169 int ignored ATTRIBUTE_UNUSED;
5172 const struct cpu_type *p;
5175 name = input_line_pointer;
5176 ch = get_symbol_end ();
5178 for (p = cpu_types; p->name; ++p)
5179 if (strcmp (name, p->name) == 0)
5181 alpha_target_name = p->name, alpha_target = p->flags;
5184 as_warn ("Unknown CPU identifier `%s'", name);
5187 *input_line_pointer = ch;
5188 demand_empty_rest_of_line ();
5192 /* print token expression with alpha specific extension. */
5195 alpha_print_token (f, exp)
5197 const expressionS *exp;
5207 expressionS nexp = *exp;
5208 nexp.X_op = O_register;
5209 print_expr (f, &nexp);
5214 print_expr (f, exp);
5221 /* The target specific pseudo-ops which we support. */
5223 const pseudo_typeS md_pseudo_table[] = {
5225 {"comm", s_alpha_comm, 0}, /* osf1 compiler does this */
5226 {"rdata", s_alpha_rdata, 0},
5228 {"text", s_alpha_text, 0},
5229 {"data", s_alpha_data, 0},
5231 {"sdata", s_alpha_sdata, 0},
5234 {"section", s_alpha_section, 0},
5235 {"section.s", s_alpha_section, 0},
5236 {"sect", s_alpha_section, 0},
5237 {"sect.s", s_alpha_section, 0},
5240 { "pdesc", s_alpha_pdesc, 0},
5241 { "name", s_alpha_name, 0},
5242 { "linkage", s_alpha_linkage, 0},
5243 { "code_address", s_alpha_code_address, 0},
5244 { "ent", s_alpha_ent, 0},
5245 { "frame", s_alpha_frame, 0},
5246 { "fp_save", s_alpha_fp_save, 0},
5247 { "mask", s_alpha_mask, 0},
5248 { "fmask", s_alpha_fmask, 0},
5249 { "end", s_alpha_end, 0},
5250 { "file", s_alpha_file, 0},
5251 { "rdata", s_alpha_section, 1},
5252 { "comm", s_alpha_comm, 0},
5253 { "link", s_alpha_section, 3},
5254 { "ctors", s_alpha_section, 4},
5255 { "dtors", s_alpha_section, 5},
5258 /* Frame related pseudos. */
5259 {"ent", s_alpha_ent, 0},
5260 {"end", s_alpha_end, 0},
5261 {"mask", s_alpha_mask, 0},
5262 {"fmask", s_alpha_mask, 1},
5263 {"frame", s_alpha_frame, 0},
5264 {"prologue", s_alpha_prologue, 0},
5265 {"file", s_alpha_file, 5},
5266 {"loc", s_alpha_loc, 9},
5267 {"stabs", s_alpha_stab, 's'},
5268 {"stabn", s_alpha_stab, 'n'},
5269 /* COFF debugging related pseudos. */
5270 {"begin", s_alpha_coff_wrapper, 0},
5271 {"bend", s_alpha_coff_wrapper, 1},
5272 {"def", s_alpha_coff_wrapper, 2},
5273 {"dim", s_alpha_coff_wrapper, 3},
5274 {"endef", s_alpha_coff_wrapper, 4},
5275 {"scl", s_alpha_coff_wrapper, 5},
5276 {"tag", s_alpha_coff_wrapper, 6},
5277 {"val", s_alpha_coff_wrapper, 7},
5279 {"prologue", s_ignore, 0},
5281 {"gprel32", s_alpha_gprel32, 0},
5282 {"t_floating", s_alpha_float_cons, 'd'},
5283 {"s_floating", s_alpha_float_cons, 'f'},
5284 {"f_floating", s_alpha_float_cons, 'F'},
5285 {"g_floating", s_alpha_float_cons, 'G'},
5286 {"d_floating", s_alpha_float_cons, 'D'},
5288 {"proc", s_alpha_proc, 0},
5289 {"aproc", s_alpha_proc, 1},
5290 {"set", s_alpha_set, 0},
5291 {"reguse", s_ignore, 0},
5292 {"livereg", s_ignore, 0},
5293 {"base", s_alpha_base, 0}, /*??*/
5294 {"option", s_ignore, 0},
5295 {"aent", s_ignore, 0},
5296 {"ugen", s_ignore, 0},
5297 {"eflag", s_ignore, 0},
5299 {"align", s_alpha_align, 0},
5300 {"double", s_alpha_float_cons, 'd'},
5301 {"float", s_alpha_float_cons, 'f'},
5302 {"single", s_alpha_float_cons, 'f'},
5303 {"ascii", s_alpha_stringer, 0},
5304 {"asciz", s_alpha_stringer, 1},
5305 {"string", s_alpha_stringer, 1},
5306 {"space", s_alpha_space, 0},
5307 {"skip", s_alpha_space, 0},
5308 {"zero", s_alpha_space, 0},
5310 /* Unaligned data pseudos. */
5311 {"uword", s_alpha_ucons, 2},
5312 {"ulong", s_alpha_ucons, 4},
5313 {"uquad", s_alpha_ucons, 8},
5316 /* Dwarf wants these versions of unaligned. */
5317 {"2byte", s_alpha_ucons, 2},
5318 {"4byte", s_alpha_ucons, 4},
5319 {"8byte", s_alpha_ucons, 8},
5322 /* We don't do any optimizing, so we can safely ignore these. */
5323 {"noalias", s_ignore, 0},
5324 {"alias", s_ignore, 0},
5326 {"arch", s_alpha_arch, 0},
5331 /* Build a BFD section with its flags set appropriately for the .lita,
5332 .lit8, or .lit4 sections. */
5335 create_literal_section (name, secp, symp)
5340 segT current_section = now_seg;
5341 int current_subsec = now_subseg;
5344 *secp = new_sec = subseg_new (name, 0);
5345 subseg_set (current_section, current_subsec);
5346 bfd_set_section_alignment (stdoutput, new_sec, 4);
5347 bfd_set_section_flags (stdoutput, new_sec,
5348 SEC_RELOC | SEC_ALLOC | SEC_LOAD | SEC_READONLY
5351 S_CLEAR_EXTERNAL (*symp = section_symbol (new_sec));
5356 /* @@@ GP selection voodoo. All of this seems overly complicated and
5357 unnecessary; which is the primary reason it's for ECOFF only. */
5366 vma = bfd_get_section_vma (foo, sec);
5367 if (vma && vma < alpha_gp_value)
5368 alpha_gp_value = vma;
5374 assert (alpha_gp_value == 0);
5376 /* Get minus-one in whatever width... */
5380 /* Select the smallest VMA of these existing sections. */
5381 maybe_set_gp (alpha_lita_section);
5383 /* These were disabled before -- should we use them? */
5384 maybe_set_gp (sdata);
5385 maybe_set_gp (lit8_sec);
5386 maybe_set_gp (lit4_sec);
5389 /* @@ Will a simple 0x8000 work here? If not, why not? */
5390 #define GP_ADJUSTMENT (0x8000 - 0x10)
5392 alpha_gp_value += GP_ADJUSTMENT;
5394 S_SET_VALUE (alpha_gp_symbol, alpha_gp_value);
5397 printf (_("Chose GP value of %lx\n"), alpha_gp_value);
5400 #endif /* OBJ_ECOFF */
5403 /* Map 's' to SHF_ALPHA_GPREL. */
5406 alpha_elf_section_letter (letter, ptr_msg)
5411 return SHF_ALPHA_GPREL;
5413 *ptr_msg = _("Bad .section directive: want a,s,w,x,M,S in string");
5417 /* Map SHF_ALPHA_GPREL to SEC_SMALL_DATA. */
5420 alpha_elf_section_flags (flags, attr, type)
5422 int attr, type ATTRIBUTE_UNUSED;
5424 if (attr & SHF_ALPHA_GPREL)
5425 flags |= SEC_SMALL_DATA;
5428 #endif /* OBJ_ELF */
5430 /* Called internally to handle all alignment needs. This takes care
5431 of eliding calls to frag_align if'n the cached current alignment
5432 says we've already got it, as well as taking care of the auto-align
5433 feature wrt labels. */
5436 alpha_align (n, pfill, label, force)
5440 int force ATTRIBUTE_UNUSED;
5442 if (alpha_current_align >= n)
5447 if (subseg_text_p (now_seg))
5448 frag_align_code (n, 0);
5450 frag_align (n, 0, 0);
5453 frag_align (n, *pfill, 0);
5455 alpha_current_align = n;
5457 if (label != NULL && S_GET_SEGMENT (label) == now_seg)
5459 symbol_set_frag (label, frag_now);
5460 S_SET_VALUE (label, (valueT) frag_now_fix ());
5463 record_alignment (now_seg, n);
5465 /* ??? If alpha_flag_relax && force && elf, record the requested alignment
5466 in a reloc for the linker to see. */
5469 /* This is called from HANDLE_ALIGN in write.c. Fill in the contents
5470 of an rs_align_code fragment. */
5473 alpha_handle_align (fragp)
5476 static char const unop[4] = { 0x00, 0x00, 0xe0, 0x2f };
5477 static char const nopunop[8] = {
5478 0x1f, 0x04, 0xff, 0x47,
5479 0x00, 0x00, 0xe0, 0x2f
5485 if (fragp->fr_type != rs_align_code)
5488 bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix;
5489 p = fragp->fr_literal + fragp->fr_fix;
5502 memcpy (p, unop, 4);
5508 memcpy (p, nopunop, 8);
5510 fragp->fr_fix += fix;
5514 /* The Alpha has support for some VAX floating point types, as well as for
5515 IEEE floating point. We consider IEEE to be the primary floating point
5516 format, and sneak in the VAX floating point support here. */
5517 #define md_atof vax_md_atof
5518 #include "config/atof-vax.c"