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