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