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