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