2005-04-05 Paolo Bonzini <bonzini@gnu.org>
[binutils.git] / gas / config / tc-alpha.c
blob08826ecd1dfd67b72d5ecf22b69c07238975cbde
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. */
27 /* Mach Operating System
28 Copyright (c) 1993 Carnegie Mellon University
29 All Rights Reserved.
31 Permission to use, copy, modify and distribute this software and its
32 documentation is hereby granted, provided that both the copyright
33 notice and this permission notice appear in all copies of the
34 software, derivative works or modified versions, and any portions
35 thereof, and that both notices appear in supporting documentation.
37 CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
38 CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
39 ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
41 Carnegie Mellon requests users of this software to return to
43 Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
44 School of Computer Science
45 Carnegie Mellon University
46 Pittsburgh PA 15213-3890
48 any improvements or extensions that they make and grant Carnegie the
49 rights to redistribute these changes. */
51 #include "as.h"
52 #include "subsegs.h"
53 #include "struc-symbol.h"
54 #include "ecoff.h"
56 #include "opcode/alpha.h"
58 #ifdef OBJ_ELF
59 #include "elf/alpha.h"
60 #include "dwarf2dbg.h"
61 #endif
63 #include "dw2gencfi.h"
64 #include "safe-ctype.h"
66 /* Local types. */
68 #define TOKENIZE_ERROR -1
69 #define TOKENIZE_ERROR_REPORT -2
70 #define MAX_INSN_FIXUPS 2
71 #define MAX_INSN_ARGS 5
73 struct alpha_fixup
75 expressionS exp;
76 bfd_reloc_code_real_type reloc;
79 struct alpha_insn
81 unsigned insn;
82 int nfixups;
83 struct alpha_fixup fixups[MAX_INSN_FIXUPS];
84 long sequence;
87 enum alpha_macro_arg
89 MACRO_EOA = 1,
90 MACRO_IR,
91 MACRO_PIR,
92 MACRO_OPIR,
93 MACRO_CPIR,
94 MACRO_FPR,
95 MACRO_EXP,
98 struct alpha_macro
100 const char *name;
101 void (*emit) (const expressionS *, int, const void *);
102 const void * arg;
103 enum alpha_macro_arg argsets[16];
106 /* Extra expression types. */
108 #define O_pregister O_md1 /* O_register, in parentheses. */
109 #define O_cpregister O_md2 /* + a leading comma. */
111 /* The alpha_reloc_op table below depends on the ordering of these. */
112 #define O_literal O_md3 /* !literal relocation. */
113 #define O_lituse_addr O_md4 /* !lituse_addr relocation. */
114 #define O_lituse_base O_md5 /* !lituse_base relocation. */
115 #define O_lituse_bytoff O_md6 /* !lituse_bytoff relocation. */
116 #define O_lituse_jsr O_md7 /* !lituse_jsr relocation. */
117 #define O_lituse_tlsgd O_md8 /* !lituse_tlsgd relocation. */
118 #define O_lituse_tlsldm O_md9 /* !lituse_tlsldm relocation. */
119 #define O_gpdisp O_md10 /* !gpdisp relocation. */
120 #define O_gprelhigh O_md11 /* !gprelhigh relocation. */
121 #define O_gprellow O_md12 /* !gprellow relocation. */
122 #define O_gprel O_md13 /* !gprel relocation. */
123 #define O_samegp O_md14 /* !samegp relocation. */
124 #define O_tlsgd O_md15 /* !tlsgd relocation. */
125 #define O_tlsldm O_md16 /* !tlsldm relocation. */
126 #define O_gotdtprel O_md17 /* !gotdtprel relocation. */
127 #define O_dtprelhi O_md18 /* !dtprelhi relocation. */
128 #define O_dtprello O_md19 /* !dtprello relocation. */
129 #define O_dtprel O_md20 /* !dtprel relocation. */
130 #define O_gottprel O_md21 /* !gottprel relocation. */
131 #define O_tprelhi O_md22 /* !tprelhi relocation. */
132 #define O_tprello O_md23 /* !tprello relocation. */
133 #define O_tprel O_md24 /* !tprel relocation. */
135 #define DUMMY_RELOC_LITUSE_ADDR (BFD_RELOC_UNUSED + 1)
136 #define DUMMY_RELOC_LITUSE_BASE (BFD_RELOC_UNUSED + 2)
137 #define DUMMY_RELOC_LITUSE_BYTOFF (BFD_RELOC_UNUSED + 3)
138 #define DUMMY_RELOC_LITUSE_JSR (BFD_RELOC_UNUSED + 4)
139 #define DUMMY_RELOC_LITUSE_TLSGD (BFD_RELOC_UNUSED + 5)
140 #define DUMMY_RELOC_LITUSE_TLSLDM (BFD_RELOC_UNUSED + 6)
142 #define USER_RELOC_P(R) ((R) >= O_literal && (R) <= O_tprel)
144 /* Macros for extracting the type and number of encoded register tokens. */
146 #define is_ir_num(x) (((x) & 32) == 0)
147 #define is_fpr_num(x) (((x) & 32) != 0)
148 #define regno(x) ((x) & 31)
150 /* Something odd inherited from the old assembler. */
152 #define note_gpreg(R) (alpha_gprmask |= (1 << (R)))
153 #define note_fpreg(R) (alpha_fprmask |= (1 << (R)))
155 /* Predicates for 16- and 32-bit ranges */
156 /* XXX: The non-shift version appears to trigger a compiler bug when
157 cross-assembling from x86 w/ gcc 2.7.2. */
159 #if 1
160 #define range_signed_16(x) \
161 (((offsetT) (x) >> 15) == 0 || ((offsetT) (x) >> 15) == -1)
162 #define range_signed_32(x) \
163 (((offsetT) (x) >> 31) == 0 || ((offsetT) (x) >> 31) == -1)
164 #else
165 #define range_signed_16(x) ((offsetT) (x) >= -(offsetT) 0x8000 && \
166 (offsetT) (x) <= (offsetT) 0x7FFF)
167 #define range_signed_32(x) ((offsetT) (x) >= -(offsetT) 0x80000000 && \
168 (offsetT) (x) <= (offsetT) 0x7FFFFFFF)
169 #endif
171 /* Macros for sign extending from 16- and 32-bits. */
172 /* XXX: The cast macros will work on all the systems that I care about,
173 but really a predicate should be found to use the non-cast forms. */
175 #if 1
176 #define sign_extend_16(x) ((short) (x))
177 #define sign_extend_32(x) ((int) (x))
178 #else
179 #define sign_extend_16(x) ((offsetT) (((x) & 0xFFFF) ^ 0x8000) - 0x8000)
180 #define sign_extend_32(x) ((offsetT) (((x) & 0xFFFFFFFF) \
181 ^ 0x80000000) - 0x80000000)
182 #endif
184 /* Macros to build tokens. */
186 #define set_tok_reg(t, r) (memset (&(t), 0, sizeof (t)), \
187 (t).X_op = O_register, \
188 (t).X_add_number = (r))
189 #define set_tok_preg(t, r) (memset (&(t), 0, sizeof (t)), \
190 (t).X_op = O_pregister, \
191 (t).X_add_number = (r))
192 #define set_tok_cpreg(t, r) (memset (&(t), 0, sizeof (t)), \
193 (t).X_op = O_cpregister, \
194 (t).X_add_number = (r))
195 #define set_tok_freg(t, r) (memset (&(t), 0, sizeof (t)), \
196 (t).X_op = O_register, \
197 (t).X_add_number = (r) + 32)
198 #define set_tok_sym(t, s, a) (memset (&(t), 0, sizeof (t)), \
199 (t).X_op = O_symbol, \
200 (t).X_add_symbol = (s), \
201 (t).X_add_number = (a))
202 #define set_tok_const(t, n) (memset (&(t), 0, sizeof (t)), \
203 (t).X_op = O_constant, \
204 (t).X_add_number = (n))
206 /* Generic assembler global variables which must be defined by all
207 targets. */
209 /* Characters which always start a comment. */
210 const char comment_chars[] = "#";
212 /* Characters which start a comment at the beginning of a line. */
213 const char line_comment_chars[] = "#";
215 /* Characters which may be used to separate multiple commands on a
216 single line. */
217 const char line_separator_chars[] = ";";
219 /* Characters which are used to indicate an exponent in a floating
220 point number. */
221 const char EXP_CHARS[] = "eE";
223 /* Characters which mean that a number is a floating point constant,
224 as in 0d1.0. */
225 /* XXX: Do all of these really get used on the alpha?? */
226 char FLT_CHARS[] = "rRsSfFdDxXpP";
228 #ifdef OBJ_EVAX
229 const char *md_shortopts = "Fm:g+1h:HG:";
230 #else
231 const char *md_shortopts = "Fm:gG:";
232 #endif
234 struct option md_longopts[] =
236 #define OPTION_32ADDR (OPTION_MD_BASE)
237 { "32addr", no_argument, NULL, OPTION_32ADDR },
238 #define OPTION_RELAX (OPTION_32ADDR + 1)
239 { "relax", no_argument, NULL, OPTION_RELAX },
240 #ifdef OBJ_ELF
241 #define OPTION_MDEBUG (OPTION_RELAX + 1)
242 #define OPTION_NO_MDEBUG (OPTION_MDEBUG + 1)
243 { "mdebug", no_argument, NULL, OPTION_MDEBUG },
244 { "no-mdebug", no_argument, NULL, OPTION_NO_MDEBUG },
245 #endif
246 { NULL, no_argument, NULL, 0 }
249 size_t md_longopts_size = sizeof (md_longopts);
251 #ifdef OBJ_EVAX
252 #define AXP_REG_R0 0
253 #define AXP_REG_R16 16
254 #define AXP_REG_R17 17
255 #undef AXP_REG_T9
256 #define AXP_REG_T9 22
257 #undef AXP_REG_T10
258 #define AXP_REG_T10 23
259 #undef AXP_REG_T11
260 #define AXP_REG_T11 24
261 #undef AXP_REG_T12
262 #define AXP_REG_T12 25
263 #define AXP_REG_AI 25
264 #undef AXP_REG_FP
265 #define AXP_REG_FP 29
267 #undef AXP_REG_GP
268 #define AXP_REG_GP AXP_REG_PV
269 #endif /* OBJ_EVAX */
271 /* The cpu for which we are generating code. */
272 static unsigned alpha_target = AXP_OPCODE_BASE;
273 static const char *alpha_target_name = "<all>";
275 /* The hash table of instruction opcodes. */
276 static struct hash_control *alpha_opcode_hash;
278 /* The hash table of macro opcodes. */
279 static struct hash_control *alpha_macro_hash;
281 #ifdef OBJ_ECOFF
282 /* The $gp relocation symbol. */
283 static symbolS *alpha_gp_symbol;
285 /* XXX: what is this, and why is it exported? */
286 valueT alpha_gp_value;
287 #endif
289 /* The current $gp register. */
290 static int alpha_gp_register = AXP_REG_GP;
292 /* A table of the register symbols. */
293 static symbolS *alpha_register_table[64];
295 /* Constant sections, or sections of constants. */
296 #ifdef OBJ_ECOFF
297 static segT alpha_lita_section;
298 #endif
299 #ifdef OBJ_EVAX
300 static segT alpha_link_section;
301 static segT alpha_ctors_section;
302 static segT alpha_dtors_section;
303 #endif
304 static segT alpha_lit8_section;
306 /* Symbols referring to said sections. */
307 #ifdef OBJ_ECOFF
308 static symbolS *alpha_lita_symbol;
309 #endif
310 #ifdef OBJ_EVAX
311 static symbolS *alpha_link_symbol;
312 static symbolS *alpha_ctors_symbol;
313 static symbolS *alpha_dtors_symbol;
314 #endif
315 static symbolS *alpha_lit8_symbol;
317 /* Literal for .litX+0x8000 within .lita. */
318 #ifdef OBJ_ECOFF
319 static offsetT alpha_lit8_literal;
320 #endif
322 /* Is the assembler not allowed to use $at? */
323 static int alpha_noat_on = 0;
325 /* Are macros enabled? */
326 static int alpha_macros_on = 1;
328 /* Are floats disabled? */
329 static int alpha_nofloats_on = 0;
331 /* Are addresses 32 bit? */
332 static int alpha_addr32_on = 0;
334 /* Symbol labelling the current insn. When the Alpha gas sees
335 foo:
336 .quad 0
337 and the section happens to not be on an eight byte boundary, it
338 will align both the symbol and the .quad to an eight byte boundary. */
339 static symbolS *alpha_insn_label;
341 /* Whether we should automatically align data generation pseudo-ops.
342 .align 0 will turn this off. */
343 static int alpha_auto_align_on = 1;
345 /* The known current alignment of the current section. */
346 static int alpha_current_align;
348 /* These are exported to ECOFF code. */
349 unsigned long alpha_gprmask, alpha_fprmask;
351 /* Whether the debugging option was seen. */
352 static int alpha_debug;
354 #ifdef OBJ_ELF
355 /* Whether we are emitting an mdebug section. */
356 int alpha_flag_mdebug = -1;
357 #endif
359 /* Don't fully resolve relocations, allowing code movement in the linker. */
360 static int alpha_flag_relax;
362 /* What value to give to bfd_set_gp_size. */
363 static int g_switch_value = 8;
365 #ifdef OBJ_EVAX
366 /* Collect information about current procedure here. */
367 static struct
369 symbolS *symbol; /* Proc pdesc symbol. */
370 int pdsckind;
371 int framereg; /* Register for frame pointer. */
372 int framesize; /* Size of frame. */
373 int rsa_offset;
374 int ra_save;
375 int fp_save;
376 long imask;
377 long fmask;
378 int type;
379 int prologue;
380 } alpha_evax_proc;
382 static int alpha_flag_hash_long_names = 0; /* -+ */
383 static int alpha_flag_show_after_trunc = 0; /* -H */
385 /* If the -+ switch is given, then a hash is appended to any name that is
386 longer than 64 characters, else longer symbol names are truncated. */
388 #endif
390 #ifdef RELOC_OP_P
391 /* A table to map the spelling of a relocation operand into an appropriate
392 bfd_reloc_code_real_type type. The table is assumed to be ordered such
393 that op-O_literal indexes into it. */
395 #define ALPHA_RELOC_TABLE(op) \
396 (&alpha_reloc_op[ ((!USER_RELOC_P (op)) \
397 ? (abort (), 0) \
398 : (int) (op) - (int) O_literal) ])
400 #define DEF(NAME, RELOC, REQ, ALLOW) \
401 { #NAME, sizeof(#NAME)-1, O_##NAME, RELOC, REQ, ALLOW}
403 static const struct alpha_reloc_op_tag
405 const char *name; /* String to lookup. */
406 size_t length; /* Size of the string. */
407 operatorT op; /* Which operator to use. */
408 bfd_reloc_code_real_type reloc; /* Relocation before frob. */
409 unsigned int require_seq : 1; /* Require a sequence number. */
410 unsigned int allow_seq : 1; /* Allow a sequence number. */
412 alpha_reloc_op[] =
414 DEF (literal, BFD_RELOC_ALPHA_ELF_LITERAL, 0, 1),
415 DEF (lituse_addr, DUMMY_RELOC_LITUSE_ADDR, 1, 1),
416 DEF (lituse_base, DUMMY_RELOC_LITUSE_BASE, 1, 1),
417 DEF (lituse_bytoff, DUMMY_RELOC_LITUSE_BYTOFF, 1, 1),
418 DEF (lituse_jsr, DUMMY_RELOC_LITUSE_JSR, 1, 1),
419 DEF (lituse_tlsgd, DUMMY_RELOC_LITUSE_TLSGD, 1, 1),
420 DEF (lituse_tlsldm, DUMMY_RELOC_LITUSE_TLSLDM, 1, 1),
421 DEF (gpdisp, BFD_RELOC_ALPHA_GPDISP, 1, 1),
422 DEF (gprelhigh, BFD_RELOC_ALPHA_GPREL_HI16, 0, 0),
423 DEF (gprellow, BFD_RELOC_ALPHA_GPREL_LO16, 0, 0),
424 DEF (gprel, BFD_RELOC_GPREL16, 0, 0),
425 DEF (samegp, BFD_RELOC_ALPHA_BRSGP, 0, 0),
426 DEF (tlsgd, BFD_RELOC_ALPHA_TLSGD, 0, 1),
427 DEF (tlsldm, BFD_RELOC_ALPHA_TLSLDM, 0, 1),
428 DEF (gotdtprel, BFD_RELOC_ALPHA_GOTDTPREL16, 0, 0),
429 DEF (dtprelhi, BFD_RELOC_ALPHA_DTPREL_HI16, 0, 0),
430 DEF (dtprello, BFD_RELOC_ALPHA_DTPREL_LO16, 0, 0),
431 DEF (dtprel, BFD_RELOC_ALPHA_DTPREL16, 0, 0),
432 DEF (gottprel, BFD_RELOC_ALPHA_GOTTPREL16, 0, 0),
433 DEF (tprelhi, BFD_RELOC_ALPHA_TPREL_HI16, 0, 0),
434 DEF (tprello, BFD_RELOC_ALPHA_TPREL_LO16, 0, 0),
435 DEF (tprel, BFD_RELOC_ALPHA_TPREL16, 0, 0),
438 #undef DEF
440 static const int alpha_num_reloc_op
441 = sizeof (alpha_reloc_op) / sizeof (*alpha_reloc_op);
442 #endif /* RELOC_OP_P */
444 /* Maximum # digits needed to hold the largest sequence #. */
445 #define ALPHA_RELOC_DIGITS 25
447 /* Structure to hold explicit sequence information. */
448 struct alpha_reloc_tag
450 fixS *master; /* The literal reloc. */
451 fixS *slaves; /* Head of linked list of lituses. */
452 segT segment; /* Segment relocs are in or undefined_section. */
453 long sequence; /* Sequence #. */
454 unsigned n_master; /* # of literals. */
455 unsigned n_slaves; /* # of lituses. */
456 unsigned saw_tlsgd : 1; /* True if ... */
457 unsigned saw_tlsldm : 1;
458 unsigned saw_lu_tlsgd : 1;
459 unsigned saw_lu_tlsldm : 1;
460 unsigned multi_section_p : 1; /* True if more than one section was used. */
461 char string[1]; /* Printable form of sequence to hash with. */
464 /* Hash table to link up literals with the appropriate lituse. */
465 static struct hash_control *alpha_literal_hash;
467 /* Sequence numbers for internal use by macros. */
468 static long next_sequence_num = -1;
470 /* A table of CPU names and opcode sets. */
472 static const struct cpu_type
474 const char *name;
475 unsigned flags;
477 cpu_types[] =
479 /* Ad hoc convention: cpu number gets palcode, process code doesn't.
480 This supports usage under DU 4.0b that does ".arch ev4", and
481 usage in MILO that does -m21064. Probably something more
482 specific like -m21064-pal should be used, but oh well. */
484 { "21064", AXP_OPCODE_BASE|AXP_OPCODE_EV4 },
485 { "21064a", AXP_OPCODE_BASE|AXP_OPCODE_EV4 },
486 { "21066", AXP_OPCODE_BASE|AXP_OPCODE_EV4 },
487 { "21068", AXP_OPCODE_BASE|AXP_OPCODE_EV4 },
488 { "21164", AXP_OPCODE_BASE|AXP_OPCODE_EV5 },
489 { "21164a", AXP_OPCODE_BASE|AXP_OPCODE_EV5|AXP_OPCODE_BWX },
490 { "21164pc", (AXP_OPCODE_BASE|AXP_OPCODE_EV5|AXP_OPCODE_BWX
491 |AXP_OPCODE_MAX) },
492 { "21264", (AXP_OPCODE_BASE|AXP_OPCODE_EV6|AXP_OPCODE_BWX
493 |AXP_OPCODE_MAX|AXP_OPCODE_CIX) },
494 { "21264a", (AXP_OPCODE_BASE|AXP_OPCODE_EV6|AXP_OPCODE_BWX
495 |AXP_OPCODE_MAX|AXP_OPCODE_CIX) },
496 { "21264b", (AXP_OPCODE_BASE|AXP_OPCODE_EV6|AXP_OPCODE_BWX
497 |AXP_OPCODE_MAX|AXP_OPCODE_CIX) },
499 { "ev4", AXP_OPCODE_BASE },
500 { "ev45", AXP_OPCODE_BASE },
501 { "lca45", AXP_OPCODE_BASE },
502 { "ev5", AXP_OPCODE_BASE },
503 { "ev56", AXP_OPCODE_BASE|AXP_OPCODE_BWX },
504 { "pca56", AXP_OPCODE_BASE|AXP_OPCODE_BWX|AXP_OPCODE_MAX },
505 { "ev6", AXP_OPCODE_BASE|AXP_OPCODE_BWX|AXP_OPCODE_MAX|AXP_OPCODE_CIX },
506 { "ev67", AXP_OPCODE_BASE|AXP_OPCODE_BWX|AXP_OPCODE_MAX|AXP_OPCODE_CIX },
507 { "ev68", AXP_OPCODE_BASE|AXP_OPCODE_BWX|AXP_OPCODE_MAX|AXP_OPCODE_CIX },
509 { "all", AXP_OPCODE_BASE },
510 { 0, 0 }
513 /* Some instruction sets indexed by lg(size). */
514 static const char * const sextX_op[] = { "sextb", "sextw", "sextl", NULL };
515 static const char * const insXl_op[] = { "insbl", "inswl", "insll", "insql" };
516 static const char * const insXh_op[] = { NULL, "inswh", "inslh", "insqh" };
517 static const char * const extXl_op[] = { "extbl", "extwl", "extll", "extql" };
518 static const char * const extXh_op[] = { NULL, "extwh", "extlh", "extqh" };
519 static const char * const mskXl_op[] = { "mskbl", "mskwl", "mskll", "mskql" };
520 static const char * const mskXh_op[] = { NULL, "mskwh", "msklh", "mskqh" };
521 static const char * const stX_op[] = { "stb", "stw", "stl", "stq" };
522 static const char * const ldXu_op[] = { "ldbu", "ldwu", NULL, NULL };
524 static void assemble_insn (const struct alpha_opcode *, const expressionS *, int, struct alpha_insn *, bfd_reloc_code_real_type);
525 static void emit_insn (struct alpha_insn *);
526 static void assemble_tokens (const char *, const expressionS *, int, int);
528 static struct alpha_reloc_tag *
529 get_alpha_reloc_tag (long sequence)
531 char buffer[ALPHA_RELOC_DIGITS];
532 struct alpha_reloc_tag *info;
534 sprintf (buffer, "!%ld", sequence);
536 info = (struct alpha_reloc_tag *) hash_find (alpha_literal_hash, buffer);
537 if (! info)
539 size_t len = strlen (buffer);
540 const char *errmsg;
542 info = xcalloc (sizeof (struct alpha_reloc_tag) + len, 1);
544 info->segment = now_seg;
545 info->sequence = sequence;
546 strcpy (info->string, buffer);
547 errmsg = hash_insert (alpha_literal_hash, info->string, (void *) info);
548 if (errmsg)
549 as_fatal (errmsg);
552 return info;
555 static void
556 alpha_adjust_relocs (bfd *abfd ATTRIBUTE_UNUSED,
557 asection *sec,
558 void * ptr ATTRIBUTE_UNUSED)
560 segment_info_type *seginfo = seg_info (sec);
561 fixS **prevP;
562 fixS *fixp;
563 fixS *next;
564 fixS *slave;
566 /* If seginfo is NULL, we did not create this section; don't do
567 anything with it. By using a pointer to a pointer, we can update
568 the links in place. */
569 if (seginfo == NULL)
570 return;
572 /* If there are no relocations, skip the section. */
573 if (! seginfo->fix_root)
574 return;
576 /* First rebuild the fixup chain without the explicit lituse and
577 gpdisp_lo16 relocs. */
578 prevP = &seginfo->fix_root;
579 for (fixp = seginfo->fix_root; fixp; fixp = next)
581 next = fixp->fx_next;
582 fixp->fx_next = (fixS *) 0;
584 switch (fixp->fx_r_type)
586 case BFD_RELOC_ALPHA_LITUSE:
587 if (fixp->tc_fix_data.info->n_master == 0)
588 as_bad_where (fixp->fx_file, fixp->fx_line,
589 _("No !literal!%ld was found"),
590 fixp->tc_fix_data.info->sequence);
591 #ifdef RELOC_OP_P
592 if (fixp->fx_offset == LITUSE_ALPHA_TLSGD)
594 if (! fixp->tc_fix_data.info->saw_tlsgd)
595 as_bad_where (fixp->fx_file, fixp->fx_line,
596 _("No !tlsgd!%ld was found"),
597 fixp->tc_fix_data.info->sequence);
599 else if (fixp->fx_offset == LITUSE_ALPHA_TLSLDM)
601 if (! fixp->tc_fix_data.info->saw_tlsldm)
602 as_bad_where (fixp->fx_file, fixp->fx_line,
603 _("No !tlsldm!%ld was found"),
604 fixp->tc_fix_data.info->sequence);
606 #endif
607 break;
609 case BFD_RELOC_ALPHA_GPDISP_LO16:
610 if (fixp->tc_fix_data.info->n_master == 0)
611 as_bad_where (fixp->fx_file, fixp->fx_line,
612 _("No ldah !gpdisp!%ld was found"),
613 fixp->tc_fix_data.info->sequence);
614 break;
616 case BFD_RELOC_ALPHA_ELF_LITERAL:
617 if (fixp->tc_fix_data.info
618 && (fixp->tc_fix_data.info->saw_tlsgd
619 || fixp->tc_fix_data.info->saw_tlsldm))
620 break;
621 /* FALLTHRU */
623 default:
624 *prevP = fixp;
625 prevP = &fixp->fx_next;
626 break;
630 /* Go back and re-chain dependent relocations. They are currently
631 linked through the next_reloc field in reverse order, so as we
632 go through the next_reloc chain, we effectively reverse the chain
633 once again.
635 Except if there is more than one !literal for a given sequence
636 number. In that case, the programmer and/or compiler is not sure
637 how control flows from literal to lituse, and we can't be sure to
638 get the relaxation correct.
640 ??? Well, actually we could, if there are enough lituses such that
641 we can make each literal have at least one of each lituse type
642 present. Not implemented.
644 Also suppress the optimization if the !literals/!lituses are spread
645 in different segments. This can happen with "intersting" uses of
646 inline assembly; examples are present in the Linux kernel semaphores. */
648 for (fixp = seginfo->fix_root; fixp; fixp = next)
650 next = fixp->fx_next;
651 switch (fixp->fx_r_type)
653 case BFD_RELOC_ALPHA_TLSGD:
654 case BFD_RELOC_ALPHA_TLSLDM:
655 if (!fixp->tc_fix_data.info)
656 break;
657 if (fixp->tc_fix_data.info->n_master == 0)
658 break;
659 else if (fixp->tc_fix_data.info->n_master > 1)
661 as_bad_where (fixp->fx_file, fixp->fx_line,
662 _("too many !literal!%ld for %s"),
663 fixp->tc_fix_data.info->sequence,
664 (fixp->fx_r_type == BFD_RELOC_ALPHA_TLSGD
665 ? "!tlsgd" : "!tlsldm"));
666 break;
669 fixp->tc_fix_data.info->master->fx_next = fixp->fx_next;
670 fixp->fx_next = fixp->tc_fix_data.info->master;
671 fixp = fixp->fx_next;
672 /* Fall through. */
674 case BFD_RELOC_ALPHA_ELF_LITERAL:
675 if (fixp->tc_fix_data.info
676 && fixp->tc_fix_data.info->n_master == 1
677 && ! fixp->tc_fix_data.info->multi_section_p)
679 for (slave = fixp->tc_fix_data.info->slaves;
680 slave != (fixS *) 0;
681 slave = slave->tc_fix_data.next_reloc)
683 slave->fx_next = fixp->fx_next;
684 fixp->fx_next = slave;
687 break;
689 case BFD_RELOC_ALPHA_GPDISP_HI16:
690 if (fixp->tc_fix_data.info->n_slaves == 0)
691 as_bad_where (fixp->fx_file, fixp->fx_line,
692 _("No lda !gpdisp!%ld was found"),
693 fixp->tc_fix_data.info->sequence);
694 else
696 slave = fixp->tc_fix_data.info->slaves;
697 slave->fx_next = next;
698 fixp->fx_next = slave;
700 break;
702 default:
703 break;
708 /* Before the relocations are written, reorder them, so that user
709 supplied !lituse relocations follow the appropriate !literal
710 relocations, and similarly for !gpdisp relocations. */
712 void
713 alpha_before_fix (void)
715 if (alpha_literal_hash)
716 bfd_map_over_sections (stdoutput, alpha_adjust_relocs, NULL);
719 #ifdef DEBUG_ALPHA
720 static void
721 debug_exp (expressionS tok[], int ntok)
723 int i;
725 fprintf (stderr, "debug_exp: %d tokens", ntok);
726 for (i = 0; i < ntok; i++)
728 expressionS *t = &tok[i];
729 const char *name;
731 switch (t->X_op)
733 default: name = "unknown"; break;
734 case O_illegal: name = "O_illegal"; break;
735 case O_absent: name = "O_absent"; break;
736 case O_constant: name = "O_constant"; break;
737 case O_symbol: name = "O_symbol"; break;
738 case O_symbol_rva: name = "O_symbol_rva"; break;
739 case O_register: name = "O_register"; break;
740 case O_big: name = "O_big"; break;
741 case O_uminus: name = "O_uminus"; break;
742 case O_bit_not: name = "O_bit_not"; break;
743 case O_logical_not: name = "O_logical_not"; break;
744 case O_multiply: name = "O_multiply"; break;
745 case O_divide: name = "O_divide"; break;
746 case O_modulus: name = "O_modulus"; break;
747 case O_left_shift: name = "O_left_shift"; break;
748 case O_right_shift: name = "O_right_shift"; break;
749 case O_bit_inclusive_or: name = "O_bit_inclusive_or"; break;
750 case O_bit_or_not: name = "O_bit_or_not"; break;
751 case O_bit_exclusive_or: name = "O_bit_exclusive_or"; break;
752 case O_bit_and: name = "O_bit_and"; break;
753 case O_add: name = "O_add"; break;
754 case O_subtract: name = "O_subtract"; break;
755 case O_eq: name = "O_eq"; break;
756 case O_ne: name = "O_ne"; break;
757 case O_lt: name = "O_lt"; break;
758 case O_le: name = "O_le"; break;
759 case O_ge: name = "O_ge"; break;
760 case O_gt: name = "O_gt"; break;
761 case O_logical_and: name = "O_logical_and"; break;
762 case O_logical_or: name = "O_logical_or"; break;
763 case O_index: name = "O_index"; break;
764 case O_pregister: name = "O_pregister"; break;
765 case O_cpregister: name = "O_cpregister"; break;
766 case O_literal: name = "O_literal"; break;
767 case O_lituse_addr: name = "O_lituse_addr"; break;
768 case O_lituse_base: name = "O_lituse_base"; break;
769 case O_lituse_bytoff: name = "O_lituse_bytoff"; break;
770 case O_lituse_jsr: name = "O_lituse_jsr"; break;
771 case O_lituse_tlsgd: name = "O_lituse_tlsgd"; break;
772 case O_lituse_tlsldm: name = "O_lituse_tlsldm"; break;
773 case O_gpdisp: name = "O_gpdisp"; break;
774 case O_gprelhigh: name = "O_gprelhigh"; break;
775 case O_gprellow: name = "O_gprellow"; break;
776 case O_gprel: name = "O_gprel"; break;
777 case O_samegp: name = "O_samegp"; break;
778 case O_tlsgd: name = "O_tlsgd"; break;
779 case O_tlsldm: name = "O_tlsldm"; break;
780 case O_gotdtprel: name = "O_gotdtprel"; break;
781 case O_dtprelhi: name = "O_dtprelhi"; break;
782 case O_dtprello: name = "O_dtprello"; break;
783 case O_dtprel: name = "O_dtprel"; break;
784 case O_gottprel: name = "O_gottprel"; break;
785 case O_tprelhi: name = "O_tprelhi"; break;
786 case O_tprello: name = "O_tprello"; break;
787 case O_tprel: name = "O_tprel"; break;
790 fprintf (stderr, ", %s(%s, %s, %d)", name,
791 (t->X_add_symbol) ? S_GET_NAME (t->X_add_symbol) : "--",
792 (t->X_op_symbol) ? S_GET_NAME (t->X_op_symbol) : "--",
793 (int) t->X_add_number);
795 fprintf (stderr, "\n");
796 fflush (stderr);
798 #endif
800 /* Parse the arguments to an opcode. */
802 static int
803 tokenize_arguments (char *str,
804 expressionS tok[],
805 int ntok)
807 expressionS *end_tok = tok + ntok;
808 char *old_input_line_pointer;
809 int saw_comma = 0, saw_arg = 0;
810 #ifdef DEBUG_ALPHA
811 expressionS *orig_tok = tok;
812 #endif
813 #ifdef RELOC_OP_P
814 char *p;
815 const struct alpha_reloc_op_tag *r;
816 int c, i;
817 size_t len;
818 int reloc_found_p = 0;
819 #endif
821 memset (tok, 0, sizeof (*tok) * ntok);
823 /* Save and restore input_line_pointer around this function. */
824 old_input_line_pointer = input_line_pointer;
825 input_line_pointer = str;
827 #ifdef RELOC_OP_P
828 /* ??? Wrest control of ! away from the regular expression parser. */
829 is_end_of_line[(unsigned char) '!'] = 1;
830 #endif
832 while (tok < end_tok && *input_line_pointer)
834 SKIP_WHITESPACE ();
835 switch (*input_line_pointer)
837 case '\0':
838 goto fini;
840 #ifdef RELOC_OP_P
841 case '!':
842 /* A relocation operand can be placed after the normal operand on an
843 assembly language statement, and has the following form:
844 !relocation_type!sequence_number. */
845 if (reloc_found_p)
847 /* Only support one relocation op per insn. */
848 as_bad (_("More than one relocation op per insn"));
849 goto err_report;
852 if (!saw_arg)
853 goto err;
855 ++input_line_pointer;
856 SKIP_WHITESPACE ();
857 p = input_line_pointer;
858 c = get_symbol_end ();
860 /* Parse !relocation_type. */
861 len = input_line_pointer - p;
862 if (len == 0)
864 as_bad (_("No relocation operand"));
865 goto err_report;
868 r = &alpha_reloc_op[0];
869 for (i = alpha_num_reloc_op - 1; i >= 0; i--, r++)
870 if (len == r->length && memcmp (p, r->name, len) == 0)
871 break;
872 if (i < 0)
874 as_bad (_("Unknown relocation operand: !%s"), p);
875 goto err_report;
878 *input_line_pointer = c;
879 SKIP_WHITESPACE ();
880 if (*input_line_pointer != '!')
882 if (r->require_seq)
884 as_bad (_("no sequence number after !%s"), p);
885 goto err_report;
888 tok->X_add_number = 0;
890 else
892 if (! r->allow_seq)
894 as_bad (_("!%s does not use a sequence number"), p);
895 goto err_report;
898 input_line_pointer++;
900 /* Parse !sequence_number. */
901 expression (tok);
902 if (tok->X_op != O_constant || tok->X_add_number <= 0)
904 as_bad (_("Bad sequence number: !%s!%s"),
905 r->name, input_line_pointer);
906 goto err_report;
910 tok->X_op = r->op;
911 reloc_found_p = 1;
912 ++tok;
913 break;
914 #endif /* RELOC_OP_P */
916 case ',':
917 ++input_line_pointer;
918 if (saw_comma || !saw_arg)
919 goto err;
920 saw_comma = 1;
921 break;
923 case '(':
925 char *hold = input_line_pointer++;
927 /* First try for parenthesized register ... */
928 expression (tok);
929 if (*input_line_pointer == ')' && tok->X_op == O_register)
931 tok->X_op = (saw_comma ? O_cpregister : O_pregister);
932 saw_comma = 0;
933 saw_arg = 1;
934 ++input_line_pointer;
935 ++tok;
936 break;
939 /* ... then fall through to plain expression. */
940 input_line_pointer = hold;
943 default:
944 if (saw_arg && !saw_comma)
945 goto err;
947 expression (tok);
948 if (tok->X_op == O_illegal || tok->X_op == O_absent)
949 goto err;
951 saw_comma = 0;
952 saw_arg = 1;
953 ++tok;
954 break;
958 fini:
959 if (saw_comma)
960 goto err;
961 input_line_pointer = old_input_line_pointer;
963 #ifdef DEBUG_ALPHA
964 debug_exp (orig_tok, ntok - (end_tok - tok));
965 #endif
966 #ifdef RELOC_OP_P
967 is_end_of_line[(unsigned char) '!'] = 0;
968 #endif
970 return ntok - (end_tok - tok);
972 err:
973 #ifdef RELOC_OP_P
974 is_end_of_line[(unsigned char) '!'] = 0;
975 #endif
976 input_line_pointer = old_input_line_pointer;
977 return TOKENIZE_ERROR;
979 #ifdef RELOC_OP_P
980 err_report:
981 is_end_of_line[(unsigned char) '!'] = 0;
982 #endif
983 input_line_pointer = old_input_line_pointer;
984 return TOKENIZE_ERROR_REPORT;
987 /* Search forward through all variants of an opcode looking for a
988 syntax match. */
990 static const struct alpha_opcode *
991 find_opcode_match (const struct alpha_opcode *first_opcode,
992 const expressionS *tok,
993 int *pntok,
994 int *pcpumatch)
996 const struct alpha_opcode *opcode = first_opcode;
997 int ntok = *pntok;
998 int got_cpu_match = 0;
1002 const unsigned char *opidx;
1003 int tokidx = 0;
1005 /* Don't match opcodes that don't exist on this architecture. */
1006 if (!(opcode->flags & alpha_target))
1007 goto match_failed;
1009 got_cpu_match = 1;
1011 for (opidx = opcode->operands; *opidx; ++opidx)
1013 const struct alpha_operand *operand = &alpha_operands[*opidx];
1015 /* Only take input from real operands. */
1016 if (operand->flags & AXP_OPERAND_FAKE)
1017 continue;
1019 /* When we expect input, make sure we have it. */
1020 if (tokidx >= ntok)
1022 if ((operand->flags & AXP_OPERAND_OPTIONAL_MASK) == 0)
1023 goto match_failed;
1024 continue;
1027 /* Match operand type with expression type. */
1028 switch (operand->flags & AXP_OPERAND_TYPECHECK_MASK)
1030 case AXP_OPERAND_IR:
1031 if (tok[tokidx].X_op != O_register
1032 || !is_ir_num (tok[tokidx].X_add_number))
1033 goto match_failed;
1034 break;
1035 case AXP_OPERAND_FPR:
1036 if (tok[tokidx].X_op != O_register
1037 || !is_fpr_num (tok[tokidx].X_add_number))
1038 goto match_failed;
1039 break;
1040 case AXP_OPERAND_IR | AXP_OPERAND_PARENS:
1041 if (tok[tokidx].X_op != O_pregister
1042 || !is_ir_num (tok[tokidx].X_add_number))
1043 goto match_failed;
1044 break;
1045 case AXP_OPERAND_IR | AXP_OPERAND_PARENS | AXP_OPERAND_COMMA:
1046 if (tok[tokidx].X_op != O_cpregister
1047 || !is_ir_num (tok[tokidx].X_add_number))
1048 goto match_failed;
1049 break;
1051 case AXP_OPERAND_RELATIVE:
1052 case AXP_OPERAND_SIGNED:
1053 case AXP_OPERAND_UNSIGNED:
1054 switch (tok[tokidx].X_op)
1056 case O_illegal:
1057 case O_absent:
1058 case O_register:
1059 case O_pregister:
1060 case O_cpregister:
1061 goto match_failed;
1063 default:
1064 break;
1066 break;
1068 default:
1069 /* Everything else should have been fake. */
1070 abort ();
1072 ++tokidx;
1075 /* Possible match -- did we use all of our input? */
1076 if (tokidx == ntok)
1078 *pntok = ntok;
1079 return opcode;
1082 match_failed:;
1084 while (++opcode - alpha_opcodes < (int) alpha_num_opcodes
1085 && !strcmp (opcode->name, first_opcode->name));
1087 if (*pcpumatch)
1088 *pcpumatch = got_cpu_match;
1090 return NULL;
1093 /* Given an opcode name and a pre-tokenized set of arguments, assemble
1094 the insn, but do not emit it.
1096 Note that this implies no macros allowed, since we can't store more
1097 than one insn in an insn structure. */
1099 static void
1100 assemble_tokens_to_insn (const char *opname,
1101 const expressionS *tok,
1102 int ntok,
1103 struct alpha_insn *insn)
1105 const struct alpha_opcode *opcode;
1107 /* Search opcodes. */
1108 opcode = (const struct alpha_opcode *) hash_find (alpha_opcode_hash, opname);
1109 if (opcode)
1111 int cpumatch;
1112 opcode = find_opcode_match (opcode, tok, &ntok, &cpumatch);
1113 if (opcode)
1115 assemble_insn (opcode, tok, ntok, insn, BFD_RELOC_UNUSED);
1116 return;
1118 else if (cpumatch)
1119 as_bad (_("inappropriate arguments for opcode `%s'"), opname);
1120 else
1121 as_bad (_("opcode `%s' not supported for target %s"), opname,
1122 alpha_target_name);
1124 else
1125 as_bad (_("unknown opcode `%s'"), opname);
1128 /* Build a BFD section with its flags set appropriately for the .lita,
1129 .lit8, or .lit4 sections. */
1131 static void
1132 create_literal_section (const char *name,
1133 segT *secp,
1134 symbolS **symp)
1136 segT current_section = now_seg;
1137 int current_subsec = now_subseg;
1138 segT new_sec;
1140 *secp = new_sec = subseg_new (name, 0);
1141 subseg_set (current_section, current_subsec);
1142 bfd_set_section_alignment (stdoutput, new_sec, 4);
1143 bfd_set_section_flags (stdoutput, new_sec,
1144 SEC_RELOC | SEC_ALLOC | SEC_LOAD | SEC_READONLY
1145 | SEC_DATA);
1147 S_CLEAR_EXTERNAL (*symp = section_symbol (new_sec));
1150 /* Load a (partial) expression into a target register.
1152 If poffset is not null, after the call it will either contain
1153 O_constant 0, or a 16-bit offset appropriate for any MEM format
1154 instruction. In addition, pbasereg will be modified to point to
1155 the base register to use in that MEM format instruction.
1157 In any case, *pbasereg should contain a base register to add to the
1158 expression. This will normally be either AXP_REG_ZERO or
1159 alpha_gp_register. Symbol addresses will always be loaded via $gp,
1160 so "foo($0)" is interpreted as adding the address of foo to $0;
1161 i.e. "ldq $targ, LIT($gp); addq $targ, $0, $targ". Odd, perhaps,
1162 but this is what OSF/1 does.
1164 If explicit relocations of the form !literal!<number> are allowed,
1165 and used, then explicit_reloc with be an expression pointer.
1167 Finally, the return value is nonzero if the calling macro may emit
1168 a LITUSE reloc if otherwise appropriate; the return value is the
1169 sequence number to use. */
1171 static long
1172 load_expression (int targreg,
1173 const expressionS *exp,
1174 int *pbasereg,
1175 expressionS *poffset)
1177 long emit_lituse = 0;
1178 offsetT addend = exp->X_add_number;
1179 int basereg = *pbasereg;
1180 struct alpha_insn insn;
1181 expressionS newtok[3];
1183 switch (exp->X_op)
1185 case O_symbol:
1187 #ifdef OBJ_ECOFF
1188 offsetT lit;
1190 /* Attempt to reduce .lit load by splitting the offset from
1191 its symbol when possible, but don't create a situation in
1192 which we'd fail. */
1193 if (!range_signed_32 (addend) &&
1194 (alpha_noat_on || targreg == AXP_REG_AT))
1196 lit = add_to_literal_pool (exp->X_add_symbol, addend,
1197 alpha_lita_section, 8);
1198 addend = 0;
1200 else
1201 lit = add_to_literal_pool (exp->X_add_symbol, 0,
1202 alpha_lita_section, 8);
1204 if (lit >= 0x8000)
1205 as_fatal (_("overflow in literal (.lita) table"));
1207 /* Emit "ldq r, lit(gp)". */
1209 if (basereg != alpha_gp_register && targreg == basereg)
1211 if (alpha_noat_on)
1212 as_bad (_("macro requires $at register while noat in effect"));
1213 if (targreg == AXP_REG_AT)
1214 as_bad (_("macro requires $at while $at in use"));
1216 set_tok_reg (newtok[0], AXP_REG_AT);
1218 else
1219 set_tok_reg (newtok[0], targreg);
1221 set_tok_sym (newtok[1], alpha_lita_symbol, lit);
1222 set_tok_preg (newtok[2], alpha_gp_register);
1224 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
1226 assert (insn.nfixups == 1);
1227 insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITERAL;
1228 insn.sequence = emit_lituse = next_sequence_num--;
1229 #endif /* OBJ_ECOFF */
1230 #ifdef OBJ_ELF
1231 /* Emit "ldq r, gotoff(gp)". */
1233 if (basereg != alpha_gp_register && targreg == basereg)
1235 if (alpha_noat_on)
1236 as_bad (_("macro requires $at register while noat in effect"));
1237 if (targreg == AXP_REG_AT)
1238 as_bad (_("macro requires $at while $at in use"));
1240 set_tok_reg (newtok[0], AXP_REG_AT);
1242 else
1243 set_tok_reg (newtok[0], targreg);
1245 /* XXX: Disable this .got minimizing optimization so that we can get
1246 better instruction offset knowledge in the compiler. This happens
1247 very infrequently anyway. */
1248 if (1
1249 || (!range_signed_32 (addend)
1250 && (alpha_noat_on || targreg == AXP_REG_AT)))
1252 newtok[1] = *exp;
1253 addend = 0;
1255 else
1256 set_tok_sym (newtok[1], exp->X_add_symbol, 0);
1258 set_tok_preg (newtok[2], alpha_gp_register);
1260 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
1262 assert (insn.nfixups == 1);
1263 insn.fixups[0].reloc = BFD_RELOC_ALPHA_ELF_LITERAL;
1264 insn.sequence = emit_lituse = next_sequence_num--;
1265 #endif /* OBJ_ELF */
1266 #ifdef OBJ_EVAX
1267 offsetT link;
1269 /* Find symbol or symbol pointer in link section. */
1271 if (exp->X_add_symbol == alpha_evax_proc.symbol)
1273 if (range_signed_16 (addend))
1275 set_tok_reg (newtok[0], targreg);
1276 set_tok_const (newtok[1], addend);
1277 set_tok_preg (newtok[2], basereg);
1278 assemble_tokens_to_insn ("lda", newtok, 3, &insn);
1279 addend = 0;
1281 else
1283 set_tok_reg (newtok[0], targreg);
1284 set_tok_const (newtok[1], 0);
1285 set_tok_preg (newtok[2], basereg);
1286 assemble_tokens_to_insn ("lda", newtok, 3, &insn);
1289 else
1291 if (!range_signed_32 (addend))
1293 link = add_to_link_pool (alpha_evax_proc.symbol,
1294 exp->X_add_symbol, addend);
1295 addend = 0;
1297 else
1298 link = add_to_link_pool (alpha_evax_proc.symbol,
1299 exp->X_add_symbol, 0);
1301 set_tok_reg (newtok[0], targreg);
1302 set_tok_const (newtok[1], link);
1303 set_tok_preg (newtok[2], basereg);
1304 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
1306 #endif /* OBJ_EVAX */
1308 emit_insn (&insn);
1310 #ifndef OBJ_EVAX
1311 if (basereg != alpha_gp_register && basereg != AXP_REG_ZERO)
1313 /* Emit "addq r, base, r". */
1315 set_tok_reg (newtok[1], basereg);
1316 set_tok_reg (newtok[2], targreg);
1317 assemble_tokens ("addq", newtok, 3, 0);
1319 #endif
1320 basereg = targreg;
1322 break;
1324 case O_constant:
1325 break;
1327 case O_subtract:
1328 /* Assume that this difference expression will be resolved to an
1329 absolute value and that that value will fit in 16 bits. */
1331 set_tok_reg (newtok[0], targreg);
1332 newtok[1] = *exp;
1333 set_tok_preg (newtok[2], basereg);
1334 assemble_tokens ("lda", newtok, 3, 0);
1336 if (poffset)
1337 set_tok_const (*poffset, 0);
1338 return 0;
1340 case O_big:
1341 if (exp->X_add_number > 0)
1342 as_bad (_("bignum invalid; zero assumed"));
1343 else
1344 as_bad (_("floating point number invalid; zero assumed"));
1345 addend = 0;
1346 break;
1348 default:
1349 as_bad (_("can't handle expression"));
1350 addend = 0;
1351 break;
1354 if (!range_signed_32 (addend))
1356 offsetT lit;
1357 long seq_num = next_sequence_num--;
1359 /* For 64-bit addends, just put it in the literal pool. */
1360 #ifdef OBJ_EVAX
1361 /* Emit "ldq targreg, lit(basereg)". */
1362 lit = add_to_link_pool (alpha_evax_proc.symbol,
1363 section_symbol (absolute_section), addend);
1364 set_tok_reg (newtok[0], targreg);
1365 set_tok_const (newtok[1], lit);
1366 set_tok_preg (newtok[2], alpha_gp_register);
1367 assemble_tokens ("ldq", newtok, 3, 0);
1368 #else
1370 if (alpha_lit8_section == NULL)
1372 create_literal_section (".lit8",
1373 &alpha_lit8_section,
1374 &alpha_lit8_symbol);
1376 #ifdef OBJ_ECOFF
1377 alpha_lit8_literal = add_to_literal_pool (alpha_lit8_symbol, 0x8000,
1378 alpha_lita_section, 8);
1379 if (alpha_lit8_literal >= 0x8000)
1380 as_fatal (_("overflow in literal (.lita) table"));
1381 #endif
1384 lit = add_to_literal_pool (NULL, addend, alpha_lit8_section, 8) - 0x8000;
1385 if (lit >= 0x8000)
1386 as_fatal (_("overflow in literal (.lit8) table"));
1388 /* Emit "lda litreg, .lit8+0x8000". */
1390 if (targreg == basereg)
1392 if (alpha_noat_on)
1393 as_bad (_("macro requires $at register while noat in effect"));
1394 if (targreg == AXP_REG_AT)
1395 as_bad (_("macro requires $at while $at in use"));
1397 set_tok_reg (newtok[0], AXP_REG_AT);
1399 else
1400 set_tok_reg (newtok[0], targreg);
1401 #ifdef OBJ_ECOFF
1402 set_tok_sym (newtok[1], alpha_lita_symbol, alpha_lit8_literal);
1403 #endif
1404 #ifdef OBJ_ELF
1405 set_tok_sym (newtok[1], alpha_lit8_symbol, 0x8000);
1406 #endif
1407 set_tok_preg (newtok[2], alpha_gp_register);
1409 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
1411 assert (insn.nfixups == 1);
1412 #ifdef OBJ_ECOFF
1413 insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITERAL;
1414 #endif
1415 #ifdef OBJ_ELF
1416 insn.fixups[0].reloc = BFD_RELOC_ALPHA_ELF_LITERAL;
1417 #endif
1418 insn.sequence = seq_num;
1420 emit_insn (&insn);
1422 /* Emit "ldq litreg, lit(litreg)". */
1424 set_tok_const (newtok[1], lit);
1425 set_tok_preg (newtok[2], newtok[0].X_add_number);
1427 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
1429 assert (insn.nfixups < MAX_INSN_FIXUPS);
1430 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
1431 insn.fixups[insn.nfixups].exp.X_op = O_absent;
1432 insn.nfixups++;
1433 insn.sequence = seq_num;
1434 emit_lituse = 0;
1436 emit_insn (&insn);
1438 /* Emit "addq litreg, base, target". */
1440 if (basereg != AXP_REG_ZERO)
1442 set_tok_reg (newtok[1], basereg);
1443 set_tok_reg (newtok[2], targreg);
1444 assemble_tokens ("addq", newtok, 3, 0);
1446 #endif /* !OBJ_EVAX */
1448 if (poffset)
1449 set_tok_const (*poffset, 0);
1450 *pbasereg = targreg;
1452 else
1454 offsetT low, high, extra, tmp;
1456 /* For 32-bit operands, break up the addend. */
1458 low = sign_extend_16 (addend);
1459 tmp = addend - low;
1460 high = sign_extend_16 (tmp >> 16);
1462 if (tmp - (high << 16))
1464 extra = 0x4000;
1465 tmp -= 0x40000000;
1466 high = sign_extend_16 (tmp >> 16);
1468 else
1469 extra = 0;
1471 set_tok_reg (newtok[0], targreg);
1472 set_tok_preg (newtok[2], basereg);
1474 if (extra)
1476 /* Emit "ldah r, extra(r). */
1477 set_tok_const (newtok[1], extra);
1478 assemble_tokens ("ldah", newtok, 3, 0);
1479 set_tok_preg (newtok[2], basereg = targreg);
1482 if (high)
1484 /* Emit "ldah r, high(r). */
1485 set_tok_const (newtok[1], high);
1486 assemble_tokens ("ldah", newtok, 3, 0);
1487 basereg = targreg;
1488 set_tok_preg (newtok[2], basereg);
1491 if ((low && !poffset) || (!poffset && basereg != targreg))
1493 /* Emit "lda r, low(base)". */
1494 set_tok_const (newtok[1], low);
1495 assemble_tokens ("lda", newtok, 3, 0);
1496 basereg = targreg;
1497 low = 0;
1500 if (poffset)
1501 set_tok_const (*poffset, low);
1502 *pbasereg = basereg;
1505 return emit_lituse;
1508 /* The lda macro differs from the lda instruction in that it handles
1509 most simple expressions, particularly symbol address loads and
1510 large constants. */
1512 static void
1513 emit_lda (const expressionS *tok,
1514 int ntok,
1515 const void * unused ATTRIBUTE_UNUSED)
1517 int basereg;
1519 if (ntok == 2)
1520 basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
1521 else
1522 basereg = tok[2].X_add_number;
1524 (void) load_expression (tok[0].X_add_number, &tok[1], &basereg, NULL);
1527 /* The ldah macro differs from the ldah instruction in that it has $31
1528 as an implied base register. */
1530 static void
1531 emit_ldah (const expressionS *tok,
1532 int ntok ATTRIBUTE_UNUSED,
1533 const void * unused ATTRIBUTE_UNUSED)
1535 expressionS newtok[3];
1537 newtok[0] = tok[0];
1538 newtok[1] = tok[1];
1539 set_tok_preg (newtok[2], AXP_REG_ZERO);
1541 assemble_tokens ("ldah", newtok, 3, 0);
1544 /* Called internally to handle all alignment needs. This takes care
1545 of eliding calls to frag_align if'n the cached current alignment
1546 says we've already got it, as well as taking care of the auto-align
1547 feature wrt labels. */
1549 static void
1550 alpha_align (int n,
1551 char *pfill,
1552 symbolS *label,
1553 int force ATTRIBUTE_UNUSED)
1555 if (alpha_current_align >= n)
1556 return;
1558 if (pfill == NULL)
1560 if (subseg_text_p (now_seg))
1561 frag_align_code (n, 0);
1562 else
1563 frag_align (n, 0, 0);
1565 else
1566 frag_align (n, *pfill, 0);
1568 alpha_current_align = n;
1570 if (label != NULL && S_GET_SEGMENT (label) == now_seg)
1572 symbol_set_frag (label, frag_now);
1573 S_SET_VALUE (label, (valueT) frag_now_fix ());
1576 record_alignment (now_seg, n);
1578 /* ??? If alpha_flag_relax && force && elf, record the requested alignment
1579 in a reloc for the linker to see. */
1582 /* Actually output an instruction with its fixup. */
1584 static void
1585 emit_insn (struct alpha_insn *insn)
1587 char *f;
1588 int i;
1590 /* Take care of alignment duties. */
1591 if (alpha_auto_align_on && alpha_current_align < 2)
1592 alpha_align (2, (char *) NULL, alpha_insn_label, 0);
1593 if (alpha_current_align > 2)
1594 alpha_current_align = 2;
1595 alpha_insn_label = NULL;
1597 /* Write out the instruction. */
1598 f = frag_more (4);
1599 md_number_to_chars (f, insn->insn, 4);
1601 #ifdef OBJ_ELF
1602 dwarf2_emit_insn (4);
1603 #endif
1605 /* Apply the fixups in order. */
1606 for (i = 0; i < insn->nfixups; ++i)
1608 const struct alpha_operand *operand = (const struct alpha_operand *) 0;
1609 struct alpha_fixup *fixup = &insn->fixups[i];
1610 struct alpha_reloc_tag *info = NULL;
1611 int size, pcrel;
1612 fixS *fixP;
1614 /* Some fixups are only used internally and so have no howto. */
1615 if ((int) fixup->reloc < 0)
1617 operand = &alpha_operands[-(int) fixup->reloc];
1618 size = 4;
1619 pcrel = ((operand->flags & AXP_OPERAND_RELATIVE) != 0);
1621 else if (fixup->reloc > BFD_RELOC_UNUSED
1622 || fixup->reloc == BFD_RELOC_ALPHA_GPDISP_HI16
1623 || fixup->reloc == BFD_RELOC_ALPHA_GPDISP_LO16)
1625 size = 2;
1626 pcrel = 0;
1628 else
1630 reloc_howto_type *reloc_howto
1631 = bfd_reloc_type_lookup (stdoutput, fixup->reloc);
1632 assert (reloc_howto);
1634 size = bfd_get_reloc_size (reloc_howto);
1635 assert (size >= 1 && size <= 4);
1637 pcrel = reloc_howto->pc_relative;
1640 fixP = fix_new_exp (frag_now, f - frag_now->fr_literal, size,
1641 &fixup->exp, pcrel, fixup->reloc);
1643 /* Turn off complaints that the addend is too large for some fixups,
1644 and copy in the sequence number for the explicit relocations. */
1645 switch (fixup->reloc)
1647 case BFD_RELOC_ALPHA_HINT:
1648 case BFD_RELOC_GPREL32:
1649 case BFD_RELOC_GPREL16:
1650 case BFD_RELOC_ALPHA_GPREL_HI16:
1651 case BFD_RELOC_ALPHA_GPREL_LO16:
1652 case BFD_RELOC_ALPHA_GOTDTPREL16:
1653 case BFD_RELOC_ALPHA_DTPREL_HI16:
1654 case BFD_RELOC_ALPHA_DTPREL_LO16:
1655 case BFD_RELOC_ALPHA_DTPREL16:
1656 case BFD_RELOC_ALPHA_GOTTPREL16:
1657 case BFD_RELOC_ALPHA_TPREL_HI16:
1658 case BFD_RELOC_ALPHA_TPREL_LO16:
1659 case BFD_RELOC_ALPHA_TPREL16:
1660 fixP->fx_no_overflow = 1;
1661 break;
1663 case BFD_RELOC_ALPHA_GPDISP_HI16:
1664 fixP->fx_no_overflow = 1;
1665 fixP->fx_addsy = section_symbol (now_seg);
1666 fixP->fx_offset = 0;
1668 info = get_alpha_reloc_tag (insn->sequence);
1669 if (++info->n_master > 1)
1670 as_bad (_("too many ldah insns for !gpdisp!%ld"), insn->sequence);
1671 if (info->segment != now_seg)
1672 as_bad (_("both insns for !gpdisp!%ld must be in the same section"),
1673 insn->sequence);
1674 fixP->tc_fix_data.info = info;
1675 break;
1677 case BFD_RELOC_ALPHA_GPDISP_LO16:
1678 fixP->fx_no_overflow = 1;
1680 info = get_alpha_reloc_tag (insn->sequence);
1681 if (++info->n_slaves > 1)
1682 as_bad (_("too many lda insns for !gpdisp!%ld"), insn->sequence);
1683 if (info->segment != now_seg)
1684 as_bad (_("both insns for !gpdisp!%ld must be in the same section"),
1685 insn->sequence);
1686 fixP->tc_fix_data.info = info;
1687 info->slaves = fixP;
1688 break;
1690 case BFD_RELOC_ALPHA_LITERAL:
1691 case BFD_RELOC_ALPHA_ELF_LITERAL:
1692 fixP->fx_no_overflow = 1;
1694 if (insn->sequence == 0)
1695 break;
1696 info = get_alpha_reloc_tag (insn->sequence);
1697 info->master = fixP;
1698 info->n_master++;
1699 if (info->segment != now_seg)
1700 info->multi_section_p = 1;
1701 fixP->tc_fix_data.info = info;
1702 break;
1704 #ifdef RELOC_OP_P
1705 case DUMMY_RELOC_LITUSE_ADDR:
1706 fixP->fx_offset = LITUSE_ALPHA_ADDR;
1707 goto do_lituse;
1708 case DUMMY_RELOC_LITUSE_BASE:
1709 fixP->fx_offset = LITUSE_ALPHA_BASE;
1710 goto do_lituse;
1711 case DUMMY_RELOC_LITUSE_BYTOFF:
1712 fixP->fx_offset = LITUSE_ALPHA_BYTOFF;
1713 goto do_lituse;
1714 case DUMMY_RELOC_LITUSE_JSR:
1715 fixP->fx_offset = LITUSE_ALPHA_JSR;
1716 goto do_lituse;
1717 case DUMMY_RELOC_LITUSE_TLSGD:
1718 fixP->fx_offset = LITUSE_ALPHA_TLSGD;
1719 goto do_lituse;
1720 case DUMMY_RELOC_LITUSE_TLSLDM:
1721 fixP->fx_offset = LITUSE_ALPHA_TLSLDM;
1722 goto do_lituse;
1723 do_lituse:
1724 fixP->fx_addsy = section_symbol (now_seg);
1725 fixP->fx_r_type = BFD_RELOC_ALPHA_LITUSE;
1727 info = get_alpha_reloc_tag (insn->sequence);
1728 if (fixup->reloc == DUMMY_RELOC_LITUSE_TLSGD)
1729 info->saw_lu_tlsgd = 1;
1730 else if (fixup->reloc == DUMMY_RELOC_LITUSE_TLSLDM)
1731 info->saw_lu_tlsldm = 1;
1732 if (++info->n_slaves > 1)
1734 if (info->saw_lu_tlsgd)
1735 as_bad (_("too many lituse insns for !lituse_tlsgd!%ld"),
1736 insn->sequence);
1737 else if (info->saw_lu_tlsldm)
1738 as_bad (_("too many lituse insns for !lituse_tlsldm!%ld"),
1739 insn->sequence);
1741 fixP->tc_fix_data.info = info;
1742 fixP->tc_fix_data.next_reloc = info->slaves;
1743 info->slaves = fixP;
1744 if (info->segment != now_seg)
1745 info->multi_section_p = 1;
1746 break;
1748 case BFD_RELOC_ALPHA_TLSGD:
1749 fixP->fx_no_overflow = 1;
1751 if (insn->sequence == 0)
1752 break;
1753 info = get_alpha_reloc_tag (insn->sequence);
1754 if (info->saw_tlsgd)
1755 as_bad (_("duplicate !tlsgd!%ld"), insn->sequence);
1756 else if (info->saw_tlsldm)
1757 as_bad (_("sequence number in use for !tlsldm!%ld"),
1758 insn->sequence);
1759 else
1760 info->saw_tlsgd = 1;
1761 fixP->tc_fix_data.info = info;
1762 break;
1764 case BFD_RELOC_ALPHA_TLSLDM:
1765 fixP->fx_no_overflow = 1;
1767 if (insn->sequence == 0)
1768 break;
1769 info = get_alpha_reloc_tag (insn->sequence);
1770 if (info->saw_tlsldm)
1771 as_bad (_("duplicate !tlsldm!%ld"), insn->sequence);
1772 else if (info->saw_tlsgd)
1773 as_bad (_("sequence number in use for !tlsgd!%ld"),
1774 insn->sequence);
1775 else
1776 info->saw_tlsldm = 1;
1777 fixP->tc_fix_data.info = info;
1778 break;
1779 #endif
1780 default:
1781 if ((int) fixup->reloc < 0)
1783 if (operand->flags & AXP_OPERAND_NOOVERFLOW)
1784 fixP->fx_no_overflow = 1;
1786 break;
1791 /* Insert an operand value into an instruction. */
1793 static unsigned
1794 insert_operand (unsigned insn,
1795 const struct alpha_operand *operand,
1796 offsetT val,
1797 char *file,
1798 unsigned line)
1800 if (operand->bits != 32 && !(operand->flags & AXP_OPERAND_NOOVERFLOW))
1802 offsetT min, max;
1804 if (operand->flags & AXP_OPERAND_SIGNED)
1806 max = (1 << (operand->bits - 1)) - 1;
1807 min = -(1 << (operand->bits - 1));
1809 else
1811 max = (1 << operand->bits) - 1;
1812 min = 0;
1815 if (val < min || val > max)
1816 as_warn_value_out_of_range (_("operand"), val, min, max, file, line);
1819 if (operand->insert)
1821 const char *errmsg = NULL;
1823 insn = (*operand->insert) (insn, val, &errmsg);
1824 if (errmsg)
1825 as_warn (errmsg);
1827 else
1828 insn |= ((val & ((1 << operand->bits) - 1)) << operand->shift);
1830 return insn;
1833 /* Turn an opcode description and a set of arguments into
1834 an instruction and a fixup. */
1836 static void
1837 assemble_insn (const struct alpha_opcode *opcode,
1838 const expressionS *tok,
1839 int ntok,
1840 struct alpha_insn *insn,
1841 bfd_reloc_code_real_type reloc)
1843 const struct alpha_operand *reloc_operand = NULL;
1844 const expressionS *reloc_exp = NULL;
1845 const unsigned char *argidx;
1846 unsigned image;
1847 int tokidx = 0;
1849 memset (insn, 0, sizeof (*insn));
1850 image = opcode->opcode;
1852 for (argidx = opcode->operands; *argidx; ++argidx)
1854 const struct alpha_operand *operand = &alpha_operands[*argidx];
1855 const expressionS *t = (const expressionS *) 0;
1857 if (operand->flags & AXP_OPERAND_FAKE)
1859 /* Fake operands take no value and generate no fixup. */
1860 image = insert_operand (image, operand, 0, NULL, 0);
1861 continue;
1864 if (tokidx >= ntok)
1866 switch (operand->flags & AXP_OPERAND_OPTIONAL_MASK)
1868 case AXP_OPERAND_DEFAULT_FIRST:
1869 t = &tok[0];
1870 break;
1871 case AXP_OPERAND_DEFAULT_SECOND:
1872 t = &tok[1];
1873 break;
1874 case AXP_OPERAND_DEFAULT_ZERO:
1876 static expressionS zero_exp;
1877 t = &zero_exp;
1878 zero_exp.X_op = O_constant;
1879 zero_exp.X_unsigned = 1;
1881 break;
1882 default:
1883 abort ();
1886 else
1887 t = &tok[tokidx++];
1889 switch (t->X_op)
1891 case O_register:
1892 case O_pregister:
1893 case O_cpregister:
1894 image = insert_operand (image, operand, regno (t->X_add_number),
1895 NULL, 0);
1896 break;
1898 case O_constant:
1899 image = insert_operand (image, operand, t->X_add_number, NULL, 0);
1900 assert (reloc_operand == NULL);
1901 reloc_operand = operand;
1902 reloc_exp = t;
1903 break;
1905 default:
1906 /* This is only 0 for fields that should contain registers,
1907 which means this pattern shouldn't have matched. */
1908 if (operand->default_reloc == 0)
1909 abort ();
1911 /* There is one special case for which an insn receives two
1912 relocations, and thus the user-supplied reloc does not
1913 override the operand reloc. */
1914 if (operand->default_reloc == BFD_RELOC_ALPHA_HINT)
1916 struct alpha_fixup *fixup;
1918 if (insn->nfixups >= MAX_INSN_FIXUPS)
1919 as_fatal (_("too many fixups"));
1921 fixup = &insn->fixups[insn->nfixups++];
1922 fixup->exp = *t;
1923 fixup->reloc = BFD_RELOC_ALPHA_HINT;
1925 else
1927 if (reloc == BFD_RELOC_UNUSED)
1928 reloc = operand->default_reloc;
1930 assert (reloc_operand == NULL);
1931 reloc_operand = operand;
1932 reloc_exp = t;
1934 break;
1938 if (reloc != BFD_RELOC_UNUSED)
1940 struct alpha_fixup *fixup;
1942 if (insn->nfixups >= MAX_INSN_FIXUPS)
1943 as_fatal (_("too many fixups"));
1945 /* ??? My but this is hacky. But the OSF/1 assembler uses the same
1946 relocation tag for both ldah and lda with gpdisp. Choose the
1947 correct internal relocation based on the opcode. */
1948 if (reloc == BFD_RELOC_ALPHA_GPDISP)
1950 if (strcmp (opcode->name, "ldah") == 0)
1951 reloc = BFD_RELOC_ALPHA_GPDISP_HI16;
1952 else if (strcmp (opcode->name, "lda") == 0)
1953 reloc = BFD_RELOC_ALPHA_GPDISP_LO16;
1954 else
1955 as_bad (_("invalid relocation for instruction"));
1958 /* If this is a real relocation (as opposed to a lituse hint), then
1959 the relocation width should match the operand width. */
1960 else if (reloc < BFD_RELOC_UNUSED)
1962 reloc_howto_type *reloc_howto
1963 = bfd_reloc_type_lookup (stdoutput, reloc);
1964 if (reloc_howto->bitsize != reloc_operand->bits)
1966 as_bad (_("invalid relocation for field"));
1967 return;
1971 fixup = &insn->fixups[insn->nfixups++];
1972 if (reloc_exp)
1973 fixup->exp = *reloc_exp;
1974 else
1975 fixup->exp.X_op = O_absent;
1976 fixup->reloc = reloc;
1979 insn->insn = image;
1982 /* Handle all "simple" integer register loads -- ldq, ldq_l, ldq_u,
1983 etc. They differ from the real instructions in that they do simple
1984 expressions like the lda macro. */
1986 static void
1987 emit_ir_load (const expressionS *tok,
1988 int ntok,
1989 const void * opname)
1991 int basereg;
1992 long lituse;
1993 expressionS newtok[3];
1994 struct alpha_insn insn;
1996 if (ntok == 2)
1997 basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
1998 else
1999 basereg = tok[2].X_add_number;
2001 lituse = load_expression (tok[0].X_add_number, &tok[1], &basereg,
2002 &newtok[1]);
2004 newtok[0] = tok[0];
2005 set_tok_preg (newtok[2], basereg);
2007 assemble_tokens_to_insn ((const char *) opname, newtok, 3, &insn);
2009 if (lituse)
2011 assert (insn.nfixups < MAX_INSN_FIXUPS);
2012 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
2013 insn.fixups[insn.nfixups].exp.X_op = O_absent;
2014 insn.nfixups++;
2015 insn.sequence = lituse;
2018 emit_insn (&insn);
2021 /* Handle fp register loads, and both integer and fp register stores.
2022 Again, we handle simple expressions. */
2024 static void
2025 emit_loadstore (const expressionS *tok,
2026 int ntok,
2027 const void * opname)
2029 int basereg;
2030 long lituse;
2031 expressionS newtok[3];
2032 struct alpha_insn insn;
2034 if (ntok == 2)
2035 basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
2036 else
2037 basereg = tok[2].X_add_number;
2039 if (tok[1].X_op != O_constant || !range_signed_16 (tok[1].X_add_number))
2041 if (alpha_noat_on)
2042 as_bad (_("macro requires $at register while noat in effect"));
2044 lituse = load_expression (AXP_REG_AT, &tok[1], &basereg, &newtok[1]);
2046 else
2048 newtok[1] = tok[1];
2049 lituse = 0;
2052 newtok[0] = tok[0];
2053 set_tok_preg (newtok[2], basereg);
2055 assemble_tokens_to_insn ((const char *) opname, newtok, 3, &insn);
2057 if (lituse)
2059 assert (insn.nfixups < MAX_INSN_FIXUPS);
2060 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
2061 insn.fixups[insn.nfixups].exp.X_op = O_absent;
2062 insn.nfixups++;
2063 insn.sequence = lituse;
2066 emit_insn (&insn);
2069 /* Load a half-word or byte as an unsigned value. */
2071 static void
2072 emit_ldXu (const expressionS *tok,
2073 int ntok,
2074 const void * vlgsize)
2076 if (alpha_target & AXP_OPCODE_BWX)
2077 emit_ir_load (tok, ntok, ldXu_op[(long) vlgsize]);
2078 else
2080 expressionS newtok[3];
2081 struct alpha_insn insn;
2082 int basereg;
2083 long lituse;
2085 if (alpha_noat_on)
2086 as_bad (_("macro requires $at register while noat in effect"));
2088 if (ntok == 2)
2089 basereg = (tok[1].X_op == O_constant
2090 ? AXP_REG_ZERO : alpha_gp_register);
2091 else
2092 basereg = tok[2].X_add_number;
2094 /* Emit "lda $at, exp". */
2095 lituse = load_expression (AXP_REG_AT, &tok[1], &basereg, NULL);
2097 /* Emit "ldq_u targ, 0($at)". */
2098 newtok[0] = tok[0];
2099 set_tok_const (newtok[1], 0);
2100 set_tok_preg (newtok[2], basereg);
2101 assemble_tokens_to_insn ("ldq_u", newtok, 3, &insn);
2103 if (lituse)
2105 assert (insn.nfixups < MAX_INSN_FIXUPS);
2106 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
2107 insn.fixups[insn.nfixups].exp.X_op = O_absent;
2108 insn.nfixups++;
2109 insn.sequence = lituse;
2112 emit_insn (&insn);
2114 /* Emit "extXl targ, $at, targ". */
2115 set_tok_reg (newtok[1], basereg);
2116 newtok[2] = newtok[0];
2117 assemble_tokens_to_insn (extXl_op[(long) vlgsize], newtok, 3, &insn);
2119 if (lituse)
2121 assert (insn.nfixups < MAX_INSN_FIXUPS);
2122 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF;
2123 insn.fixups[insn.nfixups].exp.X_op = O_absent;
2124 insn.nfixups++;
2125 insn.sequence = lituse;
2128 emit_insn (&insn);
2132 /* Load a half-word or byte as a signed value. */
2134 static void
2135 emit_ldX (const expressionS *tok,
2136 int ntok,
2137 const void * vlgsize)
2139 emit_ldXu (tok, ntok, vlgsize);
2140 assemble_tokens (sextX_op[(long) vlgsize], tok, 1, 1);
2143 /* Load an integral value from an unaligned address as an unsigned
2144 value. */
2146 static void
2147 emit_uldXu (const expressionS *tok,
2148 int ntok,
2149 const void * vlgsize)
2151 long lgsize = (long) vlgsize;
2152 expressionS newtok[3];
2154 if (alpha_noat_on)
2155 as_bad (_("macro requires $at register while noat in effect"));
2157 /* Emit "lda $at, exp". */
2158 memcpy (newtok, tok, sizeof (expressionS) * ntok);
2159 newtok[0].X_add_number = AXP_REG_AT;
2160 assemble_tokens ("lda", newtok, ntok, 1);
2162 /* Emit "ldq_u $t9, 0($at)". */
2163 set_tok_reg (newtok[0], AXP_REG_T9);
2164 set_tok_const (newtok[1], 0);
2165 set_tok_preg (newtok[2], AXP_REG_AT);
2166 assemble_tokens ("ldq_u", newtok, 3, 1);
2168 /* Emit "ldq_u $t10, size-1($at)". */
2169 set_tok_reg (newtok[0], AXP_REG_T10);
2170 set_tok_const (newtok[1], (1 << lgsize) - 1);
2171 assemble_tokens ("ldq_u", newtok, 3, 1);
2173 /* Emit "extXl $t9, $at, $t9". */
2174 set_tok_reg (newtok[0], AXP_REG_T9);
2175 set_tok_reg (newtok[1], AXP_REG_AT);
2176 set_tok_reg (newtok[2], AXP_REG_T9);
2177 assemble_tokens (extXl_op[lgsize], newtok, 3, 1);
2179 /* Emit "extXh $t10, $at, $t10". */
2180 set_tok_reg (newtok[0], AXP_REG_T10);
2181 set_tok_reg (newtok[2], AXP_REG_T10);
2182 assemble_tokens (extXh_op[lgsize], newtok, 3, 1);
2184 /* Emit "or $t9, $t10, targ". */
2185 set_tok_reg (newtok[0], AXP_REG_T9);
2186 set_tok_reg (newtok[1], AXP_REG_T10);
2187 newtok[2] = tok[0];
2188 assemble_tokens ("or", newtok, 3, 1);
2191 /* Load an integral value from an unaligned address as a signed value.
2192 Note that quads should get funneled to the unsigned load since we
2193 don't have to do the sign extension. */
2195 static void
2196 emit_uldX (const expressionS *tok,
2197 int ntok,
2198 const void * vlgsize)
2200 emit_uldXu (tok, ntok, vlgsize);
2201 assemble_tokens (sextX_op[(long) vlgsize], tok, 1, 1);
2204 /* Implement the ldil macro. */
2206 static void
2207 emit_ldil (const expressionS *tok,
2208 int ntok,
2209 const void * unused ATTRIBUTE_UNUSED)
2211 expressionS newtok[2];
2213 memcpy (newtok, tok, sizeof (newtok));
2214 newtok[1].X_add_number = sign_extend_32 (tok[1].X_add_number);
2216 assemble_tokens ("lda", newtok, ntok, 1);
2219 /* Store a half-word or byte. */
2221 static void
2222 emit_stX (const expressionS *tok,
2223 int ntok,
2224 const void * vlgsize)
2226 int lgsize = (int) (long) vlgsize;
2228 if (alpha_target & AXP_OPCODE_BWX)
2229 emit_loadstore (tok, ntok, stX_op[lgsize]);
2230 else
2232 expressionS newtok[3];
2233 struct alpha_insn insn;
2234 int basereg;
2235 long lituse;
2237 if (alpha_noat_on)
2238 as_bad (_("macro requires $at register while noat in effect"));
2240 if (ntok == 2)
2241 basereg = (tok[1].X_op == O_constant
2242 ? AXP_REG_ZERO : alpha_gp_register);
2243 else
2244 basereg = tok[2].X_add_number;
2246 /* Emit "lda $at, exp". */
2247 lituse = load_expression (AXP_REG_AT, &tok[1], &basereg, NULL);
2249 /* Emit "ldq_u $t9, 0($at)". */
2250 set_tok_reg (newtok[0], AXP_REG_T9);
2251 set_tok_const (newtok[1], 0);
2252 set_tok_preg (newtok[2], basereg);
2253 assemble_tokens_to_insn ("ldq_u", newtok, 3, &insn);
2255 if (lituse)
2257 assert (insn.nfixups < MAX_INSN_FIXUPS);
2258 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
2259 insn.fixups[insn.nfixups].exp.X_op = O_absent;
2260 insn.nfixups++;
2261 insn.sequence = lituse;
2264 emit_insn (&insn);
2266 /* Emit "insXl src, $at, $t10". */
2267 newtok[0] = tok[0];
2268 set_tok_reg (newtok[1], basereg);
2269 set_tok_reg (newtok[2], AXP_REG_T10);
2270 assemble_tokens_to_insn (insXl_op[lgsize], newtok, 3, &insn);
2272 if (lituse)
2274 assert (insn.nfixups < MAX_INSN_FIXUPS);
2275 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF;
2276 insn.fixups[insn.nfixups].exp.X_op = O_absent;
2277 insn.nfixups++;
2278 insn.sequence = lituse;
2281 emit_insn (&insn);
2283 /* Emit "mskXl $t9, $at, $t9". */
2284 set_tok_reg (newtok[0], AXP_REG_T9);
2285 newtok[2] = newtok[0];
2286 assemble_tokens_to_insn (mskXl_op[lgsize], newtok, 3, &insn);
2288 if (lituse)
2290 assert (insn.nfixups < MAX_INSN_FIXUPS);
2291 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF;
2292 insn.fixups[insn.nfixups].exp.X_op = O_absent;
2293 insn.nfixups++;
2294 insn.sequence = lituse;
2297 emit_insn (&insn);
2299 /* Emit "or $t9, $t10, $t9". */
2300 set_tok_reg (newtok[1], AXP_REG_T10);
2301 assemble_tokens ("or", newtok, 3, 1);
2303 /* Emit "stq_u $t9, 0($at). */
2304 set_tok_const(newtok[1], 0);
2305 set_tok_preg (newtok[2], AXP_REG_AT);
2306 assemble_tokens_to_insn ("stq_u", newtok, 3, &insn);
2308 if (lituse)
2310 assert (insn.nfixups < MAX_INSN_FIXUPS);
2311 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
2312 insn.fixups[insn.nfixups].exp.X_op = O_absent;
2313 insn.nfixups++;
2314 insn.sequence = lituse;
2317 emit_insn (&insn);
2321 /* Store an integer to an unaligned address. */
2323 static void
2324 emit_ustX (const expressionS *tok,
2325 int ntok,
2326 const void * vlgsize)
2328 int lgsize = (int) (long) vlgsize;
2329 expressionS newtok[3];
2331 /* Emit "lda $at, exp". */
2332 memcpy (newtok, tok, sizeof (expressionS) * ntok);
2333 newtok[0].X_add_number = AXP_REG_AT;
2334 assemble_tokens ("lda", newtok, ntok, 1);
2336 /* Emit "ldq_u $9, 0($at)". */
2337 set_tok_reg (newtok[0], AXP_REG_T9);
2338 set_tok_const (newtok[1], 0);
2339 set_tok_preg (newtok[2], AXP_REG_AT);
2340 assemble_tokens ("ldq_u", newtok, 3, 1);
2342 /* Emit "ldq_u $10, size-1($at)". */
2343 set_tok_reg (newtok[0], AXP_REG_T10);
2344 set_tok_const (newtok[1], (1 << lgsize) - 1);
2345 assemble_tokens ("ldq_u", newtok, 3, 1);
2347 /* Emit "insXl src, $at, $t11". */
2348 newtok[0] = tok[0];
2349 set_tok_reg (newtok[1], AXP_REG_AT);
2350 set_tok_reg (newtok[2], AXP_REG_T11);
2351 assemble_tokens (insXl_op[lgsize], newtok, 3, 1);
2353 /* Emit "insXh src, $at, $t12". */
2354 set_tok_reg (newtok[2], AXP_REG_T12);
2355 assemble_tokens (insXh_op[lgsize], newtok, 3, 1);
2357 /* Emit "mskXl $t9, $at, $t9". */
2358 set_tok_reg (newtok[0], AXP_REG_T9);
2359 newtok[2] = newtok[0];
2360 assemble_tokens (mskXl_op[lgsize], newtok, 3, 1);
2362 /* Emit "mskXh $t10, $at, $t10". */
2363 set_tok_reg (newtok[0], AXP_REG_T10);
2364 newtok[2] = newtok[0];
2365 assemble_tokens (mskXh_op[lgsize], newtok, 3, 1);
2367 /* Emit "or $t9, $t11, $t9". */
2368 set_tok_reg (newtok[0], AXP_REG_T9);
2369 set_tok_reg (newtok[1], AXP_REG_T11);
2370 newtok[2] = newtok[0];
2371 assemble_tokens ("or", newtok, 3, 1);
2373 /* Emit "or $t10, $t12, $t10". */
2374 set_tok_reg (newtok[0], AXP_REG_T10);
2375 set_tok_reg (newtok[1], AXP_REG_T12);
2376 newtok[2] = newtok[0];
2377 assemble_tokens ("or", newtok, 3, 1);
2379 /* Emit "stq_u $t9, 0($at)". */
2380 set_tok_reg (newtok[0], AXP_REG_T9);
2381 set_tok_const (newtok[1], 0);
2382 set_tok_preg (newtok[2], AXP_REG_AT);
2383 assemble_tokens ("stq_u", newtok, 3, 1);
2385 /* Emit "stq_u $t10, size-1($at)". */
2386 set_tok_reg (newtok[0], AXP_REG_T10);
2387 set_tok_const (newtok[1], (1 << lgsize) - 1);
2388 assemble_tokens ("stq_u", newtok, 3, 1);
2391 /* Sign extend a half-word or byte. The 32-bit sign extend is
2392 implemented as "addl $31, $r, $t" in the opcode table. */
2394 static void
2395 emit_sextX (const expressionS *tok,
2396 int ntok,
2397 const void * vlgsize)
2399 long lgsize = (long) vlgsize;
2401 if (alpha_target & AXP_OPCODE_BWX)
2402 assemble_tokens (sextX_op[lgsize], tok, ntok, 0);
2403 else
2405 int bitshift = 64 - 8 * (1 << lgsize);
2406 expressionS newtok[3];
2408 /* Emit "sll src,bits,dst". */
2409 newtok[0] = tok[0];
2410 set_tok_const (newtok[1], bitshift);
2411 newtok[2] = tok[ntok - 1];
2412 assemble_tokens ("sll", newtok, 3, 1);
2414 /* Emit "sra dst,bits,dst". */
2415 newtok[0] = newtok[2];
2416 assemble_tokens ("sra", newtok, 3, 1);
2420 /* Implement the division and modulus macros. */
2422 #ifdef OBJ_EVAX
2424 /* Make register usage like in normal procedure call.
2425 Don't clobber PV and RA. */
2427 static void
2428 emit_division (const expressionS *tok,
2429 int ntok,
2430 const void * symname)
2432 /* DIVISION and MODULUS. Yech.
2434 Convert
2435 OP x,y,result
2437 mov x,R16 # if x != R16
2438 mov y,R17 # if y != R17
2439 lda AT,__OP
2440 jsr AT,(AT),0
2441 mov R0,result
2443 with appropriate optimizations if R0,R16,R17 are the registers
2444 specified by the compiler. */
2446 int xr, yr, rr;
2447 symbolS *sym;
2448 expressionS newtok[3];
2450 xr = regno (tok[0].X_add_number);
2451 yr = regno (tok[1].X_add_number);
2453 if (ntok < 3)
2454 rr = xr;
2455 else
2456 rr = regno (tok[2].X_add_number);
2458 /* Move the operands into the right place. */
2459 if (yr == AXP_REG_R16 && xr == AXP_REG_R17)
2461 /* They are in exactly the wrong order -- swap through AT. */
2462 if (alpha_noat_on)
2463 as_bad (_("macro requires $at register while noat in effect"));
2465 set_tok_reg (newtok[0], AXP_REG_R16);
2466 set_tok_reg (newtok[1], AXP_REG_AT);
2467 assemble_tokens ("mov", newtok, 2, 1);
2469 set_tok_reg (newtok[0], AXP_REG_R17);
2470 set_tok_reg (newtok[1], AXP_REG_R16);
2471 assemble_tokens ("mov", newtok, 2, 1);
2473 set_tok_reg (newtok[0], AXP_REG_AT);
2474 set_tok_reg (newtok[1], AXP_REG_R17);
2475 assemble_tokens ("mov", newtok, 2, 1);
2477 else
2479 if (yr == AXP_REG_R16)
2481 set_tok_reg (newtok[0], AXP_REG_R16);
2482 set_tok_reg (newtok[1], AXP_REG_R17);
2483 assemble_tokens ("mov", newtok, 2, 1);
2486 if (xr != AXP_REG_R16)
2488 set_tok_reg (newtok[0], xr);
2489 set_tok_reg (newtok[1], AXP_REG_R16);
2490 assemble_tokens ("mov", newtok, 2, 1);
2493 if (yr != AXP_REG_R16 && yr != AXP_REG_R17)
2495 set_tok_reg (newtok[0], yr);
2496 set_tok_reg (newtok[1], AXP_REG_R17);
2497 assemble_tokens ("mov", newtok, 2, 1);
2501 sym = symbol_find_or_make ((const char *) symname);
2503 set_tok_reg (newtok[0], AXP_REG_AT);
2504 set_tok_sym (newtok[1], sym, 0);
2505 assemble_tokens ("lda", newtok, 2, 1);
2507 /* Call the division routine. */
2508 set_tok_reg (newtok[0], AXP_REG_AT);
2509 set_tok_cpreg (newtok[1], AXP_REG_AT);
2510 set_tok_const (newtok[2], 0);
2511 assemble_tokens ("jsr", newtok, 3, 1);
2513 /* Move the result to the right place. */
2514 if (rr != AXP_REG_R0)
2516 set_tok_reg (newtok[0], AXP_REG_R0);
2517 set_tok_reg (newtok[1], rr);
2518 assemble_tokens ("mov", newtok, 2, 1);
2522 #else /* !OBJ_EVAX */
2524 static void
2525 emit_division (const expressionS *tok,
2526 int ntok,
2527 const void * symname)
2529 /* DIVISION and MODULUS. Yech.
2530 Convert
2531 OP x,y,result
2533 lda pv,__OP
2534 mov x,t10
2535 mov y,t11
2536 jsr t9,(pv),__OP
2537 mov t12,result
2539 with appropriate optimizations if t10,t11,t12 are the registers
2540 specified by the compiler. */
2542 int xr, yr, rr;
2543 symbolS *sym;
2544 expressionS newtok[3];
2546 xr = regno (tok[0].X_add_number);
2547 yr = regno (tok[1].X_add_number);
2549 if (ntok < 3)
2550 rr = xr;
2551 else
2552 rr = regno (tok[2].X_add_number);
2554 sym = symbol_find_or_make ((const char *) symname);
2556 /* Move the operands into the right place. */
2557 if (yr == AXP_REG_T10 && xr == AXP_REG_T11)
2559 /* They are in exactly the wrong order -- swap through AT. */
2560 if (alpha_noat_on)
2561 as_bad (_("macro requires $at register while noat in effect"));
2563 set_tok_reg (newtok[0], AXP_REG_T10);
2564 set_tok_reg (newtok[1], AXP_REG_AT);
2565 assemble_tokens ("mov", newtok, 2, 1);
2567 set_tok_reg (newtok[0], AXP_REG_T11);
2568 set_tok_reg (newtok[1], AXP_REG_T10);
2569 assemble_tokens ("mov", newtok, 2, 1);
2571 set_tok_reg (newtok[0], AXP_REG_AT);
2572 set_tok_reg (newtok[1], AXP_REG_T11);
2573 assemble_tokens ("mov", newtok, 2, 1);
2575 else
2577 if (yr == AXP_REG_T10)
2579 set_tok_reg (newtok[0], AXP_REG_T10);
2580 set_tok_reg (newtok[1], AXP_REG_T11);
2581 assemble_tokens ("mov", newtok, 2, 1);
2584 if (xr != AXP_REG_T10)
2586 set_tok_reg (newtok[0], xr);
2587 set_tok_reg (newtok[1], AXP_REG_T10);
2588 assemble_tokens ("mov", newtok, 2, 1);
2591 if (yr != AXP_REG_T10 && yr != AXP_REG_T11)
2593 set_tok_reg (newtok[0], yr);
2594 set_tok_reg (newtok[1], AXP_REG_T11);
2595 assemble_tokens ("mov", newtok, 2, 1);
2599 /* Call the division routine. */
2600 set_tok_reg (newtok[0], AXP_REG_T9);
2601 set_tok_sym (newtok[1], sym, 0);
2602 assemble_tokens ("jsr", newtok, 2, 1);
2604 /* Reload the GP register. */
2605 #ifdef OBJ_AOUT
2606 FIXME
2607 #endif
2608 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
2609 set_tok_reg (newtok[0], alpha_gp_register);
2610 set_tok_const (newtok[1], 0);
2611 set_tok_preg (newtok[2], AXP_REG_T9);
2612 assemble_tokens ("ldgp", newtok, 3, 1);
2613 #endif
2615 /* Move the result to the right place. */
2616 if (rr != AXP_REG_T12)
2618 set_tok_reg (newtok[0], AXP_REG_T12);
2619 set_tok_reg (newtok[1], rr);
2620 assemble_tokens ("mov", newtok, 2, 1);
2624 #endif /* !OBJ_EVAX */
2626 /* The jsr and jmp macros differ from their instruction counterparts
2627 in that they can load the target address and default most
2628 everything. */
2630 static void
2631 emit_jsrjmp (const expressionS *tok,
2632 int ntok,
2633 const void * vopname)
2635 const char *opname = (const char *) vopname;
2636 struct alpha_insn insn;
2637 expressionS newtok[3];
2638 int r, tokidx = 0;
2639 long lituse = 0;
2641 if (tokidx < ntok && tok[tokidx].X_op == O_register)
2642 r = regno (tok[tokidx++].X_add_number);
2643 else
2644 r = strcmp (opname, "jmp") == 0 ? AXP_REG_ZERO : AXP_REG_RA;
2646 set_tok_reg (newtok[0], r);
2648 if (tokidx < ntok &&
2649 (tok[tokidx].X_op == O_pregister || tok[tokidx].X_op == O_cpregister))
2650 r = regno (tok[tokidx++].X_add_number);
2651 #ifdef OBJ_EVAX
2652 /* Keep register if jsr $n.<sym>. */
2653 #else
2654 else
2656 int basereg = alpha_gp_register;
2657 lituse = load_expression (r = AXP_REG_PV, &tok[tokidx], &basereg, NULL);
2659 #endif
2661 set_tok_cpreg (newtok[1], r);
2663 #ifdef OBJ_EVAX
2664 /* FIXME: Add hint relocs to BFD for evax. */
2665 #else
2666 if (tokidx < ntok)
2667 newtok[2] = tok[tokidx];
2668 else
2669 #endif
2670 set_tok_const (newtok[2], 0);
2672 assemble_tokens_to_insn (opname, newtok, 3, &insn);
2674 if (lituse)
2676 assert (insn.nfixups < MAX_INSN_FIXUPS);
2677 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_JSR;
2678 insn.fixups[insn.nfixups].exp.X_op = O_absent;
2679 insn.nfixups++;
2680 insn.sequence = lituse;
2683 emit_insn (&insn);
2686 /* The ret and jcr instructions differ from their instruction
2687 counterparts in that everything can be defaulted. */
2689 static void
2690 emit_retjcr (const expressionS *tok,
2691 int ntok,
2692 const void * vopname)
2694 const char *opname = (const char *) vopname;
2695 expressionS newtok[3];
2696 int r, tokidx = 0;
2698 if (tokidx < ntok && tok[tokidx].X_op == O_register)
2699 r = regno (tok[tokidx++].X_add_number);
2700 else
2701 r = AXP_REG_ZERO;
2703 set_tok_reg (newtok[0], r);
2705 if (tokidx < ntok &&
2706 (tok[tokidx].X_op == O_pregister || tok[tokidx].X_op == O_cpregister))
2707 r = regno (tok[tokidx++].X_add_number);
2708 else
2709 r = AXP_REG_RA;
2711 set_tok_cpreg (newtok[1], r);
2713 if (tokidx < ntok)
2714 newtok[2] = tok[tokidx];
2715 else
2716 set_tok_const (newtok[2], strcmp (opname, "ret") == 0);
2718 assemble_tokens (opname, newtok, 3, 0);
2721 /* Implement the ldgp macro. */
2723 static void
2724 emit_ldgp (const expressionS *tok,
2725 int ntok ATTRIBUTE_UNUSED,
2726 const void * unused ATTRIBUTE_UNUSED)
2728 #ifdef OBJ_AOUT
2729 FIXME
2730 #endif
2731 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
2732 /* from "ldgp r1,n(r2)", generate "ldah r1,X(R2); lda r1,Y(r1)"
2733 with appropriate constants and relocations. */
2734 struct alpha_insn insn;
2735 expressionS newtok[3];
2736 expressionS addend;
2738 #ifdef OBJ_ECOFF
2739 if (regno (tok[2].X_add_number) == AXP_REG_PV)
2740 ecoff_set_gp_prolog_size (0);
2741 #endif
2743 newtok[0] = tok[0];
2744 set_tok_const (newtok[1], 0);
2745 newtok[2] = tok[2];
2747 assemble_tokens_to_insn ("ldah", newtok, 3, &insn);
2749 addend = tok[1];
2751 #ifdef OBJ_ECOFF
2752 if (addend.X_op != O_constant)
2753 as_bad (_("can not resolve expression"));
2754 addend.X_op = O_symbol;
2755 addend.X_add_symbol = alpha_gp_symbol;
2756 #endif
2758 insn.nfixups = 1;
2759 insn.fixups[0].exp = addend;
2760 insn.fixups[0].reloc = BFD_RELOC_ALPHA_GPDISP_HI16;
2761 insn.sequence = next_sequence_num;
2763 emit_insn (&insn);
2765 set_tok_preg (newtok[2], tok[0].X_add_number);
2767 assemble_tokens_to_insn ("lda", newtok, 3, &insn);
2769 #ifdef OBJ_ECOFF
2770 addend.X_add_number += 4;
2771 #endif
2773 insn.nfixups = 1;
2774 insn.fixups[0].exp = addend;
2775 insn.fixups[0].reloc = BFD_RELOC_ALPHA_GPDISP_LO16;
2776 insn.sequence = next_sequence_num--;
2778 emit_insn (&insn);
2779 #endif /* OBJ_ECOFF || OBJ_ELF */
2782 /* The macro table. */
2784 static const struct alpha_macro alpha_macros[] =
2786 /* Load/Store macros. */
2787 { "lda", emit_lda, NULL,
2788 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2789 { "ldah", emit_ldah, NULL,
2790 { MACRO_IR, MACRO_EXP, MACRO_EOA } },
2792 { "ldl", emit_ir_load, "ldl",
2793 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2794 { "ldl_l", emit_ir_load, "ldl_l",
2795 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2796 { "ldq", emit_ir_load, "ldq",
2797 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2798 { "ldq_l", emit_ir_load, "ldq_l",
2799 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2800 { "ldq_u", emit_ir_load, "ldq_u",
2801 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2802 { "ldf", emit_loadstore, "ldf",
2803 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2804 { "ldg", emit_loadstore, "ldg",
2805 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2806 { "lds", emit_loadstore, "lds",
2807 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2808 { "ldt", emit_loadstore, "ldt",
2809 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2811 { "ldb", emit_ldX, (void *) 0,
2812 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2813 { "ldbu", emit_ldXu, (void *) 0,
2814 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2815 { "ldw", emit_ldX, (void *) 1,
2816 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2817 { "ldwu", emit_ldXu, (void *) 1,
2818 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2820 { "uldw", emit_uldX, (void *) 1,
2821 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2822 { "uldwu", emit_uldXu, (void *) 1,
2823 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2824 { "uldl", emit_uldX, (void *) 2,
2825 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2826 { "uldlu", emit_uldXu, (void *) 2,
2827 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2828 { "uldq", emit_uldXu, (void *) 3,
2829 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2831 { "ldgp", emit_ldgp, NULL,
2832 { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA } },
2834 { "ldi", emit_lda, NULL,
2835 { MACRO_IR, MACRO_EXP, MACRO_EOA } },
2836 { "ldil", emit_ldil, NULL,
2837 { MACRO_IR, MACRO_EXP, MACRO_EOA } },
2838 { "ldiq", emit_lda, NULL,
2839 { MACRO_IR, MACRO_EXP, MACRO_EOA } },
2841 { "stl", emit_loadstore, "stl",
2842 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2843 { "stl_c", emit_loadstore, "stl_c",
2844 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2845 { "stq", emit_loadstore, "stq",
2846 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2847 { "stq_c", emit_loadstore, "stq_c",
2848 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2849 { "stq_u", emit_loadstore, "stq_u",
2850 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2851 { "stf", emit_loadstore, "stf",
2852 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2853 { "stg", emit_loadstore, "stg",
2854 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2855 { "sts", emit_loadstore, "sts",
2856 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2857 { "stt", emit_loadstore, "stt",
2858 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2860 { "stb", emit_stX, (void *) 0,
2861 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2862 { "stw", emit_stX, (void *) 1,
2863 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2864 { "ustw", emit_ustX, (void *) 1,
2865 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2866 { "ustl", emit_ustX, (void *) 2,
2867 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2868 { "ustq", emit_ustX, (void *) 3,
2869 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2871 /* Arithmetic macros. */
2873 { "sextb", emit_sextX, (void *) 0,
2874 { MACRO_IR, MACRO_IR, MACRO_EOA,
2875 MACRO_IR, MACRO_EOA,
2876 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
2877 { "sextw", emit_sextX, (void *) 1,
2878 { MACRO_IR, MACRO_IR, MACRO_EOA,
2879 MACRO_IR, MACRO_EOA,
2880 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
2882 { "divl", emit_division, "__divl",
2883 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
2884 MACRO_IR, MACRO_IR, MACRO_EOA,
2885 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
2886 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
2887 { "divlu", emit_division, "__divlu",
2888 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
2889 MACRO_IR, MACRO_IR, MACRO_EOA,
2890 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
2891 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
2892 { "divq", emit_division, "__divq",
2893 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
2894 MACRO_IR, MACRO_IR, MACRO_EOA,
2895 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
2896 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
2897 { "divqu", emit_division, "__divqu",
2898 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
2899 MACRO_IR, MACRO_IR, MACRO_EOA,
2900 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
2901 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
2902 { "reml", emit_division, "__reml",
2903 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
2904 MACRO_IR, MACRO_IR, MACRO_EOA,
2905 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
2906 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
2907 { "remlu", emit_division, "__remlu",
2908 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
2909 MACRO_IR, MACRO_IR, MACRO_EOA,
2910 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
2911 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
2912 { "remq", emit_division, "__remq",
2913 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
2914 MACRO_IR, MACRO_IR, MACRO_EOA,
2915 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
2916 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
2917 { "remqu", emit_division, "__remqu",
2918 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
2919 MACRO_IR, MACRO_IR, MACRO_EOA,
2920 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
2921 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
2923 { "jsr", emit_jsrjmp, "jsr",
2924 { MACRO_PIR, MACRO_EXP, MACRO_EOA,
2925 MACRO_PIR, MACRO_EOA,
2926 MACRO_IR, MACRO_EXP, MACRO_EOA,
2927 MACRO_EXP, MACRO_EOA } },
2928 { "jmp", emit_jsrjmp, "jmp",
2929 { MACRO_PIR, MACRO_EXP, MACRO_EOA,
2930 MACRO_PIR, MACRO_EOA,
2931 MACRO_IR, MACRO_EXP, MACRO_EOA,
2932 MACRO_EXP, MACRO_EOA } },
2933 { "ret", emit_retjcr, "ret",
2934 { MACRO_IR, MACRO_EXP, MACRO_EOA,
2935 MACRO_IR, MACRO_EOA,
2936 MACRO_PIR, MACRO_EXP, MACRO_EOA,
2937 MACRO_PIR, MACRO_EOA,
2938 MACRO_EXP, MACRO_EOA,
2939 MACRO_EOA } },
2940 { "jcr", emit_retjcr, "jcr",
2941 { MACRO_IR, MACRO_EXP, MACRO_EOA,
2942 MACRO_IR, MACRO_EOA,
2943 MACRO_PIR, MACRO_EXP, MACRO_EOA,
2944 MACRO_PIR, MACRO_EOA,
2945 MACRO_EXP, MACRO_EOA,
2946 MACRO_EOA } },
2947 { "jsr_coroutine", emit_retjcr, "jcr",
2948 { MACRO_IR, MACRO_EXP, MACRO_EOA,
2949 MACRO_IR, MACRO_EOA,
2950 MACRO_PIR, MACRO_EXP, MACRO_EOA,
2951 MACRO_PIR, MACRO_EOA,
2952 MACRO_EXP, MACRO_EOA,
2953 MACRO_EOA } },
2956 static const unsigned int alpha_num_macros
2957 = sizeof (alpha_macros) / sizeof (*alpha_macros);
2959 /* Search forward through all variants of a macro looking for a syntax
2960 match. */
2962 static const struct alpha_macro *
2963 find_macro_match (const struct alpha_macro *first_macro,
2964 const expressionS *tok,
2965 int *pntok)
2968 const struct alpha_macro *macro = first_macro;
2969 int ntok = *pntok;
2973 const enum alpha_macro_arg *arg = macro->argsets;
2974 int tokidx = 0;
2976 while (*arg)
2978 switch (*arg)
2980 case MACRO_EOA:
2981 if (tokidx == ntok)
2982 return macro;
2983 else
2984 tokidx = 0;
2985 break;
2987 /* Index register. */
2988 case MACRO_IR:
2989 if (tokidx >= ntok || tok[tokidx].X_op != O_register
2990 || !is_ir_num (tok[tokidx].X_add_number))
2991 goto match_failed;
2992 ++tokidx;
2993 break;
2995 /* Parenthesized index register. */
2996 case MACRO_PIR:
2997 if (tokidx >= ntok || tok[tokidx].X_op != O_pregister
2998 || !is_ir_num (tok[tokidx].X_add_number))
2999 goto match_failed;
3000 ++tokidx;
3001 break;
3003 /* Optional parenthesized index register. */
3004 case MACRO_OPIR:
3005 if (tokidx < ntok && tok[tokidx].X_op == O_pregister
3006 && is_ir_num (tok[tokidx].X_add_number))
3007 ++tokidx;
3008 break;
3010 /* Leading comma with a parenthesized index register. */
3011 case MACRO_CPIR:
3012 if (tokidx >= ntok || tok[tokidx].X_op != O_cpregister
3013 || !is_ir_num (tok[tokidx].X_add_number))
3014 goto match_failed;
3015 ++tokidx;
3016 break;
3018 /* Floating point register. */
3019 case MACRO_FPR:
3020 if (tokidx >= ntok || tok[tokidx].X_op != O_register
3021 || !is_fpr_num (tok[tokidx].X_add_number))
3022 goto match_failed;
3023 ++tokidx;
3024 break;
3026 /* Normal expression. */
3027 case MACRO_EXP:
3028 if (tokidx >= ntok)
3029 goto match_failed;
3030 switch (tok[tokidx].X_op)
3032 case O_illegal:
3033 case O_absent:
3034 case O_register:
3035 case O_pregister:
3036 case O_cpregister:
3037 case O_literal:
3038 case O_lituse_base:
3039 case O_lituse_bytoff:
3040 case O_lituse_jsr:
3041 case O_gpdisp:
3042 case O_gprelhigh:
3043 case O_gprellow:
3044 case O_gprel:
3045 case O_samegp:
3046 goto match_failed;
3048 default:
3049 break;
3051 ++tokidx;
3052 break;
3054 match_failed:
3055 while (*arg != MACRO_EOA)
3056 ++arg;
3057 tokidx = 0;
3058 break;
3060 ++arg;
3063 while (++macro - alpha_macros < (int) alpha_num_macros
3064 && !strcmp (macro->name, first_macro->name));
3066 return NULL;
3069 /* Given an opcode name and a pre-tokenized set of arguments, take the
3070 opcode all the way through emission. */
3072 static void
3073 assemble_tokens (const char *opname,
3074 const expressionS *tok,
3075 int ntok,
3076 int local_macros_on)
3078 int found_something = 0;
3079 const struct alpha_opcode *opcode;
3080 const struct alpha_macro *macro;
3081 int cpumatch = 1;
3082 bfd_reloc_code_real_type reloc = BFD_RELOC_UNUSED;
3084 #ifdef RELOC_OP_P
3085 /* If a user-specified relocation is present, this is not a macro. */
3086 if (ntok && USER_RELOC_P (tok[ntok - 1].X_op))
3088 reloc = ALPHA_RELOC_TABLE (tok[ntok - 1].X_op)->reloc;
3089 ntok--;
3091 else
3092 #endif
3093 if (local_macros_on)
3095 macro = ((const struct alpha_macro *)
3096 hash_find (alpha_macro_hash, opname));
3097 if (macro)
3099 found_something = 1;
3100 macro = find_macro_match (macro, tok, &ntok);
3101 if (macro)
3103 (*macro->emit) (tok, ntok, macro->arg);
3104 return;
3109 /* Search opcodes. */
3110 opcode = (const struct alpha_opcode *) hash_find (alpha_opcode_hash, opname);
3111 if (opcode)
3113 found_something = 1;
3114 opcode = find_opcode_match (opcode, tok, &ntok, &cpumatch);
3115 if (opcode)
3117 struct alpha_insn insn;
3118 assemble_insn (opcode, tok, ntok, &insn, reloc);
3120 /* Copy the sequence number for the reloc from the reloc token. */
3121 if (reloc != BFD_RELOC_UNUSED)
3122 insn.sequence = tok[ntok].X_add_number;
3124 emit_insn (&insn);
3125 return;
3129 if (found_something)
3131 if (cpumatch)
3132 as_bad (_("inappropriate arguments for opcode `%s'"), opname);
3133 else
3134 as_bad (_("opcode `%s' not supported for target %s"), opname,
3135 alpha_target_name);
3137 else
3138 as_bad (_("unknown opcode `%s'"), opname);
3141 #ifdef OBJ_EVAX
3143 /* Add symbol+addend to link pool.
3144 Return offset from basesym to entry in link pool.
3146 Add new fixup only if offset isn't 16bit. */
3148 valueT
3149 add_to_link_pool (symbolS *basesym,
3150 symbolS *sym,
3151 offsetT addend)
3153 segT current_section = now_seg;
3154 int current_subsec = now_subseg;
3155 valueT offset;
3156 bfd_reloc_code_real_type reloc_type;
3157 char *p;
3158 segment_info_type *seginfo = seg_info (alpha_link_section);
3159 fixS *fixp;
3161 offset = - *symbol_get_obj (basesym);
3163 /* @@ This assumes all entries in a given section will be of the same
3164 size... Probably correct, but unwise to rely on. */
3165 /* This must always be called with the same subsegment. */
3167 if (seginfo->frchainP)
3168 for (fixp = seginfo->frchainP->fix_root;
3169 fixp != (fixS *) NULL;
3170 fixp = fixp->fx_next, offset += 8)
3172 if (fixp->fx_addsy == sym && fixp->fx_offset == addend)
3174 if (range_signed_16 (offset))
3176 return offset;
3181 /* Not found in 16bit signed range. */
3183 subseg_set (alpha_link_section, 0);
3184 p = frag_more (8);
3185 memset (p, 0, 8);
3187 fix_new (frag_now, p - frag_now->fr_literal, 8, sym, addend, 0,
3188 BFD_RELOC_64);
3190 subseg_set (current_section, current_subsec);
3191 seginfo->literal_pool_size += 8;
3192 return offset;
3195 #endif /* OBJ_EVAX */
3197 /* Assembler directives. */
3199 /* Handle the .text pseudo-op. This is like the usual one, but it
3200 clears alpha_insn_label and restores auto alignment. */
3202 static void
3203 s_alpha_text (int i)
3206 #ifdef OBJ_ELF
3207 obj_elf_text (i);
3208 #else
3209 s_text (i);
3210 #endif
3211 alpha_insn_label = NULL;
3212 alpha_auto_align_on = 1;
3213 alpha_current_align = 0;
3216 /* Handle the .data pseudo-op. This is like the usual one, but it
3217 clears alpha_insn_label and restores auto alignment. */
3219 static void
3220 s_alpha_data (int i)
3222 #ifdef OBJ_ELF
3223 obj_elf_data (i);
3224 #else
3225 s_data (i);
3226 #endif
3227 alpha_insn_label = NULL;
3228 alpha_auto_align_on = 1;
3229 alpha_current_align = 0;
3232 #if defined (OBJ_ECOFF) || defined (OBJ_EVAX)
3234 /* Handle the OSF/1 and openVMS .comm pseudo quirks.
3235 openVMS constructs a section for every common symbol. */
3237 static void
3238 s_alpha_comm (int ignore ATTRIBUTE_UNUSED)
3240 char *name;
3241 char c;
3242 char *p;
3243 offsetT temp;
3244 symbolS *symbolP;
3245 #ifdef OBJ_EVAX
3246 segT current_section = now_seg;
3247 int current_subsec = now_subseg;
3248 segT new_seg;
3249 #endif
3251 name = input_line_pointer;
3252 c = get_symbol_end ();
3254 /* Just after name is now '\0'. */
3255 p = input_line_pointer;
3256 *p = c;
3258 SKIP_WHITESPACE ();
3260 /* Alpha OSF/1 compiler doesn't provide the comma, gcc does. */
3261 if (*input_line_pointer == ',')
3263 input_line_pointer++;
3264 SKIP_WHITESPACE ();
3266 if ((temp = get_absolute_expression ()) < 0)
3268 as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) temp);
3269 ignore_rest_of_line ();
3270 return;
3273 *p = 0;
3274 symbolP = symbol_find_or_make (name);
3276 #ifdef OBJ_EVAX
3277 /* Make a section for the common symbol. */
3278 new_seg = subseg_new (xstrdup (name), 0);
3279 #endif
3281 *p = c;
3283 #ifdef OBJ_EVAX
3284 /* Alignment might follow. */
3285 if (*input_line_pointer == ',')
3287 offsetT align;
3289 input_line_pointer++;
3290 align = get_absolute_expression ();
3291 bfd_set_section_alignment (stdoutput, new_seg, align);
3293 #endif
3295 if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
3297 as_bad (_("Ignoring attempt to re-define symbol"));
3298 ignore_rest_of_line ();
3299 return;
3302 #ifdef OBJ_EVAX
3303 if (bfd_section_size (stdoutput, new_seg) > 0)
3305 if (bfd_section_size (stdoutput, new_seg) != temp)
3306 as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
3307 S_GET_NAME (symbolP),
3308 (long) bfd_section_size (stdoutput, new_seg),
3309 (long) temp);
3311 #else
3312 if (S_GET_VALUE (symbolP))
3314 if (S_GET_VALUE (symbolP) != (valueT) temp)
3315 as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
3316 S_GET_NAME (symbolP),
3317 (long) S_GET_VALUE (symbolP),
3318 (long) temp);
3320 #endif
3321 else
3323 #ifdef OBJ_EVAX
3324 subseg_set (new_seg, 0);
3325 p = frag_more (temp);
3326 new_seg->flags |= SEC_IS_COMMON;
3327 if (! S_IS_DEFINED (symbolP))
3328 S_SET_SEGMENT (symbolP, new_seg);
3329 #else
3330 S_SET_VALUE (symbolP, (valueT) temp);
3331 #endif
3332 S_SET_EXTERNAL (symbolP);
3335 #ifdef OBJ_EVAX
3336 subseg_set (current_section, current_subsec);
3337 #endif
3339 know (symbol_get_frag (symbolP) == &zero_address_frag);
3341 demand_empty_rest_of_line ();
3344 #endif /* ! OBJ_ELF */
3346 #ifdef OBJ_ECOFF
3348 /* Handle the .rdata pseudo-op. This is like the usual one, but it
3349 clears alpha_insn_label and restores auto alignment. */
3351 static void
3352 s_alpha_rdata (int ignore ATTRIBUTE_UNUSED)
3354 int temp;
3356 temp = get_absolute_expression ();
3357 subseg_new (".rdata", 0);
3358 demand_empty_rest_of_line ();
3359 alpha_insn_label = NULL;
3360 alpha_auto_align_on = 1;
3361 alpha_current_align = 0;
3364 #endif
3366 #ifdef OBJ_ECOFF
3368 /* Handle the .sdata pseudo-op. This is like the usual one, but it
3369 clears alpha_insn_label and restores auto alignment. */
3371 static void
3372 s_alpha_sdata (int ignore ATTRIBUTE_UNUSED)
3374 int temp;
3376 temp = get_absolute_expression ();
3377 subseg_new (".sdata", 0);
3378 demand_empty_rest_of_line ();
3379 alpha_insn_label = NULL;
3380 alpha_auto_align_on = 1;
3381 alpha_current_align = 0;
3383 #endif
3385 #ifdef OBJ_ELF
3386 struct alpha_elf_frame_data
3388 symbolS *func_sym;
3389 symbolS *func_end_sym;
3390 symbolS *prologue_sym;
3391 unsigned int mask;
3392 unsigned int fmask;
3393 int fp_regno;
3394 int ra_regno;
3395 offsetT frame_size;
3396 offsetT mask_offset;
3397 offsetT fmask_offset;
3399 struct alpha_elf_frame_data *next;
3402 static struct alpha_elf_frame_data *all_frame_data;
3403 static struct alpha_elf_frame_data **plast_frame_data = &all_frame_data;
3404 static struct alpha_elf_frame_data *cur_frame_data;
3406 /* Handle the .section pseudo-op. This is like the usual one, but it
3407 clears alpha_insn_label and restores auto alignment. */
3409 static void
3410 s_alpha_section (int ignore ATTRIBUTE_UNUSED)
3412 obj_elf_section (ignore);
3414 alpha_insn_label = NULL;
3415 alpha_auto_align_on = 1;
3416 alpha_current_align = 0;
3419 static void
3420 s_alpha_ent (int dummy ATTRIBUTE_UNUSED)
3422 if (ECOFF_DEBUGGING)
3423 ecoff_directive_ent (0);
3424 else
3426 char *name, name_end;
3427 name = input_line_pointer;
3428 name_end = get_symbol_end ();
3430 if (! is_name_beginner (*name))
3432 as_warn (_(".ent directive has no name"));
3433 *input_line_pointer = name_end;
3435 else
3437 symbolS *sym;
3439 if (cur_frame_data)
3440 as_warn (_("nested .ent directives"));
3442 sym = symbol_find_or_make (name);
3443 symbol_get_bfdsym (sym)->flags |= BSF_FUNCTION;
3445 cur_frame_data = calloc (1, sizeof (*cur_frame_data));
3446 cur_frame_data->func_sym = sym;
3448 /* Provide sensible defaults. */
3449 cur_frame_data->fp_regno = 30; /* sp */
3450 cur_frame_data->ra_regno = 26; /* ra */
3452 *plast_frame_data = cur_frame_data;
3453 plast_frame_data = &cur_frame_data->next;
3455 /* The .ent directive is sometimes followed by a number. Not sure
3456 what it really means, but ignore it. */
3457 *input_line_pointer = name_end;
3458 SKIP_WHITESPACE ();
3459 if (*input_line_pointer == ',')
3461 input_line_pointer++;
3462 SKIP_WHITESPACE ();
3464 if (ISDIGIT (*input_line_pointer) || *input_line_pointer == '-')
3465 (void) get_absolute_expression ();
3467 demand_empty_rest_of_line ();
3471 static void
3472 s_alpha_end (int dummy ATTRIBUTE_UNUSED)
3474 if (ECOFF_DEBUGGING)
3475 ecoff_directive_end (0);
3476 else
3478 char *name, name_end;
3479 name = input_line_pointer;
3480 name_end = get_symbol_end ();
3482 if (! is_name_beginner (*name))
3484 as_warn (_(".end directive has no name"));
3485 *input_line_pointer = name_end;
3487 else
3489 symbolS *sym;
3491 sym = symbol_find (name);
3492 if (!cur_frame_data)
3493 as_warn (_(".end directive without matching .ent"));
3494 else if (sym != cur_frame_data->func_sym)
3495 as_warn (_(".end directive names different symbol than .ent"));
3497 /* Create an expression to calculate the size of the function. */
3498 if (sym && cur_frame_data)
3500 OBJ_SYMFIELD_TYPE *obj = symbol_get_obj (sym);
3501 expressionS *exp = xmalloc (sizeof (expressionS));
3503 obj->size = exp;
3504 exp->X_op = O_subtract;
3505 exp->X_add_symbol = symbol_temp_new_now ();
3506 exp->X_op_symbol = sym;
3507 exp->X_add_number = 0;
3509 cur_frame_data->func_end_sym = exp->X_add_symbol;
3512 cur_frame_data = NULL;
3514 *input_line_pointer = name_end;
3516 demand_empty_rest_of_line ();
3520 static void
3521 s_alpha_mask (int fp)
3523 if (ECOFF_DEBUGGING)
3525 if (fp)
3526 ecoff_directive_fmask (0);
3527 else
3528 ecoff_directive_mask (0);
3530 else
3532 long val;
3533 offsetT offset;
3535 if (!cur_frame_data)
3537 if (fp)
3538 as_warn (_(".fmask outside of .ent"));
3539 else
3540 as_warn (_(".mask outside of .ent"));
3541 discard_rest_of_line ();
3542 return;
3545 if (get_absolute_expression_and_terminator (&val) != ',')
3547 if (fp)
3548 as_warn (_("bad .fmask directive"));
3549 else
3550 as_warn (_("bad .mask directive"));
3551 --input_line_pointer;
3552 discard_rest_of_line ();
3553 return;
3556 offset = get_absolute_expression ();
3557 demand_empty_rest_of_line ();
3559 if (fp)
3561 cur_frame_data->fmask = val;
3562 cur_frame_data->fmask_offset = offset;
3564 else
3566 cur_frame_data->mask = val;
3567 cur_frame_data->mask_offset = offset;
3572 static void
3573 s_alpha_frame (int dummy ATTRIBUTE_UNUSED)
3575 if (ECOFF_DEBUGGING)
3576 ecoff_directive_frame (0);
3577 else
3579 long val;
3581 if (!cur_frame_data)
3583 as_warn (_(".frame outside of .ent"));
3584 discard_rest_of_line ();
3585 return;
3588 cur_frame_data->fp_regno = tc_get_register (1);
3590 SKIP_WHITESPACE ();
3591 if (*input_line_pointer++ != ','
3592 || get_absolute_expression_and_terminator (&val) != ',')
3594 as_warn (_("bad .frame directive"));
3595 --input_line_pointer;
3596 discard_rest_of_line ();
3597 return;
3599 cur_frame_data->frame_size = val;
3601 cur_frame_data->ra_regno = tc_get_register (0);
3603 /* Next comes the "offset of saved $a0 from $sp". In gcc terms
3604 this is current_function_pretend_args_size. There's no place
3605 to put this value, so ignore it. */
3606 s_ignore (42);
3610 static void
3611 s_alpha_prologue (int ignore ATTRIBUTE_UNUSED)
3613 symbolS *sym;
3614 int arg;
3616 arg = get_absolute_expression ();
3617 demand_empty_rest_of_line ();
3619 if (ECOFF_DEBUGGING)
3620 sym = ecoff_get_cur_proc_sym ();
3621 else
3622 sym = cur_frame_data ? cur_frame_data->func_sym : NULL;
3624 if (sym == NULL)
3626 as_bad (_(".prologue directive without a preceding .ent directive"));
3627 return;
3630 switch (arg)
3632 case 0: /* No PV required. */
3633 S_SET_OTHER (sym, STO_ALPHA_NOPV
3634 | (S_GET_OTHER (sym) & ~STO_ALPHA_STD_GPLOAD));
3635 break;
3636 case 1: /* Std GP load. */
3637 S_SET_OTHER (sym, STO_ALPHA_STD_GPLOAD
3638 | (S_GET_OTHER (sym) & ~STO_ALPHA_STD_GPLOAD));
3639 break;
3640 case 2: /* Non-std use of PV. */
3641 break;
3643 default:
3644 as_bad (_("Invalid argument %d to .prologue."), arg);
3645 break;
3648 if (cur_frame_data)
3649 cur_frame_data->prologue_sym = symbol_temp_new_now ();
3652 static char *first_file_directive;
3654 static void
3655 s_alpha_file (int ignore ATTRIBUTE_UNUSED)
3657 /* Save the first .file directive we see, so that we can change our
3658 minds about whether ecoff debugging should or shouldn't be enabled. */
3659 if (alpha_flag_mdebug < 0 && ! first_file_directive)
3661 char *start = input_line_pointer;
3662 size_t len;
3664 discard_rest_of_line ();
3666 len = input_line_pointer - start;
3667 first_file_directive = xmalloc (len + 1);
3668 memcpy (first_file_directive, start, len);
3669 first_file_directive[len] = '\0';
3671 input_line_pointer = start;
3674 if (ECOFF_DEBUGGING)
3675 ecoff_directive_file (0);
3676 else
3677 dwarf2_directive_file (0);
3680 static void
3681 s_alpha_loc (int ignore ATTRIBUTE_UNUSED)
3683 if (ECOFF_DEBUGGING)
3684 ecoff_directive_loc (0);
3685 else
3686 dwarf2_directive_loc (0);
3689 static void
3690 s_alpha_stab (int n)
3692 /* If we've been undecided about mdebug, make up our minds in favour. */
3693 if (alpha_flag_mdebug < 0)
3695 segT sec = subseg_new (".mdebug", 0);
3696 bfd_set_section_flags (stdoutput, sec, SEC_HAS_CONTENTS | SEC_READONLY);
3697 bfd_set_section_alignment (stdoutput, sec, 3);
3699 ecoff_read_begin_hook ();
3701 if (first_file_directive)
3703 char *save_ilp = input_line_pointer;
3704 input_line_pointer = first_file_directive;
3705 ecoff_directive_file (0);
3706 input_line_pointer = save_ilp;
3707 free (first_file_directive);
3710 alpha_flag_mdebug = 1;
3712 s_stab (n);
3715 static void
3716 s_alpha_coff_wrapper (int which)
3718 static void (* const fns[]) PARAMS ((int)) = {
3719 ecoff_directive_begin,
3720 ecoff_directive_bend,
3721 ecoff_directive_def,
3722 ecoff_directive_dim,
3723 ecoff_directive_endef,
3724 ecoff_directive_scl,
3725 ecoff_directive_tag,
3726 ecoff_directive_val,
3729 assert (which >= 0 && which < (int) (sizeof (fns)/sizeof (*fns)));
3731 if (ECOFF_DEBUGGING)
3732 (*fns[which]) (0);
3733 else
3735 as_bad (_("ECOFF debugging is disabled."));
3736 ignore_rest_of_line ();
3740 /* Called at the end of assembly. Here we emit unwind info for frames
3741 unless the compiler has done it for us. */
3743 void
3744 alpha_elf_md_end (void)
3746 struct alpha_elf_frame_data *p;
3748 if (cur_frame_data)
3749 as_warn (_(".ent directive without matching .end"));
3751 /* If someone has generated the unwind info themselves, great. */
3752 if (bfd_get_section_by_name (stdoutput, ".eh_frame") != NULL)
3753 return;
3755 /* Generate .eh_frame data for the unwind directives specified. */
3756 for (p = all_frame_data; p ; p = p->next)
3757 if (p->prologue_sym)
3759 /* Create a temporary symbol at the same location as our
3760 function symbol. This prevents problems with globals. */
3761 cfi_new_fde (symbol_temp_new (S_GET_SEGMENT (p->func_sym),
3762 S_GET_VALUE (p->func_sym),
3763 symbol_get_frag (p->func_sym)));
3765 cfi_set_return_column (p->ra_regno);
3766 cfi_add_CFA_def_cfa_register (30);
3767 if (p->fp_regno != 30 || p->mask || p->fmask || p->frame_size)
3769 unsigned int mask;
3770 offsetT offset;
3772 cfi_add_advance_loc (p->prologue_sym);
3774 if (p->fp_regno != 30)
3775 if (p->frame_size != 0)
3776 cfi_add_CFA_def_cfa (p->fp_regno, p->frame_size);
3777 else
3778 cfi_add_CFA_def_cfa_register (p->fp_regno);
3779 else if (p->frame_size != 0)
3780 cfi_add_CFA_def_cfa_offset (p->frame_size);
3782 mask = p->mask;
3783 offset = p->mask_offset;
3785 /* Recall that $26 is special-cased and stored first. */
3786 if ((mask >> 26) & 1)
3788 cfi_add_CFA_offset (26, offset);
3789 offset += 8;
3790 mask &= ~(1 << 26);
3792 while (mask)
3794 unsigned int i;
3795 i = mask & -mask;
3796 mask ^= i;
3797 i = ffs (i) - 1;
3799 cfi_add_CFA_offset (i, offset);
3800 offset += 8;
3803 mask = p->fmask;
3804 offset = p->fmask_offset;
3805 while (mask)
3807 unsigned int i;
3808 i = mask & -mask;
3809 mask ^= i;
3810 i = ffs (i) - 1;
3812 cfi_add_CFA_offset (i + 32, offset);
3813 offset += 8;
3817 cfi_end_fde (p->func_end_sym);
3821 static void
3822 s_alpha_usepv (int unused ATTRIBUTE_UNUSED)
3824 char *name, name_end;
3825 char *which, which_end;
3826 symbolS *sym;
3827 int other;
3829 name = input_line_pointer;
3830 name_end = get_symbol_end ();
3832 if (! is_name_beginner (*name))
3834 as_bad (_(".usepv directive has no name"));
3835 *input_line_pointer = name_end;
3836 ignore_rest_of_line ();
3837 return;
3840 sym = symbol_find_or_make (name);
3841 *input_line_pointer++ = name_end;
3843 if (name_end != ',')
3845 as_bad (_(".usepv directive has no type"));
3846 ignore_rest_of_line ();
3847 return;
3850 SKIP_WHITESPACE ();
3851 which = input_line_pointer;
3852 which_end = get_symbol_end ();
3854 if (strcmp (which, "no") == 0)
3855 other = STO_ALPHA_NOPV;
3856 else if (strcmp (which, "std") == 0)
3857 other = STO_ALPHA_STD_GPLOAD;
3858 else
3860 as_bad (_("unknown argument for .usepv"));
3861 other = 0;
3864 *input_line_pointer = which_end;
3865 demand_empty_rest_of_line ();
3867 S_SET_OTHER (sym, other | (S_GET_OTHER (sym) & ~STO_ALPHA_STD_GPLOAD));
3869 #endif /* OBJ_ELF */
3871 /* Standard calling conventions leaves the CFA at $30 on entry. */
3873 void
3874 alpha_cfi_frame_initial_instructions (void)
3876 cfi_add_CFA_def_cfa_register (30);
3879 #ifdef OBJ_EVAX
3881 /* Handle the section specific pseudo-op. */
3883 static void
3884 s_alpha_section (int secid)
3886 int temp;
3887 #define EVAX_SECTION_COUNT 5
3888 static char *section_name[EVAX_SECTION_COUNT + 1] =
3889 { "NULL", ".rdata", ".comm", ".link", ".ctors", ".dtors" };
3891 if ((secid <= 0) || (secid > EVAX_SECTION_COUNT))
3893 as_fatal (_("Unknown section directive"));
3894 demand_empty_rest_of_line ();
3895 return;
3897 temp = get_absolute_expression ();
3898 subseg_new (section_name[secid], 0);
3899 demand_empty_rest_of_line ();
3900 alpha_insn_label = NULL;
3901 alpha_auto_align_on = 1;
3902 alpha_current_align = 0;
3905 /* Parse .ent directives. */
3907 static void
3908 s_alpha_ent (int ignore ATTRIBUTE_UNUSED)
3910 symbolS *symbol;
3911 expressionS symexpr;
3913 alpha_evax_proc.pdsckind = 0;
3914 alpha_evax_proc.framereg = -1;
3915 alpha_evax_proc.framesize = 0;
3916 alpha_evax_proc.rsa_offset = 0;
3917 alpha_evax_proc.ra_save = AXP_REG_RA;
3918 alpha_evax_proc.fp_save = -1;
3919 alpha_evax_proc.imask = 0;
3920 alpha_evax_proc.fmask = 0;
3921 alpha_evax_proc.prologue = 0;
3922 alpha_evax_proc.type = 0;
3924 expression (&symexpr);
3926 if (symexpr.X_op != O_symbol)
3928 as_fatal (_(".ent directive has no symbol"));
3929 demand_empty_rest_of_line ();
3930 return;
3933 symbol = make_expr_symbol (&symexpr);
3934 symbol_get_bfdsym (symbol)->flags |= BSF_FUNCTION;
3935 alpha_evax_proc.symbol = symbol;
3937 demand_empty_rest_of_line ();
3940 /* Parse .frame <framreg>,<framesize>,RA,<rsa_offset> directives. */
3942 static void
3943 s_alpha_frame (int ignore ATTRIBUTE_UNUSED)
3945 long val;
3947 alpha_evax_proc.framereg = tc_get_register (1);
3949 SKIP_WHITESPACE ();
3950 if (*input_line_pointer++ != ','
3951 || get_absolute_expression_and_terminator (&val) != ',')
3953 as_warn (_("Bad .frame directive 1./2. param"));
3954 --input_line_pointer;
3955 demand_empty_rest_of_line ();
3956 return;
3959 alpha_evax_proc.framesize = val;
3961 (void) tc_get_register (1);
3962 SKIP_WHITESPACE ();
3963 if (*input_line_pointer++ != ',')
3965 as_warn (_("Bad .frame directive 3./4. param"));
3966 --input_line_pointer;
3967 demand_empty_rest_of_line ();
3968 return;
3970 alpha_evax_proc.rsa_offset = get_absolute_expression ();
3973 static void
3974 s_alpha_pdesc (int ignore ATTRIBUTE_UNUSED)
3976 char *name;
3977 char name_end;
3978 long val;
3979 register char *p;
3980 expressionS exp;
3981 symbolS *entry_sym;
3982 fixS *fixp;
3983 segment_info_type *seginfo = seg_info (alpha_link_section);
3985 if (now_seg != alpha_link_section)
3987 as_bad (_(".pdesc directive not in link (.link) section"));
3988 demand_empty_rest_of_line ();
3989 return;
3992 if ((alpha_evax_proc.symbol == 0)
3993 || (!S_IS_DEFINED (alpha_evax_proc.symbol)))
3995 as_fatal (_(".pdesc has no matching .ent"));
3996 demand_empty_rest_of_line ();
3997 return;
4000 *symbol_get_obj (alpha_evax_proc.symbol) =
4001 (valueT) seginfo->literal_pool_size;
4003 expression (&exp);
4004 if (exp.X_op != O_symbol)
4006 as_warn (_(".pdesc directive has no entry symbol"));
4007 demand_empty_rest_of_line ();
4008 return;
4011 entry_sym = make_expr_symbol (&exp);
4012 /* Save bfd symbol of proc desc in function symbol. */
4013 symbol_get_bfdsym (alpha_evax_proc.symbol)->udata.p
4014 = symbol_get_bfdsym (entry_sym);
4016 SKIP_WHITESPACE ();
4017 if (*input_line_pointer++ != ',')
4019 as_warn (_("No comma after .pdesc <entryname>"));
4020 demand_empty_rest_of_line ();
4021 return;
4024 SKIP_WHITESPACE ();
4025 name = input_line_pointer;
4026 name_end = get_symbol_end ();
4028 if (strncmp (name, "stack", 5) == 0)
4029 alpha_evax_proc.pdsckind = PDSC_S_K_KIND_FP_STACK;
4031 else if (strncmp (name, "reg", 3) == 0)
4032 alpha_evax_proc.pdsckind = PDSC_S_K_KIND_FP_REGISTER;
4034 else if (strncmp (name, "null", 4) == 0)
4035 alpha_evax_proc.pdsckind = PDSC_S_K_KIND_NULL;
4037 else
4039 as_fatal (_("unknown procedure kind"));
4040 demand_empty_rest_of_line ();
4041 return;
4044 *input_line_pointer = name_end;
4045 demand_empty_rest_of_line ();
4047 #ifdef md_flush_pending_output
4048 md_flush_pending_output ();
4049 #endif
4051 frag_align (3, 0, 0);
4052 p = frag_more (16);
4053 fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
4054 fixp->fx_done = 1;
4055 seginfo->literal_pool_size += 16;
4057 *p = alpha_evax_proc.pdsckind
4058 | ((alpha_evax_proc.framereg == 29) ? PDSC_S_M_BASE_REG_IS_FP : 0);
4059 *(p + 1) = PDSC_S_M_NATIVE | PDSC_S_M_NO_JACKET;
4061 switch (alpha_evax_proc.pdsckind)
4063 case PDSC_S_K_KIND_NULL:
4064 *(p + 2) = 0;
4065 *(p + 3) = 0;
4066 break;
4067 case PDSC_S_K_KIND_FP_REGISTER:
4068 *(p + 2) = alpha_evax_proc.fp_save;
4069 *(p + 3) = alpha_evax_proc.ra_save;
4070 break;
4071 case PDSC_S_K_KIND_FP_STACK:
4072 md_number_to_chars (p + 2, (valueT) alpha_evax_proc.rsa_offset, 2);
4073 break;
4074 default: /* impossible */
4075 break;
4078 *(p + 4) = 0;
4079 *(p + 5) = alpha_evax_proc.type & 0x0f;
4081 /* Signature offset. */
4082 md_number_to_chars (p + 6, (valueT) 0, 2);
4084 fix_new_exp (frag_now, p - frag_now->fr_literal+8, 8, &exp, 0, BFD_RELOC_64);
4086 if (alpha_evax_proc.pdsckind == PDSC_S_K_KIND_NULL)
4087 return;
4089 /* Add dummy fix to make add_to_link_pool work. */
4090 p = frag_more (8);
4091 fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
4092 fixp->fx_done = 1;
4093 seginfo->literal_pool_size += 8;
4095 /* pdesc+16: Size. */
4096 md_number_to_chars (p, (valueT) alpha_evax_proc.framesize, 4);
4098 md_number_to_chars (p + 4, (valueT) 0, 2);
4100 /* Entry length. */
4101 md_number_to_chars (p + 6, alpha_evax_proc.prologue, 2);
4103 if (alpha_evax_proc.pdsckind == PDSC_S_K_KIND_FP_REGISTER)
4104 return;
4106 /* Add dummy fix to make add_to_link_pool work. */
4107 p = frag_more (8);
4108 fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
4109 fixp->fx_done = 1;
4110 seginfo->literal_pool_size += 8;
4112 /* pdesc+24: register masks. */
4114 md_number_to_chars (p, alpha_evax_proc.imask, 4);
4115 md_number_to_chars (p + 4, alpha_evax_proc.fmask, 4);
4118 /* Support for crash debug on vms. */
4120 static void
4121 s_alpha_name (int ignore ATTRIBUTE_UNUSED)
4123 char *p;
4124 expressionS exp;
4125 segment_info_type *seginfo = seg_info (alpha_link_section);
4127 if (now_seg != alpha_link_section)
4129 as_bad (_(".name directive not in link (.link) section"));
4130 demand_empty_rest_of_line ();
4131 return;
4134 expression (&exp);
4135 if (exp.X_op != O_symbol)
4137 as_warn (_(".name directive has no symbol"));
4138 demand_empty_rest_of_line ();
4139 return;
4142 demand_empty_rest_of_line ();
4144 #ifdef md_flush_pending_output
4145 md_flush_pending_output ();
4146 #endif
4148 frag_align (3, 0, 0);
4149 p = frag_more (8);
4150 seginfo->literal_pool_size += 8;
4152 fix_new_exp (frag_now, p - frag_now->fr_literal, 8, &exp, 0, BFD_RELOC_64);
4155 static void
4156 s_alpha_linkage (int ignore ATTRIBUTE_UNUSED)
4158 expressionS exp;
4159 char *p;
4161 #ifdef md_flush_pending_output
4162 md_flush_pending_output ();
4163 #endif
4165 expression (&exp);
4166 if (exp.X_op != O_symbol)
4168 as_fatal (_("No symbol after .linkage"));
4170 else
4172 p = frag_more (LKP_S_K_SIZE);
4173 memset (p, 0, LKP_S_K_SIZE);
4174 fix_new_exp (frag_now, p - frag_now->fr_literal, LKP_S_K_SIZE, &exp, 0,\
4175 BFD_RELOC_ALPHA_LINKAGE);
4177 demand_empty_rest_of_line ();
4180 static void
4181 s_alpha_code_address (int ignore ATTRIBUTE_UNUSED)
4183 expressionS exp;
4184 char *p;
4186 #ifdef md_flush_pending_output
4187 md_flush_pending_output ();
4188 #endif
4190 expression (&exp);
4191 if (exp.X_op != O_symbol)
4192 as_fatal (_("No symbol after .code_address"));
4193 else
4195 p = frag_more (8);
4196 memset (p, 0, 8);
4197 fix_new_exp (frag_now, p - frag_now->fr_literal, 8, &exp, 0,\
4198 BFD_RELOC_ALPHA_CODEADDR);
4200 demand_empty_rest_of_line ();
4203 static void
4204 s_alpha_fp_save (int ignore ATTRIBUTE_UNUSED)
4207 alpha_evax_proc.fp_save = tc_get_register (1);
4209 demand_empty_rest_of_line ();
4212 static void
4213 s_alpha_mask (int ignore ATTRIBUTE_UNUSED)
4215 long val;
4217 if (get_absolute_expression_and_terminator (&val) != ',')
4219 as_warn (_("Bad .mask directive"));
4220 --input_line_pointer;
4222 else
4224 alpha_evax_proc.imask = val;
4225 (void) get_absolute_expression ();
4227 demand_empty_rest_of_line ();
4230 static void
4231 s_alpha_fmask (int ignore ATTRIBUTE_UNUSED)
4233 long val;
4235 if (get_absolute_expression_and_terminator (&val) != ',')
4237 as_warn (_("Bad .fmask directive"));
4238 --input_line_pointer;
4240 else
4242 alpha_evax_proc.fmask = val;
4243 (void) get_absolute_expression ();
4245 demand_empty_rest_of_line ();
4248 static void
4249 s_alpha_end (int ignore ATTRIBUTE_UNUSED)
4251 char c;
4253 c = get_symbol_end ();
4254 *input_line_pointer = c;
4255 demand_empty_rest_of_line ();
4256 alpha_evax_proc.symbol = 0;
4259 static void
4260 s_alpha_file (int ignore ATTRIBUTE_UNUSED)
4262 symbolS *s;
4263 int length;
4264 static char case_hack[32];
4266 sprintf (case_hack, "<CASE:%01d%01d>",
4267 alpha_flag_hash_long_names, alpha_flag_show_after_trunc);
4269 s = symbol_find_or_make (case_hack);
4270 symbol_get_bfdsym (s)->flags |= BSF_FILE;
4272 get_absolute_expression ();
4273 s = symbol_find_or_make (demand_copy_string (&length));
4274 symbol_get_bfdsym (s)->flags |= BSF_FILE;
4275 demand_empty_rest_of_line ();
4277 #endif /* OBJ_EVAX */
4279 /* Handle the .gprel32 pseudo op. */
4281 static void
4282 s_alpha_gprel32 (int ignore ATTRIBUTE_UNUSED)
4284 expressionS e;
4285 char *p;
4287 SKIP_WHITESPACE ();
4288 expression (&e);
4290 #ifdef OBJ_ELF
4291 switch (e.X_op)
4293 case O_constant:
4294 e.X_add_symbol = section_symbol (absolute_section);
4295 e.X_op = O_symbol;
4296 /* FALLTHRU */
4297 case O_symbol:
4298 break;
4299 default:
4300 abort ();
4302 #else
4303 #ifdef OBJ_ECOFF
4304 switch (e.X_op)
4306 case O_constant:
4307 e.X_add_symbol = section_symbol (absolute_section);
4308 /* fall through */
4309 case O_symbol:
4310 e.X_op = O_subtract;
4311 e.X_op_symbol = alpha_gp_symbol;
4312 break;
4313 default:
4314 abort ();
4316 #endif
4317 #endif
4319 if (alpha_auto_align_on && alpha_current_align < 2)
4320 alpha_align (2, (char *) NULL, alpha_insn_label, 0);
4321 if (alpha_current_align > 2)
4322 alpha_current_align = 2;
4323 alpha_insn_label = NULL;
4325 p = frag_more (4);
4326 memset (p, 0, 4);
4327 fix_new_exp (frag_now, p - frag_now->fr_literal, 4,
4328 &e, 0, BFD_RELOC_GPREL32);
4331 /* Handle floating point allocation pseudo-ops. This is like the
4332 generic vresion, but it makes sure the current label, if any, is
4333 correctly aligned. */
4335 static void
4336 s_alpha_float_cons (int type)
4338 int log_size;
4340 switch (type)
4342 default:
4343 case 'f':
4344 case 'F':
4345 log_size = 2;
4346 break;
4348 case 'd':
4349 case 'D':
4350 case 'G':
4351 log_size = 3;
4352 break;
4354 case 'x':
4355 case 'X':
4356 case 'p':
4357 case 'P':
4358 log_size = 4;
4359 break;
4362 if (alpha_auto_align_on && alpha_current_align < log_size)
4363 alpha_align (log_size, (char *) NULL, alpha_insn_label, 0);
4364 if (alpha_current_align > log_size)
4365 alpha_current_align = log_size;
4366 alpha_insn_label = NULL;
4368 float_cons (type);
4371 /* Handle the .proc pseudo op. We don't really do much with it except
4372 parse it. */
4374 static void
4375 s_alpha_proc (int is_static ATTRIBUTE_UNUSED)
4377 char *name;
4378 char c;
4379 char *p;
4380 symbolS *symbolP;
4381 int temp;
4383 /* Takes ".proc name,nargs". */
4384 SKIP_WHITESPACE ();
4385 name = input_line_pointer;
4386 c = get_symbol_end ();
4387 p = input_line_pointer;
4388 symbolP = symbol_find_or_make (name);
4389 *p = c;
4390 SKIP_WHITESPACE ();
4391 if (*input_line_pointer != ',')
4393 *p = 0;
4394 as_warn (_("Expected comma after name \"%s\""), name);
4395 *p = c;
4396 temp = 0;
4397 ignore_rest_of_line ();
4399 else
4401 input_line_pointer++;
4402 temp = get_absolute_expression ();
4404 /* *symbol_get_obj (symbolP) = (signed char) temp; */
4405 as_warn (_("unhandled: .proc %s,%d"), name, temp);
4406 demand_empty_rest_of_line ();
4409 /* Handle the .set pseudo op. This is used to turn on and off most of
4410 the assembler features. */
4412 static void
4413 s_alpha_set (int x ATTRIBUTE_UNUSED)
4415 char *name, ch, *s;
4416 int yesno = 1;
4418 SKIP_WHITESPACE ();
4419 name = input_line_pointer;
4420 ch = get_symbol_end ();
4422 s = name;
4423 if (s[0] == 'n' && s[1] == 'o')
4425 yesno = 0;
4426 s += 2;
4428 if (!strcmp ("reorder", s))
4429 /* ignore */ ;
4430 else if (!strcmp ("at", s))
4431 alpha_noat_on = !yesno;
4432 else if (!strcmp ("macro", s))
4433 alpha_macros_on = yesno;
4434 else if (!strcmp ("move", s))
4435 /* ignore */ ;
4436 else if (!strcmp ("volatile", s))
4437 /* ignore */ ;
4438 else
4439 as_warn (_("Tried to .set unrecognized mode `%s'"), name);
4441 *input_line_pointer = ch;
4442 demand_empty_rest_of_line ();
4445 /* Handle the .base pseudo op. This changes the assembler's notion of
4446 the $gp register. */
4448 static void
4449 s_alpha_base (int ignore ATTRIBUTE_UNUSED)
4451 SKIP_WHITESPACE ();
4453 if (*input_line_pointer == '$')
4455 /* $rNN form. */
4456 input_line_pointer++;
4457 if (*input_line_pointer == 'r')
4458 input_line_pointer++;
4461 alpha_gp_register = get_absolute_expression ();
4462 if (alpha_gp_register < 0 || alpha_gp_register > 31)
4464 alpha_gp_register = AXP_REG_GP;
4465 as_warn (_("Bad base register, using $%d."), alpha_gp_register);
4468 demand_empty_rest_of_line ();
4471 /* Handle the .align pseudo-op. This aligns to a power of two. It
4472 also adjusts any current instruction label. We treat this the same
4473 way the MIPS port does: .align 0 turns off auto alignment. */
4475 static void
4476 s_alpha_align (int ignore ATTRIBUTE_UNUSED)
4478 int align;
4479 char fill, *pfill;
4480 long max_alignment = 15;
4482 align = get_absolute_expression ();
4483 if (align > max_alignment)
4485 align = max_alignment;
4486 as_bad (_("Alignment too large: %d. assumed"), align);
4488 else if (align < 0)
4490 as_warn (_("Alignment negative: 0 assumed"));
4491 align = 0;
4494 if (*input_line_pointer == ',')
4496 input_line_pointer++;
4497 fill = get_absolute_expression ();
4498 pfill = &fill;
4500 else
4501 pfill = NULL;
4503 if (align != 0)
4505 alpha_auto_align_on = 1;
4506 alpha_align (align, pfill, alpha_insn_label, 1);
4508 else
4510 alpha_auto_align_on = 0;
4513 demand_empty_rest_of_line ();
4516 /* Hook the normal string processor to reset known alignment. */
4518 static void
4519 s_alpha_stringer (int terminate)
4521 alpha_current_align = 0;
4522 alpha_insn_label = NULL;
4523 stringer (terminate);
4526 /* Hook the normal space processing to reset known alignment. */
4528 static void
4529 s_alpha_space (int ignore)
4531 alpha_current_align = 0;
4532 alpha_insn_label = NULL;
4533 s_space (ignore);
4536 /* Hook into cons for auto-alignment. */
4538 void
4539 alpha_cons_align (int size)
4541 int log_size;
4543 log_size = 0;
4544 while ((size >>= 1) != 0)
4545 ++log_size;
4547 if (alpha_auto_align_on && alpha_current_align < log_size)
4548 alpha_align (log_size, (char *) NULL, alpha_insn_label, 0);
4549 if (alpha_current_align > log_size)
4550 alpha_current_align = log_size;
4551 alpha_insn_label = NULL;
4554 /* Here come the .uword, .ulong, and .uquad explicitly unaligned
4555 pseudos. We just turn off auto-alignment and call down to cons. */
4557 static void
4558 s_alpha_ucons (int bytes)
4560 int hold = alpha_auto_align_on;
4561 alpha_auto_align_on = 0;
4562 cons (bytes);
4563 alpha_auto_align_on = hold;
4566 /* Switch the working cpu type. */
4568 static void
4569 s_alpha_arch (int ignored ATTRIBUTE_UNUSED)
4571 char *name, ch;
4572 const struct cpu_type *p;
4574 SKIP_WHITESPACE ();
4575 name = input_line_pointer;
4576 ch = get_symbol_end ();
4578 for (p = cpu_types; p->name; ++p)
4579 if (strcmp (name, p->name) == 0)
4581 alpha_target_name = p->name, alpha_target = p->flags;
4582 goto found;
4584 as_warn ("Unknown CPU identifier `%s'", name);
4586 found:
4587 *input_line_pointer = ch;
4588 demand_empty_rest_of_line ();
4591 #ifdef DEBUG1
4592 /* print token expression with alpha specific extension. */
4594 static void
4595 alpha_print_token (FILE *f, const expressionS *exp)
4597 switch (exp->X_op)
4599 case O_cpregister:
4600 putc (',', f);
4601 /* FALLTHRU */
4602 case O_pregister:
4603 putc ('(', f);
4605 expressionS nexp = *exp;
4606 nexp.X_op = O_register;
4607 print_expr (f, &nexp);
4609 putc (')', f);
4610 break;
4611 default:
4612 print_expr (f, exp);
4613 break;
4616 #endif
4618 /* The target specific pseudo-ops which we support. */
4620 const pseudo_typeS md_pseudo_table[] =
4622 #ifdef OBJ_ECOFF
4623 {"comm", s_alpha_comm, 0}, /* OSF1 compiler does this. */
4624 {"rdata", s_alpha_rdata, 0},
4625 #endif
4626 {"text", s_alpha_text, 0},
4627 {"data", s_alpha_data, 0},
4628 #ifdef OBJ_ECOFF
4629 {"sdata", s_alpha_sdata, 0},
4630 #endif
4631 #ifdef OBJ_ELF
4632 {"section", s_alpha_section, 0},
4633 {"section.s", s_alpha_section, 0},
4634 {"sect", s_alpha_section, 0},
4635 {"sect.s", s_alpha_section, 0},
4636 #endif
4637 #ifdef OBJ_EVAX
4638 { "pdesc", s_alpha_pdesc, 0},
4639 { "name", s_alpha_name, 0},
4640 { "linkage", s_alpha_linkage, 0},
4641 { "code_address", s_alpha_code_address, 0},
4642 { "ent", s_alpha_ent, 0},
4643 { "frame", s_alpha_frame, 0},
4644 { "fp_save", s_alpha_fp_save, 0},
4645 { "mask", s_alpha_mask, 0},
4646 { "fmask", s_alpha_fmask, 0},
4647 { "end", s_alpha_end, 0},
4648 { "file", s_alpha_file, 0},
4649 { "rdata", s_alpha_section, 1},
4650 { "comm", s_alpha_comm, 0},
4651 { "link", s_alpha_section, 3},
4652 { "ctors", s_alpha_section, 4},
4653 { "dtors", s_alpha_section, 5},
4654 #endif
4655 #ifdef OBJ_ELF
4656 /* Frame related pseudos. */
4657 {"ent", s_alpha_ent, 0},
4658 {"end", s_alpha_end, 0},
4659 {"mask", s_alpha_mask, 0},
4660 {"fmask", s_alpha_mask, 1},
4661 {"frame", s_alpha_frame, 0},
4662 {"prologue", s_alpha_prologue, 0},
4663 {"file", s_alpha_file, 5},
4664 {"loc", s_alpha_loc, 9},
4665 {"stabs", s_alpha_stab, 's'},
4666 {"stabn", s_alpha_stab, 'n'},
4667 {"usepv", s_alpha_usepv, 0},
4668 /* COFF debugging related pseudos. */
4669 {"begin", s_alpha_coff_wrapper, 0},
4670 {"bend", s_alpha_coff_wrapper, 1},
4671 {"def", s_alpha_coff_wrapper, 2},
4672 {"dim", s_alpha_coff_wrapper, 3},
4673 {"endef", s_alpha_coff_wrapper, 4},
4674 {"scl", s_alpha_coff_wrapper, 5},
4675 {"tag", s_alpha_coff_wrapper, 6},
4676 {"val", s_alpha_coff_wrapper, 7},
4677 #else
4678 {"prologue", s_ignore, 0},
4679 #endif
4680 {"gprel32", s_alpha_gprel32, 0},
4681 {"t_floating", s_alpha_float_cons, 'd'},
4682 {"s_floating", s_alpha_float_cons, 'f'},
4683 {"f_floating", s_alpha_float_cons, 'F'},
4684 {"g_floating", s_alpha_float_cons, 'G'},
4685 {"d_floating", s_alpha_float_cons, 'D'},
4687 {"proc", s_alpha_proc, 0},
4688 {"aproc", s_alpha_proc, 1},
4689 {"set", s_alpha_set, 0},
4690 {"reguse", s_ignore, 0},
4691 {"livereg", s_ignore, 0},
4692 {"base", s_alpha_base, 0}, /*??*/
4693 {"option", s_ignore, 0},
4694 {"aent", s_ignore, 0},
4695 {"ugen", s_ignore, 0},
4696 {"eflag", s_ignore, 0},
4698 {"align", s_alpha_align, 0},
4699 {"double", s_alpha_float_cons, 'd'},
4700 {"float", s_alpha_float_cons, 'f'},
4701 {"single", s_alpha_float_cons, 'f'},
4702 {"ascii", s_alpha_stringer, 0},
4703 {"asciz", s_alpha_stringer, 1},
4704 {"string", s_alpha_stringer, 1},
4705 {"space", s_alpha_space, 0},
4706 {"skip", s_alpha_space, 0},
4707 {"zero", s_alpha_space, 0},
4709 /* Unaligned data pseudos. */
4710 {"uword", s_alpha_ucons, 2},
4711 {"ulong", s_alpha_ucons, 4},
4712 {"uquad", s_alpha_ucons, 8},
4714 #ifdef OBJ_ELF
4715 /* Dwarf wants these versions of unaligned. */
4716 {"2byte", s_alpha_ucons, 2},
4717 {"4byte", s_alpha_ucons, 4},
4718 {"8byte", s_alpha_ucons, 8},
4719 #endif
4721 /* We don't do any optimizing, so we can safely ignore these. */
4722 {"noalias", s_ignore, 0},
4723 {"alias", s_ignore, 0},
4725 {"arch", s_alpha_arch, 0},
4727 {NULL, 0, 0},
4730 #ifdef OBJ_ECOFF
4732 /* @@@ GP selection voodoo. All of this seems overly complicated and
4733 unnecessary; which is the primary reason it's for ECOFF only. */
4734 static inline void maybe_set_gp PARAMS ((asection *));
4736 static inline void
4737 maybe_set_gp (asection *sec)
4739 bfd_vma vma;
4741 if (!sec)
4742 return;
4743 vma = bfd_get_section_vma (foo, sec);
4744 if (vma && vma < alpha_gp_value)
4745 alpha_gp_value = vma;
4748 static void
4749 select_gp_value (void)
4751 assert (alpha_gp_value == 0);
4753 /* Get minus-one in whatever width... */
4754 alpha_gp_value = 0;
4755 alpha_gp_value--;
4757 /* Select the smallest VMA of these existing sections. */
4758 maybe_set_gp (alpha_lita_section);
4760 /* @@ Will a simple 0x8000 work here? If not, why not? */
4761 #define GP_ADJUSTMENT (0x8000 - 0x10)
4763 alpha_gp_value += GP_ADJUSTMENT;
4765 S_SET_VALUE (alpha_gp_symbol, alpha_gp_value);
4767 #ifdef DEBUG1
4768 printf (_("Chose GP value of %lx\n"), alpha_gp_value);
4769 #endif
4771 #endif /* OBJ_ECOFF */
4773 #ifdef OBJ_ELF
4774 /* Map 's' to SHF_ALPHA_GPREL. */
4777 alpha_elf_section_letter (int letter, char **ptr_msg)
4779 if (letter == 's')
4780 return SHF_ALPHA_GPREL;
4782 *ptr_msg = _("Bad .section directive: want a,s,w,x,M,S,G,T in string");
4783 return -1;
4786 /* Map SHF_ALPHA_GPREL to SEC_SMALL_DATA. */
4788 flagword
4789 alpha_elf_section_flags (flagword flags, int attr, int type ATTRIBUTE_UNUSED)
4791 if (attr & SHF_ALPHA_GPREL)
4792 flags |= SEC_SMALL_DATA;
4793 return flags;
4795 #endif /* OBJ_ELF */
4797 /* This is called from HANDLE_ALIGN in write.c. Fill in the contents
4798 of an rs_align_code fragment. */
4800 void
4801 alpha_handle_align (fragS *fragp)
4803 static char const unop[4] = { 0x00, 0x00, 0xfe, 0x2f };
4804 static char const nopunop[8] =
4806 0x1f, 0x04, 0xff, 0x47,
4807 0x00, 0x00, 0xfe, 0x2f
4810 int bytes, fix;
4811 char *p;
4813 if (fragp->fr_type != rs_align_code)
4814 return;
4816 bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix;
4817 p = fragp->fr_literal + fragp->fr_fix;
4818 fix = 0;
4820 if (bytes & 3)
4822 fix = bytes & 3;
4823 memset (p, 0, fix);
4824 p += fix;
4825 bytes -= fix;
4828 if (bytes & 4)
4830 memcpy (p, unop, 4);
4831 p += 4;
4832 bytes -= 4;
4833 fix += 4;
4836 memcpy (p, nopunop, 8);
4838 fragp->fr_fix += fix;
4839 fragp->fr_var = 8;
4842 /* Public interface functions. */
4844 /* This function is called once, at assembler startup time. It sets
4845 up all the tables, etc. that the MD part of the assembler will
4846 need, that can be determined before arguments are parsed. */
4848 void
4849 md_begin (void)
4851 unsigned int i;
4853 /* Verify that X_op field is wide enough. */
4855 expressionS e;
4857 e.X_op = O_max;
4858 assert (e.X_op == O_max);
4861 /* Create the opcode hash table. */
4862 alpha_opcode_hash = hash_new ();
4864 for (i = 0; i < alpha_num_opcodes;)
4866 const char *name, *retval, *slash;
4868 name = alpha_opcodes[i].name;
4869 retval = hash_insert (alpha_opcode_hash, name, (void *) &alpha_opcodes[i]);
4870 if (retval)
4871 as_fatal (_("internal error: can't hash opcode `%s': %s"),
4872 name, retval);
4874 /* Some opcodes include modifiers of various sorts with a "/mod"
4875 syntax, like the architecture manual suggests. However, for
4876 use with gcc at least, we also need access to those same opcodes
4877 without the "/". */
4879 if ((slash = strchr (name, '/')) != NULL)
4881 char *p = xmalloc (strlen (name));
4883 memcpy (p, name, slash - name);
4884 strcpy (p + (slash - name), slash + 1);
4886 (void) hash_insert (alpha_opcode_hash, p, (void *) &alpha_opcodes[i]);
4887 /* Ignore failures -- the opcode table does duplicate some
4888 variants in different forms, like "hw_stq" and "hw_st/q". */
4891 while (++i < alpha_num_opcodes
4892 && (alpha_opcodes[i].name == name
4893 || !strcmp (alpha_opcodes[i].name, name)))
4894 continue;
4897 /* Create the macro hash table. */
4898 alpha_macro_hash = hash_new ();
4900 for (i = 0; i < alpha_num_macros;)
4902 const char *name, *retval;
4904 name = alpha_macros[i].name;
4905 retval = hash_insert (alpha_macro_hash, name, (void *) &alpha_macros[i]);
4906 if (retval)
4907 as_fatal (_("internal error: can't hash macro `%s': %s"),
4908 name, retval);
4910 while (++i < alpha_num_macros
4911 && (alpha_macros[i].name == name
4912 || !strcmp (alpha_macros[i].name, name)))
4913 continue;
4916 /* Construct symbols for each of the registers. */
4917 for (i = 0; i < 32; ++i)
4919 char name[4];
4921 sprintf (name, "$%d", i);
4922 alpha_register_table[i] = symbol_create (name, reg_section, i,
4923 &zero_address_frag);
4926 for (; i < 64; ++i)
4928 char name[5];
4930 sprintf (name, "$f%d", i - 32);
4931 alpha_register_table[i] = symbol_create (name, reg_section, i,
4932 &zero_address_frag);
4935 /* Create the special symbols and sections we'll be using. */
4937 /* So .sbss will get used for tiny objects. */
4938 bfd_set_gp_size (stdoutput, g_switch_value);
4940 #ifdef OBJ_ECOFF
4941 create_literal_section (".lita", &alpha_lita_section, &alpha_lita_symbol);
4943 /* For handling the GP, create a symbol that won't be output in the
4944 symbol table. We'll edit it out of relocs later. */
4945 alpha_gp_symbol = symbol_create ("<GP value>", alpha_lita_section, 0x8000,
4946 &zero_address_frag);
4947 #endif
4949 #ifdef OBJ_EVAX
4950 create_literal_section (".link", &alpha_link_section, &alpha_link_symbol);
4951 #endif
4953 #ifdef OBJ_ELF
4954 if (ECOFF_DEBUGGING)
4956 segT sec = subseg_new (".mdebug", (subsegT) 0);
4957 bfd_set_section_flags (stdoutput, sec, SEC_HAS_CONTENTS | SEC_READONLY);
4958 bfd_set_section_alignment (stdoutput, sec, 3);
4960 #endif
4962 /* Create literal lookup hash table. */
4963 alpha_literal_hash = hash_new ();
4965 subseg_set (text_section, 0);
4968 /* The public interface to the instruction assembler. */
4970 void
4971 md_assemble (char *str)
4973 /* Current maximum is 13. */
4974 char opname[32];
4975 expressionS tok[MAX_INSN_ARGS];
4976 int ntok, trunclen;
4977 size_t opnamelen;
4979 /* Split off the opcode. */
4980 opnamelen = strspn (str, "abcdefghijklmnopqrstuvwxyz_/46819");
4981 trunclen = (opnamelen < sizeof (opname) - 1
4982 ? opnamelen
4983 : sizeof (opname) - 1);
4984 memcpy (opname, str, trunclen);
4985 opname[trunclen] = '\0';
4987 /* Tokenize the rest of the line. */
4988 if ((ntok = tokenize_arguments (str + opnamelen, tok, MAX_INSN_ARGS)) < 0)
4990 if (ntok != TOKENIZE_ERROR_REPORT)
4991 as_bad (_("syntax error"));
4993 return;
4996 /* Finish it off. */
4997 assemble_tokens (opname, tok, ntok, alpha_macros_on);
5000 /* Round up a section's size to the appropriate boundary. */
5002 valueT
5003 md_section_align (segT seg, valueT size)
5005 int align = bfd_get_section_alignment (stdoutput, seg);
5006 valueT mask = ((valueT) 1 << align) - 1;
5008 return (size + mask) & ~mask;
5011 /* Turn a string in input_line_pointer into a floating point constant
5012 of type TYPE, and store the appropriate bytes in *LITP. The number
5013 of LITTLENUMS emitted is stored in *SIZEP. An error message is
5014 returned, or NULL on OK. */
5016 /* Equal to MAX_PRECISION in atof-ieee.c. */
5017 #define MAX_LITTLENUMS 6
5019 extern char *vax_md_atof (int, char *, int *);
5021 char *
5022 md_atof (int type, char *litP, int *sizeP)
5024 int prec;
5025 LITTLENUM_TYPE words[MAX_LITTLENUMS];
5026 LITTLENUM_TYPE *wordP;
5027 char *t;
5029 switch (type)
5031 /* VAX floats. */
5032 case 'G':
5033 /* VAX md_atof doesn't like "G" for some reason. */
5034 type = 'g';
5035 case 'F':
5036 case 'D':
5037 return vax_md_atof (type, litP, sizeP);
5039 /* IEEE floats. */
5040 case 'f':
5041 prec = 2;
5042 break;
5044 case 'd':
5045 prec = 4;
5046 break;
5048 case 'x':
5049 case 'X':
5050 prec = 6;
5051 break;
5053 case 'p':
5054 case 'P':
5055 prec = 6;
5056 break;
5058 default:
5059 *sizeP = 0;
5060 return _("Bad call to MD_ATOF()");
5062 t = atof_ieee (input_line_pointer, type, words);
5063 if (t)
5064 input_line_pointer = t;
5065 *sizeP = prec * sizeof (LITTLENUM_TYPE);
5067 for (wordP = words + prec - 1; prec--;)
5069 md_number_to_chars (litP, (long) (*wordP--), sizeof (LITTLENUM_TYPE));
5070 litP += sizeof (LITTLENUM_TYPE);
5073 return 0;
5076 /* Take care of the target-specific command-line options. */
5079 md_parse_option (int c, char *arg)
5081 switch (c)
5083 case 'F':
5084 alpha_nofloats_on = 1;
5085 break;
5087 case OPTION_32ADDR:
5088 alpha_addr32_on = 1;
5089 break;
5091 case 'g':
5092 alpha_debug = 1;
5093 break;
5095 case 'G':
5096 g_switch_value = atoi (arg);
5097 break;
5099 case 'm':
5101 const struct cpu_type *p;
5103 for (p = cpu_types; p->name; ++p)
5104 if (strcmp (arg, p->name) == 0)
5106 alpha_target_name = p->name, alpha_target = p->flags;
5107 goto found;
5109 as_warn (_("Unknown CPU identifier `%s'"), arg);
5110 found:;
5112 break;
5114 #ifdef OBJ_EVAX
5115 case '+': /* For g++. Hash any name > 63 chars long. */
5116 alpha_flag_hash_long_names = 1;
5117 break;
5119 case 'H': /* Show new symbol after hash truncation. */
5120 alpha_flag_show_after_trunc = 1;
5121 break;
5123 case 'h': /* For gnu-c/vax compatibility. */
5124 break;
5125 #endif
5127 case OPTION_RELAX:
5128 alpha_flag_relax = 1;
5129 break;
5131 #ifdef OBJ_ELF
5132 case OPTION_MDEBUG:
5133 alpha_flag_mdebug = 1;
5134 break;
5135 case OPTION_NO_MDEBUG:
5136 alpha_flag_mdebug = 0;
5137 break;
5138 #endif
5140 default:
5141 return 0;
5144 return 1;
5147 /* Print a description of the command-line options that we accept. */
5149 void
5150 md_show_usage (FILE *stream)
5152 fputs (_("\
5153 Alpha options:\n\
5154 -32addr treat addresses as 32-bit values\n\
5155 -F lack floating point instructions support\n\
5156 -mev4 | -mev45 | -mev5 | -mev56 | -mpca56 | -mev6 | -mev67 | -mev68 | -mall\n\
5157 specify variant of Alpha architecture\n\
5158 -m21064 | -m21066 | -m21164 | -m21164a | -m21164pc | -m21264 | -m21264a | -m21264b\n\
5159 these variants include PALcode opcodes\n"),
5160 stream);
5161 #ifdef OBJ_EVAX
5162 fputs (_("\
5163 VMS options:\n\
5164 -+ hash encode (don't truncate) names longer than 64 characters\n\
5165 -H show new symbol after hash truncation\n"),
5166 stream);
5167 #endif
5170 /* Decide from what point a pc-relative relocation is relative to,
5171 relative to the pc-relative fixup. Er, relatively speaking. */
5173 long
5174 md_pcrel_from (fixS *fixP)
5176 valueT addr = fixP->fx_where + fixP->fx_frag->fr_address;
5178 switch (fixP->fx_r_type)
5180 case BFD_RELOC_23_PCREL_S2:
5181 case BFD_RELOC_ALPHA_HINT:
5182 case BFD_RELOC_ALPHA_BRSGP:
5183 return addr + 4;
5184 default:
5185 return addr;
5189 /* Attempt to simplify or even eliminate a fixup. The return value is
5190 ignored; perhaps it was once meaningful, but now it is historical.
5191 To indicate that a fixup has been eliminated, set fixP->fx_done.
5193 For ELF, here it is that we transform the GPDISP_HI16 reloc we used
5194 internally into the GPDISP reloc used externally. We had to do
5195 this so that we'd have the GPDISP_LO16 reloc as a tag to compute
5196 the distance to the "lda" instruction for setting the addend to
5197 GPDISP. */
5199 void
5200 md_apply_fix3 (fixS *fixP, valueT * valP, segT seg)
5202 char * const fixpos = fixP->fx_frag->fr_literal + fixP->fx_where;
5203 valueT value = * valP;
5204 unsigned image, size;
5206 switch (fixP->fx_r_type)
5208 /* The GPDISP relocations are processed internally with a symbol
5209 referring to the current function's section; we need to drop
5210 in a value which, when added to the address of the start of
5211 the function, gives the desired GP. */
5212 case BFD_RELOC_ALPHA_GPDISP_HI16:
5214 fixS *next = fixP->fx_next;
5216 /* With user-specified !gpdisp relocations, we can be missing
5217 the matching LO16 reloc. We will have already issued an
5218 error message. */
5219 if (next)
5220 fixP->fx_offset = (next->fx_frag->fr_address + next->fx_where
5221 - fixP->fx_frag->fr_address - fixP->fx_where);
5223 value = (value - sign_extend_16 (value)) >> 16;
5225 #ifdef OBJ_ELF
5226 fixP->fx_r_type = BFD_RELOC_ALPHA_GPDISP;
5227 #endif
5228 goto do_reloc_gp;
5230 case BFD_RELOC_ALPHA_GPDISP_LO16:
5231 value = sign_extend_16 (value);
5232 fixP->fx_offset = 0;
5233 #ifdef OBJ_ELF
5234 fixP->fx_done = 1;
5235 #endif
5237 do_reloc_gp:
5238 fixP->fx_addsy = section_symbol (seg);
5239 md_number_to_chars (fixpos, value, 2);
5240 break;
5242 case BFD_RELOC_16:
5243 if (fixP->fx_pcrel)
5244 fixP->fx_r_type = BFD_RELOC_16_PCREL;
5245 size = 2;
5246 goto do_reloc_xx;
5248 case BFD_RELOC_32:
5249 if (fixP->fx_pcrel)
5250 fixP->fx_r_type = BFD_RELOC_32_PCREL;
5251 size = 4;
5252 goto do_reloc_xx;
5254 case BFD_RELOC_64:
5255 if (fixP->fx_pcrel)
5256 fixP->fx_r_type = BFD_RELOC_64_PCREL;
5257 size = 8;
5259 do_reloc_xx:
5260 if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0)
5262 md_number_to_chars (fixpos, value, size);
5263 goto done;
5265 return;
5267 #ifdef OBJ_ECOFF
5268 case BFD_RELOC_GPREL32:
5269 assert (fixP->fx_subsy == alpha_gp_symbol);
5270 fixP->fx_subsy = 0;
5271 /* FIXME: inherited this obliviousness of `value' -- why? */
5272 md_number_to_chars (fixpos, -alpha_gp_value, 4);
5273 break;
5274 #else
5275 case BFD_RELOC_GPREL32:
5276 #endif
5277 case BFD_RELOC_GPREL16:
5278 case BFD_RELOC_ALPHA_GPREL_HI16:
5279 case BFD_RELOC_ALPHA_GPREL_LO16:
5280 return;
5282 case BFD_RELOC_23_PCREL_S2:
5283 if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0)
5285 image = bfd_getl32 (fixpos);
5286 image = (image & ~0x1FFFFF) | ((value >> 2) & 0x1FFFFF);
5287 goto write_done;
5289 return;
5291 case BFD_RELOC_ALPHA_HINT:
5292 if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0)
5294 image = bfd_getl32 (fixpos);
5295 image = (image & ~0x3FFF) | ((value >> 2) & 0x3FFF);
5296 goto write_done;
5298 return;
5300 #ifdef OBJ_ELF
5301 case BFD_RELOC_ALPHA_BRSGP:
5302 return;
5304 case BFD_RELOC_ALPHA_TLSGD:
5305 case BFD_RELOC_ALPHA_TLSLDM:
5306 case BFD_RELOC_ALPHA_GOTDTPREL16:
5307 case BFD_RELOC_ALPHA_DTPREL_HI16:
5308 case BFD_RELOC_ALPHA_DTPREL_LO16:
5309 case BFD_RELOC_ALPHA_DTPREL16:
5310 case BFD_RELOC_ALPHA_GOTTPREL16:
5311 case BFD_RELOC_ALPHA_TPREL_HI16:
5312 case BFD_RELOC_ALPHA_TPREL_LO16:
5313 case BFD_RELOC_ALPHA_TPREL16:
5314 if (fixP->fx_addsy)
5315 S_SET_THREAD_LOCAL (fixP->fx_addsy);
5316 return;
5317 #endif
5319 #ifdef OBJ_ECOFF
5320 case BFD_RELOC_ALPHA_LITERAL:
5321 md_number_to_chars (fixpos, value, 2);
5322 return;
5323 #endif
5324 case BFD_RELOC_ALPHA_ELF_LITERAL:
5325 case BFD_RELOC_ALPHA_LITUSE:
5326 case BFD_RELOC_ALPHA_LINKAGE:
5327 case BFD_RELOC_ALPHA_CODEADDR:
5328 return;
5330 case BFD_RELOC_VTABLE_INHERIT:
5331 case BFD_RELOC_VTABLE_ENTRY:
5332 return;
5334 default:
5336 const struct alpha_operand *operand;
5338 if ((int) fixP->fx_r_type >= 0)
5339 as_fatal (_("unhandled relocation type %s"),
5340 bfd_get_reloc_code_name (fixP->fx_r_type));
5342 assert (-(int) fixP->fx_r_type < (int) alpha_num_operands);
5343 operand = &alpha_operands[-(int) fixP->fx_r_type];
5345 /* The rest of these fixups only exist internally during symbol
5346 resolution and have no representation in the object file.
5347 Therefore they must be completely resolved as constants. */
5349 if (fixP->fx_addsy != 0
5350 && S_GET_SEGMENT (fixP->fx_addsy) != absolute_section)
5351 as_bad_where (fixP->fx_file, fixP->fx_line,
5352 _("non-absolute expression in constant field"));
5354 image = bfd_getl32 (fixpos);
5355 image = insert_operand (image, operand, (offsetT) value,
5356 fixP->fx_file, fixP->fx_line);
5358 goto write_done;
5361 if (fixP->fx_addsy != 0 || fixP->fx_pcrel != 0)
5362 return;
5363 else
5365 as_warn_where (fixP->fx_file, fixP->fx_line,
5366 _("type %d reloc done?\n"), (int) fixP->fx_r_type);
5367 goto done;
5370 write_done:
5371 md_number_to_chars (fixpos, image, 4);
5373 done:
5374 fixP->fx_done = 1;
5377 /* Look for a register name in the given symbol. */
5379 symbolS *
5380 md_undefined_symbol (char *name)
5382 if (*name == '$')
5384 int is_float = 0, num;
5386 switch (*++name)
5388 case 'f':
5389 if (name[1] == 'p' && name[2] == '\0')
5390 return alpha_register_table[AXP_REG_FP];
5391 is_float = 32;
5392 /* Fall through. */
5394 case 'r':
5395 if (!ISDIGIT (*++name))
5396 break;
5397 /* Fall through. */
5399 case '0': case '1': case '2': case '3': case '4':
5400 case '5': case '6': case '7': case '8': case '9':
5401 if (name[1] == '\0')
5402 num = name[0] - '0';
5403 else if (name[0] != '0' && ISDIGIT (name[1]) && name[2] == '\0')
5405 num = (name[0] - '0') * 10 + name[1] - '0';
5406 if (num >= 32)
5407 break;
5409 else
5410 break;
5412 if (!alpha_noat_on && (num + is_float) == AXP_REG_AT)
5413 as_warn (_("Used $at without \".set noat\""));
5414 return alpha_register_table[num + is_float];
5416 case 'a':
5417 if (name[1] == 't' && name[2] == '\0')
5419 if (!alpha_noat_on)
5420 as_warn (_("Used $at without \".set noat\""));
5421 return alpha_register_table[AXP_REG_AT];
5423 break;
5425 case 'g':
5426 if (name[1] == 'p' && name[2] == '\0')
5427 return alpha_register_table[alpha_gp_register];
5428 break;
5430 case 's':
5431 if (name[1] == 'p' && name[2] == '\0')
5432 return alpha_register_table[AXP_REG_SP];
5433 break;
5436 return NULL;
5439 #ifdef OBJ_ECOFF
5440 /* @@@ Magic ECOFF bits. */
5442 void
5443 alpha_frob_ecoff_data (void)
5445 select_gp_value ();
5446 /* $zero and $f31 are read-only. */
5447 alpha_gprmask &= ~1;
5448 alpha_fprmask &= ~1;
5450 #endif
5452 /* Hook to remember a recently defined label so that the auto-align
5453 code can adjust the symbol after we know what alignment will be
5454 required. */
5456 void
5457 alpha_define_label (symbolS *sym)
5459 alpha_insn_label = sym;
5462 /* Return true if we must always emit a reloc for a type and false if
5463 there is some hope of resolving it at assembly time. */
5466 alpha_force_relocation (fixS *f)
5468 if (alpha_flag_relax)
5469 return 1;
5471 switch (f->fx_r_type)
5473 case BFD_RELOC_ALPHA_GPDISP_HI16:
5474 case BFD_RELOC_ALPHA_GPDISP_LO16:
5475 case BFD_RELOC_ALPHA_GPDISP:
5476 case BFD_RELOC_ALPHA_LITERAL:
5477 case BFD_RELOC_ALPHA_ELF_LITERAL:
5478 case BFD_RELOC_ALPHA_LITUSE:
5479 case BFD_RELOC_GPREL16:
5480 case BFD_RELOC_GPREL32:
5481 case BFD_RELOC_ALPHA_GPREL_HI16:
5482 case BFD_RELOC_ALPHA_GPREL_LO16:
5483 case BFD_RELOC_ALPHA_LINKAGE:
5484 case BFD_RELOC_ALPHA_CODEADDR:
5485 case BFD_RELOC_ALPHA_BRSGP:
5486 case BFD_RELOC_ALPHA_TLSGD:
5487 case BFD_RELOC_ALPHA_TLSLDM:
5488 case BFD_RELOC_ALPHA_GOTDTPREL16:
5489 case BFD_RELOC_ALPHA_DTPREL_HI16:
5490 case BFD_RELOC_ALPHA_DTPREL_LO16:
5491 case BFD_RELOC_ALPHA_DTPREL16:
5492 case BFD_RELOC_ALPHA_GOTTPREL16:
5493 case BFD_RELOC_ALPHA_TPREL_HI16:
5494 case BFD_RELOC_ALPHA_TPREL_LO16:
5495 case BFD_RELOC_ALPHA_TPREL16:
5496 return 1;
5498 default:
5499 break;
5502 return generic_force_reloc (f);
5505 /* Return true if we can partially resolve a relocation now. */
5508 alpha_fix_adjustable (fixS *f)
5510 /* Are there any relocation types for which we must generate a
5511 reloc but we can adjust the values contained within it? */
5512 switch (f->fx_r_type)
5514 case BFD_RELOC_ALPHA_GPDISP_HI16:
5515 case BFD_RELOC_ALPHA_GPDISP_LO16:
5516 case BFD_RELOC_ALPHA_GPDISP:
5517 return 0;
5519 case BFD_RELOC_ALPHA_LITERAL:
5520 case BFD_RELOC_ALPHA_ELF_LITERAL:
5521 case BFD_RELOC_ALPHA_LITUSE:
5522 case BFD_RELOC_ALPHA_LINKAGE:
5523 case BFD_RELOC_ALPHA_CODEADDR:
5524 return 1;
5526 case BFD_RELOC_VTABLE_ENTRY:
5527 case BFD_RELOC_VTABLE_INHERIT:
5528 return 0;
5530 case BFD_RELOC_GPREL16:
5531 case BFD_RELOC_GPREL32:
5532 case BFD_RELOC_ALPHA_GPREL_HI16:
5533 case BFD_RELOC_ALPHA_GPREL_LO16:
5534 case BFD_RELOC_23_PCREL_S2:
5535 case BFD_RELOC_32:
5536 case BFD_RELOC_64:
5537 case BFD_RELOC_ALPHA_HINT:
5538 return 1;
5540 case BFD_RELOC_ALPHA_TLSGD:
5541 case BFD_RELOC_ALPHA_TLSLDM:
5542 case BFD_RELOC_ALPHA_GOTDTPREL16:
5543 case BFD_RELOC_ALPHA_DTPREL_HI16:
5544 case BFD_RELOC_ALPHA_DTPREL_LO16:
5545 case BFD_RELOC_ALPHA_DTPREL16:
5546 case BFD_RELOC_ALPHA_GOTTPREL16:
5547 case BFD_RELOC_ALPHA_TPREL_HI16:
5548 case BFD_RELOC_ALPHA_TPREL_LO16:
5549 case BFD_RELOC_ALPHA_TPREL16:
5550 /* ??? No idea why we can't return a reference to .tbss+10, but
5551 we're preventing this in the other assemblers. Follow for now. */
5552 return 0;
5554 #ifdef OBJ_ELF
5555 case BFD_RELOC_ALPHA_BRSGP:
5556 /* If we have a BRSGP reloc to a local symbol, adjust it to BRADDR and
5557 let it get resolved at assembly time. */
5559 symbolS *sym = f->fx_addsy;
5560 const char *name;
5561 int offset = 0;
5563 if (generic_force_reloc (f))
5564 return 0;
5566 switch (S_GET_OTHER (sym) & STO_ALPHA_STD_GPLOAD)
5568 case STO_ALPHA_NOPV:
5569 break;
5570 case STO_ALPHA_STD_GPLOAD:
5571 offset = 8;
5572 break;
5573 default:
5574 if (S_IS_LOCAL (sym))
5575 name = "<local>";
5576 else
5577 name = S_GET_NAME (sym);
5578 as_bad_where (f->fx_file, f->fx_line,
5579 _("!samegp reloc against symbol without .prologue: %s"),
5580 name);
5581 break;
5583 f->fx_r_type = BFD_RELOC_23_PCREL_S2;
5584 f->fx_offset += offset;
5585 return 1;
5587 #endif
5589 default:
5590 return 1;
5594 /* Generate the BFD reloc to be stuck in the object file from the
5595 fixup used internally in the assembler. */
5597 arelent *
5598 tc_gen_reloc (asection *sec ATTRIBUTE_UNUSED,
5599 fixS *fixp)
5601 arelent *reloc;
5603 reloc = xmalloc (sizeof (* reloc));
5604 reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
5605 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
5606 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
5608 /* Make sure none of our internal relocations make it this far.
5609 They'd better have been fully resolved by this point. */
5610 assert ((int) fixp->fx_r_type > 0);
5612 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
5613 if (reloc->howto == NULL)
5615 as_bad_where (fixp->fx_file, fixp->fx_line,
5616 _("cannot represent `%s' relocation in object file"),
5617 bfd_get_reloc_code_name (fixp->fx_r_type));
5618 return NULL;
5621 if (!fixp->fx_pcrel != !reloc->howto->pc_relative)
5622 as_fatal (_("internal error? cannot generate `%s' relocation"),
5623 bfd_get_reloc_code_name (fixp->fx_r_type));
5625 assert (!fixp->fx_pcrel == !reloc->howto->pc_relative);
5627 #ifdef OBJ_ECOFF
5628 if (fixp->fx_r_type == BFD_RELOC_ALPHA_LITERAL)
5629 /* Fake out bfd_perform_relocation. sigh. */
5630 reloc->addend = -alpha_gp_value;
5631 else
5632 #endif
5634 reloc->addend = fixp->fx_offset;
5635 #ifdef OBJ_ELF
5636 /* Ohhh, this is ugly. The problem is that if this is a local global
5637 symbol, the relocation will entirely be performed at link time, not
5638 at assembly time. bfd_perform_reloc doesn't know about this sort
5639 of thing, and as a result we need to fake it out here. */
5640 if ((S_IS_EXTERN (fixp->fx_addsy) || S_IS_WEAK (fixp->fx_addsy)
5641 || (S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_MERGE)
5642 || (S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_THREAD_LOCAL))
5643 && !S_IS_COMMON (fixp->fx_addsy))
5644 reloc->addend -= symbol_get_bfdsym (fixp->fx_addsy)->value;
5645 #endif
5648 return reloc;
5651 /* Parse a register name off of the input_line and return a register
5652 number. Gets md_undefined_symbol above to do the register name
5653 matching for us.
5655 Only called as a part of processing the ECOFF .frame directive. */
5658 tc_get_register (int frame ATTRIBUTE_UNUSED)
5660 int framereg = AXP_REG_SP;
5662 SKIP_WHITESPACE ();
5663 if (*input_line_pointer == '$')
5665 char *s = input_line_pointer;
5666 char c = get_symbol_end ();
5667 symbolS *sym = md_undefined_symbol (s);
5669 *strchr (s, '\0') = c;
5670 if (sym && (framereg = S_GET_VALUE (sym)) <= 31)
5671 goto found;
5673 as_warn (_("frame reg expected, using $%d."), framereg);
5675 found:
5676 note_gpreg (framereg);
5677 return framereg;
5680 /* This is called before the symbol table is processed. In order to
5681 work with gcc when using mips-tfile, we must keep all local labels.
5682 However, in other cases, we want to discard them. If we were
5683 called with -g, but we didn't see any debugging information, it may
5684 mean that gcc is smuggling debugging information through to
5685 mips-tfile, in which case we must generate all local labels. */
5687 #ifdef OBJ_ECOFF
5689 void
5690 alpha_frob_file_before_adjust (void)
5692 if (alpha_debug != 0
5693 && ! ecoff_debugging_seen)
5694 flag_keep_locals = 1;
5697 #endif /* OBJ_ECOFF */
5699 /* The Alpha has support for some VAX floating point types, as well as for
5700 IEEE floating point. We consider IEEE to be the primary floating point
5701 format, and sneak in the VAX floating point support here. */
5702 #define md_atof vax_md_atof
5703 #include "config/atof-vax.c"