* config/tc-mips.h (mips_flush_pending_output): Delete.
[binutils.git] / gas / config / tc-alpha.c
blobdff7bac6e1e5e66616439a72d0f18e23a7e4d4e7
1 /* tc-alpha.c - Processor-specific code for the DEC Alpha AXP CPU.
2 Copyright 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 2001, 2002, 2003, 2004, 2005 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 #include "dw2gencfi.h"
64 #endif
66 #include "safe-ctype.h"
68 /* Local types. */
70 #define TOKENIZE_ERROR -1
71 #define TOKENIZE_ERROR_REPORT -2
73 #define MAX_INSN_FIXUPS 2
74 #define MAX_INSN_ARGS 5
76 struct alpha_fixup
78 expressionS exp;
79 bfd_reloc_code_real_type reloc;
82 struct alpha_insn
84 unsigned insn;
85 int nfixups;
86 struct alpha_fixup fixups[MAX_INSN_FIXUPS];
87 long sequence;
90 enum alpha_macro_arg
92 MACRO_EOA = 1,
93 MACRO_IR,
94 MACRO_PIR,
95 MACRO_OPIR,
96 MACRO_CPIR,
97 MACRO_FPR,
98 MACRO_EXP,
101 struct alpha_macro
103 const char *name;
104 void (*emit) PARAMS ((const expressionS *, int, const PTR));
105 const PTR arg;
106 enum alpha_macro_arg argsets[16];
109 /* Extra expression types. */
111 #define O_pregister O_md1 /* O_register, in parentheses */
112 #define O_cpregister O_md2 /* + a leading comma */
114 /* The alpha_reloc_op table below depends on the ordering of these. */
115 #define O_literal O_md3 /* !literal relocation */
116 #define O_lituse_addr O_md4 /* !lituse_addr relocation */
117 #define O_lituse_base O_md5 /* !lituse_base relocation */
118 #define O_lituse_bytoff O_md6 /* !lituse_bytoff relocation */
119 #define O_lituse_jsr O_md7 /* !lituse_jsr relocation */
120 #define O_lituse_tlsgd O_md8 /* !lituse_tlsgd relocation */
121 #define O_lituse_tlsldm O_md9 /* !lituse_tlsldm relocation */
122 #define O_gpdisp O_md10 /* !gpdisp relocation */
123 #define O_gprelhigh O_md11 /* !gprelhigh relocation */
124 #define O_gprellow O_md12 /* !gprellow relocation */
125 #define O_gprel O_md13 /* !gprel relocation */
126 #define O_samegp O_md14 /* !samegp relocation */
127 #define O_tlsgd O_md15 /* !tlsgd relocation */
128 #define O_tlsldm O_md16 /* !tlsldm relocation */
129 #define O_gotdtprel O_md17 /* !gotdtprel relocation */
130 #define O_dtprelhi O_md18 /* !dtprelhi relocation */
131 #define O_dtprello O_md19 /* !dtprello relocation */
132 #define O_dtprel O_md20 /* !dtprel relocation */
133 #define O_gottprel O_md21 /* !gottprel relocation */
134 #define O_tprelhi O_md22 /* !tprelhi relocation */
135 #define O_tprello O_md23 /* !tprello relocation */
136 #define O_tprel O_md24 /* !tprel relocation */
138 #define DUMMY_RELOC_LITUSE_ADDR (BFD_RELOC_UNUSED + 1)
139 #define DUMMY_RELOC_LITUSE_BASE (BFD_RELOC_UNUSED + 2)
140 #define DUMMY_RELOC_LITUSE_BYTOFF (BFD_RELOC_UNUSED + 3)
141 #define DUMMY_RELOC_LITUSE_JSR (BFD_RELOC_UNUSED + 4)
142 #define DUMMY_RELOC_LITUSE_TLSGD (BFD_RELOC_UNUSED + 5)
143 #define DUMMY_RELOC_LITUSE_TLSLDM (BFD_RELOC_UNUSED + 6)
145 #define USER_RELOC_P(R) ((R) >= O_literal && (R) <= O_tprel)
147 /* Macros for extracting the type and number of encoded register tokens. */
149 #define is_ir_num(x) (((x) & 32) == 0)
150 #define is_fpr_num(x) (((x) & 32) != 0)
151 #define regno(x) ((x) & 31)
153 /* Something odd inherited from the old assembler. */
155 #define note_gpreg(R) (alpha_gprmask |= (1 << (R)))
156 #define note_fpreg(R) (alpha_fprmask |= (1 << (R)))
158 /* Predicates for 16- and 32-bit ranges */
159 /* XXX: The non-shift version appears to trigger a compiler bug when
160 cross-assembling from x86 w/ gcc 2.7.2. */
162 #if 1
163 #define range_signed_16(x) \
164 (((offsetT) (x) >> 15) == 0 || ((offsetT) (x) >> 15) == -1)
165 #define range_signed_32(x) \
166 (((offsetT) (x) >> 31) == 0 || ((offsetT) (x) >> 31) == -1)
167 #else
168 #define range_signed_16(x) ((offsetT) (x) >= -(offsetT) 0x8000 && \
169 (offsetT) (x) <= (offsetT) 0x7FFF)
170 #define range_signed_32(x) ((offsetT) (x) >= -(offsetT) 0x80000000 && \
171 (offsetT) (x) <= (offsetT) 0x7FFFFFFF)
172 #endif
174 /* Macros for sign extending from 16- and 32-bits. */
175 /* XXX: The cast macros will work on all the systems that I care about,
176 but really a predicate should be found to use the non-cast forms. */
178 #if 1
179 #define sign_extend_16(x) ((short) (x))
180 #define sign_extend_32(x) ((int) (x))
181 #else
182 #define sign_extend_16(x) ((offsetT) (((x) & 0xFFFF) ^ 0x8000) - 0x8000)
183 #define sign_extend_32(x) ((offsetT) (((x) & 0xFFFFFFFF) \
184 ^ 0x80000000) - 0x80000000)
185 #endif
187 /* Macros to build tokens. */
189 #define set_tok_reg(t, r) (memset (&(t), 0, sizeof (t)), \
190 (t).X_op = O_register, \
191 (t).X_add_number = (r))
192 #define set_tok_preg(t, r) (memset (&(t), 0, sizeof (t)), \
193 (t).X_op = O_pregister, \
194 (t).X_add_number = (r))
195 #define set_tok_cpreg(t, r) (memset (&(t), 0, sizeof (t)), \
196 (t).X_op = O_cpregister, \
197 (t).X_add_number = (r))
198 #define set_tok_freg(t, r) (memset (&(t), 0, sizeof (t)), \
199 (t).X_op = O_register, \
200 (t).X_add_number = (r) + 32)
201 #define set_tok_sym(t, s, a) (memset (&(t), 0, sizeof (t)), \
202 (t).X_op = O_symbol, \
203 (t).X_add_symbol = (s), \
204 (t).X_add_number = (a))
205 #define set_tok_const(t, n) (memset (&(t), 0, sizeof (t)), \
206 (t).X_op = O_constant, \
207 (t).X_add_number = (n))
209 /* Prototypes for all local functions. */
211 static struct alpha_reloc_tag *get_alpha_reloc_tag PARAMS ((long));
212 static void alpha_adjust_relocs PARAMS ((bfd *, asection *, PTR));
214 static int tokenize_arguments PARAMS ((char *, expressionS *, int));
215 static const struct alpha_opcode *find_opcode_match
216 PARAMS ((const struct alpha_opcode *, const expressionS *, int *, int *));
217 static const struct alpha_macro *find_macro_match
218 PARAMS ((const struct alpha_macro *, const expressionS *, int *));
219 static unsigned insert_operand
220 PARAMS ((unsigned, const struct alpha_operand *, offsetT, char *, unsigned));
221 static void assemble_insn
222 PARAMS ((const struct alpha_opcode *, const expressionS *, int,
223 struct alpha_insn *, bfd_reloc_code_real_type));
224 static void emit_insn PARAMS ((struct alpha_insn *));
225 static void assemble_tokens_to_insn
226 PARAMS ((const char *, const expressionS *, int, struct alpha_insn *));
227 static void assemble_tokens
228 PARAMS ((const char *, const expressionS *, int, int));
230 static long load_expression
231 PARAMS ((int, const expressionS *, int *, expressionS *));
233 static void emit_ldgp PARAMS ((const expressionS *, int, const PTR));
234 static void emit_division PARAMS ((const expressionS *, int, const PTR));
235 static void emit_lda PARAMS ((const expressionS *, int, const PTR));
236 static void emit_ldah PARAMS ((const expressionS *, int, const PTR));
237 static void emit_ir_load PARAMS ((const expressionS *, int, const PTR));
238 static void emit_loadstore PARAMS ((const expressionS *, int, const PTR));
239 static void emit_jsrjmp PARAMS ((const expressionS *, int, const PTR));
240 static void emit_ldX PARAMS ((const expressionS *, int, const PTR));
241 static void emit_ldXu PARAMS ((const expressionS *, int, const PTR));
242 static void emit_uldX PARAMS ((const expressionS *, int, const PTR));
243 static void emit_uldXu PARAMS ((const expressionS *, int, const PTR));
244 static void emit_ldil PARAMS ((const expressionS *, int, const PTR));
245 static void emit_stX PARAMS ((const expressionS *, int, const PTR));
246 static void emit_ustX PARAMS ((const expressionS *, int, const PTR));
247 static void emit_sextX PARAMS ((const expressionS *, int, const PTR));
248 static void emit_retjcr PARAMS ((const expressionS *, int, const PTR));
250 static void s_alpha_text PARAMS ((int));
251 static void s_alpha_data PARAMS ((int));
252 #ifndef OBJ_ELF
253 static void s_alpha_comm PARAMS ((int));
254 static void s_alpha_rdata PARAMS ((int));
255 #endif
256 #ifdef OBJ_ECOFF
257 static void s_alpha_sdata PARAMS ((int));
258 #endif
259 #ifdef OBJ_ELF
260 static void s_alpha_section PARAMS ((int));
261 static void s_alpha_ent PARAMS ((int));
262 static void s_alpha_end PARAMS ((int));
263 static void s_alpha_mask PARAMS ((int));
264 static void s_alpha_frame PARAMS ((int));
265 static void s_alpha_prologue PARAMS ((int));
266 static void s_alpha_file PARAMS ((int));
267 static void s_alpha_loc PARAMS ((int));
268 static void s_alpha_stab PARAMS ((int));
269 static void s_alpha_coff_wrapper PARAMS ((int));
270 static void s_alpha_usepv PARAMS ((int));
271 #endif
272 #ifdef OBJ_EVAX
273 static void s_alpha_section PARAMS ((int));
274 #endif
275 static void s_alpha_gprel32 PARAMS ((int));
276 static void s_alpha_float_cons PARAMS ((int));
277 static void s_alpha_proc PARAMS ((int));
278 static void s_alpha_set PARAMS ((int));
279 static void s_alpha_base PARAMS ((int));
280 static void s_alpha_align PARAMS ((int));
281 static void s_alpha_stringer PARAMS ((int));
282 static void s_alpha_space PARAMS ((int));
283 static void s_alpha_ucons PARAMS ((int));
284 static void s_alpha_arch PARAMS ((int));
286 static void create_literal_section PARAMS ((const char *, segT *, symbolS **));
287 #ifndef OBJ_ELF
288 static void select_gp_value PARAMS ((void));
289 #endif
290 static void alpha_align PARAMS ((int, char *, symbolS *, int));
292 /* Generic assembler global variables which must be defined by all
293 targets. */
295 /* Characters which always start a comment. */
296 const char comment_chars[] = "#";
298 /* Characters which start a comment at the beginning of a line. */
299 const char line_comment_chars[] = "#";
301 /* Characters which may be used to separate multiple commands on a
302 single line. */
303 const char line_separator_chars[] = ";";
305 /* Characters which are used to indicate an exponent in a floating
306 point number. */
307 const char EXP_CHARS[] = "eE";
309 /* Characters which mean that a number is a floating point constant,
310 as in 0d1.0. */
311 /* XXX: Do all of these really get used on the alpha?? */
312 char FLT_CHARS[] = "rRsSfFdDxXpP";
314 #ifdef OBJ_EVAX
315 const char *md_shortopts = "Fm:g+1h:HG:";
316 #else
317 const char *md_shortopts = "Fm:gG:";
318 #endif
320 struct option md_longopts[] =
322 #define OPTION_32ADDR (OPTION_MD_BASE)
323 { "32addr", no_argument, NULL, OPTION_32ADDR },
324 #define OPTION_RELAX (OPTION_32ADDR + 1)
325 { "relax", no_argument, NULL, OPTION_RELAX },
326 #ifdef OBJ_ELF
327 #define OPTION_MDEBUG (OPTION_RELAX + 1)
328 #define OPTION_NO_MDEBUG (OPTION_MDEBUG + 1)
329 { "mdebug", no_argument, NULL, OPTION_MDEBUG },
330 { "no-mdebug", no_argument, NULL, OPTION_NO_MDEBUG },
331 #endif
332 { NULL, no_argument, NULL, 0 }
335 size_t md_longopts_size = sizeof (md_longopts);
337 #ifdef OBJ_EVAX
338 #define AXP_REG_R0 0
339 #define AXP_REG_R16 16
340 #define AXP_REG_R17 17
341 #undef AXP_REG_T9
342 #define AXP_REG_T9 22
343 #undef AXP_REG_T10
344 #define AXP_REG_T10 23
345 #undef AXP_REG_T11
346 #define AXP_REG_T11 24
347 #undef AXP_REG_T12
348 #define AXP_REG_T12 25
349 #define AXP_REG_AI 25
350 #undef AXP_REG_FP
351 #define AXP_REG_FP 29
353 #undef AXP_REG_GP
354 #define AXP_REG_GP AXP_REG_PV
355 #endif /* OBJ_EVAX */
357 /* The cpu for which we are generating code. */
358 static unsigned alpha_target = AXP_OPCODE_BASE;
359 static const char *alpha_target_name = "<all>";
361 /* The hash table of instruction opcodes. */
362 static struct hash_control *alpha_opcode_hash;
364 /* The hash table of macro opcodes. */
365 static struct hash_control *alpha_macro_hash;
367 #ifdef OBJ_ECOFF
368 /* The $gp relocation symbol. */
369 static symbolS *alpha_gp_symbol;
371 /* XXX: what is this, and why is it exported? */
372 valueT alpha_gp_value;
373 #endif
375 /* The current $gp register. */
376 static int alpha_gp_register = AXP_REG_GP;
378 /* A table of the register symbols. */
379 static symbolS *alpha_register_table[64];
381 /* Constant sections, or sections of constants. */
382 #ifdef OBJ_ECOFF
383 static segT alpha_lita_section;
384 #endif
385 #ifdef OBJ_EVAX
386 static segT alpha_link_section;
387 static segT alpha_ctors_section;
388 static segT alpha_dtors_section;
389 #endif
390 static segT alpha_lit8_section;
392 /* Symbols referring to said sections. */
393 #ifdef OBJ_ECOFF
394 static symbolS *alpha_lita_symbol;
395 #endif
396 #ifdef OBJ_EVAX
397 static symbolS *alpha_link_symbol;
398 static symbolS *alpha_ctors_symbol;
399 static symbolS *alpha_dtors_symbol;
400 #endif
401 static symbolS *alpha_lit8_symbol;
403 /* Literal for .litX+0x8000 within .lita. */
404 #ifdef OBJ_ECOFF
405 static offsetT alpha_lit8_literal;
406 #endif
408 /* Is the assembler not allowed to use $at? */
409 static int alpha_noat_on = 0;
411 /* Are macros enabled? */
412 static int alpha_macros_on = 1;
414 /* Are floats disabled? */
415 static int alpha_nofloats_on = 0;
417 /* Are addresses 32 bit? */
418 static int alpha_addr32_on = 0;
420 /* Symbol labelling the current insn. When the Alpha gas sees
421 foo:
422 .quad 0
423 and the section happens to not be on an eight byte boundary, it
424 will align both the symbol and the .quad to an eight byte boundary. */
425 static symbolS *alpha_insn_label;
427 /* Whether we should automatically align data generation pseudo-ops.
428 .align 0 will turn this off. */
429 static int alpha_auto_align_on = 1;
431 /* The known current alignment of the current section. */
432 static int alpha_current_align;
434 /* These are exported to ECOFF code. */
435 unsigned long alpha_gprmask, alpha_fprmask;
437 /* Whether the debugging option was seen. */
438 static int alpha_debug;
440 #ifdef OBJ_ELF
441 /* Whether we are emitting an mdebug section. */
442 int alpha_flag_mdebug = -1;
443 #endif
445 /* Don't fully resolve relocations, allowing code movement in the linker. */
446 static int alpha_flag_relax;
448 /* What value to give to bfd_set_gp_size. */
449 static int g_switch_value = 8;
451 #ifdef OBJ_EVAX
452 /* Collect information about current procedure here. */
453 static struct {
454 symbolS *symbol; /* proc pdesc symbol */
455 int pdsckind;
456 int framereg; /* register for frame pointer */
457 int framesize; /* size of frame */
458 int rsa_offset;
459 int ra_save;
460 int fp_save;
461 long imask;
462 long fmask;
463 int type;
464 int prologue;
465 } alpha_evax_proc;
467 static int alpha_flag_hash_long_names = 0; /* -+ */
468 static int alpha_flag_show_after_trunc = 0; /* -H */
470 /* If the -+ switch is given, then a hash is appended to any name that is
471 longer than 64 characters, else longer symbol names are truncated. */
473 #endif
475 #ifdef RELOC_OP_P
476 /* A table to map the spelling of a relocation operand into an appropriate
477 bfd_reloc_code_real_type type. The table is assumed to be ordered such
478 that op-O_literal indexes into it. */
480 #define ALPHA_RELOC_TABLE(op) \
481 (&alpha_reloc_op[ ((!USER_RELOC_P (op)) \
482 ? (abort (), 0) \
483 : (int) (op) - (int) O_literal) ])
485 #define DEF(NAME, RELOC, REQ, ALLOW) \
486 { #NAME, sizeof(#NAME)-1, O_##NAME, RELOC, REQ, ALLOW}
488 static const struct alpha_reloc_op_tag
490 const char *name; /* string to lookup */
491 size_t length; /* size of the string */
492 operatorT op; /* which operator to use */
493 bfd_reloc_code_real_type reloc; /* relocation before frob */
494 unsigned int require_seq : 1; /* require a sequence number */
495 unsigned int allow_seq : 1; /* allow a sequence number */
497 alpha_reloc_op[] =
499 DEF(literal, BFD_RELOC_ALPHA_ELF_LITERAL, 0, 1),
500 DEF(lituse_addr, DUMMY_RELOC_LITUSE_ADDR, 1, 1),
501 DEF(lituse_base, DUMMY_RELOC_LITUSE_BASE, 1, 1),
502 DEF(lituse_bytoff, DUMMY_RELOC_LITUSE_BYTOFF, 1, 1),
503 DEF(lituse_jsr, DUMMY_RELOC_LITUSE_JSR, 1, 1),
504 DEF(lituse_tlsgd, DUMMY_RELOC_LITUSE_TLSGD, 1, 1),
505 DEF(lituse_tlsldm, DUMMY_RELOC_LITUSE_TLSLDM, 1, 1),
506 DEF(gpdisp, BFD_RELOC_ALPHA_GPDISP, 1, 1),
507 DEF(gprelhigh, BFD_RELOC_ALPHA_GPREL_HI16, 0, 0),
508 DEF(gprellow, BFD_RELOC_ALPHA_GPREL_LO16, 0, 0),
509 DEF(gprel, BFD_RELOC_GPREL16, 0, 0),
510 DEF(samegp, BFD_RELOC_ALPHA_BRSGP, 0, 0),
511 DEF(tlsgd, BFD_RELOC_ALPHA_TLSGD, 0, 1),
512 DEF(tlsldm, BFD_RELOC_ALPHA_TLSLDM, 0, 1),
513 DEF(gotdtprel, BFD_RELOC_ALPHA_GOTDTPREL16, 0, 0),
514 DEF(dtprelhi, BFD_RELOC_ALPHA_DTPREL_HI16, 0, 0),
515 DEF(dtprello, BFD_RELOC_ALPHA_DTPREL_LO16, 0, 0),
516 DEF(dtprel, BFD_RELOC_ALPHA_DTPREL16, 0, 0),
517 DEF(gottprel, BFD_RELOC_ALPHA_GOTTPREL16, 0, 0),
518 DEF(tprelhi, BFD_RELOC_ALPHA_TPREL_HI16, 0, 0),
519 DEF(tprello, BFD_RELOC_ALPHA_TPREL_LO16, 0, 0),
520 DEF(tprel, BFD_RELOC_ALPHA_TPREL16, 0, 0),
523 #undef DEF
525 static const int alpha_num_reloc_op
526 = sizeof (alpha_reloc_op) / sizeof (*alpha_reloc_op);
527 #endif /* RELOC_OP_P */
529 /* Maximum # digits needed to hold the largest sequence # */
530 #define ALPHA_RELOC_DIGITS 25
532 /* Structure to hold explicit sequence information. */
533 struct alpha_reloc_tag
535 fixS *master; /* the literal reloc */
536 fixS *slaves; /* head of linked list of lituses */
537 segT segment; /* segment relocs are in or undefined_section*/
538 long sequence; /* sequence # */
539 unsigned n_master; /* # of literals */
540 unsigned n_slaves; /* # of lituses */
541 unsigned saw_tlsgd : 1; /* true if ... */
542 unsigned saw_tlsldm : 1;
543 unsigned saw_lu_tlsgd : 1;
544 unsigned saw_lu_tlsldm : 1;
545 unsigned multi_section_p : 1; /* true if more than one section was used */
546 char string[1]; /* printable form of sequence to hash with */
549 /* Hash table to link up literals with the appropriate lituse */
550 static struct hash_control *alpha_literal_hash;
552 /* Sequence numbers for internal use by macros. */
553 static long next_sequence_num = -1;
555 /* A table of CPU names and opcode sets. */
557 static const struct cpu_type
559 const char *name;
560 unsigned flags;
562 cpu_types[] =
564 /* Ad hoc convention: cpu number gets palcode, process code doesn't.
565 This supports usage under DU 4.0b that does ".arch ev4", and
566 usage in MILO that does -m21064. Probably something more
567 specific like -m21064-pal should be used, but oh well. */
569 { "21064", AXP_OPCODE_BASE|AXP_OPCODE_EV4 },
570 { "21064a", AXP_OPCODE_BASE|AXP_OPCODE_EV4 },
571 { "21066", AXP_OPCODE_BASE|AXP_OPCODE_EV4 },
572 { "21068", AXP_OPCODE_BASE|AXP_OPCODE_EV4 },
573 { "21164", AXP_OPCODE_BASE|AXP_OPCODE_EV5 },
574 { "21164a", AXP_OPCODE_BASE|AXP_OPCODE_EV5|AXP_OPCODE_BWX },
575 { "21164pc", (AXP_OPCODE_BASE|AXP_OPCODE_EV5|AXP_OPCODE_BWX
576 |AXP_OPCODE_MAX) },
577 { "21264", (AXP_OPCODE_BASE|AXP_OPCODE_EV6|AXP_OPCODE_BWX
578 |AXP_OPCODE_MAX|AXP_OPCODE_CIX) },
579 { "21264a", (AXP_OPCODE_BASE|AXP_OPCODE_EV6|AXP_OPCODE_BWX
580 |AXP_OPCODE_MAX|AXP_OPCODE_CIX) },
581 { "21264b", (AXP_OPCODE_BASE|AXP_OPCODE_EV6|AXP_OPCODE_BWX
582 |AXP_OPCODE_MAX|AXP_OPCODE_CIX) },
584 { "ev4", AXP_OPCODE_BASE },
585 { "ev45", AXP_OPCODE_BASE },
586 { "lca45", AXP_OPCODE_BASE },
587 { "ev5", AXP_OPCODE_BASE },
588 { "ev56", AXP_OPCODE_BASE|AXP_OPCODE_BWX },
589 { "pca56", AXP_OPCODE_BASE|AXP_OPCODE_BWX|AXP_OPCODE_MAX },
590 { "ev6", AXP_OPCODE_BASE|AXP_OPCODE_BWX|AXP_OPCODE_MAX|AXP_OPCODE_CIX },
591 { "ev67", AXP_OPCODE_BASE|AXP_OPCODE_BWX|AXP_OPCODE_MAX|AXP_OPCODE_CIX },
592 { "ev68", AXP_OPCODE_BASE|AXP_OPCODE_BWX|AXP_OPCODE_MAX|AXP_OPCODE_CIX },
594 { "all", AXP_OPCODE_BASE },
595 { 0, 0 }
598 /* The macro table */
600 static const struct alpha_macro alpha_macros[] =
602 /* Load/Store macros */
603 { "lda", emit_lda, NULL,
604 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
605 { "ldah", emit_ldah, NULL,
606 { MACRO_IR, MACRO_EXP, MACRO_EOA } },
608 { "ldl", emit_ir_load, "ldl",
609 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
610 { "ldl_l", emit_ir_load, "ldl_l",
611 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
612 { "ldq", emit_ir_load, "ldq",
613 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
614 { "ldq_l", emit_ir_load, "ldq_l",
615 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
616 { "ldq_u", emit_ir_load, "ldq_u",
617 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
618 { "ldf", emit_loadstore, "ldf",
619 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
620 { "ldg", emit_loadstore, "ldg",
621 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
622 { "lds", emit_loadstore, "lds",
623 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
624 { "ldt", emit_loadstore, "ldt",
625 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
627 { "ldb", emit_ldX, (PTR) 0,
628 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
629 { "ldbu", emit_ldXu, (PTR) 0,
630 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
631 { "ldw", emit_ldX, (PTR) 1,
632 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
633 { "ldwu", emit_ldXu, (PTR) 1,
634 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
636 { "uldw", emit_uldX, (PTR) 1,
637 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
638 { "uldwu", emit_uldXu, (PTR) 1,
639 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
640 { "uldl", emit_uldX, (PTR) 2,
641 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
642 { "uldlu", emit_uldXu, (PTR) 2,
643 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
644 { "uldq", emit_uldXu, (PTR) 3,
645 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
647 { "ldgp", emit_ldgp, NULL,
648 { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA } },
650 { "ldi", emit_lda, NULL,
651 { MACRO_IR, MACRO_EXP, MACRO_EOA } },
652 { "ldil", emit_ldil, NULL,
653 { MACRO_IR, MACRO_EXP, MACRO_EOA } },
654 { "ldiq", emit_lda, NULL,
655 { MACRO_IR, MACRO_EXP, MACRO_EOA } },
657 { "stl", emit_loadstore, "stl",
658 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
659 { "stl_c", emit_loadstore, "stl_c",
660 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
661 { "stq", emit_loadstore, "stq",
662 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
663 { "stq_c", emit_loadstore, "stq_c",
664 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
665 { "stq_u", emit_loadstore, "stq_u",
666 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
667 { "stf", emit_loadstore, "stf",
668 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
669 { "stg", emit_loadstore, "stg",
670 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
671 { "sts", emit_loadstore, "sts",
672 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
673 { "stt", emit_loadstore, "stt",
674 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
676 { "stb", emit_stX, (PTR) 0,
677 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
678 { "stw", emit_stX, (PTR) 1,
679 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
680 { "ustw", emit_ustX, (PTR) 1,
681 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
682 { "ustl", emit_ustX, (PTR) 2,
683 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
684 { "ustq", emit_ustX, (PTR) 3,
685 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
687 /* Arithmetic macros */
689 { "sextb", emit_sextX, (PTR) 0,
690 { MACRO_IR, MACRO_IR, MACRO_EOA,
691 MACRO_IR, MACRO_EOA,
692 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
693 { "sextw", emit_sextX, (PTR) 1,
694 { MACRO_IR, MACRO_IR, MACRO_EOA,
695 MACRO_IR, MACRO_EOA,
696 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
698 { "divl", emit_division, "__divl",
699 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
700 MACRO_IR, MACRO_IR, MACRO_EOA,
701 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
702 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
703 { "divlu", emit_division, "__divlu",
704 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
705 MACRO_IR, MACRO_IR, MACRO_EOA,
706 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
707 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
708 { "divq", emit_division, "__divq",
709 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
710 MACRO_IR, MACRO_IR, MACRO_EOA,
711 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
712 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
713 { "divqu", emit_division, "__divqu",
714 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
715 MACRO_IR, MACRO_IR, MACRO_EOA,
716 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
717 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
718 { "reml", emit_division, "__reml",
719 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
720 MACRO_IR, MACRO_IR, MACRO_EOA,
721 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
722 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
723 { "remlu", emit_division, "__remlu",
724 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
725 MACRO_IR, MACRO_IR, MACRO_EOA,
726 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
727 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
728 { "remq", emit_division, "__remq",
729 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
730 MACRO_IR, MACRO_IR, MACRO_EOA,
731 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
732 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
733 { "remqu", emit_division, "__remqu",
734 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
735 MACRO_IR, MACRO_IR, MACRO_EOA,
736 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
737 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
739 { "jsr", emit_jsrjmp, "jsr",
740 { MACRO_PIR, MACRO_EXP, MACRO_EOA,
741 MACRO_PIR, MACRO_EOA,
742 MACRO_IR, MACRO_EXP, MACRO_EOA,
743 MACRO_EXP, MACRO_EOA } },
744 { "jmp", emit_jsrjmp, "jmp",
745 { MACRO_PIR, MACRO_EXP, MACRO_EOA,
746 MACRO_PIR, MACRO_EOA,
747 MACRO_IR, MACRO_EXP, MACRO_EOA,
748 MACRO_EXP, MACRO_EOA } },
749 { "ret", emit_retjcr, "ret",
750 { MACRO_IR, MACRO_EXP, MACRO_EOA,
751 MACRO_IR, MACRO_EOA,
752 MACRO_PIR, MACRO_EXP, MACRO_EOA,
753 MACRO_PIR, MACRO_EOA,
754 MACRO_EXP, MACRO_EOA,
755 MACRO_EOA } },
756 { "jcr", emit_retjcr, "jcr",
757 { MACRO_IR, MACRO_EXP, MACRO_EOA,
758 MACRO_IR, MACRO_EOA,
759 MACRO_PIR, MACRO_EXP, MACRO_EOA,
760 MACRO_PIR, MACRO_EOA,
761 MACRO_EXP, MACRO_EOA,
762 MACRO_EOA } },
763 { "jsr_coroutine", emit_retjcr, "jcr",
764 { MACRO_IR, MACRO_EXP, MACRO_EOA,
765 MACRO_IR, MACRO_EOA,
766 MACRO_PIR, MACRO_EXP, MACRO_EOA,
767 MACRO_PIR, MACRO_EOA,
768 MACRO_EXP, MACRO_EOA,
769 MACRO_EOA } },
772 static const unsigned int alpha_num_macros
773 = sizeof (alpha_macros) / sizeof (*alpha_macros);
775 /* Public interface functions */
777 /* This function is called once, at assembler startup time. It sets
778 up all the tables, etc. that the MD part of the assembler will
779 need, that can be determined before arguments are parsed. */
781 void
782 md_begin ()
784 unsigned int i;
786 /* Verify that X_op field is wide enough. */
788 expressionS e;
789 e.X_op = O_max;
790 assert (e.X_op == O_max);
793 /* Create the opcode hash table. */
794 alpha_opcode_hash = hash_new ();
795 for (i = 0; i < alpha_num_opcodes;)
797 const char *name, *retval, *slash;
799 name = alpha_opcodes[i].name;
800 retval = hash_insert (alpha_opcode_hash, name, (PTR) &alpha_opcodes[i]);
801 if (retval)
802 as_fatal (_("internal error: can't hash opcode `%s': %s"),
803 name, retval);
805 /* Some opcodes include modifiers of various sorts with a "/mod"
806 syntax, like the architecture manual suggests. However, for
807 use with gcc at least, we also need access to those same opcodes
808 without the "/". */
810 if ((slash = strchr (name, '/')) != NULL)
812 char *p = xmalloc (strlen (name));
813 memcpy (p, name, slash - name);
814 strcpy (p + (slash - name), slash + 1);
816 (void) hash_insert (alpha_opcode_hash, p, (PTR) &alpha_opcodes[i]);
817 /* Ignore failures -- the opcode table does duplicate some
818 variants in different forms, like "hw_stq" and "hw_st/q". */
821 while (++i < alpha_num_opcodes
822 && (alpha_opcodes[i].name == name
823 || !strcmp (alpha_opcodes[i].name, name)))
824 continue;
827 /* Create the macro hash table. */
828 alpha_macro_hash = hash_new ();
829 for (i = 0; i < alpha_num_macros;)
831 const char *name, *retval;
833 name = alpha_macros[i].name;
834 retval = hash_insert (alpha_macro_hash, name, (PTR) &alpha_macros[i]);
835 if (retval)
836 as_fatal (_("internal error: can't hash macro `%s': %s"),
837 name, retval);
839 while (++i < alpha_num_macros
840 && (alpha_macros[i].name == name
841 || !strcmp (alpha_macros[i].name, name)))
842 continue;
845 /* Construct symbols for each of the registers. */
846 for (i = 0; i < 32; ++i)
848 char name[4];
850 sprintf (name, "$%d", i);
851 alpha_register_table[i] = symbol_create (name, reg_section, i,
852 &zero_address_frag);
854 for (; i < 64; ++i)
856 char name[5];
858 sprintf (name, "$f%d", i - 32);
859 alpha_register_table[i] = symbol_create (name, reg_section, i,
860 &zero_address_frag);
863 /* Create the special symbols and sections we'll be using. */
865 /* So .sbss will get used for tiny objects. */
866 bfd_set_gp_size (stdoutput, g_switch_value);
868 #ifdef OBJ_ECOFF
869 create_literal_section (".lita", &alpha_lita_section, &alpha_lita_symbol);
871 /* For handling the GP, create a symbol that won't be output in the
872 symbol table. We'll edit it out of relocs later. */
873 alpha_gp_symbol = symbol_create ("<GP value>", alpha_lita_section, 0x8000,
874 &zero_address_frag);
875 #endif
877 #ifdef OBJ_EVAX
878 create_literal_section (".link", &alpha_link_section, &alpha_link_symbol);
879 #endif
881 #ifdef OBJ_ELF
882 if (ECOFF_DEBUGGING)
884 segT sec = subseg_new (".mdebug", (subsegT) 0);
885 bfd_set_section_flags (stdoutput, sec, SEC_HAS_CONTENTS | SEC_READONLY);
886 bfd_set_section_alignment (stdoutput, sec, 3);
888 #endif /* OBJ_ELF */
890 /* Create literal lookup hash table. */
891 alpha_literal_hash = hash_new ();
893 subseg_set (text_section, 0);
896 /* The public interface to the instruction assembler. */
898 void
899 md_assemble (str)
900 char *str;
902 char opname[32]; /* Current maximum is 13. */
903 expressionS tok[MAX_INSN_ARGS];
904 int ntok, trunclen;
905 size_t opnamelen;
907 /* Split off the opcode. */
908 opnamelen = strspn (str, "abcdefghijklmnopqrstuvwxyz_/46819");
909 trunclen = (opnamelen < sizeof (opname) - 1
910 ? opnamelen
911 : sizeof (opname) - 1);
912 memcpy (opname, str, trunclen);
913 opname[trunclen] = '\0';
915 /* Tokenize the rest of the line. */
916 if ((ntok = tokenize_arguments (str + opnamelen, tok, MAX_INSN_ARGS)) < 0)
918 if (ntok != TOKENIZE_ERROR_REPORT)
919 as_bad (_("syntax error"));
921 return;
924 /* Finish it off. */
925 assemble_tokens (opname, tok, ntok, alpha_macros_on);
928 /* Round up a section's size to the appropriate boundary. */
930 valueT
931 md_section_align (seg, size)
932 segT seg;
933 valueT size;
935 int align = bfd_get_section_alignment (stdoutput, seg);
936 valueT mask = ((valueT) 1 << align) - 1;
938 return (size + mask) & ~mask;
941 /* Turn a string in input_line_pointer into a floating point constant
942 of type TYPE, and store the appropriate bytes in *LITP. The number
943 of LITTLENUMS emitted is stored in *SIZEP. An error message is
944 returned, or NULL on OK. */
946 /* Equal to MAX_PRECISION in atof-ieee.c. */
947 #define MAX_LITTLENUMS 6
949 extern char *vax_md_atof PARAMS ((int, char *, int *));
951 char *
952 md_atof (type, litP, sizeP)
953 char type;
954 char *litP;
955 int *sizeP;
957 int prec;
958 LITTLENUM_TYPE words[MAX_LITTLENUMS];
959 LITTLENUM_TYPE *wordP;
960 char *t;
962 switch (type)
964 /* VAX floats */
965 case 'G':
966 /* VAX md_atof doesn't like "G" for some reason. */
967 type = 'g';
968 case 'F':
969 case 'D':
970 return vax_md_atof (type, litP, sizeP);
972 /* IEEE floats */
973 case 'f':
974 prec = 2;
975 break;
977 case 'd':
978 prec = 4;
979 break;
981 case 'x':
982 case 'X':
983 prec = 6;
984 break;
986 case 'p':
987 case 'P':
988 prec = 6;
989 break;
991 default:
992 *sizeP = 0;
993 return _("Bad call to MD_ATOF()");
995 t = atof_ieee (input_line_pointer, type, words);
996 if (t)
997 input_line_pointer = t;
998 *sizeP = prec * sizeof (LITTLENUM_TYPE);
1000 for (wordP = words + prec - 1; prec--;)
1002 md_number_to_chars (litP, (long) (*wordP--), sizeof (LITTLENUM_TYPE));
1003 litP += sizeof (LITTLENUM_TYPE);
1006 return 0;
1009 /* Take care of the target-specific command-line options. */
1012 md_parse_option (c, arg)
1013 int c;
1014 char *arg;
1016 switch (c)
1018 case 'F':
1019 alpha_nofloats_on = 1;
1020 break;
1022 case OPTION_32ADDR:
1023 alpha_addr32_on = 1;
1024 break;
1026 case 'g':
1027 alpha_debug = 1;
1028 break;
1030 case 'G':
1031 g_switch_value = atoi (arg);
1032 break;
1034 case 'm':
1036 const struct cpu_type *p;
1037 for (p = cpu_types; p->name; ++p)
1038 if (strcmp (arg, p->name) == 0)
1040 alpha_target_name = p->name, alpha_target = p->flags;
1041 goto found;
1043 as_warn (_("Unknown CPU identifier `%s'"), arg);
1044 found:;
1046 break;
1048 #ifdef OBJ_EVAX
1049 case '+': /* For g++. Hash any name > 63 chars long. */
1050 alpha_flag_hash_long_names = 1;
1051 break;
1053 case 'H': /* Show new symbol after hash truncation */
1054 alpha_flag_show_after_trunc = 1;
1055 break;
1057 case 'h': /* for gnu-c/vax compatibility. */
1058 break;
1059 #endif
1061 case OPTION_RELAX:
1062 alpha_flag_relax = 1;
1063 break;
1065 #ifdef OBJ_ELF
1066 case OPTION_MDEBUG:
1067 alpha_flag_mdebug = 1;
1068 break;
1069 case OPTION_NO_MDEBUG:
1070 alpha_flag_mdebug = 0;
1071 break;
1072 #endif
1074 default:
1075 return 0;
1078 return 1;
1081 /* Print a description of the command-line options that we accept. */
1083 void
1084 md_show_usage (stream)
1085 FILE *stream;
1087 fputs (_("\
1088 Alpha options:\n\
1089 -32addr treat addresses as 32-bit values\n\
1090 -F lack floating point instructions support\n\
1091 -mev4 | -mev45 | -mev5 | -mev56 | -mpca56 | -mev6 | -mev67 | -mev68 | -mall\n\
1092 specify variant of Alpha architecture\n\
1093 -m21064 | -m21066 | -m21164 | -m21164a | -m21164pc | -m21264 | -m21264a | -m21264b\n\
1094 these variants include PALcode opcodes\n"),
1095 stream);
1096 #ifdef OBJ_EVAX
1097 fputs (_("\
1098 VMS options:\n\
1099 -+ hash encode (don't truncate) names longer than 64 characters\n\
1100 -H show new symbol after hash truncation\n"),
1101 stream);
1102 #endif
1105 /* Decide from what point a pc-relative relocation is relative to,
1106 relative to the pc-relative fixup. Er, relatively speaking. */
1108 long
1109 md_pcrel_from (fixP)
1110 fixS *fixP;
1112 valueT addr = fixP->fx_where + fixP->fx_frag->fr_address;
1113 switch (fixP->fx_r_type)
1115 case BFD_RELOC_23_PCREL_S2:
1116 case BFD_RELOC_ALPHA_HINT:
1117 case BFD_RELOC_ALPHA_BRSGP:
1118 return addr + 4;
1119 default:
1120 return addr;
1124 /* Attempt to simplify or even eliminate a fixup. The return value is
1125 ignored; perhaps it was once meaningful, but now it is historical.
1126 To indicate that a fixup has been eliminated, set fixP->fx_done.
1128 For ELF, here it is that we transform the GPDISP_HI16 reloc we used
1129 internally into the GPDISP reloc used externally. We had to do
1130 this so that we'd have the GPDISP_LO16 reloc as a tag to compute
1131 the distance to the "lda" instruction for setting the addend to
1132 GPDISP. */
1134 void
1135 md_apply_fix3 (fixP, valP, seg)
1136 fixS *fixP;
1137 valueT * valP;
1138 segT seg;
1140 char * const fixpos = fixP->fx_frag->fr_literal + fixP->fx_where;
1141 valueT value = * valP;
1142 unsigned image, size;
1144 switch (fixP->fx_r_type)
1146 /* The GPDISP relocations are processed internally with a symbol
1147 referring to the current function's section; we need to drop
1148 in a value which, when added to the address of the start of
1149 the function, gives the desired GP. */
1150 case BFD_RELOC_ALPHA_GPDISP_HI16:
1152 fixS *next = fixP->fx_next;
1154 /* With user-specified !gpdisp relocations, we can be missing
1155 the matching LO16 reloc. We will have already issued an
1156 error message. */
1157 if (next)
1158 fixP->fx_offset = (next->fx_frag->fr_address + next->fx_where
1159 - fixP->fx_frag->fr_address - fixP->fx_where);
1161 value = (value - sign_extend_16 (value)) >> 16;
1163 #ifdef OBJ_ELF
1164 fixP->fx_r_type = BFD_RELOC_ALPHA_GPDISP;
1165 #endif
1166 goto do_reloc_gp;
1168 case BFD_RELOC_ALPHA_GPDISP_LO16:
1169 value = sign_extend_16 (value);
1170 fixP->fx_offset = 0;
1171 #ifdef OBJ_ELF
1172 fixP->fx_done = 1;
1173 #endif
1175 do_reloc_gp:
1176 fixP->fx_addsy = section_symbol (seg);
1177 md_number_to_chars (fixpos, value, 2);
1178 break;
1180 case BFD_RELOC_16:
1181 if (fixP->fx_pcrel)
1182 fixP->fx_r_type = BFD_RELOC_16_PCREL;
1183 size = 2;
1184 goto do_reloc_xx;
1185 case BFD_RELOC_32:
1186 if (fixP->fx_pcrel)
1187 fixP->fx_r_type = BFD_RELOC_32_PCREL;
1188 size = 4;
1189 goto do_reloc_xx;
1190 case BFD_RELOC_64:
1191 if (fixP->fx_pcrel)
1192 fixP->fx_r_type = BFD_RELOC_64_PCREL;
1193 size = 8;
1194 do_reloc_xx:
1195 if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0)
1197 md_number_to_chars (fixpos, value, size);
1198 goto done;
1200 return;
1202 #ifdef OBJ_ECOFF
1203 case BFD_RELOC_GPREL32:
1204 assert (fixP->fx_subsy == alpha_gp_symbol);
1205 fixP->fx_subsy = 0;
1206 /* FIXME: inherited this obliviousness of `value' -- why? */
1207 md_number_to_chars (fixpos, -alpha_gp_value, 4);
1208 break;
1209 #else
1210 case BFD_RELOC_GPREL32:
1211 #endif
1212 case BFD_RELOC_GPREL16:
1213 case BFD_RELOC_ALPHA_GPREL_HI16:
1214 case BFD_RELOC_ALPHA_GPREL_LO16:
1215 return;
1217 case BFD_RELOC_23_PCREL_S2:
1218 if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0)
1220 image = bfd_getl32 (fixpos);
1221 image = (image & ~0x1FFFFF) | ((value >> 2) & 0x1FFFFF);
1222 goto write_done;
1224 return;
1226 case BFD_RELOC_ALPHA_HINT:
1227 if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0)
1229 image = bfd_getl32 (fixpos);
1230 image = (image & ~0x3FFF) | ((value >> 2) & 0x3FFF);
1231 goto write_done;
1233 return;
1235 #ifdef OBJ_ELF
1236 case BFD_RELOC_ALPHA_BRSGP:
1237 return;
1239 case BFD_RELOC_ALPHA_TLSGD:
1240 case BFD_RELOC_ALPHA_TLSLDM:
1241 case BFD_RELOC_ALPHA_GOTDTPREL16:
1242 case BFD_RELOC_ALPHA_DTPREL_HI16:
1243 case BFD_RELOC_ALPHA_DTPREL_LO16:
1244 case BFD_RELOC_ALPHA_DTPREL16:
1245 case BFD_RELOC_ALPHA_GOTTPREL16:
1246 case BFD_RELOC_ALPHA_TPREL_HI16:
1247 case BFD_RELOC_ALPHA_TPREL_LO16:
1248 case BFD_RELOC_ALPHA_TPREL16:
1249 if (fixP->fx_addsy)
1250 S_SET_THREAD_LOCAL (fixP->fx_addsy);
1251 return;
1252 #endif
1254 #ifdef OBJ_ECOFF
1255 case BFD_RELOC_ALPHA_LITERAL:
1256 md_number_to_chars (fixpos, value, 2);
1257 return;
1258 #endif
1259 case BFD_RELOC_ALPHA_ELF_LITERAL:
1260 case BFD_RELOC_ALPHA_LITUSE:
1261 case BFD_RELOC_ALPHA_LINKAGE:
1262 case BFD_RELOC_ALPHA_CODEADDR:
1263 return;
1265 case BFD_RELOC_VTABLE_INHERIT:
1266 case BFD_RELOC_VTABLE_ENTRY:
1267 return;
1269 default:
1271 const struct alpha_operand *operand;
1273 if ((int) fixP->fx_r_type >= 0)
1274 as_fatal (_("unhandled relocation type %s"),
1275 bfd_get_reloc_code_name (fixP->fx_r_type));
1277 assert (-(int) fixP->fx_r_type < (int) alpha_num_operands);
1278 operand = &alpha_operands[-(int) fixP->fx_r_type];
1280 /* The rest of these fixups only exist internally during symbol
1281 resolution and have no representation in the object file.
1282 Therefore they must be completely resolved as constants. */
1284 if (fixP->fx_addsy != 0
1285 && S_GET_SEGMENT (fixP->fx_addsy) != absolute_section)
1286 as_bad_where (fixP->fx_file, fixP->fx_line,
1287 _("non-absolute expression in constant field"));
1289 image = bfd_getl32 (fixpos);
1290 image = insert_operand (image, operand, (offsetT) value,
1291 fixP->fx_file, fixP->fx_line);
1293 goto write_done;
1296 if (fixP->fx_addsy != 0 || fixP->fx_pcrel != 0)
1297 return;
1298 else
1300 as_warn_where (fixP->fx_file, fixP->fx_line,
1301 _("type %d reloc done?\n"), (int) fixP->fx_r_type);
1302 goto done;
1305 write_done:
1306 md_number_to_chars (fixpos, image, 4);
1308 done:
1309 fixP->fx_done = 1;
1312 /* Look for a register name in the given symbol. */
1314 symbolS *
1315 md_undefined_symbol (name)
1316 char *name;
1318 if (*name == '$')
1320 int is_float = 0, num;
1322 switch (*++name)
1324 case 'f':
1325 if (name[1] == 'p' && name[2] == '\0')
1326 return alpha_register_table[AXP_REG_FP];
1327 is_float = 32;
1328 /* FALLTHRU */
1330 case 'r':
1331 if (!ISDIGIT (*++name))
1332 break;
1333 /* FALLTHRU */
1335 case '0': case '1': case '2': case '3': case '4':
1336 case '5': case '6': case '7': case '8': case '9':
1337 if (name[1] == '\0')
1338 num = name[0] - '0';
1339 else if (name[0] != '0' && ISDIGIT (name[1]) && name[2] == '\0')
1341 num = (name[0] - '0') * 10 + name[1] - '0';
1342 if (num >= 32)
1343 break;
1345 else
1346 break;
1348 if (!alpha_noat_on && (num + is_float) == AXP_REG_AT)
1349 as_warn (_("Used $at without \".set noat\""));
1350 return alpha_register_table[num + is_float];
1352 case 'a':
1353 if (name[1] == 't' && name[2] == '\0')
1355 if (!alpha_noat_on)
1356 as_warn (_("Used $at without \".set noat\""));
1357 return alpha_register_table[AXP_REG_AT];
1359 break;
1361 case 'g':
1362 if (name[1] == 'p' && name[2] == '\0')
1363 return alpha_register_table[alpha_gp_register];
1364 break;
1366 case 's':
1367 if (name[1] == 'p' && name[2] == '\0')
1368 return alpha_register_table[AXP_REG_SP];
1369 break;
1372 return NULL;
1375 #ifdef OBJ_ECOFF
1376 /* @@@ Magic ECOFF bits. */
1378 void
1379 alpha_frob_ecoff_data ()
1381 select_gp_value ();
1382 /* $zero and $f31 are read-only */
1383 alpha_gprmask &= ~1;
1384 alpha_fprmask &= ~1;
1386 #endif
1388 /* Hook to remember a recently defined label so that the auto-align
1389 code can adjust the symbol after we know what alignment will be
1390 required. */
1392 void
1393 alpha_define_label (sym)
1394 symbolS *sym;
1396 alpha_insn_label = sym;
1399 /* Return true if we must always emit a reloc for a type and false if
1400 there is some hope of resolving it at assembly time. */
1403 alpha_force_relocation (f)
1404 fixS *f;
1406 if (alpha_flag_relax)
1407 return 1;
1409 switch (f->fx_r_type)
1411 case BFD_RELOC_ALPHA_GPDISP_HI16:
1412 case BFD_RELOC_ALPHA_GPDISP_LO16:
1413 case BFD_RELOC_ALPHA_GPDISP:
1414 case BFD_RELOC_ALPHA_LITERAL:
1415 case BFD_RELOC_ALPHA_ELF_LITERAL:
1416 case BFD_RELOC_ALPHA_LITUSE:
1417 case BFD_RELOC_GPREL16:
1418 case BFD_RELOC_GPREL32:
1419 case BFD_RELOC_ALPHA_GPREL_HI16:
1420 case BFD_RELOC_ALPHA_GPREL_LO16:
1421 case BFD_RELOC_ALPHA_LINKAGE:
1422 case BFD_RELOC_ALPHA_CODEADDR:
1423 case BFD_RELOC_ALPHA_BRSGP:
1424 case BFD_RELOC_ALPHA_TLSGD:
1425 case BFD_RELOC_ALPHA_TLSLDM:
1426 case BFD_RELOC_ALPHA_GOTDTPREL16:
1427 case BFD_RELOC_ALPHA_DTPREL_HI16:
1428 case BFD_RELOC_ALPHA_DTPREL_LO16:
1429 case BFD_RELOC_ALPHA_DTPREL16:
1430 case BFD_RELOC_ALPHA_GOTTPREL16:
1431 case BFD_RELOC_ALPHA_TPREL_HI16:
1432 case BFD_RELOC_ALPHA_TPREL_LO16:
1433 case BFD_RELOC_ALPHA_TPREL16:
1434 return 1;
1436 default:
1437 break;
1440 return generic_force_reloc (f);
1443 /* Return true if we can partially resolve a relocation now. */
1446 alpha_fix_adjustable (f)
1447 fixS *f;
1449 /* Are there any relocation types for which we must generate a reloc
1450 but we can adjust the values contained within it? */
1451 switch (f->fx_r_type)
1453 case BFD_RELOC_ALPHA_GPDISP_HI16:
1454 case BFD_RELOC_ALPHA_GPDISP_LO16:
1455 case BFD_RELOC_ALPHA_GPDISP:
1456 return 0;
1458 case BFD_RELOC_ALPHA_LITERAL:
1459 case BFD_RELOC_ALPHA_ELF_LITERAL:
1460 case BFD_RELOC_ALPHA_LITUSE:
1461 case BFD_RELOC_ALPHA_LINKAGE:
1462 case BFD_RELOC_ALPHA_CODEADDR:
1463 return 1;
1465 case BFD_RELOC_VTABLE_ENTRY:
1466 case BFD_RELOC_VTABLE_INHERIT:
1467 return 0;
1469 case BFD_RELOC_GPREL16:
1470 case BFD_RELOC_GPREL32:
1471 case BFD_RELOC_ALPHA_GPREL_HI16:
1472 case BFD_RELOC_ALPHA_GPREL_LO16:
1473 case BFD_RELOC_23_PCREL_S2:
1474 case BFD_RELOC_32:
1475 case BFD_RELOC_64:
1476 case BFD_RELOC_ALPHA_HINT:
1477 return 1;
1479 case BFD_RELOC_ALPHA_TLSGD:
1480 case BFD_RELOC_ALPHA_TLSLDM:
1481 case BFD_RELOC_ALPHA_GOTDTPREL16:
1482 case BFD_RELOC_ALPHA_DTPREL_HI16:
1483 case BFD_RELOC_ALPHA_DTPREL_LO16:
1484 case BFD_RELOC_ALPHA_DTPREL16:
1485 case BFD_RELOC_ALPHA_GOTTPREL16:
1486 case BFD_RELOC_ALPHA_TPREL_HI16:
1487 case BFD_RELOC_ALPHA_TPREL_LO16:
1488 case BFD_RELOC_ALPHA_TPREL16:
1489 /* ??? No idea why we can't return a reference to .tbss+10, but
1490 we're preventing this in the other assemblers. Follow for now. */
1491 return 0;
1493 #ifdef OBJ_ELF
1494 case BFD_RELOC_ALPHA_BRSGP:
1495 /* If we have a BRSGP reloc to a local symbol, adjust it to BRADDR and
1496 let it get resolved at assembly time. */
1498 symbolS *sym = f->fx_addsy;
1499 const char *name;
1500 int offset = 0;
1502 if (generic_force_reloc (f))
1503 return 0;
1505 switch (S_GET_OTHER (sym) & STO_ALPHA_STD_GPLOAD)
1507 case STO_ALPHA_NOPV:
1508 break;
1509 case STO_ALPHA_STD_GPLOAD:
1510 offset = 8;
1511 break;
1512 default:
1513 if (S_IS_LOCAL (sym))
1514 name = "<local>";
1515 else
1516 name = S_GET_NAME (sym);
1517 as_bad_where (f->fx_file, f->fx_line,
1518 _("!samegp reloc against symbol without .prologue: %s"),
1519 name);
1520 break;
1522 f->fx_r_type = BFD_RELOC_23_PCREL_S2;
1523 f->fx_offset += offset;
1524 return 1;
1526 #endif
1528 default:
1529 return 1;
1531 /*NOTREACHED*/
1534 /* Generate the BFD reloc to be stuck in the object file from the
1535 fixup used internally in the assembler. */
1537 arelent *
1538 tc_gen_reloc (sec, fixp)
1539 asection *sec ATTRIBUTE_UNUSED;
1540 fixS *fixp;
1542 arelent *reloc;
1544 reloc = (arelent *) xmalloc (sizeof (arelent));
1545 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
1546 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
1547 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
1549 /* Make sure none of our internal relocations make it this far.
1550 They'd better have been fully resolved by this point. */
1551 assert ((int) fixp->fx_r_type > 0);
1553 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
1554 if (reloc->howto == NULL)
1556 as_bad_where (fixp->fx_file, fixp->fx_line,
1557 _("cannot represent `%s' relocation in object file"),
1558 bfd_get_reloc_code_name (fixp->fx_r_type));
1559 return NULL;
1562 if (!fixp->fx_pcrel != !reloc->howto->pc_relative)
1564 as_fatal (_("internal error? cannot generate `%s' relocation"),
1565 bfd_get_reloc_code_name (fixp->fx_r_type));
1567 assert (!fixp->fx_pcrel == !reloc->howto->pc_relative);
1569 #ifdef OBJ_ECOFF
1570 if (fixp->fx_r_type == BFD_RELOC_ALPHA_LITERAL)
1572 /* Fake out bfd_perform_relocation. sigh. */
1573 reloc->addend = -alpha_gp_value;
1575 else
1576 #endif
1578 reloc->addend = fixp->fx_offset;
1579 #ifdef OBJ_ELF
1580 /* Ohhh, this is ugly. The problem is that if this is a local global
1581 symbol, the relocation will entirely be performed at link time, not
1582 at assembly time. bfd_perform_reloc doesn't know about this sort
1583 of thing, and as a result we need to fake it out here. */
1584 if ((S_IS_EXTERN (fixp->fx_addsy) || S_IS_WEAK (fixp->fx_addsy)
1585 || (S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_MERGE)
1586 || (S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_THREAD_LOCAL))
1587 && !S_IS_COMMON (fixp->fx_addsy))
1588 reloc->addend -= symbol_get_bfdsym (fixp->fx_addsy)->value;
1589 #endif
1592 return reloc;
1595 /* Parse a register name off of the input_line and return a register
1596 number. Gets md_undefined_symbol above to do the register name
1597 matching for us.
1599 Only called as a part of processing the ECOFF .frame directive. */
1602 tc_get_register (frame)
1603 int frame ATTRIBUTE_UNUSED;
1605 int framereg = AXP_REG_SP;
1607 SKIP_WHITESPACE ();
1608 if (*input_line_pointer == '$')
1610 char *s = input_line_pointer;
1611 char c = get_symbol_end ();
1612 symbolS *sym = md_undefined_symbol (s);
1614 *strchr (s, '\0') = c;
1615 if (sym && (framereg = S_GET_VALUE (sym)) <= 31)
1616 goto found;
1618 as_warn (_("frame reg expected, using $%d."), framereg);
1620 found:
1621 note_gpreg (framereg);
1622 return framereg;
1625 /* This is called before the symbol table is processed. In order to
1626 work with gcc when using mips-tfile, we must keep all local labels.
1627 However, in other cases, we want to discard them. If we were
1628 called with -g, but we didn't see any debugging information, it may
1629 mean that gcc is smuggling debugging information through to
1630 mips-tfile, in which case we must generate all local labels. */
1632 #ifdef OBJ_ECOFF
1634 void
1635 alpha_frob_file_before_adjust ()
1637 if (alpha_debug != 0
1638 && ! ecoff_debugging_seen)
1639 flag_keep_locals = 1;
1642 #endif /* OBJ_ECOFF */
1644 static struct alpha_reloc_tag *
1645 get_alpha_reloc_tag (sequence)
1646 long sequence;
1648 char buffer[ALPHA_RELOC_DIGITS];
1649 struct alpha_reloc_tag *info;
1651 sprintf (buffer, "!%ld", sequence);
1653 info = (struct alpha_reloc_tag *) hash_find (alpha_literal_hash, buffer);
1654 if (! info)
1656 size_t len = strlen (buffer);
1657 const char *errmsg;
1659 info = (struct alpha_reloc_tag *)
1660 xcalloc (sizeof (struct alpha_reloc_tag) + len, 1);
1662 info->segment = now_seg;
1663 info->sequence = sequence;
1664 strcpy (info->string, buffer);
1665 errmsg = hash_insert (alpha_literal_hash, info->string, (PTR) info);
1666 if (errmsg)
1667 as_fatal (errmsg);
1670 return info;
1673 /* Before the relocations are written, reorder them, so that user
1674 supplied !lituse relocations follow the appropriate !literal
1675 relocations, and similarly for !gpdisp relocations. */
1677 void
1678 alpha_before_fix ()
1680 if (alpha_literal_hash)
1681 bfd_map_over_sections (stdoutput, alpha_adjust_relocs, NULL);
1684 static void
1685 alpha_adjust_relocs (abfd, sec, ptr)
1686 bfd *abfd ATTRIBUTE_UNUSED;
1687 asection *sec;
1688 PTR ptr ATTRIBUTE_UNUSED;
1690 segment_info_type *seginfo = seg_info (sec);
1691 fixS **prevP;
1692 fixS *fixp;
1693 fixS *next;
1694 fixS *slave;
1696 /* If seginfo is NULL, we did not create this section; don't do
1697 anything with it. By using a pointer to a pointer, we can update
1698 the links in place. */
1699 if (seginfo == NULL)
1700 return;
1702 /* If there are no relocations, skip the section. */
1703 if (! seginfo->fix_root)
1704 return;
1706 /* First rebuild the fixup chain without the explicit lituse and
1707 gpdisp_lo16 relocs. */
1708 prevP = &seginfo->fix_root;
1709 for (fixp = seginfo->fix_root; fixp; fixp = next)
1711 next = fixp->fx_next;
1712 fixp->fx_next = (fixS *) 0;
1714 switch (fixp->fx_r_type)
1716 case BFD_RELOC_ALPHA_LITUSE:
1717 if (fixp->tc_fix_data.info->n_master == 0)
1718 as_bad_where (fixp->fx_file, fixp->fx_line,
1719 _("No !literal!%ld was found"),
1720 fixp->tc_fix_data.info->sequence);
1721 #ifdef RELOC_OP_P
1722 if (fixp->fx_offset == LITUSE_ALPHA_TLSGD)
1724 if (! fixp->tc_fix_data.info->saw_tlsgd)
1725 as_bad_where (fixp->fx_file, fixp->fx_line,
1726 _("No !tlsgd!%ld was found"),
1727 fixp->tc_fix_data.info->sequence);
1729 else if (fixp->fx_offset == LITUSE_ALPHA_TLSLDM)
1731 if (! fixp->tc_fix_data.info->saw_tlsldm)
1732 as_bad_where (fixp->fx_file, fixp->fx_line,
1733 _("No !tlsldm!%ld was found"),
1734 fixp->tc_fix_data.info->sequence);
1736 #endif
1737 break;
1739 case BFD_RELOC_ALPHA_GPDISP_LO16:
1740 if (fixp->tc_fix_data.info->n_master == 0)
1741 as_bad_where (fixp->fx_file, fixp->fx_line,
1742 _("No ldah !gpdisp!%ld was found"),
1743 fixp->tc_fix_data.info->sequence);
1744 break;
1746 case BFD_RELOC_ALPHA_ELF_LITERAL:
1747 if (fixp->tc_fix_data.info
1748 && (fixp->tc_fix_data.info->saw_tlsgd
1749 || fixp->tc_fix_data.info->saw_tlsldm))
1750 break;
1751 /* FALLTHRU */
1753 default:
1754 *prevP = fixp;
1755 prevP = &fixp->fx_next;
1756 break;
1760 /* Go back and re-chain dependent relocations. They are currently
1761 linked through the next_reloc field in reverse order, so as we
1762 go through the next_reloc chain, we effectively reverse the chain
1763 once again.
1765 Except if there is more than one !literal for a given sequence
1766 number. In that case, the programmer and/or compiler is not sure
1767 how control flows from literal to lituse, and we can't be sure to
1768 get the relaxation correct.
1770 ??? Well, actually we could, if there are enough lituses such that
1771 we can make each literal have at least one of each lituse type
1772 present. Not implemented.
1774 Also suppress the optimization if the !literals/!lituses are spread
1775 in different segments. This can happen with "intersting" uses of
1776 inline assembly; examples are present in the Linux kernel semaphores. */
1778 for (fixp = seginfo->fix_root; fixp; fixp = next)
1780 next = fixp->fx_next;
1781 switch (fixp->fx_r_type)
1783 case BFD_RELOC_ALPHA_TLSGD:
1784 case BFD_RELOC_ALPHA_TLSLDM:
1785 if (!fixp->tc_fix_data.info)
1786 break;
1787 if (fixp->tc_fix_data.info->n_master == 0)
1788 break;
1789 else if (fixp->tc_fix_data.info->n_master > 1)
1791 as_bad_where (fixp->fx_file, fixp->fx_line,
1792 _("too many !literal!%ld for %s"),
1793 fixp->tc_fix_data.info->sequence,
1794 (fixp->fx_r_type == BFD_RELOC_ALPHA_TLSGD
1795 ? "!tlsgd" : "!tlsldm"));
1796 break;
1799 fixp->tc_fix_data.info->master->fx_next = fixp->fx_next;
1800 fixp->fx_next = fixp->tc_fix_data.info->master;
1801 fixp = fixp->fx_next;
1802 /* FALLTHRU */
1804 case BFD_RELOC_ALPHA_ELF_LITERAL:
1805 if (fixp->tc_fix_data.info
1806 && fixp->tc_fix_data.info->n_master == 1
1807 && ! fixp->tc_fix_data.info->multi_section_p)
1809 for (slave = fixp->tc_fix_data.info->slaves;
1810 slave != (fixS *) 0;
1811 slave = slave->tc_fix_data.next_reloc)
1813 slave->fx_next = fixp->fx_next;
1814 fixp->fx_next = slave;
1817 break;
1819 case BFD_RELOC_ALPHA_GPDISP_HI16:
1820 if (fixp->tc_fix_data.info->n_slaves == 0)
1821 as_bad_where (fixp->fx_file, fixp->fx_line,
1822 _("No lda !gpdisp!%ld was found"),
1823 fixp->tc_fix_data.info->sequence);
1824 else
1826 slave = fixp->tc_fix_data.info->slaves;
1827 slave->fx_next = next;
1828 fixp->fx_next = slave;
1830 break;
1832 default:
1833 break;
1838 #ifdef DEBUG_ALPHA
1839 static void
1840 debug_exp (tok, ntok)
1841 expressionS tok[];
1842 int ntok;
1844 int i;
1846 fprintf (stderr, "debug_exp: %d tokens", ntok);
1847 for (i = 0; i < ntok; i++)
1849 expressionS *t = &tok[i];
1850 const char *name;
1852 switch (t->X_op)
1854 default: name = "unknown"; break;
1855 case O_illegal: name = "O_illegal"; break;
1856 case O_absent: name = "O_absent"; break;
1857 case O_constant: name = "O_constant"; break;
1858 case O_symbol: name = "O_symbol"; break;
1859 case O_symbol_rva: name = "O_symbol_rva"; break;
1860 case O_register: name = "O_register"; break;
1861 case O_big: name = "O_big"; break;
1862 case O_uminus: name = "O_uminus"; break;
1863 case O_bit_not: name = "O_bit_not"; break;
1864 case O_logical_not: name = "O_logical_not"; break;
1865 case O_multiply: name = "O_multiply"; break;
1866 case O_divide: name = "O_divide"; break;
1867 case O_modulus: name = "O_modulus"; break;
1868 case O_left_shift: name = "O_left_shift"; break;
1869 case O_right_shift: name = "O_right_shift"; break;
1870 case O_bit_inclusive_or: name = "O_bit_inclusive_or"; break;
1871 case O_bit_or_not: name = "O_bit_or_not"; break;
1872 case O_bit_exclusive_or: name = "O_bit_exclusive_or"; break;
1873 case O_bit_and: name = "O_bit_and"; break;
1874 case O_add: name = "O_add"; break;
1875 case O_subtract: name = "O_subtract"; break;
1876 case O_eq: name = "O_eq"; break;
1877 case O_ne: name = "O_ne"; break;
1878 case O_lt: name = "O_lt"; break;
1879 case O_le: name = "O_le"; break;
1880 case O_ge: name = "O_ge"; break;
1881 case O_gt: name = "O_gt"; break;
1882 case O_logical_and: name = "O_logical_and"; break;
1883 case O_logical_or: name = "O_logical_or"; break;
1884 case O_index: name = "O_index"; break;
1885 case O_pregister: name = "O_pregister"; break;
1886 case O_cpregister: name = "O_cpregister"; break;
1887 case O_literal: name = "O_literal"; break;
1888 case O_lituse_addr: name = "O_lituse_addr"; break;
1889 case O_lituse_base: name = "O_lituse_base"; break;
1890 case O_lituse_bytoff: name = "O_lituse_bytoff"; break;
1891 case O_lituse_jsr: name = "O_lituse_jsr"; break;
1892 case O_lituse_tlsgd: name = "O_lituse_tlsgd"; break;
1893 case O_lituse_tlsldm: name = "O_lituse_tlsldm"; break;
1894 case O_gpdisp: name = "O_gpdisp"; break;
1895 case O_gprelhigh: name = "O_gprelhigh"; break;
1896 case O_gprellow: name = "O_gprellow"; break;
1897 case O_gprel: name = "O_gprel"; break;
1898 case O_samegp: name = "O_samegp"; break;
1899 case O_tlsgd: name = "O_tlsgd"; break;
1900 case O_tlsldm: name = "O_tlsldm"; break;
1901 case O_gotdtprel: name = "O_gotdtprel"; break;
1902 case O_dtprelhi: name = "O_dtprelhi"; break;
1903 case O_dtprello: name = "O_dtprello"; break;
1904 case O_dtprel: name = "O_dtprel"; break;
1905 case O_gottprel: name = "O_gottprel"; break;
1906 case O_tprelhi: name = "O_tprelhi"; break;
1907 case O_tprello: name = "O_tprello"; break;
1908 case O_tprel: name = "O_tprel"; break;
1911 fprintf (stderr, ", %s(%s, %s, %d)", name,
1912 (t->X_add_symbol) ? S_GET_NAME (t->X_add_symbol) : "--",
1913 (t->X_op_symbol) ? S_GET_NAME (t->X_op_symbol) : "--",
1914 (int) t->X_add_number);
1916 fprintf (stderr, "\n");
1917 fflush (stderr);
1919 #endif
1921 /* Parse the arguments to an opcode. */
1923 static int
1924 tokenize_arguments (str, tok, ntok)
1925 char *str;
1926 expressionS tok[];
1927 int ntok;
1929 expressionS *end_tok = tok + ntok;
1930 char *old_input_line_pointer;
1931 int saw_comma = 0, saw_arg = 0;
1932 #ifdef DEBUG_ALPHA
1933 expressionS *orig_tok = tok;
1934 #endif
1935 #ifdef RELOC_OP_P
1936 char *p;
1937 const struct alpha_reloc_op_tag *r;
1938 int c, i;
1939 size_t len;
1940 int reloc_found_p = 0;
1941 #endif
1943 memset (tok, 0, sizeof (*tok) * ntok);
1945 /* Save and restore input_line_pointer around this function. */
1946 old_input_line_pointer = input_line_pointer;
1947 input_line_pointer = str;
1949 #ifdef RELOC_OP_P
1950 /* ??? Wrest control of ! away from the regular expression parser. */
1951 is_end_of_line[(unsigned char) '!'] = 1;
1952 #endif
1954 while (tok < end_tok && *input_line_pointer)
1956 SKIP_WHITESPACE ();
1957 switch (*input_line_pointer)
1959 case '\0':
1960 goto fini;
1962 #ifdef RELOC_OP_P
1963 case '!':
1964 /* A relocation operand can be placed after the normal operand on an
1965 assembly language statement, and has the following form:
1966 !relocation_type!sequence_number. */
1967 if (reloc_found_p)
1969 /* Only support one relocation op per insn. */
1970 as_bad (_("More than one relocation op per insn"));
1971 goto err_report;
1974 if (!saw_arg)
1975 goto err;
1977 ++input_line_pointer;
1978 SKIP_WHITESPACE ();
1979 p = input_line_pointer;
1980 c = get_symbol_end ();
1982 /* Parse !relocation_type. */
1983 len = input_line_pointer - p;
1984 if (len == 0)
1986 as_bad (_("No relocation operand"));
1987 goto err_report;
1990 r = &alpha_reloc_op[0];
1991 for (i = alpha_num_reloc_op - 1; i >= 0; i--, r++)
1992 if (len == r->length && memcmp (p, r->name, len) == 0)
1993 break;
1994 if (i < 0)
1996 as_bad (_("Unknown relocation operand: !%s"), p);
1997 goto err_report;
2000 *input_line_pointer = c;
2001 SKIP_WHITESPACE ();
2002 if (*input_line_pointer != '!')
2004 if (r->require_seq)
2006 as_bad (_("no sequence number after !%s"), p);
2007 goto err_report;
2010 tok->X_add_number = 0;
2012 else
2014 if (! r->allow_seq)
2016 as_bad (_("!%s does not use a sequence number"), p);
2017 goto err_report;
2020 input_line_pointer++;
2022 /* Parse !sequence_number. */
2023 expression (tok);
2024 if (tok->X_op != O_constant || tok->X_add_number <= 0)
2026 as_bad (_("Bad sequence number: !%s!%s"),
2027 r->name, input_line_pointer);
2028 goto err_report;
2032 tok->X_op = r->op;
2033 reloc_found_p = 1;
2034 ++tok;
2035 break;
2036 #endif /* RELOC_OP_P */
2038 case ',':
2039 ++input_line_pointer;
2040 if (saw_comma || !saw_arg)
2041 goto err;
2042 saw_comma = 1;
2043 break;
2045 case '(':
2047 char *hold = input_line_pointer++;
2049 /* First try for parenthesized register ... */
2050 expression (tok);
2051 if (*input_line_pointer == ')' && tok->X_op == O_register)
2053 tok->X_op = (saw_comma ? O_cpregister : O_pregister);
2054 saw_comma = 0;
2055 saw_arg = 1;
2056 ++input_line_pointer;
2057 ++tok;
2058 break;
2061 /* ... then fall through to plain expression. */
2062 input_line_pointer = hold;
2065 default:
2066 if (saw_arg && !saw_comma)
2067 goto err;
2069 expression (tok);
2070 if (tok->X_op == O_illegal || tok->X_op == O_absent)
2071 goto err;
2073 saw_comma = 0;
2074 saw_arg = 1;
2075 ++tok;
2076 break;
2080 fini:
2081 if (saw_comma)
2082 goto err;
2083 input_line_pointer = old_input_line_pointer;
2085 #ifdef DEBUG_ALPHA
2086 debug_exp (orig_tok, ntok - (end_tok - tok));
2087 #endif
2088 #ifdef RELOC_OP_P
2089 is_end_of_line[(unsigned char) '!'] = 0;
2090 #endif
2092 return ntok - (end_tok - tok);
2094 err:
2095 #ifdef RELOC_OP_P
2096 is_end_of_line[(unsigned char) '!'] = 0;
2097 #endif
2098 input_line_pointer = old_input_line_pointer;
2099 return TOKENIZE_ERROR;
2101 #ifdef RELOC_OP_P
2102 err_report:
2103 is_end_of_line[(unsigned char) '!'] = 0;
2104 #endif
2105 input_line_pointer = old_input_line_pointer;
2106 return TOKENIZE_ERROR_REPORT;
2109 /* Search forward through all variants of an opcode looking for a
2110 syntax match. */
2112 static const struct alpha_opcode *
2113 find_opcode_match (first_opcode, tok, pntok, pcpumatch)
2114 const struct alpha_opcode *first_opcode;
2115 const expressionS *tok;
2116 int *pntok;
2117 int *pcpumatch;
2119 const struct alpha_opcode *opcode = first_opcode;
2120 int ntok = *pntok;
2121 int got_cpu_match = 0;
2125 const unsigned char *opidx;
2126 int tokidx = 0;
2128 /* Don't match opcodes that don't exist on this architecture. */
2129 if (!(opcode->flags & alpha_target))
2130 goto match_failed;
2132 got_cpu_match = 1;
2134 for (opidx = opcode->operands; *opidx; ++opidx)
2136 const struct alpha_operand *operand = &alpha_operands[*opidx];
2138 /* Only take input from real operands. */
2139 if (operand->flags & AXP_OPERAND_FAKE)
2140 continue;
2142 /* When we expect input, make sure we have it. */
2143 if (tokidx >= ntok)
2145 if ((operand->flags & AXP_OPERAND_OPTIONAL_MASK) == 0)
2146 goto match_failed;
2147 continue;
2150 /* Match operand type with expression type. */
2151 switch (operand->flags & AXP_OPERAND_TYPECHECK_MASK)
2153 case AXP_OPERAND_IR:
2154 if (tok[tokidx].X_op != O_register
2155 || !is_ir_num (tok[tokidx].X_add_number))
2156 goto match_failed;
2157 break;
2158 case AXP_OPERAND_FPR:
2159 if (tok[tokidx].X_op != O_register
2160 || !is_fpr_num (tok[tokidx].X_add_number))
2161 goto match_failed;
2162 break;
2163 case AXP_OPERAND_IR | AXP_OPERAND_PARENS:
2164 if (tok[tokidx].X_op != O_pregister
2165 || !is_ir_num (tok[tokidx].X_add_number))
2166 goto match_failed;
2167 break;
2168 case AXP_OPERAND_IR | AXP_OPERAND_PARENS | AXP_OPERAND_COMMA:
2169 if (tok[tokidx].X_op != O_cpregister
2170 || !is_ir_num (tok[tokidx].X_add_number))
2171 goto match_failed;
2172 break;
2174 case AXP_OPERAND_RELATIVE:
2175 case AXP_OPERAND_SIGNED:
2176 case AXP_OPERAND_UNSIGNED:
2177 switch (tok[tokidx].X_op)
2179 case O_illegal:
2180 case O_absent:
2181 case O_register:
2182 case O_pregister:
2183 case O_cpregister:
2184 goto match_failed;
2186 default:
2187 break;
2189 break;
2191 default:
2192 /* Everything else should have been fake. */
2193 abort ();
2195 ++tokidx;
2198 /* Possible match -- did we use all of our input? */
2199 if (tokidx == ntok)
2201 *pntok = ntok;
2202 return opcode;
2205 match_failed:;
2207 while (++opcode - alpha_opcodes < (int) alpha_num_opcodes
2208 && !strcmp (opcode->name, first_opcode->name));
2210 if (*pcpumatch)
2211 *pcpumatch = got_cpu_match;
2213 return NULL;
2216 /* Search forward through all variants of a macro looking for a syntax
2217 match. */
2219 static const struct alpha_macro *
2220 find_macro_match (first_macro, tok, pntok)
2221 const struct alpha_macro *first_macro;
2222 const expressionS *tok;
2223 int *pntok;
2225 const struct alpha_macro *macro = first_macro;
2226 int ntok = *pntok;
2230 const enum alpha_macro_arg *arg = macro->argsets;
2231 int tokidx = 0;
2233 while (*arg)
2235 switch (*arg)
2237 case MACRO_EOA:
2238 if (tokidx == ntok)
2239 return macro;
2240 else
2241 tokidx = 0;
2242 break;
2244 /* Index register. */
2245 case MACRO_IR:
2246 if (tokidx >= ntok || tok[tokidx].X_op != O_register
2247 || !is_ir_num (tok[tokidx].X_add_number))
2248 goto match_failed;
2249 ++tokidx;
2250 break;
2252 /* Parenthesized index register. */
2253 case MACRO_PIR:
2254 if (tokidx >= ntok || tok[tokidx].X_op != O_pregister
2255 || !is_ir_num (tok[tokidx].X_add_number))
2256 goto match_failed;
2257 ++tokidx;
2258 break;
2260 /* Optional parenthesized index register. */
2261 case MACRO_OPIR:
2262 if (tokidx < ntok && tok[tokidx].X_op == O_pregister
2263 && is_ir_num (tok[tokidx].X_add_number))
2264 ++tokidx;
2265 break;
2267 /* Leading comma with a parenthesized index register. */
2268 case MACRO_CPIR:
2269 if (tokidx >= ntok || tok[tokidx].X_op != O_cpregister
2270 || !is_ir_num (tok[tokidx].X_add_number))
2271 goto match_failed;
2272 ++tokidx;
2273 break;
2275 /* Floating point register. */
2276 case MACRO_FPR:
2277 if (tokidx >= ntok || tok[tokidx].X_op != O_register
2278 || !is_fpr_num (tok[tokidx].X_add_number))
2279 goto match_failed;
2280 ++tokidx;
2281 break;
2283 /* Normal expression. */
2284 case MACRO_EXP:
2285 if (tokidx >= ntok)
2286 goto match_failed;
2287 switch (tok[tokidx].X_op)
2289 case O_illegal:
2290 case O_absent:
2291 case O_register:
2292 case O_pregister:
2293 case O_cpregister:
2294 case O_literal:
2295 case O_lituse_base:
2296 case O_lituse_bytoff:
2297 case O_lituse_jsr:
2298 case O_gpdisp:
2299 case O_gprelhigh:
2300 case O_gprellow:
2301 case O_gprel:
2302 case O_samegp:
2303 goto match_failed;
2305 default:
2306 break;
2308 ++tokidx;
2309 break;
2311 match_failed:
2312 while (*arg != MACRO_EOA)
2313 ++arg;
2314 tokidx = 0;
2315 break;
2317 ++arg;
2320 while (++macro - alpha_macros < (int) alpha_num_macros
2321 && !strcmp (macro->name, first_macro->name));
2323 return NULL;
2326 /* Insert an operand value into an instruction. */
2328 static unsigned
2329 insert_operand (insn, operand, val, file, line)
2330 unsigned insn;
2331 const struct alpha_operand *operand;
2332 offsetT val;
2333 char *file;
2334 unsigned line;
2336 if (operand->bits != 32 && !(operand->flags & AXP_OPERAND_NOOVERFLOW))
2338 offsetT min, max;
2340 if (operand->flags & AXP_OPERAND_SIGNED)
2342 max = (1 << (operand->bits - 1)) - 1;
2343 min = -(1 << (operand->bits - 1));
2345 else
2347 max = (1 << operand->bits) - 1;
2348 min = 0;
2351 if (val < min || val > max)
2352 as_warn_value_out_of_range (_("operand"), val, min, max, file, line);
2355 if (operand->insert)
2357 const char *errmsg = NULL;
2359 insn = (*operand->insert) (insn, val, &errmsg);
2360 if (errmsg)
2361 as_warn (errmsg);
2363 else
2364 insn |= ((val & ((1 << operand->bits) - 1)) << operand->shift);
2366 return insn;
2369 /* Turn an opcode description and a set of arguments into
2370 an instruction and a fixup. */
2372 static void
2373 assemble_insn (opcode, tok, ntok, insn, reloc)
2374 const struct alpha_opcode *opcode;
2375 const expressionS *tok;
2376 int ntok;
2377 struct alpha_insn *insn;
2378 bfd_reloc_code_real_type reloc;
2380 const struct alpha_operand *reloc_operand = NULL;
2381 const expressionS *reloc_exp = NULL;
2382 const unsigned char *argidx;
2383 unsigned image;
2384 int tokidx = 0;
2386 memset (insn, 0, sizeof (*insn));
2387 image = opcode->opcode;
2389 for (argidx = opcode->operands; *argidx; ++argidx)
2391 const struct alpha_operand *operand = &alpha_operands[*argidx];
2392 const expressionS *t = (const expressionS *) 0;
2394 if (operand->flags & AXP_OPERAND_FAKE)
2396 /* fake operands take no value and generate no fixup */
2397 image = insert_operand (image, operand, 0, NULL, 0);
2398 continue;
2401 if (tokidx >= ntok)
2403 switch (operand->flags & AXP_OPERAND_OPTIONAL_MASK)
2405 case AXP_OPERAND_DEFAULT_FIRST:
2406 t = &tok[0];
2407 break;
2408 case AXP_OPERAND_DEFAULT_SECOND:
2409 t = &tok[1];
2410 break;
2411 case AXP_OPERAND_DEFAULT_ZERO:
2413 static expressionS zero_exp;
2414 t = &zero_exp;
2415 zero_exp.X_op = O_constant;
2416 zero_exp.X_unsigned = 1;
2418 break;
2419 default:
2420 abort ();
2423 else
2424 t = &tok[tokidx++];
2426 switch (t->X_op)
2428 case O_register:
2429 case O_pregister:
2430 case O_cpregister:
2431 image = insert_operand (image, operand, regno (t->X_add_number),
2432 NULL, 0);
2433 break;
2435 case O_constant:
2436 image = insert_operand (image, operand, t->X_add_number, NULL, 0);
2437 assert (reloc_operand == NULL);
2438 reloc_operand = operand;
2439 reloc_exp = t;
2440 break;
2442 default:
2443 /* This is only 0 for fields that should contain registers,
2444 which means this pattern shouldn't have matched. */
2445 if (operand->default_reloc == 0)
2446 abort ();
2448 /* There is one special case for which an insn receives two
2449 relocations, and thus the user-supplied reloc does not
2450 override the operand reloc. */
2451 if (operand->default_reloc == BFD_RELOC_ALPHA_HINT)
2453 struct alpha_fixup *fixup;
2455 if (insn->nfixups >= MAX_INSN_FIXUPS)
2456 as_fatal (_("too many fixups"));
2458 fixup = &insn->fixups[insn->nfixups++];
2459 fixup->exp = *t;
2460 fixup->reloc = BFD_RELOC_ALPHA_HINT;
2462 else
2464 if (reloc == BFD_RELOC_UNUSED)
2465 reloc = operand->default_reloc;
2467 assert (reloc_operand == NULL);
2468 reloc_operand = operand;
2469 reloc_exp = t;
2471 break;
2475 if (reloc != BFD_RELOC_UNUSED)
2477 struct alpha_fixup *fixup;
2479 if (insn->nfixups >= MAX_INSN_FIXUPS)
2480 as_fatal (_("too many fixups"));
2482 /* ??? My but this is hacky. But the OSF/1 assembler uses the same
2483 relocation tag for both ldah and lda with gpdisp. Choose the
2484 correct internal relocation based on the opcode. */
2485 if (reloc == BFD_RELOC_ALPHA_GPDISP)
2487 if (strcmp (opcode->name, "ldah") == 0)
2488 reloc = BFD_RELOC_ALPHA_GPDISP_HI16;
2489 else if (strcmp (opcode->name, "lda") == 0)
2490 reloc = BFD_RELOC_ALPHA_GPDISP_LO16;
2491 else
2492 as_bad (_("invalid relocation for instruction"));
2495 /* If this is a real relocation (as opposed to a lituse hint), then
2496 the relocation width should match the operand width. */
2497 else if (reloc < BFD_RELOC_UNUSED)
2499 reloc_howto_type *reloc_howto
2500 = bfd_reloc_type_lookup (stdoutput, reloc);
2501 if (reloc_howto->bitsize != reloc_operand->bits)
2503 as_bad (_("invalid relocation for field"));
2504 return;
2508 fixup = &insn->fixups[insn->nfixups++];
2509 if (reloc_exp)
2510 fixup->exp = *reloc_exp;
2511 else
2512 fixup->exp.X_op = O_absent;
2513 fixup->reloc = reloc;
2516 insn->insn = image;
2519 /* Actually output an instruction with its fixup. */
2521 static void
2522 emit_insn (insn)
2523 struct alpha_insn *insn;
2525 char *f;
2526 int i;
2528 /* Take care of alignment duties. */
2529 if (alpha_auto_align_on && alpha_current_align < 2)
2530 alpha_align (2, (char *) NULL, alpha_insn_label, 0);
2531 if (alpha_current_align > 2)
2532 alpha_current_align = 2;
2533 alpha_insn_label = NULL;
2535 /* Write out the instruction. */
2536 f = frag_more (4);
2537 md_number_to_chars (f, insn->insn, 4);
2539 #ifdef OBJ_ELF
2540 dwarf2_emit_insn (4);
2541 #endif
2543 /* Apply the fixups in order. */
2544 for (i = 0; i < insn->nfixups; ++i)
2546 const struct alpha_operand *operand = (const struct alpha_operand *) 0;
2547 struct alpha_fixup *fixup = &insn->fixups[i];
2548 struct alpha_reloc_tag *info = NULL;
2549 int size, pcrel;
2550 fixS *fixP;
2552 /* Some fixups are only used internally and so have no howto. */
2553 if ((int) fixup->reloc < 0)
2555 operand = &alpha_operands[-(int) fixup->reloc];
2556 size = 4;
2557 pcrel = ((operand->flags & AXP_OPERAND_RELATIVE) != 0);
2559 else if (fixup->reloc > BFD_RELOC_UNUSED
2560 || fixup->reloc == BFD_RELOC_ALPHA_GPDISP_HI16
2561 || fixup->reloc == BFD_RELOC_ALPHA_GPDISP_LO16)
2563 size = 2;
2564 pcrel = 0;
2566 else
2568 reloc_howto_type *reloc_howto
2569 = bfd_reloc_type_lookup (stdoutput, fixup->reloc);
2570 assert (reloc_howto);
2572 size = bfd_get_reloc_size (reloc_howto);
2573 assert (size >= 1 && size <= 4);
2575 pcrel = reloc_howto->pc_relative;
2578 fixP = fix_new_exp (frag_now, f - frag_now->fr_literal, size,
2579 &fixup->exp, pcrel, fixup->reloc);
2581 /* Turn off complaints that the addend is too large for some fixups,
2582 and copy in the sequence number for the explicit relocations. */
2583 switch (fixup->reloc)
2585 case BFD_RELOC_ALPHA_HINT:
2586 case BFD_RELOC_GPREL32:
2587 case BFD_RELOC_GPREL16:
2588 case BFD_RELOC_ALPHA_GPREL_HI16:
2589 case BFD_RELOC_ALPHA_GPREL_LO16:
2590 case BFD_RELOC_ALPHA_GOTDTPREL16:
2591 case BFD_RELOC_ALPHA_DTPREL_HI16:
2592 case BFD_RELOC_ALPHA_DTPREL_LO16:
2593 case BFD_RELOC_ALPHA_DTPREL16:
2594 case BFD_RELOC_ALPHA_GOTTPREL16:
2595 case BFD_RELOC_ALPHA_TPREL_HI16:
2596 case BFD_RELOC_ALPHA_TPREL_LO16:
2597 case BFD_RELOC_ALPHA_TPREL16:
2598 fixP->fx_no_overflow = 1;
2599 break;
2601 case BFD_RELOC_ALPHA_GPDISP_HI16:
2602 fixP->fx_no_overflow = 1;
2603 fixP->fx_addsy = section_symbol (now_seg);
2604 fixP->fx_offset = 0;
2606 info = get_alpha_reloc_tag (insn->sequence);
2607 if (++info->n_master > 1)
2608 as_bad (_("too many ldah insns for !gpdisp!%ld"), insn->sequence);
2609 if (info->segment != now_seg)
2610 as_bad (_("both insns for !gpdisp!%ld must be in the same section"),
2611 insn->sequence);
2612 fixP->tc_fix_data.info = info;
2613 break;
2615 case BFD_RELOC_ALPHA_GPDISP_LO16:
2616 fixP->fx_no_overflow = 1;
2618 info = get_alpha_reloc_tag (insn->sequence);
2619 if (++info->n_slaves > 1)
2620 as_bad (_("too many lda insns for !gpdisp!%ld"), insn->sequence);
2621 if (info->segment != now_seg)
2622 as_bad (_("both insns for !gpdisp!%ld must be in the same section"),
2623 insn->sequence);
2624 fixP->tc_fix_data.info = info;
2625 info->slaves = fixP;
2626 break;
2628 case BFD_RELOC_ALPHA_LITERAL:
2629 case BFD_RELOC_ALPHA_ELF_LITERAL:
2630 fixP->fx_no_overflow = 1;
2632 if (insn->sequence == 0)
2633 break;
2634 info = get_alpha_reloc_tag (insn->sequence);
2635 info->master = fixP;
2636 info->n_master++;
2637 if (info->segment != now_seg)
2638 info->multi_section_p = 1;
2639 fixP->tc_fix_data.info = info;
2640 break;
2642 #ifdef RELOC_OP_P
2643 case DUMMY_RELOC_LITUSE_ADDR:
2644 fixP->fx_offset = LITUSE_ALPHA_ADDR;
2645 goto do_lituse;
2646 case DUMMY_RELOC_LITUSE_BASE:
2647 fixP->fx_offset = LITUSE_ALPHA_BASE;
2648 goto do_lituse;
2649 case DUMMY_RELOC_LITUSE_BYTOFF:
2650 fixP->fx_offset = LITUSE_ALPHA_BYTOFF;
2651 goto do_lituse;
2652 case DUMMY_RELOC_LITUSE_JSR:
2653 fixP->fx_offset = LITUSE_ALPHA_JSR;
2654 goto do_lituse;
2655 case DUMMY_RELOC_LITUSE_TLSGD:
2656 fixP->fx_offset = LITUSE_ALPHA_TLSGD;
2657 goto do_lituse;
2658 case DUMMY_RELOC_LITUSE_TLSLDM:
2659 fixP->fx_offset = LITUSE_ALPHA_TLSLDM;
2660 goto do_lituse;
2661 do_lituse:
2662 fixP->fx_addsy = section_symbol (now_seg);
2663 fixP->fx_r_type = BFD_RELOC_ALPHA_LITUSE;
2665 info = get_alpha_reloc_tag (insn->sequence);
2666 if (fixup->reloc == DUMMY_RELOC_LITUSE_TLSGD)
2667 info->saw_lu_tlsgd = 1;
2668 else if (fixup->reloc == DUMMY_RELOC_LITUSE_TLSLDM)
2669 info->saw_lu_tlsldm = 1;
2670 if (++info->n_slaves > 1)
2672 if (info->saw_lu_tlsgd)
2673 as_bad (_("too many lituse insns for !lituse_tlsgd!%ld"),
2674 insn->sequence);
2675 else if (info->saw_lu_tlsldm)
2676 as_bad (_("too many lituse insns for !lituse_tlsldm!%ld"),
2677 insn->sequence);
2679 fixP->tc_fix_data.info = info;
2680 fixP->tc_fix_data.next_reloc = info->slaves;
2681 info->slaves = fixP;
2682 if (info->segment != now_seg)
2683 info->multi_section_p = 1;
2684 break;
2686 case BFD_RELOC_ALPHA_TLSGD:
2687 fixP->fx_no_overflow = 1;
2689 if (insn->sequence == 0)
2690 break;
2691 info = get_alpha_reloc_tag (insn->sequence);
2692 if (info->saw_tlsgd)
2693 as_bad (_("duplicate !tlsgd!%ld"), insn->sequence);
2694 else if (info->saw_tlsldm)
2695 as_bad (_("sequence number in use for !tlsldm!%ld"),
2696 insn->sequence);
2697 else
2698 info->saw_tlsgd = 1;
2699 fixP->tc_fix_data.info = info;
2700 break;
2702 case BFD_RELOC_ALPHA_TLSLDM:
2703 fixP->fx_no_overflow = 1;
2705 if (insn->sequence == 0)
2706 break;
2707 info = get_alpha_reloc_tag (insn->sequence);
2708 if (info->saw_tlsldm)
2709 as_bad (_("duplicate !tlsldm!%ld"), insn->sequence);
2710 else if (info->saw_tlsgd)
2711 as_bad (_("sequence number in use for !tlsgd!%ld"),
2712 insn->sequence);
2713 else
2714 info->saw_tlsldm = 1;
2715 fixP->tc_fix_data.info = info;
2716 break;
2717 #endif
2718 default:
2719 if ((int) fixup->reloc < 0)
2721 if (operand->flags & AXP_OPERAND_NOOVERFLOW)
2722 fixP->fx_no_overflow = 1;
2724 break;
2729 /* Given an opcode name and a pre-tokenized set of arguments, assemble
2730 the insn, but do not emit it.
2732 Note that this implies no macros allowed, since we can't store more
2733 than one insn in an insn structure. */
2735 static void
2736 assemble_tokens_to_insn (opname, tok, ntok, insn)
2737 const char *opname;
2738 const expressionS *tok;
2739 int ntok;
2740 struct alpha_insn *insn;
2742 const struct alpha_opcode *opcode;
2744 /* search opcodes */
2745 opcode = (const struct alpha_opcode *) hash_find (alpha_opcode_hash, opname);
2746 if (opcode)
2748 int cpumatch;
2749 opcode = find_opcode_match (opcode, tok, &ntok, &cpumatch);
2750 if (opcode)
2752 assemble_insn (opcode, tok, ntok, insn, BFD_RELOC_UNUSED);
2753 return;
2755 else if (cpumatch)
2756 as_bad (_("inappropriate arguments for opcode `%s'"), opname);
2757 else
2758 as_bad (_("opcode `%s' not supported for target %s"), opname,
2759 alpha_target_name);
2761 else
2762 as_bad (_("unknown opcode `%s'"), opname);
2765 /* Given an opcode name and a pre-tokenized set of arguments, take the
2766 opcode all the way through emission. */
2768 static void
2769 assemble_tokens (opname, tok, ntok, local_macros_on)
2770 const char *opname;
2771 const expressionS *tok;
2772 int ntok;
2773 int local_macros_on;
2775 int found_something = 0;
2776 const struct alpha_opcode *opcode;
2777 const struct alpha_macro *macro;
2778 int cpumatch = 1;
2779 bfd_reloc_code_real_type reloc = BFD_RELOC_UNUSED;
2781 #ifdef RELOC_OP_P
2782 /* If a user-specified relocation is present, this is not a macro. */
2783 if (ntok && USER_RELOC_P (tok[ntok - 1].X_op))
2785 reloc = ALPHA_RELOC_TABLE (tok[ntok - 1].X_op)->reloc;
2786 ntok--;
2788 else
2789 #endif
2790 if (local_macros_on)
2792 macro = ((const struct alpha_macro *)
2793 hash_find (alpha_macro_hash, opname));
2794 if (macro)
2796 found_something = 1;
2797 macro = find_macro_match (macro, tok, &ntok);
2798 if (macro)
2800 (*macro->emit) (tok, ntok, macro->arg);
2801 return;
2806 /* Search opcodes. */
2807 opcode = (const struct alpha_opcode *) hash_find (alpha_opcode_hash, opname);
2808 if (opcode)
2810 found_something = 1;
2811 opcode = find_opcode_match (opcode, tok, &ntok, &cpumatch);
2812 if (opcode)
2814 struct alpha_insn insn;
2815 assemble_insn (opcode, tok, ntok, &insn, reloc);
2817 /* Copy the sequence number for the reloc from the reloc token. */
2818 if (reloc != BFD_RELOC_UNUSED)
2819 insn.sequence = tok[ntok].X_add_number;
2821 emit_insn (&insn);
2822 return;
2826 if (found_something)
2828 if (cpumatch)
2829 as_bad (_("inappropriate arguments for opcode `%s'"), opname);
2830 else
2831 as_bad (_("opcode `%s' not supported for target %s"), opname,
2832 alpha_target_name);
2834 else
2835 as_bad (_("unknown opcode `%s'"), opname);
2838 /* Some instruction sets indexed by lg(size). */
2839 static const char * const sextX_op[] = { "sextb", "sextw", "sextl", NULL };
2840 static const char * const insXl_op[] = { "insbl", "inswl", "insll", "insql" };
2841 static const char * const insXh_op[] = { NULL, "inswh", "inslh", "insqh" };
2842 static const char * const extXl_op[] = { "extbl", "extwl", "extll", "extql" };
2843 static const char * const extXh_op[] = { NULL, "extwh", "extlh", "extqh" };
2844 static const char * const mskXl_op[] = { "mskbl", "mskwl", "mskll", "mskql" };
2845 static const char * const mskXh_op[] = { NULL, "mskwh", "msklh", "mskqh" };
2846 static const char * const stX_op[] = { "stb", "stw", "stl", "stq" };
2847 static const char * const ldXu_op[] = { "ldbu", "ldwu", NULL, NULL };
2849 /* Implement the ldgp macro. */
2851 static void
2852 emit_ldgp (tok, ntok, unused)
2853 const expressionS *tok;
2854 int ntok ATTRIBUTE_UNUSED;
2855 const PTR unused ATTRIBUTE_UNUSED;
2857 #ifdef OBJ_AOUT
2858 FIXME
2859 #endif
2860 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
2861 /* from "ldgp r1,n(r2)", generate "ldah r1,X(R2); lda r1,Y(r1)"
2862 with appropriate constants and relocations. */
2863 struct alpha_insn insn;
2864 expressionS newtok[3];
2865 expressionS addend;
2867 #ifdef OBJ_ECOFF
2868 if (regno (tok[2].X_add_number) == AXP_REG_PV)
2869 ecoff_set_gp_prolog_size (0);
2870 #endif
2872 newtok[0] = tok[0];
2873 set_tok_const (newtok[1], 0);
2874 newtok[2] = tok[2];
2876 assemble_tokens_to_insn ("ldah", newtok, 3, &insn);
2878 addend = tok[1];
2880 #ifdef OBJ_ECOFF
2881 if (addend.X_op != O_constant)
2882 as_bad (_("can not resolve expression"));
2883 addend.X_op = O_symbol;
2884 addend.X_add_symbol = alpha_gp_symbol;
2885 #endif
2887 insn.nfixups = 1;
2888 insn.fixups[0].exp = addend;
2889 insn.fixups[0].reloc = BFD_RELOC_ALPHA_GPDISP_HI16;
2890 insn.sequence = next_sequence_num;
2892 emit_insn (&insn);
2894 set_tok_preg (newtok[2], tok[0].X_add_number);
2896 assemble_tokens_to_insn ("lda", newtok, 3, &insn);
2898 #ifdef OBJ_ECOFF
2899 addend.X_add_number += 4;
2900 #endif
2902 insn.nfixups = 1;
2903 insn.fixups[0].exp = addend;
2904 insn.fixups[0].reloc = BFD_RELOC_ALPHA_GPDISP_LO16;
2905 insn.sequence = next_sequence_num--;
2907 emit_insn (&insn);
2908 #endif /* OBJ_ECOFF || OBJ_ELF */
2911 #ifdef OBJ_EVAX
2913 /* Add symbol+addend to link pool.
2914 Return offset from basesym to entry in link pool.
2916 Add new fixup only if offset isn't 16bit. */
2918 valueT
2919 add_to_link_pool (basesym, sym, addend)
2920 symbolS *basesym;
2921 symbolS *sym;
2922 offsetT addend;
2924 segT current_section = now_seg;
2925 int current_subsec = now_subseg;
2926 valueT offset;
2927 bfd_reloc_code_real_type reloc_type;
2928 char *p;
2929 segment_info_type *seginfo = seg_info (alpha_link_section);
2930 fixS *fixp;
2932 offset = - *symbol_get_obj (basesym);
2934 /* @@ This assumes all entries in a given section will be of the same
2935 size... Probably correct, but unwise to rely on. */
2936 /* This must always be called with the same subsegment. */
2938 if (seginfo->frchainP)
2939 for (fixp = seginfo->frchainP->fix_root;
2940 fixp != (fixS *) NULL;
2941 fixp = fixp->fx_next, offset += 8)
2943 if (fixp->fx_addsy == sym && fixp->fx_offset == addend)
2945 if (range_signed_16 (offset))
2947 return offset;
2952 /* Not found in 16bit signed range. */
2954 subseg_set (alpha_link_section, 0);
2955 p = frag_more (8);
2956 memset (p, 0, 8);
2958 fix_new (frag_now, p - frag_now->fr_literal, 8, sym, addend, 0,
2959 BFD_RELOC_64);
2961 subseg_set (current_section, current_subsec);
2962 seginfo->literal_pool_size += 8;
2963 return offset;
2966 #endif /* OBJ_EVAX */
2968 /* Load a (partial) expression into a target register.
2970 If poffset is not null, after the call it will either contain
2971 O_constant 0, or a 16-bit offset appropriate for any MEM format
2972 instruction. In addition, pbasereg will be modified to point to
2973 the base register to use in that MEM format instruction.
2975 In any case, *pbasereg should contain a base register to add to the
2976 expression. This will normally be either AXP_REG_ZERO or
2977 alpha_gp_register. Symbol addresses will always be loaded via $gp,
2978 so "foo($0)" is interpreted as adding the address of foo to $0;
2979 i.e. "ldq $targ, LIT($gp); addq $targ, $0, $targ". Odd, perhaps,
2980 but this is what OSF/1 does.
2982 If explicit relocations of the form !literal!<number> are allowed,
2983 and used, then explicit_reloc with be an expression pointer.
2985 Finally, the return value is nonzero if the calling macro may emit
2986 a LITUSE reloc if otherwise appropriate; the return value is the
2987 sequence number to use. */
2989 static long
2990 load_expression (targreg, exp, pbasereg, poffset)
2991 int targreg;
2992 const expressionS *exp;
2993 int *pbasereg;
2994 expressionS *poffset;
2996 long emit_lituse = 0;
2997 offsetT addend = exp->X_add_number;
2998 int basereg = *pbasereg;
2999 struct alpha_insn insn;
3000 expressionS newtok[3];
3002 switch (exp->X_op)
3004 case O_symbol:
3006 #ifdef OBJ_ECOFF
3007 offsetT lit;
3009 /* Attempt to reduce .lit load by splitting the offset from
3010 its symbol when possible, but don't create a situation in
3011 which we'd fail. */
3012 if (!range_signed_32 (addend) &&
3013 (alpha_noat_on || targreg == AXP_REG_AT))
3015 lit = add_to_literal_pool (exp->X_add_symbol, addend,
3016 alpha_lita_section, 8);
3017 addend = 0;
3019 else
3021 lit = add_to_literal_pool (exp->X_add_symbol, 0,
3022 alpha_lita_section, 8);
3025 if (lit >= 0x8000)
3026 as_fatal (_("overflow in literal (.lita) table"));
3028 /* emit "ldq r, lit(gp)" */
3030 if (basereg != alpha_gp_register && targreg == basereg)
3032 if (alpha_noat_on)
3033 as_bad (_("macro requires $at register while noat in effect"));
3034 if (targreg == AXP_REG_AT)
3035 as_bad (_("macro requires $at while $at in use"));
3037 set_tok_reg (newtok[0], AXP_REG_AT);
3039 else
3040 set_tok_reg (newtok[0], targreg);
3041 set_tok_sym (newtok[1], alpha_lita_symbol, lit);
3042 set_tok_preg (newtok[2], alpha_gp_register);
3044 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
3046 assert (insn.nfixups == 1);
3047 insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITERAL;
3048 insn.sequence = emit_lituse = next_sequence_num--;
3049 #endif /* OBJ_ECOFF */
3050 #ifdef OBJ_ELF
3051 /* emit "ldq r, gotoff(gp)" */
3053 if (basereg != alpha_gp_register && targreg == basereg)
3055 if (alpha_noat_on)
3056 as_bad (_("macro requires $at register while noat in effect"));
3057 if (targreg == AXP_REG_AT)
3058 as_bad (_("macro requires $at while $at in use"));
3060 set_tok_reg (newtok[0], AXP_REG_AT);
3062 else
3063 set_tok_reg (newtok[0], targreg);
3065 /* XXX: Disable this .got minimizing optimization so that we can get
3066 better instruction offset knowledge in the compiler. This happens
3067 very infrequently anyway. */
3068 if (1
3069 || (!range_signed_32 (addend)
3070 && (alpha_noat_on || targreg == AXP_REG_AT)))
3072 newtok[1] = *exp;
3073 addend = 0;
3075 else
3077 set_tok_sym (newtok[1], exp->X_add_symbol, 0);
3080 set_tok_preg (newtok[2], alpha_gp_register);
3082 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
3084 assert (insn.nfixups == 1);
3085 insn.fixups[0].reloc = BFD_RELOC_ALPHA_ELF_LITERAL;
3086 insn.sequence = emit_lituse = next_sequence_num--;
3087 #endif /* OBJ_ELF */
3088 #ifdef OBJ_EVAX
3089 offsetT link;
3091 /* Find symbol or symbol pointer in link section. */
3093 if (exp->X_add_symbol == alpha_evax_proc.symbol)
3095 if (range_signed_16 (addend))
3097 set_tok_reg (newtok[0], targreg);
3098 set_tok_const (newtok[1], addend);
3099 set_tok_preg (newtok[2], basereg);
3100 assemble_tokens_to_insn ("lda", newtok, 3, &insn);
3101 addend = 0;
3103 else
3105 set_tok_reg (newtok[0], targreg);
3106 set_tok_const (newtok[1], 0);
3107 set_tok_preg (newtok[2], basereg);
3108 assemble_tokens_to_insn ("lda", newtok, 3, &insn);
3111 else
3113 if (!range_signed_32 (addend))
3115 link = add_to_link_pool (alpha_evax_proc.symbol,
3116 exp->X_add_symbol, addend);
3117 addend = 0;
3119 else
3121 link = add_to_link_pool (alpha_evax_proc.symbol,
3122 exp->X_add_symbol, 0);
3124 set_tok_reg (newtok[0], targreg);
3125 set_tok_const (newtok[1], link);
3126 set_tok_preg (newtok[2], basereg);
3127 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
3129 #endif /* OBJ_EVAX */
3131 emit_insn (&insn);
3133 #ifndef OBJ_EVAX
3134 if (basereg != alpha_gp_register && basereg != AXP_REG_ZERO)
3136 /* emit "addq r, base, r" */
3138 set_tok_reg (newtok[1], basereg);
3139 set_tok_reg (newtok[2], targreg);
3140 assemble_tokens ("addq", newtok, 3, 0);
3142 #endif
3144 basereg = targreg;
3146 break;
3148 case O_constant:
3149 break;
3151 case O_subtract:
3152 /* Assume that this difference expression will be resolved to an
3153 absolute value and that that value will fit in 16 bits. */
3155 set_tok_reg (newtok[0], targreg);
3156 newtok[1] = *exp;
3157 set_tok_preg (newtok[2], basereg);
3158 assemble_tokens ("lda", newtok, 3, 0);
3160 if (poffset)
3161 set_tok_const (*poffset, 0);
3162 return 0;
3164 case O_big:
3165 if (exp->X_add_number > 0)
3166 as_bad (_("bignum invalid; zero assumed"));
3167 else
3168 as_bad (_("floating point number invalid; zero assumed"));
3169 addend = 0;
3170 break;
3172 default:
3173 as_bad (_("can't handle expression"));
3174 addend = 0;
3175 break;
3178 if (!range_signed_32 (addend))
3180 offsetT lit;
3181 long seq_num = next_sequence_num--;
3183 /* For 64-bit addends, just put it in the literal pool. */
3185 #ifdef OBJ_EVAX
3186 /* emit "ldq targreg, lit(basereg)" */
3187 lit = add_to_link_pool (alpha_evax_proc.symbol,
3188 section_symbol (absolute_section), addend);
3189 set_tok_reg (newtok[0], targreg);
3190 set_tok_const (newtok[1], lit);
3191 set_tok_preg (newtok[2], alpha_gp_register);
3192 assemble_tokens ("ldq", newtok, 3, 0);
3193 #else
3195 if (alpha_lit8_section == NULL)
3197 create_literal_section (".lit8",
3198 &alpha_lit8_section,
3199 &alpha_lit8_symbol);
3201 #ifdef OBJ_ECOFF
3202 alpha_lit8_literal = add_to_literal_pool (alpha_lit8_symbol, 0x8000,
3203 alpha_lita_section, 8);
3204 if (alpha_lit8_literal >= 0x8000)
3205 as_fatal (_("overflow in literal (.lita) table"));
3206 #endif
3209 lit = add_to_literal_pool (NULL, addend, alpha_lit8_section, 8) - 0x8000;
3210 if (lit >= 0x8000)
3211 as_fatal (_("overflow in literal (.lit8) table"));
3213 /* emit "lda litreg, .lit8+0x8000" */
3215 if (targreg == basereg)
3217 if (alpha_noat_on)
3218 as_bad (_("macro requires $at register while noat in effect"));
3219 if (targreg == AXP_REG_AT)
3220 as_bad (_("macro requires $at while $at in use"));
3222 set_tok_reg (newtok[0], AXP_REG_AT);
3224 else
3225 set_tok_reg (newtok[0], targreg);
3226 #ifdef OBJ_ECOFF
3227 set_tok_sym (newtok[1], alpha_lita_symbol, alpha_lit8_literal);
3228 #endif
3229 #ifdef OBJ_ELF
3230 set_tok_sym (newtok[1], alpha_lit8_symbol, 0x8000);
3231 #endif
3232 set_tok_preg (newtok[2], alpha_gp_register);
3234 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
3236 assert (insn.nfixups == 1);
3237 #ifdef OBJ_ECOFF
3238 insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITERAL;
3239 #endif
3240 #ifdef OBJ_ELF
3241 insn.fixups[0].reloc = BFD_RELOC_ALPHA_ELF_LITERAL;
3242 #endif
3243 insn.sequence = seq_num;
3245 emit_insn (&insn);
3247 /* emit "ldq litreg, lit(litreg)" */
3249 set_tok_const (newtok[1], lit);
3250 set_tok_preg (newtok[2], newtok[0].X_add_number);
3252 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
3254 assert (insn.nfixups < MAX_INSN_FIXUPS);
3255 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
3256 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3257 insn.nfixups++;
3258 insn.sequence = seq_num;
3259 emit_lituse = 0;
3261 emit_insn (&insn);
3263 /* emit "addq litreg, base, target" */
3265 if (basereg != AXP_REG_ZERO)
3267 set_tok_reg (newtok[1], basereg);
3268 set_tok_reg (newtok[2], targreg);
3269 assemble_tokens ("addq", newtok, 3, 0);
3271 #endif /* !OBJ_EVAX */
3273 if (poffset)
3274 set_tok_const (*poffset, 0);
3275 *pbasereg = targreg;
3277 else
3279 offsetT low, high, extra, tmp;
3281 /* for 32-bit operands, break up the addend */
3283 low = sign_extend_16 (addend);
3284 tmp = addend - low;
3285 high = sign_extend_16 (tmp >> 16);
3287 if (tmp - (high << 16))
3289 extra = 0x4000;
3290 tmp -= 0x40000000;
3291 high = sign_extend_16 (tmp >> 16);
3293 else
3294 extra = 0;
3296 set_tok_reg (newtok[0], targreg);
3297 set_tok_preg (newtok[2], basereg);
3299 if (extra)
3301 /* emit "ldah r, extra(r) */
3302 set_tok_const (newtok[1], extra);
3303 assemble_tokens ("ldah", newtok, 3, 0);
3304 set_tok_preg (newtok[2], basereg = targreg);
3307 if (high)
3309 /* emit "ldah r, high(r) */
3310 set_tok_const (newtok[1], high);
3311 assemble_tokens ("ldah", newtok, 3, 0);
3312 basereg = targreg;
3313 set_tok_preg (newtok[2], basereg);
3316 if ((low && !poffset) || (!poffset && basereg != targreg))
3318 /* emit "lda r, low(base)" */
3319 set_tok_const (newtok[1], low);
3320 assemble_tokens ("lda", newtok, 3, 0);
3321 basereg = targreg;
3322 low = 0;
3325 if (poffset)
3326 set_tok_const (*poffset, low);
3327 *pbasereg = basereg;
3330 return emit_lituse;
3333 /* The lda macro differs from the lda instruction in that it handles
3334 most simple expressions, particularly symbol address loads and
3335 large constants. */
3337 static void
3338 emit_lda (tok, ntok, unused)
3339 const expressionS *tok;
3340 int ntok;
3341 const PTR unused ATTRIBUTE_UNUSED;
3343 int basereg;
3345 if (ntok == 2)
3346 basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
3347 else
3348 basereg = tok[2].X_add_number;
3350 (void) load_expression (tok[0].X_add_number, &tok[1], &basereg, NULL);
3353 /* The ldah macro differs from the ldah instruction in that it has $31
3354 as an implied base register. */
3356 static void
3357 emit_ldah (tok, ntok, unused)
3358 const expressionS *tok;
3359 int ntok ATTRIBUTE_UNUSED;
3360 const PTR unused ATTRIBUTE_UNUSED;
3362 expressionS newtok[3];
3364 newtok[0] = tok[0];
3365 newtok[1] = tok[1];
3366 set_tok_preg (newtok[2], AXP_REG_ZERO);
3368 assemble_tokens ("ldah", newtok, 3, 0);
3371 /* Handle all "simple" integer register loads -- ldq, ldq_l, ldq_u,
3372 etc. They differ from the real instructions in that they do simple
3373 expressions like the lda macro. */
3375 static void
3376 emit_ir_load (tok, ntok, opname)
3377 const expressionS *tok;
3378 int ntok;
3379 const PTR opname;
3381 int basereg;
3382 long lituse;
3383 expressionS newtok[3];
3384 struct alpha_insn insn;
3386 if (ntok == 2)
3387 basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
3388 else
3389 basereg = tok[2].X_add_number;
3391 lituse = load_expression (tok[0].X_add_number, &tok[1], &basereg,
3392 &newtok[1]);
3394 newtok[0] = tok[0];
3395 set_tok_preg (newtok[2], basereg);
3397 assemble_tokens_to_insn ((const char *) opname, newtok, 3, &insn);
3399 if (lituse)
3401 assert (insn.nfixups < MAX_INSN_FIXUPS);
3402 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
3403 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3404 insn.nfixups++;
3405 insn.sequence = lituse;
3408 emit_insn (&insn);
3411 /* Handle fp register loads, and both integer and fp register stores.
3412 Again, we handle simple expressions. */
3414 static void
3415 emit_loadstore (tok, ntok, opname)
3416 const expressionS *tok;
3417 int ntok;
3418 const PTR opname;
3420 int basereg;
3421 long lituse;
3422 expressionS newtok[3];
3423 struct alpha_insn insn;
3425 if (ntok == 2)
3426 basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
3427 else
3428 basereg = tok[2].X_add_number;
3430 if (tok[1].X_op != O_constant || !range_signed_16 (tok[1].X_add_number))
3432 if (alpha_noat_on)
3433 as_bad (_("macro requires $at register while noat in effect"));
3435 lituse = load_expression (AXP_REG_AT, &tok[1], &basereg, &newtok[1]);
3437 else
3439 newtok[1] = tok[1];
3440 lituse = 0;
3443 newtok[0] = tok[0];
3444 set_tok_preg (newtok[2], basereg);
3446 assemble_tokens_to_insn ((const char *) opname, newtok, 3, &insn);
3448 if (lituse)
3450 assert (insn.nfixups < MAX_INSN_FIXUPS);
3451 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
3452 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3453 insn.nfixups++;
3454 insn.sequence = lituse;
3457 emit_insn (&insn);
3460 /* Load a half-word or byte as an unsigned value. */
3462 static void
3463 emit_ldXu (tok, ntok, vlgsize)
3464 const expressionS *tok;
3465 int ntok;
3466 const PTR vlgsize;
3468 if (alpha_target & AXP_OPCODE_BWX)
3469 emit_ir_load (tok, ntok, ldXu_op[(long) vlgsize]);
3470 else
3472 expressionS newtok[3];
3473 struct alpha_insn insn;
3474 int basereg;
3475 long lituse;
3477 if (alpha_noat_on)
3478 as_bad (_("macro requires $at register while noat in effect"));
3480 if (ntok == 2)
3481 basereg = (tok[1].X_op == O_constant
3482 ? AXP_REG_ZERO : alpha_gp_register);
3483 else
3484 basereg = tok[2].X_add_number;
3486 /* emit "lda $at, exp" */
3488 lituse = load_expression (AXP_REG_AT, &tok[1], &basereg, NULL);
3490 /* emit "ldq_u targ, 0($at)" */
3492 newtok[0] = tok[0];
3493 set_tok_const (newtok[1], 0);
3494 set_tok_preg (newtok[2], basereg);
3495 assemble_tokens_to_insn ("ldq_u", newtok, 3, &insn);
3497 if (lituse)
3499 assert (insn.nfixups < MAX_INSN_FIXUPS);
3500 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
3501 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3502 insn.nfixups++;
3503 insn.sequence = lituse;
3506 emit_insn (&insn);
3508 /* emit "extXl targ, $at, targ" */
3510 set_tok_reg (newtok[1], basereg);
3511 newtok[2] = newtok[0];
3512 assemble_tokens_to_insn (extXl_op[(long) vlgsize], newtok, 3, &insn);
3514 if (lituse)
3516 assert (insn.nfixups < MAX_INSN_FIXUPS);
3517 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF;
3518 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3519 insn.nfixups++;
3520 insn.sequence = lituse;
3523 emit_insn (&insn);
3527 /* Load a half-word or byte as a signed value. */
3529 static void
3530 emit_ldX (tok, ntok, vlgsize)
3531 const expressionS *tok;
3532 int ntok;
3533 const PTR vlgsize;
3535 emit_ldXu (tok, ntok, vlgsize);
3536 assemble_tokens (sextX_op[(long) vlgsize], tok, 1, 1);
3539 /* Load an integral value from an unaligned address as an unsigned
3540 value. */
3542 static void
3543 emit_uldXu (tok, ntok, vlgsize)
3544 const expressionS *tok;
3545 int ntok;
3546 const PTR vlgsize;
3548 long lgsize = (long) vlgsize;
3549 expressionS newtok[3];
3551 if (alpha_noat_on)
3552 as_bad (_("macro requires $at register while noat in effect"));
3554 /* emit "lda $at, exp" */
3556 memcpy (newtok, tok, sizeof (expressionS) * ntok);
3557 newtok[0].X_add_number = AXP_REG_AT;
3558 assemble_tokens ("lda", newtok, ntok, 1);
3560 /* emit "ldq_u $t9, 0($at)" */
3562 set_tok_reg (newtok[0], AXP_REG_T9);
3563 set_tok_const (newtok[1], 0);
3564 set_tok_preg (newtok[2], AXP_REG_AT);
3565 assemble_tokens ("ldq_u", newtok, 3, 1);
3567 /* emit "ldq_u $t10, size-1($at)" */
3569 set_tok_reg (newtok[0], AXP_REG_T10);
3570 set_tok_const (newtok[1], (1 << lgsize) - 1);
3571 assemble_tokens ("ldq_u", newtok, 3, 1);
3573 /* emit "extXl $t9, $at, $t9" */
3575 set_tok_reg (newtok[0], AXP_REG_T9);
3576 set_tok_reg (newtok[1], AXP_REG_AT);
3577 set_tok_reg (newtok[2], AXP_REG_T9);
3578 assemble_tokens (extXl_op[lgsize], newtok, 3, 1);
3580 /* emit "extXh $t10, $at, $t10" */
3582 set_tok_reg (newtok[0], AXP_REG_T10);
3583 set_tok_reg (newtok[2], AXP_REG_T10);
3584 assemble_tokens (extXh_op[lgsize], newtok, 3, 1);
3586 /* emit "or $t9, $t10, targ" */
3588 set_tok_reg (newtok[0], AXP_REG_T9);
3589 set_tok_reg (newtok[1], AXP_REG_T10);
3590 newtok[2] = tok[0];
3591 assemble_tokens ("or", newtok, 3, 1);
3594 /* Load an integral value from an unaligned address as a signed value.
3595 Note that quads should get funneled to the unsigned load since we
3596 don't have to do the sign extension. */
3598 static void
3599 emit_uldX (tok, ntok, vlgsize)
3600 const expressionS *tok;
3601 int ntok;
3602 const PTR vlgsize;
3604 emit_uldXu (tok, ntok, vlgsize);
3605 assemble_tokens (sextX_op[(long) vlgsize], tok, 1, 1);
3608 /* Implement the ldil macro. */
3610 static void
3611 emit_ldil (tok, ntok, unused)
3612 const expressionS *tok;
3613 int ntok;
3614 const PTR unused ATTRIBUTE_UNUSED;
3616 expressionS newtok[2];
3618 memcpy (newtok, tok, sizeof (newtok));
3619 newtok[1].X_add_number = sign_extend_32 (tok[1].X_add_number);
3621 assemble_tokens ("lda", newtok, ntok, 1);
3624 /* Store a half-word or byte. */
3626 static void
3627 emit_stX (tok, ntok, vlgsize)
3628 const expressionS *tok;
3629 int ntok;
3630 const PTR vlgsize;
3632 int lgsize = (int) (long) vlgsize;
3634 if (alpha_target & AXP_OPCODE_BWX)
3635 emit_loadstore (tok, ntok, stX_op[lgsize]);
3636 else
3638 expressionS newtok[3];
3639 struct alpha_insn insn;
3640 int basereg;
3641 long lituse;
3643 if (alpha_noat_on)
3644 as_bad (_("macro requires $at register while noat in effect"));
3646 if (ntok == 2)
3647 basereg = (tok[1].X_op == O_constant
3648 ? AXP_REG_ZERO : alpha_gp_register);
3649 else
3650 basereg = tok[2].X_add_number;
3652 /* emit "lda $at, exp" */
3654 lituse = load_expression (AXP_REG_AT, &tok[1], &basereg, NULL);
3656 /* emit "ldq_u $t9, 0($at)" */
3658 set_tok_reg (newtok[0], AXP_REG_T9);
3659 set_tok_const (newtok[1], 0);
3660 set_tok_preg (newtok[2], basereg);
3661 assemble_tokens_to_insn ("ldq_u", newtok, 3, &insn);
3663 if (lituse)
3665 assert (insn.nfixups < MAX_INSN_FIXUPS);
3666 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
3667 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3668 insn.nfixups++;
3669 insn.sequence = lituse;
3672 emit_insn (&insn);
3674 /* emit "insXl src, $at, $t10" */
3676 newtok[0] = tok[0];
3677 set_tok_reg (newtok[1], basereg);
3678 set_tok_reg (newtok[2], AXP_REG_T10);
3679 assemble_tokens_to_insn (insXl_op[lgsize], newtok, 3, &insn);
3681 if (lituse)
3683 assert (insn.nfixups < MAX_INSN_FIXUPS);
3684 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF;
3685 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3686 insn.nfixups++;
3687 insn.sequence = lituse;
3690 emit_insn (&insn);
3692 /* emit "mskXl $t9, $at, $t9" */
3694 set_tok_reg (newtok[0], AXP_REG_T9);
3695 newtok[2] = newtok[0];
3696 assemble_tokens_to_insn (mskXl_op[lgsize], newtok, 3, &insn);
3698 if (lituse)
3700 assert (insn.nfixups < MAX_INSN_FIXUPS);
3701 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF;
3702 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3703 insn.nfixups++;
3704 insn.sequence = lituse;
3707 emit_insn (&insn);
3709 /* emit "or $t9, $t10, $t9" */
3711 set_tok_reg (newtok[1], AXP_REG_T10);
3712 assemble_tokens ("or", newtok, 3, 1);
3714 /* emit "stq_u $t9, 0($at) */
3716 set_tok_const(newtok[1], 0);
3717 set_tok_preg (newtok[2], AXP_REG_AT);
3718 assemble_tokens_to_insn ("stq_u", newtok, 3, &insn);
3720 if (lituse)
3722 assert (insn.nfixups < MAX_INSN_FIXUPS);
3723 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
3724 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3725 insn.nfixups++;
3726 insn.sequence = lituse;
3729 emit_insn (&insn);
3733 /* Store an integer to an unaligned address. */
3735 static void
3736 emit_ustX (tok, ntok, vlgsize)
3737 const expressionS *tok;
3738 int ntok;
3739 const PTR vlgsize;
3741 int lgsize = (int) (long) vlgsize;
3742 expressionS newtok[3];
3744 /* emit "lda $at, exp" */
3746 memcpy (newtok, tok, sizeof (expressionS) * ntok);
3747 newtok[0].X_add_number = AXP_REG_AT;
3748 assemble_tokens ("lda", newtok, ntok, 1);
3750 /* emit "ldq_u $9, 0($at)" */
3752 set_tok_reg (newtok[0], AXP_REG_T9);
3753 set_tok_const (newtok[1], 0);
3754 set_tok_preg (newtok[2], AXP_REG_AT);
3755 assemble_tokens ("ldq_u", newtok, 3, 1);
3757 /* emit "ldq_u $10, size-1($at)" */
3759 set_tok_reg (newtok[0], AXP_REG_T10);
3760 set_tok_const (newtok[1], (1 << lgsize) - 1);
3761 assemble_tokens ("ldq_u", newtok, 3, 1);
3763 /* emit "insXl src, $at, $t11" */
3765 newtok[0] = tok[0];
3766 set_tok_reg (newtok[1], AXP_REG_AT);
3767 set_tok_reg (newtok[2], AXP_REG_T11);
3768 assemble_tokens (insXl_op[lgsize], newtok, 3, 1);
3770 /* emit "insXh src, $at, $t12" */
3772 set_tok_reg (newtok[2], AXP_REG_T12);
3773 assemble_tokens (insXh_op[lgsize], newtok, 3, 1);
3775 /* emit "mskXl $t9, $at, $t9" */
3777 set_tok_reg (newtok[0], AXP_REG_T9);
3778 newtok[2] = newtok[0];
3779 assemble_tokens (mskXl_op[lgsize], newtok, 3, 1);
3781 /* emit "mskXh $t10, $at, $t10" */
3783 set_tok_reg (newtok[0], AXP_REG_T10);
3784 newtok[2] = newtok[0];
3785 assemble_tokens (mskXh_op[lgsize], newtok, 3, 1);
3787 /* emit "or $t9, $t11, $t9" */
3789 set_tok_reg (newtok[0], AXP_REG_T9);
3790 set_tok_reg (newtok[1], AXP_REG_T11);
3791 newtok[2] = newtok[0];
3792 assemble_tokens ("or", newtok, 3, 1);
3794 /* emit "or $t10, $t12, $t10" */
3796 set_tok_reg (newtok[0], AXP_REG_T10);
3797 set_tok_reg (newtok[1], AXP_REG_T12);
3798 newtok[2] = newtok[0];
3799 assemble_tokens ("or", newtok, 3, 1);
3801 /* emit "stq_u $t9, 0($at)" */
3803 set_tok_reg (newtok[0], AXP_REG_T9);
3804 set_tok_const (newtok[1], 0);
3805 set_tok_preg (newtok[2], AXP_REG_AT);
3806 assemble_tokens ("stq_u", newtok, 3, 1);
3808 /* emit "stq_u $t10, size-1($at)" */
3810 set_tok_reg (newtok[0], AXP_REG_T10);
3811 set_tok_const (newtok[1], (1 << lgsize) - 1);
3812 assemble_tokens ("stq_u", newtok, 3, 1);
3815 /* Sign extend a half-word or byte. The 32-bit sign extend is
3816 implemented as "addl $31, $r, $t" in the opcode table. */
3818 static void
3819 emit_sextX (tok, ntok, vlgsize)
3820 const expressionS *tok;
3821 int ntok;
3822 const PTR vlgsize;
3824 long lgsize = (long) vlgsize;
3826 if (alpha_target & AXP_OPCODE_BWX)
3827 assemble_tokens (sextX_op[lgsize], tok, ntok, 0);
3828 else
3830 int bitshift = 64 - 8 * (1 << lgsize);
3831 expressionS newtok[3];
3833 /* emit "sll src,bits,dst" */
3835 newtok[0] = tok[0];
3836 set_tok_const (newtok[1], bitshift);
3837 newtok[2] = tok[ntok - 1];
3838 assemble_tokens ("sll", newtok, 3, 1);
3840 /* emit "sra dst,bits,dst" */
3842 newtok[0] = newtok[2];
3843 assemble_tokens ("sra", newtok, 3, 1);
3847 /* Implement the division and modulus macros. */
3849 #ifdef OBJ_EVAX
3851 /* Make register usage like in normal procedure call.
3852 Don't clobber PV and RA. */
3854 static void
3855 emit_division (tok, ntok, symname)
3856 const expressionS *tok;
3857 int ntok;
3858 const PTR symname;
3860 /* DIVISION and MODULUS. Yech.
3862 Convert
3863 OP x,y,result
3865 mov x,R16 # if x != R16
3866 mov y,R17 # if y != R17
3867 lda AT,__OP
3868 jsr AT,(AT),0
3869 mov R0,result
3871 with appropriate optimizations if R0,R16,R17 are the registers
3872 specified by the compiler. */
3874 int xr, yr, rr;
3875 symbolS *sym;
3876 expressionS newtok[3];
3878 xr = regno (tok[0].X_add_number);
3879 yr = regno (tok[1].X_add_number);
3881 if (ntok < 3)
3882 rr = xr;
3883 else
3884 rr = regno (tok[2].X_add_number);
3886 /* Move the operands into the right place. */
3887 if (yr == AXP_REG_R16 && xr == AXP_REG_R17)
3889 /* They are in exactly the wrong order -- swap through AT. */
3891 if (alpha_noat_on)
3892 as_bad (_("macro requires $at register while noat in effect"));
3894 set_tok_reg (newtok[0], AXP_REG_R16);
3895 set_tok_reg (newtok[1], AXP_REG_AT);
3896 assemble_tokens ("mov", newtok, 2, 1);
3898 set_tok_reg (newtok[0], AXP_REG_R17);
3899 set_tok_reg (newtok[1], AXP_REG_R16);
3900 assemble_tokens ("mov", newtok, 2, 1);
3902 set_tok_reg (newtok[0], AXP_REG_AT);
3903 set_tok_reg (newtok[1], AXP_REG_R17);
3904 assemble_tokens ("mov", newtok, 2, 1);
3906 else
3908 if (yr == AXP_REG_R16)
3910 set_tok_reg (newtok[0], AXP_REG_R16);
3911 set_tok_reg (newtok[1], AXP_REG_R17);
3912 assemble_tokens ("mov", newtok, 2, 1);
3915 if (xr != AXP_REG_R16)
3917 set_tok_reg (newtok[0], xr);
3918 set_tok_reg (newtok[1], AXP_REG_R16);
3919 assemble_tokens ("mov", newtok, 2, 1);
3922 if (yr != AXP_REG_R16 && yr != AXP_REG_R17)
3924 set_tok_reg (newtok[0], yr);
3925 set_tok_reg (newtok[1], AXP_REG_R17);
3926 assemble_tokens ("mov", newtok, 2, 1);
3930 sym = symbol_find_or_make ((const char *) symname);
3932 set_tok_reg (newtok[0], AXP_REG_AT);
3933 set_tok_sym (newtok[1], sym, 0);
3934 assemble_tokens ("lda", newtok, 2, 1);
3936 /* Call the division routine. */
3937 set_tok_reg (newtok[0], AXP_REG_AT);
3938 set_tok_cpreg (newtok[1], AXP_REG_AT);
3939 set_tok_const (newtok[2], 0);
3940 assemble_tokens ("jsr", newtok, 3, 1);
3942 /* Move the result to the right place. */
3943 if (rr != AXP_REG_R0)
3945 set_tok_reg (newtok[0], AXP_REG_R0);
3946 set_tok_reg (newtok[1], rr);
3947 assemble_tokens ("mov", newtok, 2, 1);
3951 #else /* !OBJ_EVAX */
3953 static void
3954 emit_division (tok, ntok, symname)
3955 const expressionS *tok;
3956 int ntok;
3957 const PTR symname;
3959 /* DIVISION and MODULUS. Yech.
3960 Convert
3961 OP x,y,result
3963 lda pv,__OP
3964 mov x,t10
3965 mov y,t11
3966 jsr t9,(pv),__OP
3967 mov t12,result
3969 with appropriate optimizations if t10,t11,t12 are the registers
3970 specified by the compiler. */
3972 int xr, yr, rr;
3973 symbolS *sym;
3974 expressionS newtok[3];
3976 xr = regno (tok[0].X_add_number);
3977 yr = regno (tok[1].X_add_number);
3979 if (ntok < 3)
3980 rr = xr;
3981 else
3982 rr = regno (tok[2].X_add_number);
3984 sym = symbol_find_or_make ((const char *) symname);
3986 /* Move the operands into the right place. */
3987 if (yr == AXP_REG_T10 && xr == AXP_REG_T11)
3989 /* They are in exactly the wrong order -- swap through AT. */
3990 if (alpha_noat_on)
3991 as_bad (_("macro requires $at register while noat in effect"));
3993 set_tok_reg (newtok[0], AXP_REG_T10);
3994 set_tok_reg (newtok[1], AXP_REG_AT);
3995 assemble_tokens ("mov", newtok, 2, 1);
3997 set_tok_reg (newtok[0], AXP_REG_T11);
3998 set_tok_reg (newtok[1], AXP_REG_T10);
3999 assemble_tokens ("mov", newtok, 2, 1);
4001 set_tok_reg (newtok[0], AXP_REG_AT);
4002 set_tok_reg (newtok[1], AXP_REG_T11);
4003 assemble_tokens ("mov", newtok, 2, 1);
4005 else
4007 if (yr == AXP_REG_T10)
4009 set_tok_reg (newtok[0], AXP_REG_T10);
4010 set_tok_reg (newtok[1], AXP_REG_T11);
4011 assemble_tokens ("mov", newtok, 2, 1);
4014 if (xr != AXP_REG_T10)
4016 set_tok_reg (newtok[0], xr);
4017 set_tok_reg (newtok[1], AXP_REG_T10);
4018 assemble_tokens ("mov", newtok, 2, 1);
4021 if (yr != AXP_REG_T10 && yr != AXP_REG_T11)
4023 set_tok_reg (newtok[0], yr);
4024 set_tok_reg (newtok[1], AXP_REG_T11);
4025 assemble_tokens ("mov", newtok, 2, 1);
4029 /* Call the division routine. */
4030 set_tok_reg (newtok[0], AXP_REG_T9);
4031 set_tok_sym (newtok[1], sym, 0);
4032 assemble_tokens ("jsr", newtok, 2, 1);
4034 /* Reload the GP register. */
4035 #ifdef OBJ_AOUT
4036 FIXME
4037 #endif
4038 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
4039 set_tok_reg (newtok[0], alpha_gp_register);
4040 set_tok_const (newtok[1], 0);
4041 set_tok_preg (newtok[2], AXP_REG_T9);
4042 assemble_tokens ("ldgp", newtok, 3, 1);
4043 #endif
4045 /* Move the result to the right place. */
4046 if (rr != AXP_REG_T12)
4048 set_tok_reg (newtok[0], AXP_REG_T12);
4049 set_tok_reg (newtok[1], rr);
4050 assemble_tokens ("mov", newtok, 2, 1);
4054 #endif /* !OBJ_EVAX */
4056 /* The jsr and jmp macros differ from their instruction counterparts
4057 in that they can load the target address and default most
4058 everything. */
4060 static void
4061 emit_jsrjmp (tok, ntok, vopname)
4062 const expressionS *tok;
4063 int ntok;
4064 const PTR vopname;
4066 const char *opname = (const char *) vopname;
4067 struct alpha_insn insn;
4068 expressionS newtok[3];
4069 int r, tokidx = 0;
4070 long lituse = 0;
4072 if (tokidx < ntok && tok[tokidx].X_op == O_register)
4073 r = regno (tok[tokidx++].X_add_number);
4074 else
4075 r = strcmp (opname, "jmp") == 0 ? AXP_REG_ZERO : AXP_REG_RA;
4077 set_tok_reg (newtok[0], r);
4079 if (tokidx < ntok &&
4080 (tok[tokidx].X_op == O_pregister || tok[tokidx].X_op == O_cpregister))
4081 r = regno (tok[tokidx++].X_add_number);
4082 #ifdef OBJ_EVAX
4083 /* keep register if jsr $n.<sym> */
4084 #else
4085 else
4087 int basereg = alpha_gp_register;
4088 lituse = load_expression (r = AXP_REG_PV, &tok[tokidx], &basereg, NULL);
4090 #endif
4092 set_tok_cpreg (newtok[1], r);
4094 #ifdef OBJ_EVAX
4095 /* FIXME: Add hint relocs to BFD for evax. */
4096 #else
4097 if (tokidx < ntok)
4098 newtok[2] = tok[tokidx];
4099 else
4100 #endif
4101 set_tok_const (newtok[2], 0);
4103 assemble_tokens_to_insn (opname, newtok, 3, &insn);
4105 if (lituse)
4107 assert (insn.nfixups < MAX_INSN_FIXUPS);
4108 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_JSR;
4109 insn.fixups[insn.nfixups].exp.X_op = O_absent;
4110 insn.nfixups++;
4111 insn.sequence = lituse;
4114 emit_insn (&insn);
4117 /* The ret and jcr instructions differ from their instruction
4118 counterparts in that everything can be defaulted. */
4120 static void
4121 emit_retjcr (tok, ntok, vopname)
4122 const expressionS *tok;
4123 int ntok;
4124 const PTR vopname;
4126 const char *opname = (const char *) vopname;
4127 expressionS newtok[3];
4128 int r, tokidx = 0;
4130 if (tokidx < ntok && tok[tokidx].X_op == O_register)
4131 r = regno (tok[tokidx++].X_add_number);
4132 else
4133 r = AXP_REG_ZERO;
4135 set_tok_reg (newtok[0], r);
4137 if (tokidx < ntok &&
4138 (tok[tokidx].X_op == O_pregister || tok[tokidx].X_op == O_cpregister))
4139 r = regno (tok[tokidx++].X_add_number);
4140 else
4141 r = AXP_REG_RA;
4143 set_tok_cpreg (newtok[1], r);
4145 if (tokidx < ntok)
4146 newtok[2] = tok[tokidx];
4147 else
4148 set_tok_const (newtok[2], strcmp (opname, "ret") == 0);
4150 assemble_tokens (opname, newtok, 3, 0);
4153 /* Assembler directives. */
4155 /* Handle the .text pseudo-op. This is like the usual one, but it
4156 clears alpha_insn_label and restores auto alignment. */
4158 static void
4159 s_alpha_text (i)
4160 int i;
4163 #ifdef OBJ_ELF
4164 obj_elf_text (i);
4165 #else
4166 s_text (i);
4167 #endif
4168 alpha_insn_label = NULL;
4169 alpha_auto_align_on = 1;
4170 alpha_current_align = 0;
4173 /* Handle the .data pseudo-op. This is like the usual one, but it
4174 clears alpha_insn_label and restores auto alignment. */
4176 static void
4177 s_alpha_data (i)
4178 int i;
4180 #ifdef OBJ_ELF
4181 obj_elf_data (i);
4182 #else
4183 s_data (i);
4184 #endif
4185 alpha_insn_label = NULL;
4186 alpha_auto_align_on = 1;
4187 alpha_current_align = 0;
4190 #if defined (OBJ_ECOFF) || defined (OBJ_EVAX)
4192 /* Handle the OSF/1 and openVMS .comm pseudo quirks.
4193 openVMS constructs a section for every common symbol. */
4195 static void
4196 s_alpha_comm (ignore)
4197 int ignore ATTRIBUTE_UNUSED;
4199 register char *name;
4200 register char c;
4201 register char *p;
4202 offsetT temp;
4203 register symbolS *symbolP;
4205 #ifdef OBJ_EVAX
4206 segT current_section = now_seg;
4207 int current_subsec = now_subseg;
4208 segT new_seg;
4209 #endif
4211 name = input_line_pointer;
4212 c = get_symbol_end ();
4214 /* just after name is now '\0' */
4215 p = input_line_pointer;
4216 *p = c;
4218 SKIP_WHITESPACE ();
4220 /* Alpha OSF/1 compiler doesn't provide the comma, gcc does. */
4221 if (*input_line_pointer == ',')
4223 input_line_pointer++;
4224 SKIP_WHITESPACE ();
4226 if ((temp = get_absolute_expression ()) < 0)
4228 as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) temp);
4229 ignore_rest_of_line ();
4230 return;
4233 *p = 0;
4234 symbolP = symbol_find_or_make (name);
4236 #ifdef OBJ_EVAX
4237 /* Make a section for the common symbol. */
4238 new_seg = subseg_new (xstrdup (name), 0);
4239 #endif
4241 *p = c;
4243 #ifdef OBJ_EVAX
4244 /* alignment might follow */
4245 if (*input_line_pointer == ',')
4247 offsetT align;
4249 input_line_pointer++;
4250 align = get_absolute_expression ();
4251 bfd_set_section_alignment (stdoutput, new_seg, align);
4253 #endif
4255 if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
4257 as_bad (_("Ignoring attempt to re-define symbol"));
4258 ignore_rest_of_line ();
4259 return;
4262 #ifdef OBJ_EVAX
4263 if (bfd_section_size (stdoutput, new_seg) > 0)
4265 if (bfd_section_size (stdoutput, new_seg) != temp)
4266 as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
4267 S_GET_NAME (symbolP),
4268 (long) bfd_section_size (stdoutput, new_seg),
4269 (long) temp);
4271 #else
4272 if (S_GET_VALUE (symbolP))
4274 if (S_GET_VALUE (symbolP) != (valueT) temp)
4275 as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
4276 S_GET_NAME (symbolP),
4277 (long) S_GET_VALUE (symbolP),
4278 (long) temp);
4280 #endif
4281 else
4283 #ifdef OBJ_EVAX
4284 subseg_set (new_seg, 0);
4285 p = frag_more (temp);
4286 new_seg->flags |= SEC_IS_COMMON;
4287 if (! S_IS_DEFINED (symbolP))
4288 S_SET_SEGMENT (symbolP, new_seg);
4289 #else
4290 S_SET_VALUE (symbolP, (valueT) temp);
4291 #endif
4292 S_SET_EXTERNAL (symbolP);
4295 #ifdef OBJ_EVAX
4296 subseg_set (current_section, current_subsec);
4297 #endif
4299 know (symbol_get_frag (symbolP) == &zero_address_frag);
4301 demand_empty_rest_of_line ();
4304 #endif /* ! OBJ_ELF */
4306 #ifdef OBJ_ECOFF
4308 /* Handle the .rdata pseudo-op. This is like the usual one, but it
4309 clears alpha_insn_label and restores auto alignment. */
4311 static void
4312 s_alpha_rdata (ignore)
4313 int ignore ATTRIBUTE_UNUSED;
4315 int temp;
4317 temp = get_absolute_expression ();
4318 subseg_new (".rdata", 0);
4319 demand_empty_rest_of_line ();
4320 alpha_insn_label = NULL;
4321 alpha_auto_align_on = 1;
4322 alpha_current_align = 0;
4325 #endif
4327 #ifdef OBJ_ECOFF
4329 /* Handle the .sdata pseudo-op. This is like the usual one, but it
4330 clears alpha_insn_label and restores auto alignment. */
4332 static void
4333 s_alpha_sdata (ignore)
4334 int ignore ATTRIBUTE_UNUSED;
4336 int temp;
4338 temp = get_absolute_expression ();
4339 subseg_new (".sdata", 0);
4340 demand_empty_rest_of_line ();
4341 alpha_insn_label = NULL;
4342 alpha_auto_align_on = 1;
4343 alpha_current_align = 0;
4345 #endif
4347 #ifdef OBJ_ELF
4348 struct alpha_elf_frame_data
4350 symbolS *func_sym;
4351 symbolS *func_end_sym;
4352 symbolS *prologue_sym;
4353 unsigned int mask;
4354 unsigned int fmask;
4355 int fp_regno;
4356 int ra_regno;
4357 offsetT frame_size;
4358 offsetT mask_offset;
4359 offsetT fmask_offset;
4361 struct alpha_elf_frame_data *next;
4364 static struct alpha_elf_frame_data *all_frame_data;
4365 static struct alpha_elf_frame_data **plast_frame_data = &all_frame_data;
4366 static struct alpha_elf_frame_data *cur_frame_data;
4368 /* Handle the .section pseudo-op. This is like the usual one, but it
4369 clears alpha_insn_label and restores auto alignment. */
4371 static void
4372 s_alpha_section (ignore)
4373 int ignore ATTRIBUTE_UNUSED;
4375 obj_elf_section (ignore);
4377 alpha_insn_label = NULL;
4378 alpha_auto_align_on = 1;
4379 alpha_current_align = 0;
4382 static void
4383 s_alpha_ent (dummy)
4384 int dummy ATTRIBUTE_UNUSED;
4386 if (ECOFF_DEBUGGING)
4387 ecoff_directive_ent (0);
4388 else
4390 char *name, name_end;
4391 name = input_line_pointer;
4392 name_end = get_symbol_end ();
4394 if (! is_name_beginner (*name))
4396 as_warn (_(".ent directive has no name"));
4397 *input_line_pointer = name_end;
4399 else
4401 symbolS *sym;
4403 if (cur_frame_data)
4404 as_warn (_("nested .ent directives"));
4406 sym = symbol_find_or_make (name);
4407 symbol_get_bfdsym (sym)->flags |= BSF_FUNCTION;
4409 cur_frame_data = calloc (1, sizeof (*cur_frame_data));
4410 cur_frame_data->func_sym = sym;
4412 /* Provide sensible defaults. */
4413 cur_frame_data->fp_regno = 30; /* sp */
4414 cur_frame_data->ra_regno = 26; /* ra */
4416 *plast_frame_data = cur_frame_data;
4417 plast_frame_data = &cur_frame_data->next;
4419 /* The .ent directive is sometimes followed by a number. Not sure
4420 what it really means, but ignore it. */
4421 *input_line_pointer = name_end;
4422 SKIP_WHITESPACE ();
4423 if (*input_line_pointer == ',')
4425 input_line_pointer++;
4426 SKIP_WHITESPACE ();
4428 if (ISDIGIT (*input_line_pointer) || *input_line_pointer == '-')
4429 (void) get_absolute_expression ();
4431 demand_empty_rest_of_line ();
4435 static void
4436 s_alpha_end (dummy)
4437 int dummy ATTRIBUTE_UNUSED;
4439 if (ECOFF_DEBUGGING)
4440 ecoff_directive_end (0);
4441 else
4443 char *name, name_end;
4444 name = input_line_pointer;
4445 name_end = get_symbol_end ();
4447 if (! is_name_beginner (*name))
4449 as_warn (_(".end directive has no name"));
4450 *input_line_pointer = name_end;
4452 else
4454 symbolS *sym;
4456 sym = symbol_find (name);
4457 if (!cur_frame_data)
4458 as_warn (_(".end directive without matching .ent"));
4459 else if (sym != cur_frame_data->func_sym)
4460 as_warn (_(".end directive names different symbol than .ent"));
4462 /* Create an expression to calculate the size of the function. */
4463 if (sym && cur_frame_data)
4465 OBJ_SYMFIELD_TYPE *obj = symbol_get_obj (sym);
4466 expressionS *exp = xmalloc (sizeof (expressionS));
4468 obj->size = exp;
4469 exp->X_op = O_subtract;
4470 exp->X_add_symbol = symbol_temp_new_now ();
4471 exp->X_op_symbol = sym;
4472 exp->X_add_number = 0;
4474 cur_frame_data->func_end_sym = exp->X_add_symbol;
4477 cur_frame_data = NULL;
4479 *input_line_pointer = name_end;
4481 demand_empty_rest_of_line ();
4485 static void
4486 s_alpha_mask (fp)
4487 int fp;
4489 if (ECOFF_DEBUGGING)
4491 if (fp)
4492 ecoff_directive_fmask (0);
4493 else
4494 ecoff_directive_mask (0);
4496 else
4498 long val;
4499 offsetT offset;
4501 if (!cur_frame_data)
4503 if (fp)
4504 as_warn (_(".fmask outside of .ent"));
4505 else
4506 as_warn (_(".mask outside of .ent"));
4507 discard_rest_of_line ();
4508 return;
4511 if (get_absolute_expression_and_terminator (&val) != ',')
4513 if (fp)
4514 as_warn (_("bad .fmask directive"));
4515 else
4516 as_warn (_("bad .mask directive"));
4517 --input_line_pointer;
4518 discard_rest_of_line ();
4519 return;
4522 offset = get_absolute_expression ();
4523 demand_empty_rest_of_line ();
4525 if (fp)
4527 cur_frame_data->fmask = val;
4528 cur_frame_data->fmask_offset = offset;
4530 else
4532 cur_frame_data->mask = val;
4533 cur_frame_data->mask_offset = offset;
4538 static void
4539 s_alpha_frame (dummy)
4540 int dummy ATTRIBUTE_UNUSED;
4542 if (ECOFF_DEBUGGING)
4543 ecoff_directive_frame (0);
4544 else
4546 long val;
4548 if (!cur_frame_data)
4550 as_warn (_(".frame outside of .ent"));
4551 discard_rest_of_line ();
4552 return;
4555 cur_frame_data->fp_regno = tc_get_register (1);
4557 SKIP_WHITESPACE ();
4558 if (*input_line_pointer++ != ','
4559 || get_absolute_expression_and_terminator (&val) != ',')
4561 as_warn (_("bad .frame directive"));
4562 --input_line_pointer;
4563 discard_rest_of_line ();
4564 return;
4566 cur_frame_data->frame_size = val;
4568 cur_frame_data->ra_regno = tc_get_register (0);
4570 /* Next comes the "offset of saved $a0 from $sp". In gcc terms
4571 this is current_function_pretend_args_size. There's no place
4572 to put this value, so ignore it. */
4573 s_ignore (42);
4577 static void
4578 s_alpha_prologue (ignore)
4579 int ignore ATTRIBUTE_UNUSED;
4581 symbolS *sym;
4582 int arg;
4584 arg = get_absolute_expression ();
4585 demand_empty_rest_of_line ();
4587 if (ECOFF_DEBUGGING)
4588 sym = ecoff_get_cur_proc_sym ();
4589 else
4590 sym = cur_frame_data ? cur_frame_data->func_sym : NULL;
4592 if (sym == NULL)
4594 as_bad (_(".prologue directive without a preceding .ent directive"));
4595 return;
4598 switch (arg)
4600 case 0: /* No PV required. */
4601 S_SET_OTHER (sym, STO_ALPHA_NOPV
4602 | (S_GET_OTHER (sym) & ~STO_ALPHA_STD_GPLOAD));
4603 break;
4604 case 1: /* Std GP load. */
4605 S_SET_OTHER (sym, STO_ALPHA_STD_GPLOAD
4606 | (S_GET_OTHER (sym) & ~STO_ALPHA_STD_GPLOAD));
4607 break;
4608 case 2: /* Non-std use of PV. */
4609 break;
4611 default:
4612 as_bad (_("Invalid argument %d to .prologue."), arg);
4613 break;
4616 if (cur_frame_data)
4617 cur_frame_data->prologue_sym = symbol_temp_new_now ();
4620 static char *first_file_directive;
4622 static void
4623 s_alpha_file (ignore)
4624 int ignore ATTRIBUTE_UNUSED;
4626 /* Save the first .file directive we see, so that we can change our
4627 minds about whether ecoff debugging should or shouldn't be enabled. */
4628 if (alpha_flag_mdebug < 0 && ! first_file_directive)
4630 char *start = input_line_pointer;
4631 size_t len;
4633 discard_rest_of_line ();
4635 len = input_line_pointer - start;
4636 first_file_directive = xmalloc (len + 1);
4637 memcpy (first_file_directive, start, len);
4638 first_file_directive[len] = '\0';
4640 input_line_pointer = start;
4643 if (ECOFF_DEBUGGING)
4644 ecoff_directive_file (0);
4645 else
4646 dwarf2_directive_file (0);
4649 static void
4650 s_alpha_loc (ignore)
4651 int ignore ATTRIBUTE_UNUSED;
4653 if (ECOFF_DEBUGGING)
4654 ecoff_directive_loc (0);
4655 else
4656 dwarf2_directive_loc (0);
4659 static void
4660 s_alpha_stab (n)
4661 int n;
4663 /* If we've been undecided about mdebug, make up our minds in favour. */
4664 if (alpha_flag_mdebug < 0)
4666 segT sec = subseg_new (".mdebug", 0);
4667 bfd_set_section_flags (stdoutput, sec, SEC_HAS_CONTENTS | SEC_READONLY);
4668 bfd_set_section_alignment (stdoutput, sec, 3);
4670 ecoff_read_begin_hook ();
4672 if (first_file_directive)
4674 char *save_ilp = input_line_pointer;
4675 input_line_pointer = first_file_directive;
4676 ecoff_directive_file (0);
4677 input_line_pointer = save_ilp;
4678 free (first_file_directive);
4681 alpha_flag_mdebug = 1;
4683 s_stab (n);
4686 static void
4687 s_alpha_coff_wrapper (which)
4688 int which;
4690 static void (* const fns[]) PARAMS ((int)) = {
4691 ecoff_directive_begin,
4692 ecoff_directive_bend,
4693 ecoff_directive_def,
4694 ecoff_directive_dim,
4695 ecoff_directive_endef,
4696 ecoff_directive_scl,
4697 ecoff_directive_tag,
4698 ecoff_directive_val,
4701 assert (which >= 0 && which < (int) (sizeof (fns)/sizeof (*fns)));
4703 if (ECOFF_DEBUGGING)
4704 (*fns[which]) (0);
4705 else
4707 as_bad (_("ECOFF debugging is disabled."));
4708 ignore_rest_of_line ();
4712 /* Called at the end of assembly. Here we emit unwind info for frames
4713 unless the compiler has done it for us. */
4715 void
4716 alpha_elf_md_end (void)
4718 struct alpha_elf_frame_data *p;
4720 if (cur_frame_data)
4721 as_warn (_(".ent directive without matching .end"));
4723 /* If someone has generated the unwind info themselves, great. */
4724 if (bfd_get_section_by_name (stdoutput, ".eh_frame") != NULL)
4725 return;
4727 /* Generate .eh_frame data for the unwind directives specified. */
4728 for (p = all_frame_data; p ; p = p->next)
4729 if (p->prologue_sym)
4731 /* Create a temporary symbol at the same location as our
4732 function symbol. This prevents problems with globals. */
4733 cfi_new_fde (symbol_temp_new (S_GET_SEGMENT (p->func_sym),
4734 S_GET_VALUE (p->func_sym),
4735 symbol_get_frag (p->func_sym)));
4737 cfi_set_return_column (p->ra_regno);
4738 cfi_add_CFA_def_cfa_register (30);
4739 if (p->fp_regno != 30 || p->mask || p->fmask || p->frame_size)
4741 unsigned int mask;
4742 offsetT offset;
4744 cfi_add_advance_loc (p->prologue_sym);
4746 if (p->fp_regno != 30)
4747 if (p->frame_size != 0)
4748 cfi_add_CFA_def_cfa (p->fp_regno, p->frame_size);
4749 else
4750 cfi_add_CFA_def_cfa_register (p->fp_regno);
4751 else if (p->frame_size != 0)
4752 cfi_add_CFA_def_cfa_offset (p->frame_size);
4754 mask = p->mask;
4755 offset = p->mask_offset;
4757 /* Recall that $26 is special-cased and stored first. */
4758 if ((mask >> 26) & 1)
4760 cfi_add_CFA_offset (26, offset);
4761 offset += 8;
4762 mask &= ~(1 << 26);
4764 while (mask)
4766 unsigned int i;
4767 i = mask & -mask;
4768 mask ^= i;
4769 i = ffs (i) - 1;
4771 cfi_add_CFA_offset (i, offset);
4772 offset += 8;
4775 mask = p->fmask;
4776 offset = p->fmask_offset;
4777 while (mask)
4779 unsigned int i;
4780 i = mask & -mask;
4781 mask ^= i;
4782 i = ffs (i) - 1;
4784 cfi_add_CFA_offset (i + 32, offset);
4785 offset += 8;
4789 cfi_end_fde (p->func_end_sym);
4793 static void
4794 s_alpha_usepv (int unused ATTRIBUTE_UNUSED)
4796 char *name, name_end;
4797 char *which, which_end;
4798 symbolS *sym;
4799 int other;
4801 name = input_line_pointer;
4802 name_end = get_symbol_end ();
4804 if (! is_name_beginner (*name))
4806 as_bad (_(".usepv directive has no name"));
4807 *input_line_pointer = name_end;
4808 ignore_rest_of_line ();
4809 return;
4812 sym = symbol_find_or_make (name);
4813 *input_line_pointer++ = name_end;
4815 if (name_end != ',')
4817 as_bad (_(".usepv directive has no type"));
4818 ignore_rest_of_line ();
4819 return;
4822 SKIP_WHITESPACE ();
4823 which = input_line_pointer;
4824 which_end = get_symbol_end ();
4826 if (strcmp (which, "no") == 0)
4827 other = STO_ALPHA_NOPV;
4828 else if (strcmp (which, "std") == 0)
4829 other = STO_ALPHA_STD_GPLOAD;
4830 else
4832 as_bad (_("unknown argument for .usepv"));
4833 other = 0;
4836 *input_line_pointer = which_end;
4837 demand_empty_rest_of_line ();
4839 S_SET_OTHER (sym, other | (S_GET_OTHER (sym) & ~STO_ALPHA_STD_GPLOAD));
4841 #endif /* OBJ_ELF */
4843 /* Standard calling conventions leaves the CFA at $30 on entry. */
4845 void
4846 alpha_cfi_frame_initial_instructions ()
4848 cfi_add_CFA_def_cfa_register (30);
4851 #ifdef OBJ_EVAX
4853 /* Handle the section specific pseudo-op. */
4855 static void
4856 s_alpha_section (secid)
4857 int secid;
4859 int temp;
4860 #define EVAX_SECTION_COUNT 5
4861 static char *section_name[EVAX_SECTION_COUNT + 1] =
4862 { "NULL", ".rdata", ".comm", ".link", ".ctors", ".dtors" };
4864 if ((secid <= 0) || (secid > EVAX_SECTION_COUNT))
4866 as_fatal (_("Unknown section directive"));
4867 demand_empty_rest_of_line ();
4868 return;
4870 temp = get_absolute_expression ();
4871 subseg_new (section_name[secid], 0);
4872 demand_empty_rest_of_line ();
4873 alpha_insn_label = NULL;
4874 alpha_auto_align_on = 1;
4875 alpha_current_align = 0;
4878 /* Parse .ent directives. */
4880 static void
4881 s_alpha_ent (ignore)
4882 int ignore ATTRIBUTE_UNUSED;
4884 symbolS *symbol;
4885 expressionS symexpr;
4887 alpha_evax_proc.pdsckind = 0;
4888 alpha_evax_proc.framereg = -1;
4889 alpha_evax_proc.framesize = 0;
4890 alpha_evax_proc.rsa_offset = 0;
4891 alpha_evax_proc.ra_save = AXP_REG_RA;
4892 alpha_evax_proc.fp_save = -1;
4893 alpha_evax_proc.imask = 0;
4894 alpha_evax_proc.fmask = 0;
4895 alpha_evax_proc.prologue = 0;
4896 alpha_evax_proc.type = 0;
4898 expression (&symexpr);
4900 if (symexpr.X_op != O_symbol)
4902 as_fatal (_(".ent directive has no symbol"));
4903 demand_empty_rest_of_line ();
4904 return;
4907 symbol = make_expr_symbol (&symexpr);
4908 symbol_get_bfdsym (symbol)->flags |= BSF_FUNCTION;
4909 alpha_evax_proc.symbol = symbol;
4911 demand_empty_rest_of_line ();
4914 /* Parse .frame <framreg>,<framesize>,RA,<rsa_offset> directives. */
4916 static void
4917 s_alpha_frame (ignore)
4918 int ignore ATTRIBUTE_UNUSED;
4920 long val;
4922 alpha_evax_proc.framereg = tc_get_register (1);
4924 SKIP_WHITESPACE ();
4925 if (*input_line_pointer++ != ','
4926 || get_absolute_expression_and_terminator (&val) != ',')
4928 as_warn (_("Bad .frame directive 1./2. param"));
4929 --input_line_pointer;
4930 demand_empty_rest_of_line ();
4931 return;
4934 alpha_evax_proc.framesize = val;
4936 (void) tc_get_register (1);
4937 SKIP_WHITESPACE ();
4938 if (*input_line_pointer++ != ',')
4940 as_warn (_("Bad .frame directive 3./4. param"));
4941 --input_line_pointer;
4942 demand_empty_rest_of_line ();
4943 return;
4945 alpha_evax_proc.rsa_offset = get_absolute_expression ();
4948 static void
4949 s_alpha_pdesc (ignore)
4950 int ignore ATTRIBUTE_UNUSED;
4952 char *name;
4953 char name_end;
4954 long val;
4955 register char *p;
4956 expressionS exp;
4957 symbolS *entry_sym;
4958 fixS *fixp;
4959 segment_info_type *seginfo = seg_info (alpha_link_section);
4961 if (now_seg != alpha_link_section)
4963 as_bad (_(".pdesc directive not in link (.link) section"));
4964 demand_empty_rest_of_line ();
4965 return;
4968 if ((alpha_evax_proc.symbol == 0)
4969 || (!S_IS_DEFINED (alpha_evax_proc.symbol)))
4971 as_fatal (_(".pdesc has no matching .ent"));
4972 demand_empty_rest_of_line ();
4973 return;
4976 *symbol_get_obj (alpha_evax_proc.symbol) =
4977 (valueT) seginfo->literal_pool_size;
4979 expression (&exp);
4980 if (exp.X_op != O_symbol)
4982 as_warn (_(".pdesc directive has no entry symbol"));
4983 demand_empty_rest_of_line ();
4984 return;
4987 entry_sym = make_expr_symbol (&exp);
4988 /* Save bfd symbol of proc desc in function symbol. */
4989 symbol_get_bfdsym (alpha_evax_proc.symbol)->udata.p
4990 = symbol_get_bfdsym (entry_sym);
4992 SKIP_WHITESPACE ();
4993 if (*input_line_pointer++ != ',')
4995 as_warn (_("No comma after .pdesc <entryname>"));
4996 demand_empty_rest_of_line ();
4997 return;
5000 SKIP_WHITESPACE ();
5001 name = input_line_pointer;
5002 name_end = get_symbol_end ();
5004 if (strncmp (name, "stack", 5) == 0)
5006 alpha_evax_proc.pdsckind = PDSC_S_K_KIND_FP_STACK;
5008 else if (strncmp (name, "reg", 3) == 0)
5010 alpha_evax_proc.pdsckind = PDSC_S_K_KIND_FP_REGISTER;
5012 else if (strncmp (name, "null", 4) == 0)
5014 alpha_evax_proc.pdsckind = PDSC_S_K_KIND_NULL;
5016 else
5018 as_fatal (_("unknown procedure kind"));
5019 demand_empty_rest_of_line ();
5020 return;
5023 *input_line_pointer = name_end;
5024 demand_empty_rest_of_line ();
5026 #ifdef md_flush_pending_output
5027 md_flush_pending_output ();
5028 #endif
5030 frag_align (3, 0, 0);
5031 p = frag_more (16);
5032 fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
5033 fixp->fx_done = 1;
5034 seginfo->literal_pool_size += 16;
5036 *p = alpha_evax_proc.pdsckind
5037 | ((alpha_evax_proc.framereg == 29) ? PDSC_S_M_BASE_REG_IS_FP : 0);
5038 *(p + 1) = PDSC_S_M_NATIVE | PDSC_S_M_NO_JACKET;
5040 switch (alpha_evax_proc.pdsckind)
5042 case PDSC_S_K_KIND_NULL:
5043 *(p + 2) = 0;
5044 *(p + 3) = 0;
5045 break;
5046 case PDSC_S_K_KIND_FP_REGISTER:
5047 *(p + 2) = alpha_evax_proc.fp_save;
5048 *(p + 3) = alpha_evax_proc.ra_save;
5049 break;
5050 case PDSC_S_K_KIND_FP_STACK:
5051 md_number_to_chars (p + 2, (valueT) alpha_evax_proc.rsa_offset, 2);
5052 break;
5053 default: /* impossible */
5054 break;
5057 *(p + 4) = 0;
5058 *(p + 5) = alpha_evax_proc.type & 0x0f;
5060 /* Signature offset. */
5061 md_number_to_chars (p + 6, (valueT) 0, 2);
5063 fix_new_exp (frag_now, p - frag_now->fr_literal+8, 8, &exp, 0, BFD_RELOC_64);
5065 if (alpha_evax_proc.pdsckind == PDSC_S_K_KIND_NULL)
5066 return;
5068 /* Add dummy fix to make add_to_link_pool work. */
5069 p = frag_more (8);
5070 fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
5071 fixp->fx_done = 1;
5072 seginfo->literal_pool_size += 8;
5074 /* pdesc+16: Size. */
5075 md_number_to_chars (p, (valueT) alpha_evax_proc.framesize, 4);
5077 md_number_to_chars (p + 4, (valueT) 0, 2);
5079 /* Entry length. */
5080 md_number_to_chars (p + 6, alpha_evax_proc.prologue, 2);
5082 if (alpha_evax_proc.pdsckind == PDSC_S_K_KIND_FP_REGISTER)
5083 return;
5085 /* Add dummy fix to make add_to_link_pool work. */
5086 p = frag_more (8);
5087 fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
5088 fixp->fx_done = 1;
5089 seginfo->literal_pool_size += 8;
5091 /* pdesc+24: register masks. */
5093 md_number_to_chars (p, alpha_evax_proc.imask, 4);
5094 md_number_to_chars (p + 4, alpha_evax_proc.fmask, 4);
5097 /* Support for crash debug on vms. */
5099 static void
5100 s_alpha_name (ignore)
5101 int ignore ATTRIBUTE_UNUSED;
5103 register char *p;
5104 expressionS exp;
5105 segment_info_type *seginfo = seg_info (alpha_link_section);
5107 if (now_seg != alpha_link_section)
5109 as_bad (_(".name directive not in link (.link) section"));
5110 demand_empty_rest_of_line ();
5111 return;
5114 expression (&exp);
5115 if (exp.X_op != O_symbol)
5117 as_warn (_(".name directive has no symbol"));
5118 demand_empty_rest_of_line ();
5119 return;
5122 demand_empty_rest_of_line ();
5124 #ifdef md_flush_pending_output
5125 md_flush_pending_output ();
5126 #endif
5128 frag_align (3, 0, 0);
5129 p = frag_more (8);
5130 seginfo->literal_pool_size += 8;
5132 fix_new_exp (frag_now, p - frag_now->fr_literal, 8, &exp, 0, BFD_RELOC_64);
5135 static void
5136 s_alpha_linkage (ignore)
5137 int ignore ATTRIBUTE_UNUSED;
5139 expressionS exp;
5140 char *p;
5142 #ifdef md_flush_pending_output
5143 md_flush_pending_output ();
5144 #endif
5146 expression (&exp);
5147 if (exp.X_op != O_symbol)
5149 as_fatal (_("No symbol after .linkage"));
5151 else
5153 p = frag_more (LKP_S_K_SIZE);
5154 memset (p, 0, LKP_S_K_SIZE);
5155 fix_new_exp (frag_now, p - frag_now->fr_literal, LKP_S_K_SIZE, &exp, 0,\
5156 BFD_RELOC_ALPHA_LINKAGE);
5158 demand_empty_rest_of_line ();
5161 static void
5162 s_alpha_code_address (ignore)
5163 int ignore ATTRIBUTE_UNUSED;
5165 expressionS exp;
5166 char *p;
5168 #ifdef md_flush_pending_output
5169 md_flush_pending_output ();
5170 #endif
5172 expression (&exp);
5173 if (exp.X_op != O_symbol)
5175 as_fatal (_("No symbol after .code_address"));
5177 else
5179 p = frag_more (8);
5180 memset (p, 0, 8);
5181 fix_new_exp (frag_now, p - frag_now->fr_literal, 8, &exp, 0,\
5182 BFD_RELOC_ALPHA_CODEADDR);
5184 demand_empty_rest_of_line ();
5187 static void
5188 s_alpha_fp_save (ignore)
5189 int ignore ATTRIBUTE_UNUSED;
5192 alpha_evax_proc.fp_save = tc_get_register (1);
5194 demand_empty_rest_of_line ();
5197 static void
5198 s_alpha_mask (ignore)
5199 int ignore ATTRIBUTE_UNUSED;
5201 long val;
5203 if (get_absolute_expression_and_terminator (&val) != ',')
5205 as_warn (_("Bad .mask directive"));
5206 --input_line_pointer;
5208 else
5210 alpha_evax_proc.imask = val;
5211 (void) get_absolute_expression ();
5213 demand_empty_rest_of_line ();
5216 static void
5217 s_alpha_fmask (ignore)
5218 int ignore ATTRIBUTE_UNUSED;
5220 long val;
5222 if (get_absolute_expression_and_terminator (&val) != ',')
5224 as_warn (_("Bad .fmask directive"));
5225 --input_line_pointer;
5227 else
5229 alpha_evax_proc.fmask = val;
5230 (void) get_absolute_expression ();
5232 demand_empty_rest_of_line ();
5235 static void
5236 s_alpha_end (ignore)
5237 int ignore ATTRIBUTE_UNUSED;
5239 char c;
5241 c = get_symbol_end ();
5242 *input_line_pointer = c;
5243 demand_empty_rest_of_line ();
5244 alpha_evax_proc.symbol = 0;
5247 static void
5248 s_alpha_file (ignore)
5249 int ignore ATTRIBUTE_UNUSED;
5251 symbolS *s;
5252 int length;
5253 static char case_hack[32];
5255 sprintf (case_hack, "<CASE:%01d%01d>",
5256 alpha_flag_hash_long_names, alpha_flag_show_after_trunc);
5258 s = symbol_find_or_make (case_hack);
5259 symbol_get_bfdsym (s)->flags |= BSF_FILE;
5261 get_absolute_expression ();
5262 s = symbol_find_or_make (demand_copy_string (&length));
5263 symbol_get_bfdsym (s)->flags |= BSF_FILE;
5264 demand_empty_rest_of_line ();
5266 #endif /* OBJ_EVAX */
5268 /* Handle the .gprel32 pseudo op. */
5270 static void
5271 s_alpha_gprel32 (ignore)
5272 int ignore ATTRIBUTE_UNUSED;
5274 expressionS e;
5275 char *p;
5277 SKIP_WHITESPACE ();
5278 expression (&e);
5280 #ifdef OBJ_ELF
5281 switch (e.X_op)
5283 case O_constant:
5284 e.X_add_symbol = section_symbol (absolute_section);
5285 e.X_op = O_symbol;
5286 /* FALLTHRU */
5287 case O_symbol:
5288 break;
5289 default:
5290 abort ();
5292 #else
5293 #ifdef OBJ_ECOFF
5294 switch (e.X_op)
5296 case O_constant:
5297 e.X_add_symbol = section_symbol (absolute_section);
5298 /* fall through */
5299 case O_symbol:
5300 e.X_op = O_subtract;
5301 e.X_op_symbol = alpha_gp_symbol;
5302 break;
5303 default:
5304 abort ();
5306 #endif
5307 #endif
5309 if (alpha_auto_align_on && alpha_current_align < 2)
5310 alpha_align (2, (char *) NULL, alpha_insn_label, 0);
5311 if (alpha_current_align > 2)
5312 alpha_current_align = 2;
5313 alpha_insn_label = NULL;
5315 p = frag_more (4);
5316 memset (p, 0, 4);
5317 fix_new_exp (frag_now, p - frag_now->fr_literal, 4,
5318 &e, 0, BFD_RELOC_GPREL32);
5321 /* Handle floating point allocation pseudo-ops. This is like the
5322 generic vresion, but it makes sure the current label, if any, is
5323 correctly aligned. */
5325 static void
5326 s_alpha_float_cons (type)
5327 int type;
5329 int log_size;
5331 switch (type)
5333 default:
5334 case 'f':
5335 case 'F':
5336 log_size = 2;
5337 break;
5339 case 'd':
5340 case 'D':
5341 case 'G':
5342 log_size = 3;
5343 break;
5345 case 'x':
5346 case 'X':
5347 case 'p':
5348 case 'P':
5349 log_size = 4;
5350 break;
5353 if (alpha_auto_align_on && alpha_current_align < log_size)
5354 alpha_align (log_size, (char *) NULL, alpha_insn_label, 0);
5355 if (alpha_current_align > log_size)
5356 alpha_current_align = log_size;
5357 alpha_insn_label = NULL;
5359 float_cons (type);
5362 /* Handle the .proc pseudo op. We don't really do much with it except
5363 parse it. */
5365 static void
5366 s_alpha_proc (is_static)
5367 int is_static ATTRIBUTE_UNUSED;
5369 char *name;
5370 char c;
5371 char *p;
5372 symbolS *symbolP;
5373 int temp;
5375 /* Takes ".proc name,nargs" */
5376 SKIP_WHITESPACE ();
5377 name = input_line_pointer;
5378 c = get_symbol_end ();
5379 p = input_line_pointer;
5380 symbolP = symbol_find_or_make (name);
5381 *p = c;
5382 SKIP_WHITESPACE ();
5383 if (*input_line_pointer != ',')
5385 *p = 0;
5386 as_warn (_("Expected comma after name \"%s\""), name);
5387 *p = c;
5388 temp = 0;
5389 ignore_rest_of_line ();
5391 else
5393 input_line_pointer++;
5394 temp = get_absolute_expression ();
5396 /* *symbol_get_obj (symbolP) = (signed char) temp; */
5397 as_warn (_("unhandled: .proc %s,%d"), name, temp);
5398 demand_empty_rest_of_line ();
5401 /* Handle the .set pseudo op. This is used to turn on and off most of
5402 the assembler features. */
5404 static void
5405 s_alpha_set (x)
5406 int x ATTRIBUTE_UNUSED;
5408 char *name, ch, *s;
5409 int yesno = 1;
5411 SKIP_WHITESPACE ();
5412 name = input_line_pointer;
5413 ch = get_symbol_end ();
5415 s = name;
5416 if (s[0] == 'n' && s[1] == 'o')
5418 yesno = 0;
5419 s += 2;
5421 if (!strcmp ("reorder", s))
5422 /* ignore */ ;
5423 else if (!strcmp ("at", s))
5424 alpha_noat_on = !yesno;
5425 else if (!strcmp ("macro", s))
5426 alpha_macros_on = yesno;
5427 else if (!strcmp ("move", s))
5428 /* ignore */ ;
5429 else if (!strcmp ("volatile", s))
5430 /* ignore */ ;
5431 else
5432 as_warn (_("Tried to .set unrecognized mode `%s'"), name);
5434 *input_line_pointer = ch;
5435 demand_empty_rest_of_line ();
5438 /* Handle the .base pseudo op. This changes the assembler's notion of
5439 the $gp register. */
5441 static void
5442 s_alpha_base (ignore)
5443 int ignore ATTRIBUTE_UNUSED;
5445 SKIP_WHITESPACE ();
5446 if (*input_line_pointer == '$')
5447 { /* $rNN form */
5448 input_line_pointer++;
5449 if (*input_line_pointer == 'r')
5450 input_line_pointer++;
5453 alpha_gp_register = get_absolute_expression ();
5454 if (alpha_gp_register < 0 || alpha_gp_register > 31)
5456 alpha_gp_register = AXP_REG_GP;
5457 as_warn (_("Bad base register, using $%d."), alpha_gp_register);
5460 demand_empty_rest_of_line ();
5463 /* Handle the .align pseudo-op. This aligns to a power of two. It
5464 also adjusts any current instruction label. We treat this the same
5465 way the MIPS port does: .align 0 turns off auto alignment. */
5467 static void
5468 s_alpha_align (ignore)
5469 int ignore ATTRIBUTE_UNUSED;
5471 int align;
5472 char fill, *pfill;
5473 long max_alignment = 15;
5475 align = get_absolute_expression ();
5476 if (align > max_alignment)
5478 align = max_alignment;
5479 as_bad (_("Alignment too large: %d. assumed"), align);
5481 else if (align < 0)
5483 as_warn (_("Alignment negative: 0 assumed"));
5484 align = 0;
5487 if (*input_line_pointer == ',')
5489 input_line_pointer++;
5490 fill = get_absolute_expression ();
5491 pfill = &fill;
5493 else
5494 pfill = NULL;
5496 if (align != 0)
5498 alpha_auto_align_on = 1;
5499 alpha_align (align, pfill, alpha_insn_label, 1);
5501 else
5503 alpha_auto_align_on = 0;
5506 demand_empty_rest_of_line ();
5509 /* Hook the normal string processor to reset known alignment. */
5511 static void
5512 s_alpha_stringer (terminate)
5513 int terminate;
5515 alpha_current_align = 0;
5516 alpha_insn_label = NULL;
5517 stringer (terminate);
5520 /* Hook the normal space processing to reset known alignment. */
5522 static void
5523 s_alpha_space (ignore)
5524 int ignore;
5526 alpha_current_align = 0;
5527 alpha_insn_label = NULL;
5528 s_space (ignore);
5531 /* Hook into cons for auto-alignment. */
5533 void
5534 alpha_cons_align (size)
5535 int size;
5537 int log_size;
5539 log_size = 0;
5540 while ((size >>= 1) != 0)
5541 ++log_size;
5543 if (alpha_auto_align_on && alpha_current_align < log_size)
5544 alpha_align (log_size, (char *) NULL, alpha_insn_label, 0);
5545 if (alpha_current_align > log_size)
5546 alpha_current_align = log_size;
5547 alpha_insn_label = NULL;
5550 /* Here come the .uword, .ulong, and .uquad explicitly unaligned
5551 pseudos. We just turn off auto-alignment and call down to cons. */
5553 static void
5554 s_alpha_ucons (bytes)
5555 int bytes;
5557 int hold = alpha_auto_align_on;
5558 alpha_auto_align_on = 0;
5559 cons (bytes);
5560 alpha_auto_align_on = hold;
5563 /* Switch the working cpu type. */
5565 static void
5566 s_alpha_arch (ignored)
5567 int ignored ATTRIBUTE_UNUSED;
5569 char *name, ch;
5570 const struct cpu_type *p;
5572 SKIP_WHITESPACE ();
5573 name = input_line_pointer;
5574 ch = get_symbol_end ();
5576 for (p = cpu_types; p->name; ++p)
5577 if (strcmp (name, p->name) == 0)
5579 alpha_target_name = p->name, alpha_target = p->flags;
5580 goto found;
5582 as_warn ("Unknown CPU identifier `%s'", name);
5584 found:
5585 *input_line_pointer = ch;
5586 demand_empty_rest_of_line ();
5589 #ifdef DEBUG1
5590 /* print token expression with alpha specific extension. */
5592 static void
5593 alpha_print_token (f, exp)
5594 FILE *f;
5595 const expressionS *exp;
5597 switch (exp->X_op)
5599 case O_cpregister:
5600 putc (',', f);
5601 /* FALLTHRU */
5602 case O_pregister:
5603 putc ('(', f);
5605 expressionS nexp = *exp;
5606 nexp.X_op = O_register;
5607 print_expr (f, &nexp);
5609 putc (')', f);
5610 break;
5611 default:
5612 print_expr (f, exp);
5613 break;
5616 #endif
5618 /* The target specific pseudo-ops which we support. */
5620 const pseudo_typeS md_pseudo_table[] = {
5621 #ifdef OBJ_ECOFF
5622 {"comm", s_alpha_comm, 0}, /* osf1 compiler does this */
5623 {"rdata", s_alpha_rdata, 0},
5624 #endif
5625 {"text", s_alpha_text, 0},
5626 {"data", s_alpha_data, 0},
5627 #ifdef OBJ_ECOFF
5628 {"sdata", s_alpha_sdata, 0},
5629 #endif
5630 #ifdef OBJ_ELF
5631 {"section", s_alpha_section, 0},
5632 {"section.s", s_alpha_section, 0},
5633 {"sect", s_alpha_section, 0},
5634 {"sect.s", s_alpha_section, 0},
5635 #endif
5636 #ifdef OBJ_EVAX
5637 { "pdesc", s_alpha_pdesc, 0},
5638 { "name", s_alpha_name, 0},
5639 { "linkage", s_alpha_linkage, 0},
5640 { "code_address", s_alpha_code_address, 0},
5641 { "ent", s_alpha_ent, 0},
5642 { "frame", s_alpha_frame, 0},
5643 { "fp_save", s_alpha_fp_save, 0},
5644 { "mask", s_alpha_mask, 0},
5645 { "fmask", s_alpha_fmask, 0},
5646 { "end", s_alpha_end, 0},
5647 { "file", s_alpha_file, 0},
5648 { "rdata", s_alpha_section, 1},
5649 { "comm", s_alpha_comm, 0},
5650 { "link", s_alpha_section, 3},
5651 { "ctors", s_alpha_section, 4},
5652 { "dtors", s_alpha_section, 5},
5653 #endif
5654 #ifdef OBJ_ELF
5655 /* Frame related pseudos. */
5656 {"ent", s_alpha_ent, 0},
5657 {"end", s_alpha_end, 0},
5658 {"mask", s_alpha_mask, 0},
5659 {"fmask", s_alpha_mask, 1},
5660 {"frame", s_alpha_frame, 0},
5661 {"prologue", s_alpha_prologue, 0},
5662 {"file", s_alpha_file, 5},
5663 {"loc", s_alpha_loc, 9},
5664 {"stabs", s_alpha_stab, 's'},
5665 {"stabn", s_alpha_stab, 'n'},
5666 {"usepv", s_alpha_usepv, 0},
5667 /* COFF debugging related pseudos. */
5668 {"begin", s_alpha_coff_wrapper, 0},
5669 {"bend", s_alpha_coff_wrapper, 1},
5670 {"def", s_alpha_coff_wrapper, 2},
5671 {"dim", s_alpha_coff_wrapper, 3},
5672 {"endef", s_alpha_coff_wrapper, 4},
5673 {"scl", s_alpha_coff_wrapper, 5},
5674 {"tag", s_alpha_coff_wrapper, 6},
5675 {"val", s_alpha_coff_wrapper, 7},
5676 #else
5677 {"prologue", s_ignore, 0},
5678 #endif
5679 {"gprel32", s_alpha_gprel32, 0},
5680 {"t_floating", s_alpha_float_cons, 'd'},
5681 {"s_floating", s_alpha_float_cons, 'f'},
5682 {"f_floating", s_alpha_float_cons, 'F'},
5683 {"g_floating", s_alpha_float_cons, 'G'},
5684 {"d_floating", s_alpha_float_cons, 'D'},
5686 {"proc", s_alpha_proc, 0},
5687 {"aproc", s_alpha_proc, 1},
5688 {"set", s_alpha_set, 0},
5689 {"reguse", s_ignore, 0},
5690 {"livereg", s_ignore, 0},
5691 {"base", s_alpha_base, 0}, /*??*/
5692 {"option", s_ignore, 0},
5693 {"aent", s_ignore, 0},
5694 {"ugen", s_ignore, 0},
5695 {"eflag", s_ignore, 0},
5697 {"align", s_alpha_align, 0},
5698 {"double", s_alpha_float_cons, 'd'},
5699 {"float", s_alpha_float_cons, 'f'},
5700 {"single", s_alpha_float_cons, 'f'},
5701 {"ascii", s_alpha_stringer, 0},
5702 {"asciz", s_alpha_stringer, 1},
5703 {"string", s_alpha_stringer, 1},
5704 {"space", s_alpha_space, 0},
5705 {"skip", s_alpha_space, 0},
5706 {"zero", s_alpha_space, 0},
5708 /* Unaligned data pseudos. */
5709 {"uword", s_alpha_ucons, 2},
5710 {"ulong", s_alpha_ucons, 4},
5711 {"uquad", s_alpha_ucons, 8},
5713 #ifdef OBJ_ELF
5714 /* Dwarf wants these versions of unaligned. */
5715 {"2byte", s_alpha_ucons, 2},
5716 {"4byte", s_alpha_ucons, 4},
5717 {"8byte", s_alpha_ucons, 8},
5718 #endif
5720 /* We don't do any optimizing, so we can safely ignore these. */
5721 {"noalias", s_ignore, 0},
5722 {"alias", s_ignore, 0},
5724 {"arch", s_alpha_arch, 0},
5726 {NULL, 0, 0},
5729 /* Build a BFD section with its flags set appropriately for the .lita,
5730 .lit8, or .lit4 sections. */
5732 static void
5733 create_literal_section (name, secp, symp)
5734 const char *name;
5735 segT *secp;
5736 symbolS **symp;
5738 segT current_section = now_seg;
5739 int current_subsec = now_subseg;
5740 segT new_sec;
5742 *secp = new_sec = subseg_new (name, 0);
5743 subseg_set (current_section, current_subsec);
5744 bfd_set_section_alignment (stdoutput, new_sec, 4);
5745 bfd_set_section_flags (stdoutput, new_sec,
5746 SEC_RELOC | SEC_ALLOC | SEC_LOAD | SEC_READONLY
5747 | SEC_DATA);
5749 S_CLEAR_EXTERNAL (*symp = section_symbol (new_sec));
5752 #ifdef OBJ_ECOFF
5754 /* @@@ GP selection voodoo. All of this seems overly complicated and
5755 unnecessary; which is the primary reason it's for ECOFF only. */
5756 static inline void maybe_set_gp PARAMS ((asection *));
5758 static inline void
5759 maybe_set_gp (sec)
5760 asection *sec;
5762 bfd_vma vma;
5763 if (!sec)
5764 return;
5765 vma = bfd_get_section_vma (foo, sec);
5766 if (vma && vma < alpha_gp_value)
5767 alpha_gp_value = vma;
5770 static void
5771 select_gp_value ()
5773 assert (alpha_gp_value == 0);
5775 /* Get minus-one in whatever width... */
5776 alpha_gp_value = 0;
5777 alpha_gp_value--;
5779 /* Select the smallest VMA of these existing sections. */
5780 maybe_set_gp (alpha_lita_section);
5782 /* @@ Will a simple 0x8000 work here? If not, why not? */
5783 #define GP_ADJUSTMENT (0x8000 - 0x10)
5785 alpha_gp_value += GP_ADJUSTMENT;
5787 S_SET_VALUE (alpha_gp_symbol, alpha_gp_value);
5789 #ifdef DEBUG1
5790 printf (_("Chose GP value of %lx\n"), alpha_gp_value);
5791 #endif
5793 #endif /* OBJ_ECOFF */
5795 #ifdef OBJ_ELF
5796 /* Map 's' to SHF_ALPHA_GPREL. */
5799 alpha_elf_section_letter (letter, ptr_msg)
5800 int letter;
5801 char **ptr_msg;
5803 if (letter == 's')
5804 return SHF_ALPHA_GPREL;
5806 *ptr_msg = _("Bad .section directive: want a,s,w,x,M,S,G,T in string");
5807 return -1;
5810 /* Map SHF_ALPHA_GPREL to SEC_SMALL_DATA. */
5812 flagword
5813 alpha_elf_section_flags (flags, attr, type)
5814 flagword flags;
5815 int attr, type ATTRIBUTE_UNUSED;
5817 if (attr & SHF_ALPHA_GPREL)
5818 flags |= SEC_SMALL_DATA;
5819 return flags;
5821 #endif /* OBJ_ELF */
5823 /* Called internally to handle all alignment needs. This takes care
5824 of eliding calls to frag_align if'n the cached current alignment
5825 says we've already got it, as well as taking care of the auto-align
5826 feature wrt labels. */
5828 static void
5829 alpha_align (n, pfill, label, force)
5830 int n;
5831 char *pfill;
5832 symbolS *label;
5833 int force ATTRIBUTE_UNUSED;
5835 if (alpha_current_align >= n)
5836 return;
5838 if (pfill == NULL)
5840 if (subseg_text_p (now_seg))
5841 frag_align_code (n, 0);
5842 else
5843 frag_align (n, 0, 0);
5845 else
5846 frag_align (n, *pfill, 0);
5848 alpha_current_align = n;
5850 if (label != NULL && S_GET_SEGMENT (label) == now_seg)
5852 symbol_set_frag (label, frag_now);
5853 S_SET_VALUE (label, (valueT) frag_now_fix ());
5856 record_alignment (now_seg, n);
5858 /* ??? If alpha_flag_relax && force && elf, record the requested alignment
5859 in a reloc for the linker to see. */
5862 /* This is called from HANDLE_ALIGN in write.c. Fill in the contents
5863 of an rs_align_code fragment. */
5865 void
5866 alpha_handle_align (fragp)
5867 fragS *fragp;
5869 static char const unop[4] = { 0x00, 0x00, 0xfe, 0x2f };
5870 static char const nopunop[8] = {
5871 0x1f, 0x04, 0xff, 0x47,
5872 0x00, 0x00, 0xfe, 0x2f
5875 int bytes, fix;
5876 char *p;
5878 if (fragp->fr_type != rs_align_code)
5879 return;
5881 bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix;
5882 p = fragp->fr_literal + fragp->fr_fix;
5883 fix = 0;
5885 if (bytes & 3)
5887 fix = bytes & 3;
5888 memset (p, 0, fix);
5889 p += fix;
5890 bytes -= fix;
5893 if (bytes & 4)
5895 memcpy (p, unop, 4);
5896 p += 4;
5897 bytes -= 4;
5898 fix += 4;
5901 memcpy (p, nopunop, 8);
5903 fragp->fr_fix += fix;
5904 fragp->fr_var = 8;
5907 /* The Alpha has support for some VAX floating point types, as well as for
5908 IEEE floating point. We consider IEEE to be the primary floating point
5909 format, and sneak in the VAX floating point support here. */
5910 #define md_atof vax_md_atof
5911 #include "config/atof-vax.c"