Update Maverick tests.
[binutils.git] / gas / config / tc-alpha.c
blob5a65c43ff7eea214a51c442618fa216a36b014ae
1 /* tc-alpha.c - Processor-specific code for the DEC Alpha AXP CPU.
2 Copyright 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 2001, 2002, 2003 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
77 expressionS exp;
78 bfd_reloc_code_real_type reloc;
81 struct alpha_insn
83 unsigned insn;
84 int nfixups;
85 struct alpha_fixup fixups[MAX_INSN_FIXUPS];
86 long sequence;
89 enum alpha_macro_arg
91 MACRO_EOA = 1,
92 MACRO_IR,
93 MACRO_PIR,
94 MACRO_OPIR,
95 MACRO_CPIR,
96 MACRO_FPR,
97 MACRO_EXP,
100 struct alpha_macro
102 const char *name;
103 void (*emit) PARAMS ((const expressionS *, int, const PTR));
104 const PTR arg;
105 enum alpha_macro_arg argsets[16];
108 /* Extra expression types. */
110 #define O_pregister O_md1 /* O_register, in parentheses */
111 #define O_cpregister O_md2 /* + a leading comma */
113 /* The alpha_reloc_op table below depends on the ordering of these. */
114 #define O_literal O_md3 /* !literal relocation */
115 #define O_lituse_addr O_md4 /* !lituse_addr relocation */
116 #define O_lituse_base O_md5 /* !lituse_base relocation */
117 #define O_lituse_bytoff O_md6 /* !lituse_bytoff relocation */
118 #define O_lituse_jsr O_md7 /* !lituse_jsr relocation */
119 #define O_lituse_tlsgd O_md8 /* !lituse_tlsgd relocation */
120 #define O_lituse_tlsldm O_md9 /* !lituse_tlsldm relocation */
121 #define O_gpdisp O_md10 /* !gpdisp relocation */
122 #define O_gprelhigh O_md11 /* !gprelhigh relocation */
123 #define O_gprellow O_md12 /* !gprellow relocation */
124 #define O_gprel O_md13 /* !gprel relocation */
125 #define O_samegp O_md14 /* !samegp relocation */
126 #define O_tlsgd O_md15 /* !tlsgd relocation */
127 #define O_tlsldm O_md16 /* !tlsldm relocation */
128 #define O_gotdtprel O_md17 /* !gotdtprel relocation */
129 #define O_dtprelhi O_md18 /* !dtprelhi relocation */
130 #define O_dtprello O_md19 /* !dtprello relocation */
131 #define O_dtprel O_md20 /* !dtprel relocation */
132 #define O_gottprel O_md21 /* !gottprel relocation */
133 #define O_tprelhi O_md22 /* !tprelhi relocation */
134 #define O_tprello O_md23 /* !tprello relocation */
135 #define O_tprel O_md24 /* !tprel relocation */
137 #define DUMMY_RELOC_LITUSE_ADDR (BFD_RELOC_UNUSED + 1)
138 #define DUMMY_RELOC_LITUSE_BASE (BFD_RELOC_UNUSED + 2)
139 #define DUMMY_RELOC_LITUSE_BYTOFF (BFD_RELOC_UNUSED + 3)
140 #define DUMMY_RELOC_LITUSE_JSR (BFD_RELOC_UNUSED + 4)
141 #define DUMMY_RELOC_LITUSE_TLSGD (BFD_RELOC_UNUSED + 5)
142 #define DUMMY_RELOC_LITUSE_TLSLDM (BFD_RELOC_UNUSED + 6)
144 #define USER_RELOC_P(R) ((R) >= O_literal && (R) <= O_tprel)
146 /* Macros for extracting the type and number of encoded register tokens. */
148 #define is_ir_num(x) (((x) & 32) == 0)
149 #define is_fpr_num(x) (((x) & 32) != 0)
150 #define regno(x) ((x) & 31)
152 /* Something odd inherited from the old assembler. */
154 #define note_gpreg(R) (alpha_gprmask |= (1 << (R)))
155 #define note_fpreg(R) (alpha_fprmask |= (1 << (R)))
157 /* Predicates for 16- and 32-bit ranges */
158 /* XXX: The non-shift version appears to trigger a compiler bug when
159 cross-assembling from x86 w/ gcc 2.7.2. */
161 #if 1
162 #define range_signed_16(x) \
163 (((offsetT) (x) >> 15) == 0 || ((offsetT) (x) >> 15) == -1)
164 #define range_signed_32(x) \
165 (((offsetT) (x) >> 31) == 0 || ((offsetT) (x) >> 31) == -1)
166 #else
167 #define range_signed_16(x) ((offsetT) (x) >= -(offsetT) 0x8000 && \
168 (offsetT) (x) <= (offsetT) 0x7FFF)
169 #define range_signed_32(x) ((offsetT) (x) >= -(offsetT) 0x80000000 && \
170 (offsetT) (x) <= (offsetT) 0x7FFFFFFF)
171 #endif
173 /* Macros for sign extending from 16- and 32-bits. */
174 /* XXX: The cast macros will work on all the systems that I care about,
175 but really a predicate should be found to use the non-cast forms. */
177 #if 1
178 #define sign_extend_16(x) ((short) (x))
179 #define sign_extend_32(x) ((int) (x))
180 #else
181 #define sign_extend_16(x) ((offsetT) (((x) & 0xFFFF) ^ 0x8000) - 0x8000)
182 #define sign_extend_32(x) ((offsetT) (((x) & 0xFFFFFFFF) \
183 ^ 0x80000000) - 0x80000000)
184 #endif
186 /* Macros to build tokens. */
188 #define set_tok_reg(t, r) (memset (&(t), 0, sizeof (t)), \
189 (t).X_op = O_register, \
190 (t).X_add_number = (r))
191 #define set_tok_preg(t, r) (memset (&(t), 0, sizeof (t)), \
192 (t).X_op = O_pregister, \
193 (t).X_add_number = (r))
194 #define set_tok_cpreg(t, r) (memset (&(t), 0, sizeof (t)), \
195 (t).X_op = O_cpregister, \
196 (t).X_add_number = (r))
197 #define set_tok_freg(t, r) (memset (&(t), 0, sizeof (t)), \
198 (t).X_op = O_register, \
199 (t).X_add_number = (r) + 32)
200 #define set_tok_sym(t, s, a) (memset (&(t), 0, sizeof (t)), \
201 (t).X_op = O_symbol, \
202 (t).X_add_symbol = (s), \
203 (t).X_add_number = (a))
204 #define set_tok_const(t, n) (memset (&(t), 0, sizeof (t)), \
205 (t).X_op = O_constant, \
206 (t).X_add_number = (n))
208 /* Prototypes for all local functions. */
210 static struct alpha_reloc_tag *get_alpha_reloc_tag PARAMS ((long));
211 static void alpha_adjust_relocs PARAMS ((bfd *, asection *, PTR));
213 static int tokenize_arguments PARAMS ((char *, expressionS *, int));
214 static const struct alpha_opcode *find_opcode_match
215 PARAMS ((const struct alpha_opcode *, const expressionS *, int *, int *));
216 static const struct alpha_macro *find_macro_match
217 PARAMS ((const struct alpha_macro *, const expressionS *, int *));
218 static unsigned insert_operand
219 PARAMS ((unsigned, const struct alpha_operand *, offsetT, char *, unsigned));
220 static void assemble_insn
221 PARAMS ((const struct alpha_opcode *, const expressionS *, int,
222 struct alpha_insn *, bfd_reloc_code_real_type));
223 static void emit_insn PARAMS ((struct alpha_insn *));
224 static void assemble_tokens_to_insn
225 PARAMS ((const char *, const expressionS *, int, struct alpha_insn *));
226 static void assemble_tokens
227 PARAMS ((const char *, const expressionS *, int, int));
229 static long load_expression
230 PARAMS ((int, const expressionS *, int *, expressionS *));
232 static void emit_ldgp PARAMS ((const expressionS *, int, const PTR));
233 static void emit_division PARAMS ((const expressionS *, int, const PTR));
234 static void emit_lda PARAMS ((const expressionS *, int, const PTR));
235 static void emit_ldah PARAMS ((const expressionS *, int, const PTR));
236 static void emit_ir_load PARAMS ((const expressionS *, int, const PTR));
237 static void emit_loadstore PARAMS ((const expressionS *, int, const PTR));
238 static void emit_jsrjmp PARAMS ((const expressionS *, int, const PTR));
239 static void emit_ldX PARAMS ((const expressionS *, int, const PTR));
240 static void emit_ldXu PARAMS ((const expressionS *, int, const PTR));
241 static void emit_uldX PARAMS ((const expressionS *, int, const PTR));
242 static void emit_uldXu PARAMS ((const expressionS *, int, const PTR));
243 static void emit_ldil PARAMS ((const expressionS *, int, const PTR));
244 static void emit_stX PARAMS ((const expressionS *, int, const PTR));
245 static void emit_ustX PARAMS ((const expressionS *, int, const PTR));
246 static void emit_sextX PARAMS ((const expressionS *, int, const PTR));
247 static void emit_retjcr PARAMS ((const expressionS *, int, const PTR));
249 static void s_alpha_text PARAMS ((int));
250 static void s_alpha_data PARAMS ((int));
251 #ifndef OBJ_ELF
252 static void s_alpha_comm PARAMS ((int));
253 static void s_alpha_rdata PARAMS ((int));
254 #endif
255 #ifdef OBJ_ECOFF
256 static void s_alpha_sdata PARAMS ((int));
257 #endif
258 #ifdef OBJ_ELF
259 static void s_alpha_section PARAMS ((int));
260 static void s_alpha_ent PARAMS ((int));
261 static void s_alpha_end PARAMS ((int));
262 static void s_alpha_mask PARAMS ((int));
263 static void s_alpha_frame PARAMS ((int));
264 static void s_alpha_prologue PARAMS ((int));
265 static void s_alpha_file PARAMS ((int));
266 static void s_alpha_loc PARAMS ((int));
267 static void s_alpha_stab PARAMS ((int));
268 static void s_alpha_coff_wrapper PARAMS ((int));
269 #endif
270 #ifdef OBJ_EVAX
271 static void s_alpha_section PARAMS ((int));
272 #endif
273 static void s_alpha_gprel32 PARAMS ((int));
274 static void s_alpha_float_cons PARAMS ((int));
275 static void s_alpha_proc PARAMS ((int));
276 static void s_alpha_set PARAMS ((int));
277 static void s_alpha_base PARAMS ((int));
278 static void s_alpha_align PARAMS ((int));
279 static void s_alpha_stringer PARAMS ((int));
280 static void s_alpha_space PARAMS ((int));
281 static void s_alpha_ucons PARAMS ((int));
282 static void s_alpha_arch PARAMS ((int));
284 static void create_literal_section PARAMS ((const char *, segT *, symbolS **));
285 #ifndef OBJ_ELF
286 static void select_gp_value PARAMS ((void));
287 #endif
288 static void alpha_align PARAMS ((int, char *, symbolS *, int));
290 /* Generic assembler global variables which must be defined by all
291 targets. */
293 /* Characters which always start a comment. */
294 const char comment_chars[] = "#";
296 /* Characters which start a comment at the beginning of a line. */
297 const char line_comment_chars[] = "#";
299 /* Characters which may be used to separate multiple commands on a
300 single line. */
301 const char line_separator_chars[] = ";";
303 /* Characters which are used to indicate an exponent in a floating
304 point number. */
305 const char EXP_CHARS[] = "eE";
307 /* Characters which mean that a number is a floating point constant,
308 as in 0d1.0. */
309 #if 0
310 const char FLT_CHARS[] = "dD";
311 #else
312 /* XXX: Do all of these really get used on the alpha?? */
313 char FLT_CHARS[] = "rRsSfFdDxXpP";
314 #endif
316 #ifdef OBJ_EVAX
317 const char *md_shortopts = "Fm:g+1h:HG:";
318 #else
319 const char *md_shortopts = "Fm:gG:";
320 #endif
322 struct option md_longopts[] =
324 #define OPTION_32ADDR (OPTION_MD_BASE)
325 { "32addr", no_argument, NULL, OPTION_32ADDR },
326 #define OPTION_RELAX (OPTION_32ADDR + 1)
327 { "relax", no_argument, NULL, OPTION_RELAX },
328 #ifdef OBJ_ELF
329 #define OPTION_MDEBUG (OPTION_RELAX + 1)
330 #define OPTION_NO_MDEBUG (OPTION_MDEBUG + 1)
331 { "mdebug", no_argument, NULL, OPTION_MDEBUG },
332 { "no-mdebug", no_argument, NULL, OPTION_NO_MDEBUG },
333 #endif
334 { NULL, no_argument, NULL, 0 }
337 size_t md_longopts_size = sizeof (md_longopts);
339 #ifdef OBJ_EVAX
340 #define AXP_REG_R0 0
341 #define AXP_REG_R16 16
342 #define AXP_REG_R17 17
343 #undef AXP_REG_T9
344 #define AXP_REG_T9 22
345 #undef AXP_REG_T10
346 #define AXP_REG_T10 23
347 #undef AXP_REG_T11
348 #define AXP_REG_T11 24
349 #undef AXP_REG_T12
350 #define AXP_REG_T12 25
351 #define AXP_REG_AI 25
352 #undef AXP_REG_FP
353 #define AXP_REG_FP 29
355 #undef AXP_REG_GP
356 #define AXP_REG_GP AXP_REG_PV
357 #endif /* OBJ_EVAX */
359 /* The cpu for which we are generating code. */
360 static unsigned alpha_target = AXP_OPCODE_BASE;
361 static const char *alpha_target_name = "<all>";
363 /* The hash table of instruction opcodes. */
364 static struct hash_control *alpha_opcode_hash;
366 /* The hash table of macro opcodes. */
367 static struct hash_control *alpha_macro_hash;
369 #ifdef OBJ_ECOFF
370 /* The $gp relocation symbol. */
371 static symbolS *alpha_gp_symbol;
373 /* XXX: what is this, and why is it exported? */
374 valueT alpha_gp_value;
375 #endif
377 /* The current $gp register. */
378 static int alpha_gp_register = AXP_REG_GP;
380 /* A table of the register symbols. */
381 static symbolS *alpha_register_table[64];
383 /* Constant sections, or sections of constants. */
384 #ifdef OBJ_ECOFF
385 static segT alpha_lita_section;
386 #endif
387 #ifdef OBJ_EVAX
388 static segT alpha_link_section;
389 static segT alpha_ctors_section;
390 static segT alpha_dtors_section;
391 #endif
392 static segT alpha_lit8_section;
394 /* Symbols referring to said sections. */
395 #ifdef OBJ_ECOFF
396 static symbolS *alpha_lita_symbol;
397 #endif
398 #ifdef OBJ_EVAX
399 static symbolS *alpha_link_symbol;
400 static symbolS *alpha_ctors_symbol;
401 static symbolS *alpha_dtors_symbol;
402 #endif
403 static symbolS *alpha_lit8_symbol;
405 /* Literal for .litX+0x8000 within .lita. */
406 #ifdef OBJ_ECOFF
407 static offsetT alpha_lit8_literal;
408 #endif
410 #ifdef OBJ_ELF
411 /* The active .ent symbol. */
412 static symbolS *alpha_cur_ent_sym;
413 #endif
415 /* Is the assembler not allowed to use $at? */
416 static int alpha_noat_on = 0;
418 /* Are macros enabled? */
419 static int alpha_macros_on = 1;
421 /* Are floats disabled? */
422 static int alpha_nofloats_on = 0;
424 /* Are addresses 32 bit? */
425 static int alpha_addr32_on = 0;
427 /* Symbol labelling the current insn. When the Alpha gas sees
428 foo:
429 .quad 0
430 and the section happens to not be on an eight byte boundary, it
431 will align both the symbol and the .quad to an eight byte boundary. */
432 static symbolS *alpha_insn_label;
434 /* Whether we should automatically align data generation pseudo-ops.
435 .align 0 will turn this off. */
436 static int alpha_auto_align_on = 1;
438 /* The known current alignment of the current section. */
439 static int alpha_current_align;
441 /* These are exported to ECOFF code. */
442 unsigned long alpha_gprmask, alpha_fprmask;
444 /* Whether the debugging option was seen. */
445 static int alpha_debug;
447 #ifdef OBJ_ELF
448 /* Whether we are emitting an mdebug section. */
449 int alpha_flag_mdebug = -1;
450 #endif
452 /* Don't fully resolve relocations, allowing code movement in the linker. */
453 static int alpha_flag_relax;
455 /* What value to give to bfd_set_gp_size. */
456 static int g_switch_value = 8;
458 #ifdef OBJ_EVAX
459 /* Collect information about current procedure here. */
460 static struct {
461 symbolS *symbol; /* proc pdesc symbol */
462 int pdsckind;
463 int framereg; /* register for frame pointer */
464 int framesize; /* size of frame */
465 int rsa_offset;
466 int ra_save;
467 int fp_save;
468 long imask;
469 long fmask;
470 int type;
471 int prologue;
472 } alpha_evax_proc;
474 static int alpha_flag_hash_long_names = 0; /* -+ */
475 static int alpha_flag_show_after_trunc = 0; /* -H */
477 /* If the -+ switch is given, then a hash is appended to any name that is
478 longer than 64 characters, else longer symbol names are truncated. */
480 #endif
482 #ifdef RELOC_OP_P
483 /* A table to map the spelling of a relocation operand into an appropriate
484 bfd_reloc_code_real_type type. The table is assumed to be ordered such
485 that op-O_literal indexes into it. */
487 #define ALPHA_RELOC_TABLE(op) \
488 (&alpha_reloc_op[ ((!USER_RELOC_P (op)) \
489 ? (abort (), 0) \
490 : (int) (op) - (int) O_literal) ])
492 #define DEF(NAME, RELOC, REQ, ALLOW) \
493 { #NAME, sizeof(#NAME)-1, O_##NAME, RELOC, REQ, ALLOW}
495 static const struct alpha_reloc_op_tag
497 const char *name; /* string to lookup */
498 size_t length; /* size of the string */
499 operatorT op; /* which operator to use */
500 bfd_reloc_code_real_type reloc; /* relocation before frob */
501 unsigned int require_seq : 1; /* require a sequence number */
502 unsigned int allow_seq : 1; /* allow a sequence number */
504 alpha_reloc_op[] =
506 DEF(literal, BFD_RELOC_ALPHA_ELF_LITERAL, 0, 1),
507 DEF(lituse_addr, DUMMY_RELOC_LITUSE_ADDR, 1, 1),
508 DEF(lituse_base, DUMMY_RELOC_LITUSE_BASE, 1, 1),
509 DEF(lituse_bytoff, DUMMY_RELOC_LITUSE_BYTOFF, 1, 1),
510 DEF(lituse_jsr, DUMMY_RELOC_LITUSE_JSR, 1, 1),
511 DEF(lituse_tlsgd, DUMMY_RELOC_LITUSE_TLSGD, 1, 1),
512 DEF(lituse_tlsldm, DUMMY_RELOC_LITUSE_TLSLDM, 1, 1),
513 DEF(gpdisp, BFD_RELOC_ALPHA_GPDISP, 1, 1),
514 DEF(gprelhigh, BFD_RELOC_ALPHA_GPREL_HI16, 0, 0),
515 DEF(gprellow, BFD_RELOC_ALPHA_GPREL_LO16, 0, 0),
516 DEF(gprel, BFD_RELOC_GPREL16, 0, 0),
517 DEF(samegp, BFD_RELOC_ALPHA_BRSGP, 0, 0),
518 DEF(tlsgd, BFD_RELOC_ALPHA_TLSGD, 0, 1),
519 DEF(tlsldm, BFD_RELOC_ALPHA_TLSLDM, 0, 1),
520 DEF(gotdtprel, BFD_RELOC_ALPHA_GOTDTPREL16, 0, 0),
521 DEF(dtprelhi, BFD_RELOC_ALPHA_DTPREL_HI16, 0, 0),
522 DEF(dtprello, BFD_RELOC_ALPHA_DTPREL_LO16, 0, 0),
523 DEF(dtprel, BFD_RELOC_ALPHA_DTPREL16, 0, 0),
524 DEF(gottprel, BFD_RELOC_ALPHA_GOTTPREL16, 0, 0),
525 DEF(tprelhi, BFD_RELOC_ALPHA_TPREL_HI16, 0, 0),
526 DEF(tprello, BFD_RELOC_ALPHA_TPREL_LO16, 0, 0),
527 DEF(tprel, BFD_RELOC_ALPHA_TPREL16, 0, 0),
530 #undef DEF
532 static const int alpha_num_reloc_op
533 = sizeof (alpha_reloc_op) / sizeof (*alpha_reloc_op);
534 #endif /* RELOC_OP_P */
536 /* Maximum # digits needed to hold the largest sequence # */
537 #define ALPHA_RELOC_DIGITS 25
539 /* Structure to hold explict sequence information. */
540 struct alpha_reloc_tag
542 fixS *master; /* the literal reloc */
543 fixS *slaves; /* head of linked list of lituses */
544 segT segment; /* segment relocs are in or undefined_section*/
545 long sequence; /* sequence # */
546 unsigned n_master; /* # of literals */
547 unsigned n_slaves; /* # of lituses */
548 unsigned saw_tlsgd : 1; /* true if ... */
549 unsigned saw_tlsldm : 1;
550 unsigned saw_lu_tlsgd : 1;
551 unsigned saw_lu_tlsldm : 1;
552 unsigned multi_section_p : 1; /* true if more than one section was used */
553 char string[1]; /* printable form of sequence to hash with */
556 /* Hash table to link up literals with the appropriate lituse */
557 static struct hash_control *alpha_literal_hash;
559 /* Sequence numbers for internal use by macros. */
560 static long next_sequence_num = -1;
562 /* A table of CPU names and opcode sets. */
564 static const struct cpu_type
566 const char *name;
567 unsigned flags;
569 cpu_types[] =
571 /* Ad hoc convention: cpu number gets palcode, process code doesn't.
572 This supports usage under DU 4.0b that does ".arch ev4", and
573 usage in MILO that does -m21064. Probably something more
574 specific like -m21064-pal should be used, but oh well. */
576 { "21064", AXP_OPCODE_BASE|AXP_OPCODE_EV4 },
577 { "21064a", AXP_OPCODE_BASE|AXP_OPCODE_EV4 },
578 { "21066", AXP_OPCODE_BASE|AXP_OPCODE_EV4 },
579 { "21068", AXP_OPCODE_BASE|AXP_OPCODE_EV4 },
580 { "21164", AXP_OPCODE_BASE|AXP_OPCODE_EV5 },
581 { "21164a", AXP_OPCODE_BASE|AXP_OPCODE_EV5|AXP_OPCODE_BWX },
582 { "21164pc", (AXP_OPCODE_BASE|AXP_OPCODE_EV5|AXP_OPCODE_BWX
583 |AXP_OPCODE_MAX) },
584 { "21264", (AXP_OPCODE_BASE|AXP_OPCODE_EV6|AXP_OPCODE_BWX
585 |AXP_OPCODE_MAX|AXP_OPCODE_CIX) },
586 { "21264a", (AXP_OPCODE_BASE|AXP_OPCODE_EV6|AXP_OPCODE_BWX
587 |AXP_OPCODE_MAX|AXP_OPCODE_CIX) },
588 { "21264b", (AXP_OPCODE_BASE|AXP_OPCODE_EV6|AXP_OPCODE_BWX
589 |AXP_OPCODE_MAX|AXP_OPCODE_CIX) },
591 { "ev4", AXP_OPCODE_BASE },
592 { "ev45", AXP_OPCODE_BASE },
593 { "lca45", AXP_OPCODE_BASE },
594 { "ev5", AXP_OPCODE_BASE },
595 { "ev56", AXP_OPCODE_BASE|AXP_OPCODE_BWX },
596 { "pca56", AXP_OPCODE_BASE|AXP_OPCODE_BWX|AXP_OPCODE_MAX },
597 { "ev6", AXP_OPCODE_BASE|AXP_OPCODE_BWX|AXP_OPCODE_MAX|AXP_OPCODE_CIX },
598 { "ev67", AXP_OPCODE_BASE|AXP_OPCODE_BWX|AXP_OPCODE_MAX|AXP_OPCODE_CIX },
599 { "ev68", AXP_OPCODE_BASE|AXP_OPCODE_BWX|AXP_OPCODE_MAX|AXP_OPCODE_CIX },
601 { "all", AXP_OPCODE_BASE },
602 { 0, 0 }
605 /* The macro table */
607 static const struct alpha_macro alpha_macros[] =
609 /* Load/Store macros */
610 { "lda", emit_lda, NULL,
611 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
612 { "ldah", emit_ldah, NULL,
613 { MACRO_IR, MACRO_EXP, MACRO_EOA } },
615 { "ldl", emit_ir_load, "ldl",
616 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
617 { "ldl_l", emit_ir_load, "ldl_l",
618 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
619 { "ldq", emit_ir_load, "ldq",
620 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
621 { "ldq_l", emit_ir_load, "ldq_l",
622 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
623 { "ldq_u", emit_ir_load, "ldq_u",
624 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
625 { "ldf", emit_loadstore, "ldf",
626 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
627 { "ldg", emit_loadstore, "ldg",
628 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
629 { "lds", emit_loadstore, "lds",
630 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
631 { "ldt", emit_loadstore, "ldt",
632 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
634 { "ldb", emit_ldX, (PTR) 0,
635 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
636 { "ldbu", emit_ldXu, (PTR) 0,
637 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
638 { "ldw", emit_ldX, (PTR) 1,
639 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
640 { "ldwu", emit_ldXu, (PTR) 1,
641 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
643 { "uldw", emit_uldX, (PTR) 1,
644 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
645 { "uldwu", emit_uldXu, (PTR) 1,
646 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
647 { "uldl", emit_uldX, (PTR) 2,
648 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
649 { "uldlu", emit_uldXu, (PTR) 2,
650 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
651 { "uldq", emit_uldXu, (PTR) 3,
652 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
654 { "ldgp", emit_ldgp, NULL,
655 { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA } },
657 { "ldi", emit_lda, NULL,
658 { MACRO_IR, MACRO_EXP, MACRO_EOA } },
659 { "ldil", emit_ldil, NULL,
660 { MACRO_IR, MACRO_EXP, MACRO_EOA } },
661 { "ldiq", emit_lda, NULL,
662 { MACRO_IR, MACRO_EXP, MACRO_EOA } },
663 #if 0
664 { "ldif" emit_ldiq, NULL,
665 { MACRO_FPR, MACRO_EXP, MACRO_EOA } },
666 { "ldid" emit_ldiq, NULL,
667 { MACRO_FPR, MACRO_EXP, MACRO_EOA } },
668 { "ldig" emit_ldiq, NULL,
669 { MACRO_FPR, MACRO_EXP, MACRO_EOA } },
670 { "ldis" emit_ldiq, NULL,
671 { MACRO_FPR, MACRO_EXP, MACRO_EOA } },
672 { "ldit" emit_ldiq, NULL,
673 { MACRO_FPR, MACRO_EXP, MACRO_EOA } },
674 #endif
676 { "stl", emit_loadstore, "stl",
677 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
678 { "stl_c", emit_loadstore, "stl_c",
679 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
680 { "stq", emit_loadstore, "stq",
681 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
682 { "stq_c", emit_loadstore, "stq_c",
683 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
684 { "stq_u", emit_loadstore, "stq_u",
685 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
686 { "stf", emit_loadstore, "stf",
687 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
688 { "stg", emit_loadstore, "stg",
689 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
690 { "sts", emit_loadstore, "sts",
691 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
692 { "stt", emit_loadstore, "stt",
693 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
695 { "stb", emit_stX, (PTR) 0,
696 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
697 { "stw", emit_stX, (PTR) 1,
698 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
699 { "ustw", emit_ustX, (PTR) 1,
700 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
701 { "ustl", emit_ustX, (PTR) 2,
702 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
703 { "ustq", emit_ustX, (PTR) 3,
704 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
706 /* Arithmetic macros */
707 #if 0
708 { "absl" emit_absl, 1, { IR } },
709 { "absl" emit_absl, 2, { IR, IR } },
710 { "absl" emit_absl, 2, { EXP, IR } },
711 { "absq" emit_absq, 1, { IR } },
712 { "absq" emit_absq, 2, { IR, IR } },
713 { "absq" emit_absq, 2, { EXP, IR } },
714 #endif
716 { "sextb", emit_sextX, (PTR) 0,
717 { MACRO_IR, MACRO_IR, MACRO_EOA,
718 MACRO_IR, MACRO_EOA,
719 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
720 { "sextw", emit_sextX, (PTR) 1,
721 { MACRO_IR, MACRO_IR, MACRO_EOA,
722 MACRO_IR, MACRO_EOA,
723 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
725 { "divl", emit_division, "__divl",
726 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
727 MACRO_IR, MACRO_IR, MACRO_EOA,
728 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
729 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
730 { "divlu", emit_division, "__divlu",
731 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
732 MACRO_IR, MACRO_IR, MACRO_EOA,
733 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
734 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
735 { "divq", emit_division, "__divq",
736 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
737 MACRO_IR, MACRO_IR, MACRO_EOA,
738 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
739 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
740 { "divqu", emit_division, "__divqu",
741 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
742 MACRO_IR, MACRO_IR, MACRO_EOA,
743 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
744 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
745 { "reml", emit_division, "__reml",
746 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
747 MACRO_IR, MACRO_IR, MACRO_EOA,
748 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
749 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
750 { "remlu", emit_division, "__remlu",
751 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
752 MACRO_IR, MACRO_IR, MACRO_EOA,
753 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
754 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
755 { "remq", emit_division, "__remq",
756 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
757 MACRO_IR, MACRO_IR, MACRO_EOA,
758 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
759 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
760 { "remqu", emit_division, "__remqu",
761 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
762 MACRO_IR, MACRO_IR, MACRO_EOA,
763 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
764 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
766 { "jsr", emit_jsrjmp, "jsr",
767 { MACRO_PIR, MACRO_EXP, MACRO_EOA,
768 MACRO_PIR, MACRO_EOA,
769 MACRO_IR, MACRO_EXP, MACRO_EOA,
770 MACRO_EXP, MACRO_EOA } },
771 { "jmp", emit_jsrjmp, "jmp",
772 { MACRO_PIR, MACRO_EXP, MACRO_EOA,
773 MACRO_PIR, MACRO_EOA,
774 MACRO_IR, MACRO_EXP, MACRO_EOA,
775 MACRO_EXP, MACRO_EOA } },
776 { "ret", emit_retjcr, "ret",
777 { MACRO_IR, MACRO_EXP, MACRO_EOA,
778 MACRO_IR, MACRO_EOA,
779 MACRO_PIR, MACRO_EXP, MACRO_EOA,
780 MACRO_PIR, MACRO_EOA,
781 MACRO_EXP, MACRO_EOA,
782 MACRO_EOA } },
783 { "jcr", emit_retjcr, "jcr",
784 { MACRO_IR, MACRO_EXP, MACRO_EOA,
785 MACRO_IR, MACRO_EOA,
786 MACRO_PIR, MACRO_EXP, MACRO_EOA,
787 MACRO_PIR, MACRO_EOA,
788 MACRO_EXP, MACRO_EOA,
789 MACRO_EOA } },
790 { "jsr_coroutine", emit_retjcr, "jcr",
791 { MACRO_IR, MACRO_EXP, MACRO_EOA,
792 MACRO_IR, MACRO_EOA,
793 MACRO_PIR, MACRO_EXP, MACRO_EOA,
794 MACRO_PIR, MACRO_EOA,
795 MACRO_EXP, MACRO_EOA,
796 MACRO_EOA } },
799 static const unsigned int alpha_num_macros
800 = sizeof (alpha_macros) / sizeof (*alpha_macros);
802 /* Public interface functions */
804 /* This function is called once, at assembler startup time. It sets
805 up all the tables, etc. that the MD part of the assembler will
806 need, that can be determined before arguments are parsed. */
808 void
809 md_begin ()
811 unsigned int i;
813 /* Verify that X_op field is wide enough. */
815 expressionS e;
816 e.X_op = O_max;
817 assert (e.X_op == O_max);
820 /* Create the opcode hash table. */
821 alpha_opcode_hash = hash_new ();
822 for (i = 0; i < alpha_num_opcodes;)
824 const char *name, *retval, *slash;
826 name = alpha_opcodes[i].name;
827 retval = hash_insert (alpha_opcode_hash, name, (PTR) &alpha_opcodes[i]);
828 if (retval)
829 as_fatal (_("internal error: can't hash opcode `%s': %s"),
830 name, retval);
832 /* Some opcodes include modifiers of various sorts with a "/mod"
833 syntax, like the architecture manual suggests. However, for
834 use with gcc at least, we also need access to those same opcodes
835 without the "/". */
837 if ((slash = strchr (name, '/')) != NULL)
839 char *p = xmalloc (strlen (name));
840 memcpy (p, name, slash - name);
841 strcpy (p + (slash - name), slash + 1);
843 (void) hash_insert (alpha_opcode_hash, p, (PTR) &alpha_opcodes[i]);
844 /* Ignore failures -- the opcode table does duplicate some
845 variants in different forms, like "hw_stq" and "hw_st/q". */
848 while (++i < alpha_num_opcodes
849 && (alpha_opcodes[i].name == name
850 || !strcmp (alpha_opcodes[i].name, name)))
851 continue;
854 /* Create the macro hash table. */
855 alpha_macro_hash = hash_new ();
856 for (i = 0; i < alpha_num_macros;)
858 const char *name, *retval;
860 name = alpha_macros[i].name;
861 retval = hash_insert (alpha_macro_hash, name, (PTR) &alpha_macros[i]);
862 if (retval)
863 as_fatal (_("internal error: can't hash macro `%s': %s"),
864 name, retval);
866 while (++i < alpha_num_macros
867 && (alpha_macros[i].name == name
868 || !strcmp (alpha_macros[i].name, name)))
869 continue;
872 /* Construct symbols for each of the registers. */
873 for (i = 0; i < 32; ++i)
875 char name[4];
877 sprintf (name, "$%d", i);
878 alpha_register_table[i] = symbol_create (name, reg_section, i,
879 &zero_address_frag);
881 for (; i < 64; ++i)
883 char name[5];
885 sprintf (name, "$f%d", i - 32);
886 alpha_register_table[i] = symbol_create (name, reg_section, i,
887 &zero_address_frag);
890 /* Create the special symbols and sections we'll be using. */
892 /* So .sbss will get used for tiny objects. */
893 bfd_set_gp_size (stdoutput, g_switch_value);
895 #ifdef OBJ_ECOFF
896 create_literal_section (".lita", &alpha_lita_section, &alpha_lita_symbol);
898 /* For handling the GP, create a symbol that won't be output in the
899 symbol table. We'll edit it out of relocs later. */
900 alpha_gp_symbol = symbol_create ("<GP value>", alpha_lita_section, 0x8000,
901 &zero_address_frag);
902 #endif
904 #ifdef OBJ_EVAX
905 create_literal_section (".link", &alpha_link_section, &alpha_link_symbol);
906 #endif
908 #ifdef OBJ_ELF
909 if (ECOFF_DEBUGGING)
911 segT sec = subseg_new (".mdebug", (subsegT) 0);
912 bfd_set_section_flags (stdoutput, sec, SEC_HAS_CONTENTS | SEC_READONLY);
913 bfd_set_section_alignment (stdoutput, sec, 3);
915 #endif /* OBJ_ELF */
917 /* Create literal lookup hash table. */
918 alpha_literal_hash = hash_new ();
920 subseg_set (text_section, 0);
923 /* The public interface to the instruction assembler. */
925 void
926 md_assemble (str)
927 char *str;
929 char opname[32]; /* Current maximum is 13. */
930 expressionS tok[MAX_INSN_ARGS];
931 int ntok, trunclen;
932 size_t opnamelen;
934 /* Split off the opcode. */
935 opnamelen = strspn (str, "abcdefghijklmnopqrstuvwxyz_/46819");
936 trunclen = (opnamelen < sizeof (opname) - 1
937 ? opnamelen
938 : sizeof (opname) - 1);
939 memcpy (opname, str, trunclen);
940 opname[trunclen] = '\0';
942 /* Tokenize the rest of the line. */
943 if ((ntok = tokenize_arguments (str + opnamelen, tok, MAX_INSN_ARGS)) < 0)
945 if (ntok != TOKENIZE_ERROR_REPORT)
946 as_bad (_("syntax error"));
948 return;
951 /* Finish it off. */
952 assemble_tokens (opname, tok, ntok, alpha_macros_on);
955 /* Round up a section's size to the appropriate boundary. */
957 valueT
958 md_section_align (seg, size)
959 segT seg;
960 valueT size;
962 int align = bfd_get_section_alignment (stdoutput, seg);
963 valueT mask = ((valueT) 1 << align) - 1;
965 return (size + mask) & ~mask;
968 /* Turn a string in input_line_pointer into a floating point constant
969 of type TYPE, and store the appropriate bytes in *LITP. The number
970 of LITTLENUMS emitted is stored in *SIZEP. An error message is
971 returned, or NULL on OK. */
973 /* Equal to MAX_PRECISION in atof-ieee.c. */
974 #define MAX_LITTLENUMS 6
976 extern char *vax_md_atof PARAMS ((int, char *, int *));
978 char *
979 md_atof (type, litP, sizeP)
980 char type;
981 char *litP;
982 int *sizeP;
984 int prec;
985 LITTLENUM_TYPE words[MAX_LITTLENUMS];
986 LITTLENUM_TYPE *wordP;
987 char *t;
989 switch (type)
991 /* VAX floats */
992 case 'G':
993 /* VAX md_atof doesn't like "G" for some reason. */
994 type = 'g';
995 case 'F':
996 case 'D':
997 return vax_md_atof (type, litP, sizeP);
999 /* IEEE floats */
1000 case 'f':
1001 prec = 2;
1002 break;
1004 case 'd':
1005 prec = 4;
1006 break;
1008 case 'x':
1009 case 'X':
1010 prec = 6;
1011 break;
1013 case 'p':
1014 case 'P':
1015 prec = 6;
1016 break;
1018 default:
1019 *sizeP = 0;
1020 return _("Bad call to MD_ATOF()");
1022 t = atof_ieee (input_line_pointer, type, words);
1023 if (t)
1024 input_line_pointer = t;
1025 *sizeP = prec * sizeof (LITTLENUM_TYPE);
1027 for (wordP = words + prec - 1; prec--;)
1029 md_number_to_chars (litP, (long) (*wordP--), sizeof (LITTLENUM_TYPE));
1030 litP += sizeof (LITTLENUM_TYPE);
1033 return 0;
1036 /* Take care of the target-specific command-line options. */
1039 md_parse_option (c, arg)
1040 int c;
1041 char *arg;
1043 switch (c)
1045 case 'F':
1046 alpha_nofloats_on = 1;
1047 break;
1049 case OPTION_32ADDR:
1050 alpha_addr32_on = 1;
1051 break;
1053 case 'g':
1054 alpha_debug = 1;
1055 break;
1057 case 'G':
1058 g_switch_value = atoi (arg);
1059 break;
1061 case 'm':
1063 const struct cpu_type *p;
1064 for (p = cpu_types; p->name; ++p)
1065 if (strcmp (arg, p->name) == 0)
1067 alpha_target_name = p->name, alpha_target = p->flags;
1068 goto found;
1070 as_warn (_("Unknown CPU identifier `%s'"), arg);
1071 found:;
1073 break;
1075 #ifdef OBJ_EVAX
1076 case '+': /* For g++. Hash any name > 63 chars long. */
1077 alpha_flag_hash_long_names = 1;
1078 break;
1080 case 'H': /* Show new symbol after hash truncation */
1081 alpha_flag_show_after_trunc = 1;
1082 break;
1084 case 'h': /* for gnu-c/vax compatibility. */
1085 break;
1086 #endif
1088 case OPTION_RELAX:
1089 alpha_flag_relax = 1;
1090 break;
1092 #ifdef OBJ_ELF
1093 case OPTION_MDEBUG:
1094 alpha_flag_mdebug = 1;
1095 break;
1096 case OPTION_NO_MDEBUG:
1097 alpha_flag_mdebug = 0;
1098 break;
1099 #endif
1101 default:
1102 return 0;
1105 return 1;
1108 /* Print a description of the command-line options that we accept. */
1110 void
1111 md_show_usage (stream)
1112 FILE *stream;
1114 fputs (_("\
1115 Alpha options:\n\
1116 -32addr treat addresses as 32-bit values\n\
1117 -F lack floating point instructions support\n\
1118 -mev4 | -mev45 | -mev5 | -mev56 | -mpca56 | -mev6 | -mev67 | -mev68 | -mall\n\
1119 specify variant of Alpha architecture\n\
1120 -m21064 | -m21066 | -m21164 | -m21164a | -m21164pc | -m21264 | -m21264a | -m21264b\n\
1121 these variants include PALcode opcodes\n"),
1122 stream);
1123 #ifdef OBJ_EVAX
1124 fputs (_("\
1125 VMS options:\n\
1126 -+ hash encode (don't truncate) names longer than 64 characters\n\
1127 -H show new symbol after hash truncation\n"),
1128 stream);
1129 #endif
1132 /* Decide from what point a pc-relative relocation is relative to,
1133 relative to the pc-relative fixup. Er, relatively speaking. */
1135 long
1136 md_pcrel_from (fixP)
1137 fixS *fixP;
1139 valueT addr = fixP->fx_where + fixP->fx_frag->fr_address;
1140 switch (fixP->fx_r_type)
1142 case BFD_RELOC_23_PCREL_S2:
1143 case BFD_RELOC_ALPHA_HINT:
1144 case BFD_RELOC_ALPHA_BRSGP:
1145 return addr + 4;
1146 default:
1147 return addr;
1151 /* Attempt to simplify or even eliminate a fixup. The return value is
1152 ignored; perhaps it was once meaningful, but now it is historical.
1153 To indicate that a fixup has been eliminated, set fixP->fx_done.
1155 For ELF, here it is that we transform the GPDISP_HI16 reloc we used
1156 internally into the GPDISP reloc used externally. We had to do
1157 this so that we'd have the GPDISP_LO16 reloc as a tag to compute
1158 the distance to the "lda" instruction for setting the addend to
1159 GPDISP. */
1161 void
1162 md_apply_fix3 (fixP, valP, seg)
1163 fixS *fixP;
1164 valueT * valP;
1165 segT seg;
1167 char * const fixpos = fixP->fx_frag->fr_literal + fixP->fx_where;
1168 valueT value = * valP;
1169 unsigned image, size;
1171 switch (fixP->fx_r_type)
1173 /* The GPDISP relocations are processed internally with a symbol
1174 referring to the current function's section; we need to drop
1175 in a value which, when added to the address of the start of
1176 the function, gives the desired GP. */
1177 case BFD_RELOC_ALPHA_GPDISP_HI16:
1179 fixS *next = fixP->fx_next;
1181 /* With user-specified !gpdisp relocations, we can be missing
1182 the matching LO16 reloc. We will have already issued an
1183 error message. */
1184 if (next)
1185 fixP->fx_offset = (next->fx_frag->fr_address + next->fx_where
1186 - fixP->fx_frag->fr_address - fixP->fx_where);
1188 value = (value - sign_extend_16 (value)) >> 16;
1190 #ifdef OBJ_ELF
1191 fixP->fx_r_type = BFD_RELOC_ALPHA_GPDISP;
1192 #endif
1193 goto do_reloc_gp;
1195 case BFD_RELOC_ALPHA_GPDISP_LO16:
1196 value = sign_extend_16 (value);
1197 fixP->fx_offset = 0;
1198 #ifdef OBJ_ELF
1199 fixP->fx_done = 1;
1200 #endif
1202 do_reloc_gp:
1203 fixP->fx_addsy = section_symbol (seg);
1204 md_number_to_chars (fixpos, value, 2);
1205 break;
1207 case BFD_RELOC_16:
1208 if (fixP->fx_pcrel)
1209 fixP->fx_r_type = BFD_RELOC_16_PCREL;
1210 size = 2;
1211 goto do_reloc_xx;
1212 case BFD_RELOC_32:
1213 if (fixP->fx_pcrel)
1214 fixP->fx_r_type = BFD_RELOC_32_PCREL;
1215 size = 4;
1216 goto do_reloc_xx;
1217 case BFD_RELOC_64:
1218 if (fixP->fx_pcrel)
1219 fixP->fx_r_type = BFD_RELOC_64_PCREL;
1220 size = 8;
1221 do_reloc_xx:
1222 if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0)
1224 md_number_to_chars (fixpos, value, size);
1225 goto done;
1227 return;
1229 #ifdef OBJ_ECOFF
1230 case BFD_RELOC_GPREL32:
1231 assert (fixP->fx_subsy == alpha_gp_symbol);
1232 fixP->fx_subsy = 0;
1233 /* FIXME: inherited this obliviousness of `value' -- why? */
1234 md_number_to_chars (fixpos, -alpha_gp_value, 4);
1235 break;
1236 #else
1237 case BFD_RELOC_GPREL32:
1238 #endif
1239 case BFD_RELOC_GPREL16:
1240 case BFD_RELOC_ALPHA_GPREL_HI16:
1241 case BFD_RELOC_ALPHA_GPREL_LO16:
1242 return;
1244 case BFD_RELOC_23_PCREL_S2:
1245 if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0)
1247 image = bfd_getl32 (fixpos);
1248 image = (image & ~0x1FFFFF) | ((value >> 2) & 0x1FFFFF);
1249 goto write_done;
1251 return;
1253 case BFD_RELOC_ALPHA_HINT:
1254 if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0)
1256 image = bfd_getl32 (fixpos);
1257 image = (image & ~0x3FFF) | ((value >> 2) & 0x3FFF);
1258 goto write_done;
1260 return;
1262 #ifdef OBJ_ELF
1263 case BFD_RELOC_ALPHA_BRSGP:
1264 return;
1266 case BFD_RELOC_ALPHA_TLSGD:
1267 case BFD_RELOC_ALPHA_TLSLDM:
1268 case BFD_RELOC_ALPHA_GOTDTPREL16:
1269 case BFD_RELOC_ALPHA_DTPREL_HI16:
1270 case BFD_RELOC_ALPHA_DTPREL_LO16:
1271 case BFD_RELOC_ALPHA_DTPREL16:
1272 case BFD_RELOC_ALPHA_GOTTPREL16:
1273 case BFD_RELOC_ALPHA_TPREL_HI16:
1274 case BFD_RELOC_ALPHA_TPREL_LO16:
1275 case BFD_RELOC_ALPHA_TPREL16:
1276 if (fixP->fx_addsy)
1277 S_SET_THREAD_LOCAL (fixP->fx_addsy);
1278 return;
1279 #endif
1281 #ifdef OBJ_ECOFF
1282 case BFD_RELOC_ALPHA_LITERAL:
1283 md_number_to_chars (fixpos, value, 2);
1284 return;
1285 #endif
1286 case BFD_RELOC_ALPHA_ELF_LITERAL:
1287 case BFD_RELOC_ALPHA_LITUSE:
1288 case BFD_RELOC_ALPHA_LINKAGE:
1289 case BFD_RELOC_ALPHA_CODEADDR:
1290 return;
1292 case BFD_RELOC_VTABLE_INHERIT:
1293 case BFD_RELOC_VTABLE_ENTRY:
1294 return;
1296 default:
1298 const struct alpha_operand *operand;
1300 if ((int) fixP->fx_r_type >= 0)
1301 as_fatal (_("unhandled relocation type %s"),
1302 bfd_get_reloc_code_name (fixP->fx_r_type));
1304 assert (-(int) fixP->fx_r_type < (int) alpha_num_operands);
1305 operand = &alpha_operands[-(int) fixP->fx_r_type];
1307 /* The rest of these fixups only exist internally during symbol
1308 resolution and have no representation in the object file.
1309 Therefore they must be completely resolved as constants. */
1311 if (fixP->fx_addsy != 0
1312 && S_GET_SEGMENT (fixP->fx_addsy) != absolute_section)
1313 as_bad_where (fixP->fx_file, fixP->fx_line,
1314 _("non-absolute expression in constant field"));
1316 image = bfd_getl32 (fixpos);
1317 image = insert_operand (image, operand, (offsetT) value,
1318 fixP->fx_file, fixP->fx_line);
1320 goto write_done;
1323 if (fixP->fx_addsy != 0 || fixP->fx_pcrel != 0)
1324 return;
1325 else
1327 as_warn_where (fixP->fx_file, fixP->fx_line,
1328 _("type %d reloc done?\n"), (int) fixP->fx_r_type);
1329 goto done;
1332 write_done:
1333 md_number_to_chars (fixpos, image, 4);
1335 done:
1336 fixP->fx_done = 1;
1339 /* Look for a register name in the given symbol. */
1341 symbolS *
1342 md_undefined_symbol (name)
1343 char *name;
1345 if (*name == '$')
1347 int is_float = 0, num;
1349 switch (*++name)
1351 case 'f':
1352 if (name[1] == 'p' && name[2] == '\0')
1353 return alpha_register_table[AXP_REG_FP];
1354 is_float = 32;
1355 /* FALLTHRU */
1357 case 'r':
1358 if (!ISDIGIT (*++name))
1359 break;
1360 /* FALLTHRU */
1362 case '0': case '1': case '2': case '3': case '4':
1363 case '5': case '6': case '7': case '8': case '9':
1364 if (name[1] == '\0')
1365 num = name[0] - '0';
1366 else if (name[0] != '0' && ISDIGIT (name[1]) && name[2] == '\0')
1368 num = (name[0] - '0') * 10 + name[1] - '0';
1369 if (num >= 32)
1370 break;
1372 else
1373 break;
1375 if (!alpha_noat_on && (num + is_float) == AXP_REG_AT)
1376 as_warn (_("Used $at without \".set noat\""));
1377 return alpha_register_table[num + is_float];
1379 case 'a':
1380 if (name[1] == 't' && name[2] == '\0')
1382 if (!alpha_noat_on)
1383 as_warn (_("Used $at without \".set noat\""));
1384 return alpha_register_table[AXP_REG_AT];
1386 break;
1388 case 'g':
1389 if (name[1] == 'p' && name[2] == '\0')
1390 return alpha_register_table[alpha_gp_register];
1391 break;
1393 case 's':
1394 if (name[1] == 'p' && name[2] == '\0')
1395 return alpha_register_table[AXP_REG_SP];
1396 break;
1399 return NULL;
1402 #ifdef OBJ_ECOFF
1403 /* @@@ Magic ECOFF bits. */
1405 void
1406 alpha_frob_ecoff_data ()
1408 select_gp_value ();
1409 /* $zero and $f31 are read-only */
1410 alpha_gprmask &= ~1;
1411 alpha_fprmask &= ~1;
1413 #endif
1415 /* Hook to remember a recently defined label so that the auto-align
1416 code can adjust the symbol after we know what alignment will be
1417 required. */
1419 void
1420 alpha_define_label (sym)
1421 symbolS *sym;
1423 alpha_insn_label = sym;
1426 /* Return true if we must always emit a reloc for a type and false if
1427 there is some hope of resolving it at assembly time. */
1430 alpha_force_relocation (f)
1431 fixS *f;
1433 if (alpha_flag_relax)
1434 return 1;
1436 switch (f->fx_r_type)
1438 case BFD_RELOC_ALPHA_GPDISP_HI16:
1439 case BFD_RELOC_ALPHA_GPDISP_LO16:
1440 case BFD_RELOC_ALPHA_GPDISP:
1441 case BFD_RELOC_ALPHA_LITERAL:
1442 case BFD_RELOC_ALPHA_ELF_LITERAL:
1443 case BFD_RELOC_ALPHA_LITUSE:
1444 case BFD_RELOC_GPREL16:
1445 case BFD_RELOC_GPREL32:
1446 case BFD_RELOC_ALPHA_GPREL_HI16:
1447 case BFD_RELOC_ALPHA_GPREL_LO16:
1448 case BFD_RELOC_ALPHA_LINKAGE:
1449 case BFD_RELOC_ALPHA_CODEADDR:
1450 case BFD_RELOC_ALPHA_BRSGP:
1451 case BFD_RELOC_ALPHA_TLSGD:
1452 case BFD_RELOC_ALPHA_TLSLDM:
1453 case BFD_RELOC_ALPHA_GOTDTPREL16:
1454 case BFD_RELOC_ALPHA_DTPREL_HI16:
1455 case BFD_RELOC_ALPHA_DTPREL_LO16:
1456 case BFD_RELOC_ALPHA_DTPREL16:
1457 case BFD_RELOC_ALPHA_GOTTPREL16:
1458 case BFD_RELOC_ALPHA_TPREL_HI16:
1459 case BFD_RELOC_ALPHA_TPREL_LO16:
1460 case BFD_RELOC_ALPHA_TPREL16:
1461 return 1;
1463 default:
1464 break;
1467 return generic_force_reloc (f);
1470 /* Return true if we can partially resolve a relocation now. */
1473 alpha_fix_adjustable (f)
1474 fixS *f;
1476 /* Are there any relocation types for which we must generate a reloc
1477 but we can adjust the values contained within it? */
1478 switch (f->fx_r_type)
1480 case BFD_RELOC_ALPHA_GPDISP_HI16:
1481 case BFD_RELOC_ALPHA_GPDISP_LO16:
1482 case BFD_RELOC_ALPHA_GPDISP:
1483 return 0;
1485 case BFD_RELOC_ALPHA_LITERAL:
1486 case BFD_RELOC_ALPHA_ELF_LITERAL:
1487 case BFD_RELOC_ALPHA_LITUSE:
1488 case BFD_RELOC_ALPHA_LINKAGE:
1489 case BFD_RELOC_ALPHA_CODEADDR:
1490 return 1;
1492 case BFD_RELOC_VTABLE_ENTRY:
1493 case BFD_RELOC_VTABLE_INHERIT:
1494 return 0;
1496 case BFD_RELOC_GPREL16:
1497 case BFD_RELOC_GPREL32:
1498 case BFD_RELOC_ALPHA_GPREL_HI16:
1499 case BFD_RELOC_ALPHA_GPREL_LO16:
1500 case BFD_RELOC_23_PCREL_S2:
1501 case BFD_RELOC_32:
1502 case BFD_RELOC_64:
1503 case BFD_RELOC_ALPHA_HINT:
1504 return 1;
1506 case BFD_RELOC_ALPHA_TLSGD:
1507 case BFD_RELOC_ALPHA_TLSLDM:
1508 case BFD_RELOC_ALPHA_GOTDTPREL16:
1509 case BFD_RELOC_ALPHA_DTPREL_HI16:
1510 case BFD_RELOC_ALPHA_DTPREL_LO16:
1511 case BFD_RELOC_ALPHA_DTPREL16:
1512 case BFD_RELOC_ALPHA_GOTTPREL16:
1513 case BFD_RELOC_ALPHA_TPREL_HI16:
1514 case BFD_RELOC_ALPHA_TPREL_LO16:
1515 case BFD_RELOC_ALPHA_TPREL16:
1516 /* ??? No idea why we can't return a reference to .tbss+10, but
1517 we're preventing this in the other assemblers. Follow for now. */
1518 return 0;
1520 #ifdef OBJ_ELF
1521 case BFD_RELOC_ALPHA_BRSGP:
1522 /* If we have a BRSGP reloc to a local symbol, adjust it to BRADDR and
1523 let it get resolved at assembly time. */
1525 symbolS *sym = f->fx_addsy;
1526 const char *name;
1527 int offset = 0;
1529 if (generic_force_reloc (f))
1530 return 0;
1532 switch (S_GET_OTHER (sym) & STO_ALPHA_STD_GPLOAD)
1534 case STO_ALPHA_NOPV:
1535 break;
1536 case STO_ALPHA_STD_GPLOAD:
1537 offset = 8;
1538 break;
1539 default:
1540 if (S_IS_LOCAL (sym))
1541 name = "<local>";
1542 else
1543 name = S_GET_NAME (sym);
1544 as_bad_where (f->fx_file, f->fx_line,
1545 _("!samegp reloc against symbol without .prologue: %s"),
1546 name);
1547 break;
1549 f->fx_r_type = BFD_RELOC_23_PCREL_S2;
1550 f->fx_offset += offset;
1551 return 1;
1553 #endif
1555 default:
1556 return 1;
1558 /*NOTREACHED*/
1561 /* Generate the BFD reloc to be stuck in the object file from the
1562 fixup used internally in the assembler. */
1564 arelent *
1565 tc_gen_reloc (sec, fixp)
1566 asection *sec ATTRIBUTE_UNUSED;
1567 fixS *fixp;
1569 arelent *reloc;
1571 reloc = (arelent *) xmalloc (sizeof (arelent));
1572 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
1573 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
1574 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
1576 /* Make sure none of our internal relocations make it this far.
1577 They'd better have been fully resolved by this point. */
1578 assert ((int) fixp->fx_r_type > 0);
1580 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
1581 if (reloc->howto == NULL)
1583 as_bad_where (fixp->fx_file, fixp->fx_line,
1584 _("cannot represent `%s' relocation in object file"),
1585 bfd_get_reloc_code_name (fixp->fx_r_type));
1586 return NULL;
1589 if (!fixp->fx_pcrel != !reloc->howto->pc_relative)
1591 as_fatal (_("internal error? cannot generate `%s' relocation"),
1592 bfd_get_reloc_code_name (fixp->fx_r_type));
1594 assert (!fixp->fx_pcrel == !reloc->howto->pc_relative);
1596 #ifdef OBJ_ECOFF
1597 if (fixp->fx_r_type == BFD_RELOC_ALPHA_LITERAL)
1599 /* Fake out bfd_perform_relocation. sigh. */
1600 reloc->addend = -alpha_gp_value;
1602 else
1603 #endif
1605 reloc->addend = fixp->fx_offset;
1606 #ifdef OBJ_ELF
1607 /* Ohhh, this is ugly. The problem is that if this is a local global
1608 symbol, the relocation will entirely be performed at link time, not
1609 at assembly time. bfd_perform_reloc doesn't know about this sort
1610 of thing, and as a result we need to fake it out here. */
1611 if ((S_IS_EXTERN (fixp->fx_addsy) || S_IS_WEAK (fixp->fx_addsy)
1612 || (S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_MERGE)
1613 || (S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_THREAD_LOCAL))
1614 && !S_IS_COMMON (fixp->fx_addsy))
1615 reloc->addend -= symbol_get_bfdsym (fixp->fx_addsy)->value;
1616 #endif
1619 return reloc;
1622 /* Parse a register name off of the input_line and return a register
1623 number. Gets md_undefined_symbol above to do the register name
1624 matching for us.
1626 Only called as a part of processing the ECOFF .frame directive. */
1629 tc_get_register (frame)
1630 int frame ATTRIBUTE_UNUSED;
1632 int framereg = AXP_REG_SP;
1634 SKIP_WHITESPACE ();
1635 if (*input_line_pointer == '$')
1637 char *s = input_line_pointer;
1638 char c = get_symbol_end ();
1639 symbolS *sym = md_undefined_symbol (s);
1641 *strchr (s, '\0') = c;
1642 if (sym && (framereg = S_GET_VALUE (sym)) <= 31)
1643 goto found;
1645 as_warn (_("frame reg expected, using $%d."), framereg);
1647 found:
1648 note_gpreg (framereg);
1649 return framereg;
1652 /* This is called before the symbol table is processed. In order to
1653 work with gcc when using mips-tfile, we must keep all local labels.
1654 However, in other cases, we want to discard them. If we were
1655 called with -g, but we didn't see any debugging information, it may
1656 mean that gcc is smuggling debugging information through to
1657 mips-tfile, in which case we must generate all local labels. */
1659 #ifdef OBJ_ECOFF
1661 void
1662 alpha_frob_file_before_adjust ()
1664 if (alpha_debug != 0
1665 && ! ecoff_debugging_seen)
1666 flag_keep_locals = 1;
1669 #endif /* OBJ_ECOFF */
1671 static struct alpha_reloc_tag *
1672 get_alpha_reloc_tag (sequence)
1673 long sequence;
1675 char buffer[ALPHA_RELOC_DIGITS];
1676 struct alpha_reloc_tag *info;
1678 sprintf (buffer, "!%ld", sequence);
1680 info = (struct alpha_reloc_tag *) hash_find (alpha_literal_hash, buffer);
1681 if (! info)
1683 size_t len = strlen (buffer);
1684 const char *errmsg;
1686 info = (struct alpha_reloc_tag *)
1687 xcalloc (sizeof (struct alpha_reloc_tag) + len, 1);
1689 info->segment = now_seg;
1690 info->sequence = sequence;
1691 strcpy (info->string, buffer);
1692 errmsg = hash_insert (alpha_literal_hash, info->string, (PTR) info);
1693 if (errmsg)
1694 as_fatal (errmsg);
1697 return info;
1700 /* Before the relocations are written, reorder them, so that user
1701 supplied !lituse relocations follow the appropriate !literal
1702 relocations, and similarly for !gpdisp relocations. */
1704 void
1705 alpha_before_fix ()
1707 if (alpha_literal_hash)
1708 bfd_map_over_sections (stdoutput, alpha_adjust_relocs, NULL);
1711 static void
1712 alpha_adjust_relocs (abfd, sec, ptr)
1713 bfd *abfd ATTRIBUTE_UNUSED;
1714 asection *sec;
1715 PTR ptr ATTRIBUTE_UNUSED;
1717 segment_info_type *seginfo = seg_info (sec);
1718 fixS **prevP;
1719 fixS *fixp;
1720 fixS *next;
1721 fixS *slave;
1723 /* If seginfo is NULL, we did not create this section; don't do
1724 anything with it. By using a pointer to a pointer, we can update
1725 the links in place. */
1726 if (seginfo == NULL)
1727 return;
1729 /* If there are no relocations, skip the section. */
1730 if (! seginfo->fix_root)
1731 return;
1733 /* First rebuild the fixup chain without the expicit lituse and
1734 gpdisp_lo16 relocs. */
1735 prevP = &seginfo->fix_root;
1736 for (fixp = seginfo->fix_root; fixp; fixp = next)
1738 next = fixp->fx_next;
1739 fixp->fx_next = (fixS *) 0;
1741 switch (fixp->fx_r_type)
1743 case BFD_RELOC_ALPHA_LITUSE:
1744 if (fixp->tc_fix_data.info->n_master == 0)
1745 as_bad_where (fixp->fx_file, fixp->fx_line,
1746 _("No !literal!%ld was found"),
1747 fixp->tc_fix_data.info->sequence);
1748 #ifdef RELOC_OP_P
1749 if (fixp->fx_offset == LITUSE_ALPHA_TLSGD)
1751 if (! fixp->tc_fix_data.info->saw_tlsgd)
1752 as_bad_where (fixp->fx_file, fixp->fx_line,
1753 _("No !tlsgd!%ld was found"),
1754 fixp->tc_fix_data.info->sequence);
1756 else if (fixp->fx_offset == LITUSE_ALPHA_TLSLDM)
1758 if (! fixp->tc_fix_data.info->saw_tlsldm)
1759 as_bad_where (fixp->fx_file, fixp->fx_line,
1760 _("No !tlsldm!%ld was found"),
1761 fixp->tc_fix_data.info->sequence);
1763 #endif
1764 break;
1766 case BFD_RELOC_ALPHA_GPDISP_LO16:
1767 if (fixp->tc_fix_data.info->n_master == 0)
1768 as_bad_where (fixp->fx_file, fixp->fx_line,
1769 _("No ldah !gpdisp!%ld was found"),
1770 fixp->tc_fix_data.info->sequence);
1771 break;
1773 case BFD_RELOC_ALPHA_ELF_LITERAL:
1774 if (fixp->tc_fix_data.info
1775 && (fixp->tc_fix_data.info->saw_tlsgd
1776 || fixp->tc_fix_data.info->saw_tlsldm))
1777 break;
1778 /* FALLTHRU */
1780 default:
1781 *prevP = fixp;
1782 prevP = &fixp->fx_next;
1783 break;
1787 /* Go back and re-chain dependent relocations. They are currently
1788 linked through the next_reloc field in reverse order, so as we
1789 go through the next_reloc chain, we effectively reverse the chain
1790 once again.
1792 Except if there is more than one !literal for a given sequence
1793 number. In that case, the programmer and/or compiler is not sure
1794 how control flows from literal to lituse, and we can't be sure to
1795 get the relaxation correct.
1797 ??? Well, actually we could, if there are enough lituses such that
1798 we can make each literal have at least one of each lituse type
1799 present. Not implemented.
1801 Also suppress the optimization if the !literals/!lituses are spread
1802 in different segments. This can happen with "intersting" uses of
1803 inline assembly; examples are present in the Linux kernel semaphores. */
1805 for (fixp = seginfo->fix_root; fixp; fixp = next)
1807 next = fixp->fx_next;
1808 switch (fixp->fx_r_type)
1810 case BFD_RELOC_ALPHA_TLSGD:
1811 case BFD_RELOC_ALPHA_TLSLDM:
1812 if (!fixp->tc_fix_data.info)
1813 break;
1814 if (fixp->tc_fix_data.info->n_master == 0)
1815 break;
1816 else if (fixp->tc_fix_data.info->n_master > 1)
1818 as_bad_where (fixp->fx_file, fixp->fx_line,
1819 _("too many !literal!%ld for %s"),
1820 fixp->tc_fix_data.info->sequence,
1821 (fixp->fx_r_type == BFD_RELOC_ALPHA_TLSGD
1822 ? "!tlsgd" : "!tlsldm"));
1823 break;
1826 fixp->tc_fix_data.info->master->fx_next = fixp->fx_next;
1827 fixp->fx_next = fixp->tc_fix_data.info->master;
1828 fixp = fixp->fx_next;
1829 /* FALLTHRU */
1831 case BFD_RELOC_ALPHA_ELF_LITERAL:
1832 if (fixp->tc_fix_data.info
1833 && fixp->tc_fix_data.info->n_master == 1
1834 && ! fixp->tc_fix_data.info->multi_section_p)
1836 for (slave = fixp->tc_fix_data.info->slaves;
1837 slave != (fixS *) 0;
1838 slave = slave->tc_fix_data.next_reloc)
1840 slave->fx_next = fixp->fx_next;
1841 fixp->fx_next = slave;
1844 break;
1846 case BFD_RELOC_ALPHA_GPDISP_HI16:
1847 if (fixp->tc_fix_data.info->n_slaves == 0)
1848 as_bad_where (fixp->fx_file, fixp->fx_line,
1849 _("No lda !gpdisp!%ld was found"),
1850 fixp->tc_fix_data.info->sequence);
1851 else
1853 slave = fixp->tc_fix_data.info->slaves;
1854 slave->fx_next = next;
1855 fixp->fx_next = slave;
1857 break;
1859 default:
1860 break;
1865 #ifdef DEBUG_ALPHA
1866 static void
1867 debug_exp (tok, ntok)
1868 expressionS tok[];
1869 int ntok;
1871 int i;
1873 fprintf (stderr, "debug_exp: %d tokens", ntok);
1874 for (i = 0; i < ntok; i++)
1876 expressionS *t = &tok[i];
1877 const char *name;
1879 switch (t->X_op)
1881 default: name = "unknown"; break;
1882 case O_illegal: name = "O_illegal"; break;
1883 case O_absent: name = "O_absent"; break;
1884 case O_constant: name = "O_constant"; break;
1885 case O_symbol: name = "O_symbol"; break;
1886 case O_symbol_rva: name = "O_symbol_rva"; break;
1887 case O_register: name = "O_register"; break;
1888 case O_big: name = "O_big"; break;
1889 case O_uminus: name = "O_uminus"; break;
1890 case O_bit_not: name = "O_bit_not"; break;
1891 case O_logical_not: name = "O_logical_not"; break;
1892 case O_multiply: name = "O_multiply"; break;
1893 case O_divide: name = "O_divide"; break;
1894 case O_modulus: name = "O_modulus"; break;
1895 case O_left_shift: name = "O_left_shift"; break;
1896 case O_right_shift: name = "O_right_shift"; break;
1897 case O_bit_inclusive_or: name = "O_bit_inclusive_or"; break;
1898 case O_bit_or_not: name = "O_bit_or_not"; break;
1899 case O_bit_exclusive_or: name = "O_bit_exclusive_or"; break;
1900 case O_bit_and: name = "O_bit_and"; break;
1901 case O_add: name = "O_add"; break;
1902 case O_subtract: name = "O_subtract"; break;
1903 case O_eq: name = "O_eq"; break;
1904 case O_ne: name = "O_ne"; break;
1905 case O_lt: name = "O_lt"; break;
1906 case O_le: name = "O_le"; break;
1907 case O_ge: name = "O_ge"; break;
1908 case O_gt: name = "O_gt"; break;
1909 case O_logical_and: name = "O_logical_and"; break;
1910 case O_logical_or: name = "O_logical_or"; break;
1911 case O_index: name = "O_index"; break;
1912 case O_pregister: name = "O_pregister"; break;
1913 case O_cpregister: name = "O_cpregister"; break;
1914 case O_literal: name = "O_literal"; break;
1915 case O_lituse_addr: name = "O_lituse_addr"; break;
1916 case O_lituse_base: name = "O_lituse_base"; break;
1917 case O_lituse_bytoff: name = "O_lituse_bytoff"; break;
1918 case O_lituse_jsr: name = "O_lituse_jsr"; break;
1919 case O_lituse_tlsgd: name = "O_lituse_tlsgd"; break;
1920 case O_lituse_tlsldm: name = "O_lituse_tlsldm"; break;
1921 case O_gpdisp: name = "O_gpdisp"; break;
1922 case O_gprelhigh: name = "O_gprelhigh"; break;
1923 case O_gprellow: name = "O_gprellow"; break;
1924 case O_gprel: name = "O_gprel"; break;
1925 case O_samegp: name = "O_samegp"; break;
1926 case O_tlsgd: name = "O_tlsgd"; break;
1927 case O_tlsldm: name = "O_tlsldm"; break;
1928 case O_gotdtprel: name = "O_gotdtprel"; break;
1929 case O_dtprelhi: name = "O_dtprelhi"; break;
1930 case O_dtprello: name = "O_dtprello"; break;
1931 case O_dtprel: name = "O_dtprel"; break;
1932 case O_gottprel: name = "O_gottprel"; break;
1933 case O_tprelhi: name = "O_tprelhi"; break;
1934 case O_tprello: name = "O_tprello"; break;
1935 case O_tprel: name = "O_tprel"; break;
1938 fprintf (stderr, ", %s(%s, %s, %d)", name,
1939 (t->X_add_symbol) ? S_GET_NAME (t->X_add_symbol) : "--",
1940 (t->X_op_symbol) ? S_GET_NAME (t->X_op_symbol) : "--",
1941 (int) t->X_add_number);
1943 fprintf (stderr, "\n");
1944 fflush (stderr);
1946 #endif
1948 /* Parse the arguments to an opcode. */
1950 static int
1951 tokenize_arguments (str, tok, ntok)
1952 char *str;
1953 expressionS tok[];
1954 int ntok;
1956 expressionS *end_tok = tok + ntok;
1957 char *old_input_line_pointer;
1958 int saw_comma = 0, saw_arg = 0;
1959 #ifdef DEBUG_ALPHA
1960 expressionS *orig_tok = tok;
1961 #endif
1962 #ifdef RELOC_OP_P
1963 char *p;
1964 const struct alpha_reloc_op_tag *r;
1965 int c, i;
1966 size_t len;
1967 int reloc_found_p = 0;
1968 #endif
1970 memset (tok, 0, sizeof (*tok) * ntok);
1972 /* Save and restore input_line_pointer around this function. */
1973 old_input_line_pointer = input_line_pointer;
1974 input_line_pointer = str;
1976 #ifdef RELOC_OP_P
1977 /* ??? Wrest control of ! away from the regular expression parser. */
1978 is_end_of_line[(unsigned char) '!'] = 1;
1979 #endif
1981 while (tok < end_tok && *input_line_pointer)
1983 SKIP_WHITESPACE ();
1984 switch (*input_line_pointer)
1986 case '\0':
1987 goto fini;
1989 #ifdef RELOC_OP_P
1990 case '!':
1991 /* A relocation operand can be placed after the normal operand on an
1992 assembly language statement, and has the following form:
1993 !relocation_type!sequence_number. */
1994 if (reloc_found_p)
1996 /* Only support one relocation op per insn. */
1997 as_bad (_("More than one relocation op per insn"));
1998 goto err_report;
2001 if (!saw_arg)
2002 goto err;
2004 ++input_line_pointer;
2005 SKIP_WHITESPACE ();
2006 p = input_line_pointer;
2007 c = get_symbol_end ();
2009 /* Parse !relocation_type. */
2010 len = input_line_pointer - p;
2011 if (len == 0)
2013 as_bad (_("No relocation operand"));
2014 goto err_report;
2017 r = &alpha_reloc_op[0];
2018 for (i = alpha_num_reloc_op - 1; i >= 0; i--, r++)
2019 if (len == r->length && memcmp (p, r->name, len) == 0)
2020 break;
2021 if (i < 0)
2023 as_bad (_("Unknown relocation operand: !%s"), p);
2024 goto err_report;
2027 *input_line_pointer = c;
2028 SKIP_WHITESPACE ();
2029 if (*input_line_pointer != '!')
2031 if (r->require_seq)
2033 as_bad (_("no sequence number after !%s"), p);
2034 goto err_report;
2037 tok->X_add_number = 0;
2039 else
2041 if (! r->allow_seq)
2043 as_bad (_("!%s does not use a sequence number"), p);
2044 goto err_report;
2047 input_line_pointer++;
2049 /* Parse !sequence_number. */
2050 expression (tok);
2051 if (tok->X_op != O_constant || tok->X_add_number <= 0)
2053 as_bad (_("Bad sequence number: !%s!%s"),
2054 r->name, input_line_pointer);
2055 goto err_report;
2059 tok->X_op = r->op;
2060 reloc_found_p = 1;
2061 ++tok;
2062 break;
2063 #endif /* RELOC_OP_P */
2065 case ',':
2066 ++input_line_pointer;
2067 if (saw_comma || !saw_arg)
2068 goto err;
2069 saw_comma = 1;
2070 break;
2072 case '(':
2074 char *hold = input_line_pointer++;
2076 /* First try for parenthesized register ... */
2077 expression (tok);
2078 if (*input_line_pointer == ')' && tok->X_op == O_register)
2080 tok->X_op = (saw_comma ? O_cpregister : O_pregister);
2081 saw_comma = 0;
2082 saw_arg = 1;
2083 ++input_line_pointer;
2084 ++tok;
2085 break;
2088 /* ... then fall through to plain expression. */
2089 input_line_pointer = hold;
2092 default:
2093 if (saw_arg && !saw_comma)
2094 goto err;
2096 expression (tok);
2097 if (tok->X_op == O_illegal || tok->X_op == O_absent)
2098 goto err;
2100 saw_comma = 0;
2101 saw_arg = 1;
2102 ++tok;
2103 break;
2107 fini:
2108 if (saw_comma)
2109 goto err;
2110 input_line_pointer = old_input_line_pointer;
2112 #ifdef DEBUG_ALPHA
2113 debug_exp (orig_tok, ntok - (end_tok - tok));
2114 #endif
2115 #ifdef RELOC_OP_P
2116 is_end_of_line[(unsigned char) '!'] = 0;
2117 #endif
2119 return ntok - (end_tok - tok);
2121 err:
2122 #ifdef RELOC_OP_P
2123 is_end_of_line[(unsigned char) '!'] = 0;
2124 #endif
2125 input_line_pointer = old_input_line_pointer;
2126 return TOKENIZE_ERROR;
2128 #ifdef RELOC_OP_P
2129 err_report:
2130 is_end_of_line[(unsigned char) '!'] = 0;
2131 #endif
2132 input_line_pointer = old_input_line_pointer;
2133 return TOKENIZE_ERROR_REPORT;
2136 /* Search forward through all variants of an opcode looking for a
2137 syntax match. */
2139 static const struct alpha_opcode *
2140 find_opcode_match (first_opcode, tok, pntok, pcpumatch)
2141 const struct alpha_opcode *first_opcode;
2142 const expressionS *tok;
2143 int *pntok;
2144 int *pcpumatch;
2146 const struct alpha_opcode *opcode = first_opcode;
2147 int ntok = *pntok;
2148 int got_cpu_match = 0;
2152 const unsigned char *opidx;
2153 int tokidx = 0;
2155 /* Don't match opcodes that don't exist on this architecture. */
2156 if (!(opcode->flags & alpha_target))
2157 goto match_failed;
2159 got_cpu_match = 1;
2161 for (opidx = opcode->operands; *opidx; ++opidx)
2163 const struct alpha_operand *operand = &alpha_operands[*opidx];
2165 /* Only take input from real operands. */
2166 if (operand->flags & AXP_OPERAND_FAKE)
2167 continue;
2169 /* When we expect input, make sure we have it. */
2170 if (tokidx >= ntok)
2172 if ((operand->flags & AXP_OPERAND_OPTIONAL_MASK) == 0)
2173 goto match_failed;
2174 continue;
2177 /* Match operand type with expression type. */
2178 switch (operand->flags & AXP_OPERAND_TYPECHECK_MASK)
2180 case AXP_OPERAND_IR:
2181 if (tok[tokidx].X_op != O_register
2182 || !is_ir_num (tok[tokidx].X_add_number))
2183 goto match_failed;
2184 break;
2185 case AXP_OPERAND_FPR:
2186 if (tok[tokidx].X_op != O_register
2187 || !is_fpr_num (tok[tokidx].X_add_number))
2188 goto match_failed;
2189 break;
2190 case AXP_OPERAND_IR | AXP_OPERAND_PARENS:
2191 if (tok[tokidx].X_op != O_pregister
2192 || !is_ir_num (tok[tokidx].X_add_number))
2193 goto match_failed;
2194 break;
2195 case AXP_OPERAND_IR | AXP_OPERAND_PARENS | AXP_OPERAND_COMMA:
2196 if (tok[tokidx].X_op != O_cpregister
2197 || !is_ir_num (tok[tokidx].X_add_number))
2198 goto match_failed;
2199 break;
2201 case AXP_OPERAND_RELATIVE:
2202 case AXP_OPERAND_SIGNED:
2203 case AXP_OPERAND_UNSIGNED:
2204 switch (tok[tokidx].X_op)
2206 case O_illegal:
2207 case O_absent:
2208 case O_register:
2209 case O_pregister:
2210 case O_cpregister:
2211 goto match_failed;
2213 default:
2214 break;
2216 break;
2218 default:
2219 /* Everything else should have been fake. */
2220 abort ();
2222 ++tokidx;
2225 /* Possible match -- did we use all of our input? */
2226 if (tokidx == ntok)
2228 *pntok = ntok;
2229 return opcode;
2232 match_failed:;
2234 while (++opcode - alpha_opcodes < (int) alpha_num_opcodes
2235 && !strcmp (opcode->name, first_opcode->name));
2237 if (*pcpumatch)
2238 *pcpumatch = got_cpu_match;
2240 return NULL;
2243 /* Search forward through all variants of a macro looking for a syntax
2244 match. */
2246 static const struct alpha_macro *
2247 find_macro_match (first_macro, tok, pntok)
2248 const struct alpha_macro *first_macro;
2249 const expressionS *tok;
2250 int *pntok;
2252 const struct alpha_macro *macro = first_macro;
2253 int ntok = *pntok;
2257 const enum alpha_macro_arg *arg = macro->argsets;
2258 int tokidx = 0;
2260 while (*arg)
2262 switch (*arg)
2264 case MACRO_EOA:
2265 if (tokidx == ntok)
2266 return macro;
2267 else
2268 tokidx = 0;
2269 break;
2271 /* Index register. */
2272 case MACRO_IR:
2273 if (tokidx >= ntok || tok[tokidx].X_op != O_register
2274 || !is_ir_num (tok[tokidx].X_add_number))
2275 goto match_failed;
2276 ++tokidx;
2277 break;
2279 /* Parenthesized index register. */
2280 case MACRO_PIR:
2281 if (tokidx >= ntok || tok[tokidx].X_op != O_pregister
2282 || !is_ir_num (tok[tokidx].X_add_number))
2283 goto match_failed;
2284 ++tokidx;
2285 break;
2287 /* Optional parenthesized index register. */
2288 case MACRO_OPIR:
2289 if (tokidx < ntok && tok[tokidx].X_op == O_pregister
2290 && is_ir_num (tok[tokidx].X_add_number))
2291 ++tokidx;
2292 break;
2294 /* Leading comma with a parenthesized index register. */
2295 case MACRO_CPIR:
2296 if (tokidx >= ntok || tok[tokidx].X_op != O_cpregister
2297 || !is_ir_num (tok[tokidx].X_add_number))
2298 goto match_failed;
2299 ++tokidx;
2300 break;
2302 /* Floating point register. */
2303 case MACRO_FPR:
2304 if (tokidx >= ntok || tok[tokidx].X_op != O_register
2305 || !is_fpr_num (tok[tokidx].X_add_number))
2306 goto match_failed;
2307 ++tokidx;
2308 break;
2310 /* Normal expression. */
2311 case MACRO_EXP:
2312 if (tokidx >= ntok)
2313 goto match_failed;
2314 switch (tok[tokidx].X_op)
2316 case O_illegal:
2317 case O_absent:
2318 case O_register:
2319 case O_pregister:
2320 case O_cpregister:
2321 case O_literal:
2322 case O_lituse_base:
2323 case O_lituse_bytoff:
2324 case O_lituse_jsr:
2325 case O_gpdisp:
2326 case O_gprelhigh:
2327 case O_gprellow:
2328 case O_gprel:
2329 case O_samegp:
2330 goto match_failed;
2332 default:
2333 break;
2335 ++tokidx;
2336 break;
2338 match_failed:
2339 while (*arg != MACRO_EOA)
2340 ++arg;
2341 tokidx = 0;
2342 break;
2344 ++arg;
2347 while (++macro - alpha_macros < (int) alpha_num_macros
2348 && !strcmp (macro->name, first_macro->name));
2350 return NULL;
2353 /* Insert an operand value into an instruction. */
2355 static unsigned
2356 insert_operand (insn, operand, val, file, line)
2357 unsigned insn;
2358 const struct alpha_operand *operand;
2359 offsetT val;
2360 char *file;
2361 unsigned line;
2363 if (operand->bits != 32 && !(operand->flags & AXP_OPERAND_NOOVERFLOW))
2365 offsetT min, max;
2367 if (operand->flags & AXP_OPERAND_SIGNED)
2369 max = (1 << (operand->bits - 1)) - 1;
2370 min = -(1 << (operand->bits - 1));
2372 else
2374 max = (1 << operand->bits) - 1;
2375 min = 0;
2378 if (val < min || val > max)
2380 const char *err =
2381 _("operand out of range (%s not between %d and %d)");
2382 char buf[sizeof (val) * 3 + 2];
2384 sprint_value (buf, val);
2385 if (file)
2386 as_warn_where (file, line, err, buf, min, max);
2387 else
2388 as_warn (err, buf, min, max);
2392 if (operand->insert)
2394 const char *errmsg = NULL;
2396 insn = (*operand->insert) (insn, val, &errmsg);
2397 if (errmsg)
2398 as_warn (errmsg);
2400 else
2401 insn |= ((val & ((1 << operand->bits) - 1)) << operand->shift);
2403 return insn;
2406 /* Turn an opcode description and a set of arguments into
2407 an instruction and a fixup. */
2409 static void
2410 assemble_insn (opcode, tok, ntok, insn, reloc)
2411 const struct alpha_opcode *opcode;
2412 const expressionS *tok;
2413 int ntok;
2414 struct alpha_insn *insn;
2415 bfd_reloc_code_real_type reloc;
2417 const struct alpha_operand *reloc_operand = NULL;
2418 const expressionS *reloc_exp = NULL;
2419 const unsigned char *argidx;
2420 unsigned image;
2421 int tokidx = 0;
2423 memset (insn, 0, sizeof (*insn));
2424 image = opcode->opcode;
2426 for (argidx = opcode->operands; *argidx; ++argidx)
2428 const struct alpha_operand *operand = &alpha_operands[*argidx];
2429 const expressionS *t = (const expressionS *) 0;
2431 if (operand->flags & AXP_OPERAND_FAKE)
2433 /* fake operands take no value and generate no fixup */
2434 image = insert_operand (image, operand, 0, NULL, 0);
2435 continue;
2438 if (tokidx >= ntok)
2440 switch (operand->flags & AXP_OPERAND_OPTIONAL_MASK)
2442 case AXP_OPERAND_DEFAULT_FIRST:
2443 t = &tok[0];
2444 break;
2445 case AXP_OPERAND_DEFAULT_SECOND:
2446 t = &tok[1];
2447 break;
2448 case AXP_OPERAND_DEFAULT_ZERO:
2450 static expressionS zero_exp;
2451 t = &zero_exp;
2452 zero_exp.X_op = O_constant;
2453 zero_exp.X_unsigned = 1;
2455 break;
2456 default:
2457 abort ();
2460 else
2461 t = &tok[tokidx++];
2463 switch (t->X_op)
2465 case O_register:
2466 case O_pregister:
2467 case O_cpregister:
2468 image = insert_operand (image, operand, regno (t->X_add_number),
2469 NULL, 0);
2470 break;
2472 case O_constant:
2473 image = insert_operand (image, operand, t->X_add_number, NULL, 0);
2474 assert (reloc_operand == NULL);
2475 reloc_operand = operand;
2476 reloc_exp = t;
2477 break;
2479 default:
2480 /* This is only 0 for fields that should contain registers,
2481 which means this pattern shouldn't have matched. */
2482 if (operand->default_reloc == 0)
2483 abort ();
2485 /* There is one special case for which an insn receives two
2486 relocations, and thus the user-supplied reloc does not
2487 override the operand reloc. */
2488 if (operand->default_reloc == BFD_RELOC_ALPHA_HINT)
2490 struct alpha_fixup *fixup;
2492 if (insn->nfixups >= MAX_INSN_FIXUPS)
2493 as_fatal (_("too many fixups"));
2495 fixup = &insn->fixups[insn->nfixups++];
2496 fixup->exp = *t;
2497 fixup->reloc = BFD_RELOC_ALPHA_HINT;
2499 else
2501 if (reloc == BFD_RELOC_UNUSED)
2502 reloc = operand->default_reloc;
2504 assert (reloc_operand == NULL);
2505 reloc_operand = operand;
2506 reloc_exp = t;
2508 break;
2512 if (reloc != BFD_RELOC_UNUSED)
2514 struct alpha_fixup *fixup;
2516 if (insn->nfixups >= MAX_INSN_FIXUPS)
2517 as_fatal (_("too many fixups"));
2519 /* ??? My but this is hacky. But the OSF/1 assembler uses the same
2520 relocation tag for both ldah and lda with gpdisp. Choose the
2521 correct internal relocation based on the opcode. */
2522 if (reloc == BFD_RELOC_ALPHA_GPDISP)
2524 if (strcmp (opcode->name, "ldah") == 0)
2525 reloc = BFD_RELOC_ALPHA_GPDISP_HI16;
2526 else if (strcmp (opcode->name, "lda") == 0)
2527 reloc = BFD_RELOC_ALPHA_GPDISP_LO16;
2528 else
2529 as_bad (_("invalid relocation for instruction"));
2532 /* If this is a real relocation (as opposed to a lituse hint), then
2533 the relocation width should match the operand width. */
2534 else if (reloc < BFD_RELOC_UNUSED)
2536 reloc_howto_type *reloc_howto
2537 = bfd_reloc_type_lookup (stdoutput, reloc);
2538 if (reloc_howto->bitsize != reloc_operand->bits)
2540 as_bad (_("invalid relocation for field"));
2541 return;
2545 fixup = &insn->fixups[insn->nfixups++];
2546 if (reloc_exp)
2547 fixup->exp = *reloc_exp;
2548 else
2549 fixup->exp.X_op = O_absent;
2550 fixup->reloc = reloc;
2553 insn->insn = image;
2556 /* Actually output an instruction with its fixup. */
2558 static void
2559 emit_insn (insn)
2560 struct alpha_insn *insn;
2562 char *f;
2563 int i;
2565 /* Take care of alignment duties. */
2566 if (alpha_auto_align_on && alpha_current_align < 2)
2567 alpha_align (2, (char *) NULL, alpha_insn_label, 0);
2568 if (alpha_current_align > 2)
2569 alpha_current_align = 2;
2570 alpha_insn_label = NULL;
2572 /* Write out the instruction. */
2573 f = frag_more (4);
2574 md_number_to_chars (f, insn->insn, 4);
2576 #ifdef OBJ_ELF
2577 dwarf2_emit_insn (4);
2578 #endif
2580 /* Apply the fixups in order. */
2581 for (i = 0; i < insn->nfixups; ++i)
2583 const struct alpha_operand *operand = (const struct alpha_operand *) 0;
2584 struct alpha_fixup *fixup = &insn->fixups[i];
2585 struct alpha_reloc_tag *info = NULL;
2586 int size, pcrel;
2587 fixS *fixP;
2589 /* Some fixups are only used internally and so have no howto. */
2590 if ((int) fixup->reloc < 0)
2592 operand = &alpha_operands[-(int) fixup->reloc];
2593 size = 4;
2594 pcrel = ((operand->flags & AXP_OPERAND_RELATIVE) != 0);
2596 else if (fixup->reloc > BFD_RELOC_UNUSED
2597 || fixup->reloc == BFD_RELOC_ALPHA_GPDISP_HI16
2598 || fixup->reloc == BFD_RELOC_ALPHA_GPDISP_LO16)
2600 size = 2;
2601 pcrel = 0;
2603 else
2605 reloc_howto_type *reloc_howto
2606 = bfd_reloc_type_lookup (stdoutput, fixup->reloc);
2607 assert (reloc_howto);
2609 size = bfd_get_reloc_size (reloc_howto);
2610 assert (size >= 1 && size <= 4);
2612 pcrel = reloc_howto->pc_relative;
2615 fixP = fix_new_exp (frag_now, f - frag_now->fr_literal, size,
2616 &fixup->exp, pcrel, fixup->reloc);
2618 /* Turn off complaints that the addend is too large for some fixups,
2619 and copy in the sequence number for the explicit relocations. */
2620 switch (fixup->reloc)
2622 case BFD_RELOC_ALPHA_HINT:
2623 case BFD_RELOC_GPREL32:
2624 case BFD_RELOC_GPREL16:
2625 case BFD_RELOC_ALPHA_GPREL_HI16:
2626 case BFD_RELOC_ALPHA_GPREL_LO16:
2627 case BFD_RELOC_ALPHA_GOTDTPREL16:
2628 case BFD_RELOC_ALPHA_DTPREL_HI16:
2629 case BFD_RELOC_ALPHA_DTPREL_LO16:
2630 case BFD_RELOC_ALPHA_DTPREL16:
2631 case BFD_RELOC_ALPHA_GOTTPREL16:
2632 case BFD_RELOC_ALPHA_TPREL_HI16:
2633 case BFD_RELOC_ALPHA_TPREL_LO16:
2634 case BFD_RELOC_ALPHA_TPREL16:
2635 fixP->fx_no_overflow = 1;
2636 break;
2638 case BFD_RELOC_ALPHA_GPDISP_HI16:
2639 fixP->fx_no_overflow = 1;
2640 fixP->fx_addsy = section_symbol (now_seg);
2641 fixP->fx_offset = 0;
2643 info = get_alpha_reloc_tag (insn->sequence);
2644 if (++info->n_master > 1)
2645 as_bad (_("too many ldah insns for !gpdisp!%ld"), insn->sequence);
2646 if (info->segment != now_seg)
2647 as_bad (_("both insns for !gpdisp!%ld must be in the same section"),
2648 insn->sequence);
2649 fixP->tc_fix_data.info = info;
2650 break;
2652 case BFD_RELOC_ALPHA_GPDISP_LO16:
2653 fixP->fx_no_overflow = 1;
2655 info = get_alpha_reloc_tag (insn->sequence);
2656 if (++info->n_slaves > 1)
2657 as_bad (_("too many lda insns for !gpdisp!%ld"), insn->sequence);
2658 if (info->segment != now_seg)
2659 as_bad (_("both insns for !gpdisp!%ld must be in the same section"),
2660 insn->sequence);
2661 fixP->tc_fix_data.info = info;
2662 info->slaves = fixP;
2663 break;
2665 case BFD_RELOC_ALPHA_LITERAL:
2666 case BFD_RELOC_ALPHA_ELF_LITERAL:
2667 fixP->fx_no_overflow = 1;
2669 if (insn->sequence == 0)
2670 break;
2671 info = get_alpha_reloc_tag (insn->sequence);
2672 info->master = fixP;
2673 info->n_master++;
2674 if (info->segment != now_seg)
2675 info->multi_section_p = 1;
2676 fixP->tc_fix_data.info = info;
2677 break;
2679 #ifdef RELOC_OP_P
2680 case DUMMY_RELOC_LITUSE_ADDR:
2681 fixP->fx_offset = LITUSE_ALPHA_ADDR;
2682 goto do_lituse;
2683 case DUMMY_RELOC_LITUSE_BASE:
2684 fixP->fx_offset = LITUSE_ALPHA_BASE;
2685 goto do_lituse;
2686 case DUMMY_RELOC_LITUSE_BYTOFF:
2687 fixP->fx_offset = LITUSE_ALPHA_BYTOFF;
2688 goto do_lituse;
2689 case DUMMY_RELOC_LITUSE_JSR:
2690 fixP->fx_offset = LITUSE_ALPHA_JSR;
2691 goto do_lituse;
2692 case DUMMY_RELOC_LITUSE_TLSGD:
2693 fixP->fx_offset = LITUSE_ALPHA_TLSGD;
2694 goto do_lituse;
2695 case DUMMY_RELOC_LITUSE_TLSLDM:
2696 fixP->fx_offset = LITUSE_ALPHA_TLSLDM;
2697 goto do_lituse;
2698 do_lituse:
2699 fixP->fx_addsy = section_symbol (now_seg);
2700 fixP->fx_r_type = BFD_RELOC_ALPHA_LITUSE;
2702 info = get_alpha_reloc_tag (insn->sequence);
2703 if (fixup->reloc == DUMMY_RELOC_LITUSE_TLSGD)
2704 info->saw_lu_tlsgd = 1;
2705 else if (fixup->reloc == DUMMY_RELOC_LITUSE_TLSLDM)
2706 info->saw_lu_tlsldm = 1;
2707 if (++info->n_slaves > 1)
2709 if (info->saw_lu_tlsgd)
2710 as_bad (_("too many lituse insns for !lituse_tlsgd!%ld"),
2711 insn->sequence);
2712 else if (info->saw_lu_tlsldm)
2713 as_bad (_("too many lituse insns for !lituse_tlsldm!%ld"),
2714 insn->sequence);
2716 fixP->tc_fix_data.info = info;
2717 fixP->tc_fix_data.next_reloc = info->slaves;
2718 info->slaves = fixP;
2719 if (info->segment != now_seg)
2720 info->multi_section_p = 1;
2721 break;
2723 case BFD_RELOC_ALPHA_TLSGD:
2724 fixP->fx_no_overflow = 1;
2726 if (insn->sequence == 0)
2727 break;
2728 info = get_alpha_reloc_tag (insn->sequence);
2729 if (info->saw_tlsgd)
2730 as_bad (_("duplicate !tlsgd!%ld"), insn->sequence);
2731 else if (info->saw_tlsldm)
2732 as_bad (_("sequence number in use for !tlsldm!%ld"),
2733 insn->sequence);
2734 else
2735 info->saw_tlsgd = 1;
2736 fixP->tc_fix_data.info = info;
2737 break;
2739 case BFD_RELOC_ALPHA_TLSLDM:
2740 fixP->fx_no_overflow = 1;
2742 if (insn->sequence == 0)
2743 break;
2744 info = get_alpha_reloc_tag (insn->sequence);
2745 if (info->saw_tlsldm)
2746 as_bad (_("duplicate !tlsldm!%ld"), insn->sequence);
2747 else if (info->saw_tlsgd)
2748 as_bad (_("sequence number in use for !tlsgd!%ld"),
2749 insn->sequence);
2750 else
2751 info->saw_tlsldm = 1;
2752 fixP->tc_fix_data.info = info;
2753 break;
2754 #endif
2755 default:
2756 if ((int) fixup->reloc < 0)
2758 if (operand->flags & AXP_OPERAND_NOOVERFLOW)
2759 fixP->fx_no_overflow = 1;
2761 break;
2766 /* Given an opcode name and a pre-tokenized set of arguments, assemble
2767 the insn, but do not emit it.
2769 Note that this implies no macros allowed, since we can't store more
2770 than one insn in an insn structure. */
2772 static void
2773 assemble_tokens_to_insn (opname, tok, ntok, insn)
2774 const char *opname;
2775 const expressionS *tok;
2776 int ntok;
2777 struct alpha_insn *insn;
2779 const struct alpha_opcode *opcode;
2781 /* search opcodes */
2782 opcode = (const struct alpha_opcode *) hash_find (alpha_opcode_hash, opname);
2783 if (opcode)
2785 int cpumatch;
2786 opcode = find_opcode_match (opcode, tok, &ntok, &cpumatch);
2787 if (opcode)
2789 assemble_insn (opcode, tok, ntok, insn, BFD_RELOC_UNUSED);
2790 return;
2792 else if (cpumatch)
2793 as_bad (_("inappropriate arguments for opcode `%s'"), opname);
2794 else
2795 as_bad (_("opcode `%s' not supported for target %s"), opname,
2796 alpha_target_name);
2798 else
2799 as_bad (_("unknown opcode `%s'"), opname);
2802 /* Given an opcode name and a pre-tokenized set of arguments, take the
2803 opcode all the way through emission. */
2805 static void
2806 assemble_tokens (opname, tok, ntok, local_macros_on)
2807 const char *opname;
2808 const expressionS *tok;
2809 int ntok;
2810 int local_macros_on;
2812 int found_something = 0;
2813 const struct alpha_opcode *opcode;
2814 const struct alpha_macro *macro;
2815 int cpumatch = 1;
2816 bfd_reloc_code_real_type reloc = BFD_RELOC_UNUSED;
2818 #ifdef RELOC_OP_P
2819 /* If a user-specified relocation is present, this is not a macro. */
2820 if (ntok && USER_RELOC_P (tok[ntok - 1].X_op))
2822 reloc = ALPHA_RELOC_TABLE (tok[ntok - 1].X_op)->reloc;
2823 ntok--;
2825 else
2826 #endif
2827 if (local_macros_on)
2829 macro = ((const struct alpha_macro *)
2830 hash_find (alpha_macro_hash, opname));
2831 if (macro)
2833 found_something = 1;
2834 macro = find_macro_match (macro, tok, &ntok);
2835 if (macro)
2837 (*macro->emit) (tok, ntok, macro->arg);
2838 return;
2843 /* Search opcodes. */
2844 opcode = (const struct alpha_opcode *) hash_find (alpha_opcode_hash, opname);
2845 if (opcode)
2847 found_something = 1;
2848 opcode = find_opcode_match (opcode, tok, &ntok, &cpumatch);
2849 if (opcode)
2851 struct alpha_insn insn;
2852 assemble_insn (opcode, tok, ntok, &insn, reloc);
2854 /* Copy the sequence number for the reloc from the reloc token. */
2855 if (reloc != BFD_RELOC_UNUSED)
2856 insn.sequence = tok[ntok].X_add_number;
2858 emit_insn (&insn);
2859 return;
2863 if (found_something)
2865 if (cpumatch)
2866 as_bad (_("inappropriate arguments for opcode `%s'"), opname);
2867 else
2868 as_bad (_("opcode `%s' not supported for target %s"), opname,
2869 alpha_target_name);
2871 else
2872 as_bad (_("unknown opcode `%s'"), opname);
2875 /* Some instruction sets indexed by lg(size). */
2876 static const char * const sextX_op[] = { "sextb", "sextw", "sextl", NULL };
2877 static const char * const insXl_op[] = { "insbl", "inswl", "insll", "insql" };
2878 static const char * const insXh_op[] = { NULL, "inswh", "inslh", "insqh" };
2879 static const char * const extXl_op[] = { "extbl", "extwl", "extll", "extql" };
2880 static const char * const extXh_op[] = { NULL, "extwh", "extlh", "extqh" };
2881 static const char * const mskXl_op[] = { "mskbl", "mskwl", "mskll", "mskql" };
2882 static const char * const mskXh_op[] = { NULL, "mskwh", "msklh", "mskqh" };
2883 static const char * const stX_op[] = { "stb", "stw", "stl", "stq" };
2884 static const char * const ldXu_op[] = { "ldbu", "ldwu", NULL, NULL };
2886 /* Implement the ldgp macro. */
2888 static void
2889 emit_ldgp (tok, ntok, unused)
2890 const expressionS *tok;
2891 int ntok ATTRIBUTE_UNUSED;
2892 const PTR unused ATTRIBUTE_UNUSED;
2894 #ifdef OBJ_AOUT
2895 FIXME
2896 #endif
2897 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
2898 /* from "ldgp r1,n(r2)", generate "ldah r1,X(R2); lda r1,Y(r1)"
2899 with appropriate constants and relocations. */
2900 struct alpha_insn insn;
2901 expressionS newtok[3];
2902 expressionS addend;
2904 #ifdef OBJ_ECOFF
2905 if (regno (tok[2].X_add_number) == AXP_REG_PV)
2906 ecoff_set_gp_prolog_size (0);
2907 #endif
2909 newtok[0] = tok[0];
2910 set_tok_const (newtok[1], 0);
2911 newtok[2] = tok[2];
2913 assemble_tokens_to_insn ("ldah", newtok, 3, &insn);
2915 addend = tok[1];
2917 #ifdef OBJ_ECOFF
2918 if (addend.X_op != O_constant)
2919 as_bad (_("can not resolve expression"));
2920 addend.X_op = O_symbol;
2921 addend.X_add_symbol = alpha_gp_symbol;
2922 #endif
2924 insn.nfixups = 1;
2925 insn.fixups[0].exp = addend;
2926 insn.fixups[0].reloc = BFD_RELOC_ALPHA_GPDISP_HI16;
2927 insn.sequence = next_sequence_num;
2929 emit_insn (&insn);
2931 set_tok_preg (newtok[2], tok[0].X_add_number);
2933 assemble_tokens_to_insn ("lda", newtok, 3, &insn);
2935 #ifdef OBJ_ECOFF
2936 addend.X_add_number += 4;
2937 #endif
2939 insn.nfixups = 1;
2940 insn.fixups[0].exp = addend;
2941 insn.fixups[0].reloc = BFD_RELOC_ALPHA_GPDISP_LO16;
2942 insn.sequence = next_sequence_num--;
2944 emit_insn (&insn);
2945 #endif /* OBJ_ECOFF || OBJ_ELF */
2948 #ifdef OBJ_EVAX
2950 /* Add symbol+addend to link pool.
2951 Return offset from basesym to entry in link pool.
2953 Add new fixup only if offset isn't 16bit. */
2955 valueT
2956 add_to_link_pool (basesym, sym, addend)
2957 symbolS *basesym;
2958 symbolS *sym;
2959 offsetT addend;
2961 segT current_section = now_seg;
2962 int current_subsec = now_subseg;
2963 valueT offset;
2964 bfd_reloc_code_real_type reloc_type;
2965 char *p;
2966 segment_info_type *seginfo = seg_info (alpha_link_section);
2967 fixS *fixp;
2969 offset = - *symbol_get_obj (basesym);
2971 /* @@ This assumes all entries in a given section will be of the same
2972 size... Probably correct, but unwise to rely on. */
2973 /* This must always be called with the same subsegment. */
2975 if (seginfo->frchainP)
2976 for (fixp = seginfo->frchainP->fix_root;
2977 fixp != (fixS *) NULL;
2978 fixp = fixp->fx_next, offset += 8)
2980 if (fixp->fx_addsy == sym && fixp->fx_offset == addend)
2982 if (range_signed_16 (offset))
2984 return offset;
2989 /* Not found in 16bit signed range. */
2991 subseg_set (alpha_link_section, 0);
2992 p = frag_more (8);
2993 memset (p, 0, 8);
2995 fix_new (frag_now, p - frag_now->fr_literal, 8, sym, addend, 0,
2996 BFD_RELOC_64);
2998 subseg_set (current_section, current_subsec);
2999 seginfo->literal_pool_size += 8;
3000 return offset;
3003 #endif /* OBJ_EVAX */
3005 /* Load a (partial) expression into a target register.
3007 If poffset is not null, after the call it will either contain
3008 O_constant 0, or a 16-bit offset appropriate for any MEM format
3009 instruction. In addition, pbasereg will be modified to point to
3010 the base register to use in that MEM format instruction.
3012 In any case, *pbasereg should contain a base register to add to the
3013 expression. This will normally be either AXP_REG_ZERO or
3014 alpha_gp_register. Symbol addresses will always be loaded via $gp,
3015 so "foo($0)" is interpreted as adding the address of foo to $0;
3016 i.e. "ldq $targ, LIT($gp); addq $targ, $0, $targ". Odd, perhaps,
3017 but this is what OSF/1 does.
3019 If explicit relocations of the form !literal!<number> are allowed,
3020 and used, then explict_reloc with be an expression pointer.
3022 Finally, the return value is nonzero if the calling macro may emit
3023 a LITUSE reloc if otherwise appropriate; the return value is the
3024 sequence number to use. */
3026 static long
3027 load_expression (targreg, exp, pbasereg, poffset)
3028 int targreg;
3029 const expressionS *exp;
3030 int *pbasereg;
3031 expressionS *poffset;
3033 long emit_lituse = 0;
3034 offsetT addend = exp->X_add_number;
3035 int basereg = *pbasereg;
3036 struct alpha_insn insn;
3037 expressionS newtok[3];
3039 switch (exp->X_op)
3041 case O_symbol:
3043 #ifdef OBJ_ECOFF
3044 offsetT lit;
3046 /* Attempt to reduce .lit load by splitting the offset from
3047 its symbol when possible, but don't create a situation in
3048 which we'd fail. */
3049 if (!range_signed_32 (addend) &&
3050 (alpha_noat_on || targreg == AXP_REG_AT))
3052 lit = add_to_literal_pool (exp->X_add_symbol, addend,
3053 alpha_lita_section, 8);
3054 addend = 0;
3056 else
3058 lit = add_to_literal_pool (exp->X_add_symbol, 0,
3059 alpha_lita_section, 8);
3062 if (lit >= 0x8000)
3063 as_fatal (_("overflow in literal (.lita) table"));
3065 /* emit "ldq r, lit(gp)" */
3067 if (basereg != alpha_gp_register && targreg == basereg)
3069 if (alpha_noat_on)
3070 as_bad (_("macro requires $at register while noat in effect"));
3071 if (targreg == AXP_REG_AT)
3072 as_bad (_("macro requires $at while $at in use"));
3074 set_tok_reg (newtok[0], AXP_REG_AT);
3076 else
3077 set_tok_reg (newtok[0], targreg);
3078 set_tok_sym (newtok[1], alpha_lita_symbol, lit);
3079 set_tok_preg (newtok[2], alpha_gp_register);
3081 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
3083 assert (insn.nfixups == 1);
3084 insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITERAL;
3085 insn.sequence = emit_lituse = next_sequence_num--;
3086 #endif /* OBJ_ECOFF */
3087 #ifdef OBJ_ELF
3088 /* emit "ldq r, gotoff(gp)" */
3090 if (basereg != alpha_gp_register && targreg == basereg)
3092 if (alpha_noat_on)
3093 as_bad (_("macro requires $at register while noat in effect"));
3094 if (targreg == AXP_REG_AT)
3095 as_bad (_("macro requires $at while $at in use"));
3097 set_tok_reg (newtok[0], AXP_REG_AT);
3099 else
3100 set_tok_reg (newtok[0], targreg);
3102 /* XXX: Disable this .got minimizing optimization so that we can get
3103 better instruction offset knowledge in the compiler. This happens
3104 very infrequently anyway. */
3105 if (1
3106 || (!range_signed_32 (addend)
3107 && (alpha_noat_on || targreg == AXP_REG_AT)))
3109 newtok[1] = *exp;
3110 addend = 0;
3112 else
3114 set_tok_sym (newtok[1], exp->X_add_symbol, 0);
3117 set_tok_preg (newtok[2], alpha_gp_register);
3119 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
3121 assert (insn.nfixups == 1);
3122 insn.fixups[0].reloc = BFD_RELOC_ALPHA_ELF_LITERAL;
3123 insn.sequence = emit_lituse = next_sequence_num--;
3124 #endif /* OBJ_ELF */
3125 #ifdef OBJ_EVAX
3126 offsetT link;
3128 /* Find symbol or symbol pointer in link section. */
3130 if (exp->X_add_symbol == alpha_evax_proc.symbol)
3132 if (range_signed_16 (addend))
3134 set_tok_reg (newtok[0], targreg);
3135 set_tok_const (newtok[1], addend);
3136 set_tok_preg (newtok[2], basereg);
3137 assemble_tokens_to_insn ("lda", newtok, 3, &insn);
3138 addend = 0;
3140 else
3142 set_tok_reg (newtok[0], targreg);
3143 set_tok_const (newtok[1], 0);
3144 set_tok_preg (newtok[2], basereg);
3145 assemble_tokens_to_insn ("lda", newtok, 3, &insn);
3148 else
3150 if (!range_signed_32 (addend))
3152 link = add_to_link_pool (alpha_evax_proc.symbol,
3153 exp->X_add_symbol, addend);
3154 addend = 0;
3156 else
3158 link = add_to_link_pool (alpha_evax_proc.symbol,
3159 exp->X_add_symbol, 0);
3161 set_tok_reg (newtok[0], targreg);
3162 set_tok_const (newtok[1], link);
3163 set_tok_preg (newtok[2], basereg);
3164 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
3166 #endif /* OBJ_EVAX */
3168 emit_insn (&insn);
3170 #ifndef OBJ_EVAX
3171 if (basereg != alpha_gp_register && basereg != AXP_REG_ZERO)
3173 /* emit "addq r, base, r" */
3175 set_tok_reg (newtok[1], basereg);
3176 set_tok_reg (newtok[2], targreg);
3177 assemble_tokens ("addq", newtok, 3, 0);
3179 #endif
3181 basereg = targreg;
3183 break;
3185 case O_constant:
3186 break;
3188 case O_subtract:
3189 /* Assume that this difference expression will be resolved to an
3190 absolute value and that that value will fit in 16 bits. */
3192 set_tok_reg (newtok[0], targreg);
3193 newtok[1] = *exp;
3194 set_tok_preg (newtok[2], basereg);
3195 assemble_tokens ("lda", newtok, 3, 0);
3197 if (poffset)
3198 set_tok_const (*poffset, 0);
3199 return 0;
3201 case O_big:
3202 if (exp->X_add_number > 0)
3203 as_bad (_("bignum invalid; zero assumed"));
3204 else
3205 as_bad (_("floating point number invalid; zero assumed"));
3206 addend = 0;
3207 break;
3209 default:
3210 as_bad (_("can't handle expression"));
3211 addend = 0;
3212 break;
3215 if (!range_signed_32 (addend))
3217 offsetT lit;
3218 long seq_num = next_sequence_num--;
3220 /* For 64-bit addends, just put it in the literal pool. */
3222 #ifdef OBJ_EVAX
3223 /* emit "ldq targreg, lit(basereg)" */
3224 lit = add_to_link_pool (alpha_evax_proc.symbol,
3225 section_symbol (absolute_section), addend);
3226 set_tok_reg (newtok[0], targreg);
3227 set_tok_const (newtok[1], lit);
3228 set_tok_preg (newtok[2], alpha_gp_register);
3229 assemble_tokens ("ldq", newtok, 3, 0);
3230 #else
3232 if (alpha_lit8_section == NULL)
3234 create_literal_section (".lit8",
3235 &alpha_lit8_section,
3236 &alpha_lit8_symbol);
3238 #ifdef OBJ_ECOFF
3239 alpha_lit8_literal = add_to_literal_pool (alpha_lit8_symbol, 0x8000,
3240 alpha_lita_section, 8);
3241 if (alpha_lit8_literal >= 0x8000)
3242 as_fatal (_("overflow in literal (.lita) table"));
3243 #endif
3246 lit = add_to_literal_pool (NULL, addend, alpha_lit8_section, 8) - 0x8000;
3247 if (lit >= 0x8000)
3248 as_fatal (_("overflow in literal (.lit8) table"));
3250 /* emit "lda litreg, .lit8+0x8000" */
3252 if (targreg == basereg)
3254 if (alpha_noat_on)
3255 as_bad (_("macro requires $at register while noat in effect"));
3256 if (targreg == AXP_REG_AT)
3257 as_bad (_("macro requires $at while $at in use"));
3259 set_tok_reg (newtok[0], AXP_REG_AT);
3261 else
3262 set_tok_reg (newtok[0], targreg);
3263 #ifdef OBJ_ECOFF
3264 set_tok_sym (newtok[1], alpha_lita_symbol, alpha_lit8_literal);
3265 #endif
3266 #ifdef OBJ_ELF
3267 set_tok_sym (newtok[1], alpha_lit8_symbol, 0x8000);
3268 #endif
3269 set_tok_preg (newtok[2], alpha_gp_register);
3271 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
3273 assert (insn.nfixups == 1);
3274 #ifdef OBJ_ECOFF
3275 insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITERAL;
3276 #endif
3277 #ifdef OBJ_ELF
3278 insn.fixups[0].reloc = BFD_RELOC_ALPHA_ELF_LITERAL;
3279 #endif
3280 insn.sequence = seq_num;
3282 emit_insn (&insn);
3284 /* emit "ldq litreg, lit(litreg)" */
3286 set_tok_const (newtok[1], lit);
3287 set_tok_preg (newtok[2], newtok[0].X_add_number);
3289 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
3291 assert (insn.nfixups < MAX_INSN_FIXUPS);
3292 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
3293 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3294 insn.nfixups++;
3295 insn.sequence = seq_num;
3296 emit_lituse = 0;
3298 emit_insn (&insn);
3300 /* emit "addq litreg, base, target" */
3302 if (basereg != AXP_REG_ZERO)
3304 set_tok_reg (newtok[1], basereg);
3305 set_tok_reg (newtok[2], targreg);
3306 assemble_tokens ("addq", newtok, 3, 0);
3308 #endif /* !OBJ_EVAX */
3310 if (poffset)
3311 set_tok_const (*poffset, 0);
3312 *pbasereg = targreg;
3314 else
3316 offsetT low, high, extra, tmp;
3318 /* for 32-bit operands, break up the addend */
3320 low = sign_extend_16 (addend);
3321 tmp = addend - low;
3322 high = sign_extend_16 (tmp >> 16);
3324 if (tmp - (high << 16))
3326 extra = 0x4000;
3327 tmp -= 0x40000000;
3328 high = sign_extend_16 (tmp >> 16);
3330 else
3331 extra = 0;
3333 set_tok_reg (newtok[0], targreg);
3334 set_tok_preg (newtok[2], basereg);
3336 if (extra)
3338 /* emit "ldah r, extra(r) */
3339 set_tok_const (newtok[1], extra);
3340 assemble_tokens ("ldah", newtok, 3, 0);
3341 set_tok_preg (newtok[2], basereg = targreg);
3344 if (high)
3346 /* emit "ldah r, high(r) */
3347 set_tok_const (newtok[1], high);
3348 assemble_tokens ("ldah", newtok, 3, 0);
3349 basereg = targreg;
3350 set_tok_preg (newtok[2], basereg);
3353 if ((low && !poffset) || (!poffset && basereg != targreg))
3355 /* emit "lda r, low(base)" */
3356 set_tok_const (newtok[1], low);
3357 assemble_tokens ("lda", newtok, 3, 0);
3358 basereg = targreg;
3359 low = 0;
3362 if (poffset)
3363 set_tok_const (*poffset, low);
3364 *pbasereg = basereg;
3367 return emit_lituse;
3370 /* The lda macro differs from the lda instruction in that it handles
3371 most simple expressions, particualrly symbol address loads and
3372 large constants. */
3374 static void
3375 emit_lda (tok, ntok, unused)
3376 const expressionS *tok;
3377 int ntok;
3378 const PTR unused ATTRIBUTE_UNUSED;
3380 int basereg;
3382 if (ntok == 2)
3383 basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
3384 else
3385 basereg = tok[2].X_add_number;
3387 (void) load_expression (tok[0].X_add_number, &tok[1], &basereg, NULL);
3390 /* The ldah macro differs from the ldah instruction in that it has $31
3391 as an implied base register. */
3393 static void
3394 emit_ldah (tok, ntok, unused)
3395 const expressionS *tok;
3396 int ntok ATTRIBUTE_UNUSED;
3397 const PTR unused ATTRIBUTE_UNUSED;
3399 expressionS newtok[3];
3401 newtok[0] = tok[0];
3402 newtok[1] = tok[1];
3403 set_tok_preg (newtok[2], AXP_REG_ZERO);
3405 assemble_tokens ("ldah", newtok, 3, 0);
3408 /* Handle all "simple" integer register loads -- ldq, ldq_l, ldq_u,
3409 etc. They differ from the real instructions in that they do simple
3410 expressions like the lda macro. */
3412 static void
3413 emit_ir_load (tok, ntok, opname)
3414 const expressionS *tok;
3415 int ntok;
3416 const PTR opname;
3418 int basereg;
3419 long lituse;
3420 expressionS newtok[3];
3421 struct alpha_insn insn;
3423 if (ntok == 2)
3424 basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
3425 else
3426 basereg = tok[2].X_add_number;
3428 lituse = load_expression (tok[0].X_add_number, &tok[1], &basereg,
3429 &newtok[1]);
3431 newtok[0] = tok[0];
3432 set_tok_preg (newtok[2], basereg);
3434 assemble_tokens_to_insn ((const char *) opname, newtok, 3, &insn);
3436 if (lituse)
3438 assert (insn.nfixups < MAX_INSN_FIXUPS);
3439 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
3440 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3441 insn.nfixups++;
3442 insn.sequence = lituse;
3445 emit_insn (&insn);
3448 /* Handle fp register loads, and both integer and fp register stores.
3449 Again, we handle simple expressions. */
3451 static void
3452 emit_loadstore (tok, ntok, opname)
3453 const expressionS *tok;
3454 int ntok;
3455 const PTR opname;
3457 int basereg;
3458 long lituse;
3459 expressionS newtok[3];
3460 struct alpha_insn insn;
3462 if (ntok == 2)
3463 basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
3464 else
3465 basereg = tok[2].X_add_number;
3467 if (tok[1].X_op != O_constant || !range_signed_16 (tok[1].X_add_number))
3469 if (alpha_noat_on)
3470 as_bad (_("macro requires $at register while noat in effect"));
3472 lituse = load_expression (AXP_REG_AT, &tok[1], &basereg, &newtok[1]);
3474 else
3476 newtok[1] = tok[1];
3477 lituse = 0;
3480 newtok[0] = tok[0];
3481 set_tok_preg (newtok[2], basereg);
3483 assemble_tokens_to_insn ((const char *) opname, newtok, 3, &insn);
3485 if (lituse)
3487 assert (insn.nfixups < MAX_INSN_FIXUPS);
3488 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
3489 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3490 insn.nfixups++;
3491 insn.sequence = lituse;
3494 emit_insn (&insn);
3497 /* Load a half-word or byte as an unsigned value. */
3499 static void
3500 emit_ldXu (tok, ntok, vlgsize)
3501 const expressionS *tok;
3502 int ntok;
3503 const PTR vlgsize;
3505 if (alpha_target & AXP_OPCODE_BWX)
3506 emit_ir_load (tok, ntok, ldXu_op[(long) vlgsize]);
3507 else
3509 expressionS newtok[3];
3510 struct alpha_insn insn;
3511 int basereg;
3512 long lituse;
3514 if (alpha_noat_on)
3515 as_bad (_("macro requires $at register while noat in effect"));
3517 if (ntok == 2)
3518 basereg = (tok[1].X_op == O_constant
3519 ? AXP_REG_ZERO : alpha_gp_register);
3520 else
3521 basereg = tok[2].X_add_number;
3523 /* emit "lda $at, exp" */
3525 lituse = load_expression (AXP_REG_AT, &tok[1], &basereg, NULL);
3527 /* emit "ldq_u targ, 0($at)" */
3529 newtok[0] = tok[0];
3530 set_tok_const (newtok[1], 0);
3531 set_tok_preg (newtok[2], basereg);
3532 assemble_tokens_to_insn ("ldq_u", newtok, 3, &insn);
3534 if (lituse)
3536 assert (insn.nfixups < MAX_INSN_FIXUPS);
3537 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
3538 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3539 insn.nfixups++;
3540 insn.sequence = lituse;
3543 emit_insn (&insn);
3545 /* emit "extXl targ, $at, targ" */
3547 set_tok_reg (newtok[1], basereg);
3548 newtok[2] = newtok[0];
3549 assemble_tokens_to_insn (extXl_op[(long) vlgsize], newtok, 3, &insn);
3551 if (lituse)
3553 assert (insn.nfixups < MAX_INSN_FIXUPS);
3554 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF;
3555 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3556 insn.nfixups++;
3557 insn.sequence = lituse;
3560 emit_insn (&insn);
3564 /* Load a half-word or byte as a signed value. */
3566 static void
3567 emit_ldX (tok, ntok, vlgsize)
3568 const expressionS *tok;
3569 int ntok;
3570 const PTR vlgsize;
3572 emit_ldXu (tok, ntok, vlgsize);
3573 assemble_tokens (sextX_op[(long) vlgsize], tok, 1, 1);
3576 /* Load an integral value from an unaligned address as an unsigned
3577 value. */
3579 static void
3580 emit_uldXu (tok, ntok, vlgsize)
3581 const expressionS *tok;
3582 int ntok;
3583 const PTR vlgsize;
3585 long lgsize = (long) vlgsize;
3586 expressionS newtok[3];
3588 if (alpha_noat_on)
3589 as_bad (_("macro requires $at register while noat in effect"));
3591 /* emit "lda $at, exp" */
3593 memcpy (newtok, tok, sizeof (expressionS) * ntok);
3594 newtok[0].X_add_number = AXP_REG_AT;
3595 assemble_tokens ("lda", newtok, ntok, 1);
3597 /* emit "ldq_u $t9, 0($at)" */
3599 set_tok_reg (newtok[0], AXP_REG_T9);
3600 set_tok_const (newtok[1], 0);
3601 set_tok_preg (newtok[2], AXP_REG_AT);
3602 assemble_tokens ("ldq_u", newtok, 3, 1);
3604 /* emit "ldq_u $t10, size-1($at)" */
3606 set_tok_reg (newtok[0], AXP_REG_T10);
3607 set_tok_const (newtok[1], (1 << lgsize) - 1);
3608 assemble_tokens ("ldq_u", newtok, 3, 1);
3610 /* emit "extXl $t9, $at, $t9" */
3612 set_tok_reg (newtok[0], AXP_REG_T9);
3613 set_tok_reg (newtok[1], AXP_REG_AT);
3614 set_tok_reg (newtok[2], AXP_REG_T9);
3615 assemble_tokens (extXl_op[lgsize], newtok, 3, 1);
3617 /* emit "extXh $t10, $at, $t10" */
3619 set_tok_reg (newtok[0], AXP_REG_T10);
3620 set_tok_reg (newtok[2], AXP_REG_T10);
3621 assemble_tokens (extXh_op[lgsize], newtok, 3, 1);
3623 /* emit "or $t9, $t10, targ" */
3625 set_tok_reg (newtok[0], AXP_REG_T9);
3626 set_tok_reg (newtok[1], AXP_REG_T10);
3627 newtok[2] = tok[0];
3628 assemble_tokens ("or", newtok, 3, 1);
3631 /* Load an integral value from an unaligned address as a signed value.
3632 Note that quads should get funneled to the unsigned load since we
3633 don't have to do the sign extension. */
3635 static void
3636 emit_uldX (tok, ntok, vlgsize)
3637 const expressionS *tok;
3638 int ntok;
3639 const PTR vlgsize;
3641 emit_uldXu (tok, ntok, vlgsize);
3642 assemble_tokens (sextX_op[(long) vlgsize], tok, 1, 1);
3645 /* Implement the ldil macro. */
3647 static void
3648 emit_ldil (tok, ntok, unused)
3649 const expressionS *tok;
3650 int ntok;
3651 const PTR unused ATTRIBUTE_UNUSED;
3653 expressionS newtok[2];
3655 memcpy (newtok, tok, sizeof (newtok));
3656 newtok[1].X_add_number = sign_extend_32 (tok[1].X_add_number);
3658 assemble_tokens ("lda", newtok, ntok, 1);
3661 /* Store a half-word or byte. */
3663 static void
3664 emit_stX (tok, ntok, vlgsize)
3665 const expressionS *tok;
3666 int ntok;
3667 const PTR vlgsize;
3669 int lgsize = (int) (long) vlgsize;
3671 if (alpha_target & AXP_OPCODE_BWX)
3672 emit_loadstore (tok, ntok, stX_op[lgsize]);
3673 else
3675 expressionS newtok[3];
3676 struct alpha_insn insn;
3677 int basereg;
3678 long lituse;
3680 if (alpha_noat_on)
3681 as_bad (_("macro requires $at register while noat in effect"));
3683 if (ntok == 2)
3684 basereg = (tok[1].X_op == O_constant
3685 ? AXP_REG_ZERO : alpha_gp_register);
3686 else
3687 basereg = tok[2].X_add_number;
3689 /* emit "lda $at, exp" */
3691 lituse = load_expression (AXP_REG_AT, &tok[1], &basereg, NULL);
3693 /* emit "ldq_u $t9, 0($at)" */
3695 set_tok_reg (newtok[0], AXP_REG_T9);
3696 set_tok_const (newtok[1], 0);
3697 set_tok_preg (newtok[2], basereg);
3698 assemble_tokens_to_insn ("ldq_u", newtok, 3, &insn);
3700 if (lituse)
3702 assert (insn.nfixups < MAX_INSN_FIXUPS);
3703 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
3704 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3705 insn.nfixups++;
3706 insn.sequence = lituse;
3709 emit_insn (&insn);
3711 /* emit "insXl src, $at, $t10" */
3713 newtok[0] = tok[0];
3714 set_tok_reg (newtok[1], basereg);
3715 set_tok_reg (newtok[2], AXP_REG_T10);
3716 assemble_tokens_to_insn (insXl_op[lgsize], newtok, 3, &insn);
3718 if (lituse)
3720 assert (insn.nfixups < MAX_INSN_FIXUPS);
3721 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF;
3722 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3723 insn.nfixups++;
3724 insn.sequence = lituse;
3727 emit_insn (&insn);
3729 /* emit "mskXl $t9, $at, $t9" */
3731 set_tok_reg (newtok[0], AXP_REG_T9);
3732 newtok[2] = newtok[0];
3733 assemble_tokens_to_insn (mskXl_op[lgsize], newtok, 3, &insn);
3735 if (lituse)
3737 assert (insn.nfixups < MAX_INSN_FIXUPS);
3738 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF;
3739 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3740 insn.nfixups++;
3741 insn.sequence = lituse;
3744 emit_insn (&insn);
3746 /* emit "or $t9, $t10, $t9" */
3748 set_tok_reg (newtok[1], AXP_REG_T10);
3749 assemble_tokens ("or", newtok, 3, 1);
3751 /* emit "stq_u $t9, 0($at) */
3753 set_tok_const(newtok[1], 0);
3754 set_tok_preg (newtok[2], AXP_REG_AT);
3755 assemble_tokens_to_insn ("stq_u", newtok, 3, &insn);
3757 if (lituse)
3759 assert (insn.nfixups < MAX_INSN_FIXUPS);
3760 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
3761 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3762 insn.nfixups++;
3763 insn.sequence = lituse;
3766 emit_insn (&insn);
3770 /* Store an integer to an unaligned address. */
3772 static void
3773 emit_ustX (tok, ntok, vlgsize)
3774 const expressionS *tok;
3775 int ntok;
3776 const PTR vlgsize;
3778 int lgsize = (int) (long) vlgsize;
3779 expressionS newtok[3];
3781 /* emit "lda $at, exp" */
3783 memcpy (newtok, tok, sizeof (expressionS) * ntok);
3784 newtok[0].X_add_number = AXP_REG_AT;
3785 assemble_tokens ("lda", newtok, ntok, 1);
3787 /* emit "ldq_u $9, 0($at)" */
3789 set_tok_reg (newtok[0], AXP_REG_T9);
3790 set_tok_const (newtok[1], 0);
3791 set_tok_preg (newtok[2], AXP_REG_AT);
3792 assemble_tokens ("ldq_u", newtok, 3, 1);
3794 /* emit "ldq_u $10, size-1($at)" */
3796 set_tok_reg (newtok[0], AXP_REG_T10);
3797 set_tok_const (newtok[1], (1 << lgsize) - 1);
3798 assemble_tokens ("ldq_u", newtok, 3, 1);
3800 /* emit "insXl src, $at, $t11" */
3802 newtok[0] = tok[0];
3803 set_tok_reg (newtok[1], AXP_REG_AT);
3804 set_tok_reg (newtok[2], AXP_REG_T11);
3805 assemble_tokens (insXl_op[lgsize], newtok, 3, 1);
3807 /* emit "insXh src, $at, $t12" */
3809 set_tok_reg (newtok[2], AXP_REG_T12);
3810 assemble_tokens (insXh_op[lgsize], newtok, 3, 1);
3812 /* emit "mskXl $t9, $at, $t9" */
3814 set_tok_reg (newtok[0], AXP_REG_T9);
3815 newtok[2] = newtok[0];
3816 assemble_tokens (mskXl_op[lgsize], newtok, 3, 1);
3818 /* emit "mskXh $t10, $at, $t10" */
3820 set_tok_reg (newtok[0], AXP_REG_T10);
3821 newtok[2] = newtok[0];
3822 assemble_tokens (mskXh_op[lgsize], newtok, 3, 1);
3824 /* emit "or $t9, $t11, $t9" */
3826 set_tok_reg (newtok[0], AXP_REG_T9);
3827 set_tok_reg (newtok[1], AXP_REG_T11);
3828 newtok[2] = newtok[0];
3829 assemble_tokens ("or", newtok, 3, 1);
3831 /* emit "or $t10, $t12, $t10" */
3833 set_tok_reg (newtok[0], AXP_REG_T10);
3834 set_tok_reg (newtok[1], AXP_REG_T12);
3835 newtok[2] = newtok[0];
3836 assemble_tokens ("or", newtok, 3, 1);
3838 /* emit "stq_u $t9, 0($at)" */
3840 set_tok_reg (newtok[0], AXP_REG_T9);
3841 set_tok_const (newtok[1], 0);
3842 set_tok_preg (newtok[2], AXP_REG_AT);
3843 assemble_tokens ("stq_u", newtok, 3, 1);
3845 /* emit "stq_u $t10, size-1($at)" */
3847 set_tok_reg (newtok[0], AXP_REG_T10);
3848 set_tok_const (newtok[1], (1 << lgsize) - 1);
3849 assemble_tokens ("stq_u", newtok, 3, 1);
3852 /* Sign extend a half-word or byte. The 32-bit sign extend is
3853 implemented as "addl $31, $r, $t" in the opcode table. */
3855 static void
3856 emit_sextX (tok, ntok, vlgsize)
3857 const expressionS *tok;
3858 int ntok;
3859 const PTR vlgsize;
3861 long lgsize = (long) vlgsize;
3863 if (alpha_target & AXP_OPCODE_BWX)
3864 assemble_tokens (sextX_op[lgsize], tok, ntok, 0);
3865 else
3867 int bitshift = 64 - 8 * (1 << lgsize);
3868 expressionS newtok[3];
3870 /* emit "sll src,bits,dst" */
3872 newtok[0] = tok[0];
3873 set_tok_const (newtok[1], bitshift);
3874 newtok[2] = tok[ntok - 1];
3875 assemble_tokens ("sll", newtok, 3, 1);
3877 /* emit "sra dst,bits,dst" */
3879 newtok[0] = newtok[2];
3880 assemble_tokens ("sra", newtok, 3, 1);
3884 /* Implement the division and modulus macros. */
3886 #ifdef OBJ_EVAX
3888 /* Make register usage like in normal procedure call.
3889 Don't clobber PV and RA. */
3891 static void
3892 emit_division (tok, ntok, symname)
3893 const expressionS *tok;
3894 int ntok;
3895 const PTR symname;
3897 /* DIVISION and MODULUS. Yech.
3899 Convert
3900 OP x,y,result
3902 mov x,R16 # if x != R16
3903 mov y,R17 # if y != R17
3904 lda AT,__OP
3905 jsr AT,(AT),0
3906 mov R0,result
3908 with appropriate optimizations if R0,R16,R17 are the registers
3909 specified by the compiler. */
3911 int xr, yr, rr;
3912 symbolS *sym;
3913 expressionS newtok[3];
3915 xr = regno (tok[0].X_add_number);
3916 yr = regno (tok[1].X_add_number);
3918 if (ntok < 3)
3919 rr = xr;
3920 else
3921 rr = regno (tok[2].X_add_number);
3923 /* Move the operands into the right place. */
3924 if (yr == AXP_REG_R16 && xr == AXP_REG_R17)
3926 /* They are in exactly the wrong order -- swap through AT. */
3928 if (alpha_noat_on)
3929 as_bad (_("macro requires $at register while noat in effect"));
3931 set_tok_reg (newtok[0], AXP_REG_R16);
3932 set_tok_reg (newtok[1], AXP_REG_AT);
3933 assemble_tokens ("mov", newtok, 2, 1);
3935 set_tok_reg (newtok[0], AXP_REG_R17);
3936 set_tok_reg (newtok[1], AXP_REG_R16);
3937 assemble_tokens ("mov", newtok, 2, 1);
3939 set_tok_reg (newtok[0], AXP_REG_AT);
3940 set_tok_reg (newtok[1], AXP_REG_R17);
3941 assemble_tokens ("mov", newtok, 2, 1);
3943 else
3945 if (yr == AXP_REG_R16)
3947 set_tok_reg (newtok[0], AXP_REG_R16);
3948 set_tok_reg (newtok[1], AXP_REG_R17);
3949 assemble_tokens ("mov", newtok, 2, 1);
3952 if (xr != AXP_REG_R16)
3954 set_tok_reg (newtok[0], xr);
3955 set_tok_reg (newtok[1], AXP_REG_R16);
3956 assemble_tokens ("mov", newtok, 2, 1);
3959 if (yr != AXP_REG_R16 && yr != AXP_REG_R17)
3961 set_tok_reg (newtok[0], yr);
3962 set_tok_reg (newtok[1], AXP_REG_R17);
3963 assemble_tokens ("mov", newtok, 2, 1);
3967 sym = symbol_find_or_make ((const char *) symname);
3969 set_tok_reg (newtok[0], AXP_REG_AT);
3970 set_tok_sym (newtok[1], sym, 0);
3971 assemble_tokens ("lda", newtok, 2, 1);
3973 /* Call the division routine. */
3974 set_tok_reg (newtok[0], AXP_REG_AT);
3975 set_tok_cpreg (newtok[1], AXP_REG_AT);
3976 set_tok_const (newtok[2], 0);
3977 assemble_tokens ("jsr", newtok, 3, 1);
3979 /* Move the result to the right place. */
3980 if (rr != AXP_REG_R0)
3982 set_tok_reg (newtok[0], AXP_REG_R0);
3983 set_tok_reg (newtok[1], rr);
3984 assemble_tokens ("mov", newtok, 2, 1);
3988 #else /* !OBJ_EVAX */
3990 static void
3991 emit_division (tok, ntok, symname)
3992 const expressionS *tok;
3993 int ntok;
3994 const PTR symname;
3996 /* DIVISION and MODULUS. Yech.
3997 Convert
3998 OP x,y,result
4000 lda pv,__OP
4001 mov x,t10
4002 mov y,t11
4003 jsr t9,(pv),__OP
4004 mov t12,result
4006 with appropriate optimizations if t10,t11,t12 are the registers
4007 specified by the compiler. */
4009 int xr, yr, rr;
4010 symbolS *sym;
4011 expressionS newtok[3];
4013 xr = regno (tok[0].X_add_number);
4014 yr = regno (tok[1].X_add_number);
4016 if (ntok < 3)
4017 rr = xr;
4018 else
4019 rr = regno (tok[2].X_add_number);
4021 sym = symbol_find_or_make ((const char *) symname);
4023 /* Move the operands into the right place. */
4024 if (yr == AXP_REG_T10 && xr == AXP_REG_T11)
4026 /* They are in exactly the wrong order -- swap through AT. */
4027 if (alpha_noat_on)
4028 as_bad (_("macro requires $at register while noat in effect"));
4030 set_tok_reg (newtok[0], AXP_REG_T10);
4031 set_tok_reg (newtok[1], AXP_REG_AT);
4032 assemble_tokens ("mov", newtok, 2, 1);
4034 set_tok_reg (newtok[0], AXP_REG_T11);
4035 set_tok_reg (newtok[1], AXP_REG_T10);
4036 assemble_tokens ("mov", newtok, 2, 1);
4038 set_tok_reg (newtok[0], AXP_REG_AT);
4039 set_tok_reg (newtok[1], AXP_REG_T11);
4040 assemble_tokens ("mov", newtok, 2, 1);
4042 else
4044 if (yr == AXP_REG_T10)
4046 set_tok_reg (newtok[0], AXP_REG_T10);
4047 set_tok_reg (newtok[1], AXP_REG_T11);
4048 assemble_tokens ("mov", newtok, 2, 1);
4051 if (xr != AXP_REG_T10)
4053 set_tok_reg (newtok[0], xr);
4054 set_tok_reg (newtok[1], AXP_REG_T10);
4055 assemble_tokens ("mov", newtok, 2, 1);
4058 if (yr != AXP_REG_T10 && yr != AXP_REG_T11)
4060 set_tok_reg (newtok[0], yr);
4061 set_tok_reg (newtok[1], AXP_REG_T11);
4062 assemble_tokens ("mov", newtok, 2, 1);
4066 /* Call the division routine. */
4067 set_tok_reg (newtok[0], AXP_REG_T9);
4068 set_tok_sym (newtok[1], sym, 0);
4069 assemble_tokens ("jsr", newtok, 2, 1);
4071 /* Reload the GP register. */
4072 #ifdef OBJ_AOUT
4073 FIXME
4074 #endif
4075 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
4076 set_tok_reg (newtok[0], alpha_gp_register);
4077 set_tok_const (newtok[1], 0);
4078 set_tok_preg (newtok[2], AXP_REG_T9);
4079 assemble_tokens ("ldgp", newtok, 3, 1);
4080 #endif
4082 /* Move the result to the right place. */
4083 if (rr != AXP_REG_T12)
4085 set_tok_reg (newtok[0], AXP_REG_T12);
4086 set_tok_reg (newtok[1], rr);
4087 assemble_tokens ("mov", newtok, 2, 1);
4091 #endif /* !OBJ_EVAX */
4093 /* The jsr and jmp macros differ from their instruction counterparts
4094 in that they can load the target address and default most
4095 everything. */
4097 static void
4098 emit_jsrjmp (tok, ntok, vopname)
4099 const expressionS *tok;
4100 int ntok;
4101 const PTR vopname;
4103 const char *opname = (const char *) vopname;
4104 struct alpha_insn insn;
4105 expressionS newtok[3];
4106 int r, tokidx = 0;
4107 long lituse = 0;
4109 if (tokidx < ntok && tok[tokidx].X_op == O_register)
4110 r = regno (tok[tokidx++].X_add_number);
4111 else
4112 r = strcmp (opname, "jmp") == 0 ? AXP_REG_ZERO : AXP_REG_RA;
4114 set_tok_reg (newtok[0], r);
4116 if (tokidx < ntok &&
4117 (tok[tokidx].X_op == O_pregister || tok[tokidx].X_op == O_cpregister))
4118 r = regno (tok[tokidx++].X_add_number);
4119 #ifdef OBJ_EVAX
4120 /* keep register if jsr $n.<sym> */
4121 #else
4122 else
4124 int basereg = alpha_gp_register;
4125 lituse = load_expression (r = AXP_REG_PV, &tok[tokidx], &basereg, NULL);
4127 #endif
4129 set_tok_cpreg (newtok[1], r);
4131 #ifdef OBJ_EVAX
4132 /* FIXME: Add hint relocs to BFD for evax. */
4133 #else
4134 if (tokidx < ntok)
4135 newtok[2] = tok[tokidx];
4136 else
4137 #endif
4138 set_tok_const (newtok[2], 0);
4140 assemble_tokens_to_insn (opname, newtok, 3, &insn);
4142 if (lituse)
4144 assert (insn.nfixups < MAX_INSN_FIXUPS);
4145 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_JSR;
4146 insn.fixups[insn.nfixups].exp.X_op = O_absent;
4147 insn.nfixups++;
4148 insn.sequence = lituse;
4151 emit_insn (&insn);
4154 /* The ret and jcr instructions differ from their instruction
4155 counterparts in that everything can be defaulted. */
4157 static void
4158 emit_retjcr (tok, ntok, vopname)
4159 const expressionS *tok;
4160 int ntok;
4161 const PTR vopname;
4163 const char *opname = (const char *) vopname;
4164 expressionS newtok[3];
4165 int r, tokidx = 0;
4167 if (tokidx < ntok && tok[tokidx].X_op == O_register)
4168 r = regno (tok[tokidx++].X_add_number);
4169 else
4170 r = AXP_REG_ZERO;
4172 set_tok_reg (newtok[0], r);
4174 if (tokidx < ntok &&
4175 (tok[tokidx].X_op == O_pregister || tok[tokidx].X_op == O_cpregister))
4176 r = regno (tok[tokidx++].X_add_number);
4177 else
4178 r = AXP_REG_RA;
4180 set_tok_cpreg (newtok[1], r);
4182 if (tokidx < ntok)
4183 newtok[2] = tok[tokidx];
4184 else
4185 set_tok_const (newtok[2], strcmp (opname, "ret") == 0);
4187 assemble_tokens (opname, newtok, 3, 0);
4190 /* Assembler directives. */
4192 /* Handle the .text pseudo-op. This is like the usual one, but it
4193 clears alpha_insn_label and restores auto alignment. */
4195 static void
4196 s_alpha_text (i)
4197 int i;
4200 #ifdef OBJ_ELF
4201 obj_elf_text (i);
4202 #else
4203 s_text (i);
4204 #endif
4205 alpha_insn_label = NULL;
4206 alpha_auto_align_on = 1;
4207 alpha_current_align = 0;
4210 /* Handle the .data pseudo-op. This is like the usual one, but it
4211 clears alpha_insn_label and restores auto alignment. */
4213 static void
4214 s_alpha_data (i)
4215 int i;
4217 #ifdef OBJ_ELF
4218 obj_elf_data (i);
4219 #else
4220 s_data (i);
4221 #endif
4222 alpha_insn_label = NULL;
4223 alpha_auto_align_on = 1;
4224 alpha_current_align = 0;
4227 #if defined (OBJ_ECOFF) || defined (OBJ_EVAX)
4229 /* Handle the OSF/1 and openVMS .comm pseudo quirks.
4230 openVMS constructs a section for every common symbol. */
4232 static void
4233 s_alpha_comm (ignore)
4234 int ignore ATTRIBUTE_UNUSED;
4236 register char *name;
4237 register char c;
4238 register char *p;
4239 offsetT temp;
4240 register symbolS *symbolP;
4242 #ifdef OBJ_EVAX
4243 segT current_section = now_seg;
4244 int current_subsec = now_subseg;
4245 segT new_seg;
4246 #endif
4248 name = input_line_pointer;
4249 c = get_symbol_end ();
4251 /* just after name is now '\0' */
4252 p = input_line_pointer;
4253 *p = c;
4255 SKIP_WHITESPACE ();
4257 /* Alpha OSF/1 compiler doesn't provide the comma, gcc does. */
4258 if (*input_line_pointer == ',')
4260 input_line_pointer++;
4261 SKIP_WHITESPACE ();
4263 if ((temp = get_absolute_expression ()) < 0)
4265 as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) temp);
4266 ignore_rest_of_line ();
4267 return;
4270 *p = 0;
4271 symbolP = symbol_find_or_make (name);
4273 #ifdef OBJ_EVAX
4274 /* Make a section for the common symbol. */
4275 new_seg = subseg_new (xstrdup (name), 0);
4276 #endif
4278 *p = c;
4280 #ifdef OBJ_EVAX
4281 /* alignment might follow */
4282 if (*input_line_pointer == ',')
4284 offsetT align;
4286 input_line_pointer++;
4287 align = get_absolute_expression ();
4288 bfd_set_section_alignment (stdoutput, new_seg, align);
4290 #endif
4292 if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
4294 as_bad (_("Ignoring attempt to re-define symbol"));
4295 ignore_rest_of_line ();
4296 return;
4299 #ifdef OBJ_EVAX
4300 if (bfd_section_size (stdoutput, new_seg) > 0)
4302 if (bfd_section_size (stdoutput, new_seg) != temp)
4303 as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
4304 S_GET_NAME (symbolP),
4305 (long) bfd_section_size (stdoutput, new_seg),
4306 (long) temp);
4308 #else
4309 if (S_GET_VALUE (symbolP))
4311 if (S_GET_VALUE (symbolP) != (valueT) temp)
4312 as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
4313 S_GET_NAME (symbolP),
4314 (long) S_GET_VALUE (symbolP),
4315 (long) temp);
4317 #endif
4318 else
4320 #ifdef OBJ_EVAX
4321 subseg_set (new_seg, 0);
4322 p = frag_more (temp);
4323 new_seg->flags |= SEC_IS_COMMON;
4324 if (! S_IS_DEFINED (symbolP))
4325 S_SET_SEGMENT (symbolP, new_seg);
4326 #else
4327 S_SET_VALUE (symbolP, (valueT) temp);
4328 #endif
4329 S_SET_EXTERNAL (symbolP);
4332 #ifdef OBJ_EVAX
4333 subseg_set (current_section, current_subsec);
4334 #endif
4336 know (symbol_get_frag (symbolP) == &zero_address_frag);
4338 demand_empty_rest_of_line ();
4341 #endif /* ! OBJ_ELF */
4343 #ifdef OBJ_ECOFF
4345 /* Handle the .rdata pseudo-op. This is like the usual one, but it
4346 clears alpha_insn_label and restores auto alignment. */
4348 static void
4349 s_alpha_rdata (ignore)
4350 int ignore ATTRIBUTE_UNUSED;
4352 int temp;
4354 temp = get_absolute_expression ();
4355 subseg_new (".rdata", 0);
4356 demand_empty_rest_of_line ();
4357 alpha_insn_label = NULL;
4358 alpha_auto_align_on = 1;
4359 alpha_current_align = 0;
4362 #endif
4364 #ifdef OBJ_ECOFF
4366 /* Handle the .sdata pseudo-op. This is like the usual one, but it
4367 clears alpha_insn_label and restores auto alignment. */
4369 static void
4370 s_alpha_sdata (ignore)
4371 int ignore ATTRIBUTE_UNUSED;
4373 int temp;
4375 temp = get_absolute_expression ();
4376 subseg_new (".sdata", 0);
4377 demand_empty_rest_of_line ();
4378 alpha_insn_label = NULL;
4379 alpha_auto_align_on = 1;
4380 alpha_current_align = 0;
4382 #endif
4384 #ifdef OBJ_ELF
4386 /* Handle the .section pseudo-op. This is like the usual one, but it
4387 clears alpha_insn_label and restores auto alignment. */
4389 static void
4390 s_alpha_section (ignore)
4391 int ignore ATTRIBUTE_UNUSED;
4393 obj_elf_section (ignore);
4395 alpha_insn_label = NULL;
4396 alpha_auto_align_on = 1;
4397 alpha_current_align = 0;
4400 static void
4401 s_alpha_ent (dummy)
4402 int dummy ATTRIBUTE_UNUSED;
4404 if (ECOFF_DEBUGGING)
4405 ecoff_directive_ent (0);
4406 else
4408 char *name, name_end;
4409 name = input_line_pointer;
4410 name_end = get_symbol_end ();
4412 if (! is_name_beginner (*name))
4414 as_warn (_(".ent directive has no name"));
4415 *input_line_pointer = name_end;
4417 else
4419 symbolS *sym;
4421 if (alpha_cur_ent_sym)
4422 as_warn (_("nested .ent directives"));
4424 sym = symbol_find_or_make (name);
4425 symbol_get_bfdsym (sym)->flags |= BSF_FUNCTION;
4426 alpha_cur_ent_sym = sym;
4428 /* The .ent directive is sometimes followed by a number. Not sure
4429 what it really means, but ignore it. */
4430 *input_line_pointer = name_end;
4431 SKIP_WHITESPACE ();
4432 if (*input_line_pointer == ',')
4434 input_line_pointer++;
4435 SKIP_WHITESPACE ();
4437 if (ISDIGIT (*input_line_pointer) || *input_line_pointer == '-')
4438 (void) get_absolute_expression ();
4440 demand_empty_rest_of_line ();
4444 static void
4445 s_alpha_end (dummy)
4446 int dummy ATTRIBUTE_UNUSED;
4448 if (ECOFF_DEBUGGING)
4449 ecoff_directive_end (0);
4450 else
4452 char *name, name_end;
4453 name = input_line_pointer;
4454 name_end = get_symbol_end ();
4456 if (! is_name_beginner (*name))
4458 as_warn (_(".end directive has no name"));
4459 *input_line_pointer = name_end;
4461 else
4463 symbolS *sym;
4465 sym = symbol_find (name);
4466 if (sym != alpha_cur_ent_sym)
4467 as_warn (_(".end directive names different symbol than .ent"));
4469 /* Create an expression to calculate the size of the function. */
4470 if (sym)
4472 symbol_get_obj (sym)->size =
4473 (expressionS *) xmalloc (sizeof (expressionS));
4474 symbol_get_obj (sym)->size->X_op = O_subtract;
4475 symbol_get_obj (sym)->size->X_add_symbol
4476 = symbol_new ("L0\001", now_seg, frag_now_fix (), frag_now);
4477 symbol_get_obj (sym)->size->X_op_symbol = sym;
4478 symbol_get_obj (sym)->size->X_add_number = 0;
4481 alpha_cur_ent_sym = NULL;
4483 *input_line_pointer = name_end;
4485 demand_empty_rest_of_line ();
4489 static void
4490 s_alpha_mask (fp)
4491 int fp;
4493 if (ECOFF_DEBUGGING)
4495 if (fp)
4496 ecoff_directive_fmask (0);
4497 else
4498 ecoff_directive_mask (0);
4500 else
4501 discard_rest_of_line ();
4504 static void
4505 s_alpha_frame (dummy)
4506 int dummy ATTRIBUTE_UNUSED;
4508 if (ECOFF_DEBUGGING)
4509 ecoff_directive_frame (0);
4510 else
4511 discard_rest_of_line ();
4514 static void
4515 s_alpha_prologue (ignore)
4516 int ignore ATTRIBUTE_UNUSED;
4518 symbolS *sym;
4519 int arg;
4521 arg = get_absolute_expression ();
4522 demand_empty_rest_of_line ();
4524 if (ECOFF_DEBUGGING)
4525 sym = ecoff_get_cur_proc_sym ();
4526 else
4527 sym = alpha_cur_ent_sym;
4529 if (sym == NULL)
4531 as_bad (_(".prologue directive without a preceding .ent directive"));
4532 return;
4535 switch (arg)
4537 case 0: /* No PV required. */
4538 S_SET_OTHER (sym, STO_ALPHA_NOPV
4539 | (S_GET_OTHER (sym) & ~STO_ALPHA_STD_GPLOAD));
4540 break;
4541 case 1: /* Std GP load. */
4542 S_SET_OTHER (sym, STO_ALPHA_STD_GPLOAD
4543 | (S_GET_OTHER (sym) & ~STO_ALPHA_STD_GPLOAD));
4544 break;
4545 case 2: /* Non-std use of PV. */
4546 break;
4548 default:
4549 as_bad (_("Invalid argument %d to .prologue."), arg);
4550 break;
4554 static char *first_file_directive;
4556 static void
4557 s_alpha_file (ignore)
4558 int ignore ATTRIBUTE_UNUSED;
4560 /* Save the first .file directive we see, so that we can change our
4561 minds about whether ecoff debugging should or shouldn't be enabled. */
4562 if (alpha_flag_mdebug < 0 && ! first_file_directive)
4564 char *start = input_line_pointer;
4565 size_t len;
4567 discard_rest_of_line ();
4569 len = input_line_pointer - start;
4570 first_file_directive = xmalloc (len + 1);
4571 memcpy (first_file_directive, start, len);
4572 first_file_directive[len] = '\0';
4574 input_line_pointer = start;
4577 if (ECOFF_DEBUGGING)
4578 ecoff_directive_file (0);
4579 else
4580 dwarf2_directive_file (0);
4583 static void
4584 s_alpha_loc (ignore)
4585 int ignore ATTRIBUTE_UNUSED;
4587 if (ECOFF_DEBUGGING)
4588 ecoff_directive_loc (0);
4589 else
4590 dwarf2_directive_loc (0);
4593 static void
4594 s_alpha_stab (n)
4595 int n;
4597 /* If we've been undecided about mdebug, make up our minds in favour. */
4598 if (alpha_flag_mdebug < 0)
4600 segT sec = subseg_new (".mdebug", 0);
4601 bfd_set_section_flags (stdoutput, sec, SEC_HAS_CONTENTS | SEC_READONLY);
4602 bfd_set_section_alignment (stdoutput, sec, 3);
4604 ecoff_read_begin_hook ();
4606 if (first_file_directive)
4608 char *save_ilp = input_line_pointer;
4609 input_line_pointer = first_file_directive;
4610 ecoff_directive_file (0);
4611 input_line_pointer = save_ilp;
4612 free (first_file_directive);
4615 alpha_flag_mdebug = 1;
4617 s_stab (n);
4620 static void
4621 s_alpha_coff_wrapper (which)
4622 int which;
4624 static void (* const fns[]) PARAMS ((int)) = {
4625 ecoff_directive_begin,
4626 ecoff_directive_bend,
4627 ecoff_directive_def,
4628 ecoff_directive_dim,
4629 ecoff_directive_endef,
4630 ecoff_directive_scl,
4631 ecoff_directive_tag,
4632 ecoff_directive_val,
4635 assert (which >= 0 && which < (int) (sizeof (fns)/sizeof (*fns)));
4637 if (ECOFF_DEBUGGING)
4638 (*fns[which]) (0);
4639 else
4641 as_bad (_("ECOFF debugging is disabled."));
4642 ignore_rest_of_line ();
4645 #endif /* OBJ_ELF */
4647 #ifdef OBJ_EVAX
4649 /* Handle the section specific pseudo-op. */
4651 static void
4652 s_alpha_section (secid)
4653 int secid;
4655 int temp;
4656 #define EVAX_SECTION_COUNT 5
4657 static char *section_name[EVAX_SECTION_COUNT + 1] =
4658 { "NULL", ".rdata", ".comm", ".link", ".ctors", ".dtors" };
4660 if ((secid <= 0) || (secid > EVAX_SECTION_COUNT))
4662 as_fatal (_("Unknown section directive"));
4663 demand_empty_rest_of_line ();
4664 return;
4666 temp = get_absolute_expression ();
4667 subseg_new (section_name[secid], 0);
4668 demand_empty_rest_of_line ();
4669 alpha_insn_label = NULL;
4670 alpha_auto_align_on = 1;
4671 alpha_current_align = 0;
4674 /* Parse .ent directives. */
4676 static void
4677 s_alpha_ent (ignore)
4678 int ignore ATTRIBUTE_UNUSED;
4680 symbolS *symbol;
4681 expressionS symexpr;
4683 alpha_evax_proc.pdsckind = 0;
4684 alpha_evax_proc.framereg = -1;
4685 alpha_evax_proc.framesize = 0;
4686 alpha_evax_proc.rsa_offset = 0;
4687 alpha_evax_proc.ra_save = AXP_REG_RA;
4688 alpha_evax_proc.fp_save = -1;
4689 alpha_evax_proc.imask = 0;
4690 alpha_evax_proc.fmask = 0;
4691 alpha_evax_proc.prologue = 0;
4692 alpha_evax_proc.type = 0;
4694 expression (&symexpr);
4696 if (symexpr.X_op != O_symbol)
4698 as_fatal (_(".ent directive has no symbol"));
4699 demand_empty_rest_of_line ();
4700 return;
4703 symbol = make_expr_symbol (&symexpr);
4704 symbol_get_bfdsym (symbol)->flags |= BSF_FUNCTION;
4705 alpha_evax_proc.symbol = symbol;
4707 demand_empty_rest_of_line ();
4708 return;
4711 /* Parse .frame <framreg>,<framesize>,RA,<rsa_offset> directives. */
4713 static void
4714 s_alpha_frame (ignore)
4715 int ignore ATTRIBUTE_UNUSED;
4717 long val;
4719 alpha_evax_proc.framereg = tc_get_register (1);
4721 SKIP_WHITESPACE ();
4722 if (*input_line_pointer++ != ','
4723 || get_absolute_expression_and_terminator (&val) != ',')
4725 as_warn (_("Bad .frame directive 1./2. param"));
4726 --input_line_pointer;
4727 demand_empty_rest_of_line ();
4728 return;
4731 alpha_evax_proc.framesize = val;
4733 (void) tc_get_register (1);
4734 SKIP_WHITESPACE ();
4735 if (*input_line_pointer++ != ',')
4737 as_warn (_("Bad .frame directive 3./4. param"));
4738 --input_line_pointer;
4739 demand_empty_rest_of_line ();
4740 return;
4742 alpha_evax_proc.rsa_offset = get_absolute_expression ();
4744 return;
4747 static void
4748 s_alpha_pdesc (ignore)
4749 int ignore ATTRIBUTE_UNUSED;
4751 char *name;
4752 char name_end;
4753 long val;
4754 register char *p;
4755 expressionS exp;
4756 symbolS *entry_sym;
4757 fixS *fixp;
4758 segment_info_type *seginfo = seg_info (alpha_link_section);
4760 if (now_seg != alpha_link_section)
4762 as_bad (_(".pdesc directive not in link (.link) section"));
4763 demand_empty_rest_of_line ();
4764 return;
4767 if ((alpha_evax_proc.symbol == 0)
4768 || (!S_IS_DEFINED (alpha_evax_proc.symbol)))
4770 as_fatal (_(".pdesc has no matching .ent"));
4771 demand_empty_rest_of_line ();
4772 return;
4775 *symbol_get_obj (alpha_evax_proc.symbol) =
4776 (valueT) seginfo->literal_pool_size;
4778 expression (&exp);
4779 if (exp.X_op != O_symbol)
4781 as_warn (_(".pdesc directive has no entry symbol"));
4782 demand_empty_rest_of_line ();
4783 return;
4786 entry_sym = make_expr_symbol (&exp);
4787 /* Save bfd symbol of proc desc in function symbol. */
4788 symbol_get_bfdsym (alpha_evax_proc.symbol)->udata.p
4789 = symbol_get_bfdsym (entry_sym);
4791 SKIP_WHITESPACE ();
4792 if (*input_line_pointer++ != ',')
4794 as_warn (_("No comma after .pdesc <entryname>"));
4795 demand_empty_rest_of_line ();
4796 return;
4799 SKIP_WHITESPACE ();
4800 name = input_line_pointer;
4801 name_end = get_symbol_end ();
4803 if (strncmp (name, "stack", 5) == 0)
4805 alpha_evax_proc.pdsckind = PDSC_S_K_KIND_FP_STACK;
4807 else if (strncmp (name, "reg", 3) == 0)
4809 alpha_evax_proc.pdsckind = PDSC_S_K_KIND_FP_REGISTER;
4811 else if (strncmp (name, "null", 4) == 0)
4813 alpha_evax_proc.pdsckind = PDSC_S_K_KIND_NULL;
4815 else
4817 as_fatal (_("unknown procedure kind"));
4818 demand_empty_rest_of_line ();
4819 return;
4822 *input_line_pointer = name_end;
4823 demand_empty_rest_of_line ();
4825 #ifdef md_flush_pending_output
4826 md_flush_pending_output ();
4827 #endif
4829 frag_align (3, 0, 0);
4830 p = frag_more (16);
4831 fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
4832 fixp->fx_done = 1;
4833 seginfo->literal_pool_size += 16;
4835 *p = alpha_evax_proc.pdsckind
4836 | ((alpha_evax_proc.framereg == 29) ? PDSC_S_M_BASE_REG_IS_FP : 0);
4837 *(p + 1) = PDSC_S_M_NATIVE | PDSC_S_M_NO_JACKET;
4839 switch (alpha_evax_proc.pdsckind)
4841 case PDSC_S_K_KIND_NULL:
4842 *(p + 2) = 0;
4843 *(p + 3) = 0;
4844 break;
4845 case PDSC_S_K_KIND_FP_REGISTER:
4846 *(p + 2) = alpha_evax_proc.fp_save;
4847 *(p + 3) = alpha_evax_proc.ra_save;
4848 break;
4849 case PDSC_S_K_KIND_FP_STACK:
4850 md_number_to_chars (p + 2, (valueT) alpha_evax_proc.rsa_offset, 2);
4851 break;
4852 default: /* impossible */
4853 break;
4856 *(p + 4) = 0;
4857 *(p + 5) = alpha_evax_proc.type & 0x0f;
4859 /* Signature offset. */
4860 md_number_to_chars (p + 6, (valueT) 0, 2);
4862 fix_new_exp (frag_now, p - frag_now->fr_literal+8, 8, &exp, 0, BFD_RELOC_64);
4864 if (alpha_evax_proc.pdsckind == PDSC_S_K_KIND_NULL)
4865 return;
4867 /* Add dummy fix to make add_to_link_pool work. */
4868 p = frag_more (8);
4869 fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
4870 fixp->fx_done = 1;
4871 seginfo->literal_pool_size += 8;
4873 /* pdesc+16: Size. */
4874 md_number_to_chars (p, (valueT) alpha_evax_proc.framesize, 4);
4876 md_number_to_chars (p + 4, (valueT) 0, 2);
4878 /* Entry length. */
4879 md_number_to_chars (p + 6, alpha_evax_proc.prologue, 2);
4881 if (alpha_evax_proc.pdsckind == PDSC_S_K_KIND_FP_REGISTER)
4882 return;
4884 /* Add dummy fix to make add_to_link_pool work. */
4885 p = frag_more (8);
4886 fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
4887 fixp->fx_done = 1;
4888 seginfo->literal_pool_size += 8;
4890 /* pdesc+24: register masks. */
4892 md_number_to_chars (p, alpha_evax_proc.imask, 4);
4893 md_number_to_chars (p + 4, alpha_evax_proc.fmask, 4);
4895 return;
4898 /* Support for crash debug on vms. */
4900 static void
4901 s_alpha_name (ignore)
4902 int ignore ATTRIBUTE_UNUSED;
4904 register char *p;
4905 expressionS exp;
4906 segment_info_type *seginfo = seg_info (alpha_link_section);
4908 if (now_seg != alpha_link_section)
4910 as_bad (_(".name directive not in link (.link) section"));
4911 demand_empty_rest_of_line ();
4912 return;
4915 expression (&exp);
4916 if (exp.X_op != O_symbol)
4918 as_warn (_(".name directive has no symbol"));
4919 demand_empty_rest_of_line ();
4920 return;
4923 demand_empty_rest_of_line ();
4925 #ifdef md_flush_pending_output
4926 md_flush_pending_output ();
4927 #endif
4929 frag_align (3, 0, 0);
4930 p = frag_more (8);
4931 seginfo->literal_pool_size += 8;
4933 fix_new_exp (frag_now, p - frag_now->fr_literal, 8, &exp, 0, BFD_RELOC_64);
4935 return;
4938 static void
4939 s_alpha_linkage (ignore)
4940 int ignore ATTRIBUTE_UNUSED;
4942 expressionS exp;
4943 char *p;
4945 #ifdef md_flush_pending_output
4946 md_flush_pending_output ();
4947 #endif
4949 expression (&exp);
4950 if (exp.X_op != O_symbol)
4952 as_fatal (_("No symbol after .linkage"));
4954 else
4956 p = frag_more (LKP_S_K_SIZE);
4957 memset (p, 0, LKP_S_K_SIZE);
4958 fix_new_exp (frag_now, p - frag_now->fr_literal, LKP_S_K_SIZE, &exp, 0,\
4959 BFD_RELOC_ALPHA_LINKAGE);
4961 demand_empty_rest_of_line ();
4963 return;
4966 static void
4967 s_alpha_code_address (ignore)
4968 int ignore ATTRIBUTE_UNUSED;
4970 expressionS exp;
4971 char *p;
4973 #ifdef md_flush_pending_output
4974 md_flush_pending_output ();
4975 #endif
4977 expression (&exp);
4978 if (exp.X_op != O_symbol)
4980 as_fatal (_("No symbol after .code_address"));
4982 else
4984 p = frag_more (8);
4985 memset (p, 0, 8);
4986 fix_new_exp (frag_now, p - frag_now->fr_literal, 8, &exp, 0,\
4987 BFD_RELOC_ALPHA_CODEADDR);
4989 demand_empty_rest_of_line ();
4991 return;
4994 static void
4995 s_alpha_fp_save (ignore)
4996 int ignore ATTRIBUTE_UNUSED;
4999 alpha_evax_proc.fp_save = tc_get_register (1);
5001 demand_empty_rest_of_line ();
5002 return;
5005 static void
5006 s_alpha_mask (ignore)
5007 int ignore ATTRIBUTE_UNUSED;
5009 long val;
5011 if (get_absolute_expression_and_terminator (&val) != ',')
5013 as_warn (_("Bad .mask directive"));
5014 --input_line_pointer;
5016 else
5018 alpha_evax_proc.imask = val;
5019 (void) get_absolute_expression ();
5021 demand_empty_rest_of_line ();
5023 return;
5026 static void
5027 s_alpha_fmask (ignore)
5028 int ignore ATTRIBUTE_UNUSED;
5030 long val;
5032 if (get_absolute_expression_and_terminator (&val) != ',')
5034 as_warn (_("Bad .fmask directive"));
5035 --input_line_pointer;
5037 else
5039 alpha_evax_proc.fmask = val;
5040 (void) get_absolute_expression ();
5042 demand_empty_rest_of_line ();
5044 return;
5047 static void
5048 s_alpha_end (ignore)
5049 int ignore ATTRIBUTE_UNUSED;
5051 char c;
5053 c = get_symbol_end ();
5054 *input_line_pointer = c;
5055 demand_empty_rest_of_line ();
5056 alpha_evax_proc.symbol = 0;
5058 return;
5061 static void
5062 s_alpha_file (ignore)
5063 int ignore ATTRIBUTE_UNUSED;
5065 symbolS *s;
5066 int length;
5067 static char case_hack[32];
5069 extern char *demand_copy_string PARAMS ((int *lenP));
5071 sprintf (case_hack, "<CASE:%01d%01d>",
5072 alpha_flag_hash_long_names, alpha_flag_show_after_trunc);
5074 s = symbol_find_or_make (case_hack);
5075 symbol_get_bfdsym (s)->flags |= BSF_FILE;
5077 get_absolute_expression ();
5078 s = symbol_find_or_make (demand_copy_string (&length));
5079 symbol_get_bfdsym (s)->flags |= BSF_FILE;
5080 demand_empty_rest_of_line ();
5082 return;
5084 #endif /* OBJ_EVAX */
5086 /* Handle the .gprel32 pseudo op. */
5088 static void
5089 s_alpha_gprel32 (ignore)
5090 int ignore ATTRIBUTE_UNUSED;
5092 expressionS e;
5093 char *p;
5095 SKIP_WHITESPACE ();
5096 expression (&e);
5098 #ifdef OBJ_ELF
5099 switch (e.X_op)
5101 case O_constant:
5102 e.X_add_symbol = section_symbol (absolute_section);
5103 e.X_op = O_symbol;
5104 /* FALLTHRU */
5105 case O_symbol:
5106 break;
5107 default:
5108 abort ();
5110 #else
5111 #ifdef OBJ_ECOFF
5112 switch (e.X_op)
5114 case O_constant:
5115 e.X_add_symbol = section_symbol (absolute_section);
5116 /* fall through */
5117 case O_symbol:
5118 e.X_op = O_subtract;
5119 e.X_op_symbol = alpha_gp_symbol;
5120 break;
5121 default:
5122 abort ();
5124 #endif
5125 #endif
5127 if (alpha_auto_align_on && alpha_current_align < 2)
5128 alpha_align (2, (char *) NULL, alpha_insn_label, 0);
5129 if (alpha_current_align > 2)
5130 alpha_current_align = 2;
5131 alpha_insn_label = NULL;
5133 p = frag_more (4);
5134 memset (p, 0, 4);
5135 fix_new_exp (frag_now, p - frag_now->fr_literal, 4,
5136 &e, 0, BFD_RELOC_GPREL32);
5139 /* Handle floating point allocation pseudo-ops. This is like the
5140 generic vresion, but it makes sure the current label, if any, is
5141 correctly aligned. */
5143 static void
5144 s_alpha_float_cons (type)
5145 int type;
5147 int log_size;
5149 switch (type)
5151 default:
5152 case 'f':
5153 case 'F':
5154 log_size = 2;
5155 break;
5157 case 'd':
5158 case 'D':
5159 case 'G':
5160 log_size = 3;
5161 break;
5163 case 'x':
5164 case 'X':
5165 case 'p':
5166 case 'P':
5167 log_size = 4;
5168 break;
5171 if (alpha_auto_align_on && alpha_current_align < log_size)
5172 alpha_align (log_size, (char *) NULL, alpha_insn_label, 0);
5173 if (alpha_current_align > log_size)
5174 alpha_current_align = log_size;
5175 alpha_insn_label = NULL;
5177 float_cons (type);
5180 /* Handle the .proc pseudo op. We don't really do much with it except
5181 parse it. */
5183 static void
5184 s_alpha_proc (is_static)
5185 int is_static ATTRIBUTE_UNUSED;
5187 char *name;
5188 char c;
5189 char *p;
5190 symbolS *symbolP;
5191 int temp;
5193 /* Takes ".proc name,nargs" */
5194 SKIP_WHITESPACE ();
5195 name = input_line_pointer;
5196 c = get_symbol_end ();
5197 p = input_line_pointer;
5198 symbolP = symbol_find_or_make (name);
5199 *p = c;
5200 SKIP_WHITESPACE ();
5201 if (*input_line_pointer != ',')
5203 *p = 0;
5204 as_warn (_("Expected comma after name \"%s\""), name);
5205 *p = c;
5206 temp = 0;
5207 ignore_rest_of_line ();
5209 else
5211 input_line_pointer++;
5212 temp = get_absolute_expression ();
5214 /* *symbol_get_obj (symbolP) = (signed char) temp; */
5215 as_warn (_("unhandled: .proc %s,%d"), name, temp);
5216 demand_empty_rest_of_line ();
5219 /* Handle the .set pseudo op. This is used to turn on and off most of
5220 the assembler features. */
5222 static void
5223 s_alpha_set (x)
5224 int x ATTRIBUTE_UNUSED;
5226 char *name, ch, *s;
5227 int yesno = 1;
5229 SKIP_WHITESPACE ();
5230 name = input_line_pointer;
5231 ch = get_symbol_end ();
5233 s = name;
5234 if (s[0] == 'n' && s[1] == 'o')
5236 yesno = 0;
5237 s += 2;
5239 if (!strcmp ("reorder", s))
5240 /* ignore */ ;
5241 else if (!strcmp ("at", s))
5242 alpha_noat_on = !yesno;
5243 else if (!strcmp ("macro", s))
5244 alpha_macros_on = yesno;
5245 else if (!strcmp ("move", s))
5246 /* ignore */ ;
5247 else if (!strcmp ("volatile", s))
5248 /* ignore */ ;
5249 else
5250 as_warn (_("Tried to .set unrecognized mode `%s'"), name);
5252 *input_line_pointer = ch;
5253 demand_empty_rest_of_line ();
5256 /* Handle the .base pseudo op. This changes the assembler's notion of
5257 the $gp register. */
5259 static void
5260 s_alpha_base (ignore)
5261 int ignore ATTRIBUTE_UNUSED;
5263 #if 0
5264 if (first_32bit_quadrant)
5266 /* not fatal, but it might not work in the end */
5267 as_warn (_("File overrides no-base-register option."));
5268 first_32bit_quadrant = 0;
5270 #endif
5272 SKIP_WHITESPACE ();
5273 if (*input_line_pointer == '$')
5274 { /* $rNN form */
5275 input_line_pointer++;
5276 if (*input_line_pointer == 'r')
5277 input_line_pointer++;
5280 alpha_gp_register = get_absolute_expression ();
5281 if (alpha_gp_register < 0 || alpha_gp_register > 31)
5283 alpha_gp_register = AXP_REG_GP;
5284 as_warn (_("Bad base register, using $%d."), alpha_gp_register);
5287 demand_empty_rest_of_line ();
5290 /* Handle the .align pseudo-op. This aligns to a power of two. It
5291 also adjusts any current instruction label. We treat this the same
5292 way the MIPS port does: .align 0 turns off auto alignment. */
5294 static void
5295 s_alpha_align (ignore)
5296 int ignore ATTRIBUTE_UNUSED;
5298 int align;
5299 char fill, *pfill;
5300 long max_alignment = 15;
5302 align = get_absolute_expression ();
5303 if (align > max_alignment)
5305 align = max_alignment;
5306 as_bad (_("Alignment too large: %d. assumed"), align);
5308 else if (align < 0)
5310 as_warn (_("Alignment negative: 0 assumed"));
5311 align = 0;
5314 if (*input_line_pointer == ',')
5316 input_line_pointer++;
5317 fill = get_absolute_expression ();
5318 pfill = &fill;
5320 else
5321 pfill = NULL;
5323 if (align != 0)
5325 alpha_auto_align_on = 1;
5326 alpha_align (align, pfill, alpha_insn_label, 1);
5328 else
5330 alpha_auto_align_on = 0;
5333 demand_empty_rest_of_line ();
5336 /* Hook the normal string processor to reset known alignment. */
5338 static void
5339 s_alpha_stringer (terminate)
5340 int terminate;
5342 alpha_current_align = 0;
5343 alpha_insn_label = NULL;
5344 stringer (terminate);
5347 /* Hook the normal space processing to reset known alignment. */
5349 static void
5350 s_alpha_space (ignore)
5351 int ignore;
5353 alpha_current_align = 0;
5354 alpha_insn_label = NULL;
5355 s_space (ignore);
5358 /* Hook into cons for auto-alignment. */
5360 void
5361 alpha_cons_align (size)
5362 int size;
5364 int log_size;
5366 log_size = 0;
5367 while ((size >>= 1) != 0)
5368 ++log_size;
5370 if (alpha_auto_align_on && alpha_current_align < log_size)
5371 alpha_align (log_size, (char *) NULL, alpha_insn_label, 0);
5372 if (alpha_current_align > log_size)
5373 alpha_current_align = log_size;
5374 alpha_insn_label = NULL;
5377 /* Here come the .uword, .ulong, and .uquad explicitly unaligned
5378 pseudos. We just turn off auto-alignment and call down to cons. */
5380 static void
5381 s_alpha_ucons (bytes)
5382 int bytes;
5384 int hold = alpha_auto_align_on;
5385 alpha_auto_align_on = 0;
5386 cons (bytes);
5387 alpha_auto_align_on = hold;
5390 /* Switch the working cpu type. */
5392 static void
5393 s_alpha_arch (ignored)
5394 int ignored ATTRIBUTE_UNUSED;
5396 char *name, ch;
5397 const struct cpu_type *p;
5399 SKIP_WHITESPACE ();
5400 name = input_line_pointer;
5401 ch = get_symbol_end ();
5403 for (p = cpu_types; p->name; ++p)
5404 if (strcmp (name, p->name) == 0)
5406 alpha_target_name = p->name, alpha_target = p->flags;
5407 goto found;
5409 as_warn ("Unknown CPU identifier `%s'", name);
5411 found:
5412 *input_line_pointer = ch;
5413 demand_empty_rest_of_line ();
5416 #ifdef DEBUG1
5417 /* print token expression with alpha specific extension. */
5419 static void
5420 alpha_print_token (f, exp)
5421 FILE *f;
5422 const expressionS *exp;
5424 switch (exp->X_op)
5426 case O_cpregister:
5427 putc (',', f);
5428 /* FALLTHRU */
5429 case O_pregister:
5430 putc ('(', f);
5432 expressionS nexp = *exp;
5433 nexp.X_op = O_register;
5434 print_expr (f, &nexp);
5436 putc (')', f);
5437 break;
5438 default:
5439 print_expr (f, exp);
5440 break;
5442 return;
5444 #endif
5446 /* The target specific pseudo-ops which we support. */
5448 const pseudo_typeS md_pseudo_table[] = {
5449 #ifdef OBJ_ECOFF
5450 {"comm", s_alpha_comm, 0}, /* osf1 compiler does this */
5451 {"rdata", s_alpha_rdata, 0},
5452 #endif
5453 {"text", s_alpha_text, 0},
5454 {"data", s_alpha_data, 0},
5455 #ifdef OBJ_ECOFF
5456 {"sdata", s_alpha_sdata, 0},
5457 #endif
5458 #ifdef OBJ_ELF
5459 {"section", s_alpha_section, 0},
5460 {"section.s", s_alpha_section, 0},
5461 {"sect", s_alpha_section, 0},
5462 {"sect.s", s_alpha_section, 0},
5463 #endif
5464 #ifdef OBJ_EVAX
5465 { "pdesc", s_alpha_pdesc, 0},
5466 { "name", s_alpha_name, 0},
5467 { "linkage", s_alpha_linkage, 0},
5468 { "code_address", s_alpha_code_address, 0},
5469 { "ent", s_alpha_ent, 0},
5470 { "frame", s_alpha_frame, 0},
5471 { "fp_save", s_alpha_fp_save, 0},
5472 { "mask", s_alpha_mask, 0},
5473 { "fmask", s_alpha_fmask, 0},
5474 { "end", s_alpha_end, 0},
5475 { "file", s_alpha_file, 0},
5476 { "rdata", s_alpha_section, 1},
5477 { "comm", s_alpha_comm, 0},
5478 { "link", s_alpha_section, 3},
5479 { "ctors", s_alpha_section, 4},
5480 { "dtors", s_alpha_section, 5},
5481 #endif
5482 #ifdef OBJ_ELF
5483 /* Frame related pseudos. */
5484 {"ent", s_alpha_ent, 0},
5485 {"end", s_alpha_end, 0},
5486 {"mask", s_alpha_mask, 0},
5487 {"fmask", s_alpha_mask, 1},
5488 {"frame", s_alpha_frame, 0},
5489 {"prologue", s_alpha_prologue, 0},
5490 {"file", s_alpha_file, 5},
5491 {"loc", s_alpha_loc, 9},
5492 {"stabs", s_alpha_stab, 's'},
5493 {"stabn", s_alpha_stab, 'n'},
5494 /* COFF debugging related pseudos. */
5495 {"begin", s_alpha_coff_wrapper, 0},
5496 {"bend", s_alpha_coff_wrapper, 1},
5497 {"def", s_alpha_coff_wrapper, 2},
5498 {"dim", s_alpha_coff_wrapper, 3},
5499 {"endef", s_alpha_coff_wrapper, 4},
5500 {"scl", s_alpha_coff_wrapper, 5},
5501 {"tag", s_alpha_coff_wrapper, 6},
5502 {"val", s_alpha_coff_wrapper, 7},
5503 #else
5504 {"prologue", s_ignore, 0},
5505 #endif
5506 {"gprel32", s_alpha_gprel32, 0},
5507 {"t_floating", s_alpha_float_cons, 'd'},
5508 {"s_floating", s_alpha_float_cons, 'f'},
5509 {"f_floating", s_alpha_float_cons, 'F'},
5510 {"g_floating", s_alpha_float_cons, 'G'},
5511 {"d_floating", s_alpha_float_cons, 'D'},
5513 {"proc", s_alpha_proc, 0},
5514 {"aproc", s_alpha_proc, 1},
5515 {"set", s_alpha_set, 0},
5516 {"reguse", s_ignore, 0},
5517 {"livereg", s_ignore, 0},
5518 {"base", s_alpha_base, 0}, /*??*/
5519 {"option", s_ignore, 0},
5520 {"aent", s_ignore, 0},
5521 {"ugen", s_ignore, 0},
5522 {"eflag", s_ignore, 0},
5524 {"align", s_alpha_align, 0},
5525 {"double", s_alpha_float_cons, 'd'},
5526 {"float", s_alpha_float_cons, 'f'},
5527 {"single", s_alpha_float_cons, 'f'},
5528 {"ascii", s_alpha_stringer, 0},
5529 {"asciz", s_alpha_stringer, 1},
5530 {"string", s_alpha_stringer, 1},
5531 {"space", s_alpha_space, 0},
5532 {"skip", s_alpha_space, 0},
5533 {"zero", s_alpha_space, 0},
5535 /* Unaligned data pseudos. */
5536 {"uword", s_alpha_ucons, 2},
5537 {"ulong", s_alpha_ucons, 4},
5538 {"uquad", s_alpha_ucons, 8},
5540 #ifdef OBJ_ELF
5541 /* Dwarf wants these versions of unaligned. */
5542 {"2byte", s_alpha_ucons, 2},
5543 {"4byte", s_alpha_ucons, 4},
5544 {"8byte", s_alpha_ucons, 8},
5545 #endif
5547 /* We don't do any optimizing, so we can safely ignore these. */
5548 {"noalias", s_ignore, 0},
5549 {"alias", s_ignore, 0},
5551 {"arch", s_alpha_arch, 0},
5553 {NULL, 0, 0},
5556 /* Build a BFD section with its flags set appropriately for the .lita,
5557 .lit8, or .lit4 sections. */
5559 static void
5560 create_literal_section (name, secp, symp)
5561 const char *name;
5562 segT *secp;
5563 symbolS **symp;
5565 segT current_section = now_seg;
5566 int current_subsec = now_subseg;
5567 segT new_sec;
5569 *secp = new_sec = subseg_new (name, 0);
5570 subseg_set (current_section, current_subsec);
5571 bfd_set_section_alignment (stdoutput, new_sec, 4);
5572 bfd_set_section_flags (stdoutput, new_sec,
5573 SEC_RELOC | SEC_ALLOC | SEC_LOAD | SEC_READONLY
5574 | SEC_DATA);
5576 S_CLEAR_EXTERNAL (*symp = section_symbol (new_sec));
5579 #ifdef OBJ_ECOFF
5581 /* @@@ GP selection voodoo. All of this seems overly complicated and
5582 unnecessary; which is the primary reason it's for ECOFF only. */
5583 static inline void maybe_set_gp PARAMS ((asection *));
5585 static inline void
5586 maybe_set_gp (sec)
5587 asection *sec;
5589 bfd_vma vma;
5590 if (!sec)
5591 return;
5592 vma = bfd_get_section_vma (foo, sec);
5593 if (vma && vma < alpha_gp_value)
5594 alpha_gp_value = vma;
5597 static void
5598 select_gp_value ()
5600 assert (alpha_gp_value == 0);
5602 /* Get minus-one in whatever width... */
5603 alpha_gp_value = 0;
5604 alpha_gp_value--;
5606 /* Select the smallest VMA of these existing sections. */
5607 maybe_set_gp (alpha_lita_section);
5608 #if 0
5609 /* These were disabled before -- should we use them? */
5610 maybe_set_gp (sdata);
5611 maybe_set_gp (lit8_sec);
5612 maybe_set_gp (lit4_sec);
5613 #endif
5615 /* @@ Will a simple 0x8000 work here? If not, why not? */
5616 #define GP_ADJUSTMENT (0x8000 - 0x10)
5618 alpha_gp_value += GP_ADJUSTMENT;
5620 S_SET_VALUE (alpha_gp_symbol, alpha_gp_value);
5622 #ifdef DEBUG1
5623 printf (_("Chose GP value of %lx\n"), alpha_gp_value);
5624 #endif
5626 #endif /* OBJ_ECOFF */
5628 #ifdef OBJ_ELF
5629 /* Map 's' to SHF_ALPHA_GPREL. */
5632 alpha_elf_section_letter (letter, ptr_msg)
5633 int letter;
5634 char **ptr_msg;
5636 if (letter == 's')
5637 return SHF_ALPHA_GPREL;
5639 *ptr_msg = _("Bad .section directive: want a,s,w,x,M,S,G,T in string");
5640 return 0;
5643 /* Map SHF_ALPHA_GPREL to SEC_SMALL_DATA. */
5645 flagword
5646 alpha_elf_section_flags (flags, attr, type)
5647 flagword flags;
5648 int attr, type ATTRIBUTE_UNUSED;
5650 if (attr & SHF_ALPHA_GPREL)
5651 flags |= SEC_SMALL_DATA;
5652 return flags;
5654 #endif /* OBJ_ELF */
5656 /* Called internally to handle all alignment needs. This takes care
5657 of eliding calls to frag_align if'n the cached current alignment
5658 says we've already got it, as well as taking care of the auto-align
5659 feature wrt labels. */
5661 static void
5662 alpha_align (n, pfill, label, force)
5663 int n;
5664 char *pfill;
5665 symbolS *label;
5666 int force ATTRIBUTE_UNUSED;
5668 if (alpha_current_align >= n)
5669 return;
5671 if (pfill == NULL)
5673 if (subseg_text_p (now_seg))
5674 frag_align_code (n, 0);
5675 else
5676 frag_align (n, 0, 0);
5678 else
5679 frag_align (n, *pfill, 0);
5681 alpha_current_align = n;
5683 if (label != NULL && S_GET_SEGMENT (label) == now_seg)
5685 symbol_set_frag (label, frag_now);
5686 S_SET_VALUE (label, (valueT) frag_now_fix ());
5689 record_alignment (now_seg, n);
5691 /* ??? If alpha_flag_relax && force && elf, record the requested alignment
5692 in a reloc for the linker to see. */
5695 /* This is called from HANDLE_ALIGN in write.c. Fill in the contents
5696 of an rs_align_code fragment. */
5698 void
5699 alpha_handle_align (fragp)
5700 fragS *fragp;
5702 static char const unop[4] = { 0x00, 0x00, 0xfe, 0x2f };
5703 static char const nopunop[8] = {
5704 0x1f, 0x04, 0xff, 0x47,
5705 0x00, 0x00, 0xfe, 0x2f
5708 int bytes, fix;
5709 char *p;
5711 if (fragp->fr_type != rs_align_code)
5712 return;
5714 bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix;
5715 p = fragp->fr_literal + fragp->fr_fix;
5716 fix = 0;
5718 if (bytes & 3)
5720 fix = bytes & 3;
5721 memset (p, 0, fix);
5722 p += fix;
5723 bytes -= fix;
5726 if (bytes & 4)
5728 memcpy (p, unop, 4);
5729 p += 4;
5730 bytes -= 4;
5731 fix += 4;
5734 memcpy (p, nopunop, 8);
5736 fragp->fr_fix += fix;
5737 fragp->fr_var = 8;
5740 /* The Alpha has support for some VAX floating point types, as well as for
5741 IEEE floating point. We consider IEEE to be the primary floating point
5742 format, and sneak in the VAX floating point support here. */
5743 #define md_atof vax_md_atof
5744 #include "config/atof-vax.c"