1 /* tc-alpha.c - Processor-specific code for the DEC Alpha AXP CPU.
2 Copyright 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 2001, 2002 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 */
120 #define O_samegp O_md12 /* !samegp relocation */
122 #define DUMMY_RELOC_LITUSE_ADDR (BFD_RELOC_UNUSED + 1)
123 #define DUMMY_RELOC_LITUSE_BASE (BFD_RELOC_UNUSED + 2)
124 #define DUMMY_RELOC_LITUSE_BYTOFF (BFD_RELOC_UNUSED + 3)
125 #define DUMMY_RELOC_LITUSE_JSR (BFD_RELOC_UNUSED + 4)
127 #define LITUSE_ADDR 0
128 #define LITUSE_BASE 1
129 #define LITUSE_BYTOFF 2
132 #define USER_RELOC_P(R) ((R) >= O_literal && (R) <= O_samegp)
134 /* Macros for extracting the type and number of encoded register tokens */
136 #define is_ir_num(x) (((x) & 32) == 0)
137 #define is_fpr_num(x) (((x) & 32) != 0)
138 #define regno(x) ((x) & 31)
140 /* Something odd inherited from the old assembler */
142 #define note_gpreg(R) (alpha_gprmask |= (1 << (R)))
143 #define note_fpreg(R) (alpha_fprmask |= (1 << (R)))
145 /* Predicates for 16- and 32-bit ranges */
146 /* XXX: The non-shift version appears to trigger a compiler bug when
147 cross-assembling from x86 w/ gcc 2.7.2. */
150 #define range_signed_16(x) \
151 (((offsetT) (x) >> 15) == 0 || ((offsetT) (x) >> 15) == -1)
152 #define range_signed_32(x) \
153 (((offsetT) (x) >> 31) == 0 || ((offsetT) (x) >> 31) == -1)
155 #define range_signed_16(x) ((offsetT) (x) >= -(offsetT) 0x8000 && \
156 (offsetT) (x) <= (offsetT) 0x7FFF)
157 #define range_signed_32(x) ((offsetT) (x) >= -(offsetT) 0x80000000 && \
158 (offsetT) (x) <= (offsetT) 0x7FFFFFFF)
161 /* Macros for sign extending from 16- and 32-bits. */
162 /* XXX: The cast macros will work on all the systems that I care about,
163 but really a predicate should be found to use the non-cast forms. */
166 #define sign_extend_16(x) ((short) (x))
167 #define sign_extend_32(x) ((int) (x))
169 #define sign_extend_16(x) ((offsetT) (((x) & 0xFFFF) ^ 0x8000) - 0x8000)
170 #define sign_extend_32(x) ((offsetT) (((x) & 0xFFFFFFFF) \
171 ^ 0x80000000) - 0x80000000)
174 /* Macros to build tokens */
176 #define set_tok_reg(t, r) (memset (&(t), 0, sizeof (t)), \
177 (t).X_op = O_register, \
178 (t).X_add_number = (r))
179 #define set_tok_preg(t, r) (memset (&(t), 0, sizeof (t)), \
180 (t).X_op = O_pregister, \
181 (t).X_add_number = (r))
182 #define set_tok_cpreg(t, r) (memset (&(t), 0, sizeof (t)), \
183 (t).X_op = O_cpregister, \
184 (t).X_add_number = (r))
185 #define set_tok_freg(t, r) (memset (&(t), 0, sizeof (t)), \
186 (t).X_op = O_register, \
187 (t).X_add_number = (r) + 32)
188 #define set_tok_sym(t, s, a) (memset (&(t), 0, sizeof (t)), \
189 (t).X_op = O_symbol, \
190 (t).X_add_symbol = (s), \
191 (t).X_add_number = (a))
192 #define set_tok_const(t, n) (memset (&(t), 0, sizeof (t)), \
193 (t).X_op = O_constant, \
194 (t).X_add_number = (n))
196 /* Prototypes for all local functions */
198 static struct alpha_reloc_tag
*get_alpha_reloc_tag
PARAMS ((long));
199 static void alpha_adjust_symtab_relocs
PARAMS ((bfd
*, asection
*, PTR
));
201 static int tokenize_arguments
PARAMS ((char *, expressionS
*, int));
202 static const struct alpha_opcode
*find_opcode_match
203 PARAMS ((const struct alpha_opcode
*, const expressionS
*, int *, int *));
204 static const struct alpha_macro
*find_macro_match
205 PARAMS ((const struct alpha_macro
*, const expressionS
*, int *));
206 static unsigned insert_operand
207 PARAMS ((unsigned, const struct alpha_operand
*, offsetT
, char *, unsigned));
208 static void assemble_insn
209 PARAMS ((const struct alpha_opcode
*, const expressionS
*, int,
210 struct alpha_insn
*, bfd_reloc_code_real_type
));
211 static void emit_insn
PARAMS ((struct alpha_insn
*));
212 static void assemble_tokens_to_insn
213 PARAMS ((const char *, const expressionS
*, int, struct alpha_insn
*));
214 static void assemble_tokens
215 PARAMS ((const char *, const expressionS
*, int, int));
217 static long load_expression
218 PARAMS ((int, const expressionS
*, int *, expressionS
*));
220 static void emit_ldgp
PARAMS ((const expressionS
*, int, const PTR
));
221 static void emit_division
PARAMS ((const expressionS
*, int, const PTR
));
222 static void emit_lda
PARAMS ((const expressionS
*, int, const PTR
));
223 static void emit_ldah
PARAMS ((const expressionS
*, int, const PTR
));
224 static void emit_ir_load
PARAMS ((const expressionS
*, int, const PTR
));
225 static void emit_loadstore
PARAMS ((const expressionS
*, int, const PTR
));
226 static void emit_jsrjmp
PARAMS ((const expressionS
*, int, const PTR
));
227 static void emit_ldX
PARAMS ((const expressionS
*, int, const PTR
));
228 static void emit_ldXu
PARAMS ((const expressionS
*, int, const PTR
));
229 static void emit_uldX
PARAMS ((const expressionS
*, int, const PTR
));
230 static void emit_uldXu
PARAMS ((const expressionS
*, int, const PTR
));
231 static void emit_ldil
PARAMS ((const expressionS
*, int, const PTR
));
232 static void emit_stX
PARAMS ((const expressionS
*, int, const PTR
));
233 static void emit_ustX
PARAMS ((const expressionS
*, int, const PTR
));
234 static void emit_sextX
PARAMS ((const expressionS
*, int, const PTR
));
235 static void emit_retjcr
PARAMS ((const expressionS
*, int, const PTR
));
237 static void s_alpha_text
PARAMS ((int));
238 static void s_alpha_data
PARAMS ((int));
240 static void s_alpha_comm
PARAMS ((int));
241 static void s_alpha_rdata
PARAMS ((int));
244 static void s_alpha_sdata
PARAMS ((int));
247 static void s_alpha_section
PARAMS ((int));
248 static void s_alpha_ent
PARAMS ((int));
249 static void s_alpha_end
PARAMS ((int));
250 static void s_alpha_mask
PARAMS ((int));
251 static void s_alpha_frame
PARAMS ((int));
252 static void s_alpha_prologue
PARAMS ((int));
253 static void s_alpha_file
PARAMS ((int));
254 static void s_alpha_loc
PARAMS ((int));
255 static void s_alpha_stab
PARAMS ((int));
256 static void s_alpha_coff_wrapper
PARAMS ((int));
259 static void s_alpha_section
PARAMS ((int));
261 static void s_alpha_gprel32
PARAMS ((int));
262 static void s_alpha_float_cons
PARAMS ((int));
263 static void s_alpha_proc
PARAMS ((int));
264 static void s_alpha_set
PARAMS ((int));
265 static void s_alpha_base
PARAMS ((int));
266 static void s_alpha_align
PARAMS ((int));
267 static void s_alpha_stringer
PARAMS ((int));
268 static void s_alpha_space
PARAMS ((int));
269 static void s_alpha_ucons
PARAMS ((int));
270 static void s_alpha_arch
PARAMS ((int));
272 static void create_literal_section
PARAMS ((const char *, segT
*, symbolS
**));
274 static void select_gp_value
PARAMS ((void));
276 static void alpha_align
PARAMS ((int, char *, symbolS
*, int));
278 /* Generic assembler global variables which must be defined by all
281 /* Characters which always start a comment. */
282 const char comment_chars
[] = "#";
284 /* Characters which start a comment at the beginning of a line. */
285 const char line_comment_chars
[] = "#";
287 /* Characters which may be used to separate multiple commands on a
289 const char line_separator_chars
[] = ";";
291 /* Characters which are used to indicate an exponent in a floating
293 const char EXP_CHARS
[] = "eE";
295 /* Characters which mean that a number is a floating point constant,
298 const char FLT_CHARS
[] = "dD";
300 /* XXX: Do all of these really get used on the alpha?? */
301 char FLT_CHARS
[] = "rRsSfFdDxXpP";
305 const char *md_shortopts
= "Fm:g+1h:HG:";
307 const char *md_shortopts
= "Fm:gG:";
310 struct option md_longopts
[] = {
311 #define OPTION_32ADDR (OPTION_MD_BASE)
312 { "32addr", no_argument
, NULL
, OPTION_32ADDR
},
313 #define OPTION_RELAX (OPTION_32ADDR + 1)
314 { "relax", no_argument
, NULL
, OPTION_RELAX
},
316 #define OPTION_MDEBUG (OPTION_RELAX + 1)
317 #define OPTION_NO_MDEBUG (OPTION_MDEBUG + 1)
318 { "mdebug", no_argument
, NULL
, OPTION_MDEBUG
},
319 { "no-mdebug", no_argument
, NULL
, OPTION_NO_MDEBUG
},
321 { NULL
, no_argument
, NULL
, 0 }
324 size_t md_longopts_size
= sizeof (md_longopts
);
328 #define AXP_REG_R16 16
329 #define AXP_REG_R17 17
331 #define AXP_REG_T9 22
333 #define AXP_REG_T10 23
335 #define AXP_REG_T11 24
337 #define AXP_REG_T12 25
338 #define AXP_REG_AI 25
340 #define AXP_REG_FP 29
343 #define AXP_REG_GP AXP_REG_PV
344 #endif /* OBJ_EVAX */
346 /* The cpu for which we are generating code */
347 static unsigned alpha_target
= AXP_OPCODE_BASE
;
348 static const char *alpha_target_name
= "<all>";
350 /* The hash table of instruction opcodes */
351 static struct hash_control
*alpha_opcode_hash
;
353 /* The hash table of macro opcodes */
354 static struct hash_control
*alpha_macro_hash
;
357 /* The $gp relocation symbol */
358 static symbolS
*alpha_gp_symbol
;
360 /* XXX: what is this, and why is it exported? */
361 valueT alpha_gp_value
;
364 /* The current $gp register */
365 static int alpha_gp_register
= AXP_REG_GP
;
367 /* A table of the register symbols */
368 static symbolS
*alpha_register_table
[64];
370 /* Constant sections, or sections of constants */
372 static segT alpha_lita_section
;
373 static segT alpha_lit4_section
;
376 static segT alpha_link_section
;
377 static segT alpha_ctors_section
;
378 static segT alpha_dtors_section
;
380 static segT alpha_lit8_section
;
382 /* Symbols referring to said sections. */
384 static symbolS
*alpha_lita_symbol
;
385 static symbolS
*alpha_lit4_symbol
;
388 static symbolS
*alpha_link_symbol
;
389 static symbolS
*alpha_ctors_symbol
;
390 static symbolS
*alpha_dtors_symbol
;
392 static symbolS
*alpha_lit8_symbol
;
394 /* Literal for .litX+0x8000 within .lita */
396 static offsetT alpha_lit4_literal
;
397 static offsetT alpha_lit8_literal
;
401 /* The active .ent symbol. */
402 static symbolS
*alpha_cur_ent_sym
;
405 /* Is the assembler not allowed to use $at? */
406 static int alpha_noat_on
= 0;
408 /* Are macros enabled? */
409 static int alpha_macros_on
= 1;
411 /* Are floats disabled? */
412 static int alpha_nofloats_on
= 0;
414 /* Are addresses 32 bit? */
415 static int alpha_addr32_on
= 0;
417 /* Symbol labelling the current insn. When the Alpha gas sees
420 and the section happens to not be on an eight byte boundary, it
421 will align both the symbol and the .quad to an eight byte boundary. */
422 static symbolS
*alpha_insn_label
;
424 /* Whether we should automatically align data generation pseudo-ops.
425 .align 0 will turn this off. */
426 static int alpha_auto_align_on
= 1;
428 /* The known current alignment of the current section. */
429 static int alpha_current_align
;
431 /* These are exported to ECOFF code. */
432 unsigned long alpha_gprmask
, alpha_fprmask
;
434 /* Whether the debugging option was seen. */
435 static int alpha_debug
;
438 /* Whether we are emitting an mdebug section. */
439 int alpha_flag_mdebug
= -1;
442 /* Don't fully resolve relocations, allowing code movement in the linker. */
443 static int alpha_flag_relax
;
445 /* What value to give to bfd_set_gp_size. */
446 static int g_switch_value
= 8;
449 /* Collect information about current procedure here. */
451 symbolS
*symbol
; /* proc pdesc symbol */
453 int framereg
; /* register for frame pointer */
454 int framesize
; /* size of frame */
464 static int alpha_flag_hash_long_names
= 0; /* -+ */
465 static int alpha_flag_show_after_trunc
= 0; /* -H */
467 /* If the -+ switch is given, then a hash is appended to any name that is
468 * longer than 64 characters, else longer symbol names are truncated.
474 /* A table to map the spelling of a relocation operand into an appropriate
475 bfd_reloc_code_real_type type. The table is assumed to be ordered such
476 that op-O_literal indexes into it. */
478 #define ALPHA_RELOC_TABLE(op) \
479 (&alpha_reloc_op[ ((!USER_RELOC_P (op)) \
481 : (int) (op) - (int) O_literal) ])
483 #define DEF(NAME, RELOC, REQ, ALLOW) \
484 { #NAME, sizeof(#NAME)-1, O_##NAME, RELOC, REQ, ALLOW}
486 static const struct alpha_reloc_op_tag
{
487 const char *name
; /* string to lookup */
488 size_t length
; /* size of the string */
489 operatorT op
; /* which operator to use */
490 bfd_reloc_code_real_type reloc
; /* relocation before frob */
491 unsigned int require_seq
: 1; /* require a sequence number */
492 unsigned int allow_seq
: 1; /* allow a sequence number */
493 } alpha_reloc_op
[] = {
494 DEF(literal
, BFD_RELOC_ALPHA_ELF_LITERAL
, 0, 1),
495 DEF(lituse_addr
, DUMMY_RELOC_LITUSE_ADDR
, 1, 1),
496 DEF(lituse_base
, DUMMY_RELOC_LITUSE_BASE
, 1, 1),
497 DEF(lituse_bytoff
, DUMMY_RELOC_LITUSE_BYTOFF
, 1, 1),
498 DEF(lituse_jsr
, DUMMY_RELOC_LITUSE_JSR
, 1, 1),
499 DEF(gpdisp
, BFD_RELOC_ALPHA_GPDISP
, 1, 1),
500 DEF(gprelhigh
, BFD_RELOC_ALPHA_GPREL_HI16
, 0, 0),
501 DEF(gprellow
, BFD_RELOC_ALPHA_GPREL_LO16
, 0, 0),
502 DEF(gprel
, BFD_RELOC_GPREL16
, 0, 0),
503 DEF(samegp
, BFD_RELOC_ALPHA_BRSGP
, 0, 0)
508 static const int alpha_num_reloc_op
509 = sizeof (alpha_reloc_op
) / sizeof (*alpha_reloc_op
);
510 #endif /* RELOC_OP_P */
512 /* Maximum # digits needed to hold the largest sequence # */
513 #define ALPHA_RELOC_DIGITS 25
515 /* Structure to hold explict sequence information. */
516 struct alpha_reloc_tag
518 fixS
*slaves
; /* head of linked list of !literals */
519 segT segment
; /* segment relocs are in or undefined_section*/
520 long sequence
; /* sequence # */
521 unsigned n_master
; /* # of literals */
522 unsigned n_slaves
; /* # of lituses */
523 char multi_section_p
; /* True if more than one section was used */
524 char string
[1]; /* printable form of sequence to hash with */
527 /* Hash table to link up literals with the appropriate lituse */
528 static struct hash_control
*alpha_literal_hash
;
530 /* Sequence numbers for internal use by macros. */
531 static long next_sequence_num
= -1;
533 /* A table of CPU names and opcode sets. */
535 static const struct cpu_type
{
539 /* Ad hoc convention: cpu number gets palcode, process code doesn't.
540 This supports usage under DU 4.0b that does ".arch ev4", and
541 usage in MILO that does -m21064. Probably something more
542 specific like -m21064-pal should be used, but oh well. */
544 { "21064", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
545 { "21064a", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
546 { "21066", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
547 { "21068", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
548 { "21164", AXP_OPCODE_BASE
|AXP_OPCODE_EV5
},
549 { "21164a", AXP_OPCODE_BASE
|AXP_OPCODE_EV5
|AXP_OPCODE_BWX
},
550 { "21164pc", (AXP_OPCODE_BASE
|AXP_OPCODE_EV5
|AXP_OPCODE_BWX
552 { "21264", (AXP_OPCODE_BASE
|AXP_OPCODE_EV6
|AXP_OPCODE_BWX
553 |AXP_OPCODE_MAX
|AXP_OPCODE_CIX
) },
555 { "ev4", AXP_OPCODE_BASE
},
556 { "ev45", AXP_OPCODE_BASE
},
557 { "lca45", AXP_OPCODE_BASE
},
558 { "ev5", AXP_OPCODE_BASE
},
559 { "ev56", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
},
560 { "pca56", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
|AXP_OPCODE_MAX
},
561 { "ev6", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
|AXP_OPCODE_MAX
|AXP_OPCODE_CIX
},
563 { "all", AXP_OPCODE_BASE
},
567 /* The macro table */
569 static const struct alpha_macro alpha_macros
[] = {
570 /* Load/Store macros */
571 { "lda", emit_lda
, NULL
,
572 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
573 { "ldah", emit_ldah
, NULL
,
574 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
576 { "ldl", emit_ir_load
, "ldl",
577 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
578 { "ldl_l", emit_ir_load
, "ldl_l",
579 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
580 { "ldq", emit_ir_load
, "ldq",
581 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
582 { "ldq_l", emit_ir_load
, "ldq_l",
583 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
584 { "ldq_u", emit_ir_load
, "ldq_u",
585 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
586 { "ldf", emit_loadstore
, "ldf",
587 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
588 { "ldg", emit_loadstore
, "ldg",
589 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
590 { "lds", emit_loadstore
, "lds",
591 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
592 { "ldt", emit_loadstore
, "ldt",
593 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
595 { "ldb", emit_ldX
, (PTR
) 0,
596 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
597 { "ldbu", emit_ldXu
, (PTR
) 0,
598 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
599 { "ldw", emit_ldX
, (PTR
) 1,
600 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
601 { "ldwu", emit_ldXu
, (PTR
) 1,
602 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
604 { "uldw", emit_uldX
, (PTR
) 1,
605 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
606 { "uldwu", emit_uldXu
, (PTR
) 1,
607 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
608 { "uldl", emit_uldX
, (PTR
) 2,
609 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
610 { "uldlu", emit_uldXu
, (PTR
) 2,
611 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
612 { "uldq", emit_uldXu
, (PTR
) 3,
613 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
615 { "ldgp", emit_ldgp
, NULL
,
616 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
} },
618 { "ldi", emit_lda
, NULL
,
619 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
620 { "ldil", emit_ldil
, NULL
,
621 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
622 { "ldiq", emit_lda
, NULL
,
623 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
625 { "ldif" emit_ldiq
, NULL
,
626 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
627 { "ldid" emit_ldiq
, NULL
,
628 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
629 { "ldig" emit_ldiq
, NULL
,
630 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
631 { "ldis" emit_ldiq
, NULL
,
632 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
633 { "ldit" emit_ldiq
, NULL
,
634 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
637 { "stl", emit_loadstore
, "stl",
638 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
639 { "stl_c", emit_loadstore
, "stl_c",
640 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
641 { "stq", emit_loadstore
, "stq",
642 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
643 { "stq_c", emit_loadstore
, "stq_c",
644 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
645 { "stq_u", emit_loadstore
, "stq_u",
646 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
647 { "stf", emit_loadstore
, "stf",
648 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
649 { "stg", emit_loadstore
, "stg",
650 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
651 { "sts", emit_loadstore
, "sts",
652 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
653 { "stt", emit_loadstore
, "stt",
654 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
656 { "stb", emit_stX
, (PTR
) 0,
657 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
658 { "stw", emit_stX
, (PTR
) 1,
659 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
660 { "ustw", emit_ustX
, (PTR
) 1,
661 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
662 { "ustl", emit_ustX
, (PTR
) 2,
663 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
664 { "ustq", emit_ustX
, (PTR
) 3,
665 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
667 /* Arithmetic macros */
669 { "absl" emit_absl
, 1, { IR
} },
670 { "absl" emit_absl
, 2, { IR
, IR
} },
671 { "absl" emit_absl
, 2, { EXP
, IR
} },
672 { "absq" emit_absq
, 1, { IR
} },
673 { "absq" emit_absq
, 2, { IR
, IR
} },
674 { "absq" emit_absq
, 2, { EXP
, IR
} },
677 { "sextb", emit_sextX
, (PTR
) 0,
678 { MACRO_IR
, MACRO_IR
, MACRO_EOA
,
680 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
681 { "sextw", emit_sextX
, (PTR
) 1,
682 { MACRO_IR
, MACRO_IR
, MACRO_EOA
,
684 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
686 { "divl", emit_division
, "__divl",
687 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
688 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
689 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
690 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
691 { "divlu", emit_division
, "__divlu",
692 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
693 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
694 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
695 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
696 { "divq", emit_division
, "__divq",
697 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
698 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
699 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
700 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
701 { "divqu", emit_division
, "__divqu",
702 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
703 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
704 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
705 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
706 { "reml", emit_division
, "__reml",
707 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
708 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
709 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
710 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
711 { "remlu", emit_division
, "__remlu",
712 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
713 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
714 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
715 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
716 { "remq", emit_division
, "__remq",
717 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
718 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
719 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
720 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
721 { "remqu", emit_division
, "__remqu",
722 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
723 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
724 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
725 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
727 { "jsr", emit_jsrjmp
, "jsr",
728 { MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
729 MACRO_PIR
, MACRO_EOA
,
730 MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
731 MACRO_EXP
, MACRO_EOA
} },
732 { "jmp", emit_jsrjmp
, "jmp",
733 { MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
734 MACRO_PIR
, MACRO_EOA
,
735 MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
736 MACRO_EXP
, MACRO_EOA
} },
737 { "ret", emit_retjcr
, "ret",
738 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
740 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
741 MACRO_PIR
, MACRO_EOA
,
742 MACRO_EXP
, MACRO_EOA
,
744 { "jcr", emit_retjcr
, "jcr",
745 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
747 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
748 MACRO_PIR
, MACRO_EOA
,
749 MACRO_EXP
, MACRO_EOA
,
751 { "jsr_coroutine", emit_retjcr
, "jcr",
752 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
754 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
755 MACRO_PIR
, MACRO_EOA
,
756 MACRO_EXP
, MACRO_EOA
,
760 static const unsigned int alpha_num_macros
761 = sizeof (alpha_macros
) / sizeof (*alpha_macros
);
763 /* Public interface functions */
765 /* This function is called once, at assembler startup time. It sets
766 up all the tables, etc. that the MD part of the assembler will
767 need, that can be determined before arguments are parsed. */
774 /* Verify that X_op field is wide enough. */
778 assert (e
.X_op
== O_max
);
781 /* Create the opcode hash table */
783 alpha_opcode_hash
= hash_new ();
784 for (i
= 0; i
< alpha_num_opcodes
;)
786 const char *name
, *retval
, *slash
;
788 name
= alpha_opcodes
[i
].name
;
789 retval
= hash_insert (alpha_opcode_hash
, name
, (PTR
) &alpha_opcodes
[i
]);
791 as_fatal (_("internal error: can't hash opcode `%s': %s"),
794 /* Some opcodes include modifiers of various sorts with a "/mod"
795 syntax, like the architecture manual suggests. However, for
796 use with gcc at least, we also need access to those same opcodes
799 if ((slash
= strchr (name
, '/')) != NULL
)
801 char *p
= xmalloc (strlen (name
));
802 memcpy (p
, name
, slash
- name
);
803 strcpy (p
+ (slash
- name
), slash
+ 1);
805 (void) hash_insert (alpha_opcode_hash
, p
, (PTR
) &alpha_opcodes
[i
]);
806 /* Ignore failures -- the opcode table does duplicate some
807 variants in different forms, like "hw_stq" and "hw_st/q". */
810 while (++i
< alpha_num_opcodes
811 && (alpha_opcodes
[i
].name
== name
812 || !strcmp (alpha_opcodes
[i
].name
, name
)))
816 /* Create the macro hash table */
818 alpha_macro_hash
= hash_new ();
819 for (i
= 0; i
< alpha_num_macros
;)
821 const char *name
, *retval
;
823 name
= alpha_macros
[i
].name
;
824 retval
= hash_insert (alpha_macro_hash
, name
, (PTR
) &alpha_macros
[i
]);
826 as_fatal (_("internal error: can't hash macro `%s': %s"),
829 while (++i
< alpha_num_macros
830 && (alpha_macros
[i
].name
== name
831 || !strcmp (alpha_macros
[i
].name
, name
)))
835 /* Construct symbols for each of the registers */
837 for (i
= 0; i
< 32; ++i
)
840 sprintf (name
, "$%d", i
);
841 alpha_register_table
[i
] = symbol_create (name
, reg_section
, i
,
847 sprintf (name
, "$f%d", i
- 32);
848 alpha_register_table
[i
] = symbol_create (name
, reg_section
, i
,
852 /* Create the special symbols and sections we'll be using */
854 /* So .sbss will get used for tiny objects. */
855 bfd_set_gp_size (stdoutput
, g_switch_value
);
858 create_literal_section (".lita", &alpha_lita_section
, &alpha_lita_symbol
);
860 /* For handling the GP, create a symbol that won't be output in the
861 symbol table. We'll edit it out of relocs later. */
862 alpha_gp_symbol
= symbol_create ("<GP value>", alpha_lita_section
, 0x8000,
867 create_literal_section (".link", &alpha_link_section
, &alpha_link_symbol
);
873 segT sec
= subseg_new (".mdebug", (subsegT
) 0);
874 bfd_set_section_flags (stdoutput
, sec
, SEC_HAS_CONTENTS
| SEC_READONLY
);
875 bfd_set_section_alignment (stdoutput
, sec
, 3);
879 /* Create literal lookup hash table. */
880 alpha_literal_hash
= hash_new ();
882 subseg_set (text_section
, 0);
885 /* The public interface to the instruction assembler. */
891 char opname
[32]; /* current maximum is 13 */
892 expressionS tok
[MAX_INSN_ARGS
];
896 /* split off the opcode */
897 opnamelen
= strspn (str
, "abcdefghijklmnopqrstuvwxyz_/46819");
898 trunclen
= (opnamelen
< sizeof (opname
) - 1
900 : sizeof (opname
) - 1);
901 memcpy (opname
, str
, trunclen
);
902 opname
[trunclen
] = '\0';
904 /* tokenize the rest of the line */
905 if ((ntok
= tokenize_arguments (str
+ opnamelen
, tok
, MAX_INSN_ARGS
)) < 0)
907 if (ntok
!= TOKENIZE_ERROR_REPORT
)
908 as_bad (_("syntax error"));
914 assemble_tokens (opname
, tok
, ntok
, alpha_macros_on
);
917 /* Round up a section's size to the appropriate boundary. */
920 md_section_align (seg
, size
)
924 int align
= bfd_get_section_alignment (stdoutput
, seg
);
925 valueT mask
= ((valueT
) 1 << align
) - 1;
927 return (size
+ mask
) & ~mask
;
930 /* Turn a string in input_line_pointer into a floating point constant
931 of type TYPE, and store the appropriate bytes in *LITP. The number
932 of LITTLENUMS emitted is stored in *SIZEP. An error message is
933 returned, or NULL on OK. */
935 /* Equal to MAX_PRECISION in atof-ieee.c */
936 #define MAX_LITTLENUMS 6
938 extern char *vax_md_atof
PARAMS ((int, char *, int *));
941 md_atof (type
, litP
, sizeP
)
947 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
948 LITTLENUM_TYPE
*wordP
;
955 /* VAX md_atof doesn't like "G" for some reason. */
959 return vax_md_atof (type
, litP
, sizeP
);
982 return _("Bad call to MD_ATOF()");
984 t
= atof_ieee (input_line_pointer
, type
, words
);
986 input_line_pointer
= t
;
987 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
989 for (wordP
= words
+ prec
- 1; prec
--;)
991 md_number_to_chars (litP
, (long) (*wordP
--), sizeof (LITTLENUM_TYPE
));
992 litP
+= sizeof (LITTLENUM_TYPE
);
998 /* Take care of the target-specific command-line options. */
1001 md_parse_option (c
, arg
)
1008 alpha_nofloats_on
= 1;
1012 alpha_addr32_on
= 1;
1020 g_switch_value
= atoi (arg
);
1025 const struct cpu_type
*p
;
1026 for (p
= cpu_types
; p
->name
; ++p
)
1027 if (strcmp (arg
, p
->name
) == 0)
1029 alpha_target_name
= p
->name
, alpha_target
= p
->flags
;
1032 as_warn (_("Unknown CPU identifier `%s'"), arg
);
1038 case '+': /* For g++. Hash any name > 63 chars long. */
1039 alpha_flag_hash_long_names
= 1;
1042 case 'H': /* Show new symbol after hash truncation */
1043 alpha_flag_show_after_trunc
= 1;
1046 case 'h': /* for gnu-c/vax compatibility. */
1051 alpha_flag_relax
= 1;
1056 alpha_flag_mdebug
= 1;
1058 case OPTION_NO_MDEBUG
:
1059 alpha_flag_mdebug
= 0;
1070 /* Print a description of the command-line options that we accept. */
1073 md_show_usage (stream
)
1078 -32addr treat addresses as 32-bit values\n\
1079 -F lack floating point instructions support\n\
1080 -mev4 | -mev45 | -mev5 | -mev56 | -mpca56 | -mev6 | -mall\n\
1081 specify variant of Alpha architecture\n\
1082 -m21064 | -m21066 | -m21164 | -m21164a | -m21164pc | -m21264\n\
1083 these variants include PALcode opcodes\n"),
1088 -+ hash encode (don't truncate) names longer than 64 characters\n\
1089 -H show new symbol after hash truncation\n"),
1094 /* Decide from what point a pc-relative relocation is relative to,
1095 relative to the pc-relative fixup. Er, relatively speaking. */
1098 md_pcrel_from (fixP
)
1101 valueT addr
= fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
1102 switch (fixP
->fx_r_type
)
1104 case BFD_RELOC_ALPHA_GPDISP
:
1105 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1106 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1109 return fixP
->fx_size
+ addr
;
1113 /* Attempt to simplify or even eliminate a fixup. The return value is
1114 ignored; perhaps it was once meaningful, but now it is historical.
1115 To indicate that a fixup has been eliminated, set fixP->fx_done.
1117 For ELF, here it is that we transform the GPDISP_HI16 reloc we used
1118 internally into the GPDISP reloc used externally. We had to do
1119 this so that we'd have the GPDISP_LO16 reloc as a tag to compute
1120 the distance to the "lda" instruction for setting the addend to
1124 md_apply_fix3 (fixP
, valP
, seg
)
1129 char * const fixpos
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
1130 valueT value
= * valP
;
1131 unsigned image
, size
;
1133 switch (fixP
->fx_r_type
)
1135 /* The GPDISP relocations are processed internally with a symbol
1136 referring to the current function; we need to drop in a value
1137 which, when added to the address of the start of the function,
1138 gives the desired GP. */
1139 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1141 fixS
*next
= fixP
->fx_next
;
1143 /* With user-specified !gpdisp relocations, we can be missing
1144 the matching LO16 reloc. We will have already issued an
1147 fixP
->fx_offset
= (next
->fx_frag
->fr_address
+ next
->fx_where
1148 - fixP
->fx_frag
->fr_address
- fixP
->fx_where
);
1150 value
= (value
- sign_extend_16 (value
)) >> 16;
1153 fixP
->fx_r_type
= BFD_RELOC_ALPHA_GPDISP
;
1157 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1158 value
= sign_extend_16 (value
);
1159 fixP
->fx_offset
= 0;
1165 fixP
->fx_addsy
= section_symbol (seg
);
1166 md_number_to_chars (fixpos
, value
, 2);
1171 fixP
->fx_r_type
= BFD_RELOC_16_PCREL
;
1176 fixP
->fx_r_type
= BFD_RELOC_32_PCREL
;
1181 fixP
->fx_r_type
= BFD_RELOC_64_PCREL
;
1184 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
1186 md_number_to_chars (fixpos
, value
, size
);
1192 case BFD_RELOC_GPREL32
:
1193 assert (fixP
->fx_subsy
== alpha_gp_symbol
);
1195 /* FIXME: inherited this obliviousness of `value' -- why? */
1196 md_number_to_chars (fixpos
, -alpha_gp_value
, 4);
1199 case BFD_RELOC_GPREL32
:
1201 case BFD_RELOC_GPREL16
:
1202 case BFD_RELOC_ALPHA_GPREL_HI16
:
1203 case BFD_RELOC_ALPHA_GPREL_LO16
:
1206 case BFD_RELOC_23_PCREL_S2
:
1207 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
1209 image
= bfd_getl32 (fixpos
);
1210 image
= (image
& ~0x1FFFFF) | ((value
>> 2) & 0x1FFFFF);
1215 case BFD_RELOC_ALPHA_HINT
:
1216 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
1218 image
= bfd_getl32 (fixpos
);
1219 image
= (image
& ~0x3FFF) | ((value
>> 2) & 0x3FFF);
1225 case BFD_RELOC_ALPHA_BRSGP
:
1230 case BFD_RELOC_ALPHA_LITERAL
:
1231 md_number_to_chars (fixpos
, value
, 2);
1234 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1235 case BFD_RELOC_ALPHA_LITUSE
:
1236 case BFD_RELOC_ALPHA_LINKAGE
:
1237 case BFD_RELOC_ALPHA_CODEADDR
:
1240 case BFD_RELOC_VTABLE_INHERIT
:
1241 case BFD_RELOC_VTABLE_ENTRY
:
1246 const struct alpha_operand
*operand
;
1248 if ((int) fixP
->fx_r_type
>= 0)
1249 as_fatal (_("unhandled relocation type %s"),
1250 bfd_get_reloc_code_name (fixP
->fx_r_type
));
1252 assert (-(int) fixP
->fx_r_type
< (int) alpha_num_operands
);
1253 operand
= &alpha_operands
[-(int) fixP
->fx_r_type
];
1255 /* The rest of these fixups only exist internally during symbol
1256 resolution and have no representation in the object file.
1257 Therefore they must be completely resolved as constants. */
1259 if (fixP
->fx_addsy
!= 0
1260 && S_GET_SEGMENT (fixP
->fx_addsy
) != absolute_section
)
1261 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
1262 _("non-absolute expression in constant field"));
1264 image
= bfd_getl32 (fixpos
);
1265 image
= insert_operand (image
, operand
, (offsetT
) value
,
1266 fixP
->fx_file
, fixP
->fx_line
);
1271 if (fixP
->fx_addsy
!= 0 || fixP
->fx_pcrel
!= 0)
1275 as_warn_where (fixP
->fx_file
, fixP
->fx_line
,
1276 _("type %d reloc done?\n"), (int) fixP
->fx_r_type
);
1281 md_number_to_chars (fixpos
, image
, 4);
1287 /* Look for a register name in the given symbol. */
1290 md_undefined_symbol (name
)
1295 int is_float
= 0, num
;
1300 if (name
[1] == 'p' && name
[2] == '\0')
1301 return alpha_register_table
[AXP_REG_FP
];
1306 if (!ISDIGIT (*++name
))
1310 case '0': case '1': case '2': case '3': case '4':
1311 case '5': case '6': case '7': case '8': case '9':
1312 if (name
[1] == '\0')
1313 num
= name
[0] - '0';
1314 else if (name
[0] != '0' && ISDIGIT (name
[1]) && name
[2] == '\0')
1316 num
= (name
[0] - '0') * 10 + name
[1] - '0';
1323 if (!alpha_noat_on
&& (num
+ is_float
) == AXP_REG_AT
)
1324 as_warn (_("Used $at without \".set noat\""));
1325 return alpha_register_table
[num
+ is_float
];
1328 if (name
[1] == 't' && name
[2] == '\0')
1331 as_warn (_("Used $at without \".set noat\""));
1332 return alpha_register_table
[AXP_REG_AT
];
1337 if (name
[1] == 'p' && name
[2] == '\0')
1338 return alpha_register_table
[alpha_gp_register
];
1342 if (name
[1] == 'p' && name
[2] == '\0')
1343 return alpha_register_table
[AXP_REG_SP
];
1351 /* @@@ Magic ECOFF bits. */
1354 alpha_frob_ecoff_data ()
1357 /* $zero and $f31 are read-only */
1358 alpha_gprmask
&= ~1;
1359 alpha_fprmask
&= ~1;
1363 /* Hook to remember a recently defined label so that the auto-align
1364 code can adjust the symbol after we know what alignment will be
1368 alpha_define_label (sym
)
1371 alpha_insn_label
= sym
;
1374 /* If we have a BRSGP reloc to a local symbol, adjust it to BRADDR and
1375 let it get resolved at assembly time. */
1378 alpha_validate_fix (f
)
1385 if (f
->fx_r_type
!= BFD_RELOC_ALPHA_BRSGP
)
1388 if (! S_IS_DEFINED (f
->fx_addsy
))
1391 switch (S_GET_OTHER (f
->fx_addsy
) & STO_ALPHA_STD_GPLOAD
)
1393 case STO_ALPHA_NOPV
:
1395 case STO_ALPHA_STD_GPLOAD
:
1399 if (S_IS_LOCAL (f
->fx_addsy
))
1402 name
= S_GET_NAME (f
->fx_addsy
);
1403 as_bad_where (f
->fx_file
, f
->fx_line
,
1404 _("!samegp reloc against symbol without .prologue: %s"),
1409 if (! (S_IS_EXTERN (f
->fx_addsy
) || S_IS_WEAK (f
->fx_addsy
)))
1411 f
->fx_r_type
= BFD_RELOC_23_PCREL_S2
;
1412 f
->fx_offset
+= offset
;
1417 /* Return true if we must always emit a reloc for a type and false if
1418 there is some hope of resolving it at assembly time. */
1421 alpha_force_relocation (f
)
1424 if (alpha_flag_relax
)
1427 switch (f
->fx_r_type
)
1429 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1430 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1431 case BFD_RELOC_ALPHA_GPDISP
:
1432 case BFD_RELOC_ALPHA_LITERAL
:
1433 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1434 case BFD_RELOC_ALPHA_LITUSE
:
1435 case BFD_RELOC_GPREL16
:
1436 case BFD_RELOC_GPREL32
:
1437 case BFD_RELOC_ALPHA_GPREL_HI16
:
1438 case BFD_RELOC_ALPHA_GPREL_LO16
:
1439 case BFD_RELOC_ALPHA_LINKAGE
:
1440 case BFD_RELOC_ALPHA_CODEADDR
:
1441 case BFD_RELOC_ALPHA_BRSGP
:
1442 case BFD_RELOC_VTABLE_INHERIT
:
1443 case BFD_RELOC_VTABLE_ENTRY
:
1446 case BFD_RELOC_23_PCREL_S2
:
1449 case BFD_RELOC_ALPHA_HINT
:
1457 /* Return true if we can partially resolve a relocation now. */
1460 alpha_fix_adjustable (f
)
1464 /* Prevent all adjustments to global symbols */
1465 if (S_IS_EXTERN (f
->fx_addsy
) || S_IS_WEAK (f
->fx_addsy
))
1469 /* Are there any relocation types for which we must generate a reloc
1470 but we can adjust the values contained within it? */
1471 switch (f
->fx_r_type
)
1473 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1474 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1475 case BFD_RELOC_ALPHA_GPDISP
:
1476 case BFD_RELOC_ALPHA_BRSGP
:
1479 case BFD_RELOC_ALPHA_LITERAL
:
1480 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1481 case BFD_RELOC_ALPHA_LITUSE
:
1482 case BFD_RELOC_ALPHA_LINKAGE
:
1483 case BFD_RELOC_ALPHA_CODEADDR
:
1486 case BFD_RELOC_VTABLE_ENTRY
:
1487 case BFD_RELOC_VTABLE_INHERIT
:
1490 case BFD_RELOC_GPREL16
:
1491 case BFD_RELOC_GPREL32
:
1492 case BFD_RELOC_ALPHA_GPREL_HI16
:
1493 case BFD_RELOC_ALPHA_GPREL_LO16
:
1494 case BFD_RELOC_23_PCREL_S2
:
1497 case BFD_RELOC_ALPHA_HINT
:
1506 /* Generate the BFD reloc to be stuck in the object file from the
1507 fixup used internally in the assembler. */
1510 tc_gen_reloc (sec
, fixp
)
1511 asection
*sec ATTRIBUTE_UNUSED
;
1516 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
1517 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
1518 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
1519 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
1521 /* Make sure none of our internal relocations make it this far.
1522 They'd better have been fully resolved by this point. */
1523 assert ((int) fixp
->fx_r_type
> 0);
1525 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
1526 if (reloc
->howto
== NULL
)
1528 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1529 _("cannot represent `%s' relocation in object file"),
1530 bfd_get_reloc_code_name (fixp
->fx_r_type
));
1534 if (!fixp
->fx_pcrel
!= !reloc
->howto
->pc_relative
)
1536 as_fatal (_("internal error? cannot generate `%s' relocation"),
1537 bfd_get_reloc_code_name (fixp
->fx_r_type
));
1539 assert (!fixp
->fx_pcrel
== !reloc
->howto
->pc_relative
);
1542 if (fixp
->fx_r_type
== BFD_RELOC_ALPHA_LITERAL
)
1544 /* fake out bfd_perform_relocation. sigh */
1545 reloc
->addend
= -alpha_gp_value
;
1550 reloc
->addend
= fixp
->fx_offset
;
1553 * Ohhh, this is ugly. The problem is that if this is a local global
1554 * symbol, the relocation will entirely be performed at link time, not
1555 * at assembly time. bfd_perform_reloc doesn't know about this sort
1556 * of thing, and as a result we need to fake it out here.
1558 if ((S_IS_EXTERN (fixp
->fx_addsy
) || S_IS_WEAK (fixp
->fx_addsy
)
1559 || (S_GET_SEGMENT (fixp
->fx_addsy
)->flags
& SEC_MERGE
)
1560 || (S_GET_SEGMENT (fixp
->fx_addsy
)->flags
& SEC_THREAD_LOCAL
))
1561 && !S_IS_COMMON (fixp
->fx_addsy
))
1562 reloc
->addend
-= symbol_get_bfdsym (fixp
->fx_addsy
)->value
;
1569 /* Parse a register name off of the input_line and return a register
1570 number. Gets md_undefined_symbol above to do the register name
1573 Only called as a part of processing the ECOFF .frame directive. */
1576 tc_get_register (frame
)
1577 int frame ATTRIBUTE_UNUSED
;
1579 int framereg
= AXP_REG_SP
;
1582 if (*input_line_pointer
== '$')
1584 char *s
= input_line_pointer
;
1585 char c
= get_symbol_end ();
1586 symbolS
*sym
= md_undefined_symbol (s
);
1588 *strchr (s
, '\0') = c
;
1589 if (sym
&& (framereg
= S_GET_VALUE (sym
)) <= 31)
1592 as_warn (_("frame reg expected, using $%d."), framereg
);
1595 note_gpreg (framereg
);
1599 /* This is called before the symbol table is processed. In order to
1600 work with gcc when using mips-tfile, we must keep all local labels.
1601 However, in other cases, we want to discard them. If we were
1602 called with -g, but we didn't see any debugging information, it may
1603 mean that gcc is smuggling debugging information through to
1604 mips-tfile, in which case we must generate all local labels. */
1609 alpha_frob_file_before_adjust ()
1611 if (alpha_debug
!= 0
1612 && ! ecoff_debugging_seen
)
1613 flag_keep_locals
= 1;
1616 #endif /* OBJ_ECOFF */
1618 static struct alpha_reloc_tag
*
1619 get_alpha_reloc_tag (sequence
)
1622 char buffer
[ALPHA_RELOC_DIGITS
];
1623 struct alpha_reloc_tag
*info
;
1625 sprintf (buffer
, "!%ld", sequence
);
1627 info
= (struct alpha_reloc_tag
*) hash_find (alpha_literal_hash
, buffer
);
1630 size_t len
= strlen (buffer
);
1633 info
= (struct alpha_reloc_tag
*)
1634 xcalloc (sizeof (struct alpha_reloc_tag
) + len
, 1);
1636 info
->segment
= now_seg
;
1637 info
->sequence
= sequence
;
1638 strcpy (info
->string
, buffer
);
1639 errmsg
= hash_insert (alpha_literal_hash
, info
->string
, (PTR
) info
);
1647 /* Before the relocations are written, reorder them, so that user
1648 supplied !lituse relocations follow the appropriate !literal
1649 relocations, and similarly for !gpdisp relocations. */
1652 alpha_adjust_symtab ()
1654 if (alpha_literal_hash
)
1655 bfd_map_over_sections (stdoutput
, alpha_adjust_symtab_relocs
, NULL
);
1659 alpha_adjust_symtab_relocs (abfd
, sec
, ptr
)
1660 bfd
*abfd ATTRIBUTE_UNUSED
;
1662 PTR ptr ATTRIBUTE_UNUSED
;
1664 segment_info_type
*seginfo
= seg_info (sec
);
1669 unsigned long n_slaves
= 0;
1671 /* If seginfo is NULL, we did not create this section; don't do
1672 anything with it. By using a pointer to a pointer, we can update
1673 the links in place. */
1674 if (seginfo
== NULL
)
1677 /* If there are no relocations, skip the section. */
1678 if (! seginfo
->fix_root
)
1681 /* First rebuild the fixup chain without the expicit lituse and
1682 gpdisp_lo16 relocs. */
1683 prevP
= &seginfo
->fix_root
;
1684 for (fixp
= seginfo
->fix_root
; fixp
; fixp
= next
)
1686 next
= fixp
->fx_next
;
1687 fixp
->fx_next
= (fixS
*) 0;
1689 switch (fixp
->fx_r_type
)
1691 case BFD_RELOC_ALPHA_LITUSE
:
1693 if (fixp
->tc_fix_data
.info
->n_master
== 0)
1694 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1695 _("No !literal!%ld was found"),
1696 fixp
->tc_fix_data
.info
->sequence
);
1699 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1701 if (fixp
->tc_fix_data
.info
->n_master
== 0)
1702 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1703 _("No ldah !gpdisp!%ld was found"),
1704 fixp
->tc_fix_data
.info
->sequence
);
1709 prevP
= &fixp
->fx_next
;
1714 /* If there were any dependent relocations, go and add them back to
1715 the chain. They are linked through the next_reloc field in
1716 reverse order, so as we go through the next_reloc chain, we
1717 effectively reverse the chain once again.
1719 Except if there is more than one !literal for a given sequence
1720 number. In that case, the programmer and/or compiler is not sure
1721 how control flows from literal to lituse, and we can't be sure to
1722 get the relaxation correct.
1724 ??? Well, actually we could, if there are enough lituses such that
1725 we can make each literal have at least one of each lituse type
1726 present. Not implemented.
1728 Also suppress the optimization if the !literals/!lituses are spread
1729 in different segments. This can happen with "intersting" uses of
1730 inline assembly; examples are present in the Linux kernel semaphores. */
1732 for (fixp
= seginfo
->fix_root
; fixp
; fixp
= next
)
1734 next
= fixp
->fx_next
;
1735 switch (fixp
->fx_r_type
)
1737 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1738 if (fixp
->tc_fix_data
.info
->n_master
== 1
1739 && ! fixp
->tc_fix_data
.info
->multi_section_p
)
1741 for (slave
= fixp
->tc_fix_data
.info
->slaves
;
1742 slave
!= (fixS
*) 0;
1743 slave
= slave
->tc_fix_data
.next_reloc
)
1745 slave
->fx_next
= fixp
->fx_next
;
1746 fixp
->fx_next
= slave
;
1751 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1752 if (fixp
->tc_fix_data
.info
->n_slaves
== 0)
1753 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1754 _("No lda !gpdisp!%ld was found"),
1755 fixp
->tc_fix_data
.info
->sequence
);
1758 slave
= fixp
->tc_fix_data
.info
->slaves
;
1759 slave
->fx_next
= next
;
1760 fixp
->fx_next
= slave
;
1772 debug_exp (tok
, ntok
)
1778 fprintf (stderr
, "debug_exp: %d tokens", ntok
);
1779 for (i
= 0; i
< ntok
; i
++)
1781 expressionS
*t
= &tok
[i
];
1785 default: name
= "unknown"; break;
1786 case O_illegal
: name
= "O_illegal"; break;
1787 case O_absent
: name
= "O_absent"; break;
1788 case O_constant
: name
= "O_constant"; break;
1789 case O_symbol
: name
= "O_symbol"; break;
1790 case O_symbol_rva
: name
= "O_symbol_rva"; break;
1791 case O_register
: name
= "O_register"; break;
1792 case O_big
: name
= "O_big"; break;
1793 case O_uminus
: name
= "O_uminus"; break;
1794 case O_bit_not
: name
= "O_bit_not"; break;
1795 case O_logical_not
: name
= "O_logical_not"; break;
1796 case O_multiply
: name
= "O_multiply"; break;
1797 case O_divide
: name
= "O_divide"; break;
1798 case O_modulus
: name
= "O_modulus"; break;
1799 case O_left_shift
: name
= "O_left_shift"; break;
1800 case O_right_shift
: name
= "O_right_shift"; break;
1801 case O_bit_inclusive_or
: name
= "O_bit_inclusive_or"; break;
1802 case O_bit_or_not
: name
= "O_bit_or_not"; break;
1803 case O_bit_exclusive_or
: name
= "O_bit_exclusive_or"; break;
1804 case O_bit_and
: name
= "O_bit_and"; break;
1805 case O_add
: name
= "O_add"; break;
1806 case O_subtract
: name
= "O_subtract"; break;
1807 case O_eq
: name
= "O_eq"; break;
1808 case O_ne
: name
= "O_ne"; break;
1809 case O_lt
: name
= "O_lt"; break;
1810 case O_le
: name
= "O_le"; break;
1811 case O_ge
: name
= "O_ge"; break;
1812 case O_gt
: name
= "O_gt"; break;
1813 case O_logical_and
: name
= "O_logical_and"; break;
1814 case O_logical_or
: name
= "O_logical_or"; break;
1815 case O_index
: name
= "O_index"; break;
1816 case O_pregister
: name
= "O_pregister"; break;
1817 case O_cpregister
: name
= "O_cpregister"; break;
1818 case O_literal
: name
= "O_literal"; break;
1819 case O_lituse_addr
: name
= "O_lituse_addr"; break;
1820 case O_lituse_base
: name
= "O_lituse_base"; break;
1821 case O_lituse_bytoff
: name
= "O_lituse_bytoff"; break;
1822 case O_lituse_jsr
: name
= "O_lituse_jsr"; break;
1823 case O_gpdisp
: name
= "O_gpdisp"; break;
1824 case O_gprelhigh
: name
= "O_gprelhigh"; break;
1825 case O_gprellow
: name
= "O_gprellow"; break;
1826 case O_gprel
: name
= "O_gprel"; break;
1827 case O_samegp
: name
= "O_samegp"; break;
1828 case O_md13
: name
= "O_md13"; break;
1829 case O_md14
: name
= "O_md14"; break;
1830 case O_md15
: name
= "O_md15"; break;
1831 case O_md16
: name
= "O_md16"; break;
1834 fprintf (stderr
, ", %s(%s, %s, %d)", name
,
1835 (t
->X_add_symbol
) ? S_GET_NAME (t
->X_add_symbol
) : "--",
1836 (t
->X_op_symbol
) ? S_GET_NAME (t
->X_op_symbol
) : "--",
1837 (int) t
->X_add_number
);
1839 fprintf (stderr
, "\n");
1844 /* Parse the arguments to an opcode. */
1847 tokenize_arguments (str
, tok
, ntok
)
1852 expressionS
*end_tok
= tok
+ ntok
;
1853 char *old_input_line_pointer
;
1854 int saw_comma
= 0, saw_arg
= 0;
1856 expressionS
*orig_tok
= tok
;
1859 const struct alpha_reloc_op_tag
*r
;
1862 int reloc_found_p
= 0;
1864 memset (tok
, 0, sizeof (*tok
) * ntok
);
1866 /* Save and restore input_line_pointer around this function */
1867 old_input_line_pointer
= input_line_pointer
;
1868 input_line_pointer
= str
;
1871 /* ??? Wrest control of ! away from the regular expression parser. */
1872 is_end_of_line
[(unsigned char) '!'] = 1;
1875 while (tok
< end_tok
&& *input_line_pointer
)
1878 switch (*input_line_pointer
)
1885 /* A relocation operand can be placed after the normal operand on an
1886 assembly language statement, and has the following form:
1887 !relocation_type!sequence_number. */
1889 { /* only support one relocation op per insn */
1890 as_bad (_("More than one relocation op per insn"));
1897 ++input_line_pointer
;
1899 p
= input_line_pointer
;
1900 c
= get_symbol_end ();
1902 /* Parse !relocation_type */
1903 len
= input_line_pointer
- p
;
1906 as_bad (_("No relocation operand"));
1910 r
= &alpha_reloc_op
[0];
1911 for (i
= alpha_num_reloc_op
- 1; i
>= 0; i
--, r
++)
1912 if (len
== r
->length
&& memcmp (p
, r
->name
, len
) == 0)
1916 as_bad (_("Unknown relocation operand: !%s"), p
);
1920 *input_line_pointer
= c
;
1922 if (*input_line_pointer
!= '!')
1926 as_bad (_("no sequence number after !%s"), p
);
1930 tok
->X_add_number
= 0;
1936 as_bad (_("!%s does not use a sequence number"), p
);
1940 input_line_pointer
++;
1942 /* Parse !sequence_number */
1944 if (tok
->X_op
!= O_constant
|| tok
->X_add_number
<= 0)
1946 as_bad (_("Bad sequence number: !%s!%s"),
1947 r
->name
, input_line_pointer
);
1956 #endif /* RELOC_OP_P */
1959 ++input_line_pointer
;
1960 if (saw_comma
|| !saw_arg
)
1967 char *hold
= input_line_pointer
++;
1969 /* First try for parenthesized register ... */
1971 if (*input_line_pointer
== ')' && tok
->X_op
== O_register
)
1973 tok
->X_op
= (saw_comma
? O_cpregister
: O_pregister
);
1976 ++input_line_pointer
;
1981 /* ... then fall through to plain expression */
1982 input_line_pointer
= hold
;
1986 if (saw_arg
&& !saw_comma
)
1990 if (tok
->X_op
== O_illegal
|| tok
->X_op
== O_absent
)
2003 input_line_pointer
= old_input_line_pointer
;
2006 debug_exp (orig_tok
, ntok
- (end_tok
- tok
));
2009 is_end_of_line
[(unsigned char) '!'] = 0;
2012 return ntok
- (end_tok
- tok
);
2016 is_end_of_line
[(unsigned char) '!'] = 0;
2018 input_line_pointer
= old_input_line_pointer
;
2019 return TOKENIZE_ERROR
;
2023 is_end_of_line
[(unsigned char) '!'] = 0;
2025 input_line_pointer
= old_input_line_pointer
;
2026 return TOKENIZE_ERROR_REPORT
;
2029 /* Search forward through all variants of an opcode looking for a
2032 static const struct alpha_opcode
*
2033 find_opcode_match (first_opcode
, tok
, pntok
, pcpumatch
)
2034 const struct alpha_opcode
*first_opcode
;
2035 const expressionS
*tok
;
2039 const struct alpha_opcode
*opcode
= first_opcode
;
2041 int got_cpu_match
= 0;
2045 const unsigned char *opidx
;
2048 /* Don't match opcodes that don't exist on this architecture */
2049 if (!(opcode
->flags
& alpha_target
))
2054 for (opidx
= opcode
->operands
; *opidx
; ++opidx
)
2056 const struct alpha_operand
*operand
= &alpha_operands
[*opidx
];
2058 /* only take input from real operands */
2059 if (operand
->flags
& AXP_OPERAND_FAKE
)
2062 /* when we expect input, make sure we have it */
2065 if ((operand
->flags
& AXP_OPERAND_OPTIONAL_MASK
) == 0)
2070 /* match operand type with expression type */
2071 switch (operand
->flags
& AXP_OPERAND_TYPECHECK_MASK
)
2073 case AXP_OPERAND_IR
:
2074 if (tok
[tokidx
].X_op
!= O_register
2075 || !is_ir_num (tok
[tokidx
].X_add_number
))
2078 case AXP_OPERAND_FPR
:
2079 if (tok
[tokidx
].X_op
!= O_register
2080 || !is_fpr_num (tok
[tokidx
].X_add_number
))
2083 case AXP_OPERAND_IR
| AXP_OPERAND_PARENS
:
2084 if (tok
[tokidx
].X_op
!= O_pregister
2085 || !is_ir_num (tok
[tokidx
].X_add_number
))
2088 case AXP_OPERAND_IR
| AXP_OPERAND_PARENS
| AXP_OPERAND_COMMA
:
2089 if (tok
[tokidx
].X_op
!= O_cpregister
2090 || !is_ir_num (tok
[tokidx
].X_add_number
))
2094 case AXP_OPERAND_RELATIVE
:
2095 case AXP_OPERAND_SIGNED
:
2096 case AXP_OPERAND_UNSIGNED
:
2097 switch (tok
[tokidx
].X_op
)
2112 /* everything else should have been fake */
2118 /* possible match -- did we use all of our input? */
2127 while (++opcode
- alpha_opcodes
< alpha_num_opcodes
2128 && !strcmp (opcode
->name
, first_opcode
->name
));
2131 *pcpumatch
= got_cpu_match
;
2136 /* Search forward through all variants of a macro looking for a syntax
2139 static const struct alpha_macro
*
2140 find_macro_match (first_macro
, tok
, pntok
)
2141 const struct alpha_macro
*first_macro
;
2142 const expressionS
*tok
;
2145 const struct alpha_macro
*macro
= first_macro
;
2150 const enum alpha_macro_arg
*arg
= macro
->argsets
;
2164 /* index register */
2166 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_register
2167 || !is_ir_num (tok
[tokidx
].X_add_number
))
2172 /* parenthesized index register */
2174 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_pregister
2175 || !is_ir_num (tok
[tokidx
].X_add_number
))
2180 /* optional parenthesized index register */
2182 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_pregister
2183 && is_ir_num (tok
[tokidx
].X_add_number
))
2187 /* leading comma with a parenthesized index register */
2189 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_cpregister
2190 || !is_ir_num (tok
[tokidx
].X_add_number
))
2195 /* floating point register */
2197 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_register
2198 || !is_fpr_num (tok
[tokidx
].X_add_number
))
2203 /* normal expression */
2207 switch (tok
[tokidx
].X_op
)
2216 case O_lituse_bytoff
:
2232 while (*arg
!= MACRO_EOA
)
2240 while (++macro
- alpha_macros
< alpha_num_macros
2241 && !strcmp (macro
->name
, first_macro
->name
));
2246 /* Insert an operand value into an instruction. */
2249 insert_operand (insn
, operand
, val
, file
, line
)
2251 const struct alpha_operand
*operand
;
2256 if (operand
->bits
!= 32 && !(operand
->flags
& AXP_OPERAND_NOOVERFLOW
))
2260 if (operand
->flags
& AXP_OPERAND_SIGNED
)
2262 max
= (1 << (operand
->bits
- 1)) - 1;
2263 min
= -(1 << (operand
->bits
- 1));
2267 max
= (1 << operand
->bits
) - 1;
2271 if (val
< min
|| val
> max
)
2274 _("operand out of range (%s not between %d and %d)");
2275 char buf
[sizeof (val
) * 3 + 2];
2277 sprint_value (buf
, val
);
2279 as_warn_where (file
, line
, err
, buf
, min
, max
);
2281 as_warn (err
, buf
, min
, max
);
2285 if (operand
->insert
)
2287 const char *errmsg
= NULL
;
2289 insn
= (*operand
->insert
) (insn
, val
, &errmsg
);
2294 insn
|= ((val
& ((1 << operand
->bits
) - 1)) << operand
->shift
);
2300 * Turn an opcode description and a set of arguments into
2301 * an instruction and a fixup.
2305 assemble_insn (opcode
, tok
, ntok
, insn
, reloc
)
2306 const struct alpha_opcode
*opcode
;
2307 const expressionS
*tok
;
2309 struct alpha_insn
*insn
;
2310 bfd_reloc_code_real_type reloc
;
2312 const struct alpha_operand
*reloc_operand
= NULL
;
2313 const expressionS
*reloc_exp
= NULL
;
2314 const unsigned char *argidx
;
2318 memset (insn
, 0, sizeof (*insn
));
2319 image
= opcode
->opcode
;
2321 for (argidx
= opcode
->operands
; *argidx
; ++argidx
)
2323 const struct alpha_operand
*operand
= &alpha_operands
[*argidx
];
2324 const expressionS
*t
= (const expressionS
*) 0;
2326 if (operand
->flags
& AXP_OPERAND_FAKE
)
2328 /* fake operands take no value and generate no fixup */
2329 image
= insert_operand (image
, operand
, 0, NULL
, 0);
2335 switch (operand
->flags
& AXP_OPERAND_OPTIONAL_MASK
)
2337 case AXP_OPERAND_DEFAULT_FIRST
:
2340 case AXP_OPERAND_DEFAULT_SECOND
:
2343 case AXP_OPERAND_DEFAULT_ZERO
:
2345 static expressionS zero_exp
;
2347 zero_exp
.X_op
= O_constant
;
2348 zero_exp
.X_unsigned
= 1;
2363 image
= insert_operand (image
, operand
, regno (t
->X_add_number
),
2368 image
= insert_operand (image
, operand
, t
->X_add_number
, NULL
, 0);
2369 assert (reloc_operand
== NULL
);
2370 reloc_operand
= operand
;
2375 /* This is only 0 for fields that should contain registers,
2376 which means this pattern shouldn't have matched. */
2377 if (operand
->default_reloc
== 0)
2380 /* There is one special case for which an insn receives two
2381 relocations, and thus the user-supplied reloc does not
2382 override the operand reloc. */
2383 if (operand
->default_reloc
== BFD_RELOC_ALPHA_HINT
)
2385 struct alpha_fixup
*fixup
;
2387 if (insn
->nfixups
>= MAX_INSN_FIXUPS
)
2388 as_fatal (_("too many fixups"));
2390 fixup
= &insn
->fixups
[insn
->nfixups
++];
2392 fixup
->reloc
= BFD_RELOC_ALPHA_HINT
;
2396 if (reloc
== BFD_RELOC_UNUSED
)
2397 reloc
= operand
->default_reloc
;
2399 assert (reloc_operand
== NULL
);
2400 reloc_operand
= operand
;
2407 if (reloc
!= BFD_RELOC_UNUSED
)
2409 struct alpha_fixup
*fixup
;
2411 if (insn
->nfixups
>= MAX_INSN_FIXUPS
)
2412 as_fatal (_("too many fixups"));
2414 /* ??? My but this is hacky. But the OSF/1 assembler uses the same
2415 relocation tag for both ldah and lda with gpdisp. Choose the
2416 correct internal relocation based on the opcode. */
2417 if (reloc
== BFD_RELOC_ALPHA_GPDISP
)
2419 if (strcmp (opcode
->name
, "ldah") == 0)
2420 reloc
= BFD_RELOC_ALPHA_GPDISP_HI16
;
2421 else if (strcmp (opcode
->name
, "lda") == 0)
2422 reloc
= BFD_RELOC_ALPHA_GPDISP_LO16
;
2424 as_bad (_("invalid relocation for instruction"));
2427 /* If this is a real relocation (as opposed to a lituse hint), then
2428 the relocation width should match the operand width. */
2429 else if (reloc
< BFD_RELOC_UNUSED
)
2431 reloc_howto_type
*reloc_howto
2432 = bfd_reloc_type_lookup (stdoutput
, reloc
);
2433 if (reloc_howto
->bitsize
!= reloc_operand
->bits
)
2435 as_bad (_("invalid relocation for field"));
2440 fixup
= &insn
->fixups
[insn
->nfixups
++];
2442 fixup
->exp
= *reloc_exp
;
2444 fixup
->exp
.X_op
= O_absent
;
2445 fixup
->reloc
= reloc
;
2452 * Actually output an instruction with its fixup.
2457 struct alpha_insn
*insn
;
2462 /* Take care of alignment duties. */
2463 if (alpha_auto_align_on
&& alpha_current_align
< 2)
2464 alpha_align (2, (char *) NULL
, alpha_insn_label
, 0);
2465 if (alpha_current_align
> 2)
2466 alpha_current_align
= 2;
2467 alpha_insn_label
= NULL
;
2469 /* Write out the instruction. */
2471 md_number_to_chars (f
, insn
->insn
, 4);
2474 dwarf2_emit_insn (4);
2477 /* Apply the fixups in order */
2478 for (i
= 0; i
< insn
->nfixups
; ++i
)
2480 const struct alpha_operand
*operand
= (const struct alpha_operand
*) 0;
2481 struct alpha_fixup
*fixup
= &insn
->fixups
[i
];
2482 struct alpha_reloc_tag
*info
;
2486 /* Some fixups are only used internally and so have no howto */
2487 if ((int) fixup
->reloc
< 0)
2489 operand
= &alpha_operands
[-(int) fixup
->reloc
];
2491 pcrel
= ((operand
->flags
& AXP_OPERAND_RELATIVE
) != 0);
2493 else if (fixup
->reloc
> BFD_RELOC_UNUSED
2494 || fixup
->reloc
== BFD_RELOC_ALPHA_GPDISP_HI16
2495 || fixup
->reloc
== BFD_RELOC_ALPHA_GPDISP_LO16
)
2502 reloc_howto_type
*reloc_howto
2503 = bfd_reloc_type_lookup (stdoutput
, fixup
->reloc
);
2504 assert (reloc_howto
);
2506 size
= bfd_get_reloc_size (reloc_howto
);
2507 assert (size
>= 1 && size
<= 4);
2509 pcrel
= reloc_howto
->pc_relative
;
2512 fixP
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, size
,
2513 &fixup
->exp
, pcrel
, fixup
->reloc
);
2515 /* Turn off complaints that the addend is too large for some fixups,
2516 and copy in the sequence number for the explicit relocations. */
2517 switch (fixup
->reloc
)
2519 case BFD_RELOC_ALPHA_HINT
:
2520 case BFD_RELOC_GPREL32
:
2521 case BFD_RELOC_GPREL16
:
2522 case BFD_RELOC_ALPHA_GPREL_HI16
:
2523 case BFD_RELOC_ALPHA_GPREL_LO16
:
2524 fixP
->fx_no_overflow
= 1;
2527 case BFD_RELOC_ALPHA_GPDISP_HI16
:
2528 fixP
->fx_no_overflow
= 1;
2529 fixP
->fx_addsy
= section_symbol (now_seg
);
2530 fixP
->fx_offset
= 0;
2532 info
= get_alpha_reloc_tag (insn
->sequence
);
2533 if (++info
->n_master
> 1)
2534 as_bad (_("too many ldah insns for !gpdisp!%ld"), insn
->sequence
);
2535 if (info
->segment
!= now_seg
)
2536 as_bad (_("both insns for !gpdisp!%ld must be in the same section"),
2538 fixP
->tc_fix_data
.info
= info
;
2541 case BFD_RELOC_ALPHA_GPDISP_LO16
:
2542 fixP
->fx_no_overflow
= 1;
2544 info
= get_alpha_reloc_tag (insn
->sequence
);
2545 if (++info
->n_slaves
> 1)
2546 as_bad (_("too many lda insns for !gpdisp!%ld"), insn
->sequence
);
2547 if (info
->segment
!= now_seg
)
2548 as_bad (_("both insns for !gpdisp!%ld must be in the same section"),
2550 fixP
->tc_fix_data
.info
= info
;
2551 info
->slaves
= fixP
;
2554 case BFD_RELOC_ALPHA_LITERAL
:
2555 case BFD_RELOC_ALPHA_ELF_LITERAL
:
2556 fixP
->fx_no_overflow
= 1;
2558 info
= get_alpha_reloc_tag (insn
->sequence
);
2560 if (info
->segment
!= now_seg
)
2561 info
->multi_section_p
= 1;
2562 fixP
->tc_fix_data
.info
= info
;
2565 case DUMMY_RELOC_LITUSE_ADDR
:
2566 fixP
->fx_offset
= LITUSE_ADDR
;
2568 case DUMMY_RELOC_LITUSE_BASE
:
2569 fixP
->fx_offset
= LITUSE_BASE
;
2571 case DUMMY_RELOC_LITUSE_BYTOFF
:
2572 fixP
->fx_offset
= LITUSE_BYTOFF
;
2574 case DUMMY_RELOC_LITUSE_JSR
:
2575 fixP
->fx_offset
= LITUSE_JSR
;
2577 fixP
->fx_addsy
= section_symbol (now_seg
);
2578 fixP
->fx_r_type
= BFD_RELOC_ALPHA_LITUSE
;
2580 info
= get_alpha_reloc_tag (insn
->sequence
);
2582 fixP
->tc_fix_data
.info
= info
;
2583 fixP
->tc_fix_data
.next_reloc
= info
->slaves
;
2584 info
->slaves
= fixP
;
2585 if (info
->segment
!= now_seg
)
2586 info
->multi_section_p
= 1;
2590 if ((int) fixup
->reloc
< 0)
2592 if (operand
->flags
& AXP_OPERAND_NOOVERFLOW
)
2593 fixP
->fx_no_overflow
= 1;
2600 /* Given an opcode name and a pre-tokenized set of arguments, assemble
2601 the insn, but do not emit it.
2603 Note that this implies no macros allowed, since we can't store more
2604 than one insn in an insn structure. */
2607 assemble_tokens_to_insn (opname
, tok
, ntok
, insn
)
2609 const expressionS
*tok
;
2611 struct alpha_insn
*insn
;
2613 const struct alpha_opcode
*opcode
;
2615 /* search opcodes */
2616 opcode
= (const struct alpha_opcode
*) hash_find (alpha_opcode_hash
, opname
);
2620 opcode
= find_opcode_match (opcode
, tok
, &ntok
, &cpumatch
);
2623 assemble_insn (opcode
, tok
, ntok
, insn
, BFD_RELOC_UNUSED
);
2627 as_bad (_("inappropriate arguments for opcode `%s'"), opname
);
2629 as_bad (_("opcode `%s' not supported for target %s"), opname
,
2633 as_bad (_("unknown opcode `%s'"), opname
);
2636 /* Given an opcode name and a pre-tokenized set of arguments, take the
2637 opcode all the way through emission. */
2640 assemble_tokens (opname
, tok
, ntok
, local_macros_on
)
2642 const expressionS
*tok
;
2644 int local_macros_on
;
2646 int found_something
= 0;
2647 const struct alpha_opcode
*opcode
;
2648 const struct alpha_macro
*macro
;
2650 bfd_reloc_code_real_type reloc
= BFD_RELOC_UNUSED
;
2653 /* If a user-specified relocation is present, this is not a macro. */
2654 if (ntok
&& USER_RELOC_P (tok
[ntok
- 1].X_op
))
2656 reloc
= ALPHA_RELOC_TABLE (tok
[ntok
- 1].X_op
)->reloc
;
2661 if (local_macros_on
)
2663 macro
= ((const struct alpha_macro
*)
2664 hash_find (alpha_macro_hash
, opname
));
2667 found_something
= 1;
2668 macro
= find_macro_match (macro
, tok
, &ntok
);
2671 (*macro
->emit
) (tok
, ntok
, macro
->arg
);
2677 /* search opcodes */
2678 opcode
= (const struct alpha_opcode
*) hash_find (alpha_opcode_hash
, opname
);
2681 found_something
= 1;
2682 opcode
= find_opcode_match (opcode
, tok
, &ntok
, &cpumatch
);
2685 struct alpha_insn insn
;
2686 assemble_insn (opcode
, tok
, ntok
, &insn
, reloc
);
2688 /* Copy the sequence number for the reloc from the reloc token. */
2689 if (reloc
!= BFD_RELOC_UNUSED
)
2690 insn
.sequence
= tok
[ntok
].X_add_number
;
2697 if (found_something
)
2700 as_bad (_("inappropriate arguments for opcode `%s'"), opname
);
2702 as_bad (_("opcode `%s' not supported for target %s"), opname
,
2706 as_bad (_("unknown opcode `%s'"), opname
);
2709 /* Some instruction sets indexed by lg(size) */
2710 static const char * const sextX_op
[] = { "sextb", "sextw", "sextl", NULL
};
2711 static const char * const insXl_op
[] = { "insbl", "inswl", "insll", "insql" };
2712 static const char * const insXh_op
[] = { NULL
, "inswh", "inslh", "insqh" };
2713 static const char * const extXl_op
[] = { "extbl", "extwl", "extll", "extql" };
2714 static const char * const extXh_op
[] = { NULL
, "extwh", "extlh", "extqh" };
2715 static const char * const mskXl_op
[] = { "mskbl", "mskwl", "mskll", "mskql" };
2716 static const char * const mskXh_op
[] = { NULL
, "mskwh", "msklh", "mskqh" };
2717 static const char * const stX_op
[] = { "stb", "stw", "stl", "stq" };
2718 static const char * const ldX_op
[] = { "ldb", "ldw", "ldll", "ldq" };
2719 static const char * const ldXu_op
[] = { "ldbu", "ldwu", NULL
, NULL
};
2721 /* Implement the ldgp macro. */
2724 emit_ldgp (tok
, ntok
, unused
)
2725 const expressionS
*tok
;
2726 int ntok ATTRIBUTE_UNUSED
;
2727 const PTR unused ATTRIBUTE_UNUSED
;
2732 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
2733 /* from "ldgp r1,n(r2)", generate "ldah r1,X(R2); lda r1,Y(r1)"
2734 with appropriate constants and relocations. */
2735 struct alpha_insn insn
;
2736 expressionS newtok
[3];
2740 if (regno (tok
[2].X_add_number
) == AXP_REG_PV
)
2741 ecoff_set_gp_prolog_size (0);
2745 set_tok_const (newtok
[1], 0);
2748 assemble_tokens_to_insn ("ldah", newtok
, 3, &insn
);
2753 if (addend
.X_op
!= O_constant
)
2754 as_bad (_("can not resolve expression"));
2755 addend
.X_op
= O_symbol
;
2756 addend
.X_add_symbol
= alpha_gp_symbol
;
2760 insn
.fixups
[0].exp
= addend
;
2761 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_GPDISP_HI16
;
2762 insn
.sequence
= next_sequence_num
;
2766 set_tok_preg (newtok
[2], tok
[0].X_add_number
);
2768 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
2771 addend
.X_add_number
+= 4;
2775 insn
.fixups
[0].exp
= addend
;
2776 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_GPDISP_LO16
;
2777 insn
.sequence
= next_sequence_num
--;
2780 #endif /* OBJ_ECOFF || OBJ_ELF */
2785 /* Add symbol+addend to link pool.
2786 Return offset from basesym to entry in link pool.
2788 Add new fixup only if offset isn't 16bit. */
2791 add_to_link_pool (basesym
, sym
, addend
)
2796 segT current_section
= now_seg
;
2797 int current_subsec
= now_subseg
;
2799 bfd_reloc_code_real_type reloc_type
;
2801 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
2804 offset
= - *symbol_get_obj (basesym
);
2806 /* @@ This assumes all entries in a given section will be of the same
2807 size... Probably correct, but unwise to rely on. */
2808 /* This must always be called with the same subsegment. */
2810 if (seginfo
->frchainP
)
2811 for (fixp
= seginfo
->frchainP
->fix_root
;
2812 fixp
!= (fixS
*) NULL
;
2813 fixp
= fixp
->fx_next
, offset
+= 8)
2815 if (fixp
->fx_addsy
== sym
&& fixp
->fx_offset
== addend
)
2817 if (range_signed_16 (offset
))
2824 /* Not found in 16bit signed range. */
2826 subseg_set (alpha_link_section
, 0);
2830 fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, sym
, addend
, 0,
2833 subseg_set (current_section
, current_subsec
);
2834 seginfo
->literal_pool_size
+= 8;
2838 #endif /* OBJ_EVAX */
2840 /* Load a (partial) expression into a target register.
2842 If poffset is not null, after the call it will either contain
2843 O_constant 0, or a 16-bit offset appropriate for any MEM format
2844 instruction. In addition, pbasereg will be modified to point to
2845 the base register to use in that MEM format instruction.
2847 In any case, *pbasereg should contain a base register to add to the
2848 expression. This will normally be either AXP_REG_ZERO or
2849 alpha_gp_register. Symbol addresses will always be loaded via $gp,
2850 so "foo($0)" is interpreted as adding the address of foo to $0;
2851 i.e. "ldq $targ, LIT($gp); addq $targ, $0, $targ". Odd, perhaps,
2852 but this is what OSF/1 does.
2854 If explicit relocations of the form !literal!<number> are allowed,
2855 and used, then explict_reloc with be an expression pointer.
2857 Finally, the return value is nonzero if the calling macro may emit
2858 a LITUSE reloc if otherwise appropriate; the return value is the
2859 sequence number to use. */
2862 load_expression (targreg
, exp
, pbasereg
, poffset
)
2864 const expressionS
*exp
;
2866 expressionS
*poffset
;
2868 long emit_lituse
= 0;
2869 offsetT addend
= exp
->X_add_number
;
2870 int basereg
= *pbasereg
;
2871 struct alpha_insn insn
;
2872 expressionS newtok
[3];
2881 /* attempt to reduce .lit load by splitting the offset from
2882 its symbol when possible, but don't create a situation in
2884 if (!range_signed_32 (addend
) &&
2885 (alpha_noat_on
|| targreg
== AXP_REG_AT
))
2887 lit
= add_to_literal_pool (exp
->X_add_symbol
, addend
,
2888 alpha_lita_section
, 8);
2893 lit
= add_to_literal_pool (exp
->X_add_symbol
, 0,
2894 alpha_lita_section
, 8);
2898 as_fatal (_("overflow in literal (.lita) table"));
2900 /* emit "ldq r, lit(gp)" */
2902 if (basereg
!= alpha_gp_register
&& targreg
== basereg
)
2905 as_bad (_("macro requires $at register while noat in effect"));
2906 if (targreg
== AXP_REG_AT
)
2907 as_bad (_("macro requires $at while $at in use"));
2909 set_tok_reg (newtok
[0], AXP_REG_AT
);
2912 set_tok_reg (newtok
[0], targreg
);
2913 set_tok_sym (newtok
[1], alpha_lita_symbol
, lit
);
2914 set_tok_preg (newtok
[2], alpha_gp_register
);
2916 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
2918 assert (insn
.nfixups
== 1);
2919 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITERAL
;
2920 insn
.sequence
= emit_lituse
= next_sequence_num
--;
2921 #endif /* OBJ_ECOFF */
2923 /* emit "ldq r, gotoff(gp)" */
2925 if (basereg
!= alpha_gp_register
&& targreg
== basereg
)
2928 as_bad (_("macro requires $at register while noat in effect"));
2929 if (targreg
== AXP_REG_AT
)
2930 as_bad (_("macro requires $at while $at in use"));
2932 set_tok_reg (newtok
[0], AXP_REG_AT
);
2935 set_tok_reg (newtok
[0], targreg
);
2937 /* XXX: Disable this .got minimizing optimization so that we can get
2938 better instruction offset knowledge in the compiler. This happens
2939 very infrequently anyway. */
2941 || (!range_signed_32 (addend
)
2942 && (alpha_noat_on
|| targreg
== AXP_REG_AT
)))
2949 set_tok_sym (newtok
[1], exp
->X_add_symbol
, 0);
2952 set_tok_preg (newtok
[2], alpha_gp_register
);
2954 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
2956 assert (insn
.nfixups
== 1);
2957 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_ELF_LITERAL
;
2958 insn
.sequence
= emit_lituse
= next_sequence_num
--;
2959 #endif /* OBJ_ELF */
2963 /* Find symbol or symbol pointer in link section. */
2965 if (exp
->X_add_symbol
== alpha_evax_proc
.symbol
)
2967 if (range_signed_16 (addend
))
2969 set_tok_reg (newtok
[0], targreg
);
2970 set_tok_const (newtok
[1], addend
);
2971 set_tok_preg (newtok
[2], basereg
);
2972 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
2977 set_tok_reg (newtok
[0], targreg
);
2978 set_tok_const (newtok
[1], 0);
2979 set_tok_preg (newtok
[2], basereg
);
2980 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
2985 if (!range_signed_32 (addend
))
2987 link
= add_to_link_pool (alpha_evax_proc
.symbol
,
2988 exp
->X_add_symbol
, addend
);
2993 link
= add_to_link_pool (alpha_evax_proc
.symbol
,
2994 exp
->X_add_symbol
, 0);
2996 set_tok_reg (newtok
[0], targreg
);
2997 set_tok_const (newtok
[1], link
);
2998 set_tok_preg (newtok
[2], basereg
);
2999 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
3001 #endif /* OBJ_EVAX */
3006 if (basereg
!= alpha_gp_register
&& basereg
!= AXP_REG_ZERO
)
3008 /* emit "addq r, base, r" */
3010 set_tok_reg (newtok
[1], basereg
);
3011 set_tok_reg (newtok
[2], targreg
);
3012 assemble_tokens ("addq", newtok
, 3, 0);
3024 /* Assume that this difference expression will be resolved to an
3025 absolute value and that that value will fit in 16 bits. */
3027 set_tok_reg (newtok
[0], targreg
);
3029 set_tok_preg (newtok
[2], basereg
);
3030 assemble_tokens ("lda", newtok
, 3, 0);
3033 set_tok_const (*poffset
, 0);
3037 if (exp
->X_add_number
> 0)
3038 as_bad (_("bignum invalid; zero assumed"));
3040 as_bad (_("floating point number invalid; zero assumed"));
3045 as_bad (_("can't handle expression"));
3050 if (!range_signed_32 (addend
))
3053 long seq_num
= next_sequence_num
--;
3055 /* For 64-bit addends, just put it in the literal pool. */
3058 /* emit "ldq targreg, lit(basereg)" */
3059 lit
= add_to_link_pool (alpha_evax_proc
.symbol
,
3060 section_symbol (absolute_section
), addend
);
3061 set_tok_reg (newtok
[0], targreg
);
3062 set_tok_const (newtok
[1], lit
);
3063 set_tok_preg (newtok
[2], alpha_gp_register
);
3064 assemble_tokens ("ldq", newtok
, 3, 0);
3067 if (alpha_lit8_section
== NULL
)
3069 create_literal_section (".lit8",
3070 &alpha_lit8_section
,
3071 &alpha_lit8_symbol
);
3074 alpha_lit8_literal
= add_to_literal_pool (alpha_lit8_symbol
, 0x8000,
3075 alpha_lita_section
, 8);
3076 if (alpha_lit8_literal
>= 0x8000)
3077 as_fatal (_("overflow in literal (.lita) table"));
3081 lit
= add_to_literal_pool (NULL
, addend
, alpha_lit8_section
, 8) - 0x8000;
3083 as_fatal (_("overflow in literal (.lit8) table"));
3085 /* emit "lda litreg, .lit8+0x8000" */
3087 if (targreg
== basereg
)
3090 as_bad (_("macro requires $at register while noat in effect"));
3091 if (targreg
== AXP_REG_AT
)
3092 as_bad (_("macro requires $at while $at in use"));
3094 set_tok_reg (newtok
[0], AXP_REG_AT
);
3097 set_tok_reg (newtok
[0], targreg
);
3099 set_tok_sym (newtok
[1], alpha_lita_symbol
, alpha_lit8_literal
);
3102 set_tok_sym (newtok
[1], alpha_lit8_symbol
, 0x8000);
3104 set_tok_preg (newtok
[2], alpha_gp_register
);
3106 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
3108 assert (insn
.nfixups
== 1);
3110 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITERAL
;
3113 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_ELF_LITERAL
;
3115 insn
.sequence
= seq_num
;
3119 /* emit "ldq litreg, lit(litreg)" */
3121 set_tok_const (newtok
[1], lit
);
3122 set_tok_preg (newtok
[2], newtok
[0].X_add_number
);
3124 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
3126 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3127 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BASE
;
3128 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3130 insn
.sequence
= seq_num
;
3135 /* emit "addq litreg, base, target" */
3137 if (basereg
!= AXP_REG_ZERO
)
3139 set_tok_reg (newtok
[1], basereg
);
3140 set_tok_reg (newtok
[2], targreg
);
3141 assemble_tokens ("addq", newtok
, 3, 0);
3143 #endif /* !OBJ_EVAX */
3146 set_tok_const (*poffset
, 0);
3147 *pbasereg
= targreg
;
3151 offsetT low
, high
, extra
, tmp
;
3153 /* for 32-bit operands, break up the addend */
3155 low
= sign_extend_16 (addend
);
3157 high
= sign_extend_16 (tmp
>> 16);
3159 if (tmp
- (high
<< 16))
3163 high
= sign_extend_16 (tmp
>> 16);
3168 set_tok_reg (newtok
[0], targreg
);
3169 set_tok_preg (newtok
[2], basereg
);
3173 /* emit "ldah r, extra(r) */
3174 set_tok_const (newtok
[1], extra
);
3175 assemble_tokens ("ldah", newtok
, 3, 0);
3176 set_tok_preg (newtok
[2], basereg
= targreg
);
3181 /* emit "ldah r, high(r) */
3182 set_tok_const (newtok
[1], high
);
3183 assemble_tokens ("ldah", newtok
, 3, 0);
3185 set_tok_preg (newtok
[2], basereg
);
3188 if ((low
&& !poffset
) || (!poffset
&& basereg
!= targreg
))
3190 /* emit "lda r, low(base)" */
3191 set_tok_const (newtok
[1], low
);
3192 assemble_tokens ("lda", newtok
, 3, 0);
3198 set_tok_const (*poffset
, low
);
3199 *pbasereg
= basereg
;
3205 /* The lda macro differs from the lda instruction in that it handles
3206 most simple expressions, particualrly symbol address loads and
3210 emit_lda (tok
, ntok
, unused
)
3211 const expressionS
*tok
;
3213 const PTR unused ATTRIBUTE_UNUSED
;
3218 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
3220 basereg
= tok
[2].X_add_number
;
3222 (void) load_expression (tok
[0].X_add_number
, &tok
[1], &basereg
, NULL
);
3225 /* The ldah macro differs from the ldah instruction in that it has $31
3226 as an implied base register. */
3229 emit_ldah (tok
, ntok
, unused
)
3230 const expressionS
*tok
;
3231 int ntok ATTRIBUTE_UNUSED
;
3232 const PTR unused ATTRIBUTE_UNUSED
;
3234 expressionS newtok
[3];
3238 set_tok_preg (newtok
[2], AXP_REG_ZERO
);
3240 assemble_tokens ("ldah", newtok
, 3, 0);
3243 /* Handle all "simple" integer register loads -- ldq, ldq_l, ldq_u,
3244 etc. They differ from the real instructions in that they do simple
3245 expressions like the lda macro. */
3248 emit_ir_load (tok
, ntok
, opname
)
3249 const expressionS
*tok
;
3255 expressionS newtok
[3];
3256 struct alpha_insn insn
;
3259 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
3261 basereg
= tok
[2].X_add_number
;
3263 lituse
= load_expression (tok
[0].X_add_number
, &tok
[1], &basereg
,
3267 set_tok_preg (newtok
[2], basereg
);
3269 assemble_tokens_to_insn ((const char *) opname
, newtok
, 3, &insn
);
3273 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3274 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BASE
;
3275 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3277 insn
.sequence
= lituse
;
3283 /* Handle fp register loads, and both integer and fp register stores.
3284 Again, we handle simple expressions. */
3287 emit_loadstore (tok
, ntok
, opname
)
3288 const expressionS
*tok
;
3294 expressionS newtok
[3];
3295 struct alpha_insn insn
;
3298 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
3300 basereg
= tok
[2].X_add_number
;
3302 if (tok
[1].X_op
!= O_constant
|| !range_signed_16 (tok
[1].X_add_number
))
3305 as_bad (_("macro requires $at register while noat in effect"));
3307 lituse
= load_expression (AXP_REG_AT
, &tok
[1], &basereg
, &newtok
[1]);
3316 set_tok_preg (newtok
[2], basereg
);
3318 assemble_tokens_to_insn ((const char *) opname
, newtok
, 3, &insn
);
3322 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3323 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BASE
;
3324 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3326 insn
.sequence
= lituse
;
3332 /* Load a half-word or byte as an unsigned value. */
3335 emit_ldXu (tok
, ntok
, vlgsize
)
3336 const expressionS
*tok
;
3340 if (alpha_target
& AXP_OPCODE_BWX
)
3341 emit_ir_load (tok
, ntok
, ldXu_op
[(long) vlgsize
]);
3344 expressionS newtok
[3];
3345 struct alpha_insn insn
;
3350 as_bad (_("macro requires $at register while noat in effect"));
3353 basereg
= (tok
[1].X_op
== O_constant
3354 ? AXP_REG_ZERO
: alpha_gp_register
);
3356 basereg
= tok
[2].X_add_number
;
3358 /* emit "lda $at, exp" */
3360 lituse
= load_expression (AXP_REG_AT
, &tok
[1], &basereg
, NULL
);
3362 /* emit "ldq_u targ, 0($at)" */
3365 set_tok_const (newtok
[1], 0);
3366 set_tok_preg (newtok
[2], basereg
);
3367 assemble_tokens_to_insn ("ldq_u", newtok
, 3, &insn
);
3371 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3372 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BASE
;
3373 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3375 insn
.sequence
= lituse
;
3380 /* emit "extXl targ, $at, targ" */
3382 set_tok_reg (newtok
[1], basereg
);
3383 newtok
[2] = newtok
[0];
3384 assemble_tokens_to_insn (extXl_op
[(long) vlgsize
], newtok
, 3, &insn
);
3388 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3389 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BYTOFF
;
3390 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3392 insn
.sequence
= lituse
;
3399 /* Load a half-word or byte as a signed value. */
3402 emit_ldX (tok
, ntok
, vlgsize
)
3403 const expressionS
*tok
;
3407 emit_ldXu (tok
, ntok
, vlgsize
);
3408 assemble_tokens (sextX_op
[(long) vlgsize
], tok
, 1, 1);
3411 /* Load an integral value from an unaligned address as an unsigned
3415 emit_uldXu (tok
, ntok
, vlgsize
)
3416 const expressionS
*tok
;
3420 long lgsize
= (long) vlgsize
;
3421 expressionS newtok
[3];
3424 as_bad (_("macro requires $at register while noat in effect"));
3426 /* emit "lda $at, exp" */
3428 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
3429 newtok
[0].X_add_number
= AXP_REG_AT
;
3430 assemble_tokens ("lda", newtok
, ntok
, 1);
3432 /* emit "ldq_u $t9, 0($at)" */
3434 set_tok_reg (newtok
[0], AXP_REG_T9
);
3435 set_tok_const (newtok
[1], 0);
3436 set_tok_preg (newtok
[2], AXP_REG_AT
);
3437 assemble_tokens ("ldq_u", newtok
, 3, 1);
3439 /* emit "ldq_u $t10, size-1($at)" */
3441 set_tok_reg (newtok
[0], AXP_REG_T10
);
3442 set_tok_const (newtok
[1], (1 << lgsize
) - 1);
3443 assemble_tokens ("ldq_u", newtok
, 3, 1);
3445 /* emit "extXl $t9, $at, $t9" */
3447 set_tok_reg (newtok
[0], AXP_REG_T9
);
3448 set_tok_reg (newtok
[1], AXP_REG_AT
);
3449 set_tok_reg (newtok
[2], AXP_REG_T9
);
3450 assemble_tokens (extXl_op
[lgsize
], newtok
, 3, 1);
3452 /* emit "extXh $t10, $at, $t10" */
3454 set_tok_reg (newtok
[0], AXP_REG_T10
);
3455 set_tok_reg (newtok
[2], AXP_REG_T10
);
3456 assemble_tokens (extXh_op
[lgsize
], newtok
, 3, 1);
3458 /* emit "or $t9, $t10, targ" */
3460 set_tok_reg (newtok
[0], AXP_REG_T9
);
3461 set_tok_reg (newtok
[1], AXP_REG_T10
);
3463 assemble_tokens ("or", newtok
, 3, 1);
3466 /* Load an integral value from an unaligned address as a signed value.
3467 Note that quads should get funneled to the unsigned load since we
3468 don't have to do the sign extension. */
3471 emit_uldX (tok
, ntok
, vlgsize
)
3472 const expressionS
*tok
;
3476 emit_uldXu (tok
, ntok
, vlgsize
);
3477 assemble_tokens (sextX_op
[(long) vlgsize
], tok
, 1, 1);
3480 /* Implement the ldil macro. */
3483 emit_ldil (tok
, ntok
, unused
)
3484 const expressionS
*tok
;
3486 const PTR unused ATTRIBUTE_UNUSED
;
3488 expressionS newtok
[2];
3490 memcpy (newtok
, tok
, sizeof (newtok
));
3491 newtok
[1].X_add_number
= sign_extend_32 (tok
[1].X_add_number
);
3493 assemble_tokens ("lda", newtok
, ntok
, 1);
3496 /* Store a half-word or byte. */
3499 emit_stX (tok
, ntok
, vlgsize
)
3500 const expressionS
*tok
;
3504 int lgsize
= (int) (long) vlgsize
;
3506 if (alpha_target
& AXP_OPCODE_BWX
)
3507 emit_loadstore (tok
, ntok
, stX_op
[lgsize
]);
3510 expressionS newtok
[3];
3511 struct alpha_insn insn
;
3516 as_bad (_("macro requires $at register while noat in effect"));
3519 basereg
= (tok
[1].X_op
== O_constant
3520 ? AXP_REG_ZERO
: alpha_gp_register
);
3522 basereg
= tok
[2].X_add_number
;
3524 /* emit "lda $at, exp" */
3526 lituse
= load_expression (AXP_REG_AT
, &tok
[1], &basereg
, NULL
);
3528 /* emit "ldq_u $t9, 0($at)" */
3530 set_tok_reg (newtok
[0], AXP_REG_T9
);
3531 set_tok_const (newtok
[1], 0);
3532 set_tok_preg (newtok
[2], basereg
);
3533 assemble_tokens_to_insn ("ldq_u", newtok
, 3, &insn
);
3537 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3538 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BASE
;
3539 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3541 insn
.sequence
= lituse
;
3546 /* emit "insXl src, $at, $t10" */
3549 set_tok_reg (newtok
[1], basereg
);
3550 set_tok_reg (newtok
[2], AXP_REG_T10
);
3551 assemble_tokens_to_insn (insXl_op
[lgsize
], newtok
, 3, &insn
);
3555 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3556 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BYTOFF
;
3557 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3559 insn
.sequence
= lituse
;
3564 /* emit "mskXl $t9, $at, $t9" */
3566 set_tok_reg (newtok
[0], AXP_REG_T9
);
3567 newtok
[2] = newtok
[0];
3568 assemble_tokens_to_insn (mskXl_op
[lgsize
], newtok
, 3, &insn
);
3572 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3573 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BYTOFF
;
3574 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3576 insn
.sequence
= lituse
;
3581 /* emit "or $t9, $t10, $t9" */
3583 set_tok_reg (newtok
[1], AXP_REG_T10
);
3584 assemble_tokens ("or", newtok
, 3, 1);
3586 /* emit "stq_u $t9, 0($at) */
3588 set_tok_const(newtok
[1], 0);
3589 set_tok_preg (newtok
[2], AXP_REG_AT
);
3590 assemble_tokens_to_insn ("stq_u", newtok
, 3, &insn
);
3594 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3595 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BASE
;
3596 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3598 insn
.sequence
= lituse
;
3605 /* Store an integer to an unaligned address. */
3608 emit_ustX (tok
, ntok
, vlgsize
)
3609 const expressionS
*tok
;
3613 int lgsize
= (int) (long) vlgsize
;
3614 expressionS newtok
[3];
3616 /* emit "lda $at, exp" */
3618 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
3619 newtok
[0].X_add_number
= AXP_REG_AT
;
3620 assemble_tokens ("lda", newtok
, ntok
, 1);
3622 /* emit "ldq_u $9, 0($at)" */
3624 set_tok_reg (newtok
[0], AXP_REG_T9
);
3625 set_tok_const (newtok
[1], 0);
3626 set_tok_preg (newtok
[2], AXP_REG_AT
);
3627 assemble_tokens ("ldq_u", newtok
, 3, 1);
3629 /* emit "ldq_u $10, size-1($at)" */
3631 set_tok_reg (newtok
[0], AXP_REG_T10
);
3632 set_tok_const (newtok
[1], (1 << lgsize
) - 1);
3633 assemble_tokens ("ldq_u", newtok
, 3, 1);
3635 /* emit "insXl src, $at, $t11" */
3638 set_tok_reg (newtok
[1], AXP_REG_AT
);
3639 set_tok_reg (newtok
[2], AXP_REG_T11
);
3640 assemble_tokens (insXl_op
[lgsize
], newtok
, 3, 1);
3642 /* emit "insXh src, $at, $t12" */
3644 set_tok_reg (newtok
[2], AXP_REG_T12
);
3645 assemble_tokens (insXh_op
[lgsize
], newtok
, 3, 1);
3647 /* emit "mskXl $t9, $at, $t9" */
3649 set_tok_reg (newtok
[0], AXP_REG_T9
);
3650 newtok
[2] = newtok
[0];
3651 assemble_tokens (mskXl_op
[lgsize
], newtok
, 3, 1);
3653 /* emit "mskXh $t10, $at, $t10" */
3655 set_tok_reg (newtok
[0], AXP_REG_T10
);
3656 newtok
[2] = newtok
[0];
3657 assemble_tokens (mskXh_op
[lgsize
], newtok
, 3, 1);
3659 /* emit "or $t9, $t11, $t9" */
3661 set_tok_reg (newtok
[0], AXP_REG_T9
);
3662 set_tok_reg (newtok
[1], AXP_REG_T11
);
3663 newtok
[2] = newtok
[0];
3664 assemble_tokens ("or", newtok
, 3, 1);
3666 /* emit "or $t10, $t12, $t10" */
3668 set_tok_reg (newtok
[0], AXP_REG_T10
);
3669 set_tok_reg (newtok
[1], AXP_REG_T12
);
3670 newtok
[2] = newtok
[0];
3671 assemble_tokens ("or", newtok
, 3, 1);
3673 /* emit "stq_u $t9, 0($at)" */
3675 set_tok_reg (newtok
[0], AXP_REG_T9
);
3676 set_tok_const (newtok
[1], 0);
3677 set_tok_preg (newtok
[2], AXP_REG_AT
);
3678 assemble_tokens ("stq_u", newtok
, 3, 1);
3680 /* emit "stq_u $t10, size-1($at)" */
3682 set_tok_reg (newtok
[0], AXP_REG_T10
);
3683 set_tok_const (newtok
[1], (1 << lgsize
) - 1);
3684 assemble_tokens ("stq_u", newtok
, 3, 1);
3687 /* Sign extend a half-word or byte. The 32-bit sign extend is
3688 implemented as "addl $31, $r, $t" in the opcode table. */
3691 emit_sextX (tok
, ntok
, vlgsize
)
3692 const expressionS
*tok
;
3696 long lgsize
= (long) vlgsize
;
3698 if (alpha_target
& AXP_OPCODE_BWX
)
3699 assemble_tokens (sextX_op
[lgsize
], tok
, ntok
, 0);
3702 int bitshift
= 64 - 8 * (1 << lgsize
);
3703 expressionS newtok
[3];
3705 /* emit "sll src,bits,dst" */
3708 set_tok_const (newtok
[1], bitshift
);
3709 newtok
[2] = tok
[ntok
- 1];
3710 assemble_tokens ("sll", newtok
, 3, 1);
3712 /* emit "sra dst,bits,dst" */
3714 newtok
[0] = newtok
[2];
3715 assemble_tokens ("sra", newtok
, 3, 1);
3719 /* Implement the division and modulus macros. */
3723 /* Make register usage like in normal procedure call.
3724 Don't clobber PV and RA. */
3727 emit_division (tok
, ntok
, symname
)
3728 const expressionS
*tok
;
3732 /* DIVISION and MODULUS. Yech.
3737 * mov x,R16 # if x != R16
3738 * mov y,R17 # if y != R17
3743 * with appropriate optimizations if R0,R16,R17 are the registers
3744 * specified by the compiler.
3749 expressionS newtok
[3];
3751 xr
= regno (tok
[0].X_add_number
);
3752 yr
= regno (tok
[1].X_add_number
);
3757 rr
= regno (tok
[2].X_add_number
);
3759 /* Move the operands into the right place */
3760 if (yr
== AXP_REG_R16
&& xr
== AXP_REG_R17
)
3762 /* They are in exactly the wrong order -- swap through AT */
3765 as_bad (_("macro requires $at register while noat in effect"));
3767 set_tok_reg (newtok
[0], AXP_REG_R16
);
3768 set_tok_reg (newtok
[1], AXP_REG_AT
);
3769 assemble_tokens ("mov", newtok
, 2, 1);
3771 set_tok_reg (newtok
[0], AXP_REG_R17
);
3772 set_tok_reg (newtok
[1], AXP_REG_R16
);
3773 assemble_tokens ("mov", newtok
, 2, 1);
3775 set_tok_reg (newtok
[0], AXP_REG_AT
);
3776 set_tok_reg (newtok
[1], AXP_REG_R17
);
3777 assemble_tokens ("mov", newtok
, 2, 1);
3781 if (yr
== AXP_REG_R16
)
3783 set_tok_reg (newtok
[0], AXP_REG_R16
);
3784 set_tok_reg (newtok
[1], AXP_REG_R17
);
3785 assemble_tokens ("mov", newtok
, 2, 1);
3788 if (xr
!= AXP_REG_R16
)
3790 set_tok_reg (newtok
[0], xr
);
3791 set_tok_reg (newtok
[1], AXP_REG_R16
);
3792 assemble_tokens ("mov", newtok
, 2, 1);
3795 if (yr
!= AXP_REG_R16
&& yr
!= AXP_REG_R17
)
3797 set_tok_reg (newtok
[0], yr
);
3798 set_tok_reg (newtok
[1], AXP_REG_R17
);
3799 assemble_tokens ("mov", newtok
, 2, 1);
3803 sym
= symbol_find_or_make ((const char *) symname
);
3805 set_tok_reg (newtok
[0], AXP_REG_AT
);
3806 set_tok_sym (newtok
[1], sym
, 0);
3807 assemble_tokens ("lda", newtok
, 2, 1);
3809 /* Call the division routine */
3810 set_tok_reg (newtok
[0], AXP_REG_AT
);
3811 set_tok_cpreg (newtok
[1], AXP_REG_AT
);
3812 set_tok_const (newtok
[2], 0);
3813 assemble_tokens ("jsr", newtok
, 3, 1);
3815 /* Move the result to the right place */
3816 if (rr
!= AXP_REG_R0
)
3818 set_tok_reg (newtok
[0], AXP_REG_R0
);
3819 set_tok_reg (newtok
[1], rr
);
3820 assemble_tokens ("mov", newtok
, 2, 1);
3824 #else /* !OBJ_EVAX */
3827 emit_division (tok
, ntok
, symname
)
3828 const expressionS
*tok
;
3832 /* DIVISION and MODULUS. Yech.
3842 * with appropriate optimizations if t10,t11,t12 are the registers
3843 * specified by the compiler.
3848 expressionS newtok
[3];
3850 xr
= regno (tok
[0].X_add_number
);
3851 yr
= regno (tok
[1].X_add_number
);
3856 rr
= regno (tok
[2].X_add_number
);
3858 sym
= symbol_find_or_make ((const char *) symname
);
3860 /* Move the operands into the right place */
3861 if (yr
== AXP_REG_T10
&& xr
== AXP_REG_T11
)
3863 /* They are in exactly the wrong order -- swap through AT */
3866 as_bad (_("macro requires $at register while noat in effect"));
3868 set_tok_reg (newtok
[0], AXP_REG_T10
);
3869 set_tok_reg (newtok
[1], AXP_REG_AT
);
3870 assemble_tokens ("mov", newtok
, 2, 1);
3872 set_tok_reg (newtok
[0], AXP_REG_T11
);
3873 set_tok_reg (newtok
[1], AXP_REG_T10
);
3874 assemble_tokens ("mov", newtok
, 2, 1);
3876 set_tok_reg (newtok
[0], AXP_REG_AT
);
3877 set_tok_reg (newtok
[1], AXP_REG_T11
);
3878 assemble_tokens ("mov", newtok
, 2, 1);
3882 if (yr
== AXP_REG_T10
)
3884 set_tok_reg (newtok
[0], AXP_REG_T10
);
3885 set_tok_reg (newtok
[1], AXP_REG_T11
);
3886 assemble_tokens ("mov", newtok
, 2, 1);
3889 if (xr
!= AXP_REG_T10
)
3891 set_tok_reg (newtok
[0], xr
);
3892 set_tok_reg (newtok
[1], AXP_REG_T10
);
3893 assemble_tokens ("mov", newtok
, 2, 1);
3896 if (yr
!= AXP_REG_T10
&& yr
!= AXP_REG_T11
)
3898 set_tok_reg (newtok
[0], yr
);
3899 set_tok_reg (newtok
[1], AXP_REG_T11
);
3900 assemble_tokens ("mov", newtok
, 2, 1);
3904 /* Call the division routine */
3905 set_tok_reg (newtok
[0], AXP_REG_T9
);
3906 set_tok_sym (newtok
[1], sym
, 0);
3907 assemble_tokens ("jsr", newtok
, 2, 1);
3909 /* Reload the GP register */
3913 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
3914 set_tok_reg (newtok
[0], alpha_gp_register
);
3915 set_tok_const (newtok
[1], 0);
3916 set_tok_preg (newtok
[2], AXP_REG_T9
);
3917 assemble_tokens ("ldgp", newtok
, 3, 1);
3920 /* Move the result to the right place */
3921 if (rr
!= AXP_REG_T12
)
3923 set_tok_reg (newtok
[0], AXP_REG_T12
);
3924 set_tok_reg (newtok
[1], rr
);
3925 assemble_tokens ("mov", newtok
, 2, 1);
3929 #endif /* !OBJ_EVAX */
3931 /* The jsr and jmp macros differ from their instruction counterparts
3932 in that they can load the target address and default most
3936 emit_jsrjmp (tok
, ntok
, vopname
)
3937 const expressionS
*tok
;
3941 const char *opname
= (const char *) vopname
;
3942 struct alpha_insn insn
;
3943 expressionS newtok
[3];
3947 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_register
)
3948 r
= regno (tok
[tokidx
++].X_add_number
);
3950 r
= strcmp (opname
, "jmp") == 0 ? AXP_REG_ZERO
: AXP_REG_RA
;
3952 set_tok_reg (newtok
[0], r
);
3954 if (tokidx
< ntok
&&
3955 (tok
[tokidx
].X_op
== O_pregister
|| tok
[tokidx
].X_op
== O_cpregister
))
3956 r
= regno (tok
[tokidx
++].X_add_number
);
3958 /* keep register if jsr $n.<sym> */
3962 int basereg
= alpha_gp_register
;
3963 lituse
= load_expression (r
= AXP_REG_PV
, &tok
[tokidx
], &basereg
, NULL
);
3967 set_tok_cpreg (newtok
[1], r
);
3970 /* FIXME: Add hint relocs to BFD for evax. */
3973 newtok
[2] = tok
[tokidx
];
3976 set_tok_const (newtok
[2], 0);
3978 assemble_tokens_to_insn (opname
, newtok
, 3, &insn
);
3982 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3983 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_JSR
;
3984 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3986 insn
.sequence
= lituse
;
3992 /* The ret and jcr instructions differ from their instruction
3993 counterparts in that everything can be defaulted. */
3996 emit_retjcr (tok
, ntok
, vopname
)
3997 const expressionS
*tok
;
4001 const char *opname
= (const char *) vopname
;
4002 expressionS newtok
[3];
4005 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_register
)
4006 r
= regno (tok
[tokidx
++].X_add_number
);
4010 set_tok_reg (newtok
[0], r
);
4012 if (tokidx
< ntok
&&
4013 (tok
[tokidx
].X_op
== O_pregister
|| tok
[tokidx
].X_op
== O_cpregister
))
4014 r
= regno (tok
[tokidx
++].X_add_number
);
4018 set_tok_cpreg (newtok
[1], r
);
4021 newtok
[2] = tok
[tokidx
];
4023 set_tok_const (newtok
[2], strcmp (opname
, "ret") == 0);
4025 assemble_tokens (opname
, newtok
, 3, 0);
4028 /* Assembler directives */
4030 /* Handle the .text pseudo-op. This is like the usual one, but it
4031 clears alpha_insn_label and restores auto alignment. */
4043 alpha_insn_label
= NULL
;
4044 alpha_auto_align_on
= 1;
4045 alpha_current_align
= 0;
4048 /* Handle the .data pseudo-op. This is like the usual one, but it
4049 clears alpha_insn_label and restores auto alignment. */
4060 alpha_insn_label
= NULL
;
4061 alpha_auto_align_on
= 1;
4062 alpha_current_align
= 0;
4065 #if defined (OBJ_ECOFF) || defined (OBJ_EVAX)
4067 /* Handle the OSF/1 and openVMS .comm pseudo quirks.
4068 openVMS constructs a section for every common symbol. */
4071 s_alpha_comm (ignore
)
4074 register char *name
;
4078 register symbolS
*symbolP
;
4081 segT current_section
= now_seg
;
4082 int current_subsec
= now_subseg
;
4086 name
= input_line_pointer
;
4087 c
= get_symbol_end ();
4089 /* just after name is now '\0' */
4090 p
= input_line_pointer
;
4095 /* Alpha OSF/1 compiler doesn't provide the comma, gcc does. */
4096 if (*input_line_pointer
== ',')
4098 input_line_pointer
++;
4101 if ((temp
= get_absolute_expression ()) < 0)
4103 as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) temp
);
4104 ignore_rest_of_line ();
4109 symbolP
= symbol_find_or_make (name
);
4112 /* Make a section for the common symbol. */
4113 new_seg
= subseg_new (xstrdup (name
), 0);
4119 /* alignment might follow */
4120 if (*input_line_pointer
== ',')
4124 input_line_pointer
++;
4125 align
= get_absolute_expression ();
4126 bfd_set_section_alignment (stdoutput
, new_seg
, align
);
4130 if (S_IS_DEFINED (symbolP
) && ! S_IS_COMMON (symbolP
))
4132 as_bad (_("Ignoring attempt to re-define symbol"));
4133 ignore_rest_of_line ();
4138 if (bfd_section_size (stdoutput
, new_seg
) > 0)
4140 if (bfd_section_size (stdoutput
, new_seg
) != temp
)
4141 as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
4142 S_GET_NAME (symbolP
),
4143 (long) bfd_section_size (stdoutput
, new_seg
),
4147 if (S_GET_VALUE (symbolP
))
4149 if (S_GET_VALUE (symbolP
) != (valueT
) temp
)
4150 as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
4151 S_GET_NAME (symbolP
),
4152 (long) S_GET_VALUE (symbolP
),
4159 subseg_set (new_seg
, 0);
4160 p
= frag_more (temp
);
4161 new_seg
->flags
|= SEC_IS_COMMON
;
4162 if (! S_IS_DEFINED (symbolP
))
4163 S_SET_SEGMENT (symbolP
, new_seg
);
4165 S_SET_VALUE (symbolP
, (valueT
) temp
);
4167 S_SET_EXTERNAL (symbolP
);
4171 subseg_set (current_section
, current_subsec
);
4174 know (symbol_get_frag (symbolP
) == &zero_address_frag
);
4176 demand_empty_rest_of_line ();
4179 #endif /* ! OBJ_ELF */
4183 /* Handle the .rdata pseudo-op. This is like the usual one, but it
4184 clears alpha_insn_label and restores auto alignment. */
4187 s_alpha_rdata (ignore
)
4192 temp
= get_absolute_expression ();
4193 subseg_new (".rdata", 0);
4194 demand_empty_rest_of_line ();
4195 alpha_insn_label
= NULL
;
4196 alpha_auto_align_on
= 1;
4197 alpha_current_align
= 0;
4204 /* Handle the .sdata pseudo-op. This is like the usual one, but it
4205 clears alpha_insn_label and restores auto alignment. */
4208 s_alpha_sdata (ignore
)
4213 temp
= get_absolute_expression ();
4214 subseg_new (".sdata", 0);
4215 demand_empty_rest_of_line ();
4216 alpha_insn_label
= NULL
;
4217 alpha_auto_align_on
= 1;
4218 alpha_current_align
= 0;
4224 /* Handle the .section pseudo-op. This is like the usual one, but it
4225 clears alpha_insn_label and restores auto alignment. */
4228 s_alpha_section (ignore
)
4231 obj_elf_section (ignore
);
4233 alpha_insn_label
= NULL
;
4234 alpha_auto_align_on
= 1;
4235 alpha_current_align
= 0;
4240 int dummy ATTRIBUTE_UNUSED
;
4242 if (ECOFF_DEBUGGING
)
4243 ecoff_directive_ent (0);
4246 char *name
, name_end
;
4247 name
= input_line_pointer
;
4248 name_end
= get_symbol_end ();
4250 if (! is_name_beginner (*name
))
4252 as_warn (_(".ent directive has no name"));
4253 *input_line_pointer
= name_end
;
4259 if (alpha_cur_ent_sym
)
4260 as_warn (_("nested .ent directives"));
4262 sym
= symbol_find_or_make (name
);
4263 symbol_get_bfdsym (sym
)->flags
|= BSF_FUNCTION
;
4264 alpha_cur_ent_sym
= sym
;
4266 /* The .ent directive is sometimes followed by a number. Not sure
4267 what it really means, but ignore it. */
4268 *input_line_pointer
= name_end
;
4270 if (*input_line_pointer
== ',')
4272 input_line_pointer
++;
4275 if (ISDIGIT (*input_line_pointer
) || *input_line_pointer
== '-')
4276 (void) get_absolute_expression ();
4278 demand_empty_rest_of_line ();
4284 int dummy ATTRIBUTE_UNUSED
;
4286 if (ECOFF_DEBUGGING
)
4287 ecoff_directive_end (0);
4290 char *name
, name_end
;
4291 name
= input_line_pointer
;
4292 name_end
= get_symbol_end ();
4294 if (! is_name_beginner (*name
))
4296 as_warn (_(".end directive has no name"));
4297 *input_line_pointer
= name_end
;
4303 sym
= symbol_find (name
);
4304 if (sym
!= alpha_cur_ent_sym
)
4305 as_warn (_(".end directive names different symbol than .ent"));
4307 /* Create an expression to calculate the size of the function. */
4310 symbol_get_obj (sym
)->size
=
4311 (expressionS
*) xmalloc (sizeof (expressionS
));
4312 symbol_get_obj (sym
)->size
->X_op
= O_subtract
;
4313 symbol_get_obj (sym
)->size
->X_add_symbol
4314 = symbol_new ("L0\001", now_seg
, frag_now_fix (), frag_now
);
4315 symbol_get_obj (sym
)->size
->X_op_symbol
= sym
;
4316 symbol_get_obj (sym
)->size
->X_add_number
= 0;
4319 alpha_cur_ent_sym
= NULL
;
4321 *input_line_pointer
= name_end
;
4323 demand_empty_rest_of_line ();
4331 if (ECOFF_DEBUGGING
)
4334 ecoff_directive_fmask (0);
4336 ecoff_directive_mask (0);
4339 discard_rest_of_line ();
4343 s_alpha_frame (dummy
)
4344 int dummy ATTRIBUTE_UNUSED
;
4346 if (ECOFF_DEBUGGING
)
4347 ecoff_directive_frame (0);
4349 discard_rest_of_line ();
4353 s_alpha_prologue (ignore
)
4354 int ignore ATTRIBUTE_UNUSED
;
4359 arg
= get_absolute_expression ();
4360 demand_empty_rest_of_line ();
4362 if (ECOFF_DEBUGGING
)
4363 sym
= ecoff_get_cur_proc_sym ();
4365 sym
= alpha_cur_ent_sym
;
4370 case 0: /* No PV required. */
4371 S_SET_OTHER (sym
, STO_ALPHA_NOPV
4372 | (S_GET_OTHER (sym
) & ~STO_ALPHA_STD_GPLOAD
));
4374 case 1: /* Std GP load. */
4375 S_SET_OTHER (sym
, STO_ALPHA_STD_GPLOAD
4376 | (S_GET_OTHER (sym
) & ~STO_ALPHA_STD_GPLOAD
));
4378 case 2: /* Non-std use of PV. */
4382 as_bad (_("Invalid argument %d to .prologue."), arg
);
4387 static char *first_file_directive
;
4390 s_alpha_file (ignore
)
4391 int ignore ATTRIBUTE_UNUSED
;
4393 /* Save the first .file directive we see, so that we can change our
4394 minds about whether ecoff debugging should or shouldn't be enabled. */
4395 if (alpha_flag_mdebug
< 0 && ! first_file_directive
)
4397 char *start
= input_line_pointer
;
4400 discard_rest_of_line ();
4402 len
= input_line_pointer
- start
;
4403 first_file_directive
= xmalloc (len
+ 1);
4404 memcpy (first_file_directive
, start
, len
);
4405 first_file_directive
[len
] = '\0';
4407 input_line_pointer
= start
;
4410 if (ECOFF_DEBUGGING
)
4411 ecoff_directive_file (0);
4413 dwarf2_directive_file (0);
4417 s_alpha_loc (ignore
)
4418 int ignore ATTRIBUTE_UNUSED
;
4420 if (ECOFF_DEBUGGING
)
4421 ecoff_directive_loc (0);
4423 dwarf2_directive_loc (0);
4430 /* If we've been undecided about mdebug, make up our minds in favour. */
4431 if (alpha_flag_mdebug
< 0)
4433 segT sec
= subseg_new (".mdebug", 0);
4434 bfd_set_section_flags (stdoutput
, sec
, SEC_HAS_CONTENTS
| SEC_READONLY
);
4435 bfd_set_section_alignment (stdoutput
, sec
, 3);
4437 ecoff_read_begin_hook ();
4439 if (first_file_directive
)
4441 char *save_ilp
= input_line_pointer
;
4442 input_line_pointer
= first_file_directive
;
4443 ecoff_directive_file (0);
4444 input_line_pointer
= save_ilp
;
4445 free (first_file_directive
);
4448 alpha_flag_mdebug
= 1;
4454 s_alpha_coff_wrapper (which
)
4457 static void (* const fns
[]) PARAMS ((int)) = {
4458 ecoff_directive_begin
,
4459 ecoff_directive_bend
,
4460 ecoff_directive_def
,
4461 ecoff_directive_dim
,
4462 ecoff_directive_endef
,
4463 ecoff_directive_scl
,
4464 ecoff_directive_tag
,
4465 ecoff_directive_val
,
4468 assert (which
>= 0 && which
< (int) (sizeof (fns
)/sizeof (*fns
)));
4470 if (ECOFF_DEBUGGING
)
4474 as_bad (_("ECOFF debugging is disabled."));
4475 ignore_rest_of_line ();
4478 #endif /* OBJ_ELF */
4482 /* Handle the section specific pseudo-op. */
4485 s_alpha_section (secid
)
4489 #define EVAX_SECTION_COUNT 5
4490 static char *section_name
[EVAX_SECTION_COUNT
+ 1] =
4491 { "NULL", ".rdata", ".comm", ".link", ".ctors", ".dtors" };
4493 if ((secid
<= 0) || (secid
> EVAX_SECTION_COUNT
))
4495 as_fatal (_("Unknown section directive"));
4496 demand_empty_rest_of_line ();
4499 temp
= get_absolute_expression ();
4500 subseg_new (section_name
[secid
], 0);
4501 demand_empty_rest_of_line ();
4502 alpha_insn_label
= NULL
;
4503 alpha_auto_align_on
= 1;
4504 alpha_current_align
= 0;
4507 /* Parse .ent directives. */
4510 s_alpha_ent (ignore
)
4514 expressionS symexpr
;
4516 alpha_evax_proc
.pdsckind
= 0;
4517 alpha_evax_proc
.framereg
= -1;
4518 alpha_evax_proc
.framesize
= 0;
4519 alpha_evax_proc
.rsa_offset
= 0;
4520 alpha_evax_proc
.ra_save
= AXP_REG_RA
;
4521 alpha_evax_proc
.fp_save
= -1;
4522 alpha_evax_proc
.imask
= 0;
4523 alpha_evax_proc
.fmask
= 0;
4524 alpha_evax_proc
.prologue
= 0;
4525 alpha_evax_proc
.type
= 0;
4527 expression (&symexpr
);
4529 if (symexpr
.X_op
!= O_symbol
)
4531 as_fatal (_(".ent directive has no symbol"));
4532 demand_empty_rest_of_line ();
4536 symbol
= make_expr_symbol (&symexpr
);
4537 symbol_get_bfdsym (symbol
)->flags
|= BSF_FUNCTION
;
4538 alpha_evax_proc
.symbol
= symbol
;
4540 demand_empty_rest_of_line ();
4544 /* Parse .frame <framreg>,<framesize>,RA,<rsa_offset> directives. */
4547 s_alpha_frame (ignore
)
4552 alpha_evax_proc
.framereg
= tc_get_register (1);
4555 if (*input_line_pointer
++ != ','
4556 || get_absolute_expression_and_terminator (&val
) != ',')
4558 as_warn (_("Bad .frame directive 1./2. param"));
4559 --input_line_pointer
;
4560 demand_empty_rest_of_line ();
4564 alpha_evax_proc
.framesize
= val
;
4566 (void) tc_get_register (1);
4568 if (*input_line_pointer
++ != ',')
4570 as_warn (_("Bad .frame directive 3./4. param"));
4571 --input_line_pointer
;
4572 demand_empty_rest_of_line ();
4575 alpha_evax_proc
.rsa_offset
= get_absolute_expression ();
4581 s_alpha_pdesc (ignore
)
4591 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
4593 if (now_seg
!= alpha_link_section
)
4595 as_bad (_(".pdesc directive not in link (.link) section"));
4596 demand_empty_rest_of_line ();
4600 if ((alpha_evax_proc
.symbol
== 0)
4601 || (!S_IS_DEFINED (alpha_evax_proc
.symbol
)))
4603 as_fatal (_(".pdesc has no matching .ent"));
4604 demand_empty_rest_of_line ();
4608 *symbol_get_obj (alpha_evax_proc
.symbol
) =
4609 (valueT
) seginfo
->literal_pool_size
;
4612 if (exp
.X_op
!= O_symbol
)
4614 as_warn (_(".pdesc directive has no entry symbol"));
4615 demand_empty_rest_of_line ();
4619 entry_sym
= make_expr_symbol (&exp
);
4620 /* Save bfd symbol of proc desc in function symbol. */
4621 symbol_get_bfdsym (alpha_evax_proc
.symbol
)->udata
.p
4622 = symbol_get_bfdsym (entry_sym
);
4625 if (*input_line_pointer
++ != ',')
4627 as_warn (_("No comma after .pdesc <entryname>"));
4628 demand_empty_rest_of_line ();
4633 name
= input_line_pointer
;
4634 name_end
= get_symbol_end ();
4636 if (strncmp (name
, "stack", 5) == 0)
4638 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_FP_STACK
;
4640 else if (strncmp (name
, "reg", 3) == 0)
4642 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_FP_REGISTER
;
4644 else if (strncmp (name
, "null", 4) == 0)
4646 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_NULL
;
4650 as_fatal (_("unknown procedure kind"));
4651 demand_empty_rest_of_line ();
4655 *input_line_pointer
= name_end
;
4656 demand_empty_rest_of_line ();
4658 #ifdef md_flush_pending_output
4659 md_flush_pending_output ();
4662 frag_align (3, 0, 0);
4664 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
4666 seginfo
->literal_pool_size
+= 16;
4668 *p
= alpha_evax_proc
.pdsckind
4669 | ((alpha_evax_proc
.framereg
== 29) ? PDSC_S_M_BASE_REG_IS_FP
: 0);
4670 *(p
+ 1) = PDSC_S_M_NATIVE
| PDSC_S_M_NO_JACKET
;
4672 switch (alpha_evax_proc
.pdsckind
)
4674 case PDSC_S_K_KIND_NULL
:
4678 case PDSC_S_K_KIND_FP_REGISTER
:
4679 *(p
+ 2) = alpha_evax_proc
.fp_save
;
4680 *(p
+ 3) = alpha_evax_proc
.ra_save
;
4682 case PDSC_S_K_KIND_FP_STACK
:
4683 md_number_to_chars (p
+ 2, (valueT
) alpha_evax_proc
.rsa_offset
, 2);
4685 default: /* impossible */
4690 *(p
+ 5) = alpha_evax_proc
.type
& 0x0f;
4692 /* Signature offset. */
4693 md_number_to_chars (p
+ 6, (valueT
) 0, 2);
4695 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
+8, 8, &exp
, 0, BFD_RELOC_64
);
4697 if (alpha_evax_proc
.pdsckind
== PDSC_S_K_KIND_NULL
)
4700 /* Add dummy fix to make add_to_link_pool work. */
4702 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
4704 seginfo
->literal_pool_size
+= 8;
4706 /* pdesc+16: Size. */
4707 md_number_to_chars (p
, (valueT
) alpha_evax_proc
.framesize
, 4);
4709 md_number_to_chars (p
+ 4, (valueT
) 0, 2);
4712 md_number_to_chars (p
+ 6, alpha_evax_proc
.prologue
, 2);
4714 if (alpha_evax_proc
.pdsckind
== PDSC_S_K_KIND_FP_REGISTER
)
4717 /* Add dummy fix to make add_to_link_pool work. */
4719 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
4721 seginfo
->literal_pool_size
+= 8;
4723 /* pdesc+24: register masks. */
4725 md_number_to_chars (p
, alpha_evax_proc
.imask
, 4);
4726 md_number_to_chars (p
+ 4, alpha_evax_proc
.fmask
, 4);
4731 /* Support for crash debug on vms. */
4734 s_alpha_name (ignore
)
4739 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
4741 if (now_seg
!= alpha_link_section
)
4743 as_bad (_(".name directive not in link (.link) section"));
4744 demand_empty_rest_of_line ();
4749 if (exp
.X_op
!= O_symbol
)
4751 as_warn (_(".name directive has no symbol"));
4752 demand_empty_rest_of_line ();
4756 demand_empty_rest_of_line ();
4758 #ifdef md_flush_pending_output
4759 md_flush_pending_output ();
4762 frag_align (3, 0, 0);
4764 seginfo
->literal_pool_size
+= 8;
4766 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 8, &exp
, 0, BFD_RELOC_64
);
4772 s_alpha_linkage (ignore
)
4778 #ifdef md_flush_pending_output
4779 md_flush_pending_output ();
4783 if (exp
.X_op
!= O_symbol
)
4785 as_fatal (_("No symbol after .linkage"));
4789 p
= frag_more (LKP_S_K_SIZE
);
4790 memset (p
, 0, LKP_S_K_SIZE
);
4791 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, LKP_S_K_SIZE
, &exp
, 0,\
4792 BFD_RELOC_ALPHA_LINKAGE
);
4794 demand_empty_rest_of_line ();
4800 s_alpha_code_address (ignore
)
4806 #ifdef md_flush_pending_output
4807 md_flush_pending_output ();
4811 if (exp
.X_op
!= O_symbol
)
4813 as_fatal (_("No symbol after .code_address"));
4819 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 8, &exp
, 0,\
4820 BFD_RELOC_ALPHA_CODEADDR
);
4822 demand_empty_rest_of_line ();
4828 s_alpha_fp_save (ignore
)
4832 alpha_evax_proc
.fp_save
= tc_get_register (1);
4834 demand_empty_rest_of_line ();
4839 s_alpha_mask (ignore
)
4844 if (get_absolute_expression_and_terminator (&val
) != ',')
4846 as_warn (_("Bad .mask directive"));
4847 --input_line_pointer
;
4851 alpha_evax_proc
.imask
= val
;
4852 (void) get_absolute_expression ();
4854 demand_empty_rest_of_line ();
4860 s_alpha_fmask (ignore
)
4865 if (get_absolute_expression_and_terminator (&val
) != ',')
4867 as_warn (_("Bad .fmask directive"));
4868 --input_line_pointer
;
4872 alpha_evax_proc
.fmask
= val
;
4873 (void) get_absolute_expression ();
4875 demand_empty_rest_of_line ();
4881 s_alpha_end (ignore
)
4886 c
= get_symbol_end ();
4887 *input_line_pointer
= c
;
4888 demand_empty_rest_of_line ();
4889 alpha_evax_proc
.symbol
= 0;
4895 s_alpha_file (ignore
)
4900 static char case_hack
[32];
4902 extern char *demand_copy_string
PARAMS ((int *lenP
));
4904 sprintf (case_hack
, "<CASE:%01d%01d>",
4905 alpha_flag_hash_long_names
, alpha_flag_show_after_trunc
);
4907 s
= symbol_find_or_make (case_hack
);
4908 symbol_get_bfdsym (s
)->flags
|= BSF_FILE
;
4910 get_absolute_expression ();
4911 s
= symbol_find_or_make (demand_copy_string (&length
));
4912 symbol_get_bfdsym (s
)->flags
|= BSF_FILE
;
4913 demand_empty_rest_of_line ();
4917 #endif /* OBJ_EVAX */
4919 /* Handle the .gprel32 pseudo op. */
4922 s_alpha_gprel32 (ignore
)
4923 int ignore ATTRIBUTE_UNUSED
;
4935 e
.X_add_symbol
= section_symbol (absolute_section
);
4948 e
.X_add_symbol
= section_symbol (absolute_section
);
4951 e
.X_op
= O_subtract
;
4952 e
.X_op_symbol
= alpha_gp_symbol
;
4960 if (alpha_auto_align_on
&& alpha_current_align
< 2)
4961 alpha_align (2, (char *) NULL
, alpha_insn_label
, 0);
4962 if (alpha_current_align
> 2)
4963 alpha_current_align
= 2;
4964 alpha_insn_label
= NULL
;
4968 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 4,
4969 &e
, 0, BFD_RELOC_GPREL32
);
4972 /* Handle floating point allocation pseudo-ops. This is like the
4973 generic vresion, but it makes sure the current label, if any, is
4974 correctly aligned. */
4977 s_alpha_float_cons (type
)
5004 if (alpha_auto_align_on
&& alpha_current_align
< log_size
)
5005 alpha_align (log_size
, (char *) NULL
, alpha_insn_label
, 0);
5006 if (alpha_current_align
> log_size
)
5007 alpha_current_align
= log_size
;
5008 alpha_insn_label
= NULL
;
5013 /* Handle the .proc pseudo op. We don't really do much with it except
5017 s_alpha_proc (is_static
)
5018 int is_static ATTRIBUTE_UNUSED
;
5026 /* Takes ".proc name,nargs" */
5028 name
= input_line_pointer
;
5029 c
= get_symbol_end ();
5030 p
= input_line_pointer
;
5031 symbolP
= symbol_find_or_make (name
);
5034 if (*input_line_pointer
!= ',')
5037 as_warn (_("Expected comma after name \"%s\""), name
);
5040 ignore_rest_of_line ();
5044 input_line_pointer
++;
5045 temp
= get_absolute_expression ();
5047 /* *symbol_get_obj (symbolP) = (signed char) temp; */
5048 as_warn (_("unhandled: .proc %s,%d"), name
, temp
);
5049 demand_empty_rest_of_line ();
5052 /* Handle the .set pseudo op. This is used to turn on and off most of
5053 the assembler features. */
5057 int x ATTRIBUTE_UNUSED
;
5063 name
= input_line_pointer
;
5064 ch
= get_symbol_end ();
5067 if (s
[0] == 'n' && s
[1] == 'o')
5072 if (!strcmp ("reorder", s
))
5074 else if (!strcmp ("at", s
))
5075 alpha_noat_on
= !yesno
;
5076 else if (!strcmp ("macro", s
))
5077 alpha_macros_on
= yesno
;
5078 else if (!strcmp ("move", s
))
5080 else if (!strcmp ("volatile", s
))
5083 as_warn (_("Tried to .set unrecognized mode `%s'"), name
);
5085 *input_line_pointer
= ch
;
5086 demand_empty_rest_of_line ();
5089 /* Handle the .base pseudo op. This changes the assembler's notion of
5090 the $gp register. */
5093 s_alpha_base (ignore
)
5094 int ignore ATTRIBUTE_UNUSED
;
5097 if (first_32bit_quadrant
)
5099 /* not fatal, but it might not work in the end */
5100 as_warn (_("File overrides no-base-register option."));
5101 first_32bit_quadrant
= 0;
5106 if (*input_line_pointer
== '$')
5108 input_line_pointer
++;
5109 if (*input_line_pointer
== 'r')
5110 input_line_pointer
++;
5113 alpha_gp_register
= get_absolute_expression ();
5114 if (alpha_gp_register
< 0 || alpha_gp_register
> 31)
5116 alpha_gp_register
= AXP_REG_GP
;
5117 as_warn (_("Bad base register, using $%d."), alpha_gp_register
);
5120 demand_empty_rest_of_line ();
5123 /* Handle the .align pseudo-op. This aligns to a power of two. It
5124 also adjusts any current instruction label. We treat this the same
5125 way the MIPS port does: .align 0 turns off auto alignment. */
5128 s_alpha_align (ignore
)
5129 int ignore ATTRIBUTE_UNUSED
;
5133 long max_alignment
= 15;
5135 align
= get_absolute_expression ();
5136 if (align
> max_alignment
)
5138 align
= max_alignment
;
5139 as_bad (_("Alignment too large: %d. assumed"), align
);
5143 as_warn (_("Alignment negative: 0 assumed"));
5147 if (*input_line_pointer
== ',')
5149 input_line_pointer
++;
5150 fill
= get_absolute_expression ();
5158 alpha_auto_align_on
= 1;
5159 alpha_align (align
, pfill
, alpha_insn_label
, 1);
5163 alpha_auto_align_on
= 0;
5166 demand_empty_rest_of_line ();
5169 /* Hook the normal string processor to reset known alignment. */
5172 s_alpha_stringer (terminate
)
5175 alpha_current_align
= 0;
5176 alpha_insn_label
= NULL
;
5177 stringer (terminate
);
5180 /* Hook the normal space processing to reset known alignment. */
5183 s_alpha_space (ignore
)
5186 alpha_current_align
= 0;
5187 alpha_insn_label
= NULL
;
5191 /* Hook into cons for auto-alignment. */
5194 alpha_cons_align (size
)
5200 while ((size
>>= 1) != 0)
5203 if (alpha_auto_align_on
&& alpha_current_align
< log_size
)
5204 alpha_align (log_size
, (char *) NULL
, alpha_insn_label
, 0);
5205 if (alpha_current_align
> log_size
)
5206 alpha_current_align
= log_size
;
5207 alpha_insn_label
= NULL
;
5210 /* Here come the .uword, .ulong, and .uquad explicitly unaligned
5211 pseudos. We just turn off auto-alignment and call down to cons. */
5214 s_alpha_ucons (bytes
)
5217 int hold
= alpha_auto_align_on
;
5218 alpha_auto_align_on
= 0;
5220 alpha_auto_align_on
= hold
;
5223 /* Switch the working cpu type. */
5226 s_alpha_arch (ignored
)
5227 int ignored ATTRIBUTE_UNUSED
;
5230 const struct cpu_type
*p
;
5233 name
= input_line_pointer
;
5234 ch
= get_symbol_end ();
5236 for (p
= cpu_types
; p
->name
; ++p
)
5237 if (strcmp (name
, p
->name
) == 0)
5239 alpha_target_name
= p
->name
, alpha_target
= p
->flags
;
5242 as_warn ("Unknown CPU identifier `%s'", name
);
5245 *input_line_pointer
= ch
;
5246 demand_empty_rest_of_line ();
5250 /* print token expression with alpha specific extension. */
5253 alpha_print_token (f
, exp
)
5255 const expressionS
*exp
;
5265 expressionS nexp
= *exp
;
5266 nexp
.X_op
= O_register
;
5267 print_expr (f
, &nexp
);
5272 print_expr (f
, exp
);
5279 /* The target specific pseudo-ops which we support. */
5281 const pseudo_typeS md_pseudo_table
[] = {
5283 {"comm", s_alpha_comm
, 0}, /* osf1 compiler does this */
5284 {"rdata", s_alpha_rdata
, 0},
5286 {"text", s_alpha_text
, 0},
5287 {"data", s_alpha_data
, 0},
5289 {"sdata", s_alpha_sdata
, 0},
5292 {"section", s_alpha_section
, 0},
5293 {"section.s", s_alpha_section
, 0},
5294 {"sect", s_alpha_section
, 0},
5295 {"sect.s", s_alpha_section
, 0},
5298 { "pdesc", s_alpha_pdesc
, 0},
5299 { "name", s_alpha_name
, 0},
5300 { "linkage", s_alpha_linkage
, 0},
5301 { "code_address", s_alpha_code_address
, 0},
5302 { "ent", s_alpha_ent
, 0},
5303 { "frame", s_alpha_frame
, 0},
5304 { "fp_save", s_alpha_fp_save
, 0},
5305 { "mask", s_alpha_mask
, 0},
5306 { "fmask", s_alpha_fmask
, 0},
5307 { "end", s_alpha_end
, 0},
5308 { "file", s_alpha_file
, 0},
5309 { "rdata", s_alpha_section
, 1},
5310 { "comm", s_alpha_comm
, 0},
5311 { "link", s_alpha_section
, 3},
5312 { "ctors", s_alpha_section
, 4},
5313 { "dtors", s_alpha_section
, 5},
5316 /* Frame related pseudos. */
5317 {"ent", s_alpha_ent
, 0},
5318 {"end", s_alpha_end
, 0},
5319 {"mask", s_alpha_mask
, 0},
5320 {"fmask", s_alpha_mask
, 1},
5321 {"frame", s_alpha_frame
, 0},
5322 {"prologue", s_alpha_prologue
, 0},
5323 {"file", s_alpha_file
, 5},
5324 {"loc", s_alpha_loc
, 9},
5325 {"stabs", s_alpha_stab
, 's'},
5326 {"stabn", s_alpha_stab
, 'n'},
5327 /* COFF debugging related pseudos. */
5328 {"begin", s_alpha_coff_wrapper
, 0},
5329 {"bend", s_alpha_coff_wrapper
, 1},
5330 {"def", s_alpha_coff_wrapper
, 2},
5331 {"dim", s_alpha_coff_wrapper
, 3},
5332 {"endef", s_alpha_coff_wrapper
, 4},
5333 {"scl", s_alpha_coff_wrapper
, 5},
5334 {"tag", s_alpha_coff_wrapper
, 6},
5335 {"val", s_alpha_coff_wrapper
, 7},
5337 {"prologue", s_ignore
, 0},
5339 {"gprel32", s_alpha_gprel32
, 0},
5340 {"t_floating", s_alpha_float_cons
, 'd'},
5341 {"s_floating", s_alpha_float_cons
, 'f'},
5342 {"f_floating", s_alpha_float_cons
, 'F'},
5343 {"g_floating", s_alpha_float_cons
, 'G'},
5344 {"d_floating", s_alpha_float_cons
, 'D'},
5346 {"proc", s_alpha_proc
, 0},
5347 {"aproc", s_alpha_proc
, 1},
5348 {"set", s_alpha_set
, 0},
5349 {"reguse", s_ignore
, 0},
5350 {"livereg", s_ignore
, 0},
5351 {"base", s_alpha_base
, 0}, /*??*/
5352 {"option", s_ignore
, 0},
5353 {"aent", s_ignore
, 0},
5354 {"ugen", s_ignore
, 0},
5355 {"eflag", s_ignore
, 0},
5357 {"align", s_alpha_align
, 0},
5358 {"double", s_alpha_float_cons
, 'd'},
5359 {"float", s_alpha_float_cons
, 'f'},
5360 {"single", s_alpha_float_cons
, 'f'},
5361 {"ascii", s_alpha_stringer
, 0},
5362 {"asciz", s_alpha_stringer
, 1},
5363 {"string", s_alpha_stringer
, 1},
5364 {"space", s_alpha_space
, 0},
5365 {"skip", s_alpha_space
, 0},
5366 {"zero", s_alpha_space
, 0},
5368 /* Unaligned data pseudos. */
5369 {"uword", s_alpha_ucons
, 2},
5370 {"ulong", s_alpha_ucons
, 4},
5371 {"uquad", s_alpha_ucons
, 8},
5374 /* Dwarf wants these versions of unaligned. */
5375 {"2byte", s_alpha_ucons
, 2},
5376 {"4byte", s_alpha_ucons
, 4},
5377 {"8byte", s_alpha_ucons
, 8},
5380 /* We don't do any optimizing, so we can safely ignore these. */
5381 {"noalias", s_ignore
, 0},
5382 {"alias", s_ignore
, 0},
5384 {"arch", s_alpha_arch
, 0},
5389 /* Build a BFD section with its flags set appropriately for the .lita,
5390 .lit8, or .lit4 sections. */
5393 create_literal_section (name
, secp
, symp
)
5398 segT current_section
= now_seg
;
5399 int current_subsec
= now_subseg
;
5402 *secp
= new_sec
= subseg_new (name
, 0);
5403 subseg_set (current_section
, current_subsec
);
5404 bfd_set_section_alignment (stdoutput
, new_sec
, 4);
5405 bfd_set_section_flags (stdoutput
, new_sec
,
5406 SEC_RELOC
| SEC_ALLOC
| SEC_LOAD
| SEC_READONLY
5409 S_CLEAR_EXTERNAL (*symp
= section_symbol (new_sec
));
5414 /* @@@ GP selection voodoo. All of this seems overly complicated and
5415 unnecessary; which is the primary reason it's for ECOFF only. */
5424 vma
= bfd_get_section_vma (foo
, sec
);
5425 if (vma
&& vma
< alpha_gp_value
)
5426 alpha_gp_value
= vma
;
5432 assert (alpha_gp_value
== 0);
5434 /* Get minus-one in whatever width... */
5438 /* Select the smallest VMA of these existing sections. */
5439 maybe_set_gp (alpha_lita_section
);
5441 /* These were disabled before -- should we use them? */
5442 maybe_set_gp (sdata
);
5443 maybe_set_gp (lit8_sec
);
5444 maybe_set_gp (lit4_sec
);
5447 /* @@ Will a simple 0x8000 work here? If not, why not? */
5448 #define GP_ADJUSTMENT (0x8000 - 0x10)
5450 alpha_gp_value
+= GP_ADJUSTMENT
;
5452 S_SET_VALUE (alpha_gp_symbol
, alpha_gp_value
);
5455 printf (_("Chose GP value of %lx\n"), alpha_gp_value
);
5458 #endif /* OBJ_ECOFF */
5461 /* Map 's' to SHF_ALPHA_GPREL. */
5464 alpha_elf_section_letter (letter
, ptr_msg
)
5469 return SHF_ALPHA_GPREL
;
5471 *ptr_msg
= _("Bad .section directive: want a,s,w,x,M,S,G,T in string");
5475 /* Map SHF_ALPHA_GPREL to SEC_SMALL_DATA. */
5478 alpha_elf_section_flags (flags
, attr
, type
)
5480 int attr
, type ATTRIBUTE_UNUSED
;
5482 if (attr
& SHF_ALPHA_GPREL
)
5483 flags
|= SEC_SMALL_DATA
;
5486 #endif /* OBJ_ELF */
5488 /* Called internally to handle all alignment needs. This takes care
5489 of eliding calls to frag_align if'n the cached current alignment
5490 says we've already got it, as well as taking care of the auto-align
5491 feature wrt labels. */
5494 alpha_align (n
, pfill
, label
, force
)
5498 int force ATTRIBUTE_UNUSED
;
5500 if (alpha_current_align
>= n
)
5505 if (subseg_text_p (now_seg
))
5506 frag_align_code (n
, 0);
5508 frag_align (n
, 0, 0);
5511 frag_align (n
, *pfill
, 0);
5513 alpha_current_align
= n
;
5515 if (label
!= NULL
&& S_GET_SEGMENT (label
) == now_seg
)
5517 symbol_set_frag (label
, frag_now
);
5518 S_SET_VALUE (label
, (valueT
) frag_now_fix ());
5521 record_alignment (now_seg
, n
);
5523 /* ??? If alpha_flag_relax && force && elf, record the requested alignment
5524 in a reloc for the linker to see. */
5527 /* This is called from HANDLE_ALIGN in write.c. Fill in the contents
5528 of an rs_align_code fragment. */
5531 alpha_handle_align (fragp
)
5534 static char const unop
[4] = { 0x00, 0x00, 0xfe, 0x2f };
5535 static char const nopunop
[8] = {
5536 0x1f, 0x04, 0xff, 0x47,
5537 0x00, 0x00, 0xfe, 0x2f
5543 if (fragp
->fr_type
!= rs_align_code
)
5546 bytes
= fragp
->fr_next
->fr_address
- fragp
->fr_address
- fragp
->fr_fix
;
5547 p
= fragp
->fr_literal
+ fragp
->fr_fix
;
5560 memcpy (p
, unop
, 4);
5566 memcpy (p
, nopunop
, 8);
5568 fragp
->fr_fix
+= fix
;
5572 /* The Alpha has support for some VAX floating point types, as well as for
5573 IEEE floating point. We consider IEEE to be the primary floating point
5574 format, and sneak in the VAX floating point support here. */
5575 #define md_atof vax_md_atof
5576 #include "config/atof-vax.c"