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