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