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"
65 #include "safe-ctype.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
];
87 enum alpha_macro_arg
{
99 void (*emit
) PARAMS ((const expressionS
*, int, const PTR
));
101 enum alpha_macro_arg argsets
[16];
104 /* Extra expression types. */
106 #define O_pregister O_md1 /* O_register, in parentheses */
107 #define O_cpregister O_md2 /* + a leading comma */
109 /* Note, the alpha_reloc_op table below depends on the ordering
110 of O_literal .. O_gpre16. */
111 #define O_literal O_md3 /* !literal relocation */
112 #define O_lituse_addr O_md4 /* !lituse_addr relocation */
113 #define O_lituse_base O_md5 /* !lituse_base relocation */
114 #define O_lituse_bytoff O_md6 /* !lituse_bytoff relocation */
115 #define O_lituse_jsr O_md7 /* !lituse_jsr relocation */
116 #define O_gpdisp O_md8 /* !gpdisp relocation */
117 #define O_gprelhigh O_md9 /* !gprelhigh relocation */
118 #define O_gprellow O_md10 /* !gprellow relocation */
119 #define O_gprel O_md11 /* !gprel relocation */
121 #define DUMMY_RELOC_LITUSE_ADDR (BFD_RELOC_UNUSED + 1)
122 #define DUMMY_RELOC_LITUSE_BASE (BFD_RELOC_UNUSED + 2)
123 #define DUMMY_RELOC_LITUSE_BYTOFF (BFD_RELOC_UNUSED + 3)
124 #define DUMMY_RELOC_LITUSE_JSR (BFD_RELOC_UNUSED + 4)
126 #define LITUSE_ADDR 0
127 #define LITUSE_BASE 1
128 #define LITUSE_BYTOFF 2
131 #define USER_RELOC_P(R) ((R) >= O_literal && (R) <= O_gprel)
133 /* Macros for extracting the type and number of encoded register tokens */
135 #define is_ir_num(x) (((x) & 32) == 0)
136 #define is_fpr_num(x) (((x) & 32) != 0)
137 #define regno(x) ((x) & 31)
139 /* Something odd inherited from the old assembler */
141 #define note_gpreg(R) (alpha_gprmask |= (1 << (R)))
142 #define note_fpreg(R) (alpha_fprmask |= (1 << (R)))
144 /* Predicates for 16- and 32-bit ranges */
145 /* XXX: The non-shift version appears to trigger a compiler bug when
146 cross-assembling from x86 w/ gcc 2.7.2. */
149 #define range_signed_16(x) \
150 (((offsetT) (x) >> 15) == 0 || ((offsetT) (x) >> 15) == -1)
151 #define range_signed_32(x) \
152 (((offsetT) (x) >> 31) == 0 || ((offsetT) (x) >> 31) == -1)
154 #define range_signed_16(x) ((offsetT) (x) >= -(offsetT) 0x8000 && \
155 (offsetT) (x) <= (offsetT) 0x7FFF)
156 #define range_signed_32(x) ((offsetT) (x) >= -(offsetT) 0x80000000 && \
157 (offsetT) (x) <= (offsetT) 0x7FFFFFFF)
160 /* Macros for sign extending from 16- and 32-bits. */
161 /* XXX: The cast macros will work on all the systems that I care about,
162 but really a predicate should be found to use the non-cast forms. */
165 #define sign_extend_16(x) ((short) (x))
166 #define sign_extend_32(x) ((int) (x))
168 #define sign_extend_16(x) ((offsetT) (((x) & 0xFFFF) ^ 0x8000) - 0x8000)
169 #define sign_extend_32(x) ((offsetT) (((x) & 0xFFFFFFFF) \
170 ^ 0x80000000) - 0x80000000)
173 /* Macros to build tokens */
175 #define set_tok_reg(t, r) (memset (&(t), 0, sizeof (t)), \
176 (t).X_op = O_register, \
177 (t).X_add_number = (r))
178 #define set_tok_preg(t, r) (memset (&(t), 0, sizeof (t)), \
179 (t).X_op = O_pregister, \
180 (t).X_add_number = (r))
181 #define set_tok_cpreg(t, r) (memset (&(t), 0, sizeof (t)), \
182 (t).X_op = O_cpregister, \
183 (t).X_add_number = (r))
184 #define set_tok_freg(t, r) (memset (&(t), 0, sizeof (t)), \
185 (t).X_op = O_register, \
186 (t).X_add_number = (r) + 32)
187 #define set_tok_sym(t, s, a) (memset (&(t), 0, sizeof (t)), \
188 (t).X_op = O_symbol, \
189 (t).X_add_symbol = (s), \
190 (t).X_add_number = (a))
191 #define set_tok_const(t, n) (memset (&(t), 0, sizeof (t)), \
192 (t).X_op = O_constant, \
193 (t).X_add_number = (n))
195 /* Prototypes for all local functions */
197 static struct alpha_reloc_tag
*get_alpha_reloc_tag
PARAMS ((long));
198 static void alpha_adjust_symtab_relocs
PARAMS ((bfd
*, asection
*, PTR
));
200 static int tokenize_arguments
PARAMS ((char *, expressionS
*, int));
201 static const struct alpha_opcode
*find_opcode_match
202 PARAMS ((const struct alpha_opcode
*, const expressionS
*, int *, int *));
203 static const struct alpha_macro
*find_macro_match
204 PARAMS ((const struct alpha_macro
*, const expressionS
*, int *));
205 static unsigned insert_operand
206 PARAMS ((unsigned, const struct alpha_operand
*, offsetT
, char *, unsigned));
207 static void assemble_insn
208 PARAMS ((const struct alpha_opcode
*, const expressionS
*, int,
209 struct alpha_insn
*, bfd_reloc_code_real_type
));
210 static void emit_insn
PARAMS ((struct alpha_insn
*));
211 static void assemble_tokens_to_insn
212 PARAMS ((const char *, const expressionS
*, int, struct alpha_insn
*));
213 static void assemble_tokens
214 PARAMS ((const char *, const expressionS
*, int, int));
216 static long load_expression
217 PARAMS ((int, const expressionS
*, int *, expressionS
*));
219 static void emit_ldgp
PARAMS ((const expressionS
*, int, const PTR
));
220 static void emit_division
PARAMS ((const expressionS
*, int, const PTR
));
221 static void emit_lda
PARAMS ((const expressionS
*, int, const PTR
));
222 static void emit_ldah
PARAMS ((const expressionS
*, int, const PTR
));
223 static void emit_ir_load
PARAMS ((const expressionS
*, int, const PTR
));
224 static void emit_loadstore
PARAMS ((const expressionS
*, int, const PTR
));
225 static void emit_jsrjmp
PARAMS ((const expressionS
*, int, const PTR
));
226 static void emit_ldX
PARAMS ((const expressionS
*, int, const PTR
));
227 static void emit_ldXu
PARAMS ((const expressionS
*, int, const PTR
));
228 static void emit_uldX
PARAMS ((const expressionS
*, int, const PTR
));
229 static void emit_uldXu
PARAMS ((const expressionS
*, int, const PTR
));
230 static void emit_ldil
PARAMS ((const expressionS
*, int, const PTR
));
231 static void emit_stX
PARAMS ((const expressionS
*, int, const PTR
));
232 static void emit_ustX
PARAMS ((const expressionS
*, int, const PTR
));
233 static void emit_sextX
PARAMS ((const expressionS
*, int, const PTR
));
234 static void emit_retjcr
PARAMS ((const expressionS
*, int, const PTR
));
236 static void s_alpha_text
PARAMS ((int));
237 static void s_alpha_data
PARAMS ((int));
239 static void s_alpha_comm
PARAMS ((int));
240 static void s_alpha_rdata
PARAMS ((int));
243 static void s_alpha_sdata
PARAMS ((int));
246 static void s_alpha_section
PARAMS ((int));
247 static void s_alpha_ent
PARAMS ((int));
248 static void s_alpha_end
PARAMS ((int));
249 static void s_alpha_mask
PARAMS ((int));
250 static void s_alpha_frame
PARAMS ((int));
251 static void s_alpha_prologue
PARAMS ((int));
252 static void s_alpha_file
PARAMS ((int));
253 static void s_alpha_loc
PARAMS ((int));
254 static void s_alpha_stab
PARAMS ((int));
255 static void s_alpha_coff_wrapper
PARAMS ((int));
258 static void s_alpha_section
PARAMS ((int));
260 static void s_alpha_gprel32
PARAMS ((int));
261 static void s_alpha_float_cons
PARAMS ((int));
262 static void s_alpha_proc
PARAMS ((int));
263 static void s_alpha_set
PARAMS ((int));
264 static void s_alpha_base
PARAMS ((int));
265 static void s_alpha_align
PARAMS ((int));
266 static void s_alpha_stringer
PARAMS ((int));
267 static void s_alpha_space
PARAMS ((int));
268 static void s_alpha_ucons
PARAMS ((int));
269 static void s_alpha_arch
PARAMS ((int));
271 static void create_literal_section
PARAMS ((const char *, segT
*, symbolS
**));
273 static void select_gp_value
PARAMS ((void));
275 static void alpha_align
PARAMS ((int, char *, symbolS
*, int));
277 /* Generic assembler global variables which must be defined by all
280 /* Characters which always start a comment. */
281 const char comment_chars
[] = "#";
283 /* Characters which start a comment at the beginning of a line. */
284 const char line_comment_chars
[] = "#";
286 /* Characters which may be used to separate multiple commands on a
288 const char line_separator_chars
[] = ";";
290 /* Characters which are used to indicate an exponent in a floating
292 const char EXP_CHARS
[] = "eE";
294 /* Characters which mean that a number is a floating point constant,
297 const char FLT_CHARS
[] = "dD";
299 /* XXX: Do all of these really get used on the alpha?? */
300 char FLT_CHARS
[] = "rRsSfFdDxXpP";
304 const char *md_shortopts
= "Fm:g+1h:HG:";
306 const char *md_shortopts
= "Fm:gG:";
309 struct option md_longopts
[] = {
310 #define OPTION_32ADDR (OPTION_MD_BASE)
311 { "32addr", no_argument
, NULL
, OPTION_32ADDR
},
312 #define OPTION_RELAX (OPTION_32ADDR + 1)
313 { "relax", no_argument
, NULL
, OPTION_RELAX
},
315 #define OPTION_MDEBUG (OPTION_RELAX + 1)
316 #define OPTION_NO_MDEBUG (OPTION_MDEBUG + 1)
317 { "mdebug", no_argument
, NULL
, OPTION_MDEBUG
},
318 { "no-mdebug", no_argument
, NULL
, OPTION_NO_MDEBUG
},
320 { NULL
, no_argument
, NULL
, 0 }
323 size_t md_longopts_size
= sizeof (md_longopts
);
327 #define AXP_REG_R16 16
328 #define AXP_REG_R17 17
330 #define AXP_REG_T9 22
332 #define AXP_REG_T10 23
334 #define AXP_REG_T11 24
336 #define AXP_REG_T12 25
337 #define AXP_REG_AI 25
339 #define AXP_REG_FP 29
342 #define AXP_REG_GP AXP_REG_PV
343 #endif /* OBJ_EVAX */
345 /* The cpu for which we are generating code */
346 static unsigned alpha_target
= AXP_OPCODE_BASE
;
347 static const char *alpha_target_name
= "<all>";
349 /* The hash table of instruction opcodes */
350 static struct hash_control
*alpha_opcode_hash
;
352 /* The hash table of macro opcodes */
353 static struct hash_control
*alpha_macro_hash
;
356 /* The $gp relocation symbol */
357 static symbolS
*alpha_gp_symbol
;
359 /* XXX: what is this, and why is it exported? */
360 valueT alpha_gp_value
;
363 /* The current $gp register */
364 static int alpha_gp_register
= AXP_REG_GP
;
366 /* A table of the register symbols */
367 static symbolS
*alpha_register_table
[64];
369 /* Constant sections, or sections of constants */
371 static segT alpha_lita_section
;
372 static segT alpha_lit4_section
;
375 static segT alpha_link_section
;
376 static segT alpha_ctors_section
;
377 static segT alpha_dtors_section
;
379 static segT alpha_lit8_section
;
381 /* Symbols referring to said sections. */
383 static symbolS
*alpha_lita_symbol
;
384 static symbolS
*alpha_lit4_symbol
;
387 static symbolS
*alpha_link_symbol
;
388 static symbolS
*alpha_ctors_symbol
;
389 static symbolS
*alpha_dtors_symbol
;
391 static symbolS
*alpha_lit8_symbol
;
393 /* Literal for .litX+0x8000 within .lita */
395 static offsetT alpha_lit4_literal
;
396 static offsetT alpha_lit8_literal
;
400 /* The active .ent symbol. */
401 static symbolS
*alpha_cur_ent_sym
;
404 /* Is the assembler not allowed to use $at? */
405 static int alpha_noat_on
= 0;
407 /* Are macros enabled? */
408 static int alpha_macros_on
= 1;
410 /* Are floats disabled? */
411 static int alpha_nofloats_on
= 0;
413 /* Are addresses 32 bit? */
414 static int alpha_addr32_on
= 0;
416 /* Symbol labelling the current insn. When the Alpha gas sees
419 and the section happens to not be on an eight byte boundary, it
420 will align both the symbol and the .quad to an eight byte boundary. */
421 static symbolS
*alpha_insn_label
;
423 /* Whether we should automatically align data generation pseudo-ops.
424 .align 0 will turn this off. */
425 static int alpha_auto_align_on
= 1;
427 /* The known current alignment of the current section. */
428 static int alpha_current_align
;
430 /* These are exported to ECOFF code. */
431 unsigned long alpha_gprmask
, alpha_fprmask
;
433 /* Whether the debugging option was seen. */
434 static int alpha_debug
;
437 /* Whether we are emitting an mdebug section. */
438 int alpha_flag_mdebug
= -1;
441 /* Don't fully resolve relocations, allowing code movement in the linker. */
442 static int alpha_flag_relax
;
444 /* What value to give to bfd_set_gp_size. */
445 static int g_switch_value
= 8;
448 /* Collect information about current procedure here. */
450 symbolS
*symbol
; /* proc pdesc symbol */
452 int framereg
; /* register for frame pointer */
453 int framesize
; /* size of frame */
463 static int alpha_flag_hash_long_names
= 0; /* -+ */
464 static int alpha_flag_show_after_trunc
= 0; /* -H */
466 /* If the -+ switch is given, then a hash is appended to any name that is
467 * longer than 64 characters, else longer symbol names are truncated.
473 /* A table to map the spelling of a relocation operand into an appropriate
474 bfd_reloc_code_real_type type. The table is assumed to be ordered such
475 that op-O_literal indexes into it. */
477 #define ALPHA_RELOC_TABLE(op) \
478 (&alpha_reloc_op[ ((!USER_RELOC_P (op)) \
480 : (int) (op) - (int) O_literal) ])
482 #define DEF(NAME, RELOC, REQ, ALLOW) \
483 { #NAME, sizeof(#NAME)-1, O_##NAME, RELOC, REQ, ALLOW}
485 static const struct alpha_reloc_op_tag
{
486 const char *name
; /* string to lookup */
487 size_t length
; /* size of the string */
488 operatorT op
; /* which operator to use */
489 bfd_reloc_code_real_type reloc
; /* relocation before frob */
490 unsigned int require_seq
: 1; /* require a sequence number */
491 unsigned int allow_seq
: 1; /* allow a sequence number */
492 } alpha_reloc_op
[] = {
493 DEF(literal
, BFD_RELOC_ALPHA_ELF_LITERAL
, 0, 1),
494 DEF(lituse_addr
, DUMMY_RELOC_LITUSE_ADDR
, 1, 1),
495 DEF(lituse_base
, DUMMY_RELOC_LITUSE_BASE
, 1, 1),
496 DEF(lituse_bytoff
, DUMMY_RELOC_LITUSE_BYTOFF
, 1, 1),
497 DEF(lituse_jsr
, DUMMY_RELOC_LITUSE_JSR
, 1, 1),
498 DEF(gpdisp
, BFD_RELOC_ALPHA_GPDISP
, 1, 1),
499 DEF(gprelhigh
, BFD_RELOC_ALPHA_GPREL_HI16
, 0, 0),
500 DEF(gprellow
, BFD_RELOC_ALPHA_GPREL_LO16
, 0, 0),
501 DEF(gprel
, BFD_RELOC_GPREL16
, 0, 0)
506 static const int alpha_num_reloc_op
507 = sizeof (alpha_reloc_op
) / sizeof (*alpha_reloc_op
);
508 #endif /* RELOC_OP_P */
510 /* Maximum # digits needed to hold the largest sequence # */
511 #define ALPHA_RELOC_DIGITS 25
513 /* Structure to hold explict sequence information. */
514 struct alpha_reloc_tag
516 fixS
*slaves
; /* head of linked list of !literals */
517 segT segment
; /* segment relocs are in or undefined_section*/
518 long sequence
; /* sequence # */
519 unsigned n_master
; /* # of literals */
520 unsigned n_slaves
; /* # of lituses */
521 char multi_section_p
; /* True if more than one section was used */
522 char string
[1]; /* printable form of sequence to hash with */
525 /* Hash table to link up literals with the appropriate lituse */
526 static struct hash_control
*alpha_literal_hash
;
528 /* Sequence numbers for internal use by macros. */
529 static long next_sequence_num
= -1;
531 /* A table of CPU names and opcode sets. */
533 static const struct cpu_type
{
537 /* Ad hoc convention: cpu number gets palcode, process code doesn't.
538 This supports usage under DU 4.0b that does ".arch ev4", and
539 usage in MILO that does -m21064. Probably something more
540 specific like -m21064-pal should be used, but oh well. */
542 { "21064", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
543 { "21064a", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
544 { "21066", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
545 { "21068", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
546 { "21164", AXP_OPCODE_BASE
|AXP_OPCODE_EV5
},
547 { "21164a", AXP_OPCODE_BASE
|AXP_OPCODE_EV5
|AXP_OPCODE_BWX
},
548 { "21164pc", (AXP_OPCODE_BASE
|AXP_OPCODE_EV5
|AXP_OPCODE_BWX
550 { "21264", (AXP_OPCODE_BASE
|AXP_OPCODE_EV6
|AXP_OPCODE_BWX
551 |AXP_OPCODE_MAX
|AXP_OPCODE_CIX
) },
553 { "ev4", AXP_OPCODE_BASE
},
554 { "ev45", AXP_OPCODE_BASE
},
555 { "lca45", AXP_OPCODE_BASE
},
556 { "ev5", AXP_OPCODE_BASE
},
557 { "ev56", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
},
558 { "pca56", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
|AXP_OPCODE_MAX
},
559 { "ev6", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
|AXP_OPCODE_MAX
|AXP_OPCODE_CIX
},
561 { "all", AXP_OPCODE_BASE
},
565 /* The macro table */
567 static const struct alpha_macro alpha_macros
[] = {
568 /* Load/Store macros */
569 { "lda", emit_lda
, NULL
,
570 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
571 { "ldah", emit_ldah
, NULL
,
572 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
574 { "ldl", emit_ir_load
, "ldl",
575 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
576 { "ldl_l", emit_ir_load
, "ldl_l",
577 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
578 { "ldq", emit_ir_load
, "ldq",
579 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
580 { "ldq_l", emit_ir_load
, "ldq_l",
581 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
582 { "ldq_u", emit_ir_load
, "ldq_u",
583 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
584 { "ldf", emit_loadstore
, "ldf",
585 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
586 { "ldg", emit_loadstore
, "ldg",
587 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
588 { "lds", emit_loadstore
, "lds",
589 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
590 { "ldt", emit_loadstore
, "ldt",
591 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
593 { "ldb", emit_ldX
, (PTR
) 0,
594 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
595 { "ldbu", emit_ldXu
, (PTR
) 0,
596 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
597 { "ldw", emit_ldX
, (PTR
) 1,
598 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
599 { "ldwu", emit_ldXu
, (PTR
) 1,
600 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
602 { "uldw", emit_uldX
, (PTR
) 1,
603 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
604 { "uldwu", emit_uldXu
, (PTR
) 1,
605 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
606 { "uldl", emit_uldX
, (PTR
) 2,
607 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
608 { "uldlu", emit_uldXu
, (PTR
) 2,
609 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
610 { "uldq", emit_uldXu
, (PTR
) 3,
611 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
613 { "ldgp", emit_ldgp
, NULL
,
614 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
} },
616 { "ldi", emit_lda
, NULL
,
617 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
618 { "ldil", emit_ldil
, NULL
,
619 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
620 { "ldiq", emit_lda
, NULL
,
621 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
623 { "ldif" emit_ldiq
, NULL
,
624 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
625 { "ldid" emit_ldiq
, NULL
,
626 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
627 { "ldig" emit_ldiq
, NULL
,
628 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
629 { "ldis" emit_ldiq
, NULL
,
630 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
631 { "ldit" emit_ldiq
, NULL
,
632 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
635 { "stl", emit_loadstore
, "stl",
636 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
637 { "stl_c", emit_loadstore
, "stl_c",
638 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
639 { "stq", emit_loadstore
, "stq",
640 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
641 { "stq_c", emit_loadstore
, "stq_c",
642 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
643 { "stq_u", emit_loadstore
, "stq_u",
644 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
645 { "stf", emit_loadstore
, "stf",
646 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
647 { "stg", emit_loadstore
, "stg",
648 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
649 { "sts", emit_loadstore
, "sts",
650 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
651 { "stt", emit_loadstore
, "stt",
652 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
654 { "stb", emit_stX
, (PTR
) 0,
655 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
656 { "stw", emit_stX
, (PTR
) 1,
657 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
658 { "ustw", emit_ustX
, (PTR
) 1,
659 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
660 { "ustl", emit_ustX
, (PTR
) 2,
661 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
662 { "ustq", emit_ustX
, (PTR
) 3,
663 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
665 /* Arithmetic macros */
667 { "absl" emit_absl
, 1, { IR
} },
668 { "absl" emit_absl
, 2, { IR
, IR
} },
669 { "absl" emit_absl
, 2, { EXP
, IR
} },
670 { "absq" emit_absq
, 1, { IR
} },
671 { "absq" emit_absq
, 2, { IR
, IR
} },
672 { "absq" emit_absq
, 2, { EXP
, IR
} },
675 { "sextb", emit_sextX
, (PTR
) 0,
676 { MACRO_IR
, MACRO_IR
, MACRO_EOA
,
678 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
679 { "sextw", emit_sextX
, (PTR
) 1,
680 { MACRO_IR
, MACRO_IR
, MACRO_EOA
,
682 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
684 { "divl", emit_division
, "__divl",
685 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
686 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
687 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
688 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
689 { "divlu", emit_division
, "__divlu",
690 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
691 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
692 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
693 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
694 { "divq", emit_division
, "__divq",
695 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
696 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
697 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
698 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
699 { "divqu", emit_division
, "__divqu",
700 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
701 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
702 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
703 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
704 { "reml", emit_division
, "__reml",
705 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
706 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
707 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
708 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
709 { "remlu", emit_division
, "__remlu",
710 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
711 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
712 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
713 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
714 { "remq", emit_division
, "__remq",
715 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
716 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
717 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
718 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
719 { "remqu", emit_division
, "__remqu",
720 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
721 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
722 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
723 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
725 { "jsr", emit_jsrjmp
, "jsr",
726 { MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
727 MACRO_PIR
, MACRO_EOA
,
728 MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
729 MACRO_EXP
, MACRO_EOA
} },
730 { "jmp", emit_jsrjmp
, "jmp",
731 { MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
732 MACRO_PIR
, MACRO_EOA
,
733 MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
734 MACRO_EXP
, MACRO_EOA
} },
735 { "ret", emit_retjcr
, "ret",
736 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
738 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
739 MACRO_PIR
, MACRO_EOA
,
740 MACRO_EXP
, MACRO_EOA
,
742 { "jcr", emit_retjcr
, "jcr",
743 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
745 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
746 MACRO_PIR
, MACRO_EOA
,
747 MACRO_EXP
, MACRO_EOA
,
749 { "jsr_coroutine", emit_retjcr
, "jcr",
750 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
752 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
753 MACRO_PIR
, MACRO_EOA
,
754 MACRO_EXP
, MACRO_EOA
,
758 static const unsigned int alpha_num_macros
759 = sizeof (alpha_macros
) / sizeof (*alpha_macros
);
761 /* Public interface functions */
763 /* This function is called once, at assembler startup time. It sets
764 up all the tables, etc. that the MD part of the assembler will
765 need, that can be determined before arguments are parsed. */
772 /* Verify that X_op field is wide enough. */
776 assert (e
.X_op
== O_max
);
779 /* Create the opcode hash table */
781 alpha_opcode_hash
= hash_new ();
782 for (i
= 0; i
< alpha_num_opcodes
;)
784 const char *name
, *retval
, *slash
;
786 name
= alpha_opcodes
[i
].name
;
787 retval
= hash_insert (alpha_opcode_hash
, name
, (PTR
) &alpha_opcodes
[i
]);
789 as_fatal (_("internal error: can't hash opcode `%s': %s"),
792 /* Some opcodes include modifiers of various sorts with a "/mod"
793 syntax, like the architecture manual suggests. However, for
794 use with gcc at least, we also need access to those same opcodes
797 if ((slash
= strchr (name
, '/')) != NULL
)
799 char *p
= xmalloc (strlen (name
));
800 memcpy (p
, name
, slash
- name
);
801 strcpy (p
+ (slash
- name
), slash
+ 1);
803 (void) hash_insert (alpha_opcode_hash
, p
, (PTR
) &alpha_opcodes
[i
]);
804 /* Ignore failures -- the opcode table does duplicate some
805 variants in different forms, like "hw_stq" and "hw_st/q". */
808 while (++i
< alpha_num_opcodes
809 && (alpha_opcodes
[i
].name
== name
810 || !strcmp (alpha_opcodes
[i
].name
, name
)))
814 /* Create the macro hash table */
816 alpha_macro_hash
= hash_new ();
817 for (i
= 0; i
< alpha_num_macros
;)
819 const char *name
, *retval
;
821 name
= alpha_macros
[i
].name
;
822 retval
= hash_insert (alpha_macro_hash
, name
, (PTR
) &alpha_macros
[i
]);
824 as_fatal (_("internal error: can't hash macro `%s': %s"),
827 while (++i
< alpha_num_macros
828 && (alpha_macros
[i
].name
== name
829 || !strcmp (alpha_macros
[i
].name
, name
)))
833 /* Construct symbols for each of the registers */
835 for (i
= 0; i
< 32; ++i
)
838 sprintf (name
, "$%d", i
);
839 alpha_register_table
[i
] = symbol_create (name
, reg_section
, i
,
845 sprintf (name
, "$f%d", i
- 32);
846 alpha_register_table
[i
] = symbol_create (name
, reg_section
, i
,
850 /* Create the special symbols and sections we'll be using */
852 /* So .sbss will get used for tiny objects. */
853 bfd_set_gp_size (stdoutput
, g_switch_value
);
856 create_literal_section (".lita", &alpha_lita_section
, &alpha_lita_symbol
);
858 /* For handling the GP, create a symbol that won't be output in the
859 symbol table. We'll edit it out of relocs later. */
860 alpha_gp_symbol
= symbol_create ("<GP value>", alpha_lita_section
, 0x8000,
865 create_literal_section (".link", &alpha_link_section
, &alpha_link_symbol
);
871 segT sec
= subseg_new (".mdebug", (subsegT
) 0);
872 bfd_set_section_flags (stdoutput
, sec
, SEC_HAS_CONTENTS
| SEC_READONLY
);
873 bfd_set_section_alignment (stdoutput
, sec
, 3);
877 /* Create literal lookup hash table. */
878 alpha_literal_hash
= hash_new ();
880 subseg_set (text_section
, 0);
883 /* The public interface to the instruction assembler. */
889 char opname
[32]; /* current maximum is 13 */
890 expressionS tok
[MAX_INSN_ARGS
];
894 /* split off the opcode */
895 opnamelen
= strspn (str
, "abcdefghijklmnopqrstuvwxyz_/46819");
896 trunclen
= (opnamelen
< sizeof (opname
) - 1
898 : sizeof (opname
) - 1);
899 memcpy (opname
, str
, trunclen
);
900 opname
[trunclen
] = '\0';
902 /* tokenize the rest of the line */
903 if ((ntok
= tokenize_arguments (str
+ opnamelen
, tok
, MAX_INSN_ARGS
)) < 0)
905 if (ntok
!= TOKENIZE_ERROR_REPORT
)
906 as_bad (_("syntax error"));
912 assemble_tokens (opname
, tok
, ntok
, alpha_macros_on
);
915 /* Round up a section's size to the appropriate boundary. */
918 md_section_align (seg
, size
)
922 int align
= bfd_get_section_alignment (stdoutput
, seg
);
923 valueT mask
= ((valueT
) 1 << align
) - 1;
925 return (size
+ mask
) & ~mask
;
928 /* Turn a string in input_line_pointer into a floating point constant
929 of type TYPE, and store the appropriate bytes in *LITP. The number
930 of LITTLENUMS emitted is stored in *SIZEP. An error message is
931 returned, or NULL on OK. */
933 /* Equal to MAX_PRECISION in atof-ieee.c */
934 #define MAX_LITTLENUMS 6
936 extern char *vax_md_atof
PARAMS ((int, char *, int *));
939 md_atof (type
, litP
, sizeP
)
945 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
946 LITTLENUM_TYPE
*wordP
;
953 /* VAX md_atof doesn't like "G" for some reason. */
957 return vax_md_atof (type
, litP
, sizeP
);
980 return _("Bad call to MD_ATOF()");
982 t
= atof_ieee (input_line_pointer
, type
, words
);
984 input_line_pointer
= t
;
985 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
987 for (wordP
= words
+ prec
- 1; prec
--;)
989 md_number_to_chars (litP
, (long) (*wordP
--), sizeof (LITTLENUM_TYPE
));
990 litP
+= sizeof (LITTLENUM_TYPE
);
996 /* Take care of the target-specific command-line options. */
999 md_parse_option (c
, arg
)
1006 alpha_nofloats_on
= 1;
1010 alpha_addr32_on
= 1;
1018 g_switch_value
= atoi (arg
);
1023 const struct cpu_type
*p
;
1024 for (p
= cpu_types
; p
->name
; ++p
)
1025 if (strcmp (arg
, p
->name
) == 0)
1027 alpha_target_name
= p
->name
, alpha_target
= p
->flags
;
1030 as_warn (_("Unknown CPU identifier `%s'"), arg
);
1036 case '+': /* For g++. Hash any name > 63 chars long. */
1037 alpha_flag_hash_long_names
= 1;
1040 case 'H': /* Show new symbol after hash truncation */
1041 alpha_flag_show_after_trunc
= 1;
1044 case 'h': /* for gnu-c/vax compatibility. */
1049 alpha_flag_relax
= 1;
1054 alpha_flag_mdebug
= 1;
1056 case OPTION_NO_MDEBUG
:
1057 alpha_flag_mdebug
= 0;
1068 /* Print a description of the command-line options that we accept. */
1071 md_show_usage (stream
)
1076 -32addr treat addresses as 32-bit values\n\
1077 -F lack floating point instructions support\n\
1078 -mev4 | -mev45 | -mev5 | -mev56 | -mpca56 | -mev6 | -mall\n\
1079 specify variant of Alpha architecture\n\
1080 -m21064 | -m21066 | -m21164 | -m21164a | -m21164pc | -m21264\n\
1081 these variants include PALcode opcodes\n"),
1086 -+ hash encode (don't truncate) names longer than 64 characters\n\
1087 -H show new symbol after hash truncation\n"),
1092 /* Decide from what point a pc-relative relocation is relative to,
1093 relative to the pc-relative fixup. Er, relatively speaking. */
1096 md_pcrel_from (fixP
)
1099 valueT addr
= fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
1100 switch (fixP
->fx_r_type
)
1102 case BFD_RELOC_ALPHA_GPDISP
:
1103 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1104 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1107 return fixP
->fx_size
+ addr
;
1111 /* Attempt to simplify or even eliminate a fixup. The return value is
1112 ignored; perhaps it was once meaningful, but now it is historical.
1113 To indicate that a fixup has been eliminated, set fixP->fx_done.
1115 For ELF, here it is that we transform the GPDISP_HI16 reloc we used
1116 internally into the GPDISP reloc used externally. We had to do
1117 this so that we'd have the GPDISP_LO16 reloc as a tag to compute
1118 the distance to the "lda" instruction for setting the addend to
1122 md_apply_fix3 (fixP
, valP
, seg
)
1127 char * const fixpos
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
1128 valueT value
= * valP
;
1129 unsigned image
, size
;
1131 switch (fixP
->fx_r_type
)
1133 /* The GPDISP relocations are processed internally with a symbol
1134 referring to the current function; we need to drop in a value
1135 which, when added to the address of the start of the function,
1136 gives the desired GP. */
1137 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1139 fixS
*next
= fixP
->fx_next
;
1141 /* With user-specified !gpdisp relocations, we can be missing
1142 the matching LO16 reloc. We will have already issued an
1145 fixP
->fx_offset
= (next
->fx_frag
->fr_address
+ next
->fx_where
1146 - fixP
->fx_frag
->fr_address
- fixP
->fx_where
);
1148 value
= (value
- sign_extend_16 (value
)) >> 16;
1151 fixP
->fx_r_type
= BFD_RELOC_ALPHA_GPDISP
;
1155 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1156 value
= sign_extend_16 (value
);
1157 fixP
->fx_offset
= 0;
1163 fixP
->fx_addsy
= section_symbol (seg
);
1164 md_number_to_chars (fixpos
, value
, 2);
1169 fixP
->fx_r_type
= BFD_RELOC_16_PCREL
;
1174 fixP
->fx_r_type
= BFD_RELOC_32_PCREL
;
1179 fixP
->fx_r_type
= BFD_RELOC_64_PCREL
;
1182 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
1184 md_number_to_chars (fixpos
, value
, size
);
1190 case BFD_RELOC_GPREL32
:
1191 assert (fixP
->fx_subsy
== alpha_gp_symbol
);
1193 /* FIXME: inherited this obliviousness of `value' -- why? */
1194 md_number_to_chars (fixpos
, -alpha_gp_value
, 4);
1197 case BFD_RELOC_GPREL32
:
1199 case BFD_RELOC_GPREL16
:
1200 case BFD_RELOC_ALPHA_GPREL_HI16
:
1201 case BFD_RELOC_ALPHA_GPREL_LO16
:
1204 case BFD_RELOC_23_PCREL_S2
:
1205 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
1207 image
= bfd_getl32 (fixpos
);
1208 image
= (image
& ~0x1FFFFF) | ((value
>> 2) & 0x1FFFFF);
1213 case BFD_RELOC_ALPHA_HINT
:
1214 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
1216 image
= bfd_getl32 (fixpos
);
1217 image
= (image
& ~0x3FFF) | ((value
>> 2) & 0x3FFF);
1223 case BFD_RELOC_ALPHA_LITERAL
:
1224 md_number_to_chars (fixpos
, value
, 2);
1227 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1228 case BFD_RELOC_ALPHA_LITUSE
:
1229 case BFD_RELOC_ALPHA_LINKAGE
:
1230 case BFD_RELOC_ALPHA_CODEADDR
:
1233 case BFD_RELOC_VTABLE_INHERIT
:
1234 case BFD_RELOC_VTABLE_ENTRY
:
1239 const struct alpha_operand
*operand
;
1241 if ((int) fixP
->fx_r_type
>= 0)
1242 as_fatal (_("unhandled relocation type %s"),
1243 bfd_get_reloc_code_name (fixP
->fx_r_type
));
1245 assert (-(int) fixP
->fx_r_type
< (int) alpha_num_operands
);
1246 operand
= &alpha_operands
[-(int) fixP
->fx_r_type
];
1248 /* The rest of these fixups only exist internally during symbol
1249 resolution and have no representation in the object file.
1250 Therefore they must be completely resolved as constants. */
1252 if (fixP
->fx_addsy
!= 0
1253 && S_GET_SEGMENT (fixP
->fx_addsy
) != absolute_section
)
1254 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
1255 _("non-absolute expression in constant field"));
1257 image
= bfd_getl32 (fixpos
);
1258 image
= insert_operand (image
, operand
, (offsetT
) value
,
1259 fixP
->fx_file
, fixP
->fx_line
);
1264 if (fixP
->fx_addsy
!= 0 || fixP
->fx_pcrel
!= 0)
1268 as_warn_where (fixP
->fx_file
, fixP
->fx_line
,
1269 _("type %d reloc done?\n"), (int) fixP
->fx_r_type
);
1274 md_number_to_chars (fixpos
, image
, 4);
1280 /* Look for a register name in the given symbol. */
1283 md_undefined_symbol (name
)
1288 int is_float
= 0, num
;
1293 if (name
[1] == 'p' && name
[2] == '\0')
1294 return alpha_register_table
[AXP_REG_FP
];
1299 if (!ISDIGIT (*++name
))
1303 case '0': case '1': case '2': case '3': case '4':
1304 case '5': case '6': case '7': case '8': case '9':
1305 if (name
[1] == '\0')
1306 num
= name
[0] - '0';
1307 else if (name
[0] != '0' && ISDIGIT (name
[1]) && name
[2] == '\0')
1309 num
= (name
[0] - '0') * 10 + name
[1] - '0';
1316 if (!alpha_noat_on
&& (num
+ is_float
) == AXP_REG_AT
)
1317 as_warn (_("Used $at without \".set noat\""));
1318 return alpha_register_table
[num
+ is_float
];
1321 if (name
[1] == 't' && name
[2] == '\0')
1324 as_warn (_("Used $at without \".set noat\""));
1325 return alpha_register_table
[AXP_REG_AT
];
1330 if (name
[1] == 'p' && name
[2] == '\0')
1331 return alpha_register_table
[alpha_gp_register
];
1335 if (name
[1] == 'p' && name
[2] == '\0')
1336 return alpha_register_table
[AXP_REG_SP
];
1344 /* @@@ Magic ECOFF bits. */
1347 alpha_frob_ecoff_data ()
1350 /* $zero and $f31 are read-only */
1351 alpha_gprmask
&= ~1;
1352 alpha_fprmask
&= ~1;
1356 /* Hook to remember a recently defined label so that the auto-align
1357 code can adjust the symbol after we know what alignment will be
1361 alpha_define_label (sym
)
1364 alpha_insn_label
= sym
;
1367 /* Return true if we must always emit a reloc for a type and false if
1368 there is some hope of resolving it at assembly time. */
1371 alpha_force_relocation (f
)
1374 if (alpha_flag_relax
)
1377 switch (f
->fx_r_type
)
1379 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1380 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1381 case BFD_RELOC_ALPHA_GPDISP
:
1382 case BFD_RELOC_ALPHA_LITERAL
:
1383 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1384 case BFD_RELOC_ALPHA_LITUSE
:
1385 case BFD_RELOC_GPREL16
:
1386 case BFD_RELOC_GPREL32
:
1387 case BFD_RELOC_ALPHA_GPREL_HI16
:
1388 case BFD_RELOC_ALPHA_GPREL_LO16
:
1389 case BFD_RELOC_ALPHA_LINKAGE
:
1390 case BFD_RELOC_ALPHA_CODEADDR
:
1391 case BFD_RELOC_VTABLE_INHERIT
:
1392 case BFD_RELOC_VTABLE_ENTRY
:
1395 case BFD_RELOC_23_PCREL_S2
:
1398 case BFD_RELOC_ALPHA_HINT
:
1402 assert ((int) f
->fx_r_type
< 0
1403 && -(int) f
->fx_r_type
< (int) alpha_num_operands
);
1408 /* Return true if we can partially resolve a relocation now. */
1411 alpha_fix_adjustable (f
)
1415 /* Prevent all adjustments to global symbols */
1416 if (S_IS_EXTERN (f
->fx_addsy
) || S_IS_WEAK (f
->fx_addsy
))
1420 /* Are there any relocation types for which we must generate a reloc
1421 but we can adjust the values contained within it? */
1422 switch (f
->fx_r_type
)
1424 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1425 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1426 case BFD_RELOC_ALPHA_GPDISP
:
1429 case BFD_RELOC_ALPHA_LITERAL
:
1430 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1431 case BFD_RELOC_ALPHA_LITUSE
:
1432 case BFD_RELOC_ALPHA_LINKAGE
:
1433 case BFD_RELOC_ALPHA_CODEADDR
:
1436 case BFD_RELOC_VTABLE_ENTRY
:
1437 case BFD_RELOC_VTABLE_INHERIT
:
1440 case BFD_RELOC_GPREL16
:
1441 case BFD_RELOC_GPREL32
:
1442 case BFD_RELOC_ALPHA_GPREL_HI16
:
1443 case BFD_RELOC_ALPHA_GPREL_LO16
:
1444 case BFD_RELOC_23_PCREL_S2
:
1447 case BFD_RELOC_ALPHA_HINT
:
1451 assert ((int) f
->fx_r_type
< 0
1452 && - (int) f
->fx_r_type
< (int) alpha_num_operands
);
1458 /* Generate the BFD reloc to be stuck in the object file from the
1459 fixup used internally in the assembler. */
1462 tc_gen_reloc (sec
, fixp
)
1463 asection
*sec ATTRIBUTE_UNUSED
;
1468 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
1469 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
1470 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
1471 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
1473 /* Make sure none of our internal relocations make it this far.
1474 They'd better have been fully resolved by this point. */
1475 assert ((int) fixp
->fx_r_type
> 0);
1477 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
1478 if (reloc
->howto
== NULL
)
1480 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1481 _("cannot represent `%s' relocation in object file"),
1482 bfd_get_reloc_code_name (fixp
->fx_r_type
));
1486 if (!fixp
->fx_pcrel
!= !reloc
->howto
->pc_relative
)
1488 as_fatal (_("internal error? cannot generate `%s' relocation"),
1489 bfd_get_reloc_code_name (fixp
->fx_r_type
));
1491 assert (!fixp
->fx_pcrel
== !reloc
->howto
->pc_relative
);
1494 if (fixp
->fx_r_type
== BFD_RELOC_ALPHA_LITERAL
)
1496 /* fake out bfd_perform_relocation. sigh */
1497 reloc
->addend
= -alpha_gp_value
;
1502 reloc
->addend
= fixp
->fx_offset
;
1505 * Ohhh, this is ugly. The problem is that if this is a local global
1506 * symbol, the relocation will entirely be performed at link time, not
1507 * at assembly time. bfd_perform_reloc doesn't know about this sort
1508 * of thing, and as a result we need to fake it out here.
1510 if ((S_IS_EXTERN (fixp
->fx_addsy
) || S_IS_WEAK (fixp
->fx_addsy
)
1511 || (S_GET_SEGMENT (fixp
->fx_addsy
)->flags
& SEC_MERGE
))
1512 && !S_IS_COMMON (fixp
->fx_addsy
))
1513 reloc
->addend
-= symbol_get_bfdsym (fixp
->fx_addsy
)->value
;
1520 /* Parse a register name off of the input_line and return a register
1521 number. Gets md_undefined_symbol above to do the register name
1524 Only called as a part of processing the ECOFF .frame directive. */
1527 tc_get_register (frame
)
1528 int frame ATTRIBUTE_UNUSED
;
1530 int framereg
= AXP_REG_SP
;
1533 if (*input_line_pointer
== '$')
1535 char *s
= input_line_pointer
;
1536 char c
= get_symbol_end ();
1537 symbolS
*sym
= md_undefined_symbol (s
);
1539 *strchr (s
, '\0') = c
;
1540 if (sym
&& (framereg
= S_GET_VALUE (sym
)) <= 31)
1543 as_warn (_("frame reg expected, using $%d."), framereg
);
1546 note_gpreg (framereg
);
1550 /* This is called before the symbol table is processed. In order to
1551 work with gcc when using mips-tfile, we must keep all local labels.
1552 However, in other cases, we want to discard them. If we were
1553 called with -g, but we didn't see any debugging information, it may
1554 mean that gcc is smuggling debugging information through to
1555 mips-tfile, in which case we must generate all local labels. */
1560 alpha_frob_file_before_adjust ()
1562 if (alpha_debug
!= 0
1563 && ! ecoff_debugging_seen
)
1564 flag_keep_locals
= 1;
1567 #endif /* OBJ_ECOFF */
1569 static struct alpha_reloc_tag
*
1570 get_alpha_reloc_tag (sequence
)
1573 char buffer
[ALPHA_RELOC_DIGITS
];
1574 struct alpha_reloc_tag
*info
;
1576 sprintf (buffer
, "!%ld", sequence
);
1578 info
= (struct alpha_reloc_tag
*) hash_find (alpha_literal_hash
, buffer
);
1581 size_t len
= strlen (buffer
);
1584 info
= (struct alpha_reloc_tag
*)
1585 xcalloc (sizeof (struct alpha_reloc_tag
) + len
, 1);
1587 info
->segment
= now_seg
;
1588 info
->sequence
= sequence
;
1589 strcpy (info
->string
, buffer
);
1590 errmsg
= hash_insert (alpha_literal_hash
, info
->string
, (PTR
) info
);
1598 /* Before the relocations are written, reorder them, so that user
1599 supplied !lituse relocations follow the appropriate !literal
1600 relocations, and similarly for !gpdisp relocations. */
1603 alpha_adjust_symtab ()
1605 if (alpha_literal_hash
)
1606 bfd_map_over_sections (stdoutput
, alpha_adjust_symtab_relocs
, NULL
);
1610 alpha_adjust_symtab_relocs (abfd
, sec
, ptr
)
1611 bfd
*abfd ATTRIBUTE_UNUSED
;
1613 PTR ptr ATTRIBUTE_UNUSED
;
1615 segment_info_type
*seginfo
= seg_info (sec
);
1620 unsigned long n_slaves
= 0;
1622 /* If seginfo is NULL, we did not create this section; don't do
1623 anything with it. By using a pointer to a pointer, we can update
1624 the links in place. */
1625 if (seginfo
== NULL
)
1628 /* If there are no relocations, skip the section. */
1629 if (! seginfo
->fix_root
)
1632 /* First rebuild the fixup chain without the expicit lituse and
1633 gpdisp_lo16 relocs. */
1634 prevP
= &seginfo
->fix_root
;
1635 for (fixp
= seginfo
->fix_root
; fixp
; fixp
= next
)
1637 next
= fixp
->fx_next
;
1638 fixp
->fx_next
= (fixS
*) 0;
1640 switch (fixp
->fx_r_type
)
1642 case BFD_RELOC_ALPHA_LITUSE
:
1644 if (fixp
->tc_fix_data
.info
->n_master
== 0)
1645 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1646 _("No !literal!%ld was found"),
1647 fixp
->tc_fix_data
.info
->sequence
);
1650 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1652 if (fixp
->tc_fix_data
.info
->n_master
== 0)
1653 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1654 _("No ldah !gpdisp!%ld was found"),
1655 fixp
->tc_fix_data
.info
->sequence
);
1660 prevP
= &fixp
->fx_next
;
1665 /* If there were any dependent relocations, go and add them back to
1666 the chain. They are linked through the next_reloc field in
1667 reverse order, so as we go through the next_reloc chain, we
1668 effectively reverse the chain once again.
1670 Except if there is more than one !literal for a given sequence
1671 number. In that case, the programmer and/or compiler is not sure
1672 how control flows from literal to lituse, and we can't be sure to
1673 get the relaxation correct.
1675 ??? Well, actually we could, if there are enough lituses such that
1676 we can make each literal have at least one of each lituse type
1677 present. Not implemented.
1679 Also suppress the optimization if the !literals/!lituses are spread
1680 in different segments. This can happen with "intersting" uses of
1681 inline assembly; examples are present in the Linux kernel semaphores. */
1683 for (fixp
= seginfo
->fix_root
; fixp
; fixp
= next
)
1685 next
= fixp
->fx_next
;
1686 switch (fixp
->fx_r_type
)
1688 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1689 if (fixp
->tc_fix_data
.info
->n_master
== 1
1690 && ! fixp
->tc_fix_data
.info
->multi_section_p
)
1692 for (slave
= fixp
->tc_fix_data
.info
->slaves
;
1693 slave
!= (fixS
*) 0;
1694 slave
= slave
->tc_fix_data
.next_reloc
)
1696 slave
->fx_next
= fixp
->fx_next
;
1697 fixp
->fx_next
= slave
;
1702 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1703 if (fixp
->tc_fix_data
.info
->n_slaves
== 0)
1704 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1705 _("No lda !gpdisp!%ld was found"),
1706 fixp
->tc_fix_data
.info
->sequence
);
1709 slave
= fixp
->tc_fix_data
.info
->slaves
;
1710 slave
->fx_next
= next
;
1711 fixp
->fx_next
= slave
;
1723 debug_exp (tok
, ntok
)
1729 fprintf (stderr
, "debug_exp: %d tokens", ntok
);
1730 for (i
= 0; i
< ntok
; i
++)
1732 expressionS
*t
= &tok
[i
];
1736 default: name
= "unknown"; break;
1737 case O_illegal
: name
= "O_illegal"; break;
1738 case O_absent
: name
= "O_absent"; break;
1739 case O_constant
: name
= "O_constant"; break;
1740 case O_symbol
: name
= "O_symbol"; break;
1741 case O_symbol_rva
: name
= "O_symbol_rva"; break;
1742 case O_register
: name
= "O_register"; break;
1743 case O_big
: name
= "O_big"; break;
1744 case O_uminus
: name
= "O_uminus"; break;
1745 case O_bit_not
: name
= "O_bit_not"; break;
1746 case O_logical_not
: name
= "O_logical_not"; break;
1747 case O_multiply
: name
= "O_multiply"; break;
1748 case O_divide
: name
= "O_divide"; break;
1749 case O_modulus
: name
= "O_modulus"; break;
1750 case O_left_shift
: name
= "O_left_shift"; break;
1751 case O_right_shift
: name
= "O_right_shift"; break;
1752 case O_bit_inclusive_or
: name
= "O_bit_inclusive_or"; break;
1753 case O_bit_or_not
: name
= "O_bit_or_not"; break;
1754 case O_bit_exclusive_or
: name
= "O_bit_exclusive_or"; break;
1755 case O_bit_and
: name
= "O_bit_and"; break;
1756 case O_add
: name
= "O_add"; break;
1757 case O_subtract
: name
= "O_subtract"; break;
1758 case O_eq
: name
= "O_eq"; break;
1759 case O_ne
: name
= "O_ne"; break;
1760 case O_lt
: name
= "O_lt"; break;
1761 case O_le
: name
= "O_le"; break;
1762 case O_ge
: name
= "O_ge"; break;
1763 case O_gt
: name
= "O_gt"; break;
1764 case O_logical_and
: name
= "O_logical_and"; break;
1765 case O_logical_or
: name
= "O_logical_or"; break;
1766 case O_index
: name
= "O_index"; break;
1767 case O_pregister
: name
= "O_pregister"; break;
1768 case O_cpregister
: name
= "O_cpregister"; break;
1769 case O_literal
: name
= "O_literal"; break;
1770 case O_lituse_base
: name
= "O_lituse_base"; break;
1771 case O_lituse_bytoff
: name
= "O_lituse_bytoff"; break;
1772 case O_lituse_jsr
: name
= "O_lituse_jsr"; break;
1773 case O_gpdisp
: name
= "O_gpdisp"; break;
1774 case O_gprelhigh
: name
= "O_gprelhigh"; break;
1775 case O_gprellow
: name
= "O_gprellow"; break;
1776 case O_gprel
: name
= "O_gprel"; break;
1777 case O_md11
: name
= "O_md11"; break;
1778 case O_md12
: name
= "O_md12"; break;
1779 case O_md13
: name
= "O_md13"; break;
1780 case O_md14
: name
= "O_md14"; break;
1781 case O_md15
: name
= "O_md15"; break;
1782 case O_md16
: name
= "O_md16"; break;
1785 fprintf (stderr
, ", %s(%s, %s, %d)", name
,
1786 (t
->X_add_symbol
) ? S_GET_NAME (t
->X_add_symbol
) : "--",
1787 (t
->X_op_symbol
) ? S_GET_NAME (t
->X_op_symbol
) : "--",
1788 (int) t
->X_add_number
);
1790 fprintf (stderr
, "\n");
1795 /* Parse the arguments to an opcode. */
1798 tokenize_arguments (str
, tok
, ntok
)
1803 expressionS
*end_tok
= tok
+ ntok
;
1804 char *old_input_line_pointer
;
1805 int saw_comma
= 0, saw_arg
= 0;
1807 expressionS
*orig_tok
= tok
;
1810 const struct alpha_reloc_op_tag
*r
;
1813 int reloc_found_p
= 0;
1815 memset (tok
, 0, sizeof (*tok
) * ntok
);
1817 /* Save and restore input_line_pointer around this function */
1818 old_input_line_pointer
= input_line_pointer
;
1819 input_line_pointer
= str
;
1822 /* ??? Wrest control of ! away from the regular expression parser. */
1823 is_end_of_line
[(unsigned char) '!'] = 1;
1826 while (tok
< end_tok
&& *input_line_pointer
)
1829 switch (*input_line_pointer
)
1836 /* A relocation operand can be placed after the normal operand on an
1837 assembly language statement, and has the following form:
1838 !relocation_type!sequence_number. */
1840 { /* only support one relocation op per insn */
1841 as_bad (_("More than one relocation op per insn"));
1848 ++input_line_pointer
;
1850 p
= input_line_pointer
;
1851 c
= get_symbol_end ();
1853 /* Parse !relocation_type */
1854 len
= input_line_pointer
- p
;
1857 as_bad (_("No relocation operand"));
1861 r
= &alpha_reloc_op
[0];
1862 for (i
= alpha_num_reloc_op
- 1; i
>= 0; i
--, r
++)
1863 if (len
== r
->length
&& memcmp (p
, r
->name
, len
) == 0)
1867 as_bad (_("Unknown relocation operand: !%s"), p
);
1871 *input_line_pointer
= c
;
1873 if (*input_line_pointer
!= '!')
1877 as_bad (_("no sequence number after !%s"), p
);
1881 tok
->X_add_number
= 0;
1887 as_bad (_("!%s does not use a sequence number"), p
);
1891 input_line_pointer
++;
1893 /* Parse !sequence_number */
1895 if (tok
->X_op
!= O_constant
|| tok
->X_add_number
<= 0)
1897 as_bad (_("Bad sequence number: !%s!%s"),
1898 r
->name
, input_line_pointer
);
1907 #endif /* RELOC_OP_P */
1910 ++input_line_pointer
;
1911 if (saw_comma
|| !saw_arg
)
1918 char *hold
= input_line_pointer
++;
1920 /* First try for parenthesized register ... */
1922 if (*input_line_pointer
== ')' && tok
->X_op
== O_register
)
1924 tok
->X_op
= (saw_comma
? O_cpregister
: O_pregister
);
1927 ++input_line_pointer
;
1932 /* ... then fall through to plain expression */
1933 input_line_pointer
= hold
;
1937 if (saw_arg
&& !saw_comma
)
1941 if (tok
->X_op
== O_illegal
|| tok
->X_op
== O_absent
)
1954 input_line_pointer
= old_input_line_pointer
;
1957 debug_exp (orig_tok
, ntok
- (end_tok
- tok
));
1960 is_end_of_line
[(unsigned char) '!'] = 0;
1963 return ntok
- (end_tok
- tok
);
1967 is_end_of_line
[(unsigned char) '!'] = 0;
1969 input_line_pointer
= old_input_line_pointer
;
1970 return TOKENIZE_ERROR
;
1974 is_end_of_line
[(unsigned char) '!'] = 0;
1976 input_line_pointer
= old_input_line_pointer
;
1977 return TOKENIZE_ERROR_REPORT
;
1980 /* Search forward through all variants of an opcode looking for a
1983 static const struct alpha_opcode
*
1984 find_opcode_match (first_opcode
, tok
, pntok
, pcpumatch
)
1985 const struct alpha_opcode
*first_opcode
;
1986 const expressionS
*tok
;
1990 const struct alpha_opcode
*opcode
= first_opcode
;
1992 int got_cpu_match
= 0;
1996 const unsigned char *opidx
;
1999 /* Don't match opcodes that don't exist on this architecture */
2000 if (!(opcode
->flags
& alpha_target
))
2005 for (opidx
= opcode
->operands
; *opidx
; ++opidx
)
2007 const struct alpha_operand
*operand
= &alpha_operands
[*opidx
];
2009 /* only take input from real operands */
2010 if (operand
->flags
& AXP_OPERAND_FAKE
)
2013 /* when we expect input, make sure we have it */
2016 if ((operand
->flags
& AXP_OPERAND_OPTIONAL_MASK
) == 0)
2021 /* match operand type with expression type */
2022 switch (operand
->flags
& AXP_OPERAND_TYPECHECK_MASK
)
2024 case AXP_OPERAND_IR
:
2025 if (tok
[tokidx
].X_op
!= O_register
2026 || !is_ir_num (tok
[tokidx
].X_add_number
))
2029 case AXP_OPERAND_FPR
:
2030 if (tok
[tokidx
].X_op
!= O_register
2031 || !is_fpr_num (tok
[tokidx
].X_add_number
))
2034 case AXP_OPERAND_IR
| AXP_OPERAND_PARENS
:
2035 if (tok
[tokidx
].X_op
!= O_pregister
2036 || !is_ir_num (tok
[tokidx
].X_add_number
))
2039 case AXP_OPERAND_IR
| AXP_OPERAND_PARENS
| AXP_OPERAND_COMMA
:
2040 if (tok
[tokidx
].X_op
!= O_cpregister
2041 || !is_ir_num (tok
[tokidx
].X_add_number
))
2045 case AXP_OPERAND_RELATIVE
:
2046 case AXP_OPERAND_SIGNED
:
2047 case AXP_OPERAND_UNSIGNED
:
2048 switch (tok
[tokidx
].X_op
)
2063 /* everything else should have been fake */
2069 /* possible match -- did we use all of our input? */
2078 while (++opcode
- alpha_opcodes
< alpha_num_opcodes
2079 && !strcmp (opcode
->name
, first_opcode
->name
));
2082 *pcpumatch
= got_cpu_match
;
2087 /* Search forward through all variants of a macro looking for a syntax
2090 static const struct alpha_macro
*
2091 find_macro_match (first_macro
, tok
, pntok
)
2092 const struct alpha_macro
*first_macro
;
2093 const expressionS
*tok
;
2096 const struct alpha_macro
*macro
= first_macro
;
2101 const enum alpha_macro_arg
*arg
= macro
->argsets
;
2115 /* index register */
2117 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_register
2118 || !is_ir_num (tok
[tokidx
].X_add_number
))
2123 /* parenthesized index register */
2125 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_pregister
2126 || !is_ir_num (tok
[tokidx
].X_add_number
))
2131 /* optional parenthesized index register */
2133 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_pregister
2134 && is_ir_num (tok
[tokidx
].X_add_number
))
2138 /* leading comma with a parenthesized index register */
2140 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_cpregister
2141 || !is_ir_num (tok
[tokidx
].X_add_number
))
2146 /* floating point register */
2148 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_register
2149 || !is_fpr_num (tok
[tokidx
].X_add_number
))
2154 /* normal expression */
2158 switch (tok
[tokidx
].X_op
)
2167 case O_lituse_bytoff
:
2182 while (*arg
!= MACRO_EOA
)
2190 while (++macro
- alpha_macros
< alpha_num_macros
2191 && !strcmp (macro
->name
, first_macro
->name
));
2196 /* Insert an operand value into an instruction. */
2199 insert_operand (insn
, operand
, val
, file
, line
)
2201 const struct alpha_operand
*operand
;
2206 if (operand
->bits
!= 32 && !(operand
->flags
& AXP_OPERAND_NOOVERFLOW
))
2210 if (operand
->flags
& AXP_OPERAND_SIGNED
)
2212 max
= (1 << (operand
->bits
- 1)) - 1;
2213 min
= -(1 << (operand
->bits
- 1));
2217 max
= (1 << operand
->bits
) - 1;
2221 if (val
< min
|| val
> max
)
2224 _("operand out of range (%s not between %d and %d)");
2225 char buf
[sizeof (val
) * 3 + 2];
2227 sprint_value (buf
, val
);
2229 as_warn_where (file
, line
, err
, buf
, min
, max
);
2231 as_warn (err
, buf
, min
, max
);
2235 if (operand
->insert
)
2237 const char *errmsg
= NULL
;
2239 insn
= (*operand
->insert
) (insn
, val
, &errmsg
);
2244 insn
|= ((val
& ((1 << operand
->bits
) - 1)) << operand
->shift
);
2250 * Turn an opcode description and a set of arguments into
2251 * an instruction and a fixup.
2255 assemble_insn (opcode
, tok
, ntok
, insn
, reloc
)
2256 const struct alpha_opcode
*opcode
;
2257 const expressionS
*tok
;
2259 struct alpha_insn
*insn
;
2260 bfd_reloc_code_real_type reloc
;
2262 const struct alpha_operand
*reloc_operand
= NULL
;
2263 const expressionS
*reloc_exp
= NULL
;
2264 const unsigned char *argidx
;
2268 memset (insn
, 0, sizeof (*insn
));
2269 image
= opcode
->opcode
;
2271 for (argidx
= opcode
->operands
; *argidx
; ++argidx
)
2273 const struct alpha_operand
*operand
= &alpha_operands
[*argidx
];
2274 const expressionS
*t
= (const expressionS
*) 0;
2276 if (operand
->flags
& AXP_OPERAND_FAKE
)
2278 /* fake operands take no value and generate no fixup */
2279 image
= insert_operand (image
, operand
, 0, NULL
, 0);
2285 switch (operand
->flags
& AXP_OPERAND_OPTIONAL_MASK
)
2287 case AXP_OPERAND_DEFAULT_FIRST
:
2290 case AXP_OPERAND_DEFAULT_SECOND
:
2293 case AXP_OPERAND_DEFAULT_ZERO
:
2295 static expressionS zero_exp
;
2297 zero_exp
.X_op
= O_constant
;
2298 zero_exp
.X_unsigned
= 1;
2313 image
= insert_operand (image
, operand
, regno (t
->X_add_number
),
2318 image
= insert_operand (image
, operand
, t
->X_add_number
, NULL
, 0);
2319 assert (reloc_operand
== NULL
);
2320 reloc_operand
= operand
;
2325 /* This is only 0 for fields that should contain registers,
2326 which means this pattern shouldn't have matched. */
2327 if (operand
->default_reloc
== 0)
2330 /* There is one special case for which an insn receives two
2331 relocations, and thus the user-supplied reloc does not
2332 override the operand reloc. */
2333 if (operand
->default_reloc
== BFD_RELOC_ALPHA_HINT
)
2335 struct alpha_fixup
*fixup
;
2337 if (insn
->nfixups
>= MAX_INSN_FIXUPS
)
2338 as_fatal (_("too many fixups"));
2340 fixup
= &insn
->fixups
[insn
->nfixups
++];
2342 fixup
->reloc
= BFD_RELOC_ALPHA_HINT
;
2346 if (reloc
== BFD_RELOC_UNUSED
)
2347 reloc
= operand
->default_reloc
;
2349 assert (reloc_operand
== NULL
);
2350 reloc_operand
= operand
;
2357 if (reloc
!= BFD_RELOC_UNUSED
)
2359 struct alpha_fixup
*fixup
;
2361 if (insn
->nfixups
>= MAX_INSN_FIXUPS
)
2362 as_fatal (_("too many fixups"));
2364 /* ??? My but this is hacky. But the OSF/1 assembler uses the same
2365 relocation tag for both ldah and lda with gpdisp. Choose the
2366 correct internal relocation based on the opcode. */
2367 if (reloc
== BFD_RELOC_ALPHA_GPDISP
)
2369 if (strcmp (opcode
->name
, "ldah") == 0)
2370 reloc
= BFD_RELOC_ALPHA_GPDISP_HI16
;
2371 else if (strcmp (opcode
->name
, "lda") == 0)
2372 reloc
= BFD_RELOC_ALPHA_GPDISP_LO16
;
2374 as_bad (_("invalid relocation for instruction"));
2377 /* If this is a real relocation (as opposed to a lituse hint), then
2378 the relocation width should match the operand width. */
2379 else if (reloc
< BFD_RELOC_UNUSED
)
2381 reloc_howto_type
*reloc_howto
2382 = bfd_reloc_type_lookup (stdoutput
, reloc
);
2383 if (reloc_howto
->bitsize
!= reloc_operand
->bits
)
2385 as_bad (_("invalid relocation for field"));
2390 fixup
= &insn
->fixups
[insn
->nfixups
++];
2392 fixup
->exp
= *reloc_exp
;
2394 fixup
->exp
.X_op
= O_absent
;
2395 fixup
->reloc
= reloc
;
2402 * Actually output an instruction with its fixup.
2407 struct alpha_insn
*insn
;
2412 /* Take care of alignment duties. */
2413 if (alpha_auto_align_on
&& alpha_current_align
< 2)
2414 alpha_align (2, (char *) NULL
, alpha_insn_label
, 0);
2415 if (alpha_current_align
> 2)
2416 alpha_current_align
= 2;
2417 alpha_insn_label
= NULL
;
2419 /* Write out the instruction. */
2421 md_number_to_chars (f
, insn
->insn
, 4);
2424 dwarf2_emit_insn (4);
2427 /* Apply the fixups in order */
2428 for (i
= 0; i
< insn
->nfixups
; ++i
)
2430 const struct alpha_operand
*operand
= (const struct alpha_operand
*) 0;
2431 struct alpha_fixup
*fixup
= &insn
->fixups
[i
];
2432 struct alpha_reloc_tag
*info
;
2436 /* Some fixups are only used internally and so have no howto */
2437 if ((int) fixup
->reloc
< 0)
2439 operand
= &alpha_operands
[-(int) fixup
->reloc
];
2441 pcrel
= ((operand
->flags
& AXP_OPERAND_RELATIVE
) != 0);
2443 else if (fixup
->reloc
> BFD_RELOC_UNUSED
2444 || fixup
->reloc
== BFD_RELOC_ALPHA_GPDISP_HI16
2445 || fixup
->reloc
== BFD_RELOC_ALPHA_GPDISP_LO16
)
2452 reloc_howto_type
*reloc_howto
2453 = bfd_reloc_type_lookup (stdoutput
, fixup
->reloc
);
2454 assert (reloc_howto
);
2456 size
= bfd_get_reloc_size (reloc_howto
);
2457 assert (size
>= 1 && size
<= 4);
2459 pcrel
= reloc_howto
->pc_relative
;
2462 fixP
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, size
,
2463 &fixup
->exp
, pcrel
, fixup
->reloc
);
2465 /* Turn off complaints that the addend is too large for some fixups,
2466 and copy in the sequence number for the explicit relocations. */
2467 switch (fixup
->reloc
)
2469 case BFD_RELOC_ALPHA_HINT
:
2470 case BFD_RELOC_GPREL32
:
2471 case BFD_RELOC_GPREL16
:
2472 case BFD_RELOC_ALPHA_GPREL_HI16
:
2473 case BFD_RELOC_ALPHA_GPREL_LO16
:
2474 fixP
->fx_no_overflow
= 1;
2477 case BFD_RELOC_ALPHA_GPDISP_HI16
:
2478 fixP
->fx_no_overflow
= 1;
2479 fixP
->fx_addsy
= section_symbol (now_seg
);
2480 fixP
->fx_offset
= 0;
2482 info
= get_alpha_reloc_tag (insn
->sequence
);
2483 if (++info
->n_master
> 1)
2484 as_bad (_("too many ldah insns for !gpdisp!%ld"), insn
->sequence
);
2485 if (info
->segment
!= now_seg
)
2486 as_bad (_("both insns for !gpdisp!%ld must be in the same section"),
2488 fixP
->tc_fix_data
.info
= info
;
2491 case BFD_RELOC_ALPHA_GPDISP_LO16
:
2492 fixP
->fx_no_overflow
= 1;
2494 info
= get_alpha_reloc_tag (insn
->sequence
);
2495 if (++info
->n_slaves
> 1)
2496 as_bad (_("too many lda insns for !gpdisp!%ld"), insn
->sequence
);
2497 if (info
->segment
!= now_seg
)
2498 as_bad (_("both insns for !gpdisp!%ld must be in the same section"),
2500 fixP
->tc_fix_data
.info
= info
;
2501 info
->slaves
= fixP
;
2504 case BFD_RELOC_ALPHA_LITERAL
:
2505 case BFD_RELOC_ALPHA_ELF_LITERAL
:
2506 fixP
->fx_no_overflow
= 1;
2508 info
= get_alpha_reloc_tag (insn
->sequence
);
2510 if (info
->segment
!= now_seg
)
2511 info
->multi_section_p
= 1;
2512 fixP
->tc_fix_data
.info
= info
;
2515 case DUMMY_RELOC_LITUSE_ADDR
:
2516 fixP
->fx_offset
= LITUSE_ADDR
;
2518 case DUMMY_RELOC_LITUSE_BASE
:
2519 fixP
->fx_offset
= LITUSE_BASE
;
2521 case DUMMY_RELOC_LITUSE_BYTOFF
:
2522 fixP
->fx_offset
= LITUSE_BYTOFF
;
2524 case DUMMY_RELOC_LITUSE_JSR
:
2525 fixP
->fx_offset
= LITUSE_JSR
;
2527 fixP
->fx_addsy
= section_symbol (now_seg
);
2528 fixP
->fx_r_type
= BFD_RELOC_ALPHA_LITUSE
;
2530 info
= get_alpha_reloc_tag (insn
->sequence
);
2532 fixP
->tc_fix_data
.info
= info
;
2533 fixP
->tc_fix_data
.next_reloc
= info
->slaves
;
2534 info
->slaves
= fixP
;
2535 if (info
->segment
!= now_seg
)
2536 info
->multi_section_p
= 1;
2540 if ((int) fixup
->reloc
< 0)
2542 if (operand
->flags
& AXP_OPERAND_NOOVERFLOW
)
2543 fixP
->fx_no_overflow
= 1;
2550 /* Given an opcode name and a pre-tokenized set of arguments, assemble
2551 the insn, but do not emit it.
2553 Note that this implies no macros allowed, since we can't store more
2554 than one insn in an insn structure. */
2557 assemble_tokens_to_insn (opname
, tok
, ntok
, insn
)
2559 const expressionS
*tok
;
2561 struct alpha_insn
*insn
;
2563 const struct alpha_opcode
*opcode
;
2565 /* search opcodes */
2566 opcode
= (const struct alpha_opcode
*) hash_find (alpha_opcode_hash
, opname
);
2570 opcode
= find_opcode_match (opcode
, tok
, &ntok
, &cpumatch
);
2573 assemble_insn (opcode
, tok
, ntok
, insn
, BFD_RELOC_UNUSED
);
2577 as_bad (_("inappropriate arguments for opcode `%s'"), opname
);
2579 as_bad (_("opcode `%s' not supported for target %s"), opname
,
2583 as_bad (_("unknown opcode `%s'"), opname
);
2586 /* Given an opcode name and a pre-tokenized set of arguments, take the
2587 opcode all the way through emission. */
2590 assemble_tokens (opname
, tok
, ntok
, local_macros_on
)
2592 const expressionS
*tok
;
2594 int local_macros_on
;
2596 int found_something
= 0;
2597 const struct alpha_opcode
*opcode
;
2598 const struct alpha_macro
*macro
;
2600 bfd_reloc_code_real_type reloc
= BFD_RELOC_UNUSED
;
2602 /* If a user-specified relocation is present, this is not a macro. */
2603 if (ntok
&& USER_RELOC_P (tok
[ntok
- 1].X_op
))
2605 reloc
= ALPHA_RELOC_TABLE (tok
[ntok
- 1].X_op
)->reloc
;
2608 else if (local_macros_on
)
2610 macro
= ((const struct alpha_macro
*)
2611 hash_find (alpha_macro_hash
, opname
));
2614 found_something
= 1;
2615 macro
= find_macro_match (macro
, tok
, &ntok
);
2618 (*macro
->emit
) (tok
, ntok
, macro
->arg
);
2624 /* search opcodes */
2625 opcode
= (const struct alpha_opcode
*) hash_find (alpha_opcode_hash
, opname
);
2628 found_something
= 1;
2629 opcode
= find_opcode_match (opcode
, tok
, &ntok
, &cpumatch
);
2632 struct alpha_insn insn
;
2633 assemble_insn (opcode
, tok
, ntok
, &insn
, reloc
);
2635 /* Copy the sequence number for the reloc from the reloc token. */
2636 if (reloc
!= BFD_RELOC_UNUSED
)
2637 insn
.sequence
= tok
[ntok
].X_add_number
;
2644 if (found_something
)
2647 as_bad (_("inappropriate arguments for opcode `%s'"), opname
);
2649 as_bad (_("opcode `%s' not supported for target %s"), opname
,
2653 as_bad (_("unknown opcode `%s'"), opname
);
2656 /* Some instruction sets indexed by lg(size) */
2657 static const char * const sextX_op
[] = { "sextb", "sextw", "sextl", NULL
};
2658 static const char * const insXl_op
[] = { "insbl", "inswl", "insll", "insql" };
2659 static const char * const insXh_op
[] = { NULL
, "inswh", "inslh", "insqh" };
2660 static const char * const extXl_op
[] = { "extbl", "extwl", "extll", "extql" };
2661 static const char * const extXh_op
[] = { NULL
, "extwh", "extlh", "extqh" };
2662 static const char * const mskXl_op
[] = { "mskbl", "mskwl", "mskll", "mskql" };
2663 static const char * const mskXh_op
[] = { NULL
, "mskwh", "msklh", "mskqh" };
2664 static const char * const stX_op
[] = { "stb", "stw", "stl", "stq" };
2665 static const char * const ldX_op
[] = { "ldb", "ldw", "ldll", "ldq" };
2666 static const char * const ldXu_op
[] = { "ldbu", "ldwu", NULL
, NULL
};
2668 /* Implement the ldgp macro. */
2671 emit_ldgp (tok
, ntok
, unused
)
2672 const expressionS
*tok
;
2673 int ntok ATTRIBUTE_UNUSED
;
2674 const PTR unused ATTRIBUTE_UNUSED
;
2679 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
2680 /* from "ldgp r1,n(r2)", generate "ldah r1,X(R2); lda r1,Y(r1)"
2681 with appropriate constants and relocations. */
2682 struct alpha_insn insn
;
2683 expressionS newtok
[3];
2687 if (regno (tok
[2].X_add_number
) == AXP_REG_PV
)
2688 ecoff_set_gp_prolog_size (0);
2692 set_tok_const (newtok
[1], 0);
2695 assemble_tokens_to_insn ("ldah", newtok
, 3, &insn
);
2700 if (addend
.X_op
!= O_constant
)
2701 as_bad (_("can not resolve expression"));
2702 addend
.X_op
= O_symbol
;
2703 addend
.X_add_symbol
= alpha_gp_symbol
;
2707 insn
.fixups
[0].exp
= addend
;
2708 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_GPDISP_HI16
;
2709 insn
.sequence
= next_sequence_num
;
2713 set_tok_preg (newtok
[2], tok
[0].X_add_number
);
2715 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
2718 addend
.X_add_number
+= 4;
2722 insn
.fixups
[0].exp
= addend
;
2723 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_GPDISP_LO16
;
2724 insn
.sequence
= next_sequence_num
--;
2727 #endif /* OBJ_ECOFF || OBJ_ELF */
2732 /* Add symbol+addend to link pool.
2733 Return offset from basesym to entry in link pool.
2735 Add new fixup only if offset isn't 16bit. */
2738 add_to_link_pool (basesym
, sym
, addend
)
2743 segT current_section
= now_seg
;
2744 int current_subsec
= now_subseg
;
2746 bfd_reloc_code_real_type reloc_type
;
2748 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
2751 offset
= - *symbol_get_obj (basesym
);
2753 /* @@ This assumes all entries in a given section will be of the same
2754 size... Probably correct, but unwise to rely on. */
2755 /* This must always be called with the same subsegment. */
2757 if (seginfo
->frchainP
)
2758 for (fixp
= seginfo
->frchainP
->fix_root
;
2759 fixp
!= (fixS
*) NULL
;
2760 fixp
= fixp
->fx_next
, offset
+= 8)
2762 if (fixp
->fx_addsy
== sym
&& fixp
->fx_offset
== addend
)
2764 if (range_signed_16 (offset
))
2771 /* Not found in 16bit signed range. */
2773 subseg_set (alpha_link_section
, 0);
2777 fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, sym
, addend
, 0,
2780 subseg_set (current_section
, current_subsec
);
2781 seginfo
->literal_pool_size
+= 8;
2785 #endif /* OBJ_EVAX */
2787 /* Load a (partial) expression into a target register.
2789 If poffset is not null, after the call it will either contain
2790 O_constant 0, or a 16-bit offset appropriate for any MEM format
2791 instruction. In addition, pbasereg will be modified to point to
2792 the base register to use in that MEM format instruction.
2794 In any case, *pbasereg should contain a base register to add to the
2795 expression. This will normally be either AXP_REG_ZERO or
2796 alpha_gp_register. Symbol addresses will always be loaded via $gp,
2797 so "foo($0)" is interpreted as adding the address of foo to $0;
2798 i.e. "ldq $targ, LIT($gp); addq $targ, $0, $targ". Odd, perhaps,
2799 but this is what OSF/1 does.
2801 If explicit relocations of the form !literal!<number> are allowed,
2802 and used, then explict_reloc with be an expression pointer.
2804 Finally, the return value is nonzero if the calling macro may emit
2805 a LITUSE reloc if otherwise appropriate; the return value is the
2806 sequence number to use. */
2809 load_expression (targreg
, exp
, pbasereg
, poffset
)
2811 const expressionS
*exp
;
2813 expressionS
*poffset
;
2815 long emit_lituse
= 0;
2816 offsetT addend
= exp
->X_add_number
;
2817 int basereg
= *pbasereg
;
2818 struct alpha_insn insn
;
2819 expressionS newtok
[3];
2828 /* attempt to reduce .lit load by splitting the offset from
2829 its symbol when possible, but don't create a situation in
2831 if (!range_signed_32 (addend
) &&
2832 (alpha_noat_on
|| targreg
== AXP_REG_AT
))
2834 lit
= add_to_literal_pool (exp
->X_add_symbol
, addend
,
2835 alpha_lita_section
, 8);
2840 lit
= add_to_literal_pool (exp
->X_add_symbol
, 0,
2841 alpha_lita_section
, 8);
2845 as_fatal (_("overflow in literal (.lita) table"));
2847 /* emit "ldq r, lit(gp)" */
2849 if (basereg
!= alpha_gp_register
&& targreg
== basereg
)
2852 as_bad (_("macro requires $at register while noat in effect"));
2853 if (targreg
== AXP_REG_AT
)
2854 as_bad (_("macro requires $at while $at in use"));
2856 set_tok_reg (newtok
[0], AXP_REG_AT
);
2859 set_tok_reg (newtok
[0], targreg
);
2860 set_tok_sym (newtok
[1], alpha_lita_symbol
, lit
);
2861 set_tok_preg (newtok
[2], alpha_gp_register
);
2863 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
2865 assert (insn
.nfixups
== 1);
2866 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITERAL
;
2867 insn
.sequence
= emit_lituse
= next_sequence_num
--;
2868 #endif /* OBJ_ECOFF */
2870 /* emit "ldq r, gotoff(gp)" */
2872 if (basereg
!= alpha_gp_register
&& targreg
== basereg
)
2875 as_bad (_("macro requires $at register while noat in effect"));
2876 if (targreg
== AXP_REG_AT
)
2877 as_bad (_("macro requires $at while $at in use"));
2879 set_tok_reg (newtok
[0], AXP_REG_AT
);
2882 set_tok_reg (newtok
[0], targreg
);
2884 /* XXX: Disable this .got minimizing optimization so that we can get
2885 better instruction offset knowledge in the compiler. This happens
2886 very infrequently anyway. */
2888 || (!range_signed_32 (addend
)
2889 && (alpha_noat_on
|| targreg
== AXP_REG_AT
)))
2896 set_tok_sym (newtok
[1], exp
->X_add_symbol
, 0);
2899 set_tok_preg (newtok
[2], alpha_gp_register
);
2901 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
2903 assert (insn
.nfixups
== 1);
2904 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_ELF_LITERAL
;
2905 insn
.sequence
= emit_lituse
= next_sequence_num
--;
2906 #endif /* OBJ_ELF */
2910 /* Find symbol or symbol pointer in link section. */
2912 if (exp
->X_add_symbol
== alpha_evax_proc
.symbol
)
2914 if (range_signed_16 (addend
))
2916 set_tok_reg (newtok
[0], targreg
);
2917 set_tok_const (newtok
[1], addend
);
2918 set_tok_preg (newtok
[2], basereg
);
2919 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
2924 set_tok_reg (newtok
[0], targreg
);
2925 set_tok_const (newtok
[1], 0);
2926 set_tok_preg (newtok
[2], basereg
);
2927 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
2932 if (!range_signed_32 (addend
))
2934 link
= add_to_link_pool (alpha_evax_proc
.symbol
,
2935 exp
->X_add_symbol
, addend
);
2940 link
= add_to_link_pool (alpha_evax_proc
.symbol
,
2941 exp
->X_add_symbol
, 0);
2943 set_tok_reg (newtok
[0], targreg
);
2944 set_tok_const (newtok
[1], link
);
2945 set_tok_preg (newtok
[2], basereg
);
2946 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
2948 #endif /* OBJ_EVAX */
2953 if (basereg
!= alpha_gp_register
&& basereg
!= AXP_REG_ZERO
)
2955 /* emit "addq r, base, r" */
2957 set_tok_reg (newtok
[1], basereg
);
2958 set_tok_reg (newtok
[2], targreg
);
2959 assemble_tokens ("addq", newtok
, 3, 0);
2971 /* Assume that this difference expression will be resolved to an
2972 absolute value and that that value will fit in 16 bits. */
2974 set_tok_reg (newtok
[0], targreg
);
2976 set_tok_preg (newtok
[2], basereg
);
2977 assemble_tokens ("lda", newtok
, 3, 0);
2980 set_tok_const (*poffset
, 0);
2984 if (exp
->X_add_number
> 0)
2985 as_bad (_("bignum invalid; zero assumed"));
2987 as_bad (_("floating point number invalid; zero assumed"));
2992 as_bad (_("can't handle expression"));
2997 if (!range_signed_32 (addend
))
3000 long seq_num
= next_sequence_num
--;
3002 /* For 64-bit addends, just put it in the literal pool. */
3005 /* emit "ldq targreg, lit(basereg)" */
3006 lit
= add_to_link_pool (alpha_evax_proc
.symbol
,
3007 section_symbol (absolute_section
), addend
);
3008 set_tok_reg (newtok
[0], targreg
);
3009 set_tok_const (newtok
[1], lit
);
3010 set_tok_preg (newtok
[2], alpha_gp_register
);
3011 assemble_tokens ("ldq", newtok
, 3, 0);
3014 if (alpha_lit8_section
== NULL
)
3016 create_literal_section (".lit8",
3017 &alpha_lit8_section
,
3018 &alpha_lit8_symbol
);
3021 alpha_lit8_literal
= add_to_literal_pool (alpha_lit8_symbol
, 0x8000,
3022 alpha_lita_section
, 8);
3023 if (alpha_lit8_literal
>= 0x8000)
3024 as_fatal (_("overflow in literal (.lita) table"));
3028 lit
= add_to_literal_pool (NULL
, addend
, alpha_lit8_section
, 8) - 0x8000;
3030 as_fatal (_("overflow in literal (.lit8) table"));
3032 /* emit "lda litreg, .lit8+0x8000" */
3034 if (targreg
== basereg
)
3037 as_bad (_("macro requires $at register while noat in effect"));
3038 if (targreg
== AXP_REG_AT
)
3039 as_bad (_("macro requires $at while $at in use"));
3041 set_tok_reg (newtok
[0], AXP_REG_AT
);
3044 set_tok_reg (newtok
[0], targreg
);
3046 set_tok_sym (newtok
[1], alpha_lita_symbol
, alpha_lit8_literal
);
3049 set_tok_sym (newtok
[1], alpha_lit8_symbol
, 0x8000);
3051 set_tok_preg (newtok
[2], alpha_gp_register
);
3053 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
3055 assert (insn
.nfixups
== 1);
3057 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITERAL
;
3060 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_ELF_LITERAL
;
3062 insn
.sequence
= seq_num
;
3066 /* emit "ldq litreg, lit(litreg)" */
3068 set_tok_const (newtok
[1], lit
);
3069 set_tok_preg (newtok
[2], newtok
[0].X_add_number
);
3071 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
3073 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3074 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BASE
;
3075 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3077 insn
.sequence
= seq_num
;
3082 /* emit "addq litreg, base, target" */
3084 if (basereg
!= AXP_REG_ZERO
)
3086 set_tok_reg (newtok
[1], basereg
);
3087 set_tok_reg (newtok
[2], targreg
);
3088 assemble_tokens ("addq", newtok
, 3, 0);
3090 #endif /* !OBJ_EVAX */
3093 set_tok_const (*poffset
, 0);
3094 *pbasereg
= targreg
;
3098 offsetT low
, high
, extra
, tmp
;
3100 /* for 32-bit operands, break up the addend */
3102 low
= sign_extend_16 (addend
);
3104 high
= sign_extend_16 (tmp
>> 16);
3106 if (tmp
- (high
<< 16))
3110 high
= sign_extend_16 (tmp
>> 16);
3115 set_tok_reg (newtok
[0], targreg
);
3116 set_tok_preg (newtok
[2], basereg
);
3120 /* emit "ldah r, extra(r) */
3121 set_tok_const (newtok
[1], extra
);
3122 assemble_tokens ("ldah", newtok
, 3, 0);
3123 set_tok_preg (newtok
[2], basereg
= targreg
);
3128 /* emit "ldah r, high(r) */
3129 set_tok_const (newtok
[1], high
);
3130 assemble_tokens ("ldah", newtok
, 3, 0);
3132 set_tok_preg (newtok
[2], basereg
);
3135 if ((low
&& !poffset
) || (!poffset
&& basereg
!= targreg
))
3137 /* emit "lda r, low(base)" */
3138 set_tok_const (newtok
[1], low
);
3139 assemble_tokens ("lda", newtok
, 3, 0);
3145 set_tok_const (*poffset
, low
);
3146 *pbasereg
= basereg
;
3152 /* The lda macro differs from the lda instruction in that it handles
3153 most simple expressions, particualrly symbol address loads and
3157 emit_lda (tok
, ntok
, unused
)
3158 const expressionS
*tok
;
3160 const PTR unused ATTRIBUTE_UNUSED
;
3165 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
3167 basereg
= tok
[2].X_add_number
;
3169 (void) load_expression (tok
[0].X_add_number
, &tok
[1], &basereg
, NULL
);
3172 /* The ldah macro differs from the ldah instruction in that it has $31
3173 as an implied base register. */
3176 emit_ldah (tok
, ntok
, unused
)
3177 const expressionS
*tok
;
3178 int ntok ATTRIBUTE_UNUSED
;
3179 const PTR unused ATTRIBUTE_UNUSED
;
3181 expressionS newtok
[3];
3185 set_tok_preg (newtok
[2], AXP_REG_ZERO
);
3187 assemble_tokens ("ldah", newtok
, 3, 0);
3190 /* Handle all "simple" integer register loads -- ldq, ldq_l, ldq_u,
3191 etc. They differ from the real instructions in that they do simple
3192 expressions like the lda macro. */
3195 emit_ir_load (tok
, ntok
, opname
)
3196 const expressionS
*tok
;
3202 expressionS newtok
[3];
3203 struct alpha_insn insn
;
3206 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
3208 basereg
= tok
[2].X_add_number
;
3210 lituse
= load_expression (tok
[0].X_add_number
, &tok
[1], &basereg
,
3214 set_tok_preg (newtok
[2], basereg
);
3216 assemble_tokens_to_insn ((const char *) opname
, newtok
, 3, &insn
);
3220 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3221 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BASE
;
3222 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3224 insn
.sequence
= lituse
;
3230 /* Handle fp register loads, and both integer and fp register stores.
3231 Again, we handle simple expressions. */
3234 emit_loadstore (tok
, ntok
, opname
)
3235 const expressionS
*tok
;
3241 expressionS newtok
[3];
3242 struct alpha_insn insn
;
3245 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
3247 basereg
= tok
[2].X_add_number
;
3249 if (tok
[1].X_op
!= O_constant
|| !range_signed_16 (tok
[1].X_add_number
))
3252 as_bad (_("macro requires $at register while noat in effect"));
3254 lituse
= load_expression (AXP_REG_AT
, &tok
[1], &basereg
, &newtok
[1]);
3263 set_tok_preg (newtok
[2], basereg
);
3265 assemble_tokens_to_insn ((const char *) opname
, newtok
, 3, &insn
);
3269 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3270 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BASE
;
3271 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3273 insn
.sequence
= lituse
;
3279 /* Load a half-word or byte as an unsigned value. */
3282 emit_ldXu (tok
, ntok
, vlgsize
)
3283 const expressionS
*tok
;
3287 if (alpha_target
& AXP_OPCODE_BWX
)
3288 emit_ir_load (tok
, ntok
, ldXu_op
[(long) vlgsize
]);
3291 expressionS newtok
[3];
3292 struct alpha_insn insn
;
3297 as_bad (_("macro requires $at register while noat in effect"));
3300 basereg
= (tok
[1].X_op
== O_constant
3301 ? AXP_REG_ZERO
: alpha_gp_register
);
3303 basereg
= tok
[2].X_add_number
;
3305 /* emit "lda $at, exp" */
3307 lituse
= load_expression (AXP_REG_AT
, &tok
[1], &basereg
, NULL
);
3309 /* emit "ldq_u targ, 0($at)" */
3312 set_tok_const (newtok
[1], 0);
3313 set_tok_preg (newtok
[2], basereg
);
3314 assemble_tokens_to_insn ("ldq_u", newtok
, 3, &insn
);
3318 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3319 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BASE
;
3320 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3322 insn
.sequence
= lituse
;
3327 /* emit "extXl targ, $at, targ" */
3329 set_tok_reg (newtok
[1], basereg
);
3330 newtok
[2] = newtok
[0];
3331 assemble_tokens_to_insn (extXl_op
[(long) vlgsize
], newtok
, 3, &insn
);
3335 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3336 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BYTOFF
;
3337 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3339 insn
.sequence
= lituse
;
3346 /* Load a half-word or byte as a signed value. */
3349 emit_ldX (tok
, ntok
, vlgsize
)
3350 const expressionS
*tok
;
3354 emit_ldXu (tok
, ntok
, vlgsize
);
3355 assemble_tokens (sextX_op
[(long) vlgsize
], tok
, 1, 1);
3358 /* Load an integral value from an unaligned address as an unsigned
3362 emit_uldXu (tok
, ntok
, vlgsize
)
3363 const expressionS
*tok
;
3367 long lgsize
= (long) vlgsize
;
3368 expressionS newtok
[3];
3371 as_bad (_("macro requires $at register while noat in effect"));
3373 /* emit "lda $at, exp" */
3375 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
3376 newtok
[0].X_add_number
= AXP_REG_AT
;
3377 assemble_tokens ("lda", newtok
, ntok
, 1);
3379 /* emit "ldq_u $t9, 0($at)" */
3381 set_tok_reg (newtok
[0], AXP_REG_T9
);
3382 set_tok_const (newtok
[1], 0);
3383 set_tok_preg (newtok
[2], AXP_REG_AT
);
3384 assemble_tokens ("ldq_u", newtok
, 3, 1);
3386 /* emit "ldq_u $t10, size-1($at)" */
3388 set_tok_reg (newtok
[0], AXP_REG_T10
);
3389 set_tok_const (newtok
[1], (1 << lgsize
) - 1);
3390 assemble_tokens ("ldq_u", newtok
, 3, 1);
3392 /* emit "extXl $t9, $at, $t9" */
3394 set_tok_reg (newtok
[0], AXP_REG_T9
);
3395 set_tok_reg (newtok
[1], AXP_REG_AT
);
3396 set_tok_reg (newtok
[2], AXP_REG_T9
);
3397 assemble_tokens (extXl_op
[lgsize
], newtok
, 3, 1);
3399 /* emit "extXh $t10, $at, $t10" */
3401 set_tok_reg (newtok
[0], AXP_REG_T10
);
3402 set_tok_reg (newtok
[2], AXP_REG_T10
);
3403 assemble_tokens (extXh_op
[lgsize
], newtok
, 3, 1);
3405 /* emit "or $t9, $t10, targ" */
3407 set_tok_reg (newtok
[0], AXP_REG_T9
);
3408 set_tok_reg (newtok
[1], AXP_REG_T10
);
3410 assemble_tokens ("or", newtok
, 3, 1);
3413 /* Load an integral value from an unaligned address as a signed value.
3414 Note that quads should get funneled to the unsigned load since we
3415 don't have to do the sign extension. */
3418 emit_uldX (tok
, ntok
, vlgsize
)
3419 const expressionS
*tok
;
3423 emit_uldXu (tok
, ntok
, vlgsize
);
3424 assemble_tokens (sextX_op
[(long) vlgsize
], tok
, 1, 1);
3427 /* Implement the ldil macro. */
3430 emit_ldil (tok
, ntok
, unused
)
3431 const expressionS
*tok
;
3433 const PTR unused ATTRIBUTE_UNUSED
;
3435 expressionS newtok
[2];
3437 memcpy (newtok
, tok
, sizeof (newtok
));
3438 newtok
[1].X_add_number
= sign_extend_32 (tok
[1].X_add_number
);
3440 assemble_tokens ("lda", newtok
, ntok
, 1);
3443 /* Store a half-word or byte. */
3446 emit_stX (tok
, ntok
, vlgsize
)
3447 const expressionS
*tok
;
3451 int lgsize
= (int) (long) vlgsize
;
3453 if (alpha_target
& AXP_OPCODE_BWX
)
3454 emit_loadstore (tok
, ntok
, stX_op
[lgsize
]);
3457 expressionS newtok
[3];
3458 struct alpha_insn insn
;
3463 as_bad (_("macro requires $at register while noat in effect"));
3466 basereg
= (tok
[1].X_op
== O_constant
3467 ? AXP_REG_ZERO
: alpha_gp_register
);
3469 basereg
= tok
[2].X_add_number
;
3471 /* emit "lda $at, exp" */
3473 lituse
= load_expression (AXP_REG_AT
, &tok
[1], &basereg
, NULL
);
3475 /* emit "ldq_u $t9, 0($at)" */
3477 set_tok_reg (newtok
[0], AXP_REG_T9
);
3478 set_tok_const (newtok
[1], 0);
3479 set_tok_preg (newtok
[2], basereg
);
3480 assemble_tokens_to_insn ("ldq_u", newtok
, 3, &insn
);
3484 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3485 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BASE
;
3486 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3488 insn
.sequence
= lituse
;
3493 /* emit "insXl src, $at, $t10" */
3496 set_tok_reg (newtok
[1], basereg
);
3497 set_tok_reg (newtok
[2], AXP_REG_T10
);
3498 assemble_tokens_to_insn (insXl_op
[lgsize
], newtok
, 3, &insn
);
3502 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3503 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BYTOFF
;
3504 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3506 insn
.sequence
= lituse
;
3511 /* emit "mskXl $t9, $at, $t9" */
3513 set_tok_reg (newtok
[0], AXP_REG_T9
);
3514 newtok
[2] = newtok
[0];
3515 assemble_tokens_to_insn (mskXl_op
[lgsize
], newtok
, 3, &insn
);
3519 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3520 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BYTOFF
;
3521 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3523 insn
.sequence
= lituse
;
3528 /* emit "or $t9, $t10, $t9" */
3530 set_tok_reg (newtok
[1], AXP_REG_T10
);
3531 assemble_tokens ("or", newtok
, 3, 1);
3533 /* emit "stq_u $t9, 0($at) */
3535 set_tok_const(newtok
[1], 0);
3536 set_tok_preg (newtok
[2], AXP_REG_AT
);
3537 assemble_tokens_to_insn ("stq_u", newtok
, 3, &insn
);
3541 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3542 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BASE
;
3543 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3545 insn
.sequence
= lituse
;
3552 /* Store an integer to an unaligned address. */
3555 emit_ustX (tok
, ntok
, vlgsize
)
3556 const expressionS
*tok
;
3560 int lgsize
= (int) (long) vlgsize
;
3561 expressionS newtok
[3];
3563 /* emit "lda $at, exp" */
3565 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
3566 newtok
[0].X_add_number
= AXP_REG_AT
;
3567 assemble_tokens ("lda", newtok
, ntok
, 1);
3569 /* emit "ldq_u $9, 0($at)" */
3571 set_tok_reg (newtok
[0], AXP_REG_T9
);
3572 set_tok_const (newtok
[1], 0);
3573 set_tok_preg (newtok
[2], AXP_REG_AT
);
3574 assemble_tokens ("ldq_u", newtok
, 3, 1);
3576 /* emit "ldq_u $10, size-1($at)" */
3578 set_tok_reg (newtok
[0], AXP_REG_T10
);
3579 set_tok_const (newtok
[1], (1 << lgsize
) - 1);
3580 assemble_tokens ("ldq_u", newtok
, 3, 1);
3582 /* emit "insXl src, $at, $t11" */
3585 set_tok_reg (newtok
[1], AXP_REG_AT
);
3586 set_tok_reg (newtok
[2], AXP_REG_T11
);
3587 assemble_tokens (insXl_op
[lgsize
], newtok
, 3, 1);
3589 /* emit "insXh src, $at, $t12" */
3591 set_tok_reg (newtok
[2], AXP_REG_T12
);
3592 assemble_tokens (insXh_op
[lgsize
], newtok
, 3, 1);
3594 /* emit "mskXl $t9, $at, $t9" */
3596 set_tok_reg (newtok
[0], AXP_REG_T9
);
3597 newtok
[2] = newtok
[0];
3598 assemble_tokens (mskXl_op
[lgsize
], newtok
, 3, 1);
3600 /* emit "mskXh $t10, $at, $t10" */
3602 set_tok_reg (newtok
[0], AXP_REG_T10
);
3603 newtok
[2] = newtok
[0];
3604 assemble_tokens (mskXh_op
[lgsize
], newtok
, 3, 1);
3606 /* emit "or $t9, $t11, $t9" */
3608 set_tok_reg (newtok
[0], AXP_REG_T9
);
3609 set_tok_reg (newtok
[1], AXP_REG_T11
);
3610 newtok
[2] = newtok
[0];
3611 assemble_tokens ("or", newtok
, 3, 1);
3613 /* emit "or $t10, $t12, $t10" */
3615 set_tok_reg (newtok
[0], AXP_REG_T10
);
3616 set_tok_reg (newtok
[1], AXP_REG_T12
);
3617 newtok
[2] = newtok
[0];
3618 assemble_tokens ("or", newtok
, 3, 1);
3620 /* emit "stq_u $t9, 0($at)" */
3622 set_tok_reg (newtok
[0], AXP_REG_T9
);
3623 set_tok_const (newtok
[1], 0);
3624 set_tok_preg (newtok
[2], AXP_REG_AT
);
3625 assemble_tokens ("stq_u", newtok
, 3, 1);
3627 /* emit "stq_u $t10, size-1($at)" */
3629 set_tok_reg (newtok
[0], AXP_REG_T10
);
3630 set_tok_const (newtok
[1], (1 << lgsize
) - 1);
3631 assemble_tokens ("stq_u", newtok
, 3, 1);
3634 /* Sign extend a half-word or byte. The 32-bit sign extend is
3635 implemented as "addl $31, $r, $t" in the opcode table. */
3638 emit_sextX (tok
, ntok
, vlgsize
)
3639 const expressionS
*tok
;
3643 long lgsize
= (long) vlgsize
;
3645 if (alpha_target
& AXP_OPCODE_BWX
)
3646 assemble_tokens (sextX_op
[lgsize
], tok
, ntok
, 0);
3649 int bitshift
= 64 - 8 * (1 << lgsize
);
3650 expressionS newtok
[3];
3652 /* emit "sll src,bits,dst" */
3655 set_tok_const (newtok
[1], bitshift
);
3656 newtok
[2] = tok
[ntok
- 1];
3657 assemble_tokens ("sll", newtok
, 3, 1);
3659 /* emit "sra dst,bits,dst" */
3661 newtok
[0] = newtok
[2];
3662 assemble_tokens ("sra", newtok
, 3, 1);
3666 /* Implement the division and modulus macros. */
3670 /* Make register usage like in normal procedure call.
3671 Don't clobber PV and RA. */
3674 emit_division (tok
, ntok
, symname
)
3675 const expressionS
*tok
;
3679 /* DIVISION and MODULUS. Yech.
3684 * mov x,R16 # if x != R16
3685 * mov y,R17 # if y != R17
3690 * with appropriate optimizations if R0,R16,R17 are the registers
3691 * specified by the compiler.
3696 expressionS newtok
[3];
3698 xr
= regno (tok
[0].X_add_number
);
3699 yr
= regno (tok
[1].X_add_number
);
3704 rr
= regno (tok
[2].X_add_number
);
3706 /* Move the operands into the right place */
3707 if (yr
== AXP_REG_R16
&& xr
== AXP_REG_R17
)
3709 /* They are in exactly the wrong order -- swap through AT */
3712 as_bad (_("macro requires $at register while noat in effect"));
3714 set_tok_reg (newtok
[0], AXP_REG_R16
);
3715 set_tok_reg (newtok
[1], AXP_REG_AT
);
3716 assemble_tokens ("mov", newtok
, 2, 1);
3718 set_tok_reg (newtok
[0], AXP_REG_R17
);
3719 set_tok_reg (newtok
[1], AXP_REG_R16
);
3720 assemble_tokens ("mov", newtok
, 2, 1);
3722 set_tok_reg (newtok
[0], AXP_REG_AT
);
3723 set_tok_reg (newtok
[1], AXP_REG_R17
);
3724 assemble_tokens ("mov", newtok
, 2, 1);
3728 if (yr
== AXP_REG_R16
)
3730 set_tok_reg (newtok
[0], AXP_REG_R16
);
3731 set_tok_reg (newtok
[1], AXP_REG_R17
);
3732 assemble_tokens ("mov", newtok
, 2, 1);
3735 if (xr
!= AXP_REG_R16
)
3737 set_tok_reg (newtok
[0], xr
);
3738 set_tok_reg (newtok
[1], AXP_REG_R16
);
3739 assemble_tokens ("mov", newtok
, 2, 1);
3742 if (yr
!= AXP_REG_R16
&& yr
!= AXP_REG_R17
)
3744 set_tok_reg (newtok
[0], yr
);
3745 set_tok_reg (newtok
[1], AXP_REG_R17
);
3746 assemble_tokens ("mov", newtok
, 2, 1);
3750 sym
= symbol_find_or_make ((const char *) symname
);
3752 set_tok_reg (newtok
[0], AXP_REG_AT
);
3753 set_tok_sym (newtok
[1], sym
, 0);
3754 assemble_tokens ("lda", newtok
, 2, 1);
3756 /* Call the division routine */
3757 set_tok_reg (newtok
[0], AXP_REG_AT
);
3758 set_tok_cpreg (newtok
[1], AXP_REG_AT
);
3759 set_tok_const (newtok
[2], 0);
3760 assemble_tokens ("jsr", newtok
, 3, 1);
3762 /* Move the result to the right place */
3763 if (rr
!= AXP_REG_R0
)
3765 set_tok_reg (newtok
[0], AXP_REG_R0
);
3766 set_tok_reg (newtok
[1], rr
);
3767 assemble_tokens ("mov", newtok
, 2, 1);
3771 #else /* !OBJ_EVAX */
3774 emit_division (tok
, ntok
, symname
)
3775 const expressionS
*tok
;
3779 /* DIVISION and MODULUS. Yech.
3789 * with appropriate optimizations if t10,t11,t12 are the registers
3790 * specified by the compiler.
3795 expressionS newtok
[3];
3797 xr
= regno (tok
[0].X_add_number
);
3798 yr
= regno (tok
[1].X_add_number
);
3803 rr
= regno (tok
[2].X_add_number
);
3805 sym
= symbol_find_or_make ((const char *) symname
);
3807 /* Move the operands into the right place */
3808 if (yr
== AXP_REG_T10
&& xr
== AXP_REG_T11
)
3810 /* They are in exactly the wrong order -- swap through AT */
3813 as_bad (_("macro requires $at register while noat in effect"));
3815 set_tok_reg (newtok
[0], AXP_REG_T10
);
3816 set_tok_reg (newtok
[1], AXP_REG_AT
);
3817 assemble_tokens ("mov", newtok
, 2, 1);
3819 set_tok_reg (newtok
[0], AXP_REG_T11
);
3820 set_tok_reg (newtok
[1], AXP_REG_T10
);
3821 assemble_tokens ("mov", newtok
, 2, 1);
3823 set_tok_reg (newtok
[0], AXP_REG_AT
);
3824 set_tok_reg (newtok
[1], AXP_REG_T11
);
3825 assemble_tokens ("mov", newtok
, 2, 1);
3829 if (yr
== AXP_REG_T10
)
3831 set_tok_reg (newtok
[0], AXP_REG_T10
);
3832 set_tok_reg (newtok
[1], AXP_REG_T11
);
3833 assemble_tokens ("mov", newtok
, 2, 1);
3836 if (xr
!= AXP_REG_T10
)
3838 set_tok_reg (newtok
[0], xr
);
3839 set_tok_reg (newtok
[1], AXP_REG_T10
);
3840 assemble_tokens ("mov", newtok
, 2, 1);
3843 if (yr
!= AXP_REG_T10
&& yr
!= AXP_REG_T11
)
3845 set_tok_reg (newtok
[0], yr
);
3846 set_tok_reg (newtok
[1], AXP_REG_T11
);
3847 assemble_tokens ("mov", newtok
, 2, 1);
3851 /* Call the division routine */
3852 set_tok_reg (newtok
[0], AXP_REG_T9
);
3853 set_tok_sym (newtok
[1], sym
, 0);
3854 assemble_tokens ("jsr", newtok
, 2, 1);
3856 /* Reload the GP register */
3860 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
3861 set_tok_reg (newtok
[0], alpha_gp_register
);
3862 set_tok_const (newtok
[1], 0);
3863 set_tok_preg (newtok
[2], AXP_REG_T9
);
3864 assemble_tokens ("ldgp", newtok
, 3, 1);
3867 /* Move the result to the right place */
3868 if (rr
!= AXP_REG_T12
)
3870 set_tok_reg (newtok
[0], AXP_REG_T12
);
3871 set_tok_reg (newtok
[1], rr
);
3872 assemble_tokens ("mov", newtok
, 2, 1);
3876 #endif /* !OBJ_EVAX */
3878 /* The jsr and jmp macros differ from their instruction counterparts
3879 in that they can load the target address and default most
3883 emit_jsrjmp (tok
, ntok
, vopname
)
3884 const expressionS
*tok
;
3888 const char *opname
= (const char *) vopname
;
3889 struct alpha_insn insn
;
3890 expressionS newtok
[3];
3894 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_register
)
3895 r
= regno (tok
[tokidx
++].X_add_number
);
3897 r
= strcmp (opname
, "jmp") == 0 ? AXP_REG_ZERO
: AXP_REG_RA
;
3899 set_tok_reg (newtok
[0], r
);
3901 if (tokidx
< ntok
&&
3902 (tok
[tokidx
].X_op
== O_pregister
|| tok
[tokidx
].X_op
== O_cpregister
))
3903 r
= regno (tok
[tokidx
++].X_add_number
);
3905 /* keep register if jsr $n.<sym> */
3909 int basereg
= alpha_gp_register
;
3910 lituse
= load_expression (r
= AXP_REG_PV
, &tok
[tokidx
], &basereg
, NULL
);
3914 set_tok_cpreg (newtok
[1], r
);
3917 /* FIXME: Add hint relocs to BFD for evax. */
3920 newtok
[2] = tok
[tokidx
];
3923 set_tok_const (newtok
[2], 0);
3925 assemble_tokens_to_insn (opname
, newtok
, 3, &insn
);
3929 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3930 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_JSR
;
3931 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3933 insn
.sequence
= lituse
;
3939 /* The ret and jcr instructions differ from their instruction
3940 counterparts in that everything can be defaulted. */
3943 emit_retjcr (tok
, ntok
, vopname
)
3944 const expressionS
*tok
;
3948 const char *opname
= (const char *) vopname
;
3949 expressionS newtok
[3];
3952 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_register
)
3953 r
= regno (tok
[tokidx
++].X_add_number
);
3957 set_tok_reg (newtok
[0], r
);
3959 if (tokidx
< ntok
&&
3960 (tok
[tokidx
].X_op
== O_pregister
|| tok
[tokidx
].X_op
== O_cpregister
))
3961 r
= regno (tok
[tokidx
++].X_add_number
);
3965 set_tok_cpreg (newtok
[1], r
);
3968 newtok
[2] = tok
[tokidx
];
3970 set_tok_const (newtok
[2], strcmp (opname
, "ret") == 0);
3972 assemble_tokens (opname
, newtok
, 3, 0);
3975 /* Assembler directives */
3977 /* Handle the .text pseudo-op. This is like the usual one, but it
3978 clears alpha_insn_label and restores auto alignment. */
3986 alpha_insn_label
= NULL
;
3987 alpha_auto_align_on
= 1;
3988 alpha_current_align
= 0;
3991 /* Handle the .data pseudo-op. This is like the usual one, but it
3992 clears alpha_insn_label and restores auto alignment. */
3999 alpha_insn_label
= NULL
;
4000 alpha_auto_align_on
= 1;
4001 alpha_current_align
= 0;
4004 #if defined (OBJ_ECOFF) || defined (OBJ_EVAX)
4006 /* Handle the OSF/1 and openVMS .comm pseudo quirks.
4007 openVMS constructs a section for every common symbol. */
4010 s_alpha_comm (ignore
)
4013 register char *name
;
4017 register symbolS
*symbolP
;
4020 segT current_section
= now_seg
;
4021 int current_subsec
= now_subseg
;
4025 name
= input_line_pointer
;
4026 c
= get_symbol_end ();
4028 /* just after name is now '\0' */
4029 p
= input_line_pointer
;
4034 /* Alpha OSF/1 compiler doesn't provide the comma, gcc does. */
4035 if (*input_line_pointer
== ',')
4037 input_line_pointer
++;
4040 if ((temp
= get_absolute_expression ()) < 0)
4042 as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) temp
);
4043 ignore_rest_of_line ();
4048 symbolP
= symbol_find_or_make (name
);
4051 /* Make a section for the common symbol. */
4052 new_seg
= subseg_new (xstrdup (name
), 0);
4058 /* alignment might follow */
4059 if (*input_line_pointer
== ',')
4063 input_line_pointer
++;
4064 align
= get_absolute_expression ();
4065 bfd_set_section_alignment (stdoutput
, new_seg
, align
);
4069 if (S_IS_DEFINED (symbolP
) && ! S_IS_COMMON (symbolP
))
4071 as_bad (_("Ignoring attempt to re-define symbol"));
4072 ignore_rest_of_line ();
4077 if (bfd_section_size (stdoutput
, new_seg
) > 0)
4079 if (bfd_section_size (stdoutput
, new_seg
) != temp
)
4080 as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
4081 S_GET_NAME (symbolP
),
4082 (long) bfd_section_size (stdoutput
, new_seg
),
4086 if (S_GET_VALUE (symbolP
))
4088 if (S_GET_VALUE (symbolP
) != (valueT
) temp
)
4089 as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
4090 S_GET_NAME (symbolP
),
4091 (long) S_GET_VALUE (symbolP
),
4098 subseg_set (new_seg
, 0);
4099 p
= frag_more (temp
);
4100 new_seg
->flags
|= SEC_IS_COMMON
;
4101 if (! S_IS_DEFINED (symbolP
))
4102 S_SET_SEGMENT (symbolP
, new_seg
);
4104 S_SET_VALUE (symbolP
, (valueT
) temp
);
4106 S_SET_EXTERNAL (symbolP
);
4110 subseg_set (current_section
, current_subsec
);
4113 know (symbol_get_frag (symbolP
) == &zero_address_frag
);
4115 demand_empty_rest_of_line ();
4118 #endif /* ! OBJ_ELF */
4122 /* Handle the .rdata pseudo-op. This is like the usual one, but it
4123 clears alpha_insn_label and restores auto alignment. */
4126 s_alpha_rdata (ignore
)
4131 temp
= get_absolute_expression ();
4132 subseg_new (".rdata", 0);
4133 demand_empty_rest_of_line ();
4134 alpha_insn_label
= NULL
;
4135 alpha_auto_align_on
= 1;
4136 alpha_current_align
= 0;
4143 /* Handle the .sdata pseudo-op. This is like the usual one, but it
4144 clears alpha_insn_label and restores auto alignment. */
4147 s_alpha_sdata (ignore
)
4152 temp
= get_absolute_expression ();
4153 subseg_new (".sdata", 0);
4154 demand_empty_rest_of_line ();
4155 alpha_insn_label
= NULL
;
4156 alpha_auto_align_on
= 1;
4157 alpha_current_align
= 0;
4163 /* Handle the .section pseudo-op. This is like the usual one, but it
4164 clears alpha_insn_label and restores auto alignment. */
4167 s_alpha_section (ignore
)
4170 obj_elf_section (ignore
);
4172 alpha_insn_label
= NULL
;
4173 alpha_auto_align_on
= 1;
4174 alpha_current_align
= 0;
4179 int dummy ATTRIBUTE_UNUSED
;
4181 if (ECOFF_DEBUGGING
)
4182 ecoff_directive_ent (0);
4185 char *name
, name_end
;
4186 name
= input_line_pointer
;
4187 name_end
= get_symbol_end ();
4189 if (! is_name_beginner (*name
))
4191 as_warn (_(".ent directive has no name"));
4192 *input_line_pointer
= name_end
;
4198 if (alpha_cur_ent_sym
)
4199 as_warn (_("nested .ent directives"));
4201 sym
= symbol_find_or_make (name
);
4202 symbol_get_bfdsym (sym
)->flags
|= BSF_FUNCTION
;
4203 alpha_cur_ent_sym
= sym
;
4205 /* The .ent directive is sometimes followed by a number. Not sure
4206 what it really means, but ignore it. */
4207 *input_line_pointer
= name_end
;
4209 if (*input_line_pointer
== ',')
4211 input_line_pointer
++;
4214 if (ISDIGIT (*input_line_pointer
) || *input_line_pointer
== '-')
4215 (void) get_absolute_expression ();
4217 demand_empty_rest_of_line ();
4223 int dummy ATTRIBUTE_UNUSED
;
4225 if (ECOFF_DEBUGGING
)
4226 ecoff_directive_end (0);
4229 char *name
, name_end
;
4230 name
= input_line_pointer
;
4231 name_end
= get_symbol_end ();
4233 if (! is_name_beginner (*name
))
4235 as_warn (_(".end directive has no name"));
4236 *input_line_pointer
= name_end
;
4242 sym
= symbol_find (name
);
4243 if (sym
!= alpha_cur_ent_sym
)
4244 as_warn (_(".end directive names different symbol than .ent"));
4246 /* Create an expression to calculate the size of the function. */
4249 symbol_get_obj (sym
)->size
=
4250 (expressionS
*) xmalloc (sizeof (expressionS
));
4251 symbol_get_obj (sym
)->size
->X_op
= O_subtract
;
4252 symbol_get_obj (sym
)->size
->X_add_symbol
4253 = symbol_new ("L0\001", now_seg
, frag_now_fix (), frag_now
);
4254 symbol_get_obj (sym
)->size
->X_op_symbol
= sym
;
4255 symbol_get_obj (sym
)->size
->X_add_number
= 0;
4258 alpha_cur_ent_sym
= NULL
;
4260 *input_line_pointer
= name_end
;
4262 demand_empty_rest_of_line ();
4270 if (ECOFF_DEBUGGING
)
4273 ecoff_directive_fmask (0);
4275 ecoff_directive_mask (0);
4278 discard_rest_of_line ();
4282 s_alpha_frame (dummy
)
4283 int dummy ATTRIBUTE_UNUSED
;
4285 if (ECOFF_DEBUGGING
)
4286 ecoff_directive_frame (0);
4288 discard_rest_of_line ();
4292 s_alpha_prologue (ignore
)
4293 int ignore ATTRIBUTE_UNUSED
;
4298 arg
= get_absolute_expression ();
4299 demand_empty_rest_of_line ();
4301 if (ECOFF_DEBUGGING
)
4302 sym
= ecoff_get_cur_proc_sym ();
4304 sym
= alpha_cur_ent_sym
;
4309 case 0: /* No PV required. */
4310 S_SET_OTHER (sym
, STO_ALPHA_NOPV
4311 | (S_GET_OTHER (sym
) & ~STO_ALPHA_STD_GPLOAD
));
4313 case 1: /* Std GP load. */
4314 S_SET_OTHER (sym
, STO_ALPHA_STD_GPLOAD
4315 | (S_GET_OTHER (sym
) & ~STO_ALPHA_STD_GPLOAD
));
4317 case 2: /* Non-std use of PV. */
4321 as_bad (_("Invalid argument %d to .prologue."), arg
);
4326 static char *first_file_directive
;
4329 s_alpha_file (ignore
)
4330 int ignore ATTRIBUTE_UNUSED
;
4332 /* Save the first .file directive we see, so that we can change our
4333 minds about whether ecoff debugging should or shouldn't be enabled. */
4334 if (alpha_flag_mdebug
< 0 && ! first_file_directive
)
4336 char *start
= input_line_pointer
;
4339 discard_rest_of_line ();
4341 len
= input_line_pointer
- start
;
4342 first_file_directive
= xmalloc (len
+ 1);
4343 memcpy (first_file_directive
, start
, len
);
4344 first_file_directive
[len
] = '\0';
4346 input_line_pointer
= start
;
4349 if (ECOFF_DEBUGGING
)
4350 ecoff_directive_file (0);
4352 dwarf2_directive_file (0);
4356 s_alpha_loc (ignore
)
4357 int ignore ATTRIBUTE_UNUSED
;
4359 if (ECOFF_DEBUGGING
)
4360 ecoff_directive_loc (0);
4362 dwarf2_directive_loc (0);
4369 /* If we've been undecided about mdebug, make up our minds in favour. */
4370 if (alpha_flag_mdebug
< 0)
4372 segT sec
= subseg_new (".mdebug", 0);
4373 bfd_set_section_flags (stdoutput
, sec
, SEC_HAS_CONTENTS
| SEC_READONLY
);
4374 bfd_set_section_alignment (stdoutput
, sec
, 3);
4376 ecoff_read_begin_hook ();
4378 if (first_file_directive
)
4380 char *save_ilp
= input_line_pointer
;
4381 input_line_pointer
= first_file_directive
;
4382 ecoff_directive_file (0);
4383 input_line_pointer
= save_ilp
;
4384 free (first_file_directive
);
4387 alpha_flag_mdebug
= 1;
4393 s_alpha_coff_wrapper (which
)
4396 static void (* const fns
[]) PARAMS ((int)) = {
4397 ecoff_directive_begin
,
4398 ecoff_directive_bend
,
4399 ecoff_directive_def
,
4400 ecoff_directive_dim
,
4401 ecoff_directive_endef
,
4402 ecoff_directive_scl
,
4403 ecoff_directive_tag
,
4404 ecoff_directive_val
,
4407 assert (which
>= 0 && which
< (int) (sizeof (fns
)/sizeof (*fns
)));
4409 if (ECOFF_DEBUGGING
)
4413 as_bad (_("ECOFF debugging is disabled."));
4414 ignore_rest_of_line ();
4417 #endif /* OBJ_ELF */
4421 /* Handle the section specific pseudo-op. */
4424 s_alpha_section (secid
)
4428 #define EVAX_SECTION_COUNT 5
4429 static char *section_name
[EVAX_SECTION_COUNT
+ 1] =
4430 { "NULL", ".rdata", ".comm", ".link", ".ctors", ".dtors" };
4432 if ((secid
<= 0) || (secid
> EVAX_SECTION_COUNT
))
4434 as_fatal (_("Unknown section directive"));
4435 demand_empty_rest_of_line ();
4438 temp
= get_absolute_expression ();
4439 subseg_new (section_name
[secid
], 0);
4440 demand_empty_rest_of_line ();
4441 alpha_insn_label
= NULL
;
4442 alpha_auto_align_on
= 1;
4443 alpha_current_align
= 0;
4446 /* Parse .ent directives. */
4449 s_alpha_ent (ignore
)
4453 expressionS symexpr
;
4455 alpha_evax_proc
.pdsckind
= 0;
4456 alpha_evax_proc
.framereg
= -1;
4457 alpha_evax_proc
.framesize
= 0;
4458 alpha_evax_proc
.rsa_offset
= 0;
4459 alpha_evax_proc
.ra_save
= AXP_REG_RA
;
4460 alpha_evax_proc
.fp_save
= -1;
4461 alpha_evax_proc
.imask
= 0;
4462 alpha_evax_proc
.fmask
= 0;
4463 alpha_evax_proc
.prologue
= 0;
4464 alpha_evax_proc
.type
= 0;
4466 expression (&symexpr
);
4468 if (symexpr
.X_op
!= O_symbol
)
4470 as_fatal (_(".ent directive has no symbol"));
4471 demand_empty_rest_of_line ();
4475 symbol
= make_expr_symbol (&symexpr
);
4476 symbol_get_bfdsym (symbol
)->flags
|= BSF_FUNCTION
;
4477 alpha_evax_proc
.symbol
= symbol
;
4479 demand_empty_rest_of_line ();
4483 /* Parse .frame <framreg>,<framesize>,RA,<rsa_offset> directives. */
4486 s_alpha_frame (ignore
)
4491 alpha_evax_proc
.framereg
= tc_get_register (1);
4494 if (*input_line_pointer
++ != ','
4495 || get_absolute_expression_and_terminator (&val
) != ',')
4497 as_warn (_("Bad .frame directive 1./2. param"));
4498 --input_line_pointer
;
4499 demand_empty_rest_of_line ();
4503 alpha_evax_proc
.framesize
= val
;
4505 (void) tc_get_register (1);
4507 if (*input_line_pointer
++ != ',')
4509 as_warn (_("Bad .frame directive 3./4. param"));
4510 --input_line_pointer
;
4511 demand_empty_rest_of_line ();
4514 alpha_evax_proc
.rsa_offset
= get_absolute_expression ();
4520 s_alpha_pdesc (ignore
)
4530 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
4532 if (now_seg
!= alpha_link_section
)
4534 as_bad (_(".pdesc directive not in link (.link) section"));
4535 demand_empty_rest_of_line ();
4539 if ((alpha_evax_proc
.symbol
== 0)
4540 || (!S_IS_DEFINED (alpha_evax_proc
.symbol
)))
4542 as_fatal (_(".pdesc has no matching .ent"));
4543 demand_empty_rest_of_line ();
4547 *symbol_get_obj (alpha_evax_proc
.symbol
) =
4548 (valueT
) seginfo
->literal_pool_size
;
4551 if (exp
.X_op
!= O_symbol
)
4553 as_warn (_(".pdesc directive has no entry symbol"));
4554 demand_empty_rest_of_line ();
4558 entry_sym
= make_expr_symbol (&exp
);
4559 /* Save bfd symbol of proc desc in function symbol. */
4560 symbol_get_bfdsym (alpha_evax_proc
.symbol
)->udata
.p
4561 = symbol_get_bfdsym (entry_sym
);
4564 if (*input_line_pointer
++ != ',')
4566 as_warn (_("No comma after .pdesc <entryname>"));
4567 demand_empty_rest_of_line ();
4572 name
= input_line_pointer
;
4573 name_end
= get_symbol_end ();
4575 if (strncmp (name
, "stack", 5) == 0)
4577 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_FP_STACK
;
4579 else if (strncmp (name
, "reg", 3) == 0)
4581 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_FP_REGISTER
;
4583 else if (strncmp (name
, "null", 4) == 0)
4585 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_NULL
;
4589 as_fatal (_("unknown procedure kind"));
4590 demand_empty_rest_of_line ();
4594 *input_line_pointer
= name_end
;
4595 demand_empty_rest_of_line ();
4597 #ifdef md_flush_pending_output
4598 md_flush_pending_output ();
4601 frag_align (3, 0, 0);
4603 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
4605 seginfo
->literal_pool_size
+= 16;
4607 *p
= alpha_evax_proc
.pdsckind
4608 | ((alpha_evax_proc
.framereg
== 29) ? PDSC_S_M_BASE_REG_IS_FP
: 0);
4609 *(p
+ 1) = PDSC_S_M_NATIVE
| PDSC_S_M_NO_JACKET
;
4611 switch (alpha_evax_proc
.pdsckind
)
4613 case PDSC_S_K_KIND_NULL
:
4617 case PDSC_S_K_KIND_FP_REGISTER
:
4618 *(p
+ 2) = alpha_evax_proc
.fp_save
;
4619 *(p
+ 3) = alpha_evax_proc
.ra_save
;
4621 case PDSC_S_K_KIND_FP_STACK
:
4622 md_number_to_chars (p
+ 2, (valueT
) alpha_evax_proc
.rsa_offset
, 2);
4624 default: /* impossible */
4629 *(p
+ 5) = alpha_evax_proc
.type
& 0x0f;
4631 /* Signature offset. */
4632 md_number_to_chars (p
+ 6, (valueT
) 0, 2);
4634 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
+8, 8, &exp
, 0, BFD_RELOC_64
);
4636 if (alpha_evax_proc
.pdsckind
== PDSC_S_K_KIND_NULL
)
4639 /* Add dummy fix to make add_to_link_pool work. */
4641 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
4643 seginfo
->literal_pool_size
+= 8;
4645 /* pdesc+16: Size. */
4646 md_number_to_chars (p
, (valueT
) alpha_evax_proc
.framesize
, 4);
4648 md_number_to_chars (p
+ 4, (valueT
) 0, 2);
4651 md_number_to_chars (p
+ 6, alpha_evax_proc
.prologue
, 2);
4653 if (alpha_evax_proc
.pdsckind
== PDSC_S_K_KIND_FP_REGISTER
)
4656 /* Add dummy fix to make add_to_link_pool work. */
4658 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
4660 seginfo
->literal_pool_size
+= 8;
4662 /* pdesc+24: register masks. */
4664 md_number_to_chars (p
, alpha_evax_proc
.imask
, 4);
4665 md_number_to_chars (p
+ 4, alpha_evax_proc
.fmask
, 4);
4670 /* Support for crash debug on vms. */
4673 s_alpha_name (ignore
)
4678 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
4680 if (now_seg
!= alpha_link_section
)
4682 as_bad (_(".name directive not in link (.link) section"));
4683 demand_empty_rest_of_line ();
4688 if (exp
.X_op
!= O_symbol
)
4690 as_warn (_(".name directive has no symbol"));
4691 demand_empty_rest_of_line ();
4695 demand_empty_rest_of_line ();
4697 #ifdef md_flush_pending_output
4698 md_flush_pending_output ();
4701 frag_align (3, 0, 0);
4703 seginfo
->literal_pool_size
+= 8;
4705 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 8, &exp
, 0, BFD_RELOC_64
);
4711 s_alpha_linkage (ignore
)
4717 #ifdef md_flush_pending_output
4718 md_flush_pending_output ();
4722 if (exp
.X_op
!= O_symbol
)
4724 as_fatal (_("No symbol after .linkage"));
4728 p
= frag_more (LKP_S_K_SIZE
);
4729 memset (p
, 0, LKP_S_K_SIZE
);
4730 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, LKP_S_K_SIZE
, &exp
, 0,\
4731 BFD_RELOC_ALPHA_LINKAGE
);
4733 demand_empty_rest_of_line ();
4739 s_alpha_code_address (ignore
)
4745 #ifdef md_flush_pending_output
4746 md_flush_pending_output ();
4750 if (exp
.X_op
!= O_symbol
)
4752 as_fatal (_("No symbol after .code_address"));
4758 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 8, &exp
, 0,\
4759 BFD_RELOC_ALPHA_CODEADDR
);
4761 demand_empty_rest_of_line ();
4767 s_alpha_fp_save (ignore
)
4771 alpha_evax_proc
.fp_save
= tc_get_register (1);
4773 demand_empty_rest_of_line ();
4778 s_alpha_mask (ignore
)
4783 if (get_absolute_expression_and_terminator (&val
) != ',')
4785 as_warn (_("Bad .mask directive"));
4786 --input_line_pointer
;
4790 alpha_evax_proc
.imask
= val
;
4791 (void) get_absolute_expression ();
4793 demand_empty_rest_of_line ();
4799 s_alpha_fmask (ignore
)
4804 if (get_absolute_expression_and_terminator (&val
) != ',')
4806 as_warn (_("Bad .fmask directive"));
4807 --input_line_pointer
;
4811 alpha_evax_proc
.fmask
= val
;
4812 (void) get_absolute_expression ();
4814 demand_empty_rest_of_line ();
4820 s_alpha_end (ignore
)
4825 c
= get_symbol_end ();
4826 *input_line_pointer
= c
;
4827 demand_empty_rest_of_line ();
4828 alpha_evax_proc
.symbol
= 0;
4834 s_alpha_file (ignore
)
4839 static char case_hack
[32];
4841 extern char *demand_copy_string
PARAMS ((int *lenP
));
4843 sprintf (case_hack
, "<CASE:%01d%01d>",
4844 alpha_flag_hash_long_names
, alpha_flag_show_after_trunc
);
4846 s
= symbol_find_or_make (case_hack
);
4847 symbol_get_bfdsym (s
)->flags
|= BSF_FILE
;
4849 get_absolute_expression ();
4850 s
= symbol_find_or_make (demand_copy_string (&length
));
4851 symbol_get_bfdsym (s
)->flags
|= BSF_FILE
;
4852 demand_empty_rest_of_line ();
4856 #endif /* OBJ_EVAX */
4858 /* Handle the .gprel32 pseudo op. */
4861 s_alpha_gprel32 (ignore
)
4862 int ignore ATTRIBUTE_UNUSED
;
4874 e
.X_add_symbol
= section_symbol (absolute_section
);
4887 e
.X_add_symbol
= section_symbol (absolute_section
);
4890 e
.X_op
= O_subtract
;
4891 e
.X_op_symbol
= alpha_gp_symbol
;
4899 if (alpha_auto_align_on
&& alpha_current_align
< 2)
4900 alpha_align (2, (char *) NULL
, alpha_insn_label
, 0);
4901 if (alpha_current_align
> 2)
4902 alpha_current_align
= 2;
4903 alpha_insn_label
= NULL
;
4907 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 4,
4908 &e
, 0, BFD_RELOC_GPREL32
);
4911 /* Handle floating point allocation pseudo-ops. This is like the
4912 generic vresion, but it makes sure the current label, if any, is
4913 correctly aligned. */
4916 s_alpha_float_cons (type
)
4943 if (alpha_auto_align_on
&& alpha_current_align
< log_size
)
4944 alpha_align (log_size
, (char *) NULL
, alpha_insn_label
, 0);
4945 if (alpha_current_align
> log_size
)
4946 alpha_current_align
= log_size
;
4947 alpha_insn_label
= NULL
;
4952 /* Handle the .proc pseudo op. We don't really do much with it except
4956 s_alpha_proc (is_static
)
4957 int is_static ATTRIBUTE_UNUSED
;
4965 /* Takes ".proc name,nargs" */
4967 name
= input_line_pointer
;
4968 c
= get_symbol_end ();
4969 p
= input_line_pointer
;
4970 symbolP
= symbol_find_or_make (name
);
4973 if (*input_line_pointer
!= ',')
4976 as_warn (_("Expected comma after name \"%s\""), name
);
4979 ignore_rest_of_line ();
4983 input_line_pointer
++;
4984 temp
= get_absolute_expression ();
4986 /* *symbol_get_obj (symbolP) = (signed char) temp; */
4987 as_warn (_("unhandled: .proc %s,%d"), name
, temp
);
4988 demand_empty_rest_of_line ();
4991 /* Handle the .set pseudo op. This is used to turn on and off most of
4992 the assembler features. */
4996 int x ATTRIBUTE_UNUSED
;
5002 name
= input_line_pointer
;
5003 ch
= get_symbol_end ();
5006 if (s
[0] == 'n' && s
[1] == 'o')
5011 if (!strcmp ("reorder", s
))
5013 else if (!strcmp ("at", s
))
5014 alpha_noat_on
= !yesno
;
5015 else if (!strcmp ("macro", s
))
5016 alpha_macros_on
= yesno
;
5017 else if (!strcmp ("move", s
))
5019 else if (!strcmp ("volatile", s
))
5022 as_warn (_("Tried to .set unrecognized mode `%s'"), name
);
5024 *input_line_pointer
= ch
;
5025 demand_empty_rest_of_line ();
5028 /* Handle the .base pseudo op. This changes the assembler's notion of
5029 the $gp register. */
5032 s_alpha_base (ignore
)
5033 int ignore ATTRIBUTE_UNUSED
;
5036 if (first_32bit_quadrant
)
5038 /* not fatal, but it might not work in the end */
5039 as_warn (_("File overrides no-base-register option."));
5040 first_32bit_quadrant
= 0;
5045 if (*input_line_pointer
== '$')
5047 input_line_pointer
++;
5048 if (*input_line_pointer
== 'r')
5049 input_line_pointer
++;
5052 alpha_gp_register
= get_absolute_expression ();
5053 if (alpha_gp_register
< 0 || alpha_gp_register
> 31)
5055 alpha_gp_register
= AXP_REG_GP
;
5056 as_warn (_("Bad base register, using $%d."), alpha_gp_register
);
5059 demand_empty_rest_of_line ();
5062 /* Handle the .align pseudo-op. This aligns to a power of two. It
5063 also adjusts any current instruction label. We treat this the same
5064 way the MIPS port does: .align 0 turns off auto alignment. */
5067 s_alpha_align (ignore
)
5068 int ignore ATTRIBUTE_UNUSED
;
5072 long max_alignment
= 15;
5074 align
= get_absolute_expression ();
5075 if (align
> max_alignment
)
5077 align
= max_alignment
;
5078 as_bad (_("Alignment too large: %d. assumed"), align
);
5082 as_warn (_("Alignment negative: 0 assumed"));
5086 if (*input_line_pointer
== ',')
5088 input_line_pointer
++;
5089 fill
= get_absolute_expression ();
5097 alpha_auto_align_on
= 1;
5098 alpha_align (align
, pfill
, alpha_insn_label
, 1);
5102 alpha_auto_align_on
= 0;
5105 demand_empty_rest_of_line ();
5108 /* Hook the normal string processor to reset known alignment. */
5111 s_alpha_stringer (terminate
)
5114 alpha_current_align
= 0;
5115 alpha_insn_label
= NULL
;
5116 stringer (terminate
);
5119 /* Hook the normal space processing to reset known alignment. */
5122 s_alpha_space (ignore
)
5125 alpha_current_align
= 0;
5126 alpha_insn_label
= NULL
;
5130 /* Hook into cons for auto-alignment. */
5133 alpha_cons_align (size
)
5139 while ((size
>>= 1) != 0)
5142 if (alpha_auto_align_on
&& alpha_current_align
< log_size
)
5143 alpha_align (log_size
, (char *) NULL
, alpha_insn_label
, 0);
5144 if (alpha_current_align
> log_size
)
5145 alpha_current_align
= log_size
;
5146 alpha_insn_label
= NULL
;
5149 /* Here come the .uword, .ulong, and .uquad explicitly unaligned
5150 pseudos. We just turn off auto-alignment and call down to cons. */
5153 s_alpha_ucons (bytes
)
5156 int hold
= alpha_auto_align_on
;
5157 alpha_auto_align_on
= 0;
5159 alpha_auto_align_on
= hold
;
5162 /* Switch the working cpu type. */
5165 s_alpha_arch (ignored
)
5166 int ignored ATTRIBUTE_UNUSED
;
5169 const struct cpu_type
*p
;
5172 name
= input_line_pointer
;
5173 ch
= get_symbol_end ();
5175 for (p
= cpu_types
; p
->name
; ++p
)
5176 if (strcmp (name
, p
->name
) == 0)
5178 alpha_target_name
= p
->name
, alpha_target
= p
->flags
;
5181 as_warn ("Unknown CPU identifier `%s'", name
);
5184 *input_line_pointer
= ch
;
5185 demand_empty_rest_of_line ();
5189 /* print token expression with alpha specific extension. */
5192 alpha_print_token (f
, exp
)
5194 const expressionS
*exp
;
5204 expressionS nexp
= *exp
;
5205 nexp
.X_op
= O_register
;
5206 print_expr (f
, &nexp
);
5211 print_expr (f
, exp
);
5218 /* The target specific pseudo-ops which we support. */
5220 const pseudo_typeS md_pseudo_table
[] = {
5222 {"comm", s_alpha_comm
, 0}, /* osf1 compiler does this */
5223 {"rdata", s_alpha_rdata
, 0},
5225 {"text", s_alpha_text
, 0},
5226 {"data", s_alpha_data
, 0},
5228 {"sdata", s_alpha_sdata
, 0},
5231 {"section", s_alpha_section
, 0},
5232 {"section.s", s_alpha_section
, 0},
5233 {"sect", s_alpha_section
, 0},
5234 {"sect.s", s_alpha_section
, 0},
5237 { "pdesc", s_alpha_pdesc
, 0},
5238 { "name", s_alpha_name
, 0},
5239 { "linkage", s_alpha_linkage
, 0},
5240 { "code_address", s_alpha_code_address
, 0},
5241 { "ent", s_alpha_ent
, 0},
5242 { "frame", s_alpha_frame
, 0},
5243 { "fp_save", s_alpha_fp_save
, 0},
5244 { "mask", s_alpha_mask
, 0},
5245 { "fmask", s_alpha_fmask
, 0},
5246 { "end", s_alpha_end
, 0},
5247 { "file", s_alpha_file
, 0},
5248 { "rdata", s_alpha_section
, 1},
5249 { "comm", s_alpha_comm
, 0},
5250 { "link", s_alpha_section
, 3},
5251 { "ctors", s_alpha_section
, 4},
5252 { "dtors", s_alpha_section
, 5},
5255 /* Frame related pseudos. */
5256 {"ent", s_alpha_ent
, 0},
5257 {"end", s_alpha_end
, 0},
5258 {"mask", s_alpha_mask
, 0},
5259 {"fmask", s_alpha_mask
, 1},
5260 {"frame", s_alpha_frame
, 0},
5261 {"prologue", s_alpha_prologue
, 0},
5262 {"file", s_alpha_file
, 5},
5263 {"loc", s_alpha_loc
, 9},
5264 {"stabs", s_alpha_stab
, 's'},
5265 {"stabn", s_alpha_stab
, 'n'},
5266 /* COFF debugging related pseudos. */
5267 {"begin", s_alpha_coff_wrapper
, 0},
5268 {"bend", s_alpha_coff_wrapper
, 1},
5269 {"def", s_alpha_coff_wrapper
, 2},
5270 {"dim", s_alpha_coff_wrapper
, 3},
5271 {"endef", s_alpha_coff_wrapper
, 4},
5272 {"scl", s_alpha_coff_wrapper
, 5},
5273 {"tag", s_alpha_coff_wrapper
, 6},
5274 {"val", s_alpha_coff_wrapper
, 7},
5276 {"prologue", s_ignore
, 0},
5278 {"gprel32", s_alpha_gprel32
, 0},
5279 {"t_floating", s_alpha_float_cons
, 'd'},
5280 {"s_floating", s_alpha_float_cons
, 'f'},
5281 {"f_floating", s_alpha_float_cons
, 'F'},
5282 {"g_floating", s_alpha_float_cons
, 'G'},
5283 {"d_floating", s_alpha_float_cons
, 'D'},
5285 {"proc", s_alpha_proc
, 0},
5286 {"aproc", s_alpha_proc
, 1},
5287 {"set", s_alpha_set
, 0},
5288 {"reguse", s_ignore
, 0},
5289 {"livereg", s_ignore
, 0},
5290 {"base", s_alpha_base
, 0}, /*??*/
5291 {"option", s_ignore
, 0},
5292 {"aent", s_ignore
, 0},
5293 {"ugen", s_ignore
, 0},
5294 {"eflag", s_ignore
, 0},
5296 {"align", s_alpha_align
, 0},
5297 {"double", s_alpha_float_cons
, 'd'},
5298 {"float", s_alpha_float_cons
, 'f'},
5299 {"single", s_alpha_float_cons
, 'f'},
5300 {"ascii", s_alpha_stringer
, 0},
5301 {"asciz", s_alpha_stringer
, 1},
5302 {"string", s_alpha_stringer
, 1},
5303 {"space", s_alpha_space
, 0},
5304 {"skip", s_alpha_space
, 0},
5305 {"zero", s_alpha_space
, 0},
5307 /* Unaligned data pseudos. */
5308 {"uword", s_alpha_ucons
, 2},
5309 {"ulong", s_alpha_ucons
, 4},
5310 {"uquad", s_alpha_ucons
, 8},
5313 /* Dwarf wants these versions of unaligned. */
5314 {"2byte", s_alpha_ucons
, 2},
5315 {"4byte", s_alpha_ucons
, 4},
5316 {"8byte", s_alpha_ucons
, 8},
5319 /* We don't do any optimizing, so we can safely ignore these. */
5320 {"noalias", s_ignore
, 0},
5321 {"alias", s_ignore
, 0},
5323 {"arch", s_alpha_arch
, 0},
5328 /* Build a BFD section with its flags set appropriately for the .lita,
5329 .lit8, or .lit4 sections. */
5332 create_literal_section (name
, secp
, symp
)
5337 segT current_section
= now_seg
;
5338 int current_subsec
= now_subseg
;
5341 *secp
= new_sec
= subseg_new (name
, 0);
5342 subseg_set (current_section
, current_subsec
);
5343 bfd_set_section_alignment (stdoutput
, new_sec
, 4);
5344 bfd_set_section_flags (stdoutput
, new_sec
,
5345 SEC_RELOC
| SEC_ALLOC
| SEC_LOAD
| SEC_READONLY
5348 S_CLEAR_EXTERNAL (*symp
= section_symbol (new_sec
));
5353 /* @@@ GP selection voodoo. All of this seems overly complicated and
5354 unnecessary; which is the primary reason it's for ECOFF only. */
5363 vma
= bfd_get_section_vma (foo
, sec
);
5364 if (vma
&& vma
< alpha_gp_value
)
5365 alpha_gp_value
= vma
;
5371 assert (alpha_gp_value
== 0);
5373 /* Get minus-one in whatever width... */
5377 /* Select the smallest VMA of these existing sections. */
5378 maybe_set_gp (alpha_lita_section
);
5380 /* These were disabled before -- should we use them? */
5381 maybe_set_gp (sdata
);
5382 maybe_set_gp (lit8_sec
);
5383 maybe_set_gp (lit4_sec
);
5386 /* @@ Will a simple 0x8000 work here? If not, why not? */
5387 #define GP_ADJUSTMENT (0x8000 - 0x10)
5389 alpha_gp_value
+= GP_ADJUSTMENT
;
5391 S_SET_VALUE (alpha_gp_symbol
, alpha_gp_value
);
5394 printf (_("Chose GP value of %lx\n"), alpha_gp_value
);
5397 #endif /* OBJ_ECOFF */
5400 /* Map 's' to SHF_ALPHA_GPREL. */
5403 alpha_elf_section_letter (letter
, ptr_msg
)
5408 return SHF_ALPHA_GPREL
;
5410 *ptr_msg
= _("Bad .section directive: want a,s,w,x,M,S in string");
5414 /* Map SHF_ALPHA_GPREL to SEC_SMALL_DATA. */
5417 alpha_elf_section_flags (flags
, attr
, type
)
5419 int attr
, type ATTRIBUTE_UNUSED
;
5421 if (attr
& SHF_ALPHA_GPREL
)
5422 flags
|= SEC_SMALL_DATA
;
5425 #endif /* OBJ_ELF */
5427 /* Called internally to handle all alignment needs. This takes care
5428 of eliding calls to frag_align if'n the cached current alignment
5429 says we've already got it, as well as taking care of the auto-align
5430 feature wrt labels. */
5433 alpha_align (n
, pfill
, label
, force
)
5437 int force ATTRIBUTE_UNUSED
;
5439 if (alpha_current_align
>= n
)
5444 if (subseg_text_p (now_seg
))
5445 frag_align_code (n
, 0);
5447 frag_align (n
, 0, 0);
5450 frag_align (n
, *pfill
, 0);
5452 alpha_current_align
= n
;
5454 if (label
!= NULL
&& S_GET_SEGMENT (label
) == now_seg
)
5456 symbol_set_frag (label
, frag_now
);
5457 S_SET_VALUE (label
, (valueT
) frag_now_fix ());
5460 record_alignment (now_seg
, n
);
5462 /* ??? If alpha_flag_relax && force && elf, record the requested alignment
5463 in a reloc for the linker to see. */
5466 /* This is called from HANDLE_ALIGN in write.c. Fill in the contents
5467 of an rs_align_code fragment. */
5470 alpha_handle_align (fragp
)
5473 static char const unop
[4] = { 0x00, 0x00, 0xe0, 0x2f };
5474 static char const nopunop
[8] = {
5475 0x1f, 0x04, 0xff, 0x47,
5476 0x00, 0x00, 0xe0, 0x2f
5482 if (fragp
->fr_type
!= rs_align_code
)
5485 bytes
= fragp
->fr_next
->fr_address
- fragp
->fr_address
- fragp
->fr_fix
;
5486 p
= fragp
->fr_literal
+ fragp
->fr_fix
;
5499 memcpy (p
, unop
, 4);
5505 memcpy (p
, nopunop
, 8);
5507 fragp
->fr_fix
+= fix
;
5511 /* The Alpha has support for some VAX floating point types, as well as for
5512 IEEE floating point. We consider IEEE to be the primary floating point
5513 format, and sneak in the VAX floating point support here. */
5514 #define md_atof vax_md_atof
5515 #include "config/atof-vax.c"