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