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