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