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