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