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