1 /* tc-alpha.c - Processor-specific code for the DEC Alpha AXP CPU.
2 Copyright (C) 1989, 93-98, 1999, 2000 Free Software Foundation, Inc.
3 Contributed by Carnegie Mellon University, 1993.
4 Written by Alessandro Forin, based on earlier gas-1.38 target CPU files.
5 Modified by Ken Raeburn for gas-2.x and ECOFF support.
6 Modified by Richard Henderson for ELF support.
7 Modified by Klaus K"ampf for EVAX (OpenVMS/Alpha) support.
9 This file is part of GAS, the GNU Assembler.
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)
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.
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
27 * Mach Operating System
28 * Copyright (c) 1993 Carnegie Mellon University
29 * All Rights Reserved.
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.
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.
41 * Carnegie Mellon requests users of this software to return to
43 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
44 * School of Computer Science
45 * Carnegie Mellon University
46 * Pittsburgh PA 15213-3890
48 * any improvements or extensions that they make and grant Carnegie the
49 * rights to redistribute these changes.
54 #include "struc-symbol.h"
57 #include "opcode/alpha.h"
60 #include "elf/alpha.h"
68 #define TOKENIZE_ERROR -1
69 #define TOKENIZE_ERROR_REPORT -2
71 #define MAX_INSN_FIXUPS 2
72 #define MAX_INSN_ARGS 5
77 bfd_reloc_code_real_type reloc
;
84 struct alpha_fixup fixups
[MAX_INSN_FIXUPS
];
85 unsigned sequence
[MAX_INSN_FIXUPS
];
106 void (*emit
) PARAMS ((const expressionS
*, int, const PTR
));
108 enum alpha_macro_arg argsets
[16];
111 /* Extra expression types. */
113 #define O_pregister O_md1 /* O_register, in parentheses */
114 #define O_cpregister O_md2 /* + a leading comma */
117 /* Note, the alpha_reloc_op table below depends on the ordering
118 of O_literal .. O_gprelow. */
119 #define O_literal O_md3 /* !literal relocation */
120 #define O_lituse_base O_md4 /* !lituse_base relocation */
121 #define O_lituse_bytoff O_md5 /* !lituse_bytoff relocation */
122 #define O_lituse_jsr O_md6 /* !lituse_jsr relocation */
123 #define O_gpdisp O_md7 /* !gpdisp relocation */
124 #define O_gprelhigh O_md8 /* !gprelhigh relocation */
125 #define O_gprellow O_md9 /* !gprellow relocation */
127 #define USER_RELOC_P(R) ((R) >= O_literal && (R) <= O_gprellow)
130 /* Macros for extracting the type and number of encoded register tokens */
132 #define is_ir_num(x) (((x) & 32) == 0)
133 #define is_fpr_num(x) (((x) & 32) != 0)
134 #define regno(x) ((x) & 31)
136 /* Something odd inherited from the old assembler */
138 #define note_gpreg(R) (alpha_gprmask |= (1 << (R)))
139 #define note_fpreg(R) (alpha_fprmask |= (1 << (R)))
141 /* Predicates for 16- and 32-bit ranges */
142 /* XXX: The non-shift version appears to trigger a compiler bug when
143 cross-assembling from x86 w/ gcc 2.7.2. */
146 #define range_signed_16(x) \
147 (((offsetT)(x) >> 15) == 0 || ((offsetT)(x) >> 15) == -1)
148 #define range_signed_32(x) \
149 (((offsetT)(x) >> 31) == 0 || ((offsetT)(x) >> 31) == -1)
151 #define range_signed_16(x) ((offsetT)(x) >= -(offsetT)0x8000 && \
152 (offsetT)(x) <= (offsetT)0x7FFF)
153 #define range_signed_32(x) ((offsetT)(x) >= -(offsetT)0x80000000 && \
154 (offsetT)(x) <= (offsetT)0x7FFFFFFF)
157 /* Macros for sign extending from 16- and 32-bits. */
158 /* XXX: The cast macros will work on all the systems that I care about,
159 but really a predicate should be found to use the non-cast forms. */
162 #define sign_extend_16(x) ((short)(x))
163 #define sign_extend_32(x) ((int)(x))
165 #define sign_extend_16(x) ((offsetT)(((x) & 0xFFFF) ^ 0x8000) - 0x8000)
166 #define sign_extend_32(x) ((offsetT)(((x) & 0xFFFFFFFF) \
167 ^ 0x80000000) - 0x80000000)
170 /* Macros to build tokens */
172 #define set_tok_reg(t, r) (memset(&(t), 0, sizeof(t)), \
173 (t).X_op = O_register, \
174 (t).X_add_number = (r))
175 #define set_tok_preg(t, r) (memset(&(t), 0, sizeof(t)), \
176 (t).X_op = O_pregister, \
177 (t).X_add_number = (r))
178 #define set_tok_cpreg(t, r) (memset(&(t), 0, sizeof(t)), \
179 (t).X_op = O_cpregister, \
180 (t).X_add_number = (r))
181 #define set_tok_freg(t, r) (memset(&(t), 0, sizeof(t)), \
182 (t).X_op = O_register, \
183 (t).X_add_number = (r)+32)
184 #define set_tok_sym(t, s, a) (memset(&(t), 0, sizeof(t)), \
185 (t).X_op = O_symbol, \
186 (t).X_add_symbol = (s), \
187 (t).X_add_number = (a))
188 #define set_tok_const(t, n) (memset(&(t), 0, sizeof(t)), \
189 (t).X_op = O_constant, \
190 (t).X_add_number = (n))
193 /* Prototypes for all local functions */
195 static int tokenize_arguments
PARAMS ((char *, expressionS
*, int));
196 static const struct alpha_opcode
*find_opcode_match
197 PARAMS ((const struct alpha_opcode
*, const expressionS
*, int *, int *));
198 static const struct alpha_macro
*find_macro_match
199 PARAMS ((const struct alpha_macro
*, const expressionS
*, int *));
200 static unsigned insert_operand
201 PARAMS ((unsigned, const struct alpha_operand
*, offsetT
, char *, unsigned));
202 static void assemble_insn
203 PARAMS ((const struct alpha_opcode
*, const expressionS
*, int,
204 struct alpha_insn
*));
205 static void emit_insn
PARAMS ((struct alpha_insn
*));
206 static void assemble_tokens_to_insn
207 PARAMS ((const char *, const expressionS
*, int, struct alpha_insn
*));
208 static void assemble_tokens
209 PARAMS ((const char *, const expressionS
*, int, int));
211 static int load_expression
212 PARAMS ((int, const expressionS
*, int *, expressionS
*,
213 const expressionS
*));
215 static void emit_ldgp
PARAMS ((const expressionS
*, int, const PTR
));
216 static void emit_division
PARAMS ((const expressionS
*, int, const PTR
));
217 static void emit_lda
PARAMS ((const expressionS
*, int, const PTR
));
218 static void emit_ldah
PARAMS ((const expressionS
*, int, const PTR
));
219 static void emit_ir_load
PARAMS ((const expressionS
*, int, const PTR
));
220 static void emit_loadstore
PARAMS ((const expressionS
*, int, const PTR
));
221 static void emit_jsrjmp
PARAMS ((const expressionS
*, int, const PTR
));
222 static void emit_ldX
PARAMS ((const expressionS
*, int, const PTR
));
223 static void emit_ldXu
PARAMS ((const expressionS
*, int, const PTR
));
224 static void emit_uldX
PARAMS ((const expressionS
*, int, const PTR
));
225 static void emit_uldXu
PARAMS ((const expressionS
*, int, const PTR
));
226 static void emit_ldil
PARAMS ((const expressionS
*, int, const PTR
));
227 static void emit_stX
PARAMS ((const expressionS
*, int, const PTR
));
228 static void emit_ustX
PARAMS ((const expressionS
*, int, const PTR
));
229 static void emit_sextX
PARAMS ((const expressionS
*, int, const PTR
));
230 static void emit_retjcr
PARAMS ((const expressionS
*, int, const PTR
));
232 static void s_alpha_text
PARAMS ((int));
233 static void s_alpha_data
PARAMS ((int));
235 static void s_alpha_comm
PARAMS ((int));
236 static void s_alpha_rdata
PARAMS ((int));
239 static void s_alpha_sdata
PARAMS ((int));
242 static void s_alpha_section
PARAMS ((int));
243 static void s_alpha_ent
PARAMS ((int));
244 static void s_alpha_end
PARAMS ((int));
245 static void s_alpha_mask
PARAMS ((int));
246 static void s_alpha_frame
PARAMS ((int));
247 static void s_alpha_prologue
PARAMS ((int));
248 static void s_alpha_coff_wrapper
PARAMS ((int));
251 static void s_alpha_section
PARAMS ((int));
253 static void s_alpha_gprel32
PARAMS ((int));
254 static void s_alpha_float_cons
PARAMS ((int));
255 static void s_alpha_proc
PARAMS ((int));
256 static void s_alpha_set
PARAMS ((int));
257 static void s_alpha_base
PARAMS ((int));
258 static void s_alpha_align
PARAMS ((int));
259 static void s_alpha_stringer
PARAMS ((int));
260 static void s_alpha_space
PARAMS ((int));
262 static void create_literal_section
PARAMS ((const char *, segT
*, symbolS
**));
264 static void select_gp_value
PARAMS ((void));
266 static void alpha_align
PARAMS ((int, char *, symbolS
*, int));
269 static void alpha_adjust_symtab_relocs
PARAMS ((bfd
*, asection
*, PTR
));
273 /* Generic assembler global variables which must be defined by all
276 /* Characters which always start a comment. */
277 const char comment_chars
[] = "#";
279 /* Characters which start a comment at the beginning of a line. */
280 const char line_comment_chars
[] = "#";
282 /* Characters which may be used to separate multiple commands on a
284 const char line_separator_chars
[] = ";";
286 /* Characters which are used to indicate an exponent in a floating
288 const char EXP_CHARS
[] = "eE";
290 /* Characters which mean that a number is a floating point constant,
293 const char FLT_CHARS
[] = "dD";
295 /* XXX: Do all of these really get used on the alpha?? */
296 char FLT_CHARS
[] = "rRsSfFdDxXpP";
300 const char *md_shortopts
= "Fm:g+1h:HG:";
302 const char *md_shortopts
= "Fm:gG:";
305 struct option md_longopts
[] = {
306 #define OPTION_32ADDR (OPTION_MD_BASE)
307 { "32addr", no_argument
, NULL
, OPTION_32ADDR
},
308 #define OPTION_RELAX (OPTION_32ADDR+1)
309 { "relax", no_argument
, NULL
, OPTION_RELAX
},
311 #define OPTION_MDEBUG (OPTION_RELAX+1)
312 #define OPTION_NO_MDEBUG (OPTION_MDEBUG+1)
313 { "mdebug", no_argument
, NULL
, OPTION_MDEBUG
},
314 { "no-mdebug", no_argument
, NULL
, OPTION_NO_MDEBUG
},
316 { NULL
, no_argument
, NULL
, 0 }
319 size_t md_longopts_size
= sizeof(md_longopts
);
324 #define AXP_REG_R16 16
325 #define AXP_REG_R17 17
327 #define AXP_REG_T9 22
329 #define AXP_REG_T10 23
331 #define AXP_REG_T11 24
333 #define AXP_REG_T12 25
334 #define AXP_REG_AI 25
336 #define AXP_REG_FP 29
339 #define AXP_REG_GP AXP_REG_PV
340 #endif /* OBJ_EVAX */
342 /* The cpu for which we are generating code */
343 static unsigned alpha_target
= AXP_OPCODE_BASE
;
344 static const char *alpha_target_name
= "<all>";
346 /* The hash table of instruction opcodes */
347 static struct hash_control
*alpha_opcode_hash
;
349 /* The hash table of macro opcodes */
350 static struct hash_control
*alpha_macro_hash
;
353 /* The $gp relocation symbol */
354 static symbolS
*alpha_gp_symbol
;
356 /* XXX: what is this, and why is it exported? */
357 valueT alpha_gp_value
;
360 /* The current $gp register */
361 static int alpha_gp_register
= AXP_REG_GP
;
363 /* A table of the register symbols */
364 static symbolS
*alpha_register_table
[64];
366 /* Constant sections, or sections of constants */
368 static segT alpha_lita_section
;
369 static segT alpha_lit4_section
;
372 static segT alpha_link_section
;
373 static segT alpha_ctors_section
;
374 static segT alpha_dtors_section
;
376 static segT alpha_lit8_section
;
378 /* Symbols referring to said sections. */
380 static symbolS
*alpha_lita_symbol
;
381 static symbolS
*alpha_lit4_symbol
;
384 static symbolS
*alpha_link_symbol
;
385 static symbolS
*alpha_ctors_symbol
;
386 static symbolS
*alpha_dtors_symbol
;
388 static symbolS
*alpha_lit8_symbol
;
390 /* Literal for .litX+0x8000 within .lita */
392 static offsetT alpha_lit4_literal
;
393 static offsetT alpha_lit8_literal
;
396 /* The active .ent symbol. */
398 static symbolS
*alpha_cur_ent_sym
;
401 /* Is the assembler not allowed to use $at? */
402 static int alpha_noat_on
= 0;
404 /* Are macros enabled? */
405 static int alpha_macros_on
= 1;
407 /* Are floats disabled? */
408 static int alpha_nofloats_on
= 0;
410 /* Are addresses 32 bit? */
411 static int alpha_addr32_on
= 0;
413 /* Symbol labelling the current insn. When the Alpha gas sees
416 and the section happens to not be on an eight byte boundary, it
417 will align both the symbol and the .quad to an eight byte boundary. */
418 static symbolS
*alpha_insn_label
;
420 /* Whether we should automatically align data generation pseudo-ops.
421 .align 0 will turn this off. */
422 static int alpha_auto_align_on
= 1;
424 /* The known current alignment of the current section. */
425 static int alpha_current_align
;
427 /* These are exported to ECOFF code. */
428 unsigned long alpha_gprmask
, alpha_fprmask
;
430 /* Whether the debugging option was seen. */
431 static int alpha_debug
;
434 /* Whether we are emitting an mdebug section. */
435 int alpha_flag_mdebug
= 1;
438 /* Don't fully resolve relocations, allowing code movement in the linker. */
439 static int alpha_flag_relax
;
441 /* What value to give to bfd_set_gp_size. */
442 static int g_switch_value
= 8;
445 /* Collect information about current procedure here. */
447 symbolS
*symbol
; /* proc pdesc symbol */
449 int framereg
; /* register for frame pointer */
450 int framesize
; /* size of frame */
460 static int alpha_flag_hash_long_names
= 0; /* -+ */
461 static int alpha_flag_show_after_trunc
= 0; /* -H */
463 /* If the -+ switch is given, then a hash is appended to any name that is
464 * longer than 64 characters, else longer symbol names are truncated.
470 /* A table to map the spelling of a relocation operand into an appropriate
471 bfd_reloc_code_real_type type. The table is assumed to be ordered such
472 that op-O_literal indexes into it. */
474 #define ALPHA_RELOC_TABLE(op) \
475 &alpha_reloc_op[ ((!USER_RELOC_P (op)) \
477 : (int)(op) - (int)O_literal) ]
479 #define LITUSE_BASE 1
480 #define LITUSE_BYTOFF 2
483 static const struct alpha_reloc_op_tag
{
484 const char *name
; /* string to lookup */
485 size_t length
; /* size of the string */
486 bfd_reloc_code_real_type reloc
; /* relocation before frob */
487 operatorT op
; /* which operator to use */
488 int lituse
; /* addened to specify lituse */
489 } alpha_reloc_op
[] = {
492 "literal", /* name */
493 sizeof ("literal")-1, /* length */
494 BFD_RELOC_ALPHA_USER_LITERAL
, /* reloc */
500 "lituse_base", /* name */
501 sizeof ("lituse_base")-1, /* length */
502 BFD_RELOC_ALPHA_USER_LITUSE_BASE
, /* reloc */
503 O_lituse_base
, /* op */
504 LITUSE_BASE
, /* lituse */
508 "lituse_bytoff", /* name */
509 sizeof ("lituse_bytoff")-1, /* length */
510 BFD_RELOC_ALPHA_USER_LITUSE_BYTOFF
, /* reloc */
511 O_lituse_bytoff
, /* op */
512 LITUSE_BYTOFF
, /* lituse */
516 "lituse_jsr", /* name */
517 sizeof ("lituse_jsr")-1, /* length */
518 BFD_RELOC_ALPHA_USER_LITUSE_JSR
, /* reloc */
519 O_lituse_jsr
, /* op */
520 LITUSE_JSR
, /* lituse */
525 sizeof ("gpdisp")-1, /* length */
526 BFD_RELOC_ALPHA_USER_GPDISP
, /* reloc */
532 "gprelhigh", /* name */
533 sizeof ("gprelhigh")-1, /* length */
534 BFD_RELOC_ALPHA_USER_GPRELHIGH
, /* reloc */
535 O_gprelhigh
, /* op */
540 "gprellow", /* name */
541 sizeof ("gprellow")-1, /* length */
542 BFD_RELOC_ALPHA_USER_GPRELLOW
, /* reloc */
548 static const int alpha_num_reloc_op
549 = sizeof(alpha_reloc_op
) / sizeof(*alpha_reloc_op
);
551 /* Maximum # digits needed to hold the largest sequence # */
552 #define ALPHA_RELOC_DIGITS 25
554 /* Whether a sequence number is valid. */
555 #define ALPHA_RELOC_SEQUENCE_OK(X) ((X) > 0 && ((unsigned)(X)) == (X))
557 /* Structure to hold explict sequence information. */
558 struct alpha_literal_tag
560 fixS
*lituse
; /* head of linked list of !literals */
561 segT segment
; /* segment relocs are in or undefined_section*/
562 int multi_section_p
; /* True if more than one section was used */
563 unsigned sequence
; /* sequence # */
564 unsigned n_literals
; /* # of literals */
565 unsigned n_lituses
; /* # of lituses */
566 char string
[1]; /* printable form of sequence to hash with */
569 /* Hash table to link up literals with the appropriate lituse */
570 static struct hash_control
*alpha_literal_hash
;
573 /* A table of CPU names and opcode sets. */
575 static const struct cpu_type
581 /* Ad hoc convention: cpu number gets palcode, process code doesn't.
582 This supports usage under DU 4.0b that does ".arch ev4", and
583 usage in MILO that does -m21064. Probably something more
584 specific like -m21064-pal should be used, but oh well. */
586 { "21064", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
587 { "21064a", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
588 { "21066", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
589 { "21068", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
590 { "21164", AXP_OPCODE_BASE
|AXP_OPCODE_EV5
},
591 { "21164a", AXP_OPCODE_BASE
|AXP_OPCODE_EV5
|AXP_OPCODE_BWX
},
592 { "21164pc", (AXP_OPCODE_BASE
|AXP_OPCODE_EV5
|AXP_OPCODE_BWX
594 { "21264", (AXP_OPCODE_BASE
|AXP_OPCODE_EV6
|AXP_OPCODE_BWX
595 |AXP_OPCODE_MAX
|AXP_OPCODE_CIX
) },
597 { "ev4", AXP_OPCODE_BASE
},
598 { "ev45", AXP_OPCODE_BASE
},
599 { "lca45", AXP_OPCODE_BASE
},
600 { "ev5", AXP_OPCODE_BASE
},
601 { "ev56", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
},
602 { "pca56", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
|AXP_OPCODE_MAX
},
603 { "ev6", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
|AXP_OPCODE_MAX
|AXP_OPCODE_CIX
},
605 { "all", AXP_OPCODE_BASE
},
609 /* The macro table */
611 static const struct alpha_macro alpha_macros
[] = {
612 /* Load/Store macros */
613 { "lda", emit_lda
, NULL
,
614 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_LITERAL
, MACRO_BASE
, MACRO_EOA
} },
615 { "ldah", emit_ldah
, NULL
,
616 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
618 { "ldl", emit_ir_load
, "ldl",
619 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
620 { "ldl_l", emit_ir_load
, "ldl_l",
621 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
622 { "ldq", emit_ir_load
, "ldq",
623 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_LITERAL
, MACRO_EOA
} },
624 { "ldq_l", emit_ir_load
, "ldq_l",
625 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
626 { "ldq_u", emit_ir_load
, "ldq_u",
627 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
628 { "ldf", emit_loadstore
, "ldf",
629 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
630 { "ldg", emit_loadstore
, "ldg",
631 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
632 { "lds", emit_loadstore
, "lds",
633 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
634 { "ldt", emit_loadstore
, "ldt",
635 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
637 { "ldb", emit_ldX
, (PTR
)0,
638 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
639 { "ldbu", emit_ldXu
, (PTR
)0,
640 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
641 { "ldw", emit_ldX
, (PTR
)1,
642 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
643 { "ldwu", emit_ldXu
, (PTR
)1,
644 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
646 { "uldw", emit_uldX
, (PTR
)1,
647 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
648 { "uldwu", emit_uldXu
, (PTR
)1,
649 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
650 { "uldl", emit_uldX
, (PTR
)2,
651 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
652 { "uldlu", emit_uldXu
, (PTR
)2,
653 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
654 { "uldq", emit_uldXu
, (PTR
)3,
655 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
657 { "ldgp", emit_ldgp
, NULL
,
658 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
} },
660 { "ldi", emit_lda
, NULL
,
661 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
662 { "ldil", emit_ldil
, NULL
,
663 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
664 { "ldiq", emit_lda
, NULL
,
665 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
667 { "ldif" emit_ldiq
, NULL
,
668 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
669 { "ldid" emit_ldiq
, NULL
,
670 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
671 { "ldig" emit_ldiq
, NULL
,
672 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
673 { "ldis" emit_ldiq
, NULL
,
674 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
675 { "ldit" emit_ldiq
, NULL
,
676 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
679 { "stl", emit_loadstore
, "stl",
680 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
681 { "stl_c", emit_loadstore
, "stl_c",
682 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
683 { "stq", emit_loadstore
, "stq",
684 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
685 { "stq_c", emit_loadstore
, "stq_c",
686 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
687 { "stq_u", emit_loadstore
, "stq_u",
688 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
689 { "stf", emit_loadstore
, "stf",
690 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
691 { "stg", emit_loadstore
, "stg",
692 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
693 { "sts", emit_loadstore
, "sts",
694 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
695 { "stt", emit_loadstore
, "stt",
696 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
698 { "stb", emit_stX
, (PTR
)0,
699 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
700 { "stw", emit_stX
, (PTR
)1,
701 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
702 { "ustw", emit_ustX
, (PTR
)1,
703 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
704 { "ustl", emit_ustX
, (PTR
)2,
705 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
706 { "ustq", emit_ustX
, (PTR
)3,
707 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
709 /* Arithmetic macros */
711 { "absl" emit_absl
, 1, { IR
} },
712 { "absl" emit_absl
, 2, { IR
, IR
} },
713 { "absl" emit_absl
, 2, { EXP
, IR
} },
714 { "absq" emit_absq
, 1, { IR
} },
715 { "absq" emit_absq
, 2, { IR
, IR
} },
716 { "absq" emit_absq
, 2, { EXP
, IR
} },
719 { "sextb", emit_sextX
, (PTR
)0,
720 { MACRO_IR
, MACRO_IR
, MACRO_EOA
,
722 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
723 { "sextw", emit_sextX
, (PTR
)1,
724 { MACRO_IR
, MACRO_IR
, MACRO_EOA
,
726 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
728 { "divl", emit_division
, "__divl",
729 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
730 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
731 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
732 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
733 { "divlu", emit_division
, "__divlu",
734 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
735 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
736 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
737 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
738 { "divq", emit_division
, "__divq",
739 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
740 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
741 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
742 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
743 { "divqu", emit_division
, "__divqu",
744 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
745 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
746 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
747 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
748 { "reml", emit_division
, "__reml",
749 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
750 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
751 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
752 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
753 { "remlu", emit_division
, "__remlu",
754 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
755 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
756 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
757 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
758 { "remq", emit_division
, "__remq",
759 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
760 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
761 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
762 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
763 { "remqu", emit_division
, "__remqu",
764 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
765 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
766 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
767 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
769 { "jsr", emit_jsrjmp
, "jsr",
770 { MACRO_PIR
, MACRO_EXP
, MACRO_JSR
, MACRO_EOA
,
771 MACRO_PIR
, MACRO_JSR
, MACRO_EOA
,
772 MACRO_IR
, MACRO_EXP
, MACRO_JSR
, MACRO_EOA
,
773 MACRO_EXP
, MACRO_JSR
, MACRO_EOA
} },
774 { "jmp", emit_jsrjmp
, "jmp",
775 { MACRO_PIR
, MACRO_EXP
, MACRO_JSR
, MACRO_EOA
,
776 MACRO_PIR
, MACRO_JSR
, MACRO_EOA
,
777 MACRO_IR
, MACRO_EXP
, MACRO_JSR
, MACRO_EOA
,
778 MACRO_EXP
, MACRO_JSR
, MACRO_EOA
} },
779 { "ret", emit_retjcr
, "ret",
780 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
782 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
783 MACRO_PIR
, MACRO_EOA
,
784 MACRO_EXP
, MACRO_EOA
,
786 { "jcr", emit_retjcr
, "jcr",
787 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
789 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
790 MACRO_PIR
, MACRO_EOA
,
791 MACRO_EXP
, MACRO_EOA
,
793 { "jsr_coroutine", emit_retjcr
, "jcr",
794 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
796 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
797 MACRO_PIR
, MACRO_EOA
,
798 MACRO_EXP
, MACRO_EOA
,
802 static const unsigned int alpha_num_macros
803 = sizeof(alpha_macros
) / sizeof(*alpha_macros
);
805 /* Public interface functions */
807 /* This function is called once, at assembler startup time. It sets
808 up all the tables, etc. that the MD part of the assembler will
809 need, that can be determined before arguments are parsed. */
816 /* Verify that X_op field is wide enough. */
820 assert (e
.X_op
== O_max
);
823 /* Create the opcode hash table */
825 alpha_opcode_hash
= hash_new ();
826 for (i
= 0; i
< alpha_num_opcodes
; )
828 const char *name
, *retval
, *slash
;
830 name
= alpha_opcodes
[i
].name
;
831 retval
= hash_insert (alpha_opcode_hash
, name
, (PTR
)&alpha_opcodes
[i
]);
833 as_fatal (_("internal error: can't hash opcode `%s': %s"), name
, retval
);
835 /* Some opcodes include modifiers of various sorts with a "/mod"
836 syntax, like the architecture manual suggests. However, for
837 use with gcc at least, we also need access to those same opcodes
840 if ((slash
= strchr (name
, '/')) != NULL
)
842 char *p
= xmalloc (strlen (name
));
843 memcpy (p
, name
, slash
- name
);
844 strcpy (p
+ (slash
- name
), slash
+ 1);
846 (void)hash_insert(alpha_opcode_hash
, p
, (PTR
)&alpha_opcodes
[i
]);
847 /* Ignore failures -- the opcode table does duplicate some
848 variants in different forms, like "hw_stq" and "hw_st/q". */
851 while (++i
< alpha_num_opcodes
852 && (alpha_opcodes
[i
].name
== name
853 || !strcmp (alpha_opcodes
[i
].name
, name
)))
857 /* Create the macro hash table */
859 alpha_macro_hash
= hash_new ();
860 for (i
= 0; i
< alpha_num_macros
; )
862 const char *name
, *retval
;
864 name
= alpha_macros
[i
].name
;
865 retval
= hash_insert (alpha_macro_hash
, name
, (PTR
)&alpha_macros
[i
]);
867 as_fatal (_("internal error: can't hash macro `%s': %s"), name
, retval
);
869 while (++i
< alpha_num_macros
870 && (alpha_macros
[i
].name
== name
871 || !strcmp (alpha_macros
[i
].name
, name
)))
875 /* Construct symbols for each of the registers */
877 for (i
= 0; i
< 32; ++i
)
880 sprintf(name
, "$%d", i
);
881 alpha_register_table
[i
] = symbol_create(name
, reg_section
, i
,
887 sprintf(name
, "$f%d", i
-32);
888 alpha_register_table
[i
] = symbol_create(name
, reg_section
, i
,
892 /* Create the special symbols and sections we'll be using */
894 /* So .sbss will get used for tiny objects. */
895 bfd_set_gp_size (stdoutput
, g_switch_value
);
898 create_literal_section (".lita", &alpha_lita_section
, &alpha_lita_symbol
);
900 /* For handling the GP, create a symbol that won't be output in the
901 symbol table. We'll edit it out of relocs later. */
902 alpha_gp_symbol
= symbol_create ("<GP value>", alpha_lita_section
, 0x8000,
907 create_literal_section (".link", &alpha_link_section
, &alpha_link_symbol
);
913 segT sec
= subseg_new(".mdebug", (subsegT
)0);
914 bfd_set_section_flags(stdoutput
, sec
, SEC_HAS_CONTENTS
|SEC_READONLY
);
915 bfd_set_section_alignment(stdoutput
, sec
, 3);
919 subseg_set(text_section
, 0);
922 /* Create literal lookup hash table. */
923 alpha_literal_hash
= hash_new();
927 /* The public interface to the instruction assembler. */
933 char opname
[32]; /* current maximum is 13 */
934 expressionS tok
[MAX_INSN_ARGS
];
938 /* split off the opcode */
939 opnamelen
= strspn (str
, "abcdefghijklmnopqrstuvwxyz_/46819");
940 trunclen
= (opnamelen
< sizeof (opname
) - 1
942 : sizeof (opname
) - 1);
943 memcpy (opname
, str
, trunclen
);
944 opname
[trunclen
] = '\0';
946 /* tokenize the rest of the line */
947 if ((ntok
= tokenize_arguments (str
+ opnamelen
, tok
, MAX_INSN_ARGS
)) < 0)
949 if (ntok
!= TOKENIZE_ERROR_REPORT
)
950 as_bad (_("syntax error"));
956 assemble_tokens (opname
, tok
, ntok
, alpha_macros_on
);
959 /* Round up a section's size to the appropriate boundary. */
962 md_section_align (seg
, size
)
966 int align
= bfd_get_section_alignment(stdoutput
, seg
);
967 valueT mask
= ((valueT
)1 << align
) - 1;
969 return (size
+ mask
) & ~mask
;
972 /* Turn a string in input_line_pointer into a floating point constant
973 of type TYPE, and store the appropriate bytes in *LITP. The number
974 of LITTLENUMS emitted is stored in *SIZEP. An error message is
975 returned, or NULL on OK. */
977 /* Equal to MAX_PRECISION in atof-ieee.c */
978 #define MAX_LITTLENUMS 6
980 extern char *vax_md_atof
PARAMS ((int, char *, int *));
983 md_atof (type
, litP
, sizeP
)
989 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
990 LITTLENUM_TYPE
*wordP
;
997 /* VAX md_atof doesn't like "G" for some reason. */
1001 return vax_md_atof (type
, litP
, sizeP
);
1024 return _("Bad call to MD_ATOF()");
1026 t
= atof_ieee (input_line_pointer
, type
, words
);
1028 input_line_pointer
= t
;
1029 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
1031 for (wordP
= words
+ prec
- 1; prec
--;)
1033 md_number_to_chars (litP
, (long) (*wordP
--), sizeof (LITTLENUM_TYPE
));
1034 litP
+= sizeof (LITTLENUM_TYPE
);
1040 /* Take care of the target-specific command-line options. */
1043 md_parse_option (c
, arg
)
1050 alpha_nofloats_on
= 1;
1054 alpha_addr32_on
= 1;
1062 g_switch_value
= atoi(arg
);
1067 const struct cpu_type
*p
;
1068 for (p
= cpu_types
; p
->name
; ++p
)
1069 if (strcmp(arg
, p
->name
) == 0)
1071 alpha_target_name
= p
->name
, alpha_target
= p
->flags
;
1074 as_warn(_("Unknown CPU identifier `%s'"), arg
);
1080 case '+': /* For g++. Hash any name > 63 chars long. */
1081 alpha_flag_hash_long_names
= 1;
1084 case 'H': /* Show new symbol after hash truncation */
1085 alpha_flag_show_after_trunc
= 1;
1088 case 'h': /* for gnu-c/vax compatibility. */
1093 alpha_flag_relax
= 1;
1098 alpha_flag_mdebug
= 1;
1100 case OPTION_NO_MDEBUG
:
1101 alpha_flag_mdebug
= 0;
1112 /* Print a description of the command-line options that we accept. */
1115 md_show_usage (stream
)
1120 -32addr treat addresses as 32-bit values\n\
1121 -F lack floating point instructions support\n\
1122 -mev4 | -mev45 | -mev5 | -mev56 | -mpca56 | -mev6 | -mall\n\
1123 specify variant of Alpha architecture\n\
1124 -m21064 | -m21066 | -m21164 | -m21164a | -m21164pc | -m21264\n\
1125 these variants include PALcode opcodes\n"),
1130 -+ hash encode (don't truncate) names longer than 64 characters\n\
1131 -H show new symbol after hash truncation\n"),
1136 /* Decide from what point a pc-relative relocation is relative to,
1137 relative to the pc-relative fixup. Er, relatively speaking. */
1140 md_pcrel_from (fixP
)
1143 valueT addr
= fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
1144 switch (fixP
->fx_r_type
)
1146 case BFD_RELOC_ALPHA_GPDISP
:
1147 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1148 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1151 return fixP
->fx_size
+ addr
;
1155 /* Attempt to simplify or even eliminate a fixup. The return value is
1156 ignored; perhaps it was once meaningful, but now it is historical.
1157 To indicate that a fixup has been eliminated, set fixP->fx_done.
1159 For ELF, here it is that we transform the GPDISP_HI16 reloc we used
1160 internally into the GPDISP reloc used externally. We had to do
1161 this so that we'd have the GPDISP_LO16 reloc as a tag to compute
1162 the distance to the "lda" instruction for setting the addend to
1166 md_apply_fix (fixP
, valueP
)
1170 char * const fixpos
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
1171 valueT value
= *valueP
;
1172 unsigned image
, size
;
1174 switch (fixP
->fx_r_type
)
1176 /* The GPDISP relocations are processed internally with a symbol
1177 referring to the current function; we need to drop in a value
1178 which, when added to the address of the start of the function,
1179 gives the desired GP. */
1180 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1182 fixS
*next
= fixP
->fx_next
;
1183 assert (next
->fx_r_type
== BFD_RELOC_ALPHA_GPDISP_LO16
);
1185 fixP
->fx_offset
= (next
->fx_frag
->fr_address
+ next
->fx_where
1186 - fixP
->fx_frag
->fr_address
- fixP
->fx_where
);
1188 value
= (value
- sign_extend_16 (value
)) >> 16;
1191 fixP
->fx_r_type
= BFD_RELOC_ALPHA_GPDISP
;
1195 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1196 value
= sign_extend_16 (value
);
1197 fixP
->fx_offset
= 0;
1203 fixP
->fx_addsy
= section_symbol (now_seg
);
1204 md_number_to_chars (fixpos
, value
, 2);
1209 fixP
->fx_r_type
= BFD_RELOC_16_PCREL
;
1214 fixP
->fx_r_type
= BFD_RELOC_32_PCREL
;
1219 fixP
->fx_r_type
= BFD_RELOC_64_PCREL
;
1222 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
1224 md_number_to_chars (fixpos
, value
, size
);
1230 case BFD_RELOC_GPREL32
:
1231 assert (fixP
->fx_subsy
== alpha_gp_symbol
);
1233 /* FIXME: inherited this obliviousness of `value' -- why? */
1234 md_number_to_chars (fixpos
, -alpha_gp_value
, 4);
1238 case BFD_RELOC_GPREL32
:
1242 case BFD_RELOC_23_PCREL_S2
:
1243 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
1245 image
= bfd_getl32(fixpos
);
1246 image
= (image
& ~0x1FFFFF) | ((value
>> 2) & 0x1FFFFF);
1251 case BFD_RELOC_ALPHA_HINT
:
1252 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
1254 image
= bfd_getl32(fixpos
);
1255 image
= (image
& ~0x3FFF) | ((value
>> 2) & 0x3FFF);
1261 case BFD_RELOC_ALPHA_LITERAL
:
1262 md_number_to_chars (fixpos
, value
, 2);
1265 case BFD_RELOC_ALPHA_LITUSE
:
1269 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1270 case BFD_RELOC_ALPHA_LITUSE
:
1274 case BFD_RELOC_ALPHA_LINKAGE
:
1275 case BFD_RELOC_ALPHA_CODEADDR
:
1280 case BFD_RELOC_ALPHA_USER_LITERAL
:
1281 case BFD_RELOC_ALPHA_USER_LITUSE_BASE
:
1282 case BFD_RELOC_ALPHA_USER_LITUSE_BYTOFF
:
1283 case BFD_RELOC_ALPHA_USER_LITUSE_JSR
:
1286 case BFD_RELOC_ALPHA_USER_GPDISP
:
1287 case BFD_RELOC_ALPHA_USER_GPRELHIGH
:
1288 case BFD_RELOC_ALPHA_USER_GPRELLOW
:
1294 const struct alpha_operand
*operand
;
1296 if ((int)fixP
->fx_r_type
>= 0)
1297 as_fatal (_("unhandled relocation type %s"),
1298 bfd_get_reloc_code_name (fixP
->fx_r_type
));
1300 assert (-(int)fixP
->fx_r_type
< (int)alpha_num_operands
);
1301 operand
= &alpha_operands
[-(int)fixP
->fx_r_type
];
1303 /* The rest of these fixups only exist internally during symbol
1304 resolution and have no representation in the object file.
1305 Therefore they must be completely resolved as constants. */
1307 if (fixP
->fx_addsy
!= 0
1308 && S_GET_SEGMENT (fixP
->fx_addsy
) != absolute_section
)
1309 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
1310 _("non-absolute expression in constant field"));
1312 image
= bfd_getl32(fixpos
);
1313 image
= insert_operand(image
, operand
, (offsetT
)value
,
1314 fixP
->fx_file
, fixP
->fx_line
);
1319 if (fixP
->fx_addsy
!= 0 || fixP
->fx_pcrel
!= 0)
1323 as_warn_where(fixP
->fx_file
, fixP
->fx_line
,
1324 _("type %d reloc done?\n"), (int)fixP
->fx_r_type
);
1329 md_number_to_chars(fixpos
, image
, 4);
1337 * Look for a register name in the given symbol.
1341 md_undefined_symbol(name
)
1346 int is_float
= 0, num
;
1351 if (name
[1] == 'p' && name
[2] == '\0')
1352 return alpha_register_table
[AXP_REG_FP
];
1357 if (!isdigit(*++name
))
1361 case '0': case '1': case '2': case '3': case '4':
1362 case '5': case '6': case '7': case '8': case '9':
1363 if (name
[1] == '\0')
1364 num
= name
[0] - '0';
1365 else if (name
[0] != '0' && isdigit(name
[1]) && name
[2] == '\0')
1367 num
= (name
[0] - '0') * 10 + name
[1] - '0';
1374 if (!alpha_noat_on
&& (num
+ is_float
) == AXP_REG_AT
)
1375 as_warn(_("Used $at without \".set noat\""));
1376 return alpha_register_table
[num
+ is_float
];
1379 if (name
[1] == 't' && name
[2] == '\0')
1382 as_warn(_("Used $at without \".set noat\""));
1383 return alpha_register_table
[AXP_REG_AT
];
1388 if (name
[1] == 'p' && name
[2] == '\0')
1389 return alpha_register_table
[alpha_gp_register
];
1393 if (name
[1] == 'p' && name
[2] == '\0')
1394 return alpha_register_table
[AXP_REG_SP
];
1402 /* @@@ Magic ECOFF bits. */
1405 alpha_frob_ecoff_data ()
1408 /* $zero and $f31 are read-only */
1409 alpha_gprmask
&= ~1;
1410 alpha_fprmask
&= ~1;
1414 /* Hook to remember a recently defined label so that the auto-align
1415 code can adjust the symbol after we know what alignment will be
1419 alpha_define_label (sym
)
1422 alpha_insn_label
= sym
;
1425 /* Return true if we must always emit a reloc for a type and false if
1426 there is some hope of resolving it a assembly time. */
1429 alpha_force_relocation (f
)
1432 if (alpha_flag_relax
)
1435 switch (f
->fx_r_type
)
1437 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1438 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1439 case BFD_RELOC_ALPHA_GPDISP
:
1441 case BFD_RELOC_ALPHA_LITERAL
:
1444 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1446 case BFD_RELOC_ALPHA_LITUSE
:
1447 case BFD_RELOC_GPREL32
:
1449 case BFD_RELOC_ALPHA_LINKAGE
:
1450 case BFD_RELOC_ALPHA_CODEADDR
:
1453 case BFD_RELOC_ALPHA_USER_LITERAL
:
1454 case BFD_RELOC_ALPHA_USER_LITUSE_BASE
:
1455 case BFD_RELOC_ALPHA_USER_LITUSE_BYTOFF
:
1456 case BFD_RELOC_ALPHA_USER_LITUSE_JSR
:
1457 case BFD_RELOC_ALPHA_USER_GPDISP
:
1458 case BFD_RELOC_ALPHA_USER_GPRELHIGH
:
1459 case BFD_RELOC_ALPHA_USER_GPRELLOW
:
1463 case BFD_RELOC_23_PCREL_S2
:
1466 case BFD_RELOC_ALPHA_HINT
:
1470 assert((int)f
->fx_r_type
< 0 && -(int)f
->fx_r_type
< (int)alpha_num_operands
);
1475 /* Return true if we can partially resolve a relocation now. */
1478 alpha_fix_adjustable (f
)
1482 /* Prevent all adjustments to global symbols */
1483 if (S_IS_EXTERN (f
->fx_addsy
) || S_IS_WEAK (f
->fx_addsy
))
1487 /* Are there any relocation types for which we must generate a reloc
1488 but we can adjust the values contained within it? */
1489 switch (f
->fx_r_type
)
1491 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1492 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1493 case BFD_RELOC_ALPHA_GPDISP
:
1497 case BFD_RELOC_ALPHA_LITERAL
:
1500 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1503 case BFD_RELOC_ALPHA_USER_LITERAL
:
1506 case BFD_RELOC_ALPHA_LINKAGE
:
1507 case BFD_RELOC_ALPHA_CODEADDR
:
1511 case BFD_RELOC_ALPHA_LITUSE
:
1513 case BFD_RELOC_ALPHA_USER_LITUSE_BASE
:
1514 case BFD_RELOC_ALPHA_USER_LITUSE_BYTOFF
:
1515 case BFD_RELOC_ALPHA_USER_LITUSE_JSR
:
1516 case BFD_RELOC_ALPHA_USER_GPDISP
:
1517 case BFD_RELOC_ALPHA_USER_GPRELHIGH
:
1518 case BFD_RELOC_ALPHA_USER_GPRELLOW
:
1522 case BFD_RELOC_GPREL32
:
1523 case BFD_RELOC_23_PCREL_S2
:
1526 case BFD_RELOC_ALPHA_HINT
:
1530 assert ((int)f
->fx_r_type
< 0
1531 && - (int)f
->fx_r_type
< (int)alpha_num_operands
);
1537 /* Generate the BFD reloc to be stuck in the object file from the
1538 fixup used internally in the assembler. */
1541 tc_gen_reloc (sec
, fixp
)
1542 asection
*sec ATTRIBUTE_UNUSED
;
1547 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
1548 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
1549 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
1550 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
1552 /* Make sure none of our internal relocations make it this far.
1553 They'd better have been fully resolved by this point. */
1554 assert ((int)fixp
->fx_r_type
> 0);
1556 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
1557 if (reloc
->howto
== NULL
)
1559 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1560 _("cannot represent `%s' relocation in object file"),
1561 bfd_get_reloc_code_name (fixp
->fx_r_type
));
1565 if (!fixp
->fx_pcrel
!= !reloc
->howto
->pc_relative
)
1567 as_fatal (_("internal error? cannot generate `%s' relocation"),
1568 bfd_get_reloc_code_name (fixp
->fx_r_type
));
1570 assert (!fixp
->fx_pcrel
== !reloc
->howto
->pc_relative
);
1573 if (fixp
->fx_r_type
== BFD_RELOC_ALPHA_LITERAL
)
1575 /* fake out bfd_perform_relocation. sigh */
1576 reloc
->addend
= -alpha_gp_value
;
1581 reloc
->addend
= fixp
->fx_offset
;
1584 * Ohhh, this is ugly. The problem is that if this is a local global
1585 * symbol, the relocation will entirely be performed at link time, not
1586 * at assembly time. bfd_perform_reloc doesn't know about this sort
1587 * of thing, and as a result we need to fake it out here.
1589 if ((S_IS_EXTERN (fixp
->fx_addsy
) || S_IS_WEAK (fixp
->fx_addsy
))
1590 && !S_IS_COMMON(fixp
->fx_addsy
))
1591 reloc
->addend
-= symbol_get_bfdsym (fixp
->fx_addsy
)->value
;
1598 /* Parse a register name off of the input_line and return a register
1599 number. Gets md_undefined_symbol above to do the register name
1602 Only called as a part of processing the ECOFF .frame directive. */
1605 tc_get_register (frame
)
1606 int frame ATTRIBUTE_UNUSED
;
1608 int framereg
= AXP_REG_SP
;
1611 if (*input_line_pointer
== '$')
1613 char *s
= input_line_pointer
;
1614 char c
= get_symbol_end ();
1615 symbolS
*sym
= md_undefined_symbol (s
);
1617 *strchr(s
, '\0') = c
;
1618 if (sym
&& (framereg
= S_GET_VALUE (sym
)) <= 31)
1621 as_warn (_("frame reg expected, using $%d."), framereg
);
1624 note_gpreg (framereg
);
1628 /* This is called before the symbol table is processed. In order to
1629 work with gcc when using mips-tfile, we must keep all local labels.
1630 However, in other cases, we want to discard them. If we were
1631 called with -g, but we didn't see any debugging information, it may
1632 mean that gcc is smuggling debugging information through to
1633 mips-tfile, in which case we must generate all local labels. */
1638 alpha_frob_file_before_adjust ()
1640 if (alpha_debug
!= 0
1641 && ! ecoff_debugging_seen
)
1642 flag_keep_locals
= 1;
1645 #endif /* OBJ_ECOFF */
1649 /* Before the relocations are written, reorder them, so that user supplied
1650 !lituse relocations follow the appropriate !literal relocations. Also
1651 convert the gas-internal relocations to the appropriate linker relocations.
1655 alpha_adjust_symtab ()
1657 if (alpha_literal_hash
)
1660 fprintf (stderr
, "alpha_adjust_symtab called\n");
1663 /* Go over each section, reordering the relocations so that all of the
1664 explicit LITUSE's are adjacent to the explicit LITERAL's */
1665 bfd_map_over_sections (stdoutput
, alpha_adjust_symtab_relocs
, (char *) 0);
1670 /* Inner function to move LITUSE's next to the LITERAL. */
1673 alpha_adjust_symtab_relocs (abfd
, sec
, ptr
)
1678 segment_info_type
*seginfo
= seg_info (sec
);
1688 int n_dup_literals
= 0;
1691 /* If seginfo is NULL, we did not create this section; don't do anything with
1692 it. By using a pointer to a pointer, we can update the links in place. */
1693 if (seginfo
== NULL
)
1696 /* If there are no relocations, skip the section. */
1697 if (! seginfo
->fix_root
)
1700 /* First rebuild the fixup chain without the expicit lituse's. */
1701 prevP
= &(seginfo
->fix_root
);
1702 for (fixp
= seginfo
->fix_root
; fixp
; fixp
= next
)
1704 next
= fixp
->fx_next
;
1705 fixp
->fx_next
= (fixS
*)0;
1710 switch (fixp
->fx_r_type
)
1714 prevP
= &(fixp
->fx_next
);
1717 "alpha_adjust_symtab_relocs: 0x%lx, other relocation %s\n",
1719 bfd_get_reloc_code_name (fixp
->fx_r_type
));
1723 case BFD_RELOC_ALPHA_USER_LITERAL
:
1725 prevP
= &(fixp
->fx_next
);
1726 /* prevent assembler from trying to adjust the offset */
1729 if (fixp
->tc_fix_data
.info
->n_literals
!= 1)
1732 "alpha_adjust_symtab_relocs: 0x%lx, !literal!%.6d, # literals = %2d\n",
1734 fixp
->tc_fix_data
.info
->sequence
,
1735 fixp
->tc_fix_data
.info
->n_literals
);
1739 /* do not link in lituse's */
1740 case BFD_RELOC_ALPHA_USER_LITUSE_BASE
:
1741 case BFD_RELOC_ALPHA_USER_LITUSE_BYTOFF
:
1742 case BFD_RELOC_ALPHA_USER_LITUSE_JSR
:
1744 if (fixp
->tc_fix_data
.info
->n_literals
== 0)
1745 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1746 _("No !literal!%d was found"),
1747 fixp
->tc_fix_data
.info
->sequence
);
1750 "alpha_adjust_symtab_relocs: 0x%lx, !lituse !%.6d, # lituses = %2d, next_lituse = 0x%lx\n",
1752 fixp
->tc_fix_data
.info
->sequence
,
1753 fixp
->tc_fix_data
.info
->n_lituses
,
1754 (long)fixp
->tc_fix_data
.next_lituse
);
1760 /* If there were any lituses, go and add them to the chain, unless there is
1761 more than one !literal for a given sequence number. They are linked
1762 through the next_lituse field in reverse order, so as we go through the
1763 next_lituse chain, we effectively reverse the chain once again. If there
1764 was more than one !literal, we fall back to loading up the address w/o
1765 optimization. Also, if the !literals/!lituses are spread in different
1766 segments (happens in the Linux kernel semaphores), suppress the
1770 for (fixp
= seginfo
->fix_root
; fixp
; fixp
= fixp
->fx_next
)
1772 switch (fixp
->fx_r_type
)
1777 case BFD_RELOC_ALPHA_USER_LITERAL
:
1779 fixp
->fx_r_type
= BFD_RELOC_ALPHA_ELF_LITERAL
;
1781 fixp
->fx_r_type
= BFD_RELOC_ALPHA_LITERAL
; /* XXX check this */
1783 if (fixp
->tc_fix_data
.info
->n_literals
== 1
1784 && ! fixp
->tc_fix_data
.info
->multi_section_p
)
1786 for (lituse
= fixp
->tc_fix_data
.info
->lituse
;
1787 lituse
!= (fixS
*)0;
1788 lituse
= lituse
->tc_fix_data
.next_lituse
)
1790 lituse
->fx_next
= fixp
->fx_next
;
1791 fixp
->fx_next
= lituse
;
1796 case BFD_RELOC_ALPHA_USER_LITUSE_BASE
:
1797 case BFD_RELOC_ALPHA_USER_LITUSE_BYTOFF
:
1798 case BFD_RELOC_ALPHA_USER_LITUSE_JSR
:
1799 fixp
->fx_r_type
= BFD_RELOC_ALPHA_LITUSE
;
1806 fprintf (stderr
, "alpha_adjust_symtab_relocs: %s, %d literal%s, %d duplicate literal%s, %d lituse%s\n\n",
1808 n_literals
, (n_literals
== 1) ? "" : "s",
1809 n_dup_literals
, (n_dup_literals
== 1) ? "" : "s",
1810 n_lituses
, (n_lituses
== 1) ? "" : "s");
1814 #endif /* RELOC_OP_P */
1819 debug_exp (tok
, ntok
)
1825 fprintf (stderr
, "debug_exp: %d tokens", ntok
);
1826 for (i
= 0; i
< ntok
; i
++)
1828 expressionS
*t
= &tok
[i
];
1832 default: name
= "unknown"; break;
1833 case O_illegal
: name
= "O_illegal"; break;
1834 case O_absent
: name
= "O_absent"; break;
1835 case O_constant
: name
= "O_constant"; break;
1836 case O_symbol
: name
= "O_symbol"; break;
1837 case O_symbol_rva
: name
= "O_symbol_rva"; break;
1838 case O_register
: name
= "O_register"; break;
1839 case O_big
: name
= "O_big"; break;
1840 case O_uminus
: name
= "O_uminus"; break;
1841 case O_bit_not
: name
= "O_bit_not"; break;
1842 case O_logical_not
: name
= "O_logical_not"; break;
1843 case O_multiply
: name
= "O_multiply"; break;
1844 case O_divide
: name
= "O_divide"; break;
1845 case O_modulus
: name
= "O_modulus"; break;
1846 case O_left_shift
: name
= "O_left_shift"; break;
1847 case O_right_shift
: name
= "O_right_shift"; break;
1848 case O_bit_inclusive_or
: name
= "O_bit_inclusive_or"; break;
1849 case O_bit_or_not
: name
= "O_bit_or_not"; break;
1850 case O_bit_exclusive_or
: name
= "O_bit_exclusive_or"; break;
1851 case O_bit_and
: name
= "O_bit_and"; break;
1852 case O_add
: name
= "O_add"; break;
1853 case O_subtract
: name
= "O_subtract"; break;
1854 case O_eq
: name
= "O_eq"; break;
1855 case O_ne
: name
= "O_ne"; break;
1856 case O_lt
: name
= "O_lt"; break;
1857 case O_le
: name
= "O_le"; break;
1858 case O_ge
: name
= "O_ge"; break;
1859 case O_gt
: name
= "O_gt"; break;
1860 case O_logical_and
: name
= "O_logical_and"; break;
1861 case O_logical_or
: name
= "O_logical_or"; break;
1862 case O_index
: name
= "O_index"; break;
1863 case O_pregister
: name
= "O_pregister"; break;
1864 case O_cpregister
: name
= "O_cpregister"; break;
1865 case O_literal
: name
= "O_literal"; break;
1866 case O_lituse_base
: name
= "O_lituse_base"; break;
1867 case O_lituse_bytoff
: name
= "O_lituse_bytoff"; break;
1868 case O_lituse_jsr
: name
= "O_lituse_jsr"; break;
1869 case O_gpdisp
: name
= "O_gpdisp"; break;
1870 case O_gprelhigh
: name
= "O_gprelhigh"; break;
1871 case O_gprellow
: name
= "O_gprellow"; break;
1872 case O_md10
: name
= "O_md10"; break;
1873 case O_md11
: name
= "O_md11"; break;
1874 case O_md12
: name
= "O_md12"; break;
1875 case O_md13
: name
= "O_md13"; break;
1876 case O_md14
: name
= "O_md14"; break;
1877 case O_md15
: name
= "O_md15"; break;
1878 case O_md16
: name
= "O_md16"; break;
1881 fprintf (stderr
, ", %s(%s, %s, %d)", name
,
1882 (t
->X_add_symbol
) ? S_GET_NAME (t
->X_add_symbol
) : "--",
1883 (t
->X_op_symbol
) ? S_GET_NAME (t
->X_op_symbol
) : "--",
1884 (int)t
->X_add_number
);
1886 fprintf (stderr
, "\n");
1891 /* Parse the arguments to an opcode. */
1894 tokenize_arguments (str
, tok
, ntok
)
1899 expressionS
*end_tok
= tok
+ ntok
;
1900 char *old_input_line_pointer
;
1901 int saw_comma
= 0, saw_arg
= 0;
1903 expressionS
*orig_tok
= tok
;
1907 const struct alpha_reloc_op_tag
*r
;
1910 int reloc_found_p
= 0;
1913 memset (tok
, 0, sizeof (*tok
) * ntok
);
1915 /* Save and restore input_line_pointer around this function */
1916 old_input_line_pointer
= input_line_pointer
;
1917 input_line_pointer
= str
;
1919 while (tok
< end_tok
&& *input_line_pointer
)
1922 switch (*input_line_pointer
)
1929 /* A relocation operand can be placed after the normal operand on an
1930 assembly language statement, and has the following form:
1931 !relocation_type!sequence_number. */
1933 { /* only support one relocation op per insn */
1934 as_bad (_("More than one relocation op per insn"));
1941 for (p
= ++input_line_pointer
;
1942 ((c
= *p
) != '!' && c
!= ';' && c
!= '#' && c
!= ','
1943 && !is_end_of_line
[c
]);
1947 /* Parse !relocation_type */
1948 len
= p
- input_line_pointer
;
1951 as_bad (_("No relocation operand"));
1957 as_bad (_("No !sequence-number after !%s"), input_line_pointer
);
1961 r
= &alpha_reloc_op
[0];
1962 for (i
= alpha_num_reloc_op
-1; i
>= 0; i
--, r
++)
1964 if (len
== r
->length
1965 && memcmp (input_line_pointer
, r
->name
, len
) == 0)
1970 as_bad (_("Unknown relocation operand: !%s"), input_line_pointer
);
1974 input_line_pointer
= ++p
;
1976 /* Parse !sequence_number */
1977 memset (tok
, '\0', sizeof (expressionS
));
1980 if (tok
->X_op
!= O_constant
1981 || ! ALPHA_RELOC_SEQUENCE_OK (tok
->X_add_number
))
1983 as_bad (_("Bad sequence number: !%s!%s"), r
->name
, input_line_pointer
);
1994 ++input_line_pointer
;
1995 if (saw_comma
|| !saw_arg
)
2002 char *hold
= input_line_pointer
++;
2004 /* First try for parenthesized register ... */
2006 if (*input_line_pointer
== ')' && tok
->X_op
== O_register
)
2008 tok
->X_op
= (saw_comma
? O_cpregister
: O_pregister
);
2011 ++input_line_pointer
;
2016 /* ... then fall through to plain expression */
2017 input_line_pointer
= hold
;
2021 if (saw_arg
&& !saw_comma
)
2025 if (tok
->X_op
== O_illegal
|| tok
->X_op
== O_absent
)
2038 input_line_pointer
= old_input_line_pointer
;
2041 debug_exp (orig_tok
, ntok
- (end_tok
- tok
));
2044 return ntok
- (end_tok
- tok
);
2047 input_line_pointer
= old_input_line_pointer
;
2048 return TOKENIZE_ERROR
;
2052 input_line_pointer
= old_input_line_pointer
;
2053 return TOKENIZE_ERROR_REPORT
;
2057 /* Search forward through all variants of an opcode looking for a
2060 static const struct alpha_opcode
*
2061 find_opcode_match(first_opcode
, tok
, pntok
, pcpumatch
)
2062 const struct alpha_opcode
*first_opcode
;
2063 const expressionS
*tok
;
2067 const struct alpha_opcode
*opcode
= first_opcode
;
2069 int got_cpu_match
= 0;
2073 const unsigned char *opidx
;
2076 /* Don't match opcodes that don't exist on this architecture */
2077 if (!(opcode
->flags
& alpha_target
))
2082 for (opidx
= opcode
->operands
; *opidx
; ++opidx
)
2084 const struct alpha_operand
*operand
= &alpha_operands
[*opidx
];
2086 /* only take input from real operands */
2087 if (operand
->flags
& AXP_OPERAND_FAKE
)
2090 /* when we expect input, make sure we have it */
2093 if ((operand
->flags
& AXP_OPERAND_OPTIONAL_MASK
) == 0)
2098 /* match operand type with expression type */
2099 switch (operand
->flags
& AXP_OPERAND_TYPECHECK_MASK
)
2101 case AXP_OPERAND_IR
:
2102 if (tok
[tokidx
].X_op
!= O_register
2103 || !is_ir_num(tok
[tokidx
].X_add_number
))
2106 case AXP_OPERAND_FPR
:
2107 if (tok
[tokidx
].X_op
!= O_register
2108 || !is_fpr_num(tok
[tokidx
].X_add_number
))
2111 case AXP_OPERAND_IR
|AXP_OPERAND_PARENS
:
2112 if (tok
[tokidx
].X_op
!= O_pregister
2113 || !is_ir_num(tok
[tokidx
].X_add_number
))
2116 case AXP_OPERAND_IR
|AXP_OPERAND_PARENS
|AXP_OPERAND_COMMA
:
2117 if (tok
[tokidx
].X_op
!= O_cpregister
2118 || !is_ir_num(tok
[tokidx
].X_add_number
))
2122 case AXP_OPERAND_RELATIVE
:
2123 case AXP_OPERAND_SIGNED
:
2124 case AXP_OPERAND_UNSIGNED
:
2125 switch (tok
[tokidx
].X_op
)
2140 /* everything else should have been fake */
2146 /* possible match -- did we use all of our input? */
2155 while (++opcode
-alpha_opcodes
< alpha_num_opcodes
2156 && !strcmp(opcode
->name
, first_opcode
->name
));
2159 *pcpumatch
= got_cpu_match
;
2164 /* Search forward through all variants of a macro looking for a syntax
2167 static const struct alpha_macro
*
2168 find_macro_match(first_macro
, tok
, pntok
)
2169 const struct alpha_macro
*first_macro
;
2170 const expressionS
*tok
;
2173 const struct alpha_macro
*macro
= first_macro
;
2178 const enum alpha_macro_arg
*arg
= macro
->argsets
;
2192 /* index register */
2194 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_register
2195 || !is_ir_num(tok
[tokidx
].X_add_number
))
2200 /* parenthesized index register */
2202 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_pregister
2203 || !is_ir_num(tok
[tokidx
].X_add_number
))
2208 /* optional parenthesized index register */
2210 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_pregister
2211 && is_ir_num(tok
[tokidx
].X_add_number
))
2215 /* leading comma with a parenthesized index register */
2217 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_cpregister
2218 || !is_ir_num(tok
[tokidx
].X_add_number
))
2223 /* floating point register */
2225 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_register
2226 || !is_fpr_num(tok
[tokidx
].X_add_number
))
2231 /* normal expression */
2235 switch (tok
[tokidx
].X_op
)
2245 case O_lituse_bytoff
:
2259 /* optional !literal!<number> */
2262 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_literal
)
2267 /* optional !lituse_base!<number> */
2270 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_lituse_base
)
2275 /* optional !lituse_bytoff!<number> */
2278 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_lituse_bytoff
)
2283 /* optional !lituse_jsr!<number> */
2286 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_lituse_jsr
)
2292 while (*arg
!= MACRO_EOA
)
2300 while (++macro
-alpha_macros
< alpha_num_macros
2301 && !strcmp(macro
->name
, first_macro
->name
));
2306 /* Insert an operand value into an instruction. */
2309 insert_operand(insn
, operand
, val
, file
, line
)
2311 const struct alpha_operand
*operand
;
2316 if (operand
->bits
!= 32 && !(operand
->flags
& AXP_OPERAND_NOOVERFLOW
))
2320 if (operand
->flags
& AXP_OPERAND_SIGNED
)
2322 max
= (1 << (operand
->bits
- 1)) - 1;
2323 min
= -(1 << (operand
->bits
- 1));
2327 max
= (1 << operand
->bits
) - 1;
2331 if (val
< min
|| val
> max
)
2334 _("operand out of range (%s not between %d and %d)");
2335 char buf
[sizeof (val
) * 3 + 2];
2337 sprint_value(buf
, val
);
2339 as_warn_where(file
, line
, err
, buf
, min
, max
);
2341 as_warn(err
, buf
, min
, max
);
2345 if (operand
->insert
)
2347 const char *errmsg
= NULL
;
2349 insn
= (*operand
->insert
) (insn
, val
, &errmsg
);
2354 insn
|= ((val
& ((1 << operand
->bits
) - 1)) << operand
->shift
);
2360 * Turn an opcode description and a set of arguments into
2361 * an instruction and a fixup.
2365 assemble_insn(opcode
, tok
, ntok
, insn
)
2366 const struct alpha_opcode
*opcode
;
2367 const expressionS
*tok
;
2369 struct alpha_insn
*insn
;
2371 const unsigned char *argidx
;
2375 memset (insn
, 0, sizeof (*insn
));
2376 image
= opcode
->opcode
;
2378 for (argidx
= opcode
->operands
; *argidx
; ++argidx
)
2380 const struct alpha_operand
*operand
= &alpha_operands
[*argidx
];
2381 const expressionS
*t
= (const expressionS
*)0;
2383 if (operand
->flags
& AXP_OPERAND_FAKE
)
2385 /* fake operands take no value and generate no fixup */
2386 image
= insert_operand(image
, operand
, 0, NULL
, 0);
2392 switch (operand
->flags
& AXP_OPERAND_OPTIONAL_MASK
)
2394 case AXP_OPERAND_DEFAULT_FIRST
:
2397 case AXP_OPERAND_DEFAULT_SECOND
:
2400 case AXP_OPERAND_DEFAULT_ZERO
:
2402 static expressionS zero_exp
;
2404 zero_exp
.X_op
= O_constant
;
2405 zero_exp
.X_unsigned
= 1;
2420 image
= insert_operand(image
, operand
, regno(t
->X_add_number
),
2425 image
= insert_operand(image
, operand
, t
->X_add_number
, NULL
, 0);
2430 struct alpha_fixup
*fixup
;
2432 if (insn
->nfixups
>= MAX_INSN_FIXUPS
)
2433 as_fatal(_("too many fixups"));
2435 fixup
= &insn
->fixups
[insn
->nfixups
++];
2438 fixup
->reloc
= operand
->default_reloc
;
2448 * Actually output an instruction with its fixup.
2453 struct alpha_insn
*insn
;
2458 /* Take care of alignment duties */
2459 if (alpha_auto_align_on
&& alpha_current_align
< 2)
2460 alpha_align (2, (char *) NULL
, alpha_insn_label
, 0);
2461 if (alpha_current_align
> 2)
2462 alpha_current_align
= 2;
2463 alpha_insn_label
= NULL
;
2465 /* Write out the instruction. */
2467 md_number_to_chars (f
, insn
->insn
, 4);
2469 /* Apply the fixups in order */
2470 for (i
= 0; i
< insn
->nfixups
; ++i
)
2472 const struct alpha_operand
*operand
= (const struct alpha_operand
*)0;
2473 struct alpha_fixup
*fixup
= &insn
->fixups
[i
];
2477 char buffer
[ALPHA_RELOC_DIGITS
];
2478 struct alpha_literal_tag
*info
;
2481 /* Some fixups are only used internally and so have no howto */
2482 if ((int)fixup
->reloc
< 0)
2484 operand
= &alpha_operands
[-(int)fixup
->reloc
];
2486 pcrel
= ((operand
->flags
& AXP_OPERAND_RELATIVE
) != 0);
2488 else switch (fixup
->reloc
)
2491 /* These relocation types are only used internally. */
2492 case BFD_RELOC_ALPHA_GPDISP_HI16
:
2493 case BFD_RELOC_ALPHA_GPDISP_LO16
:
2499 /* and these also are internal only relocations */
2500 case BFD_RELOC_ALPHA_USER_LITERAL
:
2501 case BFD_RELOC_ALPHA_USER_LITUSE_BASE
:
2502 case BFD_RELOC_ALPHA_USER_LITUSE_BYTOFF
:
2503 case BFD_RELOC_ALPHA_USER_LITUSE_JSR
:
2504 case BFD_RELOC_ALPHA_USER_GPDISP
:
2505 case BFD_RELOC_ALPHA_USER_GPRELHIGH
:
2506 case BFD_RELOC_ALPHA_USER_GPRELLOW
:
2514 reloc_howto_type
*reloc_howto
2515 = bfd_reloc_type_lookup (stdoutput
, fixup
->reloc
);
2516 assert (reloc_howto
);
2518 size
= bfd_get_reloc_size (reloc_howto
);
2519 pcrel
= reloc_howto
->pc_relative
;
2521 assert (size
>= 1 && size
<= 4);
2525 fixP
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, size
,
2526 &fixup
->exp
, pcrel
, fixup
->reloc
);
2528 /* Turn off complaints that the addend is too large for some fixups,
2529 and copy in the sequence number for the explicit relocations. */
2530 switch (fixup
->reloc
)
2532 case BFD_RELOC_ALPHA_GPDISP_LO16
:
2534 case BFD_RELOC_ALPHA_LITERAL
:
2537 case BFD_RELOC_ALPHA_ELF_LITERAL
:
2539 case BFD_RELOC_GPREL32
:
2540 fixP
->fx_no_overflow
= 1;
2544 case BFD_RELOC_ALPHA_USER_LITERAL
:
2545 fixP
->fx_no_overflow
= 1;
2546 sprintf (buffer
, "!%u", insn
->sequence
[i
]);
2547 info
= ((struct alpha_literal_tag
*)
2548 hash_find (alpha_literal_hash
, buffer
));
2552 size_t len
= strlen (buffer
);
2555 info
= ((struct alpha_literal_tag
*)
2556 xcalloc (sizeof (struct alpha_literal_tag
) + len
, 1));
2558 info
->segment
= now_seg
;
2559 info
->sequence
= insn
->sequence
[i
];
2560 strcpy (info
->string
, buffer
);
2561 errmsg
= hash_insert (alpha_literal_hash
, info
->string
, (PTR
)info
);
2568 if (info
->segment
!= now_seg
)
2569 info
->multi_section_p
= 1;
2571 fixP
->tc_fix_data
.info
= info
;
2574 case BFD_RELOC_ALPHA_USER_LITUSE_BASE
:
2575 case BFD_RELOC_ALPHA_USER_LITUSE_BYTOFF
:
2576 case BFD_RELOC_ALPHA_USER_LITUSE_JSR
:
2577 sprintf (buffer
, "!%u", insn
->sequence
[i
]);
2578 info
= ((struct alpha_literal_tag
*)
2579 hash_find (alpha_literal_hash
, buffer
));
2583 size_t len
= strlen (buffer
);
2586 info
= ((struct alpha_literal_tag
*)
2587 xcalloc (sizeof (struct alpha_literal_tag
) + len
, 1));
2589 info
->segment
= now_seg
;
2590 info
->sequence
= insn
->sequence
[i
];
2591 strcpy (info
->string
, buffer
);
2592 errmsg
= hash_insert (alpha_literal_hash
, info
->string
, (PTR
)info
);
2597 fixP
->tc_fix_data
.info
= info
;
2598 fixP
->tc_fix_data
.next_lituse
= info
->lituse
;
2599 info
->lituse
= fixP
;
2600 if (info
->segment
!= now_seg
)
2601 info
->multi_section_p
= 1;
2607 if ((int)fixup
->reloc
< 0)
2609 if (operand
->flags
& AXP_OPERAND_NOOVERFLOW
)
2610 fixP
->fx_no_overflow
= 1;
2617 /* Given an opcode name and a pre-tokenized set of arguments, assemble
2618 the insn, but do not emit it.
2620 Note that this implies no macros allowed, since we can't store more
2621 than one insn in an insn structure. */
2624 assemble_tokens_to_insn(opname
, tok
, ntok
, insn
)
2626 const expressionS
*tok
;
2628 struct alpha_insn
*insn
;
2630 const struct alpha_opcode
*opcode
;
2632 /* search opcodes */
2633 opcode
= (const struct alpha_opcode
*) hash_find (alpha_opcode_hash
, opname
);
2637 opcode
= find_opcode_match (opcode
, tok
, &ntok
, &cpumatch
);
2640 assemble_insn (opcode
, tok
, ntok
, insn
);
2644 as_bad (_("inappropriate arguments for opcode `%s'"), opname
);
2646 as_bad (_("opcode `%s' not supported for target %s"), opname
,
2650 as_bad (_("unknown opcode `%s'"), opname
);
2653 /* Given an opcode name and a pre-tokenized set of arguments, take the
2654 opcode all the way through emission. */
2657 assemble_tokens (opname
, tok
, ntok
, local_macros_on
)
2659 const expressionS
*tok
;
2661 int local_macros_on
;
2663 int found_something
= 0;
2664 const struct alpha_opcode
*opcode
;
2665 const struct alpha_macro
*macro
;
2669 if (local_macros_on
)
2671 macro
= ((const struct alpha_macro
*)
2672 hash_find (alpha_macro_hash
, opname
));
2675 found_something
= 1;
2676 macro
= find_macro_match (macro
, tok
, &ntok
);
2679 (*macro
->emit
) (tok
, ntok
, macro
->arg
);
2686 if (ntok
&& USER_RELOC_P (tok
[ntok
-1].X_op
))
2688 const expressionS
*reloc_exp
= &tok
[ntok
-1];
2689 const struct alpha_reloc_op_tag
*r
= ALPHA_RELOC_TABLE (reloc_exp
->X_op
);
2690 as_bad (_("Cannot use !%s!%d with %s"), r
->name
,
2691 (int)reloc_exp
->X_add_number
, opname
);
2696 /* search opcodes */
2697 opcode
= (const struct alpha_opcode
*) hash_find (alpha_opcode_hash
, opname
);
2700 found_something
= 1;
2701 opcode
= find_opcode_match (opcode
, tok
, &ntok
, &cpumatch
);
2704 struct alpha_insn insn
;
2705 assemble_insn (opcode
, tok
, ntok
, &insn
);
2711 if (found_something
)
2713 as_bad (_("inappropriate arguments for opcode `%s'"), opname
);
2715 as_bad (_("opcode `%s' not supported for target %s"), opname
,
2718 as_bad (_("unknown opcode `%s'"), opname
);
2722 /* Some instruction sets indexed by lg(size) */
2723 static const char * const sextX_op
[] = { "sextb", "sextw", "sextl", NULL
};
2724 static const char * const insXl_op
[] = { "insbl", "inswl", "insll", "insql" };
2725 static const char * const insXh_op
[] = { NULL
, "inswh", "inslh", "insqh" };
2726 static const char * const extXl_op
[] = { "extbl", "extwl", "extll", "extql" };
2727 static const char * const extXh_op
[] = { NULL
, "extwh", "extlh", "extqh" };
2728 static const char * const mskXl_op
[] = { "mskbl", "mskwl", "mskll", "mskql" };
2729 static const char * const mskXh_op
[] = { NULL
, "mskwh", "msklh", "mskqh" };
2730 static const char * const stX_op
[] = { "stb", "stw", "stl", "stq" };
2731 static const char * const ldX_op
[] = { "ldb", "ldw", "ldll", "ldq" };
2732 static const char * const ldXu_op
[] = { "ldbu", "ldwu", NULL
, NULL
};
2734 /* Implement the ldgp macro. */
2737 emit_ldgp (tok
, ntok
, unused
)
2738 const expressionS
*tok
;
2739 int ntok ATTRIBUTE_UNUSED
;
2740 const PTR unused ATTRIBUTE_UNUSED
;
2745 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
2746 /* from "ldgp r1,n(r2)", generate "ldah r1,X(R2); lda r1,Y(r1)"
2747 with appropriate constants and relocations. */
2748 struct alpha_insn insn
;
2749 expressionS newtok
[3];
2753 if (ntok
&& USER_RELOC_P (tok
[ntok
-1].X_op
))
2755 const expressionS
*reloc_exp
= &tok
[ntok
-1];
2756 const struct alpha_reloc_op_tag
*r
= ALPHA_RELOC_TABLE (reloc_exp
->X_op
);
2757 as_bad (_("Cannot use !%s!%d with %s"), r
->name
,
2758 (int)reloc_exp
->X_add_number
, "ldgp");
2764 if (regno (tok
[2].X_add_number
) == AXP_REG_PV
)
2765 ecoff_set_gp_prolog_size (0);
2769 set_tok_const (newtok
[1], 0);
2772 assemble_tokens_to_insn ("ldah", newtok
, 3, &insn
);
2777 if (addend
.X_op
!= O_constant
)
2778 as_bad (_("can not resolve expression"));
2779 addend
.X_op
= O_symbol
;
2780 addend
.X_add_symbol
= alpha_gp_symbol
;
2784 insn
.fixups
[0].exp
= addend
;
2785 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_GPDISP_HI16
;
2789 set_tok_preg (newtok
[2], tok
[0].X_add_number
);
2791 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
2794 addend
.X_add_number
+= 4;
2798 insn
.fixups
[0].exp
= addend
;
2799 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_GPDISP_LO16
;
2802 #endif /* OBJ_ECOFF || OBJ_ELF */
2807 /* Add symbol+addend to link pool.
2808 Return offset from basesym to entry in link pool.
2810 Add new fixup only if offset isn't 16bit. */
2813 add_to_link_pool (basesym
, sym
, addend
)
2818 segT current_section
= now_seg
;
2819 int current_subsec
= now_subseg
;
2821 bfd_reloc_code_real_type reloc_type
;
2823 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
2826 offset
= - *symbol_get_obj (basesym
);
2828 /* @@ This assumes all entries in a given section will be of the same
2829 size... Probably correct, but unwise to rely on. */
2830 /* This must always be called with the same subsegment. */
2832 if (seginfo
->frchainP
)
2833 for (fixp
= seginfo
->frchainP
->fix_root
;
2834 fixp
!= (fixS
*) NULL
;
2835 fixp
= fixp
->fx_next
, offset
+= 8)
2837 if (fixp
->fx_addsy
== sym
&& fixp
->fx_offset
== addend
)
2839 if (range_signed_16 (offset
))
2846 /* Not found in 16bit signed range. */
2848 subseg_set (alpha_link_section
, 0);
2852 fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, sym
, addend
, 0,
2855 subseg_set (current_section
, current_subsec
);
2856 seginfo
->literal_pool_size
+= 8;
2860 #endif /* OBJ_EVAX */
2862 /* Load a (partial) expression into a target register.
2864 If poffset is not null, after the call it will either contain
2865 O_constant 0, or a 16-bit offset appropriate for any MEM format
2866 instruction. In addition, pbasereg will be modified to point to
2867 the base register to use in that MEM format instruction.
2869 In any case, *pbasereg should contain a base register to add to the
2870 expression. This will normally be either AXP_REG_ZERO or
2871 alpha_gp_register. Symbol addresses will always be loaded via $gp,
2872 so "foo($0)" is interpreted as adding the address of foo to $0;
2873 i.e. "ldq $targ, LIT($gp); addq $targ, $0, $targ". Odd, perhaps,
2874 but this is what OSF/1 does.
2876 If explicit relocations of the form !literal!<number> are allowed,
2877 and used, then explict_reloc with be an expression pointer.
2879 Finally, the return value is true if the calling macro may emit a
2880 LITUSE reloc if otherwise appropriate. */
2883 load_expression (targreg
, exp
, pbasereg
, poffset
, explicit_reloc
)
2885 const expressionS
*exp
;
2887 expressionS
*poffset
;
2888 const expressionS
*explicit_reloc
;
2890 int emit_lituse
= 0;
2891 offsetT addend
= exp
->X_add_number
;
2892 int basereg
= *pbasereg
;
2893 struct alpha_insn insn
;
2894 expressionS newtok
[3];
2903 /* attempt to reduce .lit load by splitting the offset from
2904 its symbol when possible, but don't create a situation in
2906 if (!range_signed_32 (addend
) &&
2907 (alpha_noat_on
|| targreg
== AXP_REG_AT
))
2909 lit
= add_to_literal_pool (exp
->X_add_symbol
, addend
,
2910 alpha_lita_section
, 8);
2915 lit
= add_to_literal_pool (exp
->X_add_symbol
, 0,
2916 alpha_lita_section
, 8);
2920 as_fatal (_("overflow in literal (.lita) table"));
2922 /* emit "ldq r, lit(gp)" */
2924 if (basereg
!= alpha_gp_register
&& targreg
== basereg
)
2927 as_bad (_("macro requires $at register while noat in effect"));
2928 if (targreg
== AXP_REG_AT
)
2929 as_bad (_("macro requires $at while $at in use"));
2931 set_tok_reg (newtok
[0], AXP_REG_AT
);
2934 set_tok_reg (newtok
[0], targreg
);
2935 set_tok_sym (newtok
[1], alpha_lita_symbol
, lit
);
2936 set_tok_preg (newtok
[2], alpha_gp_register
);
2938 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
2940 assert (explicit_reloc
== (const expressionS
*)0);
2941 assert (insn
.nfixups
== 1);
2942 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITERAL
;
2943 #endif /* OBJ_ECOFF */
2945 /* emit "ldq r, gotoff(gp)" */
2947 if (basereg
!= alpha_gp_register
&& targreg
== basereg
)
2950 as_bad (_("macro requires $at register while noat in effect"));
2951 if (targreg
== AXP_REG_AT
)
2952 as_bad (_("macro requires $at while $at in use"));
2954 set_tok_reg (newtok
[0], AXP_REG_AT
);
2957 set_tok_reg (newtok
[0], targreg
);
2959 /* XXX: Disable this .got minimizing optimization so that we can get
2960 better instruction offset knowledge in the compiler. This happens
2961 very infrequently anyway. */
2962 if (1 || (!range_signed_32 (addend
)
2963 && (alpha_noat_on
|| targreg
== AXP_REG_AT
)))
2970 set_tok_sym (newtok
[1], exp
->X_add_symbol
, 0);
2973 set_tok_preg (newtok
[2], alpha_gp_register
);
2975 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
2977 assert (insn
.nfixups
== 1);
2978 if (!explicit_reloc
)
2979 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_ELF_LITERAL
;
2983 insn
.fixups
[0].reloc
2984 = (ALPHA_RELOC_TABLE (explicit_reloc
->X_op
))->reloc
;
2985 insn
.sequence
[0] = explicit_reloc
->X_add_number
;
2990 #endif /* OBJ_ELF */
2994 /* Find symbol or symbol pointer in link section. */
2996 assert (explicit_reloc
== (const expressionS
*)0);
2997 if (exp
->X_add_symbol
== alpha_evax_proc
.symbol
)
2999 if (range_signed_16 (addend
))
3001 set_tok_reg (newtok
[0], targreg
);
3002 set_tok_const (newtok
[1], addend
);
3003 set_tok_preg (newtok
[2], basereg
);
3004 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
3009 set_tok_reg (newtok
[0], targreg
);
3010 set_tok_const (newtok
[1], 0);
3011 set_tok_preg (newtok
[2], basereg
);
3012 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
3017 if (!range_signed_32 (addend
))
3019 link
= add_to_link_pool (alpha_evax_proc
.symbol
,
3020 exp
->X_add_symbol
, addend
);
3025 link
= add_to_link_pool (alpha_evax_proc
.symbol
,
3026 exp
->X_add_symbol
, 0);
3028 set_tok_reg (newtok
[0], targreg
);
3029 set_tok_const (newtok
[1], link
);
3030 set_tok_preg (newtok
[2], basereg
);
3031 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
3033 #endif /* OBJ_EVAX */
3040 if (basereg
!= alpha_gp_register
&& basereg
!= AXP_REG_ZERO
)
3042 /* emit "addq r, base, r" */
3044 set_tok_reg (newtok
[1], basereg
);
3045 set_tok_reg (newtok
[2], targreg
);
3046 assemble_tokens ("addq", newtok
, 3, 0);
3055 assert (explicit_reloc
== (const expressionS
*)0);
3059 /* Assume that this difference expression will be resolved to an
3060 absolute value and that that value will fit in 16 bits. */
3062 assert (explicit_reloc
== (const expressionS
*)0);
3063 set_tok_reg (newtok
[0], targreg
);
3065 set_tok_preg (newtok
[2], basereg
);
3066 assemble_tokens ("lda", newtok
, 3, 0);
3069 set_tok_const (*poffset
, 0);
3073 if (exp
->X_add_number
> 0)
3074 as_bad (_("bignum invalid; zero assumed"));
3076 as_bad (_("floating point number invalid; zero assumed"));
3081 as_bad (_("can't handle expression"));
3086 if (!range_signed_32 (addend
))
3090 /* for 64-bit addends, just put it in the literal pool */
3093 /* emit "ldq targreg, lit(basereg)" */
3094 lit
= add_to_link_pool (alpha_evax_proc
.symbol
,
3095 section_symbol (absolute_section
), addend
);
3096 set_tok_reg (newtok
[0], targreg
);
3097 set_tok_const (newtok
[1], lit
);
3098 set_tok_preg (newtok
[2], alpha_gp_register
);
3099 assemble_tokens ("ldq", newtok
, 3, 0);
3102 if (alpha_lit8_section
== NULL
)
3104 create_literal_section (".lit8",
3105 &alpha_lit8_section
,
3106 &alpha_lit8_symbol
);
3109 alpha_lit8_literal
= add_to_literal_pool (alpha_lit8_symbol
, 0x8000,
3110 alpha_lita_section
, 8);
3111 if (alpha_lit8_literal
>= 0x8000)
3112 as_fatal (_("overflow in literal (.lita) table"));
3116 lit
= add_to_literal_pool (NULL
, addend
, alpha_lit8_section
, 8) - 0x8000;
3118 as_fatal (_("overflow in literal (.lit8) table"));
3120 /* emit "lda litreg, .lit8+0x8000" */
3122 if (targreg
== basereg
)
3125 as_bad (_("macro requires $at register while noat in effect"));
3126 if (targreg
== AXP_REG_AT
)
3127 as_bad (_("macro requires $at while $at in use"));
3129 set_tok_reg (newtok
[0], AXP_REG_AT
);
3132 set_tok_reg (newtok
[0], targreg
);
3134 set_tok_sym (newtok
[1], alpha_lita_symbol
, alpha_lit8_literal
);
3137 set_tok_sym (newtok
[1], alpha_lit8_symbol
, 0x8000);
3139 set_tok_preg (newtok
[2], alpha_gp_register
);
3141 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
3143 assert (insn
.nfixups
== 1);
3145 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITERAL
;
3148 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_ELF_LITERAL
;
3153 /* emit "ldq litreg, lit(litreg)" */
3155 set_tok_const (newtok
[1], lit
);
3156 set_tok_preg (newtok
[2], newtok
[0].X_add_number
);
3158 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
3160 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3161 if (insn
.nfixups
> 0)
3163 memmove (&insn
.fixups
[1], &insn
.fixups
[0],
3164 sizeof(struct alpha_fixup
) * insn
.nfixups
);
3167 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITUSE
;
3168 insn
.fixups
[0].exp
.X_op
= O_symbol
;
3169 insn
.fixups
[0].exp
.X_add_symbol
= section_symbol (now_seg
);
3170 insn
.fixups
[0].exp
.X_add_number
= LITUSE_BASE
;
3175 /* emit "addq litreg, base, target" */
3177 if (basereg
!= AXP_REG_ZERO
)
3179 set_tok_reg (newtok
[1], basereg
);
3180 set_tok_reg (newtok
[2], targreg
);
3181 assemble_tokens ("addq", newtok
, 3, 0);
3183 #endif /* !OBJ_EVAX */
3186 set_tok_const (*poffset
, 0);
3187 *pbasereg
= targreg
;
3191 offsetT low
, high
, extra
, tmp
;
3193 /* for 32-bit operands, break up the addend */
3195 low
= sign_extend_16 (addend
);
3197 high
= sign_extend_16 (tmp
>> 16);
3199 if (tmp
- (high
<< 16))
3203 high
= sign_extend_16 (tmp
>> 16);
3208 set_tok_reg (newtok
[0], targreg
);
3209 set_tok_preg (newtok
[2], basereg
);
3213 /* emit "ldah r, extra(r) */
3214 set_tok_const (newtok
[1], extra
);
3215 assemble_tokens ("ldah", newtok
, 3, 0);
3216 set_tok_preg (newtok
[2], basereg
= targreg
);
3221 /* emit "ldah r, high(r) */
3222 set_tok_const (newtok
[1], high
);
3223 assemble_tokens ("ldah", newtok
, 3, 0);
3225 set_tok_preg (newtok
[2], basereg
);
3228 if ((low
&& !poffset
) || (!poffset
&& basereg
!= targreg
))
3230 /* emit "lda r, low(base)" */
3231 set_tok_const (newtok
[1], low
);
3232 assemble_tokens ("lda", newtok
, 3, 0);
3238 set_tok_const (*poffset
, low
);
3239 *pbasereg
= basereg
;
3245 /* The lda macro differs from the lda instruction in that it handles
3246 most simple expressions, particualrly symbol address loads and
3250 emit_lda (tok
, ntok
, opname
)
3251 const expressionS
*tok
;
3256 const expressionS
*reloc
= (const expressionS
*)0;
3259 if (ntok
&& USER_RELOC_P (tok
[ntok
-1].X_op
))
3261 const struct alpha_reloc_op_tag
*r
;
3263 reloc
= &tok
[ntok
-1];
3264 r
= ALPHA_RELOC_TABLE (reloc
->X_op
);
3265 switch (reloc
->X_op
)
3268 as_bad (_("Cannot use !%s!%d with %s"), r
->name
,
3269 (int)reloc
->X_add_number
, (const char *)opname
);
3271 reloc
= (const expressionS
*)0;
3279 /* For lda $x,0($x)!lituse_base!y, don't use load_expression, since
3280 it is really too general for our needs. Instead just generate the
3284 || tok
[0].X_op
!= O_register
3285 || !is_ir_num(tok
[0].X_add_number
)
3286 || tok
[1].X_op
!= O_constant
3287 || tok
[2].X_op
!= O_pregister
3288 || !is_ir_num(tok
[2].X_add_number
))
3290 as_bad (_("bad instruction format for lda !%s!%d"), r
->name
,
3291 reloc
->X_add_number
);
3293 reloc
= (const expressionS
*)0;
3298 emit_loadstore (tok
, ntok
, "lda");
3305 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
3307 basereg
= tok
[2].X_add_number
;
3309 (void) load_expression (tok
[0].X_add_number
, &tok
[1], &basereg
, NULL
, reloc
);
3312 /* The ldah macro differs from the ldah instruction in that it has $31
3313 as an implied base register. */
3316 emit_ldah (tok
, ntok
, unused
)
3317 const expressionS
*tok
;
3318 int ntok ATTRIBUTE_UNUSED
;
3319 const PTR unused ATTRIBUTE_UNUSED
;
3321 expressionS newtok
[3];
3324 if (ntok
&& USER_RELOC_P (tok
[ntok
-1].X_op
))
3326 const expressionS
*reloc_exp
= &tok
[ntok
-1];
3327 const struct alpha_reloc_op_tag
*r
= ALPHA_RELOC_TABLE (reloc_exp
->X_op
);
3328 as_bad (_("Cannot use !%s!%d with %s"), r
->name
,
3329 (int)reloc_exp
->X_add_number
, "ldah");
3336 set_tok_preg (newtok
[2], AXP_REG_ZERO
);
3338 assemble_tokens ("ldah", newtok
, 3, 0);
3341 /* Handle all "simple" integer register loads -- ldq, ldq_l, ldq_u,
3342 etc. They differ from the real instructions in that they do simple
3343 expressions like the lda macro. */
3346 emit_ir_load (tok
, ntok
, opname
)
3347 const expressionS
*tok
;
3351 int basereg
, lituse
;
3352 expressionS newtok
[3];
3353 struct alpha_insn insn
;
3356 const expressionS
*reloc
= (const expressionS
*)0;
3358 if (ntok
&& USER_RELOC_P (tok
[ntok
-1].X_op
))
3360 const struct alpha_reloc_op_tag
*r
;
3362 reloc
= &tok
[ntok
-1];
3363 switch (reloc
->X_op
)
3370 if (strcmp ((const char *)opname
, "ldq") == 0)
3372 emit_lda (tok
, ntok
, opname
);
3379 r
= ALPHA_RELOC_TABLE (reloc
->X_op
);
3380 as_bad (_("Cannot use !%s!%d with %s"), r
->name
,
3381 (int)reloc
->X_add_number
, (const char *)opname
);
3387 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
3389 basereg
= tok
[2].X_add_number
;
3391 lituse
= load_expression (tok
[0].X_add_number
, &tok
[1], &basereg
,
3392 &newtok
[1], (const expressionS
*)0);
3395 set_tok_preg (newtok
[2], basereg
);
3397 assemble_tokens_to_insn ((const char *)opname
, newtok
, 3, &insn
);
3402 int nfixups
= insn
.nfixups
;
3403 const struct alpha_reloc_op_tag
*r
= ALPHA_RELOC_TABLE (reloc
->X_op
);
3405 assert (nfixups
< MAX_INSN_FIXUPS
);
3406 insn
.fixups
[nfixups
].reloc
= r
->reloc
;
3407 insn
.fixups
[nfixups
].exp
.X_op
= O_symbol
;
3408 insn
.fixups
[nfixups
].exp
.X_add_symbol
= section_symbol (now_seg
);
3409 insn
.fixups
[nfixups
].exp
.X_add_number
= r
->lituse
;
3410 insn
.sequence
[nfixups
] = reloc
->X_add_number
;
3417 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3418 if (insn
.nfixups
> 0)
3420 memmove (&insn
.fixups
[1], &insn
.fixups
[0],
3421 sizeof(struct alpha_fixup
) * insn
.nfixups
);
3424 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITUSE
;
3425 insn
.fixups
[0].exp
.X_op
= O_symbol
;
3426 insn
.fixups
[0].exp
.X_add_symbol
= section_symbol (now_seg
);
3427 insn
.fixups
[0].exp
.X_add_number
= LITUSE_BASE
;
3433 /* Handle fp register loads, and both integer and fp register stores.
3434 Again, we handle simple expressions. */
3437 emit_loadstore (tok
, ntok
, opname
)
3438 const expressionS
*tok
;
3442 int basereg
, lituse
;
3443 expressionS newtok
[3];
3444 struct alpha_insn insn
;
3447 const expressionS
*reloc
= (const expressionS
*)0;
3449 if (ntok
&& USER_RELOC_P (tok
[ntok
-1].X_op
))
3451 reloc
= &tok
[--ntok
];
3452 if (reloc
->X_op
!= O_lituse_base
)
3454 const struct alpha_reloc_op_tag
*r
= &alpha_reloc_op
[ reloc
->X_md
];
3455 as_bad (_("Cannot use !%s!%d with %s"), r
->name
,
3456 (int)reloc
->X_add_number
, (const char *)opname
);
3462 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
3464 basereg
= tok
[2].X_add_number
;
3466 if (tok
[1].X_op
!= O_constant
|| !range_signed_16(tok
[1].X_add_number
))
3469 as_bad (_("macro requires $at register while noat in effect"));
3471 lituse
= load_expression (AXP_REG_AT
, &tok
[1], &basereg
, &newtok
[1],
3472 (const expressionS
*)0);
3481 set_tok_preg (newtok
[2], basereg
);
3483 assemble_tokens_to_insn ((const char *)opname
, newtok
, 3, &insn
);
3488 int nfixups
= insn
.nfixups
;
3489 const struct alpha_reloc_op_tag
*r
= ALPHA_RELOC_TABLE (reloc
->X_op
);
3491 assert (nfixups
< MAX_INSN_FIXUPS
);
3492 insn
.fixups
[nfixups
].reloc
= r
->reloc
;
3493 insn
.fixups
[nfixups
].exp
.X_op
= O_symbol
;
3494 insn
.fixups
[nfixups
].exp
.X_add_symbol
= section_symbol (now_seg
);
3495 insn
.fixups
[nfixups
].exp
.X_add_number
= r
->lituse
;
3496 insn
.sequence
[nfixups
] = reloc
->X_add_number
;
3503 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3504 if (insn
.nfixups
> 0)
3506 memmove (&insn
.fixups
[1], &insn
.fixups
[0],
3507 sizeof(struct alpha_fixup
) * insn
.nfixups
);
3510 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITUSE
;
3511 insn
.fixups
[0].exp
.X_op
= O_symbol
;
3512 insn
.fixups
[0].exp
.X_add_symbol
= section_symbol (now_seg
);
3513 insn
.fixups
[0].exp
.X_add_number
= LITUSE_BASE
;
3519 /* Load a half-word or byte as an unsigned value. */
3522 emit_ldXu (tok
, ntok
, vlgsize
)
3523 const expressionS
*tok
;
3527 if (alpha_target
& AXP_OPCODE_BWX
)
3528 emit_ir_load (tok
, ntok
, ldXu_op
[(long)vlgsize
]);
3531 expressionS newtok
[3];
3534 if (ntok
&& USER_RELOC_P (tok
[ntok
-1].X_op
))
3536 const expressionS
*reloc_exp
= &tok
[ntok
-1];
3537 const struct alpha_reloc_op_tag
*r
3538 = ALPHA_RELOC_TABLE (reloc_exp
->X_op
);
3540 as_bad (_("Cannot use !%s!%d with %s"), r
->name
,
3541 (int)reloc_exp
->X_add_number
, "ldbu/ldwu");
3547 as_bad (_("macro requires $at register while noat in effect"));
3549 /* emit "lda $at, exp" */
3551 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
3552 newtok
[0].X_add_number
= AXP_REG_AT
;
3553 assemble_tokens ("lda", newtok
, ntok
, 1);
3555 /* emit "ldq_u targ, 0($at)" */
3558 set_tok_const (newtok
[1], 0);
3559 set_tok_preg (newtok
[2], AXP_REG_AT
);
3560 assemble_tokens ("ldq_u", newtok
, 3, 1);
3562 /* emit "extXl targ, $at, targ" */
3564 set_tok_reg (newtok
[1], AXP_REG_AT
);
3565 newtok
[2] = newtok
[0];
3566 assemble_tokens (extXl_op
[(long)vlgsize
], newtok
, 3, 1);
3570 /* Load a half-word or byte as a signed value. */
3573 emit_ldX (tok
, ntok
, vlgsize
)
3574 const expressionS
*tok
;
3578 emit_ldXu (tok
, ntok
, vlgsize
);
3579 assemble_tokens (sextX_op
[(long)vlgsize
], tok
, 1, 1);
3582 /* Load an integral value from an unaligned address as an unsigned
3586 emit_uldXu (tok
, ntok
, vlgsize
)
3587 const expressionS
*tok
;
3591 long lgsize
= (long)vlgsize
;
3592 expressionS newtok
[3];
3595 as_bad (_("macro requires $at register while noat in effect"));
3597 /* emit "lda $at, exp" */
3599 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
3600 newtok
[0].X_add_number
= AXP_REG_AT
;
3601 assemble_tokens ("lda", newtok
, ntok
, 1);
3603 /* emit "ldq_u $t9, 0($at)" */
3605 set_tok_reg (newtok
[0], AXP_REG_T9
);
3606 set_tok_const (newtok
[1], 0);
3607 set_tok_preg (newtok
[2], AXP_REG_AT
);
3608 assemble_tokens ("ldq_u", newtok
, 3, 1);
3610 /* emit "ldq_u $t10, size-1($at)" */
3612 set_tok_reg (newtok
[0], AXP_REG_T10
);
3613 set_tok_const (newtok
[1], (1<<lgsize
)-1);
3614 assemble_tokens ("ldq_u", newtok
, 3, 1);
3616 /* emit "extXl $t9, $at, $t9" */
3618 set_tok_reg (newtok
[0], AXP_REG_T9
);
3619 set_tok_reg (newtok
[1], AXP_REG_AT
);
3620 set_tok_reg (newtok
[2], AXP_REG_T9
);
3621 assemble_tokens (extXl_op
[lgsize
], newtok
, 3, 1);
3623 /* emit "extXh $t10, $at, $t10" */
3625 set_tok_reg (newtok
[0], AXP_REG_T10
);
3626 set_tok_reg (newtok
[2], AXP_REG_T10
);
3627 assemble_tokens (extXh_op
[lgsize
], newtok
, 3, 1);
3629 /* emit "or $t9, $t10, targ" */
3631 set_tok_reg (newtok
[0], AXP_REG_T9
);
3632 set_tok_reg (newtok
[1], AXP_REG_T10
);
3634 assemble_tokens ("or", newtok
, 3, 1);
3637 /* Load an integral value from an unaligned address as a signed value.
3638 Note that quads should get funneled to the unsigned load since we
3639 don't have to do the sign extension. */
3642 emit_uldX (tok
, ntok
, vlgsize
)
3643 const expressionS
*tok
;
3647 emit_uldXu (tok
, ntok
, vlgsize
);
3648 assemble_tokens (sextX_op
[(long)vlgsize
], tok
, 1, 1);
3651 /* Implement the ldil macro. */
3654 emit_ldil (tok
, ntok
, unused
)
3655 const expressionS
*tok
;
3657 const PTR unused ATTRIBUTE_UNUSED
;
3659 expressionS newtok
[2];
3662 if (ntok
&& USER_RELOC_P (tok
[ntok
-1].X_op
))
3664 const expressionS
*reloc_exp
= &tok
[ntok
-1];
3665 const struct alpha_reloc_op_tag
*r
= ALPHA_RELOC_TABLE (reloc_exp
->X_op
);
3666 as_bad (_("Cannot use !%s!%d with %s"), r
->name
,
3667 (int)reloc_exp
->X_add_number
, "ldil");
3672 memcpy (newtok
, tok
, sizeof(newtok
));
3673 newtok
[1].X_add_number
= sign_extend_32 (tok
[1].X_add_number
);
3675 assemble_tokens ("lda", newtok
, ntok
, 1);
3678 /* Store a half-word or byte. */
3681 emit_stX (tok
, ntok
, vlgsize
)
3682 const expressionS
*tok
;
3686 int lgsize
= (int)(long)vlgsize
;
3688 if (alpha_target
& AXP_OPCODE_BWX
)
3689 emit_loadstore (tok
, ntok
, stX_op
[lgsize
]);
3692 expressionS newtok
[3];
3695 as_bad(_("macro requires $at register while noat in effect"));
3697 /* emit "lda $at, exp" */
3699 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
3700 newtok
[0].X_add_number
= AXP_REG_AT
;
3701 assemble_tokens ("lda", newtok
, ntok
, 1);
3703 /* emit "ldq_u $t9, 0($at)" */
3705 set_tok_reg (newtok
[0], AXP_REG_T9
);
3706 set_tok_const (newtok
[1], 0);
3707 set_tok_preg (newtok
[2], AXP_REG_AT
);
3708 assemble_tokens ("ldq_u", newtok
, 3, 1);
3710 /* emit "insXl src, $at, $t10" */
3713 set_tok_reg (newtok
[1], AXP_REG_AT
);
3714 set_tok_reg (newtok
[2], AXP_REG_T10
);
3715 assemble_tokens (insXl_op
[lgsize
], newtok
, 3, 1);
3717 /* emit "mskXl $t9, $at, $t9" */
3719 set_tok_reg (newtok
[0], AXP_REG_T9
);
3720 newtok
[2] = newtok
[0];
3721 assemble_tokens (mskXl_op
[lgsize
], newtok
, 3, 1);
3723 /* emit "or $t9, $t10, $t9" */
3725 set_tok_reg (newtok
[1], AXP_REG_T10
);
3726 assemble_tokens ("or", newtok
, 3, 1);
3728 /* emit "stq_u $t9, 0($at) */
3730 set_tok_const (newtok
[1], 0);
3731 set_tok_preg (newtok
[2], AXP_REG_AT
);
3732 assemble_tokens ("stq_u", newtok
, 3, 1);
3736 /* Store an integer to an unaligned address. */
3739 emit_ustX (tok
, ntok
, vlgsize
)
3740 const expressionS
*tok
;
3744 int lgsize
= (int)(long)vlgsize
;
3745 expressionS newtok
[3];
3747 /* emit "lda $at, exp" */
3749 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
3750 newtok
[0].X_add_number
= AXP_REG_AT
;
3751 assemble_tokens ("lda", newtok
, ntok
, 1);
3753 /* emit "ldq_u $9, 0($at)" */
3755 set_tok_reg (newtok
[0], AXP_REG_T9
);
3756 set_tok_const (newtok
[1], 0);
3757 set_tok_preg (newtok
[2], AXP_REG_AT
);
3758 assemble_tokens ("ldq_u", newtok
, 3, 1);
3760 /* emit "ldq_u $10, size-1($at)" */
3762 set_tok_reg (newtok
[0], AXP_REG_T10
);
3763 set_tok_const (newtok
[1], (1 << lgsize
)-1);
3764 assemble_tokens ("ldq_u", newtok
, 3, 1);
3766 /* emit "insXl src, $at, $t11" */
3769 set_tok_reg (newtok
[1], AXP_REG_AT
);
3770 set_tok_reg (newtok
[2], AXP_REG_T11
);
3771 assemble_tokens (insXl_op
[lgsize
], newtok
, 3, 1);
3773 /* emit "insXh src, $at, $t12" */
3775 set_tok_reg (newtok
[2], AXP_REG_T12
);
3776 assemble_tokens (insXh_op
[lgsize
], newtok
, 3, 1);
3778 /* emit "mskXl $t9, $at, $t9" */
3780 set_tok_reg (newtok
[0], AXP_REG_T9
);
3781 newtok
[2] = newtok
[0];
3782 assemble_tokens (mskXl_op
[lgsize
], newtok
, 3, 1);
3784 /* emit "mskXh $t10, $at, $t10" */
3786 set_tok_reg (newtok
[0], AXP_REG_T10
);
3787 newtok
[2] = newtok
[0];
3788 assemble_tokens (mskXh_op
[lgsize
], newtok
, 3, 1);
3790 /* emit "or $t9, $t11, $t9" */
3792 set_tok_reg (newtok
[0], AXP_REG_T9
);
3793 set_tok_reg (newtok
[1], AXP_REG_T11
);
3794 newtok
[2] = newtok
[0];
3795 assemble_tokens ("or", newtok
, 3, 1);
3797 /* emit "or $t10, $t12, $t10" */
3799 set_tok_reg (newtok
[0], AXP_REG_T10
);
3800 set_tok_reg (newtok
[1], AXP_REG_T12
);
3801 newtok
[2] = newtok
[0];
3802 assemble_tokens ("or", newtok
, 3, 1);
3804 /* emit "stq_u $t9, 0($at)" */
3806 set_tok_reg (newtok
[0], AXP_REG_T9
);
3807 set_tok_const (newtok
[1], 0);
3808 set_tok_preg (newtok
[2], AXP_REG_AT
);
3809 assemble_tokens ("stq_u", newtok
, 3, 1);
3811 /* emit "stq_u $t10, size-1($at)" */
3813 set_tok_reg (newtok
[0], AXP_REG_T10
);
3814 set_tok_const (newtok
[1], (1 << lgsize
)-1);
3815 assemble_tokens ("stq_u", newtok
, 3, 1);
3818 /* Sign extend a half-word or byte. The 32-bit sign extend is
3819 implemented as "addl $31, $r, $t" in the opcode table. */
3822 emit_sextX (tok
, ntok
, vlgsize
)
3823 const expressionS
*tok
;
3827 long lgsize
= (long)vlgsize
;
3829 if (alpha_target
& AXP_OPCODE_BWX
)
3830 assemble_tokens (sextX_op
[lgsize
], tok
, ntok
, 0);
3833 int bitshift
= 64 - 8 * (1 << lgsize
);
3834 expressionS newtok
[3];
3837 if (ntok
&& USER_RELOC_P (tok
[ntok
-1].X_op
))
3839 const expressionS
*reloc_exp
= &tok
[ntok
-1];
3840 const struct alpha_reloc_op_tag
*r
3841 = ALPHA_RELOC_TABLE (reloc_exp
->X_op
);
3843 as_bad (_("Cannot use !%s!%d with %s"), r
->name
,
3844 (int)reloc_exp
->X_add_number
, "setxt");
3849 /* emit "sll src,bits,dst" */
3852 set_tok_const (newtok
[1], bitshift
);
3853 newtok
[2] = tok
[ntok
- 1];
3854 assemble_tokens ("sll", newtok
, 3, 1);
3856 /* emit "sra dst,bits,dst" */
3858 newtok
[0] = newtok
[2];
3859 assemble_tokens ("sra", newtok
, 3, 1);
3863 /* Implement the division and modulus macros. */
3867 /* Make register usage like in normal procedure call.
3868 Don't clobber PV and RA. */
3871 emit_division (tok
, ntok
, symname
)
3872 const expressionS
*tok
;
3876 /* DIVISION and MODULUS. Yech.
3881 * mov x,R16 # if x != R16
3882 * mov y,R17 # if y != R17
3887 * with appropriate optimizations if R0,R16,R17 are the registers
3888 * specified by the compiler.
3893 expressionS newtok
[3];
3896 if (ntok
&& USER_RELOC_P (tok
[ntok
-1].X_op
))
3898 const expressionS
*reloc_exp
= &tok
[ntok
-1];
3899 const struct alpha_reloc_op_tag
*r
= ALPHA_RELOC_TABLE (reloc_exp
->X_op
);
3900 as_bad (_("Cannot use !%s!%d with %s"), r
->name
,
3901 (int)reloc_exp
->X_add_number
, (char char *)symname
);
3906 xr
= regno (tok
[0].X_add_number
);
3907 yr
= regno (tok
[1].X_add_number
);
3912 rr
= regno (tok
[2].X_add_number
);
3914 /* Move the operands into the right place */
3915 if (yr
== AXP_REG_R16
&& xr
== AXP_REG_R17
)
3917 /* They are in exactly the wrong order -- swap through AT */
3920 as_bad (_("macro requires $at register while noat in effect"));
3922 set_tok_reg (newtok
[0], AXP_REG_R16
);
3923 set_tok_reg (newtok
[1], AXP_REG_AT
);
3924 assemble_tokens ("mov", newtok
, 2, 1);
3926 set_tok_reg (newtok
[0], AXP_REG_R17
);
3927 set_tok_reg (newtok
[1], AXP_REG_R16
);
3928 assemble_tokens ("mov", newtok
, 2, 1);
3930 set_tok_reg (newtok
[0], AXP_REG_AT
);
3931 set_tok_reg (newtok
[1], AXP_REG_R17
);
3932 assemble_tokens ("mov", newtok
, 2, 1);
3936 if (yr
== AXP_REG_R16
)
3938 set_tok_reg (newtok
[0], AXP_REG_R16
);
3939 set_tok_reg (newtok
[1], AXP_REG_R17
);
3940 assemble_tokens ("mov", newtok
, 2, 1);
3943 if (xr
!= AXP_REG_R16
)
3945 set_tok_reg (newtok
[0], xr
);
3946 set_tok_reg (newtok
[1], AXP_REG_R16
);
3947 assemble_tokens ("mov", newtok
, 2, 1);
3950 if (yr
!= AXP_REG_R16
&& yr
!= AXP_REG_R17
)
3952 set_tok_reg (newtok
[0], yr
);
3953 set_tok_reg (newtok
[1], AXP_REG_R17
);
3954 assemble_tokens ("mov", newtok
, 2, 1);
3958 sym
= symbol_find_or_make ((const char *)symname
);
3960 set_tok_reg (newtok
[0], AXP_REG_AT
);
3961 set_tok_sym (newtok
[1], sym
, 0);
3962 assemble_tokens ("lda", newtok
, 2, 1);
3964 /* Call the division routine */
3965 set_tok_reg (newtok
[0], AXP_REG_AT
);
3966 set_tok_cpreg (newtok
[1], AXP_REG_AT
);
3967 set_tok_const (newtok
[2], 0);
3968 assemble_tokens ("jsr", newtok
, 3, 1);
3970 /* Move the result to the right place */
3971 if (rr
!= AXP_REG_R0
)
3973 set_tok_reg (newtok
[0], AXP_REG_R0
);
3974 set_tok_reg (newtok
[1], rr
);
3975 assemble_tokens ("mov", newtok
, 2, 1);
3979 #else /* !OBJ_EVAX */
3982 emit_division (tok
, ntok
, symname
)
3983 const expressionS
*tok
;
3987 /* DIVISION and MODULUS. Yech.
3997 * with appropriate optimizations if t10,t11,t12 are the registers
3998 * specified by the compiler.
4003 expressionS newtok
[3];
4006 if (ntok
&& USER_RELOC_P (tok
[ntok
-1].X_op
))
4008 const expressionS
*reloc_exp
= &tok
[ntok
-1];
4009 const struct alpha_reloc_op_tag
*r
= ALPHA_RELOC_TABLE (reloc_exp
->X_op
);
4010 as_bad (_("Cannot use !%s!%d with %s"), r
->name
,
4011 (int)reloc_exp
->X_add_number
, (const char *)symname
);
4016 xr
= regno (tok
[0].X_add_number
);
4017 yr
= regno (tok
[1].X_add_number
);
4022 rr
= regno (tok
[2].X_add_number
);
4024 sym
= symbol_find_or_make ((const char *)symname
);
4026 /* Move the operands into the right place */
4027 if (yr
== AXP_REG_T10
&& xr
== AXP_REG_T11
)
4029 /* They are in exactly the wrong order -- swap through AT */
4032 as_bad (_("macro requires $at register while noat in effect"));
4034 set_tok_reg (newtok
[0], AXP_REG_T10
);
4035 set_tok_reg (newtok
[1], AXP_REG_AT
);
4036 assemble_tokens ("mov", newtok
, 2, 1);
4038 set_tok_reg (newtok
[0], AXP_REG_T11
);
4039 set_tok_reg (newtok
[1], AXP_REG_T10
);
4040 assemble_tokens ("mov", newtok
, 2, 1);
4042 set_tok_reg (newtok
[0], AXP_REG_AT
);
4043 set_tok_reg (newtok
[1], AXP_REG_T11
);
4044 assemble_tokens ("mov", newtok
, 2, 1);
4048 if (yr
== AXP_REG_T10
)
4050 set_tok_reg (newtok
[0], AXP_REG_T10
);
4051 set_tok_reg (newtok
[1], AXP_REG_T11
);
4052 assemble_tokens ("mov", newtok
, 2, 1);
4055 if (xr
!= AXP_REG_T10
)
4057 set_tok_reg (newtok
[0], xr
);
4058 set_tok_reg (newtok
[1], AXP_REG_T10
);
4059 assemble_tokens ("mov", newtok
, 2, 1);
4062 if (yr
!= AXP_REG_T10
&& yr
!= AXP_REG_T11
)
4064 set_tok_reg (newtok
[0], yr
);
4065 set_tok_reg (newtok
[1], AXP_REG_T11
);
4066 assemble_tokens ("mov", newtok
, 2, 1);
4070 /* Call the division routine */
4071 set_tok_reg (newtok
[0], AXP_REG_T9
);
4072 set_tok_sym (newtok
[1], sym
, 0);
4073 assemble_tokens ("jsr", newtok
, 2, 1);
4075 /* Reload the GP register */
4079 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
4080 set_tok_reg (newtok
[0], alpha_gp_register
);
4081 set_tok_const (newtok
[1], 0);
4082 set_tok_preg (newtok
[2], AXP_REG_T9
);
4083 assemble_tokens ("ldgp", newtok
, 3, 1);
4086 /* Move the result to the right place */
4087 if (rr
!= AXP_REG_T12
)
4089 set_tok_reg (newtok
[0], AXP_REG_T12
);
4090 set_tok_reg (newtok
[1], rr
);
4091 assemble_tokens ("mov", newtok
, 2, 1);
4095 #endif /* !OBJ_EVAX */
4097 /* The jsr and jmp macros differ from their instruction counterparts
4098 in that they can load the target address and default most
4102 emit_jsrjmp (tok
, ntok
, vopname
)
4103 const expressionS
*tok
;
4107 const char *opname
= (const char *) vopname
;
4108 struct alpha_insn insn
;
4109 expressionS newtok
[3];
4110 int r
, tokidx
= 0, lituse
= 0;
4113 if (ntok
&& USER_RELOC_P (tok
[ntok
-1].X_op
))
4115 const expressionS
*reloc_exp
= &tok
[ntok
-1];
4116 const struct alpha_reloc_op_tag
*r
= ALPHA_RELOC_TABLE (reloc_exp
->X_op
);
4117 as_bad (_("Cannot use !%s!%d with %s"), r
->name
,
4118 (int)reloc_exp
->X_add_number
, opname
);
4123 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_register
)
4124 r
= regno (tok
[tokidx
++].X_add_number
);
4126 r
= strcmp (opname
, "jmp") == 0 ? AXP_REG_ZERO
: AXP_REG_RA
;
4128 set_tok_reg (newtok
[0], r
);
4130 if (tokidx
< ntok
&&
4131 (tok
[tokidx
].X_op
== O_pregister
|| tok
[tokidx
].X_op
== O_cpregister
))
4132 r
= regno (tok
[tokidx
++].X_add_number
);
4134 /* keep register if jsr $n.<sym> */
4138 int basereg
= alpha_gp_register
;
4139 lituse
= load_expression (r
= AXP_REG_PV
, &tok
[tokidx
], &basereg
, NULL
,
4140 (const expressionS
*)0);
4144 set_tok_cpreg (newtok
[1], r
);
4147 /* FIXME: Add hint relocs to BFD for evax. */
4150 newtok
[2] = tok
[tokidx
];
4153 set_tok_const (newtok
[2], 0);
4155 assemble_tokens_to_insn (opname
, newtok
, 3, &insn
);
4157 /* add the LITUSE fixup */
4160 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
4161 if (insn
.nfixups
> 0)
4163 memmove (&insn
.fixups
[1], &insn
.fixups
[0],
4164 sizeof(struct alpha_fixup
) * insn
.nfixups
);
4167 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITUSE
;
4168 insn
.fixups
[0].exp
.X_op
= O_symbol
;
4169 insn
.fixups
[0].exp
.X_add_symbol
= section_symbol (now_seg
);
4170 insn
.fixups
[0].exp
.X_add_number
= LITUSE_JSR
;
4176 /* The ret and jcr instructions differ from their instruction
4177 counterparts in that everything can be defaulted. */
4180 emit_retjcr (tok
, ntok
, vopname
)
4181 const expressionS
*tok
;
4185 const char *opname
= (const char *)vopname
;
4186 expressionS newtok
[3];
4190 if (ntok
&& USER_RELOC_P (tok
[ntok
-1].X_op
))
4192 const expressionS
*reloc_exp
= &tok
[ntok
-1];
4193 const struct alpha_reloc_op_tag
*r
= ALPHA_RELOC_TABLE (reloc_exp
->X_op
);
4194 as_bad (_("Cannot use !%s!%d with %s"), r
->name
,
4195 (int)reloc_exp
->X_add_number
, opname
);
4200 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_register
)
4201 r
= regno (tok
[tokidx
++].X_add_number
);
4205 set_tok_reg (newtok
[0], r
);
4207 if (tokidx
< ntok
&&
4208 (tok
[tokidx
].X_op
== O_pregister
|| tok
[tokidx
].X_op
== O_cpregister
))
4209 r
= regno (tok
[tokidx
++].X_add_number
);
4213 set_tok_cpreg (newtok
[1], r
);
4216 newtok
[2] = tok
[tokidx
];
4218 set_tok_const (newtok
[2], strcmp(opname
, "ret") == 0);
4220 assemble_tokens (opname
, newtok
, 3, 0);
4223 /* Assembler directives */
4225 /* Handle the .text pseudo-op. This is like the usual one, but it
4226 clears alpha_insn_label and restores auto alignment. */
4234 alpha_insn_label
= NULL
;
4235 alpha_auto_align_on
= 1;
4236 alpha_current_align
= 0;
4239 /* Handle the .data pseudo-op. This is like the usual one, but it
4240 clears alpha_insn_label and restores auto alignment. */
4247 alpha_insn_label
= NULL
;
4248 alpha_auto_align_on
= 1;
4249 alpha_current_align
= 0;
4252 #if defined (OBJ_ECOFF) || defined (OBJ_EVAX)
4254 /* Handle the OSF/1 and openVMS .comm pseudo quirks.
4255 openVMS constructs a section for every common symbol. */
4258 s_alpha_comm (ignore
)
4261 register char *name
;
4265 register symbolS
*symbolP
;
4268 segT current_section
= now_seg
;
4269 int current_subsec
= now_subseg
;
4273 name
= input_line_pointer
;
4274 c
= get_symbol_end ();
4276 /* just after name is now '\0' */
4277 p
= input_line_pointer
;
4282 /* Alpha OSF/1 compiler doesn't provide the comma, gcc does. */
4283 if (*input_line_pointer
== ',')
4285 input_line_pointer
++;
4288 if ((temp
= get_absolute_expression ()) < 0)
4290 as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) temp
);
4291 ignore_rest_of_line ();
4296 symbolP
= symbol_find_or_make (name
);
4299 /* Make a section for the common symbol. */
4300 new_seg
= subseg_new (xstrdup (name
), 0);
4306 /* alignment might follow */
4307 if (*input_line_pointer
== ',')
4311 input_line_pointer
++;
4312 align
= get_absolute_expression ();
4313 bfd_set_section_alignment (stdoutput
, new_seg
, align
);
4317 if (S_IS_DEFINED (symbolP
) && ! S_IS_COMMON (symbolP
))
4319 as_bad (_("Ignoring attempt to re-define symbol"));
4320 ignore_rest_of_line ();
4325 if (bfd_section_size (stdoutput
, new_seg
) > 0)
4327 if (bfd_section_size (stdoutput
, new_seg
) != temp
)
4328 as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
4329 S_GET_NAME (symbolP
),
4330 (long) bfd_section_size (stdoutput
, new_seg
),
4334 if (S_GET_VALUE (symbolP
))
4336 if (S_GET_VALUE (symbolP
) != (valueT
) temp
)
4337 as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
4338 S_GET_NAME (symbolP
),
4339 (long) S_GET_VALUE (symbolP
),
4346 subseg_set (new_seg
, 0);
4347 p
= frag_more (temp
);
4348 new_seg
->flags
|= SEC_IS_COMMON
;
4349 if (! S_IS_DEFINED (symbolP
))
4350 S_SET_SEGMENT (symbolP
, new_seg
);
4352 S_SET_VALUE (symbolP
, (valueT
) temp
);
4354 S_SET_EXTERNAL (symbolP
);
4358 subseg_set (current_section
, current_subsec
);
4361 know (symbol_get_frag (symbolP
) == &zero_address_frag
);
4363 demand_empty_rest_of_line ();
4366 #endif /* ! OBJ_ELF */
4370 /* Handle the .rdata pseudo-op. This is like the usual one, but it
4371 clears alpha_insn_label and restores auto alignment. */
4374 s_alpha_rdata (ignore
)
4379 temp
= get_absolute_expression ();
4380 subseg_new (".rdata", 0);
4381 demand_empty_rest_of_line ();
4382 alpha_insn_label
= NULL
;
4383 alpha_auto_align_on
= 1;
4384 alpha_current_align
= 0;
4391 /* Handle the .sdata pseudo-op. This is like the usual one, but it
4392 clears alpha_insn_label and restores auto alignment. */
4395 s_alpha_sdata (ignore
)
4400 temp
= get_absolute_expression ();
4401 subseg_new (".sdata", 0);
4402 demand_empty_rest_of_line ();
4403 alpha_insn_label
= NULL
;
4404 alpha_auto_align_on
= 1;
4405 alpha_current_align
= 0;
4411 /* Handle the .section pseudo-op. This is like the usual one, but it
4412 clears alpha_insn_label and restores auto alignment. */
4415 s_alpha_section (ignore
)
4418 obj_elf_section (ignore
);
4420 alpha_insn_label
= NULL
;
4421 alpha_auto_align_on
= 1;
4422 alpha_current_align
= 0;
4427 int dummy ATTRIBUTE_UNUSED
;
4429 if (ECOFF_DEBUGGING
)
4430 ecoff_directive_ent (0);
4433 char *name
, name_end
;
4434 name
= input_line_pointer
;
4435 name_end
= get_symbol_end ();
4437 if (! is_name_beginner (*name
))
4439 as_warn (_(".ent directive has no name"));
4440 *input_line_pointer
= name_end
;
4446 if (alpha_cur_ent_sym
)
4447 as_warn (_("nested .ent directives"));
4449 sym
= symbol_find_or_make (name
);
4450 symbol_get_bfdsym (sym
)->flags
|= BSF_FUNCTION
;
4451 alpha_cur_ent_sym
= sym
;
4453 /* The .ent directive is sometimes followed by a number. Not sure
4454 what it really means, but ignore it. */
4455 *input_line_pointer
= name_end
;
4457 if (*input_line_pointer
== ',')
4459 input_line_pointer
++;
4462 if (isdigit (*input_line_pointer
) || *input_line_pointer
== '-')
4463 (void) get_absolute_expression ();
4465 demand_empty_rest_of_line ();
4471 int dummy ATTRIBUTE_UNUSED
;
4473 if (ECOFF_DEBUGGING
)
4474 ecoff_directive_end (0);
4477 char *name
, name_end
;
4478 name
= input_line_pointer
;
4479 name_end
= get_symbol_end ();
4481 if (! is_name_beginner (*name
))
4483 as_warn (_(".end directive has no name"));
4484 *input_line_pointer
= name_end
;
4490 sym
= symbol_find (name
);
4491 if (sym
!= alpha_cur_ent_sym
)
4492 as_warn (_(".end directive names different symbol than .ent"));
4494 /* Create an expression to calculate the size of the function. */
4497 symbol_get_obj (sym
)->size
=
4498 (expressionS
*) xmalloc (sizeof (expressionS
));
4499 symbol_get_obj (sym
)->size
->X_op
= O_subtract
;
4500 symbol_get_obj (sym
)->size
->X_add_symbol
4501 = symbol_new ("L0\001", now_seg
, frag_now_fix (), frag_now
);
4502 symbol_get_obj (sym
)->size
->X_op_symbol
= sym
;
4503 symbol_get_obj (sym
)->size
->X_add_number
= 0;
4506 alpha_cur_ent_sym
= NULL
;
4508 *input_line_pointer
= name_end
;
4510 demand_empty_rest_of_line ();
4518 if (ECOFF_DEBUGGING
)
4521 ecoff_directive_fmask (0);
4523 ecoff_directive_mask (0);
4526 discard_rest_of_line ();
4530 s_alpha_frame (dummy
)
4531 int dummy ATTRIBUTE_UNUSED
;
4533 if (ECOFF_DEBUGGING
)
4534 ecoff_directive_frame (0);
4536 discard_rest_of_line ();
4540 s_alpha_prologue (ignore
)
4541 int ignore ATTRIBUTE_UNUSED
;
4546 arg
= get_absolute_expression ();
4547 demand_empty_rest_of_line ();
4549 if (ECOFF_DEBUGGING
)
4550 sym
= ecoff_get_cur_proc_sym ();
4552 sym
= alpha_cur_ent_sym
;
4557 case 0: /* No PV required. */
4558 S_SET_OTHER (sym
, STO_ALPHA_NOPV
4559 | (S_GET_OTHER (sym
) & ~STO_ALPHA_STD_GPLOAD
));
4561 case 1: /* Std GP load. */
4562 S_SET_OTHER (sym
, STO_ALPHA_STD_GPLOAD
4563 | (S_GET_OTHER (sym
) & ~STO_ALPHA_STD_GPLOAD
));
4565 case 2: /* Non-std use of PV. */
4569 as_bad (_("Invalid argument %d to .prologue."), arg
);
4575 s_alpha_coff_wrapper (which
)
4578 static void (* const fns
[]) PARAMS ((int)) = {
4579 ecoff_directive_begin
,
4580 ecoff_directive_bend
,
4581 ecoff_directive_def
,
4582 ecoff_directive_dim
,
4583 ecoff_directive_endef
,
4584 ecoff_directive_file
,
4585 ecoff_directive_scl
,
4586 ecoff_directive_tag
,
4587 ecoff_directive_val
,
4588 ecoff_directive_loc
,
4591 assert (which
>= 0 && which
< (int)(sizeof(fns
)/sizeof(*fns
)));
4593 if (ECOFF_DEBUGGING
)
4597 as_bad (_("ECOFF debugging is disabled."));
4598 ignore_rest_of_line ();
4601 #endif /* OBJ_ELF */
4605 /* Handle the section specific pseudo-op. */
4608 s_alpha_section (secid
)
4612 #define EVAX_SECTION_COUNT 5
4613 static char *section_name
[EVAX_SECTION_COUNT
+1] =
4614 { "NULL", ".rdata", ".comm", ".link", ".ctors", ".dtors" };
4616 if ((secid
<= 0) || (secid
> EVAX_SECTION_COUNT
))
4618 as_fatal (_("Unknown section directive"));
4619 demand_empty_rest_of_line ();
4622 temp
= get_absolute_expression ();
4623 subseg_new (section_name
[secid
], 0);
4624 demand_empty_rest_of_line ();
4625 alpha_insn_label
= NULL
;
4626 alpha_auto_align_on
= 1;
4627 alpha_current_align
= 0;
4630 /* Parse .ent directives. */
4633 s_alpha_ent (ignore
)
4637 expressionS symexpr
;
4639 alpha_evax_proc
.pdsckind
= 0;
4640 alpha_evax_proc
.framereg
= -1;
4641 alpha_evax_proc
.framesize
= 0;
4642 alpha_evax_proc
.rsa_offset
= 0;
4643 alpha_evax_proc
.ra_save
= AXP_REG_RA
;
4644 alpha_evax_proc
.fp_save
= -1;
4645 alpha_evax_proc
.imask
= 0;
4646 alpha_evax_proc
.fmask
= 0;
4647 alpha_evax_proc
.prologue
= 0;
4648 alpha_evax_proc
.type
= 0;
4650 expression (&symexpr
);
4652 if (symexpr
.X_op
!= O_symbol
)
4654 as_fatal (_(".ent directive has no symbol"));
4655 demand_empty_rest_of_line ();
4659 symbol
= make_expr_symbol (&symexpr
);
4660 symbol_get_bfdsym (symbol
)->flags
|= BSF_FUNCTION
;
4661 alpha_evax_proc
.symbol
= symbol
;
4663 demand_empty_rest_of_line ();
4667 /* Parse .frame <framreg>,<framesize>,RA,<rsa_offset> directives. */
4670 s_alpha_frame (ignore
)
4675 alpha_evax_proc
.framereg
= tc_get_register (1);
4678 if (*input_line_pointer
++ != ','
4679 || get_absolute_expression_and_terminator (&val
) != ',')
4681 as_warn (_("Bad .frame directive 1./2. param"));
4682 --input_line_pointer
;
4683 demand_empty_rest_of_line ();
4687 alpha_evax_proc
.framesize
= val
;
4689 (void) tc_get_register (1);
4691 if (*input_line_pointer
++ != ',')
4693 as_warn (_("Bad .frame directive 3./4. param"));
4694 --input_line_pointer
;
4695 demand_empty_rest_of_line ();
4698 alpha_evax_proc
.rsa_offset
= get_absolute_expression ();
4704 s_alpha_pdesc (ignore
)
4714 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
4716 if (now_seg
!= alpha_link_section
)
4718 as_bad (_(".pdesc directive not in link (.link) section"));
4719 demand_empty_rest_of_line ();
4723 if ((alpha_evax_proc
.symbol
== 0)
4724 || (!S_IS_DEFINED (alpha_evax_proc
.symbol
)))
4726 as_fatal (_(".pdesc has no matching .ent"));
4727 demand_empty_rest_of_line ();
4731 *symbol_get_obj (alpha_evax_proc
.symbol
) =
4732 (valueT
) seginfo
->literal_pool_size
;
4735 if (exp
.X_op
!= O_symbol
)
4737 as_warn (_(".pdesc directive has no entry symbol"));
4738 demand_empty_rest_of_line ();
4742 entry_sym
= make_expr_symbol (&exp
);
4743 /* Save bfd symbol of proc desc in function symbol. */
4744 symbol_get_bfdsym (alpha_evax_proc
.symbol
)->udata
.p
4745 = symbol_get_bfdsym (entry_sym
);
4748 if (*input_line_pointer
++ != ',')
4750 as_warn (_("No comma after .pdesc <entryname>"));
4751 demand_empty_rest_of_line ();
4756 name
= input_line_pointer
;
4757 name_end
= get_symbol_end ();
4759 if (strncmp(name
, "stack", 5) == 0)
4761 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_FP_STACK
;
4763 else if (strncmp(name
, "reg", 3) == 0)
4765 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_FP_REGISTER
;
4767 else if (strncmp(name
, "null", 4) == 0)
4769 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_NULL
;
4773 as_fatal (_("unknown procedure kind"));
4774 demand_empty_rest_of_line ();
4778 *input_line_pointer
= name_end
;
4779 demand_empty_rest_of_line ();
4781 #ifdef md_flush_pending_output
4782 md_flush_pending_output ();
4785 frag_align (3, 0, 0);
4787 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
4789 seginfo
->literal_pool_size
+= 16;
4791 *p
= alpha_evax_proc
.pdsckind
4792 | ((alpha_evax_proc
.framereg
== 29) ? PDSC_S_M_BASE_REG_IS_FP
: 0);
4793 *(p
+1) = PDSC_S_M_NATIVE
4794 | PDSC_S_M_NO_JACKET
;
4796 switch (alpha_evax_proc
.pdsckind
)
4798 case PDSC_S_K_KIND_NULL
:
4802 case PDSC_S_K_KIND_FP_REGISTER
:
4803 *(p
+2) = alpha_evax_proc
.fp_save
;
4804 *(p
+3) = alpha_evax_proc
.ra_save
;
4806 case PDSC_S_K_KIND_FP_STACK
:
4807 md_number_to_chars (p
+2, (valueT
)alpha_evax_proc
.rsa_offset
, 2);
4809 default: /* impossible */
4814 *(p
+5) = alpha_evax_proc
.type
& 0x0f;
4816 /* Signature offset. */
4817 md_number_to_chars (p
+6, (valueT
)0, 2);
4819 fix_new_exp (frag_now
, p
-frag_now
->fr_literal
+8, 8, &exp
, 0, BFD_RELOC_64
);
4821 if (alpha_evax_proc
.pdsckind
== PDSC_S_K_KIND_NULL
)
4824 /* Add dummy fix to make add_to_link_pool work. */
4826 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
4828 seginfo
->literal_pool_size
+= 8;
4830 /* pdesc+16: Size. */
4831 md_number_to_chars (p
, (valueT
)alpha_evax_proc
.framesize
, 4);
4833 md_number_to_chars (p
+4, (valueT
)0, 2);
4836 md_number_to_chars (p
+6, alpha_evax_proc
.prologue
, 2);
4838 if (alpha_evax_proc
.pdsckind
== PDSC_S_K_KIND_FP_REGISTER
)
4841 /* Add dummy fix to make add_to_link_pool work. */
4843 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
4845 seginfo
->literal_pool_size
+= 8;
4847 /* pdesc+24: register masks. */
4849 md_number_to_chars (p
, alpha_evax_proc
.imask
, 4);
4850 md_number_to_chars (p
+4, alpha_evax_proc
.fmask
, 4);
4855 /* Support for crash debug on vms. */
4858 s_alpha_name (ignore
)
4863 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
4865 if (now_seg
!= alpha_link_section
)
4867 as_bad (_(".name directive not in link (.link) section"));
4868 demand_empty_rest_of_line ();
4873 if (exp
.X_op
!= O_symbol
)
4875 as_warn (_(".name directive has no symbol"));
4876 demand_empty_rest_of_line ();
4880 demand_empty_rest_of_line ();
4882 #ifdef md_flush_pending_output
4883 md_flush_pending_output ();
4886 frag_align (3, 0, 0);
4888 seginfo
->literal_pool_size
+= 8;
4890 fix_new_exp (frag_now
, p
-frag_now
->fr_literal
, 8, &exp
, 0, BFD_RELOC_64
);
4896 s_alpha_linkage (ignore
)
4902 #ifdef md_flush_pending_output
4903 md_flush_pending_output ();
4907 if (exp
.X_op
!= O_symbol
)
4909 as_fatal (_("No symbol after .linkage"));
4913 p
= frag_more (LKP_S_K_SIZE
);
4914 memset (p
, 0, LKP_S_K_SIZE
);
4915 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, LKP_S_K_SIZE
, &exp
, 0,\
4916 BFD_RELOC_ALPHA_LINKAGE
);
4918 demand_empty_rest_of_line ();
4924 s_alpha_code_address (ignore
)
4930 #ifdef md_flush_pending_output
4931 md_flush_pending_output ();
4935 if (exp
.X_op
!= O_symbol
)
4937 as_fatal (_("No symbol after .code_address"));
4943 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 8, &exp
, 0,\
4944 BFD_RELOC_ALPHA_CODEADDR
);
4946 demand_empty_rest_of_line ();
4952 s_alpha_fp_save (ignore
)
4956 alpha_evax_proc
.fp_save
= tc_get_register (1);
4958 demand_empty_rest_of_line ();
4963 s_alpha_mask (ignore
)
4968 if (get_absolute_expression_and_terminator (&val
) != ',')
4970 as_warn (_("Bad .mask directive"));
4971 --input_line_pointer
;
4975 alpha_evax_proc
.imask
= val
;
4976 (void)get_absolute_expression ();
4978 demand_empty_rest_of_line ();
4984 s_alpha_fmask (ignore
)
4989 if (get_absolute_expression_and_terminator (&val
) != ',')
4991 as_warn (_("Bad .fmask directive"));
4992 --input_line_pointer
;
4996 alpha_evax_proc
.fmask
= val
;
4997 (void) get_absolute_expression ();
4999 demand_empty_rest_of_line ();
5005 s_alpha_end (ignore
)
5010 c
= get_symbol_end ();
5011 *input_line_pointer
= c
;
5012 demand_empty_rest_of_line ();
5013 alpha_evax_proc
.symbol
= 0;
5019 s_alpha_file (ignore
)
5024 static char case_hack
[32];
5026 extern char *demand_copy_string
PARAMS ((int *lenP
));
5028 sprintf (case_hack
, "<CASE:%01d%01d>",
5029 alpha_flag_hash_long_names
, alpha_flag_show_after_trunc
);
5031 s
= symbol_find_or_make (case_hack
);
5032 symbol_get_bfdsym (s
)->flags
|= BSF_FILE
;
5034 get_absolute_expression ();
5035 s
= symbol_find_or_make (demand_copy_string (&length
));
5036 symbol_get_bfdsym (s
)->flags
|= BSF_FILE
;
5037 demand_empty_rest_of_line ();
5041 #endif /* OBJ_EVAX */
5043 /* Handle the .gprel32 pseudo op. */
5046 s_alpha_gprel32 (ignore
)
5047 int ignore ATTRIBUTE_UNUSED
;
5059 e
.X_add_symbol
= section_symbol(absolute_section
);
5072 e
.X_add_symbol
= section_symbol (absolute_section
);
5075 e
.X_op
= O_subtract
;
5076 e
.X_op_symbol
= alpha_gp_symbol
;
5084 if (alpha_auto_align_on
&& alpha_current_align
< 2)
5085 alpha_align (2, (char *) NULL
, alpha_insn_label
, 0);
5086 if (alpha_current_align
> 2)
5087 alpha_current_align
= 2;
5088 alpha_insn_label
= NULL
;
5092 fix_new_exp (frag_now
, p
-frag_now
->fr_literal
, 4,
5093 &e
, 0, BFD_RELOC_GPREL32
);
5096 /* Handle floating point allocation pseudo-ops. This is like the
5097 generic vresion, but it makes sure the current label, if any, is
5098 correctly aligned. */
5101 s_alpha_float_cons (type
)
5128 if (alpha_auto_align_on
&& alpha_current_align
< log_size
)
5129 alpha_align (log_size
, (char *) NULL
, alpha_insn_label
, 0);
5130 if (alpha_current_align
> log_size
)
5131 alpha_current_align
= log_size
;
5132 alpha_insn_label
= NULL
;
5137 /* Handle the .proc pseudo op. We don't really do much with it except
5141 s_alpha_proc (is_static
)
5142 int is_static ATTRIBUTE_UNUSED
;
5150 /* Takes ".proc name,nargs" */
5152 name
= input_line_pointer
;
5153 c
= get_symbol_end ();
5154 p
= input_line_pointer
;
5155 symbolP
= symbol_find_or_make (name
);
5158 if (*input_line_pointer
!= ',')
5161 as_warn (_("Expected comma after name \"%s\""), name
);
5164 ignore_rest_of_line ();
5168 input_line_pointer
++;
5169 temp
= get_absolute_expression ();
5171 /* *symbol_get_obj (symbolP) = (signed char) temp; */
5172 as_warn (_("unhandled: .proc %s,%d"), name
, temp
);
5173 demand_empty_rest_of_line ();
5176 /* Handle the .set pseudo op. This is used to turn on and off most of
5177 the assembler features. */
5181 int x ATTRIBUTE_UNUSED
;
5187 name
= input_line_pointer
;
5188 ch
= get_symbol_end ();
5191 if (s
[0] == 'n' && s
[1] == 'o')
5196 if (!strcmp ("reorder", s
))
5198 else if (!strcmp ("at", s
))
5199 alpha_noat_on
= !yesno
;
5200 else if (!strcmp ("macro", s
))
5201 alpha_macros_on
= yesno
;
5202 else if (!strcmp ("move", s
))
5204 else if (!strcmp ("volatile", s
))
5207 as_warn (_("Tried to .set unrecognized mode `%s'"), name
);
5209 *input_line_pointer
= ch
;
5210 demand_empty_rest_of_line ();
5213 /* Handle the .base pseudo op. This changes the assembler's notion of
5214 the $gp register. */
5217 s_alpha_base (ignore
)
5218 int ignore ATTRIBUTE_UNUSED
;
5221 if (first_32bit_quadrant
)
5223 /* not fatal, but it might not work in the end */
5224 as_warn (_("File overrides no-base-register option."));
5225 first_32bit_quadrant
= 0;
5230 if (*input_line_pointer
== '$')
5232 input_line_pointer
++;
5233 if (*input_line_pointer
== 'r')
5234 input_line_pointer
++;
5237 alpha_gp_register
= get_absolute_expression ();
5238 if (alpha_gp_register
< 0 || alpha_gp_register
> 31)
5240 alpha_gp_register
= AXP_REG_GP
;
5241 as_warn (_("Bad base register, using $%d."), alpha_gp_register
);
5244 demand_empty_rest_of_line ();
5247 /* Handle the .align pseudo-op. This aligns to a power of two. It
5248 also adjusts any current instruction label. We treat this the same
5249 way the MIPS port does: .align 0 turns off auto alignment. */
5252 s_alpha_align (ignore
)
5253 int ignore ATTRIBUTE_UNUSED
;
5257 long max_alignment
= 15;
5259 align
= get_absolute_expression ();
5260 if (align
> max_alignment
)
5262 align
= max_alignment
;
5263 as_bad (_("Alignment too large: %d. assumed"), align
);
5267 as_warn (_("Alignment negative: 0 assumed"));
5271 if (*input_line_pointer
== ',')
5273 input_line_pointer
++;
5274 fill
= get_absolute_expression ();
5282 alpha_auto_align_on
= 1;
5283 alpha_align (align
, pfill
, alpha_insn_label
, 1);
5287 alpha_auto_align_on
= 0;
5290 demand_empty_rest_of_line ();
5293 /* Hook the normal string processor to reset known alignment. */
5296 s_alpha_stringer (terminate
)
5299 alpha_current_align
= 0;
5300 alpha_insn_label
= NULL
;
5301 stringer (terminate
);
5304 /* Hook the normal space processing to reset known alignment. */
5307 s_alpha_space (ignore
)
5310 alpha_current_align
= 0;
5311 alpha_insn_label
= NULL
;
5315 /* Hook into cons for auto-alignment. */
5318 alpha_cons_align (size
)
5324 while ((size
>>= 1) != 0)
5327 if (alpha_auto_align_on
&& alpha_current_align
< log_size
)
5328 alpha_align (log_size
, (char *) NULL
, alpha_insn_label
, 0);
5329 if (alpha_current_align
> log_size
)
5330 alpha_current_align
= log_size
;
5331 alpha_insn_label
= NULL
;
5334 /* Here come the .uword, .ulong, and .uquad explicitly unaligned
5335 pseudos. We just turn off auto-alignment and call down to cons. */
5338 s_alpha_ucons (bytes
)
5341 int hold
= alpha_auto_align_on
;
5342 alpha_auto_align_on
= 0;
5344 alpha_auto_align_on
= hold
;
5347 /* Switch the working cpu type. */
5350 s_alpha_arch (ignored
)
5351 int ignored ATTRIBUTE_UNUSED
;
5354 const struct cpu_type
*p
;
5357 name
= input_line_pointer
;
5358 ch
= get_symbol_end ();
5360 for (p
= cpu_types
; p
->name
; ++p
)
5361 if (strcmp(name
, p
->name
) == 0)
5363 alpha_target_name
= p
->name
, alpha_target
= p
->flags
;
5366 as_warn("Unknown CPU identifier `%s'", name
);
5369 *input_line_pointer
= ch
;
5370 demand_empty_rest_of_line ();
5376 /* print token expression with alpha specific extension. */
5379 alpha_print_token(f
, exp
)
5381 const expressionS
*exp
;
5391 expressionS nexp
= *exp
;
5392 nexp
.X_op
= O_register
;
5393 print_expr (f
, &nexp
);
5398 print_expr (f
, exp
);
5405 /* The target specific pseudo-ops which we support. */
5407 const pseudo_typeS md_pseudo_table
[] =
5410 {"comm", s_alpha_comm
, 0}, /* osf1 compiler does this */
5411 {"rdata", s_alpha_rdata
, 0},
5413 {"text", s_alpha_text
, 0},
5414 {"data", s_alpha_data
, 0},
5416 {"sdata", s_alpha_sdata
, 0},
5419 {"section", s_alpha_section
, 0},
5420 {"section.s", s_alpha_section
, 0},
5421 {"sect", s_alpha_section
, 0},
5422 {"sect.s", s_alpha_section
, 0},
5425 { "pdesc", s_alpha_pdesc
, 0},
5426 { "name", s_alpha_name
, 0},
5427 { "linkage", s_alpha_linkage
, 0},
5428 { "code_address", s_alpha_code_address
, 0},
5429 { "ent", s_alpha_ent
, 0},
5430 { "frame", s_alpha_frame
, 0},
5431 { "fp_save", s_alpha_fp_save
, 0},
5432 { "mask", s_alpha_mask
, 0},
5433 { "fmask", s_alpha_fmask
, 0},
5434 { "end", s_alpha_end
, 0},
5435 { "file", s_alpha_file
, 0},
5436 { "rdata", s_alpha_section
, 1},
5437 { "comm", s_alpha_comm
, 0},
5438 { "link", s_alpha_section
, 3},
5439 { "ctors", s_alpha_section
, 4},
5440 { "dtors", s_alpha_section
, 5},
5443 /* Frame related pseudos. */
5444 {"ent", s_alpha_ent
, 0},
5445 {"end", s_alpha_end
, 0},
5446 {"mask", s_alpha_mask
, 0},
5447 {"fmask", s_alpha_mask
, 1},
5448 {"frame", s_alpha_frame
, 0},
5449 {"prologue", s_alpha_prologue
, 0},
5450 /* COFF debugging related pseudos. */
5451 {"begin", s_alpha_coff_wrapper
, 0},
5452 {"bend", s_alpha_coff_wrapper
, 1},
5453 {"def", s_alpha_coff_wrapper
, 2},
5454 {"dim", s_alpha_coff_wrapper
, 3},
5455 {"endef", s_alpha_coff_wrapper
, 4},
5456 {"file", s_alpha_coff_wrapper
, 5},
5457 {"scl", s_alpha_coff_wrapper
, 6},
5458 {"tag", s_alpha_coff_wrapper
, 7},
5459 {"val", s_alpha_coff_wrapper
, 8},
5460 {"loc", s_alpha_coff_wrapper
, 9},
5462 {"prologue", s_ignore
, 0},
5464 {"gprel32", s_alpha_gprel32
, 0},
5465 {"t_floating", s_alpha_float_cons
, 'd'},
5466 {"s_floating", s_alpha_float_cons
, 'f'},
5467 {"f_floating", s_alpha_float_cons
, 'F'},
5468 {"g_floating", s_alpha_float_cons
, 'G'},
5469 {"d_floating", s_alpha_float_cons
, 'D'},
5471 {"proc", s_alpha_proc
, 0},
5472 {"aproc", s_alpha_proc
, 1},
5473 {"set", s_alpha_set
, 0},
5474 {"reguse", s_ignore
, 0},
5475 {"livereg", s_ignore
, 0},
5476 {"base", s_alpha_base
, 0}, /*??*/
5477 {"option", s_ignore
, 0},
5478 {"aent", s_ignore
, 0},
5479 {"ugen", s_ignore
, 0},
5480 {"eflag", s_ignore
, 0},
5482 {"align", s_alpha_align
, 0},
5483 {"double", s_alpha_float_cons
, 'd'},
5484 {"float", s_alpha_float_cons
, 'f'},
5485 {"single", s_alpha_float_cons
, 'f'},
5486 {"ascii", s_alpha_stringer
, 0},
5487 {"asciz", s_alpha_stringer
, 1},
5488 {"string", s_alpha_stringer
, 1},
5489 {"space", s_alpha_space
, 0},
5490 {"skip", s_alpha_space
, 0},
5491 {"zero", s_alpha_space
, 0},
5493 /* Unaligned data pseudos. */
5494 {"uword", s_alpha_ucons
, 2},
5495 {"ulong", s_alpha_ucons
, 4},
5496 {"uquad", s_alpha_ucons
, 8},
5499 /* Dwarf wants these versions of unaligned. */
5500 {"2byte", s_alpha_ucons
, 2},
5501 {"4byte", s_alpha_ucons
, 4},
5502 {"8byte", s_alpha_ucons
, 8},
5505 /* We don't do any optimizing, so we can safely ignore these. */
5506 {"noalias", s_ignore
, 0},
5507 {"alias", s_ignore
, 0},
5509 {"arch", s_alpha_arch
, 0},
5515 /* Build a BFD section with its flags set appropriately for the .lita,
5516 .lit8, or .lit4 sections. */
5519 create_literal_section (name
, secp
, symp
)
5524 segT current_section
= now_seg
;
5525 int current_subsec
= now_subseg
;
5528 *secp
= new_sec
= subseg_new (name
, 0);
5529 subseg_set (current_section
, current_subsec
);
5530 bfd_set_section_alignment (stdoutput
, new_sec
, 4);
5531 bfd_set_section_flags (stdoutput
, new_sec
,
5532 SEC_RELOC
| SEC_ALLOC
| SEC_LOAD
| SEC_READONLY
5535 S_CLEAR_EXTERNAL (*symp
= section_symbol (new_sec
));
5540 /* @@@ GP selection voodoo. All of this seems overly complicated and
5541 unnecessary; which is the primary reason it's for ECOFF only. */
5550 vma
= bfd_get_section_vma (foo
, sec
);
5551 if (vma
&& vma
< alpha_gp_value
)
5552 alpha_gp_value
= vma
;
5558 assert (alpha_gp_value
== 0);
5560 /* Get minus-one in whatever width... */
5561 alpha_gp_value
= 0; alpha_gp_value
--;
5563 /* Select the smallest VMA of these existing sections. */
5564 maybe_set_gp (alpha_lita_section
);
5566 /* These were disabled before -- should we use them? */
5567 maybe_set_gp (sdata
);
5568 maybe_set_gp (lit8_sec
);
5569 maybe_set_gp (lit4_sec
);
5572 /* @@ Will a simple 0x8000 work here? If not, why not? */
5573 #define GP_ADJUSTMENT (0x8000 - 0x10)
5575 alpha_gp_value
+= GP_ADJUSTMENT
;
5577 S_SET_VALUE (alpha_gp_symbol
, alpha_gp_value
);
5580 printf (_("Chose GP value of %lx\n"), alpha_gp_value
);
5583 #endif /* OBJ_ECOFF */
5585 /* Called internally to handle all alignment needs. This takes care
5586 of eliding calls to frag_align if'n the cached current alignment
5587 says we've already got it, as well as taking care of the auto-align
5588 feature wrt labels. */
5591 alpha_align (n
, pfill
, label
, force
)
5595 int force ATTRIBUTE_UNUSED
;
5597 if (alpha_current_align
>= n
)
5603 && (bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
) != 0)
5605 static char const unop
[4] = { 0x00, 0x00, 0xe0, 0x2f };
5606 static char const nopunop
[8] = {
5607 0x1f, 0x04, 0xff, 0x47,
5608 0x00, 0x00, 0xe0, 0x2f
5611 /* First, make sure we're on a four-byte boundary, in case
5612 someone has been putting .byte values into the text
5613 section. The DEC assembler silently fills with unaligned
5614 no-op instructions. This will zero-fill, then nop-fill
5615 with proper alignment. */
5616 if (alpha_current_align
< 2)
5617 frag_align (2, 0, 0);
5618 if (alpha_current_align
< 3)
5619 frag_align_pattern (3, unop
, sizeof unop
, 0);
5621 frag_align_pattern (n
, nopunop
, sizeof nopunop
, 0);
5624 frag_align (n
, 0, 0);
5627 frag_align (n
, *pfill
, 0);
5629 alpha_current_align
= n
;
5631 if (label
!= NULL
&& S_GET_SEGMENT (label
) == now_seg
)
5633 symbol_set_frag (label
, frag_now
);
5634 S_SET_VALUE (label
, (valueT
) frag_now_fix ());
5637 record_alignment (now_seg
, n
);
5639 /* ??? if alpha_flag_relax && force && elf, record the requested alignment
5640 in a reloc for the linker to see. */
5643 /* The Alpha has support for some VAX floating point types, as well as for
5644 IEEE floating point. We consider IEEE to be the primary floating point
5645 format, and sneak in the VAX floating point support here. */
5646 #define md_atof vax_md_atof
5647 #include "config/atof-vax.c"