2010-06-01 Rafael Espindola <espindola@google.com>
[binutils.git] / gas / config / tc-alpha.c
blob2fbdf39e27b1737c216571255774b4ab4ed30e8b
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 /* The symbol of the item in the linkage section. */
90 symbolS *xtrasym;
92 /* The symbol of the procedure descriptor. */
93 symbolS *procsym;
94 #endif
97 struct alpha_insn
99 unsigned insn;
100 int nfixups;
101 struct alpha_fixup fixups[MAX_INSN_FIXUPS];
102 long sequence;
105 enum alpha_macro_arg
107 MACRO_EOA = 1,
108 MACRO_IR,
109 MACRO_PIR,
110 MACRO_OPIR,
111 MACRO_CPIR,
112 MACRO_FPR,
113 MACRO_EXP
116 struct alpha_macro
118 const char *name;
119 void (*emit) (const expressionS *, int, const void *);
120 const void * arg;
121 enum alpha_macro_arg argsets[16];
124 /* Extra expression types. */
126 #define O_pregister O_md1 /* O_register, in parentheses. */
127 #define O_cpregister O_md2 /* + a leading comma. */
129 /* The alpha_reloc_op table below depends on the ordering of these. */
130 #define O_literal O_md3 /* !literal relocation. */
131 #define O_lituse_addr O_md4 /* !lituse_addr relocation. */
132 #define O_lituse_base O_md5 /* !lituse_base relocation. */
133 #define O_lituse_bytoff O_md6 /* !lituse_bytoff relocation. */
134 #define O_lituse_jsr O_md7 /* !lituse_jsr relocation. */
135 #define O_lituse_tlsgd O_md8 /* !lituse_tlsgd relocation. */
136 #define O_lituse_tlsldm O_md9 /* !lituse_tlsldm relocation. */
137 #define O_lituse_jsrdirect O_md10 /* !lituse_jsrdirect relocation. */
138 #define O_gpdisp O_md11 /* !gpdisp relocation. */
139 #define O_gprelhigh O_md12 /* !gprelhigh relocation. */
140 #define O_gprellow O_md13 /* !gprellow relocation. */
141 #define O_gprel O_md14 /* !gprel relocation. */
142 #define O_samegp O_md15 /* !samegp relocation. */
143 #define O_tlsgd O_md16 /* !tlsgd relocation. */
144 #define O_tlsldm O_md17 /* !tlsldm relocation. */
145 #define O_gotdtprel O_md18 /* !gotdtprel relocation. */
146 #define O_dtprelhi O_md19 /* !dtprelhi relocation. */
147 #define O_dtprello O_md20 /* !dtprello relocation. */
148 #define O_dtprel O_md21 /* !dtprel relocation. */
149 #define O_gottprel O_md22 /* !gottprel relocation. */
150 #define O_tprelhi O_md23 /* !tprelhi relocation. */
151 #define O_tprello O_md24 /* !tprello relocation. */
152 #define O_tprel O_md25 /* !tprel relocation. */
154 #define DUMMY_RELOC_LITUSE_ADDR (BFD_RELOC_UNUSED + 1)
155 #define DUMMY_RELOC_LITUSE_BASE (BFD_RELOC_UNUSED + 2)
156 #define DUMMY_RELOC_LITUSE_BYTOFF (BFD_RELOC_UNUSED + 3)
157 #define DUMMY_RELOC_LITUSE_JSR (BFD_RELOC_UNUSED + 4)
158 #define DUMMY_RELOC_LITUSE_TLSGD (BFD_RELOC_UNUSED + 5)
159 #define DUMMY_RELOC_LITUSE_TLSLDM (BFD_RELOC_UNUSED + 6)
160 #define DUMMY_RELOC_LITUSE_JSRDIRECT (BFD_RELOC_UNUSED + 7)
162 #define USER_RELOC_P(R) ((R) >= O_literal && (R) <= O_tprel)
164 /* Macros for extracting the type and number of encoded register tokens. */
166 #define is_ir_num(x) (((x) & 32) == 0)
167 #define is_fpr_num(x) (((x) & 32) != 0)
168 #define regno(x) ((x) & 31)
170 /* Something odd inherited from the old assembler. */
172 #define note_gpreg(R) (alpha_gprmask |= (1 << (R)))
173 #define note_fpreg(R) (alpha_fprmask |= (1 << (R)))
175 /* Predicates for 16- and 32-bit ranges */
176 /* XXX: The non-shift version appears to trigger a compiler bug when
177 cross-assembling from x86 w/ gcc 2.7.2. */
179 #if 1
180 #define range_signed_16(x) \
181 (((offsetT) (x) >> 15) == 0 || ((offsetT) (x) >> 15) == -1)
182 #define range_signed_32(x) \
183 (((offsetT) (x) >> 31) == 0 || ((offsetT) (x) >> 31) == -1)
184 #else
185 #define range_signed_16(x) ((offsetT) (x) >= -(offsetT) 0x8000 && \
186 (offsetT) (x) <= (offsetT) 0x7FFF)
187 #define range_signed_32(x) ((offsetT) (x) >= -(offsetT) 0x80000000 && \
188 (offsetT) (x) <= (offsetT) 0x7FFFFFFF)
189 #endif
191 /* Macros for sign extending from 16- and 32-bits. */
192 /* XXX: The cast macros will work on all the systems that I care about,
193 but really a predicate should be found to use the non-cast forms. */
195 #if 1
196 #define sign_extend_16(x) ((short) (x))
197 #define sign_extend_32(x) ((int) (x))
198 #else
199 #define sign_extend_16(x) ((offsetT) (((x) & 0xFFFF) ^ 0x8000) - 0x8000)
200 #define sign_extend_32(x) ((offsetT) (((x) & 0xFFFFFFFF) \
201 ^ 0x80000000) - 0x80000000)
202 #endif
204 /* Macros to build tokens. */
206 #define set_tok_reg(t, r) (memset (&(t), 0, sizeof (t)), \
207 (t).X_op = O_register, \
208 (t).X_add_number = (r))
209 #define set_tok_preg(t, r) (memset (&(t), 0, sizeof (t)), \
210 (t).X_op = O_pregister, \
211 (t).X_add_number = (r))
212 #define set_tok_cpreg(t, r) (memset (&(t), 0, sizeof (t)), \
213 (t).X_op = O_cpregister, \
214 (t).X_add_number = (r))
215 #define set_tok_freg(t, r) (memset (&(t), 0, sizeof (t)), \
216 (t).X_op = O_register, \
217 (t).X_add_number = (r) + 32)
218 #define set_tok_sym(t, s, a) (memset (&(t), 0, sizeof (t)), \
219 (t).X_op = O_symbol, \
220 (t).X_add_symbol = (s), \
221 (t).X_add_number = (a))
222 #define set_tok_const(t, n) (memset (&(t), 0, sizeof (t)), \
223 (t).X_op = O_constant, \
224 (t).X_add_number = (n))
226 /* Generic assembler global variables which must be defined by all
227 targets. */
229 /* Characters which always start a comment. */
230 const char comment_chars[] = "#";
232 /* Characters which start a comment at the beginning of a line. */
233 const char line_comment_chars[] = "#";
235 /* Characters which may be used to separate multiple commands on a
236 single line. */
237 const char line_separator_chars[] = ";";
239 /* Characters which are used to indicate an exponent in a floating
240 point number. */
241 const char EXP_CHARS[] = "eE";
243 /* Characters which mean that a number is a floating point constant,
244 as in 0d1.0. */
245 /* XXX: Do all of these really get used on the alpha?? */
246 char FLT_CHARS[] = "rRsSfFdDxXpP";
248 #ifdef OBJ_EVAX
249 const char *md_shortopts = "Fm:g+1h:HG:";
250 #else
251 const char *md_shortopts = "Fm:gG:";
252 #endif
254 struct option md_longopts[] =
256 #define OPTION_32ADDR (OPTION_MD_BASE)
257 { "32addr", no_argument, NULL, OPTION_32ADDR },
258 #define OPTION_RELAX (OPTION_32ADDR + 1)
259 { "relax", no_argument, NULL, OPTION_RELAX },
260 #ifdef OBJ_ELF
261 #define OPTION_MDEBUG (OPTION_RELAX + 1)
262 #define OPTION_NO_MDEBUG (OPTION_MDEBUG + 1)
263 { "mdebug", no_argument, NULL, OPTION_MDEBUG },
264 { "no-mdebug", no_argument, NULL, OPTION_NO_MDEBUG },
265 #endif
266 #ifdef OBJ_EVAX
267 #define OPTION_REPLACE (OPTION_RELAX + 1)
268 #define OPTION_NOREPLACE (OPTION_REPLACE+1)
269 { "replace", no_argument, NULL, OPTION_REPLACE },
270 { "noreplace", no_argument, NULL, OPTION_NOREPLACE },
271 #endif
272 { NULL, no_argument, NULL, 0 }
275 size_t md_longopts_size = sizeof (md_longopts);
277 #ifdef OBJ_EVAX
278 #define AXP_REG_R0 0
279 #define AXP_REG_R16 16
280 #define AXP_REG_R17 17
281 #undef AXP_REG_T9
282 #define AXP_REG_T9 22
283 #undef AXP_REG_T10
284 #define AXP_REG_T10 23
285 #undef AXP_REG_T11
286 #define AXP_REG_T11 24
287 #undef AXP_REG_T12
288 #define AXP_REG_T12 25
289 #define AXP_REG_AI 25
290 #undef AXP_REG_FP
291 #define AXP_REG_FP 29
293 #undef AXP_REG_GP
294 #define AXP_REG_GP AXP_REG_PV
296 static struct hash_control *alpha_evax_proc_hash;
298 #endif /* OBJ_EVAX */
300 /* The cpu for which we are generating code. */
301 static unsigned alpha_target = AXP_OPCODE_BASE;
302 static const char *alpha_target_name = "<all>";
304 /* The hash table of instruction opcodes. */
305 static struct hash_control *alpha_opcode_hash;
307 /* The hash table of macro opcodes. */
308 static struct hash_control *alpha_macro_hash;
310 #ifdef OBJ_ECOFF
311 /* The $gp relocation symbol. */
312 static symbolS *alpha_gp_symbol;
314 /* XXX: what is this, and why is it exported? */
315 valueT alpha_gp_value;
316 #endif
318 /* The current $gp register. */
319 static int alpha_gp_register = AXP_REG_GP;
321 /* A table of the register symbols. */
322 static symbolS *alpha_register_table[64];
324 /* Constant sections, or sections of constants. */
325 #ifdef OBJ_ECOFF
326 static segT alpha_lita_section;
327 #endif
328 #ifdef OBJ_EVAX
329 segT alpha_link_section;
330 #endif
331 #ifndef OBJ_EVAX
332 static segT alpha_lit8_section;
333 #endif
335 /* Symbols referring to said sections. */
336 #ifdef OBJ_ECOFF
337 static symbolS *alpha_lita_symbol;
338 #endif
339 #ifdef OBJ_EVAX
340 static symbolS *alpha_link_symbol;
341 #endif
342 #ifndef OBJ_EVAX
343 static symbolS *alpha_lit8_symbol;
344 #endif
346 /* Literal for .litX+0x8000 within .lita. */
347 #ifdef OBJ_ECOFF
348 static offsetT alpha_lit8_literal;
349 #endif
351 /* Is the assembler not allowed to use $at? */
352 static int alpha_noat_on = 0;
354 /* Are macros enabled? */
355 static int alpha_macros_on = 1;
357 /* Are floats disabled? */
358 static int alpha_nofloats_on = 0;
360 /* Are addresses 32 bit? */
361 static int alpha_addr32_on = 0;
363 /* Symbol labelling the current insn. When the Alpha gas sees
364 foo:
365 .quad 0
366 and the section happens to not be on an eight byte boundary, it
367 will align both the symbol and the .quad to an eight byte boundary. */
368 static symbolS *alpha_insn_label;
369 #if defined(OBJ_ELF) || defined (OBJ_EVAX)
370 static symbolS *alpha_prologue_label;
371 #endif
373 #ifdef OBJ_EVAX
374 /* Symbol associate with the current jsr instruction. */
375 static symbolS *alpha_linkage_symbol;
376 #endif
378 /* Whether we should automatically align data generation pseudo-ops.
379 .align 0 will turn this off. */
380 static int alpha_auto_align_on = 1;
382 /* The known current alignment of the current section. */
383 static int alpha_current_align;
385 /* These are exported to ECOFF code. */
386 unsigned long alpha_gprmask, alpha_fprmask;
388 /* Whether the debugging option was seen. */
389 static int alpha_debug;
391 #ifdef OBJ_ELF
392 /* Whether we are emitting an mdebug section. */
393 int alpha_flag_mdebug = -1;
394 #endif
396 #ifdef OBJ_EVAX
397 /* Whether to perform the VMS procedure call optimization. */
398 int alpha_flag_replace = 1;
399 #endif
401 /* Don't fully resolve relocations, allowing code movement in the linker. */
402 static int alpha_flag_relax;
404 /* What value to give to bfd_set_gp_size. */
405 static int g_switch_value = 8;
407 #ifdef OBJ_EVAX
408 /* Collect information about current procedure here. */
409 struct alpha_evax_procs
411 symbolS *symbol; /* Proc pdesc symbol. */
412 int pdsckind;
413 int framereg; /* Register for frame pointer. */
414 int framesize; /* Size of frame. */
415 int rsa_offset;
416 int ra_save;
417 int fp_save;
418 long imask;
419 long fmask;
420 int type;
421 int prologue;
422 symbolS *handler;
423 int handler_data;
426 /* Linked list of .linkage fixups. */
427 struct alpha_linkage_fixups *alpha_linkage_fixup_root;
428 static struct alpha_linkage_fixups *alpha_linkage_fixup_tail;
430 /* Current procedure descriptor. */
431 static struct alpha_evax_procs *alpha_evax_proc;
433 static int alpha_flag_hash_long_names = 0; /* -+ */
434 static int alpha_flag_show_after_trunc = 0; /* -H */
436 /* If the -+ switch is given, then a hash is appended to any name that is
437 longer than 64 characters, else longer symbol names are truncated. */
439 #endif
441 #ifdef RELOC_OP_P
442 /* A table to map the spelling of a relocation operand into an appropriate
443 bfd_reloc_code_real_type type. The table is assumed to be ordered such
444 that op-O_literal indexes into it. */
446 #define ALPHA_RELOC_TABLE(op) \
447 (&alpha_reloc_op[ ((!USER_RELOC_P (op)) \
448 ? (abort (), 0) \
449 : (int) (op) - (int) O_literal) ])
451 #define DEF(NAME, RELOC, REQ, ALLOW) \
452 { #NAME, sizeof(#NAME)-1, O_##NAME, RELOC, REQ, ALLOW}
454 static const struct alpha_reloc_op_tag
456 const char *name; /* String to lookup. */
457 size_t length; /* Size of the string. */
458 operatorT op; /* Which operator to use. */
459 extended_bfd_reloc_code_real_type reloc;
460 unsigned int require_seq : 1; /* Require a sequence number. */
461 unsigned int allow_seq : 1; /* Allow a sequence number. */
463 alpha_reloc_op[] =
465 DEF (literal, BFD_RELOC_ALPHA_ELF_LITERAL, 0, 1),
466 DEF (lituse_addr, DUMMY_RELOC_LITUSE_ADDR, 1, 1),
467 DEF (lituse_base, DUMMY_RELOC_LITUSE_BASE, 1, 1),
468 DEF (lituse_bytoff, DUMMY_RELOC_LITUSE_BYTOFF, 1, 1),
469 DEF (lituse_jsr, DUMMY_RELOC_LITUSE_JSR, 1, 1),
470 DEF (lituse_tlsgd, DUMMY_RELOC_LITUSE_TLSGD, 1, 1),
471 DEF (lituse_tlsldm, DUMMY_RELOC_LITUSE_TLSLDM, 1, 1),
472 DEF (lituse_jsrdirect, DUMMY_RELOC_LITUSE_JSRDIRECT, 1, 1),
473 DEF (gpdisp, BFD_RELOC_ALPHA_GPDISP, 1, 1),
474 DEF (gprelhigh, BFD_RELOC_ALPHA_GPREL_HI16, 0, 0),
475 DEF (gprellow, BFD_RELOC_ALPHA_GPREL_LO16, 0, 0),
476 DEF (gprel, BFD_RELOC_GPREL16, 0, 0),
477 DEF (samegp, BFD_RELOC_ALPHA_BRSGP, 0, 0),
478 DEF (tlsgd, BFD_RELOC_ALPHA_TLSGD, 0, 1),
479 DEF (tlsldm, BFD_RELOC_ALPHA_TLSLDM, 0, 1),
480 DEF (gotdtprel, BFD_RELOC_ALPHA_GOTDTPREL16, 0, 0),
481 DEF (dtprelhi, BFD_RELOC_ALPHA_DTPREL_HI16, 0, 0),
482 DEF (dtprello, BFD_RELOC_ALPHA_DTPREL_LO16, 0, 0),
483 DEF (dtprel, BFD_RELOC_ALPHA_DTPREL16, 0, 0),
484 DEF (gottprel, BFD_RELOC_ALPHA_GOTTPREL16, 0, 0),
485 DEF (tprelhi, BFD_RELOC_ALPHA_TPREL_HI16, 0, 0),
486 DEF (tprello, BFD_RELOC_ALPHA_TPREL_LO16, 0, 0),
487 DEF (tprel, BFD_RELOC_ALPHA_TPREL16, 0, 0),
490 #undef DEF
492 static const int alpha_num_reloc_op
493 = sizeof (alpha_reloc_op) / sizeof (*alpha_reloc_op);
494 #endif /* RELOC_OP_P */
496 /* Maximum # digits needed to hold the largest sequence #. */
497 #define ALPHA_RELOC_DIGITS 25
499 /* Structure to hold explicit sequence information. */
500 struct alpha_reloc_tag
502 fixS *master; /* The literal reloc. */
503 #ifdef OBJ_EVAX
504 struct symbol *sym; /* Linkage section item symbol. */
505 struct symbol *psym; /* Pdesc symbol. */
506 #endif
507 fixS *slaves; /* Head of linked list of lituses. */
508 segT segment; /* Segment relocs are in or undefined_section. */
509 long sequence; /* Sequence #. */
510 unsigned n_master; /* # of literals. */
511 unsigned n_slaves; /* # of lituses. */
512 unsigned saw_tlsgd : 1; /* True if ... */
513 unsigned saw_tlsldm : 1;
514 unsigned saw_lu_tlsgd : 1;
515 unsigned saw_lu_tlsldm : 1;
516 unsigned multi_section_p : 1; /* True if more than one section was used. */
517 char string[1]; /* Printable form of sequence to hash with. */
520 /* Hash table to link up literals with the appropriate lituse. */
521 static struct hash_control *alpha_literal_hash;
523 /* Sequence numbers for internal use by macros. */
524 static long next_sequence_num = -1;
526 /* A table of CPU names and opcode sets. */
528 static const struct cpu_type
530 const char *name;
531 unsigned flags;
533 cpu_types[] =
535 /* Ad hoc convention: cpu number gets palcode, process code doesn't.
536 This supports usage under DU 4.0b that does ".arch ev4", and
537 usage in MILO that does -m21064. Probably something more
538 specific like -m21064-pal should be used, but oh well. */
540 { "21064", AXP_OPCODE_BASE|AXP_OPCODE_EV4 },
541 { "21064a", AXP_OPCODE_BASE|AXP_OPCODE_EV4 },
542 { "21066", AXP_OPCODE_BASE|AXP_OPCODE_EV4 },
543 { "21068", AXP_OPCODE_BASE|AXP_OPCODE_EV4 },
544 { "21164", AXP_OPCODE_BASE|AXP_OPCODE_EV5 },
545 { "21164a", AXP_OPCODE_BASE|AXP_OPCODE_EV5|AXP_OPCODE_BWX },
546 { "21164pc", (AXP_OPCODE_BASE|AXP_OPCODE_EV5|AXP_OPCODE_BWX
547 |AXP_OPCODE_MAX) },
548 { "21264", (AXP_OPCODE_BASE|AXP_OPCODE_EV6|AXP_OPCODE_BWX
549 |AXP_OPCODE_MAX|AXP_OPCODE_CIX) },
550 { "21264a", (AXP_OPCODE_BASE|AXP_OPCODE_EV6|AXP_OPCODE_BWX
551 |AXP_OPCODE_MAX|AXP_OPCODE_CIX) },
552 { "21264b", (AXP_OPCODE_BASE|AXP_OPCODE_EV6|AXP_OPCODE_BWX
553 |AXP_OPCODE_MAX|AXP_OPCODE_CIX) },
555 { "ev4", AXP_OPCODE_BASE },
556 { "ev45", AXP_OPCODE_BASE },
557 { "lca45", AXP_OPCODE_BASE },
558 { "ev5", AXP_OPCODE_BASE },
559 { "ev56", AXP_OPCODE_BASE|AXP_OPCODE_BWX },
560 { "pca56", AXP_OPCODE_BASE|AXP_OPCODE_BWX|AXP_OPCODE_MAX },
561 { "ev6", AXP_OPCODE_BASE|AXP_OPCODE_BWX|AXP_OPCODE_MAX|AXP_OPCODE_CIX },
562 { "ev67", AXP_OPCODE_BASE|AXP_OPCODE_BWX|AXP_OPCODE_MAX|AXP_OPCODE_CIX },
563 { "ev68", AXP_OPCODE_BASE|AXP_OPCODE_BWX|AXP_OPCODE_MAX|AXP_OPCODE_CIX },
565 { "all", AXP_OPCODE_BASE },
566 { 0, 0 }
569 /* Some instruction sets indexed by lg(size). */
570 static const char * const sextX_op[] = { "sextb", "sextw", "sextl", NULL };
571 static const char * const insXl_op[] = { "insbl", "inswl", "insll", "insql" };
572 static const char * const insXh_op[] = { NULL, "inswh", "inslh", "insqh" };
573 static const char * const extXl_op[] = { "extbl", "extwl", "extll", "extql" };
574 static const char * const extXh_op[] = { NULL, "extwh", "extlh", "extqh" };
575 static const char * const mskXl_op[] = { "mskbl", "mskwl", "mskll", "mskql" };
576 static const char * const mskXh_op[] = { NULL, "mskwh", "msklh", "mskqh" };
577 static const char * const stX_op[] = { "stb", "stw", "stl", "stq" };
578 static const char * const ldXu_op[] = { "ldbu", "ldwu", NULL, NULL };
580 static void assemble_insn (const struct alpha_opcode *, const expressionS *, int, struct alpha_insn *, extended_bfd_reloc_code_real_type);
581 static void emit_insn (struct alpha_insn *);
582 static void assemble_tokens (const char *, const expressionS *, int, int);
583 #ifdef OBJ_EVAX
584 static char *s_alpha_section_name (void);
585 static symbolS *add_to_link_pool (symbolS *, symbolS *, offsetT);
586 #endif
588 static struct alpha_reloc_tag *
589 get_alpha_reloc_tag (long sequence)
591 char buffer[ALPHA_RELOC_DIGITS];
592 struct alpha_reloc_tag *info;
594 sprintf (buffer, "!%ld", sequence);
596 info = (struct alpha_reloc_tag *) hash_find (alpha_literal_hash, buffer);
597 if (! info)
599 size_t len = strlen (buffer);
600 const char *errmsg;
602 info = (struct alpha_reloc_tag *)
603 xcalloc (sizeof (struct alpha_reloc_tag) + len, 1);
605 info->segment = now_seg;
606 info->sequence = sequence;
607 strcpy (info->string, buffer);
608 errmsg = hash_insert (alpha_literal_hash, info->string, (void *) info);
609 if (errmsg)
610 as_fatal ("%s", errmsg);
611 #ifdef OBJ_EVAX
612 info->sym = 0;
613 info->psym = 0;
614 #endif
617 return info;
620 #ifndef OBJ_EVAX
622 static void
623 alpha_adjust_relocs (bfd *abfd ATTRIBUTE_UNUSED,
624 asection *sec,
625 void * ptr ATTRIBUTE_UNUSED)
627 segment_info_type *seginfo = seg_info (sec);
628 fixS **prevP;
629 fixS *fixp;
630 fixS *next;
631 fixS *slave;
633 /* If seginfo is NULL, we did not create this section; don't do
634 anything with it. By using a pointer to a pointer, we can update
635 the links in place. */
636 if (seginfo == NULL)
637 return;
639 /* If there are no relocations, skip the section. */
640 if (! seginfo->fix_root)
641 return;
643 /* First rebuild the fixup chain without the explicit lituse and
644 gpdisp_lo16 relocs. */
645 prevP = &seginfo->fix_root;
646 for (fixp = seginfo->fix_root; fixp; fixp = next)
648 next = fixp->fx_next;
649 fixp->fx_next = (fixS *) 0;
651 switch (fixp->fx_r_type)
653 case BFD_RELOC_ALPHA_LITUSE:
654 if (fixp->tc_fix_data.info->n_master == 0)
655 as_bad_where (fixp->fx_file, fixp->fx_line,
656 _("No !literal!%ld was found"),
657 fixp->tc_fix_data.info->sequence);
658 #ifdef RELOC_OP_P
659 if (fixp->fx_offset == LITUSE_ALPHA_TLSGD)
661 if (! fixp->tc_fix_data.info->saw_tlsgd)
662 as_bad_where (fixp->fx_file, fixp->fx_line,
663 _("No !tlsgd!%ld was found"),
664 fixp->tc_fix_data.info->sequence);
666 else if (fixp->fx_offset == LITUSE_ALPHA_TLSLDM)
668 if (! fixp->tc_fix_data.info->saw_tlsldm)
669 as_bad_where (fixp->fx_file, fixp->fx_line,
670 _("No !tlsldm!%ld was found"),
671 fixp->tc_fix_data.info->sequence);
673 #endif
674 break;
676 case BFD_RELOC_ALPHA_GPDISP_LO16:
677 if (fixp->tc_fix_data.info->n_master == 0)
678 as_bad_where (fixp->fx_file, fixp->fx_line,
679 _("No ldah !gpdisp!%ld was found"),
680 fixp->tc_fix_data.info->sequence);
681 break;
683 case BFD_RELOC_ALPHA_ELF_LITERAL:
684 if (fixp->tc_fix_data.info
685 && (fixp->tc_fix_data.info->saw_tlsgd
686 || fixp->tc_fix_data.info->saw_tlsldm))
687 break;
688 /* FALLTHRU */
690 default:
691 *prevP = fixp;
692 prevP = &fixp->fx_next;
693 break;
697 /* Go back and re-chain dependent relocations. They are currently
698 linked through the next_reloc field in reverse order, so as we
699 go through the next_reloc chain, we effectively reverse the chain
700 once again.
702 Except if there is more than one !literal for a given sequence
703 number. In that case, the programmer and/or compiler is not sure
704 how control flows from literal to lituse, and we can't be sure to
705 get the relaxation correct.
707 ??? Well, actually we could, if there are enough lituses such that
708 we can make each literal have at least one of each lituse type
709 present. Not implemented.
711 Also suppress the optimization if the !literals/!lituses are spread
712 in different segments. This can happen with "intersting" uses of
713 inline assembly; examples are present in the Linux kernel semaphores. */
715 for (fixp = seginfo->fix_root; fixp; fixp = next)
717 next = fixp->fx_next;
718 switch (fixp->fx_r_type)
720 case BFD_RELOC_ALPHA_TLSGD:
721 case BFD_RELOC_ALPHA_TLSLDM:
722 if (!fixp->tc_fix_data.info)
723 break;
724 if (fixp->tc_fix_data.info->n_master == 0)
725 break;
726 else if (fixp->tc_fix_data.info->n_master > 1)
728 as_bad_where (fixp->fx_file, fixp->fx_line,
729 _("too many !literal!%ld for %s"),
730 fixp->tc_fix_data.info->sequence,
731 (fixp->fx_r_type == BFD_RELOC_ALPHA_TLSGD
732 ? "!tlsgd" : "!tlsldm"));
733 break;
736 fixp->tc_fix_data.info->master->fx_next = fixp->fx_next;
737 fixp->fx_next = fixp->tc_fix_data.info->master;
738 fixp = fixp->fx_next;
739 /* Fall through. */
741 case BFD_RELOC_ALPHA_ELF_LITERAL:
742 if (fixp->tc_fix_data.info
743 && fixp->tc_fix_data.info->n_master == 1
744 && ! fixp->tc_fix_data.info->multi_section_p)
746 for (slave = fixp->tc_fix_data.info->slaves;
747 slave != (fixS *) 0;
748 slave = slave->tc_fix_data.next_reloc)
750 slave->fx_next = fixp->fx_next;
751 fixp->fx_next = slave;
754 break;
756 case BFD_RELOC_ALPHA_GPDISP_HI16:
757 if (fixp->tc_fix_data.info->n_slaves == 0)
758 as_bad_where (fixp->fx_file, fixp->fx_line,
759 _("No lda !gpdisp!%ld was found"),
760 fixp->tc_fix_data.info->sequence);
761 else
763 slave = fixp->tc_fix_data.info->slaves;
764 slave->fx_next = next;
765 fixp->fx_next = slave;
767 break;
769 default:
770 break;
775 /* Before the relocations are written, reorder them, so that user
776 supplied !lituse relocations follow the appropriate !literal
777 relocations, and similarly for !gpdisp relocations. */
779 void
780 alpha_before_fix (void)
782 if (alpha_literal_hash)
783 bfd_map_over_sections (stdoutput, alpha_adjust_relocs, NULL);
786 #endif
788 #ifdef DEBUG_ALPHA
789 static void
790 debug_exp (expressionS tok[], int ntok)
792 int i;
794 fprintf (stderr, "debug_exp: %d tokens", ntok);
795 for (i = 0; i < ntok; i++)
797 expressionS *t = &tok[i];
798 const char *name;
800 switch (t->X_op)
802 default: name = "unknown"; break;
803 case O_illegal: name = "O_illegal"; break;
804 case O_absent: name = "O_absent"; break;
805 case O_constant: name = "O_constant"; break;
806 case O_symbol: name = "O_symbol"; break;
807 case O_symbol_rva: name = "O_symbol_rva"; break;
808 case O_register: name = "O_register"; break;
809 case O_big: name = "O_big"; break;
810 case O_uminus: name = "O_uminus"; break;
811 case O_bit_not: name = "O_bit_not"; break;
812 case O_logical_not: name = "O_logical_not"; break;
813 case O_multiply: name = "O_multiply"; break;
814 case O_divide: name = "O_divide"; break;
815 case O_modulus: name = "O_modulus"; break;
816 case O_left_shift: name = "O_left_shift"; break;
817 case O_right_shift: name = "O_right_shift"; break;
818 case O_bit_inclusive_or: name = "O_bit_inclusive_or"; break;
819 case O_bit_or_not: name = "O_bit_or_not"; break;
820 case O_bit_exclusive_or: name = "O_bit_exclusive_or"; break;
821 case O_bit_and: name = "O_bit_and"; break;
822 case O_add: name = "O_add"; break;
823 case O_subtract: name = "O_subtract"; break;
824 case O_eq: name = "O_eq"; break;
825 case O_ne: name = "O_ne"; break;
826 case O_lt: name = "O_lt"; break;
827 case O_le: name = "O_le"; break;
828 case O_ge: name = "O_ge"; break;
829 case O_gt: name = "O_gt"; break;
830 case O_logical_and: name = "O_logical_and"; break;
831 case O_logical_or: name = "O_logical_or"; break;
832 case O_index: name = "O_index"; break;
833 case O_pregister: name = "O_pregister"; break;
834 case O_cpregister: name = "O_cpregister"; break;
835 case O_literal: name = "O_literal"; break;
836 case O_lituse_addr: name = "O_lituse_addr"; break;
837 case O_lituse_base: name = "O_lituse_base"; break;
838 case O_lituse_bytoff: name = "O_lituse_bytoff"; break;
839 case O_lituse_jsr: name = "O_lituse_jsr"; break;
840 case O_lituse_tlsgd: name = "O_lituse_tlsgd"; break;
841 case O_lituse_tlsldm: name = "O_lituse_tlsldm"; break;
842 case O_lituse_jsrdirect: name = "O_lituse_jsrdirect"; break;
843 case O_gpdisp: name = "O_gpdisp"; break;
844 case O_gprelhigh: name = "O_gprelhigh"; break;
845 case O_gprellow: name = "O_gprellow"; break;
846 case O_gprel: name = "O_gprel"; break;
847 case O_samegp: name = "O_samegp"; break;
848 case O_tlsgd: name = "O_tlsgd"; break;
849 case O_tlsldm: name = "O_tlsldm"; break;
850 case O_gotdtprel: name = "O_gotdtprel"; break;
851 case O_dtprelhi: name = "O_dtprelhi"; break;
852 case O_dtprello: name = "O_dtprello"; break;
853 case O_dtprel: name = "O_dtprel"; break;
854 case O_gottprel: name = "O_gottprel"; break;
855 case O_tprelhi: name = "O_tprelhi"; break;
856 case O_tprello: name = "O_tprello"; break;
857 case O_tprel: name = "O_tprel"; break;
860 fprintf (stderr, ", %s(%s, %s, %d)", name,
861 (t->X_add_symbol) ? S_GET_NAME (t->X_add_symbol) : "--",
862 (t->X_op_symbol) ? S_GET_NAME (t->X_op_symbol) : "--",
863 (int) t->X_add_number);
865 fprintf (stderr, "\n");
866 fflush (stderr);
868 #endif
870 /* Parse the arguments to an opcode. */
872 static int
873 tokenize_arguments (char *str,
874 expressionS tok[],
875 int ntok)
877 expressionS *end_tok = tok + ntok;
878 char *old_input_line_pointer;
879 int saw_comma = 0, saw_arg = 0;
880 #ifdef DEBUG_ALPHA
881 expressionS *orig_tok = tok;
882 #endif
883 #ifdef RELOC_OP_P
884 char *p;
885 const struct alpha_reloc_op_tag *r;
886 int c, i;
887 size_t len;
888 int reloc_found_p = 0;
889 #endif
891 memset (tok, 0, sizeof (*tok) * ntok);
893 /* Save and restore input_line_pointer around this function. */
894 old_input_line_pointer = input_line_pointer;
895 input_line_pointer = str;
897 #ifdef RELOC_OP_P
898 /* ??? Wrest control of ! away from the regular expression parser. */
899 is_end_of_line[(unsigned char) '!'] = 1;
900 #endif
902 while (tok < end_tok && *input_line_pointer)
904 SKIP_WHITESPACE ();
905 switch (*input_line_pointer)
907 case '\0':
908 goto fini;
910 #ifdef RELOC_OP_P
911 case '!':
912 /* A relocation operand can be placed after the normal operand on an
913 assembly language statement, and has the following form:
914 !relocation_type!sequence_number. */
915 if (reloc_found_p)
917 /* Only support one relocation op per insn. */
918 as_bad (_("More than one relocation op per insn"));
919 goto err_report;
922 if (!saw_arg)
923 goto err;
925 ++input_line_pointer;
926 SKIP_WHITESPACE ();
927 p = input_line_pointer;
928 c = get_symbol_end ();
930 /* Parse !relocation_type. */
931 len = input_line_pointer - p;
932 if (len == 0)
934 as_bad (_("No relocation operand"));
935 goto err_report;
938 r = &alpha_reloc_op[0];
939 for (i = alpha_num_reloc_op - 1; i >= 0; i--, r++)
940 if (len == r->length && memcmp (p, r->name, len) == 0)
941 break;
942 if (i < 0)
944 as_bad (_("Unknown relocation operand: !%s"), p);
945 goto err_report;
948 *input_line_pointer = c;
949 SKIP_WHITESPACE ();
950 if (*input_line_pointer != '!')
952 if (r->require_seq)
954 as_bad (_("no sequence number after !%s"), p);
955 goto err_report;
958 tok->X_add_number = 0;
960 else
962 if (! r->allow_seq)
964 as_bad (_("!%s does not use a sequence number"), p);
965 goto err_report;
968 input_line_pointer++;
970 /* Parse !sequence_number. */
971 expression (tok);
972 if (tok->X_op != O_constant || tok->X_add_number <= 0)
974 as_bad (_("Bad sequence number: !%s!%s"),
975 r->name, input_line_pointer);
976 goto err_report;
980 tok->X_op = r->op;
981 reloc_found_p = 1;
982 ++tok;
983 break;
984 #endif /* RELOC_OP_P */
986 case ',':
987 ++input_line_pointer;
988 if (saw_comma || !saw_arg)
989 goto err;
990 saw_comma = 1;
991 break;
993 case '(':
995 char *hold = input_line_pointer++;
997 /* First try for parenthesized register ... */
998 expression (tok);
999 if (*input_line_pointer == ')' && tok->X_op == O_register)
1001 tok->X_op = (saw_comma ? O_cpregister : O_pregister);
1002 saw_comma = 0;
1003 saw_arg = 1;
1004 ++input_line_pointer;
1005 ++tok;
1006 break;
1009 /* ... then fall through to plain expression. */
1010 input_line_pointer = hold;
1013 default:
1014 if (saw_arg && !saw_comma)
1015 goto err;
1017 expression (tok);
1018 if (tok->X_op == O_illegal || tok->X_op == O_absent)
1019 goto err;
1021 saw_comma = 0;
1022 saw_arg = 1;
1023 ++tok;
1024 break;
1028 fini:
1029 if (saw_comma)
1030 goto err;
1031 input_line_pointer = old_input_line_pointer;
1033 #ifdef DEBUG_ALPHA
1034 debug_exp (orig_tok, ntok - (end_tok - tok));
1035 #endif
1036 #ifdef RELOC_OP_P
1037 is_end_of_line[(unsigned char) '!'] = 0;
1038 #endif
1040 return ntok - (end_tok - tok);
1042 err:
1043 #ifdef RELOC_OP_P
1044 is_end_of_line[(unsigned char) '!'] = 0;
1045 #endif
1046 input_line_pointer = old_input_line_pointer;
1047 return TOKENIZE_ERROR;
1049 #ifdef RELOC_OP_P
1050 err_report:
1051 is_end_of_line[(unsigned char) '!'] = 0;
1052 #endif
1053 input_line_pointer = old_input_line_pointer;
1054 return TOKENIZE_ERROR_REPORT;
1057 /* Search forward through all variants of an opcode looking for a
1058 syntax match. */
1060 static const struct alpha_opcode *
1061 find_opcode_match (const struct alpha_opcode *first_opcode,
1062 const expressionS *tok,
1063 int *pntok,
1064 int *pcpumatch)
1066 const struct alpha_opcode *opcode = first_opcode;
1067 int ntok = *pntok;
1068 int got_cpu_match = 0;
1072 const unsigned char *opidx;
1073 int tokidx = 0;
1075 /* Don't match opcodes that don't exist on this architecture. */
1076 if (!(opcode->flags & alpha_target))
1077 goto match_failed;
1079 got_cpu_match = 1;
1081 for (opidx = opcode->operands; *opidx; ++opidx)
1083 const struct alpha_operand *operand = &alpha_operands[*opidx];
1085 /* Only take input from real operands. */
1086 if (operand->flags & AXP_OPERAND_FAKE)
1087 continue;
1089 /* When we expect input, make sure we have it. */
1090 if (tokidx >= ntok)
1092 if ((operand->flags & AXP_OPERAND_OPTIONAL_MASK) == 0)
1093 goto match_failed;
1094 continue;
1097 /* Match operand type with expression type. */
1098 switch (operand->flags & AXP_OPERAND_TYPECHECK_MASK)
1100 case AXP_OPERAND_IR:
1101 if (tok[tokidx].X_op != O_register
1102 || !is_ir_num (tok[tokidx].X_add_number))
1103 goto match_failed;
1104 break;
1105 case AXP_OPERAND_FPR:
1106 if (tok[tokidx].X_op != O_register
1107 || !is_fpr_num (tok[tokidx].X_add_number))
1108 goto match_failed;
1109 break;
1110 case AXP_OPERAND_IR | AXP_OPERAND_PARENS:
1111 if (tok[tokidx].X_op != O_pregister
1112 || !is_ir_num (tok[tokidx].X_add_number))
1113 goto match_failed;
1114 break;
1115 case AXP_OPERAND_IR | AXP_OPERAND_PARENS | AXP_OPERAND_COMMA:
1116 if (tok[tokidx].X_op != O_cpregister
1117 || !is_ir_num (tok[tokidx].X_add_number))
1118 goto match_failed;
1119 break;
1121 case AXP_OPERAND_RELATIVE:
1122 case AXP_OPERAND_SIGNED:
1123 case AXP_OPERAND_UNSIGNED:
1124 switch (tok[tokidx].X_op)
1126 case O_illegal:
1127 case O_absent:
1128 case O_register:
1129 case O_pregister:
1130 case O_cpregister:
1131 goto match_failed;
1133 default:
1134 break;
1136 break;
1138 default:
1139 /* Everything else should have been fake. */
1140 abort ();
1142 ++tokidx;
1145 /* Possible match -- did we use all of our input? */
1146 if (tokidx == ntok)
1148 *pntok = ntok;
1149 return opcode;
1152 match_failed:;
1154 while (++opcode - alpha_opcodes < (int) alpha_num_opcodes
1155 && !strcmp (opcode->name, first_opcode->name));
1157 if (*pcpumatch)
1158 *pcpumatch = got_cpu_match;
1160 return NULL;
1163 /* Given an opcode name and a pre-tokenized set of arguments, assemble
1164 the insn, but do not emit it.
1166 Note that this implies no macros allowed, since we can't store more
1167 than one insn in an insn structure. */
1169 static void
1170 assemble_tokens_to_insn (const char *opname,
1171 const expressionS *tok,
1172 int ntok,
1173 struct alpha_insn *insn)
1175 const struct alpha_opcode *opcode;
1177 /* Search opcodes. */
1178 opcode = (const struct alpha_opcode *) hash_find (alpha_opcode_hash, opname);
1179 if (opcode)
1181 int cpumatch;
1182 opcode = find_opcode_match (opcode, tok, &ntok, &cpumatch);
1183 if (opcode)
1185 assemble_insn (opcode, tok, ntok, insn, BFD_RELOC_UNUSED);
1186 return;
1188 else if (cpumatch)
1189 as_bad (_("inappropriate arguments for opcode `%s'"), opname);
1190 else
1191 as_bad (_("opcode `%s' not supported for target %s"), opname,
1192 alpha_target_name);
1194 else
1195 as_bad (_("unknown opcode `%s'"), opname);
1198 /* Build a BFD section with its flags set appropriately for the .lita,
1199 .lit8, or .lit4 sections. */
1201 static void
1202 create_literal_section (const char *name,
1203 segT *secp,
1204 symbolS **symp)
1206 segT current_section = now_seg;
1207 int current_subsec = now_subseg;
1208 segT new_sec;
1210 *secp = new_sec = subseg_new (name, 0);
1211 subseg_set (current_section, current_subsec);
1212 bfd_set_section_alignment (stdoutput, new_sec, 4);
1213 bfd_set_section_flags (stdoutput, new_sec,
1214 SEC_RELOC | SEC_ALLOC | SEC_LOAD | SEC_READONLY
1215 | SEC_DATA);
1217 S_CLEAR_EXTERNAL (*symp = section_symbol (new_sec));
1220 /* Load a (partial) expression into a target register.
1222 If poffset is not null, after the call it will either contain
1223 O_constant 0, or a 16-bit offset appropriate for any MEM format
1224 instruction. In addition, pbasereg will be modified to point to
1225 the base register to use in that MEM format instruction.
1227 In any case, *pbasereg should contain a base register to add to the
1228 expression. This will normally be either AXP_REG_ZERO or
1229 alpha_gp_register. Symbol addresses will always be loaded via $gp,
1230 so "foo($0)" is interpreted as adding the address of foo to $0;
1231 i.e. "ldq $targ, LIT($gp); addq $targ, $0, $targ". Odd, perhaps,
1232 but this is what OSF/1 does.
1234 If explicit relocations of the form !literal!<number> are allowed,
1235 and used, then explicit_reloc with be an expression pointer.
1237 Finally, the return value is nonzero if the calling macro may emit
1238 a LITUSE reloc if otherwise appropriate; the return value is the
1239 sequence number to use. */
1241 static long
1242 load_expression (int targreg,
1243 const expressionS *exp,
1244 int *pbasereg,
1245 expressionS *poffset,
1246 const char *opname)
1248 long emit_lituse = 0;
1249 offsetT addend = exp->X_add_number;
1250 int basereg = *pbasereg;
1251 struct alpha_insn insn;
1252 expressionS newtok[3];
1254 switch (exp->X_op)
1256 case O_symbol:
1258 #ifdef OBJ_ECOFF
1259 offsetT lit;
1261 /* Attempt to reduce .lit load by splitting the offset from
1262 its symbol when possible, but don't create a situation in
1263 which we'd fail. */
1264 if (!range_signed_32 (addend) &&
1265 (alpha_noat_on || targreg == AXP_REG_AT))
1267 lit = add_to_literal_pool (exp->X_add_symbol, addend,
1268 alpha_lita_section, 8);
1269 addend = 0;
1271 else
1272 lit = add_to_literal_pool (exp->X_add_symbol, 0,
1273 alpha_lita_section, 8);
1275 if (lit >= 0x8000)
1276 as_fatal (_("overflow in literal (.lita) table"));
1278 /* Emit "ldq r, lit(gp)". */
1280 if (basereg != alpha_gp_register && targreg == basereg)
1282 if (alpha_noat_on)
1283 as_bad (_("macro requires $at register while noat in effect"));
1284 if (targreg == AXP_REG_AT)
1285 as_bad (_("macro requires $at while $at in use"));
1287 set_tok_reg (newtok[0], AXP_REG_AT);
1289 else
1290 set_tok_reg (newtok[0], targreg);
1292 set_tok_sym (newtok[1], alpha_lita_symbol, lit);
1293 set_tok_preg (newtok[2], alpha_gp_register);
1295 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
1297 gas_assert (insn.nfixups == 1);
1298 insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITERAL;
1299 insn.sequence = emit_lituse = next_sequence_num--;
1300 #endif /* OBJ_ECOFF */
1301 #ifdef OBJ_ELF
1302 /* Emit "ldq r, gotoff(gp)". */
1304 if (basereg != alpha_gp_register && targreg == basereg)
1306 if (alpha_noat_on)
1307 as_bad (_("macro requires $at register while noat in effect"));
1308 if (targreg == AXP_REG_AT)
1309 as_bad (_("macro requires $at while $at in use"));
1311 set_tok_reg (newtok[0], AXP_REG_AT);
1313 else
1314 set_tok_reg (newtok[0], targreg);
1316 /* XXX: Disable this .got minimizing optimization so that we can get
1317 better instruction offset knowledge in the compiler. This happens
1318 very infrequently anyway. */
1319 if (1
1320 || (!range_signed_32 (addend)
1321 && (alpha_noat_on || targreg == AXP_REG_AT)))
1323 newtok[1] = *exp;
1324 addend = 0;
1326 else
1327 set_tok_sym (newtok[1], exp->X_add_symbol, 0);
1329 set_tok_preg (newtok[2], alpha_gp_register);
1331 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
1333 gas_assert (insn.nfixups == 1);
1334 insn.fixups[0].reloc = BFD_RELOC_ALPHA_ELF_LITERAL;
1335 insn.sequence = emit_lituse = next_sequence_num--;
1336 #endif /* OBJ_ELF */
1337 #ifdef OBJ_EVAX
1338 /* Find symbol or symbol pointer in link section. */
1340 if (exp->X_add_symbol == alpha_evax_proc->symbol)
1342 /* Linkage-relative expression. */
1343 set_tok_reg (newtok[0], targreg);
1345 if (range_signed_16 (addend))
1347 set_tok_const (newtok[1], addend);
1348 addend = 0;
1350 else
1352 set_tok_const (newtok[1], 0);
1354 set_tok_preg (newtok[2], basereg);
1355 assemble_tokens_to_insn ("lda", newtok, 3, &insn);
1357 else
1359 const char *symname = S_GET_NAME (exp->X_add_symbol);
1360 const char *ptr1, *ptr2;
1361 int symlen = strlen (symname);
1363 if ((symlen > 4 &&
1364 strcmp (ptr2 = &symname [symlen - 4], "..lk") == 0))
1366 /* Access to an item whose address is stored in the linkage
1367 section. Just read the address. */
1368 set_tok_reg (newtok[0], targreg);
1370 newtok[1] = *exp;
1371 newtok[1].X_op = O_subtract;
1372 newtok[1].X_op_symbol = alpha_evax_proc->symbol;
1374 set_tok_preg (newtok[2], basereg);
1375 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
1376 alpha_linkage_symbol = exp->X_add_symbol;
1378 if (poffset)
1379 set_tok_const (*poffset, 0);
1381 if (alpha_flag_replace && targreg == 26)
1383 /* Add a NOP fixup for 'ldX $26,YYY..NAME..lk'. */
1384 char *ensymname;
1385 symbolS *ensym;
1386 volatile asymbol *dummy;
1388 /* Build the entry name as 'NAME..en'. */
1389 ptr1 = strstr (symname, "..") + 2;
1390 if (ptr1 > ptr2)
1391 ptr1 = symname;
1392 ensymname = (char *) xmalloc (ptr2 - ptr1 + 5);
1393 memcpy (ensymname, ptr1, ptr2 - ptr1);
1394 memcpy (ensymname + (ptr2 - ptr1), "..en", 5);
1396 gas_assert (insn.nfixups + 1 <= MAX_INSN_FIXUPS);
1397 insn.fixups[insn.nfixups].reloc = BFD_RELOC_ALPHA_NOP;
1398 ensym = symbol_find_or_make (ensymname);
1399 ensym->sy_used = 1;
1400 /* The fixup must be the same as the BFD_RELOC_ALPHA_BOH
1401 case in emit_jsrjmp. See B.4.5.2 of the OpenVMS Linker
1402 Utility Manual. */
1403 insn.fixups[insn.nfixups].exp.X_op = O_symbol;
1404 insn.fixups[insn.nfixups].exp.X_add_symbol = ensym;
1405 insn.fixups[insn.nfixups].exp.X_add_number = 0;
1406 insn.fixups[insn.nfixups].xtrasym = alpha_linkage_symbol;
1407 insn.fixups[insn.nfixups].procsym = alpha_evax_proc->symbol;
1408 insn.nfixups++;
1410 /* ??? Force bsym to be instantiated now, as it will be
1411 too late to do so in tc_gen_reloc. */
1412 dummy = symbol_get_bfdsym (exp->X_add_symbol);
1414 else if (alpha_flag_replace && targreg == 27)
1416 /* Add a lda fixup for 'ldX $27,YYY.NAME..lk+8'. */
1417 char *psymname;
1418 symbolS *psym;
1420 /* Extract NAME. */
1421 ptr1 = strstr (symname, "..") + 2;
1422 if (ptr1 > ptr2)
1423 ptr1 = symname;
1424 psymname = (char *) xmalloc (ptr2 - ptr1 + 1);
1425 memcpy (psymname, ptr1, ptr2 - ptr1);
1426 psymname [ptr2 - ptr1] = 0;
1428 gas_assert (insn.nfixups + 1 <= MAX_INSN_FIXUPS);
1429 insn.fixups[insn.nfixups].reloc = BFD_RELOC_ALPHA_LDA;
1430 psym = symbol_find_or_make (psymname);
1431 psym->sy_used = 1;
1432 insn.fixups[insn.nfixups].exp.X_op = O_subtract;
1433 insn.fixups[insn.nfixups].exp.X_add_symbol = psym;
1434 insn.fixups[insn.nfixups].exp.X_op_symbol = alpha_evax_proc->symbol;
1435 insn.fixups[insn.nfixups].exp.X_add_number = 0;
1436 insn.fixups[insn.nfixups].xtrasym = alpha_linkage_symbol;
1437 insn.fixups[insn.nfixups].procsym = alpha_evax_proc->symbol;
1438 insn.nfixups++;
1441 emit_insn (&insn);
1442 return 0;
1444 else
1446 /* Not in the linkage section. Put the value into the linkage
1447 section. */
1448 symbolS *linkexp;
1450 if (!range_signed_32 (addend))
1451 addend = sign_extend_32 (addend);
1452 linkexp = add_to_link_pool (alpha_evax_proc->symbol,
1453 exp->X_add_symbol, 0);
1454 set_tok_reg (newtok[0], targreg);
1455 set_tok_sym (newtok[1], linkexp, 0);
1456 set_tok_preg (newtok[2], basereg);
1457 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
1460 #endif /* OBJ_EVAX */
1462 emit_insn (&insn);
1464 #ifndef OBJ_EVAX
1465 if (basereg != alpha_gp_register && basereg != AXP_REG_ZERO)
1467 /* Emit "addq r, base, r". */
1469 set_tok_reg (newtok[1], basereg);
1470 set_tok_reg (newtok[2], targreg);
1471 assemble_tokens ("addq", newtok, 3, 0);
1473 #endif
1474 basereg = targreg;
1476 break;
1478 case O_constant:
1479 break;
1481 case O_subtract:
1482 /* Assume that this difference expression will be resolved to an
1483 absolute value and that that value will fit in 16 bits. */
1485 set_tok_reg (newtok[0], targreg);
1486 newtok[1] = *exp;
1487 set_tok_preg (newtok[2], basereg);
1488 assemble_tokens (opname, newtok, 3, 0);
1490 if (poffset)
1491 set_tok_const (*poffset, 0);
1492 return 0;
1494 case O_big:
1495 if (exp->X_add_number > 0)
1496 as_bad (_("bignum invalid; zero assumed"));
1497 else
1498 as_bad (_("floating point number invalid; zero assumed"));
1499 addend = 0;
1500 break;
1502 default:
1503 as_bad (_("can't handle expression"));
1504 addend = 0;
1505 break;
1508 if (!range_signed_32 (addend))
1510 #ifdef OBJ_EVAX
1511 symbolS *litexp;
1512 #else
1513 offsetT lit;
1514 long seq_num = next_sequence_num--;
1515 #endif
1517 /* For 64-bit addends, just put it in the literal pool. */
1518 #ifdef OBJ_EVAX
1519 /* Emit "ldq targreg, lit(basereg)". */
1520 litexp = add_to_link_pool (alpha_evax_proc->symbol,
1521 section_symbol (absolute_section), addend);
1522 set_tok_reg (newtok[0], targreg);
1523 set_tok_sym (newtok[1], litexp, 0);
1524 set_tok_preg (newtok[2], alpha_gp_register);
1525 assemble_tokens ("ldq", newtok, 3, 0);
1526 #else
1528 if (alpha_lit8_section == NULL)
1530 create_literal_section (".lit8",
1531 &alpha_lit8_section,
1532 &alpha_lit8_symbol);
1534 #ifdef OBJ_ECOFF
1535 alpha_lit8_literal = add_to_literal_pool (alpha_lit8_symbol, 0x8000,
1536 alpha_lita_section, 8);
1537 if (alpha_lit8_literal >= 0x8000)
1538 as_fatal (_("overflow in literal (.lita) table"));
1539 #endif
1542 lit = add_to_literal_pool (NULL, addend, alpha_lit8_section, 8) - 0x8000;
1543 if (lit >= 0x8000)
1544 as_fatal (_("overflow in literal (.lit8) table"));
1546 /* Emit "lda litreg, .lit8+0x8000". */
1548 if (targreg == basereg)
1550 if (alpha_noat_on)
1551 as_bad (_("macro requires $at register while noat in effect"));
1552 if (targreg == AXP_REG_AT)
1553 as_bad (_("macro requires $at while $at in use"));
1555 set_tok_reg (newtok[0], AXP_REG_AT);
1557 else
1558 set_tok_reg (newtok[0], targreg);
1559 #ifdef OBJ_ECOFF
1560 set_tok_sym (newtok[1], alpha_lita_symbol, alpha_lit8_literal);
1561 #endif
1562 #ifdef OBJ_ELF
1563 set_tok_sym (newtok[1], alpha_lit8_symbol, 0x8000);
1564 #endif
1565 set_tok_preg (newtok[2], alpha_gp_register);
1567 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
1569 gas_assert (insn.nfixups == 1);
1570 #ifdef OBJ_ECOFF
1571 insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITERAL;
1572 #endif
1573 #ifdef OBJ_ELF
1574 insn.fixups[0].reloc = BFD_RELOC_ALPHA_ELF_LITERAL;
1575 #endif
1576 insn.sequence = seq_num;
1578 emit_insn (&insn);
1580 /* Emit "ldq litreg, lit(litreg)". */
1582 set_tok_const (newtok[1], lit);
1583 set_tok_preg (newtok[2], newtok[0].X_add_number);
1585 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
1587 gas_assert (insn.nfixups < MAX_INSN_FIXUPS);
1588 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
1589 insn.fixups[insn.nfixups].exp.X_op = O_absent;
1590 insn.nfixups++;
1591 insn.sequence = seq_num;
1592 emit_lituse = 0;
1594 emit_insn (&insn);
1596 /* Emit "addq litreg, base, target". */
1598 if (basereg != AXP_REG_ZERO)
1600 set_tok_reg (newtok[1], basereg);
1601 set_tok_reg (newtok[2], targreg);
1602 assemble_tokens ("addq", newtok, 3, 0);
1604 #endif /* !OBJ_EVAX */
1606 if (poffset)
1607 set_tok_const (*poffset, 0);
1608 *pbasereg = targreg;
1610 else
1612 offsetT low, high, extra, tmp;
1614 /* For 32-bit operands, break up the addend. */
1616 low = sign_extend_16 (addend);
1617 tmp = addend - low;
1618 high = sign_extend_16 (tmp >> 16);
1620 if (tmp - (high << 16))
1622 extra = 0x4000;
1623 tmp -= 0x40000000;
1624 high = sign_extend_16 (tmp >> 16);
1626 else
1627 extra = 0;
1629 set_tok_reg (newtok[0], targreg);
1630 set_tok_preg (newtok[2], basereg);
1632 if (extra)
1634 /* Emit "ldah r, extra(r). */
1635 set_tok_const (newtok[1], extra);
1636 assemble_tokens ("ldah", newtok, 3, 0);
1637 set_tok_preg (newtok[2], basereg = targreg);
1640 if (high)
1642 /* Emit "ldah r, high(r). */
1643 set_tok_const (newtok[1], high);
1644 assemble_tokens ("ldah", newtok, 3, 0);
1645 basereg = targreg;
1646 set_tok_preg (newtok[2], basereg);
1649 if ((low && !poffset) || (!poffset && basereg != targreg))
1651 /* Emit "lda r, low(base)". */
1652 set_tok_const (newtok[1], low);
1653 assemble_tokens ("lda", newtok, 3, 0);
1654 basereg = targreg;
1655 low = 0;
1658 if (poffset)
1659 set_tok_const (*poffset, low);
1660 *pbasereg = basereg;
1663 return emit_lituse;
1666 /* The lda macro differs from the lda instruction in that it handles
1667 most simple expressions, particularly symbol address loads and
1668 large constants. */
1670 static void
1671 emit_lda (const expressionS *tok,
1672 int ntok,
1673 const void * unused ATTRIBUTE_UNUSED)
1675 int basereg;
1677 if (ntok == 2)
1678 basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
1679 else
1680 basereg = tok[2].X_add_number;
1682 (void) load_expression (tok[0].X_add_number, &tok[1], &basereg, NULL, "lda");
1685 /* The ldah macro differs from the ldah instruction in that it has $31
1686 as an implied base register. */
1688 static void
1689 emit_ldah (const expressionS *tok,
1690 int ntok ATTRIBUTE_UNUSED,
1691 const void * unused ATTRIBUTE_UNUSED)
1693 expressionS newtok[3];
1695 newtok[0] = tok[0];
1696 newtok[1] = tok[1];
1697 set_tok_preg (newtok[2], AXP_REG_ZERO);
1699 assemble_tokens ("ldah", newtok, 3, 0);
1702 /* Called internally to handle all alignment needs. This takes care
1703 of eliding calls to frag_align if'n the cached current alignment
1704 says we've already got it, as well as taking care of the auto-align
1705 feature wrt labels. */
1707 static void
1708 alpha_align (int n,
1709 char *pfill,
1710 symbolS *label,
1711 int force ATTRIBUTE_UNUSED)
1713 if (alpha_current_align >= n)
1714 return;
1716 if (pfill == NULL)
1718 if (subseg_text_p (now_seg))
1719 frag_align_code (n, 0);
1720 else
1721 frag_align (n, 0, 0);
1723 else
1724 frag_align (n, *pfill, 0);
1726 alpha_current_align = n;
1728 if (label != NULL && S_GET_SEGMENT (label) == now_seg)
1730 symbol_set_frag (label, frag_now);
1731 S_SET_VALUE (label, (valueT) frag_now_fix ());
1734 record_alignment (now_seg, n);
1736 /* ??? If alpha_flag_relax && force && elf, record the requested alignment
1737 in a reloc for the linker to see. */
1740 /* Actually output an instruction with its fixup. */
1742 static void
1743 emit_insn (struct alpha_insn *insn)
1745 char *f;
1746 int i;
1748 /* Take care of alignment duties. */
1749 if (alpha_auto_align_on && alpha_current_align < 2)
1750 alpha_align (2, (char *) NULL, alpha_insn_label, 0);
1751 if (alpha_current_align > 2)
1752 alpha_current_align = 2;
1753 alpha_insn_label = NULL;
1755 /* Write out the instruction. */
1756 f = frag_more (4);
1757 md_number_to_chars (f, insn->insn, 4);
1759 #ifdef OBJ_ELF
1760 dwarf2_emit_insn (4);
1761 #endif
1763 /* Apply the fixups in order. */
1764 for (i = 0; i < insn->nfixups; ++i)
1766 const struct alpha_operand *operand = (const struct alpha_operand *) 0;
1767 struct alpha_fixup *fixup = &insn->fixups[i];
1768 struct alpha_reloc_tag *info = NULL;
1769 int size, pcrel;
1770 fixS *fixP;
1772 /* Some fixups are only used internally and so have no howto. */
1773 if ((int) fixup->reloc < 0)
1775 operand = &alpha_operands[-(int) fixup->reloc];
1776 size = 4;
1777 pcrel = ((operand->flags & AXP_OPERAND_RELATIVE) != 0);
1779 else if (fixup->reloc > BFD_RELOC_UNUSED
1780 || fixup->reloc == BFD_RELOC_ALPHA_GPDISP_HI16
1781 || fixup->reloc == BFD_RELOC_ALPHA_GPDISP_LO16)
1783 size = 2;
1784 pcrel = 0;
1786 else
1788 reloc_howto_type *reloc_howto =
1789 bfd_reloc_type_lookup (stdoutput,
1790 (bfd_reloc_code_real_type) fixup->reloc);
1791 gas_assert (reloc_howto);
1793 size = bfd_get_reloc_size (reloc_howto);
1795 switch (fixup->reloc)
1797 #ifdef OBJ_EVAX
1798 case BFD_RELOC_ALPHA_NOP:
1799 case BFD_RELOC_ALPHA_BSR:
1800 case BFD_RELOC_ALPHA_LDA:
1801 case BFD_RELOC_ALPHA_BOH:
1802 break;
1803 #endif
1804 default:
1805 gas_assert (size >= 1 && size <= 4);
1808 pcrel = reloc_howto->pc_relative;
1811 fixP = fix_new_exp (frag_now, f - frag_now->fr_literal, size,
1812 &fixup->exp, pcrel, (bfd_reloc_code_real_type) fixup->reloc);
1814 /* Turn off complaints that the addend is too large for some fixups,
1815 and copy in the sequence number for the explicit relocations. */
1816 switch (fixup->reloc)
1818 case BFD_RELOC_ALPHA_HINT:
1819 case BFD_RELOC_GPREL32:
1820 case BFD_RELOC_GPREL16:
1821 case BFD_RELOC_ALPHA_GPREL_HI16:
1822 case BFD_RELOC_ALPHA_GPREL_LO16:
1823 case BFD_RELOC_ALPHA_GOTDTPREL16:
1824 case BFD_RELOC_ALPHA_DTPREL_HI16:
1825 case BFD_RELOC_ALPHA_DTPREL_LO16:
1826 case BFD_RELOC_ALPHA_DTPREL16:
1827 case BFD_RELOC_ALPHA_GOTTPREL16:
1828 case BFD_RELOC_ALPHA_TPREL_HI16:
1829 case BFD_RELOC_ALPHA_TPREL_LO16:
1830 case BFD_RELOC_ALPHA_TPREL16:
1831 fixP->fx_no_overflow = 1;
1832 break;
1834 case BFD_RELOC_ALPHA_GPDISP_HI16:
1835 fixP->fx_no_overflow = 1;
1836 fixP->fx_addsy = section_symbol (now_seg);
1837 fixP->fx_offset = 0;
1839 info = get_alpha_reloc_tag (insn->sequence);
1840 if (++info->n_master > 1)
1841 as_bad (_("too many ldah insns for !gpdisp!%ld"), insn->sequence);
1842 if (info->segment != now_seg)
1843 as_bad (_("both insns for !gpdisp!%ld must be in the same section"),
1844 insn->sequence);
1845 fixP->tc_fix_data.info = info;
1846 break;
1848 case BFD_RELOC_ALPHA_GPDISP_LO16:
1849 fixP->fx_no_overflow = 1;
1851 info = get_alpha_reloc_tag (insn->sequence);
1852 if (++info->n_slaves > 1)
1853 as_bad (_("too many lda insns for !gpdisp!%ld"), insn->sequence);
1854 if (info->segment != now_seg)
1855 as_bad (_("both insns for !gpdisp!%ld must be in the same section"),
1856 insn->sequence);
1857 fixP->tc_fix_data.info = info;
1858 info->slaves = fixP;
1859 break;
1861 case BFD_RELOC_ALPHA_LITERAL:
1862 case BFD_RELOC_ALPHA_ELF_LITERAL:
1863 fixP->fx_no_overflow = 1;
1865 if (insn->sequence == 0)
1866 break;
1867 info = get_alpha_reloc_tag (insn->sequence);
1868 info->master = fixP;
1869 info->n_master++;
1870 if (info->segment != now_seg)
1871 info->multi_section_p = 1;
1872 fixP->tc_fix_data.info = info;
1873 break;
1875 #ifdef RELOC_OP_P
1876 case DUMMY_RELOC_LITUSE_ADDR:
1877 fixP->fx_offset = LITUSE_ALPHA_ADDR;
1878 goto do_lituse;
1879 case DUMMY_RELOC_LITUSE_BASE:
1880 fixP->fx_offset = LITUSE_ALPHA_BASE;
1881 goto do_lituse;
1882 case DUMMY_RELOC_LITUSE_BYTOFF:
1883 fixP->fx_offset = LITUSE_ALPHA_BYTOFF;
1884 goto do_lituse;
1885 case DUMMY_RELOC_LITUSE_JSR:
1886 fixP->fx_offset = LITUSE_ALPHA_JSR;
1887 goto do_lituse;
1888 case DUMMY_RELOC_LITUSE_TLSGD:
1889 fixP->fx_offset = LITUSE_ALPHA_TLSGD;
1890 goto do_lituse;
1891 case DUMMY_RELOC_LITUSE_TLSLDM:
1892 fixP->fx_offset = LITUSE_ALPHA_TLSLDM;
1893 goto do_lituse;
1894 case DUMMY_RELOC_LITUSE_JSRDIRECT:
1895 fixP->fx_offset = LITUSE_ALPHA_JSRDIRECT;
1896 goto do_lituse;
1897 do_lituse:
1898 fixP->fx_addsy = section_symbol (now_seg);
1899 fixP->fx_r_type = BFD_RELOC_ALPHA_LITUSE;
1901 info = get_alpha_reloc_tag (insn->sequence);
1902 if (fixup->reloc == DUMMY_RELOC_LITUSE_TLSGD)
1903 info->saw_lu_tlsgd = 1;
1904 else if (fixup->reloc == DUMMY_RELOC_LITUSE_TLSLDM)
1905 info->saw_lu_tlsldm = 1;
1906 if (++info->n_slaves > 1)
1908 if (info->saw_lu_tlsgd)
1909 as_bad (_("too many lituse insns for !lituse_tlsgd!%ld"),
1910 insn->sequence);
1911 else if (info->saw_lu_tlsldm)
1912 as_bad (_("too many lituse insns for !lituse_tlsldm!%ld"),
1913 insn->sequence);
1915 fixP->tc_fix_data.info = info;
1916 fixP->tc_fix_data.next_reloc = info->slaves;
1917 info->slaves = fixP;
1918 if (info->segment != now_seg)
1919 info->multi_section_p = 1;
1920 break;
1922 case BFD_RELOC_ALPHA_TLSGD:
1923 fixP->fx_no_overflow = 1;
1925 if (insn->sequence == 0)
1926 break;
1927 info = get_alpha_reloc_tag (insn->sequence);
1928 if (info->saw_tlsgd)
1929 as_bad (_("duplicate !tlsgd!%ld"), insn->sequence);
1930 else if (info->saw_tlsldm)
1931 as_bad (_("sequence number in use for !tlsldm!%ld"),
1932 insn->sequence);
1933 else
1934 info->saw_tlsgd = 1;
1935 fixP->tc_fix_data.info = info;
1936 break;
1938 case BFD_RELOC_ALPHA_TLSLDM:
1939 fixP->fx_no_overflow = 1;
1941 if (insn->sequence == 0)
1942 break;
1943 info = get_alpha_reloc_tag (insn->sequence);
1944 if (info->saw_tlsldm)
1945 as_bad (_("duplicate !tlsldm!%ld"), insn->sequence);
1946 else if (info->saw_tlsgd)
1947 as_bad (_("sequence number in use for !tlsgd!%ld"),
1948 insn->sequence);
1949 else
1950 info->saw_tlsldm = 1;
1951 fixP->tc_fix_data.info = info;
1952 break;
1953 #endif
1954 #ifdef OBJ_EVAX
1955 case BFD_RELOC_ALPHA_NOP:
1956 case BFD_RELOC_ALPHA_LDA:
1957 case BFD_RELOC_ALPHA_BSR:
1958 case BFD_RELOC_ALPHA_BOH:
1959 info = get_alpha_reloc_tag (next_sequence_num--);
1960 fixP->tc_fix_data.info = info;
1961 fixP->tc_fix_data.info->sym = fixup->xtrasym;
1962 fixP->tc_fix_data.info->psym = fixup->procsym;
1963 break;
1964 #endif
1966 default:
1967 if ((int) fixup->reloc < 0)
1969 if (operand->flags & AXP_OPERAND_NOOVERFLOW)
1970 fixP->fx_no_overflow = 1;
1972 break;
1977 /* Insert an operand value into an instruction. */
1979 static unsigned
1980 insert_operand (unsigned insn,
1981 const struct alpha_operand *operand,
1982 offsetT val,
1983 char *file,
1984 unsigned line)
1986 if (operand->bits != 32 && !(operand->flags & AXP_OPERAND_NOOVERFLOW))
1988 offsetT min, max;
1990 if (operand->flags & AXP_OPERAND_SIGNED)
1992 max = (1 << (operand->bits - 1)) - 1;
1993 min = -(1 << (operand->bits - 1));
1995 else
1997 max = (1 << operand->bits) - 1;
1998 min = 0;
2001 if (val < min || val > max)
2002 as_warn_value_out_of_range (_("operand"), val, min, max, file, line);
2005 if (operand->insert)
2007 const char *errmsg = NULL;
2009 insn = (*operand->insert) (insn, val, &errmsg);
2010 if (errmsg)
2011 as_warn ("%s", errmsg);
2013 else
2014 insn |= ((val & ((1 << operand->bits) - 1)) << operand->shift);
2016 return insn;
2019 /* Turn an opcode description and a set of arguments into
2020 an instruction and a fixup. */
2022 static void
2023 assemble_insn (const struct alpha_opcode *opcode,
2024 const expressionS *tok,
2025 int ntok,
2026 struct alpha_insn *insn,
2027 extended_bfd_reloc_code_real_type reloc)
2029 const struct alpha_operand *reloc_operand = NULL;
2030 const expressionS *reloc_exp = NULL;
2031 const unsigned char *argidx;
2032 unsigned image;
2033 int tokidx = 0;
2035 memset (insn, 0, sizeof (*insn));
2036 image = opcode->opcode;
2038 for (argidx = opcode->operands; *argidx; ++argidx)
2040 const struct alpha_operand *operand = &alpha_operands[*argidx];
2041 const expressionS *t = (const expressionS *) 0;
2043 if (operand->flags & AXP_OPERAND_FAKE)
2045 /* Fake operands take no value and generate no fixup. */
2046 image = insert_operand (image, operand, 0, NULL, 0);
2047 continue;
2050 if (tokidx >= ntok)
2052 switch (operand->flags & AXP_OPERAND_OPTIONAL_MASK)
2054 case AXP_OPERAND_DEFAULT_FIRST:
2055 t = &tok[0];
2056 break;
2057 case AXP_OPERAND_DEFAULT_SECOND:
2058 t = &tok[1];
2059 break;
2060 case AXP_OPERAND_DEFAULT_ZERO:
2062 static expressionS zero_exp;
2063 t = &zero_exp;
2064 zero_exp.X_op = O_constant;
2065 zero_exp.X_unsigned = 1;
2067 break;
2068 default:
2069 abort ();
2072 else
2073 t = &tok[tokidx++];
2075 switch (t->X_op)
2077 case O_register:
2078 case O_pregister:
2079 case O_cpregister:
2080 image = insert_operand (image, operand, regno (t->X_add_number),
2081 NULL, 0);
2082 break;
2084 case O_constant:
2085 image = insert_operand (image, operand, t->X_add_number, NULL, 0);
2086 gas_assert (reloc_operand == NULL);
2087 reloc_operand = operand;
2088 reloc_exp = t;
2089 break;
2091 default:
2092 /* This is only 0 for fields that should contain registers,
2093 which means this pattern shouldn't have matched. */
2094 if (operand->default_reloc == 0)
2095 abort ();
2097 /* There is one special case for which an insn receives two
2098 relocations, and thus the user-supplied reloc does not
2099 override the operand reloc. */
2100 if (operand->default_reloc == BFD_RELOC_ALPHA_HINT)
2102 struct alpha_fixup *fixup;
2104 if (insn->nfixups >= MAX_INSN_FIXUPS)
2105 as_fatal (_("too many fixups"));
2107 fixup = &insn->fixups[insn->nfixups++];
2108 fixup->exp = *t;
2109 fixup->reloc = BFD_RELOC_ALPHA_HINT;
2111 else
2113 if (reloc == BFD_RELOC_UNUSED)
2114 reloc = operand->default_reloc;
2116 gas_assert (reloc_operand == NULL);
2117 reloc_operand = operand;
2118 reloc_exp = t;
2120 break;
2124 if (reloc != BFD_RELOC_UNUSED)
2126 struct alpha_fixup *fixup;
2128 if (insn->nfixups >= MAX_INSN_FIXUPS)
2129 as_fatal (_("too many fixups"));
2131 /* ??? My but this is hacky. But the OSF/1 assembler uses the same
2132 relocation tag for both ldah and lda with gpdisp. Choose the
2133 correct internal relocation based on the opcode. */
2134 if (reloc == BFD_RELOC_ALPHA_GPDISP)
2136 if (strcmp (opcode->name, "ldah") == 0)
2137 reloc = BFD_RELOC_ALPHA_GPDISP_HI16;
2138 else if (strcmp (opcode->name, "lda") == 0)
2139 reloc = BFD_RELOC_ALPHA_GPDISP_LO16;
2140 else
2141 as_bad (_("invalid relocation for instruction"));
2144 /* If this is a real relocation (as opposed to a lituse hint), then
2145 the relocation width should match the operand width.
2146 Take care of -MDISP in operand table. */
2147 else if (reloc < BFD_RELOC_UNUSED && reloc > 0)
2149 reloc_howto_type *reloc_howto
2150 = bfd_reloc_type_lookup (stdoutput,
2151 (bfd_reloc_code_real_type) reloc);
2152 if (reloc_operand == NULL
2153 || reloc_howto->bitsize != reloc_operand->bits)
2155 as_bad (_("invalid relocation for field"));
2156 return;
2160 fixup = &insn->fixups[insn->nfixups++];
2161 if (reloc_exp)
2162 fixup->exp = *reloc_exp;
2163 else
2164 fixup->exp.X_op = O_absent;
2165 fixup->reloc = reloc;
2168 insn->insn = image;
2171 /* Handle all "simple" integer register loads -- ldq, ldq_l, ldq_u,
2172 etc. They differ from the real instructions in that they do simple
2173 expressions like the lda macro. */
2175 static void
2176 emit_ir_load (const expressionS *tok,
2177 int ntok,
2178 const void * opname)
2180 int basereg;
2181 long lituse;
2182 expressionS newtok[3];
2183 struct alpha_insn insn;
2184 const char *symname
2185 = tok[1].X_add_symbol ? S_GET_NAME (tok[1].X_add_symbol): "";
2186 int symlen = strlen (symname);
2188 if (ntok == 2)
2189 basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
2190 else
2191 basereg = tok[2].X_add_number;
2193 lituse = load_expression (tok[0].X_add_number, &tok[1],
2194 &basereg, &newtok[1], (const char *) opname);
2196 if (basereg == alpha_gp_register &&
2197 (symlen > 4 && strcmp (&symname [symlen - 4], "..lk") == 0))
2198 return;
2200 newtok[0] = tok[0];
2201 set_tok_preg (newtok[2], basereg);
2203 assemble_tokens_to_insn ((const char *) opname, newtok, 3, &insn);
2205 if (lituse)
2207 gas_assert (insn.nfixups < MAX_INSN_FIXUPS);
2208 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
2209 insn.fixups[insn.nfixups].exp.X_op = O_absent;
2210 insn.nfixups++;
2211 insn.sequence = lituse;
2214 emit_insn (&insn);
2217 /* Handle fp register loads, and both integer and fp register stores.
2218 Again, we handle simple expressions. */
2220 static void
2221 emit_loadstore (const expressionS *tok,
2222 int ntok,
2223 const void * opname)
2225 int basereg;
2226 long lituse;
2227 expressionS newtok[3];
2228 struct alpha_insn insn;
2230 if (ntok == 2)
2231 basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
2232 else
2233 basereg = tok[2].X_add_number;
2235 if (tok[1].X_op != O_constant || !range_signed_16 (tok[1].X_add_number))
2237 if (alpha_noat_on)
2238 as_bad (_("macro requires $at register while noat in effect"));
2240 lituse = load_expression (AXP_REG_AT, &tok[1],
2241 &basereg, &newtok[1], (const char *) opname);
2243 else
2245 newtok[1] = tok[1];
2246 lituse = 0;
2249 newtok[0] = tok[0];
2250 set_tok_preg (newtok[2], basereg);
2252 assemble_tokens_to_insn ((const char *) opname, newtok, 3, &insn);
2254 if (lituse)
2256 gas_assert (insn.nfixups < MAX_INSN_FIXUPS);
2257 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
2258 insn.fixups[insn.nfixups].exp.X_op = O_absent;
2259 insn.nfixups++;
2260 insn.sequence = lituse;
2263 emit_insn (&insn);
2266 /* Load a half-word or byte as an unsigned value. */
2268 static void
2269 emit_ldXu (const expressionS *tok,
2270 int ntok,
2271 const void * vlgsize)
2273 if (alpha_target & AXP_OPCODE_BWX)
2274 emit_ir_load (tok, ntok, ldXu_op[(long) vlgsize]);
2275 else
2277 expressionS newtok[3];
2278 struct alpha_insn insn;
2279 int basereg;
2280 long lituse;
2282 if (alpha_noat_on)
2283 as_bad (_("macro requires $at register while noat in effect"));
2285 if (ntok == 2)
2286 basereg = (tok[1].X_op == O_constant
2287 ? AXP_REG_ZERO : alpha_gp_register);
2288 else
2289 basereg = tok[2].X_add_number;
2291 /* Emit "lda $at, exp". */
2292 lituse = load_expression (AXP_REG_AT, &tok[1], &basereg, NULL, "lda");
2294 /* Emit "ldq_u targ, 0($at)". */
2295 newtok[0] = tok[0];
2296 set_tok_const (newtok[1], 0);
2297 set_tok_preg (newtok[2], basereg);
2298 assemble_tokens_to_insn ("ldq_u", newtok, 3, &insn);
2300 if (lituse)
2302 gas_assert (insn.nfixups < MAX_INSN_FIXUPS);
2303 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
2304 insn.fixups[insn.nfixups].exp.X_op = O_absent;
2305 insn.nfixups++;
2306 insn.sequence = lituse;
2309 emit_insn (&insn);
2311 /* Emit "extXl targ, $at, targ". */
2312 set_tok_reg (newtok[1], basereg);
2313 newtok[2] = newtok[0];
2314 assemble_tokens_to_insn (extXl_op[(long) vlgsize], newtok, 3, &insn);
2316 if (lituse)
2318 gas_assert (insn.nfixups < MAX_INSN_FIXUPS);
2319 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF;
2320 insn.fixups[insn.nfixups].exp.X_op = O_absent;
2321 insn.nfixups++;
2322 insn.sequence = lituse;
2325 emit_insn (&insn);
2329 /* Load a half-word or byte as a signed value. */
2331 static void
2332 emit_ldX (const expressionS *tok,
2333 int ntok,
2334 const void * vlgsize)
2336 emit_ldXu (tok, ntok, vlgsize);
2337 assemble_tokens (sextX_op[(long) vlgsize], tok, 1, 1);
2340 /* Load an integral value from an unaligned address as an unsigned
2341 value. */
2343 static void
2344 emit_uldXu (const expressionS *tok,
2345 int ntok,
2346 const void * vlgsize)
2348 long lgsize = (long) vlgsize;
2349 expressionS newtok[3];
2351 if (alpha_noat_on)
2352 as_bad (_("macro requires $at register while noat in effect"));
2354 /* Emit "lda $at, exp". */
2355 memcpy (newtok, tok, sizeof (expressionS) * ntok);
2356 newtok[0].X_add_number = AXP_REG_AT;
2357 assemble_tokens ("lda", newtok, ntok, 1);
2359 /* Emit "ldq_u $t9, 0($at)". */
2360 set_tok_reg (newtok[0], AXP_REG_T9);
2361 set_tok_const (newtok[1], 0);
2362 set_tok_preg (newtok[2], AXP_REG_AT);
2363 assemble_tokens ("ldq_u", newtok, 3, 1);
2365 /* Emit "ldq_u $t10, size-1($at)". */
2366 set_tok_reg (newtok[0], AXP_REG_T10);
2367 set_tok_const (newtok[1], (1 << lgsize) - 1);
2368 assemble_tokens ("ldq_u", newtok, 3, 1);
2370 /* Emit "extXl $t9, $at, $t9". */
2371 set_tok_reg (newtok[0], AXP_REG_T9);
2372 set_tok_reg (newtok[1], AXP_REG_AT);
2373 set_tok_reg (newtok[2], AXP_REG_T9);
2374 assemble_tokens (extXl_op[lgsize], newtok, 3, 1);
2376 /* Emit "extXh $t10, $at, $t10". */
2377 set_tok_reg (newtok[0], AXP_REG_T10);
2378 set_tok_reg (newtok[2], AXP_REG_T10);
2379 assemble_tokens (extXh_op[lgsize], newtok, 3, 1);
2381 /* Emit "or $t9, $t10, targ". */
2382 set_tok_reg (newtok[0], AXP_REG_T9);
2383 set_tok_reg (newtok[1], AXP_REG_T10);
2384 newtok[2] = tok[0];
2385 assemble_tokens ("or", newtok, 3, 1);
2388 /* Load an integral value from an unaligned address as a signed value.
2389 Note that quads should get funneled to the unsigned load since we
2390 don't have to do the sign extension. */
2392 static void
2393 emit_uldX (const expressionS *tok,
2394 int ntok,
2395 const void * vlgsize)
2397 emit_uldXu (tok, ntok, vlgsize);
2398 assemble_tokens (sextX_op[(long) vlgsize], tok, 1, 1);
2401 /* Implement the ldil macro. */
2403 static void
2404 emit_ldil (const expressionS *tok,
2405 int ntok,
2406 const void * unused ATTRIBUTE_UNUSED)
2408 expressionS newtok[2];
2410 memcpy (newtok, tok, sizeof (newtok));
2411 newtok[1].X_add_number = sign_extend_32 (tok[1].X_add_number);
2413 assemble_tokens ("lda", newtok, ntok, 1);
2416 /* Store a half-word or byte. */
2418 static void
2419 emit_stX (const expressionS *tok,
2420 int ntok,
2421 const void * vlgsize)
2423 int lgsize = (int) (long) vlgsize;
2425 if (alpha_target & AXP_OPCODE_BWX)
2426 emit_loadstore (tok, ntok, stX_op[lgsize]);
2427 else
2429 expressionS newtok[3];
2430 struct alpha_insn insn;
2431 int basereg;
2432 long lituse;
2434 if (alpha_noat_on)
2435 as_bad (_("macro requires $at register while noat in effect"));
2437 if (ntok == 2)
2438 basereg = (tok[1].X_op == O_constant
2439 ? AXP_REG_ZERO : alpha_gp_register);
2440 else
2441 basereg = tok[2].X_add_number;
2443 /* Emit "lda $at, exp". */
2444 lituse = load_expression (AXP_REG_AT, &tok[1], &basereg, NULL, "lda");
2446 /* Emit "ldq_u $t9, 0($at)". */
2447 set_tok_reg (newtok[0], AXP_REG_T9);
2448 set_tok_const (newtok[1], 0);
2449 set_tok_preg (newtok[2], basereg);
2450 assemble_tokens_to_insn ("ldq_u", newtok, 3, &insn);
2452 if (lituse)
2454 gas_assert (insn.nfixups < MAX_INSN_FIXUPS);
2455 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
2456 insn.fixups[insn.nfixups].exp.X_op = O_absent;
2457 insn.nfixups++;
2458 insn.sequence = lituse;
2461 emit_insn (&insn);
2463 /* Emit "insXl src, $at, $t10". */
2464 newtok[0] = tok[0];
2465 set_tok_reg (newtok[1], basereg);
2466 set_tok_reg (newtok[2], AXP_REG_T10);
2467 assemble_tokens_to_insn (insXl_op[lgsize], newtok, 3, &insn);
2469 if (lituse)
2471 gas_assert (insn.nfixups < MAX_INSN_FIXUPS);
2472 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF;
2473 insn.fixups[insn.nfixups].exp.X_op = O_absent;
2474 insn.nfixups++;
2475 insn.sequence = lituse;
2478 emit_insn (&insn);
2480 /* Emit "mskXl $t9, $at, $t9". */
2481 set_tok_reg (newtok[0], AXP_REG_T9);
2482 newtok[2] = newtok[0];
2483 assemble_tokens_to_insn (mskXl_op[lgsize], newtok, 3, &insn);
2485 if (lituse)
2487 gas_assert (insn.nfixups < MAX_INSN_FIXUPS);
2488 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF;
2489 insn.fixups[insn.nfixups].exp.X_op = O_absent;
2490 insn.nfixups++;
2491 insn.sequence = lituse;
2494 emit_insn (&insn);
2496 /* Emit "or $t9, $t10, $t9". */
2497 set_tok_reg (newtok[1], AXP_REG_T10);
2498 assemble_tokens ("or", newtok, 3, 1);
2500 /* Emit "stq_u $t9, 0($at). */
2501 set_tok_const(newtok[1], 0);
2502 set_tok_preg (newtok[2], AXP_REG_AT);
2503 assemble_tokens_to_insn ("stq_u", newtok, 3, &insn);
2505 if (lituse)
2507 gas_assert (insn.nfixups < MAX_INSN_FIXUPS);
2508 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
2509 insn.fixups[insn.nfixups].exp.X_op = O_absent;
2510 insn.nfixups++;
2511 insn.sequence = lituse;
2514 emit_insn (&insn);
2518 /* Store an integer to an unaligned address. */
2520 static void
2521 emit_ustX (const expressionS *tok,
2522 int ntok,
2523 const void * vlgsize)
2525 int lgsize = (int) (long) vlgsize;
2526 expressionS newtok[3];
2528 /* Emit "lda $at, exp". */
2529 memcpy (newtok, tok, sizeof (expressionS) * ntok);
2530 newtok[0].X_add_number = AXP_REG_AT;
2531 assemble_tokens ("lda", newtok, ntok, 1);
2533 /* Emit "ldq_u $9, 0($at)". */
2534 set_tok_reg (newtok[0], AXP_REG_T9);
2535 set_tok_const (newtok[1], 0);
2536 set_tok_preg (newtok[2], AXP_REG_AT);
2537 assemble_tokens ("ldq_u", newtok, 3, 1);
2539 /* Emit "ldq_u $10, size-1($at)". */
2540 set_tok_reg (newtok[0], AXP_REG_T10);
2541 set_tok_const (newtok[1], (1 << lgsize) - 1);
2542 assemble_tokens ("ldq_u", newtok, 3, 1);
2544 /* Emit "insXl src, $at, $t11". */
2545 newtok[0] = tok[0];
2546 set_tok_reg (newtok[1], AXP_REG_AT);
2547 set_tok_reg (newtok[2], AXP_REG_T11);
2548 assemble_tokens (insXl_op[lgsize], newtok, 3, 1);
2550 /* Emit "insXh src, $at, $t12". */
2551 set_tok_reg (newtok[2], AXP_REG_T12);
2552 assemble_tokens (insXh_op[lgsize], newtok, 3, 1);
2554 /* Emit "mskXl $t9, $at, $t9". */
2555 set_tok_reg (newtok[0], AXP_REG_T9);
2556 newtok[2] = newtok[0];
2557 assemble_tokens (mskXl_op[lgsize], newtok, 3, 1);
2559 /* Emit "mskXh $t10, $at, $t10". */
2560 set_tok_reg (newtok[0], AXP_REG_T10);
2561 newtok[2] = newtok[0];
2562 assemble_tokens (mskXh_op[lgsize], newtok, 3, 1);
2564 /* Emit "or $t9, $t11, $t9". */
2565 set_tok_reg (newtok[0], AXP_REG_T9);
2566 set_tok_reg (newtok[1], AXP_REG_T11);
2567 newtok[2] = newtok[0];
2568 assemble_tokens ("or", newtok, 3, 1);
2570 /* Emit "or $t10, $t12, $t10". */
2571 set_tok_reg (newtok[0], AXP_REG_T10);
2572 set_tok_reg (newtok[1], AXP_REG_T12);
2573 newtok[2] = newtok[0];
2574 assemble_tokens ("or", newtok, 3, 1);
2576 /* Emit "stq_u $t10, size-1($at)". */
2577 set_tok_reg (newtok[0], AXP_REG_T10);
2578 set_tok_const (newtok[1], (1 << lgsize) - 1);
2579 set_tok_preg (newtok[2], AXP_REG_AT);
2580 assemble_tokens ("stq_u", newtok, 3, 1);
2582 /* Emit "stq_u $t9, 0($at)". */
2583 set_tok_reg (newtok[0], AXP_REG_T9);
2584 set_tok_const (newtok[1], 0);
2585 assemble_tokens ("stq_u", newtok, 3, 1);
2588 /* Sign extend a half-word or byte. The 32-bit sign extend is
2589 implemented as "addl $31, $r, $t" in the opcode table. */
2591 static void
2592 emit_sextX (const expressionS *tok,
2593 int ntok,
2594 const void * vlgsize)
2596 long lgsize = (long) vlgsize;
2598 if (alpha_target & AXP_OPCODE_BWX)
2599 assemble_tokens (sextX_op[lgsize], tok, ntok, 0);
2600 else
2602 int bitshift = 64 - 8 * (1 << lgsize);
2603 expressionS newtok[3];
2605 /* Emit "sll src,bits,dst". */
2606 newtok[0] = tok[0];
2607 set_tok_const (newtok[1], bitshift);
2608 newtok[2] = tok[ntok - 1];
2609 assemble_tokens ("sll", newtok, 3, 1);
2611 /* Emit "sra dst,bits,dst". */
2612 newtok[0] = newtok[2];
2613 assemble_tokens ("sra", newtok, 3, 1);
2617 /* Implement the division and modulus macros. */
2619 #ifdef OBJ_EVAX
2621 /* Make register usage like in normal procedure call.
2622 Don't clobber PV and RA. */
2624 static void
2625 emit_division (const expressionS *tok,
2626 int ntok,
2627 const void * symname)
2629 /* DIVISION and MODULUS. Yech.
2631 Convert
2632 OP x,y,result
2634 mov x,R16 # if x != R16
2635 mov y,R17 # if y != R17
2636 lda AT,__OP
2637 jsr AT,(AT),0
2638 mov R0,result
2640 with appropriate optimizations if R0,R16,R17 are the registers
2641 specified by the compiler. */
2643 int xr, yr, rr;
2644 symbolS *sym;
2645 expressionS newtok[3];
2647 xr = regno (tok[0].X_add_number);
2648 yr = regno (tok[1].X_add_number);
2650 if (ntok < 3)
2651 rr = xr;
2652 else
2653 rr = regno (tok[2].X_add_number);
2655 /* Move the operands into the right place. */
2656 if (yr == AXP_REG_R16 && xr == AXP_REG_R17)
2658 /* They are in exactly the wrong order -- swap through AT. */
2659 if (alpha_noat_on)
2660 as_bad (_("macro requires $at register while noat in effect"));
2662 set_tok_reg (newtok[0], AXP_REG_R16);
2663 set_tok_reg (newtok[1], AXP_REG_AT);
2664 assemble_tokens ("mov", newtok, 2, 1);
2666 set_tok_reg (newtok[0], AXP_REG_R17);
2667 set_tok_reg (newtok[1], AXP_REG_R16);
2668 assemble_tokens ("mov", newtok, 2, 1);
2670 set_tok_reg (newtok[0], AXP_REG_AT);
2671 set_tok_reg (newtok[1], AXP_REG_R17);
2672 assemble_tokens ("mov", newtok, 2, 1);
2674 else
2676 if (yr == AXP_REG_R16)
2678 set_tok_reg (newtok[0], AXP_REG_R16);
2679 set_tok_reg (newtok[1], AXP_REG_R17);
2680 assemble_tokens ("mov", newtok, 2, 1);
2683 if (xr != AXP_REG_R16)
2685 set_tok_reg (newtok[0], xr);
2686 set_tok_reg (newtok[1], AXP_REG_R16);
2687 assemble_tokens ("mov", newtok, 2, 1);
2690 if (yr != AXP_REG_R16 && yr != AXP_REG_R17)
2692 set_tok_reg (newtok[0], yr);
2693 set_tok_reg (newtok[1], AXP_REG_R17);
2694 assemble_tokens ("mov", newtok, 2, 1);
2698 sym = symbol_find_or_make ((const char *) symname);
2700 set_tok_reg (newtok[0], AXP_REG_AT);
2701 set_tok_sym (newtok[1], sym, 0);
2702 assemble_tokens ("lda", newtok, 2, 1);
2704 /* Call the division routine. */
2705 set_tok_reg (newtok[0], AXP_REG_AT);
2706 set_tok_cpreg (newtok[1], AXP_REG_AT);
2707 set_tok_const (newtok[2], 0);
2708 assemble_tokens ("jsr", newtok, 3, 1);
2710 /* Move the result to the right place. */
2711 if (rr != AXP_REG_R0)
2713 set_tok_reg (newtok[0], AXP_REG_R0);
2714 set_tok_reg (newtok[1], rr);
2715 assemble_tokens ("mov", newtok, 2, 1);
2719 #else /* !OBJ_EVAX */
2721 static void
2722 emit_division (const expressionS *tok,
2723 int ntok,
2724 const void * symname)
2726 /* DIVISION and MODULUS. Yech.
2727 Convert
2728 OP x,y,result
2730 lda pv,__OP
2731 mov x,t10
2732 mov y,t11
2733 jsr t9,(pv),__OP
2734 mov t12,result
2736 with appropriate optimizations if t10,t11,t12 are the registers
2737 specified by the compiler. */
2739 int xr, yr, rr;
2740 symbolS *sym;
2741 expressionS newtok[3];
2743 xr = regno (tok[0].X_add_number);
2744 yr = regno (tok[1].X_add_number);
2746 if (ntok < 3)
2747 rr = xr;
2748 else
2749 rr = regno (tok[2].X_add_number);
2751 sym = symbol_find_or_make ((const char *) symname);
2753 /* Move the operands into the right place. */
2754 if (yr == AXP_REG_T10 && xr == AXP_REG_T11)
2756 /* They are in exactly the wrong order -- swap through AT. */
2757 if (alpha_noat_on)
2758 as_bad (_("macro requires $at register while noat in effect"));
2760 set_tok_reg (newtok[0], AXP_REG_T10);
2761 set_tok_reg (newtok[1], AXP_REG_AT);
2762 assemble_tokens ("mov", newtok, 2, 1);
2764 set_tok_reg (newtok[0], AXP_REG_T11);
2765 set_tok_reg (newtok[1], AXP_REG_T10);
2766 assemble_tokens ("mov", newtok, 2, 1);
2768 set_tok_reg (newtok[0], AXP_REG_AT);
2769 set_tok_reg (newtok[1], AXP_REG_T11);
2770 assemble_tokens ("mov", newtok, 2, 1);
2772 else
2774 if (yr == AXP_REG_T10)
2776 set_tok_reg (newtok[0], AXP_REG_T10);
2777 set_tok_reg (newtok[1], AXP_REG_T11);
2778 assemble_tokens ("mov", newtok, 2, 1);
2781 if (xr != AXP_REG_T10)
2783 set_tok_reg (newtok[0], xr);
2784 set_tok_reg (newtok[1], AXP_REG_T10);
2785 assemble_tokens ("mov", newtok, 2, 1);
2788 if (yr != AXP_REG_T10 && yr != AXP_REG_T11)
2790 set_tok_reg (newtok[0], yr);
2791 set_tok_reg (newtok[1], AXP_REG_T11);
2792 assemble_tokens ("mov", newtok, 2, 1);
2796 /* Call the division routine. */
2797 set_tok_reg (newtok[0], AXP_REG_T9);
2798 set_tok_sym (newtok[1], sym, 0);
2799 assemble_tokens ("jsr", newtok, 2, 1);
2801 /* Reload the GP register. */
2802 #ifdef OBJ_AOUT
2803 FIXME
2804 #endif
2805 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
2806 set_tok_reg (newtok[0], alpha_gp_register);
2807 set_tok_const (newtok[1], 0);
2808 set_tok_preg (newtok[2], AXP_REG_T9);
2809 assemble_tokens ("ldgp", newtok, 3, 1);
2810 #endif
2812 /* Move the result to the right place. */
2813 if (rr != AXP_REG_T12)
2815 set_tok_reg (newtok[0], AXP_REG_T12);
2816 set_tok_reg (newtok[1], rr);
2817 assemble_tokens ("mov", newtok, 2, 1);
2821 #endif /* !OBJ_EVAX */
2823 /* The jsr and jmp macros differ from their instruction counterparts
2824 in that they can load the target address and default most
2825 everything. */
2827 static void
2828 emit_jsrjmp (const expressionS *tok,
2829 int ntok,
2830 const void * vopname)
2832 const char *opname = (const char *) vopname;
2833 struct alpha_insn insn;
2834 expressionS newtok[3];
2835 int r, tokidx = 0;
2836 long lituse = 0;
2838 if (tokidx < ntok && tok[tokidx].X_op == O_register)
2839 r = regno (tok[tokidx++].X_add_number);
2840 else
2841 r = strcmp (opname, "jmp") == 0 ? AXP_REG_ZERO : AXP_REG_RA;
2843 set_tok_reg (newtok[0], r);
2845 if (tokidx < ntok &&
2846 (tok[tokidx].X_op == O_pregister || tok[tokidx].X_op == O_cpregister))
2847 r = regno (tok[tokidx++].X_add_number);
2848 #ifdef OBJ_EVAX
2849 /* Keep register if jsr $n.<sym>. */
2850 #else
2851 else
2853 int basereg = alpha_gp_register;
2854 lituse = load_expression (r = AXP_REG_PV, &tok[tokidx],
2855 &basereg, NULL, opname);
2857 #endif
2859 set_tok_cpreg (newtok[1], r);
2861 #ifndef OBJ_EVAX
2862 if (tokidx < ntok)
2863 newtok[2] = tok[tokidx];
2864 else
2865 #endif
2866 set_tok_const (newtok[2], 0);
2868 assemble_tokens_to_insn (opname, newtok, 3, &insn);
2870 if (lituse)
2872 gas_assert (insn.nfixups < MAX_INSN_FIXUPS);
2873 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_JSR;
2874 insn.fixups[insn.nfixups].exp.X_op = O_absent;
2875 insn.nfixups++;
2876 insn.sequence = lituse;
2879 #ifdef OBJ_EVAX
2880 if (alpha_flag_replace
2881 && r == AXP_REG_RA
2882 && tok[tokidx].X_add_symbol
2883 && alpha_linkage_symbol)
2885 /* Create a BOH reloc for 'jsr $27,NAME'. */
2886 const char *symname = S_GET_NAME (tok[tokidx].X_add_symbol);
2887 int symlen = strlen (symname);
2888 char *ensymname;
2890 /* Build the entry name as 'NAME..en'. */
2891 ensymname = (char *) xmalloc (symlen + 5);
2892 memcpy (ensymname, symname, symlen);
2893 memcpy (ensymname + symlen, "..en", 5);
2895 gas_assert (insn.nfixups < MAX_INSN_FIXUPS);
2896 if (insn.nfixups > 0)
2898 memmove (&insn.fixups[1], &insn.fixups[0],
2899 sizeof(struct alpha_fixup) * insn.nfixups);
2902 /* The fixup must be the same as the BFD_RELOC_ALPHA_NOP
2903 case in load_expression. See B.4.5.2 of the OpenVMS
2904 Linker Utility Manual. */
2905 insn.fixups[0].reloc = BFD_RELOC_ALPHA_BOH;
2906 insn.fixups[0].exp.X_op = O_symbol;
2907 insn.fixups[0].exp.X_add_symbol = symbol_find_or_make (ensymname);
2908 insn.fixups[0].exp.X_add_number = 0;
2909 insn.fixups[0].xtrasym = alpha_linkage_symbol;
2910 insn.fixups[0].procsym = alpha_evax_proc->symbol;
2911 insn.nfixups++;
2912 alpha_linkage_symbol = 0;
2914 #endif
2916 emit_insn (&insn);
2919 /* The ret and jcr instructions differ from their instruction
2920 counterparts in that everything can be defaulted. */
2922 static void
2923 emit_retjcr (const expressionS *tok,
2924 int ntok,
2925 const void * vopname)
2927 const char *opname = (const char *) vopname;
2928 expressionS newtok[3];
2929 int r, tokidx = 0;
2931 if (tokidx < ntok && tok[tokidx].X_op == O_register)
2932 r = regno (tok[tokidx++].X_add_number);
2933 else
2934 r = AXP_REG_ZERO;
2936 set_tok_reg (newtok[0], r);
2938 if (tokidx < ntok &&
2939 (tok[tokidx].X_op == O_pregister || tok[tokidx].X_op == O_cpregister))
2940 r = regno (tok[tokidx++].X_add_number);
2941 else
2942 r = AXP_REG_RA;
2944 set_tok_cpreg (newtok[1], r);
2946 if (tokidx < ntok)
2947 newtok[2] = tok[tokidx];
2948 else
2949 set_tok_const (newtok[2], strcmp (opname, "ret") == 0);
2951 assemble_tokens (opname, newtok, 3, 0);
2954 /* Implement the ldgp macro. */
2956 static void
2957 emit_ldgp (const expressionS *tok,
2958 int ntok ATTRIBUTE_UNUSED,
2959 const void * unused ATTRIBUTE_UNUSED)
2961 #ifdef OBJ_AOUT
2962 FIXME
2963 #endif
2964 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
2965 /* from "ldgp r1,n(r2)", generate "ldah r1,X(R2); lda r1,Y(r1)"
2966 with appropriate constants and relocations. */
2967 struct alpha_insn insn;
2968 expressionS newtok[3];
2969 expressionS addend;
2971 #ifdef OBJ_ECOFF
2972 if (regno (tok[2].X_add_number) == AXP_REG_PV)
2973 ecoff_set_gp_prolog_size (0);
2974 #endif
2976 newtok[0] = tok[0];
2977 set_tok_const (newtok[1], 0);
2978 newtok[2] = tok[2];
2980 assemble_tokens_to_insn ("ldah", newtok, 3, &insn);
2982 addend = tok[1];
2984 #ifdef OBJ_ECOFF
2985 if (addend.X_op != O_constant)
2986 as_bad (_("can not resolve expression"));
2987 addend.X_op = O_symbol;
2988 addend.X_add_symbol = alpha_gp_symbol;
2989 #endif
2991 insn.nfixups = 1;
2992 insn.fixups[0].exp = addend;
2993 insn.fixups[0].reloc = BFD_RELOC_ALPHA_GPDISP_HI16;
2994 insn.sequence = next_sequence_num;
2996 emit_insn (&insn);
2998 set_tok_preg (newtok[2], tok[0].X_add_number);
3000 assemble_tokens_to_insn ("lda", newtok, 3, &insn);
3002 #ifdef OBJ_ECOFF
3003 addend.X_add_number += 4;
3004 #endif
3006 insn.nfixups = 1;
3007 insn.fixups[0].exp = addend;
3008 insn.fixups[0].reloc = BFD_RELOC_ALPHA_GPDISP_LO16;
3009 insn.sequence = next_sequence_num--;
3011 emit_insn (&insn);
3012 #else /* OBJ_ECOFF || OBJ_ELF */
3013 /* Avoid warning. */
3014 tok = NULL;
3015 #endif
3018 /* The macro table. */
3020 static const struct alpha_macro alpha_macros[] =
3022 /* Load/Store macros. */
3023 { "lda", emit_lda, NULL,
3024 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3025 { "ldah", emit_ldah, NULL,
3026 { MACRO_IR, MACRO_EXP, MACRO_EOA } },
3028 { "ldl", emit_ir_load, "ldl",
3029 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3030 { "ldl_l", emit_ir_load, "ldl_l",
3031 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3032 { "ldq", emit_ir_load, "ldq",
3033 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3034 { "ldq_l", emit_ir_load, "ldq_l",
3035 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3036 { "ldq_u", emit_ir_load, "ldq_u",
3037 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3038 { "ldf", emit_loadstore, "ldf",
3039 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3040 { "ldg", emit_loadstore, "ldg",
3041 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3042 { "lds", emit_loadstore, "lds",
3043 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3044 { "ldt", emit_loadstore, "ldt",
3045 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3047 { "ldb", emit_ldX, (void *) 0,
3048 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3049 { "ldbu", emit_ldXu, (void *) 0,
3050 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3051 { "ldw", emit_ldX, (void *) 1,
3052 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3053 { "ldwu", emit_ldXu, (void *) 1,
3054 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3056 { "uldw", emit_uldX, (void *) 1,
3057 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3058 { "uldwu", emit_uldXu, (void *) 1,
3059 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3060 { "uldl", emit_uldX, (void *) 2,
3061 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3062 { "uldlu", emit_uldXu, (void *) 2,
3063 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3064 { "uldq", emit_uldXu, (void *) 3,
3065 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3067 { "ldgp", emit_ldgp, NULL,
3068 { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA } },
3070 { "ldi", emit_lda, NULL,
3071 { MACRO_IR, MACRO_EXP, MACRO_EOA } },
3072 { "ldil", emit_ldil, NULL,
3073 { MACRO_IR, MACRO_EXP, MACRO_EOA } },
3074 { "ldiq", emit_lda, NULL,
3075 { MACRO_IR, MACRO_EXP, MACRO_EOA } },
3077 { "stl", emit_loadstore, "stl",
3078 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3079 { "stl_c", emit_loadstore, "stl_c",
3080 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3081 { "stq", emit_loadstore, "stq",
3082 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3083 { "stq_c", emit_loadstore, "stq_c",
3084 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3085 { "stq_u", emit_loadstore, "stq_u",
3086 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3087 { "stf", emit_loadstore, "stf",
3088 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3089 { "stg", emit_loadstore, "stg",
3090 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3091 { "sts", emit_loadstore, "sts",
3092 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3093 { "stt", emit_loadstore, "stt",
3094 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3096 { "stb", emit_stX, (void *) 0,
3097 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3098 { "stw", emit_stX, (void *) 1,
3099 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3100 { "ustw", emit_ustX, (void *) 1,
3101 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3102 { "ustl", emit_ustX, (void *) 2,
3103 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3104 { "ustq", emit_ustX, (void *) 3,
3105 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
3107 /* Arithmetic macros. */
3109 { "sextb", emit_sextX, (void *) 0,
3110 { MACRO_IR, MACRO_IR, MACRO_EOA,
3111 MACRO_IR, MACRO_EOA,
3112 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
3113 { "sextw", emit_sextX, (void *) 1,
3114 { MACRO_IR, MACRO_IR, MACRO_EOA,
3115 MACRO_IR, MACRO_EOA,
3116 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
3118 { "divl", emit_division, "__divl",
3119 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
3120 MACRO_IR, MACRO_IR, MACRO_EOA,
3121 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
3122 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
3123 { "divlu", emit_division, "__divlu",
3124 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
3125 MACRO_IR, MACRO_IR, MACRO_EOA,
3126 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
3127 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
3128 { "divq", emit_division, "__divq",
3129 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
3130 MACRO_IR, MACRO_IR, MACRO_EOA,
3131 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
3132 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
3133 { "divqu", emit_division, "__divqu",
3134 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
3135 MACRO_IR, MACRO_IR, MACRO_EOA,
3136 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
3137 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
3138 { "reml", emit_division, "__reml",
3139 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
3140 MACRO_IR, MACRO_IR, MACRO_EOA,
3141 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
3142 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
3143 { "remlu", emit_division, "__remlu",
3144 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
3145 MACRO_IR, MACRO_IR, MACRO_EOA,
3146 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
3147 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
3148 { "remq", emit_division, "__remq",
3149 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
3150 MACRO_IR, MACRO_IR, MACRO_EOA,
3151 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
3152 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
3153 { "remqu", emit_division, "__remqu",
3154 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
3155 MACRO_IR, MACRO_IR, MACRO_EOA,
3156 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
3157 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
3159 { "jsr", emit_jsrjmp, "jsr",
3160 { MACRO_PIR, MACRO_EXP, MACRO_EOA,
3161 MACRO_PIR, MACRO_EOA,
3162 MACRO_IR, MACRO_EXP, MACRO_EOA,
3163 MACRO_EXP, MACRO_EOA } },
3164 { "jmp", emit_jsrjmp, "jmp",
3165 { MACRO_PIR, MACRO_EXP, MACRO_EOA,
3166 MACRO_PIR, MACRO_EOA,
3167 MACRO_IR, MACRO_EXP, MACRO_EOA,
3168 MACRO_EXP, MACRO_EOA } },
3169 { "ret", emit_retjcr, "ret",
3170 { MACRO_IR, MACRO_EXP, MACRO_EOA,
3171 MACRO_IR, MACRO_EOA,
3172 MACRO_PIR, MACRO_EXP, MACRO_EOA,
3173 MACRO_PIR, MACRO_EOA,
3174 MACRO_EXP, MACRO_EOA,
3175 MACRO_EOA } },
3176 { "jcr", emit_retjcr, "jcr",
3177 { MACRO_IR, MACRO_EXP, MACRO_EOA,
3178 MACRO_IR, MACRO_EOA,
3179 MACRO_PIR, MACRO_EXP, MACRO_EOA,
3180 MACRO_PIR, MACRO_EOA,
3181 MACRO_EXP, MACRO_EOA,
3182 MACRO_EOA } },
3183 { "jsr_coroutine", emit_retjcr, "jcr",
3184 { MACRO_IR, MACRO_EXP, MACRO_EOA,
3185 MACRO_IR, MACRO_EOA,
3186 MACRO_PIR, MACRO_EXP, MACRO_EOA,
3187 MACRO_PIR, MACRO_EOA,
3188 MACRO_EXP, MACRO_EOA,
3189 MACRO_EOA } },
3192 static const unsigned int alpha_num_macros
3193 = sizeof (alpha_macros) / sizeof (*alpha_macros);
3195 /* Search forward through all variants of a macro looking for a syntax
3196 match. */
3198 static const struct alpha_macro *
3199 find_macro_match (const struct alpha_macro *first_macro,
3200 const expressionS *tok,
3201 int *pntok)
3204 const struct alpha_macro *macro = first_macro;
3205 int ntok = *pntok;
3209 const enum alpha_macro_arg *arg = macro->argsets;
3210 int tokidx = 0;
3212 while (*arg)
3214 switch (*arg)
3216 case MACRO_EOA:
3217 if (tokidx == ntok)
3218 return macro;
3219 else
3220 tokidx = 0;
3221 break;
3223 /* Index register. */
3224 case MACRO_IR:
3225 if (tokidx >= ntok || tok[tokidx].X_op != O_register
3226 || !is_ir_num (tok[tokidx].X_add_number))
3227 goto match_failed;
3228 ++tokidx;
3229 break;
3231 /* Parenthesized index register. */
3232 case MACRO_PIR:
3233 if (tokidx >= ntok || tok[tokidx].X_op != O_pregister
3234 || !is_ir_num (tok[tokidx].X_add_number))
3235 goto match_failed;
3236 ++tokidx;
3237 break;
3239 /* Optional parenthesized index register. */
3240 case MACRO_OPIR:
3241 if (tokidx < ntok && tok[tokidx].X_op == O_pregister
3242 && is_ir_num (tok[tokidx].X_add_number))
3243 ++tokidx;
3244 break;
3246 /* Leading comma with a parenthesized index register. */
3247 case MACRO_CPIR:
3248 if (tokidx >= ntok || tok[tokidx].X_op != O_cpregister
3249 || !is_ir_num (tok[tokidx].X_add_number))
3250 goto match_failed;
3251 ++tokidx;
3252 break;
3254 /* Floating point register. */
3255 case MACRO_FPR:
3256 if (tokidx >= ntok || tok[tokidx].X_op != O_register
3257 || !is_fpr_num (tok[tokidx].X_add_number))
3258 goto match_failed;
3259 ++tokidx;
3260 break;
3262 /* Normal expression. */
3263 case MACRO_EXP:
3264 if (tokidx >= ntok)
3265 goto match_failed;
3266 switch (tok[tokidx].X_op)
3268 case O_illegal:
3269 case O_absent:
3270 case O_register:
3271 case O_pregister:
3272 case O_cpregister:
3273 case O_literal:
3274 case O_lituse_base:
3275 case O_lituse_bytoff:
3276 case O_lituse_jsr:
3277 case O_gpdisp:
3278 case O_gprelhigh:
3279 case O_gprellow:
3280 case O_gprel:
3281 case O_samegp:
3282 goto match_failed;
3284 default:
3285 break;
3287 ++tokidx;
3288 break;
3290 match_failed:
3291 while (*arg != MACRO_EOA)
3292 ++arg;
3293 tokidx = 0;
3294 break;
3296 ++arg;
3299 while (++macro - alpha_macros < (int) alpha_num_macros
3300 && !strcmp (macro->name, first_macro->name));
3302 return NULL;
3305 /* Given an opcode name and a pre-tokenized set of arguments, take the
3306 opcode all the way through emission. */
3308 static void
3309 assemble_tokens (const char *opname,
3310 const expressionS *tok,
3311 int ntok,
3312 int local_macros_on)
3314 int found_something = 0;
3315 const struct alpha_opcode *opcode;
3316 const struct alpha_macro *macro;
3317 int cpumatch = 1;
3318 extended_bfd_reloc_code_real_type reloc = BFD_RELOC_UNUSED;
3320 #ifdef RELOC_OP_P
3321 /* If a user-specified relocation is present, this is not a macro. */
3322 if (ntok && USER_RELOC_P (tok[ntok - 1].X_op))
3324 reloc = ALPHA_RELOC_TABLE (tok[ntok - 1].X_op)->reloc;
3325 ntok--;
3327 else
3328 #endif
3329 if (local_macros_on)
3331 macro = ((const struct alpha_macro *)
3332 hash_find (alpha_macro_hash, opname));
3333 if (macro)
3335 found_something = 1;
3336 macro = find_macro_match (macro, tok, &ntok);
3337 if (macro)
3339 (*macro->emit) (tok, ntok, macro->arg);
3340 return;
3345 /* Search opcodes. */
3346 opcode = (const struct alpha_opcode *) hash_find (alpha_opcode_hash, opname);
3347 if (opcode)
3349 found_something = 1;
3350 opcode = find_opcode_match (opcode, tok, &ntok, &cpumatch);
3351 if (opcode)
3353 struct alpha_insn insn;
3354 assemble_insn (opcode, tok, ntok, &insn, reloc);
3356 /* Copy the sequence number for the reloc from the reloc token. */
3357 if (reloc != BFD_RELOC_UNUSED)
3358 insn.sequence = tok[ntok].X_add_number;
3360 emit_insn (&insn);
3361 return;
3365 if (found_something)
3367 if (cpumatch)
3368 as_bad (_("inappropriate arguments for opcode `%s'"), opname);
3369 else
3370 as_bad (_("opcode `%s' not supported for target %s"), opname,
3371 alpha_target_name);
3373 else
3374 as_bad (_("unknown opcode `%s'"), opname);
3377 #ifdef OBJ_EVAX
3379 /* Add symbol+addend to link pool.
3380 Return offset from basesym to entry in link pool.
3382 Add new fixup only if offset isn't 16bit. */
3384 static symbolS *
3385 add_to_link_pool (symbolS *basesym,
3386 symbolS *sym,
3387 offsetT addend)
3389 segT current_section = now_seg;
3390 int current_subsec = now_subseg;
3391 valueT offset;
3392 char *p;
3393 segment_info_type *seginfo = seg_info (alpha_link_section);
3394 fixS *fixp;
3395 symbolS *linksym, *expsym;
3396 expressionS e;
3398 offset = 0; /* ??? DBR */
3400 /* @@ This assumes all entries in a given section will be of the same
3401 size... Probably correct, but unwise to rely on. */
3402 /* This must always be called with the same subsegment. */
3404 if (seginfo->frchainP)
3405 for (fixp = seginfo->frchainP->fix_root;
3406 fixp != (fixS *) NULL;
3407 fixp = fixp->fx_next)
3409 if (fixp->tc_fix_data.info
3410 && fixp->tc_fix_data.info->sym
3411 && fixp->tc_fix_data.info->sym->sy_value.X_op_symbol == basesym)
3412 offset += 8;
3414 if (fixp->fx_addsy == sym
3415 && fixp->fx_offset == (valueT)addend
3416 && fixp->tc_fix_data.info
3417 && fixp->tc_fix_data.info->sym
3418 && fixp->tc_fix_data.info->sym->sy_value.X_op_symbol == basesym)
3419 return fixp->tc_fix_data.info->sym;
3422 /* Not found in 16bit signed range. */
3424 subseg_set (alpha_link_section, 0);
3425 linksym = symbol_new
3426 (FAKE_LABEL_NAME, now_seg, (valueT) frag_now_fix (), frag_now);
3427 p = frag_more (8);
3428 memset (p, 0, 8);
3430 e.X_op = O_subtract;
3431 e.X_add_symbol = linksym;
3432 e.X_op_symbol = basesym;
3433 e.X_add_number = 0;
3434 expsym = make_expr_symbol (&e);
3436 fixp = fix_new
3437 (frag_now, p-frag_now->fr_literal, 8, sym, addend, 0, BFD_RELOC_64);
3438 fixp->tc_fix_data.info = get_alpha_reloc_tag (next_sequence_num--);
3439 fixp->tc_fix_data.info->sym = expsym;
3441 subseg_set (current_section, current_subsec);
3442 seginfo->literal_pool_size += 8;
3443 return expsym;
3445 #endif /* OBJ_EVAX */
3447 /* Assembler directives. */
3449 /* Handle the .text pseudo-op. This is like the usual one, but it
3450 clears alpha_insn_label and restores auto alignment. */
3452 static void
3453 s_alpha_text (int i)
3455 #ifdef OBJ_ELF
3456 obj_elf_text (i);
3457 #else
3458 s_text (i);
3459 #endif
3460 #ifdef OBJ_EVAX
3462 symbolS * symbolP;
3464 symbolP = symbol_find (".text");
3465 if (symbolP == NULL)
3467 symbolP = symbol_make (".text");
3468 S_SET_SEGMENT (symbolP, text_section);
3469 symbol_table_insert (symbolP);
3472 #endif
3473 alpha_insn_label = NULL;
3474 alpha_auto_align_on = 1;
3475 alpha_current_align = 0;
3478 /* Handle the .data pseudo-op. This is like the usual one, but it
3479 clears alpha_insn_label and restores auto alignment. */
3481 static void
3482 s_alpha_data (int i)
3484 #ifdef OBJ_ELF
3485 obj_elf_data (i);
3486 #else
3487 s_data (i);
3488 #endif
3489 alpha_insn_label = NULL;
3490 alpha_auto_align_on = 1;
3491 alpha_current_align = 0;
3494 #if defined (OBJ_ECOFF) || defined (OBJ_EVAX)
3496 /* Handle the OSF/1 and openVMS .comm pseudo quirks. */
3498 static void
3499 s_alpha_comm (int ignore ATTRIBUTE_UNUSED)
3501 char *name;
3502 char c;
3503 char *p;
3504 offsetT size;
3505 symbolS *symbolP;
3506 #ifdef OBJ_EVAX
3507 offsetT temp;
3508 int log_align = 0;
3509 #endif
3511 name = input_line_pointer;
3512 c = get_symbol_end ();
3514 /* Just after name is now '\0'. */
3515 p = input_line_pointer;
3516 *p = c;
3518 SKIP_WHITESPACE ();
3520 /* Alpha OSF/1 compiler doesn't provide the comma, gcc does. */
3521 if (*input_line_pointer == ',')
3523 input_line_pointer++;
3524 SKIP_WHITESPACE ();
3526 if ((size = get_absolute_expression ()) < 0)
3528 as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) size);
3529 ignore_rest_of_line ();
3530 return;
3533 *p = 0;
3534 symbolP = symbol_find_or_make (name);
3535 *p = c;
3537 if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
3539 as_bad (_("Ignoring attempt to re-define symbol"));
3540 ignore_rest_of_line ();
3541 return;
3544 #ifdef OBJ_EVAX
3545 if (*input_line_pointer != ',')
3546 temp = 8; /* Default alignment. */
3547 else
3549 input_line_pointer++;
3550 SKIP_WHITESPACE ();
3551 temp = get_absolute_expression ();
3554 /* ??? Unlike on OSF/1, the alignment factor is not in log units. */
3555 while ((temp >>= 1) != 0)
3556 ++log_align;
3558 if (*input_line_pointer == ',')
3560 /* Extended form of the directive
3562 .comm symbol, size, alignment, section
3564 where the "common" semantics is transferred to the section.
3565 The symbol is effectively an alias for the section name. */
3567 segT sec;
3568 char *sec_name;
3569 symbolS *sec_symbol;
3570 segT current_seg = now_seg;
3571 subsegT current_subseg = now_subseg;
3572 int cur_size;
3574 input_line_pointer++;
3575 SKIP_WHITESPACE ();
3576 sec_name = s_alpha_section_name ();
3577 sec_symbol = symbol_find_or_make (sec_name);
3578 sec = subseg_new (sec_name, 0);
3579 S_SET_SEGMENT (sec_symbol, sec);
3580 symbol_get_bfdsym (sec_symbol)->flags |= BSF_SECTION_SYM;
3581 bfd_vms_set_section_flags (stdoutput, sec, 0,
3582 EGPS__V_OVR | EGPS__V_GBL | EGPS__V_NOMOD);
3583 record_alignment (sec, log_align);
3585 /* Reuse stab_string_size to store the size of the section. */
3586 cur_size = seg_info (sec)->stabu.stab_string_size;
3587 if ((int) size > cur_size)
3589 char *pfrag
3590 = frag_var (rs_fill, 1, 1, (relax_substateT)0, NULL,
3591 (valueT)size - (valueT)cur_size, NULL);
3592 *pfrag = 0;
3593 seg_info (sec)->stabu.stab_string_size = (int)size;
3596 S_SET_SEGMENT (symbolP, sec);
3598 subseg_set (current_seg, current_subseg);
3600 else
3602 /* Regular form of the directive
3604 .comm symbol, size, alignment
3606 where the "common" semantics in on the symbol.
3607 These symbols are assembled in the .bss section. */
3609 char *pfrag;
3610 segT current_seg = now_seg;
3611 subsegT current_subseg = now_subseg;
3613 subseg_set (bss_section, 1);
3614 frag_align (log_align, 0, 0);
3615 record_alignment (bss_section, log_align);
3617 symbolP->sy_frag = frag_now;
3618 pfrag = frag_var (rs_org, 1, 1, (relax_substateT)0, symbolP,
3619 size, NULL);
3620 *pfrag = 0;
3622 S_SET_SEGMENT (symbolP, bss_section);
3624 subseg_set (current_seg, current_subseg);
3626 #endif
3628 if (S_GET_VALUE (symbolP))
3630 if (S_GET_VALUE (symbolP) != (valueT) size)
3631 as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
3632 S_GET_NAME (symbolP),
3633 (long) S_GET_VALUE (symbolP),
3634 (long) size);
3636 else
3638 #ifndef OBJ_EVAX
3639 S_SET_VALUE (symbolP, (valueT) size);
3640 #endif
3641 S_SET_EXTERNAL (symbolP);
3644 #ifndef OBJ_EVAX
3645 know (symbolP->sy_frag == &zero_address_frag);
3646 #endif
3647 demand_empty_rest_of_line ();
3650 #endif /* ! OBJ_ELF */
3652 #ifdef OBJ_ECOFF
3654 /* Handle the .rdata pseudo-op. This is like the usual one, but it
3655 clears alpha_insn_label and restores auto alignment. */
3657 static void
3658 s_alpha_rdata (int ignore ATTRIBUTE_UNUSED)
3660 int temp;
3662 temp = get_absolute_expression ();
3663 subseg_new (".rdata", 0);
3664 demand_empty_rest_of_line ();
3665 alpha_insn_label = NULL;
3666 alpha_auto_align_on = 1;
3667 alpha_current_align = 0;
3670 #endif
3672 #ifdef OBJ_ECOFF
3674 /* Handle the .sdata pseudo-op. This is like the usual one, but it
3675 clears alpha_insn_label and restores auto alignment. */
3677 static void
3678 s_alpha_sdata (int ignore ATTRIBUTE_UNUSED)
3680 int temp;
3682 temp = get_absolute_expression ();
3683 subseg_new (".sdata", 0);
3684 demand_empty_rest_of_line ();
3685 alpha_insn_label = NULL;
3686 alpha_auto_align_on = 1;
3687 alpha_current_align = 0;
3689 #endif
3691 #ifdef OBJ_ELF
3692 struct alpha_elf_frame_data
3694 symbolS *func_sym;
3695 symbolS *func_end_sym;
3696 symbolS *prologue_sym;
3697 unsigned int mask;
3698 unsigned int fmask;
3699 int fp_regno;
3700 int ra_regno;
3701 offsetT frame_size;
3702 offsetT mask_offset;
3703 offsetT fmask_offset;
3705 struct alpha_elf_frame_data *next;
3708 static struct alpha_elf_frame_data *all_frame_data;
3709 static struct alpha_elf_frame_data **plast_frame_data = &all_frame_data;
3710 static struct alpha_elf_frame_data *cur_frame_data;
3712 /* Handle the .section pseudo-op. This is like the usual one, but it
3713 clears alpha_insn_label and restores auto alignment. */
3715 static void
3716 s_alpha_section (int ignore ATTRIBUTE_UNUSED)
3718 obj_elf_section (ignore);
3720 alpha_insn_label = NULL;
3721 alpha_auto_align_on = 1;
3722 alpha_current_align = 0;
3725 static void
3726 s_alpha_ent (int dummy ATTRIBUTE_UNUSED)
3728 if (ECOFF_DEBUGGING)
3729 ecoff_directive_ent (0);
3730 else
3732 char *name, name_end;
3733 name = input_line_pointer;
3734 name_end = get_symbol_end ();
3736 if (! is_name_beginner (*name))
3738 as_warn (_(".ent directive has no name"));
3739 *input_line_pointer = name_end;
3741 else
3743 symbolS *sym;
3745 if (cur_frame_data)
3746 as_warn (_("nested .ent directives"));
3748 sym = symbol_find_or_make (name);
3749 symbol_get_bfdsym (sym)->flags |= BSF_FUNCTION;
3751 cur_frame_data = (struct alpha_elf_frame_data *)
3752 calloc (1, sizeof (*cur_frame_data));
3753 cur_frame_data->func_sym = sym;
3755 /* Provide sensible defaults. */
3756 cur_frame_data->fp_regno = 30; /* sp */
3757 cur_frame_data->ra_regno = 26; /* ra */
3759 *plast_frame_data = cur_frame_data;
3760 plast_frame_data = &cur_frame_data->next;
3762 /* The .ent directive is sometimes followed by a number. Not sure
3763 what it really means, but ignore it. */
3764 *input_line_pointer = name_end;
3765 SKIP_WHITESPACE ();
3766 if (*input_line_pointer == ',')
3768 input_line_pointer++;
3769 SKIP_WHITESPACE ();
3771 if (ISDIGIT (*input_line_pointer) || *input_line_pointer == '-')
3772 (void) get_absolute_expression ();
3774 demand_empty_rest_of_line ();
3778 static void
3779 s_alpha_end (int dummy ATTRIBUTE_UNUSED)
3781 if (ECOFF_DEBUGGING)
3782 ecoff_directive_end (0);
3783 else
3785 char *name, name_end;
3786 name = input_line_pointer;
3787 name_end = get_symbol_end ();
3789 if (! is_name_beginner (*name))
3791 as_warn (_(".end directive has no name"));
3792 *input_line_pointer = name_end;
3794 else
3796 symbolS *sym;
3798 sym = symbol_find (name);
3799 if (!cur_frame_data)
3800 as_warn (_(".end directive without matching .ent"));
3801 else if (sym != cur_frame_data->func_sym)
3802 as_warn (_(".end directive names different symbol than .ent"));
3804 /* Create an expression to calculate the size of the function. */
3805 if (sym && cur_frame_data)
3807 OBJ_SYMFIELD_TYPE *obj = symbol_get_obj (sym);
3808 expressionS *exp = (expressionS *) xmalloc (sizeof (expressionS));
3810 obj->size = exp;
3811 exp->X_op = O_subtract;
3812 exp->X_add_symbol = symbol_temp_new_now ();
3813 exp->X_op_symbol = sym;
3814 exp->X_add_number = 0;
3816 cur_frame_data->func_end_sym = exp->X_add_symbol;
3819 cur_frame_data = NULL;
3821 *input_line_pointer = name_end;
3823 demand_empty_rest_of_line ();
3827 static void
3828 s_alpha_mask (int fp)
3830 if (ECOFF_DEBUGGING)
3832 if (fp)
3833 ecoff_directive_fmask (0);
3834 else
3835 ecoff_directive_mask (0);
3837 else
3839 long val;
3840 offsetT offset;
3842 if (!cur_frame_data)
3844 if (fp)
3845 as_warn (_(".fmask outside of .ent"));
3846 else
3847 as_warn (_(".mask outside of .ent"));
3848 discard_rest_of_line ();
3849 return;
3852 if (get_absolute_expression_and_terminator (&val) != ',')
3854 if (fp)
3855 as_warn (_("bad .fmask directive"));
3856 else
3857 as_warn (_("bad .mask directive"));
3858 --input_line_pointer;
3859 discard_rest_of_line ();
3860 return;
3863 offset = get_absolute_expression ();
3864 demand_empty_rest_of_line ();
3866 if (fp)
3868 cur_frame_data->fmask = val;
3869 cur_frame_data->fmask_offset = offset;
3871 else
3873 cur_frame_data->mask = val;
3874 cur_frame_data->mask_offset = offset;
3879 static void
3880 s_alpha_frame (int dummy ATTRIBUTE_UNUSED)
3882 if (ECOFF_DEBUGGING)
3883 ecoff_directive_frame (0);
3884 else
3886 long val;
3888 if (!cur_frame_data)
3890 as_warn (_(".frame outside of .ent"));
3891 discard_rest_of_line ();
3892 return;
3895 cur_frame_data->fp_regno = tc_get_register (1);
3897 SKIP_WHITESPACE ();
3898 if (*input_line_pointer++ != ','
3899 || get_absolute_expression_and_terminator (&val) != ',')
3901 as_warn (_("bad .frame directive"));
3902 --input_line_pointer;
3903 discard_rest_of_line ();
3904 return;
3906 cur_frame_data->frame_size = val;
3908 cur_frame_data->ra_regno = tc_get_register (0);
3910 /* Next comes the "offset of saved $a0 from $sp". In gcc terms
3911 this is current_function_pretend_args_size. There's no place
3912 to put this value, so ignore it. */
3913 s_ignore (42);
3917 static void
3918 s_alpha_prologue (int ignore ATTRIBUTE_UNUSED)
3920 symbolS *sym;
3921 int arg;
3923 arg = get_absolute_expression ();
3924 demand_empty_rest_of_line ();
3925 alpha_prologue_label = symbol_new
3926 (FAKE_LABEL_NAME, now_seg, (valueT) frag_now_fix (), frag_now);
3928 if (ECOFF_DEBUGGING)
3929 sym = ecoff_get_cur_proc_sym ();
3930 else
3931 sym = cur_frame_data ? cur_frame_data->func_sym : NULL;
3933 if (sym == NULL)
3935 as_bad (_(".prologue directive without a preceding .ent directive"));
3936 return;
3939 switch (arg)
3941 case 0: /* No PV required. */
3942 S_SET_OTHER (sym, STO_ALPHA_NOPV
3943 | (S_GET_OTHER (sym) & ~STO_ALPHA_STD_GPLOAD));
3944 break;
3945 case 1: /* Std GP load. */
3946 S_SET_OTHER (sym, STO_ALPHA_STD_GPLOAD
3947 | (S_GET_OTHER (sym) & ~STO_ALPHA_STD_GPLOAD));
3948 break;
3949 case 2: /* Non-std use of PV. */
3950 break;
3952 default:
3953 as_bad (_("Invalid argument %d to .prologue."), arg);
3954 break;
3957 if (cur_frame_data)
3958 cur_frame_data->prologue_sym = symbol_temp_new_now ();
3961 static char *first_file_directive;
3963 static void
3964 s_alpha_file (int ignore ATTRIBUTE_UNUSED)
3966 /* Save the first .file directive we see, so that we can change our
3967 minds about whether ecoff debugging should or shouldn't be enabled. */
3968 if (alpha_flag_mdebug < 0 && ! first_file_directive)
3970 char *start = input_line_pointer;
3971 size_t len;
3973 discard_rest_of_line ();
3975 len = input_line_pointer - start;
3976 first_file_directive = (char *) xmalloc (len + 1);
3977 memcpy (first_file_directive, start, len);
3978 first_file_directive[len] = '\0';
3980 input_line_pointer = start;
3983 if (ECOFF_DEBUGGING)
3984 ecoff_directive_file (0);
3985 else
3986 dwarf2_directive_file (0);
3989 static void
3990 s_alpha_loc (int ignore ATTRIBUTE_UNUSED)
3992 if (ECOFF_DEBUGGING)
3993 ecoff_directive_loc (0);
3994 else
3995 dwarf2_directive_loc (0);
3998 static void
3999 s_alpha_stab (int n)
4001 /* If we've been undecided about mdebug, make up our minds in favour. */
4002 if (alpha_flag_mdebug < 0)
4004 segT sec = subseg_new (".mdebug", 0);
4005 bfd_set_section_flags (stdoutput, sec, SEC_HAS_CONTENTS | SEC_READONLY);
4006 bfd_set_section_alignment (stdoutput, sec, 3);
4008 ecoff_read_begin_hook ();
4010 if (first_file_directive)
4012 char *save_ilp = input_line_pointer;
4013 input_line_pointer = first_file_directive;
4014 ecoff_directive_file (0);
4015 input_line_pointer = save_ilp;
4016 free (first_file_directive);
4019 alpha_flag_mdebug = 1;
4021 s_stab (n);
4024 static void
4025 s_alpha_coff_wrapper (int which)
4027 static void (* const fns[]) (int) = {
4028 ecoff_directive_begin,
4029 ecoff_directive_bend,
4030 ecoff_directive_def,
4031 ecoff_directive_dim,
4032 ecoff_directive_endef,
4033 ecoff_directive_scl,
4034 ecoff_directive_tag,
4035 ecoff_directive_val,
4038 gas_assert (which >= 0 && which < (int) (sizeof (fns)/sizeof (*fns)));
4040 if (ECOFF_DEBUGGING)
4041 (*fns[which]) (0);
4042 else
4044 as_bad (_("ECOFF debugging is disabled."));
4045 ignore_rest_of_line ();
4049 /* Called at the end of assembly. Here we emit unwind info for frames
4050 unless the compiler has done it for us. */
4052 void
4053 alpha_elf_md_end (void)
4055 struct alpha_elf_frame_data *p;
4057 if (cur_frame_data)
4058 as_warn (_(".ent directive without matching .end"));
4060 /* If someone has generated the unwind info themselves, great. */
4061 if (bfd_get_section_by_name (stdoutput, ".eh_frame") != NULL)
4062 return;
4064 /* Generate .eh_frame data for the unwind directives specified. */
4065 for (p = all_frame_data; p ; p = p->next)
4066 if (p->prologue_sym)
4068 /* Create a temporary symbol at the same location as our
4069 function symbol. This prevents problems with globals. */
4070 cfi_new_fde (symbol_temp_new (S_GET_SEGMENT (p->func_sym),
4071 S_GET_VALUE (p->func_sym),
4072 symbol_get_frag (p->func_sym)));
4074 cfi_set_return_column (p->ra_regno);
4075 cfi_add_CFA_def_cfa_register (30);
4076 if (p->fp_regno != 30 || p->mask || p->fmask || p->frame_size)
4078 unsigned int mask;
4079 offsetT offset;
4081 cfi_add_advance_loc (p->prologue_sym);
4083 if (p->fp_regno != 30)
4084 if (p->frame_size != 0)
4085 cfi_add_CFA_def_cfa (p->fp_regno, p->frame_size);
4086 else
4087 cfi_add_CFA_def_cfa_register (p->fp_regno);
4088 else if (p->frame_size != 0)
4089 cfi_add_CFA_def_cfa_offset (p->frame_size);
4091 mask = p->mask;
4092 offset = p->mask_offset;
4094 /* Recall that $26 is special-cased and stored first. */
4095 if ((mask >> 26) & 1)
4097 cfi_add_CFA_offset (26, offset);
4098 offset += 8;
4099 mask &= ~(1 << 26);
4101 while (mask)
4103 unsigned int i;
4104 i = mask & -mask;
4105 mask ^= i;
4106 i = ffs (i) - 1;
4108 cfi_add_CFA_offset (i, offset);
4109 offset += 8;
4112 mask = p->fmask;
4113 offset = p->fmask_offset;
4114 while (mask)
4116 unsigned int i;
4117 i = mask & -mask;
4118 mask ^= i;
4119 i = ffs (i) - 1;
4121 cfi_add_CFA_offset (i + 32, offset);
4122 offset += 8;
4126 cfi_end_fde (p->func_end_sym);
4130 static void
4131 s_alpha_usepv (int unused ATTRIBUTE_UNUSED)
4133 char *name, name_end;
4134 char *which, which_end;
4135 symbolS *sym;
4136 int other;
4138 name = input_line_pointer;
4139 name_end = get_symbol_end ();
4141 if (! is_name_beginner (*name))
4143 as_bad (_(".usepv directive has no name"));
4144 *input_line_pointer = name_end;
4145 ignore_rest_of_line ();
4146 return;
4149 sym = symbol_find_or_make (name);
4150 *input_line_pointer++ = name_end;
4152 if (name_end != ',')
4154 as_bad (_(".usepv directive has no type"));
4155 ignore_rest_of_line ();
4156 return;
4159 SKIP_WHITESPACE ();
4160 which = input_line_pointer;
4161 which_end = get_symbol_end ();
4163 if (strcmp (which, "no") == 0)
4164 other = STO_ALPHA_NOPV;
4165 else if (strcmp (which, "std") == 0)
4166 other = STO_ALPHA_STD_GPLOAD;
4167 else
4169 as_bad (_("unknown argument for .usepv"));
4170 other = 0;
4173 *input_line_pointer = which_end;
4174 demand_empty_rest_of_line ();
4176 S_SET_OTHER (sym, other | (S_GET_OTHER (sym) & ~STO_ALPHA_STD_GPLOAD));
4178 #endif /* OBJ_ELF */
4180 /* Standard calling conventions leaves the CFA at $30 on entry. */
4182 void
4183 alpha_cfi_frame_initial_instructions (void)
4185 cfi_add_CFA_def_cfa_register (30);
4188 #ifdef OBJ_EVAX
4190 /* Get name of section. */
4191 static char *
4192 s_alpha_section_name (void)
4194 char *name;
4196 SKIP_WHITESPACE ();
4197 if (*input_line_pointer == '"')
4199 int dummy;
4201 name = demand_copy_C_string (&dummy);
4202 if (name == NULL)
4204 ignore_rest_of_line ();
4205 return NULL;
4208 else
4210 char *end = input_line_pointer;
4212 while (0 == strchr ("\n\t,; ", *end))
4213 end++;
4214 if (end == input_line_pointer)
4216 as_warn (_("missing name"));
4217 ignore_rest_of_line ();
4218 return NULL;
4221 name = xmalloc (end - input_line_pointer + 1);
4222 memcpy (name, input_line_pointer, end - input_line_pointer);
4223 name[end - input_line_pointer] = '\0';
4224 input_line_pointer = end;
4226 SKIP_WHITESPACE ();
4227 return name;
4230 /* Put clear/set flags in one flagword. The LSBs are flags to be set,
4231 the MSBs are the flags to be cleared. */
4233 #define EGPS__V_NO_SHIFT 16
4234 #define EGPS__V_MASK 0xffff
4236 /* Parse one VMS section flag. */
4238 static flagword
4239 s_alpha_section_word (char *str, size_t len)
4241 int no = 0;
4242 flagword flag = 0;
4244 if (len == 5 && strncmp (str, "NO", 2) == 0)
4246 no = 1;
4247 str += 2;
4248 len -= 2;
4251 if (len == 3)
4253 if (strncmp (str, "PIC", 3) == 0)
4254 flag = EGPS__V_PIC;
4255 else if (strncmp (str, "LIB", 3) == 0)
4256 flag = EGPS__V_LIB;
4257 else if (strncmp (str, "OVR", 3) == 0)
4258 flag = EGPS__V_OVR;
4259 else if (strncmp (str, "REL", 3) == 0)
4260 flag = EGPS__V_REL;
4261 else if (strncmp (str, "GBL", 3) == 0)
4262 flag = EGPS__V_GBL;
4263 else if (strncmp (str, "SHR", 3) == 0)
4264 flag = EGPS__V_SHR;
4265 else if (strncmp (str, "EXE", 3) == 0)
4266 flag = EGPS__V_EXE;
4267 else if (strncmp (str, "WRT", 3) == 0)
4268 flag = EGPS__V_WRT;
4269 else if (strncmp (str, "VEC", 3) == 0)
4270 flag = EGPS__V_VEC;
4271 else if (strncmp (str, "MOD", 3) == 0)
4273 flag = no ? EGPS__V_NOMOD : EGPS__V_NOMOD << EGPS__V_NO_SHIFT;
4274 no = 0;
4276 else if (strncmp (str, "COM", 3) == 0)
4277 flag = EGPS__V_COM;
4280 if (flag == 0)
4282 char c = str[len];
4283 str[len] = 0;
4284 as_warn (_("unknown section attribute %s"), str);
4285 str[len] = c;
4286 return 0;
4289 if (no)
4290 return flag << EGPS__V_NO_SHIFT;
4291 else
4292 return flag;
4295 /* Handle the section specific pseudo-op. */
4297 #define EVAX_SECTION_COUNT 5
4299 static char *section_name[EVAX_SECTION_COUNT + 1] =
4300 { "NULL", ".rdata", ".comm", ".link", ".ctors", ".dtors" };
4302 static void
4303 s_alpha_section (int secid)
4305 int temp;
4306 char *name, *beg;
4307 segT sec;
4308 flagword vms_flags = 0;
4309 symbolS *symbol;
4311 if (secid == 0)
4313 name = s_alpha_section_name ();
4314 if (name == NULL)
4315 return;
4316 sec = subseg_new (name, 0);
4317 if (*input_line_pointer == ',')
4319 /* Skip the comma. */
4320 ++input_line_pointer;
4321 SKIP_WHITESPACE ();
4325 char c;
4327 SKIP_WHITESPACE ();
4328 beg = input_line_pointer;
4329 c = get_symbol_end ();
4330 *input_line_pointer = c;
4332 vms_flags |= s_alpha_section_word (beg, input_line_pointer - beg);
4334 SKIP_WHITESPACE ();
4336 while (*input_line_pointer++ == ',');
4337 --input_line_pointer;
4340 symbol = symbol_find_or_make (name);
4341 S_SET_SEGMENT (symbol, sec);
4342 symbol_get_bfdsym (symbol)->flags |= BSF_SECTION_SYM;
4343 bfd_vms_set_section_flags
4344 (stdoutput, sec,
4345 (vms_flags >> EGPS__V_NO_SHIFT) & EGPS__V_MASK,
4346 vms_flags & EGPS__V_MASK);
4348 else
4350 temp = get_absolute_expression ();
4351 subseg_new (section_name[secid], 0);
4354 demand_empty_rest_of_line ();
4355 alpha_insn_label = NULL;
4356 alpha_auto_align_on = 1;
4357 alpha_current_align = 0;
4360 static void
4361 s_alpha_literals (int ignore ATTRIBUTE_UNUSED)
4363 subseg_new (".literals", 0);
4364 demand_empty_rest_of_line ();
4365 alpha_insn_label = NULL;
4366 alpha_auto_align_on = 1;
4367 alpha_current_align = 0;
4370 /* Parse .ent directives. */
4372 static void
4373 s_alpha_ent (int ignore ATTRIBUTE_UNUSED)
4375 symbolS *symbol;
4376 expressionS symexpr;
4378 alpha_evax_proc
4379 = (struct alpha_evax_procs *) xmalloc (sizeof (struct alpha_evax_procs));
4381 alpha_evax_proc->pdsckind = 0;
4382 alpha_evax_proc->framereg = -1;
4383 alpha_evax_proc->framesize = 0;
4384 alpha_evax_proc->rsa_offset = 0;
4385 alpha_evax_proc->ra_save = AXP_REG_RA;
4386 alpha_evax_proc->fp_save = -1;
4387 alpha_evax_proc->imask = 0;
4388 alpha_evax_proc->fmask = 0;
4389 alpha_evax_proc->prologue = 0;
4390 alpha_evax_proc->type = 0;
4391 alpha_evax_proc->handler = 0;
4392 alpha_evax_proc->handler_data = 0;
4394 expression (&symexpr);
4396 if (symexpr.X_op != O_symbol)
4398 as_fatal (_(".ent directive has no symbol"));
4399 demand_empty_rest_of_line ();
4400 return;
4403 symbol = make_expr_symbol (&symexpr);
4404 symbol_get_bfdsym (symbol)->flags |= BSF_FUNCTION;
4405 alpha_evax_proc->symbol = symbol;
4407 (void) hash_insert
4408 (alpha_evax_proc_hash,
4409 symbol_get_bfdsym (alpha_evax_proc->symbol)->name, (PTR)alpha_evax_proc);
4411 demand_empty_rest_of_line ();
4414 static void
4415 s_alpha_handler (int is_data)
4417 if (is_data)
4418 alpha_evax_proc->handler_data = get_absolute_expression ();
4419 else
4421 char *name, name_end;
4422 name = input_line_pointer;
4423 name_end = get_symbol_end ();
4425 if (! is_name_beginner (*name))
4427 as_warn (_(".handler directive has no name"));
4428 *input_line_pointer = name_end;
4430 else
4432 symbolS *sym;
4434 sym = symbol_find_or_make (name);
4435 symbol_get_bfdsym (sym)->flags |= BSF_FUNCTION;
4436 alpha_evax_proc->handler = sym;
4437 *input_line_pointer = name_end;
4440 demand_empty_rest_of_line ();
4443 /* Parse .frame <framreg>,<framesize>,RA,<rsa_offset> directives. */
4445 static void
4446 s_alpha_frame (int ignore ATTRIBUTE_UNUSED)
4448 long val;
4450 alpha_evax_proc->framereg = tc_get_register (1);
4452 SKIP_WHITESPACE ();
4453 if (*input_line_pointer++ != ','
4454 || get_absolute_expression_and_terminator (&val) != ',')
4456 as_warn (_("Bad .frame directive 1./2. param"));
4457 --input_line_pointer;
4458 demand_empty_rest_of_line ();
4459 return;
4462 alpha_evax_proc->framesize = val;
4464 (void) tc_get_register (1);
4465 SKIP_WHITESPACE ();
4466 if (*input_line_pointer++ != ',')
4468 as_warn (_("Bad .frame directive 3./4. param"));
4469 --input_line_pointer;
4470 demand_empty_rest_of_line ();
4471 return;
4473 alpha_evax_proc->rsa_offset = get_absolute_expression ();
4476 /* Parse .prologue. */
4478 static void
4479 s_alpha_prologue (int ignore ATTRIBUTE_UNUSED)
4481 int arg;
4483 arg = get_absolute_expression ();
4484 demand_empty_rest_of_line ();
4485 alpha_prologue_label = symbol_new
4486 (FAKE_LABEL_NAME, now_seg, (valueT) frag_now_fix (), frag_now);
4489 /* Parse .pdesc <entry_name>.
4490 Insert a procedure descriptor. */
4492 static void
4493 s_alpha_pdesc (int ignore ATTRIBUTE_UNUSED)
4495 char *name;
4496 char name_end;
4497 register char *p;
4498 expressionS exp;
4499 symbolS *entry_sym;
4500 fixS *fixp;
4501 segment_info_type *seginfo = seg_info (alpha_link_section);
4502 const char *entry_sym_name;
4503 char *sym_name;
4504 int len;
4506 if (now_seg != alpha_link_section)
4508 as_bad (_(".pdesc directive not in link (.link) section"));
4509 demand_empty_rest_of_line ();
4510 return;
4513 expression (&exp);
4514 if (exp.X_op != O_symbol)
4516 as_warn (_(".pdesc directive has no entry symbol"));
4517 demand_empty_rest_of_line ();
4518 return;
4521 entry_sym = make_expr_symbol (&exp);
4522 entry_sym_name = symbol_get_bfdsym (entry_sym)->name;
4524 len = strlen (entry_sym_name);
4525 sym_name = (char *) xmalloc (len - 4 + 1);
4526 strncpy (sym_name, entry_sym_name, len - 4);
4527 sym_name [len - 4] = 0;
4529 alpha_evax_proc = (struct alpha_evax_procs *)
4530 hash_find (alpha_evax_proc_hash, sym_name);
4532 if (!alpha_evax_proc || !S_IS_DEFINED (alpha_evax_proc->symbol))
4534 as_fatal (_(".pdesc has no matching .ent"));
4535 demand_empty_rest_of_line ();
4536 return;
4539 *symbol_get_obj (alpha_evax_proc->symbol) =
4540 (valueT) seginfo->literal_pool_size;
4542 alpha_evax_proc->symbol->sy_obj = (valueT)seginfo->literal_pool_size;
4544 /* Save bfd symbol of proc entry in function symbol. */
4545 ((struct evax_private_udata_struct *)
4546 symbol_get_bfdsym (alpha_evax_proc->symbol)->udata.p)->enbsym
4547 = symbol_get_bfdsym (entry_sym);
4549 SKIP_WHITESPACE ();
4550 if (*input_line_pointer++ != ',')
4552 as_warn (_("No comma after .pdesc <entryname>"));
4553 demand_empty_rest_of_line ();
4554 return;
4557 SKIP_WHITESPACE ();
4558 name = input_line_pointer;
4559 name_end = get_symbol_end ();
4561 if (strncmp (name, "stack", 5) == 0)
4562 alpha_evax_proc->pdsckind = PDSC_S_K_KIND_FP_STACK;
4564 else if (strncmp (name, "reg", 3) == 0)
4565 alpha_evax_proc->pdsckind = PDSC_S_K_KIND_FP_REGISTER;
4567 else if (strncmp (name, "null", 4) == 0)
4568 alpha_evax_proc->pdsckind = PDSC_S_K_KIND_NULL;
4570 else
4572 as_fatal (_("unknown procedure kind"));
4573 demand_empty_rest_of_line ();
4574 return;
4577 *input_line_pointer = name_end;
4578 demand_empty_rest_of_line ();
4580 #ifdef md_flush_pending_output
4581 md_flush_pending_output ();
4582 #endif
4584 frag_align (3, 0, 0);
4585 p = frag_more (16);
4586 fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
4587 fixp->fx_done = 1;
4588 seginfo->literal_pool_size += 16;
4590 *p = alpha_evax_proc->pdsckind
4591 | ((alpha_evax_proc->framereg == 29) ? PDSC_S_M_BASE_REG_IS_FP : 0)
4592 | ((alpha_evax_proc->handler) ? PDSC_S_M_HANDLER_VALID : 0)
4593 | ((alpha_evax_proc->handler_data) ? PDSC_S_M_HANDLER_DATA_VALID : 0);
4594 *(p + 1) = PDSC_S_M_NATIVE | PDSC_S_M_NO_JACKET;
4596 switch (alpha_evax_proc->pdsckind)
4598 case PDSC_S_K_KIND_NULL:
4599 *(p + 2) = 0;
4600 *(p + 3) = 0;
4601 break;
4602 case PDSC_S_K_KIND_FP_REGISTER:
4603 *(p + 2) = alpha_evax_proc->fp_save;
4604 *(p + 3) = alpha_evax_proc->ra_save;
4605 break;
4606 case PDSC_S_K_KIND_FP_STACK:
4607 md_number_to_chars (p + 2, (valueT) alpha_evax_proc->rsa_offset, 2);
4608 break;
4609 default: /* impossible */
4610 break;
4613 *(p + 4) = 0;
4614 *(p + 5) = alpha_evax_proc->type & 0x0f;
4616 /* Signature offset. */
4617 md_number_to_chars (p + 6, (valueT) 0, 2);
4619 fix_new_exp (frag_now, p - frag_now->fr_literal+8, 8, &exp, 0, BFD_RELOC_64);
4621 if (alpha_evax_proc->pdsckind == PDSC_S_K_KIND_NULL)
4622 return;
4624 /* Add dummy fix to make add_to_link_pool work. */
4625 p = frag_more (6);
4626 fixp = fix_new (frag_now, p - frag_now->fr_literal, 6, 0, 0, 0, 0);
4627 fixp->fx_done = 1;
4628 seginfo->literal_pool_size += 6;
4630 /* pdesc+16: Size. */
4631 md_number_to_chars (p, (valueT) alpha_evax_proc->framesize, 4);
4633 md_number_to_chars (p + 4, (valueT) 0, 2);
4635 /* Entry length. */
4636 exp.X_op = O_subtract;
4637 exp.X_add_symbol = alpha_prologue_label;
4638 exp.X_op_symbol = entry_sym;
4639 emit_expr (&exp, 2);
4641 if (alpha_evax_proc->pdsckind == PDSC_S_K_KIND_FP_REGISTER)
4642 return;
4644 /* Add dummy fix to make add_to_link_pool work. */
4645 p = frag_more (8);
4646 fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
4647 fixp->fx_done = 1;
4648 seginfo->literal_pool_size += 8;
4650 /* pdesc+24: register masks. */
4652 md_number_to_chars (p, alpha_evax_proc->imask, 4);
4653 md_number_to_chars (p + 4, alpha_evax_proc->fmask, 4);
4655 if (alpha_evax_proc->handler)
4657 p = frag_more (8);
4658 fixp = fix_new (frag_now, p - frag_now->fr_literal, 8,
4659 alpha_evax_proc->handler, 0, 0, BFD_RELOC_64);
4662 if (alpha_evax_proc->handler_data)
4664 /* Add dummy fix to make add_to_link_pool work. */
4665 p = frag_more (8);
4666 fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
4667 fixp->fx_done = 1;
4668 seginfo->literal_pool_size += 8;
4669 md_number_to_chars (p, alpha_evax_proc->handler_data, 8);
4673 /* Support for crash debug on vms. */
4675 static void
4676 s_alpha_name (int ignore ATTRIBUTE_UNUSED)
4678 char *p;
4679 expressionS exp;
4680 segment_info_type *seginfo = seg_info (alpha_link_section);
4682 if (now_seg != alpha_link_section)
4684 as_bad (_(".name directive not in link (.link) section"));
4685 demand_empty_rest_of_line ();
4686 return;
4689 expression (&exp);
4690 if (exp.X_op != O_symbol)
4692 as_warn (_(".name directive has no symbol"));
4693 demand_empty_rest_of_line ();
4694 return;
4697 demand_empty_rest_of_line ();
4699 #ifdef md_flush_pending_output
4700 md_flush_pending_output ();
4701 #endif
4703 frag_align (3, 0, 0);
4704 p = frag_more (8);
4705 seginfo->literal_pool_size += 8;
4707 fix_new_exp (frag_now, p - frag_now->fr_literal, 8, &exp, 0, BFD_RELOC_64);
4710 /* Parse .linkage <symbol>.
4711 Create a linkage pair relocation. */
4713 static void
4714 s_alpha_linkage (int ignore ATTRIBUTE_UNUSED)
4716 expressionS exp;
4717 char *p;
4718 fixS *fixp;
4720 #ifdef md_flush_pending_output
4721 md_flush_pending_output ();
4722 #endif
4724 expression (&exp);
4725 if (exp.X_op != O_symbol)
4727 as_fatal (_("No symbol after .linkage"));
4729 else
4731 struct alpha_linkage_fixups *linkage_fixup;
4733 p = frag_more (LKP_S_K_SIZE);
4734 memset (p, 0, LKP_S_K_SIZE);
4735 fixp = fix_new_exp
4736 (frag_now, p - frag_now->fr_literal, LKP_S_K_SIZE, &exp, 0,\
4737 BFD_RELOC_ALPHA_LINKAGE);
4739 linkage_fixup = (struct alpha_linkage_fixups *)
4740 xmalloc (sizeof (struct alpha_linkage_fixups));
4742 linkage_fixup->fixp = fixp;
4743 linkage_fixup->next = 0;
4745 if (alpha_insn_label == 0)
4746 alpha_insn_label = symbol_new
4747 (FAKE_LABEL_NAME, now_seg, (valueT) frag_now_fix (), frag_now);
4748 linkage_fixup->label = alpha_insn_label;
4750 if (alpha_linkage_fixup_root == 0)
4752 alpha_linkage_fixup_root = alpha_linkage_fixup_tail = linkage_fixup;
4753 alpha_linkage_fixup_tail->next = 0;
4755 else
4757 alpha_linkage_fixup_tail->next = linkage_fixup;
4758 alpha_linkage_fixup_tail = linkage_fixup;
4759 alpha_linkage_fixup_tail->next = 0;
4762 demand_empty_rest_of_line ();
4765 /* Parse .code_address <symbol>.
4766 Create a code address relocation. */
4768 static void
4769 s_alpha_code_address (int ignore ATTRIBUTE_UNUSED)
4771 expressionS exp;
4772 char *p;
4774 #ifdef md_flush_pending_output
4775 md_flush_pending_output ();
4776 #endif
4778 expression (&exp);
4779 if (exp.X_op != O_symbol)
4780 as_fatal (_("No symbol after .code_address"));
4781 else
4783 p = frag_more (8);
4784 memset (p, 0, 8);
4785 fix_new_exp (frag_now, p - frag_now->fr_literal, 8, &exp, 0,\
4786 BFD_RELOC_ALPHA_CODEADDR);
4788 demand_empty_rest_of_line ();
4791 static void
4792 s_alpha_fp_save (int ignore ATTRIBUTE_UNUSED)
4795 alpha_evax_proc->fp_save = tc_get_register (1);
4797 demand_empty_rest_of_line ();
4800 static void
4801 s_alpha_mask (int ignore ATTRIBUTE_UNUSED)
4803 long val;
4805 if (get_absolute_expression_and_terminator (&val) != ',')
4807 as_warn (_("Bad .mask directive"));
4808 --input_line_pointer;
4810 else
4812 alpha_evax_proc->imask = val;
4813 (void) get_absolute_expression ();
4815 demand_empty_rest_of_line ();
4818 static void
4819 s_alpha_fmask (int ignore ATTRIBUTE_UNUSED)
4821 long val;
4823 if (get_absolute_expression_and_terminator (&val) != ',')
4825 as_warn (_("Bad .fmask directive"));
4826 --input_line_pointer;
4828 else
4830 alpha_evax_proc->fmask = val;
4831 (void) get_absolute_expression ();
4833 demand_empty_rest_of_line ();
4836 static void
4837 s_alpha_end (int ignore ATTRIBUTE_UNUSED)
4839 char c;
4841 c = get_symbol_end ();
4842 *input_line_pointer = c;
4843 demand_empty_rest_of_line ();
4844 alpha_evax_proc = 0;
4847 static void
4848 s_alpha_file (int ignore ATTRIBUTE_UNUSED)
4850 symbolS *s;
4851 int length;
4852 static char case_hack[32];
4854 sprintf (case_hack, "<CASE:%01d%01d>",
4855 alpha_flag_hash_long_names, alpha_flag_show_after_trunc);
4857 s = symbol_find_or_make (case_hack);
4858 symbol_get_bfdsym (s)->flags |= BSF_FILE;
4860 get_absolute_expression ();
4861 s = symbol_find_or_make (demand_copy_string (&length));
4862 symbol_get_bfdsym (s)->flags |= BSF_FILE;
4863 demand_empty_rest_of_line ();
4865 #endif /* OBJ_EVAX */
4867 /* Handle the .gprel32 pseudo op. */
4869 static void
4870 s_alpha_gprel32 (int ignore ATTRIBUTE_UNUSED)
4872 expressionS e;
4873 char *p;
4875 SKIP_WHITESPACE ();
4876 expression (&e);
4878 #ifdef OBJ_ELF
4879 switch (e.X_op)
4881 case O_constant:
4882 e.X_add_symbol = section_symbol (absolute_section);
4883 e.X_op = O_symbol;
4884 /* FALLTHRU */
4885 case O_symbol:
4886 break;
4887 default:
4888 abort ();
4890 #else
4891 #ifdef OBJ_ECOFF
4892 switch (e.X_op)
4894 case O_constant:
4895 e.X_add_symbol = section_symbol (absolute_section);
4896 /* fall through */
4897 case O_symbol:
4898 e.X_op = O_subtract;
4899 e.X_op_symbol = alpha_gp_symbol;
4900 break;
4901 default:
4902 abort ();
4904 #endif
4905 #endif
4907 if (alpha_auto_align_on && alpha_current_align < 2)
4908 alpha_align (2, (char *) NULL, alpha_insn_label, 0);
4909 if (alpha_current_align > 2)
4910 alpha_current_align = 2;
4911 alpha_insn_label = NULL;
4913 p = frag_more (4);
4914 memset (p, 0, 4);
4915 fix_new_exp (frag_now, p - frag_now->fr_literal, 4,
4916 &e, 0, BFD_RELOC_GPREL32);
4919 /* Handle floating point allocation pseudo-ops. This is like the
4920 generic vresion, but it makes sure the current label, if any, is
4921 correctly aligned. */
4923 static void
4924 s_alpha_float_cons (int type)
4926 int log_size;
4928 switch (type)
4930 default:
4931 case 'f':
4932 case 'F':
4933 log_size = 2;
4934 break;
4936 case 'd':
4937 case 'D':
4938 case 'G':
4939 log_size = 3;
4940 break;
4942 case 'x':
4943 case 'X':
4944 case 'p':
4945 case 'P':
4946 log_size = 4;
4947 break;
4950 if (alpha_auto_align_on && alpha_current_align < log_size)
4951 alpha_align (log_size, (char *) NULL, alpha_insn_label, 0);
4952 if (alpha_current_align > log_size)
4953 alpha_current_align = log_size;
4954 alpha_insn_label = NULL;
4956 float_cons (type);
4959 /* Handle the .proc pseudo op. We don't really do much with it except
4960 parse it. */
4962 static void
4963 s_alpha_proc (int is_static ATTRIBUTE_UNUSED)
4965 char *name;
4966 char c;
4967 char *p;
4968 symbolS *symbolP;
4969 int temp;
4971 /* Takes ".proc name,nargs". */
4972 SKIP_WHITESPACE ();
4973 name = input_line_pointer;
4974 c = get_symbol_end ();
4975 p = input_line_pointer;
4976 symbolP = symbol_find_or_make (name);
4977 *p = c;
4978 SKIP_WHITESPACE ();
4979 if (*input_line_pointer != ',')
4981 *p = 0;
4982 as_warn (_("Expected comma after name \"%s\""), name);
4983 *p = c;
4984 temp = 0;
4985 ignore_rest_of_line ();
4987 else
4989 input_line_pointer++;
4990 temp = get_absolute_expression ();
4992 /* *symbol_get_obj (symbolP) = (signed char) temp; */
4993 as_warn (_("unhandled: .proc %s,%d"), name, temp);
4994 demand_empty_rest_of_line ();
4997 /* Handle the .set pseudo op. This is used to turn on and off most of
4998 the assembler features. */
5000 static void
5001 s_alpha_set (int x ATTRIBUTE_UNUSED)
5003 char *name, ch, *s;
5004 int yesno = 1;
5006 SKIP_WHITESPACE ();
5007 name = input_line_pointer;
5008 ch = get_symbol_end ();
5010 s = name;
5011 if (s[0] == 'n' && s[1] == 'o')
5013 yesno = 0;
5014 s += 2;
5016 if (!strcmp ("reorder", s))
5017 /* ignore */ ;
5018 else if (!strcmp ("at", s))
5019 alpha_noat_on = !yesno;
5020 else if (!strcmp ("macro", s))
5021 alpha_macros_on = yesno;
5022 else if (!strcmp ("move", s))
5023 /* ignore */ ;
5024 else if (!strcmp ("volatile", s))
5025 /* ignore */ ;
5026 else
5027 as_warn (_("Tried to .set unrecognized mode `%s'"), name);
5029 *input_line_pointer = ch;
5030 demand_empty_rest_of_line ();
5033 /* Handle the .base pseudo op. This changes the assembler's notion of
5034 the $gp register. */
5036 static void
5037 s_alpha_base (int ignore ATTRIBUTE_UNUSED)
5039 SKIP_WHITESPACE ();
5041 if (*input_line_pointer == '$')
5043 /* $rNN form. */
5044 input_line_pointer++;
5045 if (*input_line_pointer == 'r')
5046 input_line_pointer++;
5049 alpha_gp_register = get_absolute_expression ();
5050 if (alpha_gp_register < 0 || alpha_gp_register > 31)
5052 alpha_gp_register = AXP_REG_GP;
5053 as_warn (_("Bad base register, using $%d."), alpha_gp_register);
5056 demand_empty_rest_of_line ();
5059 /* Handle the .align pseudo-op. This aligns to a power of two. It
5060 also adjusts any current instruction label. We treat this the same
5061 way the MIPS port does: .align 0 turns off auto alignment. */
5063 static void
5064 s_alpha_align (int ignore ATTRIBUTE_UNUSED)
5066 int align;
5067 char fill, *pfill;
5068 long max_alignment = 16;
5070 align = get_absolute_expression ();
5071 if (align > max_alignment)
5073 align = max_alignment;
5074 as_bad (_("Alignment too large: %d. assumed"), align);
5076 else if (align < 0)
5078 as_warn (_("Alignment negative: 0 assumed"));
5079 align = 0;
5082 if (*input_line_pointer == ',')
5084 input_line_pointer++;
5085 fill = get_absolute_expression ();
5086 pfill = &fill;
5088 else
5089 pfill = NULL;
5091 if (align != 0)
5093 alpha_auto_align_on = 1;
5094 alpha_align (align, pfill, alpha_insn_label, 1);
5096 else
5098 alpha_auto_align_on = 0;
5101 demand_empty_rest_of_line ();
5104 /* Hook the normal string processor to reset known alignment. */
5106 static void
5107 s_alpha_stringer (int terminate)
5109 alpha_current_align = 0;
5110 alpha_insn_label = NULL;
5111 stringer (8 + terminate);
5114 /* Hook the normal space processing to reset known alignment. */
5116 static void
5117 s_alpha_space (int ignore)
5119 alpha_current_align = 0;
5120 alpha_insn_label = NULL;
5121 s_space (ignore);
5124 /* Hook into cons for auto-alignment. */
5126 void
5127 alpha_cons_align (int size)
5129 int log_size;
5131 log_size = 0;
5132 while ((size >>= 1) != 0)
5133 ++log_size;
5135 if (alpha_auto_align_on && alpha_current_align < log_size)
5136 alpha_align (log_size, (char *) NULL, alpha_insn_label, 0);
5137 if (alpha_current_align > log_size)
5138 alpha_current_align = log_size;
5139 alpha_insn_label = NULL;
5142 /* Here come the .uword, .ulong, and .uquad explicitly unaligned
5143 pseudos. We just turn off auto-alignment and call down to cons. */
5145 static void
5146 s_alpha_ucons (int bytes)
5148 int hold = alpha_auto_align_on;
5149 alpha_auto_align_on = 0;
5150 cons (bytes);
5151 alpha_auto_align_on = hold;
5154 /* Switch the working cpu type. */
5156 static void
5157 s_alpha_arch (int ignored ATTRIBUTE_UNUSED)
5159 char *name, ch;
5160 const struct cpu_type *p;
5162 SKIP_WHITESPACE ();
5163 name = input_line_pointer;
5164 ch = get_symbol_end ();
5166 for (p = cpu_types; p->name; ++p)
5167 if (strcmp (name, p->name) == 0)
5169 alpha_target_name = p->name, alpha_target = p->flags;
5170 goto found;
5172 as_warn (_("Unknown CPU identifier `%s'"), name);
5174 found:
5175 *input_line_pointer = ch;
5176 demand_empty_rest_of_line ();
5179 #ifdef DEBUG1
5180 /* print token expression with alpha specific extension. */
5182 static void
5183 alpha_print_token (FILE *f, const expressionS *exp)
5185 switch (exp->X_op)
5187 case O_cpregister:
5188 putc (',', f);
5189 /* FALLTHRU */
5190 case O_pregister:
5191 putc ('(', f);
5193 expressionS nexp = *exp;
5194 nexp.X_op = O_register;
5195 print_expr_1 (f, &nexp);
5197 putc (')', f);
5198 break;
5199 default:
5200 print_expr_1 (f, exp);
5201 break;
5204 #endif
5206 /* The target specific pseudo-ops which we support. */
5208 const pseudo_typeS md_pseudo_table[] =
5210 #ifdef OBJ_ECOFF
5211 {"comm", s_alpha_comm, 0}, /* OSF1 compiler does this. */
5212 {"rdata", s_alpha_rdata, 0},
5213 #endif
5214 {"text", s_alpha_text, 0},
5215 {"data", s_alpha_data, 0},
5216 #ifdef OBJ_ECOFF
5217 {"sdata", s_alpha_sdata, 0},
5218 #endif
5219 #ifdef OBJ_ELF
5220 {"section", s_alpha_section, 0},
5221 {"section.s", s_alpha_section, 0},
5222 {"sect", s_alpha_section, 0},
5223 {"sect.s", s_alpha_section, 0},
5224 #endif
5225 #ifdef OBJ_EVAX
5226 {"section", s_alpha_section, 0},
5227 {"literals", s_alpha_literals, 0},
5228 {"pdesc", s_alpha_pdesc, 0},
5229 {"name", s_alpha_name, 0},
5230 {"linkage", s_alpha_linkage, 0},
5231 {"code_address", s_alpha_code_address, 0},
5232 {"ent", s_alpha_ent, 0},
5233 {"frame", s_alpha_frame, 0},
5234 {"fp_save", s_alpha_fp_save, 0},
5235 {"mask", s_alpha_mask, 0},
5236 {"fmask", s_alpha_fmask, 0},
5237 {"end", s_alpha_end, 0},
5238 {"file", s_alpha_file, 0},
5239 {"rdata", s_alpha_section, 1},
5240 {"comm", s_alpha_comm, 0},
5241 {"link", s_alpha_section, 3},
5242 {"ctors", s_alpha_section, 4},
5243 {"dtors", s_alpha_section, 5},
5244 {"handler", s_alpha_handler, 0},
5245 {"handler_data", s_alpha_handler, 1},
5246 #endif
5247 #ifdef OBJ_ELF
5248 /* Frame related pseudos. */
5249 {"ent", s_alpha_ent, 0},
5250 {"end", s_alpha_end, 0},
5251 {"mask", s_alpha_mask, 0},
5252 {"fmask", s_alpha_mask, 1},
5253 {"frame", s_alpha_frame, 0},
5254 {"prologue", s_alpha_prologue, 0},
5255 {"file", s_alpha_file, 5},
5256 {"loc", s_alpha_loc, 9},
5257 {"stabs", s_alpha_stab, 's'},
5258 {"stabn", s_alpha_stab, 'n'},
5259 {"usepv", s_alpha_usepv, 0},
5260 /* COFF debugging related pseudos. */
5261 {"begin", s_alpha_coff_wrapper, 0},
5262 {"bend", s_alpha_coff_wrapper, 1},
5263 {"def", s_alpha_coff_wrapper, 2},
5264 {"dim", s_alpha_coff_wrapper, 3},
5265 {"endef", s_alpha_coff_wrapper, 4},
5266 {"scl", s_alpha_coff_wrapper, 5},
5267 {"tag", s_alpha_coff_wrapper, 6},
5268 {"val", s_alpha_coff_wrapper, 7},
5269 #else
5270 #ifdef OBJ_EVAX
5271 {"prologue", s_alpha_prologue, 0},
5272 #else
5273 {"prologue", s_ignore, 0},
5274 #endif
5275 #endif
5276 {"gprel32", s_alpha_gprel32, 0},
5277 {"t_floating", s_alpha_float_cons, 'd'},
5278 {"s_floating", s_alpha_float_cons, 'f'},
5279 {"f_floating", s_alpha_float_cons, 'F'},
5280 {"g_floating", s_alpha_float_cons, 'G'},
5281 {"d_floating", s_alpha_float_cons, 'D'},
5283 {"proc", s_alpha_proc, 0},
5284 {"aproc", s_alpha_proc, 1},
5285 {"set", s_alpha_set, 0},
5286 {"reguse", s_ignore, 0},
5287 {"livereg", s_ignore, 0},
5288 {"base", s_alpha_base, 0}, /*??*/
5289 {"option", s_ignore, 0},
5290 {"aent", s_ignore, 0},
5291 {"ugen", s_ignore, 0},
5292 {"eflag", s_ignore, 0},
5294 {"align", s_alpha_align, 0},
5295 {"double", s_alpha_float_cons, 'd'},
5296 {"float", s_alpha_float_cons, 'f'},
5297 {"single", s_alpha_float_cons, 'f'},
5298 {"ascii", s_alpha_stringer, 0},
5299 {"asciz", s_alpha_stringer, 1},
5300 {"string", s_alpha_stringer, 1},
5301 {"space", s_alpha_space, 0},
5302 {"skip", s_alpha_space, 0},
5303 {"zero", s_alpha_space, 0},
5305 /* Unaligned data pseudos. */
5306 {"uword", s_alpha_ucons, 2},
5307 {"ulong", s_alpha_ucons, 4},
5308 {"uquad", s_alpha_ucons, 8},
5310 #ifdef OBJ_ELF
5311 /* Dwarf wants these versions of unaligned. */
5312 {"2byte", s_alpha_ucons, 2},
5313 {"4byte", s_alpha_ucons, 4},
5314 {"8byte", s_alpha_ucons, 8},
5315 #endif
5317 /* We don't do any optimizing, so we can safely ignore these. */
5318 {"noalias", s_ignore, 0},
5319 {"alias", s_ignore, 0},
5321 {"arch", s_alpha_arch, 0},
5323 {NULL, 0, 0},
5326 #ifdef OBJ_ECOFF
5328 /* @@@ GP selection voodoo. All of this seems overly complicated and
5329 unnecessary; which is the primary reason it's for ECOFF only. */
5331 static inline void
5332 maybe_set_gp (asection *sec)
5334 bfd_vma vma;
5336 if (!sec)
5337 return;
5338 vma = bfd_get_section_vma (foo, sec);
5339 if (vma && vma < alpha_gp_value)
5340 alpha_gp_value = vma;
5343 static void
5344 select_gp_value (void)
5346 gas_assert (alpha_gp_value == 0);
5348 /* Get minus-one in whatever width... */
5349 alpha_gp_value = 0;
5350 alpha_gp_value--;
5352 /* Select the smallest VMA of these existing sections. */
5353 maybe_set_gp (alpha_lita_section);
5355 /* @@ Will a simple 0x8000 work here? If not, why not? */
5356 #define GP_ADJUSTMENT (0x8000 - 0x10)
5358 alpha_gp_value += GP_ADJUSTMENT;
5360 S_SET_VALUE (alpha_gp_symbol, alpha_gp_value);
5362 #ifdef DEBUG1
5363 printf (_("Chose GP value of %lx\n"), alpha_gp_value);
5364 #endif
5366 #endif /* OBJ_ECOFF */
5368 #ifdef OBJ_ELF
5369 /* Map 's' to SHF_ALPHA_GPREL. */
5371 bfd_vma
5372 alpha_elf_section_letter (int letter, char **ptr_msg)
5374 if (letter == 's')
5375 return SHF_ALPHA_GPREL;
5377 *ptr_msg = _("Bad .section directive: want a,s,w,x,M,S,G,T in string");
5378 return -1;
5381 /* Map SHF_ALPHA_GPREL to SEC_SMALL_DATA. */
5383 flagword
5384 alpha_elf_section_flags (flagword flags, bfd_vma attr, int type ATTRIBUTE_UNUSED)
5386 if (attr & SHF_ALPHA_GPREL)
5387 flags |= SEC_SMALL_DATA;
5388 return flags;
5390 #endif /* OBJ_ELF */
5392 /* This is called from HANDLE_ALIGN in write.c. Fill in the contents
5393 of an rs_align_code fragment. */
5395 void
5396 alpha_handle_align (fragS *fragp)
5398 static char const unop[4] = { 0x00, 0x00, 0xfe, 0x2f };
5399 static char const nopunop[8] =
5401 0x1f, 0x04, 0xff, 0x47,
5402 0x00, 0x00, 0xfe, 0x2f
5405 int bytes, fix;
5406 char *p;
5408 if (fragp->fr_type != rs_align_code)
5409 return;
5411 bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix;
5412 p = fragp->fr_literal + fragp->fr_fix;
5413 fix = 0;
5415 if (bytes & 3)
5417 fix = bytes & 3;
5418 memset (p, 0, fix);
5419 p += fix;
5420 bytes -= fix;
5423 if (bytes & 4)
5425 memcpy (p, unop, 4);
5426 p += 4;
5427 bytes -= 4;
5428 fix += 4;
5431 memcpy (p, nopunop, 8);
5433 fragp->fr_fix += fix;
5434 fragp->fr_var = 8;
5437 /* Public interface functions. */
5439 /* This function is called once, at assembler startup time. It sets
5440 up all the tables, etc. that the MD part of the assembler will
5441 need, that can be determined before arguments are parsed. */
5443 void
5444 md_begin (void)
5446 unsigned int i;
5448 /* Verify that X_op field is wide enough. */
5450 expressionS e;
5452 e.X_op = O_max;
5453 gas_assert (e.X_op == O_max);
5456 /* Create the opcode hash table. */
5457 alpha_opcode_hash = hash_new ();
5459 for (i = 0; i < alpha_num_opcodes;)
5461 const char *name, *retval, *slash;
5463 name = alpha_opcodes[i].name;
5464 retval = hash_insert (alpha_opcode_hash, name, (void *) &alpha_opcodes[i]);
5465 if (retval)
5466 as_fatal (_("internal error: can't hash opcode `%s': %s"),
5467 name, retval);
5469 /* Some opcodes include modifiers of various sorts with a "/mod"
5470 syntax, like the architecture manual suggests. However, for
5471 use with gcc at least, we also need access to those same opcodes
5472 without the "/". */
5474 if ((slash = strchr (name, '/')) != NULL)
5476 char *p = (char *) xmalloc (strlen (name));
5478 memcpy (p, name, slash - name);
5479 strcpy (p + (slash - name), slash + 1);
5481 (void) hash_insert (alpha_opcode_hash, p, (void *) &alpha_opcodes[i]);
5482 /* Ignore failures -- the opcode table does duplicate some
5483 variants in different forms, like "hw_stq" and "hw_st/q". */
5486 while (++i < alpha_num_opcodes
5487 && (alpha_opcodes[i].name == name
5488 || !strcmp (alpha_opcodes[i].name, name)))
5489 continue;
5492 /* Create the macro hash table. */
5493 alpha_macro_hash = hash_new ();
5495 for (i = 0; i < alpha_num_macros;)
5497 const char *name, *retval;
5499 name = alpha_macros[i].name;
5500 retval = hash_insert (alpha_macro_hash, name, (void *) &alpha_macros[i]);
5501 if (retval)
5502 as_fatal (_("internal error: can't hash macro `%s': %s"),
5503 name, retval);
5505 while (++i < alpha_num_macros
5506 && (alpha_macros[i].name == name
5507 || !strcmp (alpha_macros[i].name, name)))
5508 continue;
5511 /* Construct symbols for each of the registers. */
5512 for (i = 0; i < 32; ++i)
5514 char name[4];
5516 sprintf (name, "$%d", i);
5517 alpha_register_table[i] = symbol_create (name, reg_section, i,
5518 &zero_address_frag);
5521 for (; i < 64; ++i)
5523 char name[5];
5525 sprintf (name, "$f%d", i - 32);
5526 alpha_register_table[i] = symbol_create (name, reg_section, i,
5527 &zero_address_frag);
5530 /* Create the special symbols and sections we'll be using. */
5532 /* So .sbss will get used for tiny objects. */
5533 bfd_set_gp_size (stdoutput, g_switch_value);
5535 #ifdef OBJ_ECOFF
5536 create_literal_section (".lita", &alpha_lita_section, &alpha_lita_symbol);
5538 /* For handling the GP, create a symbol that won't be output in the
5539 symbol table. We'll edit it out of relocs later. */
5540 alpha_gp_symbol = symbol_create ("<GP value>", alpha_lita_section, 0x8000,
5541 &zero_address_frag);
5542 #endif
5544 #ifdef OBJ_EVAX
5545 create_literal_section (".link", &alpha_link_section, &alpha_link_symbol);
5546 alpha_evax_proc_hash = hash_new ();
5547 #endif
5549 #ifdef OBJ_ELF
5550 if (ECOFF_DEBUGGING)
5552 segT sec = subseg_new (".mdebug", (subsegT) 0);
5553 bfd_set_section_flags (stdoutput, sec, SEC_HAS_CONTENTS | SEC_READONLY);
5554 bfd_set_section_alignment (stdoutput, sec, 3);
5556 #endif
5558 /* Create literal lookup hash table. */
5559 alpha_literal_hash = hash_new ();
5561 subseg_set (text_section, 0);
5564 /* The public interface to the instruction assembler. */
5566 void
5567 md_assemble (char *str)
5569 /* Current maximum is 13. */
5570 char opname[32];
5571 expressionS tok[MAX_INSN_ARGS];
5572 int ntok, trunclen;
5573 size_t opnamelen;
5575 /* Split off the opcode. */
5576 opnamelen = strspn (str, "abcdefghijklmnopqrstuvwxyz_/46819");
5577 trunclen = (opnamelen < sizeof (opname) - 1
5578 ? opnamelen
5579 : sizeof (opname) - 1);
5580 memcpy (opname, str, trunclen);
5581 opname[trunclen] = '\0';
5583 /* Tokenize the rest of the line. */
5584 if ((ntok = tokenize_arguments (str + opnamelen, tok, MAX_INSN_ARGS)) < 0)
5586 if (ntok != TOKENIZE_ERROR_REPORT)
5587 as_bad (_("syntax error"));
5589 return;
5592 /* Finish it off. */
5593 assemble_tokens (opname, tok, ntok, alpha_macros_on);
5596 /* Round up a section's size to the appropriate boundary. */
5598 valueT
5599 md_section_align (segT seg, valueT size)
5601 int align = bfd_get_section_alignment (stdoutput, seg);
5602 valueT mask = ((valueT) 1 << align) - 1;
5604 return (size + mask) & ~mask;
5607 /* Turn a string in input_line_pointer into a floating point constant
5608 of type TYPE, and store the appropriate bytes in *LITP. The number
5609 of LITTLENUMS emitted is stored in *SIZEP. An error message is
5610 returned, or NULL on OK. */
5612 char *
5613 md_atof (int type, char *litP, int *sizeP)
5615 extern char *vax_md_atof (int, char *, int *);
5617 switch (type)
5619 /* VAX floats. */
5620 case 'G':
5621 /* vax_md_atof() doesn't like "G" for some reason. */
5622 type = 'g';
5623 case 'F':
5624 case 'D':
5625 return vax_md_atof (type, litP, sizeP);
5627 default:
5628 return ieee_md_atof (type, litP, sizeP, FALSE);
5632 /* Take care of the target-specific command-line options. */
5635 md_parse_option (int c, char *arg)
5637 switch (c)
5639 case 'F':
5640 alpha_nofloats_on = 1;
5641 break;
5643 case OPTION_32ADDR:
5644 alpha_addr32_on = 1;
5645 break;
5647 case 'g':
5648 alpha_debug = 1;
5649 break;
5651 case 'G':
5652 g_switch_value = atoi (arg);
5653 break;
5655 case 'm':
5657 const struct cpu_type *p;
5659 for (p = cpu_types; p->name; ++p)
5660 if (strcmp (arg, p->name) == 0)
5662 alpha_target_name = p->name, alpha_target = p->flags;
5663 goto found;
5665 as_warn (_("Unknown CPU identifier `%s'"), arg);
5666 found:;
5668 break;
5670 #ifdef OBJ_EVAX
5671 case '+': /* For g++. Hash any name > 63 chars long. */
5672 alpha_flag_hash_long_names = 1;
5673 break;
5675 case 'H': /* Show new symbol after hash truncation. */
5676 alpha_flag_show_after_trunc = 1;
5677 break;
5679 case 'h': /* For gnu-c/vax compatibility. */
5680 break;
5682 case OPTION_REPLACE:
5683 alpha_flag_replace = 1;
5684 break;
5686 case OPTION_NOREPLACE:
5687 alpha_flag_replace = 0;
5688 break;
5689 #endif
5691 case OPTION_RELAX:
5692 alpha_flag_relax = 1;
5693 break;
5695 #ifdef OBJ_ELF
5696 case OPTION_MDEBUG:
5697 alpha_flag_mdebug = 1;
5698 break;
5699 case OPTION_NO_MDEBUG:
5700 alpha_flag_mdebug = 0;
5701 break;
5702 #endif
5704 default:
5705 return 0;
5708 return 1;
5711 /* Print a description of the command-line options that we accept. */
5713 void
5714 md_show_usage (FILE *stream)
5716 fputs (_("\
5717 Alpha options:\n\
5718 -32addr treat addresses as 32-bit values\n\
5719 -F lack floating point instructions support\n\
5720 -mev4 | -mev45 | -mev5 | -mev56 | -mpca56 | -mev6 | -mev67 | -mev68 | -mall\n\
5721 specify variant of Alpha architecture\n\
5722 -m21064 | -m21066 | -m21164 | -m21164a | -m21164pc | -m21264 | -m21264a | -m21264b\n\
5723 these variants include PALcode opcodes\n"),
5724 stream);
5725 #ifdef OBJ_EVAX
5726 fputs (_("\
5727 VMS options:\n\
5728 -+ encode (don't truncate) names longer than 64 characters\n\
5729 -H show new symbol after hash truncation\n\
5730 -replace/-noreplace enable or disable the optimization of procedure calls\n"),
5731 stream);
5732 #endif
5735 /* Decide from what point a pc-relative relocation is relative to,
5736 relative to the pc-relative fixup. Er, relatively speaking. */
5738 long
5739 md_pcrel_from (fixS *fixP)
5741 valueT addr = fixP->fx_where + fixP->fx_frag->fr_address;
5743 switch (fixP->fx_r_type)
5745 case BFD_RELOC_23_PCREL_S2:
5746 case BFD_RELOC_ALPHA_HINT:
5747 case BFD_RELOC_ALPHA_BRSGP:
5748 return addr + 4;
5749 default:
5750 return addr;
5754 /* Attempt to simplify or even eliminate a fixup. The return value is
5755 ignored; perhaps it was once meaningful, but now it is historical.
5756 To indicate that a fixup has been eliminated, set fixP->fx_done.
5758 For ELF, here it is that we transform the GPDISP_HI16 reloc we used
5759 internally into the GPDISP reloc used externally. We had to do
5760 this so that we'd have the GPDISP_LO16 reloc as a tag to compute
5761 the distance to the "lda" instruction for setting the addend to
5762 GPDISP. */
5764 void
5765 md_apply_fix (fixS *fixP, valueT * valP, segT seg)
5767 char * const fixpos = fixP->fx_frag->fr_literal + fixP->fx_where;
5768 valueT value = * valP;
5769 unsigned image, size;
5771 switch (fixP->fx_r_type)
5773 /* The GPDISP relocations are processed internally with a symbol
5774 referring to the current function's section; we need to drop
5775 in a value which, when added to the address of the start of
5776 the function, gives the desired GP. */
5777 case BFD_RELOC_ALPHA_GPDISP_HI16:
5779 fixS *next = fixP->fx_next;
5781 /* With user-specified !gpdisp relocations, we can be missing
5782 the matching LO16 reloc. We will have already issued an
5783 error message. */
5784 if (next)
5785 fixP->fx_offset = (next->fx_frag->fr_address + next->fx_where
5786 - fixP->fx_frag->fr_address - fixP->fx_where);
5788 value = (value - sign_extend_16 (value)) >> 16;
5790 #ifdef OBJ_ELF
5791 fixP->fx_r_type = BFD_RELOC_ALPHA_GPDISP;
5792 #endif
5793 goto do_reloc_gp;
5795 case BFD_RELOC_ALPHA_GPDISP_LO16:
5796 value = sign_extend_16 (value);
5797 fixP->fx_offset = 0;
5798 #ifdef OBJ_ELF
5799 fixP->fx_done = 1;
5800 #endif
5802 do_reloc_gp:
5803 fixP->fx_addsy = section_symbol (seg);
5804 md_number_to_chars (fixpos, value, 2);
5805 break;
5807 case BFD_RELOC_16:
5808 if (fixP->fx_pcrel)
5809 fixP->fx_r_type = BFD_RELOC_16_PCREL;
5810 size = 2;
5811 goto do_reloc_xx;
5813 case BFD_RELOC_32:
5814 if (fixP->fx_pcrel)
5815 fixP->fx_r_type = BFD_RELOC_32_PCREL;
5816 size = 4;
5817 goto do_reloc_xx;
5819 case BFD_RELOC_64:
5820 if (fixP->fx_pcrel)
5821 fixP->fx_r_type = BFD_RELOC_64_PCREL;
5822 size = 8;
5824 do_reloc_xx:
5825 if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0)
5827 md_number_to_chars (fixpos, value, size);
5828 goto done;
5830 return;
5832 #ifdef OBJ_ECOFF
5833 case BFD_RELOC_GPREL32:
5834 gas_assert (fixP->fx_subsy == alpha_gp_symbol);
5835 fixP->fx_subsy = 0;
5836 /* FIXME: inherited this obliviousness of `value' -- why? */
5837 md_number_to_chars (fixpos, -alpha_gp_value, 4);
5838 break;
5839 #else
5840 case BFD_RELOC_GPREL32:
5841 #endif
5842 case BFD_RELOC_GPREL16:
5843 case BFD_RELOC_ALPHA_GPREL_HI16:
5844 case BFD_RELOC_ALPHA_GPREL_LO16:
5845 return;
5847 case BFD_RELOC_23_PCREL_S2:
5848 if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0)
5850 image = bfd_getl32 (fixpos);
5851 image = (image & ~0x1FFFFF) | ((value >> 2) & 0x1FFFFF);
5852 goto write_done;
5854 return;
5856 case BFD_RELOC_ALPHA_HINT:
5857 if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0)
5859 image = bfd_getl32 (fixpos);
5860 image = (image & ~0x3FFF) | ((value >> 2) & 0x3FFF);
5861 goto write_done;
5863 return;
5865 #ifdef OBJ_ELF
5866 case BFD_RELOC_ALPHA_BRSGP:
5867 return;
5869 case BFD_RELOC_ALPHA_TLSGD:
5870 case BFD_RELOC_ALPHA_TLSLDM:
5871 case BFD_RELOC_ALPHA_GOTDTPREL16:
5872 case BFD_RELOC_ALPHA_DTPREL_HI16:
5873 case BFD_RELOC_ALPHA_DTPREL_LO16:
5874 case BFD_RELOC_ALPHA_DTPREL16:
5875 case BFD_RELOC_ALPHA_GOTTPREL16:
5876 case BFD_RELOC_ALPHA_TPREL_HI16:
5877 case BFD_RELOC_ALPHA_TPREL_LO16:
5878 case BFD_RELOC_ALPHA_TPREL16:
5879 if (fixP->fx_addsy)
5880 S_SET_THREAD_LOCAL (fixP->fx_addsy);
5881 return;
5882 #endif
5884 #ifdef OBJ_ECOFF
5885 case BFD_RELOC_ALPHA_LITERAL:
5886 md_number_to_chars (fixpos, value, 2);
5887 return;
5888 #endif
5889 case BFD_RELOC_ALPHA_ELF_LITERAL:
5890 case BFD_RELOC_ALPHA_LITUSE:
5891 case BFD_RELOC_ALPHA_LINKAGE:
5892 case BFD_RELOC_ALPHA_CODEADDR:
5893 return;
5895 #ifdef OBJ_EVAX
5896 case BFD_RELOC_ALPHA_NOP:
5897 value -= (8 + 4); /* PC-relative, base is jsr+4. */
5899 /* From B.4.5.2 of the OpenVMS Linker Utility Manual:
5900 "Finally, the ETIR$C_STC_BSR command passes the same address
5901 as ETIR$C_STC_NOP (so that they will fail or succeed together),
5902 and the same test is done again." */
5903 if (S_GET_SEGMENT (fixP->fx_addsy) == undefined_section)
5905 fixP->fx_addnumber = -value;
5906 return;
5909 if ((abs (value) >> 2) & ~0xfffff)
5910 goto done;
5911 else
5913 /* Change to a nop. */
5914 image = 0x47FF041F;
5915 goto write_done;
5918 case BFD_RELOC_ALPHA_LDA:
5919 /* fixup_segment sets fixP->fx_addsy to NULL when it can pre-compute
5920 the value for an O_subtract. */
5921 if (fixP->fx_addsy
5922 && S_GET_SEGMENT (fixP->fx_addsy) == undefined_section)
5924 fixP->fx_addnumber = symbol_get_bfdsym (fixP->fx_subsy)->value;
5925 return;
5928 if ((abs (value)) & ~0x7fff)
5929 goto done;
5930 else
5932 /* Change to an lda. */
5933 image = 0x237B0000 | (value & 0xFFFF);
5934 goto write_done;
5937 case BFD_RELOC_ALPHA_BSR:
5938 case BFD_RELOC_ALPHA_BOH:
5939 value -= 4; /* PC-relative, base is jsr+4. */
5941 /* See comment in the BFD_RELOC_ALPHA_NOP case above. */
5942 if (S_GET_SEGMENT (fixP->fx_addsy) == undefined_section)
5944 fixP->fx_addnumber = -value;
5945 return;
5948 if ((abs (value) >> 2) & ~0xfffff)
5950 /* Out of range. */
5951 if (fixP->fx_r_type == BFD_RELOC_ALPHA_BOH)
5953 /* Add a hint. */
5954 image = bfd_getl32(fixpos);
5955 image = (image & ~0x3FFF) | ((value >> 2) & 0x3FFF);
5956 goto write_done;
5958 goto done;
5960 else
5962 /* Change to a branch. */
5963 image = 0xD3400000 | ((value >> 2) & 0x1FFFFF);
5964 goto write_done;
5966 #endif
5968 case BFD_RELOC_VTABLE_INHERIT:
5969 case BFD_RELOC_VTABLE_ENTRY:
5970 return;
5972 default:
5974 const struct alpha_operand *operand;
5976 if ((int) fixP->fx_r_type >= 0)
5977 as_fatal (_("unhandled relocation type %s"),
5978 bfd_get_reloc_code_name (fixP->fx_r_type));
5980 gas_assert (-(int) fixP->fx_r_type < (int) alpha_num_operands);
5981 operand = &alpha_operands[-(int) fixP->fx_r_type];
5983 /* The rest of these fixups only exist internally during symbol
5984 resolution and have no representation in the object file.
5985 Therefore they must be completely resolved as constants. */
5987 if (fixP->fx_addsy != 0
5988 && S_GET_SEGMENT (fixP->fx_addsy) != absolute_section)
5989 as_bad_where (fixP->fx_file, fixP->fx_line,
5990 _("non-absolute expression in constant field"));
5992 image = bfd_getl32 (fixpos);
5993 image = insert_operand (image, operand, (offsetT) value,
5994 fixP->fx_file, fixP->fx_line);
5996 goto write_done;
5999 if (fixP->fx_addsy != 0 || fixP->fx_pcrel != 0)
6000 return;
6001 else
6003 as_warn_where (fixP->fx_file, fixP->fx_line,
6004 _("type %d reloc done?\n"), (int) fixP->fx_r_type);
6005 goto done;
6008 write_done:
6009 md_number_to_chars (fixpos, image, 4);
6011 done:
6012 fixP->fx_done = 1;
6015 /* Look for a register name in the given symbol. */
6017 symbolS *
6018 md_undefined_symbol (char *name)
6020 if (*name == '$')
6022 int is_float = 0, num;
6024 switch (*++name)
6026 case 'f':
6027 if (name[1] == 'p' && name[2] == '\0')
6028 return alpha_register_table[AXP_REG_FP];
6029 is_float = 32;
6030 /* Fall through. */
6032 case 'r':
6033 if (!ISDIGIT (*++name))
6034 break;
6035 /* Fall through. */
6037 case '0': case '1': case '2': case '3': case '4':
6038 case '5': case '6': case '7': case '8': case '9':
6039 if (name[1] == '\0')
6040 num = name[0] - '0';
6041 else if (name[0] != '0' && ISDIGIT (name[1]) && name[2] == '\0')
6043 num = (name[0] - '0') * 10 + name[1] - '0';
6044 if (num >= 32)
6045 break;
6047 else
6048 break;
6050 if (!alpha_noat_on && (num + is_float) == AXP_REG_AT)
6051 as_warn (_("Used $at without \".set noat\""));
6052 return alpha_register_table[num + is_float];
6054 case 'a':
6055 if (name[1] == 't' && name[2] == '\0')
6057 if (!alpha_noat_on)
6058 as_warn (_("Used $at without \".set noat\""));
6059 return alpha_register_table[AXP_REG_AT];
6061 break;
6063 case 'g':
6064 if (name[1] == 'p' && name[2] == '\0')
6065 return alpha_register_table[alpha_gp_register];
6066 break;
6068 case 's':
6069 if (name[1] == 'p' && name[2] == '\0')
6070 return alpha_register_table[AXP_REG_SP];
6071 break;
6074 return NULL;
6077 #ifdef OBJ_ECOFF
6078 /* @@@ Magic ECOFF bits. */
6080 void
6081 alpha_frob_ecoff_data (void)
6083 select_gp_value ();
6084 /* $zero and $f31 are read-only. */
6085 alpha_gprmask &= ~1;
6086 alpha_fprmask &= ~1;
6088 #endif
6090 /* Hook to remember a recently defined label so that the auto-align
6091 code can adjust the symbol after we know what alignment will be
6092 required. */
6094 void
6095 alpha_define_label (symbolS *sym)
6097 alpha_insn_label = sym;
6098 #ifdef OBJ_ELF
6099 dwarf2_emit_label (sym);
6100 #endif
6103 /* Return true if we must always emit a reloc for a type and false if
6104 there is some hope of resolving it at assembly time. */
6107 alpha_force_relocation (fixS *f)
6109 if (alpha_flag_relax)
6110 return 1;
6112 switch (f->fx_r_type)
6114 case BFD_RELOC_ALPHA_GPDISP_HI16:
6115 case BFD_RELOC_ALPHA_GPDISP_LO16:
6116 case BFD_RELOC_ALPHA_GPDISP:
6117 case BFD_RELOC_ALPHA_LITERAL:
6118 case BFD_RELOC_ALPHA_ELF_LITERAL:
6119 case BFD_RELOC_ALPHA_LITUSE:
6120 case BFD_RELOC_GPREL16:
6121 case BFD_RELOC_GPREL32:
6122 case BFD_RELOC_ALPHA_GPREL_HI16:
6123 case BFD_RELOC_ALPHA_GPREL_LO16:
6124 case BFD_RELOC_ALPHA_LINKAGE:
6125 case BFD_RELOC_ALPHA_CODEADDR:
6126 case BFD_RELOC_ALPHA_BRSGP:
6127 case BFD_RELOC_ALPHA_TLSGD:
6128 case BFD_RELOC_ALPHA_TLSLDM:
6129 case BFD_RELOC_ALPHA_GOTDTPREL16:
6130 case BFD_RELOC_ALPHA_DTPREL_HI16:
6131 case BFD_RELOC_ALPHA_DTPREL_LO16:
6132 case BFD_RELOC_ALPHA_DTPREL16:
6133 case BFD_RELOC_ALPHA_GOTTPREL16:
6134 case BFD_RELOC_ALPHA_TPREL_HI16:
6135 case BFD_RELOC_ALPHA_TPREL_LO16:
6136 case BFD_RELOC_ALPHA_TPREL16:
6137 #ifdef OBJ_EVAX
6138 case BFD_RELOC_ALPHA_NOP:
6139 case BFD_RELOC_ALPHA_BSR:
6140 case BFD_RELOC_ALPHA_LDA:
6141 case BFD_RELOC_ALPHA_BOH:
6142 #endif
6143 return 1;
6145 default:
6146 break;
6149 return generic_force_reloc (f);
6152 /* Return true if we can partially resolve a relocation now. */
6155 alpha_fix_adjustable (fixS *f)
6157 /* Are there any relocation types for which we must generate a
6158 reloc but we can adjust the values contained within it? */
6159 switch (f->fx_r_type)
6161 case BFD_RELOC_ALPHA_GPDISP_HI16:
6162 case BFD_RELOC_ALPHA_GPDISP_LO16:
6163 case BFD_RELOC_ALPHA_GPDISP:
6164 return 0;
6166 case BFD_RELOC_ALPHA_LITERAL:
6167 case BFD_RELOC_ALPHA_ELF_LITERAL:
6168 case BFD_RELOC_ALPHA_LITUSE:
6169 case BFD_RELOC_ALPHA_LINKAGE:
6170 case BFD_RELOC_ALPHA_CODEADDR:
6171 return 1;
6173 case BFD_RELOC_VTABLE_ENTRY:
6174 case BFD_RELOC_VTABLE_INHERIT:
6175 return 0;
6177 case BFD_RELOC_GPREL16:
6178 case BFD_RELOC_GPREL32:
6179 case BFD_RELOC_ALPHA_GPREL_HI16:
6180 case BFD_RELOC_ALPHA_GPREL_LO16:
6181 case BFD_RELOC_23_PCREL_S2:
6182 case BFD_RELOC_16:
6183 case BFD_RELOC_32:
6184 case BFD_RELOC_64:
6185 case BFD_RELOC_ALPHA_HINT:
6186 return 1;
6188 case BFD_RELOC_ALPHA_TLSGD:
6189 case BFD_RELOC_ALPHA_TLSLDM:
6190 case BFD_RELOC_ALPHA_GOTDTPREL16:
6191 case BFD_RELOC_ALPHA_DTPREL_HI16:
6192 case BFD_RELOC_ALPHA_DTPREL_LO16:
6193 case BFD_RELOC_ALPHA_DTPREL16:
6194 case BFD_RELOC_ALPHA_GOTTPREL16:
6195 case BFD_RELOC_ALPHA_TPREL_HI16:
6196 case BFD_RELOC_ALPHA_TPREL_LO16:
6197 case BFD_RELOC_ALPHA_TPREL16:
6198 /* ??? No idea why we can't return a reference to .tbss+10, but
6199 we're preventing this in the other assemblers. Follow for now. */
6200 return 0;
6202 #ifdef OBJ_ELF
6203 case BFD_RELOC_ALPHA_BRSGP:
6204 /* If we have a BRSGP reloc to a local symbol, adjust it to BRADDR and
6205 let it get resolved at assembly time. */
6207 symbolS *sym = f->fx_addsy;
6208 const char *name;
6209 int offset = 0;
6211 if (generic_force_reloc (f))
6212 return 0;
6214 switch (S_GET_OTHER (sym) & STO_ALPHA_STD_GPLOAD)
6216 case STO_ALPHA_NOPV:
6217 break;
6218 case STO_ALPHA_STD_GPLOAD:
6219 offset = 8;
6220 break;
6221 default:
6222 if (S_IS_LOCAL (sym))
6223 name = "<local>";
6224 else
6225 name = S_GET_NAME (sym);
6226 as_bad_where (f->fx_file, f->fx_line,
6227 _("!samegp reloc against symbol without .prologue: %s"),
6228 name);
6229 break;
6231 f->fx_r_type = BFD_RELOC_23_PCREL_S2;
6232 f->fx_offset += offset;
6233 return 1;
6235 #endif
6236 #ifdef OBJ_EVAX
6237 case BFD_RELOC_ALPHA_NOP:
6238 case BFD_RELOC_ALPHA_BSR:
6239 case BFD_RELOC_ALPHA_LDA:
6240 case BFD_RELOC_ALPHA_BOH:
6241 return 1;
6242 #endif
6244 default:
6245 return 1;
6249 /* Generate the BFD reloc to be stuck in the object file from the
6250 fixup used internally in the assembler. */
6252 arelent *
6253 tc_gen_reloc (asection *sec ATTRIBUTE_UNUSED,
6254 fixS *fixp)
6256 arelent *reloc;
6258 reloc = (arelent *) xmalloc (sizeof (* reloc));
6259 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
6260 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
6261 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
6263 /* Make sure none of our internal relocations make it this far.
6264 They'd better have been fully resolved by this point. */
6265 gas_assert ((int) fixp->fx_r_type > 0);
6267 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
6268 if (reloc->howto == NULL)
6270 as_bad_where (fixp->fx_file, fixp->fx_line,
6271 _("cannot represent `%s' relocation in object file"),
6272 bfd_get_reloc_code_name (fixp->fx_r_type));
6273 return NULL;
6276 if (!fixp->fx_pcrel != !reloc->howto->pc_relative)
6277 as_fatal (_("internal error? cannot generate `%s' relocation"),
6278 bfd_get_reloc_code_name (fixp->fx_r_type));
6280 gas_assert (!fixp->fx_pcrel == !reloc->howto->pc_relative);
6282 #ifdef OBJ_ECOFF
6283 if (fixp->fx_r_type == BFD_RELOC_ALPHA_LITERAL)
6284 /* Fake out bfd_perform_relocation. sigh. */
6285 reloc->addend = -alpha_gp_value;
6286 else
6287 #endif
6289 reloc->addend = fixp->fx_offset;
6290 #ifdef OBJ_ELF
6291 /* Ohhh, this is ugly. The problem is that if this is a local global
6292 symbol, the relocation will entirely be performed at link time, not
6293 at assembly time. bfd_perform_reloc doesn't know about this sort
6294 of thing, and as a result we need to fake it out here. */
6295 if ((S_IS_EXTERNAL (fixp->fx_addsy) || S_IS_WEAK (fixp->fx_addsy)
6296 || (S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_MERGE)
6297 || (S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_THREAD_LOCAL))
6298 && !S_IS_COMMON (fixp->fx_addsy))
6299 reloc->addend -= symbol_get_bfdsym (fixp->fx_addsy)->value;
6300 #endif
6303 #ifdef OBJ_EVAX
6304 switch (fixp->fx_r_type)
6306 struct evax_private_udata_struct *udata;
6307 const char *pname;
6308 int pname_len;
6310 case BFD_RELOC_ALPHA_LINKAGE:
6311 /* Copy the linkage index. */
6312 reloc->addend = fixp->fx_addnumber;
6313 break;
6315 case BFD_RELOC_ALPHA_NOP:
6316 case BFD_RELOC_ALPHA_BSR:
6317 case BFD_RELOC_ALPHA_LDA:
6318 case BFD_RELOC_ALPHA_BOH:
6319 pname = symbol_get_bfdsym (fixp->fx_addsy)->name;
6321 /* We need the non-suffixed name of the procedure. Beware that
6322 the main symbol might be equated so look it up and take its name. */
6323 pname_len = strlen (pname);
6324 if (pname_len > 4 && strcmp (pname + pname_len - 4, "..en") == 0)
6326 symbolS *sym;
6327 char *my_pname = xstrdup (pname);
6328 my_pname [pname_len - 4] = 0;
6329 sym = symbol_find (my_pname);
6330 if (sym == NULL)
6331 abort ();
6332 while (symbol_equated_reloc_p (sym))
6334 symbolS *n = symbol_get_value_expression (sym)->X_add_symbol;
6336 /* We must avoid looping, as that can occur with a badly
6337 written program. */
6338 if (n == sym)
6339 break;
6340 sym = n;
6342 pname = symbol_get_bfdsym (sym)->name;
6345 udata = (struct evax_private_udata_struct *)
6346 xmalloc (sizeof (struct evax_private_udata_struct));
6347 udata->enbsym = symbol_get_bfdsym (fixp->fx_addsy);
6348 udata->bsym = symbol_get_bfdsym (fixp->tc_fix_data.info->psym);
6349 udata->origname = (char *)pname;
6350 udata->lkindex = ((struct evax_private_udata_struct *)
6351 symbol_get_bfdsym (fixp->tc_fix_data.info->sym)->udata.p)->lkindex;
6352 reloc->sym_ptr_ptr = (void *)udata;
6353 reloc->addend = fixp->fx_addnumber;
6355 default:
6356 break;
6358 #endif
6360 return reloc;
6363 /* Parse a register name off of the input_line and return a register
6364 number. Gets md_undefined_symbol above to do the register name
6365 matching for us.
6367 Only called as a part of processing the ECOFF .frame directive. */
6370 tc_get_register (int frame ATTRIBUTE_UNUSED)
6372 int framereg = AXP_REG_SP;
6374 SKIP_WHITESPACE ();
6375 if (*input_line_pointer == '$')
6377 char *s = input_line_pointer;
6378 char c = get_symbol_end ();
6379 symbolS *sym = md_undefined_symbol (s);
6381 *strchr (s, '\0') = c;
6382 if (sym && (framereg = S_GET_VALUE (sym)) <= 31)
6383 goto found;
6385 as_warn (_("frame reg expected, using $%d."), framereg);
6387 found:
6388 note_gpreg (framereg);
6389 return framereg;
6392 /* This is called before the symbol table is processed. In order to
6393 work with gcc when using mips-tfile, we must keep all local labels.
6394 However, in other cases, we want to discard them. If we were
6395 called with -g, but we didn't see any debugging information, it may
6396 mean that gcc is smuggling debugging information through to
6397 mips-tfile, in which case we must generate all local labels. */
6399 #ifdef OBJ_ECOFF
6401 void
6402 alpha_frob_file_before_adjust (void)
6404 if (alpha_debug != 0
6405 && ! ecoff_debugging_seen)
6406 flag_keep_locals = 1;
6409 #endif /* OBJ_ECOFF */
6411 /* The Alpha has support for some VAX floating point types, as well as for
6412 IEEE floating point. We consider IEEE to be the primary floating point
6413 format, and sneak in the VAX floating point support here. */
6414 #include "config/atof-vax.c"