* config/tc-alpha.c (alpha_force_relocation): Don't assert that
[binutils.git] / gas / config / tc-alpha.c
blob44c651b755af9e547ceaa2c56abb937bb2443f25
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 return 0;
1406 /* Return true if we can partially resolve a relocation now. */
1409 alpha_fix_adjustable (f)
1410 fixS *f;
1412 #ifdef OBJ_ELF
1413 /* Prevent all adjustments to global symbols */
1414 if (S_IS_EXTERN (f->fx_addsy) || S_IS_WEAK (f->fx_addsy))
1415 return 0;
1416 #endif
1418 /* Are there any relocation types for which we must generate a reloc
1419 but we can adjust the values contained within it? */
1420 switch (f->fx_r_type)
1422 case BFD_RELOC_ALPHA_GPDISP_HI16:
1423 case BFD_RELOC_ALPHA_GPDISP_LO16:
1424 case BFD_RELOC_ALPHA_GPDISP:
1425 return 0;
1427 case BFD_RELOC_ALPHA_LITERAL:
1428 case BFD_RELOC_ALPHA_ELF_LITERAL:
1429 case BFD_RELOC_ALPHA_LITUSE:
1430 case BFD_RELOC_ALPHA_LINKAGE:
1431 case BFD_RELOC_ALPHA_CODEADDR:
1432 return 1;
1434 case BFD_RELOC_VTABLE_ENTRY:
1435 case BFD_RELOC_VTABLE_INHERIT:
1436 return 0;
1438 case BFD_RELOC_GPREL16:
1439 case BFD_RELOC_GPREL32:
1440 case BFD_RELOC_ALPHA_GPREL_HI16:
1441 case BFD_RELOC_ALPHA_GPREL_LO16:
1442 case BFD_RELOC_23_PCREL_S2:
1443 case BFD_RELOC_32:
1444 case BFD_RELOC_64:
1445 case BFD_RELOC_ALPHA_HINT:
1446 return 1;
1448 default:
1449 return 1;
1451 /*NOTREACHED*/
1454 /* Generate the BFD reloc to be stuck in the object file from the
1455 fixup used internally in the assembler. */
1457 arelent *
1458 tc_gen_reloc (sec, fixp)
1459 asection *sec ATTRIBUTE_UNUSED;
1460 fixS *fixp;
1462 arelent *reloc;
1464 reloc = (arelent *) xmalloc (sizeof (arelent));
1465 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
1466 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
1467 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
1469 /* Make sure none of our internal relocations make it this far.
1470 They'd better have been fully resolved by this point. */
1471 assert ((int) fixp->fx_r_type > 0);
1473 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
1474 if (reloc->howto == NULL)
1476 as_bad_where (fixp->fx_file, fixp->fx_line,
1477 _("cannot represent `%s' relocation in object file"),
1478 bfd_get_reloc_code_name (fixp->fx_r_type));
1479 return NULL;
1482 if (!fixp->fx_pcrel != !reloc->howto->pc_relative)
1484 as_fatal (_("internal error? cannot generate `%s' relocation"),
1485 bfd_get_reloc_code_name (fixp->fx_r_type));
1487 assert (!fixp->fx_pcrel == !reloc->howto->pc_relative);
1489 #ifdef OBJ_ECOFF
1490 if (fixp->fx_r_type == BFD_RELOC_ALPHA_LITERAL)
1492 /* fake out bfd_perform_relocation. sigh */
1493 reloc->addend = -alpha_gp_value;
1495 else
1496 #endif
1498 reloc->addend = fixp->fx_offset;
1499 #ifdef OBJ_ELF
1501 * Ohhh, this is ugly. The problem is that if this is a local global
1502 * symbol, the relocation will entirely be performed at link time, not
1503 * at assembly time. bfd_perform_reloc doesn't know about this sort
1504 * of thing, and as a result we need to fake it out here.
1506 if ((S_IS_EXTERN (fixp->fx_addsy) || S_IS_WEAK (fixp->fx_addsy)
1507 || (S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_MERGE))
1508 && !S_IS_COMMON (fixp->fx_addsy))
1509 reloc->addend -= symbol_get_bfdsym (fixp->fx_addsy)->value;
1510 #endif
1513 return reloc;
1516 /* Parse a register name off of the input_line and return a register
1517 number. Gets md_undefined_symbol above to do the register name
1518 matching for us.
1520 Only called as a part of processing the ECOFF .frame directive. */
1523 tc_get_register (frame)
1524 int frame ATTRIBUTE_UNUSED;
1526 int framereg = AXP_REG_SP;
1528 SKIP_WHITESPACE ();
1529 if (*input_line_pointer == '$')
1531 char *s = input_line_pointer;
1532 char c = get_symbol_end ();
1533 symbolS *sym = md_undefined_symbol (s);
1535 *strchr (s, '\0') = c;
1536 if (sym && (framereg = S_GET_VALUE (sym)) <= 31)
1537 goto found;
1539 as_warn (_("frame reg expected, using $%d."), framereg);
1541 found:
1542 note_gpreg (framereg);
1543 return framereg;
1546 /* This is called before the symbol table is processed. In order to
1547 work with gcc when using mips-tfile, we must keep all local labels.
1548 However, in other cases, we want to discard them. If we were
1549 called with -g, but we didn't see any debugging information, it may
1550 mean that gcc is smuggling debugging information through to
1551 mips-tfile, in which case we must generate all local labels. */
1553 #ifdef OBJ_ECOFF
1555 void
1556 alpha_frob_file_before_adjust ()
1558 if (alpha_debug != 0
1559 && ! ecoff_debugging_seen)
1560 flag_keep_locals = 1;
1563 #endif /* OBJ_ECOFF */
1565 static struct alpha_reloc_tag *
1566 get_alpha_reloc_tag (sequence)
1567 long sequence;
1569 char buffer[ALPHA_RELOC_DIGITS];
1570 struct alpha_reloc_tag *info;
1572 sprintf (buffer, "!%ld", sequence);
1574 info = (struct alpha_reloc_tag *) hash_find (alpha_literal_hash, buffer);
1575 if (! info)
1577 size_t len = strlen (buffer);
1578 const char *errmsg;
1580 info = (struct alpha_reloc_tag *)
1581 xcalloc (sizeof (struct alpha_reloc_tag) + len, 1);
1583 info->segment = now_seg;
1584 info->sequence = sequence;
1585 strcpy (info->string, buffer);
1586 errmsg = hash_insert (alpha_literal_hash, info->string, (PTR) info);
1587 if (errmsg)
1588 as_fatal (errmsg);
1591 return info;
1594 /* Before the relocations are written, reorder them, so that user
1595 supplied !lituse relocations follow the appropriate !literal
1596 relocations, and similarly for !gpdisp relocations. */
1598 void
1599 alpha_adjust_symtab ()
1601 if (alpha_literal_hash)
1602 bfd_map_over_sections (stdoutput, alpha_adjust_symtab_relocs, NULL);
1605 static void
1606 alpha_adjust_symtab_relocs (abfd, sec, ptr)
1607 bfd *abfd ATTRIBUTE_UNUSED;
1608 asection *sec;
1609 PTR ptr ATTRIBUTE_UNUSED;
1611 segment_info_type *seginfo = seg_info (sec);
1612 fixS **prevP;
1613 fixS *fixp;
1614 fixS *next;
1615 fixS *slave;
1616 unsigned long n_slaves = 0;
1618 /* If seginfo is NULL, we did not create this section; don't do
1619 anything with it. By using a pointer to a pointer, we can update
1620 the links in place. */
1621 if (seginfo == NULL)
1622 return;
1624 /* If there are no relocations, skip the section. */
1625 if (! seginfo->fix_root)
1626 return;
1628 /* First rebuild the fixup chain without the expicit lituse and
1629 gpdisp_lo16 relocs. */
1630 prevP = &seginfo->fix_root;
1631 for (fixp = seginfo->fix_root; fixp; fixp = next)
1633 next = fixp->fx_next;
1634 fixp->fx_next = (fixS *) 0;
1636 switch (fixp->fx_r_type)
1638 case BFD_RELOC_ALPHA_LITUSE:
1639 n_slaves++;
1640 if (fixp->tc_fix_data.info->n_master == 0)
1641 as_bad_where (fixp->fx_file, fixp->fx_line,
1642 _("No !literal!%ld was found"),
1643 fixp->tc_fix_data.info->sequence);
1644 break;
1646 case BFD_RELOC_ALPHA_GPDISP_LO16:
1647 n_slaves++;
1648 if (fixp->tc_fix_data.info->n_master == 0)
1649 as_bad_where (fixp->fx_file, fixp->fx_line,
1650 _("No ldah !gpdisp!%ld was found"),
1651 fixp->tc_fix_data.info->sequence);
1652 break;
1654 default:
1655 *prevP = fixp;
1656 prevP = &fixp->fx_next;
1657 break;
1661 /* If there were any dependent relocations, go and add them back to
1662 the chain. They are linked through the next_reloc field in
1663 reverse order, so as we go through the next_reloc chain, we
1664 effectively reverse the chain once again.
1666 Except if there is more than one !literal for a given sequence
1667 number. In that case, the programmer and/or compiler is not sure
1668 how control flows from literal to lituse, and we can't be sure to
1669 get the relaxation correct.
1671 ??? Well, actually we could, if there are enough lituses such that
1672 we can make each literal have at least one of each lituse type
1673 present. Not implemented.
1675 Also suppress the optimization if the !literals/!lituses are spread
1676 in different segments. This can happen with "intersting" uses of
1677 inline assembly; examples are present in the Linux kernel semaphores. */
1679 for (fixp = seginfo->fix_root; fixp; fixp = next)
1681 next = fixp->fx_next;
1682 switch (fixp->fx_r_type)
1684 case BFD_RELOC_ALPHA_ELF_LITERAL:
1685 if (fixp->tc_fix_data.info->n_master == 1
1686 && ! fixp->tc_fix_data.info->multi_section_p)
1688 for (slave = fixp->tc_fix_data.info->slaves;
1689 slave != (fixS *) 0;
1690 slave = slave->tc_fix_data.next_reloc)
1692 slave->fx_next = fixp->fx_next;
1693 fixp->fx_next = slave;
1696 break;
1698 case BFD_RELOC_ALPHA_GPDISP_HI16:
1699 if (fixp->tc_fix_data.info->n_slaves == 0)
1700 as_bad_where (fixp->fx_file, fixp->fx_line,
1701 _("No lda !gpdisp!%ld was found"),
1702 fixp->tc_fix_data.info->sequence);
1703 else
1705 slave = fixp->tc_fix_data.info->slaves;
1706 slave->fx_next = next;
1707 fixp->fx_next = slave;
1709 break;
1711 default:
1712 break;
1717 #ifdef DEBUG_ALPHA
1718 static void
1719 debug_exp (tok, ntok)
1720 expressionS tok[];
1721 int ntok;
1723 int i;
1725 fprintf (stderr, "debug_exp: %d tokens", ntok);
1726 for (i = 0; i < ntok; i++)
1728 expressionS *t = &tok[i];
1729 const char *name;
1730 switch (t->X_op)
1732 default: name = "unknown"; break;
1733 case O_illegal: name = "O_illegal"; break;
1734 case O_absent: name = "O_absent"; break;
1735 case O_constant: name = "O_constant"; break;
1736 case O_symbol: name = "O_symbol"; break;
1737 case O_symbol_rva: name = "O_symbol_rva"; break;
1738 case O_register: name = "O_register"; break;
1739 case O_big: name = "O_big"; break;
1740 case O_uminus: name = "O_uminus"; break;
1741 case O_bit_not: name = "O_bit_not"; break;
1742 case O_logical_not: name = "O_logical_not"; break;
1743 case O_multiply: name = "O_multiply"; break;
1744 case O_divide: name = "O_divide"; break;
1745 case O_modulus: name = "O_modulus"; break;
1746 case O_left_shift: name = "O_left_shift"; break;
1747 case O_right_shift: name = "O_right_shift"; break;
1748 case O_bit_inclusive_or: name = "O_bit_inclusive_or"; break;
1749 case O_bit_or_not: name = "O_bit_or_not"; break;
1750 case O_bit_exclusive_or: name = "O_bit_exclusive_or"; break;
1751 case O_bit_and: name = "O_bit_and"; break;
1752 case O_add: name = "O_add"; break;
1753 case O_subtract: name = "O_subtract"; break;
1754 case O_eq: name = "O_eq"; break;
1755 case O_ne: name = "O_ne"; break;
1756 case O_lt: name = "O_lt"; break;
1757 case O_le: name = "O_le"; break;
1758 case O_ge: name = "O_ge"; break;
1759 case O_gt: name = "O_gt"; break;
1760 case O_logical_and: name = "O_logical_and"; break;
1761 case O_logical_or: name = "O_logical_or"; break;
1762 case O_index: name = "O_index"; break;
1763 case O_pregister: name = "O_pregister"; break;
1764 case O_cpregister: name = "O_cpregister"; break;
1765 case O_literal: name = "O_literal"; break;
1766 case O_lituse_base: name = "O_lituse_base"; break;
1767 case O_lituse_bytoff: name = "O_lituse_bytoff"; break;
1768 case O_lituse_jsr: name = "O_lituse_jsr"; break;
1769 case O_gpdisp: name = "O_gpdisp"; break;
1770 case O_gprelhigh: name = "O_gprelhigh"; break;
1771 case O_gprellow: name = "O_gprellow"; break;
1772 case O_gprel: name = "O_gprel"; break;
1773 case O_md11: name = "O_md11"; break;
1774 case O_md12: name = "O_md12"; break;
1775 case O_md13: name = "O_md13"; break;
1776 case O_md14: name = "O_md14"; break;
1777 case O_md15: name = "O_md15"; break;
1778 case O_md16: name = "O_md16"; break;
1781 fprintf (stderr, ", %s(%s, %s, %d)", name,
1782 (t->X_add_symbol) ? S_GET_NAME (t->X_add_symbol) : "--",
1783 (t->X_op_symbol) ? S_GET_NAME (t->X_op_symbol) : "--",
1784 (int) t->X_add_number);
1786 fprintf (stderr, "\n");
1787 fflush (stderr);
1789 #endif
1791 /* Parse the arguments to an opcode. */
1793 static int
1794 tokenize_arguments (str, tok, ntok)
1795 char *str;
1796 expressionS tok[];
1797 int ntok;
1799 expressionS *end_tok = tok + ntok;
1800 char *old_input_line_pointer;
1801 int saw_comma = 0, saw_arg = 0;
1802 #ifdef DEBUG_ALPHA
1803 expressionS *orig_tok = tok;
1804 #endif
1805 char *p;
1806 const struct alpha_reloc_op_tag *r;
1807 int c, i;
1808 size_t len;
1809 int reloc_found_p = 0;
1811 memset (tok, 0, sizeof (*tok) * ntok);
1813 /* Save and restore input_line_pointer around this function */
1814 old_input_line_pointer = input_line_pointer;
1815 input_line_pointer = str;
1817 #ifdef RELOC_OP_P
1818 /* ??? Wrest control of ! away from the regular expression parser. */
1819 is_end_of_line[(unsigned char) '!'] = 1;
1820 #endif
1822 while (tok < end_tok && *input_line_pointer)
1824 SKIP_WHITESPACE ();
1825 switch (*input_line_pointer)
1827 case '\0':
1828 goto fini;
1830 #ifdef RELOC_OP_P
1831 case '!':
1832 /* A relocation operand can be placed after the normal operand on an
1833 assembly language statement, and has the following form:
1834 !relocation_type!sequence_number. */
1835 if (reloc_found_p)
1836 { /* only support one relocation op per insn */
1837 as_bad (_("More than one relocation op per insn"));
1838 goto err_report;
1841 if (!saw_arg)
1842 goto err;
1844 ++input_line_pointer;
1845 SKIP_WHITESPACE ();
1846 p = input_line_pointer;
1847 c = get_symbol_end ();
1849 /* Parse !relocation_type */
1850 len = input_line_pointer - p;
1851 if (len == 0)
1853 as_bad (_("No relocation operand"));
1854 goto err_report;
1857 r = &alpha_reloc_op[0];
1858 for (i = alpha_num_reloc_op - 1; i >= 0; i--, r++)
1859 if (len == r->length && memcmp (p, r->name, len) == 0)
1860 break;
1861 if (i < 0)
1863 as_bad (_("Unknown relocation operand: !%s"), p);
1864 goto err_report;
1867 *input_line_pointer = c;
1868 SKIP_WHITESPACE ();
1869 if (*input_line_pointer != '!')
1871 if (r->require_seq)
1873 as_bad (_("no sequence number after !%s"), p);
1874 goto err_report;
1877 tok->X_add_number = 0;
1879 else
1881 if (! r->allow_seq)
1883 as_bad (_("!%s does not use a sequence number"), p);
1884 goto err_report;
1887 input_line_pointer++;
1889 /* Parse !sequence_number */
1890 expression (tok);
1891 if (tok->X_op != O_constant || tok->X_add_number <= 0)
1893 as_bad (_("Bad sequence number: !%s!%s"),
1894 r->name, input_line_pointer);
1895 goto err_report;
1899 tok->X_op = r->op;
1900 reloc_found_p = 1;
1901 ++tok;
1902 break;
1903 #endif /* RELOC_OP_P */
1905 case ',':
1906 ++input_line_pointer;
1907 if (saw_comma || !saw_arg)
1908 goto err;
1909 saw_comma = 1;
1910 break;
1912 case '(':
1914 char *hold = input_line_pointer++;
1916 /* First try for parenthesized register ... */
1917 expression (tok);
1918 if (*input_line_pointer == ')' && tok->X_op == O_register)
1920 tok->X_op = (saw_comma ? O_cpregister : O_pregister);
1921 saw_comma = 0;
1922 saw_arg = 1;
1923 ++input_line_pointer;
1924 ++tok;
1925 break;
1928 /* ... then fall through to plain expression */
1929 input_line_pointer = hold;
1932 default:
1933 if (saw_arg && !saw_comma)
1934 goto err;
1936 expression (tok);
1937 if (tok->X_op == O_illegal || tok->X_op == O_absent)
1938 goto err;
1940 saw_comma = 0;
1941 saw_arg = 1;
1942 ++tok;
1943 break;
1947 fini:
1948 if (saw_comma)
1949 goto err;
1950 input_line_pointer = old_input_line_pointer;
1952 #ifdef DEBUG_ALPHA
1953 debug_exp (orig_tok, ntok - (end_tok - tok));
1954 #endif
1955 #ifdef RELOC_OP_P
1956 is_end_of_line[(unsigned char) '!'] = 0;
1957 #endif
1959 return ntok - (end_tok - tok);
1961 err:
1962 #ifdef RELOC_OP_P
1963 is_end_of_line[(unsigned char) '!'] = 0;
1964 #endif
1965 input_line_pointer = old_input_line_pointer;
1966 return TOKENIZE_ERROR;
1968 err_report:
1969 #ifdef RELOC_OP_P
1970 is_end_of_line[(unsigned char) '!'] = 0;
1971 #endif
1972 input_line_pointer = old_input_line_pointer;
1973 return TOKENIZE_ERROR_REPORT;
1976 /* Search forward through all variants of an opcode looking for a
1977 syntax match. */
1979 static const struct alpha_opcode *
1980 find_opcode_match (first_opcode, tok, pntok, pcpumatch)
1981 const struct alpha_opcode *first_opcode;
1982 const expressionS *tok;
1983 int *pntok;
1984 int *pcpumatch;
1986 const struct alpha_opcode *opcode = first_opcode;
1987 int ntok = *pntok;
1988 int got_cpu_match = 0;
1992 const unsigned char *opidx;
1993 int tokidx = 0;
1995 /* Don't match opcodes that don't exist on this architecture */
1996 if (!(opcode->flags & alpha_target))
1997 goto match_failed;
1999 got_cpu_match = 1;
2001 for (opidx = opcode->operands; *opidx; ++opidx)
2003 const struct alpha_operand *operand = &alpha_operands[*opidx];
2005 /* only take input from real operands */
2006 if (operand->flags & AXP_OPERAND_FAKE)
2007 continue;
2009 /* when we expect input, make sure we have it */
2010 if (tokidx >= ntok)
2012 if ((operand->flags & AXP_OPERAND_OPTIONAL_MASK) == 0)
2013 goto match_failed;
2014 continue;
2017 /* match operand type with expression type */
2018 switch (operand->flags & AXP_OPERAND_TYPECHECK_MASK)
2020 case AXP_OPERAND_IR:
2021 if (tok[tokidx].X_op != O_register
2022 || !is_ir_num (tok[tokidx].X_add_number))
2023 goto match_failed;
2024 break;
2025 case AXP_OPERAND_FPR:
2026 if (tok[tokidx].X_op != O_register
2027 || !is_fpr_num (tok[tokidx].X_add_number))
2028 goto match_failed;
2029 break;
2030 case AXP_OPERAND_IR | AXP_OPERAND_PARENS:
2031 if (tok[tokidx].X_op != O_pregister
2032 || !is_ir_num (tok[tokidx].X_add_number))
2033 goto match_failed;
2034 break;
2035 case AXP_OPERAND_IR | AXP_OPERAND_PARENS | AXP_OPERAND_COMMA:
2036 if (tok[tokidx].X_op != O_cpregister
2037 || !is_ir_num (tok[tokidx].X_add_number))
2038 goto match_failed;
2039 break;
2041 case AXP_OPERAND_RELATIVE:
2042 case AXP_OPERAND_SIGNED:
2043 case AXP_OPERAND_UNSIGNED:
2044 switch (tok[tokidx].X_op)
2046 case O_illegal:
2047 case O_absent:
2048 case O_register:
2049 case O_pregister:
2050 case O_cpregister:
2051 goto match_failed;
2053 default:
2054 break;
2056 break;
2058 default:
2059 /* everything else should have been fake */
2060 abort ();
2062 ++tokidx;
2065 /* possible match -- did we use all of our input? */
2066 if (tokidx == ntok)
2068 *pntok = ntok;
2069 return opcode;
2072 match_failed:;
2074 while (++opcode - alpha_opcodes < alpha_num_opcodes
2075 && !strcmp (opcode->name, first_opcode->name));
2077 if (*pcpumatch)
2078 *pcpumatch = got_cpu_match;
2080 return NULL;
2083 /* Search forward through all variants of a macro looking for a syntax
2084 match. */
2086 static const struct alpha_macro *
2087 find_macro_match (first_macro, tok, pntok)
2088 const struct alpha_macro *first_macro;
2089 const expressionS *tok;
2090 int *pntok;
2092 const struct alpha_macro *macro = first_macro;
2093 int ntok = *pntok;
2097 const enum alpha_macro_arg *arg = macro->argsets;
2098 int tokidx = 0;
2100 while (*arg)
2102 switch (*arg)
2104 case MACRO_EOA:
2105 if (tokidx == ntok)
2106 return macro;
2107 else
2108 tokidx = 0;
2109 break;
2111 /* index register */
2112 case MACRO_IR:
2113 if (tokidx >= ntok || tok[tokidx].X_op != O_register
2114 || !is_ir_num (tok[tokidx].X_add_number))
2115 goto match_failed;
2116 ++tokidx;
2117 break;
2119 /* parenthesized index register */
2120 case MACRO_PIR:
2121 if (tokidx >= ntok || tok[tokidx].X_op != O_pregister
2122 || !is_ir_num (tok[tokidx].X_add_number))
2123 goto match_failed;
2124 ++tokidx;
2125 break;
2127 /* optional parenthesized index register */
2128 case MACRO_OPIR:
2129 if (tokidx < ntok && tok[tokidx].X_op == O_pregister
2130 && is_ir_num (tok[tokidx].X_add_number))
2131 ++tokidx;
2132 break;
2134 /* leading comma with a parenthesized index register */
2135 case MACRO_CPIR:
2136 if (tokidx >= ntok || tok[tokidx].X_op != O_cpregister
2137 || !is_ir_num (tok[tokidx].X_add_number))
2138 goto match_failed;
2139 ++tokidx;
2140 break;
2142 /* floating point register */
2143 case MACRO_FPR:
2144 if (tokidx >= ntok || tok[tokidx].X_op != O_register
2145 || !is_fpr_num (tok[tokidx].X_add_number))
2146 goto match_failed;
2147 ++tokidx;
2148 break;
2150 /* normal expression */
2151 case MACRO_EXP:
2152 if (tokidx >= ntok)
2153 goto match_failed;
2154 switch (tok[tokidx].X_op)
2156 case O_illegal:
2157 case O_absent:
2158 case O_register:
2159 case O_pregister:
2160 case O_cpregister:
2161 case O_literal:
2162 case O_lituse_base:
2163 case O_lituse_bytoff:
2164 case O_lituse_jsr:
2165 case O_gpdisp:
2166 case O_gprelhigh:
2167 case O_gprellow:
2168 case O_gprel:
2169 goto match_failed;
2171 default:
2172 break;
2174 ++tokidx;
2175 break;
2177 match_failed:
2178 while (*arg != MACRO_EOA)
2179 ++arg;
2180 tokidx = 0;
2181 break;
2183 ++arg;
2186 while (++macro - alpha_macros < alpha_num_macros
2187 && !strcmp (macro->name, first_macro->name));
2189 return NULL;
2192 /* Insert an operand value into an instruction. */
2194 static unsigned
2195 insert_operand (insn, operand, val, file, line)
2196 unsigned insn;
2197 const struct alpha_operand *operand;
2198 offsetT val;
2199 char *file;
2200 unsigned line;
2202 if (operand->bits != 32 && !(operand->flags & AXP_OPERAND_NOOVERFLOW))
2204 offsetT min, max;
2206 if (operand->flags & AXP_OPERAND_SIGNED)
2208 max = (1 << (operand->bits - 1)) - 1;
2209 min = -(1 << (operand->bits - 1));
2211 else
2213 max = (1 << operand->bits) - 1;
2214 min = 0;
2217 if (val < min || val > max)
2219 const char *err =
2220 _("operand out of range (%s not between %d and %d)");
2221 char buf[sizeof (val) * 3 + 2];
2223 sprint_value (buf, val);
2224 if (file)
2225 as_warn_where (file, line, err, buf, min, max);
2226 else
2227 as_warn (err, buf, min, max);
2231 if (operand->insert)
2233 const char *errmsg = NULL;
2235 insn = (*operand->insert) (insn, val, &errmsg);
2236 if (errmsg)
2237 as_warn (errmsg);
2239 else
2240 insn |= ((val & ((1 << operand->bits) - 1)) << operand->shift);
2242 return insn;
2246 * Turn an opcode description and a set of arguments into
2247 * an instruction and a fixup.
2250 static void
2251 assemble_insn (opcode, tok, ntok, insn, reloc)
2252 const struct alpha_opcode *opcode;
2253 const expressionS *tok;
2254 int ntok;
2255 struct alpha_insn *insn;
2256 bfd_reloc_code_real_type reloc;
2258 const struct alpha_operand *reloc_operand = NULL;
2259 const expressionS *reloc_exp = NULL;
2260 const unsigned char *argidx;
2261 unsigned image;
2262 int tokidx = 0;
2264 memset (insn, 0, sizeof (*insn));
2265 image = opcode->opcode;
2267 for (argidx = opcode->operands; *argidx; ++argidx)
2269 const struct alpha_operand *operand = &alpha_operands[*argidx];
2270 const expressionS *t = (const expressionS *) 0;
2272 if (operand->flags & AXP_OPERAND_FAKE)
2274 /* fake operands take no value and generate no fixup */
2275 image = insert_operand (image, operand, 0, NULL, 0);
2276 continue;
2279 if (tokidx >= ntok)
2281 switch (operand->flags & AXP_OPERAND_OPTIONAL_MASK)
2283 case AXP_OPERAND_DEFAULT_FIRST:
2284 t = &tok[0];
2285 break;
2286 case AXP_OPERAND_DEFAULT_SECOND:
2287 t = &tok[1];
2288 break;
2289 case AXP_OPERAND_DEFAULT_ZERO:
2291 static expressionS zero_exp;
2292 t = &zero_exp;
2293 zero_exp.X_op = O_constant;
2294 zero_exp.X_unsigned = 1;
2296 break;
2297 default:
2298 abort ();
2301 else
2302 t = &tok[tokidx++];
2304 switch (t->X_op)
2306 case O_register:
2307 case O_pregister:
2308 case O_cpregister:
2309 image = insert_operand (image, operand, regno (t->X_add_number),
2310 NULL, 0);
2311 break;
2313 case O_constant:
2314 image = insert_operand (image, operand, t->X_add_number, NULL, 0);
2315 assert (reloc_operand == NULL);
2316 reloc_operand = operand;
2317 reloc_exp = t;
2318 break;
2320 default:
2321 /* This is only 0 for fields that should contain registers,
2322 which means this pattern shouldn't have matched. */
2323 if (operand->default_reloc == 0)
2324 abort ();
2326 /* There is one special case for which an insn receives two
2327 relocations, and thus the user-supplied reloc does not
2328 override the operand reloc. */
2329 if (operand->default_reloc == BFD_RELOC_ALPHA_HINT)
2331 struct alpha_fixup *fixup;
2333 if (insn->nfixups >= MAX_INSN_FIXUPS)
2334 as_fatal (_("too many fixups"));
2336 fixup = &insn->fixups[insn->nfixups++];
2337 fixup->exp = *t;
2338 fixup->reloc = BFD_RELOC_ALPHA_HINT;
2340 else
2342 if (reloc == BFD_RELOC_UNUSED)
2343 reloc = operand->default_reloc;
2345 assert (reloc_operand == NULL);
2346 reloc_operand = operand;
2347 reloc_exp = t;
2349 break;
2353 if (reloc != BFD_RELOC_UNUSED)
2355 struct alpha_fixup *fixup;
2357 if (insn->nfixups >= MAX_INSN_FIXUPS)
2358 as_fatal (_("too many fixups"));
2360 /* ??? My but this is hacky. But the OSF/1 assembler uses the same
2361 relocation tag for both ldah and lda with gpdisp. Choose the
2362 correct internal relocation based on the opcode. */
2363 if (reloc == BFD_RELOC_ALPHA_GPDISP)
2365 if (strcmp (opcode->name, "ldah") == 0)
2366 reloc = BFD_RELOC_ALPHA_GPDISP_HI16;
2367 else if (strcmp (opcode->name, "lda") == 0)
2368 reloc = BFD_RELOC_ALPHA_GPDISP_LO16;
2369 else
2370 as_bad (_("invalid relocation for instruction"));
2373 /* If this is a real relocation (as opposed to a lituse hint), then
2374 the relocation width should match the operand width. */
2375 else if (reloc < BFD_RELOC_UNUSED)
2377 reloc_howto_type *reloc_howto
2378 = bfd_reloc_type_lookup (stdoutput, reloc);
2379 if (reloc_howto->bitsize != reloc_operand->bits)
2381 as_bad (_("invalid relocation for field"));
2382 return;
2386 fixup = &insn->fixups[insn->nfixups++];
2387 if (reloc_exp)
2388 fixup->exp = *reloc_exp;
2389 else
2390 fixup->exp.X_op = O_absent;
2391 fixup->reloc = reloc;
2394 insn->insn = image;
2398 * Actually output an instruction with its fixup.
2401 static void
2402 emit_insn (insn)
2403 struct alpha_insn *insn;
2405 char *f;
2406 int i;
2408 /* Take care of alignment duties. */
2409 if (alpha_auto_align_on && alpha_current_align < 2)
2410 alpha_align (2, (char *) NULL, alpha_insn_label, 0);
2411 if (alpha_current_align > 2)
2412 alpha_current_align = 2;
2413 alpha_insn_label = NULL;
2415 /* Write out the instruction. */
2416 f = frag_more (4);
2417 md_number_to_chars (f, insn->insn, 4);
2419 #ifdef OBJ_ELF
2420 dwarf2_emit_insn (4);
2421 #endif
2423 /* Apply the fixups in order */
2424 for (i = 0; i < insn->nfixups; ++i)
2426 const struct alpha_operand *operand = (const struct alpha_operand *) 0;
2427 struct alpha_fixup *fixup = &insn->fixups[i];
2428 struct alpha_reloc_tag *info;
2429 int size, pcrel;
2430 fixS *fixP;
2432 /* Some fixups are only used internally and so have no howto */
2433 if ((int) fixup->reloc < 0)
2435 operand = &alpha_operands[-(int) fixup->reloc];
2436 size = 4;
2437 pcrel = ((operand->flags & AXP_OPERAND_RELATIVE) != 0);
2439 else if (fixup->reloc > BFD_RELOC_UNUSED
2440 || fixup->reloc == BFD_RELOC_ALPHA_GPDISP_HI16
2441 || fixup->reloc == BFD_RELOC_ALPHA_GPDISP_LO16)
2443 size = 2;
2444 pcrel = 0;
2446 else
2448 reloc_howto_type *reloc_howto
2449 = bfd_reloc_type_lookup (stdoutput, fixup->reloc);
2450 assert (reloc_howto);
2452 size = bfd_get_reloc_size (reloc_howto);
2453 assert (size >= 1 && size <= 4);
2455 pcrel = reloc_howto->pc_relative;
2458 fixP = fix_new_exp (frag_now, f - frag_now->fr_literal, size,
2459 &fixup->exp, pcrel, fixup->reloc);
2461 /* Turn off complaints that the addend is too large for some fixups,
2462 and copy in the sequence number for the explicit relocations. */
2463 switch (fixup->reloc)
2465 case BFD_RELOC_ALPHA_HINT:
2466 case BFD_RELOC_GPREL32:
2467 case BFD_RELOC_GPREL16:
2468 case BFD_RELOC_ALPHA_GPREL_HI16:
2469 case BFD_RELOC_ALPHA_GPREL_LO16:
2470 fixP->fx_no_overflow = 1;
2471 break;
2473 case BFD_RELOC_ALPHA_GPDISP_HI16:
2474 fixP->fx_no_overflow = 1;
2475 fixP->fx_addsy = section_symbol (now_seg);
2476 fixP->fx_offset = 0;
2478 info = get_alpha_reloc_tag (insn->sequence);
2479 if (++info->n_master > 1)
2480 as_bad (_("too many ldah insns for !gpdisp!%ld"), insn->sequence);
2481 if (info->segment != now_seg)
2482 as_bad (_("both insns for !gpdisp!%ld must be in the same section"),
2483 insn->sequence);
2484 fixP->tc_fix_data.info = info;
2485 break;
2487 case BFD_RELOC_ALPHA_GPDISP_LO16:
2488 fixP->fx_no_overflow = 1;
2490 info = get_alpha_reloc_tag (insn->sequence);
2491 if (++info->n_slaves > 1)
2492 as_bad (_("too many lda insns for !gpdisp!%ld"), insn->sequence);
2493 if (info->segment != now_seg)
2494 as_bad (_("both insns for !gpdisp!%ld must be in the same section"),
2495 insn->sequence);
2496 fixP->tc_fix_data.info = info;
2497 info->slaves = fixP;
2498 break;
2500 case BFD_RELOC_ALPHA_LITERAL:
2501 case BFD_RELOC_ALPHA_ELF_LITERAL:
2502 fixP->fx_no_overflow = 1;
2504 info = get_alpha_reloc_tag (insn->sequence);
2505 info->n_master++;
2506 if (info->segment != now_seg)
2507 info->multi_section_p = 1;
2508 fixP->tc_fix_data.info = info;
2509 break;
2511 case DUMMY_RELOC_LITUSE_ADDR:
2512 fixP->fx_offset = LITUSE_ADDR;
2513 goto do_lituse;
2514 case DUMMY_RELOC_LITUSE_BASE:
2515 fixP->fx_offset = LITUSE_BASE;
2516 goto do_lituse;
2517 case DUMMY_RELOC_LITUSE_BYTOFF:
2518 fixP->fx_offset = LITUSE_BYTOFF;
2519 goto do_lituse;
2520 case DUMMY_RELOC_LITUSE_JSR:
2521 fixP->fx_offset = LITUSE_JSR;
2522 do_lituse:
2523 fixP->fx_addsy = section_symbol (now_seg);
2524 fixP->fx_r_type = BFD_RELOC_ALPHA_LITUSE;
2526 info = get_alpha_reloc_tag (insn->sequence);
2527 info->n_slaves++;
2528 fixP->tc_fix_data.info = info;
2529 fixP->tc_fix_data.next_reloc = info->slaves;
2530 info->slaves = fixP;
2531 if (info->segment != now_seg)
2532 info->multi_section_p = 1;
2533 break;
2535 default:
2536 if ((int) fixup->reloc < 0)
2538 if (operand->flags & AXP_OPERAND_NOOVERFLOW)
2539 fixP->fx_no_overflow = 1;
2541 break;
2546 /* Given an opcode name and a pre-tokenized set of arguments, assemble
2547 the insn, but do not emit it.
2549 Note that this implies no macros allowed, since we can't store more
2550 than one insn in an insn structure. */
2552 static void
2553 assemble_tokens_to_insn (opname, tok, ntok, insn)
2554 const char *opname;
2555 const expressionS *tok;
2556 int ntok;
2557 struct alpha_insn *insn;
2559 const struct alpha_opcode *opcode;
2561 /* search opcodes */
2562 opcode = (const struct alpha_opcode *) hash_find (alpha_opcode_hash, opname);
2563 if (opcode)
2565 int cpumatch;
2566 opcode = find_opcode_match (opcode, tok, &ntok, &cpumatch);
2567 if (opcode)
2569 assemble_insn (opcode, tok, ntok, insn, BFD_RELOC_UNUSED);
2570 return;
2572 else if (cpumatch)
2573 as_bad (_("inappropriate arguments for opcode `%s'"), opname);
2574 else
2575 as_bad (_("opcode `%s' not supported for target %s"), opname,
2576 alpha_target_name);
2578 else
2579 as_bad (_("unknown opcode `%s'"), opname);
2582 /* Given an opcode name and a pre-tokenized set of arguments, take the
2583 opcode all the way through emission. */
2585 static void
2586 assemble_tokens (opname, tok, ntok, local_macros_on)
2587 const char *opname;
2588 const expressionS *tok;
2589 int ntok;
2590 int local_macros_on;
2592 int found_something = 0;
2593 const struct alpha_opcode *opcode;
2594 const struct alpha_macro *macro;
2595 int cpumatch = 1;
2596 bfd_reloc_code_real_type reloc = BFD_RELOC_UNUSED;
2598 /* If a user-specified relocation is present, this is not a macro. */
2599 if (ntok && USER_RELOC_P (tok[ntok - 1].X_op))
2601 reloc = ALPHA_RELOC_TABLE (tok[ntok - 1].X_op)->reloc;
2602 ntok--;
2604 else if (local_macros_on)
2606 macro = ((const struct alpha_macro *)
2607 hash_find (alpha_macro_hash, opname));
2608 if (macro)
2610 found_something = 1;
2611 macro = find_macro_match (macro, tok, &ntok);
2612 if (macro)
2614 (*macro->emit) (tok, ntok, macro->arg);
2615 return;
2620 /* search opcodes */
2621 opcode = (const struct alpha_opcode *) hash_find (alpha_opcode_hash, opname);
2622 if (opcode)
2624 found_something = 1;
2625 opcode = find_opcode_match (opcode, tok, &ntok, &cpumatch);
2626 if (opcode)
2628 struct alpha_insn insn;
2629 assemble_insn (opcode, tok, ntok, &insn, reloc);
2631 /* Copy the sequence number for the reloc from the reloc token. */
2632 if (reloc != BFD_RELOC_UNUSED)
2633 insn.sequence = tok[ntok].X_add_number;
2635 emit_insn (&insn);
2636 return;
2640 if (found_something)
2642 if (cpumatch)
2643 as_bad (_("inappropriate arguments for opcode `%s'"), opname);
2644 else
2645 as_bad (_("opcode `%s' not supported for target %s"), opname,
2646 alpha_target_name);
2648 else
2649 as_bad (_("unknown opcode `%s'"), opname);
2652 /* Some instruction sets indexed by lg(size) */
2653 static const char * const sextX_op[] = { "sextb", "sextw", "sextl", NULL };
2654 static const char * const insXl_op[] = { "insbl", "inswl", "insll", "insql" };
2655 static const char * const insXh_op[] = { NULL, "inswh", "inslh", "insqh" };
2656 static const char * const extXl_op[] = { "extbl", "extwl", "extll", "extql" };
2657 static const char * const extXh_op[] = { NULL, "extwh", "extlh", "extqh" };
2658 static const char * const mskXl_op[] = { "mskbl", "mskwl", "mskll", "mskql" };
2659 static const char * const mskXh_op[] = { NULL, "mskwh", "msklh", "mskqh" };
2660 static const char * const stX_op[] = { "stb", "stw", "stl", "stq" };
2661 static const char * const ldX_op[] = { "ldb", "ldw", "ldll", "ldq" };
2662 static const char * const ldXu_op[] = { "ldbu", "ldwu", NULL, NULL };
2664 /* Implement the ldgp macro. */
2666 static void
2667 emit_ldgp (tok, ntok, unused)
2668 const expressionS *tok;
2669 int ntok ATTRIBUTE_UNUSED;
2670 const PTR unused ATTRIBUTE_UNUSED;
2672 #ifdef OBJ_AOUT
2673 FIXME
2674 #endif
2675 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
2676 /* from "ldgp r1,n(r2)", generate "ldah r1,X(R2); lda r1,Y(r1)"
2677 with appropriate constants and relocations. */
2678 struct alpha_insn insn;
2679 expressionS newtok[3];
2680 expressionS addend;
2682 #ifdef OBJ_ECOFF
2683 if (regno (tok[2].X_add_number) == AXP_REG_PV)
2684 ecoff_set_gp_prolog_size (0);
2685 #endif
2687 newtok[0] = tok[0];
2688 set_tok_const (newtok[1], 0);
2689 newtok[2] = tok[2];
2691 assemble_tokens_to_insn ("ldah", newtok, 3, &insn);
2693 addend = tok[1];
2695 #ifdef OBJ_ECOFF
2696 if (addend.X_op != O_constant)
2697 as_bad (_("can not resolve expression"));
2698 addend.X_op = O_symbol;
2699 addend.X_add_symbol = alpha_gp_symbol;
2700 #endif
2702 insn.nfixups = 1;
2703 insn.fixups[0].exp = addend;
2704 insn.fixups[0].reloc = BFD_RELOC_ALPHA_GPDISP_HI16;
2705 insn.sequence = next_sequence_num;
2707 emit_insn (&insn);
2709 set_tok_preg (newtok[2], tok[0].X_add_number);
2711 assemble_tokens_to_insn ("lda", newtok, 3, &insn);
2713 #ifdef OBJ_ECOFF
2714 addend.X_add_number += 4;
2715 #endif
2717 insn.nfixups = 1;
2718 insn.fixups[0].exp = addend;
2719 insn.fixups[0].reloc = BFD_RELOC_ALPHA_GPDISP_LO16;
2720 insn.sequence = next_sequence_num--;
2722 emit_insn (&insn);
2723 #endif /* OBJ_ECOFF || OBJ_ELF */
2726 #ifdef OBJ_EVAX
2728 /* Add symbol+addend to link pool.
2729 Return offset from basesym to entry in link pool.
2731 Add new fixup only if offset isn't 16bit. */
2733 valueT
2734 add_to_link_pool (basesym, sym, addend)
2735 symbolS *basesym;
2736 symbolS *sym;
2737 offsetT addend;
2739 segT current_section = now_seg;
2740 int current_subsec = now_subseg;
2741 valueT offset;
2742 bfd_reloc_code_real_type reloc_type;
2743 char *p;
2744 segment_info_type *seginfo = seg_info (alpha_link_section);
2745 fixS *fixp;
2747 offset = - *symbol_get_obj (basesym);
2749 /* @@ This assumes all entries in a given section will be of the same
2750 size... Probably correct, but unwise to rely on. */
2751 /* This must always be called with the same subsegment. */
2753 if (seginfo->frchainP)
2754 for (fixp = seginfo->frchainP->fix_root;
2755 fixp != (fixS *) NULL;
2756 fixp = fixp->fx_next, offset += 8)
2758 if (fixp->fx_addsy == sym && fixp->fx_offset == addend)
2760 if (range_signed_16 (offset))
2762 return offset;
2767 /* Not found in 16bit signed range. */
2769 subseg_set (alpha_link_section, 0);
2770 p = frag_more (8);
2771 memset (p, 0, 8);
2773 fix_new (frag_now, p - frag_now->fr_literal, 8, sym, addend, 0,
2774 BFD_RELOC_64);
2776 subseg_set (current_section, current_subsec);
2777 seginfo->literal_pool_size += 8;
2778 return offset;
2781 #endif /* OBJ_EVAX */
2783 /* Load a (partial) expression into a target register.
2785 If poffset is not null, after the call it will either contain
2786 O_constant 0, or a 16-bit offset appropriate for any MEM format
2787 instruction. In addition, pbasereg will be modified to point to
2788 the base register to use in that MEM format instruction.
2790 In any case, *pbasereg should contain a base register to add to the
2791 expression. This will normally be either AXP_REG_ZERO or
2792 alpha_gp_register. Symbol addresses will always be loaded via $gp,
2793 so "foo($0)" is interpreted as adding the address of foo to $0;
2794 i.e. "ldq $targ, LIT($gp); addq $targ, $0, $targ". Odd, perhaps,
2795 but this is what OSF/1 does.
2797 If explicit relocations of the form !literal!<number> are allowed,
2798 and used, then explict_reloc with be an expression pointer.
2800 Finally, the return value is nonzero if the calling macro may emit
2801 a LITUSE reloc if otherwise appropriate; the return value is the
2802 sequence number to use. */
2804 static long
2805 load_expression (targreg, exp, pbasereg, poffset)
2806 int targreg;
2807 const expressionS *exp;
2808 int *pbasereg;
2809 expressionS *poffset;
2811 long emit_lituse = 0;
2812 offsetT addend = exp->X_add_number;
2813 int basereg = *pbasereg;
2814 struct alpha_insn insn;
2815 expressionS newtok[3];
2817 switch (exp->X_op)
2819 case O_symbol:
2821 #ifdef OBJ_ECOFF
2822 offsetT lit;
2824 /* attempt to reduce .lit load by splitting the offset from
2825 its symbol when possible, but don't create a situation in
2826 which we'd fail. */
2827 if (!range_signed_32 (addend) &&
2828 (alpha_noat_on || targreg == AXP_REG_AT))
2830 lit = add_to_literal_pool (exp->X_add_symbol, addend,
2831 alpha_lita_section, 8);
2832 addend = 0;
2834 else
2836 lit = add_to_literal_pool (exp->X_add_symbol, 0,
2837 alpha_lita_section, 8);
2840 if (lit >= 0x8000)
2841 as_fatal (_("overflow in literal (.lita) table"));
2843 /* emit "ldq r, lit(gp)" */
2845 if (basereg != alpha_gp_register && targreg == basereg)
2847 if (alpha_noat_on)
2848 as_bad (_("macro requires $at register while noat in effect"));
2849 if (targreg == AXP_REG_AT)
2850 as_bad (_("macro requires $at while $at in use"));
2852 set_tok_reg (newtok[0], AXP_REG_AT);
2854 else
2855 set_tok_reg (newtok[0], targreg);
2856 set_tok_sym (newtok[1], alpha_lita_symbol, lit);
2857 set_tok_preg (newtok[2], alpha_gp_register);
2859 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
2861 assert (insn.nfixups == 1);
2862 insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITERAL;
2863 insn.sequence = emit_lituse = next_sequence_num--;
2864 #endif /* OBJ_ECOFF */
2865 #ifdef OBJ_ELF
2866 /* emit "ldq r, gotoff(gp)" */
2868 if (basereg != alpha_gp_register && targreg == basereg)
2870 if (alpha_noat_on)
2871 as_bad (_("macro requires $at register while noat in effect"));
2872 if (targreg == AXP_REG_AT)
2873 as_bad (_("macro requires $at while $at in use"));
2875 set_tok_reg (newtok[0], AXP_REG_AT);
2877 else
2878 set_tok_reg (newtok[0], targreg);
2880 /* XXX: Disable this .got minimizing optimization so that we can get
2881 better instruction offset knowledge in the compiler. This happens
2882 very infrequently anyway. */
2883 if (1
2884 || (!range_signed_32 (addend)
2885 && (alpha_noat_on || targreg == AXP_REG_AT)))
2887 newtok[1] = *exp;
2888 addend = 0;
2890 else
2892 set_tok_sym (newtok[1], exp->X_add_symbol, 0);
2895 set_tok_preg (newtok[2], alpha_gp_register);
2897 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
2899 assert (insn.nfixups == 1);
2900 insn.fixups[0].reloc = BFD_RELOC_ALPHA_ELF_LITERAL;
2901 insn.sequence = emit_lituse = next_sequence_num--;
2902 #endif /* OBJ_ELF */
2903 #ifdef OBJ_EVAX
2904 offsetT link;
2906 /* Find symbol or symbol pointer in link section. */
2908 if (exp->X_add_symbol == alpha_evax_proc.symbol)
2910 if (range_signed_16 (addend))
2912 set_tok_reg (newtok[0], targreg);
2913 set_tok_const (newtok[1], addend);
2914 set_tok_preg (newtok[2], basereg);
2915 assemble_tokens_to_insn ("lda", newtok, 3, &insn);
2916 addend = 0;
2918 else
2920 set_tok_reg (newtok[0], targreg);
2921 set_tok_const (newtok[1], 0);
2922 set_tok_preg (newtok[2], basereg);
2923 assemble_tokens_to_insn ("lda", newtok, 3, &insn);
2926 else
2928 if (!range_signed_32 (addend))
2930 link = add_to_link_pool (alpha_evax_proc.symbol,
2931 exp->X_add_symbol, addend);
2932 addend = 0;
2934 else
2936 link = add_to_link_pool (alpha_evax_proc.symbol,
2937 exp->X_add_symbol, 0);
2939 set_tok_reg (newtok[0], targreg);
2940 set_tok_const (newtok[1], link);
2941 set_tok_preg (newtok[2], basereg);
2942 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
2944 #endif /* OBJ_EVAX */
2946 emit_insn (&insn);
2948 #ifndef OBJ_EVAX
2949 if (basereg != alpha_gp_register && basereg != AXP_REG_ZERO)
2951 /* emit "addq r, base, r" */
2953 set_tok_reg (newtok[1], basereg);
2954 set_tok_reg (newtok[2], targreg);
2955 assemble_tokens ("addq", newtok, 3, 0);
2957 #endif
2959 basereg = targreg;
2961 break;
2963 case O_constant:
2964 break;
2966 case O_subtract:
2967 /* Assume that this difference expression will be resolved to an
2968 absolute value and that that value will fit in 16 bits. */
2970 set_tok_reg (newtok[0], targreg);
2971 newtok[1] = *exp;
2972 set_tok_preg (newtok[2], basereg);
2973 assemble_tokens ("lda", newtok, 3, 0);
2975 if (poffset)
2976 set_tok_const (*poffset, 0);
2977 return 0;
2979 case O_big:
2980 if (exp->X_add_number > 0)
2981 as_bad (_("bignum invalid; zero assumed"));
2982 else
2983 as_bad (_("floating point number invalid; zero assumed"));
2984 addend = 0;
2985 break;
2987 default:
2988 as_bad (_("can't handle expression"));
2989 addend = 0;
2990 break;
2993 if (!range_signed_32 (addend))
2995 offsetT lit;
2996 long seq_num = next_sequence_num--;
2998 /* For 64-bit addends, just put it in the literal pool. */
3000 #ifdef OBJ_EVAX
3001 /* emit "ldq targreg, lit(basereg)" */
3002 lit = add_to_link_pool (alpha_evax_proc.symbol,
3003 section_symbol (absolute_section), addend);
3004 set_tok_reg (newtok[0], targreg);
3005 set_tok_const (newtok[1], lit);
3006 set_tok_preg (newtok[2], alpha_gp_register);
3007 assemble_tokens ("ldq", newtok, 3, 0);
3008 #else
3010 if (alpha_lit8_section == NULL)
3012 create_literal_section (".lit8",
3013 &alpha_lit8_section,
3014 &alpha_lit8_symbol);
3016 #ifdef OBJ_ECOFF
3017 alpha_lit8_literal = add_to_literal_pool (alpha_lit8_symbol, 0x8000,
3018 alpha_lita_section, 8);
3019 if (alpha_lit8_literal >= 0x8000)
3020 as_fatal (_("overflow in literal (.lita) table"));
3021 #endif
3024 lit = add_to_literal_pool (NULL, addend, alpha_lit8_section, 8) - 0x8000;
3025 if (lit >= 0x8000)
3026 as_fatal (_("overflow in literal (.lit8) table"));
3028 /* emit "lda litreg, .lit8+0x8000" */
3030 if (targreg == basereg)
3032 if (alpha_noat_on)
3033 as_bad (_("macro requires $at register while noat in effect"));
3034 if (targreg == AXP_REG_AT)
3035 as_bad (_("macro requires $at while $at in use"));
3037 set_tok_reg (newtok[0], AXP_REG_AT);
3039 else
3040 set_tok_reg (newtok[0], targreg);
3041 #ifdef OBJ_ECOFF
3042 set_tok_sym (newtok[1], alpha_lita_symbol, alpha_lit8_literal);
3043 #endif
3044 #ifdef OBJ_ELF
3045 set_tok_sym (newtok[1], alpha_lit8_symbol, 0x8000);
3046 #endif
3047 set_tok_preg (newtok[2], alpha_gp_register);
3049 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
3051 assert (insn.nfixups == 1);
3052 #ifdef OBJ_ECOFF
3053 insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITERAL;
3054 #endif
3055 #ifdef OBJ_ELF
3056 insn.fixups[0].reloc = BFD_RELOC_ALPHA_ELF_LITERAL;
3057 #endif
3058 insn.sequence = seq_num;
3060 emit_insn (&insn);
3062 /* emit "ldq litreg, lit(litreg)" */
3064 set_tok_const (newtok[1], lit);
3065 set_tok_preg (newtok[2], newtok[0].X_add_number);
3067 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
3069 assert (insn.nfixups < MAX_INSN_FIXUPS);
3070 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
3071 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3072 insn.nfixups++;
3073 insn.sequence = seq_num;
3074 emit_lituse = 0;
3076 emit_insn (&insn);
3078 /* emit "addq litreg, base, target" */
3080 if (basereg != AXP_REG_ZERO)
3082 set_tok_reg (newtok[1], basereg);
3083 set_tok_reg (newtok[2], targreg);
3084 assemble_tokens ("addq", newtok, 3, 0);
3086 #endif /* !OBJ_EVAX */
3088 if (poffset)
3089 set_tok_const (*poffset, 0);
3090 *pbasereg = targreg;
3092 else
3094 offsetT low, high, extra, tmp;
3096 /* for 32-bit operands, break up the addend */
3098 low = sign_extend_16 (addend);
3099 tmp = addend - low;
3100 high = sign_extend_16 (tmp >> 16);
3102 if (tmp - (high << 16))
3104 extra = 0x4000;
3105 tmp -= 0x40000000;
3106 high = sign_extend_16 (tmp >> 16);
3108 else
3109 extra = 0;
3111 set_tok_reg (newtok[0], targreg);
3112 set_tok_preg (newtok[2], basereg);
3114 if (extra)
3116 /* emit "ldah r, extra(r) */
3117 set_tok_const (newtok[1], extra);
3118 assemble_tokens ("ldah", newtok, 3, 0);
3119 set_tok_preg (newtok[2], basereg = targreg);
3122 if (high)
3124 /* emit "ldah r, high(r) */
3125 set_tok_const (newtok[1], high);
3126 assemble_tokens ("ldah", newtok, 3, 0);
3127 basereg = targreg;
3128 set_tok_preg (newtok[2], basereg);
3131 if ((low && !poffset) || (!poffset && basereg != targreg))
3133 /* emit "lda r, low(base)" */
3134 set_tok_const (newtok[1], low);
3135 assemble_tokens ("lda", newtok, 3, 0);
3136 basereg = targreg;
3137 low = 0;
3140 if (poffset)
3141 set_tok_const (*poffset, low);
3142 *pbasereg = basereg;
3145 return emit_lituse;
3148 /* The lda macro differs from the lda instruction in that it handles
3149 most simple expressions, particualrly symbol address loads and
3150 large constants. */
3152 static void
3153 emit_lda (tok, ntok, unused)
3154 const expressionS *tok;
3155 int ntok;
3156 const PTR unused ATTRIBUTE_UNUSED;
3158 int basereg;
3160 if (ntok == 2)
3161 basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
3162 else
3163 basereg = tok[2].X_add_number;
3165 (void) load_expression (tok[0].X_add_number, &tok[1], &basereg, NULL);
3168 /* The ldah macro differs from the ldah instruction in that it has $31
3169 as an implied base register. */
3171 static void
3172 emit_ldah (tok, ntok, unused)
3173 const expressionS *tok;
3174 int ntok ATTRIBUTE_UNUSED;
3175 const PTR unused ATTRIBUTE_UNUSED;
3177 expressionS newtok[3];
3179 newtok[0] = tok[0];
3180 newtok[1] = tok[1];
3181 set_tok_preg (newtok[2], AXP_REG_ZERO);
3183 assemble_tokens ("ldah", newtok, 3, 0);
3186 /* Handle all "simple" integer register loads -- ldq, ldq_l, ldq_u,
3187 etc. They differ from the real instructions in that they do simple
3188 expressions like the lda macro. */
3190 static void
3191 emit_ir_load (tok, ntok, opname)
3192 const expressionS *tok;
3193 int ntok;
3194 const PTR opname;
3196 int basereg;
3197 long lituse;
3198 expressionS newtok[3];
3199 struct alpha_insn insn;
3201 if (ntok == 2)
3202 basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
3203 else
3204 basereg = tok[2].X_add_number;
3206 lituse = load_expression (tok[0].X_add_number, &tok[1], &basereg,
3207 &newtok[1]);
3209 newtok[0] = tok[0];
3210 set_tok_preg (newtok[2], basereg);
3212 assemble_tokens_to_insn ((const char *) opname, newtok, 3, &insn);
3214 if (lituse)
3216 assert (insn.nfixups < MAX_INSN_FIXUPS);
3217 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
3218 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3219 insn.nfixups++;
3220 insn.sequence = lituse;
3223 emit_insn (&insn);
3226 /* Handle fp register loads, and both integer and fp register stores.
3227 Again, we handle simple expressions. */
3229 static void
3230 emit_loadstore (tok, ntok, opname)
3231 const expressionS *tok;
3232 int ntok;
3233 const PTR opname;
3235 int basereg;
3236 long lituse;
3237 expressionS newtok[3];
3238 struct alpha_insn insn;
3240 if (ntok == 2)
3241 basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
3242 else
3243 basereg = tok[2].X_add_number;
3245 if (tok[1].X_op != O_constant || !range_signed_16 (tok[1].X_add_number))
3247 if (alpha_noat_on)
3248 as_bad (_("macro requires $at register while noat in effect"));
3250 lituse = load_expression (AXP_REG_AT, &tok[1], &basereg, &newtok[1]);
3252 else
3254 newtok[1] = tok[1];
3255 lituse = 0;
3258 newtok[0] = tok[0];
3259 set_tok_preg (newtok[2], basereg);
3261 assemble_tokens_to_insn ((const char *) opname, newtok, 3, &insn);
3263 if (lituse)
3265 assert (insn.nfixups < MAX_INSN_FIXUPS);
3266 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
3267 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3268 insn.nfixups++;
3269 insn.sequence = lituse;
3272 emit_insn (&insn);
3275 /* Load a half-word or byte as an unsigned value. */
3277 static void
3278 emit_ldXu (tok, ntok, vlgsize)
3279 const expressionS *tok;
3280 int ntok;
3281 const PTR vlgsize;
3283 if (alpha_target & AXP_OPCODE_BWX)
3284 emit_ir_load (tok, ntok, ldXu_op[(long) vlgsize]);
3285 else
3287 expressionS newtok[3];
3288 struct alpha_insn insn;
3289 int basereg;
3290 long lituse;
3292 if (alpha_noat_on)
3293 as_bad (_("macro requires $at register while noat in effect"));
3295 if (ntok == 2)
3296 basereg = (tok[1].X_op == O_constant
3297 ? AXP_REG_ZERO : alpha_gp_register);
3298 else
3299 basereg = tok[2].X_add_number;
3301 /* emit "lda $at, exp" */
3303 lituse = load_expression (AXP_REG_AT, &tok[1], &basereg, NULL);
3305 /* emit "ldq_u targ, 0($at)" */
3307 newtok[0] = tok[0];
3308 set_tok_const (newtok[1], 0);
3309 set_tok_preg (newtok[2], basereg);
3310 assemble_tokens_to_insn ("ldq_u", newtok, 3, &insn);
3312 if (lituse)
3314 assert (insn.nfixups < MAX_INSN_FIXUPS);
3315 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
3316 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3317 insn.nfixups++;
3318 insn.sequence = lituse;
3321 emit_insn (&insn);
3323 /* emit "extXl targ, $at, targ" */
3325 set_tok_reg (newtok[1], basereg);
3326 newtok[2] = newtok[0];
3327 assemble_tokens_to_insn (extXl_op[(long) vlgsize], newtok, 3, &insn);
3329 if (lituse)
3331 assert (insn.nfixups < MAX_INSN_FIXUPS);
3332 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF;
3333 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3334 insn.nfixups++;
3335 insn.sequence = lituse;
3338 emit_insn (&insn);
3342 /* Load a half-word or byte as a signed value. */
3344 static void
3345 emit_ldX (tok, ntok, vlgsize)
3346 const expressionS *tok;
3347 int ntok;
3348 const PTR vlgsize;
3350 emit_ldXu (tok, ntok, vlgsize);
3351 assemble_tokens (sextX_op[(long) vlgsize], tok, 1, 1);
3354 /* Load an integral value from an unaligned address as an unsigned
3355 value. */
3357 static void
3358 emit_uldXu (tok, ntok, vlgsize)
3359 const expressionS *tok;
3360 int ntok;
3361 const PTR vlgsize;
3363 long lgsize = (long) vlgsize;
3364 expressionS newtok[3];
3366 if (alpha_noat_on)
3367 as_bad (_("macro requires $at register while noat in effect"));
3369 /* emit "lda $at, exp" */
3371 memcpy (newtok, tok, sizeof (expressionS) * ntok);
3372 newtok[0].X_add_number = AXP_REG_AT;
3373 assemble_tokens ("lda", newtok, ntok, 1);
3375 /* emit "ldq_u $t9, 0($at)" */
3377 set_tok_reg (newtok[0], AXP_REG_T9);
3378 set_tok_const (newtok[1], 0);
3379 set_tok_preg (newtok[2], AXP_REG_AT);
3380 assemble_tokens ("ldq_u", newtok, 3, 1);
3382 /* emit "ldq_u $t10, size-1($at)" */
3384 set_tok_reg (newtok[0], AXP_REG_T10);
3385 set_tok_const (newtok[1], (1 << lgsize) - 1);
3386 assemble_tokens ("ldq_u", newtok, 3, 1);
3388 /* emit "extXl $t9, $at, $t9" */
3390 set_tok_reg (newtok[0], AXP_REG_T9);
3391 set_tok_reg (newtok[1], AXP_REG_AT);
3392 set_tok_reg (newtok[2], AXP_REG_T9);
3393 assemble_tokens (extXl_op[lgsize], newtok, 3, 1);
3395 /* emit "extXh $t10, $at, $t10" */
3397 set_tok_reg (newtok[0], AXP_REG_T10);
3398 set_tok_reg (newtok[2], AXP_REG_T10);
3399 assemble_tokens (extXh_op[lgsize], newtok, 3, 1);
3401 /* emit "or $t9, $t10, targ" */
3403 set_tok_reg (newtok[0], AXP_REG_T9);
3404 set_tok_reg (newtok[1], AXP_REG_T10);
3405 newtok[2] = tok[0];
3406 assemble_tokens ("or", newtok, 3, 1);
3409 /* Load an integral value from an unaligned address as a signed value.
3410 Note that quads should get funneled to the unsigned load since we
3411 don't have to do the sign extension. */
3413 static void
3414 emit_uldX (tok, ntok, vlgsize)
3415 const expressionS *tok;
3416 int ntok;
3417 const PTR vlgsize;
3419 emit_uldXu (tok, ntok, vlgsize);
3420 assemble_tokens (sextX_op[(long) vlgsize], tok, 1, 1);
3423 /* Implement the ldil macro. */
3425 static void
3426 emit_ldil (tok, ntok, unused)
3427 const expressionS *tok;
3428 int ntok;
3429 const PTR unused ATTRIBUTE_UNUSED;
3431 expressionS newtok[2];
3433 memcpy (newtok, tok, sizeof (newtok));
3434 newtok[1].X_add_number = sign_extend_32 (tok[1].X_add_number);
3436 assemble_tokens ("lda", newtok, ntok, 1);
3439 /* Store a half-word or byte. */
3441 static void
3442 emit_stX (tok, ntok, vlgsize)
3443 const expressionS *tok;
3444 int ntok;
3445 const PTR vlgsize;
3447 int lgsize = (int) (long) vlgsize;
3449 if (alpha_target & AXP_OPCODE_BWX)
3450 emit_loadstore (tok, ntok, stX_op[lgsize]);
3451 else
3453 expressionS newtok[3];
3454 struct alpha_insn insn;
3455 int basereg;
3456 long lituse;
3458 if (alpha_noat_on)
3459 as_bad (_("macro requires $at register while noat in effect"));
3461 if (ntok == 2)
3462 basereg = (tok[1].X_op == O_constant
3463 ? AXP_REG_ZERO : alpha_gp_register);
3464 else
3465 basereg = tok[2].X_add_number;
3467 /* emit "lda $at, exp" */
3469 lituse = load_expression (AXP_REG_AT, &tok[1], &basereg, NULL);
3471 /* emit "ldq_u $t9, 0($at)" */
3473 set_tok_reg (newtok[0], AXP_REG_T9);
3474 set_tok_const (newtok[1], 0);
3475 set_tok_preg (newtok[2], basereg);
3476 assemble_tokens_to_insn ("ldq_u", newtok, 3, &insn);
3478 if (lituse)
3480 assert (insn.nfixups < MAX_INSN_FIXUPS);
3481 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
3482 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3483 insn.nfixups++;
3484 insn.sequence = lituse;
3487 emit_insn (&insn);
3489 /* emit "insXl src, $at, $t10" */
3491 newtok[0] = tok[0];
3492 set_tok_reg (newtok[1], basereg);
3493 set_tok_reg (newtok[2], AXP_REG_T10);
3494 assemble_tokens_to_insn (insXl_op[lgsize], newtok, 3, &insn);
3496 if (lituse)
3498 assert (insn.nfixups < MAX_INSN_FIXUPS);
3499 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF;
3500 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3501 insn.nfixups++;
3502 insn.sequence = lituse;
3505 emit_insn (&insn);
3507 /* emit "mskXl $t9, $at, $t9" */
3509 set_tok_reg (newtok[0], AXP_REG_T9);
3510 newtok[2] = newtok[0];
3511 assemble_tokens_to_insn (mskXl_op[lgsize], newtok, 3, &insn);
3513 if (lituse)
3515 assert (insn.nfixups < MAX_INSN_FIXUPS);
3516 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF;
3517 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3518 insn.nfixups++;
3519 insn.sequence = lituse;
3522 emit_insn (&insn);
3524 /* emit "or $t9, $t10, $t9" */
3526 set_tok_reg (newtok[1], AXP_REG_T10);
3527 assemble_tokens ("or", newtok, 3, 1);
3529 /* emit "stq_u $t9, 0($at) */
3531 set_tok_const(newtok[1], 0);
3532 set_tok_preg (newtok[2], AXP_REG_AT);
3533 assemble_tokens_to_insn ("stq_u", newtok, 3, &insn);
3535 if (lituse)
3537 assert (insn.nfixups < MAX_INSN_FIXUPS);
3538 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
3539 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3540 insn.nfixups++;
3541 insn.sequence = lituse;
3544 emit_insn (&insn);
3548 /* Store an integer to an unaligned address. */
3550 static void
3551 emit_ustX (tok, ntok, vlgsize)
3552 const expressionS *tok;
3553 int ntok;
3554 const PTR vlgsize;
3556 int lgsize = (int) (long) vlgsize;
3557 expressionS newtok[3];
3559 /* emit "lda $at, exp" */
3561 memcpy (newtok, tok, sizeof (expressionS) * ntok);
3562 newtok[0].X_add_number = AXP_REG_AT;
3563 assemble_tokens ("lda", newtok, ntok, 1);
3565 /* emit "ldq_u $9, 0($at)" */
3567 set_tok_reg (newtok[0], AXP_REG_T9);
3568 set_tok_const (newtok[1], 0);
3569 set_tok_preg (newtok[2], AXP_REG_AT);
3570 assemble_tokens ("ldq_u", newtok, 3, 1);
3572 /* emit "ldq_u $10, size-1($at)" */
3574 set_tok_reg (newtok[0], AXP_REG_T10);
3575 set_tok_const (newtok[1], (1 << lgsize) - 1);
3576 assemble_tokens ("ldq_u", newtok, 3, 1);
3578 /* emit "insXl src, $at, $t11" */
3580 newtok[0] = tok[0];
3581 set_tok_reg (newtok[1], AXP_REG_AT);
3582 set_tok_reg (newtok[2], AXP_REG_T11);
3583 assemble_tokens (insXl_op[lgsize], newtok, 3, 1);
3585 /* emit "insXh src, $at, $t12" */
3587 set_tok_reg (newtok[2], AXP_REG_T12);
3588 assemble_tokens (insXh_op[lgsize], newtok, 3, 1);
3590 /* emit "mskXl $t9, $at, $t9" */
3592 set_tok_reg (newtok[0], AXP_REG_T9);
3593 newtok[2] = newtok[0];
3594 assemble_tokens (mskXl_op[lgsize], newtok, 3, 1);
3596 /* emit "mskXh $t10, $at, $t10" */
3598 set_tok_reg (newtok[0], AXP_REG_T10);
3599 newtok[2] = newtok[0];
3600 assemble_tokens (mskXh_op[lgsize], newtok, 3, 1);
3602 /* emit "or $t9, $t11, $t9" */
3604 set_tok_reg (newtok[0], AXP_REG_T9);
3605 set_tok_reg (newtok[1], AXP_REG_T11);
3606 newtok[2] = newtok[0];
3607 assemble_tokens ("or", newtok, 3, 1);
3609 /* emit "or $t10, $t12, $t10" */
3611 set_tok_reg (newtok[0], AXP_REG_T10);
3612 set_tok_reg (newtok[1], AXP_REG_T12);
3613 newtok[2] = newtok[0];
3614 assemble_tokens ("or", newtok, 3, 1);
3616 /* emit "stq_u $t9, 0($at)" */
3618 set_tok_reg (newtok[0], AXP_REG_T9);
3619 set_tok_const (newtok[1], 0);
3620 set_tok_preg (newtok[2], AXP_REG_AT);
3621 assemble_tokens ("stq_u", newtok, 3, 1);
3623 /* emit "stq_u $t10, size-1($at)" */
3625 set_tok_reg (newtok[0], AXP_REG_T10);
3626 set_tok_const (newtok[1], (1 << lgsize) - 1);
3627 assemble_tokens ("stq_u", newtok, 3, 1);
3630 /* Sign extend a half-word or byte. The 32-bit sign extend is
3631 implemented as "addl $31, $r, $t" in the opcode table. */
3633 static void
3634 emit_sextX (tok, ntok, vlgsize)
3635 const expressionS *tok;
3636 int ntok;
3637 const PTR vlgsize;
3639 long lgsize = (long) vlgsize;
3641 if (alpha_target & AXP_OPCODE_BWX)
3642 assemble_tokens (sextX_op[lgsize], tok, ntok, 0);
3643 else
3645 int bitshift = 64 - 8 * (1 << lgsize);
3646 expressionS newtok[3];
3648 /* emit "sll src,bits,dst" */
3650 newtok[0] = tok[0];
3651 set_tok_const (newtok[1], bitshift);
3652 newtok[2] = tok[ntok - 1];
3653 assemble_tokens ("sll", newtok, 3, 1);
3655 /* emit "sra dst,bits,dst" */
3657 newtok[0] = newtok[2];
3658 assemble_tokens ("sra", newtok, 3, 1);
3662 /* Implement the division and modulus macros. */
3664 #ifdef OBJ_EVAX
3666 /* Make register usage like in normal procedure call.
3667 Don't clobber PV and RA. */
3669 static void
3670 emit_division (tok, ntok, symname)
3671 const expressionS *tok;
3672 int ntok;
3673 const PTR symname;
3675 /* DIVISION and MODULUS. Yech.
3677 * Convert
3678 * OP x,y,result
3679 * to
3680 * mov x,R16 # if x != R16
3681 * mov y,R17 # if y != R17
3682 * lda AT,__OP
3683 * jsr AT,(AT),0
3684 * mov R0,result
3686 * with appropriate optimizations if R0,R16,R17 are the registers
3687 * specified by the compiler.
3690 int xr, yr, rr;
3691 symbolS *sym;
3692 expressionS newtok[3];
3694 xr = regno (tok[0].X_add_number);
3695 yr = regno (tok[1].X_add_number);
3697 if (ntok < 3)
3698 rr = xr;
3699 else
3700 rr = regno (tok[2].X_add_number);
3702 /* Move the operands into the right place */
3703 if (yr == AXP_REG_R16 && xr == AXP_REG_R17)
3705 /* They are in exactly the wrong order -- swap through AT */
3707 if (alpha_noat_on)
3708 as_bad (_("macro requires $at register while noat in effect"));
3710 set_tok_reg (newtok[0], AXP_REG_R16);
3711 set_tok_reg (newtok[1], AXP_REG_AT);
3712 assemble_tokens ("mov", newtok, 2, 1);
3714 set_tok_reg (newtok[0], AXP_REG_R17);
3715 set_tok_reg (newtok[1], AXP_REG_R16);
3716 assemble_tokens ("mov", newtok, 2, 1);
3718 set_tok_reg (newtok[0], AXP_REG_AT);
3719 set_tok_reg (newtok[1], AXP_REG_R17);
3720 assemble_tokens ("mov", newtok, 2, 1);
3722 else
3724 if (yr == AXP_REG_R16)
3726 set_tok_reg (newtok[0], AXP_REG_R16);
3727 set_tok_reg (newtok[1], AXP_REG_R17);
3728 assemble_tokens ("mov", newtok, 2, 1);
3731 if (xr != AXP_REG_R16)
3733 set_tok_reg (newtok[0], xr);
3734 set_tok_reg (newtok[1], AXP_REG_R16);
3735 assemble_tokens ("mov", newtok, 2, 1);
3738 if (yr != AXP_REG_R16 && yr != AXP_REG_R17)
3740 set_tok_reg (newtok[0], yr);
3741 set_tok_reg (newtok[1], AXP_REG_R17);
3742 assemble_tokens ("mov", newtok, 2, 1);
3746 sym = symbol_find_or_make ((const char *) symname);
3748 set_tok_reg (newtok[0], AXP_REG_AT);
3749 set_tok_sym (newtok[1], sym, 0);
3750 assemble_tokens ("lda", newtok, 2, 1);
3752 /* Call the division routine */
3753 set_tok_reg (newtok[0], AXP_REG_AT);
3754 set_tok_cpreg (newtok[1], AXP_REG_AT);
3755 set_tok_const (newtok[2], 0);
3756 assemble_tokens ("jsr", newtok, 3, 1);
3758 /* Move the result to the right place */
3759 if (rr != AXP_REG_R0)
3761 set_tok_reg (newtok[0], AXP_REG_R0);
3762 set_tok_reg (newtok[1], rr);
3763 assemble_tokens ("mov", newtok, 2, 1);
3767 #else /* !OBJ_EVAX */
3769 static void
3770 emit_division (tok, ntok, symname)
3771 const expressionS *tok;
3772 int ntok;
3773 const PTR symname;
3775 /* DIVISION and MODULUS. Yech.
3776 * Convert
3777 * OP x,y,result
3778 * to
3779 * lda pv,__OP
3780 * mov x,t10
3781 * mov y,t11
3782 * jsr t9,(pv),__OP
3783 * mov t12,result
3785 * with appropriate optimizations if t10,t11,t12 are the registers
3786 * specified by the compiler.
3789 int xr, yr, rr;
3790 symbolS *sym;
3791 expressionS newtok[3];
3793 xr = regno (tok[0].X_add_number);
3794 yr = regno (tok[1].X_add_number);
3796 if (ntok < 3)
3797 rr = xr;
3798 else
3799 rr = regno (tok[2].X_add_number);
3801 sym = symbol_find_or_make ((const char *) symname);
3803 /* Move the operands into the right place */
3804 if (yr == AXP_REG_T10 && xr == AXP_REG_T11)
3806 /* They are in exactly the wrong order -- swap through AT */
3808 if (alpha_noat_on)
3809 as_bad (_("macro requires $at register while noat in effect"));
3811 set_tok_reg (newtok[0], AXP_REG_T10);
3812 set_tok_reg (newtok[1], AXP_REG_AT);
3813 assemble_tokens ("mov", newtok, 2, 1);
3815 set_tok_reg (newtok[0], AXP_REG_T11);
3816 set_tok_reg (newtok[1], AXP_REG_T10);
3817 assemble_tokens ("mov", newtok, 2, 1);
3819 set_tok_reg (newtok[0], AXP_REG_AT);
3820 set_tok_reg (newtok[1], AXP_REG_T11);
3821 assemble_tokens ("mov", newtok, 2, 1);
3823 else
3825 if (yr == AXP_REG_T10)
3827 set_tok_reg (newtok[0], AXP_REG_T10);
3828 set_tok_reg (newtok[1], AXP_REG_T11);
3829 assemble_tokens ("mov", newtok, 2, 1);
3832 if (xr != AXP_REG_T10)
3834 set_tok_reg (newtok[0], xr);
3835 set_tok_reg (newtok[1], AXP_REG_T10);
3836 assemble_tokens ("mov", newtok, 2, 1);
3839 if (yr != AXP_REG_T10 && yr != AXP_REG_T11)
3841 set_tok_reg (newtok[0], yr);
3842 set_tok_reg (newtok[1], AXP_REG_T11);
3843 assemble_tokens ("mov", newtok, 2, 1);
3847 /* Call the division routine */
3848 set_tok_reg (newtok[0], AXP_REG_T9);
3849 set_tok_sym (newtok[1], sym, 0);
3850 assemble_tokens ("jsr", newtok, 2, 1);
3852 /* Reload the GP register */
3853 #ifdef OBJ_AOUT
3854 FIXME
3855 #endif
3856 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
3857 set_tok_reg (newtok[0], alpha_gp_register);
3858 set_tok_const (newtok[1], 0);
3859 set_tok_preg (newtok[2], AXP_REG_T9);
3860 assemble_tokens ("ldgp", newtok, 3, 1);
3861 #endif
3863 /* Move the result to the right place */
3864 if (rr != AXP_REG_T12)
3866 set_tok_reg (newtok[0], AXP_REG_T12);
3867 set_tok_reg (newtok[1], rr);
3868 assemble_tokens ("mov", newtok, 2, 1);
3872 #endif /* !OBJ_EVAX */
3874 /* The jsr and jmp macros differ from their instruction counterparts
3875 in that they can load the target address and default most
3876 everything. */
3878 static void
3879 emit_jsrjmp (tok, ntok, vopname)
3880 const expressionS *tok;
3881 int ntok;
3882 const PTR vopname;
3884 const char *opname = (const char *) vopname;
3885 struct alpha_insn insn;
3886 expressionS newtok[3];
3887 int r, tokidx = 0;
3888 long lituse = 0;
3890 if (tokidx < ntok && tok[tokidx].X_op == O_register)
3891 r = regno (tok[tokidx++].X_add_number);
3892 else
3893 r = strcmp (opname, "jmp") == 0 ? AXP_REG_ZERO : AXP_REG_RA;
3895 set_tok_reg (newtok[0], r);
3897 if (tokidx < ntok &&
3898 (tok[tokidx].X_op == O_pregister || tok[tokidx].X_op == O_cpregister))
3899 r = regno (tok[tokidx++].X_add_number);
3900 #ifdef OBJ_EVAX
3901 /* keep register if jsr $n.<sym> */
3902 #else
3903 else
3905 int basereg = alpha_gp_register;
3906 lituse = load_expression (r = AXP_REG_PV, &tok[tokidx], &basereg, NULL);
3908 #endif
3910 set_tok_cpreg (newtok[1], r);
3912 #ifdef OBJ_EVAX
3913 /* FIXME: Add hint relocs to BFD for evax. */
3914 #else
3915 if (tokidx < ntok)
3916 newtok[2] = tok[tokidx];
3917 else
3918 #endif
3919 set_tok_const (newtok[2], 0);
3921 assemble_tokens_to_insn (opname, newtok, 3, &insn);
3923 if (lituse)
3925 assert (insn.nfixups < MAX_INSN_FIXUPS);
3926 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_JSR;
3927 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3928 insn.nfixups++;
3929 insn.sequence = lituse;
3932 emit_insn (&insn);
3935 /* The ret and jcr instructions differ from their instruction
3936 counterparts in that everything can be defaulted. */
3938 static void
3939 emit_retjcr (tok, ntok, vopname)
3940 const expressionS *tok;
3941 int ntok;
3942 const PTR vopname;
3944 const char *opname = (const char *) vopname;
3945 expressionS newtok[3];
3946 int r, tokidx = 0;
3948 if (tokidx < ntok && tok[tokidx].X_op == O_register)
3949 r = regno (tok[tokidx++].X_add_number);
3950 else
3951 r = AXP_REG_ZERO;
3953 set_tok_reg (newtok[0], r);
3955 if (tokidx < ntok &&
3956 (tok[tokidx].X_op == O_pregister || tok[tokidx].X_op == O_cpregister))
3957 r = regno (tok[tokidx++].X_add_number);
3958 else
3959 r = AXP_REG_RA;
3961 set_tok_cpreg (newtok[1], r);
3963 if (tokidx < ntok)
3964 newtok[2] = tok[tokidx];
3965 else
3966 set_tok_const (newtok[2], strcmp (opname, "ret") == 0);
3968 assemble_tokens (opname, newtok, 3, 0);
3971 /* Assembler directives */
3973 /* Handle the .text pseudo-op. This is like the usual one, but it
3974 clears alpha_insn_label and restores auto alignment. */
3976 static void
3977 s_alpha_text (i)
3978 int i;
3981 s_text (i);
3982 alpha_insn_label = NULL;
3983 alpha_auto_align_on = 1;
3984 alpha_current_align = 0;
3987 /* Handle the .data pseudo-op. This is like the usual one, but it
3988 clears alpha_insn_label and restores auto alignment. */
3990 static void
3991 s_alpha_data (i)
3992 int i;
3994 s_data (i);
3995 alpha_insn_label = NULL;
3996 alpha_auto_align_on = 1;
3997 alpha_current_align = 0;
4000 #if defined (OBJ_ECOFF) || defined (OBJ_EVAX)
4002 /* Handle the OSF/1 and openVMS .comm pseudo quirks.
4003 openVMS constructs a section for every common symbol. */
4005 static void
4006 s_alpha_comm (ignore)
4007 int ignore;
4009 register char *name;
4010 register char c;
4011 register char *p;
4012 offsetT temp;
4013 register symbolS *symbolP;
4015 #ifdef OBJ_EVAX
4016 segT current_section = now_seg;
4017 int current_subsec = now_subseg;
4018 segT new_seg;
4019 #endif
4021 name = input_line_pointer;
4022 c = get_symbol_end ();
4024 /* just after name is now '\0' */
4025 p = input_line_pointer;
4026 *p = c;
4028 SKIP_WHITESPACE ();
4030 /* Alpha OSF/1 compiler doesn't provide the comma, gcc does. */
4031 if (*input_line_pointer == ',')
4033 input_line_pointer++;
4034 SKIP_WHITESPACE ();
4036 if ((temp = get_absolute_expression ()) < 0)
4038 as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) temp);
4039 ignore_rest_of_line ();
4040 return;
4043 *p = 0;
4044 symbolP = symbol_find_or_make (name);
4046 #ifdef OBJ_EVAX
4047 /* Make a section for the common symbol. */
4048 new_seg = subseg_new (xstrdup (name), 0);
4049 #endif
4051 *p = c;
4053 #ifdef OBJ_EVAX
4054 /* alignment might follow */
4055 if (*input_line_pointer == ',')
4057 offsetT align;
4059 input_line_pointer++;
4060 align = get_absolute_expression ();
4061 bfd_set_section_alignment (stdoutput, new_seg, align);
4063 #endif
4065 if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
4067 as_bad (_("Ignoring attempt to re-define symbol"));
4068 ignore_rest_of_line ();
4069 return;
4072 #ifdef OBJ_EVAX
4073 if (bfd_section_size (stdoutput, new_seg) > 0)
4075 if (bfd_section_size (stdoutput, new_seg) != temp)
4076 as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
4077 S_GET_NAME (symbolP),
4078 (long) bfd_section_size (stdoutput, new_seg),
4079 (long) temp);
4081 #else
4082 if (S_GET_VALUE (symbolP))
4084 if (S_GET_VALUE (symbolP) != (valueT) temp)
4085 as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
4086 S_GET_NAME (symbolP),
4087 (long) S_GET_VALUE (symbolP),
4088 (long) temp);
4090 #endif
4091 else
4093 #ifdef OBJ_EVAX
4094 subseg_set (new_seg, 0);
4095 p = frag_more (temp);
4096 new_seg->flags |= SEC_IS_COMMON;
4097 if (! S_IS_DEFINED (symbolP))
4098 S_SET_SEGMENT (symbolP, new_seg);
4099 #else
4100 S_SET_VALUE (symbolP, (valueT) temp);
4101 #endif
4102 S_SET_EXTERNAL (symbolP);
4105 #ifdef OBJ_EVAX
4106 subseg_set (current_section, current_subsec);
4107 #endif
4109 know (symbol_get_frag (symbolP) == &zero_address_frag);
4111 demand_empty_rest_of_line ();
4114 #endif /* ! OBJ_ELF */
4116 #ifdef OBJ_ECOFF
4118 /* Handle the .rdata pseudo-op. This is like the usual one, but it
4119 clears alpha_insn_label and restores auto alignment. */
4121 static void
4122 s_alpha_rdata (ignore)
4123 int ignore;
4125 int temp;
4127 temp = get_absolute_expression ();
4128 subseg_new (".rdata", 0);
4129 demand_empty_rest_of_line ();
4130 alpha_insn_label = NULL;
4131 alpha_auto_align_on = 1;
4132 alpha_current_align = 0;
4135 #endif
4137 #ifdef OBJ_ECOFF
4139 /* Handle the .sdata pseudo-op. This is like the usual one, but it
4140 clears alpha_insn_label and restores auto alignment. */
4142 static void
4143 s_alpha_sdata (ignore)
4144 int ignore;
4146 int temp;
4148 temp = get_absolute_expression ();
4149 subseg_new (".sdata", 0);
4150 demand_empty_rest_of_line ();
4151 alpha_insn_label = NULL;
4152 alpha_auto_align_on = 1;
4153 alpha_current_align = 0;
4155 #endif
4157 #ifdef OBJ_ELF
4159 /* Handle the .section pseudo-op. This is like the usual one, but it
4160 clears alpha_insn_label and restores auto alignment. */
4162 static void
4163 s_alpha_section (ignore)
4164 int ignore;
4166 obj_elf_section (ignore);
4168 alpha_insn_label = NULL;
4169 alpha_auto_align_on = 1;
4170 alpha_current_align = 0;
4173 static void
4174 s_alpha_ent (dummy)
4175 int dummy ATTRIBUTE_UNUSED;
4177 if (ECOFF_DEBUGGING)
4178 ecoff_directive_ent (0);
4179 else
4181 char *name, name_end;
4182 name = input_line_pointer;
4183 name_end = get_symbol_end ();
4185 if (! is_name_beginner (*name))
4187 as_warn (_(".ent directive has no name"));
4188 *input_line_pointer = name_end;
4190 else
4192 symbolS *sym;
4194 if (alpha_cur_ent_sym)
4195 as_warn (_("nested .ent directives"));
4197 sym = symbol_find_or_make (name);
4198 symbol_get_bfdsym (sym)->flags |= BSF_FUNCTION;
4199 alpha_cur_ent_sym = sym;
4201 /* The .ent directive is sometimes followed by a number. Not sure
4202 what it really means, but ignore it. */
4203 *input_line_pointer = name_end;
4204 SKIP_WHITESPACE ();
4205 if (*input_line_pointer == ',')
4207 input_line_pointer++;
4208 SKIP_WHITESPACE ();
4210 if (ISDIGIT (*input_line_pointer) || *input_line_pointer == '-')
4211 (void) get_absolute_expression ();
4213 demand_empty_rest_of_line ();
4217 static void
4218 s_alpha_end (dummy)
4219 int dummy ATTRIBUTE_UNUSED;
4221 if (ECOFF_DEBUGGING)
4222 ecoff_directive_end (0);
4223 else
4225 char *name, name_end;
4226 name = input_line_pointer;
4227 name_end = get_symbol_end ();
4229 if (! is_name_beginner (*name))
4231 as_warn (_(".end directive has no name"));
4232 *input_line_pointer = name_end;
4234 else
4236 symbolS *sym;
4238 sym = symbol_find (name);
4239 if (sym != alpha_cur_ent_sym)
4240 as_warn (_(".end directive names different symbol than .ent"));
4242 /* Create an expression to calculate the size of the function. */
4243 if (sym)
4245 symbol_get_obj (sym)->size =
4246 (expressionS *) xmalloc (sizeof (expressionS));
4247 symbol_get_obj (sym)->size->X_op = O_subtract;
4248 symbol_get_obj (sym)->size->X_add_symbol
4249 = symbol_new ("L0\001", now_seg, frag_now_fix (), frag_now);
4250 symbol_get_obj (sym)->size->X_op_symbol = sym;
4251 symbol_get_obj (sym)->size->X_add_number = 0;
4254 alpha_cur_ent_sym = NULL;
4256 *input_line_pointer = name_end;
4258 demand_empty_rest_of_line ();
4262 static void
4263 s_alpha_mask (fp)
4264 int fp;
4266 if (ECOFF_DEBUGGING)
4268 if (fp)
4269 ecoff_directive_fmask (0);
4270 else
4271 ecoff_directive_mask (0);
4273 else
4274 discard_rest_of_line ();
4277 static void
4278 s_alpha_frame (dummy)
4279 int dummy ATTRIBUTE_UNUSED;
4281 if (ECOFF_DEBUGGING)
4282 ecoff_directive_frame (0);
4283 else
4284 discard_rest_of_line ();
4287 static void
4288 s_alpha_prologue (ignore)
4289 int ignore ATTRIBUTE_UNUSED;
4291 symbolS *sym;
4292 int arg;
4294 arg = get_absolute_expression ();
4295 demand_empty_rest_of_line ();
4297 if (ECOFF_DEBUGGING)
4298 sym = ecoff_get_cur_proc_sym ();
4299 else
4300 sym = alpha_cur_ent_sym;
4301 know (sym != NULL);
4303 switch (arg)
4305 case 0: /* No PV required. */
4306 S_SET_OTHER (sym, STO_ALPHA_NOPV
4307 | (S_GET_OTHER (sym) & ~STO_ALPHA_STD_GPLOAD));
4308 break;
4309 case 1: /* Std GP load. */
4310 S_SET_OTHER (sym, STO_ALPHA_STD_GPLOAD
4311 | (S_GET_OTHER (sym) & ~STO_ALPHA_STD_GPLOAD));
4312 break;
4313 case 2: /* Non-std use of PV. */
4314 break;
4316 default:
4317 as_bad (_("Invalid argument %d to .prologue."), arg);
4318 break;
4322 static char *first_file_directive;
4324 static void
4325 s_alpha_file (ignore)
4326 int ignore ATTRIBUTE_UNUSED;
4328 /* Save the first .file directive we see, so that we can change our
4329 minds about whether ecoff debugging should or shouldn't be enabled. */
4330 if (alpha_flag_mdebug < 0 && ! first_file_directive)
4332 char *start = input_line_pointer;
4333 size_t len;
4335 discard_rest_of_line ();
4337 len = input_line_pointer - start;
4338 first_file_directive = xmalloc (len + 1);
4339 memcpy (first_file_directive, start, len);
4340 first_file_directive[len] = '\0';
4342 input_line_pointer = start;
4345 if (ECOFF_DEBUGGING)
4346 ecoff_directive_file (0);
4347 else
4348 dwarf2_directive_file (0);
4351 static void
4352 s_alpha_loc (ignore)
4353 int ignore ATTRIBUTE_UNUSED;
4355 if (ECOFF_DEBUGGING)
4356 ecoff_directive_loc (0);
4357 else
4358 dwarf2_directive_loc (0);
4361 static void
4362 s_alpha_stab (n)
4363 int n;
4365 /* If we've been undecided about mdebug, make up our minds in favour. */
4366 if (alpha_flag_mdebug < 0)
4368 segT sec = subseg_new (".mdebug", 0);
4369 bfd_set_section_flags (stdoutput, sec, SEC_HAS_CONTENTS | SEC_READONLY);
4370 bfd_set_section_alignment (stdoutput, sec, 3);
4372 ecoff_read_begin_hook ();
4374 if (first_file_directive)
4376 char *save_ilp = input_line_pointer;
4377 input_line_pointer = first_file_directive;
4378 ecoff_directive_file (0);
4379 input_line_pointer = save_ilp;
4380 free (first_file_directive);
4383 alpha_flag_mdebug = 1;
4385 s_stab (n);
4388 static void
4389 s_alpha_coff_wrapper (which)
4390 int which;
4392 static void (* const fns[]) PARAMS ((int)) = {
4393 ecoff_directive_begin,
4394 ecoff_directive_bend,
4395 ecoff_directive_def,
4396 ecoff_directive_dim,
4397 ecoff_directive_endef,
4398 ecoff_directive_scl,
4399 ecoff_directive_tag,
4400 ecoff_directive_val,
4403 assert (which >= 0 && which < (int) (sizeof (fns)/sizeof (*fns)));
4405 if (ECOFF_DEBUGGING)
4406 (*fns[which]) (0);
4407 else
4409 as_bad (_("ECOFF debugging is disabled."));
4410 ignore_rest_of_line ();
4413 #endif /* OBJ_ELF */
4415 #ifdef OBJ_EVAX
4417 /* Handle the section specific pseudo-op. */
4419 static void
4420 s_alpha_section (secid)
4421 int secid;
4423 int temp;
4424 #define EVAX_SECTION_COUNT 5
4425 static char *section_name[EVAX_SECTION_COUNT + 1] =
4426 { "NULL", ".rdata", ".comm", ".link", ".ctors", ".dtors" };
4428 if ((secid <= 0) || (secid > EVAX_SECTION_COUNT))
4430 as_fatal (_("Unknown section directive"));
4431 demand_empty_rest_of_line ();
4432 return;
4434 temp = get_absolute_expression ();
4435 subseg_new (section_name[secid], 0);
4436 demand_empty_rest_of_line ();
4437 alpha_insn_label = NULL;
4438 alpha_auto_align_on = 1;
4439 alpha_current_align = 0;
4442 /* Parse .ent directives. */
4444 static void
4445 s_alpha_ent (ignore)
4446 int ignore;
4448 symbolS *symbol;
4449 expressionS symexpr;
4451 alpha_evax_proc.pdsckind = 0;
4452 alpha_evax_proc.framereg = -1;
4453 alpha_evax_proc.framesize = 0;
4454 alpha_evax_proc.rsa_offset = 0;
4455 alpha_evax_proc.ra_save = AXP_REG_RA;
4456 alpha_evax_proc.fp_save = -1;
4457 alpha_evax_proc.imask = 0;
4458 alpha_evax_proc.fmask = 0;
4459 alpha_evax_proc.prologue = 0;
4460 alpha_evax_proc.type = 0;
4462 expression (&symexpr);
4464 if (symexpr.X_op != O_symbol)
4466 as_fatal (_(".ent directive has no symbol"));
4467 demand_empty_rest_of_line ();
4468 return;
4471 symbol = make_expr_symbol (&symexpr);
4472 symbol_get_bfdsym (symbol)->flags |= BSF_FUNCTION;
4473 alpha_evax_proc.symbol = symbol;
4475 demand_empty_rest_of_line ();
4476 return;
4479 /* Parse .frame <framreg>,<framesize>,RA,<rsa_offset> directives. */
4481 static void
4482 s_alpha_frame (ignore)
4483 int ignore;
4485 long val;
4487 alpha_evax_proc.framereg = tc_get_register (1);
4489 SKIP_WHITESPACE ();
4490 if (*input_line_pointer++ != ','
4491 || get_absolute_expression_and_terminator (&val) != ',')
4493 as_warn (_("Bad .frame directive 1./2. param"));
4494 --input_line_pointer;
4495 demand_empty_rest_of_line ();
4496 return;
4499 alpha_evax_proc.framesize = val;
4501 (void) tc_get_register (1);
4502 SKIP_WHITESPACE ();
4503 if (*input_line_pointer++ != ',')
4505 as_warn (_("Bad .frame directive 3./4. param"));
4506 --input_line_pointer;
4507 demand_empty_rest_of_line ();
4508 return;
4510 alpha_evax_proc.rsa_offset = get_absolute_expression ();
4512 return;
4515 static void
4516 s_alpha_pdesc (ignore)
4517 int ignore;
4519 char *name;
4520 char name_end;
4521 long val;
4522 register char *p;
4523 expressionS exp;
4524 symbolS *entry_sym;
4525 fixS *fixp;
4526 segment_info_type *seginfo = seg_info (alpha_link_section);
4528 if (now_seg != alpha_link_section)
4530 as_bad (_(".pdesc directive not in link (.link) section"));
4531 demand_empty_rest_of_line ();
4532 return;
4535 if ((alpha_evax_proc.symbol == 0)
4536 || (!S_IS_DEFINED (alpha_evax_proc.symbol)))
4538 as_fatal (_(".pdesc has no matching .ent"));
4539 demand_empty_rest_of_line ();
4540 return;
4543 *symbol_get_obj (alpha_evax_proc.symbol) =
4544 (valueT) seginfo->literal_pool_size;
4546 expression (&exp);
4547 if (exp.X_op != O_symbol)
4549 as_warn (_(".pdesc directive has no entry symbol"));
4550 demand_empty_rest_of_line ();
4551 return;
4554 entry_sym = make_expr_symbol (&exp);
4555 /* Save bfd symbol of proc desc in function symbol. */
4556 symbol_get_bfdsym (alpha_evax_proc.symbol)->udata.p
4557 = symbol_get_bfdsym (entry_sym);
4559 SKIP_WHITESPACE ();
4560 if (*input_line_pointer++ != ',')
4562 as_warn (_("No comma after .pdesc <entryname>"));
4563 demand_empty_rest_of_line ();
4564 return;
4567 SKIP_WHITESPACE ();
4568 name = input_line_pointer;
4569 name_end = get_symbol_end ();
4571 if (strncmp (name, "stack", 5) == 0)
4573 alpha_evax_proc.pdsckind = PDSC_S_K_KIND_FP_STACK;
4575 else if (strncmp (name, "reg", 3) == 0)
4577 alpha_evax_proc.pdsckind = PDSC_S_K_KIND_FP_REGISTER;
4579 else if (strncmp (name, "null", 4) == 0)
4581 alpha_evax_proc.pdsckind = PDSC_S_K_KIND_NULL;
4583 else
4585 as_fatal (_("unknown procedure kind"));
4586 demand_empty_rest_of_line ();
4587 return;
4590 *input_line_pointer = name_end;
4591 demand_empty_rest_of_line ();
4593 #ifdef md_flush_pending_output
4594 md_flush_pending_output ();
4595 #endif
4597 frag_align (3, 0, 0);
4598 p = frag_more (16);
4599 fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
4600 fixp->fx_done = 1;
4601 seginfo->literal_pool_size += 16;
4603 *p = alpha_evax_proc.pdsckind
4604 | ((alpha_evax_proc.framereg == 29) ? PDSC_S_M_BASE_REG_IS_FP : 0);
4605 *(p + 1) = PDSC_S_M_NATIVE | PDSC_S_M_NO_JACKET;
4607 switch (alpha_evax_proc.pdsckind)
4609 case PDSC_S_K_KIND_NULL:
4610 *(p + 2) = 0;
4611 *(p + 3) = 0;
4612 break;
4613 case PDSC_S_K_KIND_FP_REGISTER:
4614 *(p + 2) = alpha_evax_proc.fp_save;
4615 *(p + 3) = alpha_evax_proc.ra_save;
4616 break;
4617 case PDSC_S_K_KIND_FP_STACK:
4618 md_number_to_chars (p + 2, (valueT) alpha_evax_proc.rsa_offset, 2);
4619 break;
4620 default: /* impossible */
4621 break;
4624 *(p + 4) = 0;
4625 *(p + 5) = alpha_evax_proc.type & 0x0f;
4627 /* Signature offset. */
4628 md_number_to_chars (p + 6, (valueT) 0, 2);
4630 fix_new_exp (frag_now, p - frag_now->fr_literal+8, 8, &exp, 0, BFD_RELOC_64);
4632 if (alpha_evax_proc.pdsckind == PDSC_S_K_KIND_NULL)
4633 return;
4635 /* Add dummy fix to make add_to_link_pool work. */
4636 p = frag_more (8);
4637 fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
4638 fixp->fx_done = 1;
4639 seginfo->literal_pool_size += 8;
4641 /* pdesc+16: Size. */
4642 md_number_to_chars (p, (valueT) alpha_evax_proc.framesize, 4);
4644 md_number_to_chars (p + 4, (valueT) 0, 2);
4646 /* Entry length. */
4647 md_number_to_chars (p + 6, alpha_evax_proc.prologue, 2);
4649 if (alpha_evax_proc.pdsckind == PDSC_S_K_KIND_FP_REGISTER)
4650 return;
4652 /* Add dummy fix to make add_to_link_pool work. */
4653 p = frag_more (8);
4654 fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
4655 fixp->fx_done = 1;
4656 seginfo->literal_pool_size += 8;
4658 /* pdesc+24: register masks. */
4660 md_number_to_chars (p, alpha_evax_proc.imask, 4);
4661 md_number_to_chars (p + 4, alpha_evax_proc.fmask, 4);
4663 return;
4666 /* Support for crash debug on vms. */
4668 static void
4669 s_alpha_name (ignore)
4670 int ignore;
4672 register char *p;
4673 expressionS exp;
4674 segment_info_type *seginfo = seg_info (alpha_link_section);
4676 if (now_seg != alpha_link_section)
4678 as_bad (_(".name directive not in link (.link) section"));
4679 demand_empty_rest_of_line ();
4680 return;
4683 expression (&exp);
4684 if (exp.X_op != O_symbol)
4686 as_warn (_(".name directive has no symbol"));
4687 demand_empty_rest_of_line ();
4688 return;
4691 demand_empty_rest_of_line ();
4693 #ifdef md_flush_pending_output
4694 md_flush_pending_output ();
4695 #endif
4697 frag_align (3, 0, 0);
4698 p = frag_more (8);
4699 seginfo->literal_pool_size += 8;
4701 fix_new_exp (frag_now, p - frag_now->fr_literal, 8, &exp, 0, BFD_RELOC_64);
4703 return;
4706 static void
4707 s_alpha_linkage (ignore)
4708 int ignore;
4710 expressionS exp;
4711 char *p;
4713 #ifdef md_flush_pending_output
4714 md_flush_pending_output ();
4715 #endif
4717 expression (&exp);
4718 if (exp.X_op != O_symbol)
4720 as_fatal (_("No symbol after .linkage"));
4722 else
4724 p = frag_more (LKP_S_K_SIZE);
4725 memset (p, 0, LKP_S_K_SIZE);
4726 fix_new_exp (frag_now, p - frag_now->fr_literal, LKP_S_K_SIZE, &exp, 0,\
4727 BFD_RELOC_ALPHA_LINKAGE);
4729 demand_empty_rest_of_line ();
4731 return;
4734 static void
4735 s_alpha_code_address (ignore)
4736 int ignore;
4738 expressionS exp;
4739 char *p;
4741 #ifdef md_flush_pending_output
4742 md_flush_pending_output ();
4743 #endif
4745 expression (&exp);
4746 if (exp.X_op != O_symbol)
4748 as_fatal (_("No symbol after .code_address"));
4750 else
4752 p = frag_more (8);
4753 memset (p, 0, 8);
4754 fix_new_exp (frag_now, p - frag_now->fr_literal, 8, &exp, 0,\
4755 BFD_RELOC_ALPHA_CODEADDR);
4757 demand_empty_rest_of_line ();
4759 return;
4762 static void
4763 s_alpha_fp_save (ignore)
4764 int ignore;
4767 alpha_evax_proc.fp_save = tc_get_register (1);
4769 demand_empty_rest_of_line ();
4770 return;
4773 static void
4774 s_alpha_mask (ignore)
4775 int ignore;
4777 long val;
4779 if (get_absolute_expression_and_terminator (&val) != ',')
4781 as_warn (_("Bad .mask directive"));
4782 --input_line_pointer;
4784 else
4786 alpha_evax_proc.imask = val;
4787 (void) get_absolute_expression ();
4789 demand_empty_rest_of_line ();
4791 return;
4794 static void
4795 s_alpha_fmask (ignore)
4796 int ignore;
4798 long val;
4800 if (get_absolute_expression_and_terminator (&val) != ',')
4802 as_warn (_("Bad .fmask directive"));
4803 --input_line_pointer;
4805 else
4807 alpha_evax_proc.fmask = val;
4808 (void) get_absolute_expression ();
4810 demand_empty_rest_of_line ();
4812 return;
4815 static void
4816 s_alpha_end (ignore)
4817 int ignore;
4819 char c;
4821 c = get_symbol_end ();
4822 *input_line_pointer = c;
4823 demand_empty_rest_of_line ();
4824 alpha_evax_proc.symbol = 0;
4826 return;
4829 static void
4830 s_alpha_file (ignore)
4831 int ignore;
4833 symbolS *s;
4834 int length;
4835 static char case_hack[32];
4837 extern char *demand_copy_string PARAMS ((int *lenP));
4839 sprintf (case_hack, "<CASE:%01d%01d>",
4840 alpha_flag_hash_long_names, alpha_flag_show_after_trunc);
4842 s = symbol_find_or_make (case_hack);
4843 symbol_get_bfdsym (s)->flags |= BSF_FILE;
4845 get_absolute_expression ();
4846 s = symbol_find_or_make (demand_copy_string (&length));
4847 symbol_get_bfdsym (s)->flags |= BSF_FILE;
4848 demand_empty_rest_of_line ();
4850 return;
4852 #endif /* OBJ_EVAX */
4854 /* Handle the .gprel32 pseudo op. */
4856 static void
4857 s_alpha_gprel32 (ignore)
4858 int ignore ATTRIBUTE_UNUSED;
4860 expressionS e;
4861 char *p;
4863 SKIP_WHITESPACE ();
4864 expression (&e);
4866 #ifdef OBJ_ELF
4867 switch (e.X_op)
4869 case O_constant:
4870 e.X_add_symbol = section_symbol (absolute_section);
4871 e.X_op = O_symbol;
4872 /* FALLTHRU */
4873 case O_symbol:
4874 break;
4875 default:
4876 abort ();
4878 #else
4879 #ifdef OBJ_ECOFF
4880 switch (e.X_op)
4882 case O_constant:
4883 e.X_add_symbol = section_symbol (absolute_section);
4884 /* fall through */
4885 case O_symbol:
4886 e.X_op = O_subtract;
4887 e.X_op_symbol = alpha_gp_symbol;
4888 break;
4889 default:
4890 abort ();
4892 #endif
4893 #endif
4895 if (alpha_auto_align_on && alpha_current_align < 2)
4896 alpha_align (2, (char *) NULL, alpha_insn_label, 0);
4897 if (alpha_current_align > 2)
4898 alpha_current_align = 2;
4899 alpha_insn_label = NULL;
4901 p = frag_more (4);
4902 memset (p, 0, 4);
4903 fix_new_exp (frag_now, p - frag_now->fr_literal, 4,
4904 &e, 0, BFD_RELOC_GPREL32);
4907 /* Handle floating point allocation pseudo-ops. This is like the
4908 generic vresion, but it makes sure the current label, if any, is
4909 correctly aligned. */
4911 static void
4912 s_alpha_float_cons (type)
4913 int type;
4915 int log_size;
4917 switch (type)
4919 default:
4920 case 'f':
4921 case 'F':
4922 log_size = 2;
4923 break;
4925 case 'd':
4926 case 'D':
4927 case 'G':
4928 log_size = 3;
4929 break;
4931 case 'x':
4932 case 'X':
4933 case 'p':
4934 case 'P':
4935 log_size = 4;
4936 break;
4939 if (alpha_auto_align_on && alpha_current_align < log_size)
4940 alpha_align (log_size, (char *) NULL, alpha_insn_label, 0);
4941 if (alpha_current_align > log_size)
4942 alpha_current_align = log_size;
4943 alpha_insn_label = NULL;
4945 float_cons (type);
4948 /* Handle the .proc pseudo op. We don't really do much with it except
4949 parse it. */
4951 static void
4952 s_alpha_proc (is_static)
4953 int is_static ATTRIBUTE_UNUSED;
4955 char *name;
4956 char c;
4957 char *p;
4958 symbolS *symbolP;
4959 int temp;
4961 /* Takes ".proc name,nargs" */
4962 SKIP_WHITESPACE ();
4963 name = input_line_pointer;
4964 c = get_symbol_end ();
4965 p = input_line_pointer;
4966 symbolP = symbol_find_or_make (name);
4967 *p = c;
4968 SKIP_WHITESPACE ();
4969 if (*input_line_pointer != ',')
4971 *p = 0;
4972 as_warn (_("Expected comma after name \"%s\""), name);
4973 *p = c;
4974 temp = 0;
4975 ignore_rest_of_line ();
4977 else
4979 input_line_pointer++;
4980 temp = get_absolute_expression ();
4982 /* *symbol_get_obj (symbolP) = (signed char) temp; */
4983 as_warn (_("unhandled: .proc %s,%d"), name, temp);
4984 demand_empty_rest_of_line ();
4987 /* Handle the .set pseudo op. This is used to turn on and off most of
4988 the assembler features. */
4990 static void
4991 s_alpha_set (x)
4992 int x ATTRIBUTE_UNUSED;
4994 char *name, ch, *s;
4995 int yesno = 1;
4997 SKIP_WHITESPACE ();
4998 name = input_line_pointer;
4999 ch = get_symbol_end ();
5001 s = name;
5002 if (s[0] == 'n' && s[1] == 'o')
5004 yesno = 0;
5005 s += 2;
5007 if (!strcmp ("reorder", s))
5008 /* ignore */ ;
5009 else if (!strcmp ("at", s))
5010 alpha_noat_on = !yesno;
5011 else if (!strcmp ("macro", s))
5012 alpha_macros_on = yesno;
5013 else if (!strcmp ("move", s))
5014 /* ignore */ ;
5015 else if (!strcmp ("volatile", s))
5016 /* ignore */ ;
5017 else
5018 as_warn (_("Tried to .set unrecognized mode `%s'"), name);
5020 *input_line_pointer = ch;
5021 demand_empty_rest_of_line ();
5024 /* Handle the .base pseudo op. This changes the assembler's notion of
5025 the $gp register. */
5027 static void
5028 s_alpha_base (ignore)
5029 int ignore ATTRIBUTE_UNUSED;
5031 #if 0
5032 if (first_32bit_quadrant)
5034 /* not fatal, but it might not work in the end */
5035 as_warn (_("File overrides no-base-register option."));
5036 first_32bit_quadrant = 0;
5038 #endif
5040 SKIP_WHITESPACE ();
5041 if (*input_line_pointer == '$')
5042 { /* $rNN form */
5043 input_line_pointer++;
5044 if (*input_line_pointer == 'r')
5045 input_line_pointer++;
5048 alpha_gp_register = get_absolute_expression ();
5049 if (alpha_gp_register < 0 || alpha_gp_register > 31)
5051 alpha_gp_register = AXP_REG_GP;
5052 as_warn (_("Bad base register, using $%d."), alpha_gp_register);
5055 demand_empty_rest_of_line ();
5058 /* Handle the .align pseudo-op. This aligns to a power of two. It
5059 also adjusts any current instruction label. We treat this the same
5060 way the MIPS port does: .align 0 turns off auto alignment. */
5062 static void
5063 s_alpha_align (ignore)
5064 int ignore ATTRIBUTE_UNUSED;
5066 int align;
5067 char fill, *pfill;
5068 long max_alignment = 15;
5070 align = get_absolute_expression ();
5071 if (align > max_alignment)
5073 align = max_alignment;
5074 as_bad (_("Alignment too large: %d. assumed"), align);
5076 else if (align < 0)
5078 as_warn (_("Alignment negative: 0 assumed"));
5079 align = 0;
5082 if (*input_line_pointer == ',')
5084 input_line_pointer++;
5085 fill = get_absolute_expression ();
5086 pfill = &fill;
5088 else
5089 pfill = NULL;
5091 if (align != 0)
5093 alpha_auto_align_on = 1;
5094 alpha_align (align, pfill, alpha_insn_label, 1);
5096 else
5098 alpha_auto_align_on = 0;
5101 demand_empty_rest_of_line ();
5104 /* Hook the normal string processor to reset known alignment. */
5106 static void
5107 s_alpha_stringer (terminate)
5108 int terminate;
5110 alpha_current_align = 0;
5111 alpha_insn_label = NULL;
5112 stringer (terminate);
5115 /* Hook the normal space processing to reset known alignment. */
5117 static void
5118 s_alpha_space (ignore)
5119 int ignore;
5121 alpha_current_align = 0;
5122 alpha_insn_label = NULL;
5123 s_space (ignore);
5126 /* Hook into cons for auto-alignment. */
5128 void
5129 alpha_cons_align (size)
5130 int size;
5132 int log_size;
5134 log_size = 0;
5135 while ((size >>= 1) != 0)
5136 ++log_size;
5138 if (alpha_auto_align_on && alpha_current_align < log_size)
5139 alpha_align (log_size, (char *) NULL, alpha_insn_label, 0);
5140 if (alpha_current_align > log_size)
5141 alpha_current_align = log_size;
5142 alpha_insn_label = NULL;
5145 /* Here come the .uword, .ulong, and .uquad explicitly unaligned
5146 pseudos. We just turn off auto-alignment and call down to cons. */
5148 static void
5149 s_alpha_ucons (bytes)
5150 int bytes;
5152 int hold = alpha_auto_align_on;
5153 alpha_auto_align_on = 0;
5154 cons (bytes);
5155 alpha_auto_align_on = hold;
5158 /* Switch the working cpu type. */
5160 static void
5161 s_alpha_arch (ignored)
5162 int ignored ATTRIBUTE_UNUSED;
5164 char *name, ch;
5165 const struct cpu_type *p;
5167 SKIP_WHITESPACE ();
5168 name = input_line_pointer;
5169 ch = get_symbol_end ();
5171 for (p = cpu_types; p->name; ++p)
5172 if (strcmp (name, p->name) == 0)
5174 alpha_target_name = p->name, alpha_target = p->flags;
5175 goto found;
5177 as_warn ("Unknown CPU identifier `%s'", name);
5179 found:
5180 *input_line_pointer = ch;
5181 demand_empty_rest_of_line ();
5184 #ifdef DEBUG1
5185 /* print token expression with alpha specific extension. */
5187 static void
5188 alpha_print_token (f, exp)
5189 FILE *f;
5190 const expressionS *exp;
5192 switch (exp->X_op)
5194 case O_cpregister:
5195 putc (',', f);
5196 /* FALLTHRU */
5197 case O_pregister:
5198 putc ('(', f);
5200 expressionS nexp = *exp;
5201 nexp.X_op = O_register;
5202 print_expr (f, &nexp);
5204 putc (')', f);
5205 break;
5206 default:
5207 print_expr (f, exp);
5208 break;
5210 return;
5212 #endif
5214 /* The target specific pseudo-ops which we support. */
5216 const pseudo_typeS md_pseudo_table[] = {
5217 #ifdef OBJ_ECOFF
5218 {"comm", s_alpha_comm, 0}, /* osf1 compiler does this */
5219 {"rdata", s_alpha_rdata, 0},
5220 #endif
5221 {"text", s_alpha_text, 0},
5222 {"data", s_alpha_data, 0},
5223 #ifdef OBJ_ECOFF
5224 {"sdata", s_alpha_sdata, 0},
5225 #endif
5226 #ifdef OBJ_ELF
5227 {"section", s_alpha_section, 0},
5228 {"section.s", s_alpha_section, 0},
5229 {"sect", s_alpha_section, 0},
5230 {"sect.s", s_alpha_section, 0},
5231 #endif
5232 #ifdef OBJ_EVAX
5233 { "pdesc", s_alpha_pdesc, 0},
5234 { "name", s_alpha_name, 0},
5235 { "linkage", s_alpha_linkage, 0},
5236 { "code_address", s_alpha_code_address, 0},
5237 { "ent", s_alpha_ent, 0},
5238 { "frame", s_alpha_frame, 0},
5239 { "fp_save", s_alpha_fp_save, 0},
5240 { "mask", s_alpha_mask, 0},
5241 { "fmask", s_alpha_fmask, 0},
5242 { "end", s_alpha_end, 0},
5243 { "file", s_alpha_file, 0},
5244 { "rdata", s_alpha_section, 1},
5245 { "comm", s_alpha_comm, 0},
5246 { "link", s_alpha_section, 3},
5247 { "ctors", s_alpha_section, 4},
5248 { "dtors", s_alpha_section, 5},
5249 #endif
5250 #ifdef OBJ_ELF
5251 /* Frame related pseudos. */
5252 {"ent", s_alpha_ent, 0},
5253 {"end", s_alpha_end, 0},
5254 {"mask", s_alpha_mask, 0},
5255 {"fmask", s_alpha_mask, 1},
5256 {"frame", s_alpha_frame, 0},
5257 {"prologue", s_alpha_prologue, 0},
5258 {"file", s_alpha_file, 5},
5259 {"loc", s_alpha_loc, 9},
5260 {"stabs", s_alpha_stab, 's'},
5261 {"stabn", s_alpha_stab, 'n'},
5262 /* COFF debugging related pseudos. */
5263 {"begin", s_alpha_coff_wrapper, 0},
5264 {"bend", s_alpha_coff_wrapper, 1},
5265 {"def", s_alpha_coff_wrapper, 2},
5266 {"dim", s_alpha_coff_wrapper, 3},
5267 {"endef", s_alpha_coff_wrapper, 4},
5268 {"scl", s_alpha_coff_wrapper, 5},
5269 {"tag", s_alpha_coff_wrapper, 6},
5270 {"val", s_alpha_coff_wrapper, 7},
5271 #else
5272 {"prologue", s_ignore, 0},
5273 #endif
5274 {"gprel32", s_alpha_gprel32, 0},
5275 {"t_floating", s_alpha_float_cons, 'd'},
5276 {"s_floating", s_alpha_float_cons, 'f'},
5277 {"f_floating", s_alpha_float_cons, 'F'},
5278 {"g_floating", s_alpha_float_cons, 'G'},
5279 {"d_floating", s_alpha_float_cons, 'D'},
5281 {"proc", s_alpha_proc, 0},
5282 {"aproc", s_alpha_proc, 1},
5283 {"set", s_alpha_set, 0},
5284 {"reguse", s_ignore, 0},
5285 {"livereg", s_ignore, 0},
5286 {"base", s_alpha_base, 0}, /*??*/
5287 {"option", s_ignore, 0},
5288 {"aent", s_ignore, 0},
5289 {"ugen", s_ignore, 0},
5290 {"eflag", s_ignore, 0},
5292 {"align", s_alpha_align, 0},
5293 {"double", s_alpha_float_cons, 'd'},
5294 {"float", s_alpha_float_cons, 'f'},
5295 {"single", s_alpha_float_cons, 'f'},
5296 {"ascii", s_alpha_stringer, 0},
5297 {"asciz", s_alpha_stringer, 1},
5298 {"string", s_alpha_stringer, 1},
5299 {"space", s_alpha_space, 0},
5300 {"skip", s_alpha_space, 0},
5301 {"zero", s_alpha_space, 0},
5303 /* Unaligned data pseudos. */
5304 {"uword", s_alpha_ucons, 2},
5305 {"ulong", s_alpha_ucons, 4},
5306 {"uquad", s_alpha_ucons, 8},
5308 #ifdef OBJ_ELF
5309 /* Dwarf wants these versions of unaligned. */
5310 {"2byte", s_alpha_ucons, 2},
5311 {"4byte", s_alpha_ucons, 4},
5312 {"8byte", s_alpha_ucons, 8},
5313 #endif
5315 /* We don't do any optimizing, so we can safely ignore these. */
5316 {"noalias", s_ignore, 0},
5317 {"alias", s_ignore, 0},
5319 {"arch", s_alpha_arch, 0},
5321 {NULL, 0, 0},
5324 /* Build a BFD section with its flags set appropriately for the .lita,
5325 .lit8, or .lit4 sections. */
5327 static void
5328 create_literal_section (name, secp, symp)
5329 const char *name;
5330 segT *secp;
5331 symbolS **symp;
5333 segT current_section = now_seg;
5334 int current_subsec = now_subseg;
5335 segT new_sec;
5337 *secp = new_sec = subseg_new (name, 0);
5338 subseg_set (current_section, current_subsec);
5339 bfd_set_section_alignment (stdoutput, new_sec, 4);
5340 bfd_set_section_flags (stdoutput, new_sec,
5341 SEC_RELOC | SEC_ALLOC | SEC_LOAD | SEC_READONLY
5342 | SEC_DATA);
5344 S_CLEAR_EXTERNAL (*symp = section_symbol (new_sec));
5347 #ifdef OBJ_ECOFF
5349 /* @@@ GP selection voodoo. All of this seems overly complicated and
5350 unnecessary; which is the primary reason it's for ECOFF only. */
5352 static inline void
5353 maybe_set_gp (sec)
5354 asection *sec;
5356 bfd_vma vma;
5357 if (!sec)
5358 return;
5359 vma = bfd_get_section_vma (foo, sec);
5360 if (vma && vma < alpha_gp_value)
5361 alpha_gp_value = vma;
5364 static void
5365 select_gp_value ()
5367 assert (alpha_gp_value == 0);
5369 /* Get minus-one in whatever width... */
5370 alpha_gp_value = 0;
5371 alpha_gp_value--;
5373 /* Select the smallest VMA of these existing sections. */
5374 maybe_set_gp (alpha_lita_section);
5375 #if 0
5376 /* These were disabled before -- should we use them? */
5377 maybe_set_gp (sdata);
5378 maybe_set_gp (lit8_sec);
5379 maybe_set_gp (lit4_sec);
5380 #endif
5382 /* @@ Will a simple 0x8000 work here? If not, why not? */
5383 #define GP_ADJUSTMENT (0x8000 - 0x10)
5385 alpha_gp_value += GP_ADJUSTMENT;
5387 S_SET_VALUE (alpha_gp_symbol, alpha_gp_value);
5389 #ifdef DEBUG1
5390 printf (_("Chose GP value of %lx\n"), alpha_gp_value);
5391 #endif
5393 #endif /* OBJ_ECOFF */
5395 #ifdef OBJ_ELF
5396 /* Map 's' to SHF_ALPHA_GPREL. */
5399 alpha_elf_section_letter (letter, ptr_msg)
5400 int letter;
5401 char **ptr_msg;
5403 if (letter == 's')
5404 return SHF_ALPHA_GPREL;
5406 *ptr_msg = _("Bad .section directive: want a,s,w,x,M,S in string");
5407 return 0;
5410 /* Map SHF_ALPHA_GPREL to SEC_SMALL_DATA. */
5412 flagword
5413 alpha_elf_section_flags (flags, attr, type)
5414 flagword flags;
5415 int attr, type ATTRIBUTE_UNUSED;
5417 if (attr & SHF_ALPHA_GPREL)
5418 flags |= SEC_SMALL_DATA;
5419 return flags;
5421 #endif /* OBJ_ELF */
5423 /* Called internally to handle all alignment needs. This takes care
5424 of eliding calls to frag_align if'n the cached current alignment
5425 says we've already got it, as well as taking care of the auto-align
5426 feature wrt labels. */
5428 static void
5429 alpha_align (n, pfill, label, force)
5430 int n;
5431 char *pfill;
5432 symbolS *label;
5433 int force ATTRIBUTE_UNUSED;
5435 if (alpha_current_align >= n)
5436 return;
5438 if (pfill == NULL)
5440 if (subseg_text_p (now_seg))
5441 frag_align_code (n, 0);
5442 else
5443 frag_align (n, 0, 0);
5445 else
5446 frag_align (n, *pfill, 0);
5448 alpha_current_align = n;
5450 if (label != NULL && S_GET_SEGMENT (label) == now_seg)
5452 symbol_set_frag (label, frag_now);
5453 S_SET_VALUE (label, (valueT) frag_now_fix ());
5456 record_alignment (now_seg, n);
5458 /* ??? If alpha_flag_relax && force && elf, record the requested alignment
5459 in a reloc for the linker to see. */
5462 /* This is called from HANDLE_ALIGN in write.c. Fill in the contents
5463 of an rs_align_code fragment. */
5465 void
5466 alpha_handle_align (fragp)
5467 fragS *fragp;
5469 static char const unop[4] = { 0x00, 0x00, 0xfe, 0x2f };
5470 static char const nopunop[8] = {
5471 0x1f, 0x04, 0xff, 0x47,
5472 0x00, 0x00, 0xfe, 0x2f
5475 int bytes, fix;
5476 char *p;
5478 if (fragp->fr_type != rs_align_code)
5479 return;
5481 bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix;
5482 p = fragp->fr_literal + fragp->fr_fix;
5483 fix = 0;
5485 if (bytes & 3)
5487 fix = bytes & 3;
5488 memset (p, 0, fix);
5489 p += fix;
5490 bytes -= fix;
5493 if (bytes & 4)
5495 memcpy (p, unop, 4);
5496 p += 4;
5497 bytes -= 4;
5498 fix += 4;
5501 memcpy (p, nopunop, 8);
5503 fragp->fr_fix += fix;
5504 fragp->fr_var = 8;
5507 /* The Alpha has support for some VAX floating point types, as well as for
5508 IEEE floating point. We consider IEEE to be the primary floating point
5509 format, and sneak in the VAX floating point support here. */
5510 #define md_atof vax_md_atof
5511 #include "config/atof-vax.c"