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