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