Restore "call|jmp [xtrn]" in x86 assembler.
[binutils.git] / gas / config / tc-alpha.c
blob620f9749a687caca26553a96114578c2205d61fd
1 /* tc-alpha.c - Processor-specific code for the DEC Alpha AXP CPU.
2 Copyright 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009
4 Free Software Foundation, Inc.
5 Contributed by Carnegie Mellon University, 1993.
6 Written by Alessandro Forin, based on earlier gas-1.38 target CPU files.
7 Modified by Ken Raeburn for gas-2.x and ECOFF support.
8 Modified by Richard Henderson for ELF support.
9 Modified by Klaus K"ampf for EVAX (OpenVMS/Alpha) support.
11 This file is part of GAS, the GNU Assembler.
13 GAS is free software; you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation; either version 3, or (at your option)
16 any later version.
18 GAS is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
23 You should have received a copy of the GNU General Public License
24 along with GAS; see the file COPYING. If not, write to the Free
25 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
26 02110-1301, USA. */
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. */
52 #include "as.h"
53 #include "subsegs.h"
54 #include "struc-symbol.h"
55 #include "ecoff.h"
57 #include "opcode/alpha.h"
59 #ifdef OBJ_ELF
60 #include "elf/alpha.h"
61 #endif
63 #ifdef OBJ_EVAX
64 #include "vms.h"
65 #include "vms/egps.h"
66 #endif
68 #include "dwarf2dbg.h"
69 #include "dw2gencfi.h"
70 #include "safe-ctype.h"
72 /* Local types. */
74 #define TOKENIZE_ERROR -1
75 #define TOKENIZE_ERROR_REPORT -2
76 #define MAX_INSN_FIXUPS 2
77 #define MAX_INSN_ARGS 5
79 /* Used since new relocation types are introduced in this
80 file (DUMMY_RELOC_LITUSE_*) */
81 typedef int extended_bfd_reloc_code_real_type;
83 struct alpha_fixup
85 expressionS exp;
86 /* bfd_reloc_code_real_type reloc; */
87 extended_bfd_reloc_code_real_type reloc;
88 #ifdef OBJ_EVAX
89 symbolS *xtrasym, *procsym;
90 #endif
93 struct alpha_insn
95 unsigned insn;
96 int nfixups;
97 struct alpha_fixup fixups[MAX_INSN_FIXUPS];
98 long sequence;
101 enum alpha_macro_arg
103 MACRO_EOA = 1,
104 MACRO_IR,
105 MACRO_PIR,
106 MACRO_OPIR,
107 MACRO_CPIR,
108 MACRO_FPR,
109 MACRO_EXP
112 struct alpha_macro
114 const char *name;
115 void (*emit) (const expressionS *, int, const void *);
116 const void * arg;
117 enum alpha_macro_arg argsets[16];
120 /* Extra expression types. */
122 #define O_pregister O_md1 /* O_register, in parentheses. */
123 #define O_cpregister O_md2 /* + a leading comma. */
125 /* The alpha_reloc_op table below depends on the ordering of these. */
126 #define O_literal O_md3 /* !literal relocation. */
127 #define O_lituse_addr O_md4 /* !lituse_addr relocation. */
128 #define O_lituse_base O_md5 /* !lituse_base relocation. */
129 #define O_lituse_bytoff O_md6 /* !lituse_bytoff relocation. */
130 #define O_lituse_jsr O_md7 /* !lituse_jsr relocation. */
131 #define O_lituse_tlsgd O_md8 /* !lituse_tlsgd relocation. */
132 #define O_lituse_tlsldm O_md9 /* !lituse_tlsldm relocation. */
133 #define O_lituse_jsrdirect O_md10 /* !lituse_jsrdirect relocation. */
134 #define O_gpdisp O_md11 /* !gpdisp relocation. */
135 #define O_gprelhigh O_md12 /* !gprelhigh relocation. */
136 #define O_gprellow O_md13 /* !gprellow relocation. */
137 #define O_gprel O_md14 /* !gprel relocation. */
138 #define O_samegp O_md15 /* !samegp relocation. */
139 #define O_tlsgd O_md16 /* !tlsgd relocation. */
140 #define O_tlsldm O_md17 /* !tlsldm relocation. */
141 #define O_gotdtprel O_md18 /* !gotdtprel relocation. */
142 #define O_dtprelhi O_md19 /* !dtprelhi relocation. */
143 #define O_dtprello O_md20 /* !dtprello relocation. */
144 #define O_dtprel O_md21 /* !dtprel relocation. */
145 #define O_gottprel O_md22 /* !gottprel relocation. */
146 #define O_tprelhi O_md23 /* !tprelhi relocation. */
147 #define O_tprello O_md24 /* !tprello relocation. */
148 #define O_tprel O_md25 /* !tprel relocation. */
150 #define DUMMY_RELOC_LITUSE_ADDR (BFD_RELOC_UNUSED + 1)
151 #define DUMMY_RELOC_LITUSE_BASE (BFD_RELOC_UNUSED + 2)
152 #define DUMMY_RELOC_LITUSE_BYTOFF (BFD_RELOC_UNUSED + 3)
153 #define DUMMY_RELOC_LITUSE_JSR (BFD_RELOC_UNUSED + 4)
154 #define DUMMY_RELOC_LITUSE_TLSGD (BFD_RELOC_UNUSED + 5)
155 #define DUMMY_RELOC_LITUSE_TLSLDM (BFD_RELOC_UNUSED + 6)
156 #define DUMMY_RELOC_LITUSE_JSRDIRECT (BFD_RELOC_UNUSED + 7)
158 #define USER_RELOC_P(R) ((R) >= O_literal && (R) <= O_tprel)
160 /* Macros for extracting the type and number of encoded register tokens. */
162 #define is_ir_num(x) (((x) & 32) == 0)
163 #define is_fpr_num(x) (((x) & 32) != 0)
164 #define regno(x) ((x) & 31)
166 /* Something odd inherited from the old assembler. */
168 #define note_gpreg(R) (alpha_gprmask |= (1 << (R)))
169 #define note_fpreg(R) (alpha_fprmask |= (1 << (R)))
171 /* Predicates for 16- and 32-bit ranges */
172 /* XXX: The non-shift version appears to trigger a compiler bug when
173 cross-assembling from x86 w/ gcc 2.7.2. */
175 #if 1
176 #define range_signed_16(x) \
177 (((offsetT) (x) >> 15) == 0 || ((offsetT) (x) >> 15) == -1)
178 #define range_signed_32(x) \
179 (((offsetT) (x) >> 31) == 0 || ((offsetT) (x) >> 31) == -1)
180 #else
181 #define range_signed_16(x) ((offsetT) (x) >= -(offsetT) 0x8000 && \
182 (offsetT) (x) <= (offsetT) 0x7FFF)
183 #define range_signed_32(x) ((offsetT) (x) >= -(offsetT) 0x80000000 && \
184 (offsetT) (x) <= (offsetT) 0x7FFFFFFF)
185 #endif
187 /* Macros for sign extending from 16- and 32-bits. */
188 /* XXX: The cast macros will work on all the systems that I care about,
189 but really a predicate should be found to use the non-cast forms. */
191 #if 1
192 #define sign_extend_16(x) ((short) (x))
193 #define sign_extend_32(x) ((int) (x))
194 #else
195 #define sign_extend_16(x) ((offsetT) (((x) & 0xFFFF) ^ 0x8000) - 0x8000)
196 #define sign_extend_32(x) ((offsetT) (((x) & 0xFFFFFFFF) \
197 ^ 0x80000000) - 0x80000000)
198 #endif
200 /* Macros to build tokens. */
202 #define set_tok_reg(t, r) (memset (&(t), 0, sizeof (t)), \
203 (t).X_op = O_register, \
204 (t).X_add_number = (r))
205 #define set_tok_preg(t, r) (memset (&(t), 0, sizeof (t)), \
206 (t).X_op = O_pregister, \
207 (t).X_add_number = (r))
208 #define set_tok_cpreg(t, r) (memset (&(t), 0, sizeof (t)), \
209 (t).X_op = O_cpregister, \
210 (t).X_add_number = (r))
211 #define set_tok_freg(t, r) (memset (&(t), 0, sizeof (t)), \
212 (t).X_op = O_register, \
213 (t).X_add_number = (r) + 32)
214 #define set_tok_sym(t, s, a) (memset (&(t), 0, sizeof (t)), \
215 (t).X_op = O_symbol, \
216 (t).X_add_symbol = (s), \
217 (t).X_add_number = (a))
218 #define set_tok_const(t, n) (memset (&(t), 0, sizeof (t)), \
219 (t).X_op = O_constant, \
220 (t).X_add_number = (n))
222 /* Generic assembler global variables which must be defined by all
223 targets. */
225 /* Characters which always start a comment. */
226 const char comment_chars[] = "#";
228 /* Characters which start a comment at the beginning of a line. */
229 const char line_comment_chars[] = "#";
231 /* Characters which may be used to separate multiple commands on a
232 single line. */
233 const char line_separator_chars[] = ";";
235 /* Characters which are used to indicate an exponent in a floating
236 point number. */
237 const char EXP_CHARS[] = "eE";
239 /* Characters which mean that a number is a floating point constant,
240 as in 0d1.0. */
241 /* XXX: Do all of these really get used on the alpha?? */
242 char FLT_CHARS[] = "rRsSfFdDxXpP";
244 #ifdef OBJ_EVAX
245 const char *md_shortopts = "Fm:g+1h:HG:";
246 #else
247 const char *md_shortopts = "Fm:gG:";
248 #endif
250 struct option md_longopts[] =
252 #define OPTION_32ADDR (OPTION_MD_BASE)
253 { "32addr", no_argument, NULL, OPTION_32ADDR },
254 #define OPTION_RELAX (OPTION_32ADDR + 1)
255 { "relax", no_argument, NULL, OPTION_RELAX },
256 #ifdef OBJ_ELF
257 #define OPTION_MDEBUG (OPTION_RELAX + 1)
258 #define OPTION_NO_MDEBUG (OPTION_MDEBUG + 1)
259 { "mdebug", no_argument, NULL, OPTION_MDEBUG },
260 { "no-mdebug", no_argument, NULL, OPTION_NO_MDEBUG },
261 #endif
262 #ifdef OBJ_EVAX
263 #define OPTION_REPLACE (OPTION_RELAX + 1)
264 #define OPTION_NOREPLACE (OPTION_REPLACE+1)
265 { "replace", no_argument, NULL, OPTION_REPLACE },
266 { "noreplace", no_argument, NULL, OPTION_NOREPLACE },
267 #endif
268 { NULL, no_argument, NULL, 0 }
271 size_t md_longopts_size = sizeof (md_longopts);
273 #ifdef OBJ_EVAX
274 #define AXP_REG_R0 0
275 #define AXP_REG_R16 16
276 #define AXP_REG_R17 17
277 #undef AXP_REG_T9
278 #define AXP_REG_T9 22
279 #undef AXP_REG_T10
280 #define AXP_REG_T10 23
281 #undef AXP_REG_T11
282 #define AXP_REG_T11 24
283 #undef AXP_REG_T12
284 #define AXP_REG_T12 25
285 #define AXP_REG_AI 25
286 #undef AXP_REG_FP
287 #define AXP_REG_FP 29
289 #undef AXP_REG_GP
290 #define AXP_REG_GP AXP_REG_PV
292 static struct hash_control *alpha_evax_proc_hash;
294 #endif /* OBJ_EVAX */
296 /* The cpu for which we are generating code. */
297 static unsigned alpha_target = AXP_OPCODE_BASE;
298 static const char *alpha_target_name = "<all>";
300 /* The hash table of instruction opcodes. */
301 static struct hash_control *alpha_opcode_hash;
303 /* The hash table of macro opcodes. */
304 static struct hash_control *alpha_macro_hash;
306 #ifdef OBJ_ECOFF
307 /* The $gp relocation symbol. */
308 static symbolS *alpha_gp_symbol;
310 /* XXX: what is this, and why is it exported? */
311 valueT alpha_gp_value;
312 #endif
314 /* The current $gp register. */
315 static int alpha_gp_register = AXP_REG_GP;
317 /* A table of the register symbols. */
318 static symbolS *alpha_register_table[64];
320 /* Constant sections, or sections of constants. */
321 #ifdef OBJ_ECOFF
322 static segT alpha_lita_section;
323 #endif
324 #ifdef OBJ_EVAX
325 segT alpha_link_section;
326 #endif
327 #ifndef OBJ_EVAX
328 static segT alpha_lit8_section;
329 #endif
331 /* Symbols referring to said sections. */
332 #ifdef OBJ_ECOFF
333 static symbolS *alpha_lita_symbol;
334 #endif
335 #ifdef OBJ_EVAX
336 static symbolS *alpha_link_symbol;
337 #endif
338 #ifndef OBJ_EVAX
339 static symbolS *alpha_lit8_symbol;
340 #endif
342 /* Literal for .litX+0x8000 within .lita. */
343 #ifdef OBJ_ECOFF
344 static offsetT alpha_lit8_literal;
345 #endif
347 /* Is the assembler not allowed to use $at? */
348 static int alpha_noat_on = 0;
350 /* Are macros enabled? */
351 static int alpha_macros_on = 1;
353 /* Are floats disabled? */
354 static int alpha_nofloats_on = 0;
356 /* Are addresses 32 bit? */
357 static int alpha_addr32_on = 0;
359 /* Symbol labelling the current insn. When the Alpha gas sees
360 foo:
361 .quad 0
362 and the section happens to not be on an eight byte boundary, it
363 will align both the symbol and the .quad to an eight byte boundary. */
364 static symbolS *alpha_insn_label;
365 #if defined(OBJ_ELF) || defined (OBJ_EVAX)
366 static symbolS *alpha_prologue_label;
367 #endif
369 #ifdef OBJ_EVAX
370 /* Symbol associate with the current jsr instruction. */
371 static symbolS *alpha_linkage_symbol;
372 #endif
374 /* Whether we should automatically align data generation pseudo-ops.
375 .align 0 will turn this off. */
376 static int alpha_auto_align_on = 1;
378 /* The known current alignment of the current section. */
379 static int alpha_current_align;
381 /* These are exported to ECOFF code. */
382 unsigned long alpha_gprmask, alpha_fprmask;
384 /* Whether the debugging option was seen. */
385 static int alpha_debug;
387 #ifdef OBJ_ELF
388 /* Whether we are emitting an mdebug section. */
389 int alpha_flag_mdebug = -1;
390 #endif
392 #ifdef OBJ_EVAX
393 /* Whether to perform the VMS procedure call optimization. */
394 int alpha_flag_replace = 1;
395 #endif
397 /* Don't fully resolve relocations, allowing code movement in the linker. */
398 static int alpha_flag_relax;
400 /* What value to give to bfd_set_gp_size. */
401 static int g_switch_value = 8;
403 #ifdef OBJ_EVAX
404 /* Collect information about current procedure here. */
405 struct alpha_evax_procs
407 symbolS *symbol; /* Proc pdesc symbol. */
408 int pdsckind;
409 int framereg; /* Register for frame pointer. */
410 int framesize; /* Size of frame. */
411 int rsa_offset;
412 int ra_save;
413 int fp_save;
414 long imask;
415 long fmask;
416 int type;
417 int prologue;
418 symbolS *handler;
419 int handler_data;
422 struct alpha_linkage_fixups *alpha_linkage_fixup_root;
423 static struct alpha_linkage_fixups *alpha_linkage_fixup_tail;
425 static struct alpha_evax_procs *alpha_evax_proc;
427 static int alpha_flag_hash_long_names = 0; /* -+ */
428 static int alpha_flag_show_after_trunc = 0; /* -H */
430 /* If the -+ switch is given, then a hash is appended to any name that is
431 longer than 64 characters, else longer symbol names are truncated. */
433 #endif
435 #ifdef RELOC_OP_P
436 /* A table to map the spelling of a relocation operand into an appropriate
437 bfd_reloc_code_real_type type. The table is assumed to be ordered such
438 that op-O_literal indexes into it. */
440 #define ALPHA_RELOC_TABLE(op) \
441 (&alpha_reloc_op[ ((!USER_RELOC_P (op)) \
442 ? (abort (), 0) \
443 : (int) (op) - (int) O_literal) ])
445 #define DEF(NAME, RELOC, REQ, ALLOW) \
446 { #NAME, sizeof(#NAME)-1, O_##NAME, RELOC, REQ, ALLOW}
448 static const struct alpha_reloc_op_tag
450 const char *name; /* String to lookup. */
451 size_t length; /* Size of the string. */
452 operatorT op; /* Which operator to use. */
453 extended_bfd_reloc_code_real_type reloc;
454 unsigned int require_seq : 1; /* Require a sequence number. */
455 unsigned int allow_seq : 1; /* Allow a sequence number. */
457 alpha_reloc_op[] =
459 DEF (literal, BFD_RELOC_ALPHA_ELF_LITERAL, 0, 1),
460 DEF (lituse_addr, DUMMY_RELOC_LITUSE_ADDR, 1, 1),
461 DEF (lituse_base, DUMMY_RELOC_LITUSE_BASE, 1, 1),
462 DEF (lituse_bytoff, DUMMY_RELOC_LITUSE_BYTOFF, 1, 1),
463 DEF (lituse_jsr, DUMMY_RELOC_LITUSE_JSR, 1, 1),
464 DEF (lituse_tlsgd, DUMMY_RELOC_LITUSE_TLSGD, 1, 1),
465 DEF (lituse_tlsldm, DUMMY_RELOC_LITUSE_TLSLDM, 1, 1),
466 DEF (lituse_jsrdirect, DUMMY_RELOC_LITUSE_JSRDIRECT, 1, 1),
467 DEF (gpdisp, BFD_RELOC_ALPHA_GPDISP, 1, 1),
468 DEF (gprelhigh, BFD_RELOC_ALPHA_GPREL_HI16, 0, 0),
469 DEF (gprellow, BFD_RELOC_ALPHA_GPREL_LO16, 0, 0),
470 DEF (gprel, BFD_RELOC_GPREL16, 0, 0),
471 DEF (samegp, BFD_RELOC_ALPHA_BRSGP, 0, 0),
472 DEF (tlsgd, BFD_RELOC_ALPHA_TLSGD, 0, 1),
473 DEF (tlsldm, BFD_RELOC_ALPHA_TLSLDM, 0, 1),
474 DEF (gotdtprel, BFD_RELOC_ALPHA_GOTDTPREL16, 0, 0),
475 DEF (dtprelhi, BFD_RELOC_ALPHA_DTPREL_HI16, 0, 0),
476 DEF (dtprello, BFD_RELOC_ALPHA_DTPREL_LO16, 0, 0),
477 DEF (dtprel, BFD_RELOC_ALPHA_DTPREL16, 0, 0),
478 DEF (gottprel, BFD_RELOC_ALPHA_GOTTPREL16, 0, 0),
479 DEF (tprelhi, BFD_RELOC_ALPHA_TPREL_HI16, 0, 0),
480 DEF (tprello, BFD_RELOC_ALPHA_TPREL_LO16, 0, 0),
481 DEF (tprel, BFD_RELOC_ALPHA_TPREL16, 0, 0),
484 #undef DEF
486 static const int alpha_num_reloc_op
487 = sizeof (alpha_reloc_op) / sizeof (*alpha_reloc_op);
488 #endif /* RELOC_OP_P */
490 /* Maximum # digits needed to hold the largest sequence #. */
491 #define ALPHA_RELOC_DIGITS 25
493 /* Structure to hold explicit sequence information. */
494 struct alpha_reloc_tag
496 fixS *master; /* The literal reloc. */
497 #ifdef OBJ_EVAX
498 struct symbol *sym;
499 struct symbol *psym;
500 #endif
501 fixS *slaves; /* Head of linked list of lituses. */
502 segT segment; /* Segment relocs are in or undefined_section. */
503 long sequence; /* Sequence #. */
504 unsigned n_master; /* # of literals. */
505 unsigned n_slaves; /* # of lituses. */
506 unsigned saw_tlsgd : 1; /* True if ... */
507 unsigned saw_tlsldm : 1;
508 unsigned saw_lu_tlsgd : 1;
509 unsigned saw_lu_tlsldm : 1;
510 unsigned multi_section_p : 1; /* True if more than one section was used. */
511 char string[1]; /* Printable form of sequence to hash with. */
514 /* Hash table to link up literals with the appropriate lituse. */
515 static struct hash_control *alpha_literal_hash;
517 /* Sequence numbers for internal use by macros. */
518 static long next_sequence_num = -1;
520 /* A table of CPU names and opcode sets. */
522 static const struct cpu_type
524 const char *name;
525 unsigned flags;
527 cpu_types[] =
529 /* Ad hoc convention: cpu number gets palcode, process code doesn't.
530 This supports usage under DU 4.0b that does ".arch ev4", and
531 usage in MILO that does -m21064. Probably something more
532 specific like -m21064-pal should be used, but oh well. */
534 { "21064", AXP_OPCODE_BASE|AXP_OPCODE_EV4 },
535 { "21064a", AXP_OPCODE_BASE|AXP_OPCODE_EV4 },
536 { "21066", AXP_OPCODE_BASE|AXP_OPCODE_EV4 },
537 { "21068", AXP_OPCODE_BASE|AXP_OPCODE_EV4 },
538 { "21164", AXP_OPCODE_BASE|AXP_OPCODE_EV5 },
539 { "21164a", AXP_OPCODE_BASE|AXP_OPCODE_EV5|AXP_OPCODE_BWX },
540 { "21164pc", (AXP_OPCODE_BASE|AXP_OPCODE_EV5|AXP_OPCODE_BWX
541 |AXP_OPCODE_MAX) },
542 { "21264", (AXP_OPCODE_BASE|AXP_OPCODE_EV6|AXP_OPCODE_BWX
543 |AXP_OPCODE_MAX|AXP_OPCODE_CIX) },
544 { "21264a", (AXP_OPCODE_BASE|AXP_OPCODE_EV6|AXP_OPCODE_BWX
545 |AXP_OPCODE_MAX|AXP_OPCODE_CIX) },
546 { "21264b", (AXP_OPCODE_BASE|AXP_OPCODE_EV6|AXP_OPCODE_BWX
547 |AXP_OPCODE_MAX|AXP_OPCODE_CIX) },
549 { "ev4", AXP_OPCODE_BASE },
550 { "ev45", AXP_OPCODE_BASE },
551 { "lca45", AXP_OPCODE_BASE },
552 { "ev5", AXP_OPCODE_BASE },
553 { "ev56", AXP_OPCODE_BASE|AXP_OPCODE_BWX },
554 { "pca56", AXP_OPCODE_BASE|AXP_OPCODE_BWX|AXP_OPCODE_MAX },
555 { "ev6", AXP_OPCODE_BASE|AXP_OPCODE_BWX|AXP_OPCODE_MAX|AXP_OPCODE_CIX },
556 { "ev67", AXP_OPCODE_BASE|AXP_OPCODE_BWX|AXP_OPCODE_MAX|AXP_OPCODE_CIX },
557 { "ev68", AXP_OPCODE_BASE|AXP_OPCODE_BWX|AXP_OPCODE_MAX|AXP_OPCODE_CIX },
559 { "all", AXP_OPCODE_BASE },
560 { 0, 0 }
563 /* Some instruction sets indexed by lg(size). */
564 static const char * const sextX_op[] = { "sextb", "sextw", "sextl", NULL };
565 static const char * const insXl_op[] = { "insbl", "inswl", "insll", "insql" };
566 static const char * const insXh_op[] = { NULL, "inswh", "inslh", "insqh" };
567 static const char * const extXl_op[] = { "extbl", "extwl", "extll", "extql" };
568 static const char * const extXh_op[] = { NULL, "extwh", "extlh", "extqh" };
569 static const char * const mskXl_op[] = { "mskbl", "mskwl", "mskll", "mskql" };
570 static const char * const mskXh_op[] = { NULL, "mskwh", "msklh", "mskqh" };
571 static const char * const stX_op[] = { "stb", "stw", "stl", "stq" };
572 static const char * const ldXu_op[] = { "ldbu", "ldwu", NULL, NULL };
574 static void assemble_insn (const struct alpha_opcode *, const expressionS *, int, struct alpha_insn *, extended_bfd_reloc_code_real_type);
575 static void emit_insn (struct alpha_insn *);
576 static void assemble_tokens (const char *, const expressionS *, int, int);
577 #ifdef OBJ_EVAX
578 static char *s_alpha_section_name (void);
579 static symbolS *add_to_link_pool (symbolS *, symbolS *, offsetT);
580 #endif
582 static struct alpha_reloc_tag *
583 get_alpha_reloc_tag (long sequence)
585 char buffer[ALPHA_RELOC_DIGITS];
586 struct alpha_reloc_tag *info;
588 sprintf (buffer, "!%ld", sequence);
590 info = (struct alpha_reloc_tag *) hash_find (alpha_literal_hash, buffer);
591 if (! info)
593 size_t len = strlen (buffer);
594 const char *errmsg;
596 info = (struct alpha_reloc_tag *)
597 xcalloc (sizeof (struct alpha_reloc_tag) + len, 1);
599 info->segment = now_seg;
600 info->sequence = sequence;
601 strcpy (info->string, buffer);
602 errmsg = hash_insert (alpha_literal_hash, info->string, (void *) info);
603 if (errmsg)
604 as_fatal ("%s", errmsg);
605 #ifdef OBJ_EVAX
606 info->sym = 0;
607 info->psym = 0;
608 #endif
611 return info;
614 #ifndef OBJ_EVAX
616 static void
617 alpha_adjust_relocs (bfd *abfd ATTRIBUTE_UNUSED,
618 asection *sec,
619 void * ptr ATTRIBUTE_UNUSED)
621 segment_info_type *seginfo = seg_info (sec);
622 fixS **prevP;
623 fixS *fixp;
624 fixS *next;
625 fixS *slave;
627 /* If seginfo is NULL, we did not create this section; don't do
628 anything with it. By using a pointer to a pointer, we can update
629 the links in place. */
630 if (seginfo == NULL)
631 return;
633 /* If there are no relocations, skip the section. */
634 if (! seginfo->fix_root)
635 return;
637 /* First rebuild the fixup chain without the explicit lituse and
638 gpdisp_lo16 relocs. */
639 prevP = &seginfo->fix_root;
640 for (fixp = seginfo->fix_root; fixp; fixp = next)
642 next = fixp->fx_next;
643 fixp->fx_next = (fixS *) 0;
645 switch (fixp->fx_r_type)
647 case BFD_RELOC_ALPHA_LITUSE:
648 if (fixp->tc_fix_data.info->n_master == 0)
649 as_bad_where (fixp->fx_file, fixp->fx_line,
650 _("No !literal!%ld was found"),
651 fixp->tc_fix_data.info->sequence);
652 #ifdef RELOC_OP_P
653 if (fixp->fx_offset == LITUSE_ALPHA_TLSGD)
655 if (! fixp->tc_fix_data.info->saw_tlsgd)
656 as_bad_where (fixp->fx_file, fixp->fx_line,
657 _("No !tlsgd!%ld was found"),
658 fixp->tc_fix_data.info->sequence);
660 else if (fixp->fx_offset == LITUSE_ALPHA_TLSLDM)
662 if (! fixp->tc_fix_data.info->saw_tlsldm)
663 as_bad_where (fixp->fx_file, fixp->fx_line,
664 _("No !tlsldm!%ld was found"),
665 fixp->tc_fix_data.info->sequence);
667 #endif
668 break;
670 case BFD_RELOC_ALPHA_GPDISP_LO16:
671 if (fixp->tc_fix_data.info->n_master == 0)
672 as_bad_where (fixp->fx_file, fixp->fx_line,
673 _("No ldah !gpdisp!%ld was found"),
674 fixp->tc_fix_data.info->sequence);
675 break;
677 case BFD_RELOC_ALPHA_ELF_LITERAL:
678 if (fixp->tc_fix_data.info
679 && (fixp->tc_fix_data.info->saw_tlsgd
680 || fixp->tc_fix_data.info->saw_tlsldm))
681 break;
682 /* FALLTHRU */
684 default:
685 *prevP = fixp;
686 prevP = &fixp->fx_next;
687 break;
691 /* Go back and re-chain dependent relocations. They are currently
692 linked through the next_reloc field in reverse order, so as we
693 go through the next_reloc chain, we effectively reverse the chain
694 once again.
696 Except if there is more than one !literal for a given sequence
697 number. In that case, the programmer and/or compiler is not sure
698 how control flows from literal to lituse, and we can't be sure to
699 get the relaxation correct.
701 ??? Well, actually we could, if there are enough lituses such that
702 we can make each literal have at least one of each lituse type
703 present. Not implemented.
705 Also suppress the optimization if the !literals/!lituses are spread
706 in different segments. This can happen with "intersting" uses of
707 inline assembly; examples are present in the Linux kernel semaphores. */
709 for (fixp = seginfo->fix_root; fixp; fixp = next)
711 next = fixp->fx_next;
712 switch (fixp->fx_r_type)
714 case BFD_RELOC_ALPHA_TLSGD:
715 case BFD_RELOC_ALPHA_TLSLDM:
716 if (!fixp->tc_fix_data.info)
717 break;
718 if (fixp->tc_fix_data.info->n_master == 0)
719 break;
720 else if (fixp->tc_fix_data.info->n_master > 1)
722 as_bad_where (fixp->fx_file, fixp->fx_line,
723 _("too many !literal!%ld for %s"),
724 fixp->tc_fix_data.info->sequence,
725 (fixp->fx_r_type == BFD_RELOC_ALPHA_TLSGD
726 ? "!tlsgd" : "!tlsldm"));
727 break;
730 fixp->tc_fix_data.info->master->fx_next = fixp->fx_next;
731 fixp->fx_next = fixp->tc_fix_data.info->master;
732 fixp = fixp->fx_next;
733 /* Fall through. */
735 case BFD_RELOC_ALPHA_ELF_LITERAL:
736 if (fixp->tc_fix_data.info
737 && fixp->tc_fix_data.info->n_master == 1
738 && ! fixp->tc_fix_data.info->multi_section_p)
740 for (slave = fixp->tc_fix_data.info->slaves;
741 slave != (fixS *) 0;
742 slave = slave->tc_fix_data.next_reloc)
744 slave->fx_next = fixp->fx_next;
745 fixp->fx_next = slave;
748 break;
750 case BFD_RELOC_ALPHA_GPDISP_HI16:
751 if (fixp->tc_fix_data.info->n_slaves == 0)
752 as_bad_where (fixp->fx_file, fixp->fx_line,
753 _("No lda !gpdisp!%ld was found"),
754 fixp->tc_fix_data.info->sequence);
755 else
757 slave = fixp->tc_fix_data.info->slaves;
758 slave->fx_next = next;
759 fixp->fx_next = slave;
761 break;
763 default:
764 break;
769 /* Before the relocations are written, reorder them, so that user
770 supplied !lituse relocations follow the appropriate !literal
771 relocations, and similarly for !gpdisp relocations. */
773 void
774 alpha_before_fix (void)
776 if (alpha_literal_hash)
777 bfd_map_over_sections (stdoutput, alpha_adjust_relocs, NULL);
780 #endif
782 #ifdef DEBUG_ALPHA
783 static void
784 debug_exp (expressionS tok[], int ntok)
786 int i;
788 fprintf (stderr, "debug_exp: %d tokens", ntok);
789 for (i = 0; i < ntok; i++)
791 expressionS *t = &tok[i];
792 const char *name;
794 switch (t->X_op)
796 default: name = "unknown"; break;
797 case O_illegal: name = "O_illegal"; break;
798 case O_absent: name = "O_absent"; break;
799 case O_constant: name = "O_constant"; break;
800 case O_symbol: name = "O_symbol"; break;
801 case O_symbol_rva: name = "O_symbol_rva"; break;
802 case O_register: name = "O_register"; break;
803 case O_big: name = "O_big"; break;
804 case O_uminus: name = "O_uminus"; break;
805 case O_bit_not: name = "O_bit_not"; break;
806 case O_logical_not: name = "O_logical_not"; break;
807 case O_multiply: name = "O_multiply"; break;
808 case O_divide: name = "O_divide"; break;
809 case O_modulus: name = "O_modulus"; break;
810 case O_left_shift: name = "O_left_shift"; break;
811 case O_right_shift: name = "O_right_shift"; break;
812 case O_bit_inclusive_or: name = "O_bit_inclusive_or"; break;
813 case O_bit_or_not: name = "O_bit_or_not"; break;
814 case O_bit_exclusive_or: name = "O_bit_exclusive_or"; break;
815 case O_bit_and: name = "O_bit_and"; break;
816 case O_add: name = "O_add"; break;
817 case O_subtract: name = "O_subtract"; break;
818 case O_eq: name = "O_eq"; break;
819 case O_ne: name = "O_ne"; break;
820 case O_lt: name = "O_lt"; break;
821 case O_le: name = "O_le"; break;
822 case O_ge: name = "O_ge"; break;
823 case O_gt: name = "O_gt"; break;
824 case O_logical_and: name = "O_logical_and"; break;
825 case O_logical_or: name = "O_logical_or"; break;
826 case O_index: name = "O_index"; break;
827 case O_pregister: name = "O_pregister"; break;
828 case O_cpregister: name = "O_cpregister"; break;
829 case O_literal: name = "O_literal"; break;
830 case O_lituse_addr: name = "O_lituse_addr"; break;
831 case O_lituse_base: name = "O_lituse_base"; break;
832 case O_lituse_bytoff: name = "O_lituse_bytoff"; break;
833 case O_lituse_jsr: name = "O_lituse_jsr"; break;
834 case O_lituse_tlsgd: name = "O_lituse_tlsgd"; break;
835 case O_lituse_tlsldm: name = "O_lituse_tlsldm"; break;
836 case O_lituse_jsrdirect: name = "O_lituse_jsrdirect"; break;
837 case O_gpdisp: name = "O_gpdisp"; break;
838 case O_gprelhigh: name = "O_gprelhigh"; break;
839 case O_gprellow: name = "O_gprellow"; break;
840 case O_gprel: name = "O_gprel"; break;
841 case O_samegp: name = "O_samegp"; break;
842 case O_tlsgd: name = "O_tlsgd"; break;
843 case O_tlsldm: name = "O_tlsldm"; break;
844 case O_gotdtprel: name = "O_gotdtprel"; break;
845 case O_dtprelhi: name = "O_dtprelhi"; break;
846 case O_dtprello: name = "O_dtprello"; break;
847 case O_dtprel: name = "O_dtprel"; break;
848 case O_gottprel: name = "O_gottprel"; break;
849 case O_tprelhi: name = "O_tprelhi"; break;
850 case O_tprello: name = "O_tprello"; break;
851 case O_tprel: name = "O_tprel"; break;
854 fprintf (stderr, ", %s(%s, %s, %d)", name,
855 (t->X_add_symbol) ? S_GET_NAME (t->X_add_symbol) : "--",
856 (t->X_op_symbol) ? S_GET_NAME (t->X_op_symbol) : "--",
857 (int) t->X_add_number);
859 fprintf (stderr, "\n");
860 fflush (stderr);
862 #endif
864 /* Parse the arguments to an opcode. */
866 static int
867 tokenize_arguments (char *str,
868 expressionS tok[],
869 int ntok)
871 expressionS *end_tok = tok + ntok;
872 char *old_input_line_pointer;
873 int saw_comma = 0, saw_arg = 0;
874 #ifdef DEBUG_ALPHA
875 expressionS *orig_tok = tok;
876 #endif
877 #ifdef RELOC_OP_P
878 char *p;
879 const struct alpha_reloc_op_tag *r;
880 int c, i;
881 size_t len;
882 int reloc_found_p = 0;
883 #endif
885 memset (tok, 0, sizeof (*tok) * ntok);
887 /* Save and restore input_line_pointer around this function. */
888 old_input_line_pointer = input_line_pointer;
889 input_line_pointer = str;
891 #ifdef RELOC_OP_P
892 /* ??? Wrest control of ! away from the regular expression parser. */
893 is_end_of_line[(unsigned char) '!'] = 1;
894 #endif
896 while (tok < end_tok && *input_line_pointer)
898 SKIP_WHITESPACE ();
899 switch (*input_line_pointer)
901 case '\0':
902 goto fini;
904 #ifdef RELOC_OP_P
905 case '!':
906 /* A relocation operand can be placed after the normal operand on an
907 assembly language statement, and has the following form:
908 !relocation_type!sequence_number. */
909 if (reloc_found_p)
911 /* Only support one relocation op per insn. */
912 as_bad (_("More than one relocation op per insn"));
913 goto err_report;
916 if (!saw_arg)
917 goto err;
919 ++input_line_pointer;
920 SKIP_WHITESPACE ();
921 p = input_line_pointer;
922 c = get_symbol_end ();
924 /* Parse !relocation_type. */
925 len = input_line_pointer - p;
926 if (len == 0)
928 as_bad (_("No relocation operand"));
929 goto err_report;
932 r = &alpha_reloc_op[0];
933 for (i = alpha_num_reloc_op - 1; i >= 0; i--, r++)
934 if (len == r->length && memcmp (p, r->name, len) == 0)
935 break;
936 if (i < 0)
938 as_bad (_("Unknown relocation operand: !%s"), p);
939 goto err_report;
942 *input_line_pointer = c;
943 SKIP_WHITESPACE ();
944 if (*input_line_pointer != '!')
946 if (r->require_seq)
948 as_bad (_("no sequence number after !%s"), p);
949 goto err_report;
952 tok->X_add_number = 0;
954 else
956 if (! r->allow_seq)
958 as_bad (_("!%s does not use a sequence number"), p);
959 goto err_report;
962 input_line_pointer++;
964 /* Parse !sequence_number. */
965 expression (tok);
966 if (tok->X_op != O_constant || tok->X_add_number <= 0)
968 as_bad (_("Bad sequence number: !%s!%s"),
969 r->name, input_line_pointer);
970 goto err_report;
974 tok->X_op = r->op;
975 reloc_found_p = 1;
976 ++tok;
977 break;
978 #endif /* RELOC_OP_P */
980 case ',':
981 ++input_line_pointer;
982 if (saw_comma || !saw_arg)
983 goto err;
984 saw_comma = 1;
985 break;
987 case '(':
989 char *hold = input_line_pointer++;
991 /* First try for parenthesized register ... */
992 expression (tok);
993 if (*input_line_pointer == ')' && tok->X_op == O_register)
995 tok->X_op = (saw_comma ? O_cpregister : O_pregister);
996 saw_comma = 0;
997 saw_arg = 1;
998 ++input_line_pointer;
999 ++tok;
1000 break;
1003 /* ... then fall through to plain expression. */
1004 input_line_pointer = hold;
1007 default:
1008 if (saw_arg && !saw_comma)
1009 goto err;
1011 expression (tok);
1012 if (tok->X_op == O_illegal || tok->X_op == O_absent)
1013 goto err;
1015 saw_comma = 0;
1016 saw_arg = 1;
1017 ++tok;
1018 break;
1022 fini:
1023 if (saw_comma)
1024 goto err;
1025 input_line_pointer = old_input_line_pointer;
1027 #ifdef DEBUG_ALPHA
1028 debug_exp (orig_tok, ntok - (end_tok - tok));
1029 #endif
1030 #ifdef RELOC_OP_P
1031 is_end_of_line[(unsigned char) '!'] = 0;
1032 #endif
1034 return ntok - (end_tok - tok);
1036 err:
1037 #ifdef RELOC_OP_P
1038 is_end_of_line[(unsigned char) '!'] = 0;
1039 #endif
1040 input_line_pointer = old_input_line_pointer;
1041 return TOKENIZE_ERROR;
1043 #ifdef RELOC_OP_P
1044 err_report:
1045 is_end_of_line[(unsigned char) '!'] = 0;
1046 #endif
1047 input_line_pointer = old_input_line_pointer;
1048 return TOKENIZE_ERROR_REPORT;
1051 /* Search forward through all variants of an opcode looking for a
1052 syntax match. */
1054 static const struct alpha_opcode *
1055 find_opcode_match (const struct alpha_opcode *first_opcode,
1056 const expressionS *tok,
1057 int *pntok,
1058 int *pcpumatch)
1060 const struct alpha_opcode *opcode = first_opcode;
1061 int ntok = *pntok;
1062 int got_cpu_match = 0;
1066 const unsigned char *opidx;
1067 int tokidx = 0;
1069 /* Don't match opcodes that don't exist on this architecture. */
1070 if (!(opcode->flags & alpha_target))
1071 goto match_failed;
1073 got_cpu_match = 1;
1075 for (opidx = opcode->operands; *opidx; ++opidx)
1077 const struct alpha_operand *operand = &alpha_operands[*opidx];
1079 /* Only take input from real operands. */
1080 if (operand->flags & AXP_OPERAND_FAKE)
1081 continue;
1083 /* When we expect input, make sure we have it. */
1084 if (tokidx >= ntok)
1086 if ((operand->flags & AXP_OPERAND_OPTIONAL_MASK) == 0)
1087 goto match_failed;
1088 continue;
1091 /* Match operand type with expression type. */
1092 switch (operand->flags & AXP_OPERAND_TYPECHECK_MASK)
1094 case AXP_OPERAND_IR:
1095 if (tok[tokidx].X_op != O_register
1096 || !is_ir_num (tok[tokidx].X_add_number))
1097 goto match_failed;
1098 break;
1099 case AXP_OPERAND_FPR:
1100 if (tok[tokidx].X_op != O_register
1101 || !is_fpr_num (tok[tokidx].X_add_number))
1102 goto match_failed;
1103 break;
1104 case AXP_OPERAND_IR | AXP_OPERAND_PARENS:
1105 if (tok[tokidx].X_op != O_pregister
1106 || !is_ir_num (tok[tokidx].X_add_number))
1107 goto match_failed;
1108 break;
1109 case AXP_OPERAND_IR | AXP_OPERAND_PARENS | AXP_OPERAND_COMMA:
1110 if (tok[tokidx].X_op != O_cpregister
1111 || !is_ir_num (tok[tokidx].X_add_number))
1112 goto match_failed;
1113 break;
1115 case AXP_OPERAND_RELATIVE:
1116 case AXP_OPERAND_SIGNED:
1117 case AXP_OPERAND_UNSIGNED:
1118 switch (tok[tokidx].X_op)
1120 case O_illegal:
1121 case O_absent:
1122 case O_register:
1123 case O_pregister:
1124 case O_cpregister:
1125 goto match_failed;
1127 default:
1128 break;
1130 break;
1132 default:
1133 /* Everything else should have been fake. */
1134 abort ();
1136 ++tokidx;
1139 /* Possible match -- did we use all of our input? */
1140 if (tokidx == ntok)
1142 *pntok = ntok;
1143 return opcode;
1146 match_failed:;
1148 while (++opcode - alpha_opcodes < (int) alpha_num_opcodes
1149 && !strcmp (opcode->name, first_opcode->name));
1151 if (*pcpumatch)
1152 *pcpumatch = got_cpu_match;
1154 return NULL;
1157 /* Given an opcode name and a pre-tokenized set of arguments, assemble
1158 the insn, but do not emit it.
1160 Note that this implies no macros allowed, since we can't store more
1161 than one insn in an insn structure. */
1163 static void
1164 assemble_tokens_to_insn (const char *opname,
1165 const expressionS *tok,
1166 int ntok,
1167 struct alpha_insn *insn)
1169 const struct alpha_opcode *opcode;
1171 /* Search opcodes. */
1172 opcode = (const struct alpha_opcode *) hash_find (alpha_opcode_hash, opname);
1173 if (opcode)
1175 int cpumatch;
1176 opcode = find_opcode_match (opcode, tok, &ntok, &cpumatch);
1177 if (opcode)
1179 assemble_insn (opcode, tok, ntok, insn, BFD_RELOC_UNUSED);
1180 return;
1182 else if (cpumatch)
1183 as_bad (_("inappropriate arguments for opcode `%s'"), opname);
1184 else
1185 as_bad (_("opcode `%s' not supported for target %s"), opname,
1186 alpha_target_name);
1188 else
1189 as_bad (_("unknown opcode `%s'"), opname);
1192 /* Build a BFD section with its flags set appropriately for the .lita,
1193 .lit8, or .lit4 sections. */
1195 static void
1196 create_literal_section (const char *name,
1197 segT *secp,
1198 symbolS **symp)
1200 segT current_section = now_seg;
1201 int current_subsec = now_subseg;
1202 segT new_sec;
1204 *secp = new_sec = subseg_new (name, 0);
1205 subseg_set (current_section, current_subsec);
1206 bfd_set_section_alignment (stdoutput, new_sec, 4);
1207 bfd_set_section_flags (stdoutput, new_sec,
1208 SEC_RELOC | SEC_ALLOC | SEC_LOAD | SEC_READONLY
1209 | SEC_DATA);
1211 S_CLEAR_EXTERNAL (*symp = section_symbol (new_sec));
1214 /* Load a (partial) expression into a target register.
1216 If poffset is not null, after the call it will either contain
1217 O_constant 0, or a 16-bit offset appropriate for any MEM format
1218 instruction. In addition, pbasereg will be modified to point to
1219 the base register to use in that MEM format instruction.
1221 In any case, *pbasereg should contain a base register to add to the
1222 expression. This will normally be either AXP_REG_ZERO or
1223 alpha_gp_register. Symbol addresses will always be loaded via $gp,
1224 so "foo($0)" is interpreted as adding the address of foo to $0;
1225 i.e. "ldq $targ, LIT($gp); addq $targ, $0, $targ". Odd, perhaps,
1226 but this is what OSF/1 does.
1228 If explicit relocations of the form !literal!<number> are allowed,
1229 and used, then explicit_reloc with be an expression pointer.
1231 Finally, the return value is nonzero if the calling macro may emit
1232 a LITUSE reloc if otherwise appropriate; the return value is the
1233 sequence number to use. */
1235 static long
1236 load_expression (int targreg,
1237 const expressionS *exp,
1238 int *pbasereg,
1239 expressionS *poffset,
1240 const char *opname)
1242 long emit_lituse = 0;
1243 offsetT addend = exp->X_add_number;
1244 int basereg = *pbasereg;
1245 struct alpha_insn insn;
1246 expressionS newtok[3];
1248 switch (exp->X_op)
1250 case O_symbol:
1252 #ifdef OBJ_ECOFF
1253 offsetT lit;
1255 /* Attempt to reduce .lit load by splitting the offset from
1256 its symbol when possible, but don't create a situation in
1257 which we'd fail. */
1258 if (!range_signed_32 (addend) &&
1259 (alpha_noat_on || targreg == AXP_REG_AT))
1261 lit = add_to_literal_pool (exp->X_add_symbol, addend,
1262 alpha_lita_section, 8);
1263 addend = 0;
1265 else
1266 lit = add_to_literal_pool (exp->X_add_symbol, 0,
1267 alpha_lita_section, 8);
1269 if (lit >= 0x8000)
1270 as_fatal (_("overflow in literal (.lita) table"));
1272 /* Emit "ldq r, lit(gp)". */
1274 if (basereg != alpha_gp_register && targreg == basereg)
1276 if (alpha_noat_on)
1277 as_bad (_("macro requires $at register while noat in effect"));
1278 if (targreg == AXP_REG_AT)
1279 as_bad (_("macro requires $at while $at in use"));
1281 set_tok_reg (newtok[0], AXP_REG_AT);
1283 else
1284 set_tok_reg (newtok[0], targreg);
1286 set_tok_sym (newtok[1], alpha_lita_symbol, lit);
1287 set_tok_preg (newtok[2], alpha_gp_register);
1289 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
1291 gas_assert (insn.nfixups == 1);
1292 insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITERAL;
1293 insn.sequence = emit_lituse = next_sequence_num--;
1294 #endif /* OBJ_ECOFF */
1295 #ifdef OBJ_ELF
1296 /* Emit "ldq r, gotoff(gp)". */
1298 if (basereg != alpha_gp_register && targreg == basereg)
1300 if (alpha_noat_on)
1301 as_bad (_("macro requires $at register while noat in effect"));
1302 if (targreg == AXP_REG_AT)
1303 as_bad (_("macro requires $at while $at in use"));
1305 set_tok_reg (newtok[0], AXP_REG_AT);
1307 else
1308 set_tok_reg (newtok[0], targreg);
1310 /* XXX: Disable this .got minimizing optimization so that we can get
1311 better instruction offset knowledge in the compiler. This happens
1312 very infrequently anyway. */
1313 if (1
1314 || (!range_signed_32 (addend)
1315 && (alpha_noat_on || targreg == AXP_REG_AT)))
1317 newtok[1] = *exp;
1318 addend = 0;
1320 else
1321 set_tok_sym (newtok[1], exp->X_add_symbol, 0);
1323 set_tok_preg (newtok[2], alpha_gp_register);
1325 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
1327 gas_assert (insn.nfixups == 1);
1328 insn.fixups[0].reloc = BFD_RELOC_ALPHA_ELF_LITERAL;
1329 insn.sequence = emit_lituse = next_sequence_num--;
1330 #endif /* OBJ_ELF */
1331 #ifdef OBJ_EVAX
1332 /* Find symbol or symbol pointer in link section. */
1334 if (exp->X_add_symbol == alpha_evax_proc->symbol)
1336 if (range_signed_16 (addend))
1338 set_tok_reg (newtok[0], targreg);
1339 set_tok_const (newtok[1], addend);
1340 set_tok_preg (newtok[2], basereg);
1341 assemble_tokens_to_insn ("lda", newtok, 3, &insn);
1342 addend = 0;
1344 else
1346 set_tok_reg (newtok[0], targreg);
1347 set_tok_const (newtok[1], 0);
1348 set_tok_preg (newtok[2], basereg);
1349 assemble_tokens_to_insn ("lda", newtok, 3, &insn);
1352 else
1354 const char *symname = S_GET_NAME (exp->X_add_symbol);
1355 const char *ptr1, *ptr2;
1356 int symlen = strlen (symname);
1358 if ((symlen > 4 &&
1359 strcmp (ptr2 = &symname [symlen - 4], "..lk") == 0))
1361 set_tok_reg (newtok[0], targreg);
1363 newtok[1] = *exp;
1364 newtok[1].X_op = O_subtract;
1365 newtok[1].X_op_symbol = alpha_evax_proc->symbol;
1367 set_tok_preg (newtok[2], basereg);
1368 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
1369 alpha_linkage_symbol = exp->X_add_symbol;
1371 if (poffset)
1372 set_tok_const (*poffset, 0);
1374 if (alpha_flag_replace && targreg == 26)
1376 char *ensymname;
1377 symbolS *ensym;
1378 volatile asymbol *dummy;
1380 ptr1 = strstr (symname, "..") + 2;
1381 if (ptr1 > ptr2)
1382 ptr1 = symname;
1383 ensymname = (char *) xmalloc (ptr2 - ptr1 + 5);
1384 memcpy (ensymname, ptr1, ptr2 - ptr1);
1385 memcpy (ensymname + (ptr2 - ptr1), "..en", 5);
1387 gas_assert (insn.nfixups + 1 <= MAX_INSN_FIXUPS);
1388 insn.fixups[insn.nfixups].reloc = BFD_RELOC_ALPHA_NOP;
1389 ensym = symbol_find_or_make (ensymname);
1390 ensym->sy_used = 1;
1391 /* The fixup must be the same as the BFD_RELOC_ALPHA_BOH
1392 case in emit_jsrjmp. See B.4.5.2 of the OpenVMS Linker
1393 Utility Manual. */
1394 insn.fixups[insn.nfixups].exp.X_op = O_symbol;
1395 insn.fixups[insn.nfixups].exp.X_add_symbol = ensym;
1396 insn.fixups[insn.nfixups].exp.X_add_number = 0;
1397 insn.fixups[insn.nfixups].xtrasym = alpha_linkage_symbol;
1398 insn.fixups[insn.nfixups].procsym = alpha_evax_proc->symbol;
1399 insn.nfixups++;
1401 /* ??? Force bsym to be instantiated now, as it will be
1402 too late to do so in tc_gen_reloc. */
1403 dummy = symbol_get_bfdsym (exp->X_add_symbol);
1405 else if (alpha_flag_replace && targreg == 27)
1407 char *psymname;
1408 symbolS *psym;
1410 ptr1 = strstr (symname, "..") + 2;
1411 if (ptr1 > ptr2)
1412 ptr1 = symname;
1413 psymname = (char *) xmalloc (ptr2 - ptr1 + 1);
1414 memcpy (psymname, ptr1, ptr2 - ptr1);
1415 psymname [ptr2 - ptr1] = 0;
1416 gas_assert (insn.nfixups + 1 <= MAX_INSN_FIXUPS);
1417 insn.fixups[insn.nfixups].reloc = BFD_RELOC_ALPHA_LDA;
1418 psym = symbol_find_or_make (psymname);
1419 psym->sy_used = 1;
1420 insn.fixups[insn.nfixups].exp.X_op = O_subtract;
1421 insn.fixups[insn.nfixups].exp.X_add_symbol = psym;
1422 insn.fixups[insn.nfixups].exp.X_op_symbol = alpha_evax_proc->symbol;
1423 insn.fixups[insn.nfixups].exp.X_add_number = 0;
1424 insn.fixups[insn.nfixups].xtrasym = alpha_linkage_symbol;
1425 insn.fixups[insn.nfixups].procsym = alpha_evax_proc->symbol;
1426 insn.nfixups++;
1429 emit_insn(&insn);
1430 return 0;
1432 else
1434 symbolS *linkexp;
1436 if (!range_signed_32 (addend))
1437 addend = sign_extend_32 (addend);
1438 linkexp = add_to_link_pool (alpha_evax_proc->symbol,
1439 exp->X_add_symbol, 0);
1440 set_tok_reg (newtok[0], targreg);
1441 set_tok_sym (newtok[1], linkexp, 0);
1442 set_tok_preg (newtok[2], basereg);
1443 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
1446 #endif /* OBJ_EVAX */
1448 emit_insn (&insn);
1450 #ifndef OBJ_EVAX
1451 if (basereg != alpha_gp_register && basereg != AXP_REG_ZERO)
1453 /* Emit "addq r, base, r". */
1455 set_tok_reg (newtok[1], basereg);
1456 set_tok_reg (newtok[2], targreg);
1457 assemble_tokens ("addq", newtok, 3, 0);
1459 #endif
1460 basereg = targreg;
1462 break;
1464 case O_constant:
1465 break;
1467 case O_subtract:
1468 /* Assume that this difference expression will be resolved to an
1469 absolute value and that that value will fit in 16 bits. */
1471 set_tok_reg (newtok[0], targreg);
1472 newtok[1] = *exp;
1473 set_tok_preg (newtok[2], basereg);
1474 assemble_tokens (opname, newtok, 3, 0);
1476 if (poffset)
1477 set_tok_const (*poffset, 0);
1478 return 0;
1480 case O_big:
1481 if (exp->X_add_number > 0)
1482 as_bad (_("bignum invalid; zero assumed"));
1483 else
1484 as_bad (_("floating point number invalid; zero assumed"));
1485 addend = 0;
1486 break;
1488 default:
1489 as_bad (_("can't handle expression"));
1490 addend = 0;
1491 break;
1494 if (!range_signed_32 (addend))
1496 #ifdef OBJ_EVAX
1497 symbolS *litexp;
1498 #else
1499 offsetT lit;
1500 long seq_num = next_sequence_num--;
1501 #endif
1503 /* For 64-bit addends, just put it in the literal pool. */
1504 #ifdef OBJ_EVAX
1505 /* Emit "ldq targreg, lit(basereg)". */
1506 litexp = add_to_link_pool (alpha_evax_proc->symbol,
1507 section_symbol (absolute_section), addend);
1508 set_tok_reg (newtok[0], targreg);
1509 set_tok_sym (newtok[1], litexp, 0);
1510 set_tok_preg (newtok[2], alpha_gp_register);
1511 assemble_tokens ("ldq", newtok, 3, 0);
1512 #else
1514 if (alpha_lit8_section == NULL)
1516 create_literal_section (".lit8",
1517 &alpha_lit8_section,
1518 &alpha_lit8_symbol);
1520 #ifdef OBJ_ECOFF
1521 alpha_lit8_literal = add_to_literal_pool (alpha_lit8_symbol, 0x8000,
1522 alpha_lita_section, 8);
1523 if (alpha_lit8_literal >= 0x8000)
1524 as_fatal (_("overflow in literal (.lita) table"));
1525 #endif
1528 lit = add_to_literal_pool (NULL, addend, alpha_lit8_section, 8) - 0x8000;
1529 if (lit >= 0x8000)
1530 as_fatal (_("overflow in literal (.lit8) table"));
1532 /* Emit "lda litreg, .lit8+0x8000". */
1534 if (targreg == basereg)
1536 if (alpha_noat_on)
1537 as_bad (_("macro requires $at register while noat in effect"));
1538 if (targreg == AXP_REG_AT)
1539 as_bad (_("macro requires $at while $at in use"));
1541 set_tok_reg (newtok[0], AXP_REG_AT);
1543 else
1544 set_tok_reg (newtok[0], targreg);
1545 #ifdef OBJ_ECOFF
1546 set_tok_sym (newtok[1], alpha_lita_symbol, alpha_lit8_literal);
1547 #endif
1548 #ifdef OBJ_ELF
1549 set_tok_sym (newtok[1], alpha_lit8_symbol, 0x8000);
1550 #endif
1551 set_tok_preg (newtok[2], alpha_gp_register);
1553 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
1555 gas_assert (insn.nfixups == 1);
1556 #ifdef OBJ_ECOFF
1557 insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITERAL;
1558 #endif
1559 #ifdef OBJ_ELF
1560 insn.fixups[0].reloc = BFD_RELOC_ALPHA_ELF_LITERAL;
1561 #endif
1562 insn.sequence = seq_num;
1564 emit_insn (&insn);
1566 /* Emit "ldq litreg, lit(litreg)". */
1568 set_tok_const (newtok[1], lit);
1569 set_tok_preg (newtok[2], newtok[0].X_add_number);
1571 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
1573 gas_assert (insn.nfixups < MAX_INSN_FIXUPS);
1574 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
1575 insn.fixups[insn.nfixups].exp.X_op = O_absent;
1576 insn.nfixups++;
1577 insn.sequence = seq_num;
1578 emit_lituse = 0;
1580 emit_insn (&insn);
1582 /* Emit "addq litreg, base, target". */
1584 if (basereg != AXP_REG_ZERO)
1586 set_tok_reg (newtok[1], basereg);
1587 set_tok_reg (newtok[2], targreg);
1588 assemble_tokens ("addq", newtok, 3, 0);
1590 #endif /* !OBJ_EVAX */
1592 if (poffset)
1593 set_tok_const (*poffset, 0);
1594 *pbasereg = targreg;
1596 else
1598 offsetT low, high, extra, tmp;
1600 /* For 32-bit operands, break up the addend. */
1602 low = sign_extend_16 (addend);
1603 tmp = addend - low;
1604 high = sign_extend_16 (tmp >> 16);
1606 if (tmp - (high << 16))
1608 extra = 0x4000;
1609 tmp -= 0x40000000;
1610 high = sign_extend_16 (tmp >> 16);
1612 else
1613 extra = 0;
1615 set_tok_reg (newtok[0], targreg);
1616 set_tok_preg (newtok[2], basereg);
1618 if (extra)
1620 /* Emit "ldah r, extra(r). */
1621 set_tok_const (newtok[1], extra);
1622 assemble_tokens ("ldah", newtok, 3, 0);
1623 set_tok_preg (newtok[2], basereg = targreg);
1626 if (high)
1628 /* Emit "ldah r, high(r). */
1629 set_tok_const (newtok[1], high);
1630 assemble_tokens ("ldah", newtok, 3, 0);
1631 basereg = targreg;
1632 set_tok_preg (newtok[2], basereg);
1635 if ((low && !poffset) || (!poffset && basereg != targreg))
1637 /* Emit "lda r, low(base)". */
1638 set_tok_const (newtok[1], low);
1639 assemble_tokens ("lda", newtok, 3, 0);
1640 basereg = targreg;
1641 low = 0;
1644 if (poffset)
1645 set_tok_const (*poffset, low);
1646 *pbasereg = basereg;
1649 return emit_lituse;
1652 /* The lda macro differs from the lda instruction in that it handles
1653 most simple expressions, particularly symbol address loads and
1654 large constants. */
1656 static void
1657 emit_lda (const expressionS *tok,
1658 int ntok,
1659 const void * unused ATTRIBUTE_UNUSED)
1661 int basereg;
1663 if (ntok == 2)
1664 basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
1665 else
1666 basereg = tok[2].X_add_number;
1668 (void) load_expression (tok[0].X_add_number, &tok[1], &basereg, NULL, "lda");
1671 /* The ldah macro differs from the ldah instruction in that it has $31
1672 as an implied base register. */
1674 static void
1675 emit_ldah (const expressionS *tok,
1676 int ntok ATTRIBUTE_UNUSED,
1677 const void * unused ATTRIBUTE_UNUSED)
1679 expressionS newtok[3];
1681 newtok[0] = tok[0];
1682 newtok[1] = tok[1];
1683 set_tok_preg (newtok[2], AXP_REG_ZERO);
1685 assemble_tokens ("ldah", newtok, 3, 0);
1688 /* Called internally to handle all alignment needs. This takes care
1689 of eliding calls to frag_align if'n the cached current alignment
1690 says we've already got it, as well as taking care of the auto-align
1691 feature wrt labels. */
1693 static void
1694 alpha_align (int n,
1695 char *pfill,
1696 symbolS *label,
1697 int force ATTRIBUTE_UNUSED)
1699 if (alpha_current_align >= n)
1700 return;
1702 if (pfill == NULL)
1704 if (subseg_text_p (now_seg))
1705 frag_align_code (n, 0);
1706 else
1707 frag_align (n, 0, 0);
1709 else
1710 frag_align (n, *pfill, 0);
1712 alpha_current_align = n;
1714 if (label != NULL && S_GET_SEGMENT (label) == now_seg)
1716 symbol_set_frag (label, frag_now);
1717 S_SET_VALUE (label, (valueT) frag_now_fix ());
1720 record_alignment (now_seg, n);
1722 /* ??? If alpha_flag_relax && force && elf, record the requested alignment
1723 in a reloc for the linker to see. */
1726 /* Actually output an instruction with its fixup. */
1728 static void
1729 emit_insn (struct alpha_insn *insn)
1731 char *f;
1732 int i;
1734 /* Take care of alignment duties. */
1735 if (alpha_auto_align_on && alpha_current_align < 2)
1736 alpha_align (2, (char *) NULL, alpha_insn_label, 0);
1737 if (alpha_current_align > 2)
1738 alpha_current_align = 2;
1739 alpha_insn_label = NULL;
1741 /* Write out the instruction. */
1742 f = frag_more (4);
1743 md_number_to_chars (f, insn->insn, 4);
1745 #ifdef OBJ_ELF
1746 dwarf2_emit_insn (4);
1747 #endif
1749 /* Apply the fixups in order. */
1750 for (i = 0; i < insn->nfixups; ++i)
1752 const struct alpha_operand *operand = (const struct alpha_operand *) 0;
1753 struct alpha_fixup *fixup = &insn->fixups[i];
1754 struct alpha_reloc_tag *info = NULL;
1755 int size, pcrel;
1756 fixS *fixP;
1758 /* Some fixups are only used internally and so have no howto. */
1759 if ((int) fixup->reloc < 0)
1761 operand = &alpha_operands[-(int) fixup->reloc];
1762 size = 4;
1763 pcrel = ((operand->flags & AXP_OPERAND_RELATIVE) != 0);
1765 else if (fixup->reloc > BFD_RELOC_UNUSED
1766 || fixup->reloc == BFD_RELOC_ALPHA_GPDISP_HI16
1767 || fixup->reloc == BFD_RELOC_ALPHA_GPDISP_LO16)
1769 size = 2;
1770 pcrel = 0;
1772 else
1774 reloc_howto_type *reloc_howto =
1775 bfd_reloc_type_lookup (stdoutput,
1776 (bfd_reloc_code_real_type) fixup->reloc);
1777 gas_assert (reloc_howto);
1779 size = bfd_get_reloc_size (reloc_howto);
1781 switch (fixup->reloc)
1783 #ifdef OBJ_EVAX
1784 case BFD_RELOC_ALPHA_NOP:
1785 case BFD_RELOC_ALPHA_BSR:
1786 case BFD_RELOC_ALPHA_LDA:
1787 case BFD_RELOC_ALPHA_BOH:
1788 break;
1789 #endif
1790 default:
1791 gas_assert (size >= 1 && size <= 4);
1794 pcrel = reloc_howto->pc_relative;
1797 fixP = fix_new_exp (frag_now, f - frag_now->fr_literal, size,
1798 &fixup->exp, pcrel, (bfd_reloc_code_real_type) fixup->reloc);
1800 /* Turn off complaints that the addend is too large for some fixups,
1801 and copy in the sequence number for the explicit relocations. */
1802 switch (fixup->reloc)
1804 case BFD_RELOC_ALPHA_HINT:
1805 case BFD_RELOC_GPREL32:
1806 case BFD_RELOC_GPREL16:
1807 case BFD_RELOC_ALPHA_GPREL_HI16:
1808 case BFD_RELOC_ALPHA_GPREL_LO16:
1809 case BFD_RELOC_ALPHA_GOTDTPREL16:
1810 case BFD_RELOC_ALPHA_DTPREL_HI16:
1811 case BFD_RELOC_ALPHA_DTPREL_LO16:
1812 case BFD_RELOC_ALPHA_DTPREL16:
1813 case BFD_RELOC_ALPHA_GOTTPREL16:
1814 case BFD_RELOC_ALPHA_TPREL_HI16:
1815 case BFD_RELOC_ALPHA_TPREL_LO16:
1816 case BFD_RELOC_ALPHA_TPREL16:
1817 fixP->fx_no_overflow = 1;
1818 break;
1820 case BFD_RELOC_ALPHA_GPDISP_HI16:
1821 fixP->fx_no_overflow = 1;
1822 fixP->fx_addsy = section_symbol (now_seg);
1823 fixP->fx_offset = 0;
1825 info = get_alpha_reloc_tag (insn->sequence);
1826 if (++info->n_master > 1)
1827 as_bad (_("too many ldah insns for !gpdisp!%ld"), insn->sequence);
1828 if (info->segment != now_seg)
1829 as_bad (_("both insns for !gpdisp!%ld must be in the same section"),
1830 insn->sequence);
1831 fixP->tc_fix_data.info = info;
1832 break;
1834 case BFD_RELOC_ALPHA_GPDISP_LO16:
1835 fixP->fx_no_overflow = 1;
1837 info = get_alpha_reloc_tag (insn->sequence);
1838 if (++info->n_slaves > 1)
1839 as_bad (_("too many lda insns for !gpdisp!%ld"), insn->sequence);
1840 if (info->segment != now_seg)
1841 as_bad (_("both insns for !gpdisp!%ld must be in the same section"),
1842 insn->sequence);
1843 fixP->tc_fix_data.info = info;
1844 info->slaves = fixP;
1845 break;
1847 case BFD_RELOC_ALPHA_LITERAL:
1848 case BFD_RELOC_ALPHA_ELF_LITERAL:
1849 fixP->fx_no_overflow = 1;
1851 if (insn->sequence == 0)
1852 break;
1853 info = get_alpha_reloc_tag (insn->sequence);
1854 info->master = fixP;
1855 info->n_master++;
1856 if (info->segment != now_seg)
1857 info->multi_section_p = 1;
1858 fixP->tc_fix_data.info = info;
1859 break;
1861 #ifdef RELOC_OP_P
1862 case DUMMY_RELOC_LITUSE_ADDR:
1863 fixP->fx_offset = LITUSE_ALPHA_ADDR;
1864 goto do_lituse;
1865 case DUMMY_RELOC_LITUSE_BASE:
1866 fixP->fx_offset = LITUSE_ALPHA_BASE;
1867 goto do_lituse;
1868 case DUMMY_RELOC_LITUSE_BYTOFF:
1869 fixP->fx_offset = LITUSE_ALPHA_BYTOFF;
1870 goto do_lituse;
1871 case DUMMY_RELOC_LITUSE_JSR:
1872 fixP->fx_offset = LITUSE_ALPHA_JSR;
1873 goto do_lituse;
1874 case DUMMY_RELOC_LITUSE_TLSGD:
1875 fixP->fx_offset = LITUSE_ALPHA_TLSGD;
1876 goto do_lituse;
1877 case DUMMY_RELOC_LITUSE_TLSLDM:
1878 fixP->fx_offset = LITUSE_ALPHA_TLSLDM;
1879 goto do_lituse;
1880 case DUMMY_RELOC_LITUSE_JSRDIRECT:
1881 fixP->fx_offset = LITUSE_ALPHA_JSRDIRECT;
1882 goto do_lituse;
1883 do_lituse:
1884 fixP->fx_addsy = section_symbol (now_seg);
1885 fixP->fx_r_type = BFD_RELOC_ALPHA_LITUSE;
1887 info = get_alpha_reloc_tag (insn->sequence);
1888 if (fixup->reloc == DUMMY_RELOC_LITUSE_TLSGD)
1889 info->saw_lu_tlsgd = 1;
1890 else if (fixup->reloc == DUMMY_RELOC_LITUSE_TLSLDM)
1891 info->saw_lu_tlsldm = 1;
1892 if (++info->n_slaves > 1)
1894 if (info->saw_lu_tlsgd)
1895 as_bad (_("too many lituse insns for !lituse_tlsgd!%ld"),
1896 insn->sequence);
1897 else if (info->saw_lu_tlsldm)
1898 as_bad (_("too many lituse insns for !lituse_tlsldm!%ld"),
1899 insn->sequence);
1901 fixP->tc_fix_data.info = info;
1902 fixP->tc_fix_data.next_reloc = info->slaves;
1903 info->slaves = fixP;
1904 if (info->segment != now_seg)
1905 info->multi_section_p = 1;
1906 break;
1908 case BFD_RELOC_ALPHA_TLSGD:
1909 fixP->fx_no_overflow = 1;
1911 if (insn->sequence == 0)
1912 break;
1913 info = get_alpha_reloc_tag (insn->sequence);
1914 if (info->saw_tlsgd)
1915 as_bad (_("duplicate !tlsgd!%ld"), insn->sequence);
1916 else if (info->saw_tlsldm)
1917 as_bad (_("sequence number in use for !tlsldm!%ld"),
1918 insn->sequence);
1919 else
1920 info->saw_tlsgd = 1;
1921 fixP->tc_fix_data.info = info;
1922 break;
1924 case BFD_RELOC_ALPHA_TLSLDM:
1925 fixP->fx_no_overflow = 1;
1927 if (insn->sequence == 0)
1928 break;
1929 info = get_alpha_reloc_tag (insn->sequence);
1930 if (info->saw_tlsldm)
1931 as_bad (_("duplicate !tlsldm!%ld"), insn->sequence);
1932 else if (info->saw_tlsgd)
1933 as_bad (_("sequence number in use for !tlsgd!%ld"),
1934 insn->sequence);
1935 else
1936 info->saw_tlsldm = 1;
1937 fixP->tc_fix_data.info = info;
1938 break;
1939 #endif
1940 #ifdef OBJ_EVAX
1941 case BFD_RELOC_ALPHA_NOP:
1942 case BFD_RELOC_ALPHA_LDA:
1943 case BFD_RELOC_ALPHA_BSR:
1944 case BFD_RELOC_ALPHA_BOH:
1945 info = get_alpha_reloc_tag (next_sequence_num--);
1946 fixP->tc_fix_data.info = info;
1947 fixP->tc_fix_data.info->sym = fixup->xtrasym;
1948 fixP->tc_fix_data.info->psym = fixup->procsym;
1949 break;
1950 #endif
1952 default:
1953 if ((int) fixup->reloc < 0)
1955 if (operand->flags & AXP_OPERAND_NOOVERFLOW)
1956 fixP->fx_no_overflow = 1;
1958 break;
1963 /* Insert an operand value into an instruction. */
1965 static unsigned
1966 insert_operand (unsigned insn,
1967 const struct alpha_operand *operand,
1968 offsetT val,
1969 char *file,
1970 unsigned line)
1972 if (operand->bits != 32 && !(operand->flags & AXP_OPERAND_NOOVERFLOW))
1974 offsetT min, max;
1976 if (operand->flags & AXP_OPERAND_SIGNED)
1978 max = (1 << (operand->bits - 1)) - 1;
1979 min = -(1 << (operand->bits - 1));
1981 else
1983 max = (1 << operand->bits) - 1;
1984 min = 0;
1987 if (val < min || val > max)
1988 as_warn_value_out_of_range (_("operand"), val, min, max, file, line);
1991 if (operand->insert)
1993 const char *errmsg = NULL;
1995 insn = (*operand->insert) (insn, val, &errmsg);
1996 if (errmsg)
1997 as_warn ("%s", errmsg);
1999 else
2000 insn |= ((val & ((1 << operand->bits) - 1)) << operand->shift);
2002 return insn;
2005 /* Turn an opcode description and a set of arguments into
2006 an instruction and a fixup. */
2008 static void
2009 assemble_insn (const struct alpha_opcode *opcode,
2010 const expressionS *tok,
2011 int ntok,
2012 struct alpha_insn *insn,
2013 extended_bfd_reloc_code_real_type reloc)
2015 const struct alpha_operand *reloc_operand = NULL;
2016 const expressionS *reloc_exp = NULL;
2017 const unsigned char *argidx;
2018 unsigned image;
2019 int tokidx = 0;
2021 memset (insn, 0, sizeof (*insn));
2022 image = opcode->opcode;
2024 for (argidx = opcode->operands; *argidx; ++argidx)
2026 const struct alpha_operand *operand = &alpha_operands[*argidx];
2027 const expressionS *t = (const expressionS *) 0;
2029 if (operand->flags & AXP_OPERAND_FAKE)
2031 /* Fake operands take no value and generate no fixup. */
2032 image = insert_operand (image, operand, 0, NULL, 0);
2033 continue;
2036 if (tokidx >= ntok)
2038 switch (operand->flags & AXP_OPERAND_OPTIONAL_MASK)
2040 case AXP_OPERAND_DEFAULT_FIRST:
2041 t = &tok[0];
2042 break;
2043 case AXP_OPERAND_DEFAULT_SECOND:
2044 t = &tok[1];
2045 break;
2046 case AXP_OPERAND_DEFAULT_ZERO:
2048 static expressionS zero_exp;
2049 t = &zero_exp;
2050 zero_exp.X_op = O_constant;
2051 zero_exp.X_unsigned = 1;
2053 break;
2054 default:
2055 abort ();
2058 else
2059 t = &tok[tokidx++];
2061 switch (t->X_op)
2063 case O_register:
2064 case O_pregister:
2065 case O_cpregister:
2066 image = insert_operand (image, operand, regno (t->X_add_number),
2067 NULL, 0);
2068 break;
2070 case O_constant:
2071 image = insert_operand (image, operand, t->X_add_number, NULL, 0);
2072 gas_assert (reloc_operand == NULL);
2073 reloc_operand = operand;
2074 reloc_exp = t;
2075 break;
2077 default:
2078 /* This is only 0 for fields that should contain registers,
2079 which means this pattern shouldn't have matched. */
2080 if (operand->default_reloc == 0)
2081 abort ();
2083 /* There is one special case for which an insn receives two
2084 relocations, and thus the user-supplied reloc does not
2085 override the operand reloc. */
2086 if (operand->default_reloc == BFD_RELOC_ALPHA_HINT)
2088 struct alpha_fixup *fixup;
2090 if (insn->nfixups >= MAX_INSN_FIXUPS)
2091 as_fatal (_("too many fixups"));
2093 fixup = &insn->fixups[insn->nfixups++];
2094 fixup->exp = *t;
2095 fixup->reloc = BFD_RELOC_ALPHA_HINT;
2097 else
2099 if (reloc == BFD_RELOC_UNUSED)
2100 reloc = operand->default_reloc;
2102 gas_assert (reloc_operand == NULL);
2103 reloc_operand = operand;
2104 reloc_exp = t;
2106 break;
2110 if (reloc != BFD_RELOC_UNUSED)
2112 struct alpha_fixup *fixup;
2114 if (insn->nfixups >= MAX_INSN_FIXUPS)
2115 as_fatal (_("too many fixups"));
2117 /* ??? My but this is hacky. But the OSF/1 assembler uses the same
2118 relocation tag for both ldah and lda with gpdisp. Choose the
2119 correct internal relocation based on the opcode. */
2120 if (reloc == BFD_RELOC_ALPHA_GPDISP)
2122 if (strcmp (opcode->name, "ldah") == 0)
2123 reloc = BFD_RELOC_ALPHA_GPDISP_HI16;
2124 else if (strcmp (opcode->name, "lda") == 0)
2125 reloc = BFD_RELOC_ALPHA_GPDISP_LO16;
2126 else
2127 as_bad (_("invalid relocation for instruction"));
2130 /* If this is a real relocation (as opposed to a lituse hint), then
2131 the relocation width should match the operand width.
2132 Take care of -MDISP in operand table. */
2133 else if (reloc < BFD_RELOC_UNUSED && reloc > 0)
2135 reloc_howto_type *reloc_howto
2136 = bfd_reloc_type_lookup (stdoutput,
2137 (bfd_reloc_code_real_type) reloc);
2138 if (reloc_operand == NULL
2139 || reloc_howto->bitsize != reloc_operand->bits)
2141 as_bad (_("invalid relocation for field"));
2142 return;
2146 fixup = &insn->fixups[insn->nfixups++];
2147 if (reloc_exp)
2148 fixup->exp = *reloc_exp;
2149 else
2150 fixup->exp.X_op = O_absent;
2151 fixup->reloc = reloc;
2154 insn->insn = image;
2157 /* Handle all "simple" integer register loads -- ldq, ldq_l, ldq_u,
2158 etc. They differ from the real instructions in that they do simple
2159 expressions like the lda macro. */
2161 static void
2162 emit_ir_load (const expressionS *tok,
2163 int ntok,
2164 const void * opname)
2166 int basereg;
2167 long lituse;
2168 expressionS newtok[3];
2169 struct alpha_insn insn;
2170 const char *symname
2171 = tok[1].X_add_symbol ? S_GET_NAME (tok[1].X_add_symbol): "";
2172 int symlen = strlen (symname);
2174 if (ntok == 2)
2175 basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
2176 else
2177 basereg = tok[2].X_add_number;
2179 lituse = load_expression (tok[0].X_add_number, &tok[1],
2180 &basereg, &newtok[1], (const char *) opname);
2182 if (basereg == alpha_gp_register &&
2183 (symlen > 4 && strcmp (&symname [symlen - 4], "..lk") == 0))
2184 return;
2186 newtok[0] = tok[0];
2187 set_tok_preg (newtok[2], basereg);
2189 assemble_tokens_to_insn ((const char *) opname, newtok, 3, &insn);
2191 if (lituse)
2193 gas_assert (insn.nfixups < MAX_INSN_FIXUPS);
2194 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
2195 insn.fixups[insn.nfixups].exp.X_op = O_absent;
2196 insn.nfixups++;
2197 insn.sequence = lituse;
2200 emit_insn (&insn);
2203 /* Handle fp register loads, and both integer and fp register stores.
2204 Again, we handle simple expressions. */
2206 static void
2207 emit_loadstore (const expressionS *tok,
2208 int ntok,
2209 const void * opname)
2211 int basereg;
2212 long lituse;
2213 expressionS newtok[3];
2214 struct alpha_insn insn;
2216 if (ntok == 2)
2217 basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
2218 else
2219 basereg = tok[2].X_add_number;
2221 if (tok[1].X_op != O_constant || !range_signed_16 (tok[1].X_add_number))
2223 if (alpha_noat_on)
2224 as_bad (_("macro requires $at register while noat in effect"));
2226 lituse = load_expression (AXP_REG_AT, &tok[1],
2227 &basereg, &newtok[1], (const char *) opname);
2229 else
2231 newtok[1] = tok[1];
2232 lituse = 0;
2235 newtok[0] = tok[0];
2236 set_tok_preg (newtok[2], basereg);
2238 assemble_tokens_to_insn ((const char *) opname, newtok, 3, &insn);
2240 if (lituse)
2242 gas_assert (insn.nfixups < MAX_INSN_FIXUPS);
2243 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
2244 insn.fixups[insn.nfixups].exp.X_op = O_absent;
2245 insn.nfixups++;
2246 insn.sequence = lituse;
2249 emit_insn (&insn);
2252 /* Load a half-word or byte as an unsigned value. */
2254 static void
2255 emit_ldXu (const expressionS *tok,
2256 int ntok,
2257 const void * vlgsize)
2259 if (alpha_target & AXP_OPCODE_BWX)
2260 emit_ir_load (tok, ntok, ldXu_op[(long) vlgsize]);
2261 else
2263 expressionS newtok[3];
2264 struct alpha_insn insn;
2265 int basereg;
2266 long lituse;
2268 if (alpha_noat_on)
2269 as_bad (_("macro requires $at register while noat in effect"));
2271 if (ntok == 2)
2272 basereg = (tok[1].X_op == O_constant
2273 ? AXP_REG_ZERO : alpha_gp_register);
2274 else
2275 basereg = tok[2].X_add_number;
2277 /* Emit "lda $at, exp". */
2278 lituse = load_expression (AXP_REG_AT, &tok[1], &basereg, NULL, "lda");
2280 /* Emit "ldq_u targ, 0($at)". */
2281 newtok[0] = tok[0];
2282 set_tok_const (newtok[1], 0);
2283 set_tok_preg (newtok[2], basereg);
2284 assemble_tokens_to_insn ("ldq_u", newtok, 3, &insn);
2286 if (lituse)
2288 gas_assert (insn.nfixups < MAX_INSN_FIXUPS);
2289 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
2290 insn.fixups[insn.nfixups].exp.X_op = O_absent;
2291 insn.nfixups++;
2292 insn.sequence = lituse;
2295 emit_insn (&insn);
2297 /* Emit "extXl targ, $at, targ". */
2298 set_tok_reg (newtok[1], basereg);
2299 newtok[2] = newtok[0];
2300 assemble_tokens_to_insn (extXl_op[(long) vlgsize], newtok, 3, &insn);
2302 if (lituse)
2304 gas_assert (insn.nfixups < MAX_INSN_FIXUPS);
2305 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF;
2306 insn.fixups[insn.nfixups].exp.X_op = O_absent;
2307 insn.nfixups++;
2308 insn.sequence = lituse;
2311 emit_insn (&insn);
2315 /* Load a half-word or byte as a signed value. */
2317 static void
2318 emit_ldX (const expressionS *tok,
2319 int ntok,
2320 const void * vlgsize)
2322 emit_ldXu (tok, ntok, vlgsize);
2323 assemble_tokens (sextX_op[(long) vlgsize], tok, 1, 1);
2326 /* Load an integral value from an unaligned address as an unsigned
2327 value. */
2329 static void
2330 emit_uldXu (const expressionS *tok,
2331 int ntok,
2332 const void * vlgsize)
2334 long lgsize = (long) vlgsize;
2335 expressionS newtok[3];
2337 if (alpha_noat_on)
2338 as_bad (_("macro requires $at register while noat in effect"));
2340 /* Emit "lda $at, exp". */
2341 memcpy (newtok, tok, sizeof (expressionS) * ntok);
2342 newtok[0].X_add_number = AXP_REG_AT;
2343 assemble_tokens ("lda", newtok, ntok, 1);
2345 /* Emit "ldq_u $t9, 0($at)". */
2346 set_tok_reg (newtok[0], AXP_REG_T9);
2347 set_tok_const (newtok[1], 0);
2348 set_tok_preg (newtok[2], AXP_REG_AT);
2349 assemble_tokens ("ldq_u", newtok, 3, 1);
2351 /* Emit "ldq_u $t10, size-1($at)". */
2352 set_tok_reg (newtok[0], AXP_REG_T10);
2353 set_tok_const (newtok[1], (1 << lgsize) - 1);
2354 assemble_tokens ("ldq_u", newtok, 3, 1);
2356 /* Emit "extXl $t9, $at, $t9". */
2357 set_tok_reg (newtok[0], AXP_REG_T9);
2358 set_tok_reg (newtok[1], AXP_REG_AT);
2359 set_tok_reg (newtok[2], AXP_REG_T9);
2360 assemble_tokens (extXl_op[lgsize], newtok, 3, 1);
2362 /* Emit "extXh $t10, $at, $t10". */
2363 set_tok_reg (newtok[0], AXP_REG_T10);
2364 set_tok_reg (newtok[2], AXP_REG_T10);
2365 assemble_tokens (extXh_op[lgsize], newtok, 3, 1);
2367 /* Emit "or $t9, $t10, targ". */
2368 set_tok_reg (newtok[0], AXP_REG_T9);
2369 set_tok_reg (newtok[1], AXP_REG_T10);
2370 newtok[2] = tok[0];
2371 assemble_tokens ("or", newtok, 3, 1);
2374 /* Load an integral value from an unaligned address as a signed value.
2375 Note that quads should get funneled to the unsigned load since we
2376 don't have to do the sign extension. */
2378 static void
2379 emit_uldX (const expressionS *tok,
2380 int ntok,
2381 const void * vlgsize)
2383 emit_uldXu (tok, ntok, vlgsize);
2384 assemble_tokens (sextX_op[(long) vlgsize], tok, 1, 1);
2387 /* Implement the ldil macro. */
2389 static void
2390 emit_ldil (const expressionS *tok,
2391 int ntok,
2392 const void * unused ATTRIBUTE_UNUSED)
2394 expressionS newtok[2];
2396 memcpy (newtok, tok, sizeof (newtok));
2397 newtok[1].X_add_number = sign_extend_32 (tok[1].X_add_number);
2399 assemble_tokens ("lda", newtok, ntok, 1);
2402 /* Store a half-word or byte. */
2404 static void
2405 emit_stX (const expressionS *tok,
2406 int ntok,
2407 const void * vlgsize)
2409 int lgsize = (int) (long) vlgsize;
2411 if (alpha_target & AXP_OPCODE_BWX)
2412 emit_loadstore (tok, ntok, stX_op[lgsize]);
2413 else
2415 expressionS newtok[3];
2416 struct alpha_insn insn;
2417 int basereg;
2418 long lituse;
2420 if (alpha_noat_on)
2421 as_bad (_("macro requires $at register while noat in effect"));
2423 if (ntok == 2)
2424 basereg = (tok[1].X_op == O_constant
2425 ? AXP_REG_ZERO : alpha_gp_register);
2426 else
2427 basereg = tok[2].X_add_number;
2429 /* Emit "lda $at, exp". */
2430 lituse = load_expression (AXP_REG_AT, &tok[1], &basereg, NULL, "lda");
2432 /* Emit "ldq_u $t9, 0($at)". */
2433 set_tok_reg (newtok[0], AXP_REG_T9);
2434 set_tok_const (newtok[1], 0);
2435 set_tok_preg (newtok[2], basereg);
2436 assemble_tokens_to_insn ("ldq_u", newtok, 3, &insn);
2438 if (lituse)
2440 gas_assert (insn.nfixups < MAX_INSN_FIXUPS);
2441 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
2442 insn.fixups[insn.nfixups].exp.X_op = O_absent;
2443 insn.nfixups++;
2444 insn.sequence = lituse;
2447 emit_insn (&insn);
2449 /* Emit "insXl src, $at, $t10". */
2450 newtok[0] = tok[0];
2451 set_tok_reg (newtok[1], basereg);
2452 set_tok_reg (newtok[2], AXP_REG_T10);
2453 assemble_tokens_to_insn (insXl_op[lgsize], newtok, 3, &insn);
2455 if (lituse)
2457 gas_assert (insn.nfixups < MAX_INSN_FIXUPS);
2458 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF;
2459 insn.fixups[insn.nfixups].exp.X_op = O_absent;
2460 insn.nfixups++;
2461 insn.sequence = lituse;
2464 emit_insn (&insn);
2466 /* Emit "mskXl $t9, $at, $t9". */
2467 set_tok_reg (newtok[0], AXP_REG_T9);
2468 newtok[2] = newtok[0];
2469 assemble_tokens_to_insn (mskXl_op[lgsize], newtok, 3, &insn);
2471 if (lituse)
2473 gas_assert (insn.nfixups < MAX_INSN_FIXUPS);
2474 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF;
2475 insn.fixups[insn.nfixups].exp.X_op = O_absent;
2476 insn.nfixups++;
2477 insn.sequence = lituse;
2480 emit_insn (&insn);
2482 /* Emit "or $t9, $t10, $t9". */
2483 set_tok_reg (newtok[1], AXP_REG_T10);
2484 assemble_tokens ("or", newtok, 3, 1);
2486 /* Emit "stq_u $t9, 0($at). */
2487 set_tok_const(newtok[1], 0);
2488 set_tok_preg (newtok[2], AXP_REG_AT);
2489 assemble_tokens_to_insn ("stq_u", newtok, 3, &insn);
2491 if (lituse)
2493 gas_assert (insn.nfixups < MAX_INSN_FIXUPS);
2494 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
2495 insn.fixups[insn.nfixups].exp.X_op = O_absent;
2496 insn.nfixups++;
2497 insn.sequence = lituse;
2500 emit_insn (&insn);
2504 /* Store an integer to an unaligned address. */
2506 static void
2507 emit_ustX (const expressionS *tok,
2508 int ntok,
2509 const void * vlgsize)
2511 int lgsize = (int) (long) vlgsize;
2512 expressionS newtok[3];
2514 /* Emit "lda $at, exp". */
2515 memcpy (newtok, tok, sizeof (expressionS) * ntok);
2516 newtok[0].X_add_number = AXP_REG_AT;
2517 assemble_tokens ("lda", newtok, ntok, 1);
2519 /* Emit "ldq_u $9, 0($at)". */
2520 set_tok_reg (newtok[0], AXP_REG_T9);
2521 set_tok_const (newtok[1], 0);
2522 set_tok_preg (newtok[2], AXP_REG_AT);
2523 assemble_tokens ("ldq_u", newtok, 3, 1);
2525 /* Emit "ldq_u $10, size-1($at)". */
2526 set_tok_reg (newtok[0], AXP_REG_T10);
2527 set_tok_const (newtok[1], (1 << lgsize) - 1);
2528 assemble_tokens ("ldq_u", newtok, 3, 1);
2530 /* Emit "insXl src, $at, $t11". */
2531 newtok[0] = tok[0];
2532 set_tok_reg (newtok[1], AXP_REG_AT);
2533 set_tok_reg (newtok[2], AXP_REG_T11);
2534 assemble_tokens (insXl_op[lgsize], newtok, 3, 1);
2536 /* Emit "insXh src, $at, $t12". */
2537 set_tok_reg (newtok[2], AXP_REG_T12);
2538 assemble_tokens (insXh_op[lgsize], newtok, 3, 1);
2540 /* Emit "mskXl $t9, $at, $t9". */
2541 set_tok_reg (newtok[0], AXP_REG_T9);
2542 newtok[2] = newtok[0];
2543 assemble_tokens (mskXl_op[lgsize], newtok, 3, 1);
2545 /* Emit "mskXh $t10, $at, $t10". */
2546 set_tok_reg (newtok[0], AXP_REG_T10);
2547 newtok[2] = newtok[0];
2548 assemble_tokens (mskXh_op[lgsize], newtok, 3, 1);
2550 /* Emit "or $t9, $t11, $t9". */
2551 set_tok_reg (newtok[0], AXP_REG_T9);
2552 set_tok_reg (newtok[1], AXP_REG_T11);
2553 newtok[2] = newtok[0];
2554 assemble_tokens ("or", newtok, 3, 1);
2556 /* Emit "or $t10, $t12, $t10". */
2557 set_tok_reg (newtok[0], AXP_REG_T10);
2558 set_tok_reg (newtok[1], AXP_REG_T12);
2559 newtok[2] = newtok[0];
2560 assemble_tokens ("or", newtok, 3, 1);
2562 /* Emit "stq_u $t10, size-1($at)". */
2563 set_tok_reg (newtok[0], AXP_REG_T10);
2564 set_tok_const (newtok[1], (1 << lgsize) - 1);
2565 set_tok_preg (newtok[2], AXP_REG_AT);
2566 assemble_tokens ("stq_u", newtok, 3, 1);
2568 /* Emit "stq_u $t9, 0($at)". */
2569 set_tok_reg (newtok[0], AXP_REG_T9);
2570 set_tok_const (newtok[1], 0);
2571 assemble_tokens ("stq_u", newtok, 3, 1);
2574 /* Sign extend a half-word or byte. The 32-bit sign extend is
2575 implemented as "addl $31, $r, $t" in the opcode table. */
2577 static void
2578 emit_sextX (const expressionS *tok,
2579 int ntok,
2580 const void * vlgsize)
2582 long lgsize = (long) vlgsize;
2584 if (alpha_target & AXP_OPCODE_BWX)
2585 assemble_tokens (sextX_op[lgsize], tok, ntok, 0);
2586 else
2588 int bitshift = 64 - 8 * (1 << lgsize);
2589 expressionS newtok[3];
2591 /* Emit "sll src,bits,dst". */
2592 newtok[0] = tok[0];
2593 set_tok_const (newtok[1], bitshift);
2594 newtok[2] = tok[ntok - 1];
2595 assemble_tokens ("sll", newtok, 3, 1);
2597 /* Emit "sra dst,bits,dst". */
2598 newtok[0] = newtok[2];
2599 assemble_tokens ("sra", newtok, 3, 1);
2603 /* Implement the division and modulus macros. */
2605 #ifdef OBJ_EVAX
2607 /* Make register usage like in normal procedure call.
2608 Don't clobber PV and RA. */
2610 static void
2611 emit_division (const expressionS *tok,
2612 int ntok,
2613 const void * symname)
2615 /* DIVISION and MODULUS. Yech.
2617 Convert
2618 OP x,y,result
2620 mov x,R16 # if x != R16
2621 mov y,R17 # if y != R17
2622 lda AT,__OP
2623 jsr AT,(AT),0
2624 mov R0,result
2626 with appropriate optimizations if R0,R16,R17 are the registers
2627 specified by the compiler. */
2629 int xr, yr, rr;
2630 symbolS *sym;
2631 expressionS newtok[3];
2633 xr = regno (tok[0].X_add_number);
2634 yr = regno (tok[1].X_add_number);
2636 if (ntok < 3)
2637 rr = xr;
2638 else
2639 rr = regno (tok[2].X_add_number);
2641 /* Move the operands into the right place. */
2642 if (yr == AXP_REG_R16 && xr == AXP_REG_R17)
2644 /* They are in exactly the wrong order -- swap through AT. */
2645 if (alpha_noat_on)
2646 as_bad (_("macro requires $at register while noat in effect"));
2648 set_tok_reg (newtok[0], AXP_REG_R16);
2649 set_tok_reg (newtok[1], AXP_REG_AT);
2650 assemble_tokens ("mov", newtok, 2, 1);
2652 set_tok_reg (newtok[0], AXP_REG_R17);
2653 set_tok_reg (newtok[1], AXP_REG_R16);
2654 assemble_tokens ("mov", newtok, 2, 1);
2656 set_tok_reg (newtok[0], AXP_REG_AT);
2657 set_tok_reg (newtok[1], AXP_REG_R17);
2658 assemble_tokens ("mov", newtok, 2, 1);
2660 else
2662 if (yr == AXP_REG_R16)
2664 set_tok_reg (newtok[0], AXP_REG_R16);
2665 set_tok_reg (newtok[1], AXP_REG_R17);
2666 assemble_tokens ("mov", newtok, 2, 1);
2669 if (xr != AXP_REG_R16)
2671 set_tok_reg (newtok[0], xr);
2672 set_tok_reg (newtok[1], AXP_REG_R16);
2673 assemble_tokens ("mov", newtok, 2, 1);
2676 if (yr != AXP_REG_R16 && yr != AXP_REG_R17)
2678 set_tok_reg (newtok[0], yr);
2679 set_tok_reg (newtok[1], AXP_REG_R17);
2680 assemble_tokens ("mov", newtok, 2, 1);
2684 sym = symbol_find_or_make ((const char *) symname);
2686 set_tok_reg (newtok[0], AXP_REG_AT);
2687 set_tok_sym (newtok[1], sym, 0);
2688 assemble_tokens ("lda", newtok, 2, 1);
2690 /* Call the division routine. */
2691 set_tok_reg (newtok[0], AXP_REG_AT);
2692 set_tok_cpreg (newtok[1], AXP_REG_AT);
2693 set_tok_const (newtok[2], 0);
2694 assemble_tokens ("jsr", newtok, 3, 1);
2696 /* Move the result to the right place. */
2697 if (rr != AXP_REG_R0)
2699 set_tok_reg (newtok[0], AXP_REG_R0);
2700 set_tok_reg (newtok[1], rr);
2701 assemble_tokens ("mov", newtok, 2, 1);
2705 #else /* !OBJ_EVAX */
2707 static void
2708 emit_division (const expressionS *tok,
2709 int ntok,
2710 const void * symname)
2712 /* DIVISION and MODULUS. Yech.
2713 Convert
2714 OP x,y,result
2716 lda pv,__OP
2717 mov x,t10
2718 mov y,t11
2719 jsr t9,(pv),__OP
2720 mov t12,result
2722 with appropriate optimizations if t10,t11,t12 are the registers
2723 specified by the compiler. */
2725 int xr, yr, rr;
2726 symbolS *sym;
2727 expressionS newtok[3];
2729 xr = regno (tok[0].X_add_number);
2730 yr = regno (tok[1].X_add_number);
2732 if (ntok < 3)
2733 rr = xr;
2734 else
2735 rr = regno (tok[2].X_add_number);
2737 sym = symbol_find_or_make ((const char *) symname);
2739 /* Move the operands into the right place. */
2740 if (yr == AXP_REG_T10 && xr == AXP_REG_T11)
2742 /* They are in exactly the wrong order -- swap through AT. */
2743 if (alpha_noat_on)
2744 as_bad (_("macro requires $at register while noat in effect"));
2746 set_tok_reg (newtok[0], AXP_REG_T10);
2747 set_tok_reg (newtok[1], AXP_REG_AT);
2748 assemble_tokens ("mov", newtok, 2, 1);
2750 set_tok_reg (newtok[0], AXP_REG_T11);
2751 set_tok_reg (newtok[1], AXP_REG_T10);
2752 assemble_tokens ("mov", newtok, 2, 1);
2754 set_tok_reg (newtok[0], AXP_REG_AT);
2755 set_tok_reg (newtok[1], AXP_REG_T11);
2756 assemble_tokens ("mov", newtok, 2, 1);
2758 else
2760 if (yr == AXP_REG_T10)
2762 set_tok_reg (newtok[0], AXP_REG_T10);
2763 set_tok_reg (newtok[1], AXP_REG_T11);
2764 assemble_tokens ("mov", newtok, 2, 1);
2767 if (xr != AXP_REG_T10)
2769 set_tok_reg (newtok[0], xr);
2770 set_tok_reg (newtok[1], AXP_REG_T10);
2771 assemble_tokens ("mov", newtok, 2, 1);
2774 if (yr != AXP_REG_T10 && yr != AXP_REG_T11)
2776 set_tok_reg (newtok[0], yr);
2777 set_tok_reg (newtok[1], AXP_REG_T11);
2778 assemble_tokens ("mov", newtok, 2, 1);
2782 /* Call the division routine. */
2783 set_tok_reg (newtok[0], AXP_REG_T9);
2784 set_tok_sym (newtok[1], sym, 0);
2785 assemble_tokens ("jsr", newtok, 2, 1);
2787 /* Reload the GP register. */
2788 #ifdef OBJ_AOUT
2789 FIXME
2790 #endif
2791 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
2792 set_tok_reg (newtok[0], alpha_gp_register);
2793 set_tok_const (newtok[1], 0);
2794 set_tok_preg (newtok[2], AXP_REG_T9);
2795 assemble_tokens ("ldgp", newtok, 3, 1);
2796 #endif
2798 /* Move the result to the right place. */
2799 if (rr != AXP_REG_T12)
2801 set_tok_reg (newtok[0], AXP_REG_T12);
2802 set_tok_reg (newtok[1], rr);
2803 assemble_tokens ("mov", newtok, 2, 1);
2807 #endif /* !OBJ_EVAX */
2809 /* The jsr and jmp macros differ from their instruction counterparts
2810 in that they can load the target address and default most
2811 everything. */
2813 static void
2814 emit_jsrjmp (const expressionS *tok,
2815 int ntok,
2816 const void * vopname)
2818 const char *opname = (const char *) vopname;
2819 struct alpha_insn insn;
2820 expressionS newtok[3];
2821 int r, tokidx = 0;
2822 long lituse = 0;
2824 if (tokidx < ntok && tok[tokidx].X_op == O_register)
2825 r = regno (tok[tokidx++].X_add_number);
2826 else
2827 r = strcmp (opname, "jmp") == 0 ? AXP_REG_ZERO : AXP_REG_RA;
2829 set_tok_reg (newtok[0], r);
2831 if (tokidx < ntok &&
2832 (tok[tokidx].X_op == O_pregister || tok[tokidx].X_op == O_cpregister))
2833 r = regno (tok[tokidx++].X_add_number);
2834 #ifdef OBJ_EVAX
2835 /* Keep register if jsr $n.<sym>. */
2836 #else
2837 else
2839 int basereg = alpha_gp_register;
2840 lituse = load_expression (r = AXP_REG_PV, &tok[tokidx],
2841 &basereg, NULL, opname);
2843 #endif
2845 set_tok_cpreg (newtok[1], r);
2847 #ifndef OBJ_EVAX
2848 if (tokidx < ntok)
2849 newtok[2] = tok[tokidx];
2850 else
2851 #endif
2852 set_tok_const (newtok[2], 0);
2854 assemble_tokens_to_insn (opname, newtok, 3, &insn);
2856 if (lituse)
2858 gas_assert (insn.nfixups < MAX_INSN_FIXUPS);
2859 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_JSR;
2860 insn.fixups[insn.nfixups].exp.X_op = O_absent;
2861 insn.nfixups++;
2862 insn.sequence = lituse;
2865 #ifdef OBJ_EVAX
2866 if (alpha_flag_replace
2867 && r == AXP_REG_RA
2868 && tok[tokidx].X_add_symbol
2869 && alpha_linkage_symbol)
2871 const char *symname = S_GET_NAME (tok[tokidx].X_add_symbol);
2872 int symlen = strlen (symname);
2873 char *ensymname;
2875 ensymname = (char *) xmalloc (symlen + 5);
2876 memcpy (ensymname, symname, symlen);
2877 memcpy (ensymname + symlen, "..en", 5);
2879 gas_assert (insn.nfixups < MAX_INSN_FIXUPS);
2880 if (insn.nfixups > 0)
2882 memmove (&insn.fixups[1], &insn.fixups[0],
2883 sizeof(struct alpha_fixup) * insn.nfixups);
2886 /* The fixup must be the same as the BFD_RELOC_ALPHA_NOP
2887 case in load_expression. See B.4.5.2 of the OpenVMS
2888 Linker Utility Manual. */
2889 insn.fixups[0].reloc = BFD_RELOC_ALPHA_BOH;
2890 insn.fixups[0].exp.X_op = O_symbol;
2891 insn.fixups[0].exp.X_add_symbol = symbol_find_or_make (ensymname);
2892 insn.fixups[0].exp.X_add_number = 0;
2893 insn.fixups[0].xtrasym = alpha_linkage_symbol;
2894 insn.fixups[0].procsym = alpha_evax_proc->symbol;
2895 insn.nfixups++;
2896 alpha_linkage_symbol = 0;
2898 #endif
2900 emit_insn (&insn);
2903 /* The ret and jcr instructions differ from their instruction
2904 counterparts in that everything can be defaulted. */
2906 static void
2907 emit_retjcr (const expressionS *tok,
2908 int ntok,
2909 const void * vopname)
2911 const char *opname = (const char *) vopname;
2912 expressionS newtok[3];
2913 int r, tokidx = 0;
2915 if (tokidx < ntok && tok[tokidx].X_op == O_register)
2916 r = regno (tok[tokidx++].X_add_number);
2917 else
2918 r = AXP_REG_ZERO;
2920 set_tok_reg (newtok[0], r);
2922 if (tokidx < ntok &&
2923 (tok[tokidx].X_op == O_pregister || tok[tokidx].X_op == O_cpregister))
2924 r = regno (tok[tokidx++].X_add_number);
2925 else
2926 r = AXP_REG_RA;
2928 set_tok_cpreg (newtok[1], r);
2930 if (tokidx < ntok)
2931 newtok[2] = tok[tokidx];
2932 else
2933 set_tok_const (newtok[2], strcmp (opname, "ret") == 0);
2935 assemble_tokens (opname, newtok, 3, 0);
2938 /* Implement the ldgp macro. */
2940 static void
2941 emit_ldgp (const expressionS *tok,
2942 int ntok ATTRIBUTE_UNUSED,
2943 const void * unused ATTRIBUTE_UNUSED)
2945 #ifdef OBJ_AOUT
2946 FIXME
2947 #endif
2948 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
2949 /* from "ldgp r1,n(r2)", generate "ldah r1,X(R2); lda r1,Y(r1)"
2950 with appropriate constants and relocations. */
2951 struct alpha_insn insn;
2952 expressionS newtok[3];
2953 expressionS addend;
2955 #ifdef OBJ_ECOFF
2956 if (regno (tok[2].X_add_number) == AXP_REG_PV)
2957 ecoff_set_gp_prolog_size (0);
2958 #endif
2960 newtok[0] = tok[0];
2961 set_tok_const (newtok[1], 0);
2962 newtok[2] = tok[2];
2964 assemble_tokens_to_insn ("ldah", newtok, 3, &insn);
2966 addend = tok[1];
2968 #ifdef OBJ_ECOFF
2969 if (addend.X_op != O_constant)
2970 as_bad (_("can not resolve expression"));
2971 addend.X_op = O_symbol;
2972 addend.X_add_symbol = alpha_gp_symbol;
2973 #endif
2975 insn.nfixups = 1;
2976 insn.fixups[0].exp = addend;
2977 insn.fixups[0].reloc = BFD_RELOC_ALPHA_GPDISP_HI16;
2978 insn.sequence = next_sequence_num;
2980 emit_insn (&insn);
2982 set_tok_preg (newtok[2], tok[0].X_add_number);
2984 assemble_tokens_to_insn ("lda", newtok, 3, &insn);
2986 #ifdef OBJ_ECOFF
2987 addend.X_add_number += 4;
2988 #endif
2990 insn.nfixups = 1;
2991 insn.fixups[0].exp = addend;
2992 insn.fixups[0].reloc = BFD_RELOC_ALPHA_GPDISP_LO16;
2993 insn.sequence = next_sequence_num--;
2995 emit_insn (&insn);
2996 #else /* OBJ_ECOFF || OBJ_ELF */
2997 /* Avoid warning. */
2998 tok = NULL;
2999 #endif
3002 /* The macro table. */
3004 static const struct alpha_macro alpha_macros[] =
3006 /* Load/Store macros. */
3007 { "lda", emit_lda, NULL,
3008 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3009 { "ldah", emit_ldah, NULL,
3010 { MACRO_IR, MACRO_EXP, MACRO_EOA } },
3012 { "ldl", emit_ir_load, "ldl",
3013 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3014 { "ldl_l", emit_ir_load, "ldl_l",
3015 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3016 { "ldq", emit_ir_load, "ldq",
3017 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3018 { "ldq_l", emit_ir_load, "ldq_l",
3019 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3020 { "ldq_u", emit_ir_load, "ldq_u",
3021 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3022 { "ldf", emit_loadstore, "ldf",
3023 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3024 { "ldg", emit_loadstore, "ldg",
3025 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3026 { "lds", emit_loadstore, "lds",
3027 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3028 { "ldt", emit_loadstore, "ldt",
3029 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3031 { "ldb", emit_ldX, (void *) 0,
3032 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3033 { "ldbu", emit_ldXu, (void *) 0,
3034 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3035 { "ldw", emit_ldX, (void *) 1,
3036 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3037 { "ldwu", emit_ldXu, (void *) 1,
3038 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3040 { "uldw", emit_uldX, (void *) 1,
3041 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3042 { "uldwu", emit_uldXu, (void *) 1,
3043 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3044 { "uldl", emit_uldX, (void *) 2,
3045 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3046 { "uldlu", emit_uldXu, (void *) 2,
3047 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3048 { "uldq", emit_uldXu, (void *) 3,
3049 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3051 { "ldgp", emit_ldgp, NULL,
3052 { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA } },
3054 { "ldi", emit_lda, NULL,
3055 { MACRO_IR, MACRO_EXP, MACRO_EOA } },
3056 { "ldil", emit_ldil, NULL,
3057 { MACRO_IR, MACRO_EXP, MACRO_EOA } },
3058 { "ldiq", emit_lda, NULL,
3059 { MACRO_IR, MACRO_EXP, MACRO_EOA } },
3061 { "stl", emit_loadstore, "stl",
3062 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3063 { "stl_c", emit_loadstore, "stl_c",
3064 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3065 { "stq", emit_loadstore, "stq",
3066 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3067 { "stq_c", emit_loadstore, "stq_c",
3068 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3069 { "stq_u", emit_loadstore, "stq_u",
3070 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3071 { "stf", emit_loadstore, "stf",
3072 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3073 { "stg", emit_loadstore, "stg",
3074 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3075 { "sts", emit_loadstore, "sts",
3076 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3077 { "stt", emit_loadstore, "stt",
3078 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3080 { "stb", emit_stX, (void *) 0,
3081 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3082 { "stw", emit_stX, (void *) 1,
3083 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3084 { "ustw", emit_ustX, (void *) 1,
3085 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3086 { "ustl", emit_ustX, (void *) 2,
3087 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3088 { "ustq", emit_ustX, (void *) 3,
3089 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3091 /* Arithmetic macros. */
3093 { "sextb", emit_sextX, (void *) 0,
3094 { MACRO_IR, MACRO_IR, MACRO_EOA,
3095 MACRO_IR, MACRO_EOA,
3096 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
3097 { "sextw", emit_sextX, (void *) 1,
3098 { MACRO_IR, MACRO_IR, MACRO_EOA,
3099 MACRO_IR, MACRO_EOA,
3100 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
3102 { "divl", emit_division, "__divl",
3103 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
3104 MACRO_IR, MACRO_IR, MACRO_EOA,
3105 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
3106 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
3107 { "divlu", emit_division, "__divlu",
3108 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
3109 MACRO_IR, MACRO_IR, MACRO_EOA,
3110 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
3111 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
3112 { "divq", emit_division, "__divq",
3113 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
3114 MACRO_IR, MACRO_IR, MACRO_EOA,
3115 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
3116 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
3117 { "divqu", emit_division, "__divqu",
3118 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
3119 MACRO_IR, MACRO_IR, MACRO_EOA,
3120 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
3121 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
3122 { "reml", emit_division, "__reml",
3123 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
3124 MACRO_IR, MACRO_IR, MACRO_EOA,
3125 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
3126 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
3127 { "remlu", emit_division, "__remlu",
3128 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
3129 MACRO_IR, MACRO_IR, MACRO_EOA,
3130 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
3131 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
3132 { "remq", emit_division, "__remq",
3133 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
3134 MACRO_IR, MACRO_IR, MACRO_EOA,
3135 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
3136 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
3137 { "remqu", emit_division, "__remqu",
3138 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
3139 MACRO_IR, MACRO_IR, MACRO_EOA,
3140 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
3141 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
3143 { "jsr", emit_jsrjmp, "jsr",
3144 { MACRO_PIR, MACRO_EXP, MACRO_EOA,
3145 MACRO_PIR, MACRO_EOA,
3146 MACRO_IR, MACRO_EXP, MACRO_EOA,
3147 MACRO_EXP, MACRO_EOA } },
3148 { "jmp", emit_jsrjmp, "jmp",
3149 { MACRO_PIR, MACRO_EXP, MACRO_EOA,
3150 MACRO_PIR, MACRO_EOA,
3151 MACRO_IR, MACRO_EXP, MACRO_EOA,
3152 MACRO_EXP, MACRO_EOA } },
3153 { "ret", emit_retjcr, "ret",
3154 { MACRO_IR, MACRO_EXP, MACRO_EOA,
3155 MACRO_IR, MACRO_EOA,
3156 MACRO_PIR, MACRO_EXP, MACRO_EOA,
3157 MACRO_PIR, MACRO_EOA,
3158 MACRO_EXP, MACRO_EOA,
3159 MACRO_EOA } },
3160 { "jcr", emit_retjcr, "jcr",
3161 { MACRO_IR, MACRO_EXP, MACRO_EOA,
3162 MACRO_IR, MACRO_EOA,
3163 MACRO_PIR, MACRO_EXP, MACRO_EOA,
3164 MACRO_PIR, MACRO_EOA,
3165 MACRO_EXP, MACRO_EOA,
3166 MACRO_EOA } },
3167 { "jsr_coroutine", emit_retjcr, "jcr",
3168 { MACRO_IR, MACRO_EXP, MACRO_EOA,
3169 MACRO_IR, MACRO_EOA,
3170 MACRO_PIR, MACRO_EXP, MACRO_EOA,
3171 MACRO_PIR, MACRO_EOA,
3172 MACRO_EXP, MACRO_EOA,
3173 MACRO_EOA } },
3176 static const unsigned int alpha_num_macros
3177 = sizeof (alpha_macros) / sizeof (*alpha_macros);
3179 /* Search forward through all variants of a macro looking for a syntax
3180 match. */
3182 static const struct alpha_macro *
3183 find_macro_match (const struct alpha_macro *first_macro,
3184 const expressionS *tok,
3185 int *pntok)
3188 const struct alpha_macro *macro = first_macro;
3189 int ntok = *pntok;
3193 const enum alpha_macro_arg *arg = macro->argsets;
3194 int tokidx = 0;
3196 while (*arg)
3198 switch (*arg)
3200 case MACRO_EOA:
3201 if (tokidx == ntok)
3202 return macro;
3203 else
3204 tokidx = 0;
3205 break;
3207 /* Index register. */
3208 case MACRO_IR:
3209 if (tokidx >= ntok || tok[tokidx].X_op != O_register
3210 || !is_ir_num (tok[tokidx].X_add_number))
3211 goto match_failed;
3212 ++tokidx;
3213 break;
3215 /* Parenthesized index register. */
3216 case MACRO_PIR:
3217 if (tokidx >= ntok || tok[tokidx].X_op != O_pregister
3218 || !is_ir_num (tok[tokidx].X_add_number))
3219 goto match_failed;
3220 ++tokidx;
3221 break;
3223 /* Optional parenthesized index register. */
3224 case MACRO_OPIR:
3225 if (tokidx < ntok && tok[tokidx].X_op == O_pregister
3226 && is_ir_num (tok[tokidx].X_add_number))
3227 ++tokidx;
3228 break;
3230 /* Leading comma with a parenthesized index register. */
3231 case MACRO_CPIR:
3232 if (tokidx >= ntok || tok[tokidx].X_op != O_cpregister
3233 || !is_ir_num (tok[tokidx].X_add_number))
3234 goto match_failed;
3235 ++tokidx;
3236 break;
3238 /* Floating point register. */
3239 case MACRO_FPR:
3240 if (tokidx >= ntok || tok[tokidx].X_op != O_register
3241 || !is_fpr_num (tok[tokidx].X_add_number))
3242 goto match_failed;
3243 ++tokidx;
3244 break;
3246 /* Normal expression. */
3247 case MACRO_EXP:
3248 if (tokidx >= ntok)
3249 goto match_failed;
3250 switch (tok[tokidx].X_op)
3252 case O_illegal:
3253 case O_absent:
3254 case O_register:
3255 case O_pregister:
3256 case O_cpregister:
3257 case O_literal:
3258 case O_lituse_base:
3259 case O_lituse_bytoff:
3260 case O_lituse_jsr:
3261 case O_gpdisp:
3262 case O_gprelhigh:
3263 case O_gprellow:
3264 case O_gprel:
3265 case O_samegp:
3266 goto match_failed;
3268 default:
3269 break;
3271 ++tokidx;
3272 break;
3274 match_failed:
3275 while (*arg != MACRO_EOA)
3276 ++arg;
3277 tokidx = 0;
3278 break;
3280 ++arg;
3283 while (++macro - alpha_macros < (int) alpha_num_macros
3284 && !strcmp (macro->name, first_macro->name));
3286 return NULL;
3289 /* Given an opcode name and a pre-tokenized set of arguments, take the
3290 opcode all the way through emission. */
3292 static void
3293 assemble_tokens (const char *opname,
3294 const expressionS *tok,
3295 int ntok,
3296 int local_macros_on)
3298 int found_something = 0;
3299 const struct alpha_opcode *opcode;
3300 const struct alpha_macro *macro;
3301 int cpumatch = 1;
3302 extended_bfd_reloc_code_real_type reloc = BFD_RELOC_UNUSED;
3304 #ifdef RELOC_OP_P
3305 /* If a user-specified relocation is present, this is not a macro. */
3306 if (ntok && USER_RELOC_P (tok[ntok - 1].X_op))
3308 reloc = ALPHA_RELOC_TABLE (tok[ntok - 1].X_op)->reloc;
3309 ntok--;
3311 else
3312 #endif
3313 if (local_macros_on)
3315 macro = ((const struct alpha_macro *)
3316 hash_find (alpha_macro_hash, opname));
3317 if (macro)
3319 found_something = 1;
3320 macro = find_macro_match (macro, tok, &ntok);
3321 if (macro)
3323 (*macro->emit) (tok, ntok, macro->arg);
3324 return;
3329 /* Search opcodes. */
3330 opcode = (const struct alpha_opcode *) hash_find (alpha_opcode_hash, opname);
3331 if (opcode)
3333 found_something = 1;
3334 opcode = find_opcode_match (opcode, tok, &ntok, &cpumatch);
3335 if (opcode)
3337 struct alpha_insn insn;
3338 assemble_insn (opcode, tok, ntok, &insn, reloc);
3340 /* Copy the sequence number for the reloc from the reloc token. */
3341 if (reloc != BFD_RELOC_UNUSED)
3342 insn.sequence = tok[ntok].X_add_number;
3344 emit_insn (&insn);
3345 return;
3349 if (found_something)
3351 if (cpumatch)
3352 as_bad (_("inappropriate arguments for opcode `%s'"), opname);
3353 else
3354 as_bad (_("opcode `%s' not supported for target %s"), opname,
3355 alpha_target_name);
3357 else
3358 as_bad (_("unknown opcode `%s'"), opname);
3361 #ifdef OBJ_EVAX
3363 /* Add symbol+addend to link pool.
3364 Return offset from basesym to entry in link pool.
3366 Add new fixup only if offset isn't 16bit. */
3368 static symbolS *
3369 add_to_link_pool (symbolS *basesym,
3370 symbolS *sym,
3371 offsetT addend)
3373 segT current_section = now_seg;
3374 int current_subsec = now_subseg;
3375 valueT offset;
3376 char *p;
3377 segment_info_type *seginfo = seg_info (alpha_link_section);
3378 fixS *fixp;
3379 symbolS *linksym, *expsym;
3380 expressionS e;
3382 offset = 0; /* ??? DBR */
3384 /* @@ This assumes all entries in a given section will be of the same
3385 size... Probably correct, but unwise to rely on. */
3386 /* This must always be called with the same subsegment. */
3388 if (seginfo->frchainP)
3389 for (fixp = seginfo->frchainP->fix_root;
3390 fixp != (fixS *) NULL;
3391 fixp = fixp->fx_next)
3393 if (fixp->tc_fix_data.info
3394 && fixp->tc_fix_data.info->sym
3395 && fixp->tc_fix_data.info->sym->sy_value.X_op_symbol == basesym)
3396 offset += 8;
3398 if (fixp->fx_addsy == sym
3399 && fixp->fx_offset == (valueT)addend
3400 && fixp->tc_fix_data.info
3401 && fixp->tc_fix_data.info->sym
3402 && fixp->tc_fix_data.info->sym->sy_value.X_op_symbol == basesym)
3403 return fixp->tc_fix_data.info->sym;
3406 /* Not found in 16bit signed range. */
3408 subseg_set (alpha_link_section, 0);
3409 linksym = symbol_new
3410 (FAKE_LABEL_NAME, now_seg, (valueT) frag_now_fix (), frag_now);
3411 p = frag_more (8);
3412 memset (p, 0, 8);
3414 e.X_op = O_subtract;
3415 e.X_add_symbol = linksym;
3416 e.X_op_symbol = basesym;
3417 e.X_add_number = 0;
3418 expsym = make_expr_symbol (&e);
3420 fixp = fix_new
3421 (frag_now, p-frag_now->fr_literal, 8, sym, addend, 0, BFD_RELOC_64);
3422 fixp->tc_fix_data.info = get_alpha_reloc_tag (next_sequence_num--);
3423 fixp->tc_fix_data.info->sym = expsym;
3425 subseg_set (current_section, current_subsec);
3426 seginfo->literal_pool_size += 8;
3427 return expsym;
3429 #endif /* OBJ_EVAX */
3431 /* Assembler directives. */
3433 /* Handle the .text pseudo-op. This is like the usual one, but it
3434 clears alpha_insn_label and restores auto alignment. */
3436 static void
3437 s_alpha_text (int i)
3439 #ifdef OBJ_ELF
3440 obj_elf_text (i);
3441 #else
3442 s_text (i);
3443 #endif
3444 #ifdef OBJ_EVAX
3446 symbolS * symbolP;
3448 symbolP = symbol_find (".text");
3449 if (symbolP == NULL)
3451 symbolP = symbol_make (".text");
3452 S_SET_SEGMENT (symbolP, text_section);
3453 symbol_table_insert (symbolP);
3456 #endif
3457 alpha_insn_label = NULL;
3458 alpha_auto_align_on = 1;
3459 alpha_current_align = 0;
3462 /* Handle the .data pseudo-op. This is like the usual one, but it
3463 clears alpha_insn_label and restores auto alignment. */
3465 static void
3466 s_alpha_data (int i)
3468 #ifdef OBJ_ELF
3469 obj_elf_data (i);
3470 #else
3471 s_data (i);
3472 #endif
3473 alpha_insn_label = NULL;
3474 alpha_auto_align_on = 1;
3475 alpha_current_align = 0;
3478 #if defined (OBJ_ECOFF) || defined (OBJ_EVAX)
3480 /* Handle the OSF/1 and openVMS .comm pseudo quirks. */
3482 static void
3483 s_alpha_comm (int ignore ATTRIBUTE_UNUSED)
3485 char *name;
3486 char c;
3487 char *p;
3488 offsetT size;
3489 symbolS *symbolP;
3490 #ifdef OBJ_EVAX
3491 offsetT temp;
3492 int log_align = 0;
3493 #endif
3495 name = input_line_pointer;
3496 c = get_symbol_end ();
3498 /* Just after name is now '\0'. */
3499 p = input_line_pointer;
3500 *p = c;
3502 SKIP_WHITESPACE ();
3504 /* Alpha OSF/1 compiler doesn't provide the comma, gcc does. */
3505 if (*input_line_pointer == ',')
3507 input_line_pointer++;
3508 SKIP_WHITESPACE ();
3510 if ((size = get_absolute_expression ()) < 0)
3512 as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) size);
3513 ignore_rest_of_line ();
3514 return;
3517 *p = 0;
3518 symbolP = symbol_find_or_make (name);
3519 *p = c;
3521 if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
3523 as_bad (_("Ignoring attempt to re-define symbol"));
3524 ignore_rest_of_line ();
3525 return;
3528 #ifdef OBJ_EVAX
3529 if (*input_line_pointer != ',')
3530 temp = 8; /* Default alignment. */
3531 else
3533 input_line_pointer++;
3534 SKIP_WHITESPACE ();
3535 temp = get_absolute_expression ();
3538 /* ??? Unlike on OSF/1, the alignment factor is not in log units. */
3539 while ((temp >>= 1) != 0)
3540 ++log_align;
3542 if (*input_line_pointer == ',')
3544 /* Extended form of the directive
3546 .comm symbol, size, alignment, section
3548 where the "common" semantics is transferred to the section.
3549 The symbol is effectively an alias for the section name. */
3551 segT sec;
3552 char *sec_name;
3553 symbolS *sec_symbol;
3554 segT current_seg = now_seg;
3555 subsegT current_subseg = now_subseg;
3556 int cur_size;
3558 input_line_pointer++;
3559 SKIP_WHITESPACE ();
3560 sec_name = s_alpha_section_name ();
3561 sec_symbol = symbol_find_or_make (sec_name);
3562 sec = subseg_new (sec_name, 0);
3563 S_SET_SEGMENT (sec_symbol, sec);
3564 symbol_get_bfdsym (sec_symbol)->flags |= BSF_SECTION_SYM;
3565 bfd_vms_set_section_flags (stdoutput, sec, 0,
3566 EGPS__V_OVR | EGPS__V_GBL | EGPS__V_NOMOD);
3567 record_alignment (sec, log_align);
3569 /* Reuse stab_string_size to store the size of the section. */
3570 cur_size = seg_info (sec)->stabu.stab_string_size;
3571 if ((int) size > cur_size)
3573 char *pfrag
3574 = frag_var (rs_fill, 1, 1, (relax_substateT)0, NULL,
3575 (valueT)size - (valueT)cur_size, NULL);
3576 *pfrag = 0;
3577 seg_info (sec)->stabu.stab_string_size = (int)size;
3580 S_SET_SEGMENT (symbolP, sec);
3582 subseg_set (current_seg, current_subseg);
3584 else
3586 /* Regular form of the directive
3588 .comm symbol, size, alignment
3590 where the "common" semantics in on the symbol.
3591 These symbols are assembled in the .bss section. */
3593 char *pfrag;
3594 segT current_seg = now_seg;
3595 subsegT current_subseg = now_subseg;
3597 subseg_set (bss_section, 1);
3598 frag_align (log_align, 0, 0);
3599 record_alignment (bss_section, log_align);
3601 symbolP->sy_frag = frag_now;
3602 pfrag = frag_var (rs_org, 1, 1, (relax_substateT)0, symbolP,
3603 size, NULL);
3604 *pfrag = 0;
3606 S_SET_SEGMENT (symbolP, bss_section);
3608 subseg_set (current_seg, current_subseg);
3610 #endif
3612 if (S_GET_VALUE (symbolP))
3614 if (S_GET_VALUE (symbolP) != (valueT) size)
3615 as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
3616 S_GET_NAME (symbolP),
3617 (long) S_GET_VALUE (symbolP),
3618 (long) size);
3620 else
3622 #ifndef OBJ_EVAX
3623 S_SET_VALUE (symbolP, (valueT) size);
3624 #endif
3625 S_SET_EXTERNAL (symbolP);
3628 #ifndef OBJ_EVAX
3629 know (symbolP->sy_frag == &zero_address_frag);
3630 #endif
3631 demand_empty_rest_of_line ();
3634 #endif /* ! OBJ_ELF */
3636 #ifdef OBJ_ECOFF
3638 /* Handle the .rdata pseudo-op. This is like the usual one, but it
3639 clears alpha_insn_label and restores auto alignment. */
3641 static void
3642 s_alpha_rdata (int ignore ATTRIBUTE_UNUSED)
3644 int temp;
3646 temp = get_absolute_expression ();
3647 subseg_new (".rdata", 0);
3648 demand_empty_rest_of_line ();
3649 alpha_insn_label = NULL;
3650 alpha_auto_align_on = 1;
3651 alpha_current_align = 0;
3654 #endif
3656 #ifdef OBJ_ECOFF
3658 /* Handle the .sdata pseudo-op. This is like the usual one, but it
3659 clears alpha_insn_label and restores auto alignment. */
3661 static void
3662 s_alpha_sdata (int ignore ATTRIBUTE_UNUSED)
3664 int temp;
3666 temp = get_absolute_expression ();
3667 subseg_new (".sdata", 0);
3668 demand_empty_rest_of_line ();
3669 alpha_insn_label = NULL;
3670 alpha_auto_align_on = 1;
3671 alpha_current_align = 0;
3673 #endif
3675 #ifdef OBJ_ELF
3676 struct alpha_elf_frame_data
3678 symbolS *func_sym;
3679 symbolS *func_end_sym;
3680 symbolS *prologue_sym;
3681 unsigned int mask;
3682 unsigned int fmask;
3683 int fp_regno;
3684 int ra_regno;
3685 offsetT frame_size;
3686 offsetT mask_offset;
3687 offsetT fmask_offset;
3689 struct alpha_elf_frame_data *next;
3692 static struct alpha_elf_frame_data *all_frame_data;
3693 static struct alpha_elf_frame_data **plast_frame_data = &all_frame_data;
3694 static struct alpha_elf_frame_data *cur_frame_data;
3696 /* Handle the .section pseudo-op. This is like the usual one, but it
3697 clears alpha_insn_label and restores auto alignment. */
3699 static void
3700 s_alpha_section (int ignore ATTRIBUTE_UNUSED)
3702 obj_elf_section (ignore);
3704 alpha_insn_label = NULL;
3705 alpha_auto_align_on = 1;
3706 alpha_current_align = 0;
3709 static void
3710 s_alpha_ent (int dummy ATTRIBUTE_UNUSED)
3712 if (ECOFF_DEBUGGING)
3713 ecoff_directive_ent (0);
3714 else
3716 char *name, name_end;
3717 name = input_line_pointer;
3718 name_end = get_symbol_end ();
3720 if (! is_name_beginner (*name))
3722 as_warn (_(".ent directive has no name"));
3723 *input_line_pointer = name_end;
3725 else
3727 symbolS *sym;
3729 if (cur_frame_data)
3730 as_warn (_("nested .ent directives"));
3732 sym = symbol_find_or_make (name);
3733 symbol_get_bfdsym (sym)->flags |= BSF_FUNCTION;
3735 cur_frame_data = (struct alpha_elf_frame_data *)
3736 calloc (1, sizeof (*cur_frame_data));
3737 cur_frame_data->func_sym = sym;
3739 /* Provide sensible defaults. */
3740 cur_frame_data->fp_regno = 30; /* sp */
3741 cur_frame_data->ra_regno = 26; /* ra */
3743 *plast_frame_data = cur_frame_data;
3744 plast_frame_data = &cur_frame_data->next;
3746 /* The .ent directive is sometimes followed by a number. Not sure
3747 what it really means, but ignore it. */
3748 *input_line_pointer = name_end;
3749 SKIP_WHITESPACE ();
3750 if (*input_line_pointer == ',')
3752 input_line_pointer++;
3753 SKIP_WHITESPACE ();
3755 if (ISDIGIT (*input_line_pointer) || *input_line_pointer == '-')
3756 (void) get_absolute_expression ();
3758 demand_empty_rest_of_line ();
3762 static void
3763 s_alpha_end (int dummy ATTRIBUTE_UNUSED)
3765 if (ECOFF_DEBUGGING)
3766 ecoff_directive_end (0);
3767 else
3769 char *name, name_end;
3770 name = input_line_pointer;
3771 name_end = get_symbol_end ();
3773 if (! is_name_beginner (*name))
3775 as_warn (_(".end directive has no name"));
3776 *input_line_pointer = name_end;
3778 else
3780 symbolS *sym;
3782 sym = symbol_find (name);
3783 if (!cur_frame_data)
3784 as_warn (_(".end directive without matching .ent"));
3785 else if (sym != cur_frame_data->func_sym)
3786 as_warn (_(".end directive names different symbol than .ent"));
3788 /* Create an expression to calculate the size of the function. */
3789 if (sym && cur_frame_data)
3791 OBJ_SYMFIELD_TYPE *obj = symbol_get_obj (sym);
3792 expressionS *exp = (expressionS *) xmalloc (sizeof (expressionS));
3794 obj->size = exp;
3795 exp->X_op = O_subtract;
3796 exp->X_add_symbol = symbol_temp_new_now ();
3797 exp->X_op_symbol = sym;
3798 exp->X_add_number = 0;
3800 cur_frame_data->func_end_sym = exp->X_add_symbol;
3803 cur_frame_data = NULL;
3805 *input_line_pointer = name_end;
3807 demand_empty_rest_of_line ();
3811 static void
3812 s_alpha_mask (int fp)
3814 if (ECOFF_DEBUGGING)
3816 if (fp)
3817 ecoff_directive_fmask (0);
3818 else
3819 ecoff_directive_mask (0);
3821 else
3823 long val;
3824 offsetT offset;
3826 if (!cur_frame_data)
3828 if (fp)
3829 as_warn (_(".fmask outside of .ent"));
3830 else
3831 as_warn (_(".mask outside of .ent"));
3832 discard_rest_of_line ();
3833 return;
3836 if (get_absolute_expression_and_terminator (&val) != ',')
3838 if (fp)
3839 as_warn (_("bad .fmask directive"));
3840 else
3841 as_warn (_("bad .mask directive"));
3842 --input_line_pointer;
3843 discard_rest_of_line ();
3844 return;
3847 offset = get_absolute_expression ();
3848 demand_empty_rest_of_line ();
3850 if (fp)
3852 cur_frame_data->fmask = val;
3853 cur_frame_data->fmask_offset = offset;
3855 else
3857 cur_frame_data->mask = val;
3858 cur_frame_data->mask_offset = offset;
3863 static void
3864 s_alpha_frame (int dummy ATTRIBUTE_UNUSED)
3866 if (ECOFF_DEBUGGING)
3867 ecoff_directive_frame (0);
3868 else
3870 long val;
3872 if (!cur_frame_data)
3874 as_warn (_(".frame outside of .ent"));
3875 discard_rest_of_line ();
3876 return;
3879 cur_frame_data->fp_regno = tc_get_register (1);
3881 SKIP_WHITESPACE ();
3882 if (*input_line_pointer++ != ','
3883 || get_absolute_expression_and_terminator (&val) != ',')
3885 as_warn (_("bad .frame directive"));
3886 --input_line_pointer;
3887 discard_rest_of_line ();
3888 return;
3890 cur_frame_data->frame_size = val;
3892 cur_frame_data->ra_regno = tc_get_register (0);
3894 /* Next comes the "offset of saved $a0 from $sp". In gcc terms
3895 this is current_function_pretend_args_size. There's no place
3896 to put this value, so ignore it. */
3897 s_ignore (42);
3901 static void
3902 s_alpha_prologue (int ignore ATTRIBUTE_UNUSED)
3904 symbolS *sym;
3905 int arg;
3907 arg = get_absolute_expression ();
3908 demand_empty_rest_of_line ();
3909 alpha_prologue_label = symbol_new
3910 (FAKE_LABEL_NAME, now_seg, (valueT) frag_now_fix (), frag_now);
3912 if (ECOFF_DEBUGGING)
3913 sym = ecoff_get_cur_proc_sym ();
3914 else
3915 sym = cur_frame_data ? cur_frame_data->func_sym : NULL;
3917 if (sym == NULL)
3919 as_bad (_(".prologue directive without a preceding .ent directive"));
3920 return;
3923 switch (arg)
3925 case 0: /* No PV required. */
3926 S_SET_OTHER (sym, STO_ALPHA_NOPV
3927 | (S_GET_OTHER (sym) & ~STO_ALPHA_STD_GPLOAD));
3928 break;
3929 case 1: /* Std GP load. */
3930 S_SET_OTHER (sym, STO_ALPHA_STD_GPLOAD
3931 | (S_GET_OTHER (sym) & ~STO_ALPHA_STD_GPLOAD));
3932 break;
3933 case 2: /* Non-std use of PV. */
3934 break;
3936 default:
3937 as_bad (_("Invalid argument %d to .prologue."), arg);
3938 break;
3941 if (cur_frame_data)
3942 cur_frame_data->prologue_sym = symbol_temp_new_now ();
3945 static char *first_file_directive;
3947 static void
3948 s_alpha_file (int ignore ATTRIBUTE_UNUSED)
3950 /* Save the first .file directive we see, so that we can change our
3951 minds about whether ecoff debugging should or shouldn't be enabled. */
3952 if (alpha_flag_mdebug < 0 && ! first_file_directive)
3954 char *start = input_line_pointer;
3955 size_t len;
3957 discard_rest_of_line ();
3959 len = input_line_pointer - start;
3960 first_file_directive = (char *) xmalloc (len + 1);
3961 memcpy (first_file_directive, start, len);
3962 first_file_directive[len] = '\0';
3964 input_line_pointer = start;
3967 if (ECOFF_DEBUGGING)
3968 ecoff_directive_file (0);
3969 else
3970 dwarf2_directive_file (0);
3973 static void
3974 s_alpha_loc (int ignore ATTRIBUTE_UNUSED)
3976 if (ECOFF_DEBUGGING)
3977 ecoff_directive_loc (0);
3978 else
3979 dwarf2_directive_loc (0);
3982 static void
3983 s_alpha_stab (int n)
3985 /* If we've been undecided about mdebug, make up our minds in favour. */
3986 if (alpha_flag_mdebug < 0)
3988 segT sec = subseg_new (".mdebug", 0);
3989 bfd_set_section_flags (stdoutput, sec, SEC_HAS_CONTENTS | SEC_READONLY);
3990 bfd_set_section_alignment (stdoutput, sec, 3);
3992 ecoff_read_begin_hook ();
3994 if (first_file_directive)
3996 char *save_ilp = input_line_pointer;
3997 input_line_pointer = first_file_directive;
3998 ecoff_directive_file (0);
3999 input_line_pointer = save_ilp;
4000 free (first_file_directive);
4003 alpha_flag_mdebug = 1;
4005 s_stab (n);
4008 static void
4009 s_alpha_coff_wrapper (int which)
4011 static void (* const fns[]) (int) = {
4012 ecoff_directive_begin,
4013 ecoff_directive_bend,
4014 ecoff_directive_def,
4015 ecoff_directive_dim,
4016 ecoff_directive_endef,
4017 ecoff_directive_scl,
4018 ecoff_directive_tag,
4019 ecoff_directive_val,
4022 gas_assert (which >= 0 && which < (int) (sizeof (fns)/sizeof (*fns)));
4024 if (ECOFF_DEBUGGING)
4025 (*fns[which]) (0);
4026 else
4028 as_bad (_("ECOFF debugging is disabled."));
4029 ignore_rest_of_line ();
4033 /* Called at the end of assembly. Here we emit unwind info for frames
4034 unless the compiler has done it for us. */
4036 void
4037 alpha_elf_md_end (void)
4039 struct alpha_elf_frame_data *p;
4041 if (cur_frame_data)
4042 as_warn (_(".ent directive without matching .end"));
4044 /* If someone has generated the unwind info themselves, great. */
4045 if (bfd_get_section_by_name (stdoutput, ".eh_frame") != NULL)
4046 return;
4048 /* Generate .eh_frame data for the unwind directives specified. */
4049 for (p = all_frame_data; p ; p = p->next)
4050 if (p->prologue_sym)
4052 /* Create a temporary symbol at the same location as our
4053 function symbol. This prevents problems with globals. */
4054 cfi_new_fde (symbol_temp_new (S_GET_SEGMENT (p->func_sym),
4055 S_GET_VALUE (p->func_sym),
4056 symbol_get_frag (p->func_sym)));
4058 cfi_set_return_column (p->ra_regno);
4059 cfi_add_CFA_def_cfa_register (30);
4060 if (p->fp_regno != 30 || p->mask || p->fmask || p->frame_size)
4062 unsigned int mask;
4063 offsetT offset;
4065 cfi_add_advance_loc (p->prologue_sym);
4067 if (p->fp_regno != 30)
4068 if (p->frame_size != 0)
4069 cfi_add_CFA_def_cfa (p->fp_regno, p->frame_size);
4070 else
4071 cfi_add_CFA_def_cfa_register (p->fp_regno);
4072 else if (p->frame_size != 0)
4073 cfi_add_CFA_def_cfa_offset (p->frame_size);
4075 mask = p->mask;
4076 offset = p->mask_offset;
4078 /* Recall that $26 is special-cased and stored first. */
4079 if ((mask >> 26) & 1)
4081 cfi_add_CFA_offset (26, offset);
4082 offset += 8;
4083 mask &= ~(1 << 26);
4085 while (mask)
4087 unsigned int i;
4088 i = mask & -mask;
4089 mask ^= i;
4090 i = ffs (i) - 1;
4092 cfi_add_CFA_offset (i, offset);
4093 offset += 8;
4096 mask = p->fmask;
4097 offset = p->fmask_offset;
4098 while (mask)
4100 unsigned int i;
4101 i = mask & -mask;
4102 mask ^= i;
4103 i = ffs (i) - 1;
4105 cfi_add_CFA_offset (i + 32, offset);
4106 offset += 8;
4110 cfi_end_fde (p->func_end_sym);
4114 static void
4115 s_alpha_usepv (int unused ATTRIBUTE_UNUSED)
4117 char *name, name_end;
4118 char *which, which_end;
4119 symbolS *sym;
4120 int other;
4122 name = input_line_pointer;
4123 name_end = get_symbol_end ();
4125 if (! is_name_beginner (*name))
4127 as_bad (_(".usepv directive has no name"));
4128 *input_line_pointer = name_end;
4129 ignore_rest_of_line ();
4130 return;
4133 sym = symbol_find_or_make (name);
4134 *input_line_pointer++ = name_end;
4136 if (name_end != ',')
4138 as_bad (_(".usepv directive has no type"));
4139 ignore_rest_of_line ();
4140 return;
4143 SKIP_WHITESPACE ();
4144 which = input_line_pointer;
4145 which_end = get_symbol_end ();
4147 if (strcmp (which, "no") == 0)
4148 other = STO_ALPHA_NOPV;
4149 else if (strcmp (which, "std") == 0)
4150 other = STO_ALPHA_STD_GPLOAD;
4151 else
4153 as_bad (_("unknown argument for .usepv"));
4154 other = 0;
4157 *input_line_pointer = which_end;
4158 demand_empty_rest_of_line ();
4160 S_SET_OTHER (sym, other | (S_GET_OTHER (sym) & ~STO_ALPHA_STD_GPLOAD));
4162 #endif /* OBJ_ELF */
4164 /* Standard calling conventions leaves the CFA at $30 on entry. */
4166 void
4167 alpha_cfi_frame_initial_instructions (void)
4169 cfi_add_CFA_def_cfa_register (30);
4172 #ifdef OBJ_EVAX
4174 /* Get name of section. */
4175 static char *
4176 s_alpha_section_name (void)
4178 char *name;
4180 SKIP_WHITESPACE ();
4181 if (*input_line_pointer == '"')
4183 int dummy;
4185 name = demand_copy_C_string (&dummy);
4186 if (name == NULL)
4188 ignore_rest_of_line ();
4189 return NULL;
4192 else
4194 char *end = input_line_pointer;
4196 while (0 == strchr ("\n\t,; ", *end))
4197 end++;
4198 if (end == input_line_pointer)
4200 as_warn (_("missing name"));
4201 ignore_rest_of_line ();
4202 return NULL;
4205 name = xmalloc (end - input_line_pointer + 1);
4206 memcpy (name, input_line_pointer, end - input_line_pointer);
4207 name[end - input_line_pointer] = '\0';
4208 input_line_pointer = end;
4210 SKIP_WHITESPACE ();
4211 return name;
4214 /* Put clear/set flags in one flagword. The LSBs are flags to be set,
4215 the MSBs are the flags to be cleared. */
4217 #define EGPS__V_NO_SHIFT 16
4218 #define EGPS__V_MASK 0xffff
4220 /* Parse one VMS section flag. */
4222 static flagword
4223 s_alpha_section_word (char *str, size_t len)
4225 int no = 0;
4226 flagword flag = 0;
4228 if (len == 5 && strncmp (str, "NO", 2) == 0)
4230 no = 1;
4231 str += 2;
4232 len -= 2;
4235 if (len == 3)
4237 if (strncmp (str, "PIC", 3) == 0)
4238 flag = EGPS__V_PIC;
4239 else if (strncmp (str, "LIB", 3) == 0)
4240 flag = EGPS__V_LIB;
4241 else if (strncmp (str, "OVR", 3) == 0)
4242 flag = EGPS__V_OVR;
4243 else if (strncmp (str, "REL", 3) == 0)
4244 flag = EGPS__V_REL;
4245 else if (strncmp (str, "GBL", 3) == 0)
4246 flag = EGPS__V_GBL;
4247 else if (strncmp (str, "SHR", 3) == 0)
4248 flag = EGPS__V_SHR;
4249 else if (strncmp (str, "EXE", 3) == 0)
4250 flag = EGPS__V_EXE;
4251 else if (strncmp (str, "WRT", 3) == 0)
4252 flag = EGPS__V_WRT;
4253 else if (strncmp (str, "VEC", 3) == 0)
4254 flag = EGPS__V_VEC;
4255 else if (strncmp (str, "MOD", 3) == 0)
4257 flag = no ? EGPS__V_NOMOD : EGPS__V_NOMOD << EGPS__V_NO_SHIFT;
4258 no = 0;
4260 else if (strncmp (str, "COM", 3) == 0)
4261 flag = EGPS__V_COM;
4264 if (flag == 0)
4266 char c = str[len];
4267 str[len] = 0;
4268 as_warn (_("unknown section attribute %s"), str);
4269 str[len] = c;
4270 return 0;
4273 if (no)
4274 return flag << EGPS__V_NO_SHIFT;
4275 else
4276 return flag;
4279 /* Handle the section specific pseudo-op. */
4281 #define EVAX_SECTION_COUNT 5
4283 static char *section_name[EVAX_SECTION_COUNT + 1] =
4284 { "NULL", ".rdata", ".comm", ".link", ".ctors", ".dtors" };
4286 static void
4287 s_alpha_section (int secid)
4289 int temp;
4290 char *name, *beg;
4291 segT sec;
4292 flagword vms_flags = 0;
4293 symbolS *symbol;
4295 if (secid == 0)
4297 name = s_alpha_section_name ();
4298 if (name == NULL)
4299 return;
4300 sec = subseg_new (name, 0);
4301 if (*input_line_pointer == ',')
4303 /* Skip the comma. */
4304 ++input_line_pointer;
4305 SKIP_WHITESPACE ();
4309 char c;
4311 SKIP_WHITESPACE ();
4312 beg = input_line_pointer;
4313 c = get_symbol_end ();
4314 *input_line_pointer = c;
4316 vms_flags |= s_alpha_section_word (beg, input_line_pointer - beg);
4318 SKIP_WHITESPACE ();
4320 while (*input_line_pointer++ == ',');
4321 --input_line_pointer;
4324 symbol = symbol_find_or_make (name);
4325 S_SET_SEGMENT (symbol, sec);
4326 symbol_get_bfdsym (symbol)->flags |= BSF_SECTION_SYM;
4327 bfd_vms_set_section_flags
4328 (stdoutput, sec,
4329 (vms_flags >> EGPS__V_NO_SHIFT) & EGPS__V_MASK,
4330 vms_flags & EGPS__V_MASK);
4332 else
4334 temp = get_absolute_expression ();
4335 subseg_new (section_name[secid], 0);
4338 demand_empty_rest_of_line ();
4339 alpha_insn_label = NULL;
4340 alpha_auto_align_on = 1;
4341 alpha_current_align = 0;
4344 static void
4345 s_alpha_literals (int ignore ATTRIBUTE_UNUSED)
4347 subseg_new (".literals", 0);
4348 demand_empty_rest_of_line ();
4349 alpha_insn_label = NULL;
4350 alpha_auto_align_on = 1;
4351 alpha_current_align = 0;
4354 /* Parse .ent directives. */
4356 static void
4357 s_alpha_ent (int ignore ATTRIBUTE_UNUSED)
4359 symbolS *symbol;
4360 expressionS symexpr;
4362 alpha_evax_proc
4363 = (struct alpha_evax_procs *) xmalloc (sizeof (struct alpha_evax_procs));
4365 alpha_evax_proc->pdsckind = 0;
4366 alpha_evax_proc->framereg = -1;
4367 alpha_evax_proc->framesize = 0;
4368 alpha_evax_proc->rsa_offset = 0;
4369 alpha_evax_proc->ra_save = AXP_REG_RA;
4370 alpha_evax_proc->fp_save = -1;
4371 alpha_evax_proc->imask = 0;
4372 alpha_evax_proc->fmask = 0;
4373 alpha_evax_proc->prologue = 0;
4374 alpha_evax_proc->type = 0;
4375 alpha_evax_proc->handler = 0;
4376 alpha_evax_proc->handler_data = 0;
4378 expression (&symexpr);
4380 if (symexpr.X_op != O_symbol)
4382 as_fatal (_(".ent directive has no symbol"));
4383 demand_empty_rest_of_line ();
4384 return;
4387 symbol = make_expr_symbol (&symexpr);
4388 symbol_get_bfdsym (symbol)->flags |= BSF_FUNCTION;
4389 alpha_evax_proc->symbol = symbol;
4391 (void) hash_insert
4392 (alpha_evax_proc_hash,
4393 symbol_get_bfdsym (alpha_evax_proc->symbol)->name, (PTR)alpha_evax_proc);
4395 demand_empty_rest_of_line ();
4398 static void
4399 s_alpha_handler (int is_data)
4401 if (is_data)
4402 alpha_evax_proc->handler_data = get_absolute_expression ();
4403 else
4405 char *name, name_end;
4406 name = input_line_pointer;
4407 name_end = get_symbol_end ();
4409 if (! is_name_beginner (*name))
4411 as_warn (_(".handler directive has no name"));
4412 *input_line_pointer = name_end;
4414 else
4416 symbolS *sym;
4418 sym = symbol_find_or_make (name);
4419 symbol_get_bfdsym (sym)->flags |= BSF_FUNCTION;
4420 alpha_evax_proc->handler = sym;
4421 *input_line_pointer = name_end;
4424 demand_empty_rest_of_line ();
4427 /* Parse .frame <framreg>,<framesize>,RA,<rsa_offset> directives. */
4429 static void
4430 s_alpha_frame (int ignore ATTRIBUTE_UNUSED)
4432 long val;
4434 alpha_evax_proc->framereg = tc_get_register (1);
4436 SKIP_WHITESPACE ();
4437 if (*input_line_pointer++ != ','
4438 || get_absolute_expression_and_terminator (&val) != ',')
4440 as_warn (_("Bad .frame directive 1./2. param"));
4441 --input_line_pointer;
4442 demand_empty_rest_of_line ();
4443 return;
4446 alpha_evax_proc->framesize = val;
4448 (void) tc_get_register (1);
4449 SKIP_WHITESPACE ();
4450 if (*input_line_pointer++ != ',')
4452 as_warn (_("Bad .frame directive 3./4. param"));
4453 --input_line_pointer;
4454 demand_empty_rest_of_line ();
4455 return;
4457 alpha_evax_proc->rsa_offset = get_absolute_expression ();
4460 static void
4461 s_alpha_prologue (int ignore ATTRIBUTE_UNUSED)
4463 int arg;
4465 arg = get_absolute_expression ();
4466 demand_empty_rest_of_line ();
4467 alpha_prologue_label = symbol_new
4468 (FAKE_LABEL_NAME, now_seg, (valueT) frag_now_fix (), frag_now);
4471 static void
4472 s_alpha_pdesc (int ignore ATTRIBUTE_UNUSED)
4474 char *name;
4475 char name_end;
4476 register char *p;
4477 expressionS exp;
4478 symbolS *entry_sym;
4479 fixS *fixp;
4480 segment_info_type *seginfo = seg_info (alpha_link_section);
4481 const char *entry_sym_name;
4482 char *sym_name;
4483 int len;
4485 if (now_seg != alpha_link_section)
4487 as_bad (_(".pdesc directive not in link (.link) section"));
4488 demand_empty_rest_of_line ();
4489 return;
4492 expression (&exp);
4493 if (exp.X_op != O_symbol)
4495 as_warn (_(".pdesc directive has no entry symbol"));
4496 demand_empty_rest_of_line ();
4497 return;
4500 entry_sym = make_expr_symbol (&exp);
4501 entry_sym_name = symbol_get_bfdsym (entry_sym)->name;
4503 len = strlen (entry_sym_name);
4504 sym_name = (char *) xmalloc (len - 4 + 1);
4505 strncpy (sym_name, entry_sym_name, len - 4);
4506 sym_name [len - 4] = 0;
4508 alpha_evax_proc = (struct alpha_evax_procs *)
4509 hash_find (alpha_evax_proc_hash, sym_name);
4511 if (!alpha_evax_proc || !S_IS_DEFINED (alpha_evax_proc->symbol))
4513 as_fatal (_(".pdesc has no matching .ent"));
4514 demand_empty_rest_of_line ();
4515 return;
4518 *symbol_get_obj (alpha_evax_proc->symbol) =
4519 (valueT) seginfo->literal_pool_size;
4521 alpha_evax_proc->symbol->sy_obj = (valueT)seginfo->literal_pool_size;
4523 /* Save bfd symbol of proc entry in function symbol. */
4524 ((struct evax_private_udata_struct *)
4525 symbol_get_bfdsym (alpha_evax_proc->symbol)->udata.p)->enbsym
4526 = symbol_get_bfdsym (entry_sym);
4528 SKIP_WHITESPACE ();
4529 if (*input_line_pointer++ != ',')
4531 as_warn (_("No comma after .pdesc <entryname>"));
4532 demand_empty_rest_of_line ();
4533 return;
4536 SKIP_WHITESPACE ();
4537 name = input_line_pointer;
4538 name_end = get_symbol_end ();
4540 if (strncmp (name, "stack", 5) == 0)
4541 alpha_evax_proc->pdsckind = PDSC_S_K_KIND_FP_STACK;
4543 else if (strncmp (name, "reg", 3) == 0)
4544 alpha_evax_proc->pdsckind = PDSC_S_K_KIND_FP_REGISTER;
4546 else if (strncmp (name, "null", 4) == 0)
4547 alpha_evax_proc->pdsckind = PDSC_S_K_KIND_NULL;
4549 else
4551 as_fatal (_("unknown procedure kind"));
4552 demand_empty_rest_of_line ();
4553 return;
4556 *input_line_pointer = name_end;
4557 demand_empty_rest_of_line ();
4559 #ifdef md_flush_pending_output
4560 md_flush_pending_output ();
4561 #endif
4563 frag_align (3, 0, 0);
4564 p = frag_more (16);
4565 fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
4566 fixp->fx_done = 1;
4567 seginfo->literal_pool_size += 16;
4569 *p = alpha_evax_proc->pdsckind
4570 | ((alpha_evax_proc->framereg == 29) ? PDSC_S_M_BASE_REG_IS_FP : 0)
4571 | ((alpha_evax_proc->handler) ? PDSC_S_M_HANDLER_VALID : 0)
4572 | ((alpha_evax_proc->handler_data) ? PDSC_S_M_HANDLER_DATA_VALID : 0);
4573 *(p + 1) = PDSC_S_M_NATIVE | PDSC_S_M_NO_JACKET;
4575 switch (alpha_evax_proc->pdsckind)
4577 case PDSC_S_K_KIND_NULL:
4578 *(p + 2) = 0;
4579 *(p + 3) = 0;
4580 break;
4581 case PDSC_S_K_KIND_FP_REGISTER:
4582 *(p + 2) = alpha_evax_proc->fp_save;
4583 *(p + 3) = alpha_evax_proc->ra_save;
4584 break;
4585 case PDSC_S_K_KIND_FP_STACK:
4586 md_number_to_chars (p + 2, (valueT) alpha_evax_proc->rsa_offset, 2);
4587 break;
4588 default: /* impossible */
4589 break;
4592 *(p + 4) = 0;
4593 *(p + 5) = alpha_evax_proc->type & 0x0f;
4595 /* Signature offset. */
4596 md_number_to_chars (p + 6, (valueT) 0, 2);
4598 fix_new_exp (frag_now, p - frag_now->fr_literal+8, 8, &exp, 0, BFD_RELOC_64);
4600 if (alpha_evax_proc->pdsckind == PDSC_S_K_KIND_NULL)
4601 return;
4603 /* Add dummy fix to make add_to_link_pool work. */
4604 p = frag_more (6);
4605 fixp = fix_new (frag_now, p - frag_now->fr_literal, 6, 0, 0, 0, 0);
4606 fixp->fx_done = 1;
4607 seginfo->literal_pool_size += 6;
4609 /* pdesc+16: Size. */
4610 md_number_to_chars (p, (valueT) alpha_evax_proc->framesize, 4);
4612 md_number_to_chars (p + 4, (valueT) 0, 2);
4614 /* Entry length. */
4615 exp.X_op = O_subtract;
4616 exp.X_add_symbol = alpha_prologue_label;
4617 exp.X_op_symbol = entry_sym;
4618 emit_expr (&exp, 2);
4620 if (alpha_evax_proc->pdsckind == PDSC_S_K_KIND_FP_REGISTER)
4621 return;
4623 /* Add dummy fix to make add_to_link_pool work. */
4624 p = frag_more (8);
4625 fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
4626 fixp->fx_done = 1;
4627 seginfo->literal_pool_size += 8;
4629 /* pdesc+24: register masks. */
4631 md_number_to_chars (p, alpha_evax_proc->imask, 4);
4632 md_number_to_chars (p + 4, alpha_evax_proc->fmask, 4);
4634 if (alpha_evax_proc->handler)
4636 p = frag_more (8);
4637 fixp = fix_new (frag_now, p - frag_now->fr_literal, 8,
4638 alpha_evax_proc->handler, 0, 0, BFD_RELOC_64);
4641 if (alpha_evax_proc->handler_data)
4643 /* Add dummy fix to make add_to_link_pool work. */
4644 p = frag_more (8);
4645 fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
4646 fixp->fx_done = 1;
4647 seginfo->literal_pool_size += 8;
4648 md_number_to_chars (p, alpha_evax_proc->handler_data, 8);
4652 /* Support for crash debug on vms. */
4654 static void
4655 s_alpha_name (int ignore ATTRIBUTE_UNUSED)
4657 char *p;
4658 expressionS exp;
4659 segment_info_type *seginfo = seg_info (alpha_link_section);
4661 if (now_seg != alpha_link_section)
4663 as_bad (_(".name directive not in link (.link) section"));
4664 demand_empty_rest_of_line ();
4665 return;
4668 expression (&exp);
4669 if (exp.X_op != O_symbol)
4671 as_warn (_(".name directive has no symbol"));
4672 demand_empty_rest_of_line ();
4673 return;
4676 demand_empty_rest_of_line ();
4678 #ifdef md_flush_pending_output
4679 md_flush_pending_output ();
4680 #endif
4682 frag_align (3, 0, 0);
4683 p = frag_more (8);
4684 seginfo->literal_pool_size += 8;
4686 fix_new_exp (frag_now, p - frag_now->fr_literal, 8, &exp, 0, BFD_RELOC_64);
4689 static void
4690 s_alpha_linkage (int ignore ATTRIBUTE_UNUSED)
4692 expressionS exp;
4693 char *p;
4694 fixS *fixp;
4696 #ifdef md_flush_pending_output
4697 md_flush_pending_output ();
4698 #endif
4700 expression (&exp);
4701 if (exp.X_op != O_symbol)
4703 as_fatal (_("No symbol after .linkage"));
4705 else
4707 struct alpha_linkage_fixups *linkage_fixup;
4709 p = frag_more (LKP_S_K_SIZE);
4710 memset (p, 0, LKP_S_K_SIZE);
4711 fixp = fix_new_exp
4712 (frag_now, p - frag_now->fr_literal, LKP_S_K_SIZE, &exp, 0,\
4713 BFD_RELOC_ALPHA_LINKAGE);
4715 linkage_fixup = (struct alpha_linkage_fixups *)
4716 xmalloc (sizeof (struct alpha_linkage_fixups));
4718 linkage_fixup->fixp = fixp;
4719 linkage_fixup->next = 0;
4721 if (alpha_insn_label == 0)
4722 alpha_insn_label = symbol_new
4723 (FAKE_LABEL_NAME, now_seg, (valueT) frag_now_fix (), frag_now);
4724 linkage_fixup->label = alpha_insn_label;
4726 if (alpha_linkage_fixup_root == 0)
4728 alpha_linkage_fixup_root = alpha_linkage_fixup_tail = linkage_fixup;
4729 alpha_linkage_fixup_tail->next = 0;
4731 else
4733 alpha_linkage_fixup_tail->next = linkage_fixup;
4734 alpha_linkage_fixup_tail = linkage_fixup;
4735 alpha_linkage_fixup_tail->next = 0;
4738 demand_empty_rest_of_line ();
4741 static void
4742 s_alpha_code_address (int ignore ATTRIBUTE_UNUSED)
4744 expressionS exp;
4745 char *p;
4747 #ifdef md_flush_pending_output
4748 md_flush_pending_output ();
4749 #endif
4751 expression (&exp);
4752 if (exp.X_op != O_symbol)
4753 as_fatal (_("No symbol after .code_address"));
4754 else
4756 p = frag_more (8);
4757 memset (p, 0, 8);
4758 fix_new_exp (frag_now, p - frag_now->fr_literal, 8, &exp, 0,\
4759 BFD_RELOC_ALPHA_CODEADDR);
4761 demand_empty_rest_of_line ();
4764 static void
4765 s_alpha_fp_save (int ignore ATTRIBUTE_UNUSED)
4768 alpha_evax_proc->fp_save = tc_get_register (1);
4770 demand_empty_rest_of_line ();
4773 static void
4774 s_alpha_mask (int ignore ATTRIBUTE_UNUSED)
4776 long val;
4778 if (get_absolute_expression_and_terminator (&val) != ',')
4780 as_warn (_("Bad .mask directive"));
4781 --input_line_pointer;
4783 else
4785 alpha_evax_proc->imask = val;
4786 (void) get_absolute_expression ();
4788 demand_empty_rest_of_line ();
4791 static void
4792 s_alpha_fmask (int ignore ATTRIBUTE_UNUSED)
4794 long val;
4796 if (get_absolute_expression_and_terminator (&val) != ',')
4798 as_warn (_("Bad .fmask directive"));
4799 --input_line_pointer;
4801 else
4803 alpha_evax_proc->fmask = val;
4804 (void) get_absolute_expression ();
4806 demand_empty_rest_of_line ();
4809 static void
4810 s_alpha_end (int ignore ATTRIBUTE_UNUSED)
4812 char c;
4814 c = get_symbol_end ();
4815 *input_line_pointer = c;
4816 demand_empty_rest_of_line ();
4817 alpha_evax_proc = 0;
4820 static void
4821 s_alpha_file (int ignore ATTRIBUTE_UNUSED)
4823 symbolS *s;
4824 int length;
4825 static char case_hack[32];
4827 sprintf (case_hack, "<CASE:%01d%01d>",
4828 alpha_flag_hash_long_names, alpha_flag_show_after_trunc);
4830 s = symbol_find_or_make (case_hack);
4831 symbol_get_bfdsym (s)->flags |= BSF_FILE;
4833 get_absolute_expression ();
4834 s = symbol_find_or_make (demand_copy_string (&length));
4835 symbol_get_bfdsym (s)->flags |= BSF_FILE;
4836 demand_empty_rest_of_line ();
4838 #endif /* OBJ_EVAX */
4840 /* Handle the .gprel32 pseudo op. */
4842 static void
4843 s_alpha_gprel32 (int ignore ATTRIBUTE_UNUSED)
4845 expressionS e;
4846 char *p;
4848 SKIP_WHITESPACE ();
4849 expression (&e);
4851 #ifdef OBJ_ELF
4852 switch (e.X_op)
4854 case O_constant:
4855 e.X_add_symbol = section_symbol (absolute_section);
4856 e.X_op = O_symbol;
4857 /* FALLTHRU */
4858 case O_symbol:
4859 break;
4860 default:
4861 abort ();
4863 #else
4864 #ifdef OBJ_ECOFF
4865 switch (e.X_op)
4867 case O_constant:
4868 e.X_add_symbol = section_symbol (absolute_section);
4869 /* fall through */
4870 case O_symbol:
4871 e.X_op = O_subtract;
4872 e.X_op_symbol = alpha_gp_symbol;
4873 break;
4874 default:
4875 abort ();
4877 #endif
4878 #endif
4880 if (alpha_auto_align_on && alpha_current_align < 2)
4881 alpha_align (2, (char *) NULL, alpha_insn_label, 0);
4882 if (alpha_current_align > 2)
4883 alpha_current_align = 2;
4884 alpha_insn_label = NULL;
4886 p = frag_more (4);
4887 memset (p, 0, 4);
4888 fix_new_exp (frag_now, p - frag_now->fr_literal, 4,
4889 &e, 0, BFD_RELOC_GPREL32);
4892 /* Handle floating point allocation pseudo-ops. This is like the
4893 generic vresion, but it makes sure the current label, if any, is
4894 correctly aligned. */
4896 static void
4897 s_alpha_float_cons (int type)
4899 int log_size;
4901 switch (type)
4903 default:
4904 case 'f':
4905 case 'F':
4906 log_size = 2;
4907 break;
4909 case 'd':
4910 case 'D':
4911 case 'G':
4912 log_size = 3;
4913 break;
4915 case 'x':
4916 case 'X':
4917 case 'p':
4918 case 'P':
4919 log_size = 4;
4920 break;
4923 if (alpha_auto_align_on && alpha_current_align < log_size)
4924 alpha_align (log_size, (char *) NULL, alpha_insn_label, 0);
4925 if (alpha_current_align > log_size)
4926 alpha_current_align = log_size;
4927 alpha_insn_label = NULL;
4929 float_cons (type);
4932 /* Handle the .proc pseudo op. We don't really do much with it except
4933 parse it. */
4935 static void
4936 s_alpha_proc (int is_static ATTRIBUTE_UNUSED)
4938 char *name;
4939 char c;
4940 char *p;
4941 symbolS *symbolP;
4942 int temp;
4944 /* Takes ".proc name,nargs". */
4945 SKIP_WHITESPACE ();
4946 name = input_line_pointer;
4947 c = get_symbol_end ();
4948 p = input_line_pointer;
4949 symbolP = symbol_find_or_make (name);
4950 *p = c;
4951 SKIP_WHITESPACE ();
4952 if (*input_line_pointer != ',')
4954 *p = 0;
4955 as_warn (_("Expected comma after name \"%s\""), name);
4956 *p = c;
4957 temp = 0;
4958 ignore_rest_of_line ();
4960 else
4962 input_line_pointer++;
4963 temp = get_absolute_expression ();
4965 /* *symbol_get_obj (symbolP) = (signed char) temp; */
4966 as_warn (_("unhandled: .proc %s,%d"), name, temp);
4967 demand_empty_rest_of_line ();
4970 /* Handle the .set pseudo op. This is used to turn on and off most of
4971 the assembler features. */
4973 static void
4974 s_alpha_set (int x ATTRIBUTE_UNUSED)
4976 char *name, ch, *s;
4977 int yesno = 1;
4979 SKIP_WHITESPACE ();
4980 name = input_line_pointer;
4981 ch = get_symbol_end ();
4983 s = name;
4984 if (s[0] == 'n' && s[1] == 'o')
4986 yesno = 0;
4987 s += 2;
4989 if (!strcmp ("reorder", s))
4990 /* ignore */ ;
4991 else if (!strcmp ("at", s))
4992 alpha_noat_on = !yesno;
4993 else if (!strcmp ("macro", s))
4994 alpha_macros_on = yesno;
4995 else if (!strcmp ("move", s))
4996 /* ignore */ ;
4997 else if (!strcmp ("volatile", s))
4998 /* ignore */ ;
4999 else
5000 as_warn (_("Tried to .set unrecognized mode `%s'"), name);
5002 *input_line_pointer = ch;
5003 demand_empty_rest_of_line ();
5006 /* Handle the .base pseudo op. This changes the assembler's notion of
5007 the $gp register. */
5009 static void
5010 s_alpha_base (int ignore ATTRIBUTE_UNUSED)
5012 SKIP_WHITESPACE ();
5014 if (*input_line_pointer == '$')
5016 /* $rNN form. */
5017 input_line_pointer++;
5018 if (*input_line_pointer == 'r')
5019 input_line_pointer++;
5022 alpha_gp_register = get_absolute_expression ();
5023 if (alpha_gp_register < 0 || alpha_gp_register > 31)
5025 alpha_gp_register = AXP_REG_GP;
5026 as_warn (_("Bad base register, using $%d."), alpha_gp_register);
5029 demand_empty_rest_of_line ();
5032 /* Handle the .align pseudo-op. This aligns to a power of two. It
5033 also adjusts any current instruction label. We treat this the same
5034 way the MIPS port does: .align 0 turns off auto alignment. */
5036 static void
5037 s_alpha_align (int ignore ATTRIBUTE_UNUSED)
5039 int align;
5040 char fill, *pfill;
5041 long max_alignment = 16;
5043 align = get_absolute_expression ();
5044 if (align > max_alignment)
5046 align = max_alignment;
5047 as_bad (_("Alignment too large: %d. assumed"), align);
5049 else if (align < 0)
5051 as_warn (_("Alignment negative: 0 assumed"));
5052 align = 0;
5055 if (*input_line_pointer == ',')
5057 input_line_pointer++;
5058 fill = get_absolute_expression ();
5059 pfill = &fill;
5061 else
5062 pfill = NULL;
5064 if (align != 0)
5066 alpha_auto_align_on = 1;
5067 alpha_align (align, pfill, alpha_insn_label, 1);
5069 else
5071 alpha_auto_align_on = 0;
5074 demand_empty_rest_of_line ();
5077 /* Hook the normal string processor to reset known alignment. */
5079 static void
5080 s_alpha_stringer (int terminate)
5082 alpha_current_align = 0;
5083 alpha_insn_label = NULL;
5084 stringer (8 + terminate);
5087 /* Hook the normal space processing to reset known alignment. */
5089 static void
5090 s_alpha_space (int ignore)
5092 alpha_current_align = 0;
5093 alpha_insn_label = NULL;
5094 s_space (ignore);
5097 /* Hook into cons for auto-alignment. */
5099 void
5100 alpha_cons_align (int size)
5102 int log_size;
5104 log_size = 0;
5105 while ((size >>= 1) != 0)
5106 ++log_size;
5108 if (alpha_auto_align_on && alpha_current_align < log_size)
5109 alpha_align (log_size, (char *) NULL, alpha_insn_label, 0);
5110 if (alpha_current_align > log_size)
5111 alpha_current_align = log_size;
5112 alpha_insn_label = NULL;
5115 /* Here come the .uword, .ulong, and .uquad explicitly unaligned
5116 pseudos. We just turn off auto-alignment and call down to cons. */
5118 static void
5119 s_alpha_ucons (int bytes)
5121 int hold = alpha_auto_align_on;
5122 alpha_auto_align_on = 0;
5123 cons (bytes);
5124 alpha_auto_align_on = hold;
5127 /* Switch the working cpu type. */
5129 static void
5130 s_alpha_arch (int ignored ATTRIBUTE_UNUSED)
5132 char *name, ch;
5133 const struct cpu_type *p;
5135 SKIP_WHITESPACE ();
5136 name = input_line_pointer;
5137 ch = get_symbol_end ();
5139 for (p = cpu_types; p->name; ++p)
5140 if (strcmp (name, p->name) == 0)
5142 alpha_target_name = p->name, alpha_target = p->flags;
5143 goto found;
5145 as_warn (_("Unknown CPU identifier `%s'"), name);
5147 found:
5148 *input_line_pointer = ch;
5149 demand_empty_rest_of_line ();
5152 #ifdef DEBUG1
5153 /* print token expression with alpha specific extension. */
5155 static void
5156 alpha_print_token (FILE *f, const expressionS *exp)
5158 switch (exp->X_op)
5160 case O_cpregister:
5161 putc (',', f);
5162 /* FALLTHRU */
5163 case O_pregister:
5164 putc ('(', f);
5166 expressionS nexp = *exp;
5167 nexp.X_op = O_register;
5168 print_expr_1 (f, &nexp);
5170 putc (')', f);
5171 break;
5172 default:
5173 print_expr_1 (f, exp);
5174 break;
5177 #endif
5179 /* The target specific pseudo-ops which we support. */
5181 const pseudo_typeS md_pseudo_table[] =
5183 #ifdef OBJ_ECOFF
5184 {"comm", s_alpha_comm, 0}, /* OSF1 compiler does this. */
5185 {"rdata", s_alpha_rdata, 0},
5186 #endif
5187 {"text", s_alpha_text, 0},
5188 {"data", s_alpha_data, 0},
5189 #ifdef OBJ_ECOFF
5190 {"sdata", s_alpha_sdata, 0},
5191 #endif
5192 #ifdef OBJ_ELF
5193 {"section", s_alpha_section, 0},
5194 {"section.s", s_alpha_section, 0},
5195 {"sect", s_alpha_section, 0},
5196 {"sect.s", s_alpha_section, 0},
5197 #endif
5198 #ifdef OBJ_EVAX
5199 {"section", s_alpha_section, 0},
5200 {"literals", s_alpha_literals, 0},
5201 {"pdesc", s_alpha_pdesc, 0},
5202 {"name", s_alpha_name, 0},
5203 {"linkage", s_alpha_linkage, 0},
5204 {"code_address", s_alpha_code_address, 0},
5205 {"ent", s_alpha_ent, 0},
5206 {"frame", s_alpha_frame, 0},
5207 {"fp_save", s_alpha_fp_save, 0},
5208 {"mask", s_alpha_mask, 0},
5209 {"fmask", s_alpha_fmask, 0},
5210 {"end", s_alpha_end, 0},
5211 {"file", s_alpha_file, 0},
5212 {"rdata", s_alpha_section, 1},
5213 {"comm", s_alpha_comm, 0},
5214 {"link", s_alpha_section, 3},
5215 {"ctors", s_alpha_section, 4},
5216 {"dtors", s_alpha_section, 5},
5217 {"handler", s_alpha_handler, 0},
5218 {"handler_data", s_alpha_handler, 1},
5219 #endif
5220 #ifdef OBJ_ELF
5221 /* Frame related pseudos. */
5222 {"ent", s_alpha_ent, 0},
5223 {"end", s_alpha_end, 0},
5224 {"mask", s_alpha_mask, 0},
5225 {"fmask", s_alpha_mask, 1},
5226 {"frame", s_alpha_frame, 0},
5227 {"prologue", s_alpha_prologue, 0},
5228 {"file", s_alpha_file, 5},
5229 {"loc", s_alpha_loc, 9},
5230 {"stabs", s_alpha_stab, 's'},
5231 {"stabn", s_alpha_stab, 'n'},
5232 {"usepv", s_alpha_usepv, 0},
5233 /* COFF debugging related pseudos. */
5234 {"begin", s_alpha_coff_wrapper, 0},
5235 {"bend", s_alpha_coff_wrapper, 1},
5236 {"def", s_alpha_coff_wrapper, 2},
5237 {"dim", s_alpha_coff_wrapper, 3},
5238 {"endef", s_alpha_coff_wrapper, 4},
5239 {"scl", s_alpha_coff_wrapper, 5},
5240 {"tag", s_alpha_coff_wrapper, 6},
5241 {"val", s_alpha_coff_wrapper, 7},
5242 #else
5243 #ifdef OBJ_EVAX
5244 {"prologue", s_alpha_prologue, 0},
5245 #else
5246 {"prologue", s_ignore, 0},
5247 #endif
5248 #endif
5249 {"gprel32", s_alpha_gprel32, 0},
5250 {"t_floating", s_alpha_float_cons, 'd'},
5251 {"s_floating", s_alpha_float_cons, 'f'},
5252 {"f_floating", s_alpha_float_cons, 'F'},
5253 {"g_floating", s_alpha_float_cons, 'G'},
5254 {"d_floating", s_alpha_float_cons, 'D'},
5256 {"proc", s_alpha_proc, 0},
5257 {"aproc", s_alpha_proc, 1},
5258 {"set", s_alpha_set, 0},
5259 {"reguse", s_ignore, 0},
5260 {"livereg", s_ignore, 0},
5261 {"base", s_alpha_base, 0}, /*??*/
5262 {"option", s_ignore, 0},
5263 {"aent", s_ignore, 0},
5264 {"ugen", s_ignore, 0},
5265 {"eflag", s_ignore, 0},
5267 {"align", s_alpha_align, 0},
5268 {"double", s_alpha_float_cons, 'd'},
5269 {"float", s_alpha_float_cons, 'f'},
5270 {"single", s_alpha_float_cons, 'f'},
5271 {"ascii", s_alpha_stringer, 0},
5272 {"asciz", s_alpha_stringer, 1},
5273 {"string", s_alpha_stringer, 1},
5274 {"space", s_alpha_space, 0},
5275 {"skip", s_alpha_space, 0},
5276 {"zero", s_alpha_space, 0},
5278 /* Unaligned data pseudos. */
5279 {"uword", s_alpha_ucons, 2},
5280 {"ulong", s_alpha_ucons, 4},
5281 {"uquad", s_alpha_ucons, 8},
5283 #ifdef OBJ_ELF
5284 /* Dwarf wants these versions of unaligned. */
5285 {"2byte", s_alpha_ucons, 2},
5286 {"4byte", s_alpha_ucons, 4},
5287 {"8byte", s_alpha_ucons, 8},
5288 #endif
5290 /* We don't do any optimizing, so we can safely ignore these. */
5291 {"noalias", s_ignore, 0},
5292 {"alias", s_ignore, 0},
5294 {"arch", s_alpha_arch, 0},
5296 {NULL, 0, 0},
5299 #ifdef OBJ_ECOFF
5301 /* @@@ GP selection voodoo. All of this seems overly complicated and
5302 unnecessary; which is the primary reason it's for ECOFF only. */
5304 static inline void
5305 maybe_set_gp (asection *sec)
5307 bfd_vma vma;
5309 if (!sec)
5310 return;
5311 vma = bfd_get_section_vma (foo, sec);
5312 if (vma && vma < alpha_gp_value)
5313 alpha_gp_value = vma;
5316 static void
5317 select_gp_value (void)
5319 gas_assert (alpha_gp_value == 0);
5321 /* Get minus-one in whatever width... */
5322 alpha_gp_value = 0;
5323 alpha_gp_value--;
5325 /* Select the smallest VMA of these existing sections. */
5326 maybe_set_gp (alpha_lita_section);
5328 /* @@ Will a simple 0x8000 work here? If not, why not? */
5329 #define GP_ADJUSTMENT (0x8000 - 0x10)
5331 alpha_gp_value += GP_ADJUSTMENT;
5333 S_SET_VALUE (alpha_gp_symbol, alpha_gp_value);
5335 #ifdef DEBUG1
5336 printf (_("Chose GP value of %lx\n"), alpha_gp_value);
5337 #endif
5339 #endif /* OBJ_ECOFF */
5341 #ifdef OBJ_ELF
5342 /* Map 's' to SHF_ALPHA_GPREL. */
5344 bfd_vma
5345 alpha_elf_section_letter (int letter, char **ptr_msg)
5347 if (letter == 's')
5348 return SHF_ALPHA_GPREL;
5350 *ptr_msg = _("Bad .section directive: want a,s,w,x,M,S,G,T in string");
5351 return -1;
5354 /* Map SHF_ALPHA_GPREL to SEC_SMALL_DATA. */
5356 flagword
5357 alpha_elf_section_flags (flagword flags, bfd_vma attr, int type ATTRIBUTE_UNUSED)
5359 if (attr & SHF_ALPHA_GPREL)
5360 flags |= SEC_SMALL_DATA;
5361 return flags;
5363 #endif /* OBJ_ELF */
5365 /* This is called from HANDLE_ALIGN in write.c. Fill in the contents
5366 of an rs_align_code fragment. */
5368 void
5369 alpha_handle_align (fragS *fragp)
5371 static char const unop[4] = { 0x00, 0x00, 0xfe, 0x2f };
5372 static char const nopunop[8] =
5374 0x1f, 0x04, 0xff, 0x47,
5375 0x00, 0x00, 0xfe, 0x2f
5378 int bytes, fix;
5379 char *p;
5381 if (fragp->fr_type != rs_align_code)
5382 return;
5384 bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix;
5385 p = fragp->fr_literal + fragp->fr_fix;
5386 fix = 0;
5388 if (bytes & 3)
5390 fix = bytes & 3;
5391 memset (p, 0, fix);
5392 p += fix;
5393 bytes -= fix;
5396 if (bytes & 4)
5398 memcpy (p, unop, 4);
5399 p += 4;
5400 bytes -= 4;
5401 fix += 4;
5404 memcpy (p, nopunop, 8);
5406 fragp->fr_fix += fix;
5407 fragp->fr_var = 8;
5410 /* Public interface functions. */
5412 /* This function is called once, at assembler startup time. It sets
5413 up all the tables, etc. that the MD part of the assembler will
5414 need, that can be determined before arguments are parsed. */
5416 void
5417 md_begin (void)
5419 unsigned int i;
5421 /* Verify that X_op field is wide enough. */
5423 expressionS e;
5425 e.X_op = O_max;
5426 gas_assert (e.X_op == O_max);
5429 /* Create the opcode hash table. */
5430 alpha_opcode_hash = hash_new ();
5432 for (i = 0; i < alpha_num_opcodes;)
5434 const char *name, *retval, *slash;
5436 name = alpha_opcodes[i].name;
5437 retval = hash_insert (alpha_opcode_hash, name, (void *) &alpha_opcodes[i]);
5438 if (retval)
5439 as_fatal (_("internal error: can't hash opcode `%s': %s"),
5440 name, retval);
5442 /* Some opcodes include modifiers of various sorts with a "/mod"
5443 syntax, like the architecture manual suggests. However, for
5444 use with gcc at least, we also need access to those same opcodes
5445 without the "/". */
5447 if ((slash = strchr (name, '/')) != NULL)
5449 char *p = (char *) xmalloc (strlen (name));
5451 memcpy (p, name, slash - name);
5452 strcpy (p + (slash - name), slash + 1);
5454 (void) hash_insert (alpha_opcode_hash, p, (void *) &alpha_opcodes[i]);
5455 /* Ignore failures -- the opcode table does duplicate some
5456 variants in different forms, like "hw_stq" and "hw_st/q". */
5459 while (++i < alpha_num_opcodes
5460 && (alpha_opcodes[i].name == name
5461 || !strcmp (alpha_opcodes[i].name, name)))
5462 continue;
5465 /* Create the macro hash table. */
5466 alpha_macro_hash = hash_new ();
5468 for (i = 0; i < alpha_num_macros;)
5470 const char *name, *retval;
5472 name = alpha_macros[i].name;
5473 retval = hash_insert (alpha_macro_hash, name, (void *) &alpha_macros[i]);
5474 if (retval)
5475 as_fatal (_("internal error: can't hash macro `%s': %s"),
5476 name, retval);
5478 while (++i < alpha_num_macros
5479 && (alpha_macros[i].name == name
5480 || !strcmp (alpha_macros[i].name, name)))
5481 continue;
5484 /* Construct symbols for each of the registers. */
5485 for (i = 0; i < 32; ++i)
5487 char name[4];
5489 sprintf (name, "$%d", i);
5490 alpha_register_table[i] = symbol_create (name, reg_section, i,
5491 &zero_address_frag);
5494 for (; i < 64; ++i)
5496 char name[5];
5498 sprintf (name, "$f%d", i - 32);
5499 alpha_register_table[i] = symbol_create (name, reg_section, i,
5500 &zero_address_frag);
5503 /* Create the special symbols and sections we'll be using. */
5505 /* So .sbss will get used for tiny objects. */
5506 bfd_set_gp_size (stdoutput, g_switch_value);
5508 #ifdef OBJ_ECOFF
5509 create_literal_section (".lita", &alpha_lita_section, &alpha_lita_symbol);
5511 /* For handling the GP, create a symbol that won't be output in the
5512 symbol table. We'll edit it out of relocs later. */
5513 alpha_gp_symbol = symbol_create ("<GP value>", alpha_lita_section, 0x8000,
5514 &zero_address_frag);
5515 #endif
5517 #ifdef OBJ_EVAX
5518 create_literal_section (".link", &alpha_link_section, &alpha_link_symbol);
5519 alpha_evax_proc_hash = hash_new ();
5520 #endif
5522 #ifdef OBJ_ELF
5523 if (ECOFF_DEBUGGING)
5525 segT sec = subseg_new (".mdebug", (subsegT) 0);
5526 bfd_set_section_flags (stdoutput, sec, SEC_HAS_CONTENTS | SEC_READONLY);
5527 bfd_set_section_alignment (stdoutput, sec, 3);
5529 #endif
5531 /* Create literal lookup hash table. */
5532 alpha_literal_hash = hash_new ();
5534 subseg_set (text_section, 0);
5537 /* The public interface to the instruction assembler. */
5539 void
5540 md_assemble (char *str)
5542 /* Current maximum is 13. */
5543 char opname[32];
5544 expressionS tok[MAX_INSN_ARGS];
5545 int ntok, trunclen;
5546 size_t opnamelen;
5548 /* Split off the opcode. */
5549 opnamelen = strspn (str, "abcdefghijklmnopqrstuvwxyz_/46819");
5550 trunclen = (opnamelen < sizeof (opname) - 1
5551 ? opnamelen
5552 : sizeof (opname) - 1);
5553 memcpy (opname, str, trunclen);
5554 opname[trunclen] = '\0';
5556 /* Tokenize the rest of the line. */
5557 if ((ntok = tokenize_arguments (str + opnamelen, tok, MAX_INSN_ARGS)) < 0)
5559 if (ntok != TOKENIZE_ERROR_REPORT)
5560 as_bad (_("syntax error"));
5562 return;
5565 /* Finish it off. */
5566 assemble_tokens (opname, tok, ntok, alpha_macros_on);
5569 /* Round up a section's size to the appropriate boundary. */
5571 valueT
5572 md_section_align (segT seg, valueT size)
5574 int align = bfd_get_section_alignment (stdoutput, seg);
5575 valueT mask = ((valueT) 1 << align) - 1;
5577 return (size + mask) & ~mask;
5580 /* Turn a string in input_line_pointer into a floating point constant
5581 of type TYPE, and store the appropriate bytes in *LITP. The number
5582 of LITTLENUMS emitted is stored in *SIZEP. An error message is
5583 returned, or NULL on OK. */
5585 char *
5586 md_atof (int type, char *litP, int *sizeP)
5588 extern char *vax_md_atof (int, char *, int *);
5590 switch (type)
5592 /* VAX floats. */
5593 case 'G':
5594 /* vax_md_atof() doesn't like "G" for some reason. */
5595 type = 'g';
5596 case 'F':
5597 case 'D':
5598 return vax_md_atof (type, litP, sizeP);
5600 default:
5601 return ieee_md_atof (type, litP, sizeP, FALSE);
5605 /* Take care of the target-specific command-line options. */
5608 md_parse_option (int c, char *arg)
5610 switch (c)
5612 case 'F':
5613 alpha_nofloats_on = 1;
5614 break;
5616 case OPTION_32ADDR:
5617 alpha_addr32_on = 1;
5618 break;
5620 case 'g':
5621 alpha_debug = 1;
5622 break;
5624 case 'G':
5625 g_switch_value = atoi (arg);
5626 break;
5628 case 'm':
5630 const struct cpu_type *p;
5632 for (p = cpu_types; p->name; ++p)
5633 if (strcmp (arg, p->name) == 0)
5635 alpha_target_name = p->name, alpha_target = p->flags;
5636 goto found;
5638 as_warn (_("Unknown CPU identifier `%s'"), arg);
5639 found:;
5641 break;
5643 #ifdef OBJ_EVAX
5644 case '+': /* For g++. Hash any name > 63 chars long. */
5645 alpha_flag_hash_long_names = 1;
5646 break;
5648 case 'H': /* Show new symbol after hash truncation. */
5649 alpha_flag_show_after_trunc = 1;
5650 break;
5652 case 'h': /* For gnu-c/vax compatibility. */
5653 break;
5655 case OPTION_REPLACE:
5656 alpha_flag_replace = 1;
5657 break;
5659 case OPTION_NOREPLACE:
5660 alpha_flag_replace = 0;
5661 break;
5662 #endif
5664 case OPTION_RELAX:
5665 alpha_flag_relax = 1;
5666 break;
5668 #ifdef OBJ_ELF
5669 case OPTION_MDEBUG:
5670 alpha_flag_mdebug = 1;
5671 break;
5672 case OPTION_NO_MDEBUG:
5673 alpha_flag_mdebug = 0;
5674 break;
5675 #endif
5677 default:
5678 return 0;
5681 return 1;
5684 /* Print a description of the command-line options that we accept. */
5686 void
5687 md_show_usage (FILE *stream)
5689 fputs (_("\
5690 Alpha options:\n\
5691 -32addr treat addresses as 32-bit values\n\
5692 -F lack floating point instructions support\n\
5693 -mev4 | -mev45 | -mev5 | -mev56 | -mpca56 | -mev6 | -mev67 | -mev68 | -mall\n\
5694 specify variant of Alpha architecture\n\
5695 -m21064 | -m21066 | -m21164 | -m21164a | -m21164pc | -m21264 | -m21264a | -m21264b\n\
5696 these variants include PALcode opcodes\n"),
5697 stream);
5698 #ifdef OBJ_EVAX
5699 fputs (_("\
5700 VMS options:\n\
5701 -+ encode (don't truncate) names longer than 64 characters\n\
5702 -H show new symbol after hash truncation\n\
5703 -replace/-noreplace enable or disable the optimization of procedure calls\n"),
5704 stream);
5705 #endif
5708 /* Decide from what point a pc-relative relocation is relative to,
5709 relative to the pc-relative fixup. Er, relatively speaking. */
5711 long
5712 md_pcrel_from (fixS *fixP)
5714 valueT addr = fixP->fx_where + fixP->fx_frag->fr_address;
5716 switch (fixP->fx_r_type)
5718 case BFD_RELOC_23_PCREL_S2:
5719 case BFD_RELOC_ALPHA_HINT:
5720 case BFD_RELOC_ALPHA_BRSGP:
5721 return addr + 4;
5722 default:
5723 return addr;
5727 /* Attempt to simplify or even eliminate a fixup. The return value is
5728 ignored; perhaps it was once meaningful, but now it is historical.
5729 To indicate that a fixup has been eliminated, set fixP->fx_done.
5731 For ELF, here it is that we transform the GPDISP_HI16 reloc we used
5732 internally into the GPDISP reloc used externally. We had to do
5733 this so that we'd have the GPDISP_LO16 reloc as a tag to compute
5734 the distance to the "lda" instruction for setting the addend to
5735 GPDISP. */
5737 void
5738 md_apply_fix (fixS *fixP, valueT * valP, segT seg)
5740 char * const fixpos = fixP->fx_frag->fr_literal + fixP->fx_where;
5741 valueT value = * valP;
5742 unsigned image, size;
5744 switch (fixP->fx_r_type)
5746 /* The GPDISP relocations are processed internally with a symbol
5747 referring to the current function's section; we need to drop
5748 in a value which, when added to the address of the start of
5749 the function, gives the desired GP. */
5750 case BFD_RELOC_ALPHA_GPDISP_HI16:
5752 fixS *next = fixP->fx_next;
5754 /* With user-specified !gpdisp relocations, we can be missing
5755 the matching LO16 reloc. We will have already issued an
5756 error message. */
5757 if (next)
5758 fixP->fx_offset = (next->fx_frag->fr_address + next->fx_where
5759 - fixP->fx_frag->fr_address - fixP->fx_where);
5761 value = (value - sign_extend_16 (value)) >> 16;
5763 #ifdef OBJ_ELF
5764 fixP->fx_r_type = BFD_RELOC_ALPHA_GPDISP;
5765 #endif
5766 goto do_reloc_gp;
5768 case BFD_RELOC_ALPHA_GPDISP_LO16:
5769 value = sign_extend_16 (value);
5770 fixP->fx_offset = 0;
5771 #ifdef OBJ_ELF
5772 fixP->fx_done = 1;
5773 #endif
5775 do_reloc_gp:
5776 fixP->fx_addsy = section_symbol (seg);
5777 md_number_to_chars (fixpos, value, 2);
5778 break;
5780 case BFD_RELOC_16:
5781 if (fixP->fx_pcrel)
5782 fixP->fx_r_type = BFD_RELOC_16_PCREL;
5783 size = 2;
5784 goto do_reloc_xx;
5786 case BFD_RELOC_32:
5787 if (fixP->fx_pcrel)
5788 fixP->fx_r_type = BFD_RELOC_32_PCREL;
5789 size = 4;
5790 goto do_reloc_xx;
5792 case BFD_RELOC_64:
5793 if (fixP->fx_pcrel)
5794 fixP->fx_r_type = BFD_RELOC_64_PCREL;
5795 size = 8;
5797 do_reloc_xx:
5798 if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0)
5800 md_number_to_chars (fixpos, value, size);
5801 goto done;
5803 return;
5805 #ifdef OBJ_ECOFF
5806 case BFD_RELOC_GPREL32:
5807 gas_assert (fixP->fx_subsy == alpha_gp_symbol);
5808 fixP->fx_subsy = 0;
5809 /* FIXME: inherited this obliviousness of `value' -- why? */
5810 md_number_to_chars (fixpos, -alpha_gp_value, 4);
5811 break;
5812 #else
5813 case BFD_RELOC_GPREL32:
5814 #endif
5815 case BFD_RELOC_GPREL16:
5816 case BFD_RELOC_ALPHA_GPREL_HI16:
5817 case BFD_RELOC_ALPHA_GPREL_LO16:
5818 return;
5820 case BFD_RELOC_23_PCREL_S2:
5821 if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0)
5823 image = bfd_getl32 (fixpos);
5824 image = (image & ~0x1FFFFF) | ((value >> 2) & 0x1FFFFF);
5825 goto write_done;
5827 return;
5829 case BFD_RELOC_ALPHA_HINT:
5830 if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0)
5832 image = bfd_getl32 (fixpos);
5833 image = (image & ~0x3FFF) | ((value >> 2) & 0x3FFF);
5834 goto write_done;
5836 return;
5838 #ifdef OBJ_ELF
5839 case BFD_RELOC_ALPHA_BRSGP:
5840 return;
5842 case BFD_RELOC_ALPHA_TLSGD:
5843 case BFD_RELOC_ALPHA_TLSLDM:
5844 case BFD_RELOC_ALPHA_GOTDTPREL16:
5845 case BFD_RELOC_ALPHA_DTPREL_HI16:
5846 case BFD_RELOC_ALPHA_DTPREL_LO16:
5847 case BFD_RELOC_ALPHA_DTPREL16:
5848 case BFD_RELOC_ALPHA_GOTTPREL16:
5849 case BFD_RELOC_ALPHA_TPREL_HI16:
5850 case BFD_RELOC_ALPHA_TPREL_LO16:
5851 case BFD_RELOC_ALPHA_TPREL16:
5852 if (fixP->fx_addsy)
5853 S_SET_THREAD_LOCAL (fixP->fx_addsy);
5854 return;
5855 #endif
5857 #ifdef OBJ_ECOFF
5858 case BFD_RELOC_ALPHA_LITERAL:
5859 md_number_to_chars (fixpos, value, 2);
5860 return;
5861 #endif
5862 case BFD_RELOC_ALPHA_ELF_LITERAL:
5863 case BFD_RELOC_ALPHA_LITUSE:
5864 case BFD_RELOC_ALPHA_LINKAGE:
5865 case BFD_RELOC_ALPHA_CODEADDR:
5866 return;
5868 #ifdef OBJ_EVAX
5869 case BFD_RELOC_ALPHA_NOP:
5870 value -= (8 + 4); /* PC-relative, base is jsr+4. */
5872 /* From B.4.5.2 of the OpenVMS Linker Utility Manual:
5873 "Finally, the ETIR$C_STC_BSR command passes the same address
5874 as ETIR$C_STC_NOP (so that they will fail or succeed together),
5875 and the same test is done again." */
5876 if (S_GET_SEGMENT (fixP->fx_addsy) == undefined_section)
5878 fixP->fx_addnumber = -value;
5879 return;
5882 if ((abs (value) >> 2) & ~0xfffff)
5883 goto done;
5884 else
5886 /* Change to a nop. */
5887 image = 0x47FF041F;
5888 goto write_done;
5891 case BFD_RELOC_ALPHA_LDA:
5892 /* fixup_segment sets fixP->fx_addsy to NULL when it can pre-compute
5893 the value for an O_subtract. */
5894 if (fixP->fx_addsy
5895 && S_GET_SEGMENT (fixP->fx_addsy) == undefined_section)
5897 fixP->fx_addnumber = symbol_get_bfdsym (fixP->fx_subsy)->value;
5898 return;
5901 if ((abs (value)) & ~0x7fff)
5902 goto done;
5903 else
5905 /* Change to an lda. */
5906 image = 0x237B0000 | (value & 0xFFFF);
5907 goto write_done;
5910 case BFD_RELOC_ALPHA_BSR:
5911 case BFD_RELOC_ALPHA_BOH:
5912 value -= 4; /* PC-relative, base is jsr+4. */
5914 /* See comment in the BFD_RELOC_ALPHA_NOP case above. */
5915 if (S_GET_SEGMENT (fixP->fx_addsy) == undefined_section)
5917 fixP->fx_addnumber = -value;
5918 return;
5921 if ((abs (value) >> 2) & ~0xfffff)
5923 /* Out of range. */
5924 if (fixP->fx_r_type == BFD_RELOC_ALPHA_BOH)
5926 /* Add a hint. */
5927 image = bfd_getl32(fixpos);
5928 image = (image & ~0x3FFF) | ((value >> 2) & 0x3FFF);
5929 goto write_done;
5931 goto done;
5933 else
5935 /* Change to a branch. */
5936 image = 0xD3400000 | ((value >> 2) & 0x1FFFFF);
5937 goto write_done;
5939 #endif
5941 case BFD_RELOC_VTABLE_INHERIT:
5942 case BFD_RELOC_VTABLE_ENTRY:
5943 return;
5945 default:
5947 const struct alpha_operand *operand;
5949 if ((int) fixP->fx_r_type >= 0)
5950 as_fatal (_("unhandled relocation type %s"),
5951 bfd_get_reloc_code_name (fixP->fx_r_type));
5953 gas_assert (-(int) fixP->fx_r_type < (int) alpha_num_operands);
5954 operand = &alpha_operands[-(int) fixP->fx_r_type];
5956 /* The rest of these fixups only exist internally during symbol
5957 resolution and have no representation in the object file.
5958 Therefore they must be completely resolved as constants. */
5960 if (fixP->fx_addsy != 0
5961 && S_GET_SEGMENT (fixP->fx_addsy) != absolute_section)
5962 as_bad_where (fixP->fx_file, fixP->fx_line,
5963 _("non-absolute expression in constant field"));
5965 image = bfd_getl32 (fixpos);
5966 image = insert_operand (image, operand, (offsetT) value,
5967 fixP->fx_file, fixP->fx_line);
5969 goto write_done;
5972 if (fixP->fx_addsy != 0 || fixP->fx_pcrel != 0)
5973 return;
5974 else
5976 as_warn_where (fixP->fx_file, fixP->fx_line,
5977 _("type %d reloc done?\n"), (int) fixP->fx_r_type);
5978 goto done;
5981 write_done:
5982 md_number_to_chars (fixpos, image, 4);
5984 done:
5985 fixP->fx_done = 1;
5988 /* Look for a register name in the given symbol. */
5990 symbolS *
5991 md_undefined_symbol (char *name)
5993 if (*name == '$')
5995 int is_float = 0, num;
5997 switch (*++name)
5999 case 'f':
6000 if (name[1] == 'p' && name[2] == '\0')
6001 return alpha_register_table[AXP_REG_FP];
6002 is_float = 32;
6003 /* Fall through. */
6005 case 'r':
6006 if (!ISDIGIT (*++name))
6007 break;
6008 /* Fall through. */
6010 case '0': case '1': case '2': case '3': case '4':
6011 case '5': case '6': case '7': case '8': case '9':
6012 if (name[1] == '\0')
6013 num = name[0] - '0';
6014 else if (name[0] != '0' && ISDIGIT (name[1]) && name[2] == '\0')
6016 num = (name[0] - '0') * 10 + name[1] - '0';
6017 if (num >= 32)
6018 break;
6020 else
6021 break;
6023 if (!alpha_noat_on && (num + is_float) == AXP_REG_AT)
6024 as_warn (_("Used $at without \".set noat\""));
6025 return alpha_register_table[num + is_float];
6027 case 'a':
6028 if (name[1] == 't' && name[2] == '\0')
6030 if (!alpha_noat_on)
6031 as_warn (_("Used $at without \".set noat\""));
6032 return alpha_register_table[AXP_REG_AT];
6034 break;
6036 case 'g':
6037 if (name[1] == 'p' && name[2] == '\0')
6038 return alpha_register_table[alpha_gp_register];
6039 break;
6041 case 's':
6042 if (name[1] == 'p' && name[2] == '\0')
6043 return alpha_register_table[AXP_REG_SP];
6044 break;
6047 return NULL;
6050 #ifdef OBJ_ECOFF
6051 /* @@@ Magic ECOFF bits. */
6053 void
6054 alpha_frob_ecoff_data (void)
6056 select_gp_value ();
6057 /* $zero and $f31 are read-only. */
6058 alpha_gprmask &= ~1;
6059 alpha_fprmask &= ~1;
6061 #endif
6063 /* Hook to remember a recently defined label so that the auto-align
6064 code can adjust the symbol after we know what alignment will be
6065 required. */
6067 void
6068 alpha_define_label (symbolS *sym)
6070 alpha_insn_label = sym;
6071 #ifdef OBJ_ELF
6072 dwarf2_emit_label (sym);
6073 #endif
6076 /* Return true if we must always emit a reloc for a type and false if
6077 there is some hope of resolving it at assembly time. */
6080 alpha_force_relocation (fixS *f)
6082 if (alpha_flag_relax)
6083 return 1;
6085 switch (f->fx_r_type)
6087 case BFD_RELOC_ALPHA_GPDISP_HI16:
6088 case BFD_RELOC_ALPHA_GPDISP_LO16:
6089 case BFD_RELOC_ALPHA_GPDISP:
6090 case BFD_RELOC_ALPHA_LITERAL:
6091 case BFD_RELOC_ALPHA_ELF_LITERAL:
6092 case BFD_RELOC_ALPHA_LITUSE:
6093 case BFD_RELOC_GPREL16:
6094 case BFD_RELOC_GPREL32:
6095 case BFD_RELOC_ALPHA_GPREL_HI16:
6096 case BFD_RELOC_ALPHA_GPREL_LO16:
6097 case BFD_RELOC_ALPHA_LINKAGE:
6098 case BFD_RELOC_ALPHA_CODEADDR:
6099 case BFD_RELOC_ALPHA_BRSGP:
6100 case BFD_RELOC_ALPHA_TLSGD:
6101 case BFD_RELOC_ALPHA_TLSLDM:
6102 case BFD_RELOC_ALPHA_GOTDTPREL16:
6103 case BFD_RELOC_ALPHA_DTPREL_HI16:
6104 case BFD_RELOC_ALPHA_DTPREL_LO16:
6105 case BFD_RELOC_ALPHA_DTPREL16:
6106 case BFD_RELOC_ALPHA_GOTTPREL16:
6107 case BFD_RELOC_ALPHA_TPREL_HI16:
6108 case BFD_RELOC_ALPHA_TPREL_LO16:
6109 case BFD_RELOC_ALPHA_TPREL16:
6110 #ifdef OBJ_EVAX
6111 case BFD_RELOC_ALPHA_NOP:
6112 case BFD_RELOC_ALPHA_BSR:
6113 case BFD_RELOC_ALPHA_LDA:
6114 case BFD_RELOC_ALPHA_BOH:
6115 #endif
6116 return 1;
6118 default:
6119 break;
6122 return generic_force_reloc (f);
6125 /* Return true if we can partially resolve a relocation now. */
6128 alpha_fix_adjustable (fixS *f)
6130 /* Are there any relocation types for which we must generate a
6131 reloc but we can adjust the values contained within it? */
6132 switch (f->fx_r_type)
6134 case BFD_RELOC_ALPHA_GPDISP_HI16:
6135 case BFD_RELOC_ALPHA_GPDISP_LO16:
6136 case BFD_RELOC_ALPHA_GPDISP:
6137 return 0;
6139 case BFD_RELOC_ALPHA_LITERAL:
6140 case BFD_RELOC_ALPHA_ELF_LITERAL:
6141 case BFD_RELOC_ALPHA_LITUSE:
6142 case BFD_RELOC_ALPHA_LINKAGE:
6143 case BFD_RELOC_ALPHA_CODEADDR:
6144 return 1;
6146 case BFD_RELOC_VTABLE_ENTRY:
6147 case BFD_RELOC_VTABLE_INHERIT:
6148 return 0;
6150 case BFD_RELOC_GPREL16:
6151 case BFD_RELOC_GPREL32:
6152 case BFD_RELOC_ALPHA_GPREL_HI16:
6153 case BFD_RELOC_ALPHA_GPREL_LO16:
6154 case BFD_RELOC_23_PCREL_S2:
6155 case BFD_RELOC_16:
6156 case BFD_RELOC_32:
6157 case BFD_RELOC_64:
6158 case BFD_RELOC_ALPHA_HINT:
6159 return 1;
6161 case BFD_RELOC_ALPHA_TLSGD:
6162 case BFD_RELOC_ALPHA_TLSLDM:
6163 case BFD_RELOC_ALPHA_GOTDTPREL16:
6164 case BFD_RELOC_ALPHA_DTPREL_HI16:
6165 case BFD_RELOC_ALPHA_DTPREL_LO16:
6166 case BFD_RELOC_ALPHA_DTPREL16:
6167 case BFD_RELOC_ALPHA_GOTTPREL16:
6168 case BFD_RELOC_ALPHA_TPREL_HI16:
6169 case BFD_RELOC_ALPHA_TPREL_LO16:
6170 case BFD_RELOC_ALPHA_TPREL16:
6171 /* ??? No idea why we can't return a reference to .tbss+10, but
6172 we're preventing this in the other assemblers. Follow for now. */
6173 return 0;
6175 #ifdef OBJ_ELF
6176 case BFD_RELOC_ALPHA_BRSGP:
6177 /* If we have a BRSGP reloc to a local symbol, adjust it to BRADDR and
6178 let it get resolved at assembly time. */
6180 symbolS *sym = f->fx_addsy;
6181 const char *name;
6182 int offset = 0;
6184 if (generic_force_reloc (f))
6185 return 0;
6187 switch (S_GET_OTHER (sym) & STO_ALPHA_STD_GPLOAD)
6189 case STO_ALPHA_NOPV:
6190 break;
6191 case STO_ALPHA_STD_GPLOAD:
6192 offset = 8;
6193 break;
6194 default:
6195 if (S_IS_LOCAL (sym))
6196 name = "<local>";
6197 else
6198 name = S_GET_NAME (sym);
6199 as_bad_where (f->fx_file, f->fx_line,
6200 _("!samegp reloc against symbol without .prologue: %s"),
6201 name);
6202 break;
6204 f->fx_r_type = BFD_RELOC_23_PCREL_S2;
6205 f->fx_offset += offset;
6206 return 1;
6208 #endif
6209 #ifdef OBJ_EVAX
6210 case BFD_RELOC_ALPHA_NOP:
6211 case BFD_RELOC_ALPHA_BSR:
6212 case BFD_RELOC_ALPHA_LDA:
6213 case BFD_RELOC_ALPHA_BOH:
6214 return 1;
6215 #endif
6217 default:
6218 return 1;
6222 /* Generate the BFD reloc to be stuck in the object file from the
6223 fixup used internally in the assembler. */
6225 arelent *
6226 tc_gen_reloc (asection *sec ATTRIBUTE_UNUSED,
6227 fixS *fixp)
6229 arelent *reloc;
6231 reloc = (arelent *) xmalloc (sizeof (* reloc));
6232 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
6233 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
6234 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
6236 /* Make sure none of our internal relocations make it this far.
6237 They'd better have been fully resolved by this point. */
6238 gas_assert ((int) fixp->fx_r_type > 0);
6240 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
6241 if (reloc->howto == NULL)
6243 as_bad_where (fixp->fx_file, fixp->fx_line,
6244 _("cannot represent `%s' relocation in object file"),
6245 bfd_get_reloc_code_name (fixp->fx_r_type));
6246 return NULL;
6249 if (!fixp->fx_pcrel != !reloc->howto->pc_relative)
6250 as_fatal (_("internal error? cannot generate `%s' relocation"),
6251 bfd_get_reloc_code_name (fixp->fx_r_type));
6253 gas_assert (!fixp->fx_pcrel == !reloc->howto->pc_relative);
6255 #ifdef OBJ_ECOFF
6256 if (fixp->fx_r_type == BFD_RELOC_ALPHA_LITERAL)
6257 /* Fake out bfd_perform_relocation. sigh. */
6258 reloc->addend = -alpha_gp_value;
6259 else
6260 #endif
6262 reloc->addend = fixp->fx_offset;
6263 #ifdef OBJ_ELF
6264 /* Ohhh, this is ugly. The problem is that if this is a local global
6265 symbol, the relocation will entirely be performed at link time, not
6266 at assembly time. bfd_perform_reloc doesn't know about this sort
6267 of thing, and as a result we need to fake it out here. */
6268 if ((S_IS_EXTERNAL (fixp->fx_addsy) || S_IS_WEAK (fixp->fx_addsy)
6269 || (S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_MERGE)
6270 || (S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_THREAD_LOCAL))
6271 && !S_IS_COMMON (fixp->fx_addsy))
6272 reloc->addend -= symbol_get_bfdsym (fixp->fx_addsy)->value;
6273 #endif
6276 #ifdef OBJ_EVAX
6277 switch (fixp->fx_r_type)
6279 struct evax_private_udata_struct *udata;
6280 const char *pname;
6281 int pname_len;
6283 case BFD_RELOC_ALPHA_LINKAGE:
6284 reloc->addend = fixp->fx_addnumber;
6285 break;
6287 case BFD_RELOC_ALPHA_NOP:
6288 case BFD_RELOC_ALPHA_BSR:
6289 case BFD_RELOC_ALPHA_LDA:
6290 case BFD_RELOC_ALPHA_BOH:
6291 pname = symbol_get_bfdsym (fixp->fx_addsy)->name;
6293 /* We need the non-suffixed name of the procedure. Beware that
6294 the main symbol might be equated so look it up and take its name. */
6295 pname_len = strlen (pname);
6296 if (pname_len > 4 && strcmp (pname + pname_len - 4, "..en") == 0)
6298 symbolS *sym;
6299 char *my_pname = xstrdup (pname);
6300 my_pname [pname_len - 4] = 0;
6301 sym = symbol_find (my_pname);
6302 if (sym == NULL)
6303 abort ();
6304 while (symbol_equated_reloc_p (sym))
6306 symbolS *n = symbol_get_value_expression (sym)->X_add_symbol;
6308 /* We must avoid looping, as that can occur with a badly
6309 written program. */
6310 if (n == sym)
6311 break;
6312 sym = n;
6314 pname = symbol_get_bfdsym (sym)->name;
6317 udata = (struct evax_private_udata_struct *)
6318 xmalloc (sizeof (struct evax_private_udata_struct));
6319 udata->enbsym = symbol_get_bfdsym (fixp->fx_addsy);
6320 udata->bsym = symbol_get_bfdsym (fixp->tc_fix_data.info->psym);
6321 udata->origname = (char *)pname;
6322 udata->lkindex = ((struct evax_private_udata_struct *)
6323 symbol_get_bfdsym (fixp->tc_fix_data.info->sym)->udata.p)->lkindex;
6324 reloc->sym_ptr_ptr = (void *)udata;
6325 reloc->addend = fixp->fx_addnumber;
6327 default:
6328 break;
6330 #endif
6332 return reloc;
6335 /* Parse a register name off of the input_line and return a register
6336 number. Gets md_undefined_symbol above to do the register name
6337 matching for us.
6339 Only called as a part of processing the ECOFF .frame directive. */
6342 tc_get_register (int frame ATTRIBUTE_UNUSED)
6344 int framereg = AXP_REG_SP;
6346 SKIP_WHITESPACE ();
6347 if (*input_line_pointer == '$')
6349 char *s = input_line_pointer;
6350 char c = get_symbol_end ();
6351 symbolS *sym = md_undefined_symbol (s);
6353 *strchr (s, '\0') = c;
6354 if (sym && (framereg = S_GET_VALUE (sym)) <= 31)
6355 goto found;
6357 as_warn (_("frame reg expected, using $%d."), framereg);
6359 found:
6360 note_gpreg (framereg);
6361 return framereg;
6364 /* This is called before the symbol table is processed. In order to
6365 work with gcc when using mips-tfile, we must keep all local labels.
6366 However, in other cases, we want to discard them. If we were
6367 called with -g, but we didn't see any debugging information, it may
6368 mean that gcc is smuggling debugging information through to
6369 mips-tfile, in which case we must generate all local labels. */
6371 #ifdef OBJ_ECOFF
6373 void
6374 alpha_frob_file_before_adjust (void)
6376 if (alpha_debug != 0
6377 && ! ecoff_debugging_seen)
6378 flag_keep_locals = 1;
6381 #endif /* OBJ_ECOFF */
6383 /* The Alpha has support for some VAX floating point types, as well as for
6384 IEEE floating point. We consider IEEE to be the primary floating point
6385 format, and sneak in the VAX floating point support here. */
6386 #include "config/atof-vax.c"