1 /* tc-alpha.c - Processor-specific code for the DEC Alpha AXP CPU.
2 Copyright 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
3 Free Software Foundation, Inc.
4 Contributed by Carnegie Mellon University, 1993.
5 Written by Alessandro Forin, based on earlier gas-1.38 target CPU files.
6 Modified by Ken Raeburn for gas-2.x and ECOFF support.
7 Modified by Richard Henderson for ELF support.
8 Modified by Klaus K"ampf for EVAX (OpenVMS/Alpha) support.
10 This file is part of GAS, the GNU Assembler.
12 GAS is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2, or (at your option)
17 GAS is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
22 You should have received a copy of the GNU General Public License
23 along with GAS; see the file COPYING. If not, write to the Free
24 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
28 * Mach Operating System
29 * Copyright (c) 1993 Carnegie Mellon University
30 * All Rights Reserved.
32 * Permission to use, copy, modify and distribute this software and its
33 * documentation is hereby granted, provided that both the copyright
34 * notice and this permission notice appear in all copies of the
35 * software, derivative works or modified versions, and any portions
36 * thereof, and that both notices appear in supporting documentation.
38 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
39 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
40 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
42 * Carnegie Mellon requests users of this software to return to
44 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
45 * School of Computer Science
46 * Carnegie Mellon University
47 * Pittsburgh PA 15213-3890
49 * any improvements or extensions that they make and grant Carnegie the
50 * rights to redistribute these changes.
55 #include "struc-symbol.h"
58 #include "opcode/alpha.h"
61 #include "elf/alpha.h"
62 #include "dwarf2dbg.h"
69 #define TOKENIZE_ERROR -1
70 #define TOKENIZE_ERROR_REPORT -2
72 #define MAX_INSN_FIXUPS 2
73 #define MAX_INSN_ARGS 5
77 bfd_reloc_code_real_type reloc
;
83 struct alpha_fixup fixups
[MAX_INSN_FIXUPS
];
84 unsigned sequence
[MAX_INSN_FIXUPS
];
87 enum alpha_macro_arg
{
103 void (*emit
) PARAMS ((const expressionS
*, int, const PTR
));
105 enum alpha_macro_arg argsets
[16];
108 /* Extra expression types. */
110 #define O_pregister O_md1 /* O_register, in parentheses */
111 #define O_cpregister O_md2 /* + a leading comma */
114 /* Note, the alpha_reloc_op table below depends on the ordering
115 of O_literal .. O_gprelow. */
116 #define O_literal O_md3 /* !literal relocation */
117 #define O_lituse_base O_md4 /* !lituse_base relocation */
118 #define O_lituse_bytoff O_md5 /* !lituse_bytoff relocation */
119 #define O_lituse_jsr O_md6 /* !lituse_jsr relocation */
120 #define O_gpdisp O_md7 /* !gpdisp relocation */
121 #define O_gprelhigh O_md8 /* !gprelhigh relocation */
122 #define O_gprellow O_md9 /* !gprellow relocation */
124 #define USER_RELOC_P(R) ((R) >= O_literal && (R) <= O_gprellow)
127 /* Macros for extracting the type and number of encoded register tokens */
129 #define is_ir_num(x) (((x) & 32) == 0)
130 #define is_fpr_num(x) (((x) & 32) != 0)
131 #define regno(x) ((x) & 31)
133 /* Something odd inherited from the old assembler */
135 #define note_gpreg(R) (alpha_gprmask |= (1 << (R)))
136 #define note_fpreg(R) (alpha_fprmask |= (1 << (R)))
138 /* Predicates for 16- and 32-bit ranges */
139 /* XXX: The non-shift version appears to trigger a compiler bug when
140 cross-assembling from x86 w/ gcc 2.7.2. */
143 #define range_signed_16(x) \
144 (((offsetT) (x) >> 15) == 0 || ((offsetT) (x) >> 15) == -1)
145 #define range_signed_32(x) \
146 (((offsetT) (x) >> 31) == 0 || ((offsetT) (x) >> 31) == -1)
148 #define range_signed_16(x) ((offsetT) (x) >= -(offsetT) 0x8000 && \
149 (offsetT) (x) <= (offsetT) 0x7FFF)
150 #define range_signed_32(x) ((offsetT) (x) >= -(offsetT) 0x80000000 && \
151 (offsetT) (x) <= (offsetT) 0x7FFFFFFF)
154 /* Macros for sign extending from 16- and 32-bits. */
155 /* XXX: The cast macros will work on all the systems that I care about,
156 but really a predicate should be found to use the non-cast forms. */
159 #define sign_extend_16(x) ((short) (x))
160 #define sign_extend_32(x) ((int) (x))
162 #define sign_extend_16(x) ((offsetT) (((x) & 0xFFFF) ^ 0x8000) - 0x8000)
163 #define sign_extend_32(x) ((offsetT) (((x) & 0xFFFFFFFF) \
164 ^ 0x80000000) - 0x80000000)
167 /* Macros to build tokens */
169 #define set_tok_reg(t, r) (memset (&(t), 0, sizeof (t)), \
170 (t).X_op = O_register, \
171 (t).X_add_number = (r))
172 #define set_tok_preg(t, r) (memset (&(t), 0, sizeof (t)), \
173 (t).X_op = O_pregister, \
174 (t).X_add_number = (r))
175 #define set_tok_cpreg(t, r) (memset (&(t), 0, sizeof (t)), \
176 (t).X_op = O_cpregister, \
177 (t).X_add_number = (r))
178 #define set_tok_freg(t, r) (memset (&(t), 0, sizeof (t)), \
179 (t).X_op = O_register, \
180 (t).X_add_number = (r) + 32)
181 #define set_tok_sym(t, s, a) (memset (&(t), 0, sizeof (t)), \
182 (t).X_op = O_symbol, \
183 (t).X_add_symbol = (s), \
184 (t).X_add_number = (a))
185 #define set_tok_const(t, n) (memset (&(t), 0, sizeof (t)), \
186 (t).X_op = O_constant, \
187 (t).X_add_number = (n))
189 /* Prototypes for all local functions */
191 static int tokenize_arguments
PARAMS ((char *, expressionS
*, int));
192 static const struct alpha_opcode
*find_opcode_match
193 PARAMS ((const struct alpha_opcode
*, const expressionS
*, int *, int *));
194 static const struct alpha_macro
*find_macro_match
195 PARAMS ((const struct alpha_macro
*, const expressionS
*, int *));
196 static unsigned insert_operand
197 PARAMS ((unsigned, const struct alpha_operand
*, offsetT
, char *, unsigned));
198 static void assemble_insn
199 PARAMS ((const struct alpha_opcode
*, const expressionS
*, int,
200 struct alpha_insn
*));
201 static void emit_insn
PARAMS ((struct alpha_insn
*));
202 static void assemble_tokens_to_insn
203 PARAMS ((const char *, const expressionS
*, int, struct alpha_insn
*));
204 static void assemble_tokens
205 PARAMS ((const char *, const expressionS
*, int, int));
207 static int load_expression
208 PARAMS ((int, const expressionS
*, int *, expressionS
*,
209 const expressionS
*));
211 static void emit_ldgp
PARAMS ((const expressionS
*, int, const PTR
));
212 static void emit_division
PARAMS ((const expressionS
*, int, const PTR
));
213 static void emit_lda
PARAMS ((const expressionS
*, int, const PTR
));
214 static void emit_ldah
PARAMS ((const expressionS
*, int, const PTR
));
215 static void emit_ir_load
PARAMS ((const expressionS
*, int, const PTR
));
216 static void emit_loadstore
PARAMS ((const expressionS
*, int, const PTR
));
217 static void emit_jsrjmp
PARAMS ((const expressionS
*, int, const PTR
));
218 static void emit_ldX
PARAMS ((const expressionS
*, int, const PTR
));
219 static void emit_ldXu
PARAMS ((const expressionS
*, int, const PTR
));
220 static void emit_uldX
PARAMS ((const expressionS
*, int, const PTR
));
221 static void emit_uldXu
PARAMS ((const expressionS
*, int, const PTR
));
222 static void emit_ldil
PARAMS ((const expressionS
*, int, const PTR
));
223 static void emit_stX
PARAMS ((const expressionS
*, int, const PTR
));
224 static void emit_ustX
PARAMS ((const expressionS
*, int, const PTR
));
225 static void emit_sextX
PARAMS ((const expressionS
*, int, const PTR
));
226 static void emit_retjcr
PARAMS ((const expressionS
*, int, const PTR
));
228 static void s_alpha_text
PARAMS ((int));
229 static void s_alpha_data
PARAMS ((int));
231 static void s_alpha_comm
PARAMS ((int));
232 static void s_alpha_rdata
PARAMS ((int));
235 static void s_alpha_sdata
PARAMS ((int));
238 static void s_alpha_section
PARAMS ((int));
239 static void s_alpha_ent
PARAMS ((int));
240 static void s_alpha_end
PARAMS ((int));
241 static void s_alpha_mask
PARAMS ((int));
242 static void s_alpha_frame
PARAMS ((int));
243 static void s_alpha_prologue
PARAMS ((int));
244 static void s_alpha_file
PARAMS ((int));
245 static void s_alpha_loc
PARAMS ((int));
246 static void s_alpha_stab
PARAMS ((int));
247 static void s_alpha_coff_wrapper
PARAMS ((int));
250 static void s_alpha_section
PARAMS ((int));
252 static void s_alpha_gprel32
PARAMS ((int));
253 static void s_alpha_float_cons
PARAMS ((int));
254 static void s_alpha_proc
PARAMS ((int));
255 static void s_alpha_set
PARAMS ((int));
256 static void s_alpha_base
PARAMS ((int));
257 static void s_alpha_align
PARAMS ((int));
258 static void s_alpha_stringer
PARAMS ((int));
259 static void s_alpha_space
PARAMS ((int));
261 static void create_literal_section
PARAMS ((const char *, segT
*, symbolS
**));
263 static void select_gp_value
PARAMS ((void));
265 static void alpha_align
PARAMS ((int, char *, symbolS
*, int));
268 static void alpha_adjust_symtab_relocs
PARAMS ((bfd
*, asection
*, PTR
));
271 /* Generic assembler global variables which must be defined by all
274 /* Characters which always start a comment. */
275 const char comment_chars
[] = "#";
277 /* Characters which start a comment at the beginning of a line. */
278 const char line_comment_chars
[] = "#";
280 /* Characters which may be used to separate multiple commands on a
282 const char line_separator_chars
[] = ";";
284 /* Characters which are used to indicate an exponent in a floating
286 const char EXP_CHARS
[] = "eE";
288 /* Characters which mean that a number is a floating point constant,
291 const char FLT_CHARS
[] = "dD";
293 /* XXX: Do all of these really get used on the alpha?? */
294 char FLT_CHARS
[] = "rRsSfFdDxXpP";
298 const char *md_shortopts
= "Fm:g+1h:HG:";
300 const char *md_shortopts
= "Fm:gG:";
303 struct option md_longopts
[] = {
304 #define OPTION_32ADDR (OPTION_MD_BASE)
305 { "32addr", no_argument
, NULL
, OPTION_32ADDR
},
306 #define OPTION_RELAX (OPTION_32ADDR + 1)
307 { "relax", no_argument
, NULL
, OPTION_RELAX
},
309 #define OPTION_MDEBUG (OPTION_RELAX + 1)
310 #define OPTION_NO_MDEBUG (OPTION_MDEBUG + 1)
311 { "mdebug", no_argument
, NULL
, OPTION_MDEBUG
},
312 { "no-mdebug", no_argument
, NULL
, OPTION_NO_MDEBUG
},
314 { NULL
, no_argument
, NULL
, 0 }
317 size_t md_longopts_size
= sizeof (md_longopts
);
321 #define AXP_REG_R16 16
322 #define AXP_REG_R17 17
324 #define AXP_REG_T9 22
326 #define AXP_REG_T10 23
328 #define AXP_REG_T11 24
330 #define AXP_REG_T12 25
331 #define AXP_REG_AI 25
333 #define AXP_REG_FP 29
336 #define AXP_REG_GP AXP_REG_PV
337 #endif /* OBJ_EVAX */
339 /* The cpu for which we are generating code */
340 static unsigned alpha_target
= AXP_OPCODE_BASE
;
341 static const char *alpha_target_name
= "<all>";
343 /* The hash table of instruction opcodes */
344 static struct hash_control
*alpha_opcode_hash
;
346 /* The hash table of macro opcodes */
347 static struct hash_control
*alpha_macro_hash
;
350 /* The $gp relocation symbol */
351 static symbolS
*alpha_gp_symbol
;
353 /* XXX: what is this, and why is it exported? */
354 valueT alpha_gp_value
;
357 /* The current $gp register */
358 static int alpha_gp_register
= AXP_REG_GP
;
360 /* A table of the register symbols */
361 static symbolS
*alpha_register_table
[64];
363 /* Constant sections, or sections of constants */
365 static segT alpha_lita_section
;
366 static segT alpha_lit4_section
;
369 static segT alpha_link_section
;
370 static segT alpha_ctors_section
;
371 static segT alpha_dtors_section
;
373 static segT alpha_lit8_section
;
375 /* Symbols referring to said sections. */
377 static symbolS
*alpha_lita_symbol
;
378 static symbolS
*alpha_lit4_symbol
;
381 static symbolS
*alpha_link_symbol
;
382 static symbolS
*alpha_ctors_symbol
;
383 static symbolS
*alpha_dtors_symbol
;
385 static symbolS
*alpha_lit8_symbol
;
387 /* Literal for .litX+0x8000 within .lita */
389 static offsetT alpha_lit4_literal
;
390 static offsetT alpha_lit8_literal
;
394 /* The active .ent symbol. */
395 static symbolS
*alpha_cur_ent_sym
;
398 /* Is the assembler not allowed to use $at? */
399 static int alpha_noat_on
= 0;
401 /* Are macros enabled? */
402 static int alpha_macros_on
= 1;
404 /* Are floats disabled? */
405 static int alpha_nofloats_on
= 0;
407 /* Are addresses 32 bit? */
408 static int alpha_addr32_on
= 0;
410 /* Symbol labelling the current insn. When the Alpha gas sees
413 and the section happens to not be on an eight byte boundary, it
414 will align both the symbol and the .quad to an eight byte boundary. */
415 static symbolS
*alpha_insn_label
;
417 /* Whether we should automatically align data generation pseudo-ops.
418 .align 0 will turn this off. */
419 static int alpha_auto_align_on
= 1;
421 /* The known current alignment of the current section. */
422 static int alpha_current_align
;
424 /* These are exported to ECOFF code. */
425 unsigned long alpha_gprmask
, alpha_fprmask
;
427 /* Whether the debugging option was seen. */
428 static int alpha_debug
;
431 /* Whether we are emitting an mdebug section. */
432 int alpha_flag_mdebug
= -1;
435 /* Don't fully resolve relocations, allowing code movement in the linker. */
436 static int alpha_flag_relax
;
438 /* What value to give to bfd_set_gp_size. */
439 static int g_switch_value
= 8;
442 /* Collect information about current procedure here. */
444 symbolS
*symbol
; /* proc pdesc symbol */
446 int framereg
; /* register for frame pointer */
447 int framesize
; /* size of frame */
457 static int alpha_flag_hash_long_names
= 0; /* -+ */
458 static int alpha_flag_show_after_trunc
= 0; /* -H */
460 /* If the -+ switch is given, then a hash is appended to any name that is
461 * longer than 64 characters, else longer symbol names are truncated.
467 /* A table to map the spelling of a relocation operand into an appropriate
468 bfd_reloc_code_real_type type. The table is assumed to be ordered such
469 that op-O_literal indexes into it. */
471 #define ALPHA_RELOC_TABLE(op) \
472 &alpha_reloc_op[ ((!USER_RELOC_P (op)) \
474 : (int) (op) - (int) O_literal) ]
476 #define LITUSE_BASE 1
477 #define LITUSE_BYTOFF 2
480 static const struct alpha_reloc_op_tag
{
481 const char *name
; /* string to lookup */
482 size_t length
; /* size of the string */
483 bfd_reloc_code_real_type reloc
; /* relocation before frob */
484 operatorT op
; /* which operator to use */
485 int lituse
; /* addened to specify lituse */
486 } alpha_reloc_op
[] = {
489 "literal", /* name */
490 sizeof ("literal")-1, /* length */
491 BFD_RELOC_ALPHA_USER_LITERAL
, /* reloc */
497 "lituse_base", /* name */
498 sizeof ("lituse_base")-1, /* length */
499 BFD_RELOC_ALPHA_USER_LITUSE_BASE
, /* reloc */
500 O_lituse_base
, /* op */
501 LITUSE_BASE
, /* lituse */
505 "lituse_bytoff", /* name */
506 sizeof ("lituse_bytoff")-1, /* length */
507 BFD_RELOC_ALPHA_USER_LITUSE_BYTOFF
, /* reloc */
508 O_lituse_bytoff
, /* op */
509 LITUSE_BYTOFF
, /* lituse */
513 "lituse_jsr", /* name */
514 sizeof ("lituse_jsr")-1, /* length */
515 BFD_RELOC_ALPHA_USER_LITUSE_JSR
, /* reloc */
516 O_lituse_jsr
, /* op */
517 LITUSE_JSR
, /* lituse */
522 sizeof ("gpdisp")-1, /* length */
523 BFD_RELOC_ALPHA_USER_GPDISP
, /* reloc */
529 "gprelhigh", /* name */
530 sizeof ("gprelhigh")-1, /* length */
531 BFD_RELOC_ALPHA_USER_GPRELHIGH
, /* reloc */
532 O_gprelhigh
, /* op */
537 "gprellow", /* name */
538 sizeof ("gprellow")-1, /* length */
539 BFD_RELOC_ALPHA_USER_GPRELLOW
, /* reloc */
545 static const int alpha_num_reloc_op
546 = sizeof (alpha_reloc_op
) / sizeof (*alpha_reloc_op
);
548 /* Maximum # digits needed to hold the largest sequence # */
549 #define ALPHA_RELOC_DIGITS 25
551 /* Whether a sequence number is valid. */
552 #define ALPHA_RELOC_SEQUENCE_OK(X) ((X) > 0 && ((unsigned) (X)) == (X))
554 /* Structure to hold explict sequence information. */
555 struct alpha_literal_tag
557 fixS
*lituse
; /* head of linked list of !literals */
558 segT segment
; /* segment relocs are in or undefined_section*/
559 int multi_section_p
; /* True if more than one section was used */
560 unsigned sequence
; /* sequence # */
561 unsigned n_literals
; /* # of literals */
562 unsigned n_lituses
; /* # of lituses */
563 char string
[1]; /* printable form of sequence to hash with */
566 /* Hash table to link up literals with the appropriate lituse */
567 static struct hash_control
*alpha_literal_hash
;
570 /* A table of CPU names and opcode sets. */
572 static const struct cpu_type
{
576 /* Ad hoc convention: cpu number gets palcode, process code doesn't.
577 This supports usage under DU 4.0b that does ".arch ev4", and
578 usage in MILO that does -m21064. Probably something more
579 specific like -m21064-pal should be used, but oh well. */
581 { "21064", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
582 { "21064a", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
583 { "21066", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
584 { "21068", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
585 { "21164", AXP_OPCODE_BASE
|AXP_OPCODE_EV5
},
586 { "21164a", AXP_OPCODE_BASE
|AXP_OPCODE_EV5
|AXP_OPCODE_BWX
},
587 { "21164pc", (AXP_OPCODE_BASE
|AXP_OPCODE_EV5
|AXP_OPCODE_BWX
589 { "21264", (AXP_OPCODE_BASE
|AXP_OPCODE_EV6
|AXP_OPCODE_BWX
590 |AXP_OPCODE_MAX
|AXP_OPCODE_CIX
) },
592 { "ev4", AXP_OPCODE_BASE
},
593 { "ev45", AXP_OPCODE_BASE
},
594 { "lca45", AXP_OPCODE_BASE
},
595 { "ev5", AXP_OPCODE_BASE
},
596 { "ev56", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
},
597 { "pca56", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
|AXP_OPCODE_MAX
},
598 { "ev6", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
|AXP_OPCODE_MAX
|AXP_OPCODE_CIX
},
600 { "all", AXP_OPCODE_BASE
},
604 /* The macro table */
606 static const struct alpha_macro alpha_macros
[] = {
607 /* Load/Store macros */
608 { "lda", emit_lda
, NULL
,
609 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_LITERAL
, MACRO_BASE
, MACRO_EOA
} },
610 { "ldah", emit_ldah
, NULL
,
611 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
613 { "ldl", emit_ir_load
, "ldl",
614 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
615 { "ldl_l", emit_ir_load
, "ldl_l",
616 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
617 { "ldq", emit_ir_load
, "ldq",
618 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_LITERAL
, MACRO_EOA
} },
619 { "ldq_l", emit_ir_load
, "ldq_l",
620 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
621 { "ldq_u", emit_ir_load
, "ldq_u",
622 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
623 { "ldf", emit_loadstore
, "ldf",
624 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
625 { "ldg", emit_loadstore
, "ldg",
626 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
627 { "lds", emit_loadstore
, "lds",
628 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
629 { "ldt", emit_loadstore
, "ldt",
630 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
632 { "ldb", emit_ldX
, (PTR
) 0,
633 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
634 { "ldbu", emit_ldXu
, (PTR
) 0,
635 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
636 { "ldw", emit_ldX
, (PTR
) 1,
637 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
638 { "ldwu", emit_ldXu
, (PTR
) 1,
639 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
641 { "uldw", emit_uldX
, (PTR
) 1,
642 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
643 { "uldwu", emit_uldXu
, (PTR
) 1,
644 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
645 { "uldl", emit_uldX
, (PTR
) 2,
646 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
647 { "uldlu", emit_uldXu
, (PTR
) 2,
648 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
649 { "uldq", emit_uldXu
, (PTR
) 3,
650 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
652 { "ldgp", emit_ldgp
, NULL
,
653 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
} },
655 { "ldi", emit_lda
, NULL
,
656 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
657 { "ldil", emit_ldil
, NULL
,
658 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
659 { "ldiq", emit_lda
, NULL
,
660 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
662 { "ldif" emit_ldiq
, NULL
,
663 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
664 { "ldid" emit_ldiq
, NULL
,
665 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
666 { "ldig" emit_ldiq
, NULL
,
667 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
668 { "ldis" emit_ldiq
, NULL
,
669 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
670 { "ldit" emit_ldiq
, NULL
,
671 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
674 { "stl", emit_loadstore
, "stl",
675 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
676 { "stl_c", emit_loadstore
, "stl_c",
677 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
678 { "stq", emit_loadstore
, "stq",
679 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
680 { "stq_c", emit_loadstore
, "stq_c",
681 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
682 { "stq_u", emit_loadstore
, "stq_u",
683 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
684 { "stf", emit_loadstore
, "stf",
685 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
686 { "stg", emit_loadstore
, "stg",
687 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
688 { "sts", emit_loadstore
, "sts",
689 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
690 { "stt", emit_loadstore
, "stt",
691 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
693 { "stb", emit_stX
, (PTR
) 0,
694 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
695 { "stw", emit_stX
, (PTR
) 1,
696 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
697 { "ustw", emit_ustX
, (PTR
) 1,
698 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
699 { "ustl", emit_ustX
, (PTR
) 2,
700 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
701 { "ustq", emit_ustX
, (PTR
) 3,
702 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
704 /* Arithmetic macros */
706 { "absl" emit_absl
, 1, { IR
} },
707 { "absl" emit_absl
, 2, { IR
, IR
} },
708 { "absl" emit_absl
, 2, { EXP
, IR
} },
709 { "absq" emit_absq
, 1, { IR
} },
710 { "absq" emit_absq
, 2, { IR
, IR
} },
711 { "absq" emit_absq
, 2, { EXP
, IR
} },
714 { "sextb", emit_sextX
, (PTR
) 0,
715 { MACRO_IR
, MACRO_IR
, MACRO_EOA
,
717 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
718 { "sextw", emit_sextX
, (PTR
) 1,
719 { MACRO_IR
, MACRO_IR
, MACRO_EOA
,
721 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
723 { "divl", emit_division
, "__divl",
724 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
725 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
726 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
727 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
728 { "divlu", emit_division
, "__divlu",
729 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
730 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
731 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
732 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
733 { "divq", emit_division
, "__divq",
734 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
735 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
736 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
737 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
738 { "divqu", emit_division
, "__divqu",
739 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
740 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
741 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
742 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
743 { "reml", emit_division
, "__reml",
744 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
745 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
746 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
747 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
748 { "remlu", emit_division
, "__remlu",
749 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
750 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
751 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
752 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
753 { "remq", emit_division
, "__remq",
754 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
755 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
756 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
757 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
758 { "remqu", emit_division
, "__remqu",
759 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
760 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
761 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
762 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
764 { "jsr", emit_jsrjmp
, "jsr",
765 { MACRO_PIR
, MACRO_EXP
, MACRO_JSR
, MACRO_EOA
,
766 MACRO_PIR
, MACRO_JSR
, MACRO_EOA
,
767 MACRO_IR
, MACRO_EXP
, MACRO_JSR
, MACRO_EOA
,
768 MACRO_EXP
, MACRO_JSR
, MACRO_EOA
} },
769 { "jmp", emit_jsrjmp
, "jmp",
770 { MACRO_PIR
, MACRO_EXP
, MACRO_JSR
, MACRO_EOA
,
771 MACRO_PIR
, MACRO_JSR
, MACRO_EOA
,
772 MACRO_IR
, MACRO_EXP
, MACRO_JSR
, MACRO_EOA
,
773 MACRO_EXP
, MACRO_JSR
, MACRO_EOA
} },
774 { "ret", emit_retjcr
, "ret",
775 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
777 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
778 MACRO_PIR
, MACRO_EOA
,
779 MACRO_EXP
, MACRO_EOA
,
781 { "jcr", emit_retjcr
, "jcr",
782 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
784 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
785 MACRO_PIR
, MACRO_EOA
,
786 MACRO_EXP
, MACRO_EOA
,
788 { "jsr_coroutine", emit_retjcr
, "jcr",
789 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
791 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
792 MACRO_PIR
, MACRO_EOA
,
793 MACRO_EXP
, MACRO_EOA
,
797 static const unsigned int alpha_num_macros
798 = sizeof (alpha_macros
) / sizeof (*alpha_macros
);
800 /* Public interface functions */
802 /* This function is called once, at assembler startup time. It sets
803 up all the tables, etc. that the MD part of the assembler will
804 need, that can be determined before arguments are parsed. */
811 /* Verify that X_op field is wide enough. */
815 assert (e
.X_op
== O_max
);
818 /* Create the opcode hash table */
820 alpha_opcode_hash
= hash_new ();
821 for (i
= 0; i
< alpha_num_opcodes
;)
823 const char *name
, *retval
, *slash
;
825 name
= alpha_opcodes
[i
].name
;
826 retval
= hash_insert (alpha_opcode_hash
, name
, (PTR
) &alpha_opcodes
[i
]);
828 as_fatal (_("internal error: can't hash opcode `%s': %s"), name
, retval
);
830 /* Some opcodes include modifiers of various sorts with a "/mod"
831 syntax, like the architecture manual suggests. However, for
832 use with gcc at least, we also need access to those same opcodes
835 if ((slash
= strchr (name
, '/')) != NULL
)
837 char *p
= xmalloc (strlen (name
));
838 memcpy (p
, name
, slash
- name
);
839 strcpy (p
+ (slash
- name
), slash
+ 1);
841 (void) hash_insert (alpha_opcode_hash
, p
, (PTR
) &alpha_opcodes
[i
]);
842 /* Ignore failures -- the opcode table does duplicate some
843 variants in different forms, like "hw_stq" and "hw_st/q". */
846 while (++i
< alpha_num_opcodes
847 && (alpha_opcodes
[i
].name
== name
848 || !strcmp (alpha_opcodes
[i
].name
, name
)))
852 /* Create the macro hash table */
854 alpha_macro_hash
= hash_new ();
855 for (i
= 0; i
< alpha_num_macros
;)
857 const char *name
, *retval
;
859 name
= alpha_macros
[i
].name
;
860 retval
= hash_insert (alpha_macro_hash
, name
, (PTR
) &alpha_macros
[i
]);
862 as_fatal (_("internal error: can't hash macro `%s': %s"),
865 while (++i
< alpha_num_macros
866 && (alpha_macros
[i
].name
== name
867 || !strcmp (alpha_macros
[i
].name
, name
)))
871 /* Construct symbols for each of the registers */
873 for (i
= 0; i
< 32; ++i
)
876 sprintf (name
, "$%d", i
);
877 alpha_register_table
[i
] = symbol_create (name
, reg_section
, i
,
883 sprintf (name
, "$f%d", i
- 32);
884 alpha_register_table
[i
] = symbol_create (name
, reg_section
, i
,
888 /* Create the special symbols and sections we'll be using */
890 /* So .sbss will get used for tiny objects. */
891 bfd_set_gp_size (stdoutput
, g_switch_value
);
894 create_literal_section (".lita", &alpha_lita_section
, &alpha_lita_symbol
);
896 /* For handling the GP, create a symbol that won't be output in the
897 symbol table. We'll edit it out of relocs later. */
898 alpha_gp_symbol
= symbol_create ("<GP value>", alpha_lita_section
, 0x8000,
903 create_literal_section (".link", &alpha_link_section
, &alpha_link_symbol
);
909 segT sec
= subseg_new (".mdebug", (subsegT
) 0);
910 bfd_set_section_flags (stdoutput
, sec
, SEC_HAS_CONTENTS
| SEC_READONLY
);
911 bfd_set_section_alignment (stdoutput
, sec
, 3);
915 subseg_set (text_section
, 0);
918 /* Create literal lookup hash table. */
919 alpha_literal_hash
= hash_new ();
923 /* The public interface to the instruction assembler. */
929 char opname
[32]; /* current maximum is 13 */
930 expressionS tok
[MAX_INSN_ARGS
];
934 /* split off the opcode */
935 opnamelen
= strspn (str
, "abcdefghijklmnopqrstuvwxyz_/46819");
936 trunclen
= (opnamelen
< sizeof (opname
) - 1
938 : sizeof (opname
) - 1);
939 memcpy (opname
, str
, trunclen
);
940 opname
[trunclen
] = '\0';
942 /* tokenize the rest of the line */
943 if ((ntok
= tokenize_arguments (str
+ opnamelen
, tok
, MAX_INSN_ARGS
)) < 0)
945 if (ntok
!= TOKENIZE_ERROR_REPORT
)
946 as_bad (_("syntax error"));
952 assemble_tokens (opname
, tok
, ntok
, alpha_macros_on
);
955 /* Round up a section's size to the appropriate boundary. */
958 md_section_align (seg
, size
)
962 int align
= bfd_get_section_alignment (stdoutput
, seg
);
963 valueT mask
= ((valueT
) 1 << align
) - 1;
965 return (size
+ mask
) & ~mask
;
968 /* Turn a string in input_line_pointer into a floating point constant
969 of type TYPE, and store the appropriate bytes in *LITP. The number
970 of LITTLENUMS emitted is stored in *SIZEP. An error message is
971 returned, or NULL on OK. */
973 /* Equal to MAX_PRECISION in atof-ieee.c */
974 #define MAX_LITTLENUMS 6
976 extern char *vax_md_atof
PARAMS ((int, char *, int *));
979 md_atof (type
, litP
, sizeP
)
985 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
986 LITTLENUM_TYPE
*wordP
;
993 /* VAX md_atof doesn't like "G" for some reason. */
997 return vax_md_atof (type
, litP
, sizeP
);
1020 return _("Bad call to MD_ATOF()");
1022 t
= atof_ieee (input_line_pointer
, type
, words
);
1024 input_line_pointer
= t
;
1025 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
1027 for (wordP
= words
+ prec
- 1; prec
--;)
1029 md_number_to_chars (litP
, (long) (*wordP
--), sizeof (LITTLENUM_TYPE
));
1030 litP
+= sizeof (LITTLENUM_TYPE
);
1036 /* Take care of the target-specific command-line options. */
1039 md_parse_option (c
, arg
)
1046 alpha_nofloats_on
= 1;
1050 alpha_addr32_on
= 1;
1058 g_switch_value
= atoi (arg
);
1063 const struct cpu_type
*p
;
1064 for (p
= cpu_types
; p
->name
; ++p
)
1065 if (strcmp (arg
, p
->name
) == 0)
1067 alpha_target_name
= p
->name
, alpha_target
= p
->flags
;
1070 as_warn (_("Unknown CPU identifier `%s'"), arg
);
1076 case '+': /* For g++. Hash any name > 63 chars long. */
1077 alpha_flag_hash_long_names
= 1;
1080 case 'H': /* Show new symbol after hash truncation */
1081 alpha_flag_show_after_trunc
= 1;
1084 case 'h': /* for gnu-c/vax compatibility. */
1089 alpha_flag_relax
= 1;
1094 alpha_flag_mdebug
= 1;
1096 case OPTION_NO_MDEBUG
:
1097 alpha_flag_mdebug
= 0;
1108 /* Print a description of the command-line options that we accept. */
1111 md_show_usage (stream
)
1116 -32addr treat addresses as 32-bit values\n\
1117 -F lack floating point instructions support\n\
1118 -mev4 | -mev45 | -mev5 | -mev56 | -mpca56 | -mev6 | -mall\n\
1119 specify variant of Alpha architecture\n\
1120 -m21064 | -m21066 | -m21164 | -m21164a | -m21164pc | -m21264\n\
1121 these variants include PALcode opcodes\n"),
1126 -+ hash encode (don't truncate) names longer than 64 characters\n\
1127 -H show new symbol after hash truncation\n"),
1132 /* Decide from what point a pc-relative relocation is relative to,
1133 relative to the pc-relative fixup. Er, relatively speaking. */
1136 md_pcrel_from (fixP
)
1139 valueT addr
= fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
1140 switch (fixP
->fx_r_type
)
1142 case BFD_RELOC_ALPHA_GPDISP
:
1143 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1144 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1147 return fixP
->fx_size
+ addr
;
1151 /* Attempt to simplify or even eliminate a fixup. The return value is
1152 ignored; perhaps it was once meaningful, but now it is historical.
1153 To indicate that a fixup has been eliminated, set fixP->fx_done.
1155 For ELF, here it is that we transform the GPDISP_HI16 reloc we used
1156 internally into the GPDISP reloc used externally. We had to do
1157 this so that we'd have the GPDISP_LO16 reloc as a tag to compute
1158 the distance to the "lda" instruction for setting the addend to
1162 md_apply_fix (fixP
, valueP
)
1166 char * const fixpos
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
1167 valueT value
= *valueP
;
1168 unsigned image
, size
;
1170 switch (fixP
->fx_r_type
)
1172 /* The GPDISP relocations are processed internally with a symbol
1173 referring to the current function; we need to drop in a value
1174 which, when added to the address of the start of the function,
1175 gives the desired GP. */
1176 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1178 fixS
*next
= fixP
->fx_next
;
1179 assert (next
->fx_r_type
== BFD_RELOC_ALPHA_GPDISP_LO16
);
1181 fixP
->fx_offset
= (next
->fx_frag
->fr_address
+ next
->fx_where
1182 - fixP
->fx_frag
->fr_address
- fixP
->fx_where
);
1184 value
= (value
- sign_extend_16 (value
)) >> 16;
1187 fixP
->fx_r_type
= BFD_RELOC_ALPHA_GPDISP
;
1191 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1192 value
= sign_extend_16 (value
);
1193 fixP
->fx_offset
= 0;
1199 fixP
->fx_addsy
= section_symbol (now_seg
);
1200 md_number_to_chars (fixpos
, value
, 2);
1205 fixP
->fx_r_type
= BFD_RELOC_16_PCREL
;
1210 fixP
->fx_r_type
= BFD_RELOC_32_PCREL
;
1215 fixP
->fx_r_type
= BFD_RELOC_64_PCREL
;
1218 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
1220 md_number_to_chars (fixpos
, value
, size
);
1226 case BFD_RELOC_GPREL32
:
1227 assert (fixP
->fx_subsy
== alpha_gp_symbol
);
1229 /* FIXME: inherited this obliviousness of `value' -- why? */
1230 md_number_to_chars (fixpos
, -alpha_gp_value
, 4);
1234 case BFD_RELOC_GPREL32
:
1238 case BFD_RELOC_23_PCREL_S2
:
1239 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
1241 image
= bfd_getl32 (fixpos
);
1242 image
= (image
& ~0x1FFFFF) | ((value
>> 2) & 0x1FFFFF);
1247 case BFD_RELOC_ALPHA_HINT
:
1248 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
1250 image
= bfd_getl32 (fixpos
);
1251 image
= (image
& ~0x3FFF) | ((value
>> 2) & 0x3FFF);
1257 case BFD_RELOC_ALPHA_LITERAL
:
1258 md_number_to_chars (fixpos
, value
, 2);
1261 case BFD_RELOC_ALPHA_LITUSE
:
1265 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1266 case BFD_RELOC_ALPHA_LITUSE
:
1270 case BFD_RELOC_ALPHA_LINKAGE
:
1271 case BFD_RELOC_ALPHA_CODEADDR
:
1276 case BFD_RELOC_ALPHA_USER_LITERAL
:
1277 case BFD_RELOC_ALPHA_USER_LITUSE_BASE
:
1278 case BFD_RELOC_ALPHA_USER_LITUSE_BYTOFF
:
1279 case BFD_RELOC_ALPHA_USER_LITUSE_JSR
:
1282 case BFD_RELOC_ALPHA_USER_GPDISP
:
1283 case BFD_RELOC_ALPHA_USER_GPRELHIGH
:
1284 case BFD_RELOC_ALPHA_USER_GPRELLOW
:
1288 case BFD_RELOC_VTABLE_INHERIT
:
1289 case BFD_RELOC_VTABLE_ENTRY
:
1294 const struct alpha_operand
*operand
;
1296 if ((int) fixP
->fx_r_type
>= 0)
1297 as_fatal (_("unhandled relocation type %s"),
1298 bfd_get_reloc_code_name (fixP
->fx_r_type
));
1300 assert (-(int) fixP
->fx_r_type
< (int) alpha_num_operands
);
1301 operand
= &alpha_operands
[-(int) fixP
->fx_r_type
];
1303 /* The rest of these fixups only exist internally during symbol
1304 resolution and have no representation in the object file.
1305 Therefore they must be completely resolved as constants. */
1307 if (fixP
->fx_addsy
!= 0
1308 && S_GET_SEGMENT (fixP
->fx_addsy
) != absolute_section
)
1309 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
1310 _("non-absolute expression in constant field"));
1312 image
= bfd_getl32 (fixpos
);
1313 image
= insert_operand (image
, operand
, (offsetT
) value
,
1314 fixP
->fx_file
, fixP
->fx_line
);
1319 if (fixP
->fx_addsy
!= 0 || fixP
->fx_pcrel
!= 0)
1323 as_warn_where (fixP
->fx_file
, fixP
->fx_line
,
1324 _("type %d reloc done?\n"), (int) fixP
->fx_r_type
);
1329 md_number_to_chars (fixpos
, image
, 4);
1337 * Look for a register name in the given symbol.
1341 md_undefined_symbol (name
)
1346 int is_float
= 0, num
;
1351 if (name
[1] == 'p' && name
[2] == '\0')
1352 return alpha_register_table
[AXP_REG_FP
];
1357 if (!isdigit (*++name
))
1361 case '0': case '1': case '2': case '3': case '4':
1362 case '5': case '6': case '7': case '8': case '9':
1363 if (name
[1] == '\0')
1364 num
= name
[0] - '0';
1365 else if (name
[0] != '0' && isdigit (name
[1]) && name
[2] == '\0')
1367 num
= (name
[0] - '0') * 10 + name
[1] - '0';
1374 if (!alpha_noat_on
&& (num
+ is_float
) == AXP_REG_AT
)
1375 as_warn (_("Used $at without \".set noat\""));
1376 return alpha_register_table
[num
+ is_float
];
1379 if (name
[1] == 't' && name
[2] == '\0')
1382 as_warn (_("Used $at without \".set noat\""));
1383 return alpha_register_table
[AXP_REG_AT
];
1388 if (name
[1] == 'p' && name
[2] == '\0')
1389 return alpha_register_table
[alpha_gp_register
];
1393 if (name
[1] == 'p' && name
[2] == '\0')
1394 return alpha_register_table
[AXP_REG_SP
];
1402 /* @@@ Magic ECOFF bits. */
1405 alpha_frob_ecoff_data ()
1408 /* $zero and $f31 are read-only */
1409 alpha_gprmask
&= ~1;
1410 alpha_fprmask
&= ~1;
1414 /* Hook to remember a recently defined label so that the auto-align
1415 code can adjust the symbol after we know what alignment will be
1419 alpha_define_label (sym
)
1422 alpha_insn_label
= sym
;
1425 /* Return true if we must always emit a reloc for a type and false if
1426 there is some hope of resolving it a assembly time. */
1429 alpha_force_relocation (f
)
1432 if (alpha_flag_relax
)
1435 switch (f
->fx_r_type
)
1437 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1438 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1439 case BFD_RELOC_ALPHA_GPDISP
:
1441 case BFD_RELOC_ALPHA_LITERAL
:
1444 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1446 case BFD_RELOC_ALPHA_LITUSE
:
1447 case BFD_RELOC_GPREL32
:
1449 case BFD_RELOC_ALPHA_LINKAGE
:
1450 case BFD_RELOC_ALPHA_CODEADDR
:
1453 case BFD_RELOC_ALPHA_USER_LITERAL
:
1454 case BFD_RELOC_ALPHA_USER_LITUSE_BASE
:
1455 case BFD_RELOC_ALPHA_USER_LITUSE_BYTOFF
:
1456 case BFD_RELOC_ALPHA_USER_LITUSE_JSR
:
1457 case BFD_RELOC_ALPHA_USER_GPDISP
:
1458 case BFD_RELOC_ALPHA_USER_GPRELHIGH
:
1459 case BFD_RELOC_ALPHA_USER_GPRELLOW
:
1461 case BFD_RELOC_VTABLE_INHERIT
:
1462 case BFD_RELOC_VTABLE_ENTRY
:
1465 case BFD_RELOC_23_PCREL_S2
:
1468 case BFD_RELOC_ALPHA_HINT
:
1472 assert ((int) f
->fx_r_type
< 0
1473 && -(int) f
->fx_r_type
< (int) alpha_num_operands
);
1478 /* Return true if we can partially resolve a relocation now. */
1481 alpha_fix_adjustable (f
)
1485 /* Prevent all adjustments to global symbols */
1486 if (S_IS_EXTERN (f
->fx_addsy
) || S_IS_WEAK (f
->fx_addsy
))
1490 /* Are there any relocation types for which we must generate a reloc
1491 but we can adjust the values contained within it? */
1492 switch (f
->fx_r_type
)
1494 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1495 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1496 case BFD_RELOC_ALPHA_GPDISP
:
1500 case BFD_RELOC_ALPHA_LITERAL
:
1503 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1506 case BFD_RELOC_ALPHA_USER_LITERAL
:
1509 case BFD_RELOC_ALPHA_LINKAGE
:
1510 case BFD_RELOC_ALPHA_CODEADDR
:
1514 case BFD_RELOC_ALPHA_LITUSE
:
1516 case BFD_RELOC_ALPHA_USER_LITUSE_BASE
:
1517 case BFD_RELOC_ALPHA_USER_LITUSE_BYTOFF
:
1518 case BFD_RELOC_ALPHA_USER_LITUSE_JSR
:
1519 case BFD_RELOC_ALPHA_USER_GPDISP
:
1520 case BFD_RELOC_ALPHA_USER_GPRELHIGH
:
1521 case BFD_RELOC_ALPHA_USER_GPRELLOW
:
1523 case BFD_RELOC_VTABLE_ENTRY
:
1524 case BFD_RELOC_VTABLE_INHERIT
:
1527 case BFD_RELOC_GPREL32
:
1528 case BFD_RELOC_23_PCREL_S2
:
1531 case BFD_RELOC_ALPHA_HINT
:
1535 assert ((int) f
->fx_r_type
< 0
1536 && - (int) f
->fx_r_type
< (int) alpha_num_operands
);
1542 /* Generate the BFD reloc to be stuck in the object file from the
1543 fixup used internally in the assembler. */
1546 tc_gen_reloc (sec
, fixp
)
1547 asection
*sec ATTRIBUTE_UNUSED
;
1552 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
1553 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
1554 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
1555 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
1557 /* Make sure none of our internal relocations make it this far.
1558 They'd better have been fully resolved by this point. */
1559 assert ((int) fixp
->fx_r_type
> 0);
1561 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
1562 if (reloc
->howto
== NULL
)
1564 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1565 _("cannot represent `%s' relocation in object file"),
1566 bfd_get_reloc_code_name (fixp
->fx_r_type
));
1570 if (!fixp
->fx_pcrel
!= !reloc
->howto
->pc_relative
)
1572 as_fatal (_("internal error? cannot generate `%s' relocation"),
1573 bfd_get_reloc_code_name (fixp
->fx_r_type
));
1575 assert (!fixp
->fx_pcrel
== !reloc
->howto
->pc_relative
);
1578 if (fixp
->fx_r_type
== BFD_RELOC_ALPHA_LITERAL
)
1580 /* fake out bfd_perform_relocation. sigh */
1581 reloc
->addend
= -alpha_gp_value
;
1586 reloc
->addend
= fixp
->fx_offset
;
1589 * Ohhh, this is ugly. The problem is that if this is a local global
1590 * symbol, the relocation will entirely be performed at link time, not
1591 * at assembly time. bfd_perform_reloc doesn't know about this sort
1592 * of thing, and as a result we need to fake it out here.
1594 if ((S_IS_EXTERN (fixp
->fx_addsy
) || S_IS_WEAK (fixp
->fx_addsy
))
1595 && !S_IS_COMMON (fixp
->fx_addsy
))
1596 reloc
->addend
-= symbol_get_bfdsym (fixp
->fx_addsy
)->value
;
1603 /* Parse a register name off of the input_line and return a register
1604 number. Gets md_undefined_symbol above to do the register name
1607 Only called as a part of processing the ECOFF .frame directive. */
1610 tc_get_register (frame
)
1611 int frame ATTRIBUTE_UNUSED
;
1613 int framereg
= AXP_REG_SP
;
1616 if (*input_line_pointer
== '$')
1618 char *s
= input_line_pointer
;
1619 char c
= get_symbol_end ();
1620 symbolS
*sym
= md_undefined_symbol (s
);
1622 *strchr (s
, '\0') = c
;
1623 if (sym
&& (framereg
= S_GET_VALUE (sym
)) <= 31)
1626 as_warn (_("frame reg expected, using $%d."), framereg
);
1629 note_gpreg (framereg
);
1633 /* This is called before the symbol table is processed. In order to
1634 work with gcc when using mips-tfile, we must keep all local labels.
1635 However, in other cases, we want to discard them. If we were
1636 called with -g, but we didn't see any debugging information, it may
1637 mean that gcc is smuggling debugging information through to
1638 mips-tfile, in which case we must generate all local labels. */
1643 alpha_frob_file_before_adjust ()
1645 if (alpha_debug
!= 0
1646 && ! ecoff_debugging_seen
)
1647 flag_keep_locals
= 1;
1650 #endif /* OBJ_ECOFF */
1654 /* Before the relocations are written, reorder them, so that user
1655 supplied !lituse relocations follow the appropriate !literal
1656 relocations. Also convert the gas-internal relocations to the
1657 appropriate linker relocations. */
1660 alpha_adjust_symtab ()
1662 if (alpha_literal_hash
)
1665 fprintf (stderr
, "alpha_adjust_symtab called\n");
1668 /* Go over each section, reordering the relocations so that all
1669 of the explicit LITUSE's are adjacent to the explicit
1671 bfd_map_over_sections (stdoutput
, alpha_adjust_symtab_relocs
,
1676 /* Inner function to move LITUSE's next to the LITERAL. */
1679 alpha_adjust_symtab_relocs (abfd
, sec
, ptr
)
1680 bfd
*abfd ATTRIBUTE_UNUSED
;
1682 PTR ptr ATTRIBUTE_UNUSED
;
1684 segment_info_type
*seginfo
= seg_info (sec
);
1694 int n_dup_literals
= 0;
1697 /* If seginfo is NULL, we did not create this section; don't do
1698 anything with it. By using a pointer to a pointer, we can update
1699 the links in place. */
1700 if (seginfo
== NULL
)
1703 /* If there are no relocations, skip the section. */
1704 if (! seginfo
->fix_root
)
1707 /* First rebuild the fixup chain without the expicit lituse's. */
1708 prevP
= &(seginfo
->fix_root
);
1709 for (fixp
= seginfo
->fix_root
; fixp
; fixp
= next
)
1711 next
= fixp
->fx_next
;
1712 fixp
->fx_next
= (fixS
*) 0;
1717 switch (fixp
->fx_r_type
)
1721 prevP
= &(fixp
->fx_next
);
1724 "alpha_adjust_symtab_relocs: 0x%lx, other relocation %s\n",
1726 bfd_get_reloc_code_name (fixp
->fx_r_type
));
1730 case BFD_RELOC_ALPHA_USER_LITERAL
:
1732 prevP
= &(fixp
->fx_next
);
1733 /* prevent assembler from trying to adjust the offset */
1736 if (fixp
->tc_fix_data
.info
->n_literals
!= 1)
1739 "alpha_adjust_symtab_relocs: 0x%lx, !literal!%.6d, # literals = %2d\n",
1741 fixp
->tc_fix_data
.info
->sequence
,
1742 fixp
->tc_fix_data
.info
->n_literals
);
1746 /* do not link in lituse's */
1747 case BFD_RELOC_ALPHA_USER_LITUSE_BASE
:
1748 case BFD_RELOC_ALPHA_USER_LITUSE_BYTOFF
:
1749 case BFD_RELOC_ALPHA_USER_LITUSE_JSR
:
1751 if (fixp
->tc_fix_data
.info
->n_literals
== 0)
1752 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1753 _("No !literal!%d was found"),
1754 fixp
->tc_fix_data
.info
->sequence
);
1757 "alpha_adjust_symtab_relocs: 0x%lx, !lituse !%.6d, # lituses = %2d, next_lituse = 0x%lx\n",
1759 fixp
->tc_fix_data
.info
->sequence
,
1760 fixp
->tc_fix_data
.info
->n_lituses
,
1761 (long) fixp
->tc_fix_data
.next_lituse
);
1767 /* If there were any lituses, go and add them to the chain, unless there is
1768 more than one !literal for a given sequence number. They are linked
1769 through the next_lituse field in reverse order, so as we go through the
1770 next_lituse chain, we effectively reverse the chain once again. If there
1771 was more than one !literal, we fall back to loading up the address w/o
1772 optimization. Also, if the !literals/!lituses are spread in different
1773 segments (happens in the Linux kernel semaphores), suppress the
1777 for (fixp
= seginfo
->fix_root
; fixp
; fixp
= fixp
->fx_next
)
1779 switch (fixp
->fx_r_type
)
1784 case BFD_RELOC_ALPHA_USER_LITERAL
:
1786 fixp
->fx_r_type
= BFD_RELOC_ALPHA_ELF_LITERAL
;
1788 fixp
->fx_r_type
= BFD_RELOC_ALPHA_LITERAL
; /* XXX check this */
1790 if (fixp
->tc_fix_data
.info
->n_literals
== 1
1791 && ! fixp
->tc_fix_data
.info
->multi_section_p
)
1793 for (lituse
= fixp
->tc_fix_data
.info
->lituse
;
1794 lituse
!= (fixS
*) 0;
1795 lituse
= lituse
->tc_fix_data
.next_lituse
)
1797 lituse
->fx_next
= fixp
->fx_next
;
1798 fixp
->fx_next
= lituse
;
1803 case BFD_RELOC_ALPHA_USER_LITUSE_BASE
:
1804 case BFD_RELOC_ALPHA_USER_LITUSE_BYTOFF
:
1805 case BFD_RELOC_ALPHA_USER_LITUSE_JSR
:
1806 fixp
->fx_r_type
= BFD_RELOC_ALPHA_LITUSE
;
1813 fprintf (stderr
, "alpha_adjust_symtab_relocs: %s, %d literal%s, %d duplicate literal%s, %d lituse%s\n\n",
1815 n_literals
, (n_literals
== 1) ? "" : "s",
1816 n_dup_literals
, (n_dup_literals
== 1) ? "" : "s",
1817 n_lituses
, (n_lituses
== 1) ? "" : "s");
1821 #endif /* RELOC_OP_P */
1825 debug_exp (tok
, ntok
)
1831 fprintf (stderr
, "debug_exp: %d tokens", ntok
);
1832 for (i
= 0; i
< ntok
; i
++)
1834 expressionS
*t
= &tok
[i
];
1838 default: name
= "unknown"; break;
1839 case O_illegal
: name
= "O_illegal"; break;
1840 case O_absent
: name
= "O_absent"; break;
1841 case O_constant
: name
= "O_constant"; break;
1842 case O_symbol
: name
= "O_symbol"; break;
1843 case O_symbol_rva
: name
= "O_symbol_rva"; break;
1844 case O_register
: name
= "O_register"; break;
1845 case O_big
: name
= "O_big"; break;
1846 case O_uminus
: name
= "O_uminus"; break;
1847 case O_bit_not
: name
= "O_bit_not"; break;
1848 case O_logical_not
: name
= "O_logical_not"; break;
1849 case O_multiply
: name
= "O_multiply"; break;
1850 case O_divide
: name
= "O_divide"; break;
1851 case O_modulus
: name
= "O_modulus"; break;
1852 case O_left_shift
: name
= "O_left_shift"; break;
1853 case O_right_shift
: name
= "O_right_shift"; break;
1854 case O_bit_inclusive_or
: name
= "O_bit_inclusive_or"; break;
1855 case O_bit_or_not
: name
= "O_bit_or_not"; break;
1856 case O_bit_exclusive_or
: name
= "O_bit_exclusive_or"; break;
1857 case O_bit_and
: name
= "O_bit_and"; break;
1858 case O_add
: name
= "O_add"; break;
1859 case O_subtract
: name
= "O_subtract"; break;
1860 case O_eq
: name
= "O_eq"; break;
1861 case O_ne
: name
= "O_ne"; break;
1862 case O_lt
: name
= "O_lt"; break;
1863 case O_le
: name
= "O_le"; break;
1864 case O_ge
: name
= "O_ge"; break;
1865 case O_gt
: name
= "O_gt"; break;
1866 case O_logical_and
: name
= "O_logical_and"; break;
1867 case O_logical_or
: name
= "O_logical_or"; break;
1868 case O_index
: name
= "O_index"; break;
1869 case O_pregister
: name
= "O_pregister"; break;
1870 case O_cpregister
: name
= "O_cpregister"; break;
1871 case O_literal
: name
= "O_literal"; break;
1872 case O_lituse_base
: name
= "O_lituse_base"; break;
1873 case O_lituse_bytoff
: name
= "O_lituse_bytoff"; break;
1874 case O_lituse_jsr
: name
= "O_lituse_jsr"; break;
1875 case O_gpdisp
: name
= "O_gpdisp"; break;
1876 case O_gprelhigh
: name
= "O_gprelhigh"; break;
1877 case O_gprellow
: name
= "O_gprellow"; break;
1878 case O_md10
: name
= "O_md10"; break;
1879 case O_md11
: name
= "O_md11"; break;
1880 case O_md12
: name
= "O_md12"; break;
1881 case O_md13
: name
= "O_md13"; break;
1882 case O_md14
: name
= "O_md14"; break;
1883 case O_md15
: name
= "O_md15"; break;
1884 case O_md16
: name
= "O_md16"; break;
1887 fprintf (stderr
, ", %s(%s, %s, %d)", name
,
1888 (t
->X_add_symbol
) ? S_GET_NAME (t
->X_add_symbol
) : "--",
1889 (t
->X_op_symbol
) ? S_GET_NAME (t
->X_op_symbol
) : "--",
1890 (int) t
->X_add_number
);
1892 fprintf (stderr
, "\n");
1897 /* Parse the arguments to an opcode. */
1900 tokenize_arguments (str
, tok
, ntok
)
1905 expressionS
*end_tok
= tok
+ ntok
;
1906 char *old_input_line_pointer
;
1907 int saw_comma
= 0, saw_arg
= 0;
1909 expressionS
*orig_tok
= tok
;
1913 const struct alpha_reloc_op_tag
*r
;
1916 int reloc_found_p
= 0;
1919 memset (tok
, 0, sizeof (*tok
) * ntok
);
1921 /* Save and restore input_line_pointer around this function */
1922 old_input_line_pointer
= input_line_pointer
;
1923 input_line_pointer
= str
;
1925 while (tok
< end_tok
&& *input_line_pointer
)
1928 switch (*input_line_pointer
)
1935 /* A relocation operand can be placed after the normal operand on an
1936 assembly language statement, and has the following form:
1937 !relocation_type!sequence_number. */
1939 { /* only support one relocation op per insn */
1940 as_bad (_("More than one relocation op per insn"));
1947 for (p
= ++input_line_pointer
;
1948 ((c
= *p
) != '!' && c
!= ';' && c
!= '#' && c
!= ','
1949 && !is_end_of_line
[c
]);
1953 /* Parse !relocation_type */
1954 len
= p
- input_line_pointer
;
1957 as_bad (_("No relocation operand"));
1963 as_bad (_("No !sequence-number after !%s"), input_line_pointer
);
1967 r
= &alpha_reloc_op
[0];
1968 for (i
= alpha_num_reloc_op
- 1; i
>= 0; i
--, r
++)
1970 if (len
== r
->length
1971 && memcmp (input_line_pointer
, r
->name
, len
) == 0)
1976 as_bad (_("Unknown relocation operand: !%s"),
1977 input_line_pointer
);
1981 input_line_pointer
= ++p
;
1983 /* Parse !sequence_number */
1984 memset (tok
, '\0', sizeof (expressionS
));
1987 if (tok
->X_op
!= O_constant
1988 || ! ALPHA_RELOC_SEQUENCE_OK (tok
->X_add_number
))
1990 as_bad (_("Bad sequence number: !%s!%s"),
1991 r
->name
, input_line_pointer
);
2002 ++input_line_pointer
;
2003 if (saw_comma
|| !saw_arg
)
2010 char *hold
= input_line_pointer
++;
2012 /* First try for parenthesized register ... */
2014 if (*input_line_pointer
== ')' && tok
->X_op
== O_register
)
2016 tok
->X_op
= (saw_comma
? O_cpregister
: O_pregister
);
2019 ++input_line_pointer
;
2024 /* ... then fall through to plain expression */
2025 input_line_pointer
= hold
;
2029 if (saw_arg
&& !saw_comma
)
2033 if (tok
->X_op
== O_illegal
|| tok
->X_op
== O_absent
)
2046 input_line_pointer
= old_input_line_pointer
;
2049 debug_exp (orig_tok
, ntok
- (end_tok
- tok
));
2052 return ntok
- (end_tok
- tok
);
2055 input_line_pointer
= old_input_line_pointer
;
2056 return TOKENIZE_ERROR
;
2060 input_line_pointer
= old_input_line_pointer
;
2061 return TOKENIZE_ERROR_REPORT
;
2065 /* Search forward through all variants of an opcode looking for a
2068 static const struct alpha_opcode
*
2069 find_opcode_match (first_opcode
, tok
, pntok
, pcpumatch
)
2070 const struct alpha_opcode
*first_opcode
;
2071 const expressionS
*tok
;
2075 const struct alpha_opcode
*opcode
= first_opcode
;
2077 int got_cpu_match
= 0;
2081 const unsigned char *opidx
;
2084 /* Don't match opcodes that don't exist on this architecture */
2085 if (!(opcode
->flags
& alpha_target
))
2090 for (opidx
= opcode
->operands
; *opidx
; ++opidx
)
2092 const struct alpha_operand
*operand
= &alpha_operands
[*opidx
];
2094 /* only take input from real operands */
2095 if (operand
->flags
& AXP_OPERAND_FAKE
)
2098 /* when we expect input, make sure we have it */
2101 if ((operand
->flags
& AXP_OPERAND_OPTIONAL_MASK
) == 0)
2106 /* match operand type with expression type */
2107 switch (operand
->flags
& AXP_OPERAND_TYPECHECK_MASK
)
2109 case AXP_OPERAND_IR
:
2110 if (tok
[tokidx
].X_op
!= O_register
2111 || !is_ir_num (tok
[tokidx
].X_add_number
))
2114 case AXP_OPERAND_FPR
:
2115 if (tok
[tokidx
].X_op
!= O_register
2116 || !is_fpr_num (tok
[tokidx
].X_add_number
))
2119 case AXP_OPERAND_IR
| AXP_OPERAND_PARENS
:
2120 if (tok
[tokidx
].X_op
!= O_pregister
2121 || !is_ir_num (tok
[tokidx
].X_add_number
))
2124 case AXP_OPERAND_IR
| AXP_OPERAND_PARENS
| AXP_OPERAND_COMMA
:
2125 if (tok
[tokidx
].X_op
!= O_cpregister
2126 || !is_ir_num (tok
[tokidx
].X_add_number
))
2130 case AXP_OPERAND_RELATIVE
:
2131 case AXP_OPERAND_SIGNED
:
2132 case AXP_OPERAND_UNSIGNED
:
2133 switch (tok
[tokidx
].X_op
)
2148 /* everything else should have been fake */
2154 /* possible match -- did we use all of our input? */
2163 while (++opcode
- alpha_opcodes
< alpha_num_opcodes
2164 && !strcmp (opcode
->name
, first_opcode
->name
));
2167 *pcpumatch
= got_cpu_match
;
2172 /* Search forward through all variants of a macro looking for a syntax
2175 static const struct alpha_macro
*
2176 find_macro_match (first_macro
, tok
, pntok
)
2177 const struct alpha_macro
*first_macro
;
2178 const expressionS
*tok
;
2181 const struct alpha_macro
*macro
= first_macro
;
2186 const enum alpha_macro_arg
*arg
= macro
->argsets
;
2200 /* index register */
2202 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_register
2203 || !is_ir_num (tok
[tokidx
].X_add_number
))
2208 /* parenthesized index register */
2210 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_pregister
2211 || !is_ir_num (tok
[tokidx
].X_add_number
))
2216 /* optional parenthesized index register */
2218 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_pregister
2219 && is_ir_num (tok
[tokidx
].X_add_number
))
2223 /* leading comma with a parenthesized index register */
2225 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_cpregister
2226 || !is_ir_num (tok
[tokidx
].X_add_number
))
2231 /* floating point register */
2233 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_register
2234 || !is_fpr_num (tok
[tokidx
].X_add_number
))
2239 /* normal expression */
2243 switch (tok
[tokidx
].X_op
)
2253 case O_lituse_bytoff
:
2267 /* optional !literal!<number> */
2270 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_literal
)
2275 /* optional !lituse_base!<number> */
2278 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_lituse_base
)
2283 /* optional !lituse_bytoff!<number> */
2286 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_lituse_bytoff
)
2291 /* optional !lituse_jsr!<number> */
2294 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_lituse_jsr
)
2300 while (*arg
!= MACRO_EOA
)
2308 while (++macro
- alpha_macros
< alpha_num_macros
2309 && !strcmp (macro
->name
, first_macro
->name
));
2314 /* Insert an operand value into an instruction. */
2317 insert_operand (insn
, operand
, val
, file
, line
)
2319 const struct alpha_operand
*operand
;
2324 if (operand
->bits
!= 32 && !(operand
->flags
& AXP_OPERAND_NOOVERFLOW
))
2328 if (operand
->flags
& AXP_OPERAND_SIGNED
)
2330 max
= (1 << (operand
->bits
- 1)) - 1;
2331 min
= -(1 << (operand
->bits
- 1));
2335 max
= (1 << operand
->bits
) - 1;
2339 if (val
< min
|| val
> max
)
2342 _("operand out of range (%s not between %d and %d)");
2343 char buf
[sizeof (val
) * 3 + 2];
2345 sprint_value (buf
, val
);
2347 as_warn_where (file
, line
, err
, buf
, min
, max
);
2349 as_warn (err
, buf
, min
, max
);
2353 if (operand
->insert
)
2355 const char *errmsg
= NULL
;
2357 insn
= (*operand
->insert
) (insn
, val
, &errmsg
);
2362 insn
|= ((val
& ((1 << operand
->bits
) - 1)) << operand
->shift
);
2368 * Turn an opcode description and a set of arguments into
2369 * an instruction and a fixup.
2373 assemble_insn (opcode
, tok
, ntok
, insn
)
2374 const struct alpha_opcode
*opcode
;
2375 const expressionS
*tok
;
2377 struct alpha_insn
*insn
;
2379 const unsigned char *argidx
;
2383 memset (insn
, 0, sizeof (*insn
));
2384 image
= opcode
->opcode
;
2386 for (argidx
= opcode
->operands
; *argidx
; ++argidx
)
2388 const struct alpha_operand
*operand
= &alpha_operands
[*argidx
];
2389 const expressionS
*t
= (const expressionS
*) 0;
2391 if (operand
->flags
& AXP_OPERAND_FAKE
)
2393 /* fake operands take no value and generate no fixup */
2394 image
= insert_operand (image
, operand
, 0, NULL
, 0);
2400 switch (operand
->flags
& AXP_OPERAND_OPTIONAL_MASK
)
2402 case AXP_OPERAND_DEFAULT_FIRST
:
2405 case AXP_OPERAND_DEFAULT_SECOND
:
2408 case AXP_OPERAND_DEFAULT_ZERO
:
2410 static expressionS zero_exp
;
2412 zero_exp
.X_op
= O_constant
;
2413 zero_exp
.X_unsigned
= 1;
2428 image
= insert_operand (image
, operand
, regno (t
->X_add_number
),
2433 image
= insert_operand (image
, operand
, t
->X_add_number
, NULL
, 0);
2438 struct alpha_fixup
*fixup
;
2440 if (insn
->nfixups
>= MAX_INSN_FIXUPS
)
2441 as_fatal (_("too many fixups"));
2443 fixup
= &insn
->fixups
[insn
->nfixups
++];
2446 fixup
->reloc
= operand
->default_reloc
;
2456 * Actually output an instruction with its fixup.
2461 struct alpha_insn
*insn
;
2466 /* Take care of alignment duties. */
2467 if (alpha_auto_align_on
&& alpha_current_align
< 2)
2468 alpha_align (2, (char *) NULL
, alpha_insn_label
, 0);
2469 if (alpha_current_align
> 2)
2470 alpha_current_align
= 2;
2471 alpha_insn_label
= NULL
;
2473 /* Write out the instruction. */
2475 md_number_to_chars (f
, insn
->insn
, 4);
2478 dwarf2_emit_insn (4);
2481 /* Apply the fixups in order */
2482 for (i
= 0; i
< insn
->nfixups
; ++i
)
2484 const struct alpha_operand
*operand
= (const struct alpha_operand
*) 0;
2485 struct alpha_fixup
*fixup
= &insn
->fixups
[i
];
2489 char buffer
[ALPHA_RELOC_DIGITS
];
2490 struct alpha_literal_tag
*info
;
2493 /* Some fixups are only used internally and so have no howto */
2494 if ((int) fixup
->reloc
< 0)
2496 operand
= &alpha_operands
[-(int) fixup
->reloc
];
2498 pcrel
= ((operand
->flags
& AXP_OPERAND_RELATIVE
) != 0);
2501 switch (fixup
->reloc
)
2504 /* These relocation types are only used internally. */
2505 case BFD_RELOC_ALPHA_GPDISP_HI16
:
2506 case BFD_RELOC_ALPHA_GPDISP_LO16
:
2512 /* and these also are internal only relocations */
2513 case BFD_RELOC_ALPHA_USER_LITERAL
:
2514 case BFD_RELOC_ALPHA_USER_LITUSE_BASE
:
2515 case BFD_RELOC_ALPHA_USER_LITUSE_BYTOFF
:
2516 case BFD_RELOC_ALPHA_USER_LITUSE_JSR
:
2517 case BFD_RELOC_ALPHA_USER_GPDISP
:
2518 case BFD_RELOC_ALPHA_USER_GPRELHIGH
:
2519 case BFD_RELOC_ALPHA_USER_GPRELLOW
:
2527 reloc_howto_type
*reloc_howto
2528 = bfd_reloc_type_lookup (stdoutput
, fixup
->reloc
);
2529 assert (reloc_howto
);
2531 size
= bfd_get_reloc_size (reloc_howto
);
2532 pcrel
= reloc_howto
->pc_relative
;
2534 assert (size
>= 1 && size
<= 4);
2538 fixP
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, size
,
2539 &fixup
->exp
, pcrel
, fixup
->reloc
);
2541 /* Turn off complaints that the addend is too large for some fixups,
2542 and copy in the sequence number for the explicit relocations. */
2543 switch (fixup
->reloc
)
2545 case BFD_RELOC_ALPHA_GPDISP_LO16
:
2547 case BFD_RELOC_ALPHA_LITERAL
:
2550 case BFD_RELOC_ALPHA_ELF_LITERAL
:
2552 case BFD_RELOC_GPREL32
:
2553 fixP
->fx_no_overflow
= 1;
2557 case BFD_RELOC_ALPHA_USER_LITERAL
:
2558 fixP
->fx_no_overflow
= 1;
2559 sprintf (buffer
, "!%u", insn
->sequence
[i
]);
2560 info
= ((struct alpha_literal_tag
*)
2561 hash_find (alpha_literal_hash
, buffer
));
2565 size_t len
= strlen (buffer
);
2568 info
= ((struct alpha_literal_tag
*)
2569 xcalloc (sizeof (struct alpha_literal_tag
) + len
, 1));
2571 info
->segment
= now_seg
;
2572 info
->sequence
= insn
->sequence
[i
];
2573 strcpy (info
->string
, buffer
);
2574 errmsg
= hash_insert (alpha_literal_hash
, info
->string
, (PTR
) info
);
2581 if (info
->segment
!= now_seg
)
2582 info
->multi_section_p
= 1;
2584 fixP
->tc_fix_data
.info
= info
;
2587 case BFD_RELOC_ALPHA_USER_LITUSE_BASE
:
2588 case BFD_RELOC_ALPHA_USER_LITUSE_BYTOFF
:
2589 case BFD_RELOC_ALPHA_USER_LITUSE_JSR
:
2590 sprintf (buffer
, "!%u", insn
->sequence
[i
]);
2591 info
= ((struct alpha_literal_tag
*)
2592 hash_find (alpha_literal_hash
, buffer
));
2596 size_t len
= strlen (buffer
);
2599 info
= ((struct alpha_literal_tag
*)
2600 xcalloc (sizeof (struct alpha_literal_tag
) + len
, 1));
2602 info
->segment
= now_seg
;
2603 info
->sequence
= insn
->sequence
[i
];
2604 strcpy (info
->string
, buffer
);
2605 errmsg
= hash_insert (alpha_literal_hash
, info
->string
, (PTR
) info
);
2610 fixP
->tc_fix_data
.info
= info
;
2611 fixP
->tc_fix_data
.next_lituse
= info
->lituse
;
2612 info
->lituse
= fixP
;
2613 if (info
->segment
!= now_seg
)
2614 info
->multi_section_p
= 1;
2620 if ((int) fixup
->reloc
< 0)
2622 if (operand
->flags
& AXP_OPERAND_NOOVERFLOW
)
2623 fixP
->fx_no_overflow
= 1;
2630 /* Given an opcode name and a pre-tokenized set of arguments, assemble
2631 the insn, but do not emit it.
2633 Note that this implies no macros allowed, since we can't store more
2634 than one insn in an insn structure. */
2637 assemble_tokens_to_insn (opname
, tok
, ntok
, insn
)
2639 const expressionS
*tok
;
2641 struct alpha_insn
*insn
;
2643 const struct alpha_opcode
*opcode
;
2645 /* search opcodes */
2646 opcode
= (const struct alpha_opcode
*) hash_find (alpha_opcode_hash
, opname
);
2650 opcode
= find_opcode_match (opcode
, tok
, &ntok
, &cpumatch
);
2653 assemble_insn (opcode
, tok
, ntok
, insn
);
2657 as_bad (_("inappropriate arguments for opcode `%s'"), opname
);
2659 as_bad (_("opcode `%s' not supported for target %s"), opname
,
2663 as_bad (_("unknown opcode `%s'"), opname
);
2666 /* Given an opcode name and a pre-tokenized set of arguments, take the
2667 opcode all the way through emission. */
2670 assemble_tokens (opname
, tok
, ntok
, local_macros_on
)
2672 const expressionS
*tok
;
2674 int local_macros_on
;
2676 int found_something
= 0;
2677 const struct alpha_opcode
*opcode
;
2678 const struct alpha_macro
*macro
;
2682 if (local_macros_on
)
2684 macro
= ((const struct alpha_macro
*)
2685 hash_find (alpha_macro_hash
, opname
));
2688 found_something
= 1;
2689 macro
= find_macro_match (macro
, tok
, &ntok
);
2692 (*macro
->emit
) (tok
, ntok
, macro
->arg
);
2699 if (ntok
&& USER_RELOC_P (tok
[ntok
- 1].X_op
))
2701 const expressionS
*reloc_exp
= &tok
[ntok
- 1];
2702 const struct alpha_reloc_op_tag
*r
= ALPHA_RELOC_TABLE (reloc_exp
->X_op
);
2703 as_bad (_("Cannot use !%s!%d with %s"), r
->name
,
2704 (int) reloc_exp
->X_add_number
, opname
);
2709 /* search opcodes */
2710 opcode
= (const struct alpha_opcode
*) hash_find (alpha_opcode_hash
, opname
);
2713 found_something
= 1;
2714 opcode
= find_opcode_match (opcode
, tok
, &ntok
, &cpumatch
);
2717 struct alpha_insn insn
;
2718 assemble_insn (opcode
, tok
, ntok
, &insn
);
2724 if (found_something
)
2726 as_bad (_("inappropriate arguments for opcode `%s'"), opname
);
2728 as_bad (_("opcode `%s' not supported for target %s"), opname
,
2731 as_bad (_("unknown opcode `%s'"), opname
);
2734 /* Some instruction sets indexed by lg(size) */
2735 static const char * const sextX_op
[] = { "sextb", "sextw", "sextl", NULL
};
2736 static const char * const insXl_op
[] = { "insbl", "inswl", "insll", "insql" };
2737 static const char * const insXh_op
[] = { NULL
, "inswh", "inslh", "insqh" };
2738 static const char * const extXl_op
[] = { "extbl", "extwl", "extll", "extql" };
2739 static const char * const extXh_op
[] = { NULL
, "extwh", "extlh", "extqh" };
2740 static const char * const mskXl_op
[] = { "mskbl", "mskwl", "mskll", "mskql" };
2741 static const char * const mskXh_op
[] = { NULL
, "mskwh", "msklh", "mskqh" };
2742 static const char * const stX_op
[] = { "stb", "stw", "stl", "stq" };
2743 static const char * const ldX_op
[] = { "ldb", "ldw", "ldll", "ldq" };
2744 static const char * const ldXu_op
[] = { "ldbu", "ldwu", NULL
, NULL
};
2746 /* Implement the ldgp macro. */
2749 emit_ldgp (tok
, ntok
, unused
)
2750 const expressionS
*tok
;
2751 int ntok ATTRIBUTE_UNUSED
;
2752 const PTR unused ATTRIBUTE_UNUSED
;
2757 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
2758 /* from "ldgp r1,n(r2)", generate "ldah r1,X(R2); lda r1,Y(r1)"
2759 with appropriate constants and relocations. */
2760 struct alpha_insn insn
;
2761 expressionS newtok
[3];
2765 if (ntok
&& USER_RELOC_P (tok
[ntok
- 1].X_op
))
2767 const expressionS
*reloc_exp
= &tok
[ntok
- 1];
2768 const struct alpha_reloc_op_tag
*r
= ALPHA_RELOC_TABLE (reloc_exp
->X_op
);
2769 as_bad (_("Cannot use !%s!%d with %s"), r
->name
,
2770 (int) reloc_exp
->X_add_number
, "ldgp");
2776 if (regno (tok
[2].X_add_number
) == AXP_REG_PV
)
2777 ecoff_set_gp_prolog_size (0);
2781 set_tok_const (newtok
[1], 0);
2784 assemble_tokens_to_insn ("ldah", newtok
, 3, &insn
);
2789 if (addend
.X_op
!= O_constant
)
2790 as_bad (_("can not resolve expression"));
2791 addend
.X_op
= O_symbol
;
2792 addend
.X_add_symbol
= alpha_gp_symbol
;
2796 insn
.fixups
[0].exp
= addend
;
2797 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_GPDISP_HI16
;
2801 set_tok_preg (newtok
[2], tok
[0].X_add_number
);
2803 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
2806 addend
.X_add_number
+= 4;
2810 insn
.fixups
[0].exp
= addend
;
2811 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_GPDISP_LO16
;
2814 #endif /* OBJ_ECOFF || OBJ_ELF */
2819 /* Add symbol+addend to link pool.
2820 Return offset from basesym to entry in link pool.
2822 Add new fixup only if offset isn't 16bit. */
2825 add_to_link_pool (basesym
, sym
, addend
)
2830 segT current_section
= now_seg
;
2831 int current_subsec
= now_subseg
;
2833 bfd_reloc_code_real_type reloc_type
;
2835 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
2838 offset
= - *symbol_get_obj (basesym
);
2840 /* @@ This assumes all entries in a given section will be of the same
2841 size... Probably correct, but unwise to rely on. */
2842 /* This must always be called with the same subsegment. */
2844 if (seginfo
->frchainP
)
2845 for (fixp
= seginfo
->frchainP
->fix_root
;
2846 fixp
!= (fixS
*) NULL
;
2847 fixp
= fixp
->fx_next
, offset
+= 8)
2849 if (fixp
->fx_addsy
== sym
&& fixp
->fx_offset
== addend
)
2851 if (range_signed_16 (offset
))
2858 /* Not found in 16bit signed range. */
2860 subseg_set (alpha_link_section
, 0);
2864 fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, sym
, addend
, 0,
2867 subseg_set (current_section
, current_subsec
);
2868 seginfo
->literal_pool_size
+= 8;
2872 #endif /* OBJ_EVAX */
2874 /* Load a (partial) expression into a target register.
2876 If poffset is not null, after the call it will either contain
2877 O_constant 0, or a 16-bit offset appropriate for any MEM format
2878 instruction. In addition, pbasereg will be modified to point to
2879 the base register to use in that MEM format instruction.
2881 In any case, *pbasereg should contain a base register to add to the
2882 expression. This will normally be either AXP_REG_ZERO or
2883 alpha_gp_register. Symbol addresses will always be loaded via $gp,
2884 so "foo($0)" is interpreted as adding the address of foo to $0;
2885 i.e. "ldq $targ, LIT($gp); addq $targ, $0, $targ". Odd, perhaps,
2886 but this is what OSF/1 does.
2888 If explicit relocations of the form !literal!<number> are allowed,
2889 and used, then explict_reloc with be an expression pointer.
2891 Finally, the return value is true if the calling macro may emit a
2892 LITUSE reloc if otherwise appropriate. */
2895 load_expression (targreg
, exp
, pbasereg
, poffset
, explicit_reloc
)
2897 const expressionS
*exp
;
2899 expressionS
*poffset
;
2900 const expressionS
*explicit_reloc
;
2902 int emit_lituse
= 0;
2903 offsetT addend
= exp
->X_add_number
;
2904 int basereg
= *pbasereg
;
2905 struct alpha_insn insn
;
2906 expressionS newtok
[3];
2915 /* attempt to reduce .lit load by splitting the offset from
2916 its symbol when possible, but don't create a situation in
2918 if (!range_signed_32 (addend
) &&
2919 (alpha_noat_on
|| targreg
== AXP_REG_AT
))
2921 lit
= add_to_literal_pool (exp
->X_add_symbol
, addend
,
2922 alpha_lita_section
, 8);
2927 lit
= add_to_literal_pool (exp
->X_add_symbol
, 0,
2928 alpha_lita_section
, 8);
2932 as_fatal (_("overflow in literal (.lita) table"));
2934 /* emit "ldq r, lit(gp)" */
2936 if (basereg
!= alpha_gp_register
&& targreg
== basereg
)
2939 as_bad (_("macro requires $at register while noat in effect"));
2940 if (targreg
== AXP_REG_AT
)
2941 as_bad (_("macro requires $at while $at in use"));
2943 set_tok_reg (newtok
[0], AXP_REG_AT
);
2946 set_tok_reg (newtok
[0], targreg
);
2947 set_tok_sym (newtok
[1], alpha_lita_symbol
, lit
);
2948 set_tok_preg (newtok
[2], alpha_gp_register
);
2950 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
2952 assert (explicit_reloc
== (const expressionS
*) 0);
2953 assert (insn
.nfixups
== 1);
2954 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITERAL
;
2955 #endif /* OBJ_ECOFF */
2957 /* emit "ldq r, gotoff(gp)" */
2959 if (basereg
!= alpha_gp_register
&& targreg
== basereg
)
2962 as_bad (_("macro requires $at register while noat in effect"));
2963 if (targreg
== AXP_REG_AT
)
2964 as_bad (_("macro requires $at while $at in use"));
2966 set_tok_reg (newtok
[0], AXP_REG_AT
);
2969 set_tok_reg (newtok
[0], targreg
);
2971 /* XXX: Disable this .got minimizing optimization so that we can get
2972 better instruction offset knowledge in the compiler. This happens
2973 very infrequently anyway. */
2975 || (!range_signed_32 (addend
)
2976 && (alpha_noat_on
|| targreg
== AXP_REG_AT
)))
2983 set_tok_sym (newtok
[1], exp
->X_add_symbol
, 0);
2986 set_tok_preg (newtok
[2], alpha_gp_register
);
2988 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
2990 assert (insn
.nfixups
== 1);
2991 if (!explicit_reloc
)
2992 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_ELF_LITERAL
;
2996 insn
.fixups
[0].reloc
2997 = (ALPHA_RELOC_TABLE (explicit_reloc
->X_op
))->reloc
;
2998 insn
.sequence
[0] = explicit_reloc
->X_add_number
;
3003 #endif /* OBJ_ELF */
3007 /* Find symbol or symbol pointer in link section. */
3009 assert (explicit_reloc
== (const expressionS
*) 0);
3010 if (exp
->X_add_symbol
== alpha_evax_proc
.symbol
)
3012 if (range_signed_16 (addend
))
3014 set_tok_reg (newtok
[0], targreg
);
3015 set_tok_const (newtok
[1], addend
);
3016 set_tok_preg (newtok
[2], basereg
);
3017 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
3022 set_tok_reg (newtok
[0], targreg
);
3023 set_tok_const (newtok
[1], 0);
3024 set_tok_preg (newtok
[2], basereg
);
3025 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
3030 if (!range_signed_32 (addend
))
3032 link
= add_to_link_pool (alpha_evax_proc
.symbol
,
3033 exp
->X_add_symbol
, addend
);
3038 link
= add_to_link_pool (alpha_evax_proc
.symbol
,
3039 exp
->X_add_symbol
, 0);
3041 set_tok_reg (newtok
[0], targreg
);
3042 set_tok_const (newtok
[1], link
);
3043 set_tok_preg (newtok
[2], basereg
);
3044 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
3046 #endif /* OBJ_EVAX */
3053 if (basereg
!= alpha_gp_register
&& basereg
!= AXP_REG_ZERO
)
3055 /* emit "addq r, base, r" */
3057 set_tok_reg (newtok
[1], basereg
);
3058 set_tok_reg (newtok
[2], targreg
);
3059 assemble_tokens ("addq", newtok
, 3, 0);
3068 assert (explicit_reloc
== (const expressionS
*) 0);
3072 /* Assume that this difference expression will be resolved to an
3073 absolute value and that that value will fit in 16 bits. */
3075 assert (explicit_reloc
== (const expressionS
*) 0);
3076 set_tok_reg (newtok
[0], targreg
);
3078 set_tok_preg (newtok
[2], basereg
);
3079 assemble_tokens ("lda", newtok
, 3, 0);
3082 set_tok_const (*poffset
, 0);
3086 if (exp
->X_add_number
> 0)
3087 as_bad (_("bignum invalid; zero assumed"));
3089 as_bad (_("floating point number invalid; zero assumed"));
3094 as_bad (_("can't handle expression"));
3099 if (!range_signed_32 (addend
))
3103 /* for 64-bit addends, just put it in the literal pool */
3106 /* emit "ldq targreg, lit(basereg)" */
3107 lit
= add_to_link_pool (alpha_evax_proc
.symbol
,
3108 section_symbol (absolute_section
), addend
);
3109 set_tok_reg (newtok
[0], targreg
);
3110 set_tok_const (newtok
[1], lit
);
3111 set_tok_preg (newtok
[2], alpha_gp_register
);
3112 assemble_tokens ("ldq", newtok
, 3, 0);
3115 if (alpha_lit8_section
== NULL
)
3117 create_literal_section (".lit8",
3118 &alpha_lit8_section
,
3119 &alpha_lit8_symbol
);
3122 alpha_lit8_literal
= add_to_literal_pool (alpha_lit8_symbol
, 0x8000,
3123 alpha_lita_section
, 8);
3124 if (alpha_lit8_literal
>= 0x8000)
3125 as_fatal (_("overflow in literal (.lita) table"));
3129 lit
= add_to_literal_pool (NULL
, addend
, alpha_lit8_section
, 8) - 0x8000;
3131 as_fatal (_("overflow in literal (.lit8) table"));
3133 /* emit "lda litreg, .lit8+0x8000" */
3135 if (targreg
== basereg
)
3138 as_bad (_("macro requires $at register while noat in effect"));
3139 if (targreg
== AXP_REG_AT
)
3140 as_bad (_("macro requires $at while $at in use"));
3142 set_tok_reg (newtok
[0], AXP_REG_AT
);
3145 set_tok_reg (newtok
[0], targreg
);
3147 set_tok_sym (newtok
[1], alpha_lita_symbol
, alpha_lit8_literal
);
3150 set_tok_sym (newtok
[1], alpha_lit8_symbol
, 0x8000);
3152 set_tok_preg (newtok
[2], alpha_gp_register
);
3154 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
3156 assert (insn
.nfixups
== 1);
3158 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITERAL
;
3161 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_ELF_LITERAL
;
3166 /* emit "ldq litreg, lit(litreg)" */
3168 set_tok_const (newtok
[1], lit
);
3169 set_tok_preg (newtok
[2], newtok
[0].X_add_number
);
3171 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
3173 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3174 if (insn
.nfixups
> 0)
3176 memmove (&insn
.fixups
[1], &insn
.fixups
[0],
3177 sizeof (struct alpha_fixup
) * insn
.nfixups
);
3180 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITUSE
;
3181 insn
.fixups
[0].exp
.X_op
= O_symbol
;
3182 insn
.fixups
[0].exp
.X_add_symbol
= section_symbol (now_seg
);
3183 insn
.fixups
[0].exp
.X_add_number
= LITUSE_BASE
;
3188 /* emit "addq litreg, base, target" */
3190 if (basereg
!= AXP_REG_ZERO
)
3192 set_tok_reg (newtok
[1], basereg
);
3193 set_tok_reg (newtok
[2], targreg
);
3194 assemble_tokens ("addq", newtok
, 3, 0);
3196 #endif /* !OBJ_EVAX */
3199 set_tok_const (*poffset
, 0);
3200 *pbasereg
= targreg
;
3204 offsetT low
, high
, extra
, tmp
;
3206 /* for 32-bit operands, break up the addend */
3208 low
= sign_extend_16 (addend
);
3210 high
= sign_extend_16 (tmp
>> 16);
3212 if (tmp
- (high
<< 16))
3216 high
= sign_extend_16 (tmp
>> 16);
3221 set_tok_reg (newtok
[0], targreg
);
3222 set_tok_preg (newtok
[2], basereg
);
3226 /* emit "ldah r, extra(r) */
3227 set_tok_const (newtok
[1], extra
);
3228 assemble_tokens ("ldah", newtok
, 3, 0);
3229 set_tok_preg (newtok
[2], basereg
= targreg
);
3234 /* emit "ldah r, high(r) */
3235 set_tok_const (newtok
[1], high
);
3236 assemble_tokens ("ldah", newtok
, 3, 0);
3238 set_tok_preg (newtok
[2], basereg
);
3241 if ((low
&& !poffset
) || (!poffset
&& basereg
!= targreg
))
3243 /* emit "lda r, low(base)" */
3244 set_tok_const (newtok
[1], low
);
3245 assemble_tokens ("lda", newtok
, 3, 0);
3251 set_tok_const (*poffset
, low
);
3252 *pbasereg
= basereg
;
3258 /* The lda macro differs from the lda instruction in that it handles
3259 most simple expressions, particualrly symbol address loads and
3263 emit_lda (tok
, ntok
, opname
)
3264 const expressionS
*tok
;
3269 const expressionS
*reloc
= (const expressionS
*) 0;
3272 if (ntok
&& USER_RELOC_P (tok
[ntok
- 1].X_op
))
3274 const struct alpha_reloc_op_tag
*r
;
3276 reloc
= &tok
[ntok
- 1];
3277 r
= ALPHA_RELOC_TABLE (reloc
->X_op
);
3278 switch (reloc
->X_op
)
3281 as_bad (_("Cannot use !%s!%d with %s"), r
->name
,
3282 (int) reloc
->X_add_number
, (const char *) opname
);
3284 reloc
= (const expressionS
*) 0;
3292 /* For lda $x,0($x)!lituse_base!y, don't use load_expression, since
3293 it is really too general for our needs. Instead just generate the
3297 || tok
[0].X_op
!= O_register
3298 || !is_ir_num (tok
[0].X_add_number
)
3299 || tok
[1].X_op
!= O_constant
3300 || tok
[2].X_op
!= O_pregister
3301 || !is_ir_num (tok
[2].X_add_number
))
3303 as_bad (_("bad instruction format for lda !%s!%ld"), r
->name
,
3304 (long) reloc
->X_add_number
);
3306 reloc
= (const expressionS
*) 0;
3311 emit_loadstore (tok
, ntok
, "lda");
3318 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
3320 basereg
= tok
[2].X_add_number
;
3322 (void) load_expression (tok
[0].X_add_number
, &tok
[1], &basereg
, NULL
, reloc
);
3325 /* The ldah macro differs from the ldah instruction in that it has $31
3326 as an implied base register. */
3329 emit_ldah (tok
, ntok
, unused
)
3330 const expressionS
*tok
;
3331 int ntok ATTRIBUTE_UNUSED
;
3332 const PTR unused ATTRIBUTE_UNUSED
;
3334 expressionS newtok
[3];
3337 if (ntok
&& USER_RELOC_P (tok
[ntok
- 1].X_op
))
3339 const expressionS
*reloc_exp
= &tok
[ntok
- 1];
3340 const struct alpha_reloc_op_tag
*r
= ALPHA_RELOC_TABLE (reloc_exp
->X_op
);
3341 as_bad (_("Cannot use !%s!%d with %s"), r
->name
,
3342 (int) reloc_exp
->X_add_number
, "ldah");
3349 set_tok_preg (newtok
[2], AXP_REG_ZERO
);
3351 assemble_tokens ("ldah", newtok
, 3, 0);
3354 /* Handle all "simple" integer register loads -- ldq, ldq_l, ldq_u,
3355 etc. They differ from the real instructions in that they do simple
3356 expressions like the lda macro. */
3359 emit_ir_load (tok
, ntok
, opname
)
3360 const expressionS
*tok
;
3364 int basereg
, lituse
;
3365 expressionS newtok
[3];
3366 struct alpha_insn insn
;
3369 const expressionS
*reloc
= (const expressionS
*) 0;
3371 if (ntok
&& USER_RELOC_P (tok
[ntok
- 1].X_op
))
3373 const struct alpha_reloc_op_tag
*r
;
3375 reloc
= &tok
[ntok
- 1];
3376 switch (reloc
->X_op
)
3383 if (strcmp ((const char *) opname
, "ldq") == 0)
3385 emit_lda (tok
, ntok
, opname
);
3392 r
= ALPHA_RELOC_TABLE (reloc
->X_op
);
3393 as_bad (_("Cannot use !%s!%d with %s"), r
->name
,
3394 (int) reloc
->X_add_number
, (const char *) opname
);
3400 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
3402 basereg
= tok
[2].X_add_number
;
3404 lituse
= load_expression (tok
[0].X_add_number
, &tok
[1], &basereg
,
3405 &newtok
[1], (const expressionS
*) 0);
3408 set_tok_preg (newtok
[2], basereg
);
3410 assemble_tokens_to_insn ((const char *) opname
, newtok
, 3, &insn
);
3415 int nfixups
= insn
.nfixups
;
3416 const struct alpha_reloc_op_tag
*r
= ALPHA_RELOC_TABLE (reloc
->X_op
);
3418 assert (nfixups
< MAX_INSN_FIXUPS
);
3419 insn
.fixups
[nfixups
].reloc
= r
->reloc
;
3420 insn
.fixups
[nfixups
].exp
.X_op
= O_symbol
;
3421 insn
.fixups
[nfixups
].exp
.X_add_symbol
= section_symbol (now_seg
);
3422 insn
.fixups
[nfixups
].exp
.X_add_number
= r
->lituse
;
3423 insn
.sequence
[nfixups
] = reloc
->X_add_number
;
3430 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3431 if (insn
.nfixups
> 0)
3433 memmove (&insn
.fixups
[1], &insn
.fixups
[0],
3434 sizeof (struct alpha_fixup
) * insn
.nfixups
);
3437 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITUSE
;
3438 insn
.fixups
[0].exp
.X_op
= O_symbol
;
3439 insn
.fixups
[0].exp
.X_add_symbol
= section_symbol (now_seg
);
3440 insn
.fixups
[0].exp
.X_add_number
= LITUSE_BASE
;
3446 /* Handle fp register loads, and both integer and fp register stores.
3447 Again, we handle simple expressions. */
3450 emit_loadstore (tok
, ntok
, opname
)
3451 const expressionS
*tok
;
3455 int basereg
, lituse
;
3456 expressionS newtok
[3];
3457 struct alpha_insn insn
;
3460 const expressionS
*reloc
= (const expressionS
*) 0;
3462 if (ntok
&& USER_RELOC_P (tok
[ntok
- 1].X_op
))
3464 reloc
= &tok
[--ntok
];
3465 if (reloc
->X_op
!= O_lituse_base
)
3467 const struct alpha_reloc_op_tag
*r
= &alpha_reloc_op
[reloc
->X_md
];
3468 as_bad (_("Cannot use !%s!%d with %s"), r
->name
,
3469 (int) reloc
->X_add_number
, (const char *) opname
);
3475 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
3477 basereg
= tok
[2].X_add_number
;
3479 if (tok
[1].X_op
!= O_constant
|| !range_signed_16 (tok
[1].X_add_number
))
3482 as_bad (_("macro requires $at register while noat in effect"));
3484 lituse
= load_expression (AXP_REG_AT
, &tok
[1], &basereg
, &newtok
[1],
3485 (const expressionS
*) 0);
3494 set_tok_preg (newtok
[2], basereg
);
3496 assemble_tokens_to_insn ((const char *) opname
, newtok
, 3, &insn
);
3501 int nfixups
= insn
.nfixups
;
3502 const struct alpha_reloc_op_tag
*r
= ALPHA_RELOC_TABLE (reloc
->X_op
);
3504 assert (nfixups
< MAX_INSN_FIXUPS
);
3505 insn
.fixups
[nfixups
].reloc
= r
->reloc
;
3506 insn
.fixups
[nfixups
].exp
.X_op
= O_symbol
;
3507 insn
.fixups
[nfixups
].exp
.X_add_symbol
= section_symbol (now_seg
);
3508 insn
.fixups
[nfixups
].exp
.X_add_number
= r
->lituse
;
3509 insn
.sequence
[nfixups
] = reloc
->X_add_number
;
3516 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3517 if (insn
.nfixups
> 0)
3519 memmove (&insn
.fixups
[1], &insn
.fixups
[0],
3520 sizeof (struct alpha_fixup
) * insn
.nfixups
);
3523 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITUSE
;
3524 insn
.fixups
[0].exp
.X_op
= O_symbol
;
3525 insn
.fixups
[0].exp
.X_add_symbol
= section_symbol (now_seg
);
3526 insn
.fixups
[0].exp
.X_add_number
= LITUSE_BASE
;
3532 /* Load a half-word or byte as an unsigned value. */
3535 emit_ldXu (tok
, ntok
, vlgsize
)
3536 const expressionS
*tok
;
3540 if (alpha_target
& AXP_OPCODE_BWX
)
3541 emit_ir_load (tok
, ntok
, ldXu_op
[(long) vlgsize
]);
3544 expressionS newtok
[3];
3547 if (ntok
&& USER_RELOC_P (tok
[ntok
- 1].X_op
))
3549 const expressionS
*reloc_exp
= &tok
[ntok
- 1];
3550 const struct alpha_reloc_op_tag
*r
3551 = ALPHA_RELOC_TABLE (reloc_exp
->X_op
);
3553 as_bad (_("Cannot use !%s!%d with %s"), r
->name
,
3554 (int) reloc_exp
->X_add_number
, "ldbu/ldwu");
3560 as_bad (_("macro requires $at register while noat in effect"));
3562 /* emit "lda $at, exp" */
3564 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
3565 newtok
[0].X_add_number
= AXP_REG_AT
;
3566 assemble_tokens ("lda", newtok
, ntok
, 1);
3568 /* emit "ldq_u targ, 0($at)" */
3571 set_tok_const (newtok
[1], 0);
3572 set_tok_preg (newtok
[2], AXP_REG_AT
);
3573 assemble_tokens ("ldq_u", newtok
, 3, 1);
3575 /* emit "extXl targ, $at, targ" */
3577 set_tok_reg (newtok
[1], AXP_REG_AT
);
3578 newtok
[2] = newtok
[0];
3579 assemble_tokens (extXl_op
[(long) vlgsize
], newtok
, 3, 1);
3583 /* Load a half-word or byte as a signed value. */
3586 emit_ldX (tok
, ntok
, vlgsize
)
3587 const expressionS
*tok
;
3591 emit_ldXu (tok
, ntok
, vlgsize
);
3592 assemble_tokens (sextX_op
[(long) vlgsize
], tok
, 1, 1);
3595 /* Load an integral value from an unaligned address as an unsigned
3599 emit_uldXu (tok
, ntok
, vlgsize
)
3600 const expressionS
*tok
;
3604 long lgsize
= (long) vlgsize
;
3605 expressionS newtok
[3];
3608 as_bad (_("macro requires $at register while noat in effect"));
3610 /* emit "lda $at, exp" */
3612 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
3613 newtok
[0].X_add_number
= AXP_REG_AT
;
3614 assemble_tokens ("lda", newtok
, ntok
, 1);
3616 /* emit "ldq_u $t9, 0($at)" */
3618 set_tok_reg (newtok
[0], AXP_REG_T9
);
3619 set_tok_const (newtok
[1], 0);
3620 set_tok_preg (newtok
[2], AXP_REG_AT
);
3621 assemble_tokens ("ldq_u", newtok
, 3, 1);
3623 /* emit "ldq_u $t10, size-1($at)" */
3625 set_tok_reg (newtok
[0], AXP_REG_T10
);
3626 set_tok_const (newtok
[1], (1 << lgsize
) - 1);
3627 assemble_tokens ("ldq_u", newtok
, 3, 1);
3629 /* emit "extXl $t9, $at, $t9" */
3631 set_tok_reg (newtok
[0], AXP_REG_T9
);
3632 set_tok_reg (newtok
[1], AXP_REG_AT
);
3633 set_tok_reg (newtok
[2], AXP_REG_T9
);
3634 assemble_tokens (extXl_op
[lgsize
], newtok
, 3, 1);
3636 /* emit "extXh $t10, $at, $t10" */
3638 set_tok_reg (newtok
[0], AXP_REG_T10
);
3639 set_tok_reg (newtok
[2], AXP_REG_T10
);
3640 assemble_tokens (extXh_op
[lgsize
], newtok
, 3, 1);
3642 /* emit "or $t9, $t10, targ" */
3644 set_tok_reg (newtok
[0], AXP_REG_T9
);
3645 set_tok_reg (newtok
[1], AXP_REG_T10
);
3647 assemble_tokens ("or", newtok
, 3, 1);
3650 /* Load an integral value from an unaligned address as a signed value.
3651 Note that quads should get funneled to the unsigned load since we
3652 don't have to do the sign extension. */
3655 emit_uldX (tok
, ntok
, vlgsize
)
3656 const expressionS
*tok
;
3660 emit_uldXu (tok
, ntok
, vlgsize
);
3661 assemble_tokens (sextX_op
[(long) vlgsize
], tok
, 1, 1);
3664 /* Implement the ldil macro. */
3667 emit_ldil (tok
, ntok
, unused
)
3668 const expressionS
*tok
;
3670 const PTR unused ATTRIBUTE_UNUSED
;
3672 expressionS newtok
[2];
3675 if (ntok
&& USER_RELOC_P (tok
[ntok
- 1].X_op
))
3677 const expressionS
*reloc_exp
= &tok
[ntok
- 1];
3678 const struct alpha_reloc_op_tag
*r
= ALPHA_RELOC_TABLE (reloc_exp
->X_op
);
3679 as_bad (_("Cannot use !%s!%d with %s"), r
->name
,
3680 (int) reloc_exp
->X_add_number
, "ldil");
3685 memcpy (newtok
, tok
, sizeof (newtok
));
3686 newtok
[1].X_add_number
= sign_extend_32 (tok
[1].X_add_number
);
3688 assemble_tokens ("lda", newtok
, ntok
, 1);
3691 /* Store a half-word or byte. */
3694 emit_stX (tok
, ntok
, vlgsize
)
3695 const expressionS
*tok
;
3699 int lgsize
= (int) (long) vlgsize
;
3701 if (alpha_target
& AXP_OPCODE_BWX
)
3702 emit_loadstore (tok
, ntok
, stX_op
[lgsize
]);
3705 expressionS newtok
[3];
3708 as_bad (_("macro requires $at register while noat in effect"));
3710 /* emit "lda $at, exp" */
3712 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
3713 newtok
[0].X_add_number
= AXP_REG_AT
;
3714 assemble_tokens ("lda", newtok
, ntok
, 1);
3716 /* emit "ldq_u $t9, 0($at)" */
3718 set_tok_reg (newtok
[0], AXP_REG_T9
);
3719 set_tok_const (newtok
[1], 0);
3720 set_tok_preg (newtok
[2], AXP_REG_AT
);
3721 assemble_tokens ("ldq_u", newtok
, 3, 1);
3723 /* emit "insXl src, $at, $t10" */
3726 set_tok_reg (newtok
[1], AXP_REG_AT
);
3727 set_tok_reg (newtok
[2], AXP_REG_T10
);
3728 assemble_tokens (insXl_op
[lgsize
], newtok
, 3, 1);
3730 /* emit "mskXl $t9, $at, $t9" */
3732 set_tok_reg (newtok
[0], AXP_REG_T9
);
3733 newtok
[2] = newtok
[0];
3734 assemble_tokens (mskXl_op
[lgsize
], newtok
, 3, 1);
3736 /* emit "or $t9, $t10, $t9" */
3738 set_tok_reg (newtok
[1], AXP_REG_T10
);
3739 assemble_tokens ("or", newtok
, 3, 1);
3741 /* emit "stq_u $t9, 0($at) */
3743 set_tok_const (newtok
[1], 0);
3744 set_tok_preg (newtok
[2], AXP_REG_AT
);
3745 assemble_tokens ("stq_u", newtok
, 3, 1);
3749 /* Store an integer to an unaligned address. */
3752 emit_ustX (tok
, ntok
, vlgsize
)
3753 const expressionS
*tok
;
3757 int lgsize
= (int) (long) vlgsize
;
3758 expressionS newtok
[3];
3760 /* emit "lda $at, exp" */
3762 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
3763 newtok
[0].X_add_number
= AXP_REG_AT
;
3764 assemble_tokens ("lda", newtok
, ntok
, 1);
3766 /* emit "ldq_u $9, 0($at)" */
3768 set_tok_reg (newtok
[0], AXP_REG_T9
);
3769 set_tok_const (newtok
[1], 0);
3770 set_tok_preg (newtok
[2], AXP_REG_AT
);
3771 assemble_tokens ("ldq_u", newtok
, 3, 1);
3773 /* emit "ldq_u $10, size-1($at)" */
3775 set_tok_reg (newtok
[0], AXP_REG_T10
);
3776 set_tok_const (newtok
[1], (1 << lgsize
) - 1);
3777 assemble_tokens ("ldq_u", newtok
, 3, 1);
3779 /* emit "insXl src, $at, $t11" */
3782 set_tok_reg (newtok
[1], AXP_REG_AT
);
3783 set_tok_reg (newtok
[2], AXP_REG_T11
);
3784 assemble_tokens (insXl_op
[lgsize
], newtok
, 3, 1);
3786 /* emit "insXh src, $at, $t12" */
3788 set_tok_reg (newtok
[2], AXP_REG_T12
);
3789 assemble_tokens (insXh_op
[lgsize
], newtok
, 3, 1);
3791 /* emit "mskXl $t9, $at, $t9" */
3793 set_tok_reg (newtok
[0], AXP_REG_T9
);
3794 newtok
[2] = newtok
[0];
3795 assemble_tokens (mskXl_op
[lgsize
], newtok
, 3, 1);
3797 /* emit "mskXh $t10, $at, $t10" */
3799 set_tok_reg (newtok
[0], AXP_REG_T10
);
3800 newtok
[2] = newtok
[0];
3801 assemble_tokens (mskXh_op
[lgsize
], newtok
, 3, 1);
3803 /* emit "or $t9, $t11, $t9" */
3805 set_tok_reg (newtok
[0], AXP_REG_T9
);
3806 set_tok_reg (newtok
[1], AXP_REG_T11
);
3807 newtok
[2] = newtok
[0];
3808 assemble_tokens ("or", newtok
, 3, 1);
3810 /* emit "or $t10, $t12, $t10" */
3812 set_tok_reg (newtok
[0], AXP_REG_T10
);
3813 set_tok_reg (newtok
[1], AXP_REG_T12
);
3814 newtok
[2] = newtok
[0];
3815 assemble_tokens ("or", newtok
, 3, 1);
3817 /* emit "stq_u $t9, 0($at)" */
3819 set_tok_reg (newtok
[0], AXP_REG_T9
);
3820 set_tok_const (newtok
[1], 0);
3821 set_tok_preg (newtok
[2], AXP_REG_AT
);
3822 assemble_tokens ("stq_u", newtok
, 3, 1);
3824 /* emit "stq_u $t10, size-1($at)" */
3826 set_tok_reg (newtok
[0], AXP_REG_T10
);
3827 set_tok_const (newtok
[1], (1 << lgsize
) - 1);
3828 assemble_tokens ("stq_u", newtok
, 3, 1);
3831 /* Sign extend a half-word or byte. The 32-bit sign extend is
3832 implemented as "addl $31, $r, $t" in the opcode table. */
3835 emit_sextX (tok
, ntok
, vlgsize
)
3836 const expressionS
*tok
;
3840 long lgsize
= (long) vlgsize
;
3842 if (alpha_target
& AXP_OPCODE_BWX
)
3843 assemble_tokens (sextX_op
[lgsize
], tok
, ntok
, 0);
3846 int bitshift
= 64 - 8 * (1 << lgsize
);
3847 expressionS newtok
[3];
3850 if (ntok
&& USER_RELOC_P (tok
[ntok
- 1].X_op
))
3852 const expressionS
*reloc_exp
= &tok
[ntok
- 1];
3853 const struct alpha_reloc_op_tag
*r
3854 = ALPHA_RELOC_TABLE (reloc_exp
->X_op
);
3856 as_bad (_("Cannot use !%s!%d with %s"), r
->name
,
3857 (int) reloc_exp
->X_add_number
, "setxt");
3862 /* emit "sll src,bits,dst" */
3865 set_tok_const (newtok
[1], bitshift
);
3866 newtok
[2] = tok
[ntok
- 1];
3867 assemble_tokens ("sll", newtok
, 3, 1);
3869 /* emit "sra dst,bits,dst" */
3871 newtok
[0] = newtok
[2];
3872 assemble_tokens ("sra", newtok
, 3, 1);
3876 /* Implement the division and modulus macros. */
3880 /* Make register usage like in normal procedure call.
3881 Don't clobber PV and RA. */
3884 emit_division (tok
, ntok
, symname
)
3885 const expressionS
*tok
;
3889 /* DIVISION and MODULUS. Yech.
3894 * mov x,R16 # if x != R16
3895 * mov y,R17 # if y != R17
3900 * with appropriate optimizations if R0,R16,R17 are the registers
3901 * specified by the compiler.
3906 expressionS newtok
[3];
3909 if (ntok
&& USER_RELOC_P (tok
[ntok
- 1].X_op
))
3911 const expressionS
*reloc_exp
= &tok
[ntok
- 1];
3912 const struct alpha_reloc_op_tag
*r
= ALPHA_RELOC_TABLE (reloc_exp
->X_op
);
3913 as_bad (_("Cannot use !%s!%d with %s"), r
->name
,
3914 (int) reloc_exp
->X_add_number
, (char char *) symname
);
3919 xr
= regno (tok
[0].X_add_number
);
3920 yr
= regno (tok
[1].X_add_number
);
3925 rr
= regno (tok
[2].X_add_number
);
3927 /* Move the operands into the right place */
3928 if (yr
== AXP_REG_R16
&& xr
== AXP_REG_R17
)
3930 /* They are in exactly the wrong order -- swap through AT */
3933 as_bad (_("macro requires $at register while noat in effect"));
3935 set_tok_reg (newtok
[0], AXP_REG_R16
);
3936 set_tok_reg (newtok
[1], AXP_REG_AT
);
3937 assemble_tokens ("mov", newtok
, 2, 1);
3939 set_tok_reg (newtok
[0], AXP_REG_R17
);
3940 set_tok_reg (newtok
[1], AXP_REG_R16
);
3941 assemble_tokens ("mov", newtok
, 2, 1);
3943 set_tok_reg (newtok
[0], AXP_REG_AT
);
3944 set_tok_reg (newtok
[1], AXP_REG_R17
);
3945 assemble_tokens ("mov", newtok
, 2, 1);
3949 if (yr
== AXP_REG_R16
)
3951 set_tok_reg (newtok
[0], AXP_REG_R16
);
3952 set_tok_reg (newtok
[1], AXP_REG_R17
);
3953 assemble_tokens ("mov", newtok
, 2, 1);
3956 if (xr
!= AXP_REG_R16
)
3958 set_tok_reg (newtok
[0], xr
);
3959 set_tok_reg (newtok
[1], AXP_REG_R16
);
3960 assemble_tokens ("mov", newtok
, 2, 1);
3963 if (yr
!= AXP_REG_R16
&& yr
!= AXP_REG_R17
)
3965 set_tok_reg (newtok
[0], yr
);
3966 set_tok_reg (newtok
[1], AXP_REG_R17
);
3967 assemble_tokens ("mov", newtok
, 2, 1);
3971 sym
= symbol_find_or_make ((const char *) symname
);
3973 set_tok_reg (newtok
[0], AXP_REG_AT
);
3974 set_tok_sym (newtok
[1], sym
, 0);
3975 assemble_tokens ("lda", newtok
, 2, 1);
3977 /* Call the division routine */
3978 set_tok_reg (newtok
[0], AXP_REG_AT
);
3979 set_tok_cpreg (newtok
[1], AXP_REG_AT
);
3980 set_tok_const (newtok
[2], 0);
3981 assemble_tokens ("jsr", newtok
, 3, 1);
3983 /* Move the result to the right place */
3984 if (rr
!= AXP_REG_R0
)
3986 set_tok_reg (newtok
[0], AXP_REG_R0
);
3987 set_tok_reg (newtok
[1], rr
);
3988 assemble_tokens ("mov", newtok
, 2, 1);
3992 #else /* !OBJ_EVAX */
3995 emit_division (tok
, ntok
, symname
)
3996 const expressionS
*tok
;
4000 /* DIVISION and MODULUS. Yech.
4010 * with appropriate optimizations if t10,t11,t12 are the registers
4011 * specified by the compiler.
4016 expressionS newtok
[3];
4019 if (ntok
&& USER_RELOC_P (tok
[ntok
- 1].X_op
))
4021 const expressionS
*reloc_exp
= &tok
[ntok
- 1];
4022 const struct alpha_reloc_op_tag
*r
= ALPHA_RELOC_TABLE (reloc_exp
->X_op
);
4023 as_bad (_("Cannot use !%s!%d with %s"), r
->name
,
4024 (int) reloc_exp
->X_add_number
, (const char *) symname
);
4029 xr
= regno (tok
[0].X_add_number
);
4030 yr
= regno (tok
[1].X_add_number
);
4035 rr
= regno (tok
[2].X_add_number
);
4037 sym
= symbol_find_or_make ((const char *) symname
);
4039 /* Move the operands into the right place */
4040 if (yr
== AXP_REG_T10
&& xr
== AXP_REG_T11
)
4042 /* They are in exactly the wrong order -- swap through AT */
4045 as_bad (_("macro requires $at register while noat in effect"));
4047 set_tok_reg (newtok
[0], AXP_REG_T10
);
4048 set_tok_reg (newtok
[1], AXP_REG_AT
);
4049 assemble_tokens ("mov", newtok
, 2, 1);
4051 set_tok_reg (newtok
[0], AXP_REG_T11
);
4052 set_tok_reg (newtok
[1], AXP_REG_T10
);
4053 assemble_tokens ("mov", newtok
, 2, 1);
4055 set_tok_reg (newtok
[0], AXP_REG_AT
);
4056 set_tok_reg (newtok
[1], AXP_REG_T11
);
4057 assemble_tokens ("mov", newtok
, 2, 1);
4061 if (yr
== AXP_REG_T10
)
4063 set_tok_reg (newtok
[0], AXP_REG_T10
);
4064 set_tok_reg (newtok
[1], AXP_REG_T11
);
4065 assemble_tokens ("mov", newtok
, 2, 1);
4068 if (xr
!= AXP_REG_T10
)
4070 set_tok_reg (newtok
[0], xr
);
4071 set_tok_reg (newtok
[1], AXP_REG_T10
);
4072 assemble_tokens ("mov", newtok
, 2, 1);
4075 if (yr
!= AXP_REG_T10
&& yr
!= AXP_REG_T11
)
4077 set_tok_reg (newtok
[0], yr
);
4078 set_tok_reg (newtok
[1], AXP_REG_T11
);
4079 assemble_tokens ("mov", newtok
, 2, 1);
4083 /* Call the division routine */
4084 set_tok_reg (newtok
[0], AXP_REG_T9
);
4085 set_tok_sym (newtok
[1], sym
, 0);
4086 assemble_tokens ("jsr", newtok
, 2, 1);
4088 /* Reload the GP register */
4092 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
4093 set_tok_reg (newtok
[0], alpha_gp_register
);
4094 set_tok_const (newtok
[1], 0);
4095 set_tok_preg (newtok
[2], AXP_REG_T9
);
4096 assemble_tokens ("ldgp", newtok
, 3, 1);
4099 /* Move the result to the right place */
4100 if (rr
!= AXP_REG_T12
)
4102 set_tok_reg (newtok
[0], AXP_REG_T12
);
4103 set_tok_reg (newtok
[1], rr
);
4104 assemble_tokens ("mov", newtok
, 2, 1);
4108 #endif /* !OBJ_EVAX */
4110 /* The jsr and jmp macros differ from their instruction counterparts
4111 in that they can load the target address and default most
4115 emit_jsrjmp (tok
, ntok
, vopname
)
4116 const expressionS
*tok
;
4120 const char *opname
= (const char *) vopname
;
4121 struct alpha_insn insn
;
4122 expressionS newtok
[3];
4123 int r
, tokidx
= 0, lituse
= 0;
4126 if (ntok
&& USER_RELOC_P (tok
[ntok
- 1].X_op
))
4128 const expressionS
*reloc_exp
= &tok
[ntok
- 1];
4129 const struct alpha_reloc_op_tag
*r
= ALPHA_RELOC_TABLE (reloc_exp
->X_op
);
4130 as_bad (_("Cannot use !%s!%d with %s"), r
->name
,
4131 (int) reloc_exp
->X_add_number
, opname
);
4136 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_register
)
4137 r
= regno (tok
[tokidx
++].X_add_number
);
4139 r
= strcmp (opname
, "jmp") == 0 ? AXP_REG_ZERO
: AXP_REG_RA
;
4141 set_tok_reg (newtok
[0], r
);
4143 if (tokidx
< ntok
&&
4144 (tok
[tokidx
].X_op
== O_pregister
|| tok
[tokidx
].X_op
== O_cpregister
))
4145 r
= regno (tok
[tokidx
++].X_add_number
);
4147 /* keep register if jsr $n.<sym> */
4151 int basereg
= alpha_gp_register
;
4152 lituse
= load_expression (r
= AXP_REG_PV
, &tok
[tokidx
], &basereg
, NULL
,
4153 (const expressionS
*) 0);
4157 set_tok_cpreg (newtok
[1], r
);
4160 /* FIXME: Add hint relocs to BFD for evax. */
4163 newtok
[2] = tok
[tokidx
];
4166 set_tok_const (newtok
[2], 0);
4168 assemble_tokens_to_insn (opname
, newtok
, 3, &insn
);
4170 /* add the LITUSE fixup */
4173 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
4174 if (insn
.nfixups
> 0)
4176 memmove (&insn
.fixups
[1], &insn
.fixups
[0],
4177 sizeof (struct alpha_fixup
) * insn
.nfixups
);
4180 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITUSE
;
4181 insn
.fixups
[0].exp
.X_op
= O_symbol
;
4182 insn
.fixups
[0].exp
.X_add_symbol
= section_symbol (now_seg
);
4183 insn
.fixups
[0].exp
.X_add_number
= LITUSE_JSR
;
4189 /* The ret and jcr instructions differ from their instruction
4190 counterparts in that everything can be defaulted. */
4193 emit_retjcr (tok
, ntok
, vopname
)
4194 const expressionS
*tok
;
4198 const char *opname
= (const char *) vopname
;
4199 expressionS newtok
[3];
4203 if (ntok
&& USER_RELOC_P (tok
[ntok
- 1].X_op
))
4205 const expressionS
*reloc_exp
= &tok
[ntok
- 1];
4206 const struct alpha_reloc_op_tag
*r
= ALPHA_RELOC_TABLE (reloc_exp
->X_op
);
4207 as_bad (_("Cannot use !%s!%d with %s"), r
->name
,
4208 (int) reloc_exp
->X_add_number
, opname
);
4213 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_register
)
4214 r
= regno (tok
[tokidx
++].X_add_number
);
4218 set_tok_reg (newtok
[0], r
);
4220 if (tokidx
< ntok
&&
4221 (tok
[tokidx
].X_op
== O_pregister
|| tok
[tokidx
].X_op
== O_cpregister
))
4222 r
= regno (tok
[tokidx
++].X_add_number
);
4226 set_tok_cpreg (newtok
[1], r
);
4229 newtok
[2] = tok
[tokidx
];
4231 set_tok_const (newtok
[2], strcmp (opname
, "ret") == 0);
4233 assemble_tokens (opname
, newtok
, 3, 0);
4236 /* Assembler directives */
4238 /* Handle the .text pseudo-op. This is like the usual one, but it
4239 clears alpha_insn_label and restores auto alignment. */
4247 alpha_insn_label
= NULL
;
4248 alpha_auto_align_on
= 1;
4249 alpha_current_align
= 0;
4252 /* Handle the .data pseudo-op. This is like the usual one, but it
4253 clears alpha_insn_label and restores auto alignment. */
4260 alpha_insn_label
= NULL
;
4261 alpha_auto_align_on
= 1;
4262 alpha_current_align
= 0;
4265 #if defined (OBJ_ECOFF) || defined (OBJ_EVAX)
4267 /* Handle the OSF/1 and openVMS .comm pseudo quirks.
4268 openVMS constructs a section for every common symbol. */
4271 s_alpha_comm (ignore
)
4274 register char *name
;
4278 register symbolS
*symbolP
;
4281 segT current_section
= now_seg
;
4282 int current_subsec
= now_subseg
;
4286 name
= input_line_pointer
;
4287 c
= get_symbol_end ();
4289 /* just after name is now '\0' */
4290 p
= input_line_pointer
;
4295 /* Alpha OSF/1 compiler doesn't provide the comma, gcc does. */
4296 if (*input_line_pointer
== ',')
4298 input_line_pointer
++;
4301 if ((temp
= get_absolute_expression ()) < 0)
4303 as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) temp
);
4304 ignore_rest_of_line ();
4309 symbolP
= symbol_find_or_make (name
);
4312 /* Make a section for the common symbol. */
4313 new_seg
= subseg_new (xstrdup (name
), 0);
4319 /* alignment might follow */
4320 if (*input_line_pointer
== ',')
4324 input_line_pointer
++;
4325 align
= get_absolute_expression ();
4326 bfd_set_section_alignment (stdoutput
, new_seg
, align
);
4330 if (S_IS_DEFINED (symbolP
) && ! S_IS_COMMON (symbolP
))
4332 as_bad (_("Ignoring attempt to re-define symbol"));
4333 ignore_rest_of_line ();
4338 if (bfd_section_size (stdoutput
, new_seg
) > 0)
4340 if (bfd_section_size (stdoutput
, new_seg
) != temp
)
4341 as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
4342 S_GET_NAME (symbolP
),
4343 (long) bfd_section_size (stdoutput
, new_seg
),
4347 if (S_GET_VALUE (symbolP
))
4349 if (S_GET_VALUE (symbolP
) != (valueT
) temp
)
4350 as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
4351 S_GET_NAME (symbolP
),
4352 (long) S_GET_VALUE (symbolP
),
4359 subseg_set (new_seg
, 0);
4360 p
= frag_more (temp
);
4361 new_seg
->flags
|= SEC_IS_COMMON
;
4362 if (! S_IS_DEFINED (symbolP
))
4363 S_SET_SEGMENT (symbolP
, new_seg
);
4365 S_SET_VALUE (symbolP
, (valueT
) temp
);
4367 S_SET_EXTERNAL (symbolP
);
4371 subseg_set (current_section
, current_subsec
);
4374 know (symbol_get_frag (symbolP
) == &zero_address_frag
);
4376 demand_empty_rest_of_line ();
4379 #endif /* ! OBJ_ELF */
4383 /* Handle the .rdata pseudo-op. This is like the usual one, but it
4384 clears alpha_insn_label and restores auto alignment. */
4387 s_alpha_rdata (ignore
)
4392 temp
= get_absolute_expression ();
4393 subseg_new (".rdata", 0);
4394 demand_empty_rest_of_line ();
4395 alpha_insn_label
= NULL
;
4396 alpha_auto_align_on
= 1;
4397 alpha_current_align
= 0;
4404 /* Handle the .sdata pseudo-op. This is like the usual one, but it
4405 clears alpha_insn_label and restores auto alignment. */
4408 s_alpha_sdata (ignore
)
4413 temp
= get_absolute_expression ();
4414 subseg_new (".sdata", 0);
4415 demand_empty_rest_of_line ();
4416 alpha_insn_label
= NULL
;
4417 alpha_auto_align_on
= 1;
4418 alpha_current_align
= 0;
4424 /* Handle the .section pseudo-op. This is like the usual one, but it
4425 clears alpha_insn_label and restores auto alignment. */
4428 s_alpha_section (ignore
)
4431 obj_elf_section (ignore
);
4433 alpha_insn_label
= NULL
;
4434 alpha_auto_align_on
= 1;
4435 alpha_current_align
= 0;
4440 int dummy ATTRIBUTE_UNUSED
;
4442 if (ECOFF_DEBUGGING
)
4443 ecoff_directive_ent (0);
4446 char *name
, name_end
;
4447 name
= input_line_pointer
;
4448 name_end
= get_symbol_end ();
4450 if (! is_name_beginner (*name
))
4452 as_warn (_(".ent directive has no name"));
4453 *input_line_pointer
= name_end
;
4459 if (alpha_cur_ent_sym
)
4460 as_warn (_("nested .ent directives"));
4462 sym
= symbol_find_or_make (name
);
4463 symbol_get_bfdsym (sym
)->flags
|= BSF_FUNCTION
;
4464 alpha_cur_ent_sym
= sym
;
4466 /* The .ent directive is sometimes followed by a number. Not sure
4467 what it really means, but ignore it. */
4468 *input_line_pointer
= name_end
;
4470 if (*input_line_pointer
== ',')
4472 input_line_pointer
++;
4475 if (isdigit (*input_line_pointer
) || *input_line_pointer
== '-')
4476 (void) get_absolute_expression ();
4478 demand_empty_rest_of_line ();
4484 int dummy ATTRIBUTE_UNUSED
;
4486 if (ECOFF_DEBUGGING
)
4487 ecoff_directive_end (0);
4490 char *name
, name_end
;
4491 name
= input_line_pointer
;
4492 name_end
= get_symbol_end ();
4494 if (! is_name_beginner (*name
))
4496 as_warn (_(".end directive has no name"));
4497 *input_line_pointer
= name_end
;
4503 sym
= symbol_find (name
);
4504 if (sym
!= alpha_cur_ent_sym
)
4505 as_warn (_(".end directive names different symbol than .ent"));
4507 /* Create an expression to calculate the size of the function. */
4510 symbol_get_obj (sym
)->size
=
4511 (expressionS
*) xmalloc (sizeof (expressionS
));
4512 symbol_get_obj (sym
)->size
->X_op
= O_subtract
;
4513 symbol_get_obj (sym
)->size
->X_add_symbol
4514 = symbol_new ("L0\001", now_seg
, frag_now_fix (), frag_now
);
4515 symbol_get_obj (sym
)->size
->X_op_symbol
= sym
;
4516 symbol_get_obj (sym
)->size
->X_add_number
= 0;
4519 alpha_cur_ent_sym
= NULL
;
4521 *input_line_pointer
= name_end
;
4523 demand_empty_rest_of_line ();
4531 if (ECOFF_DEBUGGING
)
4534 ecoff_directive_fmask (0);
4536 ecoff_directive_mask (0);
4539 discard_rest_of_line ();
4543 s_alpha_frame (dummy
)
4544 int dummy ATTRIBUTE_UNUSED
;
4546 if (ECOFF_DEBUGGING
)
4547 ecoff_directive_frame (0);
4549 discard_rest_of_line ();
4553 s_alpha_prologue (ignore
)
4554 int ignore ATTRIBUTE_UNUSED
;
4559 arg
= get_absolute_expression ();
4560 demand_empty_rest_of_line ();
4562 if (ECOFF_DEBUGGING
)
4563 sym
= ecoff_get_cur_proc_sym ();
4565 sym
= alpha_cur_ent_sym
;
4570 case 0: /* No PV required. */
4571 S_SET_OTHER (sym
, STO_ALPHA_NOPV
4572 | (S_GET_OTHER (sym
) & ~STO_ALPHA_STD_GPLOAD
));
4574 case 1: /* Std GP load. */
4575 S_SET_OTHER (sym
, STO_ALPHA_STD_GPLOAD
4576 | (S_GET_OTHER (sym
) & ~STO_ALPHA_STD_GPLOAD
));
4578 case 2: /* Non-std use of PV. */
4582 as_bad (_("Invalid argument %d to .prologue."), arg
);
4587 static char *first_file_directive
;
4590 s_alpha_file (ignore
)
4591 int ignore ATTRIBUTE_UNUSED
;
4593 /* Save the first .file directive we see, so that we can change our
4594 minds about whether ecoff debugging should or shouldn't be enabled. */
4595 if (alpha_flag_mdebug
< 0 && ! first_file_directive
)
4597 char *start
= input_line_pointer
;
4600 discard_rest_of_line ();
4602 len
= input_line_pointer
- start
;
4603 first_file_directive
= xmalloc (len
+ 1);
4604 memcpy (first_file_directive
, start
, len
);
4605 first_file_directive
[len
] = '\0';
4607 input_line_pointer
= start
;
4610 if (ECOFF_DEBUGGING
)
4611 ecoff_directive_file (0);
4613 dwarf2_directive_file (0);
4617 s_alpha_loc (ignore
)
4618 int ignore ATTRIBUTE_UNUSED
;
4620 if (ECOFF_DEBUGGING
)
4621 ecoff_directive_loc (0);
4623 dwarf2_directive_loc (0);
4630 /* If we've been undecided about mdebug, make up our minds in favour. */
4631 if (alpha_flag_mdebug
< 0)
4633 segT sec
= subseg_new (".mdebug", 0);
4634 bfd_set_section_flags (stdoutput
, sec
, SEC_HAS_CONTENTS
| SEC_READONLY
);
4635 bfd_set_section_alignment (stdoutput
, sec
, 3);
4637 ecoff_read_begin_hook ();
4639 if (first_file_directive
)
4641 char *save_ilp
= input_line_pointer
;
4642 input_line_pointer
= first_file_directive
;
4643 ecoff_directive_file (0);
4644 input_line_pointer
= save_ilp
;
4645 free (first_file_directive
);
4648 alpha_flag_mdebug
= 1;
4654 s_alpha_coff_wrapper (which
)
4657 static void (* const fns
[]) PARAMS ((int)) = {
4658 ecoff_directive_begin
,
4659 ecoff_directive_bend
,
4660 ecoff_directive_def
,
4661 ecoff_directive_dim
,
4662 ecoff_directive_endef
,
4663 ecoff_directive_scl
,
4664 ecoff_directive_tag
,
4665 ecoff_directive_val
,
4668 assert (which
>= 0 && which
< (int) (sizeof (fns
)/sizeof (*fns
)));
4670 if (ECOFF_DEBUGGING
)
4674 as_bad (_("ECOFF debugging is disabled."));
4675 ignore_rest_of_line ();
4678 #endif /* OBJ_ELF */
4682 /* Handle the section specific pseudo-op. */
4685 s_alpha_section (secid
)
4689 #define EVAX_SECTION_COUNT 5
4690 static char *section_name
[EVAX_SECTION_COUNT
+ 1] =
4691 { "NULL", ".rdata", ".comm", ".link", ".ctors", ".dtors" };
4693 if ((secid
<= 0) || (secid
> EVAX_SECTION_COUNT
))
4695 as_fatal (_("Unknown section directive"));
4696 demand_empty_rest_of_line ();
4699 temp
= get_absolute_expression ();
4700 subseg_new (section_name
[secid
], 0);
4701 demand_empty_rest_of_line ();
4702 alpha_insn_label
= NULL
;
4703 alpha_auto_align_on
= 1;
4704 alpha_current_align
= 0;
4707 /* Parse .ent directives. */
4710 s_alpha_ent (ignore
)
4714 expressionS symexpr
;
4716 alpha_evax_proc
.pdsckind
= 0;
4717 alpha_evax_proc
.framereg
= -1;
4718 alpha_evax_proc
.framesize
= 0;
4719 alpha_evax_proc
.rsa_offset
= 0;
4720 alpha_evax_proc
.ra_save
= AXP_REG_RA
;
4721 alpha_evax_proc
.fp_save
= -1;
4722 alpha_evax_proc
.imask
= 0;
4723 alpha_evax_proc
.fmask
= 0;
4724 alpha_evax_proc
.prologue
= 0;
4725 alpha_evax_proc
.type
= 0;
4727 expression (&symexpr
);
4729 if (symexpr
.X_op
!= O_symbol
)
4731 as_fatal (_(".ent directive has no symbol"));
4732 demand_empty_rest_of_line ();
4736 symbol
= make_expr_symbol (&symexpr
);
4737 symbol_get_bfdsym (symbol
)->flags
|= BSF_FUNCTION
;
4738 alpha_evax_proc
.symbol
= symbol
;
4740 demand_empty_rest_of_line ();
4744 /* Parse .frame <framreg>,<framesize>,RA,<rsa_offset> directives. */
4747 s_alpha_frame (ignore
)
4752 alpha_evax_proc
.framereg
= tc_get_register (1);
4755 if (*input_line_pointer
++ != ','
4756 || get_absolute_expression_and_terminator (&val
) != ',')
4758 as_warn (_("Bad .frame directive 1./2. param"));
4759 --input_line_pointer
;
4760 demand_empty_rest_of_line ();
4764 alpha_evax_proc
.framesize
= val
;
4766 (void) tc_get_register (1);
4768 if (*input_line_pointer
++ != ',')
4770 as_warn (_("Bad .frame directive 3./4. param"));
4771 --input_line_pointer
;
4772 demand_empty_rest_of_line ();
4775 alpha_evax_proc
.rsa_offset
= get_absolute_expression ();
4781 s_alpha_pdesc (ignore
)
4791 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
4793 if (now_seg
!= alpha_link_section
)
4795 as_bad (_(".pdesc directive not in link (.link) section"));
4796 demand_empty_rest_of_line ();
4800 if ((alpha_evax_proc
.symbol
== 0)
4801 || (!S_IS_DEFINED (alpha_evax_proc
.symbol
)))
4803 as_fatal (_(".pdesc has no matching .ent"));
4804 demand_empty_rest_of_line ();
4808 *symbol_get_obj (alpha_evax_proc
.symbol
) =
4809 (valueT
) seginfo
->literal_pool_size
;
4812 if (exp
.X_op
!= O_symbol
)
4814 as_warn (_(".pdesc directive has no entry symbol"));
4815 demand_empty_rest_of_line ();
4819 entry_sym
= make_expr_symbol (&exp
);
4820 /* Save bfd symbol of proc desc in function symbol. */
4821 symbol_get_bfdsym (alpha_evax_proc
.symbol
)->udata
.p
4822 = symbol_get_bfdsym (entry_sym
);
4825 if (*input_line_pointer
++ != ',')
4827 as_warn (_("No comma after .pdesc <entryname>"));
4828 demand_empty_rest_of_line ();
4833 name
= input_line_pointer
;
4834 name_end
= get_symbol_end ();
4836 if (strncmp (name
, "stack", 5) == 0)
4838 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_FP_STACK
;
4840 else if (strncmp (name
, "reg", 3) == 0)
4842 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_FP_REGISTER
;
4844 else if (strncmp (name
, "null", 4) == 0)
4846 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_NULL
;
4850 as_fatal (_("unknown procedure kind"));
4851 demand_empty_rest_of_line ();
4855 *input_line_pointer
= name_end
;
4856 demand_empty_rest_of_line ();
4858 #ifdef md_flush_pending_output
4859 md_flush_pending_output ();
4862 frag_align (3, 0, 0);
4864 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
4866 seginfo
->literal_pool_size
+= 16;
4868 *p
= alpha_evax_proc
.pdsckind
4869 | ((alpha_evax_proc
.framereg
== 29) ? PDSC_S_M_BASE_REG_IS_FP
: 0);
4870 *(p
+ 1) = PDSC_S_M_NATIVE
| PDSC_S_M_NO_JACKET
;
4872 switch (alpha_evax_proc
.pdsckind
)
4874 case PDSC_S_K_KIND_NULL
:
4878 case PDSC_S_K_KIND_FP_REGISTER
:
4879 *(p
+ 2) = alpha_evax_proc
.fp_save
;
4880 *(p
+ 3) = alpha_evax_proc
.ra_save
;
4882 case PDSC_S_K_KIND_FP_STACK
:
4883 md_number_to_chars (p
+ 2, (valueT
) alpha_evax_proc
.rsa_offset
, 2);
4885 default: /* impossible */
4890 *(p
+ 5) = alpha_evax_proc
.type
& 0x0f;
4892 /* Signature offset. */
4893 md_number_to_chars (p
+ 6, (valueT
) 0, 2);
4895 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
+8, 8, &exp
, 0, BFD_RELOC_64
);
4897 if (alpha_evax_proc
.pdsckind
== PDSC_S_K_KIND_NULL
)
4900 /* Add dummy fix to make add_to_link_pool work. */
4902 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
4904 seginfo
->literal_pool_size
+= 8;
4906 /* pdesc+16: Size. */
4907 md_number_to_chars (p
, (valueT
) alpha_evax_proc
.framesize
, 4);
4909 md_number_to_chars (p
+ 4, (valueT
) 0, 2);
4912 md_number_to_chars (p
+ 6, alpha_evax_proc
.prologue
, 2);
4914 if (alpha_evax_proc
.pdsckind
== PDSC_S_K_KIND_FP_REGISTER
)
4917 /* Add dummy fix to make add_to_link_pool work. */
4919 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
4921 seginfo
->literal_pool_size
+= 8;
4923 /* pdesc+24: register masks. */
4925 md_number_to_chars (p
, alpha_evax_proc
.imask
, 4);
4926 md_number_to_chars (p
+ 4, alpha_evax_proc
.fmask
, 4);
4931 /* Support for crash debug on vms. */
4934 s_alpha_name (ignore
)
4939 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
4941 if (now_seg
!= alpha_link_section
)
4943 as_bad (_(".name directive not in link (.link) section"));
4944 demand_empty_rest_of_line ();
4949 if (exp
.X_op
!= O_symbol
)
4951 as_warn (_(".name directive has no symbol"));
4952 demand_empty_rest_of_line ();
4956 demand_empty_rest_of_line ();
4958 #ifdef md_flush_pending_output
4959 md_flush_pending_output ();
4962 frag_align (3, 0, 0);
4964 seginfo
->literal_pool_size
+= 8;
4966 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 8, &exp
, 0, BFD_RELOC_64
);
4972 s_alpha_linkage (ignore
)
4978 #ifdef md_flush_pending_output
4979 md_flush_pending_output ();
4983 if (exp
.X_op
!= O_symbol
)
4985 as_fatal (_("No symbol after .linkage"));
4989 p
= frag_more (LKP_S_K_SIZE
);
4990 memset (p
, 0, LKP_S_K_SIZE
);
4991 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, LKP_S_K_SIZE
, &exp
, 0,\
4992 BFD_RELOC_ALPHA_LINKAGE
);
4994 demand_empty_rest_of_line ();
5000 s_alpha_code_address (ignore
)
5006 #ifdef md_flush_pending_output
5007 md_flush_pending_output ();
5011 if (exp
.X_op
!= O_symbol
)
5013 as_fatal (_("No symbol after .code_address"));
5019 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 8, &exp
, 0,\
5020 BFD_RELOC_ALPHA_CODEADDR
);
5022 demand_empty_rest_of_line ();
5028 s_alpha_fp_save (ignore
)
5032 alpha_evax_proc
.fp_save
= tc_get_register (1);
5034 demand_empty_rest_of_line ();
5039 s_alpha_mask (ignore
)
5044 if (get_absolute_expression_and_terminator (&val
) != ',')
5046 as_warn (_("Bad .mask directive"));
5047 --input_line_pointer
;
5051 alpha_evax_proc
.imask
= val
;
5052 (void) get_absolute_expression ();
5054 demand_empty_rest_of_line ();
5060 s_alpha_fmask (ignore
)
5065 if (get_absolute_expression_and_terminator (&val
) != ',')
5067 as_warn (_("Bad .fmask directive"));
5068 --input_line_pointer
;
5072 alpha_evax_proc
.fmask
= val
;
5073 (void) get_absolute_expression ();
5075 demand_empty_rest_of_line ();
5081 s_alpha_end (ignore
)
5086 c
= get_symbol_end ();
5087 *input_line_pointer
= c
;
5088 demand_empty_rest_of_line ();
5089 alpha_evax_proc
.symbol
= 0;
5095 s_alpha_file (ignore
)
5100 static char case_hack
[32];
5102 extern char *demand_copy_string
PARAMS ((int *lenP
));
5104 sprintf (case_hack
, "<CASE:%01d%01d>",
5105 alpha_flag_hash_long_names
, alpha_flag_show_after_trunc
);
5107 s
= symbol_find_or_make (case_hack
);
5108 symbol_get_bfdsym (s
)->flags
|= BSF_FILE
;
5110 get_absolute_expression ();
5111 s
= symbol_find_or_make (demand_copy_string (&length
));
5112 symbol_get_bfdsym (s
)->flags
|= BSF_FILE
;
5113 demand_empty_rest_of_line ();
5117 #endif /* OBJ_EVAX */
5119 /* Handle the .gprel32 pseudo op. */
5122 s_alpha_gprel32 (ignore
)
5123 int ignore ATTRIBUTE_UNUSED
;
5135 e
.X_add_symbol
= section_symbol (absolute_section
);
5148 e
.X_add_symbol
= section_symbol (absolute_section
);
5151 e
.X_op
= O_subtract
;
5152 e
.X_op_symbol
= alpha_gp_symbol
;
5160 if (alpha_auto_align_on
&& alpha_current_align
< 2)
5161 alpha_align (2, (char *) NULL
, alpha_insn_label
, 0);
5162 if (alpha_current_align
> 2)
5163 alpha_current_align
= 2;
5164 alpha_insn_label
= NULL
;
5168 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 4,
5169 &e
, 0, BFD_RELOC_GPREL32
);
5172 /* Handle floating point allocation pseudo-ops. This is like the
5173 generic vresion, but it makes sure the current label, if any, is
5174 correctly aligned. */
5177 s_alpha_float_cons (type
)
5204 if (alpha_auto_align_on
&& alpha_current_align
< log_size
)
5205 alpha_align (log_size
, (char *) NULL
, alpha_insn_label
, 0);
5206 if (alpha_current_align
> log_size
)
5207 alpha_current_align
= log_size
;
5208 alpha_insn_label
= NULL
;
5213 /* Handle the .proc pseudo op. We don't really do much with it except
5217 s_alpha_proc (is_static
)
5218 int is_static ATTRIBUTE_UNUSED
;
5226 /* Takes ".proc name,nargs" */
5228 name
= input_line_pointer
;
5229 c
= get_symbol_end ();
5230 p
= input_line_pointer
;
5231 symbolP
= symbol_find_or_make (name
);
5234 if (*input_line_pointer
!= ',')
5237 as_warn (_("Expected comma after name \"%s\""), name
);
5240 ignore_rest_of_line ();
5244 input_line_pointer
++;
5245 temp
= get_absolute_expression ();
5247 /* *symbol_get_obj (symbolP) = (signed char) temp; */
5248 as_warn (_("unhandled: .proc %s,%d"), name
, temp
);
5249 demand_empty_rest_of_line ();
5252 /* Handle the .set pseudo op. This is used to turn on and off most of
5253 the assembler features. */
5257 int x ATTRIBUTE_UNUSED
;
5263 name
= input_line_pointer
;
5264 ch
= get_symbol_end ();
5267 if (s
[0] == 'n' && s
[1] == 'o')
5272 if (!strcmp ("reorder", s
))
5274 else if (!strcmp ("at", s
))
5275 alpha_noat_on
= !yesno
;
5276 else if (!strcmp ("macro", s
))
5277 alpha_macros_on
= yesno
;
5278 else if (!strcmp ("move", s
))
5280 else if (!strcmp ("volatile", s
))
5283 as_warn (_("Tried to .set unrecognized mode `%s'"), name
);
5285 *input_line_pointer
= ch
;
5286 demand_empty_rest_of_line ();
5289 /* Handle the .base pseudo op. This changes the assembler's notion of
5290 the $gp register. */
5293 s_alpha_base (ignore
)
5294 int ignore ATTRIBUTE_UNUSED
;
5297 if (first_32bit_quadrant
)
5299 /* not fatal, but it might not work in the end */
5300 as_warn (_("File overrides no-base-register option."));
5301 first_32bit_quadrant
= 0;
5306 if (*input_line_pointer
== '$')
5308 input_line_pointer
++;
5309 if (*input_line_pointer
== 'r')
5310 input_line_pointer
++;
5313 alpha_gp_register
= get_absolute_expression ();
5314 if (alpha_gp_register
< 0 || alpha_gp_register
> 31)
5316 alpha_gp_register
= AXP_REG_GP
;
5317 as_warn (_("Bad base register, using $%d."), alpha_gp_register
);
5320 demand_empty_rest_of_line ();
5323 /* Handle the .align pseudo-op. This aligns to a power of two. It
5324 also adjusts any current instruction label. We treat this the same
5325 way the MIPS port does: .align 0 turns off auto alignment. */
5328 s_alpha_align (ignore
)
5329 int ignore ATTRIBUTE_UNUSED
;
5333 long max_alignment
= 15;
5335 align
= get_absolute_expression ();
5336 if (align
> max_alignment
)
5338 align
= max_alignment
;
5339 as_bad (_("Alignment too large: %d. assumed"), align
);
5343 as_warn (_("Alignment negative: 0 assumed"));
5347 if (*input_line_pointer
== ',')
5349 input_line_pointer
++;
5350 fill
= get_absolute_expression ();
5358 alpha_auto_align_on
= 1;
5359 alpha_align (align
, pfill
, alpha_insn_label
, 1);
5363 alpha_auto_align_on
= 0;
5366 demand_empty_rest_of_line ();
5369 /* Hook the normal string processor to reset known alignment. */
5372 s_alpha_stringer (terminate
)
5375 alpha_current_align
= 0;
5376 alpha_insn_label
= NULL
;
5377 stringer (terminate
);
5380 /* Hook the normal space processing to reset known alignment. */
5383 s_alpha_space (ignore
)
5386 alpha_current_align
= 0;
5387 alpha_insn_label
= NULL
;
5391 /* Hook into cons for auto-alignment. */
5394 alpha_cons_align (size
)
5400 while ((size
>>= 1) != 0)
5403 if (alpha_auto_align_on
&& alpha_current_align
< log_size
)
5404 alpha_align (log_size
, (char *) NULL
, alpha_insn_label
, 0);
5405 if (alpha_current_align
> log_size
)
5406 alpha_current_align
= log_size
;
5407 alpha_insn_label
= NULL
;
5410 /* Here come the .uword, .ulong, and .uquad explicitly unaligned
5411 pseudos. We just turn off auto-alignment and call down to cons. */
5414 s_alpha_ucons (bytes
)
5417 int hold
= alpha_auto_align_on
;
5418 alpha_auto_align_on
= 0;
5420 alpha_auto_align_on
= hold
;
5423 /* Switch the working cpu type. */
5426 s_alpha_arch (ignored
)
5427 int ignored ATTRIBUTE_UNUSED
;
5430 const struct cpu_type
*p
;
5433 name
= input_line_pointer
;
5434 ch
= get_symbol_end ();
5436 for (p
= cpu_types
; p
->name
; ++p
)
5437 if (strcmp (name
, p
->name
) == 0)
5439 alpha_target_name
= p
->name
, alpha_target
= p
->flags
;
5442 as_warn ("Unknown CPU identifier `%s'", name
);
5445 *input_line_pointer
= ch
;
5446 demand_empty_rest_of_line ();
5450 /* print token expression with alpha specific extension. */
5453 alpha_print_token (f
, exp
)
5455 const expressionS
*exp
;
5465 expressionS nexp
= *exp
;
5466 nexp
.X_op
= O_register
;
5467 print_expr (f
, &nexp
);
5472 print_expr (f
, exp
);
5479 /* The target specific pseudo-ops which we support. */
5481 const pseudo_typeS md_pseudo_table
[] = {
5483 {"comm", s_alpha_comm
, 0}, /* osf1 compiler does this */
5484 {"rdata", s_alpha_rdata
, 0},
5486 {"text", s_alpha_text
, 0},
5487 {"data", s_alpha_data
, 0},
5489 {"sdata", s_alpha_sdata
, 0},
5492 {"section", s_alpha_section
, 0},
5493 {"section.s", s_alpha_section
, 0},
5494 {"sect", s_alpha_section
, 0},
5495 {"sect.s", s_alpha_section
, 0},
5498 { "pdesc", s_alpha_pdesc
, 0},
5499 { "name", s_alpha_name
, 0},
5500 { "linkage", s_alpha_linkage
, 0},
5501 { "code_address", s_alpha_code_address
, 0},
5502 { "ent", s_alpha_ent
, 0},
5503 { "frame", s_alpha_frame
, 0},
5504 { "fp_save", s_alpha_fp_save
, 0},
5505 { "mask", s_alpha_mask
, 0},
5506 { "fmask", s_alpha_fmask
, 0},
5507 { "end", s_alpha_end
, 0},
5508 { "file", s_alpha_file
, 0},
5509 { "rdata", s_alpha_section
, 1},
5510 { "comm", s_alpha_comm
, 0},
5511 { "link", s_alpha_section
, 3},
5512 { "ctors", s_alpha_section
, 4},
5513 { "dtors", s_alpha_section
, 5},
5516 /* Frame related pseudos. */
5517 {"ent", s_alpha_ent
, 0},
5518 {"end", s_alpha_end
, 0},
5519 {"mask", s_alpha_mask
, 0},
5520 {"fmask", s_alpha_mask
, 1},
5521 {"frame", s_alpha_frame
, 0},
5522 {"prologue", s_alpha_prologue
, 0},
5523 {"file", s_alpha_file
, 5},
5524 {"loc", s_alpha_loc
, 9},
5525 {"stabs", s_alpha_stab
, 's'},
5526 {"stabn", s_alpha_stab
, 'n'},
5527 /* COFF debugging related pseudos. */
5528 {"begin", s_alpha_coff_wrapper
, 0},
5529 {"bend", s_alpha_coff_wrapper
, 1},
5530 {"def", s_alpha_coff_wrapper
, 2},
5531 {"dim", s_alpha_coff_wrapper
, 3},
5532 {"endef", s_alpha_coff_wrapper
, 4},
5533 {"scl", s_alpha_coff_wrapper
, 5},
5534 {"tag", s_alpha_coff_wrapper
, 6},
5535 {"val", s_alpha_coff_wrapper
, 7},
5537 {"prologue", s_ignore
, 0},
5539 {"gprel32", s_alpha_gprel32
, 0},
5540 {"t_floating", s_alpha_float_cons
, 'd'},
5541 {"s_floating", s_alpha_float_cons
, 'f'},
5542 {"f_floating", s_alpha_float_cons
, 'F'},
5543 {"g_floating", s_alpha_float_cons
, 'G'},
5544 {"d_floating", s_alpha_float_cons
, 'D'},
5546 {"proc", s_alpha_proc
, 0},
5547 {"aproc", s_alpha_proc
, 1},
5548 {"set", s_alpha_set
, 0},
5549 {"reguse", s_ignore
, 0},
5550 {"livereg", s_ignore
, 0},
5551 {"base", s_alpha_base
, 0}, /*??*/
5552 {"option", s_ignore
, 0},
5553 {"aent", s_ignore
, 0},
5554 {"ugen", s_ignore
, 0},
5555 {"eflag", s_ignore
, 0},
5557 {"align", s_alpha_align
, 0},
5558 {"double", s_alpha_float_cons
, 'd'},
5559 {"float", s_alpha_float_cons
, 'f'},
5560 {"single", s_alpha_float_cons
, 'f'},
5561 {"ascii", s_alpha_stringer
, 0},
5562 {"asciz", s_alpha_stringer
, 1},
5563 {"string", s_alpha_stringer
, 1},
5564 {"space", s_alpha_space
, 0},
5565 {"skip", s_alpha_space
, 0},
5566 {"zero", s_alpha_space
, 0},
5568 /* Unaligned data pseudos. */
5569 {"uword", s_alpha_ucons
, 2},
5570 {"ulong", s_alpha_ucons
, 4},
5571 {"uquad", s_alpha_ucons
, 8},
5574 /* Dwarf wants these versions of unaligned. */
5575 {"2byte", s_alpha_ucons
, 2},
5576 {"4byte", s_alpha_ucons
, 4},
5577 {"8byte", s_alpha_ucons
, 8},
5580 /* We don't do any optimizing, so we can safely ignore these. */
5581 {"noalias", s_ignore
, 0},
5582 {"alias", s_ignore
, 0},
5584 {"arch", s_alpha_arch
, 0},
5589 /* Build a BFD section with its flags set appropriately for the .lita,
5590 .lit8, or .lit4 sections. */
5593 create_literal_section (name
, secp
, symp
)
5598 segT current_section
= now_seg
;
5599 int current_subsec
= now_subseg
;
5602 *secp
= new_sec
= subseg_new (name
, 0);
5603 subseg_set (current_section
, current_subsec
);
5604 bfd_set_section_alignment (stdoutput
, new_sec
, 4);
5605 bfd_set_section_flags (stdoutput
, new_sec
,
5606 SEC_RELOC
| SEC_ALLOC
| SEC_LOAD
| SEC_READONLY
5609 S_CLEAR_EXTERNAL (*symp
= section_symbol (new_sec
));
5614 /* @@@ GP selection voodoo. All of this seems overly complicated and
5615 unnecessary; which is the primary reason it's for ECOFF only. */
5624 vma
= bfd_get_section_vma (foo
, sec
);
5625 if (vma
&& vma
< alpha_gp_value
)
5626 alpha_gp_value
= vma
;
5632 assert (alpha_gp_value
== 0);
5634 /* Get minus-one in whatever width... */
5638 /* Select the smallest VMA of these existing sections. */
5639 maybe_set_gp (alpha_lita_section
);
5641 /* These were disabled before -- should we use them? */
5642 maybe_set_gp (sdata
);
5643 maybe_set_gp (lit8_sec
);
5644 maybe_set_gp (lit4_sec
);
5647 /* @@ Will a simple 0x8000 work here? If not, why not? */
5648 #define GP_ADJUSTMENT (0x8000 - 0x10)
5650 alpha_gp_value
+= GP_ADJUSTMENT
;
5652 S_SET_VALUE (alpha_gp_symbol
, alpha_gp_value
);
5655 printf (_("Chose GP value of %lx\n"), alpha_gp_value
);
5658 #endif /* OBJ_ECOFF */
5660 /* Called internally to handle all alignment needs. This takes care
5661 of eliding calls to frag_align if'n the cached current alignment
5662 says we've already got it, as well as taking care of the auto-align
5663 feature wrt labels. */
5666 alpha_align (n
, pfill
, label
, force
)
5670 int force ATTRIBUTE_UNUSED
;
5672 if (alpha_current_align
>= n
)
5677 if (subseg_text_p (now_seg
))
5678 frag_align_code (n
, 0);
5680 frag_align (n
, 0, 0);
5683 frag_align (n
, *pfill
, 0);
5685 alpha_current_align
= n
;
5687 if (label
!= NULL
&& S_GET_SEGMENT (label
) == now_seg
)
5689 symbol_set_frag (label
, frag_now
);
5690 S_SET_VALUE (label
, (valueT
) frag_now_fix ());
5693 record_alignment (now_seg
, n
);
5695 /* ??? If alpha_flag_relax && force && elf, record the requested alignment
5696 in a reloc for the linker to see. */
5699 /* This is called from HANDLE_ALIGN in write.c. Fill in the contents
5700 of an rs_align_code fragment. */
5703 alpha_handle_align (fragp
)
5706 static char const unop
[4] = { 0x00, 0x00, 0xe0, 0x2f };
5707 static char const nopunop
[8] = {
5708 0x1f, 0x04, 0xff, 0x47,
5709 0x00, 0x00, 0xe0, 0x2f
5715 if (fragp
->fr_type
!= rs_align_code
)
5718 bytes
= fragp
->fr_next
->fr_address
- fragp
->fr_address
- fragp
->fr_fix
;
5719 p
= fragp
->fr_literal
+ fragp
->fr_fix
;
5732 memcpy (p
, unop
, 4);
5738 memcpy (p
, nopunop
, 8);
5740 fragp
->fr_fix
+= fix
;
5744 /* The Alpha has support for some VAX floating point types, as well as for
5745 IEEE floating point. We consider IEEE to be the primary floating point
5746 format, and sneak in the VAX floating point support here. */
5747 #define md_atof vax_md_atof
5748 #include "config/atof-vax.c"