tc-alpha.c revision 1.1 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, 2007, 2008 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.
9
10 This file is part of GAS, the GNU Assembler.
11
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 3, or (at your option)
15 any later version.
16
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.
21
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, 51 Franklin Street - Fifth Floor, Boston, MA
25 02110-1301, USA. */
26
27 /* Mach Operating System
28 Copyright (c) 1993 Carnegie Mellon University
29 All Rights Reserved.
30
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.
36
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.
40
41 Carnegie Mellon requests users of this software to return to
42
43 Software Distribution Coordinator or Software.Distribution (at) CS.CMU.EDU
44 School of Computer Science
45 Carnegie Mellon University
46 Pittsburgh PA 15213-3890
47
48 any improvements or extensions that they make and grant Carnegie the
49 rights to redistribute these changes. */
50
51 #include "as.h"
52 #include "subsegs.h"
53 #include "struc-symbol.h"
54 #include "ecoff.h"
55
56 #include "opcode/alpha.h"
57
58 #ifdef OBJ_ELF
59 #include "elf/alpha.h"
60 #include "dwarf2dbg.h"
61 #endif
62
63 #include "dw2gencfi.h"
64 #include "safe-ctype.h"
65
66 /* Local types. */
68
69 #define TOKENIZE_ERROR -1
70 #define TOKENIZE_ERROR_REPORT -2
71 #define MAX_INSN_FIXUPS 2
72 #define MAX_INSN_ARGS 5
73
74 struct alpha_fixup
75 {
76 expressionS exp;
77 bfd_reloc_code_real_type reloc;
78 };
79
80 struct alpha_insn
81 {
82 unsigned insn;
83 int nfixups;
84 struct alpha_fixup fixups[MAX_INSN_FIXUPS];
85 long sequence;
86 };
87
88 enum alpha_macro_arg
89 {
90 MACRO_EOA = 1,
91 MACRO_IR,
92 MACRO_PIR,
93 MACRO_OPIR,
94 MACRO_CPIR,
95 MACRO_FPR,
96 MACRO_EXP,
97 };
98
99 struct alpha_macro
100 {
101 const char *name;
102 void (*emit) (const expressionS *, int, const void *);
103 const void * arg;
104 enum alpha_macro_arg argsets[16];
105 };
106
107 /* Extra expression types. */
108
109 #define O_pregister O_md1 /* O_register, in parentheses. */
110 #define O_cpregister O_md2 /* + a leading comma. */
111
112 /* The alpha_reloc_op table below depends on the ordering of these. */
113 #define O_literal O_md3 /* !literal relocation. */
114 #define O_lituse_addr O_md4 /* !lituse_addr relocation. */
115 #define O_lituse_base O_md5 /* !lituse_base relocation. */
116 #define O_lituse_bytoff O_md6 /* !lituse_bytoff relocation. */
117 #define O_lituse_jsr O_md7 /* !lituse_jsr relocation. */
118 #define O_lituse_tlsgd O_md8 /* !lituse_tlsgd relocation. */
119 #define O_lituse_tlsldm O_md9 /* !lituse_tlsldm relocation. */
120 #define O_lituse_jsrdirect O_md10 /* !lituse_jsrdirect relocation. */
121 #define O_gpdisp O_md11 /* !gpdisp relocation. */
122 #define O_gprelhigh O_md12 /* !gprelhigh relocation. */
123 #define O_gprellow O_md13 /* !gprellow relocation. */
124 #define O_gprel O_md14 /* !gprel relocation. */
125 #define O_samegp O_md15 /* !samegp relocation. */
126 #define O_tlsgd O_md16 /* !tlsgd relocation. */
127 #define O_tlsldm O_md17 /* !tlsldm relocation. */
128 #define O_gotdtprel O_md18 /* !gotdtprel relocation. */
129 #define O_dtprelhi O_md19 /* !dtprelhi relocation. */
130 #define O_dtprello O_md20 /* !dtprello relocation. */
131 #define O_dtprel O_md21 /* !dtprel relocation. */
132 #define O_gottprel O_md22 /* !gottprel relocation. */
133 #define O_tprelhi O_md23 /* !tprelhi relocation. */
134 #define O_tprello O_md24 /* !tprello relocation. */
135 #define O_tprel O_md25 /* !tprel relocation. */
136
137 #define DUMMY_RELOC_LITUSE_ADDR (BFD_RELOC_UNUSED + 1)
138 #define DUMMY_RELOC_LITUSE_BASE (BFD_RELOC_UNUSED + 2)
139 #define DUMMY_RELOC_LITUSE_BYTOFF (BFD_RELOC_UNUSED + 3)
140 #define DUMMY_RELOC_LITUSE_JSR (BFD_RELOC_UNUSED + 4)
141 #define DUMMY_RELOC_LITUSE_TLSGD (BFD_RELOC_UNUSED + 5)
142 #define DUMMY_RELOC_LITUSE_TLSLDM (BFD_RELOC_UNUSED + 6)
143 #define DUMMY_RELOC_LITUSE_JSRDIRECT (BFD_RELOC_UNUSED + 7)
144
145 #define USER_RELOC_P(R) ((R) >= O_literal && (R) <= O_tprel)
146
147 /* Macros for extracting the type and number of encoded register tokens. */
148
149 #define is_ir_num(x) (((x) & 32) == 0)
150 #define is_fpr_num(x) (((x) & 32) != 0)
151 #define regno(x) ((x) & 31)
152
153 /* Something odd inherited from the old assembler. */
154
155 #define note_gpreg(R) (alpha_gprmask |= (1 << (R)))
156 #define note_fpreg(R) (alpha_fprmask |= (1 << (R)))
157
158 /* Predicates for 16- and 32-bit ranges */
159 /* XXX: The non-shift version appears to trigger a compiler bug when
160 cross-assembling from x86 w/ gcc 2.7.2. */
161
162 #if 1
163 #define range_signed_16(x) \
164 (((offsetT) (x) >> 15) == 0 || ((offsetT) (x) >> 15) == -1)
165 #define range_signed_32(x) \
166 (((offsetT) (x) >> 31) == 0 || ((offsetT) (x) >> 31) == -1)
167 #else
168 #define range_signed_16(x) ((offsetT) (x) >= -(offsetT) 0x8000 && \
169 (offsetT) (x) <= (offsetT) 0x7FFF)
170 #define range_signed_32(x) ((offsetT) (x) >= -(offsetT) 0x80000000 && \
171 (offsetT) (x) <= (offsetT) 0x7FFFFFFF)
172 #endif
173
174 /* Macros for sign extending from 16- and 32-bits. */
175 /* XXX: The cast macros will work on all the systems that I care about,
176 but really a predicate should be found to use the non-cast forms. */
177
178 #if 1
179 #define sign_extend_16(x) ((short) (x))
180 #define sign_extend_32(x) ((int) (x))
181 #else
182 #define sign_extend_16(x) ((offsetT) (((x) & 0xFFFF) ^ 0x8000) - 0x8000)
183 #define sign_extend_32(x) ((offsetT) (((x) & 0xFFFFFFFF) \
184 ^ 0x80000000) - 0x80000000)
185 #endif
186
187 /* Macros to build tokens. */
188
189 #define set_tok_reg(t, r) (memset (&(t), 0, sizeof (t)), \
190 (t).X_op = O_register, \
191 (t).X_add_number = (r))
192 #define set_tok_preg(t, r) (memset (&(t), 0, sizeof (t)), \
193 (t).X_op = O_pregister, \
194 (t).X_add_number = (r))
195 #define set_tok_cpreg(t, r) (memset (&(t), 0, sizeof (t)), \
196 (t).X_op = O_cpregister, \
197 (t).X_add_number = (r))
198 #define set_tok_freg(t, r) (memset (&(t), 0, sizeof (t)), \
199 (t).X_op = O_register, \
200 (t).X_add_number = (r) + 32)
201 #define set_tok_sym(t, s, a) (memset (&(t), 0, sizeof (t)), \
202 (t).X_op = O_symbol, \
203 (t).X_add_symbol = (s), \
204 (t).X_add_number = (a))
205 #define set_tok_const(t, n) (memset (&(t), 0, sizeof (t)), \
206 (t).X_op = O_constant, \
207 (t).X_add_number = (n))
208
209 /* Generic assembler global variables which must be defined by all
211 targets. */
212
213 /* Characters which always start a comment. */
214 const char comment_chars[] = "#";
215
216 /* Characters which start a comment at the beginning of a line. */
217 const char line_comment_chars[] = "#";
218
219 /* Characters which may be used to separate multiple commands on a
220 single line. */
221 const char line_separator_chars[] = ";";
222
223 /* Characters which are used to indicate an exponent in a floating
224 point number. */
225 const char EXP_CHARS[] = "eE";
226
227 /* Characters which mean that a number is a floating point constant,
228 as in 0d1.0. */
229 /* XXX: Do all of these really get used on the alpha?? */
230 char FLT_CHARS[] = "rRsSfFdDxXpP";
231
232 #ifdef OBJ_EVAX
233 const char *md_shortopts = "Fm:g+1h:HG:";
234 #else
235 const char *md_shortopts = "Fm:gG:";
236 #endif
237
238 struct option md_longopts[] =
239 {
240 #define OPTION_32ADDR (OPTION_MD_BASE)
241 { "32addr", no_argument, NULL, OPTION_32ADDR },
242 #define OPTION_RELAX (OPTION_32ADDR + 1)
243 { "relax", no_argument, NULL, OPTION_RELAX },
244 #ifdef OBJ_ELF
245 #define OPTION_MDEBUG (OPTION_RELAX + 1)
246 #define OPTION_NO_MDEBUG (OPTION_MDEBUG + 1)
247 { "mdebug", no_argument, NULL, OPTION_MDEBUG },
248 { "no-mdebug", no_argument, NULL, OPTION_NO_MDEBUG },
249 #endif
250 { NULL, no_argument, NULL, 0 }
251 };
252
253 size_t md_longopts_size = sizeof (md_longopts);
254
255 #ifdef OBJ_EVAX
257 #define AXP_REG_R0 0
258 #define AXP_REG_R16 16
259 #define AXP_REG_R17 17
260 #undef AXP_REG_T9
261 #define AXP_REG_T9 22
262 #undef AXP_REG_T10
263 #define AXP_REG_T10 23
264 #undef AXP_REG_T11
265 #define AXP_REG_T11 24
266 #undef AXP_REG_T12
267 #define AXP_REG_T12 25
268 #define AXP_REG_AI 25
269 #undef AXP_REG_FP
270 #define AXP_REG_FP 29
271
272 #undef AXP_REG_GP
273 #define AXP_REG_GP AXP_REG_PV
274 #endif /* OBJ_EVAX */
275
276 /* The cpu for which we are generating code. */
277 static unsigned alpha_target = AXP_OPCODE_BASE;
278 static const char *alpha_target_name = "<all>";
279
280 /* The hash table of instruction opcodes. */
281 static struct hash_control *alpha_opcode_hash;
282
283 /* The hash table of macro opcodes. */
284 static struct hash_control *alpha_macro_hash;
285
286 #ifdef OBJ_ECOFF
287 /* The $gp relocation symbol. */
288 static symbolS *alpha_gp_symbol;
289
290 /* XXX: what is this, and why is it exported? */
291 valueT alpha_gp_value;
292 #endif
293
294 /* The current $gp register. */
295 static int alpha_gp_register = AXP_REG_GP;
296
297 /* A table of the register symbols. */
298 static symbolS *alpha_register_table[64];
299
300 /* Constant sections, or sections of constants. */
301 #ifdef OBJ_ECOFF
302 static segT alpha_lita_section;
303 #endif
304 #ifdef OBJ_EVAX
305 static segT alpha_link_section;
306 static segT alpha_ctors_section;
307 static segT alpha_dtors_section;
308 #endif
309 static segT alpha_lit8_section;
310
311 /* Symbols referring to said sections. */
312 #ifdef OBJ_ECOFF
313 static symbolS *alpha_lita_symbol;
314 #endif
315 #ifdef OBJ_EVAX
316 static symbolS *alpha_link_symbol;
317 static symbolS *alpha_ctors_symbol;
318 static symbolS *alpha_dtors_symbol;
319 #endif
320 static symbolS *alpha_lit8_symbol;
321
322 /* Literal for .litX+0x8000 within .lita. */
323 #ifdef OBJ_ECOFF
324 static offsetT alpha_lit8_literal;
325 #endif
326
327 /* Is the assembler not allowed to use $at? */
328 static int alpha_noat_on = 0;
329
330 /* Are macros enabled? */
331 static int alpha_macros_on = 1;
332
333 /* Are floats disabled? */
334 static int alpha_nofloats_on = 0;
335
336 /* Are addresses 32 bit? */
337 static int alpha_addr32_on = 0;
338
339 /* Symbol labelling the current insn. When the Alpha gas sees
340 foo:
341 .quad 0
342 and the section happens to not be on an eight byte boundary, it
343 will align both the symbol and the .quad to an eight byte boundary. */
344 static symbolS *alpha_insn_label;
345
346 /* Whether we should automatically align data generation pseudo-ops.
347 .align 0 will turn this off. */
348 static int alpha_auto_align_on = 1;
349
350 /* The known current alignment of the current section. */
351 static int alpha_current_align;
352
353 /* These are exported to ECOFF code. */
354 unsigned long alpha_gprmask, alpha_fprmask;
355
356 /* Whether the debugging option was seen. */
357 static int alpha_debug;
358
359 #ifdef OBJ_ELF
360 /* Whether we are emitting an mdebug section. */
361 int alpha_flag_mdebug = -1;
362 #endif
363
364 /* Don't fully resolve relocations, allowing code movement in the linker. */
365 static int alpha_flag_relax;
366
367 /* What value to give to bfd_set_gp_size. */
368 static int g_switch_value = 8;
369
370 #ifdef OBJ_EVAX
371 /* Collect information about current procedure here. */
372 static struct
373 {
374 symbolS *symbol; /* Proc pdesc symbol. */
375 int pdsckind;
376 int framereg; /* Register for frame pointer. */
377 int framesize; /* Size of frame. */
378 int rsa_offset;
379 int ra_save;
380 int fp_save;
381 long imask;
382 long fmask;
383 int type;
384 int prologue;
385 } alpha_evax_proc;
386
387 static int alpha_flag_hash_long_names = 0; /* -+ */
388 static int alpha_flag_show_after_trunc = 0; /* -H */
389
390 /* If the -+ switch is given, then a hash is appended to any name that is
391 longer than 64 characters, else longer symbol names are truncated. */
392
393 #endif
394
395 #ifdef RELOC_OP_P
397 /* A table to map the spelling of a relocation operand into an appropriate
398 bfd_reloc_code_real_type type. The table is assumed to be ordered such
399 that op-O_literal indexes into it. */
400
401 #define ALPHA_RELOC_TABLE(op) \
402 (&alpha_reloc_op[ ((!USER_RELOC_P (op)) \
403 ? (abort (), 0) \
404 : (int) (op) - (int) O_literal) ])
405
406 #define DEF(NAME, RELOC, REQ, ALLOW) \
407 { #NAME, sizeof(#NAME)-1, O_##NAME, RELOC, REQ, ALLOW}
408
409 static const struct alpha_reloc_op_tag
410 {
411 const char *name; /* String to lookup. */
412 size_t length; /* Size of the string. */
413 operatorT op; /* Which operator to use. */
414 bfd_reloc_code_real_type reloc; /* Relocation before frob. */
415 unsigned int require_seq : 1; /* Require a sequence number. */
416 unsigned int allow_seq : 1; /* Allow a sequence number. */
417 }
418 alpha_reloc_op[] =
419 {
420 DEF (literal, BFD_RELOC_ALPHA_ELF_LITERAL, 0, 1),
421 DEF (lituse_addr, DUMMY_RELOC_LITUSE_ADDR, 1, 1),
422 DEF (lituse_base, DUMMY_RELOC_LITUSE_BASE, 1, 1),
423 DEF (lituse_bytoff, DUMMY_RELOC_LITUSE_BYTOFF, 1, 1),
424 DEF (lituse_jsr, DUMMY_RELOC_LITUSE_JSR, 1, 1),
425 DEF (lituse_tlsgd, DUMMY_RELOC_LITUSE_TLSGD, 1, 1),
426 DEF (lituse_tlsldm, DUMMY_RELOC_LITUSE_TLSLDM, 1, 1),
427 DEF (lituse_jsrdirect, DUMMY_RELOC_LITUSE_JSRDIRECT, 1, 1),
428 DEF (gpdisp, BFD_RELOC_ALPHA_GPDISP, 1, 1),
429 DEF (gprelhigh, BFD_RELOC_ALPHA_GPREL_HI16, 0, 0),
430 DEF (gprellow, BFD_RELOC_ALPHA_GPREL_LO16, 0, 0),
431 DEF (gprel, BFD_RELOC_GPREL16, 0, 0),
432 DEF (samegp, BFD_RELOC_ALPHA_BRSGP, 0, 0),
433 DEF (tlsgd, BFD_RELOC_ALPHA_TLSGD, 0, 1),
434 DEF (tlsldm, BFD_RELOC_ALPHA_TLSLDM, 0, 1),
435 DEF (gotdtprel, BFD_RELOC_ALPHA_GOTDTPREL16, 0, 0),
436 DEF (dtprelhi, BFD_RELOC_ALPHA_DTPREL_HI16, 0, 0),
437 DEF (dtprello, BFD_RELOC_ALPHA_DTPREL_LO16, 0, 0),
438 DEF (dtprel, BFD_RELOC_ALPHA_DTPREL16, 0, 0),
439 DEF (gottprel, BFD_RELOC_ALPHA_GOTTPREL16, 0, 0),
440 DEF (tprelhi, BFD_RELOC_ALPHA_TPREL_HI16, 0, 0),
441 DEF (tprello, BFD_RELOC_ALPHA_TPREL_LO16, 0, 0),
442 DEF (tprel, BFD_RELOC_ALPHA_TPREL16, 0, 0),
443 };
444
445 #undef DEF
446
447 static const int alpha_num_reloc_op
448 = sizeof (alpha_reloc_op) / sizeof (*alpha_reloc_op);
449 #endif /* RELOC_OP_P */
450
451 /* Maximum # digits needed to hold the largest sequence #. */
452 #define ALPHA_RELOC_DIGITS 25
453
454 /* Structure to hold explicit sequence information. */
455 struct alpha_reloc_tag
456 {
457 fixS *master; /* The literal reloc. */
458 fixS *slaves; /* Head of linked list of lituses. */
459 segT segment; /* Segment relocs are in or undefined_section. */
460 long sequence; /* Sequence #. */
461 unsigned n_master; /* # of literals. */
462 unsigned n_slaves; /* # of lituses. */
463 unsigned saw_tlsgd : 1; /* True if ... */
464 unsigned saw_tlsldm : 1;
465 unsigned saw_lu_tlsgd : 1;
466 unsigned saw_lu_tlsldm : 1;
467 unsigned multi_section_p : 1; /* True if more than one section was used. */
468 char string[1]; /* Printable form of sequence to hash with. */
469 };
470
471 /* Hash table to link up literals with the appropriate lituse. */
472 static struct hash_control *alpha_literal_hash;
473
474 /* Sequence numbers for internal use by macros. */
475 static long next_sequence_num = -1;
476
477 /* A table of CPU names and opcode sets. */
479
480 static const struct cpu_type
481 {
482 const char *name;
483 unsigned flags;
484 }
485 cpu_types[] =
486 {
487 /* Ad hoc convention: cpu number gets palcode, process code doesn't.
488 This supports usage under DU 4.0b that does ".arch ev4", and
489 usage in MILO that does -m21064. Probably something more
490 specific like -m21064-pal should be used, but oh well. */
491
492 { "21064", AXP_OPCODE_BASE|AXP_OPCODE_EV4 },
493 { "21064a", AXP_OPCODE_BASE|AXP_OPCODE_EV4 },
494 { "21066", AXP_OPCODE_BASE|AXP_OPCODE_EV4 },
495 { "21068", AXP_OPCODE_BASE|AXP_OPCODE_EV4 },
496 { "21164", AXP_OPCODE_BASE|AXP_OPCODE_EV5 },
497 { "21164a", AXP_OPCODE_BASE|AXP_OPCODE_EV5|AXP_OPCODE_BWX },
498 { "21164pc", (AXP_OPCODE_BASE|AXP_OPCODE_EV5|AXP_OPCODE_BWX
499 |AXP_OPCODE_MAX) },
500 { "21264", (AXP_OPCODE_BASE|AXP_OPCODE_EV6|AXP_OPCODE_BWX
501 |AXP_OPCODE_MAX|AXP_OPCODE_CIX) },
502 { "21264a", (AXP_OPCODE_BASE|AXP_OPCODE_EV6|AXP_OPCODE_BWX
503 |AXP_OPCODE_MAX|AXP_OPCODE_CIX) },
504 { "21264b", (AXP_OPCODE_BASE|AXP_OPCODE_EV6|AXP_OPCODE_BWX
505 |AXP_OPCODE_MAX|AXP_OPCODE_CIX) },
506
507 { "ev4", AXP_OPCODE_BASE },
508 { "ev45", AXP_OPCODE_BASE },
509 { "lca45", AXP_OPCODE_BASE },
510 { "ev5", AXP_OPCODE_BASE },
511 { "ev56", AXP_OPCODE_BASE|AXP_OPCODE_BWX },
512 { "pca56", AXP_OPCODE_BASE|AXP_OPCODE_BWX|AXP_OPCODE_MAX },
513 { "ev6", AXP_OPCODE_BASE|AXP_OPCODE_BWX|AXP_OPCODE_MAX|AXP_OPCODE_CIX },
514 { "ev67", AXP_OPCODE_BASE|AXP_OPCODE_BWX|AXP_OPCODE_MAX|AXP_OPCODE_CIX },
515 { "ev68", AXP_OPCODE_BASE|AXP_OPCODE_BWX|AXP_OPCODE_MAX|AXP_OPCODE_CIX },
516
517 { "all", AXP_OPCODE_BASE },
518 { 0, 0 }
519 };
520
521 /* Some instruction sets indexed by lg(size). */
522 static const char * const sextX_op[] = { "sextb", "sextw", "sextl", NULL };
523 static const char * const insXl_op[] = { "insbl", "inswl", "insll", "insql" };
524 static const char * const insXh_op[] = { NULL, "inswh", "inslh", "insqh" };
525 static const char * const extXl_op[] = { "extbl", "extwl", "extll", "extql" };
526 static const char * const extXh_op[] = { NULL, "extwh", "extlh", "extqh" };
527 static const char * const mskXl_op[] = { "mskbl", "mskwl", "mskll", "mskql" };
528 static const char * const mskXh_op[] = { NULL, "mskwh", "msklh", "mskqh" };
529 static const char * const stX_op[] = { "stb", "stw", "stl", "stq" };
530 static const char * const ldXu_op[] = { "ldbu", "ldwu", NULL, NULL };
531
532 static void assemble_insn (const struct alpha_opcode *, const expressionS *, int, struct alpha_insn *, bfd_reloc_code_real_type);
533 static void emit_insn (struct alpha_insn *);
534 static void assemble_tokens (const char *, const expressionS *, int, int);
535
536 static struct alpha_reloc_tag *
538 get_alpha_reloc_tag (long sequence)
539 {
540 char buffer[ALPHA_RELOC_DIGITS];
541 struct alpha_reloc_tag *info;
542
543 sprintf (buffer, "!%ld", sequence);
544
545 info = (struct alpha_reloc_tag *) hash_find (alpha_literal_hash, buffer);
546 if (! info)
547 {
548 size_t len = strlen (buffer);
549 const char *errmsg;
550
551 info = xcalloc (sizeof (struct alpha_reloc_tag) + len, 1);
552
553 info->segment = now_seg;
554 info->sequence = sequence;
555 strcpy (info->string, buffer);
556 errmsg = hash_insert (alpha_literal_hash, info->string, (void *) info);
557 if (errmsg)
558 as_fatal (errmsg);
559 }
560
561 return info;
562 }
563
564 static void
565 alpha_adjust_relocs (bfd *abfd ATTRIBUTE_UNUSED,
566 asection *sec,
567 void * ptr ATTRIBUTE_UNUSED)
568 {
569 segment_info_type *seginfo = seg_info (sec);
570 fixS **prevP;
571 fixS *fixp;
572 fixS *next;
573 fixS *slave;
574
575 /* If seginfo is NULL, we did not create this section; don't do
576 anything with it. By using a pointer to a pointer, we can update
577 the links in place. */
578 if (seginfo == NULL)
579 return;
580
581 /* If there are no relocations, skip the section. */
582 if (! seginfo->fix_root)
583 return;
584
585 /* First rebuild the fixup chain without the explicit lituse and
586 gpdisp_lo16 relocs. */
587 prevP = &seginfo->fix_root;
588 for (fixp = seginfo->fix_root; fixp; fixp = next)
589 {
590 next = fixp->fx_next;
591 fixp->fx_next = (fixS *) 0;
592
593 switch (fixp->fx_r_type)
594 {
595 case BFD_RELOC_ALPHA_LITUSE:
596 if (fixp->tc_fix_data.info->n_master == 0)
597 as_bad_where (fixp->fx_file, fixp->fx_line,
598 _("No !literal!%ld was found"),
599 fixp->tc_fix_data.info->sequence);
600 #ifdef RELOC_OP_P
601 if (fixp->fx_offset == LITUSE_ALPHA_TLSGD)
602 {
603 if (! fixp->tc_fix_data.info->saw_tlsgd)
604 as_bad_where (fixp->fx_file, fixp->fx_line,
605 _("No !tlsgd!%ld was found"),
606 fixp->tc_fix_data.info->sequence);
607 }
608 else if (fixp->fx_offset == LITUSE_ALPHA_TLSLDM)
609 {
610 if (! fixp->tc_fix_data.info->saw_tlsldm)
611 as_bad_where (fixp->fx_file, fixp->fx_line,
612 _("No !tlsldm!%ld was found"),
613 fixp->tc_fix_data.info->sequence);
614 }
615 #endif
616 break;
617
618 case BFD_RELOC_ALPHA_GPDISP_LO16:
619 if (fixp->tc_fix_data.info->n_master == 0)
620 as_bad_where (fixp->fx_file, fixp->fx_line,
621 _("No ldah !gpdisp!%ld was found"),
622 fixp->tc_fix_data.info->sequence);
623 break;
624
625 case BFD_RELOC_ALPHA_ELF_LITERAL:
626 if (fixp->tc_fix_data.info
627 && (fixp->tc_fix_data.info->saw_tlsgd
628 || fixp->tc_fix_data.info->saw_tlsldm))
629 break;
630 /* FALLTHRU */
631
632 default:
633 *prevP = fixp;
634 prevP = &fixp->fx_next;
635 break;
636 }
637 }
638
639 /* Go back and re-chain dependent relocations. They are currently
640 linked through the next_reloc field in reverse order, so as we
641 go through the next_reloc chain, we effectively reverse the chain
642 once again.
643
644 Except if there is more than one !literal for a given sequence
645 number. In that case, the programmer and/or compiler is not sure
646 how control flows from literal to lituse, and we can't be sure to
647 get the relaxation correct.
648
649 ??? Well, actually we could, if there are enough lituses such that
650 we can make each literal have at least one of each lituse type
651 present. Not implemented.
652
653 Also suppress the optimization if the !literals/!lituses are spread
654 in different segments. This can happen with "intersting" uses of
655 inline assembly; examples are present in the Linux kernel semaphores. */
656
657 for (fixp = seginfo->fix_root; fixp; fixp = next)
658 {
659 next = fixp->fx_next;
660 switch (fixp->fx_r_type)
661 {
662 case BFD_RELOC_ALPHA_TLSGD:
663 case BFD_RELOC_ALPHA_TLSLDM:
664 if (!fixp->tc_fix_data.info)
665 break;
666 if (fixp->tc_fix_data.info->n_master == 0)
667 break;
668 else if (fixp->tc_fix_data.info->n_master > 1)
669 {
670 as_bad_where (fixp->fx_file, fixp->fx_line,
671 _("too many !literal!%ld for %s"),
672 fixp->tc_fix_data.info->sequence,
673 (fixp->fx_r_type == BFD_RELOC_ALPHA_TLSGD
674 ? "!tlsgd" : "!tlsldm"));
675 break;
676 }
677
678 fixp->tc_fix_data.info->master->fx_next = fixp->fx_next;
679 fixp->fx_next = fixp->tc_fix_data.info->master;
680 fixp = fixp->fx_next;
681 /* Fall through. */
682
683 case BFD_RELOC_ALPHA_ELF_LITERAL:
684 if (fixp->tc_fix_data.info
685 && fixp->tc_fix_data.info->n_master == 1
686 && ! fixp->tc_fix_data.info->multi_section_p)
687 {
688 for (slave = fixp->tc_fix_data.info->slaves;
689 slave != (fixS *) 0;
690 slave = slave->tc_fix_data.next_reloc)
691 {
692 slave->fx_next = fixp->fx_next;
693 fixp->fx_next = slave;
694 }
695 }
696 break;
697
698 case BFD_RELOC_ALPHA_GPDISP_HI16:
699 if (fixp->tc_fix_data.info->n_slaves == 0)
700 as_bad_where (fixp->fx_file, fixp->fx_line,
701 _("No lda !gpdisp!%ld was found"),
702 fixp->tc_fix_data.info->sequence);
703 else
704 {
705 slave = fixp->tc_fix_data.info->slaves;
706 slave->fx_next = next;
707 fixp->fx_next = slave;
708 }
709 break;
710
711 default:
712 break;
713 }
714 }
715 }
716
717 /* Before the relocations are written, reorder them, so that user
718 supplied !lituse relocations follow the appropriate !literal
719 relocations, and similarly for !gpdisp relocations. */
720
721 void
722 alpha_before_fix (void)
723 {
724 if (alpha_literal_hash)
725 bfd_map_over_sections (stdoutput, alpha_adjust_relocs, NULL);
726 }
727
728 #ifdef DEBUG_ALPHA
730 static void
731 debug_exp (expressionS tok[], int ntok)
732 {
733 int i;
734
735 fprintf (stderr, "debug_exp: %d tokens", ntok);
736 for (i = 0; i < ntok; i++)
737 {
738 expressionS *t = &tok[i];
739 const char *name;
740
741 switch (t->X_op)
742 {
743 default: name = "unknown"; break;
744 case O_illegal: name = "O_illegal"; break;
745 case O_absent: name = "O_absent"; break;
746 case O_constant: name = "O_constant"; break;
747 case O_symbol: name = "O_symbol"; break;
748 case O_symbol_rva: name = "O_symbol_rva"; break;
749 case O_register: name = "O_register"; break;
750 case O_big: name = "O_big"; break;
751 case O_uminus: name = "O_uminus"; break;
752 case O_bit_not: name = "O_bit_not"; break;
753 case O_logical_not: name = "O_logical_not"; break;
754 case O_multiply: name = "O_multiply"; break;
755 case O_divide: name = "O_divide"; break;
756 case O_modulus: name = "O_modulus"; break;
757 case O_left_shift: name = "O_left_shift"; break;
758 case O_right_shift: name = "O_right_shift"; break;
759 case O_bit_inclusive_or: name = "O_bit_inclusive_or"; break;
760 case O_bit_or_not: name = "O_bit_or_not"; break;
761 case O_bit_exclusive_or: name = "O_bit_exclusive_or"; break;
762 case O_bit_and: name = "O_bit_and"; break;
763 case O_add: name = "O_add"; break;
764 case O_subtract: name = "O_subtract"; break;
765 case O_eq: name = "O_eq"; break;
766 case O_ne: name = "O_ne"; break;
767 case O_lt: name = "O_lt"; break;
768 case O_le: name = "O_le"; break;
769 case O_ge: name = "O_ge"; break;
770 case O_gt: name = "O_gt"; break;
771 case O_logical_and: name = "O_logical_and"; break;
772 case O_logical_or: name = "O_logical_or"; break;
773 case O_index: name = "O_index"; break;
774 case O_pregister: name = "O_pregister"; break;
775 case O_cpregister: name = "O_cpregister"; break;
776 case O_literal: name = "O_literal"; break;
777 case O_lituse_addr: name = "O_lituse_addr"; break;
778 case O_lituse_base: name = "O_lituse_base"; break;
779 case O_lituse_bytoff: name = "O_lituse_bytoff"; break;
780 case O_lituse_jsr: name = "O_lituse_jsr"; break;
781 case O_lituse_tlsgd: name = "O_lituse_tlsgd"; break;
782 case O_lituse_tlsldm: name = "O_lituse_tlsldm"; break;
783 case O_lituse_jsrdirect: name = "O_lituse_jsrdirect"; break;
784 case O_gpdisp: name = "O_gpdisp"; break;
785 case O_gprelhigh: name = "O_gprelhigh"; break;
786 case O_gprellow: name = "O_gprellow"; break;
787 case O_gprel: name = "O_gprel"; break;
788 case O_samegp: name = "O_samegp"; break;
789 case O_tlsgd: name = "O_tlsgd"; break;
790 case O_tlsldm: name = "O_tlsldm"; break;
791 case O_gotdtprel: name = "O_gotdtprel"; break;
792 case O_dtprelhi: name = "O_dtprelhi"; break;
793 case O_dtprello: name = "O_dtprello"; break;
794 case O_dtprel: name = "O_dtprel"; break;
795 case O_gottprel: name = "O_gottprel"; break;
796 case O_tprelhi: name = "O_tprelhi"; break;
797 case O_tprello: name = "O_tprello"; break;
798 case O_tprel: name = "O_tprel"; break;
799 }
800
801 fprintf (stderr, ", %s(%s, %s, %d)", name,
802 (t->X_add_symbol) ? S_GET_NAME (t->X_add_symbol) : "--",
803 (t->X_op_symbol) ? S_GET_NAME (t->X_op_symbol) : "--",
804 (int) t->X_add_number);
805 }
806 fprintf (stderr, "\n");
807 fflush (stderr);
808 }
809 #endif
810
811 /* Parse the arguments to an opcode. */
812
813 static int
814 tokenize_arguments (char *str,
815 expressionS tok[],
816 int ntok)
817 {
818 expressionS *end_tok = tok + ntok;
819 char *old_input_line_pointer;
820 int saw_comma = 0, saw_arg = 0;
821 #ifdef DEBUG_ALPHA
822 expressionS *orig_tok = tok;
823 #endif
824 #ifdef RELOC_OP_P
825 char *p;
826 const struct alpha_reloc_op_tag *r;
827 int c, i;
828 size_t len;
829 int reloc_found_p = 0;
830 #endif
831
832 memset (tok, 0, sizeof (*tok) * ntok);
833
834 /* Save and restore input_line_pointer around this function. */
835 old_input_line_pointer = input_line_pointer;
836 input_line_pointer = str;
837
838 #ifdef RELOC_OP_P
839 /* ??? Wrest control of ! away from the regular expression parser. */
840 is_end_of_line[(unsigned char) '!'] = 1;
841 #endif
842
843 while (tok < end_tok && *input_line_pointer)
844 {
845 SKIP_WHITESPACE ();
846 switch (*input_line_pointer)
847 {
848 case '\0':
849 goto fini;
850
851 #ifdef RELOC_OP_P
852 case '!':
853 /* A relocation operand can be placed after the normal operand on an
854 assembly language statement, and has the following form:
855 !relocation_type!sequence_number. */
856 if (reloc_found_p)
857 {
858 /* Only support one relocation op per insn. */
859 as_bad (_("More than one relocation op per insn"));
860 goto err_report;
861 }
862
863 if (!saw_arg)
864 goto err;
865
866 ++input_line_pointer;
867 SKIP_WHITESPACE ();
868 p = input_line_pointer;
869 c = get_symbol_end ();
870
871 /* Parse !relocation_type. */
872 len = input_line_pointer - p;
873 if (len == 0)
874 {
875 as_bad (_("No relocation operand"));
876 goto err_report;
877 }
878
879 r = &alpha_reloc_op[0];
880 for (i = alpha_num_reloc_op - 1; i >= 0; i--, r++)
881 if (len == r->length && memcmp (p, r->name, len) == 0)
882 break;
883 if (i < 0)
884 {
885 as_bad (_("Unknown relocation operand: !%s"), p);
886 goto err_report;
887 }
888
889 *input_line_pointer = c;
890 SKIP_WHITESPACE ();
891 if (*input_line_pointer != '!')
892 {
893 if (r->require_seq)
894 {
895 as_bad (_("no sequence number after !%s"), p);
896 goto err_report;
897 }
898
899 tok->X_add_number = 0;
900 }
901 else
902 {
903 if (! r->allow_seq)
904 {
905 as_bad (_("!%s does not use a sequence number"), p);
906 goto err_report;
907 }
908
909 input_line_pointer++;
910
911 /* Parse !sequence_number. */
912 expression (tok);
913 if (tok->X_op != O_constant || tok->X_add_number <= 0)
914 {
915 as_bad (_("Bad sequence number: !%s!%s"),
916 r->name, input_line_pointer);
917 goto err_report;
918 }
919 }
920
921 tok->X_op = r->op;
922 reloc_found_p = 1;
923 ++tok;
924 break;
925 #endif /* RELOC_OP_P */
926
927 case ',':
928 ++input_line_pointer;
929 if (saw_comma || !saw_arg)
930 goto err;
931 saw_comma = 1;
932 break;
933
934 case '(':
935 {
936 char *hold = input_line_pointer++;
937
938 /* First try for parenthesized register ... */
939 expression (tok);
940 if (*input_line_pointer == ')' && tok->X_op == O_register)
941 {
942 tok->X_op = (saw_comma ? O_cpregister : O_pregister);
943 saw_comma = 0;
944 saw_arg = 1;
945 ++input_line_pointer;
946 ++tok;
947 break;
948 }
949
950 /* ... then fall through to plain expression. */
951 input_line_pointer = hold;
952 }
953
954 default:
955 if (saw_arg && !saw_comma)
956 goto err;
957
958 expression (tok);
959 if (tok->X_op == O_illegal || tok->X_op == O_absent)
960 goto err;
961
962 saw_comma = 0;
963 saw_arg = 1;
964 ++tok;
965 break;
966 }
967 }
968
969 fini:
970 if (saw_comma)
971 goto err;
972 input_line_pointer = old_input_line_pointer;
973
974 #ifdef DEBUG_ALPHA
975 debug_exp (orig_tok, ntok - (end_tok - tok));
976 #endif
977 #ifdef RELOC_OP_P
978 is_end_of_line[(unsigned char) '!'] = 0;
979 #endif
980
981 return ntok - (end_tok - tok);
982
983 err:
984 #ifdef RELOC_OP_P
985 is_end_of_line[(unsigned char) '!'] = 0;
986 #endif
987 input_line_pointer = old_input_line_pointer;
988 return TOKENIZE_ERROR;
989
990 #ifdef RELOC_OP_P
991 err_report:
992 is_end_of_line[(unsigned char) '!'] = 0;
993 #endif
994 input_line_pointer = old_input_line_pointer;
995 return TOKENIZE_ERROR_REPORT;
996 }
997
998 /* Search forward through all variants of an opcode looking for a
999 syntax match. */
1000
1001 static const struct alpha_opcode *
1002 find_opcode_match (const struct alpha_opcode *first_opcode,
1003 const expressionS *tok,
1004 int *pntok,
1005 int *pcpumatch)
1006 {
1007 const struct alpha_opcode *opcode = first_opcode;
1008 int ntok = *pntok;
1009 int got_cpu_match = 0;
1010
1011 do
1012 {
1013 const unsigned char *opidx;
1014 int tokidx = 0;
1015
1016 /* Don't match opcodes that don't exist on this architecture. */
1017 if (!(opcode->flags & alpha_target))
1018 goto match_failed;
1019
1020 got_cpu_match = 1;
1021
1022 for (opidx = opcode->operands; *opidx; ++opidx)
1023 {
1024 const struct alpha_operand *operand = &alpha_operands[*opidx];
1025
1026 /* Only take input from real operands. */
1027 if (operand->flags & AXP_OPERAND_FAKE)
1028 continue;
1029
1030 /* When we expect input, make sure we have it. */
1031 if (tokidx >= ntok)
1032 {
1033 if ((operand->flags & AXP_OPERAND_OPTIONAL_MASK) == 0)
1034 goto match_failed;
1035 continue;
1036 }
1037
1038 /* Match operand type with expression type. */
1039 switch (operand->flags & AXP_OPERAND_TYPECHECK_MASK)
1040 {
1041 case AXP_OPERAND_IR:
1042 if (tok[tokidx].X_op != O_register
1043 || !is_ir_num (tok[tokidx].X_add_number))
1044 goto match_failed;
1045 break;
1046 case AXP_OPERAND_FPR:
1047 if (tok[tokidx].X_op != O_register
1048 || !is_fpr_num (tok[tokidx].X_add_number))
1049 goto match_failed;
1050 break;
1051 case AXP_OPERAND_IR | AXP_OPERAND_PARENS:
1052 if (tok[tokidx].X_op != O_pregister
1053 || !is_ir_num (tok[tokidx].X_add_number))
1054 goto match_failed;
1055 break;
1056 case AXP_OPERAND_IR | AXP_OPERAND_PARENS | AXP_OPERAND_COMMA:
1057 if (tok[tokidx].X_op != O_cpregister
1058 || !is_ir_num (tok[tokidx].X_add_number))
1059 goto match_failed;
1060 break;
1061
1062 case AXP_OPERAND_RELATIVE:
1063 case AXP_OPERAND_SIGNED:
1064 case AXP_OPERAND_UNSIGNED:
1065 switch (tok[tokidx].X_op)
1066 {
1067 case O_illegal:
1068 case O_absent:
1069 case O_register:
1070 case O_pregister:
1071 case O_cpregister:
1072 goto match_failed;
1073
1074 default:
1075 break;
1076 }
1077 break;
1078
1079 default:
1080 /* Everything else should have been fake. */
1081 abort ();
1082 }
1083 ++tokidx;
1084 }
1085
1086 /* Possible match -- did we use all of our input? */
1087 if (tokidx == ntok)
1088 {
1089 *pntok = ntok;
1090 return opcode;
1091 }
1092
1093 match_failed:;
1094 }
1095 while (++opcode - alpha_opcodes < (int) alpha_num_opcodes
1096 && !strcmp (opcode->name, first_opcode->name));
1097
1098 if (*pcpumatch)
1099 *pcpumatch = got_cpu_match;
1100
1101 return NULL;
1102 }
1103
1104 /* Given an opcode name and a pre-tokenized set of arguments, assemble
1105 the insn, but do not emit it.
1106
1107 Note that this implies no macros allowed, since we can't store more
1108 than one insn in an insn structure. */
1109
1110 static void
1111 assemble_tokens_to_insn (const char *opname,
1112 const expressionS *tok,
1113 int ntok,
1114 struct alpha_insn *insn)
1115 {
1116 const struct alpha_opcode *opcode;
1117
1118 /* Search opcodes. */
1119 opcode = (const struct alpha_opcode *) hash_find (alpha_opcode_hash, opname);
1120 if (opcode)
1121 {
1122 int cpumatch;
1123 opcode = find_opcode_match (opcode, tok, &ntok, &cpumatch);
1124 if (opcode)
1125 {
1126 assemble_insn (opcode, tok, ntok, insn, BFD_RELOC_UNUSED);
1127 return;
1128 }
1129 else if (cpumatch)
1130 as_bad (_("inappropriate arguments for opcode `%s'"), opname);
1131 else
1132 as_bad (_("opcode `%s' not supported for target %s"), opname,
1133 alpha_target_name);
1134 }
1135 else
1136 as_bad (_("unknown opcode `%s'"), opname);
1137 }
1138
1139 /* Build a BFD section with its flags set appropriately for the .lita,
1140 .lit8, or .lit4 sections. */
1141
1142 static void
1143 create_literal_section (const char *name,
1144 segT *secp,
1145 symbolS **symp)
1146 {
1147 segT current_section = now_seg;
1148 int current_subsec = now_subseg;
1149 segT new_sec;
1150
1151 *secp = new_sec = subseg_new (name, 0);
1152 subseg_set (current_section, current_subsec);
1153 bfd_set_section_alignment (stdoutput, new_sec, 4);
1154 bfd_set_section_flags (stdoutput, new_sec,
1155 SEC_RELOC | SEC_ALLOC | SEC_LOAD | SEC_READONLY
1156 | SEC_DATA);
1157
1158 S_CLEAR_EXTERNAL (*symp = section_symbol (new_sec));
1159 }
1160
1161 /* Load a (partial) expression into a target register.
1162
1163 If poffset is not null, after the call it will either contain
1164 O_constant 0, or a 16-bit offset appropriate for any MEM format
1165 instruction. In addition, pbasereg will be modified to point to
1166 the base register to use in that MEM format instruction.
1167
1168 In any case, *pbasereg should contain a base register to add to the
1169 expression. This will normally be either AXP_REG_ZERO or
1170 alpha_gp_register. Symbol addresses will always be loaded via $gp,
1171 so "foo($0)" is interpreted as adding the address of foo to $0;
1172 i.e. "ldq $targ, LIT($gp); addq $targ, $0, $targ". Odd, perhaps,
1173 but this is what OSF/1 does.
1174
1175 If explicit relocations of the form !literal!<number> are allowed,
1176 and used, then explicit_reloc with be an expression pointer.
1177
1178 Finally, the return value is nonzero if the calling macro may emit
1179 a LITUSE reloc if otherwise appropriate; the return value is the
1180 sequence number to use. */
1181
1182 static long
1183 load_expression (int targreg,
1184 const expressionS *exp,
1185 int *pbasereg,
1186 expressionS *poffset)
1187 {
1188 long emit_lituse = 0;
1189 offsetT addend = exp->X_add_number;
1190 int basereg = *pbasereg;
1191 struct alpha_insn insn;
1192 expressionS newtok[3];
1193
1194 switch (exp->X_op)
1195 {
1196 case O_symbol:
1197 {
1198 #ifdef OBJ_ECOFF
1199 offsetT lit;
1200
1201 /* Attempt to reduce .lit load by splitting the offset from
1202 its symbol when possible, but don't create a situation in
1203 which we'd fail. */
1204 if (!range_signed_32 (addend) &&
1205 (alpha_noat_on || targreg == AXP_REG_AT))
1206 {
1207 lit = add_to_literal_pool (exp->X_add_symbol, addend,
1208 alpha_lita_section, 8);
1209 addend = 0;
1210 }
1211 else
1212 lit = add_to_literal_pool (exp->X_add_symbol, 0,
1213 alpha_lita_section, 8);
1214
1215 if (lit >= 0x8000)
1216 as_fatal (_("overflow in literal (.lita) table"));
1217
1218 /* Emit "ldq r, lit(gp)". */
1219
1220 if (basereg != alpha_gp_register && targreg == basereg)
1221 {
1222 if (alpha_noat_on)
1223 as_bad (_("macro requires $at register while noat in effect"));
1224 if (targreg == AXP_REG_AT)
1225 as_bad (_("macro requires $at while $at in use"));
1226
1227 set_tok_reg (newtok[0], AXP_REG_AT);
1228 }
1229 else
1230 set_tok_reg (newtok[0], targreg);
1231
1232 set_tok_sym (newtok[1], alpha_lita_symbol, lit);
1233 set_tok_preg (newtok[2], alpha_gp_register);
1234
1235 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
1236
1237 assert (insn.nfixups == 1);
1238 insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITERAL;
1239 insn.sequence = emit_lituse = next_sequence_num--;
1240 #endif /* OBJ_ECOFF */
1241 #ifdef OBJ_ELF
1242 /* Emit "ldq r, gotoff(gp)". */
1243
1244 if (basereg != alpha_gp_register && targreg == basereg)
1245 {
1246 if (alpha_noat_on)
1247 as_bad (_("macro requires $at register while noat in effect"));
1248 if (targreg == AXP_REG_AT)
1249 as_bad (_("macro requires $at while $at in use"));
1250
1251 set_tok_reg (newtok[0], AXP_REG_AT);
1252 }
1253 else
1254 set_tok_reg (newtok[0], targreg);
1255
1256 /* XXX: Disable this .got minimizing optimization so that we can get
1257 better instruction offset knowledge in the compiler. This happens
1258 very infrequently anyway. */
1259 if (1
1260 || (!range_signed_32 (addend)
1261 && (alpha_noat_on || targreg == AXP_REG_AT)))
1262 {
1263 newtok[1] = *exp;
1264 addend = 0;
1265 }
1266 else
1267 set_tok_sym (newtok[1], exp->X_add_symbol, 0);
1268
1269 set_tok_preg (newtok[2], alpha_gp_register);
1270
1271 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
1272
1273 assert (insn.nfixups == 1);
1274 insn.fixups[0].reloc = BFD_RELOC_ALPHA_ELF_LITERAL;
1275 insn.sequence = emit_lituse = next_sequence_num--;
1276 #endif /* OBJ_ELF */
1277 #ifdef OBJ_EVAX
1278 offsetT link;
1279
1280 /* Find symbol or symbol pointer in link section. */
1281
1282 if (exp->X_add_symbol == alpha_evax_proc.symbol)
1283 {
1284 if (range_signed_16 (addend))
1285 {
1286 set_tok_reg (newtok[0], targreg);
1287 set_tok_const (newtok[1], addend);
1288 set_tok_preg (newtok[2], basereg);
1289 assemble_tokens_to_insn ("lda", newtok, 3, &insn);
1290 addend = 0;
1291 }
1292 else
1293 {
1294 set_tok_reg (newtok[0], targreg);
1295 set_tok_const (newtok[1], 0);
1296 set_tok_preg (newtok[2], basereg);
1297 assemble_tokens_to_insn ("lda", newtok, 3, &insn);
1298 }
1299 }
1300 else
1301 {
1302 if (!range_signed_32 (addend))
1303 {
1304 link = add_to_link_pool (alpha_evax_proc.symbol,
1305 exp->X_add_symbol, addend);
1306 addend = 0;
1307 }
1308 else
1309 link = add_to_link_pool (alpha_evax_proc.symbol,
1310 exp->X_add_symbol, 0);
1311
1312 set_tok_reg (newtok[0], targreg);
1313 set_tok_const (newtok[1], link);
1314 set_tok_preg (newtok[2], basereg);
1315 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
1316 }
1317 #endif /* OBJ_EVAX */
1318
1319 emit_insn (&insn);
1320
1321 #ifndef OBJ_EVAX
1322 if (basereg != alpha_gp_register && basereg != AXP_REG_ZERO)
1323 {
1324 /* Emit "addq r, base, r". */
1325
1326 set_tok_reg (newtok[1], basereg);
1327 set_tok_reg (newtok[2], targreg);
1328 assemble_tokens ("addq", newtok, 3, 0);
1329 }
1330 #endif
1331 basereg = targreg;
1332 }
1333 break;
1334
1335 case O_constant:
1336 break;
1337
1338 case O_subtract:
1339 /* Assume that this difference expression will be resolved to an
1340 absolute value and that that value will fit in 16 bits. */
1341
1342 set_tok_reg (newtok[0], targreg);
1343 newtok[1] = *exp;
1344 set_tok_preg (newtok[2], basereg);
1345 assemble_tokens ("lda", newtok, 3, 0);
1346
1347 if (poffset)
1348 set_tok_const (*poffset, 0);
1349 return 0;
1350
1351 case O_big:
1352 if (exp->X_add_number > 0)
1353 as_bad (_("bignum invalid; zero assumed"));
1354 else
1355 as_bad (_("floating point number invalid; zero assumed"));
1356 addend = 0;
1357 break;
1358
1359 default:
1360 as_bad (_("can't handle expression"));
1361 addend = 0;
1362 break;
1363 }
1364
1365 if (!range_signed_32 (addend))
1366 {
1367 offsetT lit;
1368 long seq_num = next_sequence_num--;
1369
1370 /* For 64-bit addends, just put it in the literal pool. */
1371 #ifdef OBJ_EVAX
1372 /* Emit "ldq targreg, lit(basereg)". */
1373 lit = add_to_link_pool (alpha_evax_proc.symbol,
1374 section_symbol (absolute_section), addend);
1375 set_tok_reg (newtok[0], targreg);
1376 set_tok_const (newtok[1], lit);
1377 set_tok_preg (newtok[2], alpha_gp_register);
1378 assemble_tokens ("ldq", newtok, 3, 0);
1379 #else
1380
1381 if (alpha_lit8_section == NULL)
1382 {
1383 create_literal_section (".lit8",
1384 &alpha_lit8_section,
1385 &alpha_lit8_symbol);
1386
1387 #ifdef OBJ_ECOFF
1388 alpha_lit8_literal = add_to_literal_pool (alpha_lit8_symbol, 0x8000,
1389 alpha_lita_section, 8);
1390 if (alpha_lit8_literal >= 0x8000)
1391 as_fatal (_("overflow in literal (.lita) table"));
1392 #endif
1393 }
1394
1395 lit = add_to_literal_pool (NULL, addend, alpha_lit8_section, 8) - 0x8000;
1396 if (lit >= 0x8000)
1397 as_fatal (_("overflow in literal (.lit8) table"));
1398
1399 /* Emit "lda litreg, .lit8+0x8000". */
1400
1401 if (targreg == basereg)
1402 {
1403 if (alpha_noat_on)
1404 as_bad (_("macro requires $at register while noat in effect"));
1405 if (targreg == AXP_REG_AT)
1406 as_bad (_("macro requires $at while $at in use"));
1407
1408 set_tok_reg (newtok[0], AXP_REG_AT);
1409 }
1410 else
1411 set_tok_reg (newtok[0], targreg);
1412 #ifdef OBJ_ECOFF
1413 set_tok_sym (newtok[1], alpha_lita_symbol, alpha_lit8_literal);
1414 #endif
1415 #ifdef OBJ_ELF
1416 set_tok_sym (newtok[1], alpha_lit8_symbol, 0x8000);
1417 #endif
1418 set_tok_preg (newtok[2], alpha_gp_register);
1419
1420 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
1421
1422 assert (insn.nfixups == 1);
1423 #ifdef OBJ_ECOFF
1424 insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITERAL;
1425 #endif
1426 #ifdef OBJ_ELF
1427 insn.fixups[0].reloc = BFD_RELOC_ALPHA_ELF_LITERAL;
1428 #endif
1429 insn.sequence = seq_num;
1430
1431 emit_insn (&insn);
1432
1433 /* Emit "ldq litreg, lit(litreg)". */
1434
1435 set_tok_const (newtok[1], lit);
1436 set_tok_preg (newtok[2], newtok[0].X_add_number);
1437
1438 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
1439
1440 assert (insn.nfixups < MAX_INSN_FIXUPS);
1441 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
1442 insn.fixups[insn.nfixups].exp.X_op = O_absent;
1443 insn.nfixups++;
1444 insn.sequence = seq_num;
1445 emit_lituse = 0;
1446
1447 emit_insn (&insn);
1448
1449 /* Emit "addq litreg, base, target". */
1450
1451 if (basereg != AXP_REG_ZERO)
1452 {
1453 set_tok_reg (newtok[1], basereg);
1454 set_tok_reg (newtok[2], targreg);
1455 assemble_tokens ("addq", newtok, 3, 0);
1456 }
1457 #endif /* !OBJ_EVAX */
1458
1459 if (poffset)
1460 set_tok_const (*poffset, 0);
1461 *pbasereg = targreg;
1462 }
1463 else
1464 {
1465 offsetT low, high, extra, tmp;
1466
1467 /* For 32-bit operands, break up the addend. */
1468
1469 low = sign_extend_16 (addend);
1470 tmp = addend - low;
1471 high = sign_extend_16 (tmp >> 16);
1472
1473 if (tmp - (high << 16))
1474 {
1475 extra = 0x4000;
1476 tmp -= 0x40000000;
1477 high = sign_extend_16 (tmp >> 16);
1478 }
1479 else
1480 extra = 0;
1481
1482 set_tok_reg (newtok[0], targreg);
1483 set_tok_preg (newtok[2], basereg);
1484
1485 if (extra)
1486 {
1487 /* Emit "ldah r, extra(r). */
1488 set_tok_const (newtok[1], extra);
1489 assemble_tokens ("ldah", newtok, 3, 0);
1490 set_tok_preg (newtok[2], basereg = targreg);
1491 }
1492
1493 if (high)
1494 {
1495 /* Emit "ldah r, high(r). */
1496 set_tok_const (newtok[1], high);
1497 assemble_tokens ("ldah", newtok, 3, 0);
1498 basereg = targreg;
1499 set_tok_preg (newtok[2], basereg);
1500 }
1501
1502 if ((low && !poffset) || (!poffset && basereg != targreg))
1503 {
1504 /* Emit "lda r, low(base)". */
1505 set_tok_const (newtok[1], low);
1506 assemble_tokens ("lda", newtok, 3, 0);
1507 basereg = targreg;
1508 low = 0;
1509 }
1510
1511 if (poffset)
1512 set_tok_const (*poffset, low);
1513 *pbasereg = basereg;
1514 }
1515
1516 return emit_lituse;
1517 }
1518
1519 /* The lda macro differs from the lda instruction in that it handles
1520 most simple expressions, particularly symbol address loads and
1521 large constants. */
1522
1523 static void
1524 emit_lda (const expressionS *tok,
1525 int ntok,
1526 const void * unused ATTRIBUTE_UNUSED)
1527 {
1528 int basereg;
1529
1530 if (ntok == 2)
1531 basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
1532 else
1533 basereg = tok[2].X_add_number;
1534
1535 (void) load_expression (tok[0].X_add_number, &tok[1], &basereg, NULL);
1536 }
1537
1538 /* The ldah macro differs from the ldah instruction in that it has $31
1539 as an implied base register. */
1540
1541 static void
1542 emit_ldah (const expressionS *tok,
1543 int ntok ATTRIBUTE_UNUSED,
1544 const void * unused ATTRIBUTE_UNUSED)
1545 {
1546 expressionS newtok[3];
1547
1548 newtok[0] = tok[0];
1549 newtok[1] = tok[1];
1550 set_tok_preg (newtok[2], AXP_REG_ZERO);
1551
1552 assemble_tokens ("ldah", newtok, 3, 0);
1553 }
1554
1555 /* Called internally to handle all alignment needs. This takes care
1556 of eliding calls to frag_align if'n the cached current alignment
1557 says we've already got it, as well as taking care of the auto-align
1558 feature wrt labels. */
1559
1560 static void
1561 alpha_align (int n,
1562 char *pfill,
1563 symbolS *label,
1564 int force ATTRIBUTE_UNUSED)
1565 {
1566 if (alpha_current_align >= n)
1567 return;
1568
1569 if (pfill == NULL)
1570 {
1571 if (subseg_text_p (now_seg))
1572 frag_align_code (n, 0);
1573 else
1574 frag_align (n, 0, 0);
1575 }
1576 else
1577 frag_align (n, *pfill, 0);
1578
1579 alpha_current_align = n;
1580
1581 if (label != NULL && S_GET_SEGMENT (label) == now_seg)
1582 {
1583 symbol_set_frag (label, frag_now);
1584 S_SET_VALUE (label, (valueT) frag_now_fix ());
1585 }
1586
1587 record_alignment (now_seg, n);
1588
1589 /* ??? If alpha_flag_relax && force && elf, record the requested alignment
1590 in a reloc for the linker to see. */
1591 }
1592
1593 /* Actually output an instruction with its fixup. */
1594
1595 static void
1596 emit_insn (struct alpha_insn *insn)
1597 {
1598 char *f;
1599 int i;
1600
1601 /* Take care of alignment duties. */
1602 if (alpha_auto_align_on && alpha_current_align < 2)
1603 alpha_align (2, (char *) NULL, alpha_insn_label, 0);
1604 if (alpha_current_align > 2)
1605 alpha_current_align = 2;
1606 alpha_insn_label = NULL;
1607
1608 /* Write out the instruction. */
1609 f = frag_more (4);
1610 md_number_to_chars (f, insn->insn, 4);
1611
1612 #ifdef OBJ_ELF
1613 dwarf2_emit_insn (4);
1614 #endif
1615
1616 /* Apply the fixups in order. */
1617 for (i = 0; i < insn->nfixups; ++i)
1618 {
1619 const struct alpha_operand *operand = (const struct alpha_operand *) 0;
1620 struct alpha_fixup *fixup = &insn->fixups[i];
1621 struct alpha_reloc_tag *info = NULL;
1622 int size, pcrel;
1623 fixS *fixP;
1624
1625 /* Some fixups are only used internally and so have no howto. */
1626 if ((int) fixup->reloc < 0)
1627 {
1628 operand = &alpha_operands[-(int) fixup->reloc];
1629 size = 4;
1630 pcrel = ((operand->flags & AXP_OPERAND_RELATIVE) != 0);
1631 }
1632 else if (fixup->reloc > BFD_RELOC_UNUSED
1633 || fixup->reloc == BFD_RELOC_ALPHA_GPDISP_HI16
1634 || fixup->reloc == BFD_RELOC_ALPHA_GPDISP_LO16)
1635 {
1636 size = 2;
1637 pcrel = 0;
1638 }
1639 else
1640 {
1641 reloc_howto_type *reloc_howto
1642 = bfd_reloc_type_lookup (stdoutput, fixup->reloc);
1643 assert (reloc_howto);
1644
1645 size = bfd_get_reloc_size (reloc_howto);
1646 assert (size >= 1 && size <= 4);
1647
1648 pcrel = reloc_howto->pc_relative;
1649 }
1650
1651 fixP = fix_new_exp (frag_now, f - frag_now->fr_literal, size,
1652 &fixup->exp, pcrel, fixup->reloc);
1653
1654 /* Turn off complaints that the addend is too large for some fixups,
1655 and copy in the sequence number for the explicit relocations. */
1656 switch (fixup->reloc)
1657 {
1658 case BFD_RELOC_ALPHA_HINT:
1659 case BFD_RELOC_GPREL32:
1660 case BFD_RELOC_GPREL16:
1661 case BFD_RELOC_ALPHA_GPREL_HI16:
1662 case BFD_RELOC_ALPHA_GPREL_LO16:
1663 case BFD_RELOC_ALPHA_GOTDTPREL16:
1664 case BFD_RELOC_ALPHA_DTPREL_HI16:
1665 case BFD_RELOC_ALPHA_DTPREL_LO16:
1666 case BFD_RELOC_ALPHA_DTPREL16:
1667 case BFD_RELOC_ALPHA_GOTTPREL16:
1668 case BFD_RELOC_ALPHA_TPREL_HI16:
1669 case BFD_RELOC_ALPHA_TPREL_LO16:
1670 case BFD_RELOC_ALPHA_TPREL16:
1671 fixP->fx_no_overflow = 1;
1672 break;
1673
1674 case BFD_RELOC_ALPHA_GPDISP_HI16:
1675 fixP->fx_no_overflow = 1;
1676 fixP->fx_addsy = section_symbol (now_seg);
1677 fixP->fx_offset = 0;
1678
1679 info = get_alpha_reloc_tag (insn->sequence);
1680 if (++info->n_master > 1)
1681 as_bad (_("too many ldah insns for !gpdisp!%ld"), insn->sequence);
1682 if (info->segment != now_seg)
1683 as_bad (_("both insns for !gpdisp!%ld must be in the same section"),
1684 insn->sequence);
1685 fixP->tc_fix_data.info = info;
1686 break;
1687
1688 case BFD_RELOC_ALPHA_GPDISP_LO16:
1689 fixP->fx_no_overflow = 1;
1690
1691 info = get_alpha_reloc_tag (insn->sequence);
1692 if (++info->n_slaves > 1)
1693 as_bad (_("too many lda insns for !gpdisp!%ld"), insn->sequence);
1694 if (info->segment != now_seg)
1695 as_bad (_("both insns for !gpdisp!%ld must be in the same section"),
1696 insn->sequence);
1697 fixP->tc_fix_data.info = info;
1698 info->slaves = fixP;
1699 break;
1700
1701 case BFD_RELOC_ALPHA_LITERAL:
1702 case BFD_RELOC_ALPHA_ELF_LITERAL:
1703 fixP->fx_no_overflow = 1;
1704
1705 if (insn->sequence == 0)
1706 break;
1707 info = get_alpha_reloc_tag (insn->sequence);
1708 info->master = fixP;
1709 info->n_master++;
1710 if (info->segment != now_seg)
1711 info->multi_section_p = 1;
1712 fixP->tc_fix_data.info = info;
1713 break;
1714
1715 #ifdef RELOC_OP_P
1716 case DUMMY_RELOC_LITUSE_ADDR:
1717 fixP->fx_offset = LITUSE_ALPHA_ADDR;
1718 goto do_lituse;
1719 case DUMMY_RELOC_LITUSE_BASE:
1720 fixP->fx_offset = LITUSE_ALPHA_BASE;
1721 goto do_lituse;
1722 case DUMMY_RELOC_LITUSE_BYTOFF:
1723 fixP->fx_offset = LITUSE_ALPHA_BYTOFF;
1724 goto do_lituse;
1725 case DUMMY_RELOC_LITUSE_JSR:
1726 fixP->fx_offset = LITUSE_ALPHA_JSR;
1727 goto do_lituse;
1728 case DUMMY_RELOC_LITUSE_TLSGD:
1729 fixP->fx_offset = LITUSE_ALPHA_TLSGD;
1730 goto do_lituse;
1731 case DUMMY_RELOC_LITUSE_TLSLDM:
1732 fixP->fx_offset = LITUSE_ALPHA_TLSLDM;
1733 goto do_lituse;
1734 case DUMMY_RELOC_LITUSE_JSRDIRECT:
1735 fixP->fx_offset = LITUSE_ALPHA_JSRDIRECT;
1736 goto do_lituse;
1737 do_lituse:
1738 fixP->fx_addsy = section_symbol (now_seg);
1739 fixP->fx_r_type = BFD_RELOC_ALPHA_LITUSE;
1740
1741 info = get_alpha_reloc_tag (insn->sequence);
1742 if (fixup->reloc == DUMMY_RELOC_LITUSE_TLSGD)
1743 info->saw_lu_tlsgd = 1;
1744 else if (fixup->reloc == DUMMY_RELOC_LITUSE_TLSLDM)
1745 info->saw_lu_tlsldm = 1;
1746 if (++info->n_slaves > 1)
1747 {
1748 if (info->saw_lu_tlsgd)
1749 as_bad (_("too many lituse insns for !lituse_tlsgd!%ld"),
1750 insn->sequence);
1751 else if (info->saw_lu_tlsldm)
1752 as_bad (_("too many lituse insns for !lituse_tlsldm!%ld"),
1753 insn->sequence);
1754 }
1755 fixP->tc_fix_data.info = info;
1756 fixP->tc_fix_data.next_reloc = info->slaves;
1757 info->slaves = fixP;
1758 if (info->segment != now_seg)
1759 info->multi_section_p = 1;
1760 break;
1761
1762 case BFD_RELOC_ALPHA_TLSGD:
1763 fixP->fx_no_overflow = 1;
1764
1765 if (insn->sequence == 0)
1766 break;
1767 info = get_alpha_reloc_tag (insn->sequence);
1768 if (info->saw_tlsgd)
1769 as_bad (_("duplicate !tlsgd!%ld"), insn->sequence);
1770 else if (info->saw_tlsldm)
1771 as_bad (_("sequence number in use for !tlsldm!%ld"),
1772 insn->sequence);
1773 else
1774 info->saw_tlsgd = 1;
1775 fixP->tc_fix_data.info = info;
1776 break;
1777
1778 case BFD_RELOC_ALPHA_TLSLDM:
1779 fixP->fx_no_overflow = 1;
1780
1781 if (insn->sequence == 0)
1782 break;
1783 info = get_alpha_reloc_tag (insn->sequence);
1784 if (info->saw_tlsldm)
1785 as_bad (_("duplicate !tlsldm!%ld"), insn->sequence);
1786 else if (info->saw_tlsgd)
1787 as_bad (_("sequence number in use for !tlsgd!%ld"),
1788 insn->sequence);
1789 else
1790 info->saw_tlsldm = 1;
1791 fixP->tc_fix_data.info = info;
1792 break;
1793 #endif
1794 default:
1795 if ((int) fixup->reloc < 0)
1796 {
1797 if (operand->flags & AXP_OPERAND_NOOVERFLOW)
1798 fixP->fx_no_overflow = 1;
1799 }
1800 break;
1801 }
1802 }
1803 }
1804
1805 /* Insert an operand value into an instruction. */
1806
1807 static unsigned
1808 insert_operand (unsigned insn,
1809 const struct alpha_operand *operand,
1810 offsetT val,
1811 char *file,
1812 unsigned line)
1813 {
1814 if (operand->bits != 32 && !(operand->flags & AXP_OPERAND_NOOVERFLOW))
1815 {
1816 offsetT min, max;
1817
1818 if (operand->flags & AXP_OPERAND_SIGNED)
1819 {
1820 max = (1 << (operand->bits - 1)) - 1;
1821 min = -(1 << (operand->bits - 1));
1822 }
1823 else
1824 {
1825 max = (1 << operand->bits) - 1;
1826 min = 0;
1827 }
1828
1829 if (val < min || val > max)
1830 as_warn_value_out_of_range (_("operand"), val, min, max, file, line);
1831 }
1832
1833 if (operand->insert)
1834 {
1835 const char *errmsg = NULL;
1836
1837 insn = (*operand->insert) (insn, val, &errmsg);
1838 if (errmsg)
1839 as_warn (errmsg);
1840 }
1841 else
1842 insn |= ((val & ((1 << operand->bits) - 1)) << operand->shift);
1843
1844 return insn;
1845 }
1846
1847 /* Turn an opcode description and a set of arguments into
1848 an instruction and a fixup. */
1849
1850 static void
1851 assemble_insn (const struct alpha_opcode *opcode,
1852 const expressionS *tok,
1853 int ntok,
1854 struct alpha_insn *insn,
1855 bfd_reloc_code_real_type reloc)
1856 {
1857 const struct alpha_operand *reloc_operand = NULL;
1858 const expressionS *reloc_exp = NULL;
1859 const unsigned char *argidx;
1860 unsigned image;
1861 int tokidx = 0;
1862
1863 memset (insn, 0, sizeof (*insn));
1864 image = opcode->opcode;
1865
1866 for (argidx = opcode->operands; *argidx; ++argidx)
1867 {
1868 const struct alpha_operand *operand = &alpha_operands[*argidx];
1869 const expressionS *t = (const expressionS *) 0;
1870
1871 if (operand->flags & AXP_OPERAND_FAKE)
1872 {
1873 /* Fake operands take no value and generate no fixup. */
1874 image = insert_operand (image, operand, 0, NULL, 0);
1875 continue;
1876 }
1877
1878 if (tokidx >= ntok)
1879 {
1880 switch (operand->flags & AXP_OPERAND_OPTIONAL_MASK)
1881 {
1882 case AXP_OPERAND_DEFAULT_FIRST:
1883 t = &tok[0];
1884 break;
1885 case AXP_OPERAND_DEFAULT_SECOND:
1886 t = &tok[1];
1887 break;
1888 case AXP_OPERAND_DEFAULT_ZERO:
1889 {
1890 static expressionS zero_exp;
1891 t = &zero_exp;
1892 zero_exp.X_op = O_constant;
1893 zero_exp.X_unsigned = 1;
1894 }
1895 break;
1896 default:
1897 abort ();
1898 }
1899 }
1900 else
1901 t = &tok[tokidx++];
1902
1903 switch (t->X_op)
1904 {
1905 case O_register:
1906 case O_pregister:
1907 case O_cpregister:
1908 image = insert_operand (image, operand, regno (t->X_add_number),
1909 NULL, 0);
1910 break;
1911
1912 case O_constant:
1913 image = insert_operand (image, operand, t->X_add_number, NULL, 0);
1914 assert (reloc_operand == NULL);
1915 reloc_operand = operand;
1916 reloc_exp = t;
1917 break;
1918
1919 default:
1920 /* This is only 0 for fields that should contain registers,
1921 which means this pattern shouldn't have matched. */
1922 if (operand->default_reloc == 0)
1923 abort ();
1924
1925 /* There is one special case for which an insn receives two
1926 relocations, and thus the user-supplied reloc does not
1927 override the operand reloc. */
1928 if (operand->default_reloc == BFD_RELOC_ALPHA_HINT)
1929 {
1930 struct alpha_fixup *fixup;
1931
1932 if (insn->nfixups >= MAX_INSN_FIXUPS)
1933 as_fatal (_("too many fixups"));
1934
1935 fixup = &insn->fixups[insn->nfixups++];
1936 fixup->exp = *t;
1937 fixup->reloc = BFD_RELOC_ALPHA_HINT;
1938 }
1939 else
1940 {
1941 if (reloc == BFD_RELOC_UNUSED)
1942 reloc = operand->default_reloc;
1943
1944 assert (reloc_operand == NULL);
1945 reloc_operand = operand;
1946 reloc_exp = t;
1947 }
1948 break;
1949 }
1950 }
1951
1952 if (reloc != BFD_RELOC_UNUSED)
1953 {
1954 struct alpha_fixup *fixup;
1955
1956 if (insn->nfixups >= MAX_INSN_FIXUPS)
1957 as_fatal (_("too many fixups"));
1958
1959 /* ??? My but this is hacky. But the OSF/1 assembler uses the same
1960 relocation tag for both ldah and lda with gpdisp. Choose the
1961 correct internal relocation based on the opcode. */
1962 if (reloc == BFD_RELOC_ALPHA_GPDISP)
1963 {
1964 if (strcmp (opcode->name, "ldah") == 0)
1965 reloc = BFD_RELOC_ALPHA_GPDISP_HI16;
1966 else if (strcmp (opcode->name, "lda") == 0)
1967 reloc = BFD_RELOC_ALPHA_GPDISP_LO16;
1968 else
1969 as_bad (_("invalid relocation for instruction"));
1970 }
1971
1972 /* If this is a real relocation (as opposed to a lituse hint), then
1973 the relocation width should match the operand width. */
1974 else if (reloc < BFD_RELOC_UNUSED)
1975 {
1976 reloc_howto_type *reloc_howto
1977 = bfd_reloc_type_lookup (stdoutput, reloc);
1978 if (reloc_operand == NULL
1979 || reloc_howto->bitsize != reloc_operand->bits)
1980 {
1981 as_bad (_("invalid relocation for field"));
1982 return;
1983 }
1984 }
1985
1986 fixup = &insn->fixups[insn->nfixups++];
1987 if (reloc_exp)
1988 fixup->exp = *reloc_exp;
1989 else
1990 fixup->exp.X_op = O_absent;
1991 fixup->reloc = reloc;
1992 }
1993
1994 insn->insn = image;
1995 }
1996
1997 /* Handle all "simple" integer register loads -- ldq, ldq_l, ldq_u,
1998 etc. They differ from the real instructions in that they do simple
1999 expressions like the lda macro. */
2000
2001 static void
2002 emit_ir_load (const expressionS *tok,
2003 int ntok,
2004 const void * opname)
2005 {
2006 int basereg;
2007 long lituse;
2008 expressionS newtok[3];
2009 struct alpha_insn insn;
2010
2011 if (ntok == 2)
2012 basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
2013 else
2014 basereg = tok[2].X_add_number;
2015
2016 lituse = load_expression (tok[0].X_add_number, &tok[1], &basereg,
2017 &newtok[1]);
2018
2019 newtok[0] = tok[0];
2020 set_tok_preg (newtok[2], basereg);
2021
2022 assemble_tokens_to_insn ((const char *) opname, newtok, 3, &insn);
2023
2024 if (lituse)
2025 {
2026 assert (insn.nfixups < MAX_INSN_FIXUPS);
2027 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
2028 insn.fixups[insn.nfixups].exp.X_op = O_absent;
2029 insn.nfixups++;
2030 insn.sequence = lituse;
2031 }
2032
2033 emit_insn (&insn);
2034 }
2035
2036 /* Handle fp register loads, and both integer and fp register stores.
2037 Again, we handle simple expressions. */
2038
2039 static void
2040 emit_loadstore (const expressionS *tok,
2041 int ntok,
2042 const void * opname)
2043 {
2044 int basereg;
2045 long lituse;
2046 expressionS newtok[3];
2047 struct alpha_insn insn;
2048
2049 if (ntok == 2)
2050 basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
2051 else
2052 basereg = tok[2].X_add_number;
2053
2054 if (tok[1].X_op != O_constant || !range_signed_16 (tok[1].X_add_number))
2055 {
2056 if (alpha_noat_on)
2057 as_bad (_("macro requires $at register while noat in effect"));
2058
2059 lituse = load_expression (AXP_REG_AT, &tok[1], &basereg, &newtok[1]);
2060 }
2061 else
2062 {
2063 newtok[1] = tok[1];
2064 lituse = 0;
2065 }
2066
2067 newtok[0] = tok[0];
2068 set_tok_preg (newtok[2], basereg);
2069
2070 assemble_tokens_to_insn ((const char *) opname, newtok, 3, &insn);
2071
2072 if (lituse)
2073 {
2074 assert (insn.nfixups < MAX_INSN_FIXUPS);
2075 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
2076 insn.fixups[insn.nfixups].exp.X_op = O_absent;
2077 insn.nfixups++;
2078 insn.sequence = lituse;
2079 }
2080
2081 emit_insn (&insn);
2082 }
2083
2084 /* Load a half-word or byte as an unsigned value. */
2085
2086 static void
2087 emit_ldXu (const expressionS *tok,
2088 int ntok,
2089 const void * vlgsize)
2090 {
2091 if (alpha_target & AXP_OPCODE_BWX)
2092 emit_ir_load (tok, ntok, ldXu_op[(long) vlgsize]);
2093 else
2094 {
2095 expressionS newtok[3];
2096 struct alpha_insn insn;
2097 int basereg;
2098 long lituse;
2099
2100 if (alpha_noat_on)
2101 as_bad (_("macro requires $at register while noat in effect"));
2102
2103 if (ntok == 2)
2104 basereg = (tok[1].X_op == O_constant
2105 ? AXP_REG_ZERO : alpha_gp_register);
2106 else
2107 basereg = tok[2].X_add_number;
2108
2109 /* Emit "lda $at, exp". */
2110 lituse = load_expression (AXP_REG_AT, &tok[1], &basereg, NULL);
2111
2112 /* Emit "ldq_u targ, 0($at)". */
2113 newtok[0] = tok[0];
2114 set_tok_const (newtok[1], 0);
2115 set_tok_preg (newtok[2], basereg);
2116 assemble_tokens_to_insn ("ldq_u", newtok, 3, &insn);
2117
2118 if (lituse)
2119 {
2120 assert (insn.nfixups < MAX_INSN_FIXUPS);
2121 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
2122 insn.fixups[insn.nfixups].exp.X_op = O_absent;
2123 insn.nfixups++;
2124 insn.sequence = lituse;
2125 }
2126
2127 emit_insn (&insn);
2128
2129 /* Emit "extXl targ, $at, targ". */
2130 set_tok_reg (newtok[1], basereg);
2131 newtok[2] = newtok[0];
2132 assemble_tokens_to_insn (extXl_op[(long) vlgsize], newtok, 3, &insn);
2133
2134 if (lituse)
2135 {
2136 assert (insn.nfixups < MAX_INSN_FIXUPS);
2137 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF;
2138 insn.fixups[insn.nfixups].exp.X_op = O_absent;
2139 insn.nfixups++;
2140 insn.sequence = lituse;
2141 }
2142
2143 emit_insn (&insn);
2144 }
2145 }
2146
2147 /* Load a half-word or byte as a signed value. */
2148
2149 static void
2150 emit_ldX (const expressionS *tok,
2151 int ntok,
2152 const void * vlgsize)
2153 {
2154 emit_ldXu (tok, ntok, vlgsize);
2155 assemble_tokens (sextX_op[(long) vlgsize], tok, 1, 1);
2156 }
2157
2158 /* Load an integral value from an unaligned address as an unsigned
2159 value. */
2160
2161 static void
2162 emit_uldXu (const expressionS *tok,
2163 int ntok,
2164 const void * vlgsize)
2165 {
2166 long lgsize = (long) vlgsize;
2167 expressionS newtok[3];
2168
2169 if (alpha_noat_on)
2170 as_bad (_("macro requires $at register while noat in effect"));
2171
2172 /* Emit "lda $at, exp". */
2173 memcpy (newtok, tok, sizeof (expressionS) * ntok);
2174 newtok[0].X_add_number = AXP_REG_AT;
2175 assemble_tokens ("lda", newtok, ntok, 1);
2176
2177 /* Emit "ldq_u $t9, 0($at)". */
2178 set_tok_reg (newtok[0], AXP_REG_T9);
2179 set_tok_const (newtok[1], 0);
2180 set_tok_preg (newtok[2], AXP_REG_AT);
2181 assemble_tokens ("ldq_u", newtok, 3, 1);
2182
2183 /* Emit "ldq_u $t10, size-1($at)". */
2184 set_tok_reg (newtok[0], AXP_REG_T10);
2185 set_tok_const (newtok[1], (1 << lgsize) - 1);
2186 assemble_tokens ("ldq_u", newtok, 3, 1);
2187
2188 /* Emit "extXl $t9, $at, $t9". */
2189 set_tok_reg (newtok[0], AXP_REG_T9);
2190 set_tok_reg (newtok[1], AXP_REG_AT);
2191 set_tok_reg (newtok[2], AXP_REG_T9);
2192 assemble_tokens (extXl_op[lgsize], newtok, 3, 1);
2193
2194 /* Emit "extXh $t10, $at, $t10". */
2195 set_tok_reg (newtok[0], AXP_REG_T10);
2196 set_tok_reg (newtok[2], AXP_REG_T10);
2197 assemble_tokens (extXh_op[lgsize], newtok, 3, 1);
2198
2199 /* Emit "or $t9, $t10, targ". */
2200 set_tok_reg (newtok[0], AXP_REG_T9);
2201 set_tok_reg (newtok[1], AXP_REG_T10);
2202 newtok[2] = tok[0];
2203 assemble_tokens ("or", newtok, 3, 1);
2204 }
2205
2206 /* Load an integral value from an unaligned address as a signed value.
2207 Note that quads should get funneled to the unsigned load since we
2208 don't have to do the sign extension. */
2209
2210 static void
2211 emit_uldX (const expressionS *tok,
2212 int ntok,
2213 const void * vlgsize)
2214 {
2215 emit_uldXu (tok, ntok, vlgsize);
2216 assemble_tokens (sextX_op[(long) vlgsize], tok, 1, 1);
2217 }
2218
2219 /* Implement the ldil macro. */
2220
2221 static void
2222 emit_ldil (const expressionS *tok,
2223 int ntok,
2224 const void * unused ATTRIBUTE_UNUSED)
2225 {
2226 expressionS newtok[2];
2227
2228 memcpy (newtok, tok, sizeof (newtok));
2229 newtok[1].X_add_number = sign_extend_32 (tok[1].X_add_number);
2230
2231 assemble_tokens ("lda", newtok, ntok, 1);
2232 }
2233
2234 /* Store a half-word or byte. */
2235
2236 static void
2237 emit_stX (const expressionS *tok,
2238 int ntok,
2239 const void * vlgsize)
2240 {
2241 int lgsize = (int) (long) vlgsize;
2242
2243 if (alpha_target & AXP_OPCODE_BWX)
2244 emit_loadstore (tok, ntok, stX_op[lgsize]);
2245 else
2246 {
2247 expressionS newtok[3];
2248 struct alpha_insn insn;
2249 int basereg;
2250 long lituse;
2251
2252 if (alpha_noat_on)
2253 as_bad (_("macro requires $at register while noat in effect"));
2254
2255 if (ntok == 2)
2256 basereg = (tok[1].X_op == O_constant
2257 ? AXP_REG_ZERO : alpha_gp_register);
2258 else
2259 basereg = tok[2].X_add_number;
2260
2261 /* Emit "lda $at, exp". */
2262 lituse = load_expression (AXP_REG_AT, &tok[1], &basereg, NULL);
2263
2264 /* Emit "ldq_u $t9, 0($at)". */
2265 set_tok_reg (newtok[0], AXP_REG_T9);
2266 set_tok_const (newtok[1], 0);
2267 set_tok_preg (newtok[2], basereg);
2268 assemble_tokens_to_insn ("ldq_u", newtok, 3, &insn);
2269
2270 if (lituse)
2271 {
2272 assert (insn.nfixups < MAX_INSN_FIXUPS);
2273 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
2274 insn.fixups[insn.nfixups].exp.X_op = O_absent;
2275 insn.nfixups++;
2276 insn.sequence = lituse;
2277 }
2278
2279 emit_insn (&insn);
2280
2281 /* Emit "insXl src, $at, $t10". */
2282 newtok[0] = tok[0];
2283 set_tok_reg (newtok[1], basereg);
2284 set_tok_reg (newtok[2], AXP_REG_T10);
2285 assemble_tokens_to_insn (insXl_op[lgsize], newtok, 3, &insn);
2286
2287 if (lituse)
2288 {
2289 assert (insn.nfixups < MAX_INSN_FIXUPS);
2290 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF;
2291 insn.fixups[insn.nfixups].exp.X_op = O_absent;
2292 insn.nfixups++;
2293 insn.sequence = lituse;
2294 }
2295
2296 emit_insn (&insn);
2297
2298 /* Emit "mskXl $t9, $at, $t9". */
2299 set_tok_reg (newtok[0], AXP_REG_T9);
2300 newtok[2] = newtok[0];
2301 assemble_tokens_to_insn (mskXl_op[lgsize], newtok, 3, &insn);
2302
2303 if (lituse)
2304 {
2305 assert (insn.nfixups < MAX_INSN_FIXUPS);
2306 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF;
2307 insn.fixups[insn.nfixups].exp.X_op = O_absent;
2308 insn.nfixups++;
2309 insn.sequence = lituse;
2310 }
2311
2312 emit_insn (&insn);
2313
2314 /* Emit "or $t9, $t10, $t9". */
2315 set_tok_reg (newtok[1], AXP_REG_T10);
2316 assemble_tokens ("or", newtok, 3, 1);
2317
2318 /* Emit "stq_u $t9, 0($at). */
2319 set_tok_const(newtok[1], 0);
2320 set_tok_preg (newtok[2], AXP_REG_AT);
2321 assemble_tokens_to_insn ("stq_u", newtok, 3, &insn);
2322
2323 if (lituse)
2324 {
2325 assert (insn.nfixups < MAX_INSN_FIXUPS);
2326 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
2327 insn.fixups[insn.nfixups].exp.X_op = O_absent;
2328 insn.nfixups++;
2329 insn.sequence = lituse;
2330 }
2331
2332 emit_insn (&insn);
2333 }
2334 }
2335
2336 /* Store an integer to an unaligned address. */
2337
2338 static void
2339 emit_ustX (const expressionS *tok,
2340 int ntok,
2341 const void * vlgsize)
2342 {
2343 int lgsize = (int) (long) vlgsize;
2344 expressionS newtok[3];
2345
2346 /* Emit "lda $at, exp". */
2347 memcpy (newtok, tok, sizeof (expressionS) * ntok);
2348 newtok[0].X_add_number = AXP_REG_AT;
2349 assemble_tokens ("lda", newtok, ntok, 1);
2350
2351 /* Emit "ldq_u $9, 0($at)". */
2352 set_tok_reg (newtok[0], AXP_REG_T9);
2353 set_tok_const (newtok[1], 0);
2354 set_tok_preg (newtok[2], AXP_REG_AT);
2355 assemble_tokens ("ldq_u", newtok, 3, 1);
2356
2357 /* Emit "ldq_u $10, size-1($at)". */
2358 set_tok_reg (newtok[0], AXP_REG_T10);
2359 set_tok_const (newtok[1], (1 << lgsize) - 1);
2360 assemble_tokens ("ldq_u", newtok, 3, 1);
2361
2362 /* Emit "insXl src, $at, $t11". */
2363 newtok[0] = tok[0];
2364 set_tok_reg (newtok[1], AXP_REG_AT);
2365 set_tok_reg (newtok[2], AXP_REG_T11);
2366 assemble_tokens (insXl_op[lgsize], newtok, 3, 1);
2367
2368 /* Emit "insXh src, $at, $t12". */
2369 set_tok_reg (newtok[2], AXP_REG_T12);
2370 assemble_tokens (insXh_op[lgsize], newtok, 3, 1);
2371
2372 /* Emit "mskXl $t9, $at, $t9". */
2373 set_tok_reg (newtok[0], AXP_REG_T9);
2374 newtok[2] = newtok[0];
2375 assemble_tokens (mskXl_op[lgsize], newtok, 3, 1);
2376
2377 /* Emit "mskXh $t10, $at, $t10". */
2378 set_tok_reg (newtok[0], AXP_REG_T10);
2379 newtok[2] = newtok[0];
2380 assemble_tokens (mskXh_op[lgsize], newtok, 3, 1);
2381
2382 /* Emit "or $t9, $t11, $t9". */
2383 set_tok_reg (newtok[0], AXP_REG_T9);
2384 set_tok_reg (newtok[1], AXP_REG_T11);
2385 newtok[2] = newtok[0];
2386 assemble_tokens ("or", newtok, 3, 1);
2387
2388 /* Emit "or $t10, $t12, $t10". */
2389 set_tok_reg (newtok[0], AXP_REG_T10);
2390 set_tok_reg (newtok[1], AXP_REG_T12);
2391 newtok[2] = newtok[0];
2392 assemble_tokens ("or", newtok, 3, 1);
2393
2394 /* Emit "stq_u $t10, size-1($at)". */
2395 set_tok_reg (newtok[0], AXP_REG_T10);
2396 set_tok_const (newtok[1], (1 << lgsize) - 1);
2397 set_tok_preg (newtok[2], AXP_REG_AT);
2398 assemble_tokens ("stq_u", newtok, 3, 1);
2399
2400 /* Emit "stq_u $t9, 0($at)". */
2401 set_tok_reg (newtok[0], AXP_REG_T9);
2402 set_tok_const (newtok[1], 0);
2403 assemble_tokens ("stq_u", newtok, 3, 1);
2404 }
2405
2406 /* Sign extend a half-word or byte. The 32-bit sign extend is
2407 implemented as "addl $31, $r, $t" in the opcode table. */
2408
2409 static void
2410 emit_sextX (const expressionS *tok,
2411 int ntok,
2412 const void * vlgsize)
2413 {
2414 long lgsize = (long) vlgsize;
2415
2416 if (alpha_target & AXP_OPCODE_BWX)
2417 assemble_tokens (sextX_op[lgsize], tok, ntok, 0);
2418 else
2419 {
2420 int bitshift = 64 - 8 * (1 << lgsize);
2421 expressionS newtok[3];
2422
2423 /* Emit "sll src,bits,dst". */
2424 newtok[0] = tok[0];
2425 set_tok_const (newtok[1], bitshift);
2426 newtok[2] = tok[ntok - 1];
2427 assemble_tokens ("sll", newtok, 3, 1);
2428
2429 /* Emit "sra dst,bits,dst". */
2430 newtok[0] = newtok[2];
2431 assemble_tokens ("sra", newtok, 3, 1);
2432 }
2433 }
2434
2435 /* Implement the division and modulus macros. */
2436
2437 #ifdef OBJ_EVAX
2438
2439 /* Make register usage like in normal procedure call.
2440 Don't clobber PV and RA. */
2441
2442 static void
2443 emit_division (const expressionS *tok,
2444 int ntok,
2445 const void * symname)
2446 {
2447 /* DIVISION and MODULUS. Yech.
2448
2449 Convert
2450 OP x,y,result
2451 to
2452 mov x,R16 # if x != R16
2453 mov y,R17 # if y != R17
2454 lda AT,__OP
2455 jsr AT,(AT),0
2456 mov R0,result
2457
2458 with appropriate optimizations if R0,R16,R17 are the registers
2459 specified by the compiler. */
2460
2461 int xr, yr, rr;
2462 symbolS *sym;
2463 expressionS newtok[3];
2464
2465 xr = regno (tok[0].X_add_number);
2466 yr = regno (tok[1].X_add_number);
2467
2468 if (ntok < 3)
2469 rr = xr;
2470 else
2471 rr = regno (tok[2].X_add_number);
2472
2473 /* Move the operands into the right place. */
2474 if (yr == AXP_REG_R16 && xr == AXP_REG_R17)
2475 {
2476 /* They are in exactly the wrong order -- swap through AT. */
2477 if (alpha_noat_on)
2478 as_bad (_("macro requires $at register while noat in effect"));
2479
2480 set_tok_reg (newtok[0], AXP_REG_R16);
2481 set_tok_reg (newtok[1], AXP_REG_AT);
2482 assemble_tokens ("mov", newtok, 2, 1);
2483
2484 set_tok_reg (newtok[0], AXP_REG_R17);
2485 set_tok_reg (newtok[1], AXP_REG_R16);
2486 assemble_tokens ("mov", newtok, 2, 1);
2487
2488 set_tok_reg (newtok[0], AXP_REG_AT);
2489 set_tok_reg (newtok[1], AXP_REG_R17);
2490 assemble_tokens ("mov", newtok, 2, 1);
2491 }
2492 else
2493 {
2494 if (yr == AXP_REG_R16)
2495 {
2496 set_tok_reg (newtok[0], AXP_REG_R16);
2497 set_tok_reg (newtok[1], AXP_REG_R17);
2498 assemble_tokens ("mov", newtok, 2, 1);
2499 }
2500
2501 if (xr != AXP_REG_R16)
2502 {
2503 set_tok_reg (newtok[0], xr);
2504 set_tok_reg (newtok[1], AXP_REG_R16);
2505 assemble_tokens ("mov", newtok, 2, 1);
2506 }
2507
2508 if (yr != AXP_REG_R16 && yr != AXP_REG_R17)
2509 {
2510 set_tok_reg (newtok[0], yr);
2511 set_tok_reg (newtok[1], AXP_REG_R17);
2512 assemble_tokens ("mov", newtok, 2, 1);
2513 }
2514 }
2515
2516 sym = symbol_find_or_make ((const char *) symname);
2517
2518 set_tok_reg (newtok[0], AXP_REG_AT);
2519 set_tok_sym (newtok[1], sym, 0);
2520 assemble_tokens ("lda", newtok, 2, 1);
2521
2522 /* Call the division routine. */
2523 set_tok_reg (newtok[0], AXP_REG_AT);
2524 set_tok_cpreg (newtok[1], AXP_REG_AT);
2525 set_tok_const (newtok[2], 0);
2526 assemble_tokens ("jsr", newtok, 3, 1);
2527
2528 /* Move the result to the right place. */
2529 if (rr != AXP_REG_R0)
2530 {
2531 set_tok_reg (newtok[0], AXP_REG_R0);
2532 set_tok_reg (newtok[1], rr);
2533 assemble_tokens ("mov", newtok, 2, 1);
2534 }
2535 }
2536
2537 #else /* !OBJ_EVAX */
2538
2539 static void
2540 emit_division (const expressionS *tok,
2541 int ntok,
2542 const void * symname)
2543 {
2544 /* DIVISION and MODULUS. Yech.
2545 Convert
2546 OP x,y,result
2547 to
2548 lda pv,__OP
2549 mov x,t10
2550 mov y,t11
2551 jsr t9,(pv),__OP
2552 mov t12,result
2553
2554 with appropriate optimizations if t10,t11,t12 are the registers
2555 specified by the compiler. */
2556
2557 int xr, yr, rr;
2558 symbolS *sym;
2559 expressionS newtok[3];
2560
2561 xr = regno (tok[0].X_add_number);
2562 yr = regno (tok[1].X_add_number);
2563
2564 if (ntok < 3)
2565 rr = xr;
2566 else
2567 rr = regno (tok[2].X_add_number);
2568
2569 sym = symbol_find_or_make ((const char *) symname);
2570
2571 /* Move the operands into the right place. */
2572 if (yr == AXP_REG_T10 && xr == AXP_REG_T11)
2573 {
2574 /* They are in exactly the wrong order -- swap through AT. */
2575 if (alpha_noat_on)
2576 as_bad (_("macro requires $at register while noat in effect"));
2577
2578 set_tok_reg (newtok[0], AXP_REG_T10);
2579 set_tok_reg (newtok[1], AXP_REG_AT);
2580 assemble_tokens ("mov", newtok, 2, 1);
2581
2582 set_tok_reg (newtok[0], AXP_REG_T11);
2583 set_tok_reg (newtok[1], AXP_REG_T10);
2584 assemble_tokens ("mov", newtok, 2, 1);
2585
2586 set_tok_reg (newtok[0], AXP_REG_AT);
2587 set_tok_reg (newtok[1], AXP_REG_T11);
2588 assemble_tokens ("mov", newtok, 2, 1);
2589 }
2590 else
2591 {
2592 if (yr == AXP_REG_T10)
2593 {
2594 set_tok_reg (newtok[0], AXP_REG_T10);
2595 set_tok_reg (newtok[1], AXP_REG_T11);
2596 assemble_tokens ("mov", newtok, 2, 1);
2597 }
2598
2599 if (xr != AXP_REG_T10)
2600 {
2601 set_tok_reg (newtok[0], xr);
2602 set_tok_reg (newtok[1], AXP_REG_T10);
2603 assemble_tokens ("mov", newtok, 2, 1);
2604 }
2605
2606 if (yr != AXP_REG_T10 && yr != AXP_REG_T11)
2607 {
2608 set_tok_reg (newtok[0], yr);
2609 set_tok_reg (newtok[1], AXP_REG_T11);
2610 assemble_tokens ("mov", newtok, 2, 1);
2611 }
2612 }
2613
2614 /* Call the division routine. */
2615 set_tok_reg (newtok[0], AXP_REG_T9);
2616 set_tok_sym (newtok[1], sym, 0);
2617 assemble_tokens ("jsr", newtok, 2, 1);
2618
2619 /* Reload the GP register. */
2620 #ifdef OBJ_AOUT
2621 FIXME
2622 #endif
2623 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
2624 set_tok_reg (newtok[0], alpha_gp_register);
2625 set_tok_const (newtok[1], 0);
2626 set_tok_preg (newtok[2], AXP_REG_T9);
2627 assemble_tokens ("ldgp", newtok, 3, 1);
2628 #endif
2629
2630 /* Move the result to the right place. */
2631 if (rr != AXP_REG_T12)
2632 {
2633 set_tok_reg (newtok[0], AXP_REG_T12);
2634 set_tok_reg (newtok[1], rr);
2635 assemble_tokens ("mov", newtok, 2, 1);
2636 }
2637 }
2638
2639 #endif /* !OBJ_EVAX */
2640
2641 /* The jsr and jmp macros differ from their instruction counterparts
2642 in that they can load the target address and default most
2643 everything. */
2644
2645 static void
2646 emit_jsrjmp (const expressionS *tok,
2647 int ntok,
2648 const void * vopname)
2649 {
2650 const char *opname = (const char *) vopname;
2651 struct alpha_insn insn;
2652 expressionS newtok[3];
2653 int r, tokidx = 0;
2654 long lituse = 0;
2655
2656 if (tokidx < ntok && tok[tokidx].X_op == O_register)
2657 r = regno (tok[tokidx++].X_add_number);
2658 else
2659 r = strcmp (opname, "jmp") == 0 ? AXP_REG_ZERO : AXP_REG_RA;
2660
2661 set_tok_reg (newtok[0], r);
2662
2663 if (tokidx < ntok &&
2664 (tok[tokidx].X_op == O_pregister || tok[tokidx].X_op == O_cpregister))
2665 r = regno (tok[tokidx++].X_add_number);
2666 #ifdef OBJ_EVAX
2667 /* Keep register if jsr $n.<sym>. */
2668 #else
2669 else
2670 {
2671 int basereg = alpha_gp_register;
2672 lituse = load_expression (r = AXP_REG_PV, &tok[tokidx], &basereg, NULL);
2673 }
2674 #endif
2675
2676 set_tok_cpreg (newtok[1], r);
2677
2678 #ifdef OBJ_EVAX
2679 /* FIXME: Add hint relocs to BFD for evax. */
2680 #else
2681 if (tokidx < ntok)
2682 newtok[2] = tok[tokidx];
2683 else
2684 #endif
2685 set_tok_const (newtok[2], 0);
2686
2687 assemble_tokens_to_insn (opname, newtok, 3, &insn);
2688
2689 if (lituse)
2690 {
2691 assert (insn.nfixups < MAX_INSN_FIXUPS);
2692 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_JSR;
2693 insn.fixups[insn.nfixups].exp.X_op = O_absent;
2694 insn.nfixups++;
2695 insn.sequence = lituse;
2696 }
2697
2698 emit_insn (&insn);
2699 }
2700
2701 /* The ret and jcr instructions differ from their instruction
2702 counterparts in that everything can be defaulted. */
2703
2704 static void
2705 emit_retjcr (const expressionS *tok,
2706 int ntok,
2707 const void * vopname)
2708 {
2709 const char *opname = (const char *) vopname;
2710 expressionS newtok[3];
2711 int r, tokidx = 0;
2712
2713 if (tokidx < ntok && tok[tokidx].X_op == O_register)
2714 r = regno (tok[tokidx++].X_add_number);
2715 else
2716 r = AXP_REG_ZERO;
2717
2718 set_tok_reg (newtok[0], r);
2719
2720 if (tokidx < ntok &&
2721 (tok[tokidx].X_op == O_pregister || tok[tokidx].X_op == O_cpregister))
2722 r = regno (tok[tokidx++].X_add_number);
2723 else
2724 r = AXP_REG_RA;
2725
2726 set_tok_cpreg (newtok[1], r);
2727
2728 if (tokidx < ntok)
2729 newtok[2] = tok[tokidx];
2730 else
2731 set_tok_const (newtok[2], strcmp (opname, "ret") == 0);
2732
2733 assemble_tokens (opname, newtok, 3, 0);
2734 }
2735
2736 /* Implement the ldgp macro. */
2737
2738 static void
2739 emit_ldgp (const expressionS *tok,
2740 int ntok ATTRIBUTE_UNUSED,
2741 const void * unused ATTRIBUTE_UNUSED)
2742 {
2743 #ifdef OBJ_AOUT
2744 FIXME
2745 #endif
2746 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
2747 /* from "ldgp r1,n(r2)", generate "ldah r1,X(R2); lda r1,Y(r1)"
2748 with appropriate constants and relocations. */
2749 struct alpha_insn insn;
2750 expressionS newtok[3];
2751 expressionS addend;
2752
2753 #ifdef OBJ_ECOFF
2754 if (regno (tok[2].X_add_number) == AXP_REG_PV)
2755 ecoff_set_gp_prolog_size (0);
2756 #endif
2757
2758 newtok[0] = tok[0];
2759 set_tok_const (newtok[1], 0);
2760 newtok[2] = tok[2];
2761
2762 assemble_tokens_to_insn ("ldah", newtok, 3, &insn);
2763
2764 addend = tok[1];
2765
2766 #ifdef OBJ_ECOFF
2767 if (addend.X_op != O_constant)
2768 as_bad (_("can not resolve expression"));
2769 addend.X_op = O_symbol;
2770 addend.X_add_symbol = alpha_gp_symbol;
2771 #endif
2772
2773 insn.nfixups = 1;
2774 insn.fixups[0].exp = addend;
2775 insn.fixups[0].reloc = BFD_RELOC_ALPHA_GPDISP_HI16;
2776 insn.sequence = next_sequence_num;
2777
2778 emit_insn (&insn);
2779
2780 set_tok_preg (newtok[2], tok[0].X_add_number);
2781
2782 assemble_tokens_to_insn ("lda", newtok, 3, &insn);
2783
2784 #ifdef OBJ_ECOFF
2785 addend.X_add_number += 4;
2786 #endif
2787
2788 insn.nfixups = 1;
2789 insn.fixups[0].exp = addend;
2790 insn.fixups[0].reloc = BFD_RELOC_ALPHA_GPDISP_LO16;
2791 insn.sequence = next_sequence_num--;
2792
2793 emit_insn (&insn);
2794 #endif /* OBJ_ECOFF || OBJ_ELF */
2795 }
2796
2797 /* The macro table. */
2798
2799 static const struct alpha_macro alpha_macros[] =
2800 {
2801 /* Load/Store macros. */
2802 { "lda", emit_lda, NULL,
2803 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2804 { "ldah", emit_ldah, NULL,
2805 { MACRO_IR, MACRO_EXP, MACRO_EOA } },
2806
2807 { "ldl", emit_ir_load, "ldl",
2808 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2809 { "ldl_l", emit_ir_load, "ldl_l",
2810 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2811 { "ldq", emit_ir_load, "ldq",
2812 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2813 { "ldq_l", emit_ir_load, "ldq_l",
2814 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2815 { "ldq_u", emit_ir_load, "ldq_u",
2816 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2817 { "ldf", emit_loadstore, "ldf",
2818 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2819 { "ldg", emit_loadstore, "ldg",
2820 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2821 { "lds", emit_loadstore, "lds",
2822 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2823 { "ldt", emit_loadstore, "ldt",
2824 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2825
2826 { "ldb", emit_ldX, (void *) 0,
2827 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2828 { "ldbu", emit_ldXu, (void *) 0,
2829 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2830 { "ldw", emit_ldX, (void *) 1,
2831 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2832 { "ldwu", emit_ldXu, (void *) 1,
2833 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2834
2835 { "uldw", emit_uldX, (void *) 1,
2836 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2837 { "uldwu", emit_uldXu, (void *) 1,
2838 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2839 { "uldl", emit_uldX, (void *) 2,
2840 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2841 { "uldlu", emit_uldXu, (void *) 2,
2842 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2843 { "uldq", emit_uldXu, (void *) 3,
2844 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2845
2846 { "ldgp", emit_ldgp, NULL,
2847 { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA } },
2848
2849 { "ldi", emit_lda, NULL,
2850 { MACRO_IR, MACRO_EXP, MACRO_EOA } },
2851 { "ldil", emit_ldil, NULL,
2852 { MACRO_IR, MACRO_EXP, MACRO_EOA } },
2853 { "ldiq", emit_lda, NULL,
2854 { MACRO_IR, MACRO_EXP, MACRO_EOA } },
2855
2856 { "stl", emit_loadstore, "stl",
2857 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2858 { "stl_c", emit_loadstore, "stl_c",
2859 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2860 { "stq", emit_loadstore, "stq",
2861 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2862 { "stq_c", emit_loadstore, "stq_c",
2863 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2864 { "stq_u", emit_loadstore, "stq_u",
2865 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2866 { "stf", emit_loadstore, "stf",
2867 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2868 { "stg", emit_loadstore, "stg",
2869 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2870 { "sts", emit_loadstore, "sts",
2871 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2872 { "stt", emit_loadstore, "stt",
2873 { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2874
2875 { "stb", emit_stX, (void *) 0,
2876 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2877 { "stw", emit_stX, (void *) 1,
2878 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2879 { "ustw", emit_ustX, (void *) 1,
2880 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2881 { "ustl", emit_ustX, (void *) 2,
2882 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2883 { "ustq", emit_ustX, (void *) 3,
2884 { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
2885
2886 /* Arithmetic macros. */
2887
2888 { "sextb", emit_sextX, (void *) 0,
2889 { MACRO_IR, MACRO_IR, MACRO_EOA,
2890 MACRO_IR, MACRO_EOA,
2891 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
2892 { "sextw", emit_sextX, (void *) 1,
2893 { MACRO_IR, MACRO_IR, MACRO_EOA,
2894 MACRO_IR, MACRO_EOA,
2895 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
2896
2897 { "divl", emit_division, "__divl",
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 { "divlu", emit_division, "__divlu",
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 { "divq", emit_division, "__divq",
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 { "divqu", emit_division, "__divqu",
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 { "reml", emit_division, "__reml",
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 */ } },
2922 { "remlu", emit_division, "__remlu",
2923 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
2924 MACRO_IR, MACRO_IR, MACRO_EOA,
2925 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
2926 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
2927 { "remq", emit_division, "__remq",
2928 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
2929 MACRO_IR, MACRO_IR, MACRO_EOA,
2930 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
2931 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
2932 { "remqu", emit_division, "__remqu",
2933 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
2934 MACRO_IR, MACRO_IR, MACRO_EOA,
2935 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
2936 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
2937
2938 { "jsr", emit_jsrjmp, "jsr",
2939 { MACRO_PIR, MACRO_EXP, MACRO_EOA,
2940 MACRO_PIR, MACRO_EOA,
2941 MACRO_IR, MACRO_EXP, MACRO_EOA,
2942 MACRO_EXP, MACRO_EOA } },
2943 { "jmp", emit_jsrjmp, "jmp",
2944 { MACRO_PIR, MACRO_EXP, MACRO_EOA,
2945 MACRO_PIR, MACRO_EOA,
2946 MACRO_IR, MACRO_EXP, MACRO_EOA,
2947 MACRO_EXP, MACRO_EOA } },
2948 { "ret", emit_retjcr, "ret",
2949 { MACRO_IR, MACRO_EXP, MACRO_EOA,
2950 MACRO_IR, MACRO_EOA,
2951 MACRO_PIR, MACRO_EXP, MACRO_EOA,
2952 MACRO_PIR, MACRO_EOA,
2953 MACRO_EXP, MACRO_EOA,
2954 MACRO_EOA } },
2955 { "jcr", emit_retjcr, "jcr",
2956 { MACRO_IR, MACRO_EXP, MACRO_EOA,
2957 MACRO_IR, MACRO_EOA,
2958 MACRO_PIR, MACRO_EXP, MACRO_EOA,
2959 MACRO_PIR, MACRO_EOA,
2960 MACRO_EXP, MACRO_EOA,
2961 MACRO_EOA } },
2962 { "jsr_coroutine", emit_retjcr, "jcr",
2963 { MACRO_IR, MACRO_EXP, MACRO_EOA,
2964 MACRO_IR, MACRO_EOA,
2965 MACRO_PIR, MACRO_EXP, MACRO_EOA,
2966 MACRO_PIR, MACRO_EOA,
2967 MACRO_EXP, MACRO_EOA,
2968 MACRO_EOA } },
2969 };
2970
2971 static const unsigned int alpha_num_macros
2972 = sizeof (alpha_macros) / sizeof (*alpha_macros);
2973
2974 /* Search forward through all variants of a macro looking for a syntax
2975 match. */
2976
2977 static const struct alpha_macro *
2978 find_macro_match (const struct alpha_macro *first_macro,
2979 const expressionS *tok,
2980 int *pntok)
2981
2982 {
2983 const struct alpha_macro *macro = first_macro;
2984 int ntok = *pntok;
2985
2986 do
2987 {
2988 const enum alpha_macro_arg *arg = macro->argsets;
2989 int tokidx = 0;
2990
2991 while (*arg)
2992 {
2993 switch (*arg)
2994 {
2995 case MACRO_EOA:
2996 if (tokidx == ntok)
2997 return macro;
2998 else
2999 tokidx = 0;
3000 break;
3001
3002 /* Index register. */
3003 case MACRO_IR:
3004 if (tokidx >= ntok || tok[tokidx].X_op != O_register
3005 || !is_ir_num (tok[tokidx].X_add_number))
3006 goto match_failed;
3007 ++tokidx;
3008 break;
3009
3010 /* Parenthesized index register. */
3011 case MACRO_PIR:
3012 if (tokidx >= ntok || tok[tokidx].X_op != O_pregister
3013 || !is_ir_num (tok[tokidx].X_add_number))
3014 goto match_failed;
3015 ++tokidx;
3016 break;
3017
3018 /* Optional parenthesized index register. */
3019 case MACRO_OPIR:
3020 if (tokidx < ntok && tok[tokidx].X_op == O_pregister
3021 && is_ir_num (tok[tokidx].X_add_number))
3022 ++tokidx;
3023 break;
3024
3025 /* Leading comma with a parenthesized index register. */
3026 case MACRO_CPIR:
3027 if (tokidx >= ntok || tok[tokidx].X_op != O_cpregister
3028 || !is_ir_num (tok[tokidx].X_add_number))
3029 goto match_failed;
3030 ++tokidx;
3031 break;
3032
3033 /* Floating point register. */
3034 case MACRO_FPR:
3035 if (tokidx >= ntok || tok[tokidx].X_op != O_register
3036 || !is_fpr_num (tok[tokidx].X_add_number))
3037 goto match_failed;
3038 ++tokidx;
3039 break;
3040
3041 /* Normal expression. */
3042 case MACRO_EXP:
3043 if (tokidx >= ntok)
3044 goto match_failed;
3045 switch (tok[tokidx].X_op)
3046 {
3047 case O_illegal:
3048 case O_absent:
3049 case O_register:
3050 case O_pregister:
3051 case O_cpregister:
3052 case O_literal:
3053 case O_lituse_base:
3054 case O_lituse_bytoff:
3055 case O_lituse_jsr:
3056 case O_gpdisp:
3057 case O_gprelhigh:
3058 case O_gprellow:
3059 case O_gprel:
3060 case O_samegp:
3061 goto match_failed;
3062
3063 default:
3064 break;
3065 }
3066 ++tokidx;
3067 break;
3068
3069 match_failed:
3070 while (*arg != MACRO_EOA)
3071 ++arg;
3072 tokidx = 0;
3073 break;
3074 }
3075 ++arg;
3076 }
3077 }
3078 while (++macro - alpha_macros < (int) alpha_num_macros
3079 && !strcmp (macro->name, first_macro->name));
3080
3081 return NULL;
3082 }
3083
3084 /* Given an opcode name and a pre-tokenized set of arguments, take the
3085 opcode all the way through emission. */
3086
3087 static void
3088 assemble_tokens (const char *opname,
3089 const expressionS *tok,
3090 int ntok,
3091 int local_macros_on)
3092 {
3093 int found_something = 0;
3094 const struct alpha_opcode *opcode;
3095 const struct alpha_macro *macro;
3096 int cpumatch = 1;
3097 bfd_reloc_code_real_type reloc = BFD_RELOC_UNUSED;
3098
3099 #ifdef RELOC_OP_P
3100 /* If a user-specified relocation is present, this is not a macro. */
3101 if (ntok && USER_RELOC_P (tok[ntok - 1].X_op))
3102 {
3103 reloc = ALPHA_RELOC_TABLE (tok[ntok - 1].X_op)->reloc;
3104 ntok--;
3105 }
3106 else
3107 #endif
3108 if (local_macros_on)
3109 {
3110 macro = ((const struct alpha_macro *)
3111 hash_find (alpha_macro_hash, opname));
3112 if (macro)
3113 {
3114 found_something = 1;
3115 macro = find_macro_match (macro, tok, &ntok);
3116 if (macro)
3117 {
3118 (*macro->emit) (tok, ntok, macro->arg);
3119 return;
3120 }
3121 }
3122 }
3123
3124 /* Search opcodes. */
3125 opcode = (const struct alpha_opcode *) hash_find (alpha_opcode_hash, opname);
3126 if (opcode)
3127 {
3128 found_something = 1;
3129 opcode = find_opcode_match (opcode, tok, &ntok, &cpumatch);
3130 if (opcode)
3131 {
3132 struct alpha_insn insn;
3133 assemble_insn (opcode, tok, ntok, &insn, reloc);
3134
3135 /* Copy the sequence number for the reloc from the reloc token. */
3136 if (reloc != BFD_RELOC_UNUSED)
3137 insn.sequence = tok[ntok].X_add_number;
3138
3139 emit_insn (&insn);
3140 return;
3141 }
3142 }
3143
3144 if (found_something)
3145 {
3146 if (cpumatch)
3147 as_bad (_("inappropriate arguments for opcode `%s'"), opname);
3148 else
3149 as_bad (_("opcode `%s' not supported for target %s"), opname,
3150 alpha_target_name);
3151 }
3152 else
3153 as_bad (_("unknown opcode `%s'"), opname);
3154 }
3155
3156 #ifdef OBJ_EVAX
3158
3159 /* Add symbol+addend to link pool.
3160 Return offset from basesym to entry in link pool.
3161
3162 Add new fixup only if offset isn't 16bit. */
3163
3164 valueT
3165 add_to_link_pool (symbolS *basesym,
3166 symbolS *sym,
3167 offsetT addend)
3168 {
3169 segT current_section = now_seg;
3170 int current_subsec = now_subseg;
3171 valueT offset;
3172 bfd_reloc_code_real_type reloc_type;
3173 char *p;
3174 segment_info_type *seginfo = seg_info (alpha_link_section);
3175 fixS *fixp;
3176
3177 offset = - *symbol_get_obj (basesym);
3178
3179 /* @@ This assumes all entries in a given section will be of the same
3180 size... Probably correct, but unwise to rely on. */
3181 /* This must always be called with the same subsegment. */
3182
3183 if (seginfo->frchainP)
3184 for (fixp = seginfo->frchainP->fix_root;
3185 fixp != (fixS *) NULL;
3186 fixp = fixp->fx_next, offset += 8)
3187 {
3188 if (fixp->fx_addsy == sym && fixp->fx_offset == addend)
3189 {
3190 if (range_signed_16 (offset))
3191 {
3192 return offset;
3193 }
3194 }
3195 }
3196
3197 /* Not found in 16bit signed range. */
3198
3199 subseg_set (alpha_link_section, 0);
3200 p = frag_more (8);
3201 memset (p, 0, 8);
3202
3203 fix_new (frag_now, p - frag_now->fr_literal, 8, sym, addend, 0,
3204 BFD_RELOC_64);
3205
3206 subseg_set (current_section, current_subsec);
3207 seginfo->literal_pool_size += 8;
3208 return offset;
3209 }
3210
3211 #endif /* OBJ_EVAX */
3212
3213 /* Assembler directives. */
3215
3216 /* Handle the .text pseudo-op. This is like the usual one, but it
3217 clears alpha_insn_label and restores auto alignment. */
3218
3219 static void
3220 s_alpha_text (int i)
3221
3222 {
3223 #ifdef OBJ_ELF
3224 obj_elf_text (i);
3225 #else
3226 s_text (i);
3227 #endif
3228 alpha_insn_label = NULL;
3229 alpha_auto_align_on = 1;
3230 alpha_current_align = 0;
3231 }
3232
3233 /* Handle the .data pseudo-op. This is like the usual one, but it
3234 clears alpha_insn_label and restores auto alignment. */
3235
3236 static void
3237 s_alpha_data (int i)
3238 {
3239 #ifdef OBJ_ELF
3240 obj_elf_data (i);
3241 #else
3242 s_data (i);
3243 #endif
3244 alpha_insn_label = NULL;
3245 alpha_auto_align_on = 1;
3246 alpha_current_align = 0;
3247 }
3248
3249 #if defined (OBJ_ECOFF) || defined (OBJ_EVAX)
3250
3251 /* Handle the OSF/1 and openVMS .comm pseudo quirks.
3252 openVMS constructs a section for every common symbol. */
3253
3254 static void
3255 s_alpha_comm (int ignore ATTRIBUTE_UNUSED)
3256 {
3257 char *name;
3258 char c;
3259 char *p;
3260 offsetT temp;
3261 symbolS *symbolP;
3262 #ifdef OBJ_EVAX
3263 segT current_section = now_seg;
3264 int current_subsec = now_subseg;
3265 segT new_seg;
3266 #endif
3267
3268 name = input_line_pointer;
3269 c = get_symbol_end ();
3270
3271 /* Just after name is now '\0'. */
3272 p = input_line_pointer;
3273 *p = c;
3274
3275 SKIP_WHITESPACE ();
3276
3277 /* Alpha OSF/1 compiler doesn't provide the comma, gcc does. */
3278 if (*input_line_pointer == ',')
3279 {
3280 input_line_pointer++;
3281 SKIP_WHITESPACE ();
3282 }
3283 if ((temp = get_absolute_expression ()) < 0)
3284 {
3285 as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) temp);
3286 ignore_rest_of_line ();
3287 return;
3288 }
3289
3290 *p = 0;
3291 symbolP = symbol_find_or_make (name);
3292
3293 #ifdef OBJ_EVAX
3294 /* Make a section for the common symbol. */
3295 new_seg = subseg_new (xstrdup (name), 0);
3296 #endif
3297
3298 *p = c;
3299
3300 #ifdef OBJ_EVAX
3301 /* Alignment might follow. */
3302 if (*input_line_pointer == ',')
3303 {
3304 offsetT align;
3305
3306 input_line_pointer++;
3307 align = get_absolute_expression ();
3308 bfd_set_section_alignment (stdoutput, new_seg, align);
3309 }
3310 #endif
3311
3312 if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
3313 {
3314 as_bad (_("Ignoring attempt to re-define symbol"));
3315 ignore_rest_of_line ();
3316 return;
3317 }
3318
3319 #ifdef OBJ_EVAX
3320 if (bfd_section_size (stdoutput, new_seg) > 0)
3321 {
3322 if (bfd_section_size (stdoutput, new_seg) != temp)
3323 as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
3324 S_GET_NAME (symbolP),
3325 (long) bfd_section_size (stdoutput, new_seg),
3326 (long) temp);
3327 }
3328 #else
3329 if (S_GET_VALUE (symbolP))
3330 {
3331 if (S_GET_VALUE (symbolP) != (valueT) temp)
3332 as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
3333 S_GET_NAME (symbolP),
3334 (long) S_GET_VALUE (symbolP),
3335 (long) temp);
3336 }
3337 #endif
3338 else
3339 {
3340 #ifdef OBJ_EVAX
3341 subseg_set (new_seg, 0);
3342 p = frag_more (temp);
3343 new_seg->flags |= SEC_IS_COMMON;
3344 S_SET_SEGMENT (symbolP, new_seg);
3345 #else
3346 S_SET_VALUE (symbolP, (valueT) temp);
3347 S_SET_SEGMENT (symbolP, bfd_com_section_ptr);
3348 #endif
3349 S_SET_EXTERNAL (symbolP);
3350 }
3351
3352 #ifdef OBJ_EVAX
3353 subseg_set (current_section, current_subsec);
3354 #endif
3355
3356 know (symbol_get_frag (symbolP) == &zero_address_frag);
3357
3358 demand_empty_rest_of_line ();
3359 }
3360
3361 #endif /* ! OBJ_ELF */
3362
3363 #ifdef OBJ_ECOFF
3364
3365 /* Handle the .rdata pseudo-op. This is like the usual one, but it
3366 clears alpha_insn_label and restores auto alignment. */
3367
3368 static void
3369 s_alpha_rdata (int ignore ATTRIBUTE_UNUSED)
3370 {
3371 int temp;
3372
3373 temp = get_absolute_expression ();
3374 subseg_new (".rdata", 0);
3375 demand_empty_rest_of_line ();
3376 alpha_insn_label = NULL;
3377 alpha_auto_align_on = 1;
3378 alpha_current_align = 0;
3379 }
3380
3381 #endif
3382
3383 #ifdef OBJ_ECOFF
3384
3385 /* Handle the .sdata pseudo-op. This is like the usual one, but it
3386 clears alpha_insn_label and restores auto alignment. */
3387
3388 static void
3389 s_alpha_sdata (int ignore ATTRIBUTE_UNUSED)
3390 {
3391 int temp;
3392
3393 temp = get_absolute_expression ();
3394 subseg_new (".sdata", 0);
3395 demand_empty_rest_of_line ();
3396 alpha_insn_label = NULL;
3397 alpha_auto_align_on = 1;
3398 alpha_current_align = 0;
3399 }
3400 #endif
3401
3402 #ifdef OBJ_ELF
3403 struct alpha_elf_frame_data
3404 {
3405 symbolS *func_sym;
3406 symbolS *func_end_sym;
3407 symbolS *prologue_sym;
3408 unsigned int mask;
3409 unsigned int fmask;
3410 int fp_regno;
3411 int ra_regno;
3412 offsetT frame_size;
3413 offsetT mask_offset;
3414 offsetT fmask_offset;
3415
3416 struct alpha_elf_frame_data *next;
3417 };
3418
3419 static struct alpha_elf_frame_data *all_frame_data;
3420 static struct alpha_elf_frame_data **plast_frame_data = &all_frame_data;
3421 static struct alpha_elf_frame_data *cur_frame_data;
3422
3423 /* Handle the .section pseudo-op. This is like the usual one, but it
3424 clears alpha_insn_label and restores auto alignment. */
3425
3426 static void
3427 s_alpha_section (int ignore ATTRIBUTE_UNUSED)
3428 {
3429 obj_elf_section (ignore);
3430
3431 alpha_insn_label = NULL;
3432 alpha_auto_align_on = 1;
3433 alpha_current_align = 0;
3434 }
3435
3436 static void
3437 s_alpha_ent (int dummy ATTRIBUTE_UNUSED)
3438 {
3439 if (ECOFF_DEBUGGING)
3440 ecoff_directive_ent (0);
3441 else
3442 {
3443 char *name, name_end;
3444 name = input_line_pointer;
3445 name_end = get_symbol_end ();
3446
3447 if (! is_name_beginner (*name))
3448 {
3449 as_warn (_(".ent directive has no name"));
3450 *input_line_pointer = name_end;
3451 }
3452 else
3453 {
3454 symbolS *sym;
3455
3456 if (cur_frame_data)
3457 as_warn (_("nested .ent directives"));
3458
3459 sym = symbol_find_or_make (name);
3460 symbol_get_bfdsym (sym)->flags |= BSF_FUNCTION;
3461
3462 cur_frame_data = calloc (1, sizeof (*cur_frame_data));
3463 cur_frame_data->func_sym = sym;
3464
3465 /* Provide sensible defaults. */
3466 cur_frame_data->fp_regno = 30; /* sp */
3467 cur_frame_data->ra_regno = 26; /* ra */
3468
3469 *plast_frame_data = cur_frame_data;
3470 plast_frame_data = &cur_frame_data->next;
3471
3472 /* The .ent directive is sometimes followed by a number. Not sure
3473 what it really means, but ignore it. */
3474 *input_line_pointer = name_end;
3475 SKIP_WHITESPACE ();
3476 if (*input_line_pointer == ',')
3477 {
3478 input_line_pointer++;
3479 SKIP_WHITESPACE ();
3480 }
3481 if (ISDIGIT (*input_line_pointer) || *input_line_pointer == '-')
3482 (void) get_absolute_expression ();
3483 }
3484 demand_empty_rest_of_line ();
3485 }
3486 }
3487
3488 static void
3489 s_alpha_end (int dummy ATTRIBUTE_UNUSED)
3490 {
3491 if (ECOFF_DEBUGGING)
3492 ecoff_directive_end (0);
3493 else
3494 {
3495 char *name, name_end;
3496 name = input_line_pointer;
3497 name_end = get_symbol_end ();
3498
3499 if (! is_name_beginner (*name))
3500 {
3501 as_warn (_(".end directive has no name"));
3502 *input_line_pointer = name_end;
3503 }
3504 else
3505 {
3506 symbolS *sym;
3507
3508 sym = symbol_find (name);
3509 if (!cur_frame_data)
3510 as_warn (_(".end directive without matching .ent"));
3511 else if (sym != cur_frame_data->func_sym)
3512 as_warn (_(".end directive names different symbol than .ent"));
3513
3514 /* Create an expression to calculate the size of the function. */
3515 if (sym && cur_frame_data)
3516 {
3517 OBJ_SYMFIELD_TYPE *obj = symbol_get_obj (sym);
3518 expressionS *exp = xmalloc (sizeof (expressionS));
3519
3520 obj->size = exp;
3521 exp->X_op = O_subtract;
3522 exp->X_add_symbol = symbol_temp_new_now ();
3523 exp->X_op_symbol = sym;
3524 exp->X_add_number = 0;
3525
3526 cur_frame_data->func_end_sym = exp->X_add_symbol;
3527 }
3528
3529 cur_frame_data = NULL;
3530
3531 *input_line_pointer = name_end;
3532 }
3533 demand_empty_rest_of_line ();
3534 }
3535 }
3536
3537 static void
3538 s_alpha_mask (int fp)
3539 {
3540 if (ECOFF_DEBUGGING)
3541 {
3542 if (fp)
3543 ecoff_directive_fmask (0);
3544 else
3545 ecoff_directive_mask (0);
3546 }
3547 else
3548 {
3549 long val;
3550 offsetT offset;
3551
3552 if (!cur_frame_data)
3553 {
3554 if (fp)
3555 as_warn (_(".fmask outside of .ent"));
3556 else
3557 as_warn (_(".mask outside of .ent"));
3558 discard_rest_of_line ();
3559 return;
3560 }
3561
3562 if (get_absolute_expression_and_terminator (&val) != ',')
3563 {
3564 if (fp)
3565 as_warn (_("bad .fmask directive"));
3566 else
3567 as_warn (_("bad .mask directive"));
3568 --input_line_pointer;
3569 discard_rest_of_line ();
3570 return;
3571 }
3572
3573 offset = get_absolute_expression ();
3574 demand_empty_rest_of_line ();
3575
3576 if (fp)
3577 {
3578 cur_frame_data->fmask = val;
3579 cur_frame_data->fmask_offset = offset;
3580 }
3581 else
3582 {
3583 cur_frame_data->mask = val;
3584 cur_frame_data->mask_offset = offset;
3585 }
3586 }
3587 }
3588
3589 static void
3590 s_alpha_frame (int dummy ATTRIBUTE_UNUSED)
3591 {
3592 if (ECOFF_DEBUGGING)
3593 ecoff_directive_frame (0);
3594 else
3595 {
3596 long val;
3597
3598 if (!cur_frame_data)
3599 {
3600 as_warn (_(".frame outside of .ent"));
3601 discard_rest_of_line ();
3602 return;
3603 }
3604
3605 cur_frame_data->fp_regno = tc_get_register (1);
3606
3607 SKIP_WHITESPACE ();
3608 if (*input_line_pointer++ != ','
3609 || get_absolute_expression_and_terminator (&val) != ',')
3610 {
3611 as_warn (_("bad .frame directive"));
3612 --input_line_pointer;
3613 discard_rest_of_line ();
3614 return;
3615 }
3616 cur_frame_data->frame_size = val;
3617
3618 cur_frame_data->ra_regno = tc_get_register (0);
3619
3620 /* Next comes the "offset of saved $a0 from $sp". In gcc terms
3621 this is current_function_pretend_args_size. There's no place
3622 to put this value, so ignore it. */
3623 s_ignore (42);
3624 }
3625 }
3626
3627 static void
3628 s_alpha_prologue (int ignore ATTRIBUTE_UNUSED)
3629 {
3630 symbolS *sym;
3631 int arg;
3632
3633 arg = get_absolute_expression ();
3634 demand_empty_rest_of_line ();
3635
3636 if (ECOFF_DEBUGGING)
3637 sym = ecoff_get_cur_proc_sym ();
3638 else
3639 sym = cur_frame_data ? cur_frame_data->func_sym : NULL;
3640
3641 if (sym == NULL)
3642 {
3643 as_bad (_(".prologue directive without a preceding .ent directive"));
3644 return;
3645 }
3646
3647 switch (arg)
3648 {
3649 case 0: /* No PV required. */
3650 S_SET_OTHER (sym, STO_ALPHA_NOPV
3651 | (S_GET_OTHER (sym) & ~STO_ALPHA_STD_GPLOAD));
3652 break;
3653 case 1: /* Std GP load. */
3654 S_SET_OTHER (sym, STO_ALPHA_STD_GPLOAD
3655 | (S_GET_OTHER (sym) & ~STO_ALPHA_STD_GPLOAD));
3656 break;
3657 case 2: /* Non-std use of PV. */
3658 break;
3659
3660 default:
3661 as_bad (_("Invalid argument %d to .prologue."), arg);
3662 break;
3663 }
3664
3665 if (cur_frame_data)
3666 cur_frame_data->prologue_sym = symbol_temp_new_now ();
3667 }
3668
3669 static char *first_file_directive;
3670
3671 static void
3672 s_alpha_file (int ignore ATTRIBUTE_UNUSED)
3673 {
3674 /* Save the first .file directive we see, so that we can change our
3675 minds about whether ecoff debugging should or shouldn't be enabled. */
3676 if (alpha_flag_mdebug < 0 && ! first_file_directive)
3677 {
3678 char *start = input_line_pointer;
3679 size_t len;
3680
3681 discard_rest_of_line ();
3682
3683 len = input_line_pointer - start;
3684 first_file_directive = xmalloc (len + 1);
3685 memcpy (first_file_directive, start, len);
3686 first_file_directive[len] = '\0';
3687
3688 input_line_pointer = start;
3689 }
3690
3691 if (ECOFF_DEBUGGING)
3692 ecoff_directive_file (0);
3693 else
3694 dwarf2_directive_file (0);
3695 }
3696
3697 static void
3698 s_alpha_loc (int ignore ATTRIBUTE_UNUSED)
3699 {
3700 if (ECOFF_DEBUGGING)
3701 ecoff_directive_loc (0);
3702 else
3703 dwarf2_directive_loc (0);
3704 }
3705
3706 static void
3707 s_alpha_stab (int n)
3708 {
3709 /* If we've been undecided about mdebug, make up our minds in favour. */
3710 if (alpha_flag_mdebug < 0)
3711 {
3712 segT sec = subseg_new (".mdebug", 0);
3713 bfd_set_section_flags (stdoutput, sec, SEC_HAS_CONTENTS | SEC_READONLY);
3714 bfd_set_section_alignment (stdoutput, sec, 3);
3715
3716 ecoff_read_begin_hook ();
3717
3718 if (first_file_directive)
3719 {
3720 char *save_ilp = input_line_pointer;
3721 input_line_pointer = first_file_directive;
3722 ecoff_directive_file (0);
3723 input_line_pointer = save_ilp;
3724 free (first_file_directive);
3725 }
3726
3727 alpha_flag_mdebug = 1;
3728 }
3729 s_stab (n);
3730 }
3731
3732 static void
3733 s_alpha_coff_wrapper (int which)
3734 {
3735 static void (* const fns[]) (int) = {
3736 ecoff_directive_begin,
3737 ecoff_directive_bend,
3738 ecoff_directive_def,
3739 ecoff_directive_dim,
3740 ecoff_directive_endef,
3741 ecoff_directive_scl,
3742 ecoff_directive_tag,
3743 ecoff_directive_val,
3744 };
3745
3746 assert (which >= 0 && which < (int) (sizeof (fns)/sizeof (*fns)));
3747
3748 if (ECOFF_DEBUGGING)
3749 (*fns[which]) (0);
3750 else
3751 {
3752 as_bad (_("ECOFF debugging is disabled."));
3753 ignore_rest_of_line ();
3754 }
3755 }
3756
3757 /* Called at the end of assembly. Here we emit unwind info for frames
3758 unless the compiler has done it for us. */
3759
3760 void
3761 alpha_elf_md_end (void)
3762 {
3763 struct alpha_elf_frame_data *p;
3764
3765 if (cur_frame_data)
3766 as_warn (_(".ent directive without matching .end"));
3767
3768 /* If someone has generated the unwind info themselves, great. */
3769 if (bfd_get_section_by_name (stdoutput, ".eh_frame") != NULL)
3770 return;
3771
3772 /* Generate .eh_frame data for the unwind directives specified. */
3773 for (p = all_frame_data; p ; p = p->next)
3774 if (p->prologue_sym)
3775 {
3776 /* Create a temporary symbol at the same location as our
3777 function symbol. This prevents problems with globals. */
3778 cfi_new_fde (symbol_temp_new (S_GET_SEGMENT (p->func_sym),
3779 S_GET_VALUE (p->func_sym),
3780 symbol_get_frag (p->func_sym)));
3781
3782 cfi_set_return_column (p->ra_regno);
3783 cfi_add_CFA_def_cfa_register (30);
3784 if (p->fp_regno != 30 || p->mask || p->fmask || p->frame_size)
3785 {
3786 unsigned int mask;
3787 offsetT offset;
3788
3789 cfi_add_advance_loc (p->prologue_sym);
3790
3791 if (p->fp_regno != 30)
3792 if (p->frame_size != 0)
3793 cfi_add_CFA_def_cfa (p->fp_regno, p->frame_size);
3794 else
3795 cfi_add_CFA_def_cfa_register (p->fp_regno);
3796 else if (p->frame_size != 0)
3797 cfi_add_CFA_def_cfa_offset (p->frame_size);
3798
3799 mask = p->mask;
3800 offset = p->mask_offset;
3801
3802 /* Recall that $26 is special-cased and stored first. */
3803 if ((mask >> 26) & 1)
3804 {
3805 cfi_add_CFA_offset (26, offset);
3806 offset += 8;
3807 mask &= ~(1 << 26);
3808 }
3809 while (mask)
3810 {
3811 unsigned int i;
3812 i = mask & -mask;
3813 mask ^= i;
3814 i = ffs (i) - 1;
3815
3816 cfi_add_CFA_offset (i, offset);
3817 offset += 8;
3818 }
3819
3820 mask = p->fmask;
3821 offset = p->fmask_offset;
3822 while (mask)
3823 {
3824 unsigned int i;
3825 i = mask & -mask;
3826 mask ^= i;
3827 i = ffs (i) - 1;
3828
3829 cfi_add_CFA_offset (i + 32, offset);
3830 offset += 8;
3831 }
3832 }
3833
3834 cfi_end_fde (p->func_end_sym);
3835 }
3836 }
3837
3838 static void
3839 s_alpha_usepv (int unused ATTRIBUTE_UNUSED)
3840 {
3841 char *name, name_end;
3842 char *which, which_end;
3843 symbolS *sym;
3844 int other;
3845
3846 name = input_line_pointer;
3847 name_end = get_symbol_end ();
3848
3849 if (! is_name_beginner (*name))
3850 {
3851 as_bad (_(".usepv directive has no name"));
3852 *input_line_pointer = name_end;
3853 ignore_rest_of_line ();
3854 return;
3855 }
3856
3857 sym = symbol_find_or_make (name);
3858 *input_line_pointer++ = name_end;
3859
3860 if (name_end != ',')
3861 {
3862 as_bad (_(".usepv directive has no type"));
3863 ignore_rest_of_line ();
3864 return;
3865 }
3866
3867 SKIP_WHITESPACE ();
3868 which = input_line_pointer;
3869 which_end = get_symbol_end ();
3870
3871 if (strcmp (which, "no") == 0)
3872 other = STO_ALPHA_NOPV;
3873 else if (strcmp (which, "std") == 0)
3874 other = STO_ALPHA_STD_GPLOAD;
3875 else
3876 {
3877 as_bad (_("unknown argument for .usepv"));
3878 other = 0;
3879 }
3880
3881 *input_line_pointer = which_end;
3882 demand_empty_rest_of_line ();
3883
3884 S_SET_OTHER (sym, other | (S_GET_OTHER (sym) & ~STO_ALPHA_STD_GPLOAD));
3885 }
3886 #endif /* OBJ_ELF */
3887
3888 /* Standard calling conventions leaves the CFA at $30 on entry. */
3889
3890 void
3891 alpha_cfi_frame_initial_instructions (void)
3892 {
3893 cfi_add_CFA_def_cfa_register (30);
3894 }
3895
3896 #ifdef OBJ_EVAX
3897
3898 /* Handle the section specific pseudo-op. */
3899
3900 static void
3901 s_alpha_section (int secid)
3902 {
3903 int temp;
3904 #define EVAX_SECTION_COUNT 5
3905 static char *section_name[EVAX_SECTION_COUNT + 1] =
3906 { "NULL", ".rdata", ".comm", ".link", ".ctors", ".dtors" };
3907
3908 if ((secid <= 0) || (secid > EVAX_SECTION_COUNT))
3909 {
3910 as_fatal (_("Unknown section directive"));
3911 demand_empty_rest_of_line ();
3912 return;
3913 }
3914 temp = get_absolute_expression ();
3915 subseg_new (section_name[secid], 0);
3916 demand_empty_rest_of_line ();
3917 alpha_insn_label = NULL;
3918 alpha_auto_align_on = 1;
3919 alpha_current_align = 0;
3920 }
3921
3922 /* Parse .ent directives. */
3923
3924 static void
3925 s_alpha_ent (int ignore ATTRIBUTE_UNUSED)
3926 {
3927 symbolS *symbol;
3928 expressionS symexpr;
3929
3930 alpha_evax_proc.pdsckind = 0;
3931 alpha_evax_proc.framereg = -1;
3932 alpha_evax_proc.framesize = 0;
3933 alpha_evax_proc.rsa_offset = 0;
3934 alpha_evax_proc.ra_save = AXP_REG_RA;
3935 alpha_evax_proc.fp_save = -1;
3936 alpha_evax_proc.imask = 0;
3937 alpha_evax_proc.fmask = 0;
3938 alpha_evax_proc.prologue = 0;
3939 alpha_evax_proc.type = 0;
3940
3941 expression (&symexpr);
3942
3943 if (symexpr.X_op != O_symbol)
3944 {
3945 as_fatal (_(".ent directive has no symbol"));
3946 demand_empty_rest_of_line ();
3947 return;
3948 }
3949
3950 symbol = make_expr_symbol (&symexpr);
3951 symbol_get_bfdsym (symbol)->flags |= BSF_FUNCTION;
3952 alpha_evax_proc.symbol = symbol;
3953
3954 demand_empty_rest_of_line ();
3955 }
3956
3957 /* Parse .frame <framreg>,<framesize>,RA,<rsa_offset> directives. */
3958
3959 static void
3960 s_alpha_frame (int ignore ATTRIBUTE_UNUSED)
3961 {
3962 long val;
3963
3964 alpha_evax_proc.framereg = tc_get_register (1);
3965
3966 SKIP_WHITESPACE ();
3967 if (*input_line_pointer++ != ','
3968 || get_absolute_expression_and_terminator (&val) != ',')
3969 {
3970 as_warn (_("Bad .frame directive 1./2. param"));
3971 --input_line_pointer;
3972 demand_empty_rest_of_line ();
3973 return;
3974 }
3975
3976 alpha_evax_proc.framesize = val;
3977
3978 (void) tc_get_register (1);
3979 SKIP_WHITESPACE ();
3980 if (*input_line_pointer++ != ',')
3981 {
3982 as_warn (_("Bad .frame directive 3./4. param"));
3983 --input_line_pointer;
3984 demand_empty_rest_of_line ();
3985 return;
3986 }
3987 alpha_evax_proc.rsa_offset = get_absolute_expression ();
3988 }
3989
3990 static void
3991 s_alpha_pdesc (int ignore ATTRIBUTE_UNUSED)
3992 {
3993 char *name;
3994 char name_end;
3995 long val;
3996 register char *p;
3997 expressionS exp;
3998 symbolS *entry_sym;
3999 fixS *fixp;
4000 segment_info_type *seginfo = seg_info (alpha_link_section);
4001
4002 if (now_seg != alpha_link_section)
4003 {
4004 as_bad (_(".pdesc directive not in link (.link) section"));
4005 demand_empty_rest_of_line ();
4006 return;
4007 }
4008
4009 if ((alpha_evax_proc.symbol == 0)
4010 || (!S_IS_DEFINED (alpha_evax_proc.symbol)))
4011 {
4012 as_fatal (_(".pdesc has no matching .ent"));
4013 demand_empty_rest_of_line ();
4014 return;
4015 }
4016
4017 *symbol_get_obj (alpha_evax_proc.symbol) =
4018 (valueT) seginfo->literal_pool_size;
4019
4020 expression (&exp);
4021 if (exp.X_op != O_symbol)
4022 {
4023 as_warn (_(".pdesc directive has no entry symbol"));
4024 demand_empty_rest_of_line ();
4025 return;
4026 }
4027
4028 entry_sym = make_expr_symbol (&exp);
4029 /* Save bfd symbol of proc desc in function symbol. */
4030 symbol_get_bfdsym (alpha_evax_proc.symbol)->udata.p
4031 = symbol_get_bfdsym (entry_sym);
4032
4033 SKIP_WHITESPACE ();
4034 if (*input_line_pointer++ != ',')
4035 {
4036 as_warn (_("No comma after .pdesc <entryname>"));
4037 demand_empty_rest_of_line ();
4038 return;
4039 }
4040
4041 SKIP_WHITESPACE ();
4042 name = input_line_pointer;
4043 name_end = get_symbol_end ();
4044
4045 if (strncmp (name, "stack", 5) == 0)
4046 alpha_evax_proc.pdsckind = PDSC_S_K_KIND_FP_STACK;
4047
4048 else if (strncmp (name, "reg", 3) == 0)
4049 alpha_evax_proc.pdsckind = PDSC_S_K_KIND_FP_REGISTER;
4050
4051 else if (strncmp (name, "null", 4) == 0)
4052 alpha_evax_proc.pdsckind = PDSC_S_K_KIND_NULL;
4053
4054 else
4055 {
4056 as_fatal (_("unknown procedure kind"));
4057 demand_empty_rest_of_line ();
4058 return;
4059 }
4060
4061 *input_line_pointer = name_end;
4062 demand_empty_rest_of_line ();
4063
4064 #ifdef md_flush_pending_output
4065 md_flush_pending_output ();
4066 #endif
4067
4068 frag_align (3, 0, 0);
4069 p = frag_more (16);
4070 fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
4071 fixp->fx_done = 1;
4072 seginfo->literal_pool_size += 16;
4073
4074 *p = alpha_evax_proc.pdsckind
4075 | ((alpha_evax_proc.framereg == 29) ? PDSC_S_M_BASE_REG_IS_FP : 0);
4076 *(p + 1) = PDSC_S_M_NATIVE | PDSC_S_M_NO_JACKET;
4077
4078 switch (alpha_evax_proc.pdsckind)
4079 {
4080 case PDSC_S_K_KIND_NULL:
4081 *(p + 2) = 0;
4082 *(p + 3) = 0;
4083 break;
4084 case PDSC_S_K_KIND_FP_REGISTER:
4085 *(p + 2) = alpha_evax_proc.fp_save;
4086 *(p + 3) = alpha_evax_proc.ra_save;
4087 break;
4088 case PDSC_S_K_KIND_FP_STACK:
4089 md_number_to_chars (p + 2, (valueT) alpha_evax_proc.rsa_offset, 2);
4090 break;
4091 default: /* impossible */
4092 break;
4093 }
4094
4095 *(p + 4) = 0;
4096 *(p + 5) = alpha_evax_proc.type & 0x0f;
4097
4098 /* Signature offset. */
4099 md_number_to_chars (p + 6, (valueT) 0, 2);
4100
4101 fix_new_exp (frag_now, p - frag_now->fr_literal+8, 8, &exp, 0, BFD_RELOC_64);
4102
4103 if (alpha_evax_proc.pdsckind == PDSC_S_K_KIND_NULL)
4104 return;
4105
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;
4111
4112 /* pdesc+16: Size. */
4113 md_number_to_chars (p, (valueT) alpha_evax_proc.framesize, 4);
4114
4115 md_number_to_chars (p + 4, (valueT) 0, 2);
4116
4117 /* Entry length. */
4118 md_number_to_chars (p + 6, alpha_evax_proc.prologue, 2);
4119
4120 if (alpha_evax_proc.pdsckind == PDSC_S_K_KIND_FP_REGISTER)
4121 return;
4122
4123 /* Add dummy fix to make add_to_link_pool work. */
4124 p = frag_more (8);
4125 fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
4126 fixp->fx_done = 1;
4127 seginfo->literal_pool_size += 8;
4128
4129 /* pdesc+24: register masks. */
4130
4131 md_number_to_chars (p, alpha_evax_proc.imask, 4);
4132 md_number_to_chars (p + 4, alpha_evax_proc.fmask, 4);
4133 }
4134
4135 /* Support for crash debug on vms. */
4136
4137 static void
4138 s_alpha_name (int ignore ATTRIBUTE_UNUSED)
4139 {
4140 char *p;
4141 expressionS exp;
4142 segment_info_type *seginfo = seg_info (alpha_link_section);
4143
4144 if (now_seg != alpha_link_section)
4145 {
4146 as_bad (_(".name directive not in link (.link) section"));
4147 demand_empty_rest_of_line ();
4148 return;
4149 }
4150
4151 expression (&exp);
4152 if (exp.X_op != O_symbol)
4153 {
4154 as_warn (_(".name directive has no symbol"));
4155 demand_empty_rest_of_line ();
4156 return;
4157 }
4158
4159 demand_empty_rest_of_line ();
4160
4161 #ifdef md_flush_pending_output
4162 md_flush_pending_output ();
4163 #endif
4164
4165 frag_align (3, 0, 0);
4166 p = frag_more (8);
4167 seginfo->literal_pool_size += 8;
4168
4169 fix_new_exp (frag_now, p - frag_now->fr_literal, 8, &exp, 0, BFD_RELOC_64);
4170 }
4171
4172 static void
4173 s_alpha_linkage (int ignore ATTRIBUTE_UNUSED)
4174 {
4175 expressionS exp;
4176 char *p;
4177
4178 #ifdef md_flush_pending_output
4179 md_flush_pending_output ();
4180 #endif
4181
4182 expression (&exp);
4183 if (exp.X_op != O_symbol)
4184 {
4185 as_fatal (_("No symbol after .linkage"));
4186 }
4187 else
4188 {
4189 p = frag_more (LKP_S_K_SIZE);
4190 memset (p, 0, LKP_S_K_SIZE);
4191 fix_new_exp (frag_now, p - frag_now->fr_literal, LKP_S_K_SIZE, &exp, 0,\
4192 BFD_RELOC_ALPHA_LINKAGE);
4193 }
4194 demand_empty_rest_of_line ();
4195 }
4196
4197 static void
4198 s_alpha_code_address (int ignore ATTRIBUTE_UNUSED)
4199 {
4200 expressionS exp;
4201 char *p;
4202
4203 #ifdef md_flush_pending_output
4204 md_flush_pending_output ();
4205 #endif
4206
4207 expression (&exp);
4208 if (exp.X_op != O_symbol)
4209 as_fatal (_("No symbol after .code_address"));
4210 else
4211 {
4212 p = frag_more (8);
4213 memset (p, 0, 8);
4214 fix_new_exp (frag_now, p - frag_now->fr_literal, 8, &exp, 0,\
4215 BFD_RELOC_ALPHA_CODEADDR);
4216 }
4217 demand_empty_rest_of_line ();
4218 }
4219
4220 static void
4221 s_alpha_fp_save (int ignore ATTRIBUTE_UNUSED)
4222 {
4223
4224 alpha_evax_proc.fp_save = tc_get_register (1);
4225
4226 demand_empty_rest_of_line ();
4227 }
4228
4229 static void
4230 s_alpha_mask (int ignore ATTRIBUTE_UNUSED)
4231 {
4232 long val;
4233
4234 if (get_absolute_expression_and_terminator (&val) != ',')
4235 {
4236 as_warn (_("Bad .mask directive"));
4237 --input_line_pointer;
4238 }
4239 else
4240 {
4241 alpha_evax_proc.imask = val;
4242 (void) get_absolute_expression ();
4243 }
4244 demand_empty_rest_of_line ();
4245 }
4246
4247 static void
4248 s_alpha_fmask (int ignore ATTRIBUTE_UNUSED)
4249 {
4250 long val;
4251
4252 if (get_absolute_expression_and_terminator (&val) != ',')
4253 {
4254 as_warn (_("Bad .fmask directive"));
4255 --input_line_pointer;
4256 }
4257 else
4258 {
4259 alpha_evax_proc.fmask = val;
4260 (void) get_absolute_expression ();
4261 }
4262 demand_empty_rest_of_line ();
4263 }
4264
4265 static void
4266 s_alpha_end (int ignore ATTRIBUTE_UNUSED)
4267 {
4268 char c;
4269
4270 c = get_symbol_end ();
4271 *input_line_pointer = c;
4272 demand_empty_rest_of_line ();
4273 alpha_evax_proc.symbol = 0;
4274 }
4275
4276 static void
4277 s_alpha_file (int ignore ATTRIBUTE_UNUSED)
4278 {
4279 symbolS *s;
4280 int length;
4281 static char case_hack[32];
4282
4283 sprintf (case_hack, "<CASE:%01d%01d>",
4284 alpha_flag_hash_long_names, alpha_flag_show_after_trunc);
4285
4286 s = symbol_find_or_make (case_hack);
4287 symbol_get_bfdsym (s)->flags |= BSF_FILE;
4288
4289 get_absolute_expression ();
4290 s = symbol_find_or_make (demand_copy_string (&length));
4291 symbol_get_bfdsym (s)->flags |= BSF_FILE;
4292 demand_empty_rest_of_line ();
4293 }
4294 #endif /* OBJ_EVAX */
4295
4296 /* Handle the .gprel32 pseudo op. */
4297
4298 static void
4299 s_alpha_gprel32 (int ignore ATTRIBUTE_UNUSED)
4300 {
4301 expressionS e;
4302 char *p;
4303
4304 SKIP_WHITESPACE ();
4305 expression (&e);
4306
4307 #ifdef OBJ_ELF
4308 switch (e.X_op)
4309 {
4310 case O_constant:
4311 e.X_add_symbol = section_symbol (absolute_section);
4312 e.X_op = O_symbol;
4313 /* FALLTHRU */
4314 case O_symbol:
4315 break;
4316 default:
4317 abort ();
4318 }
4319 #else
4320 #ifdef OBJ_ECOFF
4321 switch (e.X_op)
4322 {
4323 case O_constant:
4324 e.X_add_symbol = section_symbol (absolute_section);
4325 /* fall through */
4326 case O_symbol:
4327 e.X_op = O_subtract;
4328 e.X_op_symbol = alpha_gp_symbol;
4329 break;
4330 default:
4331 abort ();
4332 }
4333 #endif
4334 #endif
4335
4336 if (alpha_auto_align_on && alpha_current_align < 2)
4337 alpha_align (2, (char *) NULL, alpha_insn_label, 0);
4338 if (alpha_current_align > 2)
4339 alpha_current_align = 2;
4340 alpha_insn_label = NULL;
4341
4342 p = frag_more (4);
4343 memset (p, 0, 4);
4344 fix_new_exp (frag_now, p - frag_now->fr_literal, 4,
4345 &e, 0, BFD_RELOC_GPREL32);
4346 }
4347
4348 /* Handle floating point allocation pseudo-ops. This is like the
4349 generic vresion, but it makes sure the current label, if any, is
4350 correctly aligned. */
4351
4352 static void
4353 s_alpha_float_cons (int type)
4354 {
4355 int log_size;
4356
4357 switch (type)
4358 {
4359 default:
4360 case 'f':
4361 case 'F':
4362 log_size = 2;
4363 break;
4364
4365 case 'd':
4366 case 'D':
4367 case 'G':
4368 log_size = 3;
4369 break;
4370
4371 case 'x':
4372 case 'X':
4373 case 'p':
4374 case 'P':
4375 log_size = 4;
4376 break;
4377 }
4378
4379 if (alpha_auto_align_on && alpha_current_align < log_size)
4380 alpha_align (log_size, (char *) NULL, alpha_insn_label, 0);
4381 if (alpha_current_align > log_size)
4382 alpha_current_align = log_size;
4383 alpha_insn_label = NULL;
4384
4385 float_cons (type);
4386 }
4387
4388 /* Handle the .proc pseudo op. We don't really do much with it except
4389 parse it. */
4390
4391 static void
4392 s_alpha_proc (int is_static ATTRIBUTE_UNUSED)
4393 {
4394 char *name;
4395 char c;
4396 char *p;
4397 symbolS *symbolP;
4398 int temp;
4399
4400 /* Takes ".proc name,nargs". */
4401 SKIP_WHITESPACE ();
4402 name = input_line_pointer;
4403 c = get_symbol_end ();
4404 p = input_line_pointer;
4405 symbolP = symbol_find_or_make (name);
4406 *p = c;
4407 SKIP_WHITESPACE ();
4408 if (*input_line_pointer != ',')
4409 {
4410 *p = 0;
4411 as_warn (_("Expected comma after name \"%s\""), name);
4412 *p = c;
4413 temp = 0;
4414 ignore_rest_of_line ();
4415 }
4416 else
4417 {
4418 input_line_pointer++;
4419 temp = get_absolute_expression ();
4420 }
4421 /* *symbol_get_obj (symbolP) = (signed char) temp; */
4422 as_warn (_("unhandled: .proc %s,%d"), name, temp);
4423 demand_empty_rest_of_line ();
4424 }
4425
4426 /* Handle the .set pseudo op. This is used to turn on and off most of
4427 the assembler features. */
4428
4429 static void
4430 s_alpha_set (int x ATTRIBUTE_UNUSED)
4431 {
4432 char *name, ch, *s;
4433 int yesno = 1;
4434
4435 SKIP_WHITESPACE ();
4436 name = input_line_pointer;
4437 ch = get_symbol_end ();
4438
4439 s = name;
4440 if (s[0] == 'n' && s[1] == 'o')
4441 {
4442 yesno = 0;
4443 s += 2;
4444 }
4445 if (!strcmp ("reorder", s))
4446 /* ignore */ ;
4447 else if (!strcmp ("at", s))
4448 alpha_noat_on = !yesno;
4449 else if (!strcmp ("macro", s))
4450 alpha_macros_on = yesno;
4451 else if (!strcmp ("move", s))
4452 /* ignore */ ;
4453 else if (!strcmp ("volatile", s))
4454 /* ignore */ ;
4455 else
4456 as_warn (_("Tried to .set unrecognized mode `%s'"), name);
4457
4458 *input_line_pointer = ch;
4459 demand_empty_rest_of_line ();
4460 }
4461
4462 /* Handle the .base pseudo op. This changes the assembler's notion of
4463 the $gp register. */
4464
4465 static void
4466 s_alpha_base (int ignore ATTRIBUTE_UNUSED)
4467 {
4468 SKIP_WHITESPACE ();
4469
4470 if (*input_line_pointer == '$')
4471 {
4472 /* $rNN form. */
4473 input_line_pointer++;
4474 if (*input_line_pointer == 'r')
4475 input_line_pointer++;
4476 }
4477
4478 alpha_gp_register = get_absolute_expression ();
4479 if (alpha_gp_register < 0 || alpha_gp_register > 31)
4480 {
4481 alpha_gp_register = AXP_REG_GP;
4482 as_warn (_("Bad base register, using $%d."), alpha_gp_register);
4483 }
4484
4485 demand_empty_rest_of_line ();
4486 }
4487
4488 /* Handle the .align pseudo-op. This aligns to a power of two. It
4489 also adjusts any current instruction label. We treat this the same
4490 way the MIPS port does: .align 0 turns off auto alignment. */
4491
4492 static void
4493 s_alpha_align (int ignore ATTRIBUTE_UNUSED)
4494 {
4495 int align;
4496 char fill, *pfill;
4497 long max_alignment = 15;
4498
4499 align = get_absolute_expression ();
4500 if (align > max_alignment)
4501 {
4502 align = max_alignment;
4503 as_bad (_("Alignment too large: %d. assumed"), align);
4504 }
4505 else if (align < 0)
4506 {
4507 as_warn (_("Alignment negative: 0 assumed"));
4508 align = 0;
4509 }
4510
4511 if (*input_line_pointer == ',')
4512 {
4513 input_line_pointer++;
4514 fill = get_absolute_expression ();
4515 pfill = &fill;
4516 }
4517 else
4518 pfill = NULL;
4519
4520 if (align != 0)
4521 {
4522 alpha_auto_align_on = 1;
4523 alpha_align (align, pfill, alpha_insn_label, 1);
4524 }
4525 else
4526 {
4527 alpha_auto_align_on = 0;
4528 }
4529
4530 demand_empty_rest_of_line ();
4531 }
4532
4533 /* Hook the normal string processor to reset known alignment. */
4534
4535 static void
4536 s_alpha_stringer (int terminate)
4537 {
4538 alpha_current_align = 0;
4539 alpha_insn_label = NULL;
4540 stringer (8 + terminate);
4541 }
4542
4543 /* Hook the normal space processing to reset known alignment. */
4544
4545 static void
4546 s_alpha_space (int ignore)
4547 {
4548 alpha_current_align = 0;
4549 alpha_insn_label = NULL;
4550 s_space (ignore);
4551 }
4552
4553 /* Hook into cons for auto-alignment. */
4554
4555 void
4556 alpha_cons_align (int size)
4557 {
4558 int log_size;
4559
4560 log_size = 0;
4561 while ((size >>= 1) != 0)
4562 ++log_size;
4563
4564 if (alpha_auto_align_on && alpha_current_align < log_size)
4565 alpha_align (log_size, (char *) NULL, alpha_insn_label, 0);
4566 if (alpha_current_align > log_size)
4567 alpha_current_align = log_size;
4568 alpha_insn_label = NULL;
4569 }
4570
4571 /* Here come the .uword, .ulong, and .uquad explicitly unaligned
4572 pseudos. We just turn off auto-alignment and call down to cons. */
4573
4574 static void
4575 s_alpha_ucons (int bytes)
4576 {
4577 int hold = alpha_auto_align_on;
4578 alpha_auto_align_on = 0;
4579 cons (bytes);
4580 alpha_auto_align_on = hold;
4581 }
4582
4583 /* Switch the working cpu type. */
4584
4585 static void
4586 s_alpha_arch (int ignored ATTRIBUTE_UNUSED)
4587 {
4588 char *name, ch;
4589 const struct cpu_type *p;
4590
4591 SKIP_WHITESPACE ();
4592 name = input_line_pointer;
4593 ch = get_symbol_end ();
4594
4595 for (p = cpu_types; p->name; ++p)
4596 if (strcmp (name, p->name) == 0)
4597 {
4598 alpha_target_name = p->name, alpha_target = p->flags;
4599 goto found;
4600 }
4601 as_warn ("Unknown CPU identifier `%s'", name);
4602
4603 found:
4604 *input_line_pointer = ch;
4605 demand_empty_rest_of_line ();
4606 }
4607
4608 #ifdef DEBUG1
4610 /* print token expression with alpha specific extension. */
4611
4612 static void
4613 alpha_print_token (FILE *f, const expressionS *exp)
4614 {
4615 switch (exp->X_op)
4616 {
4617 case O_cpregister:
4618 putc (',', f);
4619 /* FALLTHRU */
4620 case O_pregister:
4621 putc ('(', f);
4622 {
4623 expressionS nexp = *exp;
4624 nexp.X_op = O_register;
4625 print_expr (f, &nexp);
4626 }
4627 putc (')', f);
4628 break;
4629 default:
4630 print_expr (f, exp);
4631 break;
4632 }
4633 }
4634 #endif
4635
4636 /* The target specific pseudo-ops which we support. */
4638
4639 const pseudo_typeS md_pseudo_table[] =
4640 {
4641 #ifdef OBJ_ECOFF
4642 {"comm", s_alpha_comm, 0}, /* OSF1 compiler does this. */
4643 {"rdata", s_alpha_rdata, 0},
4644 #endif
4645 {"text", s_alpha_text, 0},
4646 {"data", s_alpha_data, 0},
4647 #ifdef OBJ_ECOFF
4648 {"sdata", s_alpha_sdata, 0},
4649 #endif
4650 #ifdef OBJ_ELF
4651 {"section", s_alpha_section, 0},
4652 {"section.s", s_alpha_section, 0},
4653 {"sect", s_alpha_section, 0},
4654 {"sect.s", s_alpha_section, 0},
4655 #endif
4656 #ifdef OBJ_EVAX
4657 { "pdesc", s_alpha_pdesc, 0},
4658 { "name", s_alpha_name, 0},
4659 { "linkage", s_alpha_linkage, 0},
4660 { "code_address", s_alpha_code_address, 0},
4661 { "ent", s_alpha_ent, 0},
4662 { "frame", s_alpha_frame, 0},
4663 { "fp_save", s_alpha_fp_save, 0},
4664 { "mask", s_alpha_mask, 0},
4665 { "fmask", s_alpha_fmask, 0},
4666 { "end", s_alpha_end, 0},
4667 { "file", s_alpha_file, 0},
4668 { "rdata", s_alpha_section, 1},
4669 { "comm", s_alpha_comm, 0},
4670 { "link", s_alpha_section, 3},
4671 { "ctors", s_alpha_section, 4},
4672 { "dtors", s_alpha_section, 5},
4673 #endif
4674 #ifdef OBJ_ELF
4675 /* Frame related pseudos. */
4676 {"ent", s_alpha_ent, 0},
4677 {"end", s_alpha_end, 0},
4678 {"mask", s_alpha_mask, 0},
4679 {"fmask", s_alpha_mask, 1},
4680 {"frame", s_alpha_frame, 0},
4681 {"prologue", s_alpha_prologue, 0},
4682 {"file", s_alpha_file, 5},
4683 {"loc", s_alpha_loc, 9},
4684 {"stabs", s_alpha_stab, 's'},
4685 {"stabn", s_alpha_stab, 'n'},
4686 {"usepv", s_alpha_usepv, 0},
4687 /* COFF debugging related pseudos. */
4688 {"begin", s_alpha_coff_wrapper, 0},
4689 {"bend", s_alpha_coff_wrapper, 1},
4690 {"def", s_alpha_coff_wrapper, 2},
4691 {"dim", s_alpha_coff_wrapper, 3},
4692 {"endef", s_alpha_coff_wrapper, 4},
4693 {"scl", s_alpha_coff_wrapper, 5},
4694 {"tag", s_alpha_coff_wrapper, 6},
4695 {"val", s_alpha_coff_wrapper, 7},
4696 #else
4697 {"prologue", s_ignore, 0},
4698 #endif
4699 {"gprel32", s_alpha_gprel32, 0},
4700 {"t_floating", s_alpha_float_cons, 'd'},
4701 {"s_floating", s_alpha_float_cons, 'f'},
4702 {"f_floating", s_alpha_float_cons, 'F'},
4703 {"g_floating", s_alpha_float_cons, 'G'},
4704 {"d_floating", s_alpha_float_cons, 'D'},
4705
4706 {"proc", s_alpha_proc, 0},
4707 {"aproc", s_alpha_proc, 1},
4708 {"set", s_alpha_set, 0},
4709 {"reguse", s_ignore, 0},
4710 {"livereg", s_ignore, 0},
4711 {"base", s_alpha_base, 0}, /*??*/
4712 {"option", s_ignore, 0},
4713 {"aent", s_ignore, 0},
4714 {"ugen", s_ignore, 0},
4715 {"eflag", s_ignore, 0},
4716
4717 {"align", s_alpha_align, 0},
4718 {"double", s_alpha_float_cons, 'd'},
4719 {"float", s_alpha_float_cons, 'f'},
4720 {"single", s_alpha_float_cons, 'f'},
4721 {"ascii", s_alpha_stringer, 0},
4722 {"asciz", s_alpha_stringer, 1},
4723 {"string", s_alpha_stringer, 1},
4724 {"space", s_alpha_space, 0},
4725 {"skip", s_alpha_space, 0},
4726 {"zero", s_alpha_space, 0},
4727
4728 /* Unaligned data pseudos. */
4729 {"uword", s_alpha_ucons, 2},
4730 {"ulong", s_alpha_ucons, 4},
4731 {"uquad", s_alpha_ucons, 8},
4732
4733 #ifdef OBJ_ELF
4734 /* Dwarf wants these versions of unaligned. */
4735 {"2byte", s_alpha_ucons, 2},
4736 {"4byte", s_alpha_ucons, 4},
4737 {"8byte", s_alpha_ucons, 8},
4738 #endif
4739
4740 /* We don't do any optimizing, so we can safely ignore these. */
4741 {"noalias", s_ignore, 0},
4742 {"alias", s_ignore, 0},
4743
4744 {"arch", s_alpha_arch, 0},
4745
4746 {NULL, 0, 0},
4747 };
4748
4749 #ifdef OBJ_ECOFF
4751
4752 /* @@@ GP selection voodoo. All of this seems overly complicated and
4753 unnecessary; which is the primary reason it's for ECOFF only. */
4754
4755 static inline void
4756 maybe_set_gp (asection *sec)
4757 {
4758 bfd_vma vma;
4759
4760 if (!sec)
4761 return;
4762 vma = bfd_get_section_vma (foo, sec);
4763 if (vma && vma < alpha_gp_value)
4764 alpha_gp_value = vma;
4765 }
4766
4767 static void
4768 select_gp_value (void)
4769 {
4770 assert (alpha_gp_value == 0);
4771
4772 /* Get minus-one in whatever width... */
4773 alpha_gp_value = 0;
4774 alpha_gp_value--;
4775
4776 /* Select the smallest VMA of these existing sections. */
4777 maybe_set_gp (alpha_lita_section);
4778
4779 /* @@ Will a simple 0x8000 work here? If not, why not? */
4780 #define GP_ADJUSTMENT (0x8000 - 0x10)
4781
4782 alpha_gp_value += GP_ADJUSTMENT;
4783
4784 S_SET_VALUE (alpha_gp_symbol, alpha_gp_value);
4785
4786 #ifdef DEBUG1
4787 printf (_("Chose GP value of %lx\n"), alpha_gp_value);
4788 #endif
4789 }
4790 #endif /* OBJ_ECOFF */
4791
4792 #ifdef OBJ_ELF
4793 /* Map 's' to SHF_ALPHA_GPREL. */
4794
4795 int
4796 alpha_elf_section_letter (int letter, char **ptr_msg)
4797 {
4798 if (letter == 's')
4799 return SHF_ALPHA_GPREL;
4800
4801 *ptr_msg = _("Bad .section directive: want a,s,w,x,M,S,G,T in string");
4802 return -1;
4803 }
4804
4805 /* Map SHF_ALPHA_GPREL to SEC_SMALL_DATA. */
4806
4807 flagword
4808 alpha_elf_section_flags (flagword flags, int attr, int type ATTRIBUTE_UNUSED)
4809 {
4810 if (attr & SHF_ALPHA_GPREL)
4811 flags |= SEC_SMALL_DATA;
4812 return flags;
4813 }
4814 #endif /* OBJ_ELF */
4815
4816 /* This is called from HANDLE_ALIGN in write.c. Fill in the contents
4817 of an rs_align_code fragment. */
4818
4819 void
4820 alpha_handle_align (fragS *fragp)
4821 {
4822 static char const unop[4] = { 0x00, 0x00, 0xfe, 0x2f };
4823 static char const nopunop[8] =
4824 {
4825 0x1f, 0x04, 0xff, 0x47,
4826 0x00, 0x00, 0xfe, 0x2f
4827 };
4828
4829 int bytes, fix;
4830 char *p;
4831
4832 if (fragp->fr_type != rs_align_code)
4833 return;
4834
4835 bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix;
4836 p = fragp->fr_literal + fragp->fr_fix;
4837 fix = 0;
4838
4839 if (bytes & 3)
4840 {
4841 fix = bytes & 3;
4842 memset (p, 0, fix);
4843 p += fix;
4844 bytes -= fix;
4845 }
4846
4847 if (bytes & 4)
4848 {
4849 memcpy (p, unop, 4);
4850 p += 4;
4851 bytes -= 4;
4852 fix += 4;
4853 }
4854
4855 memcpy (p, nopunop, 8);
4856
4857 fragp->fr_fix += fix;
4858 fragp->fr_var = 8;
4859 }
4860
4861 /* Public interface functions. */
4863
4864 /* This function is called once, at assembler startup time. It sets
4865 up all the tables, etc. that the MD part of the assembler will
4866 need, that can be determined before arguments are parsed. */
4867
4868 void
4869 md_begin (void)
4870 {
4871 unsigned int i;
4872
4873 /* Verify that X_op field is wide enough. */
4874 {
4875 expressionS e;
4876
4877 e.X_op = O_max;
4878 assert (e.X_op == O_max);
4879 }
4880
4881 /* Create the opcode hash table. */
4882 alpha_opcode_hash = hash_new ();
4883
4884 for (i = 0; i < alpha_num_opcodes;)
4885 {
4886 const char *name, *retval, *slash;
4887
4888 name = alpha_opcodes[i].name;
4889 retval = hash_insert (alpha_opcode_hash, name, (void *) &alpha_opcodes[i]);
4890 if (retval)
4891 as_fatal (_("internal error: can't hash opcode `%s': %s"),
4892 name, retval);
4893
4894 /* Some opcodes include modifiers of various sorts with a "/mod"
4895 syntax, like the architecture manual suggests. However, for
4896 use with gcc at least, we also need access to those same opcodes
4897 without the "/". */
4898
4899 if ((slash = strchr (name, '/')) != NULL)
4900 {
4901 char *p = xmalloc (strlen (name));
4902
4903 memcpy (p, name, slash - name);
4904 strcpy (p + (slash - name), slash + 1);
4905
4906 (void) hash_insert (alpha_opcode_hash, p, (void *) &alpha_opcodes[i]);
4907 /* Ignore failures -- the opcode table does duplicate some
4908 variants in different forms, like "hw_stq" and "hw_st/q". */
4909 }
4910
4911 while (++i < alpha_num_opcodes
4912 && (alpha_opcodes[i].name == name
4913 || !strcmp (alpha_opcodes[i].name, name)))
4914 continue;
4915 }
4916
4917 /* Create the macro hash table. */
4918 alpha_macro_hash = hash_new ();
4919
4920 for (i = 0; i < alpha_num_macros;)
4921 {
4922 const char *name, *retval;
4923
4924 name = alpha_macros[i].name;
4925 retval = hash_insert (alpha_macro_hash, name, (void *) &alpha_macros[i]);
4926 if (retval)
4927 as_fatal (_("internal error: can't hash macro `%s': %s"),
4928 name, retval);
4929
4930 while (++i < alpha_num_macros
4931 && (alpha_macros[i].name == name
4932 || !strcmp (alpha_macros[i].name, name)))
4933 continue;
4934 }
4935
4936 /* Construct symbols for each of the registers. */
4937 for (i = 0; i < 32; ++i)
4938 {
4939 char name[4];
4940
4941 sprintf (name, "$%d", i);
4942 alpha_register_table[i] = symbol_create (name, reg_section, i,
4943 &zero_address_frag);
4944 }
4945
4946 for (; i < 64; ++i)
4947 {
4948 char name[5];
4949
4950 sprintf (name, "$f%d", i - 32);
4951 alpha_register_table[i] = symbol_create (name, reg_section, i,
4952 &zero_address_frag);
4953 }
4954
4955 /* Create the special symbols and sections we'll be using. */
4956
4957 /* So .sbss will get used for tiny objects. */
4958 bfd_set_gp_size (stdoutput, g_switch_value);
4959
4960 #ifdef OBJ_ECOFF
4961 create_literal_section (".lita", &alpha_lita_section, &alpha_lita_symbol);
4962
4963 /* For handling the GP, create a symbol that won't be output in the
4964 symbol table. We'll edit it out of relocs later. */
4965 alpha_gp_symbol = symbol_create ("<GP value>", alpha_lita_section, 0x8000,
4966 &zero_address_frag);
4967 #endif
4968
4969 #ifdef OBJ_EVAX
4970 create_literal_section (".link", &alpha_link_section, &alpha_link_symbol);
4971 #endif
4972
4973 #ifdef OBJ_ELF
4974 if (ECOFF_DEBUGGING)
4975 {
4976 segT sec = subseg_new (".mdebug", (subsegT) 0);
4977 bfd_set_section_flags (stdoutput, sec, SEC_HAS_CONTENTS | SEC_READONLY);
4978 bfd_set_section_alignment (stdoutput, sec, 3);
4979 }
4980 #endif
4981
4982 /* Create literal lookup hash table. */
4983 alpha_literal_hash = hash_new ();
4984
4985 subseg_set (text_section, 0);
4986 }
4987
4988 /* The public interface to the instruction assembler. */
4989
4990 void
4991 md_assemble (char *str)
4992 {
4993 /* Current maximum is 13. */
4994 char opname[32];
4995 expressionS tok[MAX_INSN_ARGS];
4996 int ntok, trunclen;
4997 size_t opnamelen;
4998
4999 /* Split off the opcode. */
5000 opnamelen = strspn (str, "abcdefghijklmnopqrstuvwxyz_/46819");
5001 trunclen = (opnamelen < sizeof (opname) - 1
5002 ? opnamelen
5003 : sizeof (opname) - 1);
5004 memcpy (opname, str, trunclen);
5005 opname[trunclen] = '\0';
5006
5007 /* Tokenize the rest of the line. */
5008 if ((ntok = tokenize_arguments (str + opnamelen, tok, MAX_INSN_ARGS)) < 0)
5009 {
5010 if (ntok != TOKENIZE_ERROR_REPORT)
5011 as_bad (_("syntax error"));
5012
5013 return;
5014 }
5015
5016 /* Finish it off. */
5017 assemble_tokens (opname, tok, ntok, alpha_macros_on);
5018 }
5019
5020 /* Round up a section's size to the appropriate boundary. */
5021
5022 valueT
5023 md_section_align (segT seg, valueT size)
5024 {
5025 int align = bfd_get_section_alignment (stdoutput, seg);
5026 valueT mask = ((valueT) 1 << align) - 1;
5027
5028 return (size + mask) & ~mask;
5029 }
5030
5031 /* Turn a string in input_line_pointer into a floating point constant
5032 of type TYPE, and store the appropriate bytes in *LITP. The number
5033 of LITTLENUMS emitted is stored in *SIZEP. An error message is
5034 returned, or NULL on OK. */
5035
5036 char *
5037 md_atof (int type, char *litP, int *sizeP)
5038 {
5039 extern char *vax_md_atof (int, char *, int *);
5040
5041 switch (type)
5042 {
5043 /* VAX floats. */
5044 case 'G':
5045 /* vax_md_atof() doesn't like "G" for some reason. */
5046 type = 'g';
5047 case 'F':
5048 case 'D':
5049 return vax_md_atof (type, litP, sizeP);
5050
5051 default:
5052 return ieee_md_atof (type, litP, sizeP, FALSE);
5053 }
5054 }
5055
5056 /* Take care of the target-specific command-line options. */
5057
5058 int
5059 md_parse_option (int c, char *arg)
5060 {
5061 switch (c)
5062 {
5063 case 'F':
5064 alpha_nofloats_on = 1;
5065 break;
5066
5067 case OPTION_32ADDR:
5068 alpha_addr32_on = 1;
5069 break;
5070
5071 case 'g':
5072 alpha_debug = 1;
5073 break;
5074
5075 case 'G':
5076 g_switch_value = atoi (arg);
5077 break;
5078
5079 case 'm':
5080 {
5081 const struct cpu_type *p;
5082
5083 for (p = cpu_types; p->name; ++p)
5084 if (strcmp (arg, p->name) == 0)
5085 {
5086 alpha_target_name = p->name, alpha_target = p->flags;
5087 goto found;
5088 }
5089 as_warn (_("Unknown CPU identifier `%s'"), arg);
5090 found:;
5091 }
5092 break;
5093
5094 #ifdef OBJ_EVAX
5095 case '+': /* For g++. Hash any name > 63 chars long. */
5096 alpha_flag_hash_long_names = 1;
5097 break;
5098
5099 case 'H': /* Show new symbol after hash truncation. */
5100 alpha_flag_show_after_trunc = 1;
5101 break;
5102
5103 case 'h': /* For gnu-c/vax compatibility. */
5104 break;
5105 #endif
5106
5107 case OPTION_RELAX:
5108 alpha_flag_relax = 1;
5109 break;
5110
5111 #ifdef OBJ_ELF
5112 case OPTION_MDEBUG:
5113 alpha_flag_mdebug = 1;
5114 break;
5115 case OPTION_NO_MDEBUG:
5116 alpha_flag_mdebug = 0;
5117 break;
5118 #endif
5119
5120 default:
5121 return 0;
5122 }
5123
5124 return 1;
5125 }
5126
5127 /* Print a description of the command-line options that we accept. */
5128
5129 void
5130 md_show_usage (FILE *stream)
5131 {
5132 fputs (_("\
5133 Alpha options:\n\
5134 -32addr treat addresses as 32-bit values\n\
5135 -F lack floating point instructions support\n\
5136 -mev4 | -mev45 | -mev5 | -mev56 | -mpca56 | -mev6 | -mev67 | -mev68 | -mall\n\
5137 specify variant of Alpha architecture\n\
5138 -m21064 | -m21066 | -m21164 | -m21164a | -m21164pc | -m21264 | -m21264a | -m21264b\n\
5139 these variants include PALcode opcodes\n"),
5140 stream);
5141 #ifdef OBJ_EVAX
5142 fputs (_("\
5143 VMS options:\n\
5144 -+ hash encode (don't truncate) names longer than 64 characters\n\
5145 -H show new symbol after hash truncation\n"),
5146 stream);
5147 #endif
5148 }
5149
5150 /* Decide from what point a pc-relative relocation is relative to,
5151 relative to the pc-relative fixup. Er, relatively speaking. */
5152
5153 long
5154 md_pcrel_from (fixS *fixP)
5155 {
5156 valueT addr = fixP->fx_where + fixP->fx_frag->fr_address;
5157
5158 switch (fixP->fx_r_type)
5159 {
5160 case BFD_RELOC_23_PCREL_S2:
5161 case BFD_RELOC_ALPHA_HINT:
5162 case BFD_RELOC_ALPHA_BRSGP:
5163 return addr + 4;
5164 default:
5165 return addr;
5166 }
5167 }
5168
5169 /* Attempt to simplify or even eliminate a fixup. The return value is
5170 ignored; perhaps it was once meaningful, but now it is historical.
5171 To indicate that a fixup has been eliminated, set fixP->fx_done.
5172
5173 For ELF, here it is that we transform the GPDISP_HI16 reloc we used
5174 internally into the GPDISP reloc used externally. We had to do
5175 this so that we'd have the GPDISP_LO16 reloc as a tag to compute
5176 the distance to the "lda" instruction for setting the addend to
5177 GPDISP. */
5178
5179 void
5180 md_apply_fix (fixS *fixP, valueT * valP, segT seg)
5181 {
5182 char * const fixpos = fixP->fx_frag->fr_literal + fixP->fx_where;
5183 valueT value = * valP;
5184 unsigned image, size;
5185
5186 switch (fixP->fx_r_type)
5187 {
5188 /* The GPDISP relocations are processed internally with a symbol
5189 referring to the current function's section; we need to drop
5190 in a value which, when added to the address of the start of
5191 the function, gives the desired GP. */
5192 case BFD_RELOC_ALPHA_GPDISP_HI16:
5193 {
5194 fixS *next = fixP->fx_next;
5195
5196 /* With user-specified !gpdisp relocations, we can be missing
5197 the matching LO16 reloc. We will have already issued an
5198 error message. */
5199 if (next)
5200 fixP->fx_offset = (next->fx_frag->fr_address + next->fx_where
5201 - fixP->fx_frag->fr_address - fixP->fx_where);
5202
5203 value = (value - sign_extend_16 (value)) >> 16;
5204 }
5205 #ifdef OBJ_ELF
5206 fixP->fx_r_type = BFD_RELOC_ALPHA_GPDISP;
5207 #endif
5208 goto do_reloc_gp;
5209
5210 case BFD_RELOC_ALPHA_GPDISP_LO16:
5211 value = sign_extend_16 (value);
5212 fixP->fx_offset = 0;
5213 #ifdef OBJ_ELF
5214 fixP->fx_done = 1;
5215 #endif
5216
5217 do_reloc_gp:
5218 fixP->fx_addsy = section_symbol (seg);
5219 md_number_to_chars (fixpos, value, 2);
5220 break;
5221
5222 case BFD_RELOC_16:
5223 if (fixP->fx_pcrel)
5224 fixP->fx_r_type = BFD_RELOC_16_PCREL;
5225 size = 2;
5226 goto do_reloc_xx;
5227
5228 case BFD_RELOC_32:
5229 if (fixP->fx_pcrel)
5230 fixP->fx_r_type = BFD_RELOC_32_PCREL;
5231 size = 4;
5232 goto do_reloc_xx;
5233
5234 case BFD_RELOC_64:
5235 if (fixP->fx_pcrel)
5236 fixP->fx_r_type = BFD_RELOC_64_PCREL;
5237 size = 8;
5238
5239 do_reloc_xx:
5240 if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0)
5241 {
5242 md_number_to_chars (fixpos, value, size);
5243 goto done;
5244 }
5245 return;
5246
5247 #ifdef OBJ_ECOFF
5248 case BFD_RELOC_GPREL32:
5249 assert (fixP->fx_subsy == alpha_gp_symbol);
5250 fixP->fx_subsy = 0;
5251 /* FIXME: inherited this obliviousness of `value' -- why? */
5252 md_number_to_chars (fixpos, -alpha_gp_value, 4);
5253 break;
5254 #else
5255 case BFD_RELOC_GPREL32:
5256 #endif
5257 case BFD_RELOC_GPREL16:
5258 case BFD_RELOC_ALPHA_GPREL_HI16:
5259 case BFD_RELOC_ALPHA_GPREL_LO16:
5260 return;
5261
5262 case BFD_RELOC_23_PCREL_S2:
5263 if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0)
5264 {
5265 image = bfd_getl32 (fixpos);
5266 image = (image & ~0x1FFFFF) | ((value >> 2) & 0x1FFFFF);
5267 goto write_done;
5268 }
5269 return;
5270
5271 case BFD_RELOC_ALPHA_HINT:
5272 if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0)
5273 {
5274 image = bfd_getl32 (fixpos);
5275 image = (image & ~0x3FFF) | ((value >> 2) & 0x3FFF);
5276 goto write_done;
5277 }
5278 return;
5279
5280 #ifdef OBJ_ELF
5281 case BFD_RELOC_ALPHA_BRSGP:
5282 return;
5283
5284 case BFD_RELOC_ALPHA_TLSGD:
5285 case BFD_RELOC_ALPHA_TLSLDM:
5286 case BFD_RELOC_ALPHA_GOTDTPREL16:
5287 case BFD_RELOC_ALPHA_DTPREL_HI16:
5288 case BFD_RELOC_ALPHA_DTPREL_LO16:
5289 case BFD_RELOC_ALPHA_DTPREL16:
5290 case BFD_RELOC_ALPHA_GOTTPREL16:
5291 case BFD_RELOC_ALPHA_TPREL_HI16:
5292 case BFD_RELOC_ALPHA_TPREL_LO16:
5293 case BFD_RELOC_ALPHA_TPREL16:
5294 if (fixP->fx_addsy)
5295 S_SET_THREAD_LOCAL (fixP->fx_addsy);
5296 return;
5297 #endif
5298
5299 #ifdef OBJ_ECOFF
5300 case BFD_RELOC_ALPHA_LITERAL:
5301 md_number_to_chars (fixpos, value, 2);
5302 return;
5303 #endif
5304 case BFD_RELOC_ALPHA_ELF_LITERAL:
5305 case BFD_RELOC_ALPHA_LITUSE:
5306 case BFD_RELOC_ALPHA_LINKAGE:
5307 case BFD_RELOC_ALPHA_CODEADDR:
5308 return;
5309
5310 case BFD_RELOC_VTABLE_INHERIT:
5311 case BFD_RELOC_VTABLE_ENTRY:
5312 return;
5313
5314 default:
5315 {
5316 const struct alpha_operand *operand;
5317
5318 if ((int) fixP->fx_r_type >= 0)
5319 as_fatal (_("unhandled relocation type %s"),
5320 bfd_get_reloc_code_name (fixP->fx_r_type));
5321
5322 assert (-(int) fixP->fx_r_type < (int) alpha_num_operands);
5323 operand = &alpha_operands[-(int) fixP->fx_r_type];
5324
5325 /* The rest of these fixups only exist internally during symbol
5326 resolution and have no representation in the object file.
5327 Therefore they must be completely resolved as constants. */
5328
5329 if (fixP->fx_addsy != 0
5330 && S_GET_SEGMENT (fixP->fx_addsy) != absolute_section)
5331 as_bad_where (fixP->fx_file, fixP->fx_line,
5332 _("non-absolute expression in constant field"));
5333
5334 image = bfd_getl32 (fixpos);
5335 image = insert_operand (image, operand, (offsetT) value,
5336 fixP->fx_file, fixP->fx_line);
5337 }
5338 goto write_done;
5339 }
5340
5341 if (fixP->fx_addsy != 0 || fixP->fx_pcrel != 0)
5342 return;
5343 else
5344 {
5345 as_warn_where (fixP->fx_file, fixP->fx_line,
5346 _("type %d reloc done?\n"), (int) fixP->fx_r_type);
5347 goto done;
5348 }
5349
5350 write_done:
5351 md_number_to_chars (fixpos, image, 4);
5352
5353 done:
5354 fixP->fx_done = 1;
5355 }
5356
5357 /* Look for a register name in the given symbol. */
5358
5359 symbolS *
5360 md_undefined_symbol (char *name)
5361 {
5362 if (*name == '$')
5363 {
5364 int is_float = 0, num;
5365
5366 switch (*++name)
5367 {
5368 case 'f':
5369 if (name[1] == 'p' && name[2] == '\0')
5370 return alpha_register_table[AXP_REG_FP];
5371 is_float = 32;
5372 /* Fall through. */
5373
5374 case 'r':
5375 if (!ISDIGIT (*++name))
5376 break;
5377 /* Fall through. */
5378
5379 case '0': case '1': case '2': case '3': case '4':
5380 case '5': case '6': case '7': case '8': case '9':
5381 if (name[1] == '\0')
5382 num = name[0] - '0';
5383 else if (name[0] != '0' && ISDIGIT (name[1]) && name[2] == '\0')
5384 {
5385 num = (name[0] - '0') * 10 + name[1] - '0';
5386 if (num >= 32)
5387 break;
5388 }
5389 else
5390 break;
5391
5392 if (!alpha_noat_on && (num + is_float) == AXP_REG_AT)
5393 as_warn (_("Used $at without \".set noat\""));
5394 return alpha_register_table[num + is_float];
5395
5396 case 'a':
5397 if (name[1] == 't' && name[2] == '\0')
5398 {
5399 if (!alpha_noat_on)
5400 as_warn (_("Used $at without \".set noat\""));
5401 return alpha_register_table[AXP_REG_AT];
5402 }
5403 break;
5404
5405 case 'g':
5406 if (name[1] == 'p' && name[2] == '\0')
5407 return alpha_register_table[alpha_gp_register];
5408 break;
5409
5410 case 's':
5411 if (name[1] == 'p' && name[2] == '\0')
5412 return alpha_register_table[AXP_REG_SP];
5413 break;
5414 }
5415 }
5416 return NULL;
5417 }
5418
5419 #ifdef OBJ_ECOFF
5420 /* @@@ Magic ECOFF bits. */
5421
5422 void
5423 alpha_frob_ecoff_data (void)
5424 {
5425 select_gp_value ();
5426 /* $zero and $f31 are read-only. */
5427 alpha_gprmask &= ~1;
5428 alpha_fprmask &= ~1;
5429 }
5430 #endif
5431
5432 /* Hook to remember a recently defined label so that the auto-align
5433 code can adjust the symbol after we know what alignment will be
5434 required. */
5435
5436 void
5437 alpha_define_label (symbolS *sym)
5438 {
5439 alpha_insn_label = sym;
5440 #ifdef OBJ_ELF
5441 dwarf2_emit_label (sym);
5442 #endif
5443 }
5444
5445 /* Return true if we must always emit a reloc for a type and false if
5446 there is some hope of resolving it at assembly time. */
5447
5448 int
5449 alpha_force_relocation (fixS *f)
5450 {
5451 if (alpha_flag_relax)
5452 return 1;
5453
5454 switch (f->fx_r_type)
5455 {
5456 case BFD_RELOC_ALPHA_GPDISP_HI16:
5457 case BFD_RELOC_ALPHA_GPDISP_LO16:
5458 case BFD_RELOC_ALPHA_GPDISP:
5459 case BFD_RELOC_ALPHA_LITERAL:
5460 case BFD_RELOC_ALPHA_ELF_LITERAL:
5461 case BFD_RELOC_ALPHA_LITUSE:
5462 case BFD_RELOC_GPREL16:
5463 case BFD_RELOC_GPREL32:
5464 case BFD_RELOC_ALPHA_GPREL_HI16:
5465 case BFD_RELOC_ALPHA_GPREL_LO16:
5466 case BFD_RELOC_ALPHA_LINKAGE:
5467 case BFD_RELOC_ALPHA_CODEADDR:
5468 case BFD_RELOC_ALPHA_BRSGP:
5469 case BFD_RELOC_ALPHA_TLSGD:
5470 case BFD_RELOC_ALPHA_TLSLDM:
5471 case BFD_RELOC_ALPHA_GOTDTPREL16:
5472 case BFD_RELOC_ALPHA_DTPREL_HI16:
5473 case BFD_RELOC_ALPHA_DTPREL_LO16:
5474 case BFD_RELOC_ALPHA_DTPREL16:
5475 case BFD_RELOC_ALPHA_GOTTPREL16:
5476 case BFD_RELOC_ALPHA_TPREL_HI16:
5477 case BFD_RELOC_ALPHA_TPREL_LO16:
5478 case BFD_RELOC_ALPHA_TPREL16:
5479 return 1;
5480
5481 default:
5482 break;
5483 }
5484
5485 return generic_force_reloc (f);
5486 }
5487
5488 /* Return true if we can partially resolve a relocation now. */
5489
5490 int
5491 alpha_fix_adjustable (fixS *f)
5492 {
5493 /* Are there any relocation types for which we must generate a
5494 reloc but we can adjust the values contained within it? */
5495 switch (f->fx_r_type)
5496 {
5497 case BFD_RELOC_ALPHA_GPDISP_HI16:
5498 case BFD_RELOC_ALPHA_GPDISP_LO16:
5499 case BFD_RELOC_ALPHA_GPDISP:
5500 return 0;
5501
5502 case BFD_RELOC_ALPHA_LITERAL:
5503 case BFD_RELOC_ALPHA_ELF_LITERAL:
5504 case BFD_RELOC_ALPHA_LITUSE:
5505 case BFD_RELOC_ALPHA_LINKAGE:
5506 case BFD_RELOC_ALPHA_CODEADDR:
5507 return 1;
5508
5509 case BFD_RELOC_VTABLE_ENTRY:
5510 case BFD_RELOC_VTABLE_INHERIT:
5511 return 0;
5512
5513 case BFD_RELOC_GPREL16:
5514 case BFD_RELOC_GPREL32:
5515 case BFD_RELOC_ALPHA_GPREL_HI16:
5516 case BFD_RELOC_ALPHA_GPREL_LO16:
5517 case BFD_RELOC_23_PCREL_S2:
5518 case BFD_RELOC_32:
5519 case BFD_RELOC_64:
5520 case BFD_RELOC_ALPHA_HINT:
5521 return 1;
5522
5523 case BFD_RELOC_ALPHA_TLSGD:
5524 case BFD_RELOC_ALPHA_TLSLDM:
5525 case BFD_RELOC_ALPHA_GOTDTPREL16:
5526 case BFD_RELOC_ALPHA_DTPREL_HI16:
5527 case BFD_RELOC_ALPHA_DTPREL_LO16:
5528 case BFD_RELOC_ALPHA_DTPREL16:
5529 case BFD_RELOC_ALPHA_GOTTPREL16:
5530 case BFD_RELOC_ALPHA_TPREL_HI16:
5531 case BFD_RELOC_ALPHA_TPREL_LO16:
5532 case BFD_RELOC_ALPHA_TPREL16:
5533 /* ??? No idea why we can't return a reference to .tbss+10, but
5534 we're preventing this in the other assemblers. Follow for now. */
5535 return 0;
5536
5537 #ifdef OBJ_ELF
5538 case BFD_RELOC_ALPHA_BRSGP:
5539 /* If we have a BRSGP reloc to a local symbol, adjust it to BRADDR and
5540 let it get resolved at assembly time. */
5541 {
5542 symbolS *sym = f->fx_addsy;
5543 const char *name;
5544 int offset = 0;
5545
5546 if (generic_force_reloc (f))
5547 return 0;
5548
5549 switch (S_GET_OTHER (sym) & STO_ALPHA_STD_GPLOAD)
5550 {
5551 case STO_ALPHA_NOPV:
5552 break;
5553 case STO_ALPHA_STD_GPLOAD:
5554 offset = 8;
5555 break;
5556 default:
5557 if (S_IS_LOCAL (sym))
5558 name = "<local>";
5559 else
5560 name = S_GET_NAME (sym);
5561 as_bad_where (f->fx_file, f->fx_line,
5562 _("!samegp reloc against symbol without .prologue: %s"),
5563 name);
5564 break;
5565 }
5566 f->fx_r_type = BFD_RELOC_23_PCREL_S2;
5567 f->fx_offset += offset;
5568 return 1;
5569 }
5570 #endif
5571
5572 default:
5573 return 1;
5574 }
5575 }
5576
5577 /* Generate the BFD reloc to be stuck in the object file from the
5578 fixup used internally in the assembler. */
5579
5580 arelent *
5581 tc_gen_reloc (asection *sec ATTRIBUTE_UNUSED,
5582 fixS *fixp)
5583 {
5584 arelent *reloc;
5585
5586 reloc = xmalloc (sizeof (* reloc));
5587 reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
5588 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
5589 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
5590
5591 /* Make sure none of our internal relocations make it this far.
5592 They'd better have been fully resolved by this point. */
5593 assert ((int) fixp->fx_r_type > 0);
5594
5595 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
5596 if (reloc->howto == NULL)
5597 {
5598 as_bad_where (fixp->fx_file, fixp->fx_line,
5599 _("cannot represent `%s' relocation in object file"),
5600 bfd_get_reloc_code_name (fixp->fx_r_type));
5601 return NULL;
5602 }
5603
5604 if (!fixp->fx_pcrel != !reloc->howto->pc_relative)
5605 as_fatal (_("internal error? cannot generate `%s' relocation"),
5606 bfd_get_reloc_code_name (fixp->fx_r_type));
5607
5608 assert (!fixp->fx_pcrel == !reloc->howto->pc_relative);
5609
5610 #ifdef OBJ_ECOFF
5611 if (fixp->fx_r_type == BFD_RELOC_ALPHA_LITERAL)
5612 /* Fake out bfd_perform_relocation. sigh. */
5613 reloc->addend = -alpha_gp_value;
5614 else
5615 #endif
5616 {
5617 reloc->addend = fixp->fx_offset;
5618 #ifdef OBJ_ELF
5619 /* Ohhh, this is ugly. The problem is that if this is a local global
5620 symbol, the relocation will entirely be performed at link time, not
5621 at assembly time. bfd_perform_reloc doesn't know about this sort
5622 of thing, and as a result we need to fake it out here. */
5623 if ((S_IS_EXTERNAL (fixp->fx_addsy) || S_IS_WEAK (fixp->fx_addsy)
5624 || (S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_MERGE)
5625 || (S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_THREAD_LOCAL))
5626 && !S_IS_COMMON (fixp->fx_addsy))
5627 reloc->addend -= symbol_get_bfdsym (fixp->fx_addsy)->value;
5628 #endif
5629 }
5630
5631 return reloc;
5632 }
5633
5634 /* Parse a register name off of the input_line and return a register
5635 number. Gets md_undefined_symbol above to do the register name
5636 matching for us.
5637
5638 Only called as a part of processing the ECOFF .frame directive. */
5639
5640 int
5641 tc_get_register (int frame ATTRIBUTE_UNUSED)
5642 {
5643 int framereg = AXP_REG_SP;
5644
5645 SKIP_WHITESPACE ();
5646 if (*input_line_pointer == '$')
5647 {
5648 char *s = input_line_pointer;
5649 char c = get_symbol_end ();
5650 symbolS *sym = md_undefined_symbol (s);
5651
5652 *strchr (s, '\0') = c;
5653 if (sym && (framereg = S_GET_VALUE (sym)) <= 31)
5654 goto found;
5655 }
5656 as_warn (_("frame reg expected, using $%d."), framereg);
5657
5658 found:
5659 note_gpreg (framereg);
5660 return framereg;
5661 }
5662
5663 /* This is called before the symbol table is processed. In order to
5664 work with gcc when using mips-tfile, we must keep all local labels.
5665 However, in other cases, we want to discard them. If we were
5666 called with -g, but we didn't see any debugging information, it may
5667 mean that gcc is smuggling debugging information through to
5668 mips-tfile, in which case we must generate all local labels. */
5669
5670 #ifdef OBJ_ECOFF
5671
5672 void
5673 alpha_frob_file_before_adjust (void)
5674 {
5675 if (alpha_debug != 0
5676 && ! ecoff_debugging_seen)
5677 flag_keep_locals = 1;
5678 }
5679
5680 #endif /* OBJ_ECOFF */
5681
5682 /* The Alpha has support for some VAX floating point types, as well as for
5683 IEEE floating point. We consider IEEE to be the primary floating point
5684 format, and sneak in the VAX floating point support here. */
5685 #include "config/atof-vax.c"
5686