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