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