* elf.c (_bfd_elf_rela_local_sym): New.
[binutils.git] / gas / config / tc-alpha.c
blobf9908e7924ac1553383bf27080efe6770d7e49ad
1 /* tc-alpha.c - Processor-specific code for the DEC Alpha AXP CPU.
2 Copyright 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
3 Free Software Foundation, Inc.
4 Contributed by Carnegie Mellon University, 1993.
5 Written by Alessandro Forin, based on earlier gas-1.38 target CPU files.
6 Modified by Ken Raeburn for gas-2.x and ECOFF support.
7 Modified by Richard Henderson for ELF support.
8 Modified by Klaus K"ampf for EVAX (OpenVMS/Alpha) support.
10 This file is part of GAS, the GNU Assembler.
12 GAS is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2, or (at your option)
15 any later version.
17 GAS is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
22 You should have received a copy of the GNU General Public License
23 along with GAS; see the file COPYING. If not, write to the Free
24 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
25 02111-1307, 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.
53 #include "as.h"
54 #include "subsegs.h"
55 #include "struc-symbol.h"
56 #include "ecoff.h"
58 #include "opcode/alpha.h"
60 #ifdef OBJ_ELF
61 #include "elf/alpha.h"
62 #include "dwarf2dbg.h"
63 #endif
65 #include "safe-ctype.h"
67 /* Local types */
69 #define TOKENIZE_ERROR -1
70 #define TOKENIZE_ERROR_REPORT -2
72 #define MAX_INSN_FIXUPS 2
73 #define MAX_INSN_ARGS 5
75 struct alpha_fixup {
76 expressionS exp;
77 bfd_reloc_code_real_type reloc;
80 struct alpha_insn {
81 unsigned insn;
82 int nfixups;
83 struct alpha_fixup fixups[MAX_INSN_FIXUPS];
84 long sequence;
87 enum alpha_macro_arg {
88 MACRO_EOA = 1,
89 MACRO_IR,
90 MACRO_PIR,
91 MACRO_OPIR,
92 MACRO_CPIR,
93 MACRO_FPR,
94 MACRO_EXP,
97 struct alpha_macro {
98 const char *name;
99 void (*emit) PARAMS ((const expressionS *, int, const PTR));
100 const PTR arg;
101 enum alpha_macro_arg argsets[16];
104 /* Extra expression types. */
106 #define O_pregister O_md1 /* O_register, in parentheses */
107 #define O_cpregister O_md2 /* + a leading comma */
109 /* Note, the alpha_reloc_op table below depends on the ordering
110 of O_literal .. O_gpre16. */
111 #define O_literal O_md3 /* !literal relocation */
112 #define O_lituse_addr O_md4 /* !lituse_addr relocation */
113 #define O_lituse_base O_md5 /* !lituse_base relocation */
114 #define O_lituse_bytoff O_md6 /* !lituse_bytoff relocation */
115 #define O_lituse_jsr O_md7 /* !lituse_jsr relocation */
116 #define O_gpdisp O_md8 /* !gpdisp relocation */
117 #define O_gprelhigh O_md9 /* !gprelhigh relocation */
118 #define O_gprellow O_md10 /* !gprellow relocation */
119 #define O_gprel O_md11 /* !gprel relocation */
121 #define DUMMY_RELOC_LITUSE_ADDR (BFD_RELOC_UNUSED + 1)
122 #define DUMMY_RELOC_LITUSE_BASE (BFD_RELOC_UNUSED + 2)
123 #define DUMMY_RELOC_LITUSE_BYTOFF (BFD_RELOC_UNUSED + 3)
124 #define DUMMY_RELOC_LITUSE_JSR (BFD_RELOC_UNUSED + 4)
126 #define LITUSE_ADDR 0
127 #define LITUSE_BASE 1
128 #define LITUSE_BYTOFF 2
129 #define LITUSE_JSR 3
131 #define USER_RELOC_P(R) ((R) >= O_literal && (R) <= O_gprel)
133 /* Macros for extracting the type and number of encoded register tokens */
135 #define is_ir_num(x) (((x) & 32) == 0)
136 #define is_fpr_num(x) (((x) & 32) != 0)
137 #define regno(x) ((x) & 31)
139 /* Something odd inherited from the old assembler */
141 #define note_gpreg(R) (alpha_gprmask |= (1 << (R)))
142 #define note_fpreg(R) (alpha_fprmask |= (1 << (R)))
144 /* Predicates for 16- and 32-bit ranges */
145 /* XXX: The non-shift version appears to trigger a compiler bug when
146 cross-assembling from x86 w/ gcc 2.7.2. */
148 #if 1
149 #define range_signed_16(x) \
150 (((offsetT) (x) >> 15) == 0 || ((offsetT) (x) >> 15) == -1)
151 #define range_signed_32(x) \
152 (((offsetT) (x) >> 31) == 0 || ((offsetT) (x) >> 31) == -1)
153 #else
154 #define range_signed_16(x) ((offsetT) (x) >= -(offsetT) 0x8000 && \
155 (offsetT) (x) <= (offsetT) 0x7FFF)
156 #define range_signed_32(x) ((offsetT) (x) >= -(offsetT) 0x80000000 && \
157 (offsetT) (x) <= (offsetT) 0x7FFFFFFF)
158 #endif
160 /* Macros for sign extending from 16- and 32-bits. */
161 /* XXX: The cast macros will work on all the systems that I care about,
162 but really a predicate should be found to use the non-cast forms. */
164 #if 1
165 #define sign_extend_16(x) ((short) (x))
166 #define sign_extend_32(x) ((int) (x))
167 #else
168 #define sign_extend_16(x) ((offsetT) (((x) & 0xFFFF) ^ 0x8000) - 0x8000)
169 #define sign_extend_32(x) ((offsetT) (((x) & 0xFFFFFFFF) \
170 ^ 0x80000000) - 0x80000000)
171 #endif
173 /* Macros to build tokens */
175 #define set_tok_reg(t, r) (memset (&(t), 0, sizeof (t)), \
176 (t).X_op = O_register, \
177 (t).X_add_number = (r))
178 #define set_tok_preg(t, r) (memset (&(t), 0, sizeof (t)), \
179 (t).X_op = O_pregister, \
180 (t).X_add_number = (r))
181 #define set_tok_cpreg(t, r) (memset (&(t), 0, sizeof (t)), \
182 (t).X_op = O_cpregister, \
183 (t).X_add_number = (r))
184 #define set_tok_freg(t, r) (memset (&(t), 0, sizeof (t)), \
185 (t).X_op = O_register, \
186 (t).X_add_number = (r) + 32)
187 #define set_tok_sym(t, s, a) (memset (&(t), 0, sizeof (t)), \
188 (t).X_op = O_symbol, \
189 (t).X_add_symbol = (s), \
190 (t).X_add_number = (a))
191 #define set_tok_const(t, n) (memset (&(t), 0, sizeof (t)), \
192 (t).X_op = O_constant, \
193 (t).X_add_number = (n))
195 /* Prototypes for all local functions */
197 static struct alpha_reloc_tag *get_alpha_reloc_tag PARAMS ((long));
198 static void alpha_adjust_symtab_relocs PARAMS ((bfd *, asection *, PTR));
200 static int tokenize_arguments PARAMS ((char *, expressionS *, int));
201 static const struct alpha_opcode *find_opcode_match
202 PARAMS ((const struct alpha_opcode *, const expressionS *, int *, int *));
203 static const struct alpha_macro *find_macro_match
204 PARAMS ((const struct alpha_macro *, const expressionS *, int *));
205 static unsigned insert_operand
206 PARAMS ((unsigned, const struct alpha_operand *, offsetT, char *, unsigned));
207 static void assemble_insn
208 PARAMS ((const struct alpha_opcode *, const expressionS *, int,
209 struct alpha_insn *, bfd_reloc_code_real_type));
210 static void emit_insn PARAMS ((struct alpha_insn *));
211 static void assemble_tokens_to_insn
212 PARAMS ((const char *, const expressionS *, int, struct alpha_insn *));
213 static void assemble_tokens
214 PARAMS ((const char *, const expressionS *, int, int));
216 static long load_expression
217 PARAMS ((int, const expressionS *, int *, expressionS *));
219 static void emit_ldgp PARAMS ((const expressionS *, int, const PTR));
220 static void emit_division PARAMS ((const expressionS *, int, const PTR));
221 static void emit_lda PARAMS ((const expressionS *, int, const PTR));
222 static void emit_ldah PARAMS ((const expressionS *, int, const PTR));
223 static void emit_ir_load PARAMS ((const expressionS *, int, const PTR));
224 static void emit_loadstore PARAMS ((const expressionS *, int, const PTR));
225 static void emit_jsrjmp PARAMS ((const expressionS *, int, const PTR));
226 static void emit_ldX PARAMS ((const expressionS *, int, const PTR));
227 static void emit_ldXu PARAMS ((const expressionS *, int, const PTR));
228 static void emit_uldX PARAMS ((const expressionS *, int, const PTR));
229 static void emit_uldXu PARAMS ((const expressionS *, int, const PTR));
230 static void emit_ldil PARAMS ((const expressionS *, int, const PTR));
231 static void emit_stX PARAMS ((const expressionS *, int, const PTR));
232 static void emit_ustX PARAMS ((const expressionS *, int, const PTR));
233 static void emit_sextX PARAMS ((const expressionS *, int, const PTR));
234 static void emit_retjcr PARAMS ((const expressionS *, int, const PTR));
236 static void s_alpha_text PARAMS ((int));
237 static void s_alpha_data PARAMS ((int));
238 #ifndef OBJ_ELF
239 static void s_alpha_comm PARAMS ((int));
240 static void s_alpha_rdata PARAMS ((int));
241 #endif
242 #ifdef OBJ_ECOFF
243 static void s_alpha_sdata PARAMS ((int));
244 #endif
245 #ifdef OBJ_ELF
246 static void s_alpha_section PARAMS ((int));
247 static void s_alpha_ent PARAMS ((int));
248 static void s_alpha_end PARAMS ((int));
249 static void s_alpha_mask PARAMS ((int));
250 static void s_alpha_frame PARAMS ((int));
251 static void s_alpha_prologue PARAMS ((int));
252 static void s_alpha_file PARAMS ((int));
253 static void s_alpha_loc PARAMS ((int));
254 static void s_alpha_stab PARAMS ((int));
255 static void s_alpha_coff_wrapper PARAMS ((int));
256 #endif
257 #ifdef OBJ_EVAX
258 static void s_alpha_section PARAMS ((int));
259 #endif
260 static void s_alpha_gprel32 PARAMS ((int));
261 static void s_alpha_float_cons PARAMS ((int));
262 static void s_alpha_proc PARAMS ((int));
263 static void s_alpha_set PARAMS ((int));
264 static void s_alpha_base PARAMS ((int));
265 static void s_alpha_align PARAMS ((int));
266 static void s_alpha_stringer PARAMS ((int));
267 static void s_alpha_space PARAMS ((int));
268 static void s_alpha_ucons PARAMS ((int));
269 static void s_alpha_arch PARAMS ((int));
271 static void create_literal_section PARAMS ((const char *, segT *, symbolS **));
272 #ifndef OBJ_ELF
273 static void select_gp_value PARAMS ((void));
274 #endif
275 static void alpha_align PARAMS ((int, char *, symbolS *, int));
277 /* Generic assembler global variables which must be defined by all
278 targets. */
280 /* Characters which always start a comment. */
281 const char comment_chars[] = "#";
283 /* Characters which start a comment at the beginning of a line. */
284 const char line_comment_chars[] = "#";
286 /* Characters which may be used to separate multiple commands on a
287 single line. */
288 const char line_separator_chars[] = ";";
290 /* Characters which are used to indicate an exponent in a floating
291 point number. */
292 const char EXP_CHARS[] = "eE";
294 /* Characters which mean that a number is a floating point constant,
295 as in 0d1.0. */
296 #if 0
297 const char FLT_CHARS[] = "dD";
298 #else
299 /* XXX: Do all of these really get used on the alpha?? */
300 char FLT_CHARS[] = "rRsSfFdDxXpP";
301 #endif
303 #ifdef OBJ_EVAX
304 const char *md_shortopts = "Fm:g+1h:HG:";
305 #else
306 const char *md_shortopts = "Fm:gG:";
307 #endif
309 struct option md_longopts[] = {
310 #define OPTION_32ADDR (OPTION_MD_BASE)
311 { "32addr", no_argument, NULL, OPTION_32ADDR },
312 #define OPTION_RELAX (OPTION_32ADDR + 1)
313 { "relax", no_argument, NULL, OPTION_RELAX },
314 #ifdef OBJ_ELF
315 #define OPTION_MDEBUG (OPTION_RELAX + 1)
316 #define OPTION_NO_MDEBUG (OPTION_MDEBUG + 1)
317 { "mdebug", no_argument, NULL, OPTION_MDEBUG },
318 { "no-mdebug", no_argument, NULL, OPTION_NO_MDEBUG },
319 #endif
320 { NULL, no_argument, NULL, 0 }
323 size_t md_longopts_size = sizeof (md_longopts);
325 #ifdef OBJ_EVAX
326 #define AXP_REG_R0 0
327 #define AXP_REG_R16 16
328 #define AXP_REG_R17 17
329 #undef AXP_REG_T9
330 #define AXP_REG_T9 22
331 #undef AXP_REG_T10
332 #define AXP_REG_T10 23
333 #undef AXP_REG_T11
334 #define AXP_REG_T11 24
335 #undef AXP_REG_T12
336 #define AXP_REG_T12 25
337 #define AXP_REG_AI 25
338 #undef AXP_REG_FP
339 #define AXP_REG_FP 29
341 #undef AXP_REG_GP
342 #define AXP_REG_GP AXP_REG_PV
343 #endif /* OBJ_EVAX */
345 /* The cpu for which we are generating code */
346 static unsigned alpha_target = AXP_OPCODE_BASE;
347 static const char *alpha_target_name = "<all>";
349 /* The hash table of instruction opcodes */
350 static struct hash_control *alpha_opcode_hash;
352 /* The hash table of macro opcodes */
353 static struct hash_control *alpha_macro_hash;
355 #ifdef OBJ_ECOFF
356 /* The $gp relocation symbol */
357 static symbolS *alpha_gp_symbol;
359 /* XXX: what is this, and why is it exported? */
360 valueT alpha_gp_value;
361 #endif
363 /* The current $gp register */
364 static int alpha_gp_register = AXP_REG_GP;
366 /* A table of the register symbols */
367 static symbolS *alpha_register_table[64];
369 /* Constant sections, or sections of constants */
370 #ifdef OBJ_ECOFF
371 static segT alpha_lita_section;
372 static segT alpha_lit4_section;
373 #endif
374 #ifdef OBJ_EVAX
375 static segT alpha_link_section;
376 static segT alpha_ctors_section;
377 static segT alpha_dtors_section;
378 #endif
379 static segT alpha_lit8_section;
381 /* Symbols referring to said sections. */
382 #ifdef OBJ_ECOFF
383 static symbolS *alpha_lita_symbol;
384 static symbolS *alpha_lit4_symbol;
385 #endif
386 #ifdef OBJ_EVAX
387 static symbolS *alpha_link_symbol;
388 static symbolS *alpha_ctors_symbol;
389 static symbolS *alpha_dtors_symbol;
390 #endif
391 static symbolS *alpha_lit8_symbol;
393 /* Literal for .litX+0x8000 within .lita */
394 #ifdef OBJ_ECOFF
395 static offsetT alpha_lit4_literal;
396 static offsetT alpha_lit8_literal;
397 #endif
399 #ifdef OBJ_ELF
400 /* The active .ent symbol. */
401 static symbolS *alpha_cur_ent_sym;
402 #endif
404 /* Is the assembler not allowed to use $at? */
405 static int alpha_noat_on = 0;
407 /* Are macros enabled? */
408 static int alpha_macros_on = 1;
410 /* Are floats disabled? */
411 static int alpha_nofloats_on = 0;
413 /* Are addresses 32 bit? */
414 static int alpha_addr32_on = 0;
416 /* Symbol labelling the current insn. When the Alpha gas sees
417 foo:
418 .quad 0
419 and the section happens to not be on an eight byte boundary, it
420 will align both the symbol and the .quad to an eight byte boundary. */
421 static symbolS *alpha_insn_label;
423 /* Whether we should automatically align data generation pseudo-ops.
424 .align 0 will turn this off. */
425 static int alpha_auto_align_on = 1;
427 /* The known current alignment of the current section. */
428 static int alpha_current_align;
430 /* These are exported to ECOFF code. */
431 unsigned long alpha_gprmask, alpha_fprmask;
433 /* Whether the debugging option was seen. */
434 static int alpha_debug;
436 #ifdef OBJ_ELF
437 /* Whether we are emitting an mdebug section. */
438 int alpha_flag_mdebug = -1;
439 #endif
441 /* Don't fully resolve relocations, allowing code movement in the linker. */
442 static int alpha_flag_relax;
444 /* What value to give to bfd_set_gp_size. */
445 static int g_switch_value = 8;
447 #ifdef OBJ_EVAX
448 /* Collect information about current procedure here. */
449 static struct {
450 symbolS *symbol; /* proc pdesc symbol */
451 int pdsckind;
452 int framereg; /* register for frame pointer */
453 int framesize; /* size of frame */
454 int rsa_offset;
455 int ra_save;
456 int fp_save;
457 long imask;
458 long fmask;
459 int type;
460 int prologue;
461 } alpha_evax_proc;
463 static int alpha_flag_hash_long_names = 0; /* -+ */
464 static int alpha_flag_show_after_trunc = 0; /* -H */
466 /* If the -+ switch is given, then a hash is appended to any name that is
467 * longer than 64 characters, else longer symbol names are truncated.
470 #endif
472 #ifdef RELOC_OP_P
473 /* A table to map the spelling of a relocation operand into an appropriate
474 bfd_reloc_code_real_type type. The table is assumed to be ordered such
475 that op-O_literal indexes into it. */
477 #define ALPHA_RELOC_TABLE(op) \
478 (&alpha_reloc_op[ ((!USER_RELOC_P (op)) \
479 ? (abort (), 0) \
480 : (int) (op) - (int) O_literal) ])
482 #define DEF(NAME, RELOC, REQ, ALLOW) \
483 { #NAME, sizeof(#NAME)-1, O_##NAME, RELOC, REQ, ALLOW}
485 static const struct alpha_reloc_op_tag {
486 const char *name; /* string to lookup */
487 size_t length; /* size of the string */
488 operatorT op; /* which operator to use */
489 bfd_reloc_code_real_type reloc; /* relocation before frob */
490 unsigned int require_seq : 1; /* require a sequence number */
491 unsigned int allow_seq : 1; /* allow a sequence number */
492 } alpha_reloc_op[] = {
493 DEF(literal, BFD_RELOC_ALPHA_ELF_LITERAL, 0, 1),
494 DEF(lituse_addr, DUMMY_RELOC_LITUSE_ADDR, 1, 1),
495 DEF(lituse_base, DUMMY_RELOC_LITUSE_BASE, 1, 1),
496 DEF(lituse_bytoff, DUMMY_RELOC_LITUSE_BYTOFF, 1, 1),
497 DEF(lituse_jsr, DUMMY_RELOC_LITUSE_JSR, 1, 1),
498 DEF(gpdisp, BFD_RELOC_ALPHA_GPDISP, 1, 1),
499 DEF(gprelhigh, BFD_RELOC_ALPHA_GPREL_HI16, 0, 0),
500 DEF(gprellow, BFD_RELOC_ALPHA_GPREL_LO16, 0, 0),
501 DEF(gprel, BFD_RELOC_GPREL16, 0, 0)
504 #undef DEF
506 static const int alpha_num_reloc_op
507 = sizeof (alpha_reloc_op) / sizeof (*alpha_reloc_op);
508 #endif /* RELOC_OP_P */
510 /* Maximum # digits needed to hold the largest sequence # */
511 #define ALPHA_RELOC_DIGITS 25
513 /* Structure to hold explict sequence information. */
514 struct alpha_reloc_tag
516 fixS *slaves; /* head of linked list of !literals */
517 segT segment; /* segment relocs are in or undefined_section*/
518 long sequence; /* sequence # */
519 unsigned n_master; /* # of literals */
520 unsigned n_slaves; /* # of lituses */
521 char multi_section_p; /* True if more than one section was used */
522 char string[1]; /* printable form of sequence to hash with */
525 /* Hash table to link up literals with the appropriate lituse */
526 static struct hash_control *alpha_literal_hash;
528 /* Sequence numbers for internal use by macros. */
529 static long next_sequence_num = -1;
531 /* A table of CPU names and opcode sets. */
533 static const struct cpu_type {
534 const char *name;
535 unsigned flags;
536 } cpu_types[] = {
537 /* Ad hoc convention: cpu number gets palcode, process code doesn't.
538 This supports usage under DU 4.0b that does ".arch ev4", and
539 usage in MILO that does -m21064. Probably something more
540 specific like -m21064-pal should be used, but oh well. */
542 { "21064", AXP_OPCODE_BASE|AXP_OPCODE_EV4 },
543 { "21064a", AXP_OPCODE_BASE|AXP_OPCODE_EV4 },
544 { "21066", AXP_OPCODE_BASE|AXP_OPCODE_EV4 },
545 { "21068", AXP_OPCODE_BASE|AXP_OPCODE_EV4 },
546 { "21164", AXP_OPCODE_BASE|AXP_OPCODE_EV5 },
547 { "21164a", AXP_OPCODE_BASE|AXP_OPCODE_EV5|AXP_OPCODE_BWX },
548 { "21164pc", (AXP_OPCODE_BASE|AXP_OPCODE_EV5|AXP_OPCODE_BWX
549 |AXP_OPCODE_MAX) },
550 { "21264", (AXP_OPCODE_BASE|AXP_OPCODE_EV6|AXP_OPCODE_BWX
551 |AXP_OPCODE_MAX|AXP_OPCODE_CIX) },
553 { "ev4", AXP_OPCODE_BASE },
554 { "ev45", AXP_OPCODE_BASE },
555 { "lca45", AXP_OPCODE_BASE },
556 { "ev5", AXP_OPCODE_BASE },
557 { "ev56", AXP_OPCODE_BASE|AXP_OPCODE_BWX },
558 { "pca56", AXP_OPCODE_BASE|AXP_OPCODE_BWX|AXP_OPCODE_MAX },
559 { "ev6", AXP_OPCODE_BASE|AXP_OPCODE_BWX|AXP_OPCODE_MAX|AXP_OPCODE_CIX },
561 { "all", AXP_OPCODE_BASE },
562 { 0, 0 }
565 /* The macro table */
567 static const struct alpha_macro alpha_macros[] = {
568 /* Load/Store macros */
569 { "lda", emit_lda, NULL,
570 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
571 { "ldah", emit_ldah, NULL,
572 { MACRO_IR, MACRO_EXP, MACRO_EOA } },
574 { "ldl", emit_ir_load, "ldl",
575 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
576 { "ldl_l", emit_ir_load, "ldl_l",
577 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
578 { "ldq", emit_ir_load, "ldq",
579 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
580 { "ldq_l", emit_ir_load, "ldq_l",
581 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
582 { "ldq_u", emit_ir_load, "ldq_u",
583 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
584 { "ldf", emit_loadstore, "ldf",
585 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
586 { "ldg", emit_loadstore, "ldg",
587 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
588 { "lds", emit_loadstore, "lds",
589 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
590 { "ldt", emit_loadstore, "ldt",
591 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
593 { "ldb", emit_ldX, (PTR) 0,
594 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
595 { "ldbu", emit_ldXu, (PTR) 0,
596 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
597 { "ldw", emit_ldX, (PTR) 1,
598 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
599 { "ldwu", emit_ldXu, (PTR) 1,
600 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
602 { "uldw", emit_uldX, (PTR) 1,
603 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
604 { "uldwu", emit_uldXu, (PTR) 1,
605 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
606 { "uldl", emit_uldX, (PTR) 2,
607 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
608 { "uldlu", emit_uldXu, (PTR) 2,
609 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
610 { "uldq", emit_uldXu, (PTR) 3,
611 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
613 { "ldgp", emit_ldgp, NULL,
614 { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA } },
616 { "ldi", emit_lda, NULL,
617 { MACRO_IR, MACRO_EXP, MACRO_EOA } },
618 { "ldil", emit_ldil, NULL,
619 { MACRO_IR, MACRO_EXP, MACRO_EOA } },
620 { "ldiq", emit_lda, NULL,
621 { MACRO_IR, MACRO_EXP, MACRO_EOA } },
622 #if 0
623 { "ldif" emit_ldiq, NULL,
624 { MACRO_FPR, MACRO_EXP, MACRO_EOA } },
625 { "ldid" emit_ldiq, NULL,
626 { MACRO_FPR, MACRO_EXP, MACRO_EOA } },
627 { "ldig" emit_ldiq, NULL,
628 { MACRO_FPR, MACRO_EXP, MACRO_EOA } },
629 { "ldis" emit_ldiq, NULL,
630 { MACRO_FPR, MACRO_EXP, MACRO_EOA } },
631 { "ldit" emit_ldiq, NULL,
632 { MACRO_FPR, MACRO_EXP, MACRO_EOA } },
633 #endif
635 { "stl", emit_loadstore, "stl",
636 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
637 { "stl_c", emit_loadstore, "stl_c",
638 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
639 { "stq", emit_loadstore, "stq",
640 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
641 { "stq_c", emit_loadstore, "stq_c",
642 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
643 { "stq_u", emit_loadstore, "stq_u",
644 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
645 { "stf", emit_loadstore, "stf",
646 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
647 { "stg", emit_loadstore, "stg",
648 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
649 { "sts", emit_loadstore, "sts",
650 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
651 { "stt", emit_loadstore, "stt",
652 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
654 { "stb", emit_stX, (PTR) 0,
655 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
656 { "stw", emit_stX, (PTR) 1,
657 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
658 { "ustw", emit_ustX, (PTR) 1,
659 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
660 { "ustl", emit_ustX, (PTR) 2,
661 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
662 { "ustq", emit_ustX, (PTR) 3,
663 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
665 /* Arithmetic macros */
666 #if 0
667 { "absl" emit_absl, 1, { IR } },
668 { "absl" emit_absl, 2, { IR, IR } },
669 { "absl" emit_absl, 2, { EXP, IR } },
670 { "absq" emit_absq, 1, { IR } },
671 { "absq" emit_absq, 2, { IR, IR } },
672 { "absq" emit_absq, 2, { EXP, IR } },
673 #endif
675 { "sextb", emit_sextX, (PTR) 0,
676 { MACRO_IR, MACRO_IR, MACRO_EOA,
677 MACRO_IR, MACRO_EOA,
678 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
679 { "sextw", emit_sextX, (PTR) 1,
680 { MACRO_IR, MACRO_IR, MACRO_EOA,
681 MACRO_IR, MACRO_EOA,
682 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
684 { "divl", emit_division, "__divl",
685 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
686 MACRO_IR, MACRO_IR, MACRO_EOA,
687 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
688 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
689 { "divlu", emit_division, "__divlu",
690 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
691 MACRO_IR, MACRO_IR, MACRO_EOA,
692 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
693 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
694 { "divq", emit_division, "__divq",
695 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
696 MACRO_IR, MACRO_IR, MACRO_EOA,
697 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
698 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
699 { "divqu", emit_division, "__divqu",
700 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
701 MACRO_IR, MACRO_IR, MACRO_EOA,
702 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
703 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
704 { "reml", emit_division, "__reml",
705 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
706 MACRO_IR, MACRO_IR, MACRO_EOA,
707 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
708 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
709 { "remlu", emit_division, "__remlu",
710 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
711 MACRO_IR, MACRO_IR, MACRO_EOA,
712 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
713 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
714 { "remq", emit_division, "__remq",
715 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
716 MACRO_IR, MACRO_IR, MACRO_EOA,
717 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
718 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
719 { "remqu", emit_division, "__remqu",
720 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
721 MACRO_IR, MACRO_IR, MACRO_EOA,
722 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
723 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
725 { "jsr", emit_jsrjmp, "jsr",
726 { MACRO_PIR, MACRO_EXP, MACRO_EOA,
727 MACRO_PIR, MACRO_EOA,
728 MACRO_IR, MACRO_EXP, MACRO_EOA,
729 MACRO_EXP, MACRO_EOA } },
730 { "jmp", emit_jsrjmp, "jmp",
731 { MACRO_PIR, MACRO_EXP, MACRO_EOA,
732 MACRO_PIR, MACRO_EOA,
733 MACRO_IR, MACRO_EXP, MACRO_EOA,
734 MACRO_EXP, MACRO_EOA } },
735 { "ret", emit_retjcr, "ret",
736 { MACRO_IR, MACRO_EXP, MACRO_EOA,
737 MACRO_IR, MACRO_EOA,
738 MACRO_PIR, MACRO_EXP, MACRO_EOA,
739 MACRO_PIR, MACRO_EOA,
740 MACRO_EXP, MACRO_EOA,
741 MACRO_EOA } },
742 { "jcr", emit_retjcr, "jcr",
743 { MACRO_IR, MACRO_EXP, MACRO_EOA,
744 MACRO_IR, MACRO_EOA,
745 MACRO_PIR, MACRO_EXP, MACRO_EOA,
746 MACRO_PIR, MACRO_EOA,
747 MACRO_EXP, MACRO_EOA,
748 MACRO_EOA } },
749 { "jsr_coroutine", emit_retjcr, "jcr",
750 { MACRO_IR, MACRO_EXP, MACRO_EOA,
751 MACRO_IR, MACRO_EOA,
752 MACRO_PIR, MACRO_EXP, MACRO_EOA,
753 MACRO_PIR, MACRO_EOA,
754 MACRO_EXP, MACRO_EOA,
755 MACRO_EOA } },
758 static const unsigned int alpha_num_macros
759 = sizeof (alpha_macros) / sizeof (*alpha_macros);
761 /* Public interface functions */
763 /* This function is called once, at assembler startup time. It sets
764 up all the tables, etc. that the MD part of the assembler will
765 need, that can be determined before arguments are parsed. */
767 void
768 md_begin ()
770 unsigned int i;
772 /* Verify that X_op field is wide enough. */
774 expressionS e;
775 e.X_op = O_max;
776 assert (e.X_op == O_max);
779 /* Create the opcode hash table */
781 alpha_opcode_hash = hash_new ();
782 for (i = 0; i < alpha_num_opcodes;)
784 const char *name, *retval, *slash;
786 name = alpha_opcodes[i].name;
787 retval = hash_insert (alpha_opcode_hash, name, (PTR) &alpha_opcodes[i]);
788 if (retval)
789 as_fatal (_("internal error: can't hash opcode `%s': %s"),
790 name, retval);
792 /* Some opcodes include modifiers of various sorts with a "/mod"
793 syntax, like the architecture manual suggests. However, for
794 use with gcc at least, we also need access to those same opcodes
795 without the "/". */
797 if ((slash = strchr (name, '/')) != NULL)
799 char *p = xmalloc (strlen (name));
800 memcpy (p, name, slash - name);
801 strcpy (p + (slash - name), slash + 1);
803 (void) hash_insert (alpha_opcode_hash, p, (PTR) &alpha_opcodes[i]);
804 /* Ignore failures -- the opcode table does duplicate some
805 variants in different forms, like "hw_stq" and "hw_st/q". */
808 while (++i < alpha_num_opcodes
809 && (alpha_opcodes[i].name == name
810 || !strcmp (alpha_opcodes[i].name, name)))
811 continue;
814 /* Create the macro hash table */
816 alpha_macro_hash = hash_new ();
817 for (i = 0; i < alpha_num_macros;)
819 const char *name, *retval;
821 name = alpha_macros[i].name;
822 retval = hash_insert (alpha_macro_hash, name, (PTR) &alpha_macros[i]);
823 if (retval)
824 as_fatal (_("internal error: can't hash macro `%s': %s"),
825 name, retval);
827 while (++i < alpha_num_macros
828 && (alpha_macros[i].name == name
829 || !strcmp (alpha_macros[i].name, name)))
830 continue;
833 /* Construct symbols for each of the registers */
835 for (i = 0; i < 32; ++i)
837 char name[4];
838 sprintf (name, "$%d", i);
839 alpha_register_table[i] = symbol_create (name, reg_section, i,
840 &zero_address_frag);
842 for (; i < 64; ++i)
844 char name[5];
845 sprintf (name, "$f%d", i - 32);
846 alpha_register_table[i] = symbol_create (name, reg_section, i,
847 &zero_address_frag);
850 /* Create the special symbols and sections we'll be using */
852 /* So .sbss will get used for tiny objects. */
853 bfd_set_gp_size (stdoutput, g_switch_value);
855 #ifdef OBJ_ECOFF
856 create_literal_section (".lita", &alpha_lita_section, &alpha_lita_symbol);
858 /* For handling the GP, create a symbol that won't be output in the
859 symbol table. We'll edit it out of relocs later. */
860 alpha_gp_symbol = symbol_create ("<GP value>", alpha_lita_section, 0x8000,
861 &zero_address_frag);
862 #endif
864 #ifdef OBJ_EVAX
865 create_literal_section (".link", &alpha_link_section, &alpha_link_symbol);
866 #endif
868 #ifdef OBJ_ELF
869 if (ECOFF_DEBUGGING)
871 segT sec = subseg_new (".mdebug", (subsegT) 0);
872 bfd_set_section_flags (stdoutput, sec, SEC_HAS_CONTENTS | SEC_READONLY);
873 bfd_set_section_alignment (stdoutput, sec, 3);
875 #endif /* OBJ_ELF */
877 /* Create literal lookup hash table. */
878 alpha_literal_hash = hash_new ();
880 subseg_set (text_section, 0);
883 /* The public interface to the instruction assembler. */
885 void
886 md_assemble (str)
887 char *str;
889 char opname[32]; /* current maximum is 13 */
890 expressionS tok[MAX_INSN_ARGS];
891 int ntok, trunclen;
892 size_t opnamelen;
894 /* split off the opcode */
895 opnamelen = strspn (str, "abcdefghijklmnopqrstuvwxyz_/46819");
896 trunclen = (opnamelen < sizeof (opname) - 1
897 ? opnamelen
898 : sizeof (opname) - 1);
899 memcpy (opname, str, trunclen);
900 opname[trunclen] = '\0';
902 /* tokenize the rest of the line */
903 if ((ntok = tokenize_arguments (str + opnamelen, tok, MAX_INSN_ARGS)) < 0)
905 if (ntok != TOKENIZE_ERROR_REPORT)
906 as_bad (_("syntax error"));
908 return;
911 /* finish it off */
912 assemble_tokens (opname, tok, ntok, alpha_macros_on);
915 /* Round up a section's size to the appropriate boundary. */
917 valueT
918 md_section_align (seg, size)
919 segT seg;
920 valueT size;
922 int align = bfd_get_section_alignment (stdoutput, seg);
923 valueT mask = ((valueT) 1 << align) - 1;
925 return (size + mask) & ~mask;
928 /* Turn a string in input_line_pointer into a floating point constant
929 of type TYPE, and store the appropriate bytes in *LITP. The number
930 of LITTLENUMS emitted is stored in *SIZEP. An error message is
931 returned, or NULL on OK. */
933 /* Equal to MAX_PRECISION in atof-ieee.c */
934 #define MAX_LITTLENUMS 6
936 extern char *vax_md_atof PARAMS ((int, char *, int *));
938 char *
939 md_atof (type, litP, sizeP)
940 char type;
941 char *litP;
942 int *sizeP;
944 int prec;
945 LITTLENUM_TYPE words[MAX_LITTLENUMS];
946 LITTLENUM_TYPE *wordP;
947 char *t;
949 switch (type)
951 /* VAX floats */
952 case 'G':
953 /* VAX md_atof doesn't like "G" for some reason. */
954 type = 'g';
955 case 'F':
956 case 'D':
957 return vax_md_atof (type, litP, sizeP);
959 /* IEEE floats */
960 case 'f':
961 prec = 2;
962 break;
964 case 'd':
965 prec = 4;
966 break;
968 case 'x':
969 case 'X':
970 prec = 6;
971 break;
973 case 'p':
974 case 'P':
975 prec = 6;
976 break;
978 default:
979 *sizeP = 0;
980 return _("Bad call to MD_ATOF()");
982 t = atof_ieee (input_line_pointer, type, words);
983 if (t)
984 input_line_pointer = t;
985 *sizeP = prec * sizeof (LITTLENUM_TYPE);
987 for (wordP = words + prec - 1; prec--;)
989 md_number_to_chars (litP, (long) (*wordP--), sizeof (LITTLENUM_TYPE));
990 litP += sizeof (LITTLENUM_TYPE);
993 return 0;
996 /* Take care of the target-specific command-line options. */
999 md_parse_option (c, arg)
1000 int c;
1001 char *arg;
1003 switch (c)
1005 case 'F':
1006 alpha_nofloats_on = 1;
1007 break;
1009 case OPTION_32ADDR:
1010 alpha_addr32_on = 1;
1011 break;
1013 case 'g':
1014 alpha_debug = 1;
1015 break;
1017 case 'G':
1018 g_switch_value = atoi (arg);
1019 break;
1021 case 'm':
1023 const struct cpu_type *p;
1024 for (p = cpu_types; p->name; ++p)
1025 if (strcmp (arg, p->name) == 0)
1027 alpha_target_name = p->name, alpha_target = p->flags;
1028 goto found;
1030 as_warn (_("Unknown CPU identifier `%s'"), arg);
1031 found:;
1033 break;
1035 #ifdef OBJ_EVAX
1036 case '+': /* For g++. Hash any name > 63 chars long. */
1037 alpha_flag_hash_long_names = 1;
1038 break;
1040 case 'H': /* Show new symbol after hash truncation */
1041 alpha_flag_show_after_trunc = 1;
1042 break;
1044 case 'h': /* for gnu-c/vax compatibility. */
1045 break;
1046 #endif
1048 case OPTION_RELAX:
1049 alpha_flag_relax = 1;
1050 break;
1052 #ifdef OBJ_ELF
1053 case OPTION_MDEBUG:
1054 alpha_flag_mdebug = 1;
1055 break;
1056 case OPTION_NO_MDEBUG:
1057 alpha_flag_mdebug = 0;
1058 break;
1059 #endif
1061 default:
1062 return 0;
1065 return 1;
1068 /* Print a description of the command-line options that we accept. */
1070 void
1071 md_show_usage (stream)
1072 FILE *stream;
1074 fputs (_("\
1075 Alpha options:\n\
1076 -32addr treat addresses as 32-bit values\n\
1077 -F lack floating point instructions support\n\
1078 -mev4 | -mev45 | -mev5 | -mev56 | -mpca56 | -mev6 | -mall\n\
1079 specify variant of Alpha architecture\n\
1080 -m21064 | -m21066 | -m21164 | -m21164a | -m21164pc | -m21264\n\
1081 these variants include PALcode opcodes\n"),
1082 stream);
1083 #ifdef OBJ_EVAX
1084 fputs (_("\
1085 VMS options:\n\
1086 -+ hash encode (don't truncate) names longer than 64 characters\n\
1087 -H show new symbol after hash truncation\n"),
1088 stream);
1089 #endif
1092 /* Decide from what point a pc-relative relocation is relative to,
1093 relative to the pc-relative fixup. Er, relatively speaking. */
1095 long
1096 md_pcrel_from (fixP)
1097 fixS *fixP;
1099 valueT addr = fixP->fx_where + fixP->fx_frag->fr_address;
1100 switch (fixP->fx_r_type)
1102 case BFD_RELOC_ALPHA_GPDISP:
1103 case BFD_RELOC_ALPHA_GPDISP_HI16:
1104 case BFD_RELOC_ALPHA_GPDISP_LO16:
1105 return addr;
1106 default:
1107 return fixP->fx_size + addr;
1111 /* Attempt to simplify or even eliminate a fixup. The return value is
1112 ignored; perhaps it was once meaningful, but now it is historical.
1113 To indicate that a fixup has been eliminated, set fixP->fx_done.
1115 For ELF, here it is that we transform the GPDISP_HI16 reloc we used
1116 internally into the GPDISP reloc used externally. We had to do
1117 this so that we'd have the GPDISP_LO16 reloc as a tag to compute
1118 the distance to the "lda" instruction for setting the addend to
1119 GPDISP. */
1121 void
1122 md_apply_fix3 (fixP, valP, seg)
1123 fixS *fixP;
1124 valueT * valP;
1125 segT seg;
1127 char * const fixpos = fixP->fx_frag->fr_literal + fixP->fx_where;
1128 valueT value = * valP;
1129 unsigned image, size;
1131 switch (fixP->fx_r_type)
1133 /* The GPDISP relocations are processed internally with a symbol
1134 referring to the current function; we need to drop in a value
1135 which, when added to the address of the start of the function,
1136 gives the desired GP. */
1137 case BFD_RELOC_ALPHA_GPDISP_HI16:
1139 fixS *next = fixP->fx_next;
1141 /* With user-specified !gpdisp relocations, we can be missing
1142 the matching LO16 reloc. We will have already issued an
1143 error message. */
1144 if (next)
1145 fixP->fx_offset = (next->fx_frag->fr_address + next->fx_where
1146 - fixP->fx_frag->fr_address - fixP->fx_where);
1148 value = (value - sign_extend_16 (value)) >> 16;
1150 #ifdef OBJ_ELF
1151 fixP->fx_r_type = BFD_RELOC_ALPHA_GPDISP;
1152 #endif
1153 goto do_reloc_gp;
1155 case BFD_RELOC_ALPHA_GPDISP_LO16:
1156 value = sign_extend_16 (value);
1157 fixP->fx_offset = 0;
1158 #ifdef OBJ_ELF
1159 fixP->fx_done = 1;
1160 #endif
1162 do_reloc_gp:
1163 fixP->fx_addsy = section_symbol (seg);
1164 md_number_to_chars (fixpos, value, 2);
1165 break;
1167 case BFD_RELOC_16:
1168 if (fixP->fx_pcrel)
1169 fixP->fx_r_type = BFD_RELOC_16_PCREL;
1170 size = 2;
1171 goto do_reloc_xx;
1172 case BFD_RELOC_32:
1173 if (fixP->fx_pcrel)
1174 fixP->fx_r_type = BFD_RELOC_32_PCREL;
1175 size = 4;
1176 goto do_reloc_xx;
1177 case BFD_RELOC_64:
1178 if (fixP->fx_pcrel)
1179 fixP->fx_r_type = BFD_RELOC_64_PCREL;
1180 size = 8;
1181 do_reloc_xx:
1182 if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0)
1184 md_number_to_chars (fixpos, value, size);
1185 goto done;
1187 return;
1189 #ifdef OBJ_ECOFF
1190 case BFD_RELOC_GPREL32:
1191 assert (fixP->fx_subsy == alpha_gp_symbol);
1192 fixP->fx_subsy = 0;
1193 /* FIXME: inherited this obliviousness of `value' -- why? */
1194 md_number_to_chars (fixpos, -alpha_gp_value, 4);
1195 break;
1196 #else
1197 case BFD_RELOC_GPREL32:
1198 #endif
1199 case BFD_RELOC_GPREL16:
1200 case BFD_RELOC_ALPHA_GPREL_HI16:
1201 case BFD_RELOC_ALPHA_GPREL_LO16:
1202 return;
1204 case BFD_RELOC_23_PCREL_S2:
1205 if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0)
1207 image = bfd_getl32 (fixpos);
1208 image = (image & ~0x1FFFFF) | ((value >> 2) & 0x1FFFFF);
1209 goto write_done;
1211 return;
1213 case BFD_RELOC_ALPHA_HINT:
1214 if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0)
1216 image = bfd_getl32 (fixpos);
1217 image = (image & ~0x3FFF) | ((value >> 2) & 0x3FFF);
1218 goto write_done;
1220 return;
1222 #ifdef OBJ_ECOFF
1223 case BFD_RELOC_ALPHA_LITERAL:
1224 md_number_to_chars (fixpos, value, 2);
1225 return;
1226 #endif
1227 case BFD_RELOC_ALPHA_ELF_LITERAL:
1228 case BFD_RELOC_ALPHA_LITUSE:
1229 case BFD_RELOC_ALPHA_LINKAGE:
1230 case BFD_RELOC_ALPHA_CODEADDR:
1231 return;
1233 case BFD_RELOC_VTABLE_INHERIT:
1234 case BFD_RELOC_VTABLE_ENTRY:
1235 return;
1237 default:
1239 const struct alpha_operand *operand;
1241 if ((int) fixP->fx_r_type >= 0)
1242 as_fatal (_("unhandled relocation type %s"),
1243 bfd_get_reloc_code_name (fixP->fx_r_type));
1245 assert (-(int) fixP->fx_r_type < (int) alpha_num_operands);
1246 operand = &alpha_operands[-(int) fixP->fx_r_type];
1248 /* The rest of these fixups only exist internally during symbol
1249 resolution and have no representation in the object file.
1250 Therefore they must be completely resolved as constants. */
1252 if (fixP->fx_addsy != 0
1253 && S_GET_SEGMENT (fixP->fx_addsy) != absolute_section)
1254 as_bad_where (fixP->fx_file, fixP->fx_line,
1255 _("non-absolute expression in constant field"));
1257 image = bfd_getl32 (fixpos);
1258 image = insert_operand (image, operand, (offsetT) value,
1259 fixP->fx_file, fixP->fx_line);
1261 goto write_done;
1264 if (fixP->fx_addsy != 0 || fixP->fx_pcrel != 0)
1265 return;
1266 else
1268 as_warn_where (fixP->fx_file, fixP->fx_line,
1269 _("type %d reloc done?\n"), (int) fixP->fx_r_type);
1270 goto done;
1273 write_done:
1274 md_number_to_chars (fixpos, image, 4);
1276 done:
1277 fixP->fx_done = 1;
1280 /* Look for a register name in the given symbol. */
1282 symbolS *
1283 md_undefined_symbol (name)
1284 char *name;
1286 if (*name == '$')
1288 int is_float = 0, num;
1290 switch (*++name)
1292 case 'f':
1293 if (name[1] == 'p' && name[2] == '\0')
1294 return alpha_register_table[AXP_REG_FP];
1295 is_float = 32;
1296 /* FALLTHRU */
1298 case 'r':
1299 if (!ISDIGIT (*++name))
1300 break;
1301 /* FALLTHRU */
1303 case '0': case '1': case '2': case '3': case '4':
1304 case '5': case '6': case '7': case '8': case '9':
1305 if (name[1] == '\0')
1306 num = name[0] - '0';
1307 else if (name[0] != '0' && ISDIGIT (name[1]) && name[2] == '\0')
1309 num = (name[0] - '0') * 10 + name[1] - '0';
1310 if (num >= 32)
1311 break;
1313 else
1314 break;
1316 if (!alpha_noat_on && (num + is_float) == AXP_REG_AT)
1317 as_warn (_("Used $at without \".set noat\""));
1318 return alpha_register_table[num + is_float];
1320 case 'a':
1321 if (name[1] == 't' && name[2] == '\0')
1323 if (!alpha_noat_on)
1324 as_warn (_("Used $at without \".set noat\""));
1325 return alpha_register_table[AXP_REG_AT];
1327 break;
1329 case 'g':
1330 if (name[1] == 'p' && name[2] == '\0')
1331 return alpha_register_table[alpha_gp_register];
1332 break;
1334 case 's':
1335 if (name[1] == 'p' && name[2] == '\0')
1336 return alpha_register_table[AXP_REG_SP];
1337 break;
1340 return NULL;
1343 #ifdef OBJ_ECOFF
1344 /* @@@ Magic ECOFF bits. */
1346 void
1347 alpha_frob_ecoff_data ()
1349 select_gp_value ();
1350 /* $zero and $f31 are read-only */
1351 alpha_gprmask &= ~1;
1352 alpha_fprmask &= ~1;
1354 #endif
1356 /* Hook to remember a recently defined label so that the auto-align
1357 code can adjust the symbol after we know what alignment will be
1358 required. */
1360 void
1361 alpha_define_label (sym)
1362 symbolS *sym;
1364 alpha_insn_label = sym;
1367 /* Return true if we must always emit a reloc for a type and false if
1368 there is some hope of resolving it at assembly time. */
1371 alpha_force_relocation (f)
1372 fixS *f;
1374 if (alpha_flag_relax)
1375 return 1;
1377 switch (f->fx_r_type)
1379 case BFD_RELOC_ALPHA_GPDISP_HI16:
1380 case BFD_RELOC_ALPHA_GPDISP_LO16:
1381 case BFD_RELOC_ALPHA_GPDISP:
1382 case BFD_RELOC_ALPHA_LITERAL:
1383 case BFD_RELOC_ALPHA_ELF_LITERAL:
1384 case BFD_RELOC_ALPHA_LITUSE:
1385 case BFD_RELOC_GPREL16:
1386 case BFD_RELOC_GPREL32:
1387 case BFD_RELOC_ALPHA_GPREL_HI16:
1388 case BFD_RELOC_ALPHA_GPREL_LO16:
1389 case BFD_RELOC_ALPHA_LINKAGE:
1390 case BFD_RELOC_ALPHA_CODEADDR:
1391 case BFD_RELOC_VTABLE_INHERIT:
1392 case BFD_RELOC_VTABLE_ENTRY:
1393 return 1;
1395 case BFD_RELOC_23_PCREL_S2:
1396 case BFD_RELOC_32:
1397 case BFD_RELOC_64:
1398 case BFD_RELOC_ALPHA_HINT:
1399 return 0;
1401 default:
1402 assert ((int) f->fx_r_type < 0
1403 && -(int) f->fx_r_type < (int) alpha_num_operands);
1404 return 0;
1408 /* Return true if we can partially resolve a relocation now. */
1411 alpha_fix_adjustable (f)
1412 fixS *f;
1414 #ifdef OBJ_ELF
1415 /* Prevent all adjustments to global symbols */
1416 if (S_IS_EXTERN (f->fx_addsy) || S_IS_WEAK (f->fx_addsy))
1417 return 0;
1418 #endif
1420 /* Are there any relocation types for which we must generate a reloc
1421 but we can adjust the values contained within it? */
1422 switch (f->fx_r_type)
1424 case BFD_RELOC_ALPHA_GPDISP_HI16:
1425 case BFD_RELOC_ALPHA_GPDISP_LO16:
1426 case BFD_RELOC_ALPHA_GPDISP:
1427 return 0;
1429 case BFD_RELOC_ALPHA_LITERAL:
1430 case BFD_RELOC_ALPHA_ELF_LITERAL:
1431 case BFD_RELOC_ALPHA_LITUSE:
1432 case BFD_RELOC_ALPHA_LINKAGE:
1433 case BFD_RELOC_ALPHA_CODEADDR:
1434 return 1;
1436 case BFD_RELOC_VTABLE_ENTRY:
1437 case BFD_RELOC_VTABLE_INHERIT:
1438 return 0;
1440 case BFD_RELOC_GPREL16:
1441 case BFD_RELOC_GPREL32:
1442 case BFD_RELOC_ALPHA_GPREL_HI16:
1443 case BFD_RELOC_ALPHA_GPREL_LO16:
1444 case BFD_RELOC_23_PCREL_S2:
1445 case BFD_RELOC_32:
1446 case BFD_RELOC_64:
1447 case BFD_RELOC_ALPHA_HINT:
1448 return 1;
1450 default:
1451 assert ((int) f->fx_r_type < 0
1452 && - (int) f->fx_r_type < (int) alpha_num_operands);
1453 return 1;
1455 /*NOTREACHED*/
1458 /* Generate the BFD reloc to be stuck in the object file from the
1459 fixup used internally in the assembler. */
1461 arelent *
1462 tc_gen_reloc (sec, fixp)
1463 asection *sec ATTRIBUTE_UNUSED;
1464 fixS *fixp;
1466 arelent *reloc;
1468 reloc = (arelent *) xmalloc (sizeof (arelent));
1469 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
1470 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
1471 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
1473 /* Make sure none of our internal relocations make it this far.
1474 They'd better have been fully resolved by this point. */
1475 assert ((int) fixp->fx_r_type > 0);
1477 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
1478 if (reloc->howto == NULL)
1480 as_bad_where (fixp->fx_file, fixp->fx_line,
1481 _("cannot represent `%s' relocation in object file"),
1482 bfd_get_reloc_code_name (fixp->fx_r_type));
1483 return NULL;
1486 if (!fixp->fx_pcrel != !reloc->howto->pc_relative)
1488 as_fatal (_("internal error? cannot generate `%s' relocation"),
1489 bfd_get_reloc_code_name (fixp->fx_r_type));
1491 assert (!fixp->fx_pcrel == !reloc->howto->pc_relative);
1493 #ifdef OBJ_ECOFF
1494 if (fixp->fx_r_type == BFD_RELOC_ALPHA_LITERAL)
1496 /* fake out bfd_perform_relocation. sigh */
1497 reloc->addend = -alpha_gp_value;
1499 else
1500 #endif
1502 reloc->addend = fixp->fx_offset;
1503 #ifdef OBJ_ELF
1505 * Ohhh, this is ugly. The problem is that if this is a local global
1506 * symbol, the relocation will entirely be performed at link time, not
1507 * at assembly time. bfd_perform_reloc doesn't know about this sort
1508 * of thing, and as a result we need to fake it out here.
1510 if ((S_IS_EXTERN (fixp->fx_addsy) || S_IS_WEAK (fixp->fx_addsy))
1511 && !S_IS_COMMON (fixp->fx_addsy))
1512 reloc->addend -= symbol_get_bfdsym (fixp->fx_addsy)->value;
1513 #endif
1516 return reloc;
1519 /* Parse a register name off of the input_line and return a register
1520 number. Gets md_undefined_symbol above to do the register name
1521 matching for us.
1523 Only called as a part of processing the ECOFF .frame directive. */
1526 tc_get_register (frame)
1527 int frame ATTRIBUTE_UNUSED;
1529 int framereg = AXP_REG_SP;
1531 SKIP_WHITESPACE ();
1532 if (*input_line_pointer == '$')
1534 char *s = input_line_pointer;
1535 char c = get_symbol_end ();
1536 symbolS *sym = md_undefined_symbol (s);
1538 *strchr (s, '\0') = c;
1539 if (sym && (framereg = S_GET_VALUE (sym)) <= 31)
1540 goto found;
1542 as_warn (_("frame reg expected, using $%d."), framereg);
1544 found:
1545 note_gpreg (framereg);
1546 return framereg;
1549 /* This is called before the symbol table is processed. In order to
1550 work with gcc when using mips-tfile, we must keep all local labels.
1551 However, in other cases, we want to discard them. If we were
1552 called with -g, but we didn't see any debugging information, it may
1553 mean that gcc is smuggling debugging information through to
1554 mips-tfile, in which case we must generate all local labels. */
1556 #ifdef OBJ_ECOFF
1558 void
1559 alpha_frob_file_before_adjust ()
1561 if (alpha_debug != 0
1562 && ! ecoff_debugging_seen)
1563 flag_keep_locals = 1;
1566 #endif /* OBJ_ECOFF */
1568 static struct alpha_reloc_tag *
1569 get_alpha_reloc_tag (sequence)
1570 long sequence;
1572 char buffer[ALPHA_RELOC_DIGITS];
1573 struct alpha_reloc_tag *info;
1575 sprintf (buffer, "!%ld", sequence);
1577 info = (struct alpha_reloc_tag *) hash_find (alpha_literal_hash, buffer);
1578 if (! info)
1580 size_t len = strlen (buffer);
1581 const char *errmsg;
1583 info = (struct alpha_reloc_tag *)
1584 xcalloc (sizeof (struct alpha_reloc_tag) + len, 1);
1586 info->segment = now_seg;
1587 info->sequence = sequence;
1588 strcpy (info->string, buffer);
1589 errmsg = hash_insert (alpha_literal_hash, info->string, (PTR) info);
1590 if (errmsg)
1591 as_fatal (errmsg);
1594 return info;
1597 /* Before the relocations are written, reorder them, so that user
1598 supplied !lituse relocations follow the appropriate !literal
1599 relocations, and similarly for !gpdisp relocations. */
1601 void
1602 alpha_adjust_symtab ()
1604 if (alpha_literal_hash)
1605 bfd_map_over_sections (stdoutput, alpha_adjust_symtab_relocs, NULL);
1608 static void
1609 alpha_adjust_symtab_relocs (abfd, sec, ptr)
1610 bfd *abfd ATTRIBUTE_UNUSED;
1611 asection *sec;
1612 PTR ptr ATTRIBUTE_UNUSED;
1614 segment_info_type *seginfo = seg_info (sec);
1615 fixS **prevP;
1616 fixS *fixp;
1617 fixS *next;
1618 fixS *slave;
1619 unsigned long n_slaves = 0;
1621 /* If seginfo is NULL, we did not create this section; don't do
1622 anything with it. By using a pointer to a pointer, we can update
1623 the links in place. */
1624 if (seginfo == NULL)
1625 return;
1627 /* If there are no relocations, skip the section. */
1628 if (! seginfo->fix_root)
1629 return;
1631 /* First rebuild the fixup chain without the expicit lituse and
1632 gpdisp_lo16 relocs. */
1633 prevP = &seginfo->fix_root;
1634 for (fixp = seginfo->fix_root; fixp; fixp = next)
1636 next = fixp->fx_next;
1637 fixp->fx_next = (fixS *) 0;
1639 switch (fixp->fx_r_type)
1641 case BFD_RELOC_ALPHA_LITUSE:
1642 n_slaves++;
1643 if (fixp->tc_fix_data.info->n_master == 0)
1644 as_bad_where (fixp->fx_file, fixp->fx_line,
1645 _("No !literal!%ld was found"),
1646 fixp->tc_fix_data.info->sequence);
1647 break;
1649 case BFD_RELOC_ALPHA_GPDISP_LO16:
1650 n_slaves++;
1651 if (fixp->tc_fix_data.info->n_master == 0)
1652 as_bad_where (fixp->fx_file, fixp->fx_line,
1653 _("No ldah !gpdisp!%ld was found"),
1654 fixp->tc_fix_data.info->sequence);
1655 break;
1657 default:
1658 *prevP = fixp;
1659 prevP = &fixp->fx_next;
1660 break;
1664 /* If there were any dependent relocations, go and add them back to
1665 the chain. They are linked through the next_reloc field in
1666 reverse order, so as we go through the next_reloc chain, we
1667 effectively reverse the chain once again.
1669 Except if there is more than one !literal for a given sequence
1670 number. In that case, the programmer and/or compiler is not sure
1671 how control flows from literal to lituse, and we can't be sure to
1672 get the relaxation correct.
1674 ??? Well, actually we could, if there are enough lituses such that
1675 we can make each literal have at least one of each lituse type
1676 present. Not implemented.
1678 Also suppress the optimization if the !literals/!lituses are spread
1679 in different segments. This can happen with "intersting" uses of
1680 inline assembly; examples are present in the Linux kernel semaphores. */
1682 for (fixp = seginfo->fix_root; fixp; fixp = next)
1684 next = fixp->fx_next;
1685 switch (fixp->fx_r_type)
1687 case BFD_RELOC_ALPHA_ELF_LITERAL:
1688 if (fixp->tc_fix_data.info->n_master == 1
1689 && ! fixp->tc_fix_data.info->multi_section_p)
1691 for (slave = fixp->tc_fix_data.info->slaves;
1692 slave != (fixS *) 0;
1693 slave = slave->tc_fix_data.next_reloc)
1695 slave->fx_next = fixp->fx_next;
1696 fixp->fx_next = slave;
1699 break;
1701 case BFD_RELOC_ALPHA_GPDISP_HI16:
1702 if (fixp->tc_fix_data.info->n_slaves == 0)
1703 as_bad_where (fixp->fx_file, fixp->fx_line,
1704 _("No lda !gpdisp!%ld was found"),
1705 fixp->tc_fix_data.info->sequence);
1706 else
1708 slave = fixp->tc_fix_data.info->slaves;
1709 slave->fx_next = next;
1710 fixp->fx_next = slave;
1712 break;
1714 default:
1715 break;
1720 #ifdef DEBUG_ALPHA
1721 static void
1722 debug_exp (tok, ntok)
1723 expressionS tok[];
1724 int ntok;
1726 int i;
1728 fprintf (stderr, "debug_exp: %d tokens", ntok);
1729 for (i = 0; i < ntok; i++)
1731 expressionS *t = &tok[i];
1732 const char *name;
1733 switch (t->X_op)
1735 default: name = "unknown"; break;
1736 case O_illegal: name = "O_illegal"; break;
1737 case O_absent: name = "O_absent"; break;
1738 case O_constant: name = "O_constant"; break;
1739 case O_symbol: name = "O_symbol"; break;
1740 case O_symbol_rva: name = "O_symbol_rva"; break;
1741 case O_register: name = "O_register"; break;
1742 case O_big: name = "O_big"; break;
1743 case O_uminus: name = "O_uminus"; break;
1744 case O_bit_not: name = "O_bit_not"; break;
1745 case O_logical_not: name = "O_logical_not"; break;
1746 case O_multiply: name = "O_multiply"; break;
1747 case O_divide: name = "O_divide"; break;
1748 case O_modulus: name = "O_modulus"; break;
1749 case O_left_shift: name = "O_left_shift"; break;
1750 case O_right_shift: name = "O_right_shift"; break;
1751 case O_bit_inclusive_or: name = "O_bit_inclusive_or"; break;
1752 case O_bit_or_not: name = "O_bit_or_not"; break;
1753 case O_bit_exclusive_or: name = "O_bit_exclusive_or"; break;
1754 case O_bit_and: name = "O_bit_and"; break;
1755 case O_add: name = "O_add"; break;
1756 case O_subtract: name = "O_subtract"; break;
1757 case O_eq: name = "O_eq"; break;
1758 case O_ne: name = "O_ne"; break;
1759 case O_lt: name = "O_lt"; break;
1760 case O_le: name = "O_le"; break;
1761 case O_ge: name = "O_ge"; break;
1762 case O_gt: name = "O_gt"; break;
1763 case O_logical_and: name = "O_logical_and"; break;
1764 case O_logical_or: name = "O_logical_or"; break;
1765 case O_index: name = "O_index"; break;
1766 case O_pregister: name = "O_pregister"; break;
1767 case O_cpregister: name = "O_cpregister"; break;
1768 case O_literal: name = "O_literal"; break;
1769 case O_lituse_base: name = "O_lituse_base"; break;
1770 case O_lituse_bytoff: name = "O_lituse_bytoff"; break;
1771 case O_lituse_jsr: name = "O_lituse_jsr"; break;
1772 case O_gpdisp: name = "O_gpdisp"; break;
1773 case O_gprelhigh: name = "O_gprelhigh"; break;
1774 case O_gprellow: name = "O_gprellow"; break;
1775 case O_gprel: name = "O_gprel"; break;
1776 case O_md11: name = "O_md11"; break;
1777 case O_md12: name = "O_md12"; break;
1778 case O_md13: name = "O_md13"; break;
1779 case O_md14: name = "O_md14"; break;
1780 case O_md15: name = "O_md15"; break;
1781 case O_md16: name = "O_md16"; break;
1784 fprintf (stderr, ", %s(%s, %s, %d)", name,
1785 (t->X_add_symbol) ? S_GET_NAME (t->X_add_symbol) : "--",
1786 (t->X_op_symbol) ? S_GET_NAME (t->X_op_symbol) : "--",
1787 (int) t->X_add_number);
1789 fprintf (stderr, "\n");
1790 fflush (stderr);
1792 #endif
1794 /* Parse the arguments to an opcode. */
1796 static int
1797 tokenize_arguments (str, tok, ntok)
1798 char *str;
1799 expressionS tok[];
1800 int ntok;
1802 expressionS *end_tok = tok + ntok;
1803 char *old_input_line_pointer;
1804 int saw_comma = 0, saw_arg = 0;
1805 #ifdef DEBUG_ALPHA
1806 expressionS *orig_tok = tok;
1807 #endif
1808 char *p;
1809 const struct alpha_reloc_op_tag *r;
1810 int c, i;
1811 size_t len;
1812 int reloc_found_p = 0;
1814 memset (tok, 0, sizeof (*tok) * ntok);
1816 /* Save and restore input_line_pointer around this function */
1817 old_input_line_pointer = input_line_pointer;
1818 input_line_pointer = str;
1820 #ifdef RELOC_OP_P
1821 /* ??? Wrest control of ! away from the regular expression parser. */
1822 is_end_of_line[(unsigned char) '!'] = 1;
1823 #endif
1825 while (tok < end_tok && *input_line_pointer)
1827 SKIP_WHITESPACE ();
1828 switch (*input_line_pointer)
1830 case '\0':
1831 goto fini;
1833 #ifdef RELOC_OP_P
1834 case '!':
1835 /* A relocation operand can be placed after the normal operand on an
1836 assembly language statement, and has the following form:
1837 !relocation_type!sequence_number. */
1838 if (reloc_found_p)
1839 { /* only support one relocation op per insn */
1840 as_bad (_("More than one relocation op per insn"));
1841 goto err_report;
1844 if (!saw_arg)
1845 goto err;
1847 ++input_line_pointer;
1848 SKIP_WHITESPACE ();
1849 p = input_line_pointer;
1850 c = get_symbol_end ();
1852 /* Parse !relocation_type */
1853 len = input_line_pointer - p;
1854 if (len == 0)
1856 as_bad (_("No relocation operand"));
1857 goto err_report;
1860 r = &alpha_reloc_op[0];
1861 for (i = alpha_num_reloc_op - 1; i >= 0; i--, r++)
1862 if (len == r->length && memcmp (p, r->name, len) == 0)
1863 break;
1864 if (i < 0)
1866 as_bad (_("Unknown relocation operand: !%s"), p);
1867 goto err_report;
1870 *input_line_pointer = c;
1871 SKIP_WHITESPACE ();
1872 if (*input_line_pointer != '!')
1874 if (r->require_seq)
1876 as_bad (_("no sequence number after !%s"), p);
1877 goto err_report;
1880 tok->X_add_number = 0;
1882 else
1884 if (! r->allow_seq)
1886 as_bad (_("!%s does not use a sequence number"), p);
1887 goto err_report;
1890 input_line_pointer++;
1892 /* Parse !sequence_number */
1893 expression (tok);
1894 if (tok->X_op != O_constant || tok->X_add_number <= 0)
1896 as_bad (_("Bad sequence number: !%s!%s"),
1897 r->name, input_line_pointer);
1898 goto err_report;
1902 tok->X_op = r->op;
1903 reloc_found_p = 1;
1904 ++tok;
1905 break;
1906 #endif /* RELOC_OP_P */
1908 case ',':
1909 ++input_line_pointer;
1910 if (saw_comma || !saw_arg)
1911 goto err;
1912 saw_comma = 1;
1913 break;
1915 case '(':
1917 char *hold = input_line_pointer++;
1919 /* First try for parenthesized register ... */
1920 expression (tok);
1921 if (*input_line_pointer == ')' && tok->X_op == O_register)
1923 tok->X_op = (saw_comma ? O_cpregister : O_pregister);
1924 saw_comma = 0;
1925 saw_arg = 1;
1926 ++input_line_pointer;
1927 ++tok;
1928 break;
1931 /* ... then fall through to plain expression */
1932 input_line_pointer = hold;
1935 default:
1936 if (saw_arg && !saw_comma)
1937 goto err;
1939 expression (tok);
1940 if (tok->X_op == O_illegal || tok->X_op == O_absent)
1941 goto err;
1943 saw_comma = 0;
1944 saw_arg = 1;
1945 ++tok;
1946 break;
1950 fini:
1951 if (saw_comma)
1952 goto err;
1953 input_line_pointer = old_input_line_pointer;
1955 #ifdef DEBUG_ALPHA
1956 debug_exp (orig_tok, ntok - (end_tok - tok));
1957 #endif
1958 #ifdef RELOC_OP_P
1959 is_end_of_line[(unsigned char) '!'] = 0;
1960 #endif
1962 return ntok - (end_tok - tok);
1964 err:
1965 #ifdef RELOC_OP_P
1966 is_end_of_line[(unsigned char) '!'] = 0;
1967 #endif
1968 input_line_pointer = old_input_line_pointer;
1969 return TOKENIZE_ERROR;
1971 err_report:
1972 #ifdef RELOC_OP_P
1973 is_end_of_line[(unsigned char) '!'] = 0;
1974 #endif
1975 input_line_pointer = old_input_line_pointer;
1976 return TOKENIZE_ERROR_REPORT;
1979 /* Search forward through all variants of an opcode looking for a
1980 syntax match. */
1982 static const struct alpha_opcode *
1983 find_opcode_match (first_opcode, tok, pntok, pcpumatch)
1984 const struct alpha_opcode *first_opcode;
1985 const expressionS *tok;
1986 int *pntok;
1987 int *pcpumatch;
1989 const struct alpha_opcode *opcode = first_opcode;
1990 int ntok = *pntok;
1991 int got_cpu_match = 0;
1995 const unsigned char *opidx;
1996 int tokidx = 0;
1998 /* Don't match opcodes that don't exist on this architecture */
1999 if (!(opcode->flags & alpha_target))
2000 goto match_failed;
2002 got_cpu_match = 1;
2004 for (opidx = opcode->operands; *opidx; ++opidx)
2006 const struct alpha_operand *operand = &alpha_operands[*opidx];
2008 /* only take input from real operands */
2009 if (operand->flags & AXP_OPERAND_FAKE)
2010 continue;
2012 /* when we expect input, make sure we have it */
2013 if (tokidx >= ntok)
2015 if ((operand->flags & AXP_OPERAND_OPTIONAL_MASK) == 0)
2016 goto match_failed;
2017 continue;
2020 /* match operand type with expression type */
2021 switch (operand->flags & AXP_OPERAND_TYPECHECK_MASK)
2023 case AXP_OPERAND_IR:
2024 if (tok[tokidx].X_op != O_register
2025 || !is_ir_num (tok[tokidx].X_add_number))
2026 goto match_failed;
2027 break;
2028 case AXP_OPERAND_FPR:
2029 if (tok[tokidx].X_op != O_register
2030 || !is_fpr_num (tok[tokidx].X_add_number))
2031 goto match_failed;
2032 break;
2033 case AXP_OPERAND_IR | AXP_OPERAND_PARENS:
2034 if (tok[tokidx].X_op != O_pregister
2035 || !is_ir_num (tok[tokidx].X_add_number))
2036 goto match_failed;
2037 break;
2038 case AXP_OPERAND_IR | AXP_OPERAND_PARENS | AXP_OPERAND_COMMA:
2039 if (tok[tokidx].X_op != O_cpregister
2040 || !is_ir_num (tok[tokidx].X_add_number))
2041 goto match_failed;
2042 break;
2044 case AXP_OPERAND_RELATIVE:
2045 case AXP_OPERAND_SIGNED:
2046 case AXP_OPERAND_UNSIGNED:
2047 switch (tok[tokidx].X_op)
2049 case O_illegal:
2050 case O_absent:
2051 case O_register:
2052 case O_pregister:
2053 case O_cpregister:
2054 goto match_failed;
2056 default:
2057 break;
2059 break;
2061 default:
2062 /* everything else should have been fake */
2063 abort ();
2065 ++tokidx;
2068 /* possible match -- did we use all of our input? */
2069 if (tokidx == ntok)
2071 *pntok = ntok;
2072 return opcode;
2075 match_failed:;
2077 while (++opcode - alpha_opcodes < alpha_num_opcodes
2078 && !strcmp (opcode->name, first_opcode->name));
2080 if (*pcpumatch)
2081 *pcpumatch = got_cpu_match;
2083 return NULL;
2086 /* Search forward through all variants of a macro looking for a syntax
2087 match. */
2089 static const struct alpha_macro *
2090 find_macro_match (first_macro, tok, pntok)
2091 const struct alpha_macro *first_macro;
2092 const expressionS *tok;
2093 int *pntok;
2095 const struct alpha_macro *macro = first_macro;
2096 int ntok = *pntok;
2100 const enum alpha_macro_arg *arg = macro->argsets;
2101 int tokidx = 0;
2103 while (*arg)
2105 switch (*arg)
2107 case MACRO_EOA:
2108 if (tokidx == ntok)
2109 return macro;
2110 else
2111 tokidx = 0;
2112 break;
2114 /* index register */
2115 case MACRO_IR:
2116 if (tokidx >= ntok || tok[tokidx].X_op != O_register
2117 || !is_ir_num (tok[tokidx].X_add_number))
2118 goto match_failed;
2119 ++tokidx;
2120 break;
2122 /* parenthesized index register */
2123 case MACRO_PIR:
2124 if (tokidx >= ntok || tok[tokidx].X_op != O_pregister
2125 || !is_ir_num (tok[tokidx].X_add_number))
2126 goto match_failed;
2127 ++tokidx;
2128 break;
2130 /* optional parenthesized index register */
2131 case MACRO_OPIR:
2132 if (tokidx < ntok && tok[tokidx].X_op == O_pregister
2133 && is_ir_num (tok[tokidx].X_add_number))
2134 ++tokidx;
2135 break;
2137 /* leading comma with a parenthesized index register */
2138 case MACRO_CPIR:
2139 if (tokidx >= ntok || tok[tokidx].X_op != O_cpregister
2140 || !is_ir_num (tok[tokidx].X_add_number))
2141 goto match_failed;
2142 ++tokidx;
2143 break;
2145 /* floating point register */
2146 case MACRO_FPR:
2147 if (tokidx >= ntok || tok[tokidx].X_op != O_register
2148 || !is_fpr_num (tok[tokidx].X_add_number))
2149 goto match_failed;
2150 ++tokidx;
2151 break;
2153 /* normal expression */
2154 case MACRO_EXP:
2155 if (tokidx >= ntok)
2156 goto match_failed;
2157 switch (tok[tokidx].X_op)
2159 case O_illegal:
2160 case O_absent:
2161 case O_register:
2162 case O_pregister:
2163 case O_cpregister:
2164 case O_literal:
2165 case O_lituse_base:
2166 case O_lituse_bytoff:
2167 case O_lituse_jsr:
2168 case O_gpdisp:
2169 case O_gprelhigh:
2170 case O_gprellow:
2171 case O_gprel:
2172 goto match_failed;
2174 default:
2175 break;
2177 ++tokidx;
2178 break;
2180 match_failed:
2181 while (*arg != MACRO_EOA)
2182 ++arg;
2183 tokidx = 0;
2184 break;
2186 ++arg;
2189 while (++macro - alpha_macros < alpha_num_macros
2190 && !strcmp (macro->name, first_macro->name));
2192 return NULL;
2195 /* Insert an operand value into an instruction. */
2197 static unsigned
2198 insert_operand (insn, operand, val, file, line)
2199 unsigned insn;
2200 const struct alpha_operand *operand;
2201 offsetT val;
2202 char *file;
2203 unsigned line;
2205 if (operand->bits != 32 && !(operand->flags & AXP_OPERAND_NOOVERFLOW))
2207 offsetT min, max;
2209 if (operand->flags & AXP_OPERAND_SIGNED)
2211 max = (1 << (operand->bits - 1)) - 1;
2212 min = -(1 << (operand->bits - 1));
2214 else
2216 max = (1 << operand->bits) - 1;
2217 min = 0;
2220 if (val < min || val > max)
2222 const char *err =
2223 _("operand out of range (%s not between %d and %d)");
2224 char buf[sizeof (val) * 3 + 2];
2226 sprint_value (buf, val);
2227 if (file)
2228 as_warn_where (file, line, err, buf, min, max);
2229 else
2230 as_warn (err, buf, min, max);
2234 if (operand->insert)
2236 const char *errmsg = NULL;
2238 insn = (*operand->insert) (insn, val, &errmsg);
2239 if (errmsg)
2240 as_warn (errmsg);
2242 else
2243 insn |= ((val & ((1 << operand->bits) - 1)) << operand->shift);
2245 return insn;
2249 * Turn an opcode description and a set of arguments into
2250 * an instruction and a fixup.
2253 static void
2254 assemble_insn (opcode, tok, ntok, insn, reloc)
2255 const struct alpha_opcode *opcode;
2256 const expressionS *tok;
2257 int ntok;
2258 struct alpha_insn *insn;
2259 bfd_reloc_code_real_type reloc;
2261 const struct alpha_operand *reloc_operand = NULL;
2262 const expressionS *reloc_exp = NULL;
2263 const unsigned char *argidx;
2264 unsigned image;
2265 int tokidx = 0;
2267 memset (insn, 0, sizeof (*insn));
2268 image = opcode->opcode;
2270 for (argidx = opcode->operands; *argidx; ++argidx)
2272 const struct alpha_operand *operand = &alpha_operands[*argidx];
2273 const expressionS *t = (const expressionS *) 0;
2275 if (operand->flags & AXP_OPERAND_FAKE)
2277 /* fake operands take no value and generate no fixup */
2278 image = insert_operand (image, operand, 0, NULL, 0);
2279 continue;
2282 if (tokidx >= ntok)
2284 switch (operand->flags & AXP_OPERAND_OPTIONAL_MASK)
2286 case AXP_OPERAND_DEFAULT_FIRST:
2287 t = &tok[0];
2288 break;
2289 case AXP_OPERAND_DEFAULT_SECOND:
2290 t = &tok[1];
2291 break;
2292 case AXP_OPERAND_DEFAULT_ZERO:
2294 static expressionS zero_exp;
2295 t = &zero_exp;
2296 zero_exp.X_op = O_constant;
2297 zero_exp.X_unsigned = 1;
2299 break;
2300 default:
2301 abort ();
2304 else
2305 t = &tok[tokidx++];
2307 switch (t->X_op)
2309 case O_register:
2310 case O_pregister:
2311 case O_cpregister:
2312 image = insert_operand (image, operand, regno (t->X_add_number),
2313 NULL, 0);
2314 break;
2316 case O_constant:
2317 image = insert_operand (image, operand, t->X_add_number, NULL, 0);
2318 assert (reloc_operand == NULL);
2319 reloc_operand = operand;
2320 reloc_exp = t;
2321 break;
2323 default:
2324 /* This is only 0 for fields that should contain registers,
2325 which means this pattern shouldn't have matched. */
2326 if (operand->default_reloc == 0)
2327 abort ();
2329 /* There is one special case for which an insn receives two
2330 relocations, and thus the user-supplied reloc does not
2331 override the operand reloc. */
2332 if (operand->default_reloc == BFD_RELOC_ALPHA_HINT)
2334 struct alpha_fixup *fixup;
2336 if (insn->nfixups >= MAX_INSN_FIXUPS)
2337 as_fatal (_("too many fixups"));
2339 fixup = &insn->fixups[insn->nfixups++];
2340 fixup->exp = *t;
2341 fixup->reloc = BFD_RELOC_ALPHA_HINT;
2343 else
2345 if (reloc == BFD_RELOC_UNUSED)
2346 reloc = operand->default_reloc;
2348 assert (reloc_operand == NULL);
2349 reloc_operand = operand;
2350 reloc_exp = t;
2352 break;
2356 if (reloc != BFD_RELOC_UNUSED)
2358 struct alpha_fixup *fixup;
2360 if (insn->nfixups >= MAX_INSN_FIXUPS)
2361 as_fatal (_("too many fixups"));
2363 /* ??? My but this is hacky. But the OSF/1 assembler uses the same
2364 relocation tag for both ldah and lda with gpdisp. Choose the
2365 correct internal relocation based on the opcode. */
2366 if (reloc == BFD_RELOC_ALPHA_GPDISP)
2368 if (strcmp (opcode->name, "ldah") == 0)
2369 reloc = BFD_RELOC_ALPHA_GPDISP_HI16;
2370 else if (strcmp (opcode->name, "lda") == 0)
2371 reloc = BFD_RELOC_ALPHA_GPDISP_LO16;
2372 else
2373 as_bad (_("invalid relocation for instruction"));
2376 /* If this is a real relocation (as opposed to a lituse hint), then
2377 the relocation width should match the operand width. */
2378 else if (reloc < BFD_RELOC_UNUSED)
2380 reloc_howto_type *reloc_howto
2381 = bfd_reloc_type_lookup (stdoutput, reloc);
2382 if (reloc_howto->bitsize != reloc_operand->bits)
2384 as_bad (_("invalid relocation for field"));
2385 return;
2389 fixup = &insn->fixups[insn->nfixups++];
2390 if (reloc_exp)
2391 fixup->exp = *reloc_exp;
2392 else
2393 fixup->exp.X_op = O_absent;
2394 fixup->reloc = reloc;
2397 insn->insn = image;
2401 * Actually output an instruction with its fixup.
2404 static void
2405 emit_insn (insn)
2406 struct alpha_insn *insn;
2408 char *f;
2409 int i;
2411 /* Take care of alignment duties. */
2412 if (alpha_auto_align_on && alpha_current_align < 2)
2413 alpha_align (2, (char *) NULL, alpha_insn_label, 0);
2414 if (alpha_current_align > 2)
2415 alpha_current_align = 2;
2416 alpha_insn_label = NULL;
2418 /* Write out the instruction. */
2419 f = frag_more (4);
2420 md_number_to_chars (f, insn->insn, 4);
2422 #ifdef OBJ_ELF
2423 dwarf2_emit_insn (4);
2424 #endif
2426 /* Apply the fixups in order */
2427 for (i = 0; i < insn->nfixups; ++i)
2429 const struct alpha_operand *operand = (const struct alpha_operand *) 0;
2430 struct alpha_fixup *fixup = &insn->fixups[i];
2431 struct alpha_reloc_tag *info;
2432 int size, pcrel;
2433 fixS *fixP;
2435 /* Some fixups are only used internally and so have no howto */
2436 if ((int) fixup->reloc < 0)
2438 operand = &alpha_operands[-(int) fixup->reloc];
2439 size = 4;
2440 pcrel = ((operand->flags & AXP_OPERAND_RELATIVE) != 0);
2442 else if (fixup->reloc > BFD_RELOC_UNUSED
2443 || fixup->reloc == BFD_RELOC_ALPHA_GPDISP_HI16
2444 || fixup->reloc == BFD_RELOC_ALPHA_GPDISP_LO16)
2446 size = 2;
2447 pcrel = 0;
2449 else
2451 reloc_howto_type *reloc_howto
2452 = bfd_reloc_type_lookup (stdoutput, fixup->reloc);
2453 assert (reloc_howto);
2455 size = bfd_get_reloc_size (reloc_howto);
2456 assert (size >= 1 && size <= 4);
2458 pcrel = reloc_howto->pc_relative;
2461 fixP = fix_new_exp (frag_now, f - frag_now->fr_literal, size,
2462 &fixup->exp, pcrel, fixup->reloc);
2464 /* Turn off complaints that the addend is too large for some fixups,
2465 and copy in the sequence number for the explicit relocations. */
2466 switch (fixup->reloc)
2468 case BFD_RELOC_ALPHA_HINT:
2469 case BFD_RELOC_GPREL32:
2470 case BFD_RELOC_GPREL16:
2471 case BFD_RELOC_ALPHA_GPREL_HI16:
2472 case BFD_RELOC_ALPHA_GPREL_LO16:
2473 fixP->fx_no_overflow = 1;
2474 break;
2476 case BFD_RELOC_ALPHA_GPDISP_HI16:
2477 fixP->fx_no_overflow = 1;
2478 fixP->fx_addsy = section_symbol (now_seg);
2479 fixP->fx_offset = 0;
2481 info = get_alpha_reloc_tag (insn->sequence);
2482 if (++info->n_master > 1)
2483 as_bad (_("too many ldah insns for !gpdisp!%ld"), insn->sequence);
2484 if (info->segment != now_seg)
2485 as_bad (_("both insns for !gpdisp!%ld must be in the same section"),
2486 insn->sequence);
2487 fixP->tc_fix_data.info = info;
2488 break;
2490 case BFD_RELOC_ALPHA_GPDISP_LO16:
2491 fixP->fx_no_overflow = 1;
2493 info = get_alpha_reloc_tag (insn->sequence);
2494 if (++info->n_slaves > 1)
2495 as_bad (_("too many lda insns for !gpdisp!%ld"), insn->sequence);
2496 if (info->segment != now_seg)
2497 as_bad (_("both insns for !gpdisp!%ld must be in the same section"),
2498 insn->sequence);
2499 fixP->tc_fix_data.info = info;
2500 info->slaves = fixP;
2501 break;
2503 case BFD_RELOC_ALPHA_LITERAL:
2504 case BFD_RELOC_ALPHA_ELF_LITERAL:
2505 fixP->fx_no_overflow = 1;
2507 info = get_alpha_reloc_tag (insn->sequence);
2508 info->n_master++;
2509 if (info->segment != now_seg)
2510 info->multi_section_p = 1;
2511 fixP->tc_fix_data.info = info;
2512 break;
2514 case DUMMY_RELOC_LITUSE_ADDR:
2515 fixP->fx_offset = LITUSE_ADDR;
2516 goto do_lituse;
2517 case DUMMY_RELOC_LITUSE_BASE:
2518 fixP->fx_offset = LITUSE_BASE;
2519 goto do_lituse;
2520 case DUMMY_RELOC_LITUSE_BYTOFF:
2521 fixP->fx_offset = LITUSE_BYTOFF;
2522 goto do_lituse;
2523 case DUMMY_RELOC_LITUSE_JSR:
2524 fixP->fx_offset = LITUSE_JSR;
2525 do_lituse:
2526 fixP->fx_addsy = section_symbol (now_seg);
2527 fixP->fx_r_type = BFD_RELOC_ALPHA_LITUSE;
2529 info = get_alpha_reloc_tag (insn->sequence);
2530 info->n_slaves++;
2531 fixP->tc_fix_data.info = info;
2532 fixP->tc_fix_data.next_reloc = info->slaves;
2533 info->slaves = fixP;
2534 if (info->segment != now_seg)
2535 info->multi_section_p = 1;
2536 break;
2538 default:
2539 if ((int) fixup->reloc < 0)
2541 if (operand->flags & AXP_OPERAND_NOOVERFLOW)
2542 fixP->fx_no_overflow = 1;
2544 break;
2549 /* Given an opcode name and a pre-tokenized set of arguments, assemble
2550 the insn, but do not emit it.
2552 Note that this implies no macros allowed, since we can't store more
2553 than one insn in an insn structure. */
2555 static void
2556 assemble_tokens_to_insn (opname, tok, ntok, insn)
2557 const char *opname;
2558 const expressionS *tok;
2559 int ntok;
2560 struct alpha_insn *insn;
2562 const struct alpha_opcode *opcode;
2564 /* search opcodes */
2565 opcode = (const struct alpha_opcode *) hash_find (alpha_opcode_hash, opname);
2566 if (opcode)
2568 int cpumatch;
2569 opcode = find_opcode_match (opcode, tok, &ntok, &cpumatch);
2570 if (opcode)
2572 assemble_insn (opcode, tok, ntok, insn, BFD_RELOC_UNUSED);
2573 return;
2575 else if (cpumatch)
2576 as_bad (_("inappropriate arguments for opcode `%s'"), opname);
2577 else
2578 as_bad (_("opcode `%s' not supported for target %s"), opname,
2579 alpha_target_name);
2581 else
2582 as_bad (_("unknown opcode `%s'"), opname);
2585 /* Given an opcode name and a pre-tokenized set of arguments, take the
2586 opcode all the way through emission. */
2588 static void
2589 assemble_tokens (opname, tok, ntok, local_macros_on)
2590 const char *opname;
2591 const expressionS *tok;
2592 int ntok;
2593 int local_macros_on;
2595 int found_something = 0;
2596 const struct alpha_opcode *opcode;
2597 const struct alpha_macro *macro;
2598 int cpumatch = 1;
2599 bfd_reloc_code_real_type reloc = BFD_RELOC_UNUSED;
2601 /* If a user-specified relocation is present, this is not a macro. */
2602 if (ntok && USER_RELOC_P (tok[ntok - 1].X_op))
2604 reloc = ALPHA_RELOC_TABLE (tok[ntok - 1].X_op)->reloc;
2605 ntok--;
2607 else if (local_macros_on)
2609 macro = ((const struct alpha_macro *)
2610 hash_find (alpha_macro_hash, opname));
2611 if (macro)
2613 found_something = 1;
2614 macro = find_macro_match (macro, tok, &ntok);
2615 if (macro)
2617 (*macro->emit) (tok, ntok, macro->arg);
2618 return;
2623 /* search opcodes */
2624 opcode = (const struct alpha_opcode *) hash_find (alpha_opcode_hash, opname);
2625 if (opcode)
2627 found_something = 1;
2628 opcode = find_opcode_match (opcode, tok, &ntok, &cpumatch);
2629 if (opcode)
2631 struct alpha_insn insn;
2632 assemble_insn (opcode, tok, ntok, &insn, reloc);
2634 /* Copy the sequence number for the reloc from the reloc token. */
2635 if (reloc != BFD_RELOC_UNUSED)
2636 insn.sequence = tok[ntok].X_add_number;
2638 emit_insn (&insn);
2639 return;
2643 if (found_something)
2645 if (cpumatch)
2646 as_bad (_("inappropriate arguments for opcode `%s'"), opname);
2647 else
2648 as_bad (_("opcode `%s' not supported for target %s"), opname,
2649 alpha_target_name);
2651 else
2652 as_bad (_("unknown opcode `%s'"), opname);
2655 /* Some instruction sets indexed by lg(size) */
2656 static const char * const sextX_op[] = { "sextb", "sextw", "sextl", NULL };
2657 static const char * const insXl_op[] = { "insbl", "inswl", "insll", "insql" };
2658 static const char * const insXh_op[] = { NULL, "inswh", "inslh", "insqh" };
2659 static const char * const extXl_op[] = { "extbl", "extwl", "extll", "extql" };
2660 static const char * const extXh_op[] = { NULL, "extwh", "extlh", "extqh" };
2661 static const char * const mskXl_op[] = { "mskbl", "mskwl", "mskll", "mskql" };
2662 static const char * const mskXh_op[] = { NULL, "mskwh", "msklh", "mskqh" };
2663 static const char * const stX_op[] = { "stb", "stw", "stl", "stq" };
2664 static const char * const ldX_op[] = { "ldb", "ldw", "ldll", "ldq" };
2665 static const char * const ldXu_op[] = { "ldbu", "ldwu", NULL, NULL };
2667 /* Implement the ldgp macro. */
2669 static void
2670 emit_ldgp (tok, ntok, unused)
2671 const expressionS *tok;
2672 int ntok ATTRIBUTE_UNUSED;
2673 const PTR unused ATTRIBUTE_UNUSED;
2675 #ifdef OBJ_AOUT
2676 FIXME
2677 #endif
2678 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
2679 /* from "ldgp r1,n(r2)", generate "ldah r1,X(R2); lda r1,Y(r1)"
2680 with appropriate constants and relocations. */
2681 struct alpha_insn insn;
2682 expressionS newtok[3];
2683 expressionS addend;
2685 #ifdef OBJ_ECOFF
2686 if (regno (tok[2].X_add_number) == AXP_REG_PV)
2687 ecoff_set_gp_prolog_size (0);
2688 #endif
2690 newtok[0] = tok[0];
2691 set_tok_const (newtok[1], 0);
2692 newtok[2] = tok[2];
2694 assemble_tokens_to_insn ("ldah", newtok, 3, &insn);
2696 addend = tok[1];
2698 #ifdef OBJ_ECOFF
2699 if (addend.X_op != O_constant)
2700 as_bad (_("can not resolve expression"));
2701 addend.X_op = O_symbol;
2702 addend.X_add_symbol = alpha_gp_symbol;
2703 #endif
2705 insn.nfixups = 1;
2706 insn.fixups[0].exp = addend;
2707 insn.fixups[0].reloc = BFD_RELOC_ALPHA_GPDISP_HI16;
2708 insn.sequence = next_sequence_num;
2710 emit_insn (&insn);
2712 set_tok_preg (newtok[2], tok[0].X_add_number);
2714 assemble_tokens_to_insn ("lda", newtok, 3, &insn);
2716 #ifdef OBJ_ECOFF
2717 addend.X_add_number += 4;
2718 #endif
2720 insn.nfixups = 1;
2721 insn.fixups[0].exp = addend;
2722 insn.fixups[0].reloc = BFD_RELOC_ALPHA_GPDISP_LO16;
2723 insn.sequence = next_sequence_num--;
2725 emit_insn (&insn);
2726 #endif /* OBJ_ECOFF || OBJ_ELF */
2729 #ifdef OBJ_EVAX
2731 /* Add symbol+addend to link pool.
2732 Return offset from basesym to entry in link pool.
2734 Add new fixup only if offset isn't 16bit. */
2736 valueT
2737 add_to_link_pool (basesym, sym, addend)
2738 symbolS *basesym;
2739 symbolS *sym;
2740 offsetT addend;
2742 segT current_section = now_seg;
2743 int current_subsec = now_subseg;
2744 valueT offset;
2745 bfd_reloc_code_real_type reloc_type;
2746 char *p;
2747 segment_info_type *seginfo = seg_info (alpha_link_section);
2748 fixS *fixp;
2750 offset = - *symbol_get_obj (basesym);
2752 /* @@ This assumes all entries in a given section will be of the same
2753 size... Probably correct, but unwise to rely on. */
2754 /* This must always be called with the same subsegment. */
2756 if (seginfo->frchainP)
2757 for (fixp = seginfo->frchainP->fix_root;
2758 fixp != (fixS *) NULL;
2759 fixp = fixp->fx_next, offset += 8)
2761 if (fixp->fx_addsy == sym && fixp->fx_offset == addend)
2763 if (range_signed_16 (offset))
2765 return offset;
2770 /* Not found in 16bit signed range. */
2772 subseg_set (alpha_link_section, 0);
2773 p = frag_more (8);
2774 memset (p, 0, 8);
2776 fix_new (frag_now, p - frag_now->fr_literal, 8, sym, addend, 0,
2777 BFD_RELOC_64);
2779 subseg_set (current_section, current_subsec);
2780 seginfo->literal_pool_size += 8;
2781 return offset;
2784 #endif /* OBJ_EVAX */
2786 /* Load a (partial) expression into a target register.
2788 If poffset is not null, after the call it will either contain
2789 O_constant 0, or a 16-bit offset appropriate for any MEM format
2790 instruction. In addition, pbasereg will be modified to point to
2791 the base register to use in that MEM format instruction.
2793 In any case, *pbasereg should contain a base register to add to the
2794 expression. This will normally be either AXP_REG_ZERO or
2795 alpha_gp_register. Symbol addresses will always be loaded via $gp,
2796 so "foo($0)" is interpreted as adding the address of foo to $0;
2797 i.e. "ldq $targ, LIT($gp); addq $targ, $0, $targ". Odd, perhaps,
2798 but this is what OSF/1 does.
2800 If explicit relocations of the form !literal!<number> are allowed,
2801 and used, then explict_reloc with be an expression pointer.
2803 Finally, the return value is nonzero if the calling macro may emit
2804 a LITUSE reloc if otherwise appropriate; the return value is the
2805 sequence number to use. */
2807 static long
2808 load_expression (targreg, exp, pbasereg, poffset)
2809 int targreg;
2810 const expressionS *exp;
2811 int *pbasereg;
2812 expressionS *poffset;
2814 long emit_lituse = 0;
2815 offsetT addend = exp->X_add_number;
2816 int basereg = *pbasereg;
2817 struct alpha_insn insn;
2818 expressionS newtok[3];
2820 switch (exp->X_op)
2822 case O_symbol:
2824 #ifdef OBJ_ECOFF
2825 offsetT lit;
2827 /* attempt to reduce .lit load by splitting the offset from
2828 its symbol when possible, but don't create a situation in
2829 which we'd fail. */
2830 if (!range_signed_32 (addend) &&
2831 (alpha_noat_on || targreg == AXP_REG_AT))
2833 lit = add_to_literal_pool (exp->X_add_symbol, addend,
2834 alpha_lita_section, 8);
2835 addend = 0;
2837 else
2839 lit = add_to_literal_pool (exp->X_add_symbol, 0,
2840 alpha_lita_section, 8);
2843 if (lit >= 0x8000)
2844 as_fatal (_("overflow in literal (.lita) table"));
2846 /* emit "ldq r, lit(gp)" */
2848 if (basereg != alpha_gp_register && targreg == basereg)
2850 if (alpha_noat_on)
2851 as_bad (_("macro requires $at register while noat in effect"));
2852 if (targreg == AXP_REG_AT)
2853 as_bad (_("macro requires $at while $at in use"));
2855 set_tok_reg (newtok[0], AXP_REG_AT);
2857 else
2858 set_tok_reg (newtok[0], targreg);
2859 set_tok_sym (newtok[1], alpha_lita_symbol, lit);
2860 set_tok_preg (newtok[2], alpha_gp_register);
2862 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
2864 assert (insn.nfixups == 1);
2865 insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITERAL;
2866 insn.sequence = emit_lituse = next_sequence_num--;
2867 #endif /* OBJ_ECOFF */
2868 #ifdef OBJ_ELF
2869 /* emit "ldq r, gotoff(gp)" */
2871 if (basereg != alpha_gp_register && targreg == basereg)
2873 if (alpha_noat_on)
2874 as_bad (_("macro requires $at register while noat in effect"));
2875 if (targreg == AXP_REG_AT)
2876 as_bad (_("macro requires $at while $at in use"));
2878 set_tok_reg (newtok[0], AXP_REG_AT);
2880 else
2881 set_tok_reg (newtok[0], targreg);
2883 /* XXX: Disable this .got minimizing optimization so that we can get
2884 better instruction offset knowledge in the compiler. This happens
2885 very infrequently anyway. */
2886 if (1
2887 || (!range_signed_32 (addend)
2888 && (alpha_noat_on || targreg == AXP_REG_AT)))
2890 newtok[1] = *exp;
2891 addend = 0;
2893 else
2895 set_tok_sym (newtok[1], exp->X_add_symbol, 0);
2898 set_tok_preg (newtok[2], alpha_gp_register);
2900 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
2902 assert (insn.nfixups == 1);
2903 insn.fixups[0].reloc = BFD_RELOC_ALPHA_ELF_LITERAL;
2904 insn.sequence = emit_lituse = next_sequence_num--;
2905 #endif /* OBJ_ELF */
2906 #ifdef OBJ_EVAX
2907 offsetT link;
2909 /* Find symbol or symbol pointer in link section. */
2911 if (exp->X_add_symbol == alpha_evax_proc.symbol)
2913 if (range_signed_16 (addend))
2915 set_tok_reg (newtok[0], targreg);
2916 set_tok_const (newtok[1], addend);
2917 set_tok_preg (newtok[2], basereg);
2918 assemble_tokens_to_insn ("lda", newtok, 3, &insn);
2919 addend = 0;
2921 else
2923 set_tok_reg (newtok[0], targreg);
2924 set_tok_const (newtok[1], 0);
2925 set_tok_preg (newtok[2], basereg);
2926 assemble_tokens_to_insn ("lda", newtok, 3, &insn);
2929 else
2931 if (!range_signed_32 (addend))
2933 link = add_to_link_pool (alpha_evax_proc.symbol,
2934 exp->X_add_symbol, addend);
2935 addend = 0;
2937 else
2939 link = add_to_link_pool (alpha_evax_proc.symbol,
2940 exp->X_add_symbol, 0);
2942 set_tok_reg (newtok[0], targreg);
2943 set_tok_const (newtok[1], link);
2944 set_tok_preg (newtok[2], basereg);
2945 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
2947 #endif /* OBJ_EVAX */
2949 emit_insn (&insn);
2951 #ifndef OBJ_EVAX
2952 if (basereg != alpha_gp_register && basereg != AXP_REG_ZERO)
2954 /* emit "addq r, base, r" */
2956 set_tok_reg (newtok[1], basereg);
2957 set_tok_reg (newtok[2], targreg);
2958 assemble_tokens ("addq", newtok, 3, 0);
2960 #endif
2962 basereg = targreg;
2964 break;
2966 case O_constant:
2967 break;
2969 case O_subtract:
2970 /* Assume that this difference expression will be resolved to an
2971 absolute value and that that value will fit in 16 bits. */
2973 set_tok_reg (newtok[0], targreg);
2974 newtok[1] = *exp;
2975 set_tok_preg (newtok[2], basereg);
2976 assemble_tokens ("lda", newtok, 3, 0);
2978 if (poffset)
2979 set_tok_const (*poffset, 0);
2980 return 0;
2982 case O_big:
2983 if (exp->X_add_number > 0)
2984 as_bad (_("bignum invalid; zero assumed"));
2985 else
2986 as_bad (_("floating point number invalid; zero assumed"));
2987 addend = 0;
2988 break;
2990 default:
2991 as_bad (_("can't handle expression"));
2992 addend = 0;
2993 break;
2996 if (!range_signed_32 (addend))
2998 offsetT lit;
2999 long seq_num = next_sequence_num--;
3001 /* For 64-bit addends, just put it in the literal pool. */
3003 #ifdef OBJ_EVAX
3004 /* emit "ldq targreg, lit(basereg)" */
3005 lit = add_to_link_pool (alpha_evax_proc.symbol,
3006 section_symbol (absolute_section), addend);
3007 set_tok_reg (newtok[0], targreg);
3008 set_tok_const (newtok[1], lit);
3009 set_tok_preg (newtok[2], alpha_gp_register);
3010 assemble_tokens ("ldq", newtok, 3, 0);
3011 #else
3013 if (alpha_lit8_section == NULL)
3015 create_literal_section (".lit8",
3016 &alpha_lit8_section,
3017 &alpha_lit8_symbol);
3019 #ifdef OBJ_ECOFF
3020 alpha_lit8_literal = add_to_literal_pool (alpha_lit8_symbol, 0x8000,
3021 alpha_lita_section, 8);
3022 if (alpha_lit8_literal >= 0x8000)
3023 as_fatal (_("overflow in literal (.lita) table"));
3024 #endif
3027 lit = add_to_literal_pool (NULL, addend, alpha_lit8_section, 8) - 0x8000;
3028 if (lit >= 0x8000)
3029 as_fatal (_("overflow in literal (.lit8) table"));
3031 /* emit "lda litreg, .lit8+0x8000" */
3033 if (targreg == basereg)
3035 if (alpha_noat_on)
3036 as_bad (_("macro requires $at register while noat in effect"));
3037 if (targreg == AXP_REG_AT)
3038 as_bad (_("macro requires $at while $at in use"));
3040 set_tok_reg (newtok[0], AXP_REG_AT);
3042 else
3043 set_tok_reg (newtok[0], targreg);
3044 #ifdef OBJ_ECOFF
3045 set_tok_sym (newtok[1], alpha_lita_symbol, alpha_lit8_literal);
3046 #endif
3047 #ifdef OBJ_ELF
3048 set_tok_sym (newtok[1], alpha_lit8_symbol, 0x8000);
3049 #endif
3050 set_tok_preg (newtok[2], alpha_gp_register);
3052 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
3054 assert (insn.nfixups == 1);
3055 #ifdef OBJ_ECOFF
3056 insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITERAL;
3057 #endif
3058 #ifdef OBJ_ELF
3059 insn.fixups[0].reloc = BFD_RELOC_ALPHA_ELF_LITERAL;
3060 #endif
3061 insn.sequence = seq_num;
3063 emit_insn (&insn);
3065 /* emit "ldq litreg, lit(litreg)" */
3067 set_tok_const (newtok[1], lit);
3068 set_tok_preg (newtok[2], newtok[0].X_add_number);
3070 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
3072 assert (insn.nfixups < MAX_INSN_FIXUPS);
3073 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
3074 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3075 insn.nfixups++;
3076 insn.sequence = seq_num;
3077 emit_lituse = 0;
3079 emit_insn (&insn);
3081 /* emit "addq litreg, base, target" */
3083 if (basereg != AXP_REG_ZERO)
3085 set_tok_reg (newtok[1], basereg);
3086 set_tok_reg (newtok[2], targreg);
3087 assemble_tokens ("addq", newtok, 3, 0);
3089 #endif /* !OBJ_EVAX */
3091 if (poffset)
3092 set_tok_const (*poffset, 0);
3093 *pbasereg = targreg;
3095 else
3097 offsetT low, high, extra, tmp;
3099 /* for 32-bit operands, break up the addend */
3101 low = sign_extend_16 (addend);
3102 tmp = addend - low;
3103 high = sign_extend_16 (tmp >> 16);
3105 if (tmp - (high << 16))
3107 extra = 0x4000;
3108 tmp -= 0x40000000;
3109 high = sign_extend_16 (tmp >> 16);
3111 else
3112 extra = 0;
3114 set_tok_reg (newtok[0], targreg);
3115 set_tok_preg (newtok[2], basereg);
3117 if (extra)
3119 /* emit "ldah r, extra(r) */
3120 set_tok_const (newtok[1], extra);
3121 assemble_tokens ("ldah", newtok, 3, 0);
3122 set_tok_preg (newtok[2], basereg = targreg);
3125 if (high)
3127 /* emit "ldah r, high(r) */
3128 set_tok_const (newtok[1], high);
3129 assemble_tokens ("ldah", newtok, 3, 0);
3130 basereg = targreg;
3131 set_tok_preg (newtok[2], basereg);
3134 if ((low && !poffset) || (!poffset && basereg != targreg))
3136 /* emit "lda r, low(base)" */
3137 set_tok_const (newtok[1], low);
3138 assemble_tokens ("lda", newtok, 3, 0);
3139 basereg = targreg;
3140 low = 0;
3143 if (poffset)
3144 set_tok_const (*poffset, low);
3145 *pbasereg = basereg;
3148 return emit_lituse;
3151 /* The lda macro differs from the lda instruction in that it handles
3152 most simple expressions, particualrly symbol address loads and
3153 large constants. */
3155 static void
3156 emit_lda (tok, ntok, unused)
3157 const expressionS *tok;
3158 int ntok;
3159 const PTR unused ATTRIBUTE_UNUSED;
3161 int basereg;
3163 if (ntok == 2)
3164 basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
3165 else
3166 basereg = tok[2].X_add_number;
3168 (void) load_expression (tok[0].X_add_number, &tok[1], &basereg, NULL);
3171 /* The ldah macro differs from the ldah instruction in that it has $31
3172 as an implied base register. */
3174 static void
3175 emit_ldah (tok, ntok, unused)
3176 const expressionS *tok;
3177 int ntok ATTRIBUTE_UNUSED;
3178 const PTR unused ATTRIBUTE_UNUSED;
3180 expressionS newtok[3];
3182 newtok[0] = tok[0];
3183 newtok[1] = tok[1];
3184 set_tok_preg (newtok[2], AXP_REG_ZERO);
3186 assemble_tokens ("ldah", newtok, 3, 0);
3189 /* Handle all "simple" integer register loads -- ldq, ldq_l, ldq_u,
3190 etc. They differ from the real instructions in that they do simple
3191 expressions like the lda macro. */
3193 static void
3194 emit_ir_load (tok, ntok, opname)
3195 const expressionS *tok;
3196 int ntok;
3197 const PTR opname;
3199 int basereg;
3200 long lituse;
3201 expressionS newtok[3];
3202 struct alpha_insn insn;
3204 if (ntok == 2)
3205 basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
3206 else
3207 basereg = tok[2].X_add_number;
3209 lituse = load_expression (tok[0].X_add_number, &tok[1], &basereg,
3210 &newtok[1]);
3212 newtok[0] = tok[0];
3213 set_tok_preg (newtok[2], basereg);
3215 assemble_tokens_to_insn ((const char *) opname, newtok, 3, &insn);
3217 if (lituse)
3219 assert (insn.nfixups < MAX_INSN_FIXUPS);
3220 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
3221 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3222 insn.nfixups++;
3223 insn.sequence = lituse;
3226 emit_insn (&insn);
3229 /* Handle fp register loads, and both integer and fp register stores.
3230 Again, we handle simple expressions. */
3232 static void
3233 emit_loadstore (tok, ntok, opname)
3234 const expressionS *tok;
3235 int ntok;
3236 const PTR opname;
3238 int basereg;
3239 long lituse;
3240 expressionS newtok[3];
3241 struct alpha_insn insn;
3243 if (ntok == 2)
3244 basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
3245 else
3246 basereg = tok[2].X_add_number;
3248 if (tok[1].X_op != O_constant || !range_signed_16 (tok[1].X_add_number))
3250 if (alpha_noat_on)
3251 as_bad (_("macro requires $at register while noat in effect"));
3253 lituse = load_expression (AXP_REG_AT, &tok[1], &basereg, &newtok[1]);
3255 else
3257 newtok[1] = tok[1];
3258 lituse = 0;
3261 newtok[0] = tok[0];
3262 set_tok_preg (newtok[2], basereg);
3264 assemble_tokens_to_insn ((const char *) opname, newtok, 3, &insn);
3266 if (lituse)
3268 assert (insn.nfixups < MAX_INSN_FIXUPS);
3269 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
3270 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3271 insn.nfixups++;
3272 insn.sequence = lituse;
3275 emit_insn (&insn);
3278 /* Load a half-word or byte as an unsigned value. */
3280 static void
3281 emit_ldXu (tok, ntok, vlgsize)
3282 const expressionS *tok;
3283 int ntok;
3284 const PTR vlgsize;
3286 if (alpha_target & AXP_OPCODE_BWX)
3287 emit_ir_load (tok, ntok, ldXu_op[(long) vlgsize]);
3288 else
3290 expressionS newtok[3];
3291 struct alpha_insn insn;
3292 int basereg;
3293 long lituse;
3295 if (alpha_noat_on)
3296 as_bad (_("macro requires $at register while noat in effect"));
3298 if (ntok == 2)
3299 basereg = (tok[1].X_op == O_constant
3300 ? AXP_REG_ZERO : alpha_gp_register);
3301 else
3302 basereg = tok[2].X_add_number;
3304 /* emit "lda $at, exp" */
3306 lituse = load_expression (AXP_REG_AT, &tok[1], &basereg, NULL);
3308 /* emit "ldq_u targ, 0($at)" */
3310 newtok[0] = tok[0];
3311 set_tok_const (newtok[1], 0);
3312 set_tok_preg (newtok[2], basereg);
3313 assemble_tokens_to_insn ("ldq_u", newtok, 3, &insn);
3315 if (lituse)
3317 assert (insn.nfixups < MAX_INSN_FIXUPS);
3318 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
3319 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3320 insn.nfixups++;
3321 insn.sequence = lituse;
3324 emit_insn (&insn);
3326 /* emit "extXl targ, $at, targ" */
3328 set_tok_reg (newtok[1], basereg);
3329 newtok[2] = newtok[0];
3330 assemble_tokens_to_insn (extXl_op[(long) vlgsize], newtok, 3, &insn);
3332 if (lituse)
3334 assert (insn.nfixups < MAX_INSN_FIXUPS);
3335 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF;
3336 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3337 insn.nfixups++;
3338 insn.sequence = lituse;
3341 emit_insn (&insn);
3345 /* Load a half-word or byte as a signed value. */
3347 static void
3348 emit_ldX (tok, ntok, vlgsize)
3349 const expressionS *tok;
3350 int ntok;
3351 const PTR vlgsize;
3353 emit_ldXu (tok, ntok, vlgsize);
3354 assemble_tokens (sextX_op[(long) vlgsize], tok, 1, 1);
3357 /* Load an integral value from an unaligned address as an unsigned
3358 value. */
3360 static void
3361 emit_uldXu (tok, ntok, vlgsize)
3362 const expressionS *tok;
3363 int ntok;
3364 const PTR vlgsize;
3366 long lgsize = (long) vlgsize;
3367 expressionS newtok[3];
3369 if (alpha_noat_on)
3370 as_bad (_("macro requires $at register while noat in effect"));
3372 /* emit "lda $at, exp" */
3374 memcpy (newtok, tok, sizeof (expressionS) * ntok);
3375 newtok[0].X_add_number = AXP_REG_AT;
3376 assemble_tokens ("lda", newtok, ntok, 1);
3378 /* emit "ldq_u $t9, 0($at)" */
3380 set_tok_reg (newtok[0], AXP_REG_T9);
3381 set_tok_const (newtok[1], 0);
3382 set_tok_preg (newtok[2], AXP_REG_AT);
3383 assemble_tokens ("ldq_u", newtok, 3, 1);
3385 /* emit "ldq_u $t10, size-1($at)" */
3387 set_tok_reg (newtok[0], AXP_REG_T10);
3388 set_tok_const (newtok[1], (1 << lgsize) - 1);
3389 assemble_tokens ("ldq_u", newtok, 3, 1);
3391 /* emit "extXl $t9, $at, $t9" */
3393 set_tok_reg (newtok[0], AXP_REG_T9);
3394 set_tok_reg (newtok[1], AXP_REG_AT);
3395 set_tok_reg (newtok[2], AXP_REG_T9);
3396 assemble_tokens (extXl_op[lgsize], newtok, 3, 1);
3398 /* emit "extXh $t10, $at, $t10" */
3400 set_tok_reg (newtok[0], AXP_REG_T10);
3401 set_tok_reg (newtok[2], AXP_REG_T10);
3402 assemble_tokens (extXh_op[lgsize], newtok, 3, 1);
3404 /* emit "or $t9, $t10, targ" */
3406 set_tok_reg (newtok[0], AXP_REG_T9);
3407 set_tok_reg (newtok[1], AXP_REG_T10);
3408 newtok[2] = tok[0];
3409 assemble_tokens ("or", newtok, 3, 1);
3412 /* Load an integral value from an unaligned address as a signed value.
3413 Note that quads should get funneled to the unsigned load since we
3414 don't have to do the sign extension. */
3416 static void
3417 emit_uldX (tok, ntok, vlgsize)
3418 const expressionS *tok;
3419 int ntok;
3420 const PTR vlgsize;
3422 emit_uldXu (tok, ntok, vlgsize);
3423 assemble_tokens (sextX_op[(long) vlgsize], tok, 1, 1);
3426 /* Implement the ldil macro. */
3428 static void
3429 emit_ldil (tok, ntok, unused)
3430 const expressionS *tok;
3431 int ntok;
3432 const PTR unused ATTRIBUTE_UNUSED;
3434 expressionS newtok[2];
3436 memcpy (newtok, tok, sizeof (newtok));
3437 newtok[1].X_add_number = sign_extend_32 (tok[1].X_add_number);
3439 assemble_tokens ("lda", newtok, ntok, 1);
3442 /* Store a half-word or byte. */
3444 static void
3445 emit_stX (tok, ntok, vlgsize)
3446 const expressionS *tok;
3447 int ntok;
3448 const PTR vlgsize;
3450 int lgsize = (int) (long) vlgsize;
3452 if (alpha_target & AXP_OPCODE_BWX)
3453 emit_loadstore (tok, ntok, stX_op[lgsize]);
3454 else
3456 expressionS newtok[3];
3457 struct alpha_insn insn;
3458 int basereg;
3459 long lituse;
3461 if (alpha_noat_on)
3462 as_bad (_("macro requires $at register while noat in effect"));
3464 if (ntok == 2)
3465 basereg = (tok[1].X_op == O_constant
3466 ? AXP_REG_ZERO : alpha_gp_register);
3467 else
3468 basereg = tok[2].X_add_number;
3470 /* emit "lda $at, exp" */
3472 lituse = load_expression (AXP_REG_AT, &tok[1], &basereg, NULL);
3474 /* emit "ldq_u $t9, 0($at)" */
3476 set_tok_reg (newtok[0], AXP_REG_T9);
3477 set_tok_const (newtok[1], 0);
3478 set_tok_preg (newtok[2], basereg);
3479 assemble_tokens_to_insn ("ldq_u", newtok, 3, &insn);
3481 if (lituse)
3483 assert (insn.nfixups < MAX_INSN_FIXUPS);
3484 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
3485 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3486 insn.nfixups++;
3487 insn.sequence = lituse;
3490 emit_insn (&insn);
3492 /* emit "insXl src, $at, $t10" */
3494 newtok[0] = tok[0];
3495 set_tok_reg (newtok[1], basereg);
3496 set_tok_reg (newtok[2], AXP_REG_T10);
3497 assemble_tokens_to_insn (insXl_op[lgsize], newtok, 3, &insn);
3499 if (lituse)
3501 assert (insn.nfixups < MAX_INSN_FIXUPS);
3502 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF;
3503 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3504 insn.nfixups++;
3505 insn.sequence = lituse;
3508 emit_insn (&insn);
3510 /* emit "mskXl $t9, $at, $t9" */
3512 set_tok_reg (newtok[0], AXP_REG_T9);
3513 newtok[2] = newtok[0];
3514 assemble_tokens_to_insn (mskXl_op[lgsize], newtok, 3, &insn);
3516 if (lituse)
3518 assert (insn.nfixups < MAX_INSN_FIXUPS);
3519 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF;
3520 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3521 insn.nfixups++;
3522 insn.sequence = lituse;
3525 emit_insn (&insn);
3527 /* emit "or $t9, $t10, $t9" */
3529 set_tok_reg (newtok[1], AXP_REG_T10);
3530 assemble_tokens ("or", newtok, 3, 1);
3532 /* emit "stq_u $t9, 0($at) */
3534 set_tok_const(newtok[1], 0);
3535 set_tok_preg (newtok[2], AXP_REG_AT);
3536 assemble_tokens_to_insn ("stq_u", newtok, 3, &insn);
3538 if (lituse)
3540 assert (insn.nfixups < MAX_INSN_FIXUPS);
3541 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
3542 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3543 insn.nfixups++;
3544 insn.sequence = lituse;
3547 emit_insn (&insn);
3551 /* Store an integer to an unaligned address. */
3553 static void
3554 emit_ustX (tok, ntok, vlgsize)
3555 const expressionS *tok;
3556 int ntok;
3557 const PTR vlgsize;
3559 int lgsize = (int) (long) vlgsize;
3560 expressionS newtok[3];
3562 /* emit "lda $at, exp" */
3564 memcpy (newtok, tok, sizeof (expressionS) * ntok);
3565 newtok[0].X_add_number = AXP_REG_AT;
3566 assemble_tokens ("lda", newtok, ntok, 1);
3568 /* emit "ldq_u $9, 0($at)" */
3570 set_tok_reg (newtok[0], AXP_REG_T9);
3571 set_tok_const (newtok[1], 0);
3572 set_tok_preg (newtok[2], AXP_REG_AT);
3573 assemble_tokens ("ldq_u", newtok, 3, 1);
3575 /* emit "ldq_u $10, size-1($at)" */
3577 set_tok_reg (newtok[0], AXP_REG_T10);
3578 set_tok_const (newtok[1], (1 << lgsize) - 1);
3579 assemble_tokens ("ldq_u", newtok, 3, 1);
3581 /* emit "insXl src, $at, $t11" */
3583 newtok[0] = tok[0];
3584 set_tok_reg (newtok[1], AXP_REG_AT);
3585 set_tok_reg (newtok[2], AXP_REG_T11);
3586 assemble_tokens (insXl_op[lgsize], newtok, 3, 1);
3588 /* emit "insXh src, $at, $t12" */
3590 set_tok_reg (newtok[2], AXP_REG_T12);
3591 assemble_tokens (insXh_op[lgsize], newtok, 3, 1);
3593 /* emit "mskXl $t9, $at, $t9" */
3595 set_tok_reg (newtok[0], AXP_REG_T9);
3596 newtok[2] = newtok[0];
3597 assemble_tokens (mskXl_op[lgsize], newtok, 3, 1);
3599 /* emit "mskXh $t10, $at, $t10" */
3601 set_tok_reg (newtok[0], AXP_REG_T10);
3602 newtok[2] = newtok[0];
3603 assemble_tokens (mskXh_op[lgsize], newtok, 3, 1);
3605 /* emit "or $t9, $t11, $t9" */
3607 set_tok_reg (newtok[0], AXP_REG_T9);
3608 set_tok_reg (newtok[1], AXP_REG_T11);
3609 newtok[2] = newtok[0];
3610 assemble_tokens ("or", newtok, 3, 1);
3612 /* emit "or $t10, $t12, $t10" */
3614 set_tok_reg (newtok[0], AXP_REG_T10);
3615 set_tok_reg (newtok[1], AXP_REG_T12);
3616 newtok[2] = newtok[0];
3617 assemble_tokens ("or", newtok, 3, 1);
3619 /* emit "stq_u $t9, 0($at)" */
3621 set_tok_reg (newtok[0], AXP_REG_T9);
3622 set_tok_const (newtok[1], 0);
3623 set_tok_preg (newtok[2], AXP_REG_AT);
3624 assemble_tokens ("stq_u", newtok, 3, 1);
3626 /* emit "stq_u $t10, size-1($at)" */
3628 set_tok_reg (newtok[0], AXP_REG_T10);
3629 set_tok_const (newtok[1], (1 << lgsize) - 1);
3630 assemble_tokens ("stq_u", newtok, 3, 1);
3633 /* Sign extend a half-word or byte. The 32-bit sign extend is
3634 implemented as "addl $31, $r, $t" in the opcode table. */
3636 static void
3637 emit_sextX (tok, ntok, vlgsize)
3638 const expressionS *tok;
3639 int ntok;
3640 const PTR vlgsize;
3642 long lgsize = (long) vlgsize;
3644 if (alpha_target & AXP_OPCODE_BWX)
3645 assemble_tokens (sextX_op[lgsize], tok, ntok, 0);
3646 else
3648 int bitshift = 64 - 8 * (1 << lgsize);
3649 expressionS newtok[3];
3651 /* emit "sll src,bits,dst" */
3653 newtok[0] = tok[0];
3654 set_tok_const (newtok[1], bitshift);
3655 newtok[2] = tok[ntok - 1];
3656 assemble_tokens ("sll", newtok, 3, 1);
3658 /* emit "sra dst,bits,dst" */
3660 newtok[0] = newtok[2];
3661 assemble_tokens ("sra", newtok, 3, 1);
3665 /* Implement the division and modulus macros. */
3667 #ifdef OBJ_EVAX
3669 /* Make register usage like in normal procedure call.
3670 Don't clobber PV and RA. */
3672 static void
3673 emit_division (tok, ntok, symname)
3674 const expressionS *tok;
3675 int ntok;
3676 const PTR symname;
3678 /* DIVISION and MODULUS. Yech.
3680 * Convert
3681 * OP x,y,result
3682 * to
3683 * mov x,R16 # if x != R16
3684 * mov y,R17 # if y != R17
3685 * lda AT,__OP
3686 * jsr AT,(AT),0
3687 * mov R0,result
3689 * with appropriate optimizations if R0,R16,R17 are the registers
3690 * specified by the compiler.
3693 int xr, yr, rr;
3694 symbolS *sym;
3695 expressionS newtok[3];
3697 xr = regno (tok[0].X_add_number);
3698 yr = regno (tok[1].X_add_number);
3700 if (ntok < 3)
3701 rr = xr;
3702 else
3703 rr = regno (tok[2].X_add_number);
3705 /* Move the operands into the right place */
3706 if (yr == AXP_REG_R16 && xr == AXP_REG_R17)
3708 /* They are in exactly the wrong order -- swap through AT */
3710 if (alpha_noat_on)
3711 as_bad (_("macro requires $at register while noat in effect"));
3713 set_tok_reg (newtok[0], AXP_REG_R16);
3714 set_tok_reg (newtok[1], AXP_REG_AT);
3715 assemble_tokens ("mov", newtok, 2, 1);
3717 set_tok_reg (newtok[0], AXP_REG_R17);
3718 set_tok_reg (newtok[1], AXP_REG_R16);
3719 assemble_tokens ("mov", newtok, 2, 1);
3721 set_tok_reg (newtok[0], AXP_REG_AT);
3722 set_tok_reg (newtok[1], AXP_REG_R17);
3723 assemble_tokens ("mov", newtok, 2, 1);
3725 else
3727 if (yr == AXP_REG_R16)
3729 set_tok_reg (newtok[0], AXP_REG_R16);
3730 set_tok_reg (newtok[1], AXP_REG_R17);
3731 assemble_tokens ("mov", newtok, 2, 1);
3734 if (xr != AXP_REG_R16)
3736 set_tok_reg (newtok[0], xr);
3737 set_tok_reg (newtok[1], AXP_REG_R16);
3738 assemble_tokens ("mov", newtok, 2, 1);
3741 if (yr != AXP_REG_R16 && yr != AXP_REG_R17)
3743 set_tok_reg (newtok[0], yr);
3744 set_tok_reg (newtok[1], AXP_REG_R17);
3745 assemble_tokens ("mov", newtok, 2, 1);
3749 sym = symbol_find_or_make ((const char *) symname);
3751 set_tok_reg (newtok[0], AXP_REG_AT);
3752 set_tok_sym (newtok[1], sym, 0);
3753 assemble_tokens ("lda", newtok, 2, 1);
3755 /* Call the division routine */
3756 set_tok_reg (newtok[0], AXP_REG_AT);
3757 set_tok_cpreg (newtok[1], AXP_REG_AT);
3758 set_tok_const (newtok[2], 0);
3759 assemble_tokens ("jsr", newtok, 3, 1);
3761 /* Move the result to the right place */
3762 if (rr != AXP_REG_R0)
3764 set_tok_reg (newtok[0], AXP_REG_R0);
3765 set_tok_reg (newtok[1], rr);
3766 assemble_tokens ("mov", newtok, 2, 1);
3770 #else /* !OBJ_EVAX */
3772 static void
3773 emit_division (tok, ntok, symname)
3774 const expressionS *tok;
3775 int ntok;
3776 const PTR symname;
3778 /* DIVISION and MODULUS. Yech.
3779 * Convert
3780 * OP x,y,result
3781 * to
3782 * lda pv,__OP
3783 * mov x,t10
3784 * mov y,t11
3785 * jsr t9,(pv),__OP
3786 * mov t12,result
3788 * with appropriate optimizations if t10,t11,t12 are the registers
3789 * specified by the compiler.
3792 int xr, yr, rr;
3793 symbolS *sym;
3794 expressionS newtok[3];
3796 xr = regno (tok[0].X_add_number);
3797 yr = regno (tok[1].X_add_number);
3799 if (ntok < 3)
3800 rr = xr;
3801 else
3802 rr = regno (tok[2].X_add_number);
3804 sym = symbol_find_or_make ((const char *) symname);
3806 /* Move the operands into the right place */
3807 if (yr == AXP_REG_T10 && xr == AXP_REG_T11)
3809 /* They are in exactly the wrong order -- swap through AT */
3811 if (alpha_noat_on)
3812 as_bad (_("macro requires $at register while noat in effect"));
3814 set_tok_reg (newtok[0], AXP_REG_T10);
3815 set_tok_reg (newtok[1], AXP_REG_AT);
3816 assemble_tokens ("mov", newtok, 2, 1);
3818 set_tok_reg (newtok[0], AXP_REG_T11);
3819 set_tok_reg (newtok[1], AXP_REG_T10);
3820 assemble_tokens ("mov", newtok, 2, 1);
3822 set_tok_reg (newtok[0], AXP_REG_AT);
3823 set_tok_reg (newtok[1], AXP_REG_T11);
3824 assemble_tokens ("mov", newtok, 2, 1);
3826 else
3828 if (yr == AXP_REG_T10)
3830 set_tok_reg (newtok[0], AXP_REG_T10);
3831 set_tok_reg (newtok[1], AXP_REG_T11);
3832 assemble_tokens ("mov", newtok, 2, 1);
3835 if (xr != AXP_REG_T10)
3837 set_tok_reg (newtok[0], xr);
3838 set_tok_reg (newtok[1], AXP_REG_T10);
3839 assemble_tokens ("mov", newtok, 2, 1);
3842 if (yr != AXP_REG_T10 && yr != AXP_REG_T11)
3844 set_tok_reg (newtok[0], yr);
3845 set_tok_reg (newtok[1], AXP_REG_T11);
3846 assemble_tokens ("mov", newtok, 2, 1);
3850 /* Call the division routine */
3851 set_tok_reg (newtok[0], AXP_REG_T9);
3852 set_tok_sym (newtok[1], sym, 0);
3853 assemble_tokens ("jsr", newtok, 2, 1);
3855 /* Reload the GP register */
3856 #ifdef OBJ_AOUT
3857 FIXME
3858 #endif
3859 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
3860 set_tok_reg (newtok[0], alpha_gp_register);
3861 set_tok_const (newtok[1], 0);
3862 set_tok_preg (newtok[2], AXP_REG_T9);
3863 assemble_tokens ("ldgp", newtok, 3, 1);
3864 #endif
3866 /* Move the result to the right place */
3867 if (rr != AXP_REG_T12)
3869 set_tok_reg (newtok[0], AXP_REG_T12);
3870 set_tok_reg (newtok[1], rr);
3871 assemble_tokens ("mov", newtok, 2, 1);
3875 #endif /* !OBJ_EVAX */
3877 /* The jsr and jmp macros differ from their instruction counterparts
3878 in that they can load the target address and default most
3879 everything. */
3881 static void
3882 emit_jsrjmp (tok, ntok, vopname)
3883 const expressionS *tok;
3884 int ntok;
3885 const PTR vopname;
3887 const char *opname = (const char *) vopname;
3888 struct alpha_insn insn;
3889 expressionS newtok[3];
3890 int r, tokidx = 0;
3891 long lituse = 0;
3893 if (tokidx < ntok && tok[tokidx].X_op == O_register)
3894 r = regno (tok[tokidx++].X_add_number);
3895 else
3896 r = strcmp (opname, "jmp") == 0 ? AXP_REG_ZERO : AXP_REG_RA;
3898 set_tok_reg (newtok[0], r);
3900 if (tokidx < ntok &&
3901 (tok[tokidx].X_op == O_pregister || tok[tokidx].X_op == O_cpregister))
3902 r = regno (tok[tokidx++].X_add_number);
3903 #ifdef OBJ_EVAX
3904 /* keep register if jsr $n.<sym> */
3905 #else
3906 else
3908 int basereg = alpha_gp_register;
3909 lituse = load_expression (r = AXP_REG_PV, &tok[tokidx], &basereg, NULL);
3911 #endif
3913 set_tok_cpreg (newtok[1], r);
3915 #ifdef OBJ_EVAX
3916 /* FIXME: Add hint relocs to BFD for evax. */
3917 #else
3918 if (tokidx < ntok)
3919 newtok[2] = tok[tokidx];
3920 else
3921 #endif
3922 set_tok_const (newtok[2], 0);
3924 assemble_tokens_to_insn (opname, newtok, 3, &insn);
3926 if (lituse)
3928 assert (insn.nfixups < MAX_INSN_FIXUPS);
3929 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_JSR;
3930 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3931 insn.nfixups++;
3932 insn.sequence = lituse;
3935 emit_insn (&insn);
3938 /* The ret and jcr instructions differ from their instruction
3939 counterparts in that everything can be defaulted. */
3941 static void
3942 emit_retjcr (tok, ntok, vopname)
3943 const expressionS *tok;
3944 int ntok;
3945 const PTR vopname;
3947 const char *opname = (const char *) vopname;
3948 expressionS newtok[3];
3949 int r, tokidx = 0;
3951 if (tokidx < ntok && tok[tokidx].X_op == O_register)
3952 r = regno (tok[tokidx++].X_add_number);
3953 else
3954 r = AXP_REG_ZERO;
3956 set_tok_reg (newtok[0], r);
3958 if (tokidx < ntok &&
3959 (tok[tokidx].X_op == O_pregister || tok[tokidx].X_op == O_cpregister))
3960 r = regno (tok[tokidx++].X_add_number);
3961 else
3962 r = AXP_REG_RA;
3964 set_tok_cpreg (newtok[1], r);
3966 if (tokidx < ntok)
3967 newtok[2] = tok[tokidx];
3968 else
3969 set_tok_const (newtok[2], strcmp (opname, "ret") == 0);
3971 assemble_tokens (opname, newtok, 3, 0);
3974 /* Assembler directives */
3976 /* Handle the .text pseudo-op. This is like the usual one, but it
3977 clears alpha_insn_label and restores auto alignment. */
3979 static void
3980 s_alpha_text (i)
3981 int i;
3984 s_text (i);
3985 alpha_insn_label = NULL;
3986 alpha_auto_align_on = 1;
3987 alpha_current_align = 0;
3990 /* Handle the .data pseudo-op. This is like the usual one, but it
3991 clears alpha_insn_label and restores auto alignment. */
3993 static void
3994 s_alpha_data (i)
3995 int i;
3997 s_data (i);
3998 alpha_insn_label = NULL;
3999 alpha_auto_align_on = 1;
4000 alpha_current_align = 0;
4003 #if defined (OBJ_ECOFF) || defined (OBJ_EVAX)
4005 /* Handle the OSF/1 and openVMS .comm pseudo quirks.
4006 openVMS constructs a section for every common symbol. */
4008 static void
4009 s_alpha_comm (ignore)
4010 int ignore;
4012 register char *name;
4013 register char c;
4014 register char *p;
4015 offsetT temp;
4016 register symbolS *symbolP;
4018 #ifdef OBJ_EVAX
4019 segT current_section = now_seg;
4020 int current_subsec = now_subseg;
4021 segT new_seg;
4022 #endif
4024 name = input_line_pointer;
4025 c = get_symbol_end ();
4027 /* just after name is now '\0' */
4028 p = input_line_pointer;
4029 *p = c;
4031 SKIP_WHITESPACE ();
4033 /* Alpha OSF/1 compiler doesn't provide the comma, gcc does. */
4034 if (*input_line_pointer == ',')
4036 input_line_pointer++;
4037 SKIP_WHITESPACE ();
4039 if ((temp = get_absolute_expression ()) < 0)
4041 as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) temp);
4042 ignore_rest_of_line ();
4043 return;
4046 *p = 0;
4047 symbolP = symbol_find_or_make (name);
4049 #ifdef OBJ_EVAX
4050 /* Make a section for the common symbol. */
4051 new_seg = subseg_new (xstrdup (name), 0);
4052 #endif
4054 *p = c;
4056 #ifdef OBJ_EVAX
4057 /* alignment might follow */
4058 if (*input_line_pointer == ',')
4060 offsetT align;
4062 input_line_pointer++;
4063 align = get_absolute_expression ();
4064 bfd_set_section_alignment (stdoutput, new_seg, align);
4066 #endif
4068 if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
4070 as_bad (_("Ignoring attempt to re-define symbol"));
4071 ignore_rest_of_line ();
4072 return;
4075 #ifdef OBJ_EVAX
4076 if (bfd_section_size (stdoutput, new_seg) > 0)
4078 if (bfd_section_size (stdoutput, new_seg) != temp)
4079 as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
4080 S_GET_NAME (symbolP),
4081 (long) bfd_section_size (stdoutput, new_seg),
4082 (long) temp);
4084 #else
4085 if (S_GET_VALUE (symbolP))
4087 if (S_GET_VALUE (symbolP) != (valueT) temp)
4088 as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
4089 S_GET_NAME (symbolP),
4090 (long) S_GET_VALUE (symbolP),
4091 (long) temp);
4093 #endif
4094 else
4096 #ifdef OBJ_EVAX
4097 subseg_set (new_seg, 0);
4098 p = frag_more (temp);
4099 new_seg->flags |= SEC_IS_COMMON;
4100 if (! S_IS_DEFINED (symbolP))
4101 S_SET_SEGMENT (symbolP, new_seg);
4102 #else
4103 S_SET_VALUE (symbolP, (valueT) temp);
4104 #endif
4105 S_SET_EXTERNAL (symbolP);
4108 #ifdef OBJ_EVAX
4109 subseg_set (current_section, current_subsec);
4110 #endif
4112 know (symbol_get_frag (symbolP) == &zero_address_frag);
4114 demand_empty_rest_of_line ();
4117 #endif /* ! OBJ_ELF */
4119 #ifdef OBJ_ECOFF
4121 /* Handle the .rdata pseudo-op. This is like the usual one, but it
4122 clears alpha_insn_label and restores auto alignment. */
4124 static void
4125 s_alpha_rdata (ignore)
4126 int ignore;
4128 int temp;
4130 temp = get_absolute_expression ();
4131 subseg_new (".rdata", 0);
4132 demand_empty_rest_of_line ();
4133 alpha_insn_label = NULL;
4134 alpha_auto_align_on = 1;
4135 alpha_current_align = 0;
4138 #endif
4140 #ifdef OBJ_ECOFF
4142 /* Handle the .sdata pseudo-op. This is like the usual one, but it
4143 clears alpha_insn_label and restores auto alignment. */
4145 static void
4146 s_alpha_sdata (ignore)
4147 int ignore;
4149 int temp;
4151 temp = get_absolute_expression ();
4152 subseg_new (".sdata", 0);
4153 demand_empty_rest_of_line ();
4154 alpha_insn_label = NULL;
4155 alpha_auto_align_on = 1;
4156 alpha_current_align = 0;
4158 #endif
4160 #ifdef OBJ_ELF
4162 /* Handle the .section pseudo-op. This is like the usual one, but it
4163 clears alpha_insn_label and restores auto alignment. */
4165 static void
4166 s_alpha_section (ignore)
4167 int ignore;
4169 obj_elf_section (ignore);
4171 alpha_insn_label = NULL;
4172 alpha_auto_align_on = 1;
4173 alpha_current_align = 0;
4176 static void
4177 s_alpha_ent (dummy)
4178 int dummy ATTRIBUTE_UNUSED;
4180 if (ECOFF_DEBUGGING)
4181 ecoff_directive_ent (0);
4182 else
4184 char *name, name_end;
4185 name = input_line_pointer;
4186 name_end = get_symbol_end ();
4188 if (! is_name_beginner (*name))
4190 as_warn (_(".ent directive has no name"));
4191 *input_line_pointer = name_end;
4193 else
4195 symbolS *sym;
4197 if (alpha_cur_ent_sym)
4198 as_warn (_("nested .ent directives"));
4200 sym = symbol_find_or_make (name);
4201 symbol_get_bfdsym (sym)->flags |= BSF_FUNCTION;
4202 alpha_cur_ent_sym = sym;
4204 /* The .ent directive is sometimes followed by a number. Not sure
4205 what it really means, but ignore it. */
4206 *input_line_pointer = name_end;
4207 SKIP_WHITESPACE ();
4208 if (*input_line_pointer == ',')
4210 input_line_pointer++;
4211 SKIP_WHITESPACE ();
4213 if (ISDIGIT (*input_line_pointer) || *input_line_pointer == '-')
4214 (void) get_absolute_expression ();
4216 demand_empty_rest_of_line ();
4220 static void
4221 s_alpha_end (dummy)
4222 int dummy ATTRIBUTE_UNUSED;
4224 if (ECOFF_DEBUGGING)
4225 ecoff_directive_end (0);
4226 else
4228 char *name, name_end;
4229 name = input_line_pointer;
4230 name_end = get_symbol_end ();
4232 if (! is_name_beginner (*name))
4234 as_warn (_(".end directive has no name"));
4235 *input_line_pointer = name_end;
4237 else
4239 symbolS *sym;
4241 sym = symbol_find (name);
4242 if (sym != alpha_cur_ent_sym)
4243 as_warn (_(".end directive names different symbol than .ent"));
4245 /* Create an expression to calculate the size of the function. */
4246 if (sym)
4248 symbol_get_obj (sym)->size =
4249 (expressionS *) xmalloc (sizeof (expressionS));
4250 symbol_get_obj (sym)->size->X_op = O_subtract;
4251 symbol_get_obj (sym)->size->X_add_symbol
4252 = symbol_new ("L0\001", now_seg, frag_now_fix (), frag_now);
4253 symbol_get_obj (sym)->size->X_op_symbol = sym;
4254 symbol_get_obj (sym)->size->X_add_number = 0;
4257 alpha_cur_ent_sym = NULL;
4259 *input_line_pointer = name_end;
4261 demand_empty_rest_of_line ();
4265 static void
4266 s_alpha_mask (fp)
4267 int fp;
4269 if (ECOFF_DEBUGGING)
4271 if (fp)
4272 ecoff_directive_fmask (0);
4273 else
4274 ecoff_directive_mask (0);
4276 else
4277 discard_rest_of_line ();
4280 static void
4281 s_alpha_frame (dummy)
4282 int dummy ATTRIBUTE_UNUSED;
4284 if (ECOFF_DEBUGGING)
4285 ecoff_directive_frame (0);
4286 else
4287 discard_rest_of_line ();
4290 static void
4291 s_alpha_prologue (ignore)
4292 int ignore ATTRIBUTE_UNUSED;
4294 symbolS *sym;
4295 int arg;
4297 arg = get_absolute_expression ();
4298 demand_empty_rest_of_line ();
4300 if (ECOFF_DEBUGGING)
4301 sym = ecoff_get_cur_proc_sym ();
4302 else
4303 sym = alpha_cur_ent_sym;
4304 know (sym != NULL);
4306 switch (arg)
4308 case 0: /* No PV required. */
4309 S_SET_OTHER (sym, STO_ALPHA_NOPV
4310 | (S_GET_OTHER (sym) & ~STO_ALPHA_STD_GPLOAD));
4311 break;
4312 case 1: /* Std GP load. */
4313 S_SET_OTHER (sym, STO_ALPHA_STD_GPLOAD
4314 | (S_GET_OTHER (sym) & ~STO_ALPHA_STD_GPLOAD));
4315 break;
4316 case 2: /* Non-std use of PV. */
4317 break;
4319 default:
4320 as_bad (_("Invalid argument %d to .prologue."), arg);
4321 break;
4325 static char *first_file_directive;
4327 static void
4328 s_alpha_file (ignore)
4329 int ignore ATTRIBUTE_UNUSED;
4331 /* Save the first .file directive we see, so that we can change our
4332 minds about whether ecoff debugging should or shouldn't be enabled. */
4333 if (alpha_flag_mdebug < 0 && ! first_file_directive)
4335 char *start = input_line_pointer;
4336 size_t len;
4338 discard_rest_of_line ();
4340 len = input_line_pointer - start;
4341 first_file_directive = xmalloc (len + 1);
4342 memcpy (first_file_directive, start, len);
4343 first_file_directive[len] = '\0';
4345 input_line_pointer = start;
4348 if (ECOFF_DEBUGGING)
4349 ecoff_directive_file (0);
4350 else
4351 dwarf2_directive_file (0);
4354 static void
4355 s_alpha_loc (ignore)
4356 int ignore ATTRIBUTE_UNUSED;
4358 if (ECOFF_DEBUGGING)
4359 ecoff_directive_loc (0);
4360 else
4361 dwarf2_directive_loc (0);
4364 static void
4365 s_alpha_stab (n)
4366 int n;
4368 /* If we've been undecided about mdebug, make up our minds in favour. */
4369 if (alpha_flag_mdebug < 0)
4371 segT sec = subseg_new (".mdebug", 0);
4372 bfd_set_section_flags (stdoutput, sec, SEC_HAS_CONTENTS | SEC_READONLY);
4373 bfd_set_section_alignment (stdoutput, sec, 3);
4375 ecoff_read_begin_hook ();
4377 if (first_file_directive)
4379 char *save_ilp = input_line_pointer;
4380 input_line_pointer = first_file_directive;
4381 ecoff_directive_file (0);
4382 input_line_pointer = save_ilp;
4383 free (first_file_directive);
4386 alpha_flag_mdebug = 1;
4388 s_stab (n);
4391 static void
4392 s_alpha_coff_wrapper (which)
4393 int which;
4395 static void (* const fns[]) PARAMS ((int)) = {
4396 ecoff_directive_begin,
4397 ecoff_directive_bend,
4398 ecoff_directive_def,
4399 ecoff_directive_dim,
4400 ecoff_directive_endef,
4401 ecoff_directive_scl,
4402 ecoff_directive_tag,
4403 ecoff_directive_val,
4406 assert (which >= 0 && which < (int) (sizeof (fns)/sizeof (*fns)));
4408 if (ECOFF_DEBUGGING)
4409 (*fns[which]) (0);
4410 else
4412 as_bad (_("ECOFF debugging is disabled."));
4413 ignore_rest_of_line ();
4416 #endif /* OBJ_ELF */
4418 #ifdef OBJ_EVAX
4420 /* Handle the section specific pseudo-op. */
4422 static void
4423 s_alpha_section (secid)
4424 int secid;
4426 int temp;
4427 #define EVAX_SECTION_COUNT 5
4428 static char *section_name[EVAX_SECTION_COUNT + 1] =
4429 { "NULL", ".rdata", ".comm", ".link", ".ctors", ".dtors" };
4431 if ((secid <= 0) || (secid > EVAX_SECTION_COUNT))
4433 as_fatal (_("Unknown section directive"));
4434 demand_empty_rest_of_line ();
4435 return;
4437 temp = get_absolute_expression ();
4438 subseg_new (section_name[secid], 0);
4439 demand_empty_rest_of_line ();
4440 alpha_insn_label = NULL;
4441 alpha_auto_align_on = 1;
4442 alpha_current_align = 0;
4445 /* Parse .ent directives. */
4447 static void
4448 s_alpha_ent (ignore)
4449 int ignore;
4451 symbolS *symbol;
4452 expressionS symexpr;
4454 alpha_evax_proc.pdsckind = 0;
4455 alpha_evax_proc.framereg = -1;
4456 alpha_evax_proc.framesize = 0;
4457 alpha_evax_proc.rsa_offset = 0;
4458 alpha_evax_proc.ra_save = AXP_REG_RA;
4459 alpha_evax_proc.fp_save = -1;
4460 alpha_evax_proc.imask = 0;
4461 alpha_evax_proc.fmask = 0;
4462 alpha_evax_proc.prologue = 0;
4463 alpha_evax_proc.type = 0;
4465 expression (&symexpr);
4467 if (symexpr.X_op != O_symbol)
4469 as_fatal (_(".ent directive has no symbol"));
4470 demand_empty_rest_of_line ();
4471 return;
4474 symbol = make_expr_symbol (&symexpr);
4475 symbol_get_bfdsym (symbol)->flags |= BSF_FUNCTION;
4476 alpha_evax_proc.symbol = symbol;
4478 demand_empty_rest_of_line ();
4479 return;
4482 /* Parse .frame <framreg>,<framesize>,RA,<rsa_offset> directives. */
4484 static void
4485 s_alpha_frame (ignore)
4486 int ignore;
4488 long val;
4490 alpha_evax_proc.framereg = tc_get_register (1);
4492 SKIP_WHITESPACE ();
4493 if (*input_line_pointer++ != ','
4494 || get_absolute_expression_and_terminator (&val) != ',')
4496 as_warn (_("Bad .frame directive 1./2. param"));
4497 --input_line_pointer;
4498 demand_empty_rest_of_line ();
4499 return;
4502 alpha_evax_proc.framesize = val;
4504 (void) tc_get_register (1);
4505 SKIP_WHITESPACE ();
4506 if (*input_line_pointer++ != ',')
4508 as_warn (_("Bad .frame directive 3./4. param"));
4509 --input_line_pointer;
4510 demand_empty_rest_of_line ();
4511 return;
4513 alpha_evax_proc.rsa_offset = get_absolute_expression ();
4515 return;
4518 static void
4519 s_alpha_pdesc (ignore)
4520 int ignore;
4522 char *name;
4523 char name_end;
4524 long val;
4525 register char *p;
4526 expressionS exp;
4527 symbolS *entry_sym;
4528 fixS *fixp;
4529 segment_info_type *seginfo = seg_info (alpha_link_section);
4531 if (now_seg != alpha_link_section)
4533 as_bad (_(".pdesc directive not in link (.link) section"));
4534 demand_empty_rest_of_line ();
4535 return;
4538 if ((alpha_evax_proc.symbol == 0)
4539 || (!S_IS_DEFINED (alpha_evax_proc.symbol)))
4541 as_fatal (_(".pdesc has no matching .ent"));
4542 demand_empty_rest_of_line ();
4543 return;
4546 *symbol_get_obj (alpha_evax_proc.symbol) =
4547 (valueT) seginfo->literal_pool_size;
4549 expression (&exp);
4550 if (exp.X_op != O_symbol)
4552 as_warn (_(".pdesc directive has no entry symbol"));
4553 demand_empty_rest_of_line ();
4554 return;
4557 entry_sym = make_expr_symbol (&exp);
4558 /* Save bfd symbol of proc desc in function symbol. */
4559 symbol_get_bfdsym (alpha_evax_proc.symbol)->udata.p
4560 = symbol_get_bfdsym (entry_sym);
4562 SKIP_WHITESPACE ();
4563 if (*input_line_pointer++ != ',')
4565 as_warn (_("No comma after .pdesc <entryname>"));
4566 demand_empty_rest_of_line ();
4567 return;
4570 SKIP_WHITESPACE ();
4571 name = input_line_pointer;
4572 name_end = get_symbol_end ();
4574 if (strncmp (name, "stack", 5) == 0)
4576 alpha_evax_proc.pdsckind = PDSC_S_K_KIND_FP_STACK;
4578 else if (strncmp (name, "reg", 3) == 0)
4580 alpha_evax_proc.pdsckind = PDSC_S_K_KIND_FP_REGISTER;
4582 else if (strncmp (name, "null", 4) == 0)
4584 alpha_evax_proc.pdsckind = PDSC_S_K_KIND_NULL;
4586 else
4588 as_fatal (_("unknown procedure kind"));
4589 demand_empty_rest_of_line ();
4590 return;
4593 *input_line_pointer = name_end;
4594 demand_empty_rest_of_line ();
4596 #ifdef md_flush_pending_output
4597 md_flush_pending_output ();
4598 #endif
4600 frag_align (3, 0, 0);
4601 p = frag_more (16);
4602 fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
4603 fixp->fx_done = 1;
4604 seginfo->literal_pool_size += 16;
4606 *p = alpha_evax_proc.pdsckind
4607 | ((alpha_evax_proc.framereg == 29) ? PDSC_S_M_BASE_REG_IS_FP : 0);
4608 *(p + 1) = PDSC_S_M_NATIVE | PDSC_S_M_NO_JACKET;
4610 switch (alpha_evax_proc.pdsckind)
4612 case PDSC_S_K_KIND_NULL:
4613 *(p + 2) = 0;
4614 *(p + 3) = 0;
4615 break;
4616 case PDSC_S_K_KIND_FP_REGISTER:
4617 *(p + 2) = alpha_evax_proc.fp_save;
4618 *(p + 3) = alpha_evax_proc.ra_save;
4619 break;
4620 case PDSC_S_K_KIND_FP_STACK:
4621 md_number_to_chars (p + 2, (valueT) alpha_evax_proc.rsa_offset, 2);
4622 break;
4623 default: /* impossible */
4624 break;
4627 *(p + 4) = 0;
4628 *(p + 5) = alpha_evax_proc.type & 0x0f;
4630 /* Signature offset. */
4631 md_number_to_chars (p + 6, (valueT) 0, 2);
4633 fix_new_exp (frag_now, p - frag_now->fr_literal+8, 8, &exp, 0, BFD_RELOC_64);
4635 if (alpha_evax_proc.pdsckind == PDSC_S_K_KIND_NULL)
4636 return;
4638 /* Add dummy fix to make add_to_link_pool work. */
4639 p = frag_more (8);
4640 fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
4641 fixp->fx_done = 1;
4642 seginfo->literal_pool_size += 8;
4644 /* pdesc+16: Size. */
4645 md_number_to_chars (p, (valueT) alpha_evax_proc.framesize, 4);
4647 md_number_to_chars (p + 4, (valueT) 0, 2);
4649 /* Entry length. */
4650 md_number_to_chars (p + 6, alpha_evax_proc.prologue, 2);
4652 if (alpha_evax_proc.pdsckind == PDSC_S_K_KIND_FP_REGISTER)
4653 return;
4655 /* Add dummy fix to make add_to_link_pool work. */
4656 p = frag_more (8);
4657 fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
4658 fixp->fx_done = 1;
4659 seginfo->literal_pool_size += 8;
4661 /* pdesc+24: register masks. */
4663 md_number_to_chars (p, alpha_evax_proc.imask, 4);
4664 md_number_to_chars (p + 4, alpha_evax_proc.fmask, 4);
4666 return;
4669 /* Support for crash debug on vms. */
4671 static void
4672 s_alpha_name (ignore)
4673 int ignore;
4675 register char *p;
4676 expressionS exp;
4677 segment_info_type *seginfo = seg_info (alpha_link_section);
4679 if (now_seg != alpha_link_section)
4681 as_bad (_(".name directive not in link (.link) section"));
4682 demand_empty_rest_of_line ();
4683 return;
4686 expression (&exp);
4687 if (exp.X_op != O_symbol)
4689 as_warn (_(".name directive has no symbol"));
4690 demand_empty_rest_of_line ();
4691 return;
4694 demand_empty_rest_of_line ();
4696 #ifdef md_flush_pending_output
4697 md_flush_pending_output ();
4698 #endif
4700 frag_align (3, 0, 0);
4701 p = frag_more (8);
4702 seginfo->literal_pool_size += 8;
4704 fix_new_exp (frag_now, p - frag_now->fr_literal, 8, &exp, 0, BFD_RELOC_64);
4706 return;
4709 static void
4710 s_alpha_linkage (ignore)
4711 int ignore;
4713 expressionS exp;
4714 char *p;
4716 #ifdef md_flush_pending_output
4717 md_flush_pending_output ();
4718 #endif
4720 expression (&exp);
4721 if (exp.X_op != O_symbol)
4723 as_fatal (_("No symbol after .linkage"));
4725 else
4727 p = frag_more (LKP_S_K_SIZE);
4728 memset (p, 0, LKP_S_K_SIZE);
4729 fix_new_exp (frag_now, p - frag_now->fr_literal, LKP_S_K_SIZE, &exp, 0,\
4730 BFD_RELOC_ALPHA_LINKAGE);
4732 demand_empty_rest_of_line ();
4734 return;
4737 static void
4738 s_alpha_code_address (ignore)
4739 int ignore;
4741 expressionS exp;
4742 char *p;
4744 #ifdef md_flush_pending_output
4745 md_flush_pending_output ();
4746 #endif
4748 expression (&exp);
4749 if (exp.X_op != O_symbol)
4751 as_fatal (_("No symbol after .code_address"));
4753 else
4755 p = frag_more (8);
4756 memset (p, 0, 8);
4757 fix_new_exp (frag_now, p - frag_now->fr_literal, 8, &exp, 0,\
4758 BFD_RELOC_ALPHA_CODEADDR);
4760 demand_empty_rest_of_line ();
4762 return;
4765 static void
4766 s_alpha_fp_save (ignore)
4767 int ignore;
4770 alpha_evax_proc.fp_save = tc_get_register (1);
4772 demand_empty_rest_of_line ();
4773 return;
4776 static void
4777 s_alpha_mask (ignore)
4778 int ignore;
4780 long val;
4782 if (get_absolute_expression_and_terminator (&val) != ',')
4784 as_warn (_("Bad .mask directive"));
4785 --input_line_pointer;
4787 else
4789 alpha_evax_proc.imask = val;
4790 (void) get_absolute_expression ();
4792 demand_empty_rest_of_line ();
4794 return;
4797 static void
4798 s_alpha_fmask (ignore)
4799 int ignore;
4801 long val;
4803 if (get_absolute_expression_and_terminator (&val) != ',')
4805 as_warn (_("Bad .fmask directive"));
4806 --input_line_pointer;
4808 else
4810 alpha_evax_proc.fmask = val;
4811 (void) get_absolute_expression ();
4813 demand_empty_rest_of_line ();
4815 return;
4818 static void
4819 s_alpha_end (ignore)
4820 int ignore;
4822 char c;
4824 c = get_symbol_end ();
4825 *input_line_pointer = c;
4826 demand_empty_rest_of_line ();
4827 alpha_evax_proc.symbol = 0;
4829 return;
4832 static void
4833 s_alpha_file (ignore)
4834 int ignore;
4836 symbolS *s;
4837 int length;
4838 static char case_hack[32];
4840 extern char *demand_copy_string PARAMS ((int *lenP));
4842 sprintf (case_hack, "<CASE:%01d%01d>",
4843 alpha_flag_hash_long_names, alpha_flag_show_after_trunc);
4845 s = symbol_find_or_make (case_hack);
4846 symbol_get_bfdsym (s)->flags |= BSF_FILE;
4848 get_absolute_expression ();
4849 s = symbol_find_or_make (demand_copy_string (&length));
4850 symbol_get_bfdsym (s)->flags |= BSF_FILE;
4851 demand_empty_rest_of_line ();
4853 return;
4855 #endif /* OBJ_EVAX */
4857 /* Handle the .gprel32 pseudo op. */
4859 static void
4860 s_alpha_gprel32 (ignore)
4861 int ignore ATTRIBUTE_UNUSED;
4863 expressionS e;
4864 char *p;
4866 SKIP_WHITESPACE ();
4867 expression (&e);
4869 #ifdef OBJ_ELF
4870 switch (e.X_op)
4872 case O_constant:
4873 e.X_add_symbol = section_symbol (absolute_section);
4874 e.X_op = O_symbol;
4875 /* FALLTHRU */
4876 case O_symbol:
4877 break;
4878 default:
4879 abort ();
4881 #else
4882 #ifdef OBJ_ECOFF
4883 switch (e.X_op)
4885 case O_constant:
4886 e.X_add_symbol = section_symbol (absolute_section);
4887 /* fall through */
4888 case O_symbol:
4889 e.X_op = O_subtract;
4890 e.X_op_symbol = alpha_gp_symbol;
4891 break;
4892 default:
4893 abort ();
4895 #endif
4896 #endif
4898 if (alpha_auto_align_on && alpha_current_align < 2)
4899 alpha_align (2, (char *) NULL, alpha_insn_label, 0);
4900 if (alpha_current_align > 2)
4901 alpha_current_align = 2;
4902 alpha_insn_label = NULL;
4904 p = frag_more (4);
4905 memset (p, 0, 4);
4906 fix_new_exp (frag_now, p - frag_now->fr_literal, 4,
4907 &e, 0, BFD_RELOC_GPREL32);
4910 /* Handle floating point allocation pseudo-ops. This is like the
4911 generic vresion, but it makes sure the current label, if any, is
4912 correctly aligned. */
4914 static void
4915 s_alpha_float_cons (type)
4916 int type;
4918 int log_size;
4920 switch (type)
4922 default:
4923 case 'f':
4924 case 'F':
4925 log_size = 2;
4926 break;
4928 case 'd':
4929 case 'D':
4930 case 'G':
4931 log_size = 3;
4932 break;
4934 case 'x':
4935 case 'X':
4936 case 'p':
4937 case 'P':
4938 log_size = 4;
4939 break;
4942 if (alpha_auto_align_on && alpha_current_align < log_size)
4943 alpha_align (log_size, (char *) NULL, alpha_insn_label, 0);
4944 if (alpha_current_align > log_size)
4945 alpha_current_align = log_size;
4946 alpha_insn_label = NULL;
4948 float_cons (type);
4951 /* Handle the .proc pseudo op. We don't really do much with it except
4952 parse it. */
4954 static void
4955 s_alpha_proc (is_static)
4956 int is_static ATTRIBUTE_UNUSED;
4958 char *name;
4959 char c;
4960 char *p;
4961 symbolS *symbolP;
4962 int temp;
4964 /* Takes ".proc name,nargs" */
4965 SKIP_WHITESPACE ();
4966 name = input_line_pointer;
4967 c = get_symbol_end ();
4968 p = input_line_pointer;
4969 symbolP = symbol_find_or_make (name);
4970 *p = c;
4971 SKIP_WHITESPACE ();
4972 if (*input_line_pointer != ',')
4974 *p = 0;
4975 as_warn (_("Expected comma after name \"%s\""), name);
4976 *p = c;
4977 temp = 0;
4978 ignore_rest_of_line ();
4980 else
4982 input_line_pointer++;
4983 temp = get_absolute_expression ();
4985 /* *symbol_get_obj (symbolP) = (signed char) temp; */
4986 as_warn (_("unhandled: .proc %s,%d"), name, temp);
4987 demand_empty_rest_of_line ();
4990 /* Handle the .set pseudo op. This is used to turn on and off most of
4991 the assembler features. */
4993 static void
4994 s_alpha_set (x)
4995 int x ATTRIBUTE_UNUSED;
4997 char *name, ch, *s;
4998 int yesno = 1;
5000 SKIP_WHITESPACE ();
5001 name = input_line_pointer;
5002 ch = get_symbol_end ();
5004 s = name;
5005 if (s[0] == 'n' && s[1] == 'o')
5007 yesno = 0;
5008 s += 2;
5010 if (!strcmp ("reorder", s))
5011 /* ignore */ ;
5012 else if (!strcmp ("at", s))
5013 alpha_noat_on = !yesno;
5014 else if (!strcmp ("macro", s))
5015 alpha_macros_on = yesno;
5016 else if (!strcmp ("move", s))
5017 /* ignore */ ;
5018 else if (!strcmp ("volatile", s))
5019 /* ignore */ ;
5020 else
5021 as_warn (_("Tried to .set unrecognized mode `%s'"), name);
5023 *input_line_pointer = ch;
5024 demand_empty_rest_of_line ();
5027 /* Handle the .base pseudo op. This changes the assembler's notion of
5028 the $gp register. */
5030 static void
5031 s_alpha_base (ignore)
5032 int ignore ATTRIBUTE_UNUSED;
5034 #if 0
5035 if (first_32bit_quadrant)
5037 /* not fatal, but it might not work in the end */
5038 as_warn (_("File overrides no-base-register option."));
5039 first_32bit_quadrant = 0;
5041 #endif
5043 SKIP_WHITESPACE ();
5044 if (*input_line_pointer == '$')
5045 { /* $rNN form */
5046 input_line_pointer++;
5047 if (*input_line_pointer == 'r')
5048 input_line_pointer++;
5051 alpha_gp_register = get_absolute_expression ();
5052 if (alpha_gp_register < 0 || alpha_gp_register > 31)
5054 alpha_gp_register = AXP_REG_GP;
5055 as_warn (_("Bad base register, using $%d."), alpha_gp_register);
5058 demand_empty_rest_of_line ();
5061 /* Handle the .align pseudo-op. This aligns to a power of two. It
5062 also adjusts any current instruction label. We treat this the same
5063 way the MIPS port does: .align 0 turns off auto alignment. */
5065 static void
5066 s_alpha_align (ignore)
5067 int ignore ATTRIBUTE_UNUSED;
5069 int align;
5070 char fill, *pfill;
5071 long max_alignment = 15;
5073 align = get_absolute_expression ();
5074 if (align > max_alignment)
5076 align = max_alignment;
5077 as_bad (_("Alignment too large: %d. assumed"), align);
5079 else if (align < 0)
5081 as_warn (_("Alignment negative: 0 assumed"));
5082 align = 0;
5085 if (*input_line_pointer == ',')
5087 input_line_pointer++;
5088 fill = get_absolute_expression ();
5089 pfill = &fill;
5091 else
5092 pfill = NULL;
5094 if (align != 0)
5096 alpha_auto_align_on = 1;
5097 alpha_align (align, pfill, alpha_insn_label, 1);
5099 else
5101 alpha_auto_align_on = 0;
5104 demand_empty_rest_of_line ();
5107 /* Hook the normal string processor to reset known alignment. */
5109 static void
5110 s_alpha_stringer (terminate)
5111 int terminate;
5113 alpha_current_align = 0;
5114 alpha_insn_label = NULL;
5115 stringer (terminate);
5118 /* Hook the normal space processing to reset known alignment. */
5120 static void
5121 s_alpha_space (ignore)
5122 int ignore;
5124 alpha_current_align = 0;
5125 alpha_insn_label = NULL;
5126 s_space (ignore);
5129 /* Hook into cons for auto-alignment. */
5131 void
5132 alpha_cons_align (size)
5133 int size;
5135 int log_size;
5137 log_size = 0;
5138 while ((size >>= 1) != 0)
5139 ++log_size;
5141 if (alpha_auto_align_on && alpha_current_align < log_size)
5142 alpha_align (log_size, (char *) NULL, alpha_insn_label, 0);
5143 if (alpha_current_align > log_size)
5144 alpha_current_align = log_size;
5145 alpha_insn_label = NULL;
5148 /* Here come the .uword, .ulong, and .uquad explicitly unaligned
5149 pseudos. We just turn off auto-alignment and call down to cons. */
5151 static void
5152 s_alpha_ucons (bytes)
5153 int bytes;
5155 int hold = alpha_auto_align_on;
5156 alpha_auto_align_on = 0;
5157 cons (bytes);
5158 alpha_auto_align_on = hold;
5161 /* Switch the working cpu type. */
5163 static void
5164 s_alpha_arch (ignored)
5165 int ignored ATTRIBUTE_UNUSED;
5167 char *name, ch;
5168 const struct cpu_type *p;
5170 SKIP_WHITESPACE ();
5171 name = input_line_pointer;
5172 ch = get_symbol_end ();
5174 for (p = cpu_types; p->name; ++p)
5175 if (strcmp (name, p->name) == 0)
5177 alpha_target_name = p->name, alpha_target = p->flags;
5178 goto found;
5180 as_warn ("Unknown CPU identifier `%s'", name);
5182 found:
5183 *input_line_pointer = ch;
5184 demand_empty_rest_of_line ();
5187 #ifdef DEBUG1
5188 /* print token expression with alpha specific extension. */
5190 static void
5191 alpha_print_token (f, exp)
5192 FILE *f;
5193 const expressionS *exp;
5195 switch (exp->X_op)
5197 case O_cpregister:
5198 putc (',', f);
5199 /* FALLTHRU */
5200 case O_pregister:
5201 putc ('(', f);
5203 expressionS nexp = *exp;
5204 nexp.X_op = O_register;
5205 print_expr (f, &nexp);
5207 putc (')', f);
5208 break;
5209 default:
5210 print_expr (f, exp);
5211 break;
5213 return;
5215 #endif
5217 /* The target specific pseudo-ops which we support. */
5219 const pseudo_typeS md_pseudo_table[] = {
5220 #ifdef OBJ_ECOFF
5221 {"comm", s_alpha_comm, 0}, /* osf1 compiler does this */
5222 {"rdata", s_alpha_rdata, 0},
5223 #endif
5224 {"text", s_alpha_text, 0},
5225 {"data", s_alpha_data, 0},
5226 #ifdef OBJ_ECOFF
5227 {"sdata", s_alpha_sdata, 0},
5228 #endif
5229 #ifdef OBJ_ELF
5230 {"section", s_alpha_section, 0},
5231 {"section.s", s_alpha_section, 0},
5232 {"sect", s_alpha_section, 0},
5233 {"sect.s", s_alpha_section, 0},
5234 #endif
5235 #ifdef OBJ_EVAX
5236 { "pdesc", s_alpha_pdesc, 0},
5237 { "name", s_alpha_name, 0},
5238 { "linkage", s_alpha_linkage, 0},
5239 { "code_address", s_alpha_code_address, 0},
5240 { "ent", s_alpha_ent, 0},
5241 { "frame", s_alpha_frame, 0},
5242 { "fp_save", s_alpha_fp_save, 0},
5243 { "mask", s_alpha_mask, 0},
5244 { "fmask", s_alpha_fmask, 0},
5245 { "end", s_alpha_end, 0},
5246 { "file", s_alpha_file, 0},
5247 { "rdata", s_alpha_section, 1},
5248 { "comm", s_alpha_comm, 0},
5249 { "link", s_alpha_section, 3},
5250 { "ctors", s_alpha_section, 4},
5251 { "dtors", s_alpha_section, 5},
5252 #endif
5253 #ifdef OBJ_ELF
5254 /* Frame related pseudos. */
5255 {"ent", s_alpha_ent, 0},
5256 {"end", s_alpha_end, 0},
5257 {"mask", s_alpha_mask, 0},
5258 {"fmask", s_alpha_mask, 1},
5259 {"frame", s_alpha_frame, 0},
5260 {"prologue", s_alpha_prologue, 0},
5261 {"file", s_alpha_file, 5},
5262 {"loc", s_alpha_loc, 9},
5263 {"stabs", s_alpha_stab, 's'},
5264 {"stabn", s_alpha_stab, 'n'},
5265 /* COFF debugging related pseudos. */
5266 {"begin", s_alpha_coff_wrapper, 0},
5267 {"bend", s_alpha_coff_wrapper, 1},
5268 {"def", s_alpha_coff_wrapper, 2},
5269 {"dim", s_alpha_coff_wrapper, 3},
5270 {"endef", s_alpha_coff_wrapper, 4},
5271 {"scl", s_alpha_coff_wrapper, 5},
5272 {"tag", s_alpha_coff_wrapper, 6},
5273 {"val", s_alpha_coff_wrapper, 7},
5274 #else
5275 {"prologue", s_ignore, 0},
5276 #endif
5277 {"gprel32", s_alpha_gprel32, 0},
5278 {"t_floating", s_alpha_float_cons, 'd'},
5279 {"s_floating", s_alpha_float_cons, 'f'},
5280 {"f_floating", s_alpha_float_cons, 'F'},
5281 {"g_floating", s_alpha_float_cons, 'G'},
5282 {"d_floating", s_alpha_float_cons, 'D'},
5284 {"proc", s_alpha_proc, 0},
5285 {"aproc", s_alpha_proc, 1},
5286 {"set", s_alpha_set, 0},
5287 {"reguse", s_ignore, 0},
5288 {"livereg", s_ignore, 0},
5289 {"base", s_alpha_base, 0}, /*??*/
5290 {"option", s_ignore, 0},
5291 {"aent", s_ignore, 0},
5292 {"ugen", s_ignore, 0},
5293 {"eflag", s_ignore, 0},
5295 {"align", s_alpha_align, 0},
5296 {"double", s_alpha_float_cons, 'd'},
5297 {"float", s_alpha_float_cons, 'f'},
5298 {"single", s_alpha_float_cons, 'f'},
5299 {"ascii", s_alpha_stringer, 0},
5300 {"asciz", s_alpha_stringer, 1},
5301 {"string", s_alpha_stringer, 1},
5302 {"space", s_alpha_space, 0},
5303 {"skip", s_alpha_space, 0},
5304 {"zero", s_alpha_space, 0},
5306 /* Unaligned data pseudos. */
5307 {"uword", s_alpha_ucons, 2},
5308 {"ulong", s_alpha_ucons, 4},
5309 {"uquad", s_alpha_ucons, 8},
5311 #ifdef OBJ_ELF
5312 /* Dwarf wants these versions of unaligned. */
5313 {"2byte", s_alpha_ucons, 2},
5314 {"4byte", s_alpha_ucons, 4},
5315 {"8byte", s_alpha_ucons, 8},
5316 #endif
5318 /* We don't do any optimizing, so we can safely ignore these. */
5319 {"noalias", s_ignore, 0},
5320 {"alias", s_ignore, 0},
5322 {"arch", s_alpha_arch, 0},
5324 {NULL, 0, 0},
5327 /* Build a BFD section with its flags set appropriately for the .lita,
5328 .lit8, or .lit4 sections. */
5330 static void
5331 create_literal_section (name, secp, symp)
5332 const char *name;
5333 segT *secp;
5334 symbolS **symp;
5336 segT current_section = now_seg;
5337 int current_subsec = now_subseg;
5338 segT new_sec;
5340 *secp = new_sec = subseg_new (name, 0);
5341 subseg_set (current_section, current_subsec);
5342 bfd_set_section_alignment (stdoutput, new_sec, 4);
5343 bfd_set_section_flags (stdoutput, new_sec,
5344 SEC_RELOC | SEC_ALLOC | SEC_LOAD | SEC_READONLY
5345 | SEC_DATA);
5347 S_CLEAR_EXTERNAL (*symp = section_symbol (new_sec));
5350 #ifdef OBJ_ECOFF
5352 /* @@@ GP selection voodoo. All of this seems overly complicated and
5353 unnecessary; which is the primary reason it's for ECOFF only. */
5355 static inline void
5356 maybe_set_gp (sec)
5357 asection *sec;
5359 bfd_vma vma;
5360 if (!sec)
5361 return;
5362 vma = bfd_get_section_vma (foo, sec);
5363 if (vma && vma < alpha_gp_value)
5364 alpha_gp_value = vma;
5367 static void
5368 select_gp_value ()
5370 assert (alpha_gp_value == 0);
5372 /* Get minus-one in whatever width... */
5373 alpha_gp_value = 0;
5374 alpha_gp_value--;
5376 /* Select the smallest VMA of these existing sections. */
5377 maybe_set_gp (alpha_lita_section);
5378 #if 0
5379 /* These were disabled before -- should we use them? */
5380 maybe_set_gp (sdata);
5381 maybe_set_gp (lit8_sec);
5382 maybe_set_gp (lit4_sec);
5383 #endif
5385 /* @@ Will a simple 0x8000 work here? If not, why not? */
5386 #define GP_ADJUSTMENT (0x8000 - 0x10)
5388 alpha_gp_value += GP_ADJUSTMENT;
5390 S_SET_VALUE (alpha_gp_symbol, alpha_gp_value);
5392 #ifdef DEBUG1
5393 printf (_("Chose GP value of %lx\n"), alpha_gp_value);
5394 #endif
5396 #endif /* OBJ_ECOFF */
5398 #ifdef OBJ_ELF
5399 /* Map 's' to SHF_ALPHA_GPREL. */
5402 alpha_elf_section_letter (letter, ptr_msg)
5403 int letter;
5404 char **ptr_msg;
5406 if (letter == 's')
5407 return SHF_ALPHA_GPREL;
5409 *ptr_msg = _("Bad .section directive: want a,s,w,x,M,S in string");
5410 return 0;
5413 /* Map SHF_ALPHA_GPREL to SEC_SMALL_DATA. */
5415 flagword
5416 alpha_elf_section_flags (flags, attr, type)
5417 flagword flags;
5418 int attr, type ATTRIBUTE_UNUSED;
5420 if (attr & SHF_ALPHA_GPREL)
5421 flags |= SEC_SMALL_DATA;
5422 return flags;
5424 #endif /* OBJ_ELF */
5426 /* Called internally to handle all alignment needs. This takes care
5427 of eliding calls to frag_align if'n the cached current alignment
5428 says we've already got it, as well as taking care of the auto-align
5429 feature wrt labels. */
5431 static void
5432 alpha_align (n, pfill, label, force)
5433 int n;
5434 char *pfill;
5435 symbolS *label;
5436 int force ATTRIBUTE_UNUSED;
5438 if (alpha_current_align >= n)
5439 return;
5441 if (pfill == NULL)
5443 if (subseg_text_p (now_seg))
5444 frag_align_code (n, 0);
5445 else
5446 frag_align (n, 0, 0);
5448 else
5449 frag_align (n, *pfill, 0);
5451 alpha_current_align = n;
5453 if (label != NULL && S_GET_SEGMENT (label) == now_seg)
5455 symbol_set_frag (label, frag_now);
5456 S_SET_VALUE (label, (valueT) frag_now_fix ());
5459 record_alignment (now_seg, n);
5461 /* ??? If alpha_flag_relax && force && elf, record the requested alignment
5462 in a reloc for the linker to see. */
5465 /* This is called from HANDLE_ALIGN in write.c. Fill in the contents
5466 of an rs_align_code fragment. */
5468 void
5469 alpha_handle_align (fragp)
5470 fragS *fragp;
5472 static char const unop[4] = { 0x00, 0x00, 0xe0, 0x2f };
5473 static char const nopunop[8] = {
5474 0x1f, 0x04, 0xff, 0x47,
5475 0x00, 0x00, 0xe0, 0x2f
5478 int bytes, fix;
5479 char *p;
5481 if (fragp->fr_type != rs_align_code)
5482 return;
5484 bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix;
5485 p = fragp->fr_literal + fragp->fr_fix;
5486 fix = 0;
5488 if (bytes & 3)
5490 fix = bytes & 3;
5491 memset (p, 0, fix);
5492 p += fix;
5493 bytes -= fix;
5496 if (bytes & 4)
5498 memcpy (p, unop, 4);
5499 p += 4;
5500 bytes -= 4;
5501 fix += 4;
5504 memcpy (p, nopunop, 8);
5506 fragp->fr_fix += fix;
5507 fragp->fr_var = 8;
5510 /* The Alpha has support for some VAX floating point types, as well as for
5511 IEEE floating point. We consider IEEE to be the primary floating point
5512 format, and sneak in the VAX floating point support here. */
5513 #define md_atof vax_md_atof
5514 #include "config/atof-vax.c"