1 /* tc-alpha.c - Processor-specific code for the DEC Alpha AXP CPU.
2 Copyright (C) 1989, 93-98, 1999 Free Software Foundation, Inc.
3 Contributed by Carnegie Mellon University, 1993.
4 Written by Alessandro Forin, based on earlier gas-1.38 target CPU files.
5 Modified by Ken Raeburn for gas-2.x and ECOFF support.
6 Modified by Richard Henderson for ELF support.
7 Modified by Klaus K"ampf for EVAX (OpenVMS/Alpha) support.
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)
131 /* Macros for extracting the type and number of encoded register tokens */
133 #define is_ir_num(x) (((x) & 32) == 0)
134 #define is_fpr_num(x) (((x) & 32) != 0)
135 #define regno(x) ((x) & 31)
137 /* Something odd inherited from the old assembler */
139 #define note_gpreg(R) (alpha_gprmask |= (1 << (R)))
140 #define note_fpreg(R) (alpha_fprmask |= (1 << (R)))
142 /* Predicates for 16- and 32-bit ranges */
143 /* XXX: The non-shift version appears to trigger a compiler bug when
144 cross-assembling from x86 w/ gcc 2.7.2. */
147 #define range_signed_16(x) \
148 (((offsetT)(x) >> 15) == 0 || ((offsetT)(x) >> 15) == -1)
149 #define range_signed_32(x) \
150 (((offsetT)(x) >> 31) == 0 || ((offsetT)(x) >> 31) == -1)
152 #define range_signed_16(x) ((offsetT)(x) >= -(offsetT)0x8000 && \
153 (offsetT)(x) <= (offsetT)0x7FFF)
154 #define range_signed_32(x) ((offsetT)(x) >= -(offsetT)0x80000000 && \
155 (offsetT)(x) <= (offsetT)0x7FFFFFFF)
158 /* Macros for sign extending from 16- and 32-bits. */
159 /* XXX: The cast macros will work on all the systems that I care about,
160 but really a predicate should be found to use the non-cast forms. */
163 #define sign_extend_16(x) ((short)(x))
164 #define sign_extend_32(x) ((int)(x))
166 #define sign_extend_16(x) ((offsetT)(((x) & 0xFFFF) ^ 0x8000) - 0x8000)
167 #define sign_extend_32(x) ((offsetT)(((x) & 0xFFFFFFFF) \
168 ^ 0x80000000) - 0x80000000)
171 /* Macros to build tokens */
173 #define set_tok_reg(t, r) (memset(&(t), 0, sizeof(t)), \
174 (t).X_op = O_register, \
175 (t).X_add_number = (r))
176 #define set_tok_preg(t, r) (memset(&(t), 0, sizeof(t)), \
177 (t).X_op = O_pregister, \
178 (t).X_add_number = (r))
179 #define set_tok_cpreg(t, r) (memset(&(t), 0, sizeof(t)), \
180 (t).X_op = O_cpregister, \
181 (t).X_add_number = (r))
182 #define set_tok_freg(t, r) (memset(&(t), 0, sizeof(t)), \
183 (t).X_op = O_register, \
184 (t).X_add_number = (r)+32)
185 #define set_tok_sym(t, s, a) (memset(&(t), 0, sizeof(t)), \
186 (t).X_op = O_symbol, \
187 (t).X_add_symbol = (s), \
188 (t).X_add_number = (a))
189 #define set_tok_const(t, n) (memset(&(t), 0, sizeof(t)), \
190 (t).X_op = O_constant, \
191 (t).X_add_number = (n))
194 /* Prototypes for all local functions */
196 static int tokenize_arguments
PARAMS ((char *, expressionS
*, int));
197 static const struct alpha_opcode
*find_opcode_match
198 PARAMS ((const struct alpha_opcode
*, const expressionS
*, int *, int *));
199 static const struct alpha_macro
*find_macro_match
200 PARAMS ((const struct alpha_macro
*, const expressionS
*, int *));
201 static unsigned insert_operand
202 PARAMS ((unsigned, const struct alpha_operand
*, offsetT
, char *, unsigned));
203 static void assemble_insn
204 PARAMS ((const struct alpha_opcode
*, const expressionS
*, int,
205 struct alpha_insn
*));
206 static void emit_insn
PARAMS ((struct alpha_insn
*));
207 static void assemble_tokens_to_insn
208 PARAMS ((const char *, const expressionS
*, int, struct alpha_insn
*));
209 static void assemble_tokens
210 PARAMS ((const char *, const expressionS
*, int, int));
212 static int load_expression
213 PARAMS ((int, const expressionS
*, int *, expressionS
*,
214 const expressionS
*));
216 static void emit_ldgp
PARAMS ((const expressionS
*, int, const PTR
));
217 static void emit_division
PARAMS ((const expressionS
*, int, const PTR
));
218 static void emit_lda
PARAMS ((const expressionS
*, int, const PTR
));
219 static void emit_ldah
PARAMS ((const expressionS
*, int, const PTR
));
220 static void emit_ir_load
PARAMS ((const expressionS
*, int, const PTR
));
221 static void emit_loadstore
PARAMS ((const expressionS
*, int, const PTR
));
222 static void emit_jsrjmp
PARAMS ((const expressionS
*, int, const PTR
));
223 static void emit_ldX
PARAMS ((const expressionS
*, int, const PTR
));
224 static void emit_ldXu
PARAMS ((const expressionS
*, int, const PTR
));
225 static void emit_uldX
PARAMS ((const expressionS
*, int, const PTR
));
226 static void emit_uldXu
PARAMS ((const expressionS
*, int, const PTR
));
227 static void emit_ldil
PARAMS ((const expressionS
*, int, const PTR
));
228 static void emit_stX
PARAMS ((const expressionS
*, int, const PTR
));
229 static void emit_ustX
PARAMS ((const expressionS
*, int, const PTR
));
230 static void emit_sextX
PARAMS ((const expressionS
*, int, const PTR
));
231 static void emit_retjcr
PARAMS ((const expressionS
*, int, const PTR
));
233 static void s_alpha_text
PARAMS ((int));
234 static void s_alpha_data
PARAMS ((int));
236 static void s_alpha_comm
PARAMS ((int));
237 static void s_alpha_rdata
PARAMS ((int));
240 static void s_alpha_sdata
PARAMS ((int));
243 static void s_alpha_section
PARAMS ((int));
244 static void s_alpha_ent
PARAMS ((int));
245 static void s_alpha_end
PARAMS ((int));
246 static void s_alpha_mask
PARAMS ((int));
247 static void s_alpha_frame
PARAMS ((int));
248 static void s_alpha_prologue
PARAMS ((int));
249 static void s_alpha_coff_wrapper
PARAMS ((int));
252 static void s_alpha_section
PARAMS ((int));
254 static void s_alpha_gprel32
PARAMS ((int));
255 static void s_alpha_float_cons
PARAMS ((int));
256 static void s_alpha_proc
PARAMS ((int));
257 static void s_alpha_set
PARAMS ((int));
258 static void s_alpha_base
PARAMS ((int));
259 static void s_alpha_align
PARAMS ((int));
260 static void s_alpha_stringer
PARAMS ((int));
261 static void s_alpha_space
PARAMS ((int));
263 static void create_literal_section
PARAMS ((const char *, segT
*, symbolS
**));
265 static void select_gp_value
PARAMS ((void));
267 static void alpha_align
PARAMS ((int, char *, symbolS
*, int));
270 static void alpha_adjust_symtab_relocs
PARAMS ((bfd
*, asection
*, PTR
));
274 /* Generic assembler global variables which must be defined by all
277 /* Characters which always start a comment. */
278 const char comment_chars
[] = "#";
280 /* Characters which start a comment at the beginning of a line. */
281 const char line_comment_chars
[] = "#";
283 /* Characters which may be used to separate multiple commands on a
285 const char line_separator_chars
[] = ";";
287 /* Characters which are used to indicate an exponent in a floating
289 const char EXP_CHARS
[] = "eE";
291 /* Characters which mean that a number is a floating point constant,
294 const char FLT_CHARS
[] = "dD";
296 /* XXX: Do all of these really get used on the alpha?? */
297 char FLT_CHARS
[] = "rRsSfFdDxXpP";
301 const char *md_shortopts
= "Fm:g+1h:HG:";
303 const char *md_shortopts
= "Fm:gG:";
306 struct option md_longopts
[] = {
307 #define OPTION_32ADDR (OPTION_MD_BASE)
308 { "32addr", no_argument
, NULL
, OPTION_32ADDR
},
309 #define OPTION_RELAX (OPTION_32ADDR+1)
310 { "relax", no_argument
, NULL
, OPTION_RELAX
},
312 #define OPTION_MDEBUG (OPTION_RELAX+1)
313 #define OPTION_NO_MDEBUG (OPTION_MDEBUG+1)
314 { "mdebug", no_argument
, NULL
, OPTION_MDEBUG
},
315 { "no-mdebug", no_argument
, NULL
, OPTION_NO_MDEBUG
},
317 { NULL
, no_argument
, NULL
, 0 }
320 size_t md_longopts_size
= sizeof(md_longopts
);
325 #define AXP_REG_R16 16
326 #define AXP_REG_R17 17
328 #define AXP_REG_T9 22
330 #define AXP_REG_T10 23
332 #define AXP_REG_T11 24
334 #define AXP_REG_T12 25
335 #define AXP_REG_AI 25
337 #define AXP_REG_FP 29
340 #define AXP_REG_GP AXP_REG_PV
341 #endif /* OBJ_EVAX */
343 /* The cpu for which we are generating code */
344 static unsigned alpha_target
= AXP_OPCODE_BASE
;
345 static const char *alpha_target_name
= "<all>";
347 /* The hash table of instruction opcodes */
348 static struct hash_control
*alpha_opcode_hash
;
350 /* The hash table of macro opcodes */
351 static struct hash_control
*alpha_macro_hash
;
354 /* The $gp relocation symbol */
355 static symbolS
*alpha_gp_symbol
;
357 /* XXX: what is this, and why is it exported? */
358 valueT alpha_gp_value
;
361 /* The current $gp register */
362 static int alpha_gp_register
= AXP_REG_GP
;
364 /* A table of the register symbols */
365 static symbolS
*alpha_register_table
[64];
367 /* Constant sections, or sections of constants */
369 static segT alpha_lita_section
;
370 static segT alpha_lit4_section
;
373 static segT alpha_link_section
;
374 static segT alpha_ctors_section
;
375 static segT alpha_dtors_section
;
377 static segT alpha_lit8_section
;
379 /* Symbols referring to said sections. */
381 static symbolS
*alpha_lita_symbol
;
382 static symbolS
*alpha_lit4_symbol
;
385 static symbolS
*alpha_link_symbol
;
386 static symbolS
*alpha_ctors_symbol
;
387 static symbolS
*alpha_dtors_symbol
;
389 static symbolS
*alpha_lit8_symbol
;
391 /* Literal for .litX+0x8000 within .lita */
393 static offsetT alpha_lit4_literal
;
394 static offsetT alpha_lit8_literal
;
397 /* The active .ent symbol. */
399 static symbolS
*alpha_cur_ent_sym
;
402 /* Is the assembler not allowed to use $at? */
403 static int alpha_noat_on
= 0;
405 /* Are macros enabled? */
406 static int alpha_macros_on
= 1;
408 /* Are floats disabled? */
409 static int alpha_nofloats_on
= 0;
411 /* Are addresses 32 bit? */
412 static int alpha_addr32_on
= 0;
414 /* Symbol labelling the current insn. When the Alpha gas sees
417 and the section happens to not be on an eight byte boundary, it
418 will align both the symbol and the .quad to an eight byte boundary. */
419 static symbolS
*alpha_insn_label
;
421 /* Whether we should automatically align data generation pseudo-ops.
422 .align 0 will turn this off. */
423 static int alpha_auto_align_on
= 1;
425 /* The known current alignment of the current section. */
426 static int alpha_current_align
;
428 /* These are exported to ECOFF code. */
429 unsigned long alpha_gprmask
, alpha_fprmask
;
431 /* Whether the debugging option was seen. */
432 static int alpha_debug
;
435 /* Whether we are emitting an mdebug section. */
436 int alpha_flag_mdebug
= 1;
439 /* Don't fully resolve relocations, allowing code movement in the linker. */
440 static int alpha_flag_relax
;
442 /* What value to give to bfd_set_gp_size. */
443 static int g_switch_value
= 8;
446 /* Collect information about current procedure here. */
448 symbolS
*symbol
; /* proc pdesc symbol */
450 int framereg
; /* register for frame pointer */
451 int framesize
; /* size of frame */
461 static int alpha_flag_hash_long_names
= 0; /* -+ */
462 static int alpha_flag_show_after_trunc
= 0; /* -H */
464 /* If the -+ switch is given, then a hash is appended to any name that is
465 * longer than 64 characters, else longer symbol names are truncated.
471 /* A table to map the spelling of a relocation operand into an appropriate
472 bfd_reloc_code_real_type type. The table is assumed to be ordered such
473 that op-O_literal indexes into it. */
475 #define ALPHA_RELOC_TABLE(op) \
476 &alpha_reloc_op[ ((!USER_RELOC_P (op)) \
478 : (int)(op) - (int)O_literal) ]
480 #define LITUSE_BASE 1
481 #define LITUSE_BYTOFF 2
484 static const struct alpha_reloc_op_tag
{
485 const char *name
; /* string to lookup */
486 size_t length
; /* size of the string */
487 bfd_reloc_code_real_type reloc
; /* relocation before frob */
488 operatorT op
; /* which operator to use */
489 int lituse
; /* addened to specify lituse */
490 } alpha_reloc_op
[] = {
493 "literal", /* name */
494 sizeof ("literal")-1, /* length */
495 BFD_RELOC_ALPHA_USER_LITERAL
, /* reloc */
501 "lituse_base", /* name */
502 sizeof ("lituse_base")-1, /* length */
503 BFD_RELOC_ALPHA_USER_LITUSE_BASE
, /* reloc */
504 O_lituse_base
, /* op */
505 LITUSE_BASE
, /* lituse */
509 "lituse_bytoff", /* name */
510 sizeof ("lituse_bytoff")-1, /* length */
511 BFD_RELOC_ALPHA_USER_LITUSE_BYTOFF
, /* reloc */
512 O_lituse_bytoff
, /* op */
513 LITUSE_BYTOFF
, /* lituse */
517 "lituse_jsr", /* name */
518 sizeof ("lituse_jsr")-1, /* length */
519 BFD_RELOC_ALPHA_USER_LITUSE_JSR
, /* reloc */
520 O_lituse_jsr
, /* op */
521 LITUSE_JSR
, /* lituse */
526 sizeof ("gpdisp")-1, /* length */
527 BFD_RELOC_ALPHA_USER_GPDISP
, /* reloc */
533 "gprelhigh", /* name */
534 sizeof ("gprelhigh")-1, /* length */
535 BFD_RELOC_ALPHA_USER_GPRELHIGH
, /* reloc */
536 O_gprelhigh
, /* op */
541 "gprellow", /* name */
542 sizeof ("gprellow")-1, /* length */
543 BFD_RELOC_ALPHA_USER_GPRELLOW
, /* reloc */
549 static const int alpha_num_reloc_op
550 = sizeof(alpha_reloc_op
) / sizeof(*alpha_reloc_op
);
552 /* Maximum # digits needed to hold the largest sequence # */
553 #define ALPHA_RELOC_DIGITS 25
555 /* Whether a sequence number is valid. */
556 #define ALPHA_RELOC_SEQUENCE_OK(X) ((X) > 0 && ((unsigned)(X)) == (X))
558 /* Structure to hold explict sequence information. */
559 struct alpha_literal_tag
561 fixS
*lituse
; /* head of linked list of !literals */
562 segT segment
; /* segment relocs are in or undefined_section*/
563 int multi_section_p
; /* True if more than one section was used */
564 unsigned sequence
; /* sequence # */
565 unsigned n_literals
; /* # of literals */
566 unsigned n_lituses
; /* # of lituses */
567 char string
[1]; /* printable form of sequence to hash with */
570 /* Hash table to link up literals with the appropriate lituse */
571 static struct hash_control
*alpha_literal_hash
;
574 /* A table of CPU names and opcode sets. */
576 static const struct cpu_type
582 /* Ad hoc convention: cpu number gets palcode, process code doesn't.
583 This supports usage under DU 4.0b that does ".arch ev4", and
584 usage in MILO that does -m21064. Probably something more
585 specific like -m21064-pal should be used, but oh well. */
587 { "21064", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
588 { "21064a", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
589 { "21066", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
590 { "21068", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
591 { "21164", AXP_OPCODE_BASE
|AXP_OPCODE_EV5
},
592 { "21164a", AXP_OPCODE_BASE
|AXP_OPCODE_EV5
|AXP_OPCODE_BWX
},
593 { "21164pc", (AXP_OPCODE_BASE
|AXP_OPCODE_EV5
|AXP_OPCODE_BWX
595 { "21264", (AXP_OPCODE_BASE
|AXP_OPCODE_EV6
|AXP_OPCODE_BWX
596 |AXP_OPCODE_MAX
|AXP_OPCODE_CIX
) },
598 { "ev4", AXP_OPCODE_BASE
},
599 { "ev45", AXP_OPCODE_BASE
},
600 { "lca45", AXP_OPCODE_BASE
},
601 { "ev5", AXP_OPCODE_BASE
},
602 { "ev56", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
},
603 { "pca56", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
|AXP_OPCODE_MAX
},
604 { "ev6", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
|AXP_OPCODE_MAX
|AXP_OPCODE_CIX
},
606 { "all", AXP_OPCODE_BASE
},
610 /* The macro table */
612 static const struct alpha_macro alpha_macros
[] = {
613 /* Load/Store macros */
614 { "lda", emit_lda
, NULL
,
615 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_LITERAL
, MACRO_BASE
, MACRO_EOA
} },
616 { "ldah", emit_ldah
, NULL
,
617 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
619 { "ldl", emit_ir_load
, "ldl",
620 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
621 { "ldl_l", emit_ir_load
, "ldl_l",
622 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
623 { "ldq", emit_ir_load
, "ldq",
624 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_LITERAL
, MACRO_EOA
} },
625 { "ldq_l", emit_ir_load
, "ldq_l",
626 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
627 { "ldq_u", emit_ir_load
, "ldq_u",
628 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
629 { "ldf", emit_loadstore
, "ldf",
630 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
631 { "ldg", emit_loadstore
, "ldg",
632 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
633 { "lds", emit_loadstore
, "lds",
634 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
635 { "ldt", emit_loadstore
, "ldt",
636 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
638 { "ldb", emit_ldX
, (PTR
)0,
639 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
640 { "ldbu", emit_ldXu
, (PTR
)0,
641 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
642 { "ldw", emit_ldX
, (PTR
)1,
643 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
644 { "ldwu", emit_ldXu
, (PTR
)1,
645 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
647 { "uldw", emit_uldX
, (PTR
)1,
648 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
649 { "uldwu", emit_uldXu
, (PTR
)1,
650 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
651 { "uldl", emit_uldX
, (PTR
)2,
652 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
653 { "uldlu", emit_uldXu
, (PTR
)2,
654 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
655 { "uldq", emit_uldXu
, (PTR
)3,
656 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
658 { "ldgp", emit_ldgp
, NULL
,
659 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
} },
661 { "ldi", emit_lda
, NULL
,
662 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
663 { "ldil", emit_ldil
, NULL
,
664 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
665 { "ldiq", emit_lda
, NULL
,
666 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
668 { "ldif" emit_ldiq
, NULL
,
669 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
670 { "ldid" emit_ldiq
, NULL
,
671 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
672 { "ldig" emit_ldiq
, NULL
,
673 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
674 { "ldis" emit_ldiq
, NULL
,
675 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
676 { "ldit" emit_ldiq
, NULL
,
677 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
680 { "stl", emit_loadstore
, "stl",
681 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
682 { "stl_c", emit_loadstore
, "stl_c",
683 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
684 { "stq", emit_loadstore
, "stq",
685 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
686 { "stq_c", emit_loadstore
, "stq_c",
687 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
688 { "stq_u", emit_loadstore
, "stq_u",
689 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
690 { "stf", emit_loadstore
, "stf",
691 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
692 { "stg", emit_loadstore
, "stg",
693 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
694 { "sts", emit_loadstore
, "sts",
695 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
696 { "stt", emit_loadstore
, "stt",
697 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
699 { "stb", emit_stX
, (PTR
)0,
700 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
701 { "stw", emit_stX
, (PTR
)1,
702 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
703 { "ustw", emit_ustX
, (PTR
)1,
704 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
705 { "ustl", emit_ustX
, (PTR
)2,
706 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
707 { "ustq", emit_ustX
, (PTR
)3,
708 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
710 /* Arithmetic macros */
712 { "absl" emit_absl
, 1, { IR
} },
713 { "absl" emit_absl
, 2, { IR
, IR
} },
714 { "absl" emit_absl
, 2, { EXP
, IR
} },
715 { "absq" emit_absq
, 1, { IR
} },
716 { "absq" emit_absq
, 2, { IR
, IR
} },
717 { "absq" emit_absq
, 2, { EXP
, IR
} },
720 { "sextb", emit_sextX
, (PTR
)0,
721 { MACRO_IR
, MACRO_IR
, MACRO_EOA
,
723 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
724 { "sextw", emit_sextX
, (PTR
)1,
725 { MACRO_IR
, MACRO_IR
, MACRO_EOA
,
727 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
729 { "divl", emit_division
, "__divl",
730 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
731 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
732 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
733 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
734 { "divlu", emit_division
, "__divlu",
735 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
736 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
737 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
738 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
739 { "divq", emit_division
, "__divq",
740 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
741 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
742 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
743 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
744 { "divqu", emit_division
, "__divqu",
745 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
746 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
747 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
748 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
749 { "reml", emit_division
, "__reml",
750 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
751 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
752 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
753 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
754 { "remlu", emit_division
, "__remlu",
755 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
756 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
757 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
758 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
759 { "remq", emit_division
, "__remq",
760 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
761 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
762 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
763 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
764 { "remqu", emit_division
, "__remqu",
765 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
766 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
767 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
768 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
770 { "jsr", emit_jsrjmp
, "jsr",
771 { MACRO_PIR
, MACRO_EXP
, MACRO_JSR
, MACRO_EOA
,
772 MACRO_PIR
, MACRO_JSR
, MACRO_EOA
,
773 MACRO_IR
, MACRO_EXP
, MACRO_JSR
, MACRO_EOA
,
774 MACRO_EXP
, MACRO_JSR
, MACRO_EOA
} },
775 { "jmp", emit_jsrjmp
, "jmp",
776 { MACRO_PIR
, MACRO_EXP
, MACRO_JSR
, MACRO_EOA
,
777 MACRO_PIR
, MACRO_JSR
, MACRO_EOA
,
778 MACRO_IR
, MACRO_EXP
, MACRO_JSR
, MACRO_EOA
,
779 MACRO_EXP
, MACRO_JSR
, MACRO_EOA
} },
780 { "ret", emit_retjcr
, "ret",
781 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
783 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
784 MACRO_PIR
, MACRO_EOA
,
785 MACRO_EXP
, MACRO_EOA
,
787 { "jcr", emit_retjcr
, "jcr",
788 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
790 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
791 MACRO_PIR
, MACRO_EOA
,
792 MACRO_EXP
, MACRO_EOA
,
794 { "jsr_coroutine", emit_retjcr
, "jcr",
795 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
797 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
798 MACRO_PIR
, MACRO_EOA
,
799 MACRO_EXP
, MACRO_EOA
,
803 static const unsigned int alpha_num_macros
804 = sizeof(alpha_macros
) / sizeof(*alpha_macros
);
806 /* Public interface functions */
808 /* This function is called once, at assembler startup time. It sets
809 up all the tables, etc. that the MD part of the assembler will
810 need, that can be determined before arguments are parsed. */
817 /* Verify that X_op field is wide enough. */
821 assert (e
.X_op
== O_max
);
824 /* Create the opcode hash table */
826 alpha_opcode_hash
= hash_new ();
827 for (i
= 0; i
< alpha_num_opcodes
; )
829 const char *name
, *retval
, *slash
;
831 name
= alpha_opcodes
[i
].name
;
832 retval
= hash_insert (alpha_opcode_hash
, name
, (PTR
)&alpha_opcodes
[i
]);
834 as_fatal (_("internal error: can't hash opcode `%s': %s"), name
, retval
);
836 /* Some opcodes include modifiers of various sorts with a "/mod"
837 syntax, like the architecture manual suggests. However, for
838 use with gcc at least, we also need access to those same opcodes
841 if ((slash
= strchr (name
, '/')) != NULL
)
843 char *p
= xmalloc (strlen (name
));
844 memcpy (p
, name
, slash
- name
);
845 strcpy (p
+ (slash
- name
), slash
+ 1);
847 (void)hash_insert(alpha_opcode_hash
, p
, (PTR
)&alpha_opcodes
[i
]);
848 /* Ignore failures -- the opcode table does duplicate some
849 variants in different forms, like "hw_stq" and "hw_st/q". */
852 while (++i
< alpha_num_opcodes
853 && (alpha_opcodes
[i
].name
== name
854 || !strcmp (alpha_opcodes
[i
].name
, name
)))
858 /* Create the macro hash table */
860 alpha_macro_hash
= hash_new ();
861 for (i
= 0; i
< alpha_num_macros
; )
863 const char *name
, *retval
;
865 name
= alpha_macros
[i
].name
;
866 retval
= hash_insert (alpha_macro_hash
, name
, (PTR
)&alpha_macros
[i
]);
868 as_fatal (_("internal error: can't hash macro `%s': %s"), name
, retval
);
870 while (++i
< alpha_num_macros
871 && (alpha_macros
[i
].name
== name
872 || !strcmp (alpha_macros
[i
].name
, name
)))
876 /* Construct symbols for each of the registers */
878 for (i
= 0; i
< 32; ++i
)
881 sprintf(name
, "$%d", i
);
882 alpha_register_table
[i
] = symbol_create(name
, reg_section
, i
,
888 sprintf(name
, "$f%d", i
-32);
889 alpha_register_table
[i
] = symbol_create(name
, reg_section
, i
,
893 /* Create the special symbols and sections we'll be using */
895 /* So .sbss will get used for tiny objects. */
896 bfd_set_gp_size (stdoutput
, g_switch_value
);
899 create_literal_section (".lita", &alpha_lita_section
, &alpha_lita_symbol
);
901 /* For handling the GP, create a symbol that won't be output in the
902 symbol table. We'll edit it out of relocs later. */
903 alpha_gp_symbol
= symbol_create ("<GP value>", alpha_lita_section
, 0x8000,
908 create_literal_section (".link", &alpha_link_section
, &alpha_link_symbol
);
914 segT sec
= subseg_new(".mdebug", (subsegT
)0);
915 bfd_set_section_flags(stdoutput
, sec
, SEC_HAS_CONTENTS
|SEC_READONLY
);
916 bfd_set_section_alignment(stdoutput
, sec
, 3);
920 subseg_set(text_section
, 0);
923 /* Create literal lookup hash table. */
924 alpha_literal_hash
= hash_new();
928 /* The public interface to the instruction assembler. */
934 char opname
[32]; /* current maximum is 13 */
935 expressionS tok
[MAX_INSN_ARGS
];
939 /* split off the opcode */
940 opnamelen
= strspn (str
, "abcdefghijklmnopqrstuvwxyz_/46819");
941 trunclen
= (opnamelen
< sizeof (opname
) - 1
943 : sizeof (opname
) - 1);
944 memcpy (opname
, str
, trunclen
);
945 opname
[trunclen
] = '\0';
947 /* tokenize the rest of the line */
948 if ((ntok
= tokenize_arguments (str
+ opnamelen
, tok
, MAX_INSN_ARGS
)) < 0)
950 if (ntok
!= TOKENIZE_ERROR_REPORT
)
951 as_bad (_("syntax error"));
957 assemble_tokens (opname
, tok
, ntok
, alpha_macros_on
);
960 /* Round up a section's size to the appropriate boundary. */
963 md_section_align (seg
, size
)
967 int align
= bfd_get_section_alignment(stdoutput
, seg
);
968 valueT mask
= ((valueT
)1 << align
) - 1;
970 return (size
+ mask
) & ~mask
;
973 /* Turn a string in input_line_pointer into a floating point constant
974 of type type, and store the appropriate bytes in *litP. The number
975 of LITTLENUMS emitted is stored in *sizeP. An error message is
976 returned, or NULL on OK. */
978 /* Equal to MAX_PRECISION in atof-ieee.c */
979 #define MAX_LITTLENUMS 6
981 extern char *vax_md_atof
PARAMS ((int, char *, int *));
984 md_atof (type
, litP
, sizeP
)
990 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
991 LITTLENUM_TYPE
*wordP
;
998 /* VAX md_atof doesn't like "G" for some reason. */
1002 return vax_md_atof (type
, litP
, sizeP
);
1025 return _("Bad call to MD_ATOF()");
1027 t
= atof_ieee (input_line_pointer
, type
, words
);
1029 input_line_pointer
= t
;
1030 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
1032 for (wordP
= words
+ prec
- 1; prec
--;)
1034 md_number_to_chars (litP
, (long) (*wordP
--), sizeof (LITTLENUM_TYPE
));
1035 litP
+= sizeof (LITTLENUM_TYPE
);
1041 /* Take care of the target-specific command-line options. */
1044 md_parse_option (c
, arg
)
1051 alpha_nofloats_on
= 1;
1055 alpha_addr32_on
= 1;
1063 g_switch_value
= atoi(arg
);
1068 const struct cpu_type
*p
;
1069 for (p
= cpu_types
; p
->name
; ++p
)
1070 if (strcmp(arg
, p
->name
) == 0)
1072 alpha_target_name
= p
->name
, alpha_target
= p
->flags
;
1075 as_warn(_("Unknown CPU identifier `%s'"), arg
);
1081 case '+': /* For g++. Hash any name > 63 chars long. */
1082 alpha_flag_hash_long_names
= 1;
1085 case 'H': /* Show new symbol after hash truncation */
1086 alpha_flag_show_after_trunc
= 1;
1089 case 'h': /* for gnu-c/vax compatibility. */
1094 alpha_flag_relax
= 1;
1099 alpha_flag_mdebug
= 1;
1101 case OPTION_NO_MDEBUG
:
1102 alpha_flag_mdebug
= 0;
1113 /* Print a description of the command-line options that we accept. */
1116 md_show_usage (stream
)
1121 -32addr treat addresses as 32-bit values\n\
1122 -F lack floating point instructions support\n\
1123 -mev4 | -mev45 | -mev5 | -mev56 | -mpca56 | -mev6 | -mall\n\
1124 specify variant of Alpha architecture\n\
1125 -m21064 | -m21066 | -m21164 | -m21164a | -m21164pc | -m21264\n\
1126 these variants include PALcode opcodes\n"),
1131 -+ hash encode (don't truncate) names longer than 64 characters\n\
1132 -H show new symbol after hash truncation\n"),
1137 /* Decide from what point a pc-relative relocation is relative to,
1138 relative to the pc-relative fixup. Er, relatively speaking. */
1141 md_pcrel_from (fixP
)
1144 valueT addr
= fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
1145 switch (fixP
->fx_r_type
)
1147 case BFD_RELOC_ALPHA_GPDISP
:
1148 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1149 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1152 return fixP
->fx_size
+ addr
;
1156 /* Attempt to simplify or even eliminate a fixup. The return value is
1157 ignored; perhaps it was once meaningful, but now it is historical.
1158 To indicate that a fixup has been eliminated, set fixP->fx_done.
1160 For ELF, here it is that we transform the GPDISP_HI16 reloc we used
1161 internally into the GPDISP reloc used externally. We had to do
1162 this so that we'd have the GPDISP_LO16 reloc as a tag to compute
1163 the distance to the "lda" instruction for setting the addend to
1167 md_apply_fix (fixP
, valueP
)
1171 char * const fixpos
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
1172 valueT value
= *valueP
;
1173 unsigned image
, size
;
1175 switch (fixP
->fx_r_type
)
1177 /* The GPDISP relocations are processed internally with a symbol
1178 referring to the current function; we need to drop in a value
1179 which, when added to the address of the start of the function,
1180 gives the desired GP. */
1181 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1183 fixS
*next
= fixP
->fx_next
;
1184 assert (next
->fx_r_type
== BFD_RELOC_ALPHA_GPDISP_LO16
);
1186 fixP
->fx_offset
= (next
->fx_frag
->fr_address
+ next
->fx_where
1187 - fixP
->fx_frag
->fr_address
- fixP
->fx_where
);
1189 value
= (value
- sign_extend_16 (value
)) >> 16;
1192 fixP
->fx_r_type
= BFD_RELOC_ALPHA_GPDISP
;
1196 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1197 value
= sign_extend_16 (value
);
1198 fixP
->fx_offset
= 0;
1204 fixP
->fx_addsy
= section_symbol (now_seg
);
1205 md_number_to_chars (fixpos
, value
, 2);
1210 fixP
->fx_r_type
= BFD_RELOC_16_PCREL
;
1215 fixP
->fx_r_type
= BFD_RELOC_32_PCREL
;
1220 fixP
->fx_r_type
= BFD_RELOC_64_PCREL
;
1223 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
1225 md_number_to_chars (fixpos
, value
, size
);
1231 case BFD_RELOC_GPREL32
:
1232 assert (fixP
->fx_subsy
== alpha_gp_symbol
);
1234 /* FIXME: inherited this obliviousness of `value' -- why? */
1235 md_number_to_chars (fixpos
, -alpha_gp_value
, 4);
1239 case BFD_RELOC_GPREL32
:
1243 case BFD_RELOC_23_PCREL_S2
:
1244 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
1246 image
= bfd_getl32(fixpos
);
1247 image
= (image
& ~0x1FFFFF) | ((value
>> 2) & 0x1FFFFF);
1252 case BFD_RELOC_ALPHA_HINT
:
1253 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
1255 image
= bfd_getl32(fixpos
);
1256 image
= (image
& ~0x3FFF) | ((value
>> 2) & 0x3FFF);
1262 case BFD_RELOC_ALPHA_LITERAL
:
1263 md_number_to_chars (fixpos
, value
, 2);
1266 case BFD_RELOC_ALPHA_LITUSE
:
1270 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1271 case BFD_RELOC_ALPHA_LITUSE
:
1275 case BFD_RELOC_ALPHA_LINKAGE
:
1276 case BFD_RELOC_ALPHA_CODEADDR
:
1281 case BFD_RELOC_ALPHA_USER_LITERAL
:
1282 case BFD_RELOC_ALPHA_USER_LITUSE_BASE
:
1283 case BFD_RELOC_ALPHA_USER_LITUSE_BYTOFF
:
1284 case BFD_RELOC_ALPHA_USER_LITUSE_JSR
:
1287 case BFD_RELOC_ALPHA_USER_GPDISP
:
1288 case BFD_RELOC_ALPHA_USER_GPRELHIGH
:
1289 case BFD_RELOC_ALPHA_USER_GPRELLOW
:
1295 const struct alpha_operand
*operand
;
1297 if ((int)fixP
->fx_r_type
>= 0)
1298 as_fatal (_("unhandled relocation type %s"),
1299 bfd_get_reloc_code_name (fixP
->fx_r_type
));
1301 assert (-(int)fixP
->fx_r_type
< (int)alpha_num_operands
);
1302 operand
= &alpha_operands
[-(int)fixP
->fx_r_type
];
1304 /* The rest of these fixups only exist internally during symbol
1305 resolution and have no representation in the object file.
1306 Therefore they must be completely resolved as constants. */
1308 if (fixP
->fx_addsy
!= 0
1309 && S_GET_SEGMENT (fixP
->fx_addsy
) != absolute_section
)
1310 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
1311 _("non-absolute expression in constant field"));
1313 image
= bfd_getl32(fixpos
);
1314 image
= insert_operand(image
, operand
, (offsetT
)value
,
1315 fixP
->fx_file
, fixP
->fx_line
);
1320 if (fixP
->fx_addsy
!= 0 || fixP
->fx_pcrel
!= 0)
1324 as_warn_where(fixP
->fx_file
, fixP
->fx_line
,
1325 _("type %d reloc done?\n"), (int)fixP
->fx_r_type
);
1330 md_number_to_chars(fixpos
, image
, 4);
1338 * Look for a register name in the given symbol.
1342 md_undefined_symbol(name
)
1347 int is_float
= 0, num
;
1352 if (name
[1] == 'p' && name
[2] == '\0')
1353 return alpha_register_table
[AXP_REG_FP
];
1358 if (!isdigit(*++name
))
1362 case '0': case '1': case '2': case '3': case '4':
1363 case '5': case '6': case '7': case '8': case '9':
1364 if (name
[1] == '\0')
1365 num
= name
[0] - '0';
1366 else if (name
[0] != '0' && isdigit(name
[1]) && name
[2] == '\0')
1368 num
= (name
[0] - '0') * 10 + name
[1] - '0';
1375 if (!alpha_noat_on
&& num
== AXP_REG_AT
)
1376 as_warn(_("Used $at without \".set noat\""));
1377 return alpha_register_table
[num
+ is_float
];
1380 if (name
[1] == 't' && name
[2] == '\0')
1383 as_warn(_("Used $at without \".set noat\""));
1384 return alpha_register_table
[AXP_REG_AT
];
1389 if (name
[1] == 'p' && name
[2] == '\0')
1390 return alpha_register_table
[alpha_gp_register
];
1394 if (name
[1] == 'p' && name
[2] == '\0')
1395 return alpha_register_table
[AXP_REG_SP
];
1403 /* @@@ Magic ECOFF bits. */
1406 alpha_frob_ecoff_data ()
1409 /* $zero and $f31 are read-only */
1410 alpha_gprmask
&= ~1;
1411 alpha_fprmask
&= ~1;
1415 /* Hook to remember a recently defined label so that the auto-align
1416 code can adjust the symbol after we know what alignment will be
1420 alpha_define_label (sym
)
1423 alpha_insn_label
= sym
;
1426 /* Return true if we must always emit a reloc for a type and false if
1427 there is some hope of resolving it a assembly time. */
1430 alpha_force_relocation (f
)
1433 if (alpha_flag_relax
)
1436 switch (f
->fx_r_type
)
1438 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1439 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1440 case BFD_RELOC_ALPHA_GPDISP
:
1442 case BFD_RELOC_ALPHA_LITERAL
:
1445 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1447 case BFD_RELOC_ALPHA_LITUSE
:
1448 case BFD_RELOC_GPREL32
:
1450 case BFD_RELOC_ALPHA_LINKAGE
:
1451 case BFD_RELOC_ALPHA_CODEADDR
:
1454 case BFD_RELOC_ALPHA_USER_LITERAL
:
1455 case BFD_RELOC_ALPHA_USER_LITUSE_BASE
:
1456 case BFD_RELOC_ALPHA_USER_LITUSE_BYTOFF
:
1457 case BFD_RELOC_ALPHA_USER_LITUSE_JSR
:
1458 case BFD_RELOC_ALPHA_USER_GPDISP
:
1459 case BFD_RELOC_ALPHA_USER_GPRELHIGH
:
1460 case BFD_RELOC_ALPHA_USER_GPRELLOW
:
1464 case BFD_RELOC_23_PCREL_S2
:
1467 case BFD_RELOC_ALPHA_HINT
:
1471 assert((int)f
->fx_r_type
< 0 && -(int)f
->fx_r_type
< (int)alpha_num_operands
);
1476 /* Return true if we can partially resolve a relocation now. */
1479 alpha_fix_adjustable (f
)
1483 /* Prevent all adjustments to global symbols */
1484 if (S_IS_EXTERN (f
->fx_addsy
) || S_IS_WEAK (f
->fx_addsy
))
1488 /* Are there any relocation types for which we must generate a reloc
1489 but we can adjust the values contained within it? */
1490 switch (f
->fx_r_type
)
1492 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1493 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1494 case BFD_RELOC_ALPHA_GPDISP
:
1498 case BFD_RELOC_ALPHA_LITERAL
:
1501 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1504 case BFD_RELOC_ALPHA_USER_LITERAL
:
1507 case BFD_RELOC_ALPHA_LINKAGE
:
1508 case BFD_RELOC_ALPHA_CODEADDR
:
1512 case BFD_RELOC_ALPHA_LITUSE
:
1514 case BFD_RELOC_ALPHA_USER_LITUSE_BASE
:
1515 case BFD_RELOC_ALPHA_USER_LITUSE_BYTOFF
:
1516 case BFD_RELOC_ALPHA_USER_LITUSE_JSR
:
1517 case BFD_RELOC_ALPHA_USER_GPDISP
:
1518 case BFD_RELOC_ALPHA_USER_GPRELHIGH
:
1519 case BFD_RELOC_ALPHA_USER_GPRELLOW
:
1523 case BFD_RELOC_GPREL32
:
1524 case BFD_RELOC_23_PCREL_S2
:
1527 case BFD_RELOC_ALPHA_HINT
:
1531 assert ((int)f
->fx_r_type
< 0
1532 && - (int)f
->fx_r_type
< (int)alpha_num_operands
);
1538 /* Generate the BFD reloc to be stuck in the object file from the
1539 fixup used internally in the assembler. */
1542 tc_gen_reloc (sec
, fixp
)
1543 asection
*sec ATTRIBUTE_UNUSED
;
1548 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
1549 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
1550 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
1551 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
1553 /* Make sure none of our internal relocations make it this far.
1554 They'd better have been fully resolved by this point. */
1555 assert ((int)fixp
->fx_r_type
> 0);
1557 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
1558 if (reloc
->howto
== NULL
)
1560 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1561 _("cannot represent `%s' relocation in object file"),
1562 bfd_get_reloc_code_name (fixp
->fx_r_type
));
1566 if (!fixp
->fx_pcrel
!= !reloc
->howto
->pc_relative
)
1568 as_fatal (_("internal error? cannot generate `%s' relocation"),
1569 bfd_get_reloc_code_name (fixp
->fx_r_type
));
1571 assert (!fixp
->fx_pcrel
== !reloc
->howto
->pc_relative
);
1574 if (fixp
->fx_r_type
== BFD_RELOC_ALPHA_LITERAL
)
1576 /* fake out bfd_perform_relocation. sigh */
1577 reloc
->addend
= -alpha_gp_value
;
1582 reloc
->addend
= fixp
->fx_offset
;
1585 * Ohhh, this is ugly. The problem is that if this is a local global
1586 * symbol, the relocation will entirely be performed at link time, not
1587 * at assembly time. bfd_perform_reloc doesn't know about this sort
1588 * of thing, and as a result we need to fake it out here.
1590 if ((S_IS_EXTERN (fixp
->fx_addsy
) || S_IS_WEAK (fixp
->fx_addsy
))
1591 && !S_IS_COMMON(fixp
->fx_addsy
))
1592 reloc
->addend
-= symbol_get_bfdsym (fixp
->fx_addsy
)->value
;
1599 /* Parse a register name off of the input_line and return a register
1600 number. Gets md_undefined_symbol above to do the register name
1603 Only called as a part of processing the ECOFF .frame directive. */
1606 tc_get_register (frame
)
1607 int frame ATTRIBUTE_UNUSED
;
1609 int framereg
= AXP_REG_SP
;
1612 if (*input_line_pointer
== '$')
1614 char *s
= input_line_pointer
;
1615 char c
= get_symbol_end ();
1616 symbolS
*sym
= md_undefined_symbol (s
);
1618 *strchr(s
, '\0') = c
;
1619 if (sym
&& (framereg
= S_GET_VALUE (sym
)) <= 31)
1622 as_warn (_("frame reg expected, using $%d."), framereg
);
1625 note_gpreg (framereg
);
1629 /* This is called before the symbol table is processed. In order to
1630 work with gcc when using mips-tfile, we must keep all local labels.
1631 However, in other cases, we want to discard them. If we were
1632 called with -g, but we didn't see any debugging information, it may
1633 mean that gcc is smuggling debugging information through to
1634 mips-tfile, in which case we must generate all local labels. */
1639 alpha_frob_file_before_adjust ()
1641 if (alpha_debug
!= 0
1642 && ! ecoff_debugging_seen
)
1643 flag_keep_locals
= 1;
1646 #endif /* OBJ_ECOFF */
1650 /* Before the relocations are written, reorder them, so that user supplied
1651 !lituse relocations follow the appropriate !literal relocations. Also
1652 convert the gas-internal relocations to the appropriate linker relocations.
1656 alpha_adjust_symtab ()
1658 if (alpha_literal_hash
)
1661 fprintf (stderr
, "alpha_adjust_symtab called\n");
1664 /* Go over each section, reordering the relocations so that all of the
1665 explicit LITUSE's are adjacent to the explicit LITERAL's */
1666 bfd_map_over_sections (stdoutput
, alpha_adjust_symtab_relocs
, (char *) 0);
1671 /* Inner function to move LITUSE's next to the LITERAL. */
1674 alpha_adjust_symtab_relocs (abfd
, sec
, ptr
)
1679 segment_info_type
*seginfo
= seg_info (sec
);
1689 int n_dup_literals
= 0;
1692 /* If seginfo is NULL, we did not create this section; don't do anything with
1693 it. By using a pointer to a pointer, we can update the links in place. */
1694 if (seginfo
== NULL
)
1697 /* If there are no relocations, skip the section. */
1698 if (! seginfo
->fix_root
)
1701 /* First rebuild the fixup chain without the expicit lituse's. */
1702 prevP
= &(seginfo
->fix_root
);
1703 for (fixp
= seginfo
->fix_root
; fixp
; fixp
= next
)
1705 next
= fixp
->fx_next
;
1706 fixp
->fx_next
= (fixS
*)0;
1711 switch (fixp
->fx_r_type
)
1715 prevP
= &(fixp
->fx_next
);
1718 "alpha_adjust_symtab_relocs: 0x%lx, other relocation %s\n",
1720 bfd_get_reloc_code_name (fixp
->fx_r_type
));
1724 case BFD_RELOC_ALPHA_USER_LITERAL
:
1726 prevP
= &(fixp
->fx_next
);
1727 /* prevent assembler from trying to adjust the offset */
1730 if (fixp
->tc_fix_data
.info
->n_literals
!= 1)
1733 "alpha_adjust_symtab_relocs: 0x%lx, !literal!%.6d, # literals = %2d\n",
1735 fixp
->tc_fix_data
.info
->sequence
,
1736 fixp
->tc_fix_data
.info
->n_literals
);
1740 /* do not link in lituse's */
1741 case BFD_RELOC_ALPHA_USER_LITUSE_BASE
:
1742 case BFD_RELOC_ALPHA_USER_LITUSE_BYTOFF
:
1743 case BFD_RELOC_ALPHA_USER_LITUSE_JSR
:
1745 if (fixp
->tc_fix_data
.info
->n_literals
== 0)
1746 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1747 _("No !literal!%d was found"),
1748 fixp
->tc_fix_data
.info
->sequence
);
1751 "alpha_adjust_symtab_relocs: 0x%lx, !lituse !%.6d, # lituses = %2d, next_lituse = 0x%lx\n",
1753 fixp
->tc_fix_data
.info
->sequence
,
1754 fixp
->tc_fix_data
.info
->n_lituses
,
1755 (long)fixp
->tc_fix_data
.next_lituse
);
1761 /* If there were any lituses, go and add them to the chain, unless there is
1762 more than one !literal for a given sequence number. They are linked
1763 through the next_lituse field in reverse order, so as we go through the
1764 next_lituse chain, we effectively reverse the chain once again. If there
1765 was more than one !literal, we fall back to loading up the address w/o
1766 optimization. Also, if the !literals/!lituses are spread in different
1767 segments (happens in the Linux kernel semaphores), suppress the
1771 for (fixp
= seginfo
->fix_root
; fixp
; fixp
= fixp
->fx_next
)
1773 switch (fixp
->fx_r_type
)
1778 case BFD_RELOC_ALPHA_USER_LITERAL
:
1780 fixp
->fx_r_type
= BFD_RELOC_ALPHA_ELF_LITERAL
;
1782 fixp
->fx_r_type
= BFD_RELOC_ALPHA_LITERAL
; /* XXX check this */
1784 if (fixp
->tc_fix_data
.info
->n_literals
== 1
1785 && ! fixp
->tc_fix_data
.info
->multi_section_p
)
1787 for (lituse
= fixp
->tc_fix_data
.info
->lituse
;
1788 lituse
!= (fixS
*)0;
1789 lituse
= lituse
->tc_fix_data
.next_lituse
)
1791 lituse
->fx_next
= fixp
->fx_next
;
1792 fixp
->fx_next
= lituse
;
1797 case BFD_RELOC_ALPHA_USER_LITUSE_BASE
:
1798 case BFD_RELOC_ALPHA_USER_LITUSE_BYTOFF
:
1799 case BFD_RELOC_ALPHA_USER_LITUSE_JSR
:
1800 fixp
->fx_r_type
= BFD_RELOC_ALPHA_LITUSE
;
1807 fprintf (stderr
, "alpha_adjust_symtab_relocs: %s, %d literal%s, %d duplicate literal%s, %d lituse%s\n\n",
1809 n_literals
, (n_literals
== 1) ? "" : "s",
1810 n_dup_literals
, (n_dup_literals
== 1) ? "" : "s",
1811 n_lituses
, (n_lituses
== 1) ? "" : "s");
1815 #endif /* RELOC_OP_P */
1820 debug_exp (tok
, ntok
)
1826 fprintf (stderr
, "debug_exp: %d tokens", ntok
);
1827 for (i
= 0; i
< ntok
; i
++)
1829 expressionS
*t
= &tok
[i
];
1833 default: name
= "unknown"; break;
1834 case O_illegal
: name
= "O_illegal"; break;
1835 case O_absent
: name
= "O_absent"; break;
1836 case O_constant
: name
= "O_constant"; break;
1837 case O_symbol
: name
= "O_symbol"; break;
1838 case O_symbol_rva
: name
= "O_symbol_rva"; break;
1839 case O_register
: name
= "O_register"; break;
1840 case O_big
: name
= "O_big"; break;
1841 case O_uminus
: name
= "O_uminus"; break;
1842 case O_bit_not
: name
= "O_bit_not"; break;
1843 case O_logical_not
: name
= "O_logical_not"; break;
1844 case O_multiply
: name
= "O_multiply"; break;
1845 case O_divide
: name
= "O_divide"; break;
1846 case O_modulus
: name
= "O_modulus"; break;
1847 case O_left_shift
: name
= "O_left_shift"; break;
1848 case O_right_shift
: name
= "O_right_shift"; break;
1849 case O_bit_inclusive_or
: name
= "O_bit_inclusive_or"; break;
1850 case O_bit_or_not
: name
= "O_bit_or_not"; break;
1851 case O_bit_exclusive_or
: name
= "O_bit_exclusive_or"; break;
1852 case O_bit_and
: name
= "O_bit_and"; break;
1853 case O_add
: name
= "O_add"; break;
1854 case O_subtract
: name
= "O_subtract"; break;
1855 case O_eq
: name
= "O_eq"; break;
1856 case O_ne
: name
= "O_ne"; break;
1857 case O_lt
: name
= "O_lt"; break;
1858 case O_le
: name
= "O_le"; break;
1859 case O_ge
: name
= "O_ge"; break;
1860 case O_gt
: name
= "O_gt"; break;
1861 case O_logical_and
: name
= "O_logical_and"; break;
1862 case O_logical_or
: name
= "O_logical_or"; break;
1863 case O_index
: name
= "O_index"; break;
1864 case O_pregister
: name
= "O_pregister"; break;
1865 case O_cpregister
: name
= "O_cpregister"; break;
1866 case O_literal
: name
= "O_literal"; break;
1867 case O_lituse_base
: name
= "O_lituse_base"; break;
1868 case O_lituse_bytoff
: name
= "O_lituse_bytoff"; break;
1869 case O_lituse_jsr
: name
= "O_lituse_jsr"; break;
1870 case O_gpdisp
: name
= "O_gpdisp"; break;
1871 case O_gprelhigh
: name
= "O_gprelhigh"; break;
1872 case O_gprellow
: name
= "O_gprellow"; break;
1873 case O_md10
: name
= "O_md10"; break;
1874 case O_md11
: name
= "O_md11"; break;
1875 case O_md12
: name
= "O_md12"; break;
1876 case O_md13
: name
= "O_md13"; break;
1877 case O_md14
: name
= "O_md14"; break;
1878 case O_md15
: name
= "O_md15"; break;
1879 case O_md16
: name
= "O_md16"; break;
1882 fprintf (stderr
, ", %s(%s, %s, %d)", name
,
1883 (t
->X_add_symbol
) ? S_GET_NAME (t
->X_add_symbol
) : "--",
1884 (t
->X_op_symbol
) ? S_GET_NAME (t
->X_op_symbol
) : "--",
1885 (int)t
->X_add_number
);
1887 fprintf (stderr
, "\n");
1892 /* Parse the arguments to an opcode. */
1895 tokenize_arguments (str
, tok
, ntok
)
1900 expressionS
*end_tok
= tok
+ ntok
;
1901 char *old_input_line_pointer
;
1902 int saw_comma
= 0, saw_arg
= 0;
1904 expressionS
*orig_tok
= tok
;
1908 const struct alpha_reloc_op_tag
*r
;
1911 int reloc_found_p
= 0;
1914 memset (tok
, 0, sizeof (*tok
) * ntok
);
1916 /* Save and restore input_line_pointer around this function */
1917 old_input_line_pointer
= input_line_pointer
;
1918 input_line_pointer
= str
;
1920 while (tok
< end_tok
&& *input_line_pointer
)
1923 switch (*input_line_pointer
)
1930 /* A relocation operand can be placed after the normal operand on an
1931 assembly language statement, and has the following form:
1932 !relocation_type!sequence_number. */
1934 { /* only support one relocation op per insn */
1935 as_bad (_("More than one relocation op per insn"));
1942 for (p
= ++input_line_pointer
;
1943 ((c
= *p
) != '!' && c
!= ';' && c
!= '#' && c
!= ','
1944 && !is_end_of_line
[c
]);
1948 /* Parse !relocation_type */
1949 len
= p
- input_line_pointer
;
1952 as_bad (_("No relocation operand"));
1958 as_bad (_("No !sequence-number after !%s"), input_line_pointer
);
1962 r
= &alpha_reloc_op
[0];
1963 for (i
= alpha_num_reloc_op
-1; i
>= 0; i
--, r
++)
1965 if (len
== r
->length
1966 && memcmp (input_line_pointer
, r
->name
, len
) == 0)
1971 as_bad (_("Unknown relocation operand: !%s"), input_line_pointer
);
1975 input_line_pointer
= ++p
;
1977 /* Parse !sequence_number */
1978 memset (tok
, '\0', sizeof (expressionS
));
1981 if (tok
->X_op
!= O_constant
1982 || ! ALPHA_RELOC_SEQUENCE_OK (tok
->X_add_number
))
1984 as_bad (_("Bad sequence number: !%s!%s"), r
->name
, input_line_pointer
);
1995 ++input_line_pointer
;
1996 if (saw_comma
|| !saw_arg
)
2003 char *hold
= input_line_pointer
++;
2005 /* First try for parenthesized register ... */
2007 if (*input_line_pointer
== ')' && tok
->X_op
== O_register
)
2009 tok
->X_op
= (saw_comma
? O_cpregister
: O_pregister
);
2012 ++input_line_pointer
;
2017 /* ... then fall through to plain expression */
2018 input_line_pointer
= hold
;
2022 if (saw_arg
&& !saw_comma
)
2026 if (tok
->X_op
== O_illegal
|| tok
->X_op
== O_absent
)
2039 input_line_pointer
= old_input_line_pointer
;
2042 debug_exp (orig_tok
, ntok
- (end_tok
- tok
));
2045 return ntok
- (end_tok
- tok
);
2048 input_line_pointer
= old_input_line_pointer
;
2049 return TOKENIZE_ERROR
;
2053 input_line_pointer
= old_input_line_pointer
;
2054 return TOKENIZE_ERROR_REPORT
;
2058 /* Search forward through all variants of an opcode looking for a
2061 static const struct alpha_opcode
*
2062 find_opcode_match(first_opcode
, tok
, pntok
, pcpumatch
)
2063 const struct alpha_opcode
*first_opcode
;
2064 const expressionS
*tok
;
2068 const struct alpha_opcode
*opcode
= first_opcode
;
2070 int got_cpu_match
= 0;
2074 const unsigned char *opidx
;
2077 /* Don't match opcodes that don't exist on this architecture */
2078 if (!(opcode
->flags
& alpha_target
))
2083 for (opidx
= opcode
->operands
; *opidx
; ++opidx
)
2085 const struct alpha_operand
*operand
= &alpha_operands
[*opidx
];
2087 /* only take input from real operands */
2088 if (operand
->flags
& AXP_OPERAND_FAKE
)
2091 /* when we expect input, make sure we have it */
2094 if ((operand
->flags
& AXP_OPERAND_OPTIONAL_MASK
) == 0)
2099 /* match operand type with expression type */
2100 switch (operand
->flags
& AXP_OPERAND_TYPECHECK_MASK
)
2102 case AXP_OPERAND_IR
:
2103 if (tok
[tokidx
].X_op
!= O_register
2104 || !is_ir_num(tok
[tokidx
].X_add_number
))
2107 case AXP_OPERAND_FPR
:
2108 if (tok
[tokidx
].X_op
!= O_register
2109 || !is_fpr_num(tok
[tokidx
].X_add_number
))
2112 case AXP_OPERAND_IR
|AXP_OPERAND_PARENS
:
2113 if (tok
[tokidx
].X_op
!= O_pregister
2114 || !is_ir_num(tok
[tokidx
].X_add_number
))
2117 case AXP_OPERAND_IR
|AXP_OPERAND_PARENS
|AXP_OPERAND_COMMA
:
2118 if (tok
[tokidx
].X_op
!= O_cpregister
2119 || !is_ir_num(tok
[tokidx
].X_add_number
))
2123 case AXP_OPERAND_RELATIVE
:
2124 case AXP_OPERAND_SIGNED
:
2125 case AXP_OPERAND_UNSIGNED
:
2126 switch (tok
[tokidx
].X_op
)
2141 /* everything else should have been fake */
2147 /* possible match -- did we use all of our input? */
2156 while (++opcode
-alpha_opcodes
< alpha_num_opcodes
2157 && !strcmp(opcode
->name
, first_opcode
->name
));
2160 *pcpumatch
= got_cpu_match
;
2165 /* Search forward through all variants of a macro looking for a syntax
2168 static const struct alpha_macro
*
2169 find_macro_match(first_macro
, tok
, pntok
)
2170 const struct alpha_macro
*first_macro
;
2171 const expressionS
*tok
;
2174 const struct alpha_macro
*macro
= first_macro
;
2179 const enum alpha_macro_arg
*arg
= macro
->argsets
;
2193 /* index register */
2195 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_register
2196 || !is_ir_num(tok
[tokidx
].X_add_number
))
2201 /* parenthesized index register */
2203 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_pregister
2204 || !is_ir_num(tok
[tokidx
].X_add_number
))
2209 /* optional parenthesized index register */
2211 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_pregister
2212 && is_ir_num(tok
[tokidx
].X_add_number
))
2216 /* leading comma with a parenthesized index register */
2218 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_cpregister
2219 || !is_ir_num(tok
[tokidx
].X_add_number
))
2224 /* floating point register */
2226 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_register
2227 || !is_fpr_num(tok
[tokidx
].X_add_number
))
2232 /* normal expression */
2236 switch (tok
[tokidx
].X_op
)
2246 case O_lituse_bytoff
:
2260 /* optional !literal!<number> */
2263 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_literal
)
2268 /* optional !lituse_base!<number> */
2271 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_lituse_base
)
2276 /* optional !lituse_bytoff!<number> */
2279 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_lituse_bytoff
)
2284 /* optional !lituse_jsr!<number> */
2287 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_lituse_jsr
)
2293 while (*arg
!= MACRO_EOA
)
2301 while (++macro
-alpha_macros
< alpha_num_macros
2302 && !strcmp(macro
->name
, first_macro
->name
));
2307 /* Insert an operand value into an instruction. */
2310 insert_operand(insn
, operand
, val
, file
, line
)
2312 const struct alpha_operand
*operand
;
2317 if (operand
->bits
!= 32 && !(operand
->flags
& AXP_OPERAND_NOOVERFLOW
))
2321 if (operand
->flags
& AXP_OPERAND_SIGNED
)
2323 max
= (1 << (operand
->bits
- 1)) - 1;
2324 min
= -(1 << (operand
->bits
- 1));
2328 max
= (1 << operand
->bits
) - 1;
2332 if (val
< min
|| val
> max
)
2335 _("operand out of range (%s not between %d and %d)");
2336 char buf
[sizeof (val
) * 3 + 2];
2338 sprint_value(buf
, val
);
2340 as_warn_where(file
, line
, err
, buf
, min
, max
);
2342 as_warn(err
, buf
, min
, max
);
2346 if (operand
->insert
)
2348 const char *errmsg
= NULL
;
2350 insn
= (*operand
->insert
) (insn
, val
, &errmsg
);
2355 insn
|= ((val
& ((1 << operand
->bits
) - 1)) << operand
->shift
);
2361 * Turn an opcode description and a set of arguments into
2362 * an instruction and a fixup.
2366 assemble_insn(opcode
, tok
, ntok
, insn
)
2367 const struct alpha_opcode
*opcode
;
2368 const expressionS
*tok
;
2370 struct alpha_insn
*insn
;
2372 const unsigned char *argidx
;
2376 memset (insn
, 0, sizeof (*insn
));
2377 image
= opcode
->opcode
;
2379 for (argidx
= opcode
->operands
; *argidx
; ++argidx
)
2381 const struct alpha_operand
*operand
= &alpha_operands
[*argidx
];
2382 const expressionS
*t
= (const expressionS
*)0;
2384 if (operand
->flags
& AXP_OPERAND_FAKE
)
2386 /* fake operands take no value and generate no fixup */
2387 image
= insert_operand(image
, operand
, 0, NULL
, 0);
2393 switch (operand
->flags
& AXP_OPERAND_OPTIONAL_MASK
)
2395 case AXP_OPERAND_DEFAULT_FIRST
:
2398 case AXP_OPERAND_DEFAULT_SECOND
:
2401 case AXP_OPERAND_DEFAULT_ZERO
:
2403 static expressionS zero_exp
;
2405 zero_exp
.X_op
= O_constant
;
2406 zero_exp
.X_unsigned
= 1;
2421 image
= insert_operand(image
, operand
, regno(t
->X_add_number
),
2426 image
= insert_operand(image
, operand
, t
->X_add_number
, NULL
, 0);
2431 struct alpha_fixup
*fixup
;
2433 if (insn
->nfixups
>= MAX_INSN_FIXUPS
)
2434 as_fatal(_("too many fixups"));
2436 fixup
= &insn
->fixups
[insn
->nfixups
++];
2439 fixup
->reloc
= operand
->default_reloc
;
2449 * Actually output an instruction with its fixup.
2454 struct alpha_insn
*insn
;
2459 /* Take care of alignment duties */
2460 if (alpha_auto_align_on
&& alpha_current_align
< 2)
2461 alpha_align (2, (char *) NULL
, alpha_insn_label
, 0);
2462 if (alpha_current_align
> 2)
2463 alpha_current_align
= 2;
2464 alpha_insn_label
= NULL
;
2466 /* Write out the instruction. */
2468 md_number_to_chars (f
, insn
->insn
, 4);
2470 /* Apply the fixups in order */
2471 for (i
= 0; i
< insn
->nfixups
; ++i
)
2473 const struct alpha_operand
*operand
= (const struct alpha_operand
*)0;
2474 struct alpha_fixup
*fixup
= &insn
->fixups
[i
];
2478 char buffer
[ALPHA_RELOC_DIGITS
];
2479 struct alpha_literal_tag
*info
;
2482 /* Some fixups are only used internally and so have no howto */
2483 if ((int)fixup
->reloc
< 0)
2485 operand
= &alpha_operands
[-(int)fixup
->reloc
];
2487 pcrel
= ((operand
->flags
& AXP_OPERAND_RELATIVE
) != 0);
2489 else switch (fixup
->reloc
)
2492 /* These relocation types are only used internally. */
2493 case BFD_RELOC_ALPHA_GPDISP_HI16
:
2494 case BFD_RELOC_ALPHA_GPDISP_LO16
:
2500 /* and these also are internal only relocations */
2501 case BFD_RELOC_ALPHA_USER_LITERAL
:
2502 case BFD_RELOC_ALPHA_USER_LITUSE_BASE
:
2503 case BFD_RELOC_ALPHA_USER_LITUSE_BYTOFF
:
2504 case BFD_RELOC_ALPHA_USER_LITUSE_JSR
:
2505 case BFD_RELOC_ALPHA_USER_GPDISP
:
2506 case BFD_RELOC_ALPHA_USER_GPRELHIGH
:
2507 case BFD_RELOC_ALPHA_USER_GPRELLOW
:
2515 reloc_howto_type
*reloc_howto
2516 = bfd_reloc_type_lookup (stdoutput
, fixup
->reloc
);
2517 assert (reloc_howto
);
2519 size
= bfd_get_reloc_size (reloc_howto
);
2520 pcrel
= reloc_howto
->pc_relative
;
2522 assert (size
>= 1 && size
<= 4);
2526 fixP
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, size
,
2527 &fixup
->exp
, pcrel
, fixup
->reloc
);
2529 /* Turn off complaints that the addend is too large for some fixups,
2530 and copy in the sequence number for the explicit relocations. */
2531 switch (fixup
->reloc
)
2533 case BFD_RELOC_ALPHA_GPDISP_LO16
:
2535 case BFD_RELOC_ALPHA_LITERAL
:
2538 case BFD_RELOC_ALPHA_ELF_LITERAL
:
2540 case BFD_RELOC_GPREL32
:
2541 fixP
->fx_no_overflow
= 1;
2545 case BFD_RELOC_ALPHA_USER_LITERAL
:
2546 fixP
->fx_no_overflow
= 1;
2547 sprintf (buffer
, "!%u", insn
->sequence
[i
]);
2548 info
= ((struct alpha_literal_tag
*)
2549 hash_find (alpha_literal_hash
, buffer
));
2553 size_t len
= strlen (buffer
);
2556 info
= ((struct alpha_literal_tag
*)
2557 xcalloc (sizeof (struct alpha_literal_tag
) + len
, 1));
2559 info
->segment
= now_seg
;
2560 info
->sequence
= insn
->sequence
[i
];
2561 strcpy (info
->string
, buffer
);
2562 errmsg
= hash_insert (alpha_literal_hash
, info
->string
, (PTR
)info
);
2569 if (info
->segment
!= now_seg
)
2570 info
->multi_section_p
= 1;
2572 fixP
->tc_fix_data
.info
= info
;
2575 case BFD_RELOC_ALPHA_USER_LITUSE_BASE
:
2576 case BFD_RELOC_ALPHA_USER_LITUSE_BYTOFF
:
2577 case BFD_RELOC_ALPHA_USER_LITUSE_JSR
:
2578 sprintf (buffer
, "!%u", insn
->sequence
[i
]);
2579 info
= ((struct alpha_literal_tag
*)
2580 hash_find (alpha_literal_hash
, buffer
));
2584 size_t len
= strlen (buffer
);
2587 info
= ((struct alpha_literal_tag
*)
2588 xcalloc (sizeof (struct alpha_literal_tag
) + len
, 1));
2590 info
->segment
= now_seg
;
2591 info
->sequence
= insn
->sequence
[i
];
2592 strcpy (info
->string
, buffer
);
2593 errmsg
= hash_insert (alpha_literal_hash
, info
->string
, (PTR
)info
);
2598 fixP
->tc_fix_data
.info
= info
;
2599 fixP
->tc_fix_data
.next_lituse
= info
->lituse
;
2600 info
->lituse
= fixP
;
2601 if (info
->segment
!= now_seg
)
2602 info
->multi_section_p
= 1;
2608 if ((int)fixup
->reloc
< 0)
2610 if (operand
->flags
& AXP_OPERAND_NOOVERFLOW
)
2611 fixP
->fx_no_overflow
= 1;
2618 /* Given an opcode name and a pre-tokenized set of arguments, assemble
2619 the insn, but do not emit it.
2621 Note that this implies no macros allowed, since we can't store more
2622 than one insn in an insn structure. */
2625 assemble_tokens_to_insn(opname
, tok
, ntok
, insn
)
2627 const expressionS
*tok
;
2629 struct alpha_insn
*insn
;
2631 const struct alpha_opcode
*opcode
;
2633 /* search opcodes */
2634 opcode
= (const struct alpha_opcode
*) hash_find (alpha_opcode_hash
, opname
);
2638 opcode
= find_opcode_match (opcode
, tok
, &ntok
, &cpumatch
);
2641 assemble_insn (opcode
, tok
, ntok
, insn
);
2645 as_bad (_("inappropriate arguments for opcode `%s'"), opname
);
2647 as_bad (_("opcode `%s' not supported for target %s"), opname
,
2651 as_bad (_("unknown opcode `%s'"), opname
);
2654 /* Given an opcode name and a pre-tokenized set of arguments, take the
2655 opcode all the way through emission. */
2658 assemble_tokens (opname
, tok
, ntok
, local_macros_on
)
2660 const expressionS
*tok
;
2662 int local_macros_on
;
2664 int found_something
= 0;
2665 const struct alpha_opcode
*opcode
;
2666 const struct alpha_macro
*macro
;
2670 if (local_macros_on
)
2672 macro
= ((const struct alpha_macro
*)
2673 hash_find (alpha_macro_hash
, opname
));
2676 found_something
= 1;
2677 macro
= find_macro_match (macro
, tok
, &ntok
);
2680 (*macro
->emit
) (tok
, ntok
, macro
->arg
);
2687 if (ntok
&& USER_RELOC_P (tok
[ntok
-1].X_op
))
2689 const expressionS
*reloc_exp
= &tok
[ntok
-1];
2690 const struct alpha_reloc_op_tag
*r
= ALPHA_RELOC_TABLE (reloc_exp
->X_op
);
2691 as_bad (_("Cannot use !%s!%d with %s"), r
->name
,
2692 (int)reloc_exp
->X_add_number
, opname
);
2697 /* search opcodes */
2698 opcode
= (const struct alpha_opcode
*) hash_find (alpha_opcode_hash
, opname
);
2701 found_something
= 1;
2702 opcode
= find_opcode_match (opcode
, tok
, &ntok
, &cpumatch
);
2705 struct alpha_insn insn
;
2706 assemble_insn (opcode
, tok
, ntok
, &insn
);
2712 if (found_something
)
2714 as_bad (_("inappropriate arguments for opcode `%s'"), opname
);
2716 as_bad (_("opcode `%s' not supported for target %s"), opname
,
2719 as_bad (_("unknown opcode `%s'"), opname
);
2723 /* Some instruction sets indexed by lg(size) */
2724 static const char * const sextX_op
[] = { "sextb", "sextw", "sextl", NULL
};
2725 static const char * const insXl_op
[] = { "insbl", "inswl", "insll", "insql" };
2726 static const char * const insXh_op
[] = { NULL
, "inswh", "inslh", "insqh" };
2727 static const char * const extXl_op
[] = { "extbl", "extwl", "extll", "extql" };
2728 static const char * const extXh_op
[] = { NULL
, "extwh", "extlh", "extqh" };
2729 static const char * const mskXl_op
[] = { "mskbl", "mskwl", "mskll", "mskql" };
2730 static const char * const mskXh_op
[] = { NULL
, "mskwh", "msklh", "mskqh" };
2731 static const char * const stX_op
[] = { "stb", "stw", "stl", "stq" };
2732 static const char * const ldX_op
[] = { "ldb", "ldw", "ldll", "ldq" };
2733 static const char * const ldXu_op
[] = { "ldbu", "ldwu", NULL
, NULL
};
2735 /* Implement the ldgp macro. */
2738 emit_ldgp (tok
, ntok
, unused
)
2739 const expressionS
*tok
;
2740 int ntok ATTRIBUTE_UNUSED
;
2741 const PTR unused ATTRIBUTE_UNUSED
;
2746 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
2747 /* from "ldgp r1,n(r2)", generate "ldah r1,X(R2); lda r1,Y(r1)"
2748 with appropriate constants and relocations. */
2749 struct alpha_insn insn
;
2750 expressionS newtok
[3];
2754 if (ntok
&& USER_RELOC_P (tok
[ntok
-1].X_op
))
2756 const expressionS
*reloc_exp
= &tok
[ntok
-1];
2757 const struct alpha_reloc_op_tag
*r
= ALPHA_RELOC_TABLE (reloc_exp
->X_op
);
2758 as_bad (_("Cannot use !%s!%d with %s"), r
->name
,
2759 (int)reloc_exp
->X_add_number
, "ldgp");
2765 if (regno (tok
[2].X_add_number
) == AXP_REG_PV
)
2766 ecoff_set_gp_prolog_size (0);
2770 set_tok_const (newtok
[1], 0);
2773 assemble_tokens_to_insn ("ldah", newtok
, 3, &insn
);
2778 if (addend
.X_op
!= O_constant
)
2779 as_bad (_("can not resolve expression"));
2780 addend
.X_op
= O_symbol
;
2781 addend
.X_add_symbol
= alpha_gp_symbol
;
2785 insn
.fixups
[0].exp
= addend
;
2786 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_GPDISP_HI16
;
2790 set_tok_preg (newtok
[2], tok
[0].X_add_number
);
2792 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
2795 addend
.X_add_number
+= 4;
2799 insn
.fixups
[0].exp
= addend
;
2800 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_GPDISP_LO16
;
2803 #endif /* OBJ_ECOFF || OBJ_ELF */
2808 /* Add symbol+addend to link pool.
2809 Return offset from basesym to entry in link pool.
2811 Add new fixup only if offset isn't 16bit. */
2814 add_to_link_pool (basesym
, sym
, addend
)
2819 segT current_section
= now_seg
;
2820 int current_subsec
= now_subseg
;
2822 bfd_reloc_code_real_type reloc_type
;
2824 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
2827 offset
= - *symbol_get_obj (basesym
);
2829 /* @@ This assumes all entries in a given section will be of the same
2830 size... Probably correct, but unwise to rely on. */
2831 /* This must always be called with the same subsegment. */
2833 if (seginfo
->frchainP
)
2834 for (fixp
= seginfo
->frchainP
->fix_root
;
2835 fixp
!= (fixS
*) NULL
;
2836 fixp
= fixp
->fx_next
, offset
+= 8)
2838 if (fixp
->fx_addsy
== sym
&& fixp
->fx_offset
== addend
)
2840 if (range_signed_16 (offset
))
2847 /* Not found in 16bit signed range. */
2849 subseg_set (alpha_link_section
, 0);
2853 fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, sym
, addend
, 0,
2856 subseg_set (current_section
, current_subsec
);
2857 seginfo
->literal_pool_size
+= 8;
2861 #endif /* OBJ_EVAX */
2863 /* Load a (partial) expression into a target register.
2865 If poffset is not null, after the call it will either contain
2866 O_constant 0, or a 16-bit offset appropriate for any MEM format
2867 instruction. In addition, pbasereg will be modified to point to
2868 the base register to use in that MEM format instruction.
2870 In any case, *pbasereg should contain a base register to add to the
2871 expression. This will normally be either AXP_REG_ZERO or
2872 alpha_gp_register. Symbol addresses will always be loaded via $gp,
2873 so "foo($0)" is interpreted as adding the address of foo to $0;
2874 i.e. "ldq $targ, LIT($gp); addq $targ, $0, $targ". Odd, perhaps,
2875 but this is what OSF/1 does.
2877 If explicit relocations of the form !literal!<number> are allowed,
2878 and used, then explict_reloc with be an expression pointer.
2880 Finally, the return value is true if the calling macro may emit a
2881 LITUSE reloc if otherwise appropriate. */
2884 load_expression (targreg
, exp
, pbasereg
, poffset
, explicit_reloc
)
2886 const expressionS
*exp
;
2888 expressionS
*poffset
;
2889 const expressionS
*explicit_reloc
;
2891 int emit_lituse
= 0;
2892 offsetT addend
= exp
->X_add_number
;
2893 int basereg
= *pbasereg
;
2894 struct alpha_insn insn
;
2895 expressionS newtok
[3];
2904 /* attempt to reduce .lit load by splitting the offset from
2905 its symbol when possible, but don't create a situation in
2907 if (!range_signed_32 (addend
) &&
2908 (alpha_noat_on
|| targreg
== AXP_REG_AT
))
2910 lit
= add_to_literal_pool (exp
->X_add_symbol
, addend
,
2911 alpha_lita_section
, 8);
2916 lit
= add_to_literal_pool (exp
->X_add_symbol
, 0,
2917 alpha_lita_section
, 8);
2921 as_fatal (_("overflow in literal (.lita) table"));
2923 /* emit "ldq r, lit(gp)" */
2925 if (basereg
!= alpha_gp_register
&& targreg
== basereg
)
2928 as_bad (_("macro requires $at register while noat in effect"));
2929 if (targreg
== AXP_REG_AT
)
2930 as_bad (_("macro requires $at while $at in use"));
2932 set_tok_reg (newtok
[0], AXP_REG_AT
);
2935 set_tok_reg (newtok
[0], targreg
);
2936 set_tok_sym (newtok
[1], alpha_lita_symbol
, lit
);
2937 set_tok_preg (newtok
[2], alpha_gp_register
);
2939 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
2941 assert (explicit_reloc
== (const expressionS
*)0);
2942 assert (insn
.nfixups
== 1);
2943 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITERAL
;
2944 #endif /* OBJ_ECOFF */
2946 /* emit "ldq r, gotoff(gp)" */
2948 if (basereg
!= alpha_gp_register
&& targreg
== basereg
)
2951 as_bad (_("macro requires $at register while noat in effect"));
2952 if (targreg
== AXP_REG_AT
)
2953 as_bad (_("macro requires $at while $at in use"));
2955 set_tok_reg (newtok
[0], AXP_REG_AT
);
2958 set_tok_reg (newtok
[0], targreg
);
2960 /* XXX: Disable this .got minimizing optimization so that we can get
2961 better instruction offset knowledge in the compiler. This happens
2962 very infrequently anyway. */
2963 if (1 || (!range_signed_32 (addend
)
2964 && (alpha_noat_on
|| targreg
== AXP_REG_AT
)))
2971 set_tok_sym (newtok
[1], exp
->X_add_symbol
, 0);
2974 set_tok_preg (newtok
[2], alpha_gp_register
);
2976 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
2978 assert (insn
.nfixups
== 1);
2979 if (!explicit_reloc
)
2980 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_ELF_LITERAL
;
2984 insn
.fixups
[0].reloc
2985 = (ALPHA_RELOC_TABLE (explicit_reloc
->X_op
))->reloc
;
2986 insn
.sequence
[0] = explicit_reloc
->X_add_number
;
2991 #endif /* OBJ_ELF */
2995 /* Find symbol or symbol pointer in link section. */
2997 assert (explicit_reloc
== (const expressionS
*)0);
2998 if (exp
->X_add_symbol
== alpha_evax_proc
.symbol
)
3000 if (range_signed_16 (addend
))
3002 set_tok_reg (newtok
[0], targreg
);
3003 set_tok_const (newtok
[1], addend
);
3004 set_tok_preg (newtok
[2], basereg
);
3005 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
3010 set_tok_reg (newtok
[0], targreg
);
3011 set_tok_const (newtok
[1], 0);
3012 set_tok_preg (newtok
[2], basereg
);
3013 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
3018 if (!range_signed_32 (addend
))
3020 link
= add_to_link_pool (alpha_evax_proc
.symbol
,
3021 exp
->X_add_symbol
, addend
);
3026 link
= add_to_link_pool (alpha_evax_proc
.symbol
,
3027 exp
->X_add_symbol
, 0);
3029 set_tok_reg (newtok
[0], targreg
);
3030 set_tok_const (newtok
[1], link
);
3031 set_tok_preg (newtok
[2], basereg
);
3032 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
3034 #endif /* OBJ_EVAX */
3041 if (basereg
!= alpha_gp_register
&& basereg
!= AXP_REG_ZERO
)
3043 /* emit "addq r, base, r" */
3045 set_tok_reg (newtok
[1], basereg
);
3046 set_tok_reg (newtok
[2], targreg
);
3047 assemble_tokens ("addq", newtok
, 3, 0);
3056 assert (explicit_reloc
== (const expressionS
*)0);
3060 /* Assume that this difference expression will be resolved to an
3061 absolute value and that that value will fit in 16 bits. */
3063 assert (explicit_reloc
== (const expressionS
*)0);
3064 set_tok_reg (newtok
[0], targreg
);
3066 set_tok_preg (newtok
[2], basereg
);
3067 assemble_tokens ("lda", newtok
, 3, 0);
3070 set_tok_const (*poffset
, 0);
3074 if (exp
->X_add_number
> 0)
3075 as_bad (_("bignum invalid; zero assumed"));
3077 as_bad (_("floating point number invalid; zero assumed"));
3082 as_bad (_("can't handle expression"));
3087 if (!range_signed_32 (addend
))
3091 /* for 64-bit addends, just put it in the literal pool */
3094 /* emit "ldq targreg, lit(basereg)" */
3095 lit
= add_to_link_pool (alpha_evax_proc
.symbol
,
3096 section_symbol (absolute_section
), addend
);
3097 set_tok_reg (newtok
[0], targreg
);
3098 set_tok_const (newtok
[1], lit
);
3099 set_tok_preg (newtok
[2], alpha_gp_register
);
3100 assemble_tokens ("ldq", newtok
, 3, 0);
3103 if (alpha_lit8_section
== NULL
)
3105 create_literal_section (".lit8",
3106 &alpha_lit8_section
,
3107 &alpha_lit8_symbol
);
3110 alpha_lit8_literal
= add_to_literal_pool (alpha_lit8_symbol
, 0x8000,
3111 alpha_lita_section
, 8);
3112 if (alpha_lit8_literal
>= 0x8000)
3113 as_fatal (_("overflow in literal (.lita) table"));
3117 lit
= add_to_literal_pool (NULL
, addend
, alpha_lit8_section
, 8) - 0x8000;
3119 as_fatal (_("overflow in literal (.lit8) table"));
3121 /* emit "lda litreg, .lit8+0x8000" */
3123 if (targreg
== basereg
)
3126 as_bad (_("macro requires $at register while noat in effect"));
3127 if (targreg
== AXP_REG_AT
)
3128 as_bad (_("macro requires $at while $at in use"));
3130 set_tok_reg (newtok
[0], AXP_REG_AT
);
3133 set_tok_reg (newtok
[0], targreg
);
3135 set_tok_sym (newtok
[1], alpha_lita_symbol
, alpha_lit8_literal
);
3138 set_tok_sym (newtok
[1], alpha_lit8_symbol
, 0x8000);
3140 set_tok_preg (newtok
[2], alpha_gp_register
);
3142 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
3144 assert (insn
.nfixups
== 1);
3146 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITERAL
;
3149 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_ELF_LITERAL
;
3154 /* emit "ldq litreg, lit(litreg)" */
3156 set_tok_const (newtok
[1], lit
);
3157 set_tok_preg (newtok
[2], newtok
[0].X_add_number
);
3159 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
3161 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3162 if (insn
.nfixups
> 0)
3164 memmove (&insn
.fixups
[1], &insn
.fixups
[0],
3165 sizeof(struct alpha_fixup
) * insn
.nfixups
);
3168 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITUSE
;
3169 insn
.fixups
[0].exp
.X_op
= O_symbol
;
3170 insn
.fixups
[0].exp
.X_add_symbol
= section_symbol (now_seg
);
3171 insn
.fixups
[0].exp
.X_add_number
= LITUSE_BASE
;
3176 /* emit "addq litreg, base, target" */
3178 if (basereg
!= AXP_REG_ZERO
)
3180 set_tok_reg (newtok
[1], basereg
);
3181 set_tok_reg (newtok
[2], targreg
);
3182 assemble_tokens ("addq", newtok
, 3, 0);
3184 #endif /* !OBJ_EVAX */
3187 set_tok_const (*poffset
, 0);
3188 *pbasereg
= targreg
;
3192 offsetT low
, high
, extra
, tmp
;
3194 /* for 32-bit operands, break up the addend */
3196 low
= sign_extend_16 (addend
);
3198 high
= sign_extend_16 (tmp
>> 16);
3200 if (tmp
- (high
<< 16))
3204 high
= sign_extend_16 (tmp
>> 16);
3209 set_tok_reg (newtok
[0], targreg
);
3210 set_tok_preg (newtok
[2], basereg
);
3214 /* emit "ldah r, extra(r) */
3215 set_tok_const (newtok
[1], extra
);
3216 assemble_tokens ("ldah", newtok
, 3, 0);
3217 set_tok_preg (newtok
[2], basereg
= targreg
);
3222 /* emit "ldah r, high(r) */
3223 set_tok_const (newtok
[1], high
);
3224 assemble_tokens ("ldah", newtok
, 3, 0);
3226 set_tok_preg (newtok
[2], basereg
);
3229 if ((low
&& !poffset
) || (!poffset
&& basereg
!= targreg
))
3231 /* emit "lda r, low(base)" */
3232 set_tok_const (newtok
[1], low
);
3233 assemble_tokens ("lda", newtok
, 3, 0);
3239 set_tok_const (*poffset
, low
);
3240 *pbasereg
= basereg
;
3246 /* The lda macro differs from the lda instruction in that it handles
3247 most simple expressions, particualrly symbol address loads and
3251 emit_lda (tok
, ntok
, opname
)
3252 const expressionS
*tok
;
3257 const expressionS
*reloc
= (const expressionS
*)0;
3260 if (ntok
&& USER_RELOC_P (tok
[ntok
-1].X_op
))
3262 const struct alpha_reloc_op_tag
*r
;
3264 reloc
= &tok
[ntok
-1];
3265 r
= ALPHA_RELOC_TABLE (reloc
->X_op
);
3266 switch (reloc
->X_op
)
3269 as_bad (_("Cannot use !%s!%d with %s"), r
->name
,
3270 (int)reloc
->X_add_number
, (const char *)opname
);
3272 reloc
= (const expressionS
*)0;
3280 /* For lda $x,0($x)!lituse_base!y, don't use load_expression, since
3281 it is really too general for our needs. Instead just generate the
3285 || tok
[0].X_op
!= O_register
3286 || !is_ir_num(tok
[0].X_add_number
)
3287 || tok
[1].X_op
!= O_constant
3288 || tok
[2].X_op
!= O_pregister
3289 || !is_ir_num(tok
[2].X_add_number
))
3291 as_bad (_("bad instruction format for lda !%s!%d"), r
->name
,
3292 reloc
->X_add_number
);
3294 reloc
= (const expressionS
*)0;
3299 emit_loadstore (tok
, ntok
, "lda");
3306 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
3308 basereg
= tok
[2].X_add_number
;
3310 (void) load_expression (tok
[0].X_add_number
, &tok
[1], &basereg
, NULL
, reloc
);
3313 /* The ldah macro differs from the ldah instruction in that it has $31
3314 as an implied base register. */
3317 emit_ldah (tok
, ntok
, unused
)
3318 const expressionS
*tok
;
3319 int ntok ATTRIBUTE_UNUSED
;
3320 const PTR unused ATTRIBUTE_UNUSED
;
3322 expressionS newtok
[3];
3325 if (ntok
&& USER_RELOC_P (tok
[ntok
-1].X_op
))
3327 const expressionS
*reloc_exp
= &tok
[ntok
-1];
3328 const struct alpha_reloc_op_tag
*r
= ALPHA_RELOC_TABLE (reloc_exp
->X_op
);
3329 as_bad (_("Cannot use !%s!%d with %s"), r
->name
,
3330 (int)reloc_exp
->X_add_number
, "ldah");
3337 set_tok_preg (newtok
[2], AXP_REG_ZERO
);
3339 assemble_tokens ("ldah", newtok
, 3, 0);
3342 /* Handle all "simple" integer register loads -- ldq, ldq_l, ldq_u,
3343 etc. They differ from the real instructions in that they do simple
3344 expressions like the lda macro. */
3347 emit_ir_load (tok
, ntok
, opname
)
3348 const expressionS
*tok
;
3352 int basereg
, lituse
;
3353 expressionS newtok
[3];
3354 struct alpha_insn insn
;
3357 const expressionS
*reloc
= (const expressionS
*)0;
3359 if (ntok
&& USER_RELOC_P (tok
[ntok
-1].X_op
))
3361 const struct alpha_reloc_op_tag
*r
;
3363 reloc
= &tok
[ntok
-1];
3364 switch (reloc
->X_op
)
3371 if (strcmp ((const char *)opname
, "ldq") == 0)
3373 emit_lda (tok
, ntok
, opname
);
3380 r
= ALPHA_RELOC_TABLE (reloc
->X_op
);
3381 as_bad (_("Cannot use !%s!%d with %s"), r
->name
,
3382 (int)reloc
->X_add_number
, (const char *)opname
);
3388 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
3390 basereg
= tok
[2].X_add_number
;
3392 lituse
= load_expression (tok
[0].X_add_number
, &tok
[1], &basereg
,
3393 &newtok
[1], (const expressionS
*)0);
3396 set_tok_preg (newtok
[2], basereg
);
3398 assemble_tokens_to_insn ((const char *)opname
, newtok
, 3, &insn
);
3403 int nfixups
= insn
.nfixups
;
3404 const struct alpha_reloc_op_tag
*r
= ALPHA_RELOC_TABLE (reloc
->X_op
);
3406 assert (nfixups
< MAX_INSN_FIXUPS
);
3407 insn
.fixups
[nfixups
].reloc
= r
->reloc
;
3408 insn
.fixups
[nfixups
].exp
.X_op
= O_symbol
;
3409 insn
.fixups
[nfixups
].exp
.X_add_symbol
= section_symbol (now_seg
);
3410 insn
.fixups
[nfixups
].exp
.X_add_number
= r
->lituse
;
3411 insn
.sequence
[nfixups
] = reloc
->X_add_number
;
3418 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3419 if (insn
.nfixups
> 0)
3421 memmove (&insn
.fixups
[1], &insn
.fixups
[0],
3422 sizeof(struct alpha_fixup
) * insn
.nfixups
);
3425 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITUSE
;
3426 insn
.fixups
[0].exp
.X_op
= O_symbol
;
3427 insn
.fixups
[0].exp
.X_add_symbol
= section_symbol (now_seg
);
3428 insn
.fixups
[0].exp
.X_add_number
= LITUSE_BASE
;
3434 /* Handle fp register loads, and both integer and fp register stores.
3435 Again, we handle simple expressions. */
3438 emit_loadstore (tok
, ntok
, opname
)
3439 const expressionS
*tok
;
3443 int basereg
, lituse
;
3444 expressionS newtok
[3];
3445 struct alpha_insn insn
;
3448 const expressionS
*reloc
= (const expressionS
*)0;
3450 if (ntok
&& USER_RELOC_P (tok
[ntok
-1].X_op
))
3452 reloc
= &tok
[--ntok
];
3453 if (reloc
->X_op
!= O_lituse_base
)
3455 const struct alpha_reloc_op_tag
*r
= &alpha_reloc_op
[ reloc
->X_md
];
3456 as_bad (_("Cannot use !%s!%d with %s"), r
->name
,
3457 (int)reloc
->X_add_number
, (const char *)opname
);
3463 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
3465 basereg
= tok
[2].X_add_number
;
3467 if (tok
[1].X_op
!= O_constant
|| !range_signed_16(tok
[1].X_add_number
))
3470 as_bad (_("macro requires $at register while noat in effect"));
3472 lituse
= load_expression (AXP_REG_AT
, &tok
[1], &basereg
, &newtok
[1],
3473 (const expressionS
*)0);
3482 set_tok_preg (newtok
[2], basereg
);
3484 assemble_tokens_to_insn ((const char *)opname
, newtok
, 3, &insn
);
3489 int nfixups
= insn
.nfixups
;
3490 const struct alpha_reloc_op_tag
*r
= ALPHA_RELOC_TABLE (reloc
->X_op
);
3492 assert (nfixups
< MAX_INSN_FIXUPS
);
3493 insn
.fixups
[nfixups
].reloc
= r
->reloc
;
3494 insn
.fixups
[nfixups
].exp
.X_op
= O_symbol
;
3495 insn
.fixups
[nfixups
].exp
.X_add_symbol
= section_symbol (now_seg
);
3496 insn
.fixups
[nfixups
].exp
.X_add_number
= r
->lituse
;
3497 insn
.sequence
[nfixups
] = reloc
->X_add_number
;
3504 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3505 if (insn
.nfixups
> 0)
3507 memmove (&insn
.fixups
[1], &insn
.fixups
[0],
3508 sizeof(struct alpha_fixup
) * insn
.nfixups
);
3511 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITUSE
;
3512 insn
.fixups
[0].exp
.X_op
= O_symbol
;
3513 insn
.fixups
[0].exp
.X_add_symbol
= section_symbol (now_seg
);
3514 insn
.fixups
[0].exp
.X_add_number
= LITUSE_BASE
;
3520 /* Load a half-word or byte as an unsigned value. */
3523 emit_ldXu (tok
, ntok
, vlgsize
)
3524 const expressionS
*tok
;
3528 if (alpha_target
& AXP_OPCODE_BWX
)
3529 emit_ir_load (tok
, ntok
, ldXu_op
[(long)vlgsize
]);
3532 expressionS newtok
[3];
3535 if (ntok
&& USER_RELOC_P (tok
[ntok
-1].X_op
))
3537 const expressionS
*reloc_exp
= &tok
[ntok
-1];
3538 const struct alpha_reloc_op_tag
*r
3539 = ALPHA_RELOC_TABLE (reloc_exp
->X_op
);
3541 as_bad (_("Cannot use !%s!%d with %s"), r
->name
,
3542 (int)reloc_exp
->X_add_number
, "ldbu/ldwu");
3548 as_bad (_("macro requires $at register while noat in effect"));
3550 /* emit "lda $at, exp" */
3552 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
3553 newtok
[0].X_add_number
= AXP_REG_AT
;
3554 assemble_tokens ("lda", newtok
, ntok
, 1);
3556 /* emit "ldq_u targ, 0($at)" */
3559 set_tok_const (newtok
[1], 0);
3560 set_tok_preg (newtok
[2], AXP_REG_AT
);
3561 assemble_tokens ("ldq_u", newtok
, 3, 1);
3563 /* emit "extXl targ, $at, targ" */
3565 set_tok_reg (newtok
[1], AXP_REG_AT
);
3566 newtok
[2] = newtok
[0];
3567 assemble_tokens (extXl_op
[(long)vlgsize
], newtok
, 3, 1);
3571 /* Load a half-word or byte as a signed value. */
3574 emit_ldX (tok
, ntok
, vlgsize
)
3575 const expressionS
*tok
;
3579 emit_ldXu (tok
, ntok
, vlgsize
);
3580 assemble_tokens (sextX_op
[(long)vlgsize
], tok
, 1, 1);
3583 /* Load an integral value from an unaligned address as an unsigned
3587 emit_uldXu (tok
, ntok
, vlgsize
)
3588 const expressionS
*tok
;
3592 long lgsize
= (long)vlgsize
;
3593 expressionS newtok
[3];
3596 as_bad (_("macro requires $at register while noat in effect"));
3598 /* emit "lda $at, exp" */
3600 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
3601 newtok
[0].X_add_number
= AXP_REG_AT
;
3602 assemble_tokens ("lda", newtok
, ntok
, 1);
3604 /* emit "ldq_u $t9, 0($at)" */
3606 set_tok_reg (newtok
[0], AXP_REG_T9
);
3607 set_tok_const (newtok
[1], 0);
3608 set_tok_preg (newtok
[2], AXP_REG_AT
);
3609 assemble_tokens ("ldq_u", newtok
, 3, 1);
3611 /* emit "ldq_u $t10, size-1($at)" */
3613 set_tok_reg (newtok
[0], AXP_REG_T10
);
3614 set_tok_const (newtok
[1], (1<<lgsize
)-1);
3615 assemble_tokens ("ldq_u", newtok
, 3, 1);
3617 /* emit "extXl $t9, $at, $t9" */
3619 set_tok_reg (newtok
[0], AXP_REG_T9
);
3620 set_tok_reg (newtok
[1], AXP_REG_AT
);
3621 set_tok_reg (newtok
[2], AXP_REG_T9
);
3622 assemble_tokens (extXl_op
[lgsize
], newtok
, 3, 1);
3624 /* emit "extXh $t10, $at, $t10" */
3626 set_tok_reg (newtok
[0], AXP_REG_T10
);
3627 set_tok_reg (newtok
[2], AXP_REG_T10
);
3628 assemble_tokens (extXh_op
[lgsize
], newtok
, 3, 1);
3630 /* emit "or $t9, $t10, targ" */
3632 set_tok_reg (newtok
[0], AXP_REG_T9
);
3633 set_tok_reg (newtok
[1], AXP_REG_T10
);
3635 assemble_tokens ("or", newtok
, 3, 1);
3638 /* Load an integral value from an unaligned address as a signed value.
3639 Note that quads should get funneled to the unsigned load since we
3640 don't have to do the sign extension. */
3643 emit_uldX (tok
, ntok
, vlgsize
)
3644 const expressionS
*tok
;
3648 emit_uldXu (tok
, ntok
, vlgsize
);
3649 assemble_tokens (sextX_op
[(long)vlgsize
], tok
, 1, 1);
3652 /* Implement the ldil macro. */
3655 emit_ldil (tok
, ntok
, unused
)
3656 const expressionS
*tok
;
3658 const PTR unused ATTRIBUTE_UNUSED
;
3660 expressionS newtok
[2];
3663 if (ntok
&& USER_RELOC_P (tok
[ntok
-1].X_op
))
3665 const expressionS
*reloc_exp
= &tok
[ntok
-1];
3666 const struct alpha_reloc_op_tag
*r
= ALPHA_RELOC_TABLE (reloc_exp
->X_op
);
3667 as_bad (_("Cannot use !%s!%d with %s"), r
->name
,
3668 (int)reloc_exp
->X_add_number
, "ldil");
3673 memcpy (newtok
, tok
, sizeof(newtok
));
3674 newtok
[1].X_add_number
= sign_extend_32 (tok
[1].X_add_number
);
3676 assemble_tokens ("lda", newtok
, ntok
, 1);
3679 /* Store a half-word or byte. */
3682 emit_stX (tok
, ntok
, vlgsize
)
3683 const expressionS
*tok
;
3687 int lgsize
= (int)(long)vlgsize
;
3689 if (alpha_target
& AXP_OPCODE_BWX
)
3690 emit_loadstore (tok
, ntok
, stX_op
[lgsize
]);
3693 expressionS newtok
[3];
3696 as_bad(_("macro requires $at register while noat in effect"));
3698 /* emit "lda $at, exp" */
3700 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
3701 newtok
[0].X_add_number
= AXP_REG_AT
;
3702 assemble_tokens ("lda", newtok
, ntok
, 1);
3704 /* emit "ldq_u $t9, 0($at)" */
3706 set_tok_reg (newtok
[0], AXP_REG_T9
);
3707 set_tok_const (newtok
[1], 0);
3708 set_tok_preg (newtok
[2], AXP_REG_AT
);
3709 assemble_tokens ("ldq_u", newtok
, 3, 1);
3711 /* emit "insXl src, $at, $t10" */
3714 set_tok_reg (newtok
[1], AXP_REG_AT
);
3715 set_tok_reg (newtok
[2], AXP_REG_T10
);
3716 assemble_tokens (insXl_op
[lgsize
], newtok
, 3, 1);
3718 /* emit "mskXl $t9, $at, $t9" */
3720 set_tok_reg (newtok
[0], AXP_REG_T9
);
3721 newtok
[2] = newtok
[0];
3722 assemble_tokens (mskXl_op
[lgsize
], newtok
, 3, 1);
3724 /* emit "or $t9, $t10, $t9" */
3726 set_tok_reg (newtok
[1], AXP_REG_T10
);
3727 assemble_tokens ("or", newtok
, 3, 1);
3729 /* emit "stq_u $t9, 0($at) */
3731 set_tok_const (newtok
[1], 0);
3732 set_tok_preg (newtok
[2], AXP_REG_AT
);
3733 assemble_tokens ("stq_u", newtok
, 3, 1);
3737 /* Store an integer to an unaligned address. */
3740 emit_ustX (tok
, ntok
, vlgsize
)
3741 const expressionS
*tok
;
3745 int lgsize
= (int)(long)vlgsize
;
3746 expressionS newtok
[3];
3748 /* emit "lda $at, exp" */
3750 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
3751 newtok
[0].X_add_number
= AXP_REG_AT
;
3752 assemble_tokens ("lda", newtok
, ntok
, 1);
3754 /* emit "ldq_u $9, 0($at)" */
3756 set_tok_reg (newtok
[0], AXP_REG_T9
);
3757 set_tok_const (newtok
[1], 0);
3758 set_tok_preg (newtok
[2], AXP_REG_AT
);
3759 assemble_tokens ("ldq_u", newtok
, 3, 1);
3761 /* emit "ldq_u $10, size-1($at)" */
3763 set_tok_reg (newtok
[0], AXP_REG_T10
);
3764 set_tok_const (newtok
[1], (1 << lgsize
)-1);
3765 assemble_tokens ("ldq_u", newtok
, 3, 1);
3767 /* emit "insXl src, $at, $t11" */
3770 set_tok_reg (newtok
[1], AXP_REG_AT
);
3771 set_tok_reg (newtok
[2], AXP_REG_T11
);
3772 assemble_tokens (insXl_op
[lgsize
], newtok
, 3, 1);
3774 /* emit "insXh src, $at, $t12" */
3776 set_tok_reg (newtok
[2], AXP_REG_T12
);
3777 assemble_tokens (insXh_op
[lgsize
], newtok
, 3, 1);
3779 /* emit "mskXl $t9, $at, $t9" */
3781 set_tok_reg (newtok
[0], AXP_REG_T9
);
3782 newtok
[2] = newtok
[0];
3783 assemble_tokens (mskXl_op
[lgsize
], newtok
, 3, 1);
3785 /* emit "mskXh $t10, $at, $t10" */
3787 set_tok_reg (newtok
[0], AXP_REG_T10
);
3788 newtok
[2] = newtok
[0];
3789 assemble_tokens (mskXh_op
[lgsize
], newtok
, 3, 1);
3791 /* emit "or $t9, $t11, $t9" */
3793 set_tok_reg (newtok
[0], AXP_REG_T9
);
3794 set_tok_reg (newtok
[1], AXP_REG_T11
);
3795 newtok
[2] = newtok
[0];
3796 assemble_tokens ("or", newtok
, 3, 1);
3798 /* emit "or $t10, $t12, $t10" */
3800 set_tok_reg (newtok
[0], AXP_REG_T10
);
3801 set_tok_reg (newtok
[1], AXP_REG_T12
);
3802 newtok
[2] = newtok
[0];
3803 assemble_tokens ("or", newtok
, 3, 1);
3805 /* emit "stq_u $t9, 0($at)" */
3807 set_tok_reg (newtok
[0], AXP_REG_T9
);
3808 set_tok_const (newtok
[1], 0);
3809 set_tok_preg (newtok
[2], AXP_REG_AT
);
3810 assemble_tokens ("stq_u", newtok
, 3, 1);
3812 /* emit "stq_u $t10, size-1($at)" */
3814 set_tok_reg (newtok
[0], AXP_REG_T10
);
3815 set_tok_const (newtok
[1], (1 << lgsize
)-1);
3816 assemble_tokens ("stq_u", newtok
, 3, 1);
3819 /* Sign extend a half-word or byte. The 32-bit sign extend is
3820 implemented as "addl $31, $r, $t" in the opcode table. */
3823 emit_sextX (tok
, ntok
, vlgsize
)
3824 const expressionS
*tok
;
3828 long lgsize
= (long)vlgsize
;
3830 if (alpha_target
& AXP_OPCODE_BWX
)
3831 assemble_tokens (sextX_op
[lgsize
], tok
, ntok
, 0);
3834 int bitshift
= 64 - 8 * (1 << lgsize
);
3835 expressionS newtok
[3];
3838 if (ntok
&& USER_RELOC_P (tok
[ntok
-1].X_op
))
3840 const expressionS
*reloc_exp
= &tok
[ntok
-1];
3841 const struct alpha_reloc_op_tag
*r
3842 = ALPHA_RELOC_TABLE (reloc_exp
->X_op
);
3844 as_bad (_("Cannot use !%s!%d with %s"), r
->name
,
3845 (int)reloc_exp
->X_add_number
, "setxt");
3850 /* emit "sll src,bits,dst" */
3853 set_tok_const (newtok
[1], bitshift
);
3854 newtok
[2] = tok
[ntok
- 1];
3855 assemble_tokens ("sll", newtok
, 3, 1);
3857 /* emit "sra dst,bits,dst" */
3859 newtok
[0] = newtok
[2];
3860 assemble_tokens ("sra", newtok
, 3, 1);
3864 /* Implement the division and modulus macros. */
3868 /* Make register usage like in normal procedure call.
3869 Don't clobber PV and RA. */
3872 emit_division (tok
, ntok
, symname
)
3873 const expressionS
*tok
;
3877 /* DIVISION and MODULUS. Yech.
3882 * mov x,R16 # if x != R16
3883 * mov y,R17 # if y != R17
3888 * with appropriate optimizations if R0,R16,R17 are the registers
3889 * specified by the compiler.
3894 expressionS newtok
[3];
3897 if (ntok
&& USER_RELOC_P (tok
[ntok
-1].X_op
))
3899 const expressionS
*reloc_exp
= &tok
[ntok
-1];
3900 const struct alpha_reloc_op_tag
*r
= ALPHA_RELOC_TABLE (reloc_exp
->X_op
);
3901 as_bad (_("Cannot use !%s!%d with %s"), r
->name
,
3902 (int)reloc_exp
->X_add_number
, (char char *)symname
);
3907 xr
= regno (tok
[0].X_add_number
);
3908 yr
= regno (tok
[1].X_add_number
);
3913 rr
= regno (tok
[2].X_add_number
);
3915 /* Move the operands into the right place */
3916 if (yr
== AXP_REG_R16
&& xr
== AXP_REG_R17
)
3918 /* They are in exactly the wrong order -- swap through AT */
3921 as_bad (_("macro requires $at register while noat in effect"));
3923 set_tok_reg (newtok
[0], AXP_REG_R16
);
3924 set_tok_reg (newtok
[1], AXP_REG_AT
);
3925 assemble_tokens ("mov", newtok
, 2, 1);
3927 set_tok_reg (newtok
[0], AXP_REG_R17
);
3928 set_tok_reg (newtok
[1], AXP_REG_R16
);
3929 assemble_tokens ("mov", newtok
, 2, 1);
3931 set_tok_reg (newtok
[0], AXP_REG_AT
);
3932 set_tok_reg (newtok
[1], AXP_REG_R17
);
3933 assemble_tokens ("mov", newtok
, 2, 1);
3937 if (yr
== AXP_REG_R16
)
3939 set_tok_reg (newtok
[0], AXP_REG_R16
);
3940 set_tok_reg (newtok
[1], AXP_REG_R17
);
3941 assemble_tokens ("mov", newtok
, 2, 1);
3944 if (xr
!= AXP_REG_R16
)
3946 set_tok_reg (newtok
[0], xr
);
3947 set_tok_reg (newtok
[1], AXP_REG_R16
);
3948 assemble_tokens ("mov", newtok
, 2, 1);
3951 if (yr
!= AXP_REG_R16
&& yr
!= AXP_REG_R17
)
3953 set_tok_reg (newtok
[0], yr
);
3954 set_tok_reg (newtok
[1], AXP_REG_R17
);
3955 assemble_tokens ("mov", newtok
, 2, 1);
3959 sym
= symbol_find_or_make ((const char *)symname
);
3961 set_tok_reg (newtok
[0], AXP_REG_AT
);
3962 set_tok_sym (newtok
[1], sym
, 0);
3963 assemble_tokens ("lda", newtok
, 2, 1);
3965 /* Call the division routine */
3966 set_tok_reg (newtok
[0], AXP_REG_AT
);
3967 set_tok_cpreg (newtok
[1], AXP_REG_AT
);
3968 set_tok_const (newtok
[2], 0);
3969 assemble_tokens ("jsr", newtok
, 3, 1);
3971 /* Move the result to the right place */
3972 if (rr
!= AXP_REG_R0
)
3974 set_tok_reg (newtok
[0], AXP_REG_R0
);
3975 set_tok_reg (newtok
[1], rr
);
3976 assemble_tokens ("mov", newtok
, 2, 1);
3980 #else /* !OBJ_EVAX */
3983 emit_division (tok
, ntok
, symname
)
3984 const expressionS
*tok
;
3988 /* DIVISION and MODULUS. Yech.
3998 * with appropriate optimizations if t10,t11,t12 are the registers
3999 * specified by the compiler.
4004 expressionS newtok
[3];
4007 if (ntok
&& USER_RELOC_P (tok
[ntok
-1].X_op
))
4009 const expressionS
*reloc_exp
= &tok
[ntok
-1];
4010 const struct alpha_reloc_op_tag
*r
= ALPHA_RELOC_TABLE (reloc_exp
->X_op
);
4011 as_bad (_("Cannot use !%s!%d with %s"), r
->name
,
4012 (int)reloc_exp
->X_add_number
, (const char *)symname
);
4017 xr
= regno (tok
[0].X_add_number
);
4018 yr
= regno (tok
[1].X_add_number
);
4023 rr
= regno (tok
[2].X_add_number
);
4025 sym
= symbol_find_or_make ((const char *)symname
);
4027 /* Move the operands into the right place */
4028 if (yr
== AXP_REG_T10
&& xr
== AXP_REG_T11
)
4030 /* They are in exactly the wrong order -- swap through AT */
4033 as_bad (_("macro requires $at register while noat in effect"));
4035 set_tok_reg (newtok
[0], AXP_REG_T10
);
4036 set_tok_reg (newtok
[1], AXP_REG_AT
);
4037 assemble_tokens ("mov", newtok
, 2, 1);
4039 set_tok_reg (newtok
[0], AXP_REG_T11
);
4040 set_tok_reg (newtok
[1], AXP_REG_T10
);
4041 assemble_tokens ("mov", newtok
, 2, 1);
4043 set_tok_reg (newtok
[0], AXP_REG_AT
);
4044 set_tok_reg (newtok
[1], AXP_REG_T11
);
4045 assemble_tokens ("mov", newtok
, 2, 1);
4049 if (yr
== AXP_REG_T10
)
4051 set_tok_reg (newtok
[0], AXP_REG_T10
);
4052 set_tok_reg (newtok
[1], AXP_REG_T11
);
4053 assemble_tokens ("mov", newtok
, 2, 1);
4056 if (xr
!= AXP_REG_T10
)
4058 set_tok_reg (newtok
[0], xr
);
4059 set_tok_reg (newtok
[1], AXP_REG_T10
);
4060 assemble_tokens ("mov", newtok
, 2, 1);
4063 if (yr
!= AXP_REG_T10
&& yr
!= AXP_REG_T11
)
4065 set_tok_reg (newtok
[0], yr
);
4066 set_tok_reg (newtok
[1], AXP_REG_T11
);
4067 assemble_tokens ("mov", newtok
, 2, 1);
4071 /* Call the division routine */
4072 set_tok_reg (newtok
[0], AXP_REG_T9
);
4073 set_tok_sym (newtok
[1], sym
, 0);
4074 assemble_tokens ("jsr", newtok
, 2, 1);
4076 /* Reload the GP register */
4080 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
4081 set_tok_reg (newtok
[0], alpha_gp_register
);
4082 set_tok_const (newtok
[1], 0);
4083 set_tok_preg (newtok
[2], AXP_REG_T9
);
4084 assemble_tokens ("ldgp", newtok
, 3, 1);
4087 /* Move the result to the right place */
4088 if (rr
!= AXP_REG_T12
)
4090 set_tok_reg (newtok
[0], AXP_REG_T12
);
4091 set_tok_reg (newtok
[1], rr
);
4092 assemble_tokens ("mov", newtok
, 2, 1);
4096 #endif /* !OBJ_EVAX */
4098 /* The jsr and jmp macros differ from their instruction counterparts
4099 in that they can load the target address and default most
4103 emit_jsrjmp (tok
, ntok
, vopname
)
4104 const expressionS
*tok
;
4108 const char *opname
= (const char *) vopname
;
4109 struct alpha_insn insn
;
4110 expressionS newtok
[3];
4111 int r
, tokidx
= 0, lituse
= 0;
4114 if (ntok
&& USER_RELOC_P (tok
[ntok
-1].X_op
))
4116 const expressionS
*reloc_exp
= &tok
[ntok
-1];
4117 const struct alpha_reloc_op_tag
*r
= ALPHA_RELOC_TABLE (reloc_exp
->X_op
);
4118 as_bad (_("Cannot use !%s!%d with %s"), r
->name
,
4119 (int)reloc_exp
->X_add_number
, opname
);
4124 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_register
)
4125 r
= regno (tok
[tokidx
++].X_add_number
);
4127 r
= strcmp (opname
, "jmp") == 0 ? AXP_REG_ZERO
: AXP_REG_RA
;
4129 set_tok_reg (newtok
[0], r
);
4131 if (tokidx
< ntok
&&
4132 (tok
[tokidx
].X_op
== O_pregister
|| tok
[tokidx
].X_op
== O_cpregister
))
4133 r
= regno (tok
[tokidx
++].X_add_number
);
4135 /* keep register if jsr $n.<sym> */
4139 int basereg
= alpha_gp_register
;
4140 lituse
= load_expression (r
= AXP_REG_PV
, &tok
[tokidx
], &basereg
, NULL
,
4141 (const expressionS
*)0);
4145 set_tok_cpreg (newtok
[1], r
);
4148 /* FIXME: Add hint relocs to BFD for evax. */
4151 newtok
[2] = tok
[tokidx
];
4154 set_tok_const (newtok
[2], 0);
4156 assemble_tokens_to_insn (opname
, newtok
, 3, &insn
);
4158 /* add the LITUSE fixup */
4161 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
4162 if (insn
.nfixups
> 0)
4164 memmove (&insn
.fixups
[1], &insn
.fixups
[0],
4165 sizeof(struct alpha_fixup
) * insn
.nfixups
);
4168 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITUSE
;
4169 insn
.fixups
[0].exp
.X_op
= O_symbol
;
4170 insn
.fixups
[0].exp
.X_add_symbol
= section_symbol (now_seg
);
4171 insn
.fixups
[0].exp
.X_add_number
= LITUSE_JSR
;
4177 /* The ret and jcr instructions differ from their instruction
4178 counterparts in that everything can be defaulted. */
4181 emit_retjcr (tok
, ntok
, vopname
)
4182 const expressionS
*tok
;
4186 const char *opname
= (const char *)vopname
;
4187 expressionS newtok
[3];
4191 if (ntok
&& USER_RELOC_P (tok
[ntok
-1].X_op
))
4193 const expressionS
*reloc_exp
= &tok
[ntok
-1];
4194 const struct alpha_reloc_op_tag
*r
= ALPHA_RELOC_TABLE (reloc_exp
->X_op
);
4195 as_bad (_("Cannot use !%s!%d with %s"), r
->name
,
4196 (int)reloc_exp
->X_add_number
, opname
);
4201 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_register
)
4202 r
= regno (tok
[tokidx
++].X_add_number
);
4206 set_tok_reg (newtok
[0], r
);
4208 if (tokidx
< ntok
&&
4209 (tok
[tokidx
].X_op
== O_pregister
|| tok
[tokidx
].X_op
== O_cpregister
))
4210 r
= regno (tok
[tokidx
++].X_add_number
);
4214 set_tok_cpreg (newtok
[1], r
);
4217 newtok
[2] = tok
[tokidx
];
4219 set_tok_const (newtok
[2], strcmp(opname
, "ret") == 0);
4221 assemble_tokens (opname
, newtok
, 3, 0);
4224 /* Assembler directives */
4226 /* Handle the .text pseudo-op. This is like the usual one, but it
4227 clears alpha_insn_label and restores auto alignment. */
4235 alpha_insn_label
= NULL
;
4236 alpha_auto_align_on
= 1;
4237 alpha_current_align
= 0;
4240 /* Handle the .data pseudo-op. This is like the usual one, but it
4241 clears alpha_insn_label and restores auto alignment. */
4248 alpha_insn_label
= NULL
;
4249 alpha_auto_align_on
= 1;
4250 alpha_current_align
= 0;
4253 #if defined (OBJ_ECOFF) || defined (OBJ_EVAX)
4255 /* Handle the OSF/1 and openVMS .comm pseudo quirks.
4256 openVMS constructs a section for every common symbol. */
4259 s_alpha_comm (ignore
)
4262 register char *name
;
4266 register symbolS
*symbolP
;
4269 segT current_section
= now_seg
;
4270 int current_subsec
= now_subseg
;
4274 name
= input_line_pointer
;
4275 c
= get_symbol_end ();
4277 /* just after name is now '\0' */
4278 p
= input_line_pointer
;
4283 /* Alpha OSF/1 compiler doesn't provide the comma, gcc does. */
4284 if (*input_line_pointer
== ',')
4286 input_line_pointer
++;
4289 if ((temp
= get_absolute_expression ()) < 0)
4291 as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) temp
);
4292 ignore_rest_of_line ();
4297 symbolP
= symbol_find_or_make (name
);
4300 /* Make a section for the common symbol. */
4301 new_seg
= subseg_new (xstrdup (name
), 0);
4307 /* alignment might follow */
4308 if (*input_line_pointer
== ',')
4312 input_line_pointer
++;
4313 align
= get_absolute_expression ();
4314 bfd_set_section_alignment (stdoutput
, new_seg
, align
);
4318 if (S_IS_DEFINED (symbolP
) && ! S_IS_COMMON (symbolP
))
4320 as_bad (_("Ignoring attempt to re-define symbol"));
4321 ignore_rest_of_line ();
4326 if (bfd_section_size (stdoutput
, new_seg
) > 0)
4328 if (bfd_section_size (stdoutput
, new_seg
) != temp
)
4329 as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
4330 S_GET_NAME (symbolP
),
4331 (long) bfd_section_size (stdoutput
, new_seg
),
4335 if (S_GET_VALUE (symbolP
))
4337 if (S_GET_VALUE (symbolP
) != (valueT
) temp
)
4338 as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
4339 S_GET_NAME (symbolP
),
4340 (long) S_GET_VALUE (symbolP
),
4347 subseg_set (new_seg
, 0);
4348 p
= frag_more (temp
);
4349 new_seg
->flags
|= SEC_IS_COMMON
;
4350 if (! S_IS_DEFINED (symbolP
))
4351 S_SET_SEGMENT (symbolP
, new_seg
);
4353 S_SET_VALUE (symbolP
, (valueT
) temp
);
4355 S_SET_EXTERNAL (symbolP
);
4359 subseg_set (current_section
, current_subsec
);
4362 know (symbol_get_frag (symbolP
) == &zero_address_frag
);
4364 demand_empty_rest_of_line ();
4367 #endif /* ! OBJ_ELF */
4371 /* Handle the .rdata pseudo-op. This is like the usual one, but it
4372 clears alpha_insn_label and restores auto alignment. */
4375 s_alpha_rdata (ignore
)
4380 temp
= get_absolute_expression ();
4381 subseg_new (".rdata", 0);
4382 demand_empty_rest_of_line ();
4383 alpha_insn_label
= NULL
;
4384 alpha_auto_align_on
= 1;
4385 alpha_current_align
= 0;
4392 /* Handle the .sdata pseudo-op. This is like the usual one, but it
4393 clears alpha_insn_label and restores auto alignment. */
4396 s_alpha_sdata (ignore
)
4401 temp
= get_absolute_expression ();
4402 subseg_new (".sdata", 0);
4403 demand_empty_rest_of_line ();
4404 alpha_insn_label
= NULL
;
4405 alpha_auto_align_on
= 1;
4406 alpha_current_align
= 0;
4412 /* Handle the .section pseudo-op. This is like the usual one, but it
4413 clears alpha_insn_label and restores auto alignment. */
4416 s_alpha_section (ignore
)
4419 obj_elf_section (ignore
);
4421 alpha_insn_label
= NULL
;
4422 alpha_auto_align_on
= 1;
4423 alpha_current_align
= 0;
4428 int dummy ATTRIBUTE_UNUSED
;
4430 if (ECOFF_DEBUGGING
)
4431 ecoff_directive_ent (0);
4434 char *name
, name_end
;
4435 name
= input_line_pointer
;
4436 name_end
= get_symbol_end ();
4438 if (! is_name_beginner (*name
))
4440 as_warn (_(".ent directive has no name"));
4441 *input_line_pointer
= name_end
;
4447 if (alpha_cur_ent_sym
)
4448 as_warn (_("nested .ent directives"));
4450 sym
= symbol_find_or_make (name
);
4451 symbol_get_bfdsym (sym
)->flags
|= BSF_FUNCTION
;
4452 alpha_cur_ent_sym
= sym
;
4454 /* The .ent directive is sometimes followed by a number. Not sure
4455 what it really means, but ignore it. */
4456 *input_line_pointer
= name_end
;
4458 if (*input_line_pointer
== ',')
4460 input_line_pointer
++;
4463 if (isdigit (*input_line_pointer
) || *input_line_pointer
== '-')
4464 (void) get_absolute_expression ();
4466 demand_empty_rest_of_line ();
4472 int dummy ATTRIBUTE_UNUSED
;
4474 if (ECOFF_DEBUGGING
)
4475 ecoff_directive_end (0);
4478 char *name
, name_end
;
4479 name
= input_line_pointer
;
4480 name_end
= get_symbol_end ();
4482 if (! is_name_beginner (*name
))
4484 as_warn (_(".end directive has no name"));
4485 *input_line_pointer
= name_end
;
4491 sym
= symbol_find (name
);
4492 if (sym
!= alpha_cur_ent_sym
)
4493 as_warn (_(".end directive names different symbol than .ent"));
4495 /* Create an expression to calculate the size of the function. */
4498 symbol_get_obj (sym
)->size
=
4499 (expressionS
*) xmalloc (sizeof (expressionS
));
4500 symbol_get_obj (sym
)->size
->X_op
= O_subtract
;
4501 symbol_get_obj (sym
)->size
->X_add_symbol
4502 = symbol_new ("L0\001", now_seg
, frag_now_fix (), frag_now
);
4503 symbol_get_obj (sym
)->size
->X_op_symbol
= sym
;
4504 symbol_get_obj (sym
)->size
->X_add_number
= 0;
4507 alpha_cur_ent_sym
= NULL
;
4509 *input_line_pointer
= name_end
;
4511 demand_empty_rest_of_line ();
4519 if (ECOFF_DEBUGGING
)
4522 ecoff_directive_fmask (0);
4524 ecoff_directive_mask (0);
4527 discard_rest_of_line ();
4531 s_alpha_frame (dummy
)
4532 int dummy ATTRIBUTE_UNUSED
;
4534 if (ECOFF_DEBUGGING
)
4535 ecoff_directive_frame (0);
4537 discard_rest_of_line ();
4541 s_alpha_prologue (ignore
)
4542 int ignore ATTRIBUTE_UNUSED
;
4547 arg
= get_absolute_expression ();
4548 demand_empty_rest_of_line ();
4550 if (ECOFF_DEBUGGING
)
4551 sym
= ecoff_get_cur_proc_sym ();
4553 sym
= alpha_cur_ent_sym
;
4558 case 0: /* No PV required. */
4559 S_SET_OTHER (sym
, STO_ALPHA_NOPV
);
4561 case 1: /* Std GP load. */
4562 S_SET_OTHER (sym
, STO_ALPHA_STD_GPLOAD
);
4564 case 2: /* Non-std use of PV. */
4568 as_bad (_("Invalid argument %d to .prologue."), arg
);
4574 s_alpha_coff_wrapper (which
)
4577 static void (* const fns
[]) PARAMS ((int)) = {
4578 ecoff_directive_begin
,
4579 ecoff_directive_bend
,
4580 ecoff_directive_def
,
4581 ecoff_directive_dim
,
4582 ecoff_directive_endef
,
4583 ecoff_directive_file
,
4584 ecoff_directive_scl
,
4585 ecoff_directive_tag
,
4586 ecoff_directive_val
,
4587 ecoff_directive_loc
,
4590 assert (which
>= 0 && which
< (int)(sizeof(fns
)/sizeof(*fns
)));
4592 if (ECOFF_DEBUGGING
)
4596 as_bad (_("ECOFF debugging is disabled."));
4597 ignore_rest_of_line ();
4600 #endif /* OBJ_ELF */
4604 /* Handle the section specific pseudo-op. */
4607 s_alpha_section (secid
)
4611 #define EVAX_SECTION_COUNT 5
4612 static char *section_name
[EVAX_SECTION_COUNT
+1] =
4613 { "NULL", ".rdata", ".comm", ".link", ".ctors", ".dtors" };
4615 if ((secid
<= 0) || (secid
> EVAX_SECTION_COUNT
))
4617 as_fatal (_("Unknown section directive"));
4618 demand_empty_rest_of_line ();
4621 temp
= get_absolute_expression ();
4622 subseg_new (section_name
[secid
], 0);
4623 demand_empty_rest_of_line ();
4624 alpha_insn_label
= NULL
;
4625 alpha_auto_align_on
= 1;
4626 alpha_current_align
= 0;
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 ();
4668 /* Parse .frame <framreg>,<framesize>,RA,<rsa_offset> directives. */
4671 s_alpha_frame (ignore
)
4676 alpha_evax_proc
.framereg
= tc_get_register (1);
4679 if (*input_line_pointer
++ != ','
4680 || get_absolute_expression_and_terminator (&val
) != ',')
4682 as_warn (_("Bad .frame directive 1./2. param"));
4683 --input_line_pointer
;
4684 demand_empty_rest_of_line ();
4688 alpha_evax_proc
.framesize
= val
;
4690 (void) tc_get_register (1);
4692 if (*input_line_pointer
++ != ',')
4694 as_warn (_("Bad .frame directive 3./4. param"));
4695 --input_line_pointer
;
4696 demand_empty_rest_of_line ();
4699 alpha_evax_proc
.rsa_offset
= get_absolute_expression ();
4705 s_alpha_pdesc (ignore
)
4715 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
4717 if (now_seg
!= alpha_link_section
)
4719 as_bad (_(".pdesc directive not in link (.link) section"));
4720 demand_empty_rest_of_line ();
4724 if ((alpha_evax_proc
.symbol
== 0)
4725 || (!S_IS_DEFINED (alpha_evax_proc
.symbol
)))
4727 as_fatal (_(".pdesc has no matching .ent"));
4728 demand_empty_rest_of_line ();
4732 *symbol_get_obj (alpha_evax_proc
.symbol
) =
4733 (valueT
) seginfo
->literal_pool_size
;
4736 if (exp
.X_op
!= O_symbol
)
4738 as_warn (_(".pdesc directive has no entry symbol"));
4739 demand_empty_rest_of_line ();
4743 entry_sym
= make_expr_symbol (&exp
);
4744 /* Save bfd symbol of proc desc in function symbol. */
4745 symbol_get_bfdsym (alpha_evax_proc
.symbol
)->udata
.p
4746 = symbol_get_bfdsym (entry_sym
);
4749 if (*input_line_pointer
++ != ',')
4751 as_warn (_("No comma after .pdesc <entryname>"));
4752 demand_empty_rest_of_line ();
4757 name
= input_line_pointer
;
4758 name_end
= get_symbol_end ();
4760 if (strncmp(name
, "stack", 5) == 0)
4762 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_FP_STACK
;
4764 else if (strncmp(name
, "reg", 3) == 0)
4766 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_FP_REGISTER
;
4768 else if (strncmp(name
, "null", 4) == 0)
4770 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_NULL
;
4774 as_fatal (_("unknown procedure kind"));
4775 demand_empty_rest_of_line ();
4779 *input_line_pointer
= name_end
;
4780 demand_empty_rest_of_line ();
4782 #ifdef md_flush_pending_output
4783 md_flush_pending_output ();
4786 frag_align (3, 0, 0);
4788 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
4790 seginfo
->literal_pool_size
+= 16;
4792 *p
= alpha_evax_proc
.pdsckind
4793 | ((alpha_evax_proc
.framereg
== 29) ? PDSC_S_M_BASE_REG_IS_FP
: 0);
4794 *(p
+1) = PDSC_S_M_NATIVE
4795 | PDSC_S_M_NO_JACKET
;
4797 switch (alpha_evax_proc
.pdsckind
)
4799 case PDSC_S_K_KIND_NULL
:
4803 case PDSC_S_K_KIND_FP_REGISTER
:
4804 *(p
+2) = alpha_evax_proc
.fp_save
;
4805 *(p
+3) = alpha_evax_proc
.ra_save
;
4807 case PDSC_S_K_KIND_FP_STACK
:
4808 md_number_to_chars (p
+2, (valueT
)alpha_evax_proc
.rsa_offset
, 2);
4810 default: /* impossible */
4815 *(p
+5) = alpha_evax_proc
.type
& 0x0f;
4817 /* Signature offset. */
4818 md_number_to_chars (p
+6, (valueT
)0, 2);
4820 fix_new_exp (frag_now
, p
-frag_now
->fr_literal
+8, 8, &exp
, 0, BFD_RELOC_64
);
4822 if (alpha_evax_proc
.pdsckind
== PDSC_S_K_KIND_NULL
)
4825 /* Add dummy fix to make add_to_link_pool work. */
4827 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
4829 seginfo
->literal_pool_size
+= 8;
4831 /* pdesc+16: Size. */
4832 md_number_to_chars (p
, (valueT
)alpha_evax_proc
.framesize
, 4);
4834 md_number_to_chars (p
+4, (valueT
)0, 2);
4837 md_number_to_chars (p
+6, alpha_evax_proc
.prologue
, 2);
4839 if (alpha_evax_proc
.pdsckind
== PDSC_S_K_KIND_FP_REGISTER
)
4842 /* Add dummy fix to make add_to_link_pool work. */
4844 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
4846 seginfo
->literal_pool_size
+= 8;
4848 /* pdesc+24: register masks. */
4850 md_number_to_chars (p
, alpha_evax_proc
.imask
, 4);
4851 md_number_to_chars (p
+4, alpha_evax_proc
.fmask
, 4);
4857 /* Support for crash debug on vms. */
4860 s_alpha_name (ignore
)
4865 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
4867 if (now_seg
!= alpha_link_section
)
4869 as_bad (_(".name directive not in link (.link) section"));
4870 demand_empty_rest_of_line ();
4875 if (exp
.X_op
!= O_symbol
)
4877 as_warn (_(".name directive has no symbol"));
4878 demand_empty_rest_of_line ();
4882 demand_empty_rest_of_line ();
4884 #ifdef md_flush_pending_output
4885 md_flush_pending_output ();
4888 frag_align (3, 0, 0);
4890 seginfo
->literal_pool_size
+= 8;
4892 fix_new_exp (frag_now
, p
-frag_now
->fr_literal
, 8, &exp
, 0, BFD_RELOC_64
);
4899 s_alpha_linkage (ignore
)
4905 #ifdef md_flush_pending_output
4906 md_flush_pending_output ();
4910 if (exp
.X_op
!= O_symbol
)
4912 as_fatal (_("No symbol after .linkage"));
4916 p
= frag_more (LKP_S_K_SIZE
);
4917 memset (p
, 0, LKP_S_K_SIZE
);
4918 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, LKP_S_K_SIZE
, &exp
, 0,\
4919 BFD_RELOC_ALPHA_LINKAGE
);
4921 demand_empty_rest_of_line ();
4928 s_alpha_code_address (ignore
)
4934 #ifdef md_flush_pending_output
4935 md_flush_pending_output ();
4939 if (exp
.X_op
!= O_symbol
)
4941 as_fatal (_("No symbol after .code_address"));
4947 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 8, &exp
, 0,\
4948 BFD_RELOC_ALPHA_CODEADDR
);
4950 demand_empty_rest_of_line ();
4957 s_alpha_fp_save (ignore
)
4961 alpha_evax_proc
.fp_save
= tc_get_register (1);
4963 demand_empty_rest_of_line ();
4969 s_alpha_mask (ignore
)
4974 if (get_absolute_expression_and_terminator (&val
) != ',')
4976 as_warn (_("Bad .mask directive"));
4977 --input_line_pointer
;
4981 alpha_evax_proc
.imask
= val
;
4982 (void)get_absolute_expression ();
4984 demand_empty_rest_of_line ();
4991 s_alpha_fmask (ignore
)
4996 if (get_absolute_expression_and_terminator (&val
) != ',')
4998 as_warn (_("Bad .fmask directive"));
4999 --input_line_pointer
;
5003 alpha_evax_proc
.fmask
= val
;
5004 (void) get_absolute_expression ();
5006 demand_empty_rest_of_line ();
5012 s_alpha_end (ignore
)
5017 c
= get_symbol_end ();
5018 *input_line_pointer
= c
;
5019 demand_empty_rest_of_line ();
5020 alpha_evax_proc
.symbol
= 0;
5027 s_alpha_file (ignore
)
5032 static char case_hack
[32];
5034 extern char *demand_copy_string
PARAMS ((int *lenP
));
5036 sprintf (case_hack
, "<CASE:%01d%01d>",
5037 alpha_flag_hash_long_names
, alpha_flag_show_after_trunc
);
5039 s
= symbol_find_or_make (case_hack
);
5040 symbol_get_bfdsym (s
)->flags
|= BSF_FILE
;
5042 get_absolute_expression ();
5043 s
= symbol_find_or_make (demand_copy_string (&length
));
5044 symbol_get_bfdsym (s
)->flags
|= BSF_FILE
;
5045 demand_empty_rest_of_line ();
5049 #endif /* OBJ_EVAX */
5051 /* Handle the .gprel32 pseudo op. */
5054 s_alpha_gprel32 (ignore
)
5055 int ignore ATTRIBUTE_UNUSED
;
5067 e
.X_add_symbol
= section_symbol(absolute_section
);
5080 e
.X_add_symbol
= section_symbol (absolute_section
);
5083 e
.X_op
= O_subtract
;
5084 e
.X_op_symbol
= alpha_gp_symbol
;
5092 if (alpha_auto_align_on
&& alpha_current_align
< 2)
5093 alpha_align (2, (char *) NULL
, alpha_insn_label
, 0);
5094 if (alpha_current_align
> 2)
5095 alpha_current_align
= 2;
5096 alpha_insn_label
= NULL
;
5100 fix_new_exp (frag_now
, p
-frag_now
->fr_literal
, 4,
5101 &e
, 0, BFD_RELOC_GPREL32
);
5104 /* Handle floating point allocation pseudo-ops. This is like the
5105 generic vresion, but it makes sure the current label, if any, is
5106 correctly aligned. */
5109 s_alpha_float_cons (type
)
5136 if (alpha_auto_align_on
&& alpha_current_align
< log_size
)
5137 alpha_align (log_size
, (char *) NULL
, alpha_insn_label
, 0);
5138 if (alpha_current_align
> log_size
)
5139 alpha_current_align
= log_size
;
5140 alpha_insn_label
= NULL
;
5145 /* Handle the .proc pseudo op. We don't really do much with it except
5149 s_alpha_proc (is_static
)
5150 int is_static ATTRIBUTE_UNUSED
;
5158 /* Takes ".proc name,nargs" */
5160 name
= input_line_pointer
;
5161 c
= get_symbol_end ();
5162 p
= input_line_pointer
;
5163 symbolP
= symbol_find_or_make (name
);
5166 if (*input_line_pointer
!= ',')
5169 as_warn (_("Expected comma after name \"%s\""), name
);
5172 ignore_rest_of_line ();
5176 input_line_pointer
++;
5177 temp
= get_absolute_expression ();
5179 /* *symbol_get_obj (symbolP) = (signed char) temp; */
5180 as_warn (_("unhandled: .proc %s,%d"), name
, temp
);
5181 demand_empty_rest_of_line ();
5184 /* Handle the .set pseudo op. This is used to turn on and off most of
5185 the assembler features. */
5189 int x ATTRIBUTE_UNUSED
;
5195 name
= input_line_pointer
;
5196 ch
= get_symbol_end ();
5199 if (s
[0] == 'n' && s
[1] == 'o')
5204 if (!strcmp ("reorder", s
))
5206 else if (!strcmp ("at", s
))
5207 alpha_noat_on
= !yesno
;
5208 else if (!strcmp ("macro", s
))
5209 alpha_macros_on
= yesno
;
5210 else if (!strcmp ("move", s
))
5212 else if (!strcmp ("volatile", s
))
5215 as_warn (_("Tried to .set unrecognized mode `%s'"), name
);
5217 *input_line_pointer
= ch
;
5218 demand_empty_rest_of_line ();
5221 /* Handle the .base pseudo op. This changes the assembler's notion of
5222 the $gp register. */
5225 s_alpha_base (ignore
)
5226 int ignore ATTRIBUTE_UNUSED
;
5229 if (first_32bit_quadrant
)
5231 /* not fatal, but it might not work in the end */
5232 as_warn (_("File overrides no-base-register option."));
5233 first_32bit_quadrant
= 0;
5238 if (*input_line_pointer
== '$')
5240 input_line_pointer
++;
5241 if (*input_line_pointer
== 'r')
5242 input_line_pointer
++;
5245 alpha_gp_register
= get_absolute_expression ();
5246 if (alpha_gp_register
< 0 || alpha_gp_register
> 31)
5248 alpha_gp_register
= AXP_REG_GP
;
5249 as_warn (_("Bad base register, using $%d."), alpha_gp_register
);
5252 demand_empty_rest_of_line ();
5255 /* Handle the .align pseudo-op. This aligns to a power of two. It
5256 also adjusts any current instruction label. We treat this the same
5257 way the MIPS port does: .align 0 turns off auto alignment. */
5260 s_alpha_align (ignore
)
5261 int ignore ATTRIBUTE_UNUSED
;
5265 long max_alignment
= 15;
5267 align
= get_absolute_expression ();
5268 if (align
> max_alignment
)
5270 align
= max_alignment
;
5271 as_bad (_("Alignment too large: %d. assumed"), align
);
5275 as_warn (_("Alignment negative: 0 assumed"));
5279 if (*input_line_pointer
== ',')
5281 input_line_pointer
++;
5282 fill
= get_absolute_expression ();
5290 alpha_auto_align_on
= 1;
5291 alpha_align (align
, pfill
, alpha_insn_label
, 1);
5295 alpha_auto_align_on
= 0;
5298 demand_empty_rest_of_line ();
5301 /* Hook the normal string processor to reset known alignment. */
5304 s_alpha_stringer (terminate
)
5307 alpha_current_align
= 0;
5308 alpha_insn_label
= NULL
;
5309 stringer (terminate
);
5312 /* Hook the normal space processing to reset known alignment. */
5315 s_alpha_space (ignore
)
5318 alpha_current_align
= 0;
5319 alpha_insn_label
= NULL
;
5323 /* Hook into cons for auto-alignment. */
5326 alpha_cons_align (size
)
5332 while ((size
>>= 1) != 0)
5335 if (alpha_auto_align_on
&& alpha_current_align
< log_size
)
5336 alpha_align (log_size
, (char *) NULL
, alpha_insn_label
, 0);
5337 if (alpha_current_align
> log_size
)
5338 alpha_current_align
= log_size
;
5339 alpha_insn_label
= NULL
;
5342 /* Here come the .uword, .ulong, and .uquad explicitly unaligned
5343 pseudos. We just turn off auto-alignment and call down to cons. */
5346 s_alpha_ucons (bytes
)
5349 int hold
= alpha_auto_align_on
;
5350 alpha_auto_align_on
= 0;
5352 alpha_auto_align_on
= hold
;
5355 /* Switch the working cpu type. */
5358 s_alpha_arch (ignored
)
5359 int ignored ATTRIBUTE_UNUSED
;
5362 const struct cpu_type
*p
;
5365 name
= input_line_pointer
;
5366 ch
= get_symbol_end ();
5368 for (p
= cpu_types
; p
->name
; ++p
)
5369 if (strcmp(name
, p
->name
) == 0)
5371 alpha_target_name
= p
->name
, alpha_target
= p
->flags
;
5374 as_warn("Unknown CPU identifier `%s'", name
);
5377 *input_line_pointer
= ch
;
5378 demand_empty_rest_of_line ();
5384 /* print token expression with alpha specific extension. */
5387 alpha_print_token(f
, exp
)
5389 const expressionS
*exp
;
5399 expressionS nexp
= *exp
;
5400 nexp
.X_op
= O_register
;
5401 print_expr (f
, &nexp
);
5406 print_expr (f
, exp
);
5413 /* The target specific pseudo-ops which we support. */
5415 const pseudo_typeS md_pseudo_table
[] =
5418 {"comm", s_alpha_comm
, 0}, /* osf1 compiler does this */
5419 {"rdata", s_alpha_rdata
, 0},
5421 {"text", s_alpha_text
, 0},
5422 {"data", s_alpha_data
, 0},
5424 {"sdata", s_alpha_sdata
, 0},
5427 {"section", s_alpha_section
, 0},
5428 {"section.s", s_alpha_section
, 0},
5429 {"sect", s_alpha_section
, 0},
5430 {"sect.s", s_alpha_section
, 0},
5433 { "pdesc", s_alpha_pdesc
, 0},
5434 { "name", s_alpha_name
, 0},
5435 { "linkage", s_alpha_linkage
, 0},
5436 { "code_address", s_alpha_code_address
, 0},
5437 { "ent", s_alpha_ent
, 0},
5438 { "frame", s_alpha_frame
, 0},
5439 { "fp_save", s_alpha_fp_save
, 0},
5440 { "mask", s_alpha_mask
, 0},
5441 { "fmask", s_alpha_fmask
, 0},
5442 { "end", s_alpha_end
, 0},
5443 { "file", s_alpha_file
, 0},
5444 { "rdata", s_alpha_section
, 1},
5445 { "comm", s_alpha_comm
, 0},
5446 { "link", s_alpha_section
, 3},
5447 { "ctors", s_alpha_section
, 4},
5448 { "dtors", s_alpha_section
, 5},
5451 /* Frame related pseudos. */
5452 {"ent", s_alpha_ent
, 0},
5453 {"end", s_alpha_end
, 0},
5454 {"mask", s_alpha_mask
, 0},
5455 {"fmask", s_alpha_mask
, 1},
5456 {"frame", s_alpha_frame
, 0},
5457 {"prologue", s_alpha_prologue
, 0},
5458 /* COFF debugging related pseudos. */
5459 {"begin", s_alpha_coff_wrapper
, 0},
5460 {"bend", s_alpha_coff_wrapper
, 1},
5461 {"def", s_alpha_coff_wrapper
, 2},
5462 {"dim", s_alpha_coff_wrapper
, 3},
5463 {"endef", s_alpha_coff_wrapper
, 4},
5464 {"file", s_alpha_coff_wrapper
, 5},
5465 {"scl", s_alpha_coff_wrapper
, 6},
5466 {"tag", s_alpha_coff_wrapper
, 7},
5467 {"val", s_alpha_coff_wrapper
, 8},
5468 {"loc", s_alpha_coff_wrapper
, 9},
5470 {"prologue", s_ignore
, 0},
5472 {"gprel32", s_alpha_gprel32
, 0},
5473 {"t_floating", s_alpha_float_cons
, 'd'},
5474 {"s_floating", s_alpha_float_cons
, 'f'},
5475 {"f_floating", s_alpha_float_cons
, 'F'},
5476 {"g_floating", s_alpha_float_cons
, 'G'},
5477 {"d_floating", s_alpha_float_cons
, 'D'},
5479 {"proc", s_alpha_proc
, 0},
5480 {"aproc", s_alpha_proc
, 1},
5481 {"set", s_alpha_set
, 0},
5482 {"reguse", s_ignore
, 0},
5483 {"livereg", s_ignore
, 0},
5484 {"base", s_alpha_base
, 0}, /*??*/
5485 {"option", s_ignore
, 0},
5486 {"aent", s_ignore
, 0},
5487 {"ugen", s_ignore
, 0},
5488 {"eflag", s_ignore
, 0},
5490 {"align", s_alpha_align
, 0},
5491 {"double", s_alpha_float_cons
, 'd'},
5492 {"float", s_alpha_float_cons
, 'f'},
5493 {"single", s_alpha_float_cons
, 'f'},
5494 {"ascii", s_alpha_stringer
, 0},
5495 {"asciz", s_alpha_stringer
, 1},
5496 {"string", s_alpha_stringer
, 1},
5497 {"space", s_alpha_space
, 0},
5498 {"skip", s_alpha_space
, 0},
5499 {"zero", s_alpha_space
, 0},
5501 /* Unaligned data pseudos. */
5502 {"uword", s_alpha_ucons
, 2},
5503 {"ulong", s_alpha_ucons
, 4},
5504 {"uquad", s_alpha_ucons
, 8},
5507 /* Dwarf wants these versions of unaligned. */
5508 {"2byte", s_alpha_ucons
, 2},
5509 {"4byte", s_alpha_ucons
, 4},
5510 {"8byte", s_alpha_ucons
, 8},
5513 /* We don't do any optimizing, so we can safely ignore these. */
5514 {"noalias", s_ignore
, 0},
5515 {"alias", s_ignore
, 0},
5517 {"arch", s_alpha_arch
, 0},
5523 /* Build a BFD section with its flags set appropriately for the .lita,
5524 .lit8, or .lit4 sections. */
5527 create_literal_section (name
, secp
, symp
)
5532 segT current_section
= now_seg
;
5533 int current_subsec
= now_subseg
;
5536 *secp
= new_sec
= subseg_new (name
, 0);
5537 subseg_set (current_section
, current_subsec
);
5538 bfd_set_section_alignment (stdoutput
, new_sec
, 4);
5539 bfd_set_section_flags (stdoutput
, new_sec
,
5540 SEC_RELOC
| SEC_ALLOC
| SEC_LOAD
| SEC_READONLY
5543 S_CLEAR_EXTERNAL (*symp
= section_symbol (new_sec
));
5548 /* @@@ GP selection voodoo. All of this seems overly complicated and
5549 unnecessary; which is the primary reason it's for ECOFF only. */
5558 vma
= bfd_get_section_vma (foo
, sec
);
5559 if (vma
&& vma
< alpha_gp_value
)
5560 alpha_gp_value
= vma
;
5566 assert (alpha_gp_value
== 0);
5568 /* Get minus-one in whatever width... */
5569 alpha_gp_value
= 0; alpha_gp_value
--;
5571 /* Select the smallest VMA of these existing sections. */
5572 maybe_set_gp (alpha_lita_section
);
5574 /* These were disabled before -- should we use them? */
5575 maybe_set_gp (sdata
);
5576 maybe_set_gp (lit8_sec
);
5577 maybe_set_gp (lit4_sec
);
5580 /* @@ Will a simple 0x8000 work here? If not, why not? */
5581 #define GP_ADJUSTMENT (0x8000 - 0x10)
5583 alpha_gp_value
+= GP_ADJUSTMENT
;
5585 S_SET_VALUE (alpha_gp_symbol
, alpha_gp_value
);
5588 printf (_("Chose GP value of %lx\n"), alpha_gp_value
);
5591 #endif /* OBJ_ECOFF */
5593 /* Called internally to handle all alignment needs. This takes care
5594 of eliding calls to frag_align if'n the cached current alignment
5595 says we've already got it, as well as taking care of the auto-align
5596 feature wrt labels. */
5599 alpha_align (n
, pfill
, label
, force
)
5603 int force ATTRIBUTE_UNUSED
;
5605 if (alpha_current_align
>= n
)
5611 && (bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
) != 0)
5613 static char const unop
[4] = { 0x00, 0x00, 0xe0, 0x2f };
5614 static char const nopunop
[8] = {
5615 0x1f, 0x04, 0xff, 0x47,
5616 0x00, 0x00, 0xe0, 0x2f
5619 /* First, make sure we're on a four-byte boundary, in case
5620 someone has been putting .byte values into the text
5621 section. The DEC assembler silently fills with unaligned
5622 no-op instructions. This will zero-fill, then nop-fill
5623 with proper alignment. */
5624 if (alpha_current_align
< 2)
5625 frag_align (2, 0, 0);
5626 if (alpha_current_align
< 3)
5627 frag_align_pattern (3, unop
, sizeof unop
, 0);
5629 frag_align_pattern (n
, nopunop
, sizeof nopunop
, 0);
5632 frag_align (n
, 0, 0);
5635 frag_align (n
, *pfill
, 0);
5637 alpha_current_align
= n
;
5639 if (label
!= NULL
&& S_GET_SEGMENT (label
) == now_seg
)
5641 symbol_set_frag (label
, frag_now
);
5642 S_SET_VALUE (label
, (valueT
) frag_now_fix ());
5645 record_alignment (now_seg
, n
);
5647 /* ??? if alpha_flag_relax && force && elf, record the requested alignment
5648 in a reloc for the linker to see. */
5651 /* The Alpha has support for some VAX floating point types, as well as for
5652 IEEE floating point. We consider IEEE to be the primary floating point
5653 format, and sneak in the VAX floating point support here. */
5654 #define md_atof vax_md_atof
5655 #include "config/atof-vax.c"