* chew.c (paramstuff, outputdots, perform, bang and usage): Remove
[binutils.git] / gas / config / tc-alpha.c
blobb84fa582a4205848e381f8628a81f5982b999a2c
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 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_symtab_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_ALPHA_GPDISP:
1143 case BFD_RELOC_ALPHA_GPDISP_HI16:
1144 case BFD_RELOC_ALPHA_GPDISP_LO16:
1145 return addr;
1146 default:
1147 return fixP->fx_size + 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; we need to drop in a value
1175 which, when added to the address of the start of the function,
1176 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 case BFD_RELOC_ALPHA_TLSGD:
1265 case BFD_RELOC_ALPHA_TLSLDM:
1266 case BFD_RELOC_ALPHA_GOTDTPREL16:
1267 case BFD_RELOC_ALPHA_DTPREL_HI16:
1268 case BFD_RELOC_ALPHA_DTPREL_LO16:
1269 case BFD_RELOC_ALPHA_DTPREL16:
1270 case BFD_RELOC_ALPHA_GOTTPREL16:
1271 case BFD_RELOC_ALPHA_TPREL_HI16:
1272 case BFD_RELOC_ALPHA_TPREL_LO16:
1273 case BFD_RELOC_ALPHA_TPREL16:
1274 return;
1275 #endif
1277 #ifdef OBJ_ECOFF
1278 case BFD_RELOC_ALPHA_LITERAL:
1279 md_number_to_chars (fixpos, value, 2);
1280 return;
1281 #endif
1282 case BFD_RELOC_ALPHA_ELF_LITERAL:
1283 case BFD_RELOC_ALPHA_LITUSE:
1284 case BFD_RELOC_ALPHA_LINKAGE:
1285 case BFD_RELOC_ALPHA_CODEADDR:
1286 return;
1288 case BFD_RELOC_VTABLE_INHERIT:
1289 case BFD_RELOC_VTABLE_ENTRY:
1290 return;
1292 default:
1294 const struct alpha_operand *operand;
1296 if ((int) fixP->fx_r_type >= 0)
1297 as_fatal (_("unhandled relocation type %s"),
1298 bfd_get_reloc_code_name (fixP->fx_r_type));
1300 assert (-(int) fixP->fx_r_type < (int) alpha_num_operands);
1301 operand = &alpha_operands[-(int) fixP->fx_r_type];
1303 /* The rest of these fixups only exist internally during symbol
1304 resolution and have no representation in the object file.
1305 Therefore they must be completely resolved as constants. */
1307 if (fixP->fx_addsy != 0
1308 && S_GET_SEGMENT (fixP->fx_addsy) != absolute_section)
1309 as_bad_where (fixP->fx_file, fixP->fx_line,
1310 _("non-absolute expression in constant field"));
1312 image = bfd_getl32 (fixpos);
1313 image = insert_operand (image, operand, (offsetT) value,
1314 fixP->fx_file, fixP->fx_line);
1316 goto write_done;
1319 if (fixP->fx_addsy != 0 || fixP->fx_pcrel != 0)
1320 return;
1321 else
1323 as_warn_where (fixP->fx_file, fixP->fx_line,
1324 _("type %d reloc done?\n"), (int) fixP->fx_r_type);
1325 goto done;
1328 write_done:
1329 md_number_to_chars (fixpos, image, 4);
1331 done:
1332 fixP->fx_done = 1;
1335 /* Look for a register name in the given symbol. */
1337 symbolS *
1338 md_undefined_symbol (name)
1339 char *name;
1341 if (*name == '$')
1343 int is_float = 0, num;
1345 switch (*++name)
1347 case 'f':
1348 if (name[1] == 'p' && name[2] == '\0')
1349 return alpha_register_table[AXP_REG_FP];
1350 is_float = 32;
1351 /* FALLTHRU */
1353 case 'r':
1354 if (!ISDIGIT (*++name))
1355 break;
1356 /* FALLTHRU */
1358 case '0': case '1': case '2': case '3': case '4':
1359 case '5': case '6': case '7': case '8': case '9':
1360 if (name[1] == '\0')
1361 num = name[0] - '0';
1362 else if (name[0] != '0' && ISDIGIT (name[1]) && name[2] == '\0')
1364 num = (name[0] - '0') * 10 + name[1] - '0';
1365 if (num >= 32)
1366 break;
1368 else
1369 break;
1371 if (!alpha_noat_on && (num + is_float) == AXP_REG_AT)
1372 as_warn (_("Used $at without \".set noat\""));
1373 return alpha_register_table[num + is_float];
1375 case 'a':
1376 if (name[1] == 't' && name[2] == '\0')
1378 if (!alpha_noat_on)
1379 as_warn (_("Used $at without \".set noat\""));
1380 return alpha_register_table[AXP_REG_AT];
1382 break;
1384 case 'g':
1385 if (name[1] == 'p' && name[2] == '\0')
1386 return alpha_register_table[alpha_gp_register];
1387 break;
1389 case 's':
1390 if (name[1] == 'p' && name[2] == '\0')
1391 return alpha_register_table[AXP_REG_SP];
1392 break;
1395 return NULL;
1398 #ifdef OBJ_ECOFF
1399 /* @@@ Magic ECOFF bits. */
1401 void
1402 alpha_frob_ecoff_data ()
1404 select_gp_value ();
1405 /* $zero and $f31 are read-only */
1406 alpha_gprmask &= ~1;
1407 alpha_fprmask &= ~1;
1409 #endif
1411 /* Hook to remember a recently defined label so that the auto-align
1412 code can adjust the symbol after we know what alignment will be
1413 required. */
1415 void
1416 alpha_define_label (sym)
1417 symbolS *sym;
1419 alpha_insn_label = sym;
1422 /* If we have a BRSGP reloc to a local symbol, adjust it to BRADDR and
1423 let it get resolved at assembly time. */
1425 #ifdef OBJ_ELF
1426 void
1427 alpha_validate_fix (f)
1428 fixS *f;
1430 int offset = 0;
1431 const char *name;
1433 if (f->fx_r_type != BFD_RELOC_ALPHA_BRSGP)
1434 return;
1436 if (! S_IS_DEFINED (f->fx_addsy))
1437 return;
1439 switch (S_GET_OTHER (f->fx_addsy) & STO_ALPHA_STD_GPLOAD)
1441 case STO_ALPHA_NOPV:
1442 break;
1443 case STO_ALPHA_STD_GPLOAD:
1444 offset = 8;
1445 break;
1446 default:
1447 if (S_IS_LOCAL (f->fx_addsy))
1448 name = "<local>";
1449 else
1450 name = S_GET_NAME (f->fx_addsy);
1451 as_bad_where (f->fx_file, f->fx_line,
1452 _("!samegp reloc against symbol without .prologue: %s"),
1453 name);
1454 break;
1457 if (! (S_IS_EXTERN (f->fx_addsy) || S_IS_WEAK (f->fx_addsy)))
1459 f->fx_r_type = BFD_RELOC_23_PCREL_S2;
1460 f->fx_offset += offset;
1463 #endif
1465 /* Return true if we must always emit a reloc for a type and false if
1466 there is some hope of resolving it at assembly time. */
1469 alpha_force_relocation (f)
1470 fixS *f;
1472 if (alpha_flag_relax)
1473 return 1;
1475 switch (f->fx_r_type)
1477 case BFD_RELOC_ALPHA_GPDISP_HI16:
1478 case BFD_RELOC_ALPHA_GPDISP_LO16:
1479 case BFD_RELOC_ALPHA_GPDISP:
1480 case BFD_RELOC_ALPHA_LITERAL:
1481 case BFD_RELOC_ALPHA_ELF_LITERAL:
1482 case BFD_RELOC_ALPHA_LITUSE:
1483 case BFD_RELOC_GPREL16:
1484 case BFD_RELOC_GPREL32:
1485 case BFD_RELOC_ALPHA_GPREL_HI16:
1486 case BFD_RELOC_ALPHA_GPREL_LO16:
1487 case BFD_RELOC_ALPHA_LINKAGE:
1488 case BFD_RELOC_ALPHA_CODEADDR:
1489 case BFD_RELOC_ALPHA_BRSGP:
1490 case BFD_RELOC_VTABLE_INHERIT:
1491 case BFD_RELOC_VTABLE_ENTRY:
1492 case BFD_RELOC_ALPHA_TLSGD:
1493 case BFD_RELOC_ALPHA_TLSLDM:
1494 case BFD_RELOC_ALPHA_GOTDTPREL16:
1495 case BFD_RELOC_ALPHA_DTPREL_HI16:
1496 case BFD_RELOC_ALPHA_DTPREL_LO16:
1497 case BFD_RELOC_ALPHA_DTPREL16:
1498 case BFD_RELOC_ALPHA_GOTTPREL16:
1499 case BFD_RELOC_ALPHA_TPREL_HI16:
1500 case BFD_RELOC_ALPHA_TPREL_LO16:
1501 case BFD_RELOC_ALPHA_TPREL16:
1502 return 1;
1504 case BFD_RELOC_23_PCREL_S2:
1505 case BFD_RELOC_32:
1506 case BFD_RELOC_64:
1507 case BFD_RELOC_ALPHA_HINT:
1508 return 0;
1510 default:
1511 return 0;
1515 /* Return true if we can partially resolve a relocation now. */
1518 alpha_fix_adjustable (f)
1519 fixS *f;
1521 #ifdef OBJ_ELF
1522 /* Prevent all adjustments to global symbols */
1523 if (S_IS_EXTERN (f->fx_addsy) || S_IS_WEAK (f->fx_addsy))
1524 return 0;
1525 #endif
1527 /* Are there any relocation types for which we must generate a reloc
1528 but we can adjust the values contained within it? */
1529 switch (f->fx_r_type)
1531 case BFD_RELOC_ALPHA_GPDISP_HI16:
1532 case BFD_RELOC_ALPHA_GPDISP_LO16:
1533 case BFD_RELOC_ALPHA_GPDISP:
1534 case BFD_RELOC_ALPHA_BRSGP:
1535 return 0;
1537 case BFD_RELOC_ALPHA_LITERAL:
1538 case BFD_RELOC_ALPHA_ELF_LITERAL:
1539 case BFD_RELOC_ALPHA_LITUSE:
1540 case BFD_RELOC_ALPHA_LINKAGE:
1541 case BFD_RELOC_ALPHA_CODEADDR:
1542 return 1;
1544 case BFD_RELOC_VTABLE_ENTRY:
1545 case BFD_RELOC_VTABLE_INHERIT:
1546 return 0;
1548 case BFD_RELOC_GPREL16:
1549 case BFD_RELOC_GPREL32:
1550 case BFD_RELOC_ALPHA_GPREL_HI16:
1551 case BFD_RELOC_ALPHA_GPREL_LO16:
1552 case BFD_RELOC_23_PCREL_S2:
1553 case BFD_RELOC_32:
1554 case BFD_RELOC_64:
1555 case BFD_RELOC_ALPHA_HINT:
1556 return 1;
1558 case BFD_RELOC_ALPHA_TLSGD:
1559 case BFD_RELOC_ALPHA_TLSLDM:
1560 case BFD_RELOC_ALPHA_GOTDTPREL16:
1561 case BFD_RELOC_ALPHA_DTPREL_HI16:
1562 case BFD_RELOC_ALPHA_DTPREL_LO16:
1563 case BFD_RELOC_ALPHA_DTPREL16:
1564 case BFD_RELOC_ALPHA_GOTTPREL16:
1565 case BFD_RELOC_ALPHA_TPREL_HI16:
1566 case BFD_RELOC_ALPHA_TPREL_LO16:
1567 case BFD_RELOC_ALPHA_TPREL16:
1568 /* ??? No idea why we can't return a reference to .tbss+10, but
1569 we're preventing this in the other assemblers. Follow for now. */
1570 return 0;
1572 default:
1573 return 1;
1575 /*NOTREACHED*/
1578 /* Generate the BFD reloc to be stuck in the object file from the
1579 fixup used internally in the assembler. */
1581 arelent *
1582 tc_gen_reloc (sec, fixp)
1583 asection *sec ATTRIBUTE_UNUSED;
1584 fixS *fixp;
1586 arelent *reloc;
1588 reloc = (arelent *) xmalloc (sizeof (arelent));
1589 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
1590 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
1591 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
1593 /* Make sure none of our internal relocations make it this far.
1594 They'd better have been fully resolved by this point. */
1595 assert ((int) fixp->fx_r_type > 0);
1597 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
1598 if (reloc->howto == NULL)
1600 as_bad_where (fixp->fx_file, fixp->fx_line,
1601 _("cannot represent `%s' relocation in object file"),
1602 bfd_get_reloc_code_name (fixp->fx_r_type));
1603 return NULL;
1606 if (!fixp->fx_pcrel != !reloc->howto->pc_relative)
1608 as_fatal (_("internal error? cannot generate `%s' relocation"),
1609 bfd_get_reloc_code_name (fixp->fx_r_type));
1611 assert (!fixp->fx_pcrel == !reloc->howto->pc_relative);
1613 #ifdef OBJ_ECOFF
1614 if (fixp->fx_r_type == BFD_RELOC_ALPHA_LITERAL)
1616 /* Fake out bfd_perform_relocation. sigh. */
1617 reloc->addend = -alpha_gp_value;
1619 else
1620 #endif
1622 reloc->addend = fixp->fx_offset;
1623 #ifdef OBJ_ELF
1624 /* Ohhh, this is ugly. The problem is that if this is a local global
1625 symbol, the relocation will entirely be performed at link time, not
1626 at assembly time. bfd_perform_reloc doesn't know about this sort
1627 of thing, and as a result we need to fake it out here. */
1628 if ((S_IS_EXTERN (fixp->fx_addsy) || S_IS_WEAK (fixp->fx_addsy)
1629 || (S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_MERGE)
1630 || (S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_THREAD_LOCAL))
1631 && !S_IS_COMMON (fixp->fx_addsy))
1632 reloc->addend -= symbol_get_bfdsym (fixp->fx_addsy)->value;
1633 #endif
1636 return reloc;
1639 /* Parse a register name off of the input_line and return a register
1640 number. Gets md_undefined_symbol above to do the register name
1641 matching for us.
1643 Only called as a part of processing the ECOFF .frame directive. */
1646 tc_get_register (frame)
1647 int frame ATTRIBUTE_UNUSED;
1649 int framereg = AXP_REG_SP;
1651 SKIP_WHITESPACE ();
1652 if (*input_line_pointer == '$')
1654 char *s = input_line_pointer;
1655 char c = get_symbol_end ();
1656 symbolS *sym = md_undefined_symbol (s);
1658 *strchr (s, '\0') = c;
1659 if (sym && (framereg = S_GET_VALUE (sym)) <= 31)
1660 goto found;
1662 as_warn (_("frame reg expected, using $%d."), framereg);
1664 found:
1665 note_gpreg (framereg);
1666 return framereg;
1669 /* This is called before the symbol table is processed. In order to
1670 work with gcc when using mips-tfile, we must keep all local labels.
1671 However, in other cases, we want to discard them. If we were
1672 called with -g, but we didn't see any debugging information, it may
1673 mean that gcc is smuggling debugging information through to
1674 mips-tfile, in which case we must generate all local labels. */
1676 #ifdef OBJ_ECOFF
1678 void
1679 alpha_frob_file_before_adjust ()
1681 if (alpha_debug != 0
1682 && ! ecoff_debugging_seen)
1683 flag_keep_locals = 1;
1686 #endif /* OBJ_ECOFF */
1688 static struct alpha_reloc_tag *
1689 get_alpha_reloc_tag (sequence)
1690 long sequence;
1692 char buffer[ALPHA_RELOC_DIGITS];
1693 struct alpha_reloc_tag *info;
1695 sprintf (buffer, "!%ld", sequence);
1697 info = (struct alpha_reloc_tag *) hash_find (alpha_literal_hash, buffer);
1698 if (! info)
1700 size_t len = strlen (buffer);
1701 const char *errmsg;
1703 info = (struct alpha_reloc_tag *)
1704 xcalloc (sizeof (struct alpha_reloc_tag) + len, 1);
1706 info->segment = now_seg;
1707 info->sequence = sequence;
1708 strcpy (info->string, buffer);
1709 errmsg = hash_insert (alpha_literal_hash, info->string, (PTR) info);
1710 if (errmsg)
1711 as_fatal (errmsg);
1714 return info;
1717 /* Before the relocations are written, reorder them, so that user
1718 supplied !lituse relocations follow the appropriate !literal
1719 relocations, and similarly for !gpdisp relocations. */
1721 void
1722 alpha_adjust_symtab ()
1724 if (alpha_literal_hash)
1725 bfd_map_over_sections (stdoutput, alpha_adjust_symtab_relocs, NULL);
1728 static void
1729 alpha_adjust_symtab_relocs (abfd, sec, ptr)
1730 bfd *abfd ATTRIBUTE_UNUSED;
1731 asection *sec;
1732 PTR ptr ATTRIBUTE_UNUSED;
1734 segment_info_type *seginfo = seg_info (sec);
1735 fixS **prevP;
1736 fixS *fixp;
1737 fixS *next;
1738 fixS *slave;
1740 /* If seginfo is NULL, we did not create this section; don't do
1741 anything with it. By using a pointer to a pointer, we can update
1742 the links in place. */
1743 if (seginfo == NULL)
1744 return;
1746 /* If there are no relocations, skip the section. */
1747 if (! seginfo->fix_root)
1748 return;
1750 /* First rebuild the fixup chain without the expicit lituse and
1751 gpdisp_lo16 relocs. */
1752 prevP = &seginfo->fix_root;
1753 for (fixp = seginfo->fix_root; fixp; fixp = next)
1755 next = fixp->fx_next;
1756 fixp->fx_next = (fixS *) 0;
1758 switch (fixp->fx_r_type)
1760 case BFD_RELOC_ALPHA_LITUSE:
1761 if (fixp->tc_fix_data.info->n_master == 0)
1762 as_bad_where (fixp->fx_file, fixp->fx_line,
1763 _("No !literal!%ld was found"),
1764 fixp->tc_fix_data.info->sequence);
1765 #ifdef RELOC_OP_P
1766 if (fixp->fx_offset == LITUSE_ALPHA_TLSGD)
1768 if (! fixp->tc_fix_data.info->saw_tlsgd)
1769 as_bad_where (fixp->fx_file, fixp->fx_line,
1770 _("No !tlsgd!%ld was found"),
1771 fixp->tc_fix_data.info->sequence);
1773 else if (fixp->fx_offset == LITUSE_ALPHA_TLSLDM)
1775 if (! fixp->tc_fix_data.info->saw_tlsldm)
1776 as_bad_where (fixp->fx_file, fixp->fx_line,
1777 _("No !tlsldm!%ld was found"),
1778 fixp->tc_fix_data.info->sequence);
1780 #endif
1781 break;
1783 case BFD_RELOC_ALPHA_GPDISP_LO16:
1784 if (fixp->tc_fix_data.info->n_master == 0)
1785 as_bad_where (fixp->fx_file, fixp->fx_line,
1786 _("No ldah !gpdisp!%ld was found"),
1787 fixp->tc_fix_data.info->sequence);
1788 break;
1790 case BFD_RELOC_ALPHA_ELF_LITERAL:
1791 if (fixp->tc_fix_data.info
1792 && (fixp->tc_fix_data.info->saw_tlsgd
1793 || fixp->tc_fix_data.info->saw_tlsldm))
1794 break;
1795 /* FALLTHRU */
1797 default:
1798 *prevP = fixp;
1799 prevP = &fixp->fx_next;
1800 break;
1804 /* Go back and re-chain dependent relocations. They are currently
1805 linked through the next_reloc field in reverse order, so as we
1806 go through the next_reloc chain, we effectively reverse the chain
1807 once again.
1809 Except if there is more than one !literal for a given sequence
1810 number. In that case, the programmer and/or compiler is not sure
1811 how control flows from literal to lituse, and we can't be sure to
1812 get the relaxation correct.
1814 ??? Well, actually we could, if there are enough lituses such that
1815 we can make each literal have at least one of each lituse type
1816 present. Not implemented.
1818 Also suppress the optimization if the !literals/!lituses are spread
1819 in different segments. This can happen with "intersting" uses of
1820 inline assembly; examples are present in the Linux kernel semaphores. */
1822 for (fixp = seginfo->fix_root; fixp; fixp = next)
1824 next = fixp->fx_next;
1825 switch (fixp->fx_r_type)
1827 case BFD_RELOC_ALPHA_TLSGD:
1828 case BFD_RELOC_ALPHA_TLSLDM:
1829 if (!fixp->tc_fix_data.info)
1830 break;
1831 if (fixp->tc_fix_data.info->n_master == 0)
1832 break;
1833 else if (fixp->tc_fix_data.info->n_master > 1)
1835 as_bad_where (fixp->fx_file, fixp->fx_line,
1836 _("too many !literal!%ld for %s"),
1837 fixp->tc_fix_data.info->sequence,
1838 (fixp->fx_r_type == BFD_RELOC_ALPHA_TLSGD
1839 ? "!tlsgd" : "!tlsldm"));
1840 break;
1843 fixp->tc_fix_data.info->master->fx_next = fixp->fx_next;
1844 fixp->fx_next = fixp->tc_fix_data.info->master;
1845 fixp = fixp->fx_next;
1846 /* FALLTHRU */
1848 case BFD_RELOC_ALPHA_ELF_LITERAL:
1849 if (fixp->tc_fix_data.info
1850 && fixp->tc_fix_data.info->n_master == 1
1851 && ! fixp->tc_fix_data.info->multi_section_p)
1853 for (slave = fixp->tc_fix_data.info->slaves;
1854 slave != (fixS *) 0;
1855 slave = slave->tc_fix_data.next_reloc)
1857 slave->fx_next = fixp->fx_next;
1858 fixp->fx_next = slave;
1861 break;
1863 case BFD_RELOC_ALPHA_GPDISP_HI16:
1864 if (fixp->tc_fix_data.info->n_slaves == 0)
1865 as_bad_where (fixp->fx_file, fixp->fx_line,
1866 _("No lda !gpdisp!%ld was found"),
1867 fixp->tc_fix_data.info->sequence);
1868 else
1870 slave = fixp->tc_fix_data.info->slaves;
1871 slave->fx_next = next;
1872 fixp->fx_next = slave;
1874 break;
1876 default:
1877 break;
1882 #ifdef DEBUG_ALPHA
1883 static void
1884 debug_exp (tok, ntok)
1885 expressionS tok[];
1886 int ntok;
1888 int i;
1890 fprintf (stderr, "debug_exp: %d tokens", ntok);
1891 for (i = 0; i < ntok; i++)
1893 expressionS *t = &tok[i];
1894 const char *name;
1896 switch (t->X_op)
1898 default: name = "unknown"; break;
1899 case O_illegal: name = "O_illegal"; break;
1900 case O_absent: name = "O_absent"; break;
1901 case O_constant: name = "O_constant"; break;
1902 case O_symbol: name = "O_symbol"; break;
1903 case O_symbol_rva: name = "O_symbol_rva"; break;
1904 case O_register: name = "O_register"; break;
1905 case O_big: name = "O_big"; break;
1906 case O_uminus: name = "O_uminus"; break;
1907 case O_bit_not: name = "O_bit_not"; break;
1908 case O_logical_not: name = "O_logical_not"; break;
1909 case O_multiply: name = "O_multiply"; break;
1910 case O_divide: name = "O_divide"; break;
1911 case O_modulus: name = "O_modulus"; break;
1912 case O_left_shift: name = "O_left_shift"; break;
1913 case O_right_shift: name = "O_right_shift"; break;
1914 case O_bit_inclusive_or: name = "O_bit_inclusive_or"; break;
1915 case O_bit_or_not: name = "O_bit_or_not"; break;
1916 case O_bit_exclusive_or: name = "O_bit_exclusive_or"; break;
1917 case O_bit_and: name = "O_bit_and"; break;
1918 case O_add: name = "O_add"; break;
1919 case O_subtract: name = "O_subtract"; break;
1920 case O_eq: name = "O_eq"; break;
1921 case O_ne: name = "O_ne"; break;
1922 case O_lt: name = "O_lt"; break;
1923 case O_le: name = "O_le"; break;
1924 case O_ge: name = "O_ge"; break;
1925 case O_gt: name = "O_gt"; break;
1926 case O_logical_and: name = "O_logical_and"; break;
1927 case O_logical_or: name = "O_logical_or"; break;
1928 case O_index: name = "O_index"; break;
1929 case O_pregister: name = "O_pregister"; break;
1930 case O_cpregister: name = "O_cpregister"; break;
1931 case O_literal: name = "O_literal"; break;
1932 case O_lituse_addr: name = "O_lituse_addr"; break;
1933 case O_lituse_base: name = "O_lituse_base"; break;
1934 case O_lituse_bytoff: name = "O_lituse_bytoff"; break;
1935 case O_lituse_jsr: name = "O_lituse_jsr"; break;
1936 case O_lituse_tlsgd: name = "O_lituse_tlsgd"; break;
1937 case O_lituse_tlsldm: name = "O_lituse_tlsldm"; break;
1938 case O_gpdisp: name = "O_gpdisp"; break;
1939 case O_gprelhigh: name = "O_gprelhigh"; break;
1940 case O_gprellow: name = "O_gprellow"; break;
1941 case O_gprel: name = "O_gprel"; break;
1942 case O_samegp: name = "O_samegp"; break;
1943 case O_tlsgd: name = "O_tlsgd"; break;
1944 case O_tlsldm: name = "O_tlsldm"; break;
1945 case O_gotdtprel: name = "O_gotdtprel"; break;
1946 case O_dtprelhi: name = "O_dtprelhi"; break;
1947 case O_dtprello: name = "O_dtprello"; break;
1948 case O_dtprel: name = "O_dtprel"; break;
1949 case O_gottprel: name = "O_gottprel"; break;
1950 case O_tprelhi: name = "O_tprelhi"; break;
1951 case O_tprello: name = "O_tprello"; break;
1952 case O_tprel: name = "O_tprel"; break;
1955 fprintf (stderr, ", %s(%s, %s, %d)", name,
1956 (t->X_add_symbol) ? S_GET_NAME (t->X_add_symbol) : "--",
1957 (t->X_op_symbol) ? S_GET_NAME (t->X_op_symbol) : "--",
1958 (int) t->X_add_number);
1960 fprintf (stderr, "\n");
1961 fflush (stderr);
1963 #endif
1965 /* Parse the arguments to an opcode. */
1967 static int
1968 tokenize_arguments (str, tok, ntok)
1969 char *str;
1970 expressionS tok[];
1971 int ntok;
1973 expressionS *end_tok = tok + ntok;
1974 char *old_input_line_pointer;
1975 int saw_comma = 0, saw_arg = 0;
1976 #ifdef DEBUG_ALPHA
1977 expressionS *orig_tok = tok;
1978 #endif
1979 #ifdef RELOC_OP_P
1980 char *p;
1981 const struct alpha_reloc_op_tag *r;
1982 int c, i;
1983 size_t len;
1984 int reloc_found_p = 0;
1985 #endif
1987 memset (tok, 0, sizeof (*tok) * ntok);
1989 /* Save and restore input_line_pointer around this function. */
1990 old_input_line_pointer = input_line_pointer;
1991 input_line_pointer = str;
1993 #ifdef RELOC_OP_P
1994 /* ??? Wrest control of ! away from the regular expression parser. */
1995 is_end_of_line[(unsigned char) '!'] = 1;
1996 #endif
1998 while (tok < end_tok && *input_line_pointer)
2000 SKIP_WHITESPACE ();
2001 switch (*input_line_pointer)
2003 case '\0':
2004 goto fini;
2006 #ifdef RELOC_OP_P
2007 case '!':
2008 /* A relocation operand can be placed after the normal operand on an
2009 assembly language statement, and has the following form:
2010 !relocation_type!sequence_number. */
2011 if (reloc_found_p)
2013 /* Only support one relocation op per insn. */
2014 as_bad (_("More than one relocation op per insn"));
2015 goto err_report;
2018 if (!saw_arg)
2019 goto err;
2021 ++input_line_pointer;
2022 SKIP_WHITESPACE ();
2023 p = input_line_pointer;
2024 c = get_symbol_end ();
2026 /* Parse !relocation_type. */
2027 len = input_line_pointer - p;
2028 if (len == 0)
2030 as_bad (_("No relocation operand"));
2031 goto err_report;
2034 r = &alpha_reloc_op[0];
2035 for (i = alpha_num_reloc_op - 1; i >= 0; i--, r++)
2036 if (len == r->length && memcmp (p, r->name, len) == 0)
2037 break;
2038 if (i < 0)
2040 as_bad (_("Unknown relocation operand: !%s"), p);
2041 goto err_report;
2044 *input_line_pointer = c;
2045 SKIP_WHITESPACE ();
2046 if (*input_line_pointer != '!')
2048 if (r->require_seq)
2050 as_bad (_("no sequence number after !%s"), p);
2051 goto err_report;
2054 tok->X_add_number = 0;
2056 else
2058 if (! r->allow_seq)
2060 as_bad (_("!%s does not use a sequence number"), p);
2061 goto err_report;
2064 input_line_pointer++;
2066 /* Parse !sequence_number. */
2067 expression (tok);
2068 if (tok->X_op != O_constant || tok->X_add_number <= 0)
2070 as_bad (_("Bad sequence number: !%s!%s"),
2071 r->name, input_line_pointer);
2072 goto err_report;
2076 tok->X_op = r->op;
2077 reloc_found_p = 1;
2078 ++tok;
2079 break;
2080 #endif /* RELOC_OP_P */
2082 case ',':
2083 ++input_line_pointer;
2084 if (saw_comma || !saw_arg)
2085 goto err;
2086 saw_comma = 1;
2087 break;
2089 case '(':
2091 char *hold = input_line_pointer++;
2093 /* First try for parenthesized register ... */
2094 expression (tok);
2095 if (*input_line_pointer == ')' && tok->X_op == O_register)
2097 tok->X_op = (saw_comma ? O_cpregister : O_pregister);
2098 saw_comma = 0;
2099 saw_arg = 1;
2100 ++input_line_pointer;
2101 ++tok;
2102 break;
2105 /* ... then fall through to plain expression. */
2106 input_line_pointer = hold;
2109 default:
2110 if (saw_arg && !saw_comma)
2111 goto err;
2113 expression (tok);
2114 if (tok->X_op == O_illegal || tok->X_op == O_absent)
2115 goto err;
2117 saw_comma = 0;
2118 saw_arg = 1;
2119 ++tok;
2120 break;
2124 fini:
2125 if (saw_comma)
2126 goto err;
2127 input_line_pointer = old_input_line_pointer;
2129 #ifdef DEBUG_ALPHA
2130 debug_exp (orig_tok, ntok - (end_tok - tok));
2131 #endif
2132 #ifdef RELOC_OP_P
2133 is_end_of_line[(unsigned char) '!'] = 0;
2134 #endif
2136 return ntok - (end_tok - tok);
2138 err:
2139 #ifdef RELOC_OP_P
2140 is_end_of_line[(unsigned char) '!'] = 0;
2141 #endif
2142 input_line_pointer = old_input_line_pointer;
2143 return TOKENIZE_ERROR;
2145 #ifdef RELOC_OP_P
2146 err_report:
2147 is_end_of_line[(unsigned char) '!'] = 0;
2148 #endif
2149 input_line_pointer = old_input_line_pointer;
2150 return TOKENIZE_ERROR_REPORT;
2153 /* Search forward through all variants of an opcode looking for a
2154 syntax match. */
2156 static const struct alpha_opcode *
2157 find_opcode_match (first_opcode, tok, pntok, pcpumatch)
2158 const struct alpha_opcode *first_opcode;
2159 const expressionS *tok;
2160 int *pntok;
2161 int *pcpumatch;
2163 const struct alpha_opcode *opcode = first_opcode;
2164 int ntok = *pntok;
2165 int got_cpu_match = 0;
2169 const unsigned char *opidx;
2170 int tokidx = 0;
2172 /* Don't match opcodes that don't exist on this architecture. */
2173 if (!(opcode->flags & alpha_target))
2174 goto match_failed;
2176 got_cpu_match = 1;
2178 for (opidx = opcode->operands; *opidx; ++opidx)
2180 const struct alpha_operand *operand = &alpha_operands[*opidx];
2182 /* Only take input from real operands. */
2183 if (operand->flags & AXP_OPERAND_FAKE)
2184 continue;
2186 /* When we expect input, make sure we have it. */
2187 if (tokidx >= ntok)
2189 if ((operand->flags & AXP_OPERAND_OPTIONAL_MASK) == 0)
2190 goto match_failed;
2191 continue;
2194 /* Match operand type with expression type. */
2195 switch (operand->flags & AXP_OPERAND_TYPECHECK_MASK)
2197 case AXP_OPERAND_IR:
2198 if (tok[tokidx].X_op != O_register
2199 || !is_ir_num (tok[tokidx].X_add_number))
2200 goto match_failed;
2201 break;
2202 case AXP_OPERAND_FPR:
2203 if (tok[tokidx].X_op != O_register
2204 || !is_fpr_num (tok[tokidx].X_add_number))
2205 goto match_failed;
2206 break;
2207 case AXP_OPERAND_IR | AXP_OPERAND_PARENS:
2208 if (tok[tokidx].X_op != O_pregister
2209 || !is_ir_num (tok[tokidx].X_add_number))
2210 goto match_failed;
2211 break;
2212 case AXP_OPERAND_IR | AXP_OPERAND_PARENS | AXP_OPERAND_COMMA:
2213 if (tok[tokidx].X_op != O_cpregister
2214 || !is_ir_num (tok[tokidx].X_add_number))
2215 goto match_failed;
2216 break;
2218 case AXP_OPERAND_RELATIVE:
2219 case AXP_OPERAND_SIGNED:
2220 case AXP_OPERAND_UNSIGNED:
2221 switch (tok[tokidx].X_op)
2223 case O_illegal:
2224 case O_absent:
2225 case O_register:
2226 case O_pregister:
2227 case O_cpregister:
2228 goto match_failed;
2230 default:
2231 break;
2233 break;
2235 default:
2236 /* Everything else should have been fake. */
2237 abort ();
2239 ++tokidx;
2242 /* Possible match -- did we use all of our input? */
2243 if (tokidx == ntok)
2245 *pntok = ntok;
2246 return opcode;
2249 match_failed:;
2251 while (++opcode - alpha_opcodes < (int) alpha_num_opcodes
2252 && !strcmp (opcode->name, first_opcode->name));
2254 if (*pcpumatch)
2255 *pcpumatch = got_cpu_match;
2257 return NULL;
2260 /* Search forward through all variants of a macro looking for a syntax
2261 match. */
2263 static const struct alpha_macro *
2264 find_macro_match (first_macro, tok, pntok)
2265 const struct alpha_macro *first_macro;
2266 const expressionS *tok;
2267 int *pntok;
2269 const struct alpha_macro *macro = first_macro;
2270 int ntok = *pntok;
2274 const enum alpha_macro_arg *arg = macro->argsets;
2275 int tokidx = 0;
2277 while (*arg)
2279 switch (*arg)
2281 case MACRO_EOA:
2282 if (tokidx == ntok)
2283 return macro;
2284 else
2285 tokidx = 0;
2286 break;
2288 /* Index register. */
2289 case MACRO_IR:
2290 if (tokidx >= ntok || tok[tokidx].X_op != O_register
2291 || !is_ir_num (tok[tokidx].X_add_number))
2292 goto match_failed;
2293 ++tokidx;
2294 break;
2296 /* Parenthesized index register. */
2297 case MACRO_PIR:
2298 if (tokidx >= ntok || tok[tokidx].X_op != O_pregister
2299 || !is_ir_num (tok[tokidx].X_add_number))
2300 goto match_failed;
2301 ++tokidx;
2302 break;
2304 /* Optional parenthesized index register. */
2305 case MACRO_OPIR:
2306 if (tokidx < ntok && tok[tokidx].X_op == O_pregister
2307 && is_ir_num (tok[tokidx].X_add_number))
2308 ++tokidx;
2309 break;
2311 /* Leading comma with a parenthesized index register. */
2312 case MACRO_CPIR:
2313 if (tokidx >= ntok || tok[tokidx].X_op != O_cpregister
2314 || !is_ir_num (tok[tokidx].X_add_number))
2315 goto match_failed;
2316 ++tokidx;
2317 break;
2319 /* Floating point register. */
2320 case MACRO_FPR:
2321 if (tokidx >= ntok || tok[tokidx].X_op != O_register
2322 || !is_fpr_num (tok[tokidx].X_add_number))
2323 goto match_failed;
2324 ++tokidx;
2325 break;
2327 /* Normal expression. */
2328 case MACRO_EXP:
2329 if (tokidx >= ntok)
2330 goto match_failed;
2331 switch (tok[tokidx].X_op)
2333 case O_illegal:
2334 case O_absent:
2335 case O_register:
2336 case O_pregister:
2337 case O_cpregister:
2338 case O_literal:
2339 case O_lituse_base:
2340 case O_lituse_bytoff:
2341 case O_lituse_jsr:
2342 case O_gpdisp:
2343 case O_gprelhigh:
2344 case O_gprellow:
2345 case O_gprel:
2346 case O_samegp:
2347 goto match_failed;
2349 default:
2350 break;
2352 ++tokidx;
2353 break;
2355 match_failed:
2356 while (*arg != MACRO_EOA)
2357 ++arg;
2358 tokidx = 0;
2359 break;
2361 ++arg;
2364 while (++macro - alpha_macros < (int) alpha_num_macros
2365 && !strcmp (macro->name, first_macro->name));
2367 return NULL;
2370 /* Insert an operand value into an instruction. */
2372 static unsigned
2373 insert_operand (insn, operand, val, file, line)
2374 unsigned insn;
2375 const struct alpha_operand *operand;
2376 offsetT val;
2377 char *file;
2378 unsigned line;
2380 if (operand->bits != 32 && !(operand->flags & AXP_OPERAND_NOOVERFLOW))
2382 offsetT min, max;
2384 if (operand->flags & AXP_OPERAND_SIGNED)
2386 max = (1 << (operand->bits - 1)) - 1;
2387 min = -(1 << (operand->bits - 1));
2389 else
2391 max = (1 << operand->bits) - 1;
2392 min = 0;
2395 if (val < min || val > max)
2397 const char *err =
2398 _("operand out of range (%s not between %d and %d)");
2399 char buf[sizeof (val) * 3 + 2];
2401 sprint_value (buf, val);
2402 if (file)
2403 as_warn_where (file, line, err, buf, min, max);
2404 else
2405 as_warn (err, buf, min, max);
2409 if (operand->insert)
2411 const char *errmsg = NULL;
2413 insn = (*operand->insert) (insn, val, &errmsg);
2414 if (errmsg)
2415 as_warn (errmsg);
2417 else
2418 insn |= ((val & ((1 << operand->bits) - 1)) << operand->shift);
2420 return insn;
2423 /* Turn an opcode description and a set of arguments into
2424 an instruction and a fixup. */
2426 static void
2427 assemble_insn (opcode, tok, ntok, insn, reloc)
2428 const struct alpha_opcode *opcode;
2429 const expressionS *tok;
2430 int ntok;
2431 struct alpha_insn *insn;
2432 bfd_reloc_code_real_type reloc;
2434 const struct alpha_operand *reloc_operand = NULL;
2435 const expressionS *reloc_exp = NULL;
2436 const unsigned char *argidx;
2437 unsigned image;
2438 int tokidx = 0;
2440 memset (insn, 0, sizeof (*insn));
2441 image = opcode->opcode;
2443 for (argidx = opcode->operands; *argidx; ++argidx)
2445 const struct alpha_operand *operand = &alpha_operands[*argidx];
2446 const expressionS *t = (const expressionS *) 0;
2448 if (operand->flags & AXP_OPERAND_FAKE)
2450 /* fake operands take no value and generate no fixup */
2451 image = insert_operand (image, operand, 0, NULL, 0);
2452 continue;
2455 if (tokidx >= ntok)
2457 switch (operand->flags & AXP_OPERAND_OPTIONAL_MASK)
2459 case AXP_OPERAND_DEFAULT_FIRST:
2460 t = &tok[0];
2461 break;
2462 case AXP_OPERAND_DEFAULT_SECOND:
2463 t = &tok[1];
2464 break;
2465 case AXP_OPERAND_DEFAULT_ZERO:
2467 static expressionS zero_exp;
2468 t = &zero_exp;
2469 zero_exp.X_op = O_constant;
2470 zero_exp.X_unsigned = 1;
2472 break;
2473 default:
2474 abort ();
2477 else
2478 t = &tok[tokidx++];
2480 switch (t->X_op)
2482 case O_register:
2483 case O_pregister:
2484 case O_cpregister:
2485 image = insert_operand (image, operand, regno (t->X_add_number),
2486 NULL, 0);
2487 break;
2489 case O_constant:
2490 image = insert_operand (image, operand, t->X_add_number, NULL, 0);
2491 assert (reloc_operand == NULL);
2492 reloc_operand = operand;
2493 reloc_exp = t;
2494 break;
2496 default:
2497 /* This is only 0 for fields that should contain registers,
2498 which means this pattern shouldn't have matched. */
2499 if (operand->default_reloc == 0)
2500 abort ();
2502 /* There is one special case for which an insn receives two
2503 relocations, and thus the user-supplied reloc does not
2504 override the operand reloc. */
2505 if (operand->default_reloc == BFD_RELOC_ALPHA_HINT)
2507 struct alpha_fixup *fixup;
2509 if (insn->nfixups >= MAX_INSN_FIXUPS)
2510 as_fatal (_("too many fixups"));
2512 fixup = &insn->fixups[insn->nfixups++];
2513 fixup->exp = *t;
2514 fixup->reloc = BFD_RELOC_ALPHA_HINT;
2516 else
2518 if (reloc == BFD_RELOC_UNUSED)
2519 reloc = operand->default_reloc;
2521 assert (reloc_operand == NULL);
2522 reloc_operand = operand;
2523 reloc_exp = t;
2525 break;
2529 if (reloc != BFD_RELOC_UNUSED)
2531 struct alpha_fixup *fixup;
2533 if (insn->nfixups >= MAX_INSN_FIXUPS)
2534 as_fatal (_("too many fixups"));
2536 /* ??? My but this is hacky. But the OSF/1 assembler uses the same
2537 relocation tag for both ldah and lda with gpdisp. Choose the
2538 correct internal relocation based on the opcode. */
2539 if (reloc == BFD_RELOC_ALPHA_GPDISP)
2541 if (strcmp (opcode->name, "ldah") == 0)
2542 reloc = BFD_RELOC_ALPHA_GPDISP_HI16;
2543 else if (strcmp (opcode->name, "lda") == 0)
2544 reloc = BFD_RELOC_ALPHA_GPDISP_LO16;
2545 else
2546 as_bad (_("invalid relocation for instruction"));
2549 /* If this is a real relocation (as opposed to a lituse hint), then
2550 the relocation width should match the operand width. */
2551 else if (reloc < BFD_RELOC_UNUSED)
2553 reloc_howto_type *reloc_howto
2554 = bfd_reloc_type_lookup (stdoutput, reloc);
2555 if (reloc_howto->bitsize != reloc_operand->bits)
2557 as_bad (_("invalid relocation for field"));
2558 return;
2562 fixup = &insn->fixups[insn->nfixups++];
2563 if (reloc_exp)
2564 fixup->exp = *reloc_exp;
2565 else
2566 fixup->exp.X_op = O_absent;
2567 fixup->reloc = reloc;
2570 insn->insn = image;
2573 /* Actually output an instruction with its fixup. */
2575 static void
2576 emit_insn (insn)
2577 struct alpha_insn *insn;
2579 char *f;
2580 int i;
2582 /* Take care of alignment duties. */
2583 if (alpha_auto_align_on && alpha_current_align < 2)
2584 alpha_align (2, (char *) NULL, alpha_insn_label, 0);
2585 if (alpha_current_align > 2)
2586 alpha_current_align = 2;
2587 alpha_insn_label = NULL;
2589 /* Write out the instruction. */
2590 f = frag_more (4);
2591 md_number_to_chars (f, insn->insn, 4);
2593 #ifdef OBJ_ELF
2594 dwarf2_emit_insn (4);
2595 #endif
2597 /* Apply the fixups in order. */
2598 for (i = 0; i < insn->nfixups; ++i)
2600 const struct alpha_operand *operand = (const struct alpha_operand *) 0;
2601 struct alpha_fixup *fixup = &insn->fixups[i];
2602 struct alpha_reloc_tag *info = NULL;
2603 int size, pcrel;
2604 fixS *fixP;
2606 /* Some fixups are only used internally and so have no howto. */
2607 if ((int) fixup->reloc < 0)
2609 operand = &alpha_operands[-(int) fixup->reloc];
2610 size = 4;
2611 pcrel = ((operand->flags & AXP_OPERAND_RELATIVE) != 0);
2613 else if (fixup->reloc > BFD_RELOC_UNUSED
2614 || fixup->reloc == BFD_RELOC_ALPHA_GPDISP_HI16
2615 || fixup->reloc == BFD_RELOC_ALPHA_GPDISP_LO16)
2617 size = 2;
2618 pcrel = 0;
2620 else
2622 reloc_howto_type *reloc_howto
2623 = bfd_reloc_type_lookup (stdoutput, fixup->reloc);
2624 assert (reloc_howto);
2626 size = bfd_get_reloc_size (reloc_howto);
2627 assert (size >= 1 && size <= 4);
2629 pcrel = reloc_howto->pc_relative;
2632 fixP = fix_new_exp (frag_now, f - frag_now->fr_literal, size,
2633 &fixup->exp, pcrel, fixup->reloc);
2635 /* Turn off complaints that the addend is too large for some fixups,
2636 and copy in the sequence number for the explicit relocations. */
2637 switch (fixup->reloc)
2639 case BFD_RELOC_ALPHA_HINT:
2640 case BFD_RELOC_GPREL32:
2641 case BFD_RELOC_GPREL16:
2642 case BFD_RELOC_ALPHA_GPREL_HI16:
2643 case BFD_RELOC_ALPHA_GPREL_LO16:
2644 case BFD_RELOC_ALPHA_GOTDTPREL16:
2645 case BFD_RELOC_ALPHA_DTPREL_HI16:
2646 case BFD_RELOC_ALPHA_DTPREL_LO16:
2647 case BFD_RELOC_ALPHA_DTPREL16:
2648 case BFD_RELOC_ALPHA_GOTTPREL16:
2649 case BFD_RELOC_ALPHA_TPREL_HI16:
2650 case BFD_RELOC_ALPHA_TPREL_LO16:
2651 case BFD_RELOC_ALPHA_TPREL16:
2652 fixP->fx_no_overflow = 1;
2653 break;
2655 case BFD_RELOC_ALPHA_GPDISP_HI16:
2656 fixP->fx_no_overflow = 1;
2657 fixP->fx_addsy = section_symbol (now_seg);
2658 fixP->fx_offset = 0;
2660 info = get_alpha_reloc_tag (insn->sequence);
2661 if (++info->n_master > 1)
2662 as_bad (_("too many ldah insns for !gpdisp!%ld"), insn->sequence);
2663 if (info->segment != now_seg)
2664 as_bad (_("both insns for !gpdisp!%ld must be in the same section"),
2665 insn->sequence);
2666 fixP->tc_fix_data.info = info;
2667 break;
2669 case BFD_RELOC_ALPHA_GPDISP_LO16:
2670 fixP->fx_no_overflow = 1;
2672 info = get_alpha_reloc_tag (insn->sequence);
2673 if (++info->n_slaves > 1)
2674 as_bad (_("too many lda insns for !gpdisp!%ld"), insn->sequence);
2675 if (info->segment != now_seg)
2676 as_bad (_("both insns for !gpdisp!%ld must be in the same section"),
2677 insn->sequence);
2678 fixP->tc_fix_data.info = info;
2679 info->slaves = fixP;
2680 break;
2682 case BFD_RELOC_ALPHA_LITERAL:
2683 case BFD_RELOC_ALPHA_ELF_LITERAL:
2684 fixP->fx_no_overflow = 1;
2686 if (insn->sequence == 0)
2687 break;
2688 info = get_alpha_reloc_tag (insn->sequence);
2689 info->master = fixP;
2690 info->n_master++;
2691 if (info->segment != now_seg)
2692 info->multi_section_p = 1;
2693 fixP->tc_fix_data.info = info;
2694 break;
2696 #ifdef RELOC_OP_P
2697 case DUMMY_RELOC_LITUSE_ADDR:
2698 fixP->fx_offset = LITUSE_ALPHA_ADDR;
2699 goto do_lituse;
2700 case DUMMY_RELOC_LITUSE_BASE:
2701 fixP->fx_offset = LITUSE_ALPHA_BASE;
2702 goto do_lituse;
2703 case DUMMY_RELOC_LITUSE_BYTOFF:
2704 fixP->fx_offset = LITUSE_ALPHA_BYTOFF;
2705 goto do_lituse;
2706 case DUMMY_RELOC_LITUSE_JSR:
2707 fixP->fx_offset = LITUSE_ALPHA_JSR;
2708 goto do_lituse;
2709 case DUMMY_RELOC_LITUSE_TLSGD:
2710 fixP->fx_offset = LITUSE_ALPHA_TLSGD;
2711 goto do_lituse;
2712 case DUMMY_RELOC_LITUSE_TLSLDM:
2713 fixP->fx_offset = LITUSE_ALPHA_TLSLDM;
2714 goto do_lituse;
2715 do_lituse:
2716 fixP->fx_addsy = section_symbol (now_seg);
2717 fixP->fx_r_type = BFD_RELOC_ALPHA_LITUSE;
2719 info = get_alpha_reloc_tag (insn->sequence);
2720 if (fixup->reloc == DUMMY_RELOC_LITUSE_TLSGD)
2721 info->saw_lu_tlsgd = 1;
2722 else if (fixup->reloc == DUMMY_RELOC_LITUSE_TLSLDM)
2723 info->saw_lu_tlsldm = 1;
2724 if (++info->n_slaves > 1)
2726 if (info->saw_lu_tlsgd)
2727 as_bad (_("too many lituse insns for !lituse_tlsgd!%ld"),
2728 insn->sequence);
2729 else if (info->saw_lu_tlsldm)
2730 as_bad (_("too many lituse insns for !lituse_tlsldm!%ld"),
2731 insn->sequence);
2733 fixP->tc_fix_data.info = info;
2734 fixP->tc_fix_data.next_reloc = info->slaves;
2735 info->slaves = fixP;
2736 if (info->segment != now_seg)
2737 info->multi_section_p = 1;
2738 break;
2740 case BFD_RELOC_ALPHA_TLSGD:
2741 fixP->fx_no_overflow = 1;
2743 if (insn->sequence == 0)
2744 break;
2745 info = get_alpha_reloc_tag (insn->sequence);
2746 if (info->saw_tlsgd)
2747 as_bad (_("duplicate !tlsgd!%ld"), insn->sequence);
2748 else if (info->saw_tlsldm)
2749 as_bad (_("sequence number in use for !tlsldm!%ld"),
2750 insn->sequence);
2751 else
2752 info->saw_tlsgd = 1;
2753 fixP->tc_fix_data.info = info;
2754 break;
2756 case BFD_RELOC_ALPHA_TLSLDM:
2757 fixP->fx_no_overflow = 1;
2759 if (insn->sequence == 0)
2760 break;
2761 info = get_alpha_reloc_tag (insn->sequence);
2762 if (info->saw_tlsldm)
2763 as_bad (_("duplicate !tlsldm!%ld"), insn->sequence);
2764 else if (info->saw_tlsgd)
2765 as_bad (_("sequence number in use for !tlsgd!%ld"),
2766 insn->sequence);
2767 else
2768 info->saw_tlsldm = 1;
2769 fixP->tc_fix_data.info = info;
2770 break;
2771 #endif
2772 default:
2773 if ((int) fixup->reloc < 0)
2775 if (operand->flags & AXP_OPERAND_NOOVERFLOW)
2776 fixP->fx_no_overflow = 1;
2778 break;
2783 /* Given an opcode name and a pre-tokenized set of arguments, assemble
2784 the insn, but do not emit it.
2786 Note that this implies no macros allowed, since we can't store more
2787 than one insn in an insn structure. */
2789 static void
2790 assemble_tokens_to_insn (opname, tok, ntok, insn)
2791 const char *opname;
2792 const expressionS *tok;
2793 int ntok;
2794 struct alpha_insn *insn;
2796 const struct alpha_opcode *opcode;
2798 /* search opcodes */
2799 opcode = (const struct alpha_opcode *) hash_find (alpha_opcode_hash, opname);
2800 if (opcode)
2802 int cpumatch;
2803 opcode = find_opcode_match (opcode, tok, &ntok, &cpumatch);
2804 if (opcode)
2806 assemble_insn (opcode, tok, ntok, insn, BFD_RELOC_UNUSED);
2807 return;
2809 else if (cpumatch)
2810 as_bad (_("inappropriate arguments for opcode `%s'"), opname);
2811 else
2812 as_bad (_("opcode `%s' not supported for target %s"), opname,
2813 alpha_target_name);
2815 else
2816 as_bad (_("unknown opcode `%s'"), opname);
2819 /* Given an opcode name and a pre-tokenized set of arguments, take the
2820 opcode all the way through emission. */
2822 static void
2823 assemble_tokens (opname, tok, ntok, local_macros_on)
2824 const char *opname;
2825 const expressionS *tok;
2826 int ntok;
2827 int local_macros_on;
2829 int found_something = 0;
2830 const struct alpha_opcode *opcode;
2831 const struct alpha_macro *macro;
2832 int cpumatch = 1;
2833 bfd_reloc_code_real_type reloc = BFD_RELOC_UNUSED;
2835 #ifdef RELOC_OP_P
2836 /* If a user-specified relocation is present, this is not a macro. */
2837 if (ntok && USER_RELOC_P (tok[ntok - 1].X_op))
2839 reloc = ALPHA_RELOC_TABLE (tok[ntok - 1].X_op)->reloc;
2840 ntok--;
2842 else
2843 #endif
2844 if (local_macros_on)
2846 macro = ((const struct alpha_macro *)
2847 hash_find (alpha_macro_hash, opname));
2848 if (macro)
2850 found_something = 1;
2851 macro = find_macro_match (macro, tok, &ntok);
2852 if (macro)
2854 (*macro->emit) (tok, ntok, macro->arg);
2855 return;
2860 /* Search opcodes. */
2861 opcode = (const struct alpha_opcode *) hash_find (alpha_opcode_hash, opname);
2862 if (opcode)
2864 found_something = 1;
2865 opcode = find_opcode_match (opcode, tok, &ntok, &cpumatch);
2866 if (opcode)
2868 struct alpha_insn insn;
2869 assemble_insn (opcode, tok, ntok, &insn, reloc);
2871 /* Copy the sequence number for the reloc from the reloc token. */
2872 if (reloc != BFD_RELOC_UNUSED)
2873 insn.sequence = tok[ntok].X_add_number;
2875 emit_insn (&insn);
2876 return;
2880 if (found_something)
2882 if (cpumatch)
2883 as_bad (_("inappropriate arguments for opcode `%s'"), opname);
2884 else
2885 as_bad (_("opcode `%s' not supported for target %s"), opname,
2886 alpha_target_name);
2888 else
2889 as_bad (_("unknown opcode `%s'"), opname);
2892 /* Some instruction sets indexed by lg(size). */
2893 static const char * const sextX_op[] = { "sextb", "sextw", "sextl", NULL };
2894 static const char * const insXl_op[] = { "insbl", "inswl", "insll", "insql" };
2895 static const char * const insXh_op[] = { NULL, "inswh", "inslh", "insqh" };
2896 static const char * const extXl_op[] = { "extbl", "extwl", "extll", "extql" };
2897 static const char * const extXh_op[] = { NULL, "extwh", "extlh", "extqh" };
2898 static const char * const mskXl_op[] = { "mskbl", "mskwl", "mskll", "mskql" };
2899 static const char * const mskXh_op[] = { NULL, "mskwh", "msklh", "mskqh" };
2900 static const char * const stX_op[] = { "stb", "stw", "stl", "stq" };
2901 static const char * const ldXu_op[] = { "ldbu", "ldwu", NULL, NULL };
2903 /* Implement the ldgp macro. */
2905 static void
2906 emit_ldgp (tok, ntok, unused)
2907 const expressionS *tok;
2908 int ntok ATTRIBUTE_UNUSED;
2909 const PTR unused ATTRIBUTE_UNUSED;
2911 #ifdef OBJ_AOUT
2912 FIXME
2913 #endif
2914 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
2915 /* from "ldgp r1,n(r2)", generate "ldah r1,X(R2); lda r1,Y(r1)"
2916 with appropriate constants and relocations. */
2917 struct alpha_insn insn;
2918 expressionS newtok[3];
2919 expressionS addend;
2921 #ifdef OBJ_ECOFF
2922 if (regno (tok[2].X_add_number) == AXP_REG_PV)
2923 ecoff_set_gp_prolog_size (0);
2924 #endif
2926 newtok[0] = tok[0];
2927 set_tok_const (newtok[1], 0);
2928 newtok[2] = tok[2];
2930 assemble_tokens_to_insn ("ldah", newtok, 3, &insn);
2932 addend = tok[1];
2934 #ifdef OBJ_ECOFF
2935 if (addend.X_op != O_constant)
2936 as_bad (_("can not resolve expression"));
2937 addend.X_op = O_symbol;
2938 addend.X_add_symbol = alpha_gp_symbol;
2939 #endif
2941 insn.nfixups = 1;
2942 insn.fixups[0].exp = addend;
2943 insn.fixups[0].reloc = BFD_RELOC_ALPHA_GPDISP_HI16;
2944 insn.sequence = next_sequence_num;
2946 emit_insn (&insn);
2948 set_tok_preg (newtok[2], tok[0].X_add_number);
2950 assemble_tokens_to_insn ("lda", newtok, 3, &insn);
2952 #ifdef OBJ_ECOFF
2953 addend.X_add_number += 4;
2954 #endif
2956 insn.nfixups = 1;
2957 insn.fixups[0].exp = addend;
2958 insn.fixups[0].reloc = BFD_RELOC_ALPHA_GPDISP_LO16;
2959 insn.sequence = next_sequence_num--;
2961 emit_insn (&insn);
2962 #endif /* OBJ_ECOFF || OBJ_ELF */
2965 #ifdef OBJ_EVAX
2967 /* Add symbol+addend to link pool.
2968 Return offset from basesym to entry in link pool.
2970 Add new fixup only if offset isn't 16bit. */
2972 valueT
2973 add_to_link_pool (basesym, sym, addend)
2974 symbolS *basesym;
2975 symbolS *sym;
2976 offsetT addend;
2978 segT current_section = now_seg;
2979 int current_subsec = now_subseg;
2980 valueT offset;
2981 bfd_reloc_code_real_type reloc_type;
2982 char *p;
2983 segment_info_type *seginfo = seg_info (alpha_link_section);
2984 fixS *fixp;
2986 offset = - *symbol_get_obj (basesym);
2988 /* @@ This assumes all entries in a given section will be of the same
2989 size... Probably correct, but unwise to rely on. */
2990 /* This must always be called with the same subsegment. */
2992 if (seginfo->frchainP)
2993 for (fixp = seginfo->frchainP->fix_root;
2994 fixp != (fixS *) NULL;
2995 fixp = fixp->fx_next, offset += 8)
2997 if (fixp->fx_addsy == sym && fixp->fx_offset == addend)
2999 if (range_signed_16 (offset))
3001 return offset;
3006 /* Not found in 16bit signed range. */
3008 subseg_set (alpha_link_section, 0);
3009 p = frag_more (8);
3010 memset (p, 0, 8);
3012 fix_new (frag_now, p - frag_now->fr_literal, 8, sym, addend, 0,
3013 BFD_RELOC_64);
3015 subseg_set (current_section, current_subsec);
3016 seginfo->literal_pool_size += 8;
3017 return offset;
3020 #endif /* OBJ_EVAX */
3022 /* Load a (partial) expression into a target register.
3024 If poffset is not null, after the call it will either contain
3025 O_constant 0, or a 16-bit offset appropriate for any MEM format
3026 instruction. In addition, pbasereg will be modified to point to
3027 the base register to use in that MEM format instruction.
3029 In any case, *pbasereg should contain a base register to add to the
3030 expression. This will normally be either AXP_REG_ZERO or
3031 alpha_gp_register. Symbol addresses will always be loaded via $gp,
3032 so "foo($0)" is interpreted as adding the address of foo to $0;
3033 i.e. "ldq $targ, LIT($gp); addq $targ, $0, $targ". Odd, perhaps,
3034 but this is what OSF/1 does.
3036 If explicit relocations of the form !literal!<number> are allowed,
3037 and used, then explict_reloc with be an expression pointer.
3039 Finally, the return value is nonzero if the calling macro may emit
3040 a LITUSE reloc if otherwise appropriate; the return value is the
3041 sequence number to use. */
3043 static long
3044 load_expression (targreg, exp, pbasereg, poffset)
3045 int targreg;
3046 const expressionS *exp;
3047 int *pbasereg;
3048 expressionS *poffset;
3050 long emit_lituse = 0;
3051 offsetT addend = exp->X_add_number;
3052 int basereg = *pbasereg;
3053 struct alpha_insn insn;
3054 expressionS newtok[3];
3056 switch (exp->X_op)
3058 case O_symbol:
3060 #ifdef OBJ_ECOFF
3061 offsetT lit;
3063 /* Attempt to reduce .lit load by splitting the offset from
3064 its symbol when possible, but don't create a situation in
3065 which we'd fail. */
3066 if (!range_signed_32 (addend) &&
3067 (alpha_noat_on || targreg == AXP_REG_AT))
3069 lit = add_to_literal_pool (exp->X_add_symbol, addend,
3070 alpha_lita_section, 8);
3071 addend = 0;
3073 else
3075 lit = add_to_literal_pool (exp->X_add_symbol, 0,
3076 alpha_lita_section, 8);
3079 if (lit >= 0x8000)
3080 as_fatal (_("overflow in literal (.lita) table"));
3082 /* emit "ldq r, lit(gp)" */
3084 if (basereg != alpha_gp_register && targreg == basereg)
3086 if (alpha_noat_on)
3087 as_bad (_("macro requires $at register while noat in effect"));
3088 if (targreg == AXP_REG_AT)
3089 as_bad (_("macro requires $at while $at in use"));
3091 set_tok_reg (newtok[0], AXP_REG_AT);
3093 else
3094 set_tok_reg (newtok[0], targreg);
3095 set_tok_sym (newtok[1], alpha_lita_symbol, lit);
3096 set_tok_preg (newtok[2], alpha_gp_register);
3098 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
3100 assert (insn.nfixups == 1);
3101 insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITERAL;
3102 insn.sequence = emit_lituse = next_sequence_num--;
3103 #endif /* OBJ_ECOFF */
3104 #ifdef OBJ_ELF
3105 /* emit "ldq r, gotoff(gp)" */
3107 if (basereg != alpha_gp_register && targreg == basereg)
3109 if (alpha_noat_on)
3110 as_bad (_("macro requires $at register while noat in effect"));
3111 if (targreg == AXP_REG_AT)
3112 as_bad (_("macro requires $at while $at in use"));
3114 set_tok_reg (newtok[0], AXP_REG_AT);
3116 else
3117 set_tok_reg (newtok[0], targreg);
3119 /* XXX: Disable this .got minimizing optimization so that we can get
3120 better instruction offset knowledge in the compiler. This happens
3121 very infrequently anyway. */
3122 if (1
3123 || (!range_signed_32 (addend)
3124 && (alpha_noat_on || targreg == AXP_REG_AT)))
3126 newtok[1] = *exp;
3127 addend = 0;
3129 else
3131 set_tok_sym (newtok[1], exp->X_add_symbol, 0);
3134 set_tok_preg (newtok[2], alpha_gp_register);
3136 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
3138 assert (insn.nfixups == 1);
3139 insn.fixups[0].reloc = BFD_RELOC_ALPHA_ELF_LITERAL;
3140 insn.sequence = emit_lituse = next_sequence_num--;
3141 #endif /* OBJ_ELF */
3142 #ifdef OBJ_EVAX
3143 offsetT link;
3145 /* Find symbol or symbol pointer in link section. */
3147 if (exp->X_add_symbol == alpha_evax_proc.symbol)
3149 if (range_signed_16 (addend))
3151 set_tok_reg (newtok[0], targreg);
3152 set_tok_const (newtok[1], addend);
3153 set_tok_preg (newtok[2], basereg);
3154 assemble_tokens_to_insn ("lda", newtok, 3, &insn);
3155 addend = 0;
3157 else
3159 set_tok_reg (newtok[0], targreg);
3160 set_tok_const (newtok[1], 0);
3161 set_tok_preg (newtok[2], basereg);
3162 assemble_tokens_to_insn ("lda", newtok, 3, &insn);
3165 else
3167 if (!range_signed_32 (addend))
3169 link = add_to_link_pool (alpha_evax_proc.symbol,
3170 exp->X_add_symbol, addend);
3171 addend = 0;
3173 else
3175 link = add_to_link_pool (alpha_evax_proc.symbol,
3176 exp->X_add_symbol, 0);
3178 set_tok_reg (newtok[0], targreg);
3179 set_tok_const (newtok[1], link);
3180 set_tok_preg (newtok[2], basereg);
3181 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
3183 #endif /* OBJ_EVAX */
3185 emit_insn (&insn);
3187 #ifndef OBJ_EVAX
3188 if (basereg != alpha_gp_register && basereg != AXP_REG_ZERO)
3190 /* emit "addq r, base, r" */
3192 set_tok_reg (newtok[1], basereg);
3193 set_tok_reg (newtok[2], targreg);
3194 assemble_tokens ("addq", newtok, 3, 0);
3196 #endif
3198 basereg = targreg;
3200 break;
3202 case O_constant:
3203 break;
3205 case O_subtract:
3206 /* Assume that this difference expression will be resolved to an
3207 absolute value and that that value will fit in 16 bits. */
3209 set_tok_reg (newtok[0], targreg);
3210 newtok[1] = *exp;
3211 set_tok_preg (newtok[2], basereg);
3212 assemble_tokens ("lda", newtok, 3, 0);
3214 if (poffset)
3215 set_tok_const (*poffset, 0);
3216 return 0;
3218 case O_big:
3219 if (exp->X_add_number > 0)
3220 as_bad (_("bignum invalid; zero assumed"));
3221 else
3222 as_bad (_("floating point number invalid; zero assumed"));
3223 addend = 0;
3224 break;
3226 default:
3227 as_bad (_("can't handle expression"));
3228 addend = 0;
3229 break;
3232 if (!range_signed_32 (addend))
3234 offsetT lit;
3235 long seq_num = next_sequence_num--;
3237 /* For 64-bit addends, just put it in the literal pool. */
3239 #ifdef OBJ_EVAX
3240 /* emit "ldq targreg, lit(basereg)" */
3241 lit = add_to_link_pool (alpha_evax_proc.symbol,
3242 section_symbol (absolute_section), addend);
3243 set_tok_reg (newtok[0], targreg);
3244 set_tok_const (newtok[1], lit);
3245 set_tok_preg (newtok[2], alpha_gp_register);
3246 assemble_tokens ("ldq", newtok, 3, 0);
3247 #else
3249 if (alpha_lit8_section == NULL)
3251 create_literal_section (".lit8",
3252 &alpha_lit8_section,
3253 &alpha_lit8_symbol);
3255 #ifdef OBJ_ECOFF
3256 alpha_lit8_literal = add_to_literal_pool (alpha_lit8_symbol, 0x8000,
3257 alpha_lita_section, 8);
3258 if (alpha_lit8_literal >= 0x8000)
3259 as_fatal (_("overflow in literal (.lita) table"));
3260 #endif
3263 lit = add_to_literal_pool (NULL, addend, alpha_lit8_section, 8) - 0x8000;
3264 if (lit >= 0x8000)
3265 as_fatal (_("overflow in literal (.lit8) table"));
3267 /* emit "lda litreg, .lit8+0x8000" */
3269 if (targreg == basereg)
3271 if (alpha_noat_on)
3272 as_bad (_("macro requires $at register while noat in effect"));
3273 if (targreg == AXP_REG_AT)
3274 as_bad (_("macro requires $at while $at in use"));
3276 set_tok_reg (newtok[0], AXP_REG_AT);
3278 else
3279 set_tok_reg (newtok[0], targreg);
3280 #ifdef OBJ_ECOFF
3281 set_tok_sym (newtok[1], alpha_lita_symbol, alpha_lit8_literal);
3282 #endif
3283 #ifdef OBJ_ELF
3284 set_tok_sym (newtok[1], alpha_lit8_symbol, 0x8000);
3285 #endif
3286 set_tok_preg (newtok[2], alpha_gp_register);
3288 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
3290 assert (insn.nfixups == 1);
3291 #ifdef OBJ_ECOFF
3292 insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITERAL;
3293 #endif
3294 #ifdef OBJ_ELF
3295 insn.fixups[0].reloc = BFD_RELOC_ALPHA_ELF_LITERAL;
3296 #endif
3297 insn.sequence = seq_num;
3299 emit_insn (&insn);
3301 /* emit "ldq litreg, lit(litreg)" */
3303 set_tok_const (newtok[1], lit);
3304 set_tok_preg (newtok[2], newtok[0].X_add_number);
3306 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
3308 assert (insn.nfixups < MAX_INSN_FIXUPS);
3309 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
3310 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3311 insn.nfixups++;
3312 insn.sequence = seq_num;
3313 emit_lituse = 0;
3315 emit_insn (&insn);
3317 /* emit "addq litreg, base, target" */
3319 if (basereg != AXP_REG_ZERO)
3321 set_tok_reg (newtok[1], basereg);
3322 set_tok_reg (newtok[2], targreg);
3323 assemble_tokens ("addq", newtok, 3, 0);
3325 #endif /* !OBJ_EVAX */
3327 if (poffset)
3328 set_tok_const (*poffset, 0);
3329 *pbasereg = targreg;
3331 else
3333 offsetT low, high, extra, tmp;
3335 /* for 32-bit operands, break up the addend */
3337 low = sign_extend_16 (addend);
3338 tmp = addend - low;
3339 high = sign_extend_16 (tmp >> 16);
3341 if (tmp - (high << 16))
3343 extra = 0x4000;
3344 tmp -= 0x40000000;
3345 high = sign_extend_16 (tmp >> 16);
3347 else
3348 extra = 0;
3350 set_tok_reg (newtok[0], targreg);
3351 set_tok_preg (newtok[2], basereg);
3353 if (extra)
3355 /* emit "ldah r, extra(r) */
3356 set_tok_const (newtok[1], extra);
3357 assemble_tokens ("ldah", newtok, 3, 0);
3358 set_tok_preg (newtok[2], basereg = targreg);
3361 if (high)
3363 /* emit "ldah r, high(r) */
3364 set_tok_const (newtok[1], high);
3365 assemble_tokens ("ldah", newtok, 3, 0);
3366 basereg = targreg;
3367 set_tok_preg (newtok[2], basereg);
3370 if ((low && !poffset) || (!poffset && basereg != targreg))
3372 /* emit "lda r, low(base)" */
3373 set_tok_const (newtok[1], low);
3374 assemble_tokens ("lda", newtok, 3, 0);
3375 basereg = targreg;
3376 low = 0;
3379 if (poffset)
3380 set_tok_const (*poffset, low);
3381 *pbasereg = basereg;
3384 return emit_lituse;
3387 /* The lda macro differs from the lda instruction in that it handles
3388 most simple expressions, particualrly symbol address loads and
3389 large constants. */
3391 static void
3392 emit_lda (tok, ntok, unused)
3393 const expressionS *tok;
3394 int ntok;
3395 const PTR unused ATTRIBUTE_UNUSED;
3397 int basereg;
3399 if (ntok == 2)
3400 basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
3401 else
3402 basereg = tok[2].X_add_number;
3404 (void) load_expression (tok[0].X_add_number, &tok[1], &basereg, NULL);
3407 /* The ldah macro differs from the ldah instruction in that it has $31
3408 as an implied base register. */
3410 static void
3411 emit_ldah (tok, ntok, unused)
3412 const expressionS *tok;
3413 int ntok ATTRIBUTE_UNUSED;
3414 const PTR unused ATTRIBUTE_UNUSED;
3416 expressionS newtok[3];
3418 newtok[0] = tok[0];
3419 newtok[1] = tok[1];
3420 set_tok_preg (newtok[2], AXP_REG_ZERO);
3422 assemble_tokens ("ldah", newtok, 3, 0);
3425 /* Handle all "simple" integer register loads -- ldq, ldq_l, ldq_u,
3426 etc. They differ from the real instructions in that they do simple
3427 expressions like the lda macro. */
3429 static void
3430 emit_ir_load (tok, ntok, opname)
3431 const expressionS *tok;
3432 int ntok;
3433 const PTR opname;
3435 int basereg;
3436 long lituse;
3437 expressionS newtok[3];
3438 struct alpha_insn insn;
3440 if (ntok == 2)
3441 basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
3442 else
3443 basereg = tok[2].X_add_number;
3445 lituse = load_expression (tok[0].X_add_number, &tok[1], &basereg,
3446 &newtok[1]);
3448 newtok[0] = tok[0];
3449 set_tok_preg (newtok[2], basereg);
3451 assemble_tokens_to_insn ((const char *) opname, newtok, 3, &insn);
3453 if (lituse)
3455 assert (insn.nfixups < MAX_INSN_FIXUPS);
3456 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
3457 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3458 insn.nfixups++;
3459 insn.sequence = lituse;
3462 emit_insn (&insn);
3465 /* Handle fp register loads, and both integer and fp register stores.
3466 Again, we handle simple expressions. */
3468 static void
3469 emit_loadstore (tok, ntok, opname)
3470 const expressionS *tok;
3471 int ntok;
3472 const PTR opname;
3474 int basereg;
3475 long lituse;
3476 expressionS newtok[3];
3477 struct alpha_insn insn;
3479 if (ntok == 2)
3480 basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
3481 else
3482 basereg = tok[2].X_add_number;
3484 if (tok[1].X_op != O_constant || !range_signed_16 (tok[1].X_add_number))
3486 if (alpha_noat_on)
3487 as_bad (_("macro requires $at register while noat in effect"));
3489 lituse = load_expression (AXP_REG_AT, &tok[1], &basereg, &newtok[1]);
3491 else
3493 newtok[1] = tok[1];
3494 lituse = 0;
3497 newtok[0] = tok[0];
3498 set_tok_preg (newtok[2], basereg);
3500 assemble_tokens_to_insn ((const char *) opname, newtok, 3, &insn);
3502 if (lituse)
3504 assert (insn.nfixups < MAX_INSN_FIXUPS);
3505 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
3506 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3507 insn.nfixups++;
3508 insn.sequence = lituse;
3511 emit_insn (&insn);
3514 /* Load a half-word or byte as an unsigned value. */
3516 static void
3517 emit_ldXu (tok, ntok, vlgsize)
3518 const expressionS *tok;
3519 int ntok;
3520 const PTR vlgsize;
3522 if (alpha_target & AXP_OPCODE_BWX)
3523 emit_ir_load (tok, ntok, ldXu_op[(long) vlgsize]);
3524 else
3526 expressionS newtok[3];
3527 struct alpha_insn insn;
3528 int basereg;
3529 long lituse;
3531 if (alpha_noat_on)
3532 as_bad (_("macro requires $at register while noat in effect"));
3534 if (ntok == 2)
3535 basereg = (tok[1].X_op == O_constant
3536 ? AXP_REG_ZERO : alpha_gp_register);
3537 else
3538 basereg = tok[2].X_add_number;
3540 /* emit "lda $at, exp" */
3542 lituse = load_expression (AXP_REG_AT, &tok[1], &basereg, NULL);
3544 /* emit "ldq_u targ, 0($at)" */
3546 newtok[0] = tok[0];
3547 set_tok_const (newtok[1], 0);
3548 set_tok_preg (newtok[2], basereg);
3549 assemble_tokens_to_insn ("ldq_u", newtok, 3, &insn);
3551 if (lituse)
3553 assert (insn.nfixups < MAX_INSN_FIXUPS);
3554 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
3555 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3556 insn.nfixups++;
3557 insn.sequence = lituse;
3560 emit_insn (&insn);
3562 /* emit "extXl targ, $at, targ" */
3564 set_tok_reg (newtok[1], basereg);
3565 newtok[2] = newtok[0];
3566 assemble_tokens_to_insn (extXl_op[(long) vlgsize], newtok, 3, &insn);
3568 if (lituse)
3570 assert (insn.nfixups < MAX_INSN_FIXUPS);
3571 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF;
3572 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3573 insn.nfixups++;
3574 insn.sequence = lituse;
3577 emit_insn (&insn);
3581 /* Load a half-word or byte as a signed value. */
3583 static void
3584 emit_ldX (tok, ntok, vlgsize)
3585 const expressionS *tok;
3586 int ntok;
3587 const PTR vlgsize;
3589 emit_ldXu (tok, ntok, vlgsize);
3590 assemble_tokens (sextX_op[(long) vlgsize], tok, 1, 1);
3593 /* Load an integral value from an unaligned address as an unsigned
3594 value. */
3596 static void
3597 emit_uldXu (tok, ntok, vlgsize)
3598 const expressionS *tok;
3599 int ntok;
3600 const PTR vlgsize;
3602 long lgsize = (long) vlgsize;
3603 expressionS newtok[3];
3605 if (alpha_noat_on)
3606 as_bad (_("macro requires $at register while noat in effect"));
3608 /* emit "lda $at, exp" */
3610 memcpy (newtok, tok, sizeof (expressionS) * ntok);
3611 newtok[0].X_add_number = AXP_REG_AT;
3612 assemble_tokens ("lda", newtok, ntok, 1);
3614 /* emit "ldq_u $t9, 0($at)" */
3616 set_tok_reg (newtok[0], AXP_REG_T9);
3617 set_tok_const (newtok[1], 0);
3618 set_tok_preg (newtok[2], AXP_REG_AT);
3619 assemble_tokens ("ldq_u", newtok, 3, 1);
3621 /* emit "ldq_u $t10, size-1($at)" */
3623 set_tok_reg (newtok[0], AXP_REG_T10);
3624 set_tok_const (newtok[1], (1 << lgsize) - 1);
3625 assemble_tokens ("ldq_u", newtok, 3, 1);
3627 /* emit "extXl $t9, $at, $t9" */
3629 set_tok_reg (newtok[0], AXP_REG_T9);
3630 set_tok_reg (newtok[1], AXP_REG_AT);
3631 set_tok_reg (newtok[2], AXP_REG_T9);
3632 assemble_tokens (extXl_op[lgsize], newtok, 3, 1);
3634 /* emit "extXh $t10, $at, $t10" */
3636 set_tok_reg (newtok[0], AXP_REG_T10);
3637 set_tok_reg (newtok[2], AXP_REG_T10);
3638 assemble_tokens (extXh_op[lgsize], newtok, 3, 1);
3640 /* emit "or $t9, $t10, targ" */
3642 set_tok_reg (newtok[0], AXP_REG_T9);
3643 set_tok_reg (newtok[1], AXP_REG_T10);
3644 newtok[2] = tok[0];
3645 assemble_tokens ("or", newtok, 3, 1);
3648 /* Load an integral value from an unaligned address as a signed value.
3649 Note that quads should get funneled to the unsigned load since we
3650 don't have to do the sign extension. */
3652 static void
3653 emit_uldX (tok, ntok, vlgsize)
3654 const expressionS *tok;
3655 int ntok;
3656 const PTR vlgsize;
3658 emit_uldXu (tok, ntok, vlgsize);
3659 assemble_tokens (sextX_op[(long) vlgsize], tok, 1, 1);
3662 /* Implement the ldil macro. */
3664 static void
3665 emit_ldil (tok, ntok, unused)
3666 const expressionS *tok;
3667 int ntok;
3668 const PTR unused ATTRIBUTE_UNUSED;
3670 expressionS newtok[2];
3672 memcpy (newtok, tok, sizeof (newtok));
3673 newtok[1].X_add_number = sign_extend_32 (tok[1].X_add_number);
3675 assemble_tokens ("lda", newtok, ntok, 1);
3678 /* Store a half-word or byte. */
3680 static void
3681 emit_stX (tok, ntok, vlgsize)
3682 const expressionS *tok;
3683 int ntok;
3684 const PTR vlgsize;
3686 int lgsize = (int) (long) vlgsize;
3688 if (alpha_target & AXP_OPCODE_BWX)
3689 emit_loadstore (tok, ntok, stX_op[lgsize]);
3690 else
3692 expressionS newtok[3];
3693 struct alpha_insn insn;
3694 int basereg;
3695 long lituse;
3697 if (alpha_noat_on)
3698 as_bad (_("macro requires $at register while noat in effect"));
3700 if (ntok == 2)
3701 basereg = (tok[1].X_op == O_constant
3702 ? AXP_REG_ZERO : alpha_gp_register);
3703 else
3704 basereg = tok[2].X_add_number;
3706 /* emit "lda $at, exp" */
3708 lituse = load_expression (AXP_REG_AT, &tok[1], &basereg, NULL);
3710 /* emit "ldq_u $t9, 0($at)" */
3712 set_tok_reg (newtok[0], AXP_REG_T9);
3713 set_tok_const (newtok[1], 0);
3714 set_tok_preg (newtok[2], basereg);
3715 assemble_tokens_to_insn ("ldq_u", newtok, 3, &insn);
3717 if (lituse)
3719 assert (insn.nfixups < MAX_INSN_FIXUPS);
3720 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
3721 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3722 insn.nfixups++;
3723 insn.sequence = lituse;
3726 emit_insn (&insn);
3728 /* emit "insXl src, $at, $t10" */
3730 newtok[0] = tok[0];
3731 set_tok_reg (newtok[1], basereg);
3732 set_tok_reg (newtok[2], AXP_REG_T10);
3733 assemble_tokens_to_insn (insXl_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 "mskXl $t9, $at, $t9" */
3748 set_tok_reg (newtok[0], AXP_REG_T9);
3749 newtok[2] = newtok[0];
3750 assemble_tokens_to_insn (mskXl_op[lgsize], newtok, 3, &insn);
3752 if (lituse)
3754 assert (insn.nfixups < MAX_INSN_FIXUPS);
3755 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF;
3756 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3757 insn.nfixups++;
3758 insn.sequence = lituse;
3761 emit_insn (&insn);
3763 /* emit "or $t9, $t10, $t9" */
3765 set_tok_reg (newtok[1], AXP_REG_T10);
3766 assemble_tokens ("or", newtok, 3, 1);
3768 /* emit "stq_u $t9, 0($at) */
3770 set_tok_const(newtok[1], 0);
3771 set_tok_preg (newtok[2], AXP_REG_AT);
3772 assemble_tokens_to_insn ("stq_u", newtok, 3, &insn);
3774 if (lituse)
3776 assert (insn.nfixups < MAX_INSN_FIXUPS);
3777 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
3778 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3779 insn.nfixups++;
3780 insn.sequence = lituse;
3783 emit_insn (&insn);
3787 /* Store an integer to an unaligned address. */
3789 static void
3790 emit_ustX (tok, ntok, vlgsize)
3791 const expressionS *tok;
3792 int ntok;
3793 const PTR vlgsize;
3795 int lgsize = (int) (long) vlgsize;
3796 expressionS newtok[3];
3798 /* emit "lda $at, exp" */
3800 memcpy (newtok, tok, sizeof (expressionS) * ntok);
3801 newtok[0].X_add_number = AXP_REG_AT;
3802 assemble_tokens ("lda", newtok, ntok, 1);
3804 /* emit "ldq_u $9, 0($at)" */
3806 set_tok_reg (newtok[0], AXP_REG_T9);
3807 set_tok_const (newtok[1], 0);
3808 set_tok_preg (newtok[2], AXP_REG_AT);
3809 assemble_tokens ("ldq_u", newtok, 3, 1);
3811 /* emit "ldq_u $10, size-1($at)" */
3813 set_tok_reg (newtok[0], AXP_REG_T10);
3814 set_tok_const (newtok[1], (1 << lgsize) - 1);
3815 assemble_tokens ("ldq_u", newtok, 3, 1);
3817 /* emit "insXl src, $at, $t11" */
3819 newtok[0] = tok[0];
3820 set_tok_reg (newtok[1], AXP_REG_AT);
3821 set_tok_reg (newtok[2], AXP_REG_T11);
3822 assemble_tokens (insXl_op[lgsize], newtok, 3, 1);
3824 /* emit "insXh src, $at, $t12" */
3826 set_tok_reg (newtok[2], AXP_REG_T12);
3827 assemble_tokens (insXh_op[lgsize], newtok, 3, 1);
3829 /* emit "mskXl $t9, $at, $t9" */
3831 set_tok_reg (newtok[0], AXP_REG_T9);
3832 newtok[2] = newtok[0];
3833 assemble_tokens (mskXl_op[lgsize], newtok, 3, 1);
3835 /* emit "mskXh $t10, $at, $t10" */
3837 set_tok_reg (newtok[0], AXP_REG_T10);
3838 newtok[2] = newtok[0];
3839 assemble_tokens (mskXh_op[lgsize], newtok, 3, 1);
3841 /* emit "or $t9, $t11, $t9" */
3843 set_tok_reg (newtok[0], AXP_REG_T9);
3844 set_tok_reg (newtok[1], AXP_REG_T11);
3845 newtok[2] = newtok[0];
3846 assemble_tokens ("or", newtok, 3, 1);
3848 /* emit "or $t10, $t12, $t10" */
3850 set_tok_reg (newtok[0], AXP_REG_T10);
3851 set_tok_reg (newtok[1], AXP_REG_T12);
3852 newtok[2] = newtok[0];
3853 assemble_tokens ("or", newtok, 3, 1);
3855 /* emit "stq_u $t9, 0($at)" */
3857 set_tok_reg (newtok[0], AXP_REG_T9);
3858 set_tok_const (newtok[1], 0);
3859 set_tok_preg (newtok[2], AXP_REG_AT);
3860 assemble_tokens ("stq_u", newtok, 3, 1);
3862 /* emit "stq_u $t10, size-1($at)" */
3864 set_tok_reg (newtok[0], AXP_REG_T10);
3865 set_tok_const (newtok[1], (1 << lgsize) - 1);
3866 assemble_tokens ("stq_u", newtok, 3, 1);
3869 /* Sign extend a half-word or byte. The 32-bit sign extend is
3870 implemented as "addl $31, $r, $t" in the opcode table. */
3872 static void
3873 emit_sextX (tok, ntok, vlgsize)
3874 const expressionS *tok;
3875 int ntok;
3876 const PTR vlgsize;
3878 long lgsize = (long) vlgsize;
3880 if (alpha_target & AXP_OPCODE_BWX)
3881 assemble_tokens (sextX_op[lgsize], tok, ntok, 0);
3882 else
3884 int bitshift = 64 - 8 * (1 << lgsize);
3885 expressionS newtok[3];
3887 /* emit "sll src,bits,dst" */
3889 newtok[0] = tok[0];
3890 set_tok_const (newtok[1], bitshift);
3891 newtok[2] = tok[ntok - 1];
3892 assemble_tokens ("sll", newtok, 3, 1);
3894 /* emit "sra dst,bits,dst" */
3896 newtok[0] = newtok[2];
3897 assemble_tokens ("sra", newtok, 3, 1);
3901 /* Implement the division and modulus macros. */
3903 #ifdef OBJ_EVAX
3905 /* Make register usage like in normal procedure call.
3906 Don't clobber PV and RA. */
3908 static void
3909 emit_division (tok, ntok, symname)
3910 const expressionS *tok;
3911 int ntok;
3912 const PTR symname;
3914 /* DIVISION and MODULUS. Yech.
3916 Convert
3917 OP x,y,result
3919 mov x,R16 # if x != R16
3920 mov y,R17 # if y != R17
3921 lda AT,__OP
3922 jsr AT,(AT),0
3923 mov R0,result
3925 with appropriate optimizations if R0,R16,R17 are the registers
3926 specified by the compiler. */
3928 int xr, yr, rr;
3929 symbolS *sym;
3930 expressionS newtok[3];
3932 xr = regno (tok[0].X_add_number);
3933 yr = regno (tok[1].X_add_number);
3935 if (ntok < 3)
3936 rr = xr;
3937 else
3938 rr = regno (tok[2].X_add_number);
3940 /* Move the operands into the right place. */
3941 if (yr == AXP_REG_R16 && xr == AXP_REG_R17)
3943 /* They are in exactly the wrong order -- swap through AT. */
3945 if (alpha_noat_on)
3946 as_bad (_("macro requires $at register while noat in effect"));
3948 set_tok_reg (newtok[0], AXP_REG_R16);
3949 set_tok_reg (newtok[1], AXP_REG_AT);
3950 assemble_tokens ("mov", newtok, 2, 1);
3952 set_tok_reg (newtok[0], AXP_REG_R17);
3953 set_tok_reg (newtok[1], AXP_REG_R16);
3954 assemble_tokens ("mov", newtok, 2, 1);
3956 set_tok_reg (newtok[0], AXP_REG_AT);
3957 set_tok_reg (newtok[1], AXP_REG_R17);
3958 assemble_tokens ("mov", newtok, 2, 1);
3960 else
3962 if (yr == AXP_REG_R16)
3964 set_tok_reg (newtok[0], AXP_REG_R16);
3965 set_tok_reg (newtok[1], AXP_REG_R17);
3966 assemble_tokens ("mov", newtok, 2, 1);
3969 if (xr != AXP_REG_R16)
3971 set_tok_reg (newtok[0], xr);
3972 set_tok_reg (newtok[1], AXP_REG_R16);
3973 assemble_tokens ("mov", newtok, 2, 1);
3976 if (yr != AXP_REG_R16 && yr != AXP_REG_R17)
3978 set_tok_reg (newtok[0], yr);
3979 set_tok_reg (newtok[1], AXP_REG_R17);
3980 assemble_tokens ("mov", newtok, 2, 1);
3984 sym = symbol_find_or_make ((const char *) symname);
3986 set_tok_reg (newtok[0], AXP_REG_AT);
3987 set_tok_sym (newtok[1], sym, 0);
3988 assemble_tokens ("lda", newtok, 2, 1);
3990 /* Call the division routine. */
3991 set_tok_reg (newtok[0], AXP_REG_AT);
3992 set_tok_cpreg (newtok[1], AXP_REG_AT);
3993 set_tok_const (newtok[2], 0);
3994 assemble_tokens ("jsr", newtok, 3, 1);
3996 /* Move the result to the right place. */
3997 if (rr != AXP_REG_R0)
3999 set_tok_reg (newtok[0], AXP_REG_R0);
4000 set_tok_reg (newtok[1], rr);
4001 assemble_tokens ("mov", newtok, 2, 1);
4005 #else /* !OBJ_EVAX */
4007 static void
4008 emit_division (tok, ntok, symname)
4009 const expressionS *tok;
4010 int ntok;
4011 const PTR symname;
4013 /* DIVISION and MODULUS. Yech.
4014 Convert
4015 OP x,y,result
4017 lda pv,__OP
4018 mov x,t10
4019 mov y,t11
4020 jsr t9,(pv),__OP
4021 mov t12,result
4023 with appropriate optimizations if t10,t11,t12 are the registers
4024 specified by the compiler. */
4026 int xr, yr, rr;
4027 symbolS *sym;
4028 expressionS newtok[3];
4030 xr = regno (tok[0].X_add_number);
4031 yr = regno (tok[1].X_add_number);
4033 if (ntok < 3)
4034 rr = xr;
4035 else
4036 rr = regno (tok[2].X_add_number);
4038 sym = symbol_find_or_make ((const char *) symname);
4040 /* Move the operands into the right place. */
4041 if (yr == AXP_REG_T10 && xr == AXP_REG_T11)
4043 /* They are in exactly the wrong order -- swap through AT. */
4044 if (alpha_noat_on)
4045 as_bad (_("macro requires $at register while noat in effect"));
4047 set_tok_reg (newtok[0], AXP_REG_T10);
4048 set_tok_reg (newtok[1], AXP_REG_AT);
4049 assemble_tokens ("mov", newtok, 2, 1);
4051 set_tok_reg (newtok[0], AXP_REG_T11);
4052 set_tok_reg (newtok[1], AXP_REG_T10);
4053 assemble_tokens ("mov", newtok, 2, 1);
4055 set_tok_reg (newtok[0], AXP_REG_AT);
4056 set_tok_reg (newtok[1], AXP_REG_T11);
4057 assemble_tokens ("mov", newtok, 2, 1);
4059 else
4061 if (yr == AXP_REG_T10)
4063 set_tok_reg (newtok[0], AXP_REG_T10);
4064 set_tok_reg (newtok[1], AXP_REG_T11);
4065 assemble_tokens ("mov", newtok, 2, 1);
4068 if (xr != AXP_REG_T10)
4070 set_tok_reg (newtok[0], xr);
4071 set_tok_reg (newtok[1], AXP_REG_T10);
4072 assemble_tokens ("mov", newtok, 2, 1);
4075 if (yr != AXP_REG_T10 && yr != AXP_REG_T11)
4077 set_tok_reg (newtok[0], yr);
4078 set_tok_reg (newtok[1], AXP_REG_T11);
4079 assemble_tokens ("mov", newtok, 2, 1);
4083 /* Call the division routine. */
4084 set_tok_reg (newtok[0], AXP_REG_T9);
4085 set_tok_sym (newtok[1], sym, 0);
4086 assemble_tokens ("jsr", newtok, 2, 1);
4088 /* Reload the GP register. */
4089 #ifdef OBJ_AOUT
4090 FIXME
4091 #endif
4092 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
4093 set_tok_reg (newtok[0], alpha_gp_register);
4094 set_tok_const (newtok[1], 0);
4095 set_tok_preg (newtok[2], AXP_REG_T9);
4096 assemble_tokens ("ldgp", newtok, 3, 1);
4097 #endif
4099 /* Move the result to the right place. */
4100 if (rr != AXP_REG_T12)
4102 set_tok_reg (newtok[0], AXP_REG_T12);
4103 set_tok_reg (newtok[1], rr);
4104 assemble_tokens ("mov", newtok, 2, 1);
4108 #endif /* !OBJ_EVAX */
4110 /* The jsr and jmp macros differ from their instruction counterparts
4111 in that they can load the target address and default most
4112 everything. */
4114 static void
4115 emit_jsrjmp (tok, ntok, vopname)
4116 const expressionS *tok;
4117 int ntok;
4118 const PTR vopname;
4120 const char *opname = (const char *) vopname;
4121 struct alpha_insn insn;
4122 expressionS newtok[3];
4123 int r, tokidx = 0;
4124 long lituse = 0;
4126 if (tokidx < ntok && tok[tokidx].X_op == O_register)
4127 r = regno (tok[tokidx++].X_add_number);
4128 else
4129 r = strcmp (opname, "jmp") == 0 ? AXP_REG_ZERO : AXP_REG_RA;
4131 set_tok_reg (newtok[0], r);
4133 if (tokidx < ntok &&
4134 (tok[tokidx].X_op == O_pregister || tok[tokidx].X_op == O_cpregister))
4135 r = regno (tok[tokidx++].X_add_number);
4136 #ifdef OBJ_EVAX
4137 /* keep register if jsr $n.<sym> */
4138 #else
4139 else
4141 int basereg = alpha_gp_register;
4142 lituse = load_expression (r = AXP_REG_PV, &tok[tokidx], &basereg, NULL);
4144 #endif
4146 set_tok_cpreg (newtok[1], r);
4148 #ifdef OBJ_EVAX
4149 /* FIXME: Add hint relocs to BFD for evax. */
4150 #else
4151 if (tokidx < ntok)
4152 newtok[2] = tok[tokidx];
4153 else
4154 #endif
4155 set_tok_const (newtok[2], 0);
4157 assemble_tokens_to_insn (opname, newtok, 3, &insn);
4159 if (lituse)
4161 assert (insn.nfixups < MAX_INSN_FIXUPS);
4162 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_JSR;
4163 insn.fixups[insn.nfixups].exp.X_op = O_absent;
4164 insn.nfixups++;
4165 insn.sequence = lituse;
4168 emit_insn (&insn);
4171 /* The ret and jcr instructions differ from their instruction
4172 counterparts in that everything can be defaulted. */
4174 static void
4175 emit_retjcr (tok, ntok, vopname)
4176 const expressionS *tok;
4177 int ntok;
4178 const PTR vopname;
4180 const char *opname = (const char *) vopname;
4181 expressionS newtok[3];
4182 int r, tokidx = 0;
4184 if (tokidx < ntok && tok[tokidx].X_op == O_register)
4185 r = regno (tok[tokidx++].X_add_number);
4186 else
4187 r = AXP_REG_ZERO;
4189 set_tok_reg (newtok[0], r);
4191 if (tokidx < ntok &&
4192 (tok[tokidx].X_op == O_pregister || tok[tokidx].X_op == O_cpregister))
4193 r = regno (tok[tokidx++].X_add_number);
4194 else
4195 r = AXP_REG_RA;
4197 set_tok_cpreg (newtok[1], r);
4199 if (tokidx < ntok)
4200 newtok[2] = tok[tokidx];
4201 else
4202 set_tok_const (newtok[2], strcmp (opname, "ret") == 0);
4204 assemble_tokens (opname, newtok, 3, 0);
4207 /* Assembler directives. */
4209 /* Handle the .text pseudo-op. This is like the usual one, but it
4210 clears alpha_insn_label and restores auto alignment. */
4212 static void
4213 s_alpha_text (i)
4214 int i;
4217 #ifdef OBJ_ELF
4218 obj_elf_text (i);
4219 #else
4220 s_text (i);
4221 #endif
4222 alpha_insn_label = NULL;
4223 alpha_auto_align_on = 1;
4224 alpha_current_align = 0;
4227 /* Handle the .data pseudo-op. This is like the usual one, but it
4228 clears alpha_insn_label and restores auto alignment. */
4230 static void
4231 s_alpha_data (i)
4232 int i;
4234 #ifdef OBJ_ELF
4235 obj_elf_data (i);
4236 #else
4237 s_data (i);
4238 #endif
4239 alpha_insn_label = NULL;
4240 alpha_auto_align_on = 1;
4241 alpha_current_align = 0;
4244 #if defined (OBJ_ECOFF) || defined (OBJ_EVAX)
4246 /* Handle the OSF/1 and openVMS .comm pseudo quirks.
4247 openVMS constructs a section for every common symbol. */
4249 static void
4250 s_alpha_comm (ignore)
4251 int ignore ATTRIBUTE_UNUSED;
4253 register char *name;
4254 register char c;
4255 register char *p;
4256 offsetT temp;
4257 register symbolS *symbolP;
4259 #ifdef OBJ_EVAX
4260 segT current_section = now_seg;
4261 int current_subsec = now_subseg;
4262 segT new_seg;
4263 #endif
4265 name = input_line_pointer;
4266 c = get_symbol_end ();
4268 /* just after name is now '\0' */
4269 p = input_line_pointer;
4270 *p = c;
4272 SKIP_WHITESPACE ();
4274 /* Alpha OSF/1 compiler doesn't provide the comma, gcc does. */
4275 if (*input_line_pointer == ',')
4277 input_line_pointer++;
4278 SKIP_WHITESPACE ();
4280 if ((temp = get_absolute_expression ()) < 0)
4282 as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) temp);
4283 ignore_rest_of_line ();
4284 return;
4287 *p = 0;
4288 symbolP = symbol_find_or_make (name);
4290 #ifdef OBJ_EVAX
4291 /* Make a section for the common symbol. */
4292 new_seg = subseg_new (xstrdup (name), 0);
4293 #endif
4295 *p = c;
4297 #ifdef OBJ_EVAX
4298 /* alignment might follow */
4299 if (*input_line_pointer == ',')
4301 offsetT align;
4303 input_line_pointer++;
4304 align = get_absolute_expression ();
4305 bfd_set_section_alignment (stdoutput, new_seg, align);
4307 #endif
4309 if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
4311 as_bad (_("Ignoring attempt to re-define symbol"));
4312 ignore_rest_of_line ();
4313 return;
4316 #ifdef OBJ_EVAX
4317 if (bfd_section_size (stdoutput, new_seg) > 0)
4319 if (bfd_section_size (stdoutput, new_seg) != temp)
4320 as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
4321 S_GET_NAME (symbolP),
4322 (long) bfd_section_size (stdoutput, new_seg),
4323 (long) temp);
4325 #else
4326 if (S_GET_VALUE (symbolP))
4328 if (S_GET_VALUE (symbolP) != (valueT) temp)
4329 as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
4330 S_GET_NAME (symbolP),
4331 (long) S_GET_VALUE (symbolP),
4332 (long) temp);
4334 #endif
4335 else
4337 #ifdef OBJ_EVAX
4338 subseg_set (new_seg, 0);
4339 p = frag_more (temp);
4340 new_seg->flags |= SEC_IS_COMMON;
4341 if (! S_IS_DEFINED (symbolP))
4342 S_SET_SEGMENT (symbolP, new_seg);
4343 #else
4344 S_SET_VALUE (symbolP, (valueT) temp);
4345 #endif
4346 S_SET_EXTERNAL (symbolP);
4349 #ifdef OBJ_EVAX
4350 subseg_set (current_section, current_subsec);
4351 #endif
4353 know (symbol_get_frag (symbolP) == &zero_address_frag);
4355 demand_empty_rest_of_line ();
4358 #endif /* ! OBJ_ELF */
4360 #ifdef OBJ_ECOFF
4362 /* Handle the .rdata pseudo-op. This is like the usual one, but it
4363 clears alpha_insn_label and restores auto alignment. */
4365 static void
4366 s_alpha_rdata (ignore)
4367 int ignore ATTRIBUTE_UNUSED;
4369 int temp;
4371 temp = get_absolute_expression ();
4372 subseg_new (".rdata", 0);
4373 demand_empty_rest_of_line ();
4374 alpha_insn_label = NULL;
4375 alpha_auto_align_on = 1;
4376 alpha_current_align = 0;
4379 #endif
4381 #ifdef OBJ_ECOFF
4383 /* Handle the .sdata pseudo-op. This is like the usual one, but it
4384 clears alpha_insn_label and restores auto alignment. */
4386 static void
4387 s_alpha_sdata (ignore)
4388 int ignore ATTRIBUTE_UNUSED;
4390 int temp;
4392 temp = get_absolute_expression ();
4393 subseg_new (".sdata", 0);
4394 demand_empty_rest_of_line ();
4395 alpha_insn_label = NULL;
4396 alpha_auto_align_on = 1;
4397 alpha_current_align = 0;
4399 #endif
4401 #ifdef OBJ_ELF
4403 /* Handle the .section pseudo-op. This is like the usual one, but it
4404 clears alpha_insn_label and restores auto alignment. */
4406 static void
4407 s_alpha_section (ignore)
4408 int ignore ATTRIBUTE_UNUSED;
4410 obj_elf_section (ignore);
4412 alpha_insn_label = NULL;
4413 alpha_auto_align_on = 1;
4414 alpha_current_align = 0;
4417 static void
4418 s_alpha_ent (dummy)
4419 int dummy ATTRIBUTE_UNUSED;
4421 if (ECOFF_DEBUGGING)
4422 ecoff_directive_ent (0);
4423 else
4425 char *name, name_end;
4426 name = input_line_pointer;
4427 name_end = get_symbol_end ();
4429 if (! is_name_beginner (*name))
4431 as_warn (_(".ent directive has no name"));
4432 *input_line_pointer = name_end;
4434 else
4436 symbolS *sym;
4438 if (alpha_cur_ent_sym)
4439 as_warn (_("nested .ent directives"));
4441 sym = symbol_find_or_make (name);
4442 symbol_get_bfdsym (sym)->flags |= BSF_FUNCTION;
4443 alpha_cur_ent_sym = sym;
4445 /* The .ent directive is sometimes followed by a number. Not sure
4446 what it really means, but ignore it. */
4447 *input_line_pointer = name_end;
4448 SKIP_WHITESPACE ();
4449 if (*input_line_pointer == ',')
4451 input_line_pointer++;
4452 SKIP_WHITESPACE ();
4454 if (ISDIGIT (*input_line_pointer) || *input_line_pointer == '-')
4455 (void) get_absolute_expression ();
4457 demand_empty_rest_of_line ();
4461 static void
4462 s_alpha_end (dummy)
4463 int dummy ATTRIBUTE_UNUSED;
4465 if (ECOFF_DEBUGGING)
4466 ecoff_directive_end (0);
4467 else
4469 char *name, name_end;
4470 name = input_line_pointer;
4471 name_end = get_symbol_end ();
4473 if (! is_name_beginner (*name))
4475 as_warn (_(".end directive has no name"));
4476 *input_line_pointer = name_end;
4478 else
4480 symbolS *sym;
4482 sym = symbol_find (name);
4483 if (sym != alpha_cur_ent_sym)
4484 as_warn (_(".end directive names different symbol than .ent"));
4486 /* Create an expression to calculate the size of the function. */
4487 if (sym)
4489 symbol_get_obj (sym)->size =
4490 (expressionS *) xmalloc (sizeof (expressionS));
4491 symbol_get_obj (sym)->size->X_op = O_subtract;
4492 symbol_get_obj (sym)->size->X_add_symbol
4493 = symbol_new ("L0\001", now_seg, frag_now_fix (), frag_now);
4494 symbol_get_obj (sym)->size->X_op_symbol = sym;
4495 symbol_get_obj (sym)->size->X_add_number = 0;
4498 alpha_cur_ent_sym = NULL;
4500 *input_line_pointer = name_end;
4502 demand_empty_rest_of_line ();
4506 static void
4507 s_alpha_mask (fp)
4508 int fp;
4510 if (ECOFF_DEBUGGING)
4512 if (fp)
4513 ecoff_directive_fmask (0);
4514 else
4515 ecoff_directive_mask (0);
4517 else
4518 discard_rest_of_line ();
4521 static void
4522 s_alpha_frame (dummy)
4523 int dummy ATTRIBUTE_UNUSED;
4525 if (ECOFF_DEBUGGING)
4526 ecoff_directive_frame (0);
4527 else
4528 discard_rest_of_line ();
4531 static void
4532 s_alpha_prologue (ignore)
4533 int ignore ATTRIBUTE_UNUSED;
4535 symbolS *sym;
4536 int arg;
4538 arg = get_absolute_expression ();
4539 demand_empty_rest_of_line ();
4541 if (ECOFF_DEBUGGING)
4542 sym = ecoff_get_cur_proc_sym ();
4543 else
4544 sym = alpha_cur_ent_sym;
4545 know (sym != NULL);
4547 switch (arg)
4549 case 0: /* No PV required. */
4550 S_SET_OTHER (sym, STO_ALPHA_NOPV
4551 | (S_GET_OTHER (sym) & ~STO_ALPHA_STD_GPLOAD));
4552 break;
4553 case 1: /* Std GP load. */
4554 S_SET_OTHER (sym, STO_ALPHA_STD_GPLOAD
4555 | (S_GET_OTHER (sym) & ~STO_ALPHA_STD_GPLOAD));
4556 break;
4557 case 2: /* Non-std use of PV. */
4558 break;
4560 default:
4561 as_bad (_("Invalid argument %d to .prologue."), arg);
4562 break;
4566 static char *first_file_directive;
4568 static void
4569 s_alpha_file (ignore)
4570 int ignore ATTRIBUTE_UNUSED;
4572 /* Save the first .file directive we see, so that we can change our
4573 minds about whether ecoff debugging should or shouldn't be enabled. */
4574 if (alpha_flag_mdebug < 0 && ! first_file_directive)
4576 char *start = input_line_pointer;
4577 size_t len;
4579 discard_rest_of_line ();
4581 len = input_line_pointer - start;
4582 first_file_directive = xmalloc (len + 1);
4583 memcpy (first_file_directive, start, len);
4584 first_file_directive[len] = '\0';
4586 input_line_pointer = start;
4589 if (ECOFF_DEBUGGING)
4590 ecoff_directive_file (0);
4591 else
4592 dwarf2_directive_file (0);
4595 static void
4596 s_alpha_loc (ignore)
4597 int ignore ATTRIBUTE_UNUSED;
4599 if (ECOFF_DEBUGGING)
4600 ecoff_directive_loc (0);
4601 else
4602 dwarf2_directive_loc (0);
4605 static void
4606 s_alpha_stab (n)
4607 int n;
4609 /* If we've been undecided about mdebug, make up our minds in favour. */
4610 if (alpha_flag_mdebug < 0)
4612 segT sec = subseg_new (".mdebug", 0);
4613 bfd_set_section_flags (stdoutput, sec, SEC_HAS_CONTENTS | SEC_READONLY);
4614 bfd_set_section_alignment (stdoutput, sec, 3);
4616 ecoff_read_begin_hook ();
4618 if (first_file_directive)
4620 char *save_ilp = input_line_pointer;
4621 input_line_pointer = first_file_directive;
4622 ecoff_directive_file (0);
4623 input_line_pointer = save_ilp;
4624 free (first_file_directive);
4627 alpha_flag_mdebug = 1;
4629 s_stab (n);
4632 static void
4633 s_alpha_coff_wrapper (which)
4634 int which;
4636 static void (* const fns[]) PARAMS ((int)) = {
4637 ecoff_directive_begin,
4638 ecoff_directive_bend,
4639 ecoff_directive_def,
4640 ecoff_directive_dim,
4641 ecoff_directive_endef,
4642 ecoff_directive_scl,
4643 ecoff_directive_tag,
4644 ecoff_directive_val,
4647 assert (which >= 0 && which < (int) (sizeof (fns)/sizeof (*fns)));
4649 if (ECOFF_DEBUGGING)
4650 (*fns[which]) (0);
4651 else
4653 as_bad (_("ECOFF debugging is disabled."));
4654 ignore_rest_of_line ();
4657 #endif /* OBJ_ELF */
4659 #ifdef OBJ_EVAX
4661 /* Handle the section specific pseudo-op. */
4663 static void
4664 s_alpha_section (secid)
4665 int secid;
4667 int temp;
4668 #define EVAX_SECTION_COUNT 5
4669 static char *section_name[EVAX_SECTION_COUNT + 1] =
4670 { "NULL", ".rdata", ".comm", ".link", ".ctors", ".dtors" };
4672 if ((secid <= 0) || (secid > EVAX_SECTION_COUNT))
4674 as_fatal (_("Unknown section directive"));
4675 demand_empty_rest_of_line ();
4676 return;
4678 temp = get_absolute_expression ();
4679 subseg_new (section_name[secid], 0);
4680 demand_empty_rest_of_line ();
4681 alpha_insn_label = NULL;
4682 alpha_auto_align_on = 1;
4683 alpha_current_align = 0;
4686 /* Parse .ent directives. */
4688 static void
4689 s_alpha_ent (ignore)
4690 int ignore ATTRIBUTE_UNUSED;
4692 symbolS *symbol;
4693 expressionS symexpr;
4695 alpha_evax_proc.pdsckind = 0;
4696 alpha_evax_proc.framereg = -1;
4697 alpha_evax_proc.framesize = 0;
4698 alpha_evax_proc.rsa_offset = 0;
4699 alpha_evax_proc.ra_save = AXP_REG_RA;
4700 alpha_evax_proc.fp_save = -1;
4701 alpha_evax_proc.imask = 0;
4702 alpha_evax_proc.fmask = 0;
4703 alpha_evax_proc.prologue = 0;
4704 alpha_evax_proc.type = 0;
4706 expression (&symexpr);
4708 if (symexpr.X_op != O_symbol)
4710 as_fatal (_(".ent directive has no symbol"));
4711 demand_empty_rest_of_line ();
4712 return;
4715 symbol = make_expr_symbol (&symexpr);
4716 symbol_get_bfdsym (symbol)->flags |= BSF_FUNCTION;
4717 alpha_evax_proc.symbol = symbol;
4719 demand_empty_rest_of_line ();
4720 return;
4723 /* Parse .frame <framreg>,<framesize>,RA,<rsa_offset> directives. */
4725 static void
4726 s_alpha_frame (ignore)
4727 int ignore ATTRIBUTE_UNUSED;
4729 long val;
4731 alpha_evax_proc.framereg = tc_get_register (1);
4733 SKIP_WHITESPACE ();
4734 if (*input_line_pointer++ != ','
4735 || get_absolute_expression_and_terminator (&val) != ',')
4737 as_warn (_("Bad .frame directive 1./2. param"));
4738 --input_line_pointer;
4739 demand_empty_rest_of_line ();
4740 return;
4743 alpha_evax_proc.framesize = val;
4745 (void) tc_get_register (1);
4746 SKIP_WHITESPACE ();
4747 if (*input_line_pointer++ != ',')
4749 as_warn (_("Bad .frame directive 3./4. param"));
4750 --input_line_pointer;
4751 demand_empty_rest_of_line ();
4752 return;
4754 alpha_evax_proc.rsa_offset = get_absolute_expression ();
4756 return;
4759 static void
4760 s_alpha_pdesc (ignore)
4761 int ignore ATTRIBUTE_UNUSED;
4763 char *name;
4764 char name_end;
4765 long val;
4766 register char *p;
4767 expressionS exp;
4768 symbolS *entry_sym;
4769 fixS *fixp;
4770 segment_info_type *seginfo = seg_info (alpha_link_section);
4772 if (now_seg != alpha_link_section)
4774 as_bad (_(".pdesc directive not in link (.link) section"));
4775 demand_empty_rest_of_line ();
4776 return;
4779 if ((alpha_evax_proc.symbol == 0)
4780 || (!S_IS_DEFINED (alpha_evax_proc.symbol)))
4782 as_fatal (_(".pdesc has no matching .ent"));
4783 demand_empty_rest_of_line ();
4784 return;
4787 *symbol_get_obj (alpha_evax_proc.symbol) =
4788 (valueT) seginfo->literal_pool_size;
4790 expression (&exp);
4791 if (exp.X_op != O_symbol)
4793 as_warn (_(".pdesc directive has no entry symbol"));
4794 demand_empty_rest_of_line ();
4795 return;
4798 entry_sym = make_expr_symbol (&exp);
4799 /* Save bfd symbol of proc desc in function symbol. */
4800 symbol_get_bfdsym (alpha_evax_proc.symbol)->udata.p
4801 = symbol_get_bfdsym (entry_sym);
4803 SKIP_WHITESPACE ();
4804 if (*input_line_pointer++ != ',')
4806 as_warn (_("No comma after .pdesc <entryname>"));
4807 demand_empty_rest_of_line ();
4808 return;
4811 SKIP_WHITESPACE ();
4812 name = input_line_pointer;
4813 name_end = get_symbol_end ();
4815 if (strncmp (name, "stack", 5) == 0)
4817 alpha_evax_proc.pdsckind = PDSC_S_K_KIND_FP_STACK;
4819 else if (strncmp (name, "reg", 3) == 0)
4821 alpha_evax_proc.pdsckind = PDSC_S_K_KIND_FP_REGISTER;
4823 else if (strncmp (name, "null", 4) == 0)
4825 alpha_evax_proc.pdsckind = PDSC_S_K_KIND_NULL;
4827 else
4829 as_fatal (_("unknown procedure kind"));
4830 demand_empty_rest_of_line ();
4831 return;
4834 *input_line_pointer = name_end;
4835 demand_empty_rest_of_line ();
4837 #ifdef md_flush_pending_output
4838 md_flush_pending_output ();
4839 #endif
4841 frag_align (3, 0, 0);
4842 p = frag_more (16);
4843 fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
4844 fixp->fx_done = 1;
4845 seginfo->literal_pool_size += 16;
4847 *p = alpha_evax_proc.pdsckind
4848 | ((alpha_evax_proc.framereg == 29) ? PDSC_S_M_BASE_REG_IS_FP : 0);
4849 *(p + 1) = PDSC_S_M_NATIVE | PDSC_S_M_NO_JACKET;
4851 switch (alpha_evax_proc.pdsckind)
4853 case PDSC_S_K_KIND_NULL:
4854 *(p + 2) = 0;
4855 *(p + 3) = 0;
4856 break;
4857 case PDSC_S_K_KIND_FP_REGISTER:
4858 *(p + 2) = alpha_evax_proc.fp_save;
4859 *(p + 3) = alpha_evax_proc.ra_save;
4860 break;
4861 case PDSC_S_K_KIND_FP_STACK:
4862 md_number_to_chars (p + 2, (valueT) alpha_evax_proc.rsa_offset, 2);
4863 break;
4864 default: /* impossible */
4865 break;
4868 *(p + 4) = 0;
4869 *(p + 5) = alpha_evax_proc.type & 0x0f;
4871 /* Signature offset. */
4872 md_number_to_chars (p + 6, (valueT) 0, 2);
4874 fix_new_exp (frag_now, p - frag_now->fr_literal+8, 8, &exp, 0, BFD_RELOC_64);
4876 if (alpha_evax_proc.pdsckind == PDSC_S_K_KIND_NULL)
4877 return;
4879 /* Add dummy fix to make add_to_link_pool work. */
4880 p = frag_more (8);
4881 fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
4882 fixp->fx_done = 1;
4883 seginfo->literal_pool_size += 8;
4885 /* pdesc+16: Size. */
4886 md_number_to_chars (p, (valueT) alpha_evax_proc.framesize, 4);
4888 md_number_to_chars (p + 4, (valueT) 0, 2);
4890 /* Entry length. */
4891 md_number_to_chars (p + 6, alpha_evax_proc.prologue, 2);
4893 if (alpha_evax_proc.pdsckind == PDSC_S_K_KIND_FP_REGISTER)
4894 return;
4896 /* Add dummy fix to make add_to_link_pool work. */
4897 p = frag_more (8);
4898 fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
4899 fixp->fx_done = 1;
4900 seginfo->literal_pool_size += 8;
4902 /* pdesc+24: register masks. */
4904 md_number_to_chars (p, alpha_evax_proc.imask, 4);
4905 md_number_to_chars (p + 4, alpha_evax_proc.fmask, 4);
4907 return;
4910 /* Support for crash debug on vms. */
4912 static void
4913 s_alpha_name (ignore)
4914 int ignore ATTRIBUTE_UNUSED;
4916 register char *p;
4917 expressionS exp;
4918 segment_info_type *seginfo = seg_info (alpha_link_section);
4920 if (now_seg != alpha_link_section)
4922 as_bad (_(".name directive not in link (.link) section"));
4923 demand_empty_rest_of_line ();
4924 return;
4927 expression (&exp);
4928 if (exp.X_op != O_symbol)
4930 as_warn (_(".name directive has no symbol"));
4931 demand_empty_rest_of_line ();
4932 return;
4935 demand_empty_rest_of_line ();
4937 #ifdef md_flush_pending_output
4938 md_flush_pending_output ();
4939 #endif
4941 frag_align (3, 0, 0);
4942 p = frag_more (8);
4943 seginfo->literal_pool_size += 8;
4945 fix_new_exp (frag_now, p - frag_now->fr_literal, 8, &exp, 0, BFD_RELOC_64);
4947 return;
4950 static void
4951 s_alpha_linkage (ignore)
4952 int ignore ATTRIBUTE_UNUSED;
4954 expressionS exp;
4955 char *p;
4957 #ifdef md_flush_pending_output
4958 md_flush_pending_output ();
4959 #endif
4961 expression (&exp);
4962 if (exp.X_op != O_symbol)
4964 as_fatal (_("No symbol after .linkage"));
4966 else
4968 p = frag_more (LKP_S_K_SIZE);
4969 memset (p, 0, LKP_S_K_SIZE);
4970 fix_new_exp (frag_now, p - frag_now->fr_literal, LKP_S_K_SIZE, &exp, 0,\
4971 BFD_RELOC_ALPHA_LINKAGE);
4973 demand_empty_rest_of_line ();
4975 return;
4978 static void
4979 s_alpha_code_address (ignore)
4980 int ignore ATTRIBUTE_UNUSED;
4982 expressionS exp;
4983 char *p;
4985 #ifdef md_flush_pending_output
4986 md_flush_pending_output ();
4987 #endif
4989 expression (&exp);
4990 if (exp.X_op != O_symbol)
4992 as_fatal (_("No symbol after .code_address"));
4994 else
4996 p = frag_more (8);
4997 memset (p, 0, 8);
4998 fix_new_exp (frag_now, p - frag_now->fr_literal, 8, &exp, 0,\
4999 BFD_RELOC_ALPHA_CODEADDR);
5001 demand_empty_rest_of_line ();
5003 return;
5006 static void
5007 s_alpha_fp_save (ignore)
5008 int ignore ATTRIBUTE_UNUSED;
5011 alpha_evax_proc.fp_save = tc_get_register (1);
5013 demand_empty_rest_of_line ();
5014 return;
5017 static void
5018 s_alpha_mask (ignore)
5019 int ignore ATTRIBUTE_UNUSED;
5021 long val;
5023 if (get_absolute_expression_and_terminator (&val) != ',')
5025 as_warn (_("Bad .mask directive"));
5026 --input_line_pointer;
5028 else
5030 alpha_evax_proc.imask = val;
5031 (void) get_absolute_expression ();
5033 demand_empty_rest_of_line ();
5035 return;
5038 static void
5039 s_alpha_fmask (ignore)
5040 int ignore ATTRIBUTE_UNUSED;
5042 long val;
5044 if (get_absolute_expression_and_terminator (&val) != ',')
5046 as_warn (_("Bad .fmask directive"));
5047 --input_line_pointer;
5049 else
5051 alpha_evax_proc.fmask = val;
5052 (void) get_absolute_expression ();
5054 demand_empty_rest_of_line ();
5056 return;
5059 static void
5060 s_alpha_end (ignore)
5061 int ignore ATTRIBUTE_UNUSED;
5063 char c;
5065 c = get_symbol_end ();
5066 *input_line_pointer = c;
5067 demand_empty_rest_of_line ();
5068 alpha_evax_proc.symbol = 0;
5070 return;
5073 static void
5074 s_alpha_file (ignore)
5075 int ignore ATTRIBUTE_UNUSED;
5077 symbolS *s;
5078 int length;
5079 static char case_hack[32];
5081 extern char *demand_copy_string PARAMS ((int *lenP));
5083 sprintf (case_hack, "<CASE:%01d%01d>",
5084 alpha_flag_hash_long_names, alpha_flag_show_after_trunc);
5086 s = symbol_find_or_make (case_hack);
5087 symbol_get_bfdsym (s)->flags |= BSF_FILE;
5089 get_absolute_expression ();
5090 s = symbol_find_or_make (demand_copy_string (&length));
5091 symbol_get_bfdsym (s)->flags |= BSF_FILE;
5092 demand_empty_rest_of_line ();
5094 return;
5096 #endif /* OBJ_EVAX */
5098 /* Handle the .gprel32 pseudo op. */
5100 static void
5101 s_alpha_gprel32 (ignore)
5102 int ignore ATTRIBUTE_UNUSED;
5104 expressionS e;
5105 char *p;
5107 SKIP_WHITESPACE ();
5108 expression (&e);
5110 #ifdef OBJ_ELF
5111 switch (e.X_op)
5113 case O_constant:
5114 e.X_add_symbol = section_symbol (absolute_section);
5115 e.X_op = O_symbol;
5116 /* FALLTHRU */
5117 case O_symbol:
5118 break;
5119 default:
5120 abort ();
5122 #else
5123 #ifdef OBJ_ECOFF
5124 switch (e.X_op)
5126 case O_constant:
5127 e.X_add_symbol = section_symbol (absolute_section);
5128 /* fall through */
5129 case O_symbol:
5130 e.X_op = O_subtract;
5131 e.X_op_symbol = alpha_gp_symbol;
5132 break;
5133 default:
5134 abort ();
5136 #endif
5137 #endif
5139 if (alpha_auto_align_on && alpha_current_align < 2)
5140 alpha_align (2, (char *) NULL, alpha_insn_label, 0);
5141 if (alpha_current_align > 2)
5142 alpha_current_align = 2;
5143 alpha_insn_label = NULL;
5145 p = frag_more (4);
5146 memset (p, 0, 4);
5147 fix_new_exp (frag_now, p - frag_now->fr_literal, 4,
5148 &e, 0, BFD_RELOC_GPREL32);
5151 /* Handle floating point allocation pseudo-ops. This is like the
5152 generic vresion, but it makes sure the current label, if any, is
5153 correctly aligned. */
5155 static void
5156 s_alpha_float_cons (type)
5157 int type;
5159 int log_size;
5161 switch (type)
5163 default:
5164 case 'f':
5165 case 'F':
5166 log_size = 2;
5167 break;
5169 case 'd':
5170 case 'D':
5171 case 'G':
5172 log_size = 3;
5173 break;
5175 case 'x':
5176 case 'X':
5177 case 'p':
5178 case 'P':
5179 log_size = 4;
5180 break;
5183 if (alpha_auto_align_on && alpha_current_align < log_size)
5184 alpha_align (log_size, (char *) NULL, alpha_insn_label, 0);
5185 if (alpha_current_align > log_size)
5186 alpha_current_align = log_size;
5187 alpha_insn_label = NULL;
5189 float_cons (type);
5192 /* Handle the .proc pseudo op. We don't really do much with it except
5193 parse it. */
5195 static void
5196 s_alpha_proc (is_static)
5197 int is_static ATTRIBUTE_UNUSED;
5199 char *name;
5200 char c;
5201 char *p;
5202 symbolS *symbolP;
5203 int temp;
5205 /* Takes ".proc name,nargs" */
5206 SKIP_WHITESPACE ();
5207 name = input_line_pointer;
5208 c = get_symbol_end ();
5209 p = input_line_pointer;
5210 symbolP = symbol_find_or_make (name);
5211 *p = c;
5212 SKIP_WHITESPACE ();
5213 if (*input_line_pointer != ',')
5215 *p = 0;
5216 as_warn (_("Expected comma after name \"%s\""), name);
5217 *p = c;
5218 temp = 0;
5219 ignore_rest_of_line ();
5221 else
5223 input_line_pointer++;
5224 temp = get_absolute_expression ();
5226 /* *symbol_get_obj (symbolP) = (signed char) temp; */
5227 as_warn (_("unhandled: .proc %s,%d"), name, temp);
5228 demand_empty_rest_of_line ();
5231 /* Handle the .set pseudo op. This is used to turn on and off most of
5232 the assembler features. */
5234 static void
5235 s_alpha_set (x)
5236 int x ATTRIBUTE_UNUSED;
5238 char *name, ch, *s;
5239 int yesno = 1;
5241 SKIP_WHITESPACE ();
5242 name = input_line_pointer;
5243 ch = get_symbol_end ();
5245 s = name;
5246 if (s[0] == 'n' && s[1] == 'o')
5248 yesno = 0;
5249 s += 2;
5251 if (!strcmp ("reorder", s))
5252 /* ignore */ ;
5253 else if (!strcmp ("at", s))
5254 alpha_noat_on = !yesno;
5255 else if (!strcmp ("macro", s))
5256 alpha_macros_on = yesno;
5257 else if (!strcmp ("move", s))
5258 /* ignore */ ;
5259 else if (!strcmp ("volatile", s))
5260 /* ignore */ ;
5261 else
5262 as_warn (_("Tried to .set unrecognized mode `%s'"), name);
5264 *input_line_pointer = ch;
5265 demand_empty_rest_of_line ();
5268 /* Handle the .base pseudo op. This changes the assembler's notion of
5269 the $gp register. */
5271 static void
5272 s_alpha_base (ignore)
5273 int ignore ATTRIBUTE_UNUSED;
5275 #if 0
5276 if (first_32bit_quadrant)
5278 /* not fatal, but it might not work in the end */
5279 as_warn (_("File overrides no-base-register option."));
5280 first_32bit_quadrant = 0;
5282 #endif
5284 SKIP_WHITESPACE ();
5285 if (*input_line_pointer == '$')
5286 { /* $rNN form */
5287 input_line_pointer++;
5288 if (*input_line_pointer == 'r')
5289 input_line_pointer++;
5292 alpha_gp_register = get_absolute_expression ();
5293 if (alpha_gp_register < 0 || alpha_gp_register > 31)
5295 alpha_gp_register = AXP_REG_GP;
5296 as_warn (_("Bad base register, using $%d."), alpha_gp_register);
5299 demand_empty_rest_of_line ();
5302 /* Handle the .align pseudo-op. This aligns to a power of two. It
5303 also adjusts any current instruction label. We treat this the same
5304 way the MIPS port does: .align 0 turns off auto alignment. */
5306 static void
5307 s_alpha_align (ignore)
5308 int ignore ATTRIBUTE_UNUSED;
5310 int align;
5311 char fill, *pfill;
5312 long max_alignment = 15;
5314 align = get_absolute_expression ();
5315 if (align > max_alignment)
5317 align = max_alignment;
5318 as_bad (_("Alignment too large: %d. assumed"), align);
5320 else if (align < 0)
5322 as_warn (_("Alignment negative: 0 assumed"));
5323 align = 0;
5326 if (*input_line_pointer == ',')
5328 input_line_pointer++;
5329 fill = get_absolute_expression ();
5330 pfill = &fill;
5332 else
5333 pfill = NULL;
5335 if (align != 0)
5337 alpha_auto_align_on = 1;
5338 alpha_align (align, pfill, alpha_insn_label, 1);
5340 else
5342 alpha_auto_align_on = 0;
5345 demand_empty_rest_of_line ();
5348 /* Hook the normal string processor to reset known alignment. */
5350 static void
5351 s_alpha_stringer (terminate)
5352 int terminate;
5354 alpha_current_align = 0;
5355 alpha_insn_label = NULL;
5356 stringer (terminate);
5359 /* Hook the normal space processing to reset known alignment. */
5361 static void
5362 s_alpha_space (ignore)
5363 int ignore;
5365 alpha_current_align = 0;
5366 alpha_insn_label = NULL;
5367 s_space (ignore);
5370 /* Hook into cons for auto-alignment. */
5372 void
5373 alpha_cons_align (size)
5374 int size;
5376 int log_size;
5378 log_size = 0;
5379 while ((size >>= 1) != 0)
5380 ++log_size;
5382 if (alpha_auto_align_on && alpha_current_align < log_size)
5383 alpha_align (log_size, (char *) NULL, alpha_insn_label, 0);
5384 if (alpha_current_align > log_size)
5385 alpha_current_align = log_size;
5386 alpha_insn_label = NULL;
5389 /* Here come the .uword, .ulong, and .uquad explicitly unaligned
5390 pseudos. We just turn off auto-alignment and call down to cons. */
5392 static void
5393 s_alpha_ucons (bytes)
5394 int bytes;
5396 int hold = alpha_auto_align_on;
5397 alpha_auto_align_on = 0;
5398 cons (bytes);
5399 alpha_auto_align_on = hold;
5402 /* Switch the working cpu type. */
5404 static void
5405 s_alpha_arch (ignored)
5406 int ignored ATTRIBUTE_UNUSED;
5408 char *name, ch;
5409 const struct cpu_type *p;
5411 SKIP_WHITESPACE ();
5412 name = input_line_pointer;
5413 ch = get_symbol_end ();
5415 for (p = cpu_types; p->name; ++p)
5416 if (strcmp (name, p->name) == 0)
5418 alpha_target_name = p->name, alpha_target = p->flags;
5419 goto found;
5421 as_warn ("Unknown CPU identifier `%s'", name);
5423 found:
5424 *input_line_pointer = ch;
5425 demand_empty_rest_of_line ();
5428 #ifdef DEBUG1
5429 /* print token expression with alpha specific extension. */
5431 static void
5432 alpha_print_token (f, exp)
5433 FILE *f;
5434 const expressionS *exp;
5436 switch (exp->X_op)
5438 case O_cpregister:
5439 putc (',', f);
5440 /* FALLTHRU */
5441 case O_pregister:
5442 putc ('(', f);
5444 expressionS nexp = *exp;
5445 nexp.X_op = O_register;
5446 print_expr (f, &nexp);
5448 putc (')', f);
5449 break;
5450 default:
5451 print_expr (f, exp);
5452 break;
5454 return;
5456 #endif
5458 /* The target specific pseudo-ops which we support. */
5460 const pseudo_typeS md_pseudo_table[] = {
5461 #ifdef OBJ_ECOFF
5462 {"comm", s_alpha_comm, 0}, /* osf1 compiler does this */
5463 {"rdata", s_alpha_rdata, 0},
5464 #endif
5465 {"text", s_alpha_text, 0},
5466 {"data", s_alpha_data, 0},
5467 #ifdef OBJ_ECOFF
5468 {"sdata", s_alpha_sdata, 0},
5469 #endif
5470 #ifdef OBJ_ELF
5471 {"section", s_alpha_section, 0},
5472 {"section.s", s_alpha_section, 0},
5473 {"sect", s_alpha_section, 0},
5474 {"sect.s", s_alpha_section, 0},
5475 #endif
5476 #ifdef OBJ_EVAX
5477 { "pdesc", s_alpha_pdesc, 0},
5478 { "name", s_alpha_name, 0},
5479 { "linkage", s_alpha_linkage, 0},
5480 { "code_address", s_alpha_code_address, 0},
5481 { "ent", s_alpha_ent, 0},
5482 { "frame", s_alpha_frame, 0},
5483 { "fp_save", s_alpha_fp_save, 0},
5484 { "mask", s_alpha_mask, 0},
5485 { "fmask", s_alpha_fmask, 0},
5486 { "end", s_alpha_end, 0},
5487 { "file", s_alpha_file, 0},
5488 { "rdata", s_alpha_section, 1},
5489 { "comm", s_alpha_comm, 0},
5490 { "link", s_alpha_section, 3},
5491 { "ctors", s_alpha_section, 4},
5492 { "dtors", s_alpha_section, 5},
5493 #endif
5494 #ifdef OBJ_ELF
5495 /* Frame related pseudos. */
5496 {"ent", s_alpha_ent, 0},
5497 {"end", s_alpha_end, 0},
5498 {"mask", s_alpha_mask, 0},
5499 {"fmask", s_alpha_mask, 1},
5500 {"frame", s_alpha_frame, 0},
5501 {"prologue", s_alpha_prologue, 0},
5502 {"file", s_alpha_file, 5},
5503 {"loc", s_alpha_loc, 9},
5504 {"stabs", s_alpha_stab, 's'},
5505 {"stabn", s_alpha_stab, 'n'},
5506 /* COFF debugging related pseudos. */
5507 {"begin", s_alpha_coff_wrapper, 0},
5508 {"bend", s_alpha_coff_wrapper, 1},
5509 {"def", s_alpha_coff_wrapper, 2},
5510 {"dim", s_alpha_coff_wrapper, 3},
5511 {"endef", s_alpha_coff_wrapper, 4},
5512 {"scl", s_alpha_coff_wrapper, 5},
5513 {"tag", s_alpha_coff_wrapper, 6},
5514 {"val", s_alpha_coff_wrapper, 7},
5515 #else
5516 {"prologue", s_ignore, 0},
5517 #endif
5518 {"gprel32", s_alpha_gprel32, 0},
5519 {"t_floating", s_alpha_float_cons, 'd'},
5520 {"s_floating", s_alpha_float_cons, 'f'},
5521 {"f_floating", s_alpha_float_cons, 'F'},
5522 {"g_floating", s_alpha_float_cons, 'G'},
5523 {"d_floating", s_alpha_float_cons, 'D'},
5525 {"proc", s_alpha_proc, 0},
5526 {"aproc", s_alpha_proc, 1},
5527 {"set", s_alpha_set, 0},
5528 {"reguse", s_ignore, 0},
5529 {"livereg", s_ignore, 0},
5530 {"base", s_alpha_base, 0}, /*??*/
5531 {"option", s_ignore, 0},
5532 {"aent", s_ignore, 0},
5533 {"ugen", s_ignore, 0},
5534 {"eflag", s_ignore, 0},
5536 {"align", s_alpha_align, 0},
5537 {"double", s_alpha_float_cons, 'd'},
5538 {"float", s_alpha_float_cons, 'f'},
5539 {"single", s_alpha_float_cons, 'f'},
5540 {"ascii", s_alpha_stringer, 0},
5541 {"asciz", s_alpha_stringer, 1},
5542 {"string", s_alpha_stringer, 1},
5543 {"space", s_alpha_space, 0},
5544 {"skip", s_alpha_space, 0},
5545 {"zero", s_alpha_space, 0},
5547 /* Unaligned data pseudos. */
5548 {"uword", s_alpha_ucons, 2},
5549 {"ulong", s_alpha_ucons, 4},
5550 {"uquad", s_alpha_ucons, 8},
5552 #ifdef OBJ_ELF
5553 /* Dwarf wants these versions of unaligned. */
5554 {"2byte", s_alpha_ucons, 2},
5555 {"4byte", s_alpha_ucons, 4},
5556 {"8byte", s_alpha_ucons, 8},
5557 #endif
5559 /* We don't do any optimizing, so we can safely ignore these. */
5560 {"noalias", s_ignore, 0},
5561 {"alias", s_ignore, 0},
5563 {"arch", s_alpha_arch, 0},
5565 {NULL, 0, 0},
5568 /* Build a BFD section with its flags set appropriately for the .lita,
5569 .lit8, or .lit4 sections. */
5571 static void
5572 create_literal_section (name, secp, symp)
5573 const char *name;
5574 segT *secp;
5575 symbolS **symp;
5577 segT current_section = now_seg;
5578 int current_subsec = now_subseg;
5579 segT new_sec;
5581 *secp = new_sec = subseg_new (name, 0);
5582 subseg_set (current_section, current_subsec);
5583 bfd_set_section_alignment (stdoutput, new_sec, 4);
5584 bfd_set_section_flags (stdoutput, new_sec,
5585 SEC_RELOC | SEC_ALLOC | SEC_LOAD | SEC_READONLY
5586 | SEC_DATA);
5588 S_CLEAR_EXTERNAL (*symp = section_symbol (new_sec));
5591 #ifdef OBJ_ECOFF
5593 /* @@@ GP selection voodoo. All of this seems overly complicated and
5594 unnecessary; which is the primary reason it's for ECOFF only. */
5595 static inline void maybe_set_gp PARAMS ((asection *));
5597 static inline void
5598 maybe_set_gp (sec)
5599 asection *sec;
5601 bfd_vma vma;
5602 if (!sec)
5603 return;
5604 vma = bfd_get_section_vma (foo, sec);
5605 if (vma && vma < alpha_gp_value)
5606 alpha_gp_value = vma;
5609 static void
5610 select_gp_value ()
5612 assert (alpha_gp_value == 0);
5614 /* Get minus-one in whatever width... */
5615 alpha_gp_value = 0;
5616 alpha_gp_value--;
5618 /* Select the smallest VMA of these existing sections. */
5619 maybe_set_gp (alpha_lita_section);
5620 #if 0
5621 /* These were disabled before -- should we use them? */
5622 maybe_set_gp (sdata);
5623 maybe_set_gp (lit8_sec);
5624 maybe_set_gp (lit4_sec);
5625 #endif
5627 /* @@ Will a simple 0x8000 work here? If not, why not? */
5628 #define GP_ADJUSTMENT (0x8000 - 0x10)
5630 alpha_gp_value += GP_ADJUSTMENT;
5632 S_SET_VALUE (alpha_gp_symbol, alpha_gp_value);
5634 #ifdef DEBUG1
5635 printf (_("Chose GP value of %lx\n"), alpha_gp_value);
5636 #endif
5638 #endif /* OBJ_ECOFF */
5640 #ifdef OBJ_ELF
5641 /* Map 's' to SHF_ALPHA_GPREL. */
5644 alpha_elf_section_letter (letter, ptr_msg)
5645 int letter;
5646 char **ptr_msg;
5648 if (letter == 's')
5649 return SHF_ALPHA_GPREL;
5651 *ptr_msg = _("Bad .section directive: want a,s,w,x,M,S,G,T in string");
5652 return 0;
5655 /* Map SHF_ALPHA_GPREL to SEC_SMALL_DATA. */
5657 flagword
5658 alpha_elf_section_flags (flags, attr, type)
5659 flagword flags;
5660 int attr, type ATTRIBUTE_UNUSED;
5662 if (attr & SHF_ALPHA_GPREL)
5663 flags |= SEC_SMALL_DATA;
5664 return flags;
5666 #endif /* OBJ_ELF */
5668 /* Called internally to handle all alignment needs. This takes care
5669 of eliding calls to frag_align if'n the cached current alignment
5670 says we've already got it, as well as taking care of the auto-align
5671 feature wrt labels. */
5673 static void
5674 alpha_align (n, pfill, label, force)
5675 int n;
5676 char *pfill;
5677 symbolS *label;
5678 int force ATTRIBUTE_UNUSED;
5680 if (alpha_current_align >= n)
5681 return;
5683 if (pfill == NULL)
5685 if (subseg_text_p (now_seg))
5686 frag_align_code (n, 0);
5687 else
5688 frag_align (n, 0, 0);
5690 else
5691 frag_align (n, *pfill, 0);
5693 alpha_current_align = n;
5695 if (label != NULL && S_GET_SEGMENT (label) == now_seg)
5697 symbol_set_frag (label, frag_now);
5698 S_SET_VALUE (label, (valueT) frag_now_fix ());
5701 record_alignment (now_seg, n);
5703 /* ??? If alpha_flag_relax && force && elf, record the requested alignment
5704 in a reloc for the linker to see. */
5707 /* This is called from HANDLE_ALIGN in write.c. Fill in the contents
5708 of an rs_align_code fragment. */
5710 void
5711 alpha_handle_align (fragp)
5712 fragS *fragp;
5714 static char const unop[4] = { 0x00, 0x00, 0xfe, 0x2f };
5715 static char const nopunop[8] = {
5716 0x1f, 0x04, 0xff, 0x47,
5717 0x00, 0x00, 0xfe, 0x2f
5720 int bytes, fix;
5721 char *p;
5723 if (fragp->fr_type != rs_align_code)
5724 return;
5726 bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix;
5727 p = fragp->fr_literal + fragp->fr_fix;
5728 fix = 0;
5730 if (bytes & 3)
5732 fix = bytes & 3;
5733 memset (p, 0, fix);
5734 p += fix;
5735 bytes -= fix;
5738 if (bytes & 4)
5740 memcpy (p, unop, 4);
5741 p += 4;
5742 bytes -= 4;
5743 fix += 4;
5746 memcpy (p, nopunop, 8);
5748 fragp->fr_fix += fix;
5749 fragp->fr_var = 8;
5752 /* The Alpha has support for some VAX floating point types, as well as for
5753 IEEE floating point. We consider IEEE to be the primary floating point
5754 format, and sneak in the VAX floating point support here. */
5755 #define md_atof vax_md_atof
5756 #include "config/atof-vax.c"