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