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