1 /* tc-alpha.c - Processor-specific code for the DEC Alpha AXP CPU.
2 Copyright 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
3 Free Software Foundation, Inc.
4 Contributed by Carnegie Mellon University, 1993.
5 Written by Alessandro Forin, based on earlier gas-1.38 target CPU files.
6 Modified by Ken Raeburn for gas-2.x and ECOFF support.
7 Modified by Richard Henderson for ELF support.
8 Modified by Klaus K"ampf for EVAX (OpenVMS/Alpha) support.
10 This file is part of GAS, the GNU Assembler.
12 GAS is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2, or (at your option)
17 GAS is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
22 You should have received a copy of the GNU General Public License
23 along with GAS; see the file COPYING. If not, write to the Free
24 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
28 * Mach Operating System
29 * Copyright (c) 1993 Carnegie Mellon University
30 * All Rights Reserved.
32 * Permission to use, copy, modify and distribute this software and its
33 * documentation is hereby granted, provided that both the copyright
34 * notice and this permission notice appear in all copies of the
35 * software, derivative works or modified versions, and any portions
36 * thereof, and that both notices appear in supporting documentation.
38 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
39 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
40 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
42 * Carnegie Mellon requests users of this software to return to
44 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
45 * School of Computer Science
46 * Carnegie Mellon University
47 * Pittsburgh PA 15213-3890
49 * any improvements or extensions that they make and grant Carnegie the
50 * rights to redistribute these changes.
55 #include "struc-symbol.h"
58 #include "opcode/alpha.h"
61 #include "elf/alpha.h"
62 #include "dwarf2dbg.h"
65 #include "safe-ctype.h"
69 #define TOKENIZE_ERROR -1
70 #define TOKENIZE_ERROR_REPORT -2
72 #define MAX_INSN_FIXUPS 2
73 #define MAX_INSN_ARGS 5
77 bfd_reloc_code_real_type reloc
;
83 struct alpha_fixup fixups
[MAX_INSN_FIXUPS
];
87 enum alpha_macro_arg
{
99 void (*emit
) PARAMS ((const expressionS
*, int, const PTR
));
101 enum alpha_macro_arg argsets
[16];
104 /* Extra expression types. */
106 #define O_pregister O_md1 /* O_register, in parentheses */
107 #define O_cpregister O_md2 /* + a leading comma */
109 /* Note, the alpha_reloc_op table below depends on the ordering
110 of O_literal .. O_gpre16. */
111 #define O_literal O_md3 /* !literal relocation */
112 #define O_lituse_addr O_md4 /* !lituse_addr relocation */
113 #define O_lituse_base O_md5 /* !lituse_base relocation */
114 #define O_lituse_bytoff O_md6 /* !lituse_bytoff relocation */
115 #define O_lituse_jsr O_md7 /* !lituse_jsr relocation */
116 #define O_gpdisp O_md8 /* !gpdisp relocation */
117 #define O_gprelhigh O_md9 /* !gprelhigh relocation */
118 #define O_gprellow O_md10 /* !gprellow relocation */
119 #define O_gprel O_md11 /* !gprel relocation */
121 #define DUMMY_RELOC_LITUSE_ADDR (BFD_RELOC_UNUSED + 1)
122 #define DUMMY_RELOC_LITUSE_BASE (BFD_RELOC_UNUSED + 2)
123 #define DUMMY_RELOC_LITUSE_BYTOFF (BFD_RELOC_UNUSED + 3)
124 #define DUMMY_RELOC_LITUSE_JSR (BFD_RELOC_UNUSED + 4)
126 #define LITUSE_ADDR 0
127 #define LITUSE_BASE 1
128 #define LITUSE_BYTOFF 2
131 #define USER_RELOC_P(R) ((R) >= O_literal && (R) <= O_gprel)
133 /* Macros for extracting the type and number of encoded register tokens */
135 #define is_ir_num(x) (((x) & 32) == 0)
136 #define is_fpr_num(x) (((x) & 32) != 0)
137 #define regno(x) ((x) & 31)
139 /* Something odd inherited from the old assembler */
141 #define note_gpreg(R) (alpha_gprmask |= (1 << (R)))
142 #define note_fpreg(R) (alpha_fprmask |= (1 << (R)))
144 /* Predicates for 16- and 32-bit ranges */
145 /* XXX: The non-shift version appears to trigger a compiler bug when
146 cross-assembling from x86 w/ gcc 2.7.2. */
149 #define range_signed_16(x) \
150 (((offsetT) (x) >> 15) == 0 || ((offsetT) (x) >> 15) == -1)
151 #define range_signed_32(x) \
152 (((offsetT) (x) >> 31) == 0 || ((offsetT) (x) >> 31) == -1)
154 #define range_signed_16(x) ((offsetT) (x) >= -(offsetT) 0x8000 && \
155 (offsetT) (x) <= (offsetT) 0x7FFF)
156 #define range_signed_32(x) ((offsetT) (x) >= -(offsetT) 0x80000000 && \
157 (offsetT) (x) <= (offsetT) 0x7FFFFFFF)
160 /* Macros for sign extending from 16- and 32-bits. */
161 /* XXX: The cast macros will work on all the systems that I care about,
162 but really a predicate should be found to use the non-cast forms. */
165 #define sign_extend_16(x) ((short) (x))
166 #define sign_extend_32(x) ((int) (x))
168 #define sign_extend_16(x) ((offsetT) (((x) & 0xFFFF) ^ 0x8000) - 0x8000)
169 #define sign_extend_32(x) ((offsetT) (((x) & 0xFFFFFFFF) \
170 ^ 0x80000000) - 0x80000000)
173 /* Macros to build tokens */
175 #define set_tok_reg(t, r) (memset (&(t), 0, sizeof (t)), \
176 (t).X_op = O_register, \
177 (t).X_add_number = (r))
178 #define set_tok_preg(t, r) (memset (&(t), 0, sizeof (t)), \
179 (t).X_op = O_pregister, \
180 (t).X_add_number = (r))
181 #define set_tok_cpreg(t, r) (memset (&(t), 0, sizeof (t)), \
182 (t).X_op = O_cpregister, \
183 (t).X_add_number = (r))
184 #define set_tok_freg(t, r) (memset (&(t), 0, sizeof (t)), \
185 (t).X_op = O_register, \
186 (t).X_add_number = (r) + 32)
187 #define set_tok_sym(t, s, a) (memset (&(t), 0, sizeof (t)), \
188 (t).X_op = O_symbol, \
189 (t).X_add_symbol = (s), \
190 (t).X_add_number = (a))
191 #define set_tok_const(t, n) (memset (&(t), 0, sizeof (t)), \
192 (t).X_op = O_constant, \
193 (t).X_add_number = (n))
195 /* Prototypes for all local functions */
197 static struct alpha_reloc_tag
*get_alpha_reloc_tag
PARAMS ((long));
198 static void alpha_adjust_symtab_relocs
PARAMS ((bfd
*, asection
*, PTR
));
200 static int tokenize_arguments
PARAMS ((char *, expressionS
*, int));
201 static const struct alpha_opcode
*find_opcode_match
202 PARAMS ((const struct alpha_opcode
*, const expressionS
*, int *, int *));
203 static const struct alpha_macro
*find_macro_match
204 PARAMS ((const struct alpha_macro
*, const expressionS
*, int *));
205 static unsigned insert_operand
206 PARAMS ((unsigned, const struct alpha_operand
*, offsetT
, char *, unsigned));
207 static void assemble_insn
208 PARAMS ((const struct alpha_opcode
*, const expressionS
*, int,
209 struct alpha_insn
*, bfd_reloc_code_real_type
));
210 static void emit_insn
PARAMS ((struct alpha_insn
*));
211 static void assemble_tokens_to_insn
212 PARAMS ((const char *, const expressionS
*, int, struct alpha_insn
*));
213 static void assemble_tokens
214 PARAMS ((const char *, const expressionS
*, int, int));
216 static long load_expression
217 PARAMS ((int, const expressionS
*, int *, expressionS
*));
219 static void emit_ldgp
PARAMS ((const expressionS
*, int, const PTR
));
220 static void emit_division
PARAMS ((const expressionS
*, int, const PTR
));
221 static void emit_lda
PARAMS ((const expressionS
*, int, const PTR
));
222 static void emit_ldah
PARAMS ((const expressionS
*, int, const PTR
));
223 static void emit_ir_load
PARAMS ((const expressionS
*, int, const PTR
));
224 static void emit_loadstore
PARAMS ((const expressionS
*, int, const PTR
));
225 static void emit_jsrjmp
PARAMS ((const expressionS
*, int, const PTR
));
226 static void emit_ldX
PARAMS ((const expressionS
*, int, const PTR
));
227 static void emit_ldXu
PARAMS ((const expressionS
*, int, const PTR
));
228 static void emit_uldX
PARAMS ((const expressionS
*, int, const PTR
));
229 static void emit_uldXu
PARAMS ((const expressionS
*, int, const PTR
));
230 static void emit_ldil
PARAMS ((const expressionS
*, int, const PTR
));
231 static void emit_stX
PARAMS ((const expressionS
*, int, const PTR
));
232 static void emit_ustX
PARAMS ((const expressionS
*, int, const PTR
));
233 static void emit_sextX
PARAMS ((const expressionS
*, int, const PTR
));
234 static void emit_retjcr
PARAMS ((const expressionS
*, int, const PTR
));
236 static void s_alpha_text
PARAMS ((int));
237 static void s_alpha_data
PARAMS ((int));
239 static void s_alpha_comm
PARAMS ((int));
240 static void s_alpha_rdata
PARAMS ((int));
243 static void s_alpha_sdata
PARAMS ((int));
246 static void s_alpha_section
PARAMS ((int));
247 static void s_alpha_ent
PARAMS ((int));
248 static void s_alpha_end
PARAMS ((int));
249 static void s_alpha_mask
PARAMS ((int));
250 static void s_alpha_frame
PARAMS ((int));
251 static void s_alpha_prologue
PARAMS ((int));
252 static void s_alpha_file
PARAMS ((int));
253 static void s_alpha_loc
PARAMS ((int));
254 static void s_alpha_stab
PARAMS ((int));
255 static void s_alpha_coff_wrapper
PARAMS ((int));
258 static void s_alpha_section
PARAMS ((int));
260 static void s_alpha_gprel32
PARAMS ((int));
261 static void s_alpha_float_cons
PARAMS ((int));
262 static void s_alpha_proc
PARAMS ((int));
263 static void s_alpha_set
PARAMS ((int));
264 static void s_alpha_base
PARAMS ((int));
265 static void s_alpha_align
PARAMS ((int));
266 static void s_alpha_stringer
PARAMS ((int));
267 static void s_alpha_space
PARAMS ((int));
268 static void s_alpha_ucons
PARAMS ((int));
269 static void s_alpha_arch
PARAMS ((int));
271 static void create_literal_section
PARAMS ((const char *, segT
*, symbolS
**));
273 static void select_gp_value
PARAMS ((void));
275 static void alpha_align
PARAMS ((int, char *, symbolS
*, int));
277 /* Generic assembler global variables which must be defined by all
280 /* Characters which always start a comment. */
281 const char comment_chars
[] = "#";
283 /* Characters which start a comment at the beginning of a line. */
284 const char line_comment_chars
[] = "#";
286 /* Characters which may be used to separate multiple commands on a
288 const char line_separator_chars
[] = ";";
290 /* Characters which are used to indicate an exponent in a floating
292 const char EXP_CHARS
[] = "eE";
294 /* Characters which mean that a number is a floating point constant,
297 const char FLT_CHARS
[] = "dD";
299 /* XXX: Do all of these really get used on the alpha?? */
300 char FLT_CHARS
[] = "rRsSfFdDxXpP";
304 const char *md_shortopts
= "Fm:g+1h:HG:";
306 const char *md_shortopts
= "Fm:gG:";
309 struct option md_longopts
[] = {
310 #define OPTION_32ADDR (OPTION_MD_BASE)
311 { "32addr", no_argument
, NULL
, OPTION_32ADDR
},
312 #define OPTION_RELAX (OPTION_32ADDR + 1)
313 { "relax", no_argument
, NULL
, OPTION_RELAX
},
315 #define OPTION_MDEBUG (OPTION_RELAX + 1)
316 #define OPTION_NO_MDEBUG (OPTION_MDEBUG + 1)
317 { "mdebug", no_argument
, NULL
, OPTION_MDEBUG
},
318 { "no-mdebug", no_argument
, NULL
, OPTION_NO_MDEBUG
},
320 { NULL
, no_argument
, NULL
, 0 }
323 size_t md_longopts_size
= sizeof (md_longopts
);
327 #define AXP_REG_R16 16
328 #define AXP_REG_R17 17
330 #define AXP_REG_T9 22
332 #define AXP_REG_T10 23
334 #define AXP_REG_T11 24
336 #define AXP_REG_T12 25
337 #define AXP_REG_AI 25
339 #define AXP_REG_FP 29
342 #define AXP_REG_GP AXP_REG_PV
343 #endif /* OBJ_EVAX */
345 /* The cpu for which we are generating code */
346 static unsigned alpha_target
= AXP_OPCODE_BASE
;
347 static const char *alpha_target_name
= "<all>";
349 /* The hash table of instruction opcodes */
350 static struct hash_control
*alpha_opcode_hash
;
352 /* The hash table of macro opcodes */
353 static struct hash_control
*alpha_macro_hash
;
356 /* The $gp relocation symbol */
357 static symbolS
*alpha_gp_symbol
;
359 /* XXX: what is this, and why is it exported? */
360 valueT alpha_gp_value
;
363 /* The current $gp register */
364 static int alpha_gp_register
= AXP_REG_GP
;
366 /* A table of the register symbols */
367 static symbolS
*alpha_register_table
[64];
369 /* Constant sections, or sections of constants */
371 static segT alpha_lita_section
;
372 static segT alpha_lit4_section
;
375 static segT alpha_link_section
;
376 static segT alpha_ctors_section
;
377 static segT alpha_dtors_section
;
379 static segT alpha_lit8_section
;
381 /* Symbols referring to said sections. */
383 static symbolS
*alpha_lita_symbol
;
384 static symbolS
*alpha_lit4_symbol
;
387 static symbolS
*alpha_link_symbol
;
388 static symbolS
*alpha_ctors_symbol
;
389 static symbolS
*alpha_dtors_symbol
;
391 static symbolS
*alpha_lit8_symbol
;
393 /* Literal for .litX+0x8000 within .lita */
395 static offsetT alpha_lit4_literal
;
396 static offsetT alpha_lit8_literal
;
400 /* The active .ent symbol. */
401 static symbolS
*alpha_cur_ent_sym
;
404 /* Is the assembler not allowed to use $at? */
405 static int alpha_noat_on
= 0;
407 /* Are macros enabled? */
408 static int alpha_macros_on
= 1;
410 /* Are floats disabled? */
411 static int alpha_nofloats_on
= 0;
413 /* Are addresses 32 bit? */
414 static int alpha_addr32_on
= 0;
416 /* Symbol labelling the current insn. When the Alpha gas sees
419 and the section happens to not be on an eight byte boundary, it
420 will align both the symbol and the .quad to an eight byte boundary. */
421 static symbolS
*alpha_insn_label
;
423 /* Whether we should automatically align data generation pseudo-ops.
424 .align 0 will turn this off. */
425 static int alpha_auto_align_on
= 1;
427 /* The known current alignment of the current section. */
428 static int alpha_current_align
;
430 /* These are exported to ECOFF code. */
431 unsigned long alpha_gprmask
, alpha_fprmask
;
433 /* Whether the debugging option was seen. */
434 static int alpha_debug
;
437 /* Whether we are emitting an mdebug section. */
438 int alpha_flag_mdebug
= -1;
441 /* Don't fully resolve relocations, allowing code movement in the linker. */
442 static int alpha_flag_relax
;
444 /* What value to give to bfd_set_gp_size. */
445 static int g_switch_value
= 8;
448 /* Collect information about current procedure here. */
450 symbolS
*symbol
; /* proc pdesc symbol */
452 int framereg
; /* register for frame pointer */
453 int framesize
; /* size of frame */
463 static int alpha_flag_hash_long_names
= 0; /* -+ */
464 static int alpha_flag_show_after_trunc
= 0; /* -H */
466 /* If the -+ switch is given, then a hash is appended to any name that is
467 * longer than 64 characters, else longer symbol names are truncated.
473 /* A table to map the spelling of a relocation operand into an appropriate
474 bfd_reloc_code_real_type type. The table is assumed to be ordered such
475 that op-O_literal indexes into it. */
477 #define ALPHA_RELOC_TABLE(op) \
478 (&alpha_reloc_op[ ((!USER_RELOC_P (op)) \
480 : (int) (op) - (int) O_literal) ])
482 #define DEF(NAME, RELOC, REQ, ALLOW) \
483 { #NAME, sizeof(#NAME)-1, O_##NAME, RELOC, REQ, ALLOW}
485 static const struct alpha_reloc_op_tag
{
486 const char *name
; /* string to lookup */
487 size_t length
; /* size of the string */
488 operatorT op
; /* which operator to use */
489 bfd_reloc_code_real_type reloc
; /* relocation before frob */
490 unsigned int require_seq
: 1; /* require a sequence number */
491 unsigned int allow_seq
: 1; /* allow a sequence number */
492 } alpha_reloc_op
[] = {
493 DEF(literal
, BFD_RELOC_ALPHA_ELF_LITERAL
, 0, 1),
494 DEF(lituse_addr
, DUMMY_RELOC_LITUSE_ADDR
, 1, 1),
495 DEF(lituse_base
, DUMMY_RELOC_LITUSE_BASE
, 1, 1),
496 DEF(lituse_bytoff
, DUMMY_RELOC_LITUSE_BYTOFF
, 1, 1),
497 DEF(lituse_jsr
, DUMMY_RELOC_LITUSE_JSR
, 1, 1),
498 DEF(gpdisp
, BFD_RELOC_ALPHA_GPDISP
, 1, 1),
499 DEF(gprelhigh
, BFD_RELOC_ALPHA_GPREL_HI16
, 0, 0),
500 DEF(gprellow
, BFD_RELOC_ALPHA_GPREL_LO16
, 0, 0),
501 DEF(gprel
, BFD_RELOC_GPREL16
, 0, 0)
506 static const int alpha_num_reloc_op
507 = sizeof (alpha_reloc_op
) / sizeof (*alpha_reloc_op
);
508 #endif /* RELOC_OP_P */
510 /* Maximum # digits needed to hold the largest sequence # */
511 #define ALPHA_RELOC_DIGITS 25
513 /* Structure to hold explict sequence information. */
514 struct alpha_reloc_tag
516 fixS
*slaves
; /* head of linked list of !literals */
517 segT segment
; /* segment relocs are in or undefined_section*/
518 long sequence
; /* sequence # */
519 unsigned n_master
; /* # of literals */
520 unsigned n_slaves
; /* # of lituses */
521 char multi_section_p
; /* True if more than one section was used */
522 char string
[1]; /* printable form of sequence to hash with */
525 /* Hash table to link up literals with the appropriate lituse */
526 static struct hash_control
*alpha_literal_hash
;
528 /* Sequence numbers for internal use by macros. */
529 static long next_sequence_num
= -1;
531 /* A table of CPU names and opcode sets. */
533 static const struct cpu_type
{
537 /* Ad hoc convention: cpu number gets palcode, process code doesn't.
538 This supports usage under DU 4.0b that does ".arch ev4", and
539 usage in MILO that does -m21064. Probably something more
540 specific like -m21064-pal should be used, but oh well. */
542 { "21064", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
543 { "21064a", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
544 { "21066", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
545 { "21068", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
546 { "21164", AXP_OPCODE_BASE
|AXP_OPCODE_EV5
},
547 { "21164a", AXP_OPCODE_BASE
|AXP_OPCODE_EV5
|AXP_OPCODE_BWX
},
548 { "21164pc", (AXP_OPCODE_BASE
|AXP_OPCODE_EV5
|AXP_OPCODE_BWX
550 { "21264", (AXP_OPCODE_BASE
|AXP_OPCODE_EV6
|AXP_OPCODE_BWX
551 |AXP_OPCODE_MAX
|AXP_OPCODE_CIX
) },
553 { "ev4", AXP_OPCODE_BASE
},
554 { "ev45", AXP_OPCODE_BASE
},
555 { "lca45", AXP_OPCODE_BASE
},
556 { "ev5", AXP_OPCODE_BASE
},
557 { "ev56", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
},
558 { "pca56", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
|AXP_OPCODE_MAX
},
559 { "ev6", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
|AXP_OPCODE_MAX
|AXP_OPCODE_CIX
},
561 { "all", AXP_OPCODE_BASE
},
565 /* The macro table */
567 static const struct alpha_macro alpha_macros
[] = {
568 /* Load/Store macros */
569 { "lda", emit_lda
, NULL
,
570 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
571 { "ldah", emit_ldah
, NULL
,
572 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
574 { "ldl", emit_ir_load
, "ldl",
575 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
576 { "ldl_l", emit_ir_load
, "ldl_l",
577 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
578 { "ldq", emit_ir_load
, "ldq",
579 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
580 { "ldq_l", emit_ir_load
, "ldq_l",
581 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
582 { "ldq_u", emit_ir_load
, "ldq_u",
583 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
584 { "ldf", emit_loadstore
, "ldf",
585 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
586 { "ldg", emit_loadstore
, "ldg",
587 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
588 { "lds", emit_loadstore
, "lds",
589 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
590 { "ldt", emit_loadstore
, "ldt",
591 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
593 { "ldb", emit_ldX
, (PTR
) 0,
594 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
595 { "ldbu", emit_ldXu
, (PTR
) 0,
596 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
597 { "ldw", emit_ldX
, (PTR
) 1,
598 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
599 { "ldwu", emit_ldXu
, (PTR
) 1,
600 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
602 { "uldw", emit_uldX
, (PTR
) 1,
603 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
604 { "uldwu", emit_uldXu
, (PTR
) 1,
605 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
606 { "uldl", emit_uldX
, (PTR
) 2,
607 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
608 { "uldlu", emit_uldXu
, (PTR
) 2,
609 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
610 { "uldq", emit_uldXu
, (PTR
) 3,
611 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
613 { "ldgp", emit_ldgp
, NULL
,
614 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
} },
616 { "ldi", emit_lda
, NULL
,
617 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
618 { "ldil", emit_ldil
, NULL
,
619 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
620 { "ldiq", emit_lda
, NULL
,
621 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
623 { "ldif" emit_ldiq
, NULL
,
624 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
625 { "ldid" emit_ldiq
, NULL
,
626 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
627 { "ldig" emit_ldiq
, NULL
,
628 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
629 { "ldis" emit_ldiq
, NULL
,
630 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
631 { "ldit" emit_ldiq
, NULL
,
632 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
635 { "stl", emit_loadstore
, "stl",
636 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
637 { "stl_c", emit_loadstore
, "stl_c",
638 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
639 { "stq", emit_loadstore
, "stq",
640 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
641 { "stq_c", emit_loadstore
, "stq_c",
642 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
643 { "stq_u", emit_loadstore
, "stq_u",
644 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
645 { "stf", emit_loadstore
, "stf",
646 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
647 { "stg", emit_loadstore
, "stg",
648 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
649 { "sts", emit_loadstore
, "sts",
650 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
651 { "stt", emit_loadstore
, "stt",
652 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
654 { "stb", emit_stX
, (PTR
) 0,
655 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
656 { "stw", emit_stX
, (PTR
) 1,
657 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
658 { "ustw", emit_ustX
, (PTR
) 1,
659 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
660 { "ustl", emit_ustX
, (PTR
) 2,
661 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
662 { "ustq", emit_ustX
, (PTR
) 3,
663 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
665 /* Arithmetic macros */
667 { "absl" emit_absl
, 1, { IR
} },
668 { "absl" emit_absl
, 2, { IR
, IR
} },
669 { "absl" emit_absl
, 2, { EXP
, IR
} },
670 { "absq" emit_absq
, 1, { IR
} },
671 { "absq" emit_absq
, 2, { IR
, IR
} },
672 { "absq" emit_absq
, 2, { EXP
, IR
} },
675 { "sextb", emit_sextX
, (PTR
) 0,
676 { MACRO_IR
, MACRO_IR
, MACRO_EOA
,
678 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
679 { "sextw", emit_sextX
, (PTR
) 1,
680 { MACRO_IR
, MACRO_IR
, MACRO_EOA
,
682 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
684 { "divl", emit_division
, "__divl",
685 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
686 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
687 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
688 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
689 { "divlu", emit_division
, "__divlu",
690 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
691 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
692 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
693 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
694 { "divq", emit_division
, "__divq",
695 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
696 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
697 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
698 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
699 { "divqu", emit_division
, "__divqu",
700 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
701 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
702 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
703 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
704 { "reml", emit_division
, "__reml",
705 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
706 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
707 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
708 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
709 { "remlu", emit_division
, "__remlu",
710 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
711 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
712 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
713 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
714 { "remq", emit_division
, "__remq",
715 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
716 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
717 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
718 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
719 { "remqu", emit_division
, "__remqu",
720 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
721 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
722 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
723 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
725 { "jsr", emit_jsrjmp
, "jsr",
726 { MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
727 MACRO_PIR
, MACRO_EOA
,
728 MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
729 MACRO_EXP
, MACRO_EOA
} },
730 { "jmp", emit_jsrjmp
, "jmp",
731 { MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
732 MACRO_PIR
, MACRO_EOA
,
733 MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
734 MACRO_EXP
, MACRO_EOA
} },
735 { "ret", emit_retjcr
, "ret",
736 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
738 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
739 MACRO_PIR
, MACRO_EOA
,
740 MACRO_EXP
, MACRO_EOA
,
742 { "jcr", emit_retjcr
, "jcr",
743 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
745 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
746 MACRO_PIR
, MACRO_EOA
,
747 MACRO_EXP
, MACRO_EOA
,
749 { "jsr_coroutine", emit_retjcr
, "jcr",
750 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
752 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
753 MACRO_PIR
, MACRO_EOA
,
754 MACRO_EXP
, MACRO_EOA
,
758 static const unsigned int alpha_num_macros
759 = sizeof (alpha_macros
) / sizeof (*alpha_macros
);
761 /* Public interface functions */
763 /* This function is called once, at assembler startup time. It sets
764 up all the tables, etc. that the MD part of the assembler will
765 need, that can be determined before arguments are parsed. */
772 /* Verify that X_op field is wide enough. */
776 assert (e
.X_op
== O_max
);
779 /* Create the opcode hash table */
781 alpha_opcode_hash
= hash_new ();
782 for (i
= 0; i
< alpha_num_opcodes
;)
784 const char *name
, *retval
, *slash
;
786 name
= alpha_opcodes
[i
].name
;
787 retval
= hash_insert (alpha_opcode_hash
, name
, (PTR
) &alpha_opcodes
[i
]);
789 as_fatal (_("internal error: can't hash opcode `%s': %s"),
792 /* Some opcodes include modifiers of various sorts with a "/mod"
793 syntax, like the architecture manual suggests. However, for
794 use with gcc at least, we also need access to those same opcodes
797 if ((slash
= strchr (name
, '/')) != NULL
)
799 char *p
= xmalloc (strlen (name
));
800 memcpy (p
, name
, slash
- name
);
801 strcpy (p
+ (slash
- name
), slash
+ 1);
803 (void) hash_insert (alpha_opcode_hash
, p
, (PTR
) &alpha_opcodes
[i
]);
804 /* Ignore failures -- the opcode table does duplicate some
805 variants in different forms, like "hw_stq" and "hw_st/q". */
808 while (++i
< alpha_num_opcodes
809 && (alpha_opcodes
[i
].name
== name
810 || !strcmp (alpha_opcodes
[i
].name
, name
)))
814 /* Create the macro hash table */
816 alpha_macro_hash
= hash_new ();
817 for (i
= 0; i
< alpha_num_macros
;)
819 const char *name
, *retval
;
821 name
= alpha_macros
[i
].name
;
822 retval
= hash_insert (alpha_macro_hash
, name
, (PTR
) &alpha_macros
[i
]);
824 as_fatal (_("internal error: can't hash macro `%s': %s"),
827 while (++i
< alpha_num_macros
828 && (alpha_macros
[i
].name
== name
829 || !strcmp (alpha_macros
[i
].name
, name
)))
833 /* Construct symbols for each of the registers */
835 for (i
= 0; i
< 32; ++i
)
838 sprintf (name
, "$%d", i
);
839 alpha_register_table
[i
] = symbol_create (name
, reg_section
, i
,
845 sprintf (name
, "$f%d", i
- 32);
846 alpha_register_table
[i
] = symbol_create (name
, reg_section
, i
,
850 /* Create the special symbols and sections we'll be using */
852 /* So .sbss will get used for tiny objects. */
853 bfd_set_gp_size (stdoutput
, g_switch_value
);
856 create_literal_section (".lita", &alpha_lita_section
, &alpha_lita_symbol
);
858 /* For handling the GP, create a symbol that won't be output in the
859 symbol table. We'll edit it out of relocs later. */
860 alpha_gp_symbol
= symbol_create ("<GP value>", alpha_lita_section
, 0x8000,
865 create_literal_section (".link", &alpha_link_section
, &alpha_link_symbol
);
871 segT sec
= subseg_new (".mdebug", (subsegT
) 0);
872 bfd_set_section_flags (stdoutput
, sec
, SEC_HAS_CONTENTS
| SEC_READONLY
);
873 bfd_set_section_alignment (stdoutput
, sec
, 3);
877 /* Create literal lookup hash table. */
878 alpha_literal_hash
= hash_new ();
880 subseg_set (text_section
, 0);
883 /* The public interface to the instruction assembler. */
889 char opname
[32]; /* current maximum is 13 */
890 expressionS tok
[MAX_INSN_ARGS
];
894 /* split off the opcode */
895 opnamelen
= strspn (str
, "abcdefghijklmnopqrstuvwxyz_/46819");
896 trunclen
= (opnamelen
< sizeof (opname
) - 1
898 : sizeof (opname
) - 1);
899 memcpy (opname
, str
, trunclen
);
900 opname
[trunclen
] = '\0';
902 /* tokenize the rest of the line */
903 if ((ntok
= tokenize_arguments (str
+ opnamelen
, tok
, MAX_INSN_ARGS
)) < 0)
905 if (ntok
!= TOKENIZE_ERROR_REPORT
)
906 as_bad (_("syntax error"));
912 assemble_tokens (opname
, tok
, ntok
, alpha_macros_on
);
915 /* Round up a section's size to the appropriate boundary. */
918 md_section_align (seg
, size
)
922 int align
= bfd_get_section_alignment (stdoutput
, seg
);
923 valueT mask
= ((valueT
) 1 << align
) - 1;
925 return (size
+ mask
) & ~mask
;
928 /* Turn a string in input_line_pointer into a floating point constant
929 of type TYPE, and store the appropriate bytes in *LITP. The number
930 of LITTLENUMS emitted is stored in *SIZEP. An error message is
931 returned, or NULL on OK. */
933 /* Equal to MAX_PRECISION in atof-ieee.c */
934 #define MAX_LITTLENUMS 6
936 extern char *vax_md_atof
PARAMS ((int, char *, int *));
939 md_atof (type
, litP
, sizeP
)
945 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
946 LITTLENUM_TYPE
*wordP
;
953 /* VAX md_atof doesn't like "G" for some reason. */
957 return vax_md_atof (type
, litP
, sizeP
);
980 return _("Bad call to MD_ATOF()");
982 t
= atof_ieee (input_line_pointer
, type
, words
);
984 input_line_pointer
= t
;
985 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
987 for (wordP
= words
+ prec
- 1; prec
--;)
989 md_number_to_chars (litP
, (long) (*wordP
--), sizeof (LITTLENUM_TYPE
));
990 litP
+= sizeof (LITTLENUM_TYPE
);
996 /* Take care of the target-specific command-line options. */
999 md_parse_option (c
, arg
)
1006 alpha_nofloats_on
= 1;
1010 alpha_addr32_on
= 1;
1018 g_switch_value
= atoi (arg
);
1023 const struct cpu_type
*p
;
1024 for (p
= cpu_types
; p
->name
; ++p
)
1025 if (strcmp (arg
, p
->name
) == 0)
1027 alpha_target_name
= p
->name
, alpha_target
= p
->flags
;
1030 as_warn (_("Unknown CPU identifier `%s'"), arg
);
1036 case '+': /* For g++. Hash any name > 63 chars long. */
1037 alpha_flag_hash_long_names
= 1;
1040 case 'H': /* Show new symbol after hash truncation */
1041 alpha_flag_show_after_trunc
= 1;
1044 case 'h': /* for gnu-c/vax compatibility. */
1049 alpha_flag_relax
= 1;
1054 alpha_flag_mdebug
= 1;
1056 case OPTION_NO_MDEBUG
:
1057 alpha_flag_mdebug
= 0;
1068 /* Print a description of the command-line options that we accept. */
1071 md_show_usage (stream
)
1076 -32addr treat addresses as 32-bit values\n\
1077 -F lack floating point instructions support\n\
1078 -mev4 | -mev45 | -mev5 | -mev56 | -mpca56 | -mev6 | -mall\n\
1079 specify variant of Alpha architecture\n\
1080 -m21064 | -m21066 | -m21164 | -m21164a | -m21164pc | -m21264\n\
1081 these variants include PALcode opcodes\n"),
1086 -+ hash encode (don't truncate) names longer than 64 characters\n\
1087 -H show new symbol after hash truncation\n"),
1092 /* Decide from what point a pc-relative relocation is relative to,
1093 relative to the pc-relative fixup. Er, relatively speaking. */
1096 md_pcrel_from (fixP
)
1099 valueT addr
= fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
1100 switch (fixP
->fx_r_type
)
1102 case BFD_RELOC_ALPHA_GPDISP
:
1103 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1104 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1107 return fixP
->fx_size
+ addr
;
1111 /* Attempt to simplify or even eliminate a fixup. The return value is
1112 ignored; perhaps it was once meaningful, but now it is historical.
1113 To indicate that a fixup has been eliminated, set fixP->fx_done.
1115 For ELF, here it is that we transform the GPDISP_HI16 reloc we used
1116 internally into the GPDISP reloc used externally. We had to do
1117 this so that we'd have the GPDISP_LO16 reloc as a tag to compute
1118 the distance to the "lda" instruction for setting the addend to
1122 md_apply_fix3 (fixP
, valP
, seg
)
1127 char * const fixpos
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
1128 valueT value
= * valP
;
1129 unsigned image
, size
;
1131 switch (fixP
->fx_r_type
)
1133 /* The GPDISP relocations are processed internally with a symbol
1134 referring to the current function; we need to drop in a value
1135 which, when added to the address of the start of the function,
1136 gives the desired GP. */
1137 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1139 fixS
*next
= fixP
->fx_next
;
1141 /* With user-specified !gpdisp relocations, we can be missing
1142 the matching LO16 reloc. We will have already issued an
1145 fixP
->fx_offset
= (next
->fx_frag
->fr_address
+ next
->fx_where
1146 - fixP
->fx_frag
->fr_address
- fixP
->fx_where
);
1148 value
= (value
- sign_extend_16 (value
)) >> 16;
1151 fixP
->fx_r_type
= BFD_RELOC_ALPHA_GPDISP
;
1155 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1156 value
= sign_extend_16 (value
);
1157 fixP
->fx_offset
= 0;
1163 fixP
->fx_addsy
= section_symbol (seg
);
1164 md_number_to_chars (fixpos
, value
, 2);
1169 fixP
->fx_r_type
= BFD_RELOC_16_PCREL
;
1174 fixP
->fx_r_type
= BFD_RELOC_32_PCREL
;
1179 fixP
->fx_r_type
= BFD_RELOC_64_PCREL
;
1182 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
1184 md_number_to_chars (fixpos
, value
, size
);
1190 case BFD_RELOC_GPREL32
:
1191 assert (fixP
->fx_subsy
== alpha_gp_symbol
);
1193 /* FIXME: inherited this obliviousness of `value' -- why? */
1194 md_number_to_chars (fixpos
, -alpha_gp_value
, 4);
1197 case BFD_RELOC_GPREL32
:
1199 case BFD_RELOC_GPREL16
:
1200 case BFD_RELOC_ALPHA_GPREL_HI16
:
1201 case BFD_RELOC_ALPHA_GPREL_LO16
:
1204 case BFD_RELOC_23_PCREL_S2
:
1205 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
1207 image
= bfd_getl32 (fixpos
);
1208 image
= (image
& ~0x1FFFFF) | ((value
>> 2) & 0x1FFFFF);
1213 case BFD_RELOC_ALPHA_HINT
:
1214 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
1216 image
= bfd_getl32 (fixpos
);
1217 image
= (image
& ~0x3FFF) | ((value
>> 2) & 0x3FFF);
1223 case BFD_RELOC_ALPHA_LITERAL
:
1224 md_number_to_chars (fixpos
, value
, 2);
1227 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1228 case BFD_RELOC_ALPHA_LITUSE
:
1229 case BFD_RELOC_ALPHA_LINKAGE
:
1230 case BFD_RELOC_ALPHA_CODEADDR
:
1233 case BFD_RELOC_VTABLE_INHERIT
:
1234 case BFD_RELOC_VTABLE_ENTRY
:
1239 const struct alpha_operand
*operand
;
1241 if ((int) fixP
->fx_r_type
>= 0)
1242 as_fatal (_("unhandled relocation type %s"),
1243 bfd_get_reloc_code_name (fixP
->fx_r_type
));
1245 assert (-(int) fixP
->fx_r_type
< (int) alpha_num_operands
);
1246 operand
= &alpha_operands
[-(int) fixP
->fx_r_type
];
1248 /* The rest of these fixups only exist internally during symbol
1249 resolution and have no representation in the object file.
1250 Therefore they must be completely resolved as constants. */
1252 if (fixP
->fx_addsy
!= 0
1253 && S_GET_SEGMENT (fixP
->fx_addsy
) != absolute_section
)
1254 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
1255 _("non-absolute expression in constant field"));
1257 image
= bfd_getl32 (fixpos
);
1258 image
= insert_operand (image
, operand
, (offsetT
) value
,
1259 fixP
->fx_file
, fixP
->fx_line
);
1264 if (fixP
->fx_addsy
!= 0 || fixP
->fx_pcrel
!= 0)
1268 as_warn_where (fixP
->fx_file
, fixP
->fx_line
,
1269 _("type %d reloc done?\n"), (int) fixP
->fx_r_type
);
1274 md_number_to_chars (fixpos
, image
, 4);
1280 /* Look for a register name in the given symbol. */
1283 md_undefined_symbol (name
)
1288 int is_float
= 0, num
;
1293 if (name
[1] == 'p' && name
[2] == '\0')
1294 return alpha_register_table
[AXP_REG_FP
];
1299 if (!ISDIGIT (*++name
))
1303 case '0': case '1': case '2': case '3': case '4':
1304 case '5': case '6': case '7': case '8': case '9':
1305 if (name
[1] == '\0')
1306 num
= name
[0] - '0';
1307 else if (name
[0] != '0' && ISDIGIT (name
[1]) && name
[2] == '\0')
1309 num
= (name
[0] - '0') * 10 + name
[1] - '0';
1316 if (!alpha_noat_on
&& (num
+ is_float
) == AXP_REG_AT
)
1317 as_warn (_("Used $at without \".set noat\""));
1318 return alpha_register_table
[num
+ is_float
];
1321 if (name
[1] == 't' && name
[2] == '\0')
1324 as_warn (_("Used $at without \".set noat\""));
1325 return alpha_register_table
[AXP_REG_AT
];
1330 if (name
[1] == 'p' && name
[2] == '\0')
1331 return alpha_register_table
[alpha_gp_register
];
1335 if (name
[1] == 'p' && name
[2] == '\0')
1336 return alpha_register_table
[AXP_REG_SP
];
1344 /* @@@ Magic ECOFF bits. */
1347 alpha_frob_ecoff_data ()
1350 /* $zero and $f31 are read-only */
1351 alpha_gprmask
&= ~1;
1352 alpha_fprmask
&= ~1;
1356 /* Hook to remember a recently defined label so that the auto-align
1357 code can adjust the symbol after we know what alignment will be
1361 alpha_define_label (sym
)
1364 alpha_insn_label
= sym
;
1367 /* Return true if we must always emit a reloc for a type and false if
1368 there is some hope of resolving it at assembly time. */
1371 alpha_force_relocation (f
)
1374 if (alpha_flag_relax
)
1377 switch (f
->fx_r_type
)
1379 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1380 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1381 case BFD_RELOC_ALPHA_GPDISP
:
1382 case BFD_RELOC_ALPHA_LITERAL
:
1383 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1384 case BFD_RELOC_ALPHA_LITUSE
:
1385 case BFD_RELOC_GPREL16
:
1386 case BFD_RELOC_GPREL32
:
1387 case BFD_RELOC_ALPHA_GPREL_HI16
:
1388 case BFD_RELOC_ALPHA_GPREL_LO16
:
1389 case BFD_RELOC_ALPHA_LINKAGE
:
1390 case BFD_RELOC_ALPHA_CODEADDR
:
1391 case BFD_RELOC_VTABLE_INHERIT
:
1392 case BFD_RELOC_VTABLE_ENTRY
:
1395 case BFD_RELOC_23_PCREL_S2
:
1398 case BFD_RELOC_ALPHA_HINT
:
1406 /* Return true if we can partially resolve a relocation now. */
1409 alpha_fix_adjustable (f
)
1413 /* Prevent all adjustments to global symbols */
1414 if (S_IS_EXTERN (f
->fx_addsy
) || S_IS_WEAK (f
->fx_addsy
))
1418 /* Are there any relocation types for which we must generate a reloc
1419 but we can adjust the values contained within it? */
1420 switch (f
->fx_r_type
)
1422 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1423 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1424 case BFD_RELOC_ALPHA_GPDISP
:
1427 case BFD_RELOC_ALPHA_LITERAL
:
1428 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1429 case BFD_RELOC_ALPHA_LITUSE
:
1430 case BFD_RELOC_ALPHA_LINKAGE
:
1431 case BFD_RELOC_ALPHA_CODEADDR
:
1434 case BFD_RELOC_VTABLE_ENTRY
:
1435 case BFD_RELOC_VTABLE_INHERIT
:
1438 case BFD_RELOC_GPREL16
:
1439 case BFD_RELOC_GPREL32
:
1440 case BFD_RELOC_ALPHA_GPREL_HI16
:
1441 case BFD_RELOC_ALPHA_GPREL_LO16
:
1442 case BFD_RELOC_23_PCREL_S2
:
1445 case BFD_RELOC_ALPHA_HINT
:
1454 /* Generate the BFD reloc to be stuck in the object file from the
1455 fixup used internally in the assembler. */
1458 tc_gen_reloc (sec
, fixp
)
1459 asection
*sec ATTRIBUTE_UNUSED
;
1464 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
1465 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
1466 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
1467 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
1469 /* Make sure none of our internal relocations make it this far.
1470 They'd better have been fully resolved by this point. */
1471 assert ((int) fixp
->fx_r_type
> 0);
1473 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
1474 if (reloc
->howto
== NULL
)
1476 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1477 _("cannot represent `%s' relocation in object file"),
1478 bfd_get_reloc_code_name (fixp
->fx_r_type
));
1482 if (!fixp
->fx_pcrel
!= !reloc
->howto
->pc_relative
)
1484 as_fatal (_("internal error? cannot generate `%s' relocation"),
1485 bfd_get_reloc_code_name (fixp
->fx_r_type
));
1487 assert (!fixp
->fx_pcrel
== !reloc
->howto
->pc_relative
);
1490 if (fixp
->fx_r_type
== BFD_RELOC_ALPHA_LITERAL
)
1492 /* fake out bfd_perform_relocation. sigh */
1493 reloc
->addend
= -alpha_gp_value
;
1498 reloc
->addend
= fixp
->fx_offset
;
1501 * Ohhh, this is ugly. The problem is that if this is a local global
1502 * symbol, the relocation will entirely be performed at link time, not
1503 * at assembly time. bfd_perform_reloc doesn't know about this sort
1504 * of thing, and as a result we need to fake it out here.
1506 if ((S_IS_EXTERN (fixp
->fx_addsy
) || S_IS_WEAK (fixp
->fx_addsy
)
1507 || (S_GET_SEGMENT (fixp
->fx_addsy
)->flags
& SEC_MERGE
))
1508 && !S_IS_COMMON (fixp
->fx_addsy
))
1509 reloc
->addend
-= symbol_get_bfdsym (fixp
->fx_addsy
)->value
;
1516 /* Parse a register name off of the input_line and return a register
1517 number. Gets md_undefined_symbol above to do the register name
1520 Only called as a part of processing the ECOFF .frame directive. */
1523 tc_get_register (frame
)
1524 int frame ATTRIBUTE_UNUSED
;
1526 int framereg
= AXP_REG_SP
;
1529 if (*input_line_pointer
== '$')
1531 char *s
= input_line_pointer
;
1532 char c
= get_symbol_end ();
1533 symbolS
*sym
= md_undefined_symbol (s
);
1535 *strchr (s
, '\0') = c
;
1536 if (sym
&& (framereg
= S_GET_VALUE (sym
)) <= 31)
1539 as_warn (_("frame reg expected, using $%d."), framereg
);
1542 note_gpreg (framereg
);
1546 /* This is called before the symbol table is processed. In order to
1547 work with gcc when using mips-tfile, we must keep all local labels.
1548 However, in other cases, we want to discard them. If we were
1549 called with -g, but we didn't see any debugging information, it may
1550 mean that gcc is smuggling debugging information through to
1551 mips-tfile, in which case we must generate all local labels. */
1556 alpha_frob_file_before_adjust ()
1558 if (alpha_debug
!= 0
1559 && ! ecoff_debugging_seen
)
1560 flag_keep_locals
= 1;
1563 #endif /* OBJ_ECOFF */
1565 static struct alpha_reloc_tag
*
1566 get_alpha_reloc_tag (sequence
)
1569 char buffer
[ALPHA_RELOC_DIGITS
];
1570 struct alpha_reloc_tag
*info
;
1572 sprintf (buffer
, "!%ld", sequence
);
1574 info
= (struct alpha_reloc_tag
*) hash_find (alpha_literal_hash
, buffer
);
1577 size_t len
= strlen (buffer
);
1580 info
= (struct alpha_reloc_tag
*)
1581 xcalloc (sizeof (struct alpha_reloc_tag
) + len
, 1);
1583 info
->segment
= now_seg
;
1584 info
->sequence
= sequence
;
1585 strcpy (info
->string
, buffer
);
1586 errmsg
= hash_insert (alpha_literal_hash
, info
->string
, (PTR
) info
);
1594 /* Before the relocations are written, reorder them, so that user
1595 supplied !lituse relocations follow the appropriate !literal
1596 relocations, and similarly for !gpdisp relocations. */
1599 alpha_adjust_symtab ()
1601 if (alpha_literal_hash
)
1602 bfd_map_over_sections (stdoutput
, alpha_adjust_symtab_relocs
, NULL
);
1606 alpha_adjust_symtab_relocs (abfd
, sec
, ptr
)
1607 bfd
*abfd ATTRIBUTE_UNUSED
;
1609 PTR ptr ATTRIBUTE_UNUSED
;
1611 segment_info_type
*seginfo
= seg_info (sec
);
1616 unsigned long n_slaves
= 0;
1618 /* If seginfo is NULL, we did not create this section; don't do
1619 anything with it. By using a pointer to a pointer, we can update
1620 the links in place. */
1621 if (seginfo
== NULL
)
1624 /* If there are no relocations, skip the section. */
1625 if (! seginfo
->fix_root
)
1628 /* First rebuild the fixup chain without the expicit lituse and
1629 gpdisp_lo16 relocs. */
1630 prevP
= &seginfo
->fix_root
;
1631 for (fixp
= seginfo
->fix_root
; fixp
; fixp
= next
)
1633 next
= fixp
->fx_next
;
1634 fixp
->fx_next
= (fixS
*) 0;
1636 switch (fixp
->fx_r_type
)
1638 case BFD_RELOC_ALPHA_LITUSE
:
1640 if (fixp
->tc_fix_data
.info
->n_master
== 0)
1641 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1642 _("No !literal!%ld was found"),
1643 fixp
->tc_fix_data
.info
->sequence
);
1646 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1648 if (fixp
->tc_fix_data
.info
->n_master
== 0)
1649 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1650 _("No ldah !gpdisp!%ld was found"),
1651 fixp
->tc_fix_data
.info
->sequence
);
1656 prevP
= &fixp
->fx_next
;
1661 /* If there were any dependent relocations, go and add them back to
1662 the chain. They are linked through the next_reloc field in
1663 reverse order, so as we go through the next_reloc chain, we
1664 effectively reverse the chain once again.
1666 Except if there is more than one !literal for a given sequence
1667 number. In that case, the programmer and/or compiler is not sure
1668 how control flows from literal to lituse, and we can't be sure to
1669 get the relaxation correct.
1671 ??? Well, actually we could, if there are enough lituses such that
1672 we can make each literal have at least one of each lituse type
1673 present. Not implemented.
1675 Also suppress the optimization if the !literals/!lituses are spread
1676 in different segments. This can happen with "intersting" uses of
1677 inline assembly; examples are present in the Linux kernel semaphores. */
1679 for (fixp
= seginfo
->fix_root
; fixp
; fixp
= next
)
1681 next
= fixp
->fx_next
;
1682 switch (fixp
->fx_r_type
)
1684 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1685 if (fixp
->tc_fix_data
.info
->n_master
== 1
1686 && ! fixp
->tc_fix_data
.info
->multi_section_p
)
1688 for (slave
= fixp
->tc_fix_data
.info
->slaves
;
1689 slave
!= (fixS
*) 0;
1690 slave
= slave
->tc_fix_data
.next_reloc
)
1692 slave
->fx_next
= fixp
->fx_next
;
1693 fixp
->fx_next
= slave
;
1698 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1699 if (fixp
->tc_fix_data
.info
->n_slaves
== 0)
1700 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1701 _("No lda !gpdisp!%ld was found"),
1702 fixp
->tc_fix_data
.info
->sequence
);
1705 slave
= fixp
->tc_fix_data
.info
->slaves
;
1706 slave
->fx_next
= next
;
1707 fixp
->fx_next
= slave
;
1719 debug_exp (tok
, ntok
)
1725 fprintf (stderr
, "debug_exp: %d tokens", ntok
);
1726 for (i
= 0; i
< ntok
; i
++)
1728 expressionS
*t
= &tok
[i
];
1732 default: name
= "unknown"; break;
1733 case O_illegal
: name
= "O_illegal"; break;
1734 case O_absent
: name
= "O_absent"; break;
1735 case O_constant
: name
= "O_constant"; break;
1736 case O_symbol
: name
= "O_symbol"; break;
1737 case O_symbol_rva
: name
= "O_symbol_rva"; break;
1738 case O_register
: name
= "O_register"; break;
1739 case O_big
: name
= "O_big"; break;
1740 case O_uminus
: name
= "O_uminus"; break;
1741 case O_bit_not
: name
= "O_bit_not"; break;
1742 case O_logical_not
: name
= "O_logical_not"; break;
1743 case O_multiply
: name
= "O_multiply"; break;
1744 case O_divide
: name
= "O_divide"; break;
1745 case O_modulus
: name
= "O_modulus"; break;
1746 case O_left_shift
: name
= "O_left_shift"; break;
1747 case O_right_shift
: name
= "O_right_shift"; break;
1748 case O_bit_inclusive_or
: name
= "O_bit_inclusive_or"; break;
1749 case O_bit_or_not
: name
= "O_bit_or_not"; break;
1750 case O_bit_exclusive_or
: name
= "O_bit_exclusive_or"; break;
1751 case O_bit_and
: name
= "O_bit_and"; break;
1752 case O_add
: name
= "O_add"; break;
1753 case O_subtract
: name
= "O_subtract"; break;
1754 case O_eq
: name
= "O_eq"; break;
1755 case O_ne
: name
= "O_ne"; break;
1756 case O_lt
: name
= "O_lt"; break;
1757 case O_le
: name
= "O_le"; break;
1758 case O_ge
: name
= "O_ge"; break;
1759 case O_gt
: name
= "O_gt"; break;
1760 case O_logical_and
: name
= "O_logical_and"; break;
1761 case O_logical_or
: name
= "O_logical_or"; break;
1762 case O_index
: name
= "O_index"; break;
1763 case O_pregister
: name
= "O_pregister"; break;
1764 case O_cpregister
: name
= "O_cpregister"; break;
1765 case O_literal
: name
= "O_literal"; break;
1766 case O_lituse_base
: name
= "O_lituse_base"; break;
1767 case O_lituse_bytoff
: name
= "O_lituse_bytoff"; break;
1768 case O_lituse_jsr
: name
= "O_lituse_jsr"; break;
1769 case O_gpdisp
: name
= "O_gpdisp"; break;
1770 case O_gprelhigh
: name
= "O_gprelhigh"; break;
1771 case O_gprellow
: name
= "O_gprellow"; break;
1772 case O_gprel
: name
= "O_gprel"; break;
1773 case O_md11
: name
= "O_md11"; break;
1774 case O_md12
: name
= "O_md12"; break;
1775 case O_md13
: name
= "O_md13"; break;
1776 case O_md14
: name
= "O_md14"; break;
1777 case O_md15
: name
= "O_md15"; break;
1778 case O_md16
: name
= "O_md16"; break;
1781 fprintf (stderr
, ", %s(%s, %s, %d)", name
,
1782 (t
->X_add_symbol
) ? S_GET_NAME (t
->X_add_symbol
) : "--",
1783 (t
->X_op_symbol
) ? S_GET_NAME (t
->X_op_symbol
) : "--",
1784 (int) t
->X_add_number
);
1786 fprintf (stderr
, "\n");
1791 /* Parse the arguments to an opcode. */
1794 tokenize_arguments (str
, tok
, ntok
)
1799 expressionS
*end_tok
= tok
+ ntok
;
1800 char *old_input_line_pointer
;
1801 int saw_comma
= 0, saw_arg
= 0;
1803 expressionS
*orig_tok
= tok
;
1806 const struct alpha_reloc_op_tag
*r
;
1809 int reloc_found_p
= 0;
1811 memset (tok
, 0, sizeof (*tok
) * ntok
);
1813 /* Save and restore input_line_pointer around this function */
1814 old_input_line_pointer
= input_line_pointer
;
1815 input_line_pointer
= str
;
1818 /* ??? Wrest control of ! away from the regular expression parser. */
1819 is_end_of_line
[(unsigned char) '!'] = 1;
1822 while (tok
< end_tok
&& *input_line_pointer
)
1825 switch (*input_line_pointer
)
1832 /* A relocation operand can be placed after the normal operand on an
1833 assembly language statement, and has the following form:
1834 !relocation_type!sequence_number. */
1836 { /* only support one relocation op per insn */
1837 as_bad (_("More than one relocation op per insn"));
1844 ++input_line_pointer
;
1846 p
= input_line_pointer
;
1847 c
= get_symbol_end ();
1849 /* Parse !relocation_type */
1850 len
= input_line_pointer
- p
;
1853 as_bad (_("No relocation operand"));
1857 r
= &alpha_reloc_op
[0];
1858 for (i
= alpha_num_reloc_op
- 1; i
>= 0; i
--, r
++)
1859 if (len
== r
->length
&& memcmp (p
, r
->name
, len
) == 0)
1863 as_bad (_("Unknown relocation operand: !%s"), p
);
1867 *input_line_pointer
= c
;
1869 if (*input_line_pointer
!= '!')
1873 as_bad (_("no sequence number after !%s"), p
);
1877 tok
->X_add_number
= 0;
1883 as_bad (_("!%s does not use a sequence number"), p
);
1887 input_line_pointer
++;
1889 /* Parse !sequence_number */
1891 if (tok
->X_op
!= O_constant
|| tok
->X_add_number
<= 0)
1893 as_bad (_("Bad sequence number: !%s!%s"),
1894 r
->name
, input_line_pointer
);
1903 #endif /* RELOC_OP_P */
1906 ++input_line_pointer
;
1907 if (saw_comma
|| !saw_arg
)
1914 char *hold
= input_line_pointer
++;
1916 /* First try for parenthesized register ... */
1918 if (*input_line_pointer
== ')' && tok
->X_op
== O_register
)
1920 tok
->X_op
= (saw_comma
? O_cpregister
: O_pregister
);
1923 ++input_line_pointer
;
1928 /* ... then fall through to plain expression */
1929 input_line_pointer
= hold
;
1933 if (saw_arg
&& !saw_comma
)
1937 if (tok
->X_op
== O_illegal
|| tok
->X_op
== O_absent
)
1950 input_line_pointer
= old_input_line_pointer
;
1953 debug_exp (orig_tok
, ntok
- (end_tok
- tok
));
1956 is_end_of_line
[(unsigned char) '!'] = 0;
1959 return ntok
- (end_tok
- tok
);
1963 is_end_of_line
[(unsigned char) '!'] = 0;
1965 input_line_pointer
= old_input_line_pointer
;
1966 return TOKENIZE_ERROR
;
1970 is_end_of_line
[(unsigned char) '!'] = 0;
1972 input_line_pointer
= old_input_line_pointer
;
1973 return TOKENIZE_ERROR_REPORT
;
1976 /* Search forward through all variants of an opcode looking for a
1979 static const struct alpha_opcode
*
1980 find_opcode_match (first_opcode
, tok
, pntok
, pcpumatch
)
1981 const struct alpha_opcode
*first_opcode
;
1982 const expressionS
*tok
;
1986 const struct alpha_opcode
*opcode
= first_opcode
;
1988 int got_cpu_match
= 0;
1992 const unsigned char *opidx
;
1995 /* Don't match opcodes that don't exist on this architecture */
1996 if (!(opcode
->flags
& alpha_target
))
2001 for (opidx
= opcode
->operands
; *opidx
; ++opidx
)
2003 const struct alpha_operand
*operand
= &alpha_operands
[*opidx
];
2005 /* only take input from real operands */
2006 if (operand
->flags
& AXP_OPERAND_FAKE
)
2009 /* when we expect input, make sure we have it */
2012 if ((operand
->flags
& AXP_OPERAND_OPTIONAL_MASK
) == 0)
2017 /* match operand type with expression type */
2018 switch (operand
->flags
& AXP_OPERAND_TYPECHECK_MASK
)
2020 case AXP_OPERAND_IR
:
2021 if (tok
[tokidx
].X_op
!= O_register
2022 || !is_ir_num (tok
[tokidx
].X_add_number
))
2025 case AXP_OPERAND_FPR
:
2026 if (tok
[tokidx
].X_op
!= O_register
2027 || !is_fpr_num (tok
[tokidx
].X_add_number
))
2030 case AXP_OPERAND_IR
| AXP_OPERAND_PARENS
:
2031 if (tok
[tokidx
].X_op
!= O_pregister
2032 || !is_ir_num (tok
[tokidx
].X_add_number
))
2035 case AXP_OPERAND_IR
| AXP_OPERAND_PARENS
| AXP_OPERAND_COMMA
:
2036 if (tok
[tokidx
].X_op
!= O_cpregister
2037 || !is_ir_num (tok
[tokidx
].X_add_number
))
2041 case AXP_OPERAND_RELATIVE
:
2042 case AXP_OPERAND_SIGNED
:
2043 case AXP_OPERAND_UNSIGNED
:
2044 switch (tok
[tokidx
].X_op
)
2059 /* everything else should have been fake */
2065 /* possible match -- did we use all of our input? */
2074 while (++opcode
- alpha_opcodes
< alpha_num_opcodes
2075 && !strcmp (opcode
->name
, first_opcode
->name
));
2078 *pcpumatch
= got_cpu_match
;
2083 /* Search forward through all variants of a macro looking for a syntax
2086 static const struct alpha_macro
*
2087 find_macro_match (first_macro
, tok
, pntok
)
2088 const struct alpha_macro
*first_macro
;
2089 const expressionS
*tok
;
2092 const struct alpha_macro
*macro
= first_macro
;
2097 const enum alpha_macro_arg
*arg
= macro
->argsets
;
2111 /* index register */
2113 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_register
2114 || !is_ir_num (tok
[tokidx
].X_add_number
))
2119 /* parenthesized index register */
2121 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_pregister
2122 || !is_ir_num (tok
[tokidx
].X_add_number
))
2127 /* optional parenthesized index register */
2129 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_pregister
2130 && is_ir_num (tok
[tokidx
].X_add_number
))
2134 /* leading comma with a parenthesized index register */
2136 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_cpregister
2137 || !is_ir_num (tok
[tokidx
].X_add_number
))
2142 /* floating point register */
2144 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_register
2145 || !is_fpr_num (tok
[tokidx
].X_add_number
))
2150 /* normal expression */
2154 switch (tok
[tokidx
].X_op
)
2163 case O_lituse_bytoff
:
2178 while (*arg
!= MACRO_EOA
)
2186 while (++macro
- alpha_macros
< alpha_num_macros
2187 && !strcmp (macro
->name
, first_macro
->name
));
2192 /* Insert an operand value into an instruction. */
2195 insert_operand (insn
, operand
, val
, file
, line
)
2197 const struct alpha_operand
*operand
;
2202 if (operand
->bits
!= 32 && !(operand
->flags
& AXP_OPERAND_NOOVERFLOW
))
2206 if (operand
->flags
& AXP_OPERAND_SIGNED
)
2208 max
= (1 << (operand
->bits
- 1)) - 1;
2209 min
= -(1 << (operand
->bits
- 1));
2213 max
= (1 << operand
->bits
) - 1;
2217 if (val
< min
|| val
> max
)
2220 _("operand out of range (%s not between %d and %d)");
2221 char buf
[sizeof (val
) * 3 + 2];
2223 sprint_value (buf
, val
);
2225 as_warn_where (file
, line
, err
, buf
, min
, max
);
2227 as_warn (err
, buf
, min
, max
);
2231 if (operand
->insert
)
2233 const char *errmsg
= NULL
;
2235 insn
= (*operand
->insert
) (insn
, val
, &errmsg
);
2240 insn
|= ((val
& ((1 << operand
->bits
) - 1)) << operand
->shift
);
2246 * Turn an opcode description and a set of arguments into
2247 * an instruction and a fixup.
2251 assemble_insn (opcode
, tok
, ntok
, insn
, reloc
)
2252 const struct alpha_opcode
*opcode
;
2253 const expressionS
*tok
;
2255 struct alpha_insn
*insn
;
2256 bfd_reloc_code_real_type reloc
;
2258 const struct alpha_operand
*reloc_operand
= NULL
;
2259 const expressionS
*reloc_exp
= NULL
;
2260 const unsigned char *argidx
;
2264 memset (insn
, 0, sizeof (*insn
));
2265 image
= opcode
->opcode
;
2267 for (argidx
= opcode
->operands
; *argidx
; ++argidx
)
2269 const struct alpha_operand
*operand
= &alpha_operands
[*argidx
];
2270 const expressionS
*t
= (const expressionS
*) 0;
2272 if (operand
->flags
& AXP_OPERAND_FAKE
)
2274 /* fake operands take no value and generate no fixup */
2275 image
= insert_operand (image
, operand
, 0, NULL
, 0);
2281 switch (operand
->flags
& AXP_OPERAND_OPTIONAL_MASK
)
2283 case AXP_OPERAND_DEFAULT_FIRST
:
2286 case AXP_OPERAND_DEFAULT_SECOND
:
2289 case AXP_OPERAND_DEFAULT_ZERO
:
2291 static expressionS zero_exp
;
2293 zero_exp
.X_op
= O_constant
;
2294 zero_exp
.X_unsigned
= 1;
2309 image
= insert_operand (image
, operand
, regno (t
->X_add_number
),
2314 image
= insert_operand (image
, operand
, t
->X_add_number
, NULL
, 0);
2315 assert (reloc_operand
== NULL
);
2316 reloc_operand
= operand
;
2321 /* This is only 0 for fields that should contain registers,
2322 which means this pattern shouldn't have matched. */
2323 if (operand
->default_reloc
== 0)
2326 /* There is one special case for which an insn receives two
2327 relocations, and thus the user-supplied reloc does not
2328 override the operand reloc. */
2329 if (operand
->default_reloc
== BFD_RELOC_ALPHA_HINT
)
2331 struct alpha_fixup
*fixup
;
2333 if (insn
->nfixups
>= MAX_INSN_FIXUPS
)
2334 as_fatal (_("too many fixups"));
2336 fixup
= &insn
->fixups
[insn
->nfixups
++];
2338 fixup
->reloc
= BFD_RELOC_ALPHA_HINT
;
2342 if (reloc
== BFD_RELOC_UNUSED
)
2343 reloc
= operand
->default_reloc
;
2345 assert (reloc_operand
== NULL
);
2346 reloc_operand
= operand
;
2353 if (reloc
!= BFD_RELOC_UNUSED
)
2355 struct alpha_fixup
*fixup
;
2357 if (insn
->nfixups
>= MAX_INSN_FIXUPS
)
2358 as_fatal (_("too many fixups"));
2360 /* ??? My but this is hacky. But the OSF/1 assembler uses the same
2361 relocation tag for both ldah and lda with gpdisp. Choose the
2362 correct internal relocation based on the opcode. */
2363 if (reloc
== BFD_RELOC_ALPHA_GPDISP
)
2365 if (strcmp (opcode
->name
, "ldah") == 0)
2366 reloc
= BFD_RELOC_ALPHA_GPDISP_HI16
;
2367 else if (strcmp (opcode
->name
, "lda") == 0)
2368 reloc
= BFD_RELOC_ALPHA_GPDISP_LO16
;
2370 as_bad (_("invalid relocation for instruction"));
2373 /* If this is a real relocation (as opposed to a lituse hint), then
2374 the relocation width should match the operand width. */
2375 else if (reloc
< BFD_RELOC_UNUSED
)
2377 reloc_howto_type
*reloc_howto
2378 = bfd_reloc_type_lookup (stdoutput
, reloc
);
2379 if (reloc_howto
->bitsize
!= reloc_operand
->bits
)
2381 as_bad (_("invalid relocation for field"));
2386 fixup
= &insn
->fixups
[insn
->nfixups
++];
2388 fixup
->exp
= *reloc_exp
;
2390 fixup
->exp
.X_op
= O_absent
;
2391 fixup
->reloc
= reloc
;
2398 * Actually output an instruction with its fixup.
2403 struct alpha_insn
*insn
;
2408 /* Take care of alignment duties. */
2409 if (alpha_auto_align_on
&& alpha_current_align
< 2)
2410 alpha_align (2, (char *) NULL
, alpha_insn_label
, 0);
2411 if (alpha_current_align
> 2)
2412 alpha_current_align
= 2;
2413 alpha_insn_label
= NULL
;
2415 /* Write out the instruction. */
2417 md_number_to_chars (f
, insn
->insn
, 4);
2420 dwarf2_emit_insn (4);
2423 /* Apply the fixups in order */
2424 for (i
= 0; i
< insn
->nfixups
; ++i
)
2426 const struct alpha_operand
*operand
= (const struct alpha_operand
*) 0;
2427 struct alpha_fixup
*fixup
= &insn
->fixups
[i
];
2428 struct alpha_reloc_tag
*info
;
2432 /* Some fixups are only used internally and so have no howto */
2433 if ((int) fixup
->reloc
< 0)
2435 operand
= &alpha_operands
[-(int) fixup
->reloc
];
2437 pcrel
= ((operand
->flags
& AXP_OPERAND_RELATIVE
) != 0);
2439 else if (fixup
->reloc
> BFD_RELOC_UNUSED
2440 || fixup
->reloc
== BFD_RELOC_ALPHA_GPDISP_HI16
2441 || fixup
->reloc
== BFD_RELOC_ALPHA_GPDISP_LO16
)
2448 reloc_howto_type
*reloc_howto
2449 = bfd_reloc_type_lookup (stdoutput
, fixup
->reloc
);
2450 assert (reloc_howto
);
2452 size
= bfd_get_reloc_size (reloc_howto
);
2453 assert (size
>= 1 && size
<= 4);
2455 pcrel
= reloc_howto
->pc_relative
;
2458 fixP
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, size
,
2459 &fixup
->exp
, pcrel
, fixup
->reloc
);
2461 /* Turn off complaints that the addend is too large for some fixups,
2462 and copy in the sequence number for the explicit relocations. */
2463 switch (fixup
->reloc
)
2465 case BFD_RELOC_ALPHA_HINT
:
2466 case BFD_RELOC_GPREL32
:
2467 case BFD_RELOC_GPREL16
:
2468 case BFD_RELOC_ALPHA_GPREL_HI16
:
2469 case BFD_RELOC_ALPHA_GPREL_LO16
:
2470 fixP
->fx_no_overflow
= 1;
2473 case BFD_RELOC_ALPHA_GPDISP_HI16
:
2474 fixP
->fx_no_overflow
= 1;
2475 fixP
->fx_addsy
= section_symbol (now_seg
);
2476 fixP
->fx_offset
= 0;
2478 info
= get_alpha_reloc_tag (insn
->sequence
);
2479 if (++info
->n_master
> 1)
2480 as_bad (_("too many ldah insns for !gpdisp!%ld"), insn
->sequence
);
2481 if (info
->segment
!= now_seg
)
2482 as_bad (_("both insns for !gpdisp!%ld must be in the same section"),
2484 fixP
->tc_fix_data
.info
= info
;
2487 case BFD_RELOC_ALPHA_GPDISP_LO16
:
2488 fixP
->fx_no_overflow
= 1;
2490 info
= get_alpha_reloc_tag (insn
->sequence
);
2491 if (++info
->n_slaves
> 1)
2492 as_bad (_("too many lda insns for !gpdisp!%ld"), insn
->sequence
);
2493 if (info
->segment
!= now_seg
)
2494 as_bad (_("both insns for !gpdisp!%ld must be in the same section"),
2496 fixP
->tc_fix_data
.info
= info
;
2497 info
->slaves
= fixP
;
2500 case BFD_RELOC_ALPHA_LITERAL
:
2501 case BFD_RELOC_ALPHA_ELF_LITERAL
:
2502 fixP
->fx_no_overflow
= 1;
2504 info
= get_alpha_reloc_tag (insn
->sequence
);
2506 if (info
->segment
!= now_seg
)
2507 info
->multi_section_p
= 1;
2508 fixP
->tc_fix_data
.info
= info
;
2511 case DUMMY_RELOC_LITUSE_ADDR
:
2512 fixP
->fx_offset
= LITUSE_ADDR
;
2514 case DUMMY_RELOC_LITUSE_BASE
:
2515 fixP
->fx_offset
= LITUSE_BASE
;
2517 case DUMMY_RELOC_LITUSE_BYTOFF
:
2518 fixP
->fx_offset
= LITUSE_BYTOFF
;
2520 case DUMMY_RELOC_LITUSE_JSR
:
2521 fixP
->fx_offset
= LITUSE_JSR
;
2523 fixP
->fx_addsy
= section_symbol (now_seg
);
2524 fixP
->fx_r_type
= BFD_RELOC_ALPHA_LITUSE
;
2526 info
= get_alpha_reloc_tag (insn
->sequence
);
2528 fixP
->tc_fix_data
.info
= info
;
2529 fixP
->tc_fix_data
.next_reloc
= info
->slaves
;
2530 info
->slaves
= fixP
;
2531 if (info
->segment
!= now_seg
)
2532 info
->multi_section_p
= 1;
2536 if ((int) fixup
->reloc
< 0)
2538 if (operand
->flags
& AXP_OPERAND_NOOVERFLOW
)
2539 fixP
->fx_no_overflow
= 1;
2546 /* Given an opcode name and a pre-tokenized set of arguments, assemble
2547 the insn, but do not emit it.
2549 Note that this implies no macros allowed, since we can't store more
2550 than one insn in an insn structure. */
2553 assemble_tokens_to_insn (opname
, tok
, ntok
, insn
)
2555 const expressionS
*tok
;
2557 struct alpha_insn
*insn
;
2559 const struct alpha_opcode
*opcode
;
2561 /* search opcodes */
2562 opcode
= (const struct alpha_opcode
*) hash_find (alpha_opcode_hash
, opname
);
2566 opcode
= find_opcode_match (opcode
, tok
, &ntok
, &cpumatch
);
2569 assemble_insn (opcode
, tok
, ntok
, insn
, BFD_RELOC_UNUSED
);
2573 as_bad (_("inappropriate arguments for opcode `%s'"), opname
);
2575 as_bad (_("opcode `%s' not supported for target %s"), opname
,
2579 as_bad (_("unknown opcode `%s'"), opname
);
2582 /* Given an opcode name and a pre-tokenized set of arguments, take the
2583 opcode all the way through emission. */
2586 assemble_tokens (opname
, tok
, ntok
, local_macros_on
)
2588 const expressionS
*tok
;
2590 int local_macros_on
;
2592 int found_something
= 0;
2593 const struct alpha_opcode
*opcode
;
2594 const struct alpha_macro
*macro
;
2596 bfd_reloc_code_real_type reloc
= BFD_RELOC_UNUSED
;
2598 /* If a user-specified relocation is present, this is not a macro. */
2599 if (ntok
&& USER_RELOC_P (tok
[ntok
- 1].X_op
))
2601 reloc
= ALPHA_RELOC_TABLE (tok
[ntok
- 1].X_op
)->reloc
;
2604 else if (local_macros_on
)
2606 macro
= ((const struct alpha_macro
*)
2607 hash_find (alpha_macro_hash
, opname
));
2610 found_something
= 1;
2611 macro
= find_macro_match (macro
, tok
, &ntok
);
2614 (*macro
->emit
) (tok
, ntok
, macro
->arg
);
2620 /* search opcodes */
2621 opcode
= (const struct alpha_opcode
*) hash_find (alpha_opcode_hash
, opname
);
2624 found_something
= 1;
2625 opcode
= find_opcode_match (opcode
, tok
, &ntok
, &cpumatch
);
2628 struct alpha_insn insn
;
2629 assemble_insn (opcode
, tok
, ntok
, &insn
, reloc
);
2631 /* Copy the sequence number for the reloc from the reloc token. */
2632 if (reloc
!= BFD_RELOC_UNUSED
)
2633 insn
.sequence
= tok
[ntok
].X_add_number
;
2640 if (found_something
)
2643 as_bad (_("inappropriate arguments for opcode `%s'"), opname
);
2645 as_bad (_("opcode `%s' not supported for target %s"), opname
,
2649 as_bad (_("unknown opcode `%s'"), opname
);
2652 /* Some instruction sets indexed by lg(size) */
2653 static const char * const sextX_op
[] = { "sextb", "sextw", "sextl", NULL
};
2654 static const char * const insXl_op
[] = { "insbl", "inswl", "insll", "insql" };
2655 static const char * const insXh_op
[] = { NULL
, "inswh", "inslh", "insqh" };
2656 static const char * const extXl_op
[] = { "extbl", "extwl", "extll", "extql" };
2657 static const char * const extXh_op
[] = { NULL
, "extwh", "extlh", "extqh" };
2658 static const char * const mskXl_op
[] = { "mskbl", "mskwl", "mskll", "mskql" };
2659 static const char * const mskXh_op
[] = { NULL
, "mskwh", "msklh", "mskqh" };
2660 static const char * const stX_op
[] = { "stb", "stw", "stl", "stq" };
2661 static const char * const ldX_op
[] = { "ldb", "ldw", "ldll", "ldq" };
2662 static const char * const ldXu_op
[] = { "ldbu", "ldwu", NULL
, NULL
};
2664 /* Implement the ldgp macro. */
2667 emit_ldgp (tok
, ntok
, unused
)
2668 const expressionS
*tok
;
2669 int ntok ATTRIBUTE_UNUSED
;
2670 const PTR unused ATTRIBUTE_UNUSED
;
2675 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
2676 /* from "ldgp r1,n(r2)", generate "ldah r1,X(R2); lda r1,Y(r1)"
2677 with appropriate constants and relocations. */
2678 struct alpha_insn insn
;
2679 expressionS newtok
[3];
2683 if (regno (tok
[2].X_add_number
) == AXP_REG_PV
)
2684 ecoff_set_gp_prolog_size (0);
2688 set_tok_const (newtok
[1], 0);
2691 assemble_tokens_to_insn ("ldah", newtok
, 3, &insn
);
2696 if (addend
.X_op
!= O_constant
)
2697 as_bad (_("can not resolve expression"));
2698 addend
.X_op
= O_symbol
;
2699 addend
.X_add_symbol
= alpha_gp_symbol
;
2703 insn
.fixups
[0].exp
= addend
;
2704 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_GPDISP_HI16
;
2705 insn
.sequence
= next_sequence_num
;
2709 set_tok_preg (newtok
[2], tok
[0].X_add_number
);
2711 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
2714 addend
.X_add_number
+= 4;
2718 insn
.fixups
[0].exp
= addend
;
2719 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_GPDISP_LO16
;
2720 insn
.sequence
= next_sequence_num
--;
2723 #endif /* OBJ_ECOFF || OBJ_ELF */
2728 /* Add symbol+addend to link pool.
2729 Return offset from basesym to entry in link pool.
2731 Add new fixup only if offset isn't 16bit. */
2734 add_to_link_pool (basesym
, sym
, addend
)
2739 segT current_section
= now_seg
;
2740 int current_subsec
= now_subseg
;
2742 bfd_reloc_code_real_type reloc_type
;
2744 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
2747 offset
= - *symbol_get_obj (basesym
);
2749 /* @@ This assumes all entries in a given section will be of the same
2750 size... Probably correct, but unwise to rely on. */
2751 /* This must always be called with the same subsegment. */
2753 if (seginfo
->frchainP
)
2754 for (fixp
= seginfo
->frchainP
->fix_root
;
2755 fixp
!= (fixS
*) NULL
;
2756 fixp
= fixp
->fx_next
, offset
+= 8)
2758 if (fixp
->fx_addsy
== sym
&& fixp
->fx_offset
== addend
)
2760 if (range_signed_16 (offset
))
2767 /* Not found in 16bit signed range. */
2769 subseg_set (alpha_link_section
, 0);
2773 fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, sym
, addend
, 0,
2776 subseg_set (current_section
, current_subsec
);
2777 seginfo
->literal_pool_size
+= 8;
2781 #endif /* OBJ_EVAX */
2783 /* Load a (partial) expression into a target register.
2785 If poffset is not null, after the call it will either contain
2786 O_constant 0, or a 16-bit offset appropriate for any MEM format
2787 instruction. In addition, pbasereg will be modified to point to
2788 the base register to use in that MEM format instruction.
2790 In any case, *pbasereg should contain a base register to add to the
2791 expression. This will normally be either AXP_REG_ZERO or
2792 alpha_gp_register. Symbol addresses will always be loaded via $gp,
2793 so "foo($0)" is interpreted as adding the address of foo to $0;
2794 i.e. "ldq $targ, LIT($gp); addq $targ, $0, $targ". Odd, perhaps,
2795 but this is what OSF/1 does.
2797 If explicit relocations of the form !literal!<number> are allowed,
2798 and used, then explict_reloc with be an expression pointer.
2800 Finally, the return value is nonzero if the calling macro may emit
2801 a LITUSE reloc if otherwise appropriate; the return value is the
2802 sequence number to use. */
2805 load_expression (targreg
, exp
, pbasereg
, poffset
)
2807 const expressionS
*exp
;
2809 expressionS
*poffset
;
2811 long emit_lituse
= 0;
2812 offsetT addend
= exp
->X_add_number
;
2813 int basereg
= *pbasereg
;
2814 struct alpha_insn insn
;
2815 expressionS newtok
[3];
2824 /* attempt to reduce .lit load by splitting the offset from
2825 its symbol when possible, but don't create a situation in
2827 if (!range_signed_32 (addend
) &&
2828 (alpha_noat_on
|| targreg
== AXP_REG_AT
))
2830 lit
= add_to_literal_pool (exp
->X_add_symbol
, addend
,
2831 alpha_lita_section
, 8);
2836 lit
= add_to_literal_pool (exp
->X_add_symbol
, 0,
2837 alpha_lita_section
, 8);
2841 as_fatal (_("overflow in literal (.lita) table"));
2843 /* emit "ldq r, lit(gp)" */
2845 if (basereg
!= alpha_gp_register
&& targreg
== basereg
)
2848 as_bad (_("macro requires $at register while noat in effect"));
2849 if (targreg
== AXP_REG_AT
)
2850 as_bad (_("macro requires $at while $at in use"));
2852 set_tok_reg (newtok
[0], AXP_REG_AT
);
2855 set_tok_reg (newtok
[0], targreg
);
2856 set_tok_sym (newtok
[1], alpha_lita_symbol
, lit
);
2857 set_tok_preg (newtok
[2], alpha_gp_register
);
2859 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
2861 assert (insn
.nfixups
== 1);
2862 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITERAL
;
2863 insn
.sequence
= emit_lituse
= next_sequence_num
--;
2864 #endif /* OBJ_ECOFF */
2866 /* emit "ldq r, gotoff(gp)" */
2868 if (basereg
!= alpha_gp_register
&& targreg
== basereg
)
2871 as_bad (_("macro requires $at register while noat in effect"));
2872 if (targreg
== AXP_REG_AT
)
2873 as_bad (_("macro requires $at while $at in use"));
2875 set_tok_reg (newtok
[0], AXP_REG_AT
);
2878 set_tok_reg (newtok
[0], targreg
);
2880 /* XXX: Disable this .got minimizing optimization so that we can get
2881 better instruction offset knowledge in the compiler. This happens
2882 very infrequently anyway. */
2884 || (!range_signed_32 (addend
)
2885 && (alpha_noat_on
|| targreg
== AXP_REG_AT
)))
2892 set_tok_sym (newtok
[1], exp
->X_add_symbol
, 0);
2895 set_tok_preg (newtok
[2], alpha_gp_register
);
2897 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
2899 assert (insn
.nfixups
== 1);
2900 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_ELF_LITERAL
;
2901 insn
.sequence
= emit_lituse
= next_sequence_num
--;
2902 #endif /* OBJ_ELF */
2906 /* Find symbol or symbol pointer in link section. */
2908 if (exp
->X_add_symbol
== alpha_evax_proc
.symbol
)
2910 if (range_signed_16 (addend
))
2912 set_tok_reg (newtok
[0], targreg
);
2913 set_tok_const (newtok
[1], addend
);
2914 set_tok_preg (newtok
[2], basereg
);
2915 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
2920 set_tok_reg (newtok
[0], targreg
);
2921 set_tok_const (newtok
[1], 0);
2922 set_tok_preg (newtok
[2], basereg
);
2923 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
2928 if (!range_signed_32 (addend
))
2930 link
= add_to_link_pool (alpha_evax_proc
.symbol
,
2931 exp
->X_add_symbol
, addend
);
2936 link
= add_to_link_pool (alpha_evax_proc
.symbol
,
2937 exp
->X_add_symbol
, 0);
2939 set_tok_reg (newtok
[0], targreg
);
2940 set_tok_const (newtok
[1], link
);
2941 set_tok_preg (newtok
[2], basereg
);
2942 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
2944 #endif /* OBJ_EVAX */
2949 if (basereg
!= alpha_gp_register
&& basereg
!= AXP_REG_ZERO
)
2951 /* emit "addq r, base, r" */
2953 set_tok_reg (newtok
[1], basereg
);
2954 set_tok_reg (newtok
[2], targreg
);
2955 assemble_tokens ("addq", newtok
, 3, 0);
2967 /* Assume that this difference expression will be resolved to an
2968 absolute value and that that value will fit in 16 bits. */
2970 set_tok_reg (newtok
[0], targreg
);
2972 set_tok_preg (newtok
[2], basereg
);
2973 assemble_tokens ("lda", newtok
, 3, 0);
2976 set_tok_const (*poffset
, 0);
2980 if (exp
->X_add_number
> 0)
2981 as_bad (_("bignum invalid; zero assumed"));
2983 as_bad (_("floating point number invalid; zero assumed"));
2988 as_bad (_("can't handle expression"));
2993 if (!range_signed_32 (addend
))
2996 long seq_num
= next_sequence_num
--;
2998 /* For 64-bit addends, just put it in the literal pool. */
3001 /* emit "ldq targreg, lit(basereg)" */
3002 lit
= add_to_link_pool (alpha_evax_proc
.symbol
,
3003 section_symbol (absolute_section
), addend
);
3004 set_tok_reg (newtok
[0], targreg
);
3005 set_tok_const (newtok
[1], lit
);
3006 set_tok_preg (newtok
[2], alpha_gp_register
);
3007 assemble_tokens ("ldq", newtok
, 3, 0);
3010 if (alpha_lit8_section
== NULL
)
3012 create_literal_section (".lit8",
3013 &alpha_lit8_section
,
3014 &alpha_lit8_symbol
);
3017 alpha_lit8_literal
= add_to_literal_pool (alpha_lit8_symbol
, 0x8000,
3018 alpha_lita_section
, 8);
3019 if (alpha_lit8_literal
>= 0x8000)
3020 as_fatal (_("overflow in literal (.lita) table"));
3024 lit
= add_to_literal_pool (NULL
, addend
, alpha_lit8_section
, 8) - 0x8000;
3026 as_fatal (_("overflow in literal (.lit8) table"));
3028 /* emit "lda litreg, .lit8+0x8000" */
3030 if (targreg
== basereg
)
3033 as_bad (_("macro requires $at register while noat in effect"));
3034 if (targreg
== AXP_REG_AT
)
3035 as_bad (_("macro requires $at while $at in use"));
3037 set_tok_reg (newtok
[0], AXP_REG_AT
);
3040 set_tok_reg (newtok
[0], targreg
);
3042 set_tok_sym (newtok
[1], alpha_lita_symbol
, alpha_lit8_literal
);
3045 set_tok_sym (newtok
[1], alpha_lit8_symbol
, 0x8000);
3047 set_tok_preg (newtok
[2], alpha_gp_register
);
3049 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
3051 assert (insn
.nfixups
== 1);
3053 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITERAL
;
3056 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_ELF_LITERAL
;
3058 insn
.sequence
= seq_num
;
3062 /* emit "ldq litreg, lit(litreg)" */
3064 set_tok_const (newtok
[1], lit
);
3065 set_tok_preg (newtok
[2], newtok
[0].X_add_number
);
3067 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
3069 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3070 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BASE
;
3071 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3073 insn
.sequence
= seq_num
;
3078 /* emit "addq litreg, base, target" */
3080 if (basereg
!= AXP_REG_ZERO
)
3082 set_tok_reg (newtok
[1], basereg
);
3083 set_tok_reg (newtok
[2], targreg
);
3084 assemble_tokens ("addq", newtok
, 3, 0);
3086 #endif /* !OBJ_EVAX */
3089 set_tok_const (*poffset
, 0);
3090 *pbasereg
= targreg
;
3094 offsetT low
, high
, extra
, tmp
;
3096 /* for 32-bit operands, break up the addend */
3098 low
= sign_extend_16 (addend
);
3100 high
= sign_extend_16 (tmp
>> 16);
3102 if (tmp
- (high
<< 16))
3106 high
= sign_extend_16 (tmp
>> 16);
3111 set_tok_reg (newtok
[0], targreg
);
3112 set_tok_preg (newtok
[2], basereg
);
3116 /* emit "ldah r, extra(r) */
3117 set_tok_const (newtok
[1], extra
);
3118 assemble_tokens ("ldah", newtok
, 3, 0);
3119 set_tok_preg (newtok
[2], basereg
= targreg
);
3124 /* emit "ldah r, high(r) */
3125 set_tok_const (newtok
[1], high
);
3126 assemble_tokens ("ldah", newtok
, 3, 0);
3128 set_tok_preg (newtok
[2], basereg
);
3131 if ((low
&& !poffset
) || (!poffset
&& basereg
!= targreg
))
3133 /* emit "lda r, low(base)" */
3134 set_tok_const (newtok
[1], low
);
3135 assemble_tokens ("lda", newtok
, 3, 0);
3141 set_tok_const (*poffset
, low
);
3142 *pbasereg
= basereg
;
3148 /* The lda macro differs from the lda instruction in that it handles
3149 most simple expressions, particualrly symbol address loads and
3153 emit_lda (tok
, ntok
, unused
)
3154 const expressionS
*tok
;
3156 const PTR unused ATTRIBUTE_UNUSED
;
3161 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
3163 basereg
= tok
[2].X_add_number
;
3165 (void) load_expression (tok
[0].X_add_number
, &tok
[1], &basereg
, NULL
);
3168 /* The ldah macro differs from the ldah instruction in that it has $31
3169 as an implied base register. */
3172 emit_ldah (tok
, ntok
, unused
)
3173 const expressionS
*tok
;
3174 int ntok ATTRIBUTE_UNUSED
;
3175 const PTR unused ATTRIBUTE_UNUSED
;
3177 expressionS newtok
[3];
3181 set_tok_preg (newtok
[2], AXP_REG_ZERO
);
3183 assemble_tokens ("ldah", newtok
, 3, 0);
3186 /* Handle all "simple" integer register loads -- ldq, ldq_l, ldq_u,
3187 etc. They differ from the real instructions in that they do simple
3188 expressions like the lda macro. */
3191 emit_ir_load (tok
, ntok
, opname
)
3192 const expressionS
*tok
;
3198 expressionS newtok
[3];
3199 struct alpha_insn insn
;
3202 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
3204 basereg
= tok
[2].X_add_number
;
3206 lituse
= load_expression (tok
[0].X_add_number
, &tok
[1], &basereg
,
3210 set_tok_preg (newtok
[2], basereg
);
3212 assemble_tokens_to_insn ((const char *) opname
, newtok
, 3, &insn
);
3216 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3217 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BASE
;
3218 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3220 insn
.sequence
= lituse
;
3226 /* Handle fp register loads, and both integer and fp register stores.
3227 Again, we handle simple expressions. */
3230 emit_loadstore (tok
, ntok
, opname
)
3231 const expressionS
*tok
;
3237 expressionS newtok
[3];
3238 struct alpha_insn insn
;
3241 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
3243 basereg
= tok
[2].X_add_number
;
3245 if (tok
[1].X_op
!= O_constant
|| !range_signed_16 (tok
[1].X_add_number
))
3248 as_bad (_("macro requires $at register while noat in effect"));
3250 lituse
= load_expression (AXP_REG_AT
, &tok
[1], &basereg
, &newtok
[1]);
3259 set_tok_preg (newtok
[2], basereg
);
3261 assemble_tokens_to_insn ((const char *) opname
, newtok
, 3, &insn
);
3265 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3266 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BASE
;
3267 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3269 insn
.sequence
= lituse
;
3275 /* Load a half-word or byte as an unsigned value. */
3278 emit_ldXu (tok
, ntok
, vlgsize
)
3279 const expressionS
*tok
;
3283 if (alpha_target
& AXP_OPCODE_BWX
)
3284 emit_ir_load (tok
, ntok
, ldXu_op
[(long) vlgsize
]);
3287 expressionS newtok
[3];
3288 struct alpha_insn insn
;
3293 as_bad (_("macro requires $at register while noat in effect"));
3296 basereg
= (tok
[1].X_op
== O_constant
3297 ? AXP_REG_ZERO
: alpha_gp_register
);
3299 basereg
= tok
[2].X_add_number
;
3301 /* emit "lda $at, exp" */
3303 lituse
= load_expression (AXP_REG_AT
, &tok
[1], &basereg
, NULL
);
3305 /* emit "ldq_u targ, 0($at)" */
3308 set_tok_const (newtok
[1], 0);
3309 set_tok_preg (newtok
[2], basereg
);
3310 assemble_tokens_to_insn ("ldq_u", newtok
, 3, &insn
);
3314 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3315 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BASE
;
3316 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3318 insn
.sequence
= lituse
;
3323 /* emit "extXl targ, $at, targ" */
3325 set_tok_reg (newtok
[1], basereg
);
3326 newtok
[2] = newtok
[0];
3327 assemble_tokens_to_insn (extXl_op
[(long) vlgsize
], newtok
, 3, &insn
);
3331 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3332 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BYTOFF
;
3333 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3335 insn
.sequence
= lituse
;
3342 /* Load a half-word or byte as a signed value. */
3345 emit_ldX (tok
, ntok
, vlgsize
)
3346 const expressionS
*tok
;
3350 emit_ldXu (tok
, ntok
, vlgsize
);
3351 assemble_tokens (sextX_op
[(long) vlgsize
], tok
, 1, 1);
3354 /* Load an integral value from an unaligned address as an unsigned
3358 emit_uldXu (tok
, ntok
, vlgsize
)
3359 const expressionS
*tok
;
3363 long lgsize
= (long) vlgsize
;
3364 expressionS newtok
[3];
3367 as_bad (_("macro requires $at register while noat in effect"));
3369 /* emit "lda $at, exp" */
3371 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
3372 newtok
[0].X_add_number
= AXP_REG_AT
;
3373 assemble_tokens ("lda", newtok
, ntok
, 1);
3375 /* emit "ldq_u $t9, 0($at)" */
3377 set_tok_reg (newtok
[0], AXP_REG_T9
);
3378 set_tok_const (newtok
[1], 0);
3379 set_tok_preg (newtok
[2], AXP_REG_AT
);
3380 assemble_tokens ("ldq_u", newtok
, 3, 1);
3382 /* emit "ldq_u $t10, size-1($at)" */
3384 set_tok_reg (newtok
[0], AXP_REG_T10
);
3385 set_tok_const (newtok
[1], (1 << lgsize
) - 1);
3386 assemble_tokens ("ldq_u", newtok
, 3, 1);
3388 /* emit "extXl $t9, $at, $t9" */
3390 set_tok_reg (newtok
[0], AXP_REG_T9
);
3391 set_tok_reg (newtok
[1], AXP_REG_AT
);
3392 set_tok_reg (newtok
[2], AXP_REG_T9
);
3393 assemble_tokens (extXl_op
[lgsize
], newtok
, 3, 1);
3395 /* emit "extXh $t10, $at, $t10" */
3397 set_tok_reg (newtok
[0], AXP_REG_T10
);
3398 set_tok_reg (newtok
[2], AXP_REG_T10
);
3399 assemble_tokens (extXh_op
[lgsize
], newtok
, 3, 1);
3401 /* emit "or $t9, $t10, targ" */
3403 set_tok_reg (newtok
[0], AXP_REG_T9
);
3404 set_tok_reg (newtok
[1], AXP_REG_T10
);
3406 assemble_tokens ("or", newtok
, 3, 1);
3409 /* Load an integral value from an unaligned address as a signed value.
3410 Note that quads should get funneled to the unsigned load since we
3411 don't have to do the sign extension. */
3414 emit_uldX (tok
, ntok
, vlgsize
)
3415 const expressionS
*tok
;
3419 emit_uldXu (tok
, ntok
, vlgsize
);
3420 assemble_tokens (sextX_op
[(long) vlgsize
], tok
, 1, 1);
3423 /* Implement the ldil macro. */
3426 emit_ldil (tok
, ntok
, unused
)
3427 const expressionS
*tok
;
3429 const PTR unused ATTRIBUTE_UNUSED
;
3431 expressionS newtok
[2];
3433 memcpy (newtok
, tok
, sizeof (newtok
));
3434 newtok
[1].X_add_number
= sign_extend_32 (tok
[1].X_add_number
);
3436 assemble_tokens ("lda", newtok
, ntok
, 1);
3439 /* Store a half-word or byte. */
3442 emit_stX (tok
, ntok
, vlgsize
)
3443 const expressionS
*tok
;
3447 int lgsize
= (int) (long) vlgsize
;
3449 if (alpha_target
& AXP_OPCODE_BWX
)
3450 emit_loadstore (tok
, ntok
, stX_op
[lgsize
]);
3453 expressionS newtok
[3];
3454 struct alpha_insn insn
;
3459 as_bad (_("macro requires $at register while noat in effect"));
3462 basereg
= (tok
[1].X_op
== O_constant
3463 ? AXP_REG_ZERO
: alpha_gp_register
);
3465 basereg
= tok
[2].X_add_number
;
3467 /* emit "lda $at, exp" */
3469 lituse
= load_expression (AXP_REG_AT
, &tok
[1], &basereg
, NULL
);
3471 /* emit "ldq_u $t9, 0($at)" */
3473 set_tok_reg (newtok
[0], AXP_REG_T9
);
3474 set_tok_const (newtok
[1], 0);
3475 set_tok_preg (newtok
[2], basereg
);
3476 assemble_tokens_to_insn ("ldq_u", newtok
, 3, &insn
);
3480 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3481 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BASE
;
3482 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3484 insn
.sequence
= lituse
;
3489 /* emit "insXl src, $at, $t10" */
3492 set_tok_reg (newtok
[1], basereg
);
3493 set_tok_reg (newtok
[2], AXP_REG_T10
);
3494 assemble_tokens_to_insn (insXl_op
[lgsize
], newtok
, 3, &insn
);
3498 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3499 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BYTOFF
;
3500 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3502 insn
.sequence
= lituse
;
3507 /* emit "mskXl $t9, $at, $t9" */
3509 set_tok_reg (newtok
[0], AXP_REG_T9
);
3510 newtok
[2] = newtok
[0];
3511 assemble_tokens_to_insn (mskXl_op
[lgsize
], newtok
, 3, &insn
);
3515 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3516 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BYTOFF
;
3517 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3519 insn
.sequence
= lituse
;
3524 /* emit "or $t9, $t10, $t9" */
3526 set_tok_reg (newtok
[1], AXP_REG_T10
);
3527 assemble_tokens ("or", newtok
, 3, 1);
3529 /* emit "stq_u $t9, 0($at) */
3531 set_tok_const(newtok
[1], 0);
3532 set_tok_preg (newtok
[2], AXP_REG_AT
);
3533 assemble_tokens_to_insn ("stq_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
;
3548 /* Store an integer to an unaligned address. */
3551 emit_ustX (tok
, ntok
, vlgsize
)
3552 const expressionS
*tok
;
3556 int lgsize
= (int) (long) vlgsize
;
3557 expressionS newtok
[3];
3559 /* emit "lda $at, exp" */
3561 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
3562 newtok
[0].X_add_number
= AXP_REG_AT
;
3563 assemble_tokens ("lda", newtok
, ntok
, 1);
3565 /* emit "ldq_u $9, 0($at)" */
3567 set_tok_reg (newtok
[0], AXP_REG_T9
);
3568 set_tok_const (newtok
[1], 0);
3569 set_tok_preg (newtok
[2], AXP_REG_AT
);
3570 assemble_tokens ("ldq_u", newtok
, 3, 1);
3572 /* emit "ldq_u $10, size-1($at)" */
3574 set_tok_reg (newtok
[0], AXP_REG_T10
);
3575 set_tok_const (newtok
[1], (1 << lgsize
) - 1);
3576 assemble_tokens ("ldq_u", newtok
, 3, 1);
3578 /* emit "insXl src, $at, $t11" */
3581 set_tok_reg (newtok
[1], AXP_REG_AT
);
3582 set_tok_reg (newtok
[2], AXP_REG_T11
);
3583 assemble_tokens (insXl_op
[lgsize
], newtok
, 3, 1);
3585 /* emit "insXh src, $at, $t12" */
3587 set_tok_reg (newtok
[2], AXP_REG_T12
);
3588 assemble_tokens (insXh_op
[lgsize
], newtok
, 3, 1);
3590 /* emit "mskXl $t9, $at, $t9" */
3592 set_tok_reg (newtok
[0], AXP_REG_T9
);
3593 newtok
[2] = newtok
[0];
3594 assemble_tokens (mskXl_op
[lgsize
], newtok
, 3, 1);
3596 /* emit "mskXh $t10, $at, $t10" */
3598 set_tok_reg (newtok
[0], AXP_REG_T10
);
3599 newtok
[2] = newtok
[0];
3600 assemble_tokens (mskXh_op
[lgsize
], newtok
, 3, 1);
3602 /* emit "or $t9, $t11, $t9" */
3604 set_tok_reg (newtok
[0], AXP_REG_T9
);
3605 set_tok_reg (newtok
[1], AXP_REG_T11
);
3606 newtok
[2] = newtok
[0];
3607 assemble_tokens ("or", newtok
, 3, 1);
3609 /* emit "or $t10, $t12, $t10" */
3611 set_tok_reg (newtok
[0], AXP_REG_T10
);
3612 set_tok_reg (newtok
[1], AXP_REG_T12
);
3613 newtok
[2] = newtok
[0];
3614 assemble_tokens ("or", newtok
, 3, 1);
3616 /* emit "stq_u $t9, 0($at)" */
3618 set_tok_reg (newtok
[0], AXP_REG_T9
);
3619 set_tok_const (newtok
[1], 0);
3620 set_tok_preg (newtok
[2], AXP_REG_AT
);
3621 assemble_tokens ("stq_u", newtok
, 3, 1);
3623 /* emit "stq_u $t10, size-1($at)" */
3625 set_tok_reg (newtok
[0], AXP_REG_T10
);
3626 set_tok_const (newtok
[1], (1 << lgsize
) - 1);
3627 assemble_tokens ("stq_u", newtok
, 3, 1);
3630 /* Sign extend a half-word or byte. The 32-bit sign extend is
3631 implemented as "addl $31, $r, $t" in the opcode table. */
3634 emit_sextX (tok
, ntok
, vlgsize
)
3635 const expressionS
*tok
;
3639 long lgsize
= (long) vlgsize
;
3641 if (alpha_target
& AXP_OPCODE_BWX
)
3642 assemble_tokens (sextX_op
[lgsize
], tok
, ntok
, 0);
3645 int bitshift
= 64 - 8 * (1 << lgsize
);
3646 expressionS newtok
[3];
3648 /* emit "sll src,bits,dst" */
3651 set_tok_const (newtok
[1], bitshift
);
3652 newtok
[2] = tok
[ntok
- 1];
3653 assemble_tokens ("sll", newtok
, 3, 1);
3655 /* emit "sra dst,bits,dst" */
3657 newtok
[0] = newtok
[2];
3658 assemble_tokens ("sra", newtok
, 3, 1);
3662 /* Implement the division and modulus macros. */
3666 /* Make register usage like in normal procedure call.
3667 Don't clobber PV and RA. */
3670 emit_division (tok
, ntok
, symname
)
3671 const expressionS
*tok
;
3675 /* DIVISION and MODULUS. Yech.
3680 * mov x,R16 # if x != R16
3681 * mov y,R17 # if y != R17
3686 * with appropriate optimizations if R0,R16,R17 are the registers
3687 * specified by the compiler.
3692 expressionS newtok
[3];
3694 xr
= regno (tok
[0].X_add_number
);
3695 yr
= regno (tok
[1].X_add_number
);
3700 rr
= regno (tok
[2].X_add_number
);
3702 /* Move the operands into the right place */
3703 if (yr
== AXP_REG_R16
&& xr
== AXP_REG_R17
)
3705 /* They are in exactly the wrong order -- swap through AT */
3708 as_bad (_("macro requires $at register while noat in effect"));
3710 set_tok_reg (newtok
[0], AXP_REG_R16
);
3711 set_tok_reg (newtok
[1], AXP_REG_AT
);
3712 assemble_tokens ("mov", newtok
, 2, 1);
3714 set_tok_reg (newtok
[0], AXP_REG_R17
);
3715 set_tok_reg (newtok
[1], AXP_REG_R16
);
3716 assemble_tokens ("mov", newtok
, 2, 1);
3718 set_tok_reg (newtok
[0], AXP_REG_AT
);
3719 set_tok_reg (newtok
[1], AXP_REG_R17
);
3720 assemble_tokens ("mov", newtok
, 2, 1);
3724 if (yr
== AXP_REG_R16
)
3726 set_tok_reg (newtok
[0], AXP_REG_R16
);
3727 set_tok_reg (newtok
[1], AXP_REG_R17
);
3728 assemble_tokens ("mov", newtok
, 2, 1);
3731 if (xr
!= AXP_REG_R16
)
3733 set_tok_reg (newtok
[0], xr
);
3734 set_tok_reg (newtok
[1], AXP_REG_R16
);
3735 assemble_tokens ("mov", newtok
, 2, 1);
3738 if (yr
!= AXP_REG_R16
&& yr
!= AXP_REG_R17
)
3740 set_tok_reg (newtok
[0], yr
);
3741 set_tok_reg (newtok
[1], AXP_REG_R17
);
3742 assemble_tokens ("mov", newtok
, 2, 1);
3746 sym
= symbol_find_or_make ((const char *) symname
);
3748 set_tok_reg (newtok
[0], AXP_REG_AT
);
3749 set_tok_sym (newtok
[1], sym
, 0);
3750 assemble_tokens ("lda", newtok
, 2, 1);
3752 /* Call the division routine */
3753 set_tok_reg (newtok
[0], AXP_REG_AT
);
3754 set_tok_cpreg (newtok
[1], AXP_REG_AT
);
3755 set_tok_const (newtok
[2], 0);
3756 assemble_tokens ("jsr", newtok
, 3, 1);
3758 /* Move the result to the right place */
3759 if (rr
!= AXP_REG_R0
)
3761 set_tok_reg (newtok
[0], AXP_REG_R0
);
3762 set_tok_reg (newtok
[1], rr
);
3763 assemble_tokens ("mov", newtok
, 2, 1);
3767 #else /* !OBJ_EVAX */
3770 emit_division (tok
, ntok
, symname
)
3771 const expressionS
*tok
;
3775 /* DIVISION and MODULUS. Yech.
3785 * with appropriate optimizations if t10,t11,t12 are the registers
3786 * specified by the compiler.
3791 expressionS newtok
[3];
3793 xr
= regno (tok
[0].X_add_number
);
3794 yr
= regno (tok
[1].X_add_number
);
3799 rr
= regno (tok
[2].X_add_number
);
3801 sym
= symbol_find_or_make ((const char *) symname
);
3803 /* Move the operands into the right place */
3804 if (yr
== AXP_REG_T10
&& xr
== AXP_REG_T11
)
3806 /* They are in exactly the wrong order -- swap through AT */
3809 as_bad (_("macro requires $at register while noat in effect"));
3811 set_tok_reg (newtok
[0], AXP_REG_T10
);
3812 set_tok_reg (newtok
[1], AXP_REG_AT
);
3813 assemble_tokens ("mov", newtok
, 2, 1);
3815 set_tok_reg (newtok
[0], AXP_REG_T11
);
3816 set_tok_reg (newtok
[1], AXP_REG_T10
);
3817 assemble_tokens ("mov", newtok
, 2, 1);
3819 set_tok_reg (newtok
[0], AXP_REG_AT
);
3820 set_tok_reg (newtok
[1], AXP_REG_T11
);
3821 assemble_tokens ("mov", newtok
, 2, 1);
3825 if (yr
== AXP_REG_T10
)
3827 set_tok_reg (newtok
[0], AXP_REG_T10
);
3828 set_tok_reg (newtok
[1], AXP_REG_T11
);
3829 assemble_tokens ("mov", newtok
, 2, 1);
3832 if (xr
!= AXP_REG_T10
)
3834 set_tok_reg (newtok
[0], xr
);
3835 set_tok_reg (newtok
[1], AXP_REG_T10
);
3836 assemble_tokens ("mov", newtok
, 2, 1);
3839 if (yr
!= AXP_REG_T10
&& yr
!= AXP_REG_T11
)
3841 set_tok_reg (newtok
[0], yr
);
3842 set_tok_reg (newtok
[1], AXP_REG_T11
);
3843 assemble_tokens ("mov", newtok
, 2, 1);
3847 /* Call the division routine */
3848 set_tok_reg (newtok
[0], AXP_REG_T9
);
3849 set_tok_sym (newtok
[1], sym
, 0);
3850 assemble_tokens ("jsr", newtok
, 2, 1);
3852 /* Reload the GP register */
3856 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
3857 set_tok_reg (newtok
[0], alpha_gp_register
);
3858 set_tok_const (newtok
[1], 0);
3859 set_tok_preg (newtok
[2], AXP_REG_T9
);
3860 assemble_tokens ("ldgp", newtok
, 3, 1);
3863 /* Move the result to the right place */
3864 if (rr
!= AXP_REG_T12
)
3866 set_tok_reg (newtok
[0], AXP_REG_T12
);
3867 set_tok_reg (newtok
[1], rr
);
3868 assemble_tokens ("mov", newtok
, 2, 1);
3872 #endif /* !OBJ_EVAX */
3874 /* The jsr and jmp macros differ from their instruction counterparts
3875 in that they can load the target address and default most
3879 emit_jsrjmp (tok
, ntok
, vopname
)
3880 const expressionS
*tok
;
3884 const char *opname
= (const char *) vopname
;
3885 struct alpha_insn insn
;
3886 expressionS newtok
[3];
3890 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_register
)
3891 r
= regno (tok
[tokidx
++].X_add_number
);
3893 r
= strcmp (opname
, "jmp") == 0 ? AXP_REG_ZERO
: AXP_REG_RA
;
3895 set_tok_reg (newtok
[0], r
);
3897 if (tokidx
< ntok
&&
3898 (tok
[tokidx
].X_op
== O_pregister
|| tok
[tokidx
].X_op
== O_cpregister
))
3899 r
= regno (tok
[tokidx
++].X_add_number
);
3901 /* keep register if jsr $n.<sym> */
3905 int basereg
= alpha_gp_register
;
3906 lituse
= load_expression (r
= AXP_REG_PV
, &tok
[tokidx
], &basereg
, NULL
);
3910 set_tok_cpreg (newtok
[1], r
);
3913 /* FIXME: Add hint relocs to BFD for evax. */
3916 newtok
[2] = tok
[tokidx
];
3919 set_tok_const (newtok
[2], 0);
3921 assemble_tokens_to_insn (opname
, newtok
, 3, &insn
);
3925 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3926 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_JSR
;
3927 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3929 insn
.sequence
= lituse
;
3935 /* The ret and jcr instructions differ from their instruction
3936 counterparts in that everything can be defaulted. */
3939 emit_retjcr (tok
, ntok
, vopname
)
3940 const expressionS
*tok
;
3944 const char *opname
= (const char *) vopname
;
3945 expressionS newtok
[3];
3948 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_register
)
3949 r
= regno (tok
[tokidx
++].X_add_number
);
3953 set_tok_reg (newtok
[0], r
);
3955 if (tokidx
< ntok
&&
3956 (tok
[tokidx
].X_op
== O_pregister
|| tok
[tokidx
].X_op
== O_cpregister
))
3957 r
= regno (tok
[tokidx
++].X_add_number
);
3961 set_tok_cpreg (newtok
[1], r
);
3964 newtok
[2] = tok
[tokidx
];
3966 set_tok_const (newtok
[2], strcmp (opname
, "ret") == 0);
3968 assemble_tokens (opname
, newtok
, 3, 0);
3971 /* Assembler directives */
3973 /* Handle the .text pseudo-op. This is like the usual one, but it
3974 clears alpha_insn_label and restores auto alignment. */
3982 alpha_insn_label
= NULL
;
3983 alpha_auto_align_on
= 1;
3984 alpha_current_align
= 0;
3987 /* Handle the .data pseudo-op. This is like the usual one, but it
3988 clears alpha_insn_label and restores auto alignment. */
3995 alpha_insn_label
= NULL
;
3996 alpha_auto_align_on
= 1;
3997 alpha_current_align
= 0;
4000 #if defined (OBJ_ECOFF) || defined (OBJ_EVAX)
4002 /* Handle the OSF/1 and openVMS .comm pseudo quirks.
4003 openVMS constructs a section for every common symbol. */
4006 s_alpha_comm (ignore
)
4009 register char *name
;
4013 register symbolS
*symbolP
;
4016 segT current_section
= now_seg
;
4017 int current_subsec
= now_subseg
;
4021 name
= input_line_pointer
;
4022 c
= get_symbol_end ();
4024 /* just after name is now '\0' */
4025 p
= input_line_pointer
;
4030 /* Alpha OSF/1 compiler doesn't provide the comma, gcc does. */
4031 if (*input_line_pointer
== ',')
4033 input_line_pointer
++;
4036 if ((temp
= get_absolute_expression ()) < 0)
4038 as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) temp
);
4039 ignore_rest_of_line ();
4044 symbolP
= symbol_find_or_make (name
);
4047 /* Make a section for the common symbol. */
4048 new_seg
= subseg_new (xstrdup (name
), 0);
4054 /* alignment might follow */
4055 if (*input_line_pointer
== ',')
4059 input_line_pointer
++;
4060 align
= get_absolute_expression ();
4061 bfd_set_section_alignment (stdoutput
, new_seg
, align
);
4065 if (S_IS_DEFINED (symbolP
) && ! S_IS_COMMON (symbolP
))
4067 as_bad (_("Ignoring attempt to re-define symbol"));
4068 ignore_rest_of_line ();
4073 if (bfd_section_size (stdoutput
, new_seg
) > 0)
4075 if (bfd_section_size (stdoutput
, new_seg
) != temp
)
4076 as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
4077 S_GET_NAME (symbolP
),
4078 (long) bfd_section_size (stdoutput
, new_seg
),
4082 if (S_GET_VALUE (symbolP
))
4084 if (S_GET_VALUE (symbolP
) != (valueT
) temp
)
4085 as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
4086 S_GET_NAME (symbolP
),
4087 (long) S_GET_VALUE (symbolP
),
4094 subseg_set (new_seg
, 0);
4095 p
= frag_more (temp
);
4096 new_seg
->flags
|= SEC_IS_COMMON
;
4097 if (! S_IS_DEFINED (symbolP
))
4098 S_SET_SEGMENT (symbolP
, new_seg
);
4100 S_SET_VALUE (symbolP
, (valueT
) temp
);
4102 S_SET_EXTERNAL (symbolP
);
4106 subseg_set (current_section
, current_subsec
);
4109 know (symbol_get_frag (symbolP
) == &zero_address_frag
);
4111 demand_empty_rest_of_line ();
4114 #endif /* ! OBJ_ELF */
4118 /* Handle the .rdata pseudo-op. This is like the usual one, but it
4119 clears alpha_insn_label and restores auto alignment. */
4122 s_alpha_rdata (ignore
)
4127 temp
= get_absolute_expression ();
4128 subseg_new (".rdata", 0);
4129 demand_empty_rest_of_line ();
4130 alpha_insn_label
= NULL
;
4131 alpha_auto_align_on
= 1;
4132 alpha_current_align
= 0;
4139 /* Handle the .sdata pseudo-op. This is like the usual one, but it
4140 clears alpha_insn_label and restores auto alignment. */
4143 s_alpha_sdata (ignore
)
4148 temp
= get_absolute_expression ();
4149 subseg_new (".sdata", 0);
4150 demand_empty_rest_of_line ();
4151 alpha_insn_label
= NULL
;
4152 alpha_auto_align_on
= 1;
4153 alpha_current_align
= 0;
4159 /* Handle the .section pseudo-op. This is like the usual one, but it
4160 clears alpha_insn_label and restores auto alignment. */
4163 s_alpha_section (ignore
)
4166 obj_elf_section (ignore
);
4168 alpha_insn_label
= NULL
;
4169 alpha_auto_align_on
= 1;
4170 alpha_current_align
= 0;
4175 int dummy ATTRIBUTE_UNUSED
;
4177 if (ECOFF_DEBUGGING
)
4178 ecoff_directive_ent (0);
4181 char *name
, name_end
;
4182 name
= input_line_pointer
;
4183 name_end
= get_symbol_end ();
4185 if (! is_name_beginner (*name
))
4187 as_warn (_(".ent directive has no name"));
4188 *input_line_pointer
= name_end
;
4194 if (alpha_cur_ent_sym
)
4195 as_warn (_("nested .ent directives"));
4197 sym
= symbol_find_or_make (name
);
4198 symbol_get_bfdsym (sym
)->flags
|= BSF_FUNCTION
;
4199 alpha_cur_ent_sym
= sym
;
4201 /* The .ent directive is sometimes followed by a number. Not sure
4202 what it really means, but ignore it. */
4203 *input_line_pointer
= name_end
;
4205 if (*input_line_pointer
== ',')
4207 input_line_pointer
++;
4210 if (ISDIGIT (*input_line_pointer
) || *input_line_pointer
== '-')
4211 (void) get_absolute_expression ();
4213 demand_empty_rest_of_line ();
4219 int dummy ATTRIBUTE_UNUSED
;
4221 if (ECOFF_DEBUGGING
)
4222 ecoff_directive_end (0);
4225 char *name
, name_end
;
4226 name
= input_line_pointer
;
4227 name_end
= get_symbol_end ();
4229 if (! is_name_beginner (*name
))
4231 as_warn (_(".end directive has no name"));
4232 *input_line_pointer
= name_end
;
4238 sym
= symbol_find (name
);
4239 if (sym
!= alpha_cur_ent_sym
)
4240 as_warn (_(".end directive names different symbol than .ent"));
4242 /* Create an expression to calculate the size of the function. */
4245 symbol_get_obj (sym
)->size
=
4246 (expressionS
*) xmalloc (sizeof (expressionS
));
4247 symbol_get_obj (sym
)->size
->X_op
= O_subtract
;
4248 symbol_get_obj (sym
)->size
->X_add_symbol
4249 = symbol_new ("L0\001", now_seg
, frag_now_fix (), frag_now
);
4250 symbol_get_obj (sym
)->size
->X_op_symbol
= sym
;
4251 symbol_get_obj (sym
)->size
->X_add_number
= 0;
4254 alpha_cur_ent_sym
= NULL
;
4256 *input_line_pointer
= name_end
;
4258 demand_empty_rest_of_line ();
4266 if (ECOFF_DEBUGGING
)
4269 ecoff_directive_fmask (0);
4271 ecoff_directive_mask (0);
4274 discard_rest_of_line ();
4278 s_alpha_frame (dummy
)
4279 int dummy ATTRIBUTE_UNUSED
;
4281 if (ECOFF_DEBUGGING
)
4282 ecoff_directive_frame (0);
4284 discard_rest_of_line ();
4288 s_alpha_prologue (ignore
)
4289 int ignore ATTRIBUTE_UNUSED
;
4294 arg
= get_absolute_expression ();
4295 demand_empty_rest_of_line ();
4297 if (ECOFF_DEBUGGING
)
4298 sym
= ecoff_get_cur_proc_sym ();
4300 sym
= alpha_cur_ent_sym
;
4305 case 0: /* No PV required. */
4306 S_SET_OTHER (sym
, STO_ALPHA_NOPV
4307 | (S_GET_OTHER (sym
) & ~STO_ALPHA_STD_GPLOAD
));
4309 case 1: /* Std GP load. */
4310 S_SET_OTHER (sym
, STO_ALPHA_STD_GPLOAD
4311 | (S_GET_OTHER (sym
) & ~STO_ALPHA_STD_GPLOAD
));
4313 case 2: /* Non-std use of PV. */
4317 as_bad (_("Invalid argument %d to .prologue."), arg
);
4322 static char *first_file_directive
;
4325 s_alpha_file (ignore
)
4326 int ignore ATTRIBUTE_UNUSED
;
4328 /* Save the first .file directive we see, so that we can change our
4329 minds about whether ecoff debugging should or shouldn't be enabled. */
4330 if (alpha_flag_mdebug
< 0 && ! first_file_directive
)
4332 char *start
= input_line_pointer
;
4335 discard_rest_of_line ();
4337 len
= input_line_pointer
- start
;
4338 first_file_directive
= xmalloc (len
+ 1);
4339 memcpy (first_file_directive
, start
, len
);
4340 first_file_directive
[len
] = '\0';
4342 input_line_pointer
= start
;
4345 if (ECOFF_DEBUGGING
)
4346 ecoff_directive_file (0);
4348 dwarf2_directive_file (0);
4352 s_alpha_loc (ignore
)
4353 int ignore ATTRIBUTE_UNUSED
;
4355 if (ECOFF_DEBUGGING
)
4356 ecoff_directive_loc (0);
4358 dwarf2_directive_loc (0);
4365 /* If we've been undecided about mdebug, make up our minds in favour. */
4366 if (alpha_flag_mdebug
< 0)
4368 segT sec
= subseg_new (".mdebug", 0);
4369 bfd_set_section_flags (stdoutput
, sec
, SEC_HAS_CONTENTS
| SEC_READONLY
);
4370 bfd_set_section_alignment (stdoutput
, sec
, 3);
4372 ecoff_read_begin_hook ();
4374 if (first_file_directive
)
4376 char *save_ilp
= input_line_pointer
;
4377 input_line_pointer
= first_file_directive
;
4378 ecoff_directive_file (0);
4379 input_line_pointer
= save_ilp
;
4380 free (first_file_directive
);
4383 alpha_flag_mdebug
= 1;
4389 s_alpha_coff_wrapper (which
)
4392 static void (* const fns
[]) PARAMS ((int)) = {
4393 ecoff_directive_begin
,
4394 ecoff_directive_bend
,
4395 ecoff_directive_def
,
4396 ecoff_directive_dim
,
4397 ecoff_directive_endef
,
4398 ecoff_directive_scl
,
4399 ecoff_directive_tag
,
4400 ecoff_directive_val
,
4403 assert (which
>= 0 && which
< (int) (sizeof (fns
)/sizeof (*fns
)));
4405 if (ECOFF_DEBUGGING
)
4409 as_bad (_("ECOFF debugging is disabled."));
4410 ignore_rest_of_line ();
4413 #endif /* OBJ_ELF */
4417 /* Handle the section specific pseudo-op. */
4420 s_alpha_section (secid
)
4424 #define EVAX_SECTION_COUNT 5
4425 static char *section_name
[EVAX_SECTION_COUNT
+ 1] =
4426 { "NULL", ".rdata", ".comm", ".link", ".ctors", ".dtors" };
4428 if ((secid
<= 0) || (secid
> EVAX_SECTION_COUNT
))
4430 as_fatal (_("Unknown section directive"));
4431 demand_empty_rest_of_line ();
4434 temp
= get_absolute_expression ();
4435 subseg_new (section_name
[secid
], 0);
4436 demand_empty_rest_of_line ();
4437 alpha_insn_label
= NULL
;
4438 alpha_auto_align_on
= 1;
4439 alpha_current_align
= 0;
4442 /* Parse .ent directives. */
4445 s_alpha_ent (ignore
)
4449 expressionS symexpr
;
4451 alpha_evax_proc
.pdsckind
= 0;
4452 alpha_evax_proc
.framereg
= -1;
4453 alpha_evax_proc
.framesize
= 0;
4454 alpha_evax_proc
.rsa_offset
= 0;
4455 alpha_evax_proc
.ra_save
= AXP_REG_RA
;
4456 alpha_evax_proc
.fp_save
= -1;
4457 alpha_evax_proc
.imask
= 0;
4458 alpha_evax_proc
.fmask
= 0;
4459 alpha_evax_proc
.prologue
= 0;
4460 alpha_evax_proc
.type
= 0;
4462 expression (&symexpr
);
4464 if (symexpr
.X_op
!= O_symbol
)
4466 as_fatal (_(".ent directive has no symbol"));
4467 demand_empty_rest_of_line ();
4471 symbol
= make_expr_symbol (&symexpr
);
4472 symbol_get_bfdsym (symbol
)->flags
|= BSF_FUNCTION
;
4473 alpha_evax_proc
.symbol
= symbol
;
4475 demand_empty_rest_of_line ();
4479 /* Parse .frame <framreg>,<framesize>,RA,<rsa_offset> directives. */
4482 s_alpha_frame (ignore
)
4487 alpha_evax_proc
.framereg
= tc_get_register (1);
4490 if (*input_line_pointer
++ != ','
4491 || get_absolute_expression_and_terminator (&val
) != ',')
4493 as_warn (_("Bad .frame directive 1./2. param"));
4494 --input_line_pointer
;
4495 demand_empty_rest_of_line ();
4499 alpha_evax_proc
.framesize
= val
;
4501 (void) tc_get_register (1);
4503 if (*input_line_pointer
++ != ',')
4505 as_warn (_("Bad .frame directive 3./4. param"));
4506 --input_line_pointer
;
4507 demand_empty_rest_of_line ();
4510 alpha_evax_proc
.rsa_offset
= get_absolute_expression ();
4516 s_alpha_pdesc (ignore
)
4526 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
4528 if (now_seg
!= alpha_link_section
)
4530 as_bad (_(".pdesc directive not in link (.link) section"));
4531 demand_empty_rest_of_line ();
4535 if ((alpha_evax_proc
.symbol
== 0)
4536 || (!S_IS_DEFINED (alpha_evax_proc
.symbol
)))
4538 as_fatal (_(".pdesc has no matching .ent"));
4539 demand_empty_rest_of_line ();
4543 *symbol_get_obj (alpha_evax_proc
.symbol
) =
4544 (valueT
) seginfo
->literal_pool_size
;
4547 if (exp
.X_op
!= O_symbol
)
4549 as_warn (_(".pdesc directive has no entry symbol"));
4550 demand_empty_rest_of_line ();
4554 entry_sym
= make_expr_symbol (&exp
);
4555 /* Save bfd symbol of proc desc in function symbol. */
4556 symbol_get_bfdsym (alpha_evax_proc
.symbol
)->udata
.p
4557 = symbol_get_bfdsym (entry_sym
);
4560 if (*input_line_pointer
++ != ',')
4562 as_warn (_("No comma after .pdesc <entryname>"));
4563 demand_empty_rest_of_line ();
4568 name
= input_line_pointer
;
4569 name_end
= get_symbol_end ();
4571 if (strncmp (name
, "stack", 5) == 0)
4573 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_FP_STACK
;
4575 else if (strncmp (name
, "reg", 3) == 0)
4577 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_FP_REGISTER
;
4579 else if (strncmp (name
, "null", 4) == 0)
4581 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_NULL
;
4585 as_fatal (_("unknown procedure kind"));
4586 demand_empty_rest_of_line ();
4590 *input_line_pointer
= name_end
;
4591 demand_empty_rest_of_line ();
4593 #ifdef md_flush_pending_output
4594 md_flush_pending_output ();
4597 frag_align (3, 0, 0);
4599 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
4601 seginfo
->literal_pool_size
+= 16;
4603 *p
= alpha_evax_proc
.pdsckind
4604 | ((alpha_evax_proc
.framereg
== 29) ? PDSC_S_M_BASE_REG_IS_FP
: 0);
4605 *(p
+ 1) = PDSC_S_M_NATIVE
| PDSC_S_M_NO_JACKET
;
4607 switch (alpha_evax_proc
.pdsckind
)
4609 case PDSC_S_K_KIND_NULL
:
4613 case PDSC_S_K_KIND_FP_REGISTER
:
4614 *(p
+ 2) = alpha_evax_proc
.fp_save
;
4615 *(p
+ 3) = alpha_evax_proc
.ra_save
;
4617 case PDSC_S_K_KIND_FP_STACK
:
4618 md_number_to_chars (p
+ 2, (valueT
) alpha_evax_proc
.rsa_offset
, 2);
4620 default: /* impossible */
4625 *(p
+ 5) = alpha_evax_proc
.type
& 0x0f;
4627 /* Signature offset. */
4628 md_number_to_chars (p
+ 6, (valueT
) 0, 2);
4630 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
+8, 8, &exp
, 0, BFD_RELOC_64
);
4632 if (alpha_evax_proc
.pdsckind
== PDSC_S_K_KIND_NULL
)
4635 /* Add dummy fix to make add_to_link_pool work. */
4637 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
4639 seginfo
->literal_pool_size
+= 8;
4641 /* pdesc+16: Size. */
4642 md_number_to_chars (p
, (valueT
) alpha_evax_proc
.framesize
, 4);
4644 md_number_to_chars (p
+ 4, (valueT
) 0, 2);
4647 md_number_to_chars (p
+ 6, alpha_evax_proc
.prologue
, 2);
4649 if (alpha_evax_proc
.pdsckind
== PDSC_S_K_KIND_FP_REGISTER
)
4652 /* Add dummy fix to make add_to_link_pool work. */
4654 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
4656 seginfo
->literal_pool_size
+= 8;
4658 /* pdesc+24: register masks. */
4660 md_number_to_chars (p
, alpha_evax_proc
.imask
, 4);
4661 md_number_to_chars (p
+ 4, alpha_evax_proc
.fmask
, 4);
4666 /* Support for crash debug on vms. */
4669 s_alpha_name (ignore
)
4674 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
4676 if (now_seg
!= alpha_link_section
)
4678 as_bad (_(".name directive not in link (.link) section"));
4679 demand_empty_rest_of_line ();
4684 if (exp
.X_op
!= O_symbol
)
4686 as_warn (_(".name directive has no symbol"));
4687 demand_empty_rest_of_line ();
4691 demand_empty_rest_of_line ();
4693 #ifdef md_flush_pending_output
4694 md_flush_pending_output ();
4697 frag_align (3, 0, 0);
4699 seginfo
->literal_pool_size
+= 8;
4701 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 8, &exp
, 0, BFD_RELOC_64
);
4707 s_alpha_linkage (ignore
)
4713 #ifdef md_flush_pending_output
4714 md_flush_pending_output ();
4718 if (exp
.X_op
!= O_symbol
)
4720 as_fatal (_("No symbol after .linkage"));
4724 p
= frag_more (LKP_S_K_SIZE
);
4725 memset (p
, 0, LKP_S_K_SIZE
);
4726 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, LKP_S_K_SIZE
, &exp
, 0,\
4727 BFD_RELOC_ALPHA_LINKAGE
);
4729 demand_empty_rest_of_line ();
4735 s_alpha_code_address (ignore
)
4741 #ifdef md_flush_pending_output
4742 md_flush_pending_output ();
4746 if (exp
.X_op
!= O_symbol
)
4748 as_fatal (_("No symbol after .code_address"));
4754 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 8, &exp
, 0,\
4755 BFD_RELOC_ALPHA_CODEADDR
);
4757 demand_empty_rest_of_line ();
4763 s_alpha_fp_save (ignore
)
4767 alpha_evax_proc
.fp_save
= tc_get_register (1);
4769 demand_empty_rest_of_line ();
4774 s_alpha_mask (ignore
)
4779 if (get_absolute_expression_and_terminator (&val
) != ',')
4781 as_warn (_("Bad .mask directive"));
4782 --input_line_pointer
;
4786 alpha_evax_proc
.imask
= val
;
4787 (void) get_absolute_expression ();
4789 demand_empty_rest_of_line ();
4795 s_alpha_fmask (ignore
)
4800 if (get_absolute_expression_and_terminator (&val
) != ',')
4802 as_warn (_("Bad .fmask directive"));
4803 --input_line_pointer
;
4807 alpha_evax_proc
.fmask
= val
;
4808 (void) get_absolute_expression ();
4810 demand_empty_rest_of_line ();
4816 s_alpha_end (ignore
)
4821 c
= get_symbol_end ();
4822 *input_line_pointer
= c
;
4823 demand_empty_rest_of_line ();
4824 alpha_evax_proc
.symbol
= 0;
4830 s_alpha_file (ignore
)
4835 static char case_hack
[32];
4837 extern char *demand_copy_string
PARAMS ((int *lenP
));
4839 sprintf (case_hack
, "<CASE:%01d%01d>",
4840 alpha_flag_hash_long_names
, alpha_flag_show_after_trunc
);
4842 s
= symbol_find_or_make (case_hack
);
4843 symbol_get_bfdsym (s
)->flags
|= BSF_FILE
;
4845 get_absolute_expression ();
4846 s
= symbol_find_or_make (demand_copy_string (&length
));
4847 symbol_get_bfdsym (s
)->flags
|= BSF_FILE
;
4848 demand_empty_rest_of_line ();
4852 #endif /* OBJ_EVAX */
4854 /* Handle the .gprel32 pseudo op. */
4857 s_alpha_gprel32 (ignore
)
4858 int ignore ATTRIBUTE_UNUSED
;
4870 e
.X_add_symbol
= section_symbol (absolute_section
);
4883 e
.X_add_symbol
= section_symbol (absolute_section
);
4886 e
.X_op
= O_subtract
;
4887 e
.X_op_symbol
= alpha_gp_symbol
;
4895 if (alpha_auto_align_on
&& alpha_current_align
< 2)
4896 alpha_align (2, (char *) NULL
, alpha_insn_label
, 0);
4897 if (alpha_current_align
> 2)
4898 alpha_current_align
= 2;
4899 alpha_insn_label
= NULL
;
4903 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 4,
4904 &e
, 0, BFD_RELOC_GPREL32
);
4907 /* Handle floating point allocation pseudo-ops. This is like the
4908 generic vresion, but it makes sure the current label, if any, is
4909 correctly aligned. */
4912 s_alpha_float_cons (type
)
4939 if (alpha_auto_align_on
&& alpha_current_align
< log_size
)
4940 alpha_align (log_size
, (char *) NULL
, alpha_insn_label
, 0);
4941 if (alpha_current_align
> log_size
)
4942 alpha_current_align
= log_size
;
4943 alpha_insn_label
= NULL
;
4948 /* Handle the .proc pseudo op. We don't really do much with it except
4952 s_alpha_proc (is_static
)
4953 int is_static ATTRIBUTE_UNUSED
;
4961 /* Takes ".proc name,nargs" */
4963 name
= input_line_pointer
;
4964 c
= get_symbol_end ();
4965 p
= input_line_pointer
;
4966 symbolP
= symbol_find_or_make (name
);
4969 if (*input_line_pointer
!= ',')
4972 as_warn (_("Expected comma after name \"%s\""), name
);
4975 ignore_rest_of_line ();
4979 input_line_pointer
++;
4980 temp
= get_absolute_expression ();
4982 /* *symbol_get_obj (symbolP) = (signed char) temp; */
4983 as_warn (_("unhandled: .proc %s,%d"), name
, temp
);
4984 demand_empty_rest_of_line ();
4987 /* Handle the .set pseudo op. This is used to turn on and off most of
4988 the assembler features. */
4992 int x ATTRIBUTE_UNUSED
;
4998 name
= input_line_pointer
;
4999 ch
= get_symbol_end ();
5002 if (s
[0] == 'n' && s
[1] == 'o')
5007 if (!strcmp ("reorder", s
))
5009 else if (!strcmp ("at", s
))
5010 alpha_noat_on
= !yesno
;
5011 else if (!strcmp ("macro", s
))
5012 alpha_macros_on
= yesno
;
5013 else if (!strcmp ("move", s
))
5015 else if (!strcmp ("volatile", s
))
5018 as_warn (_("Tried to .set unrecognized mode `%s'"), name
);
5020 *input_line_pointer
= ch
;
5021 demand_empty_rest_of_line ();
5024 /* Handle the .base pseudo op. This changes the assembler's notion of
5025 the $gp register. */
5028 s_alpha_base (ignore
)
5029 int ignore ATTRIBUTE_UNUSED
;
5032 if (first_32bit_quadrant
)
5034 /* not fatal, but it might not work in the end */
5035 as_warn (_("File overrides no-base-register option."));
5036 first_32bit_quadrant
= 0;
5041 if (*input_line_pointer
== '$')
5043 input_line_pointer
++;
5044 if (*input_line_pointer
== 'r')
5045 input_line_pointer
++;
5048 alpha_gp_register
= get_absolute_expression ();
5049 if (alpha_gp_register
< 0 || alpha_gp_register
> 31)
5051 alpha_gp_register
= AXP_REG_GP
;
5052 as_warn (_("Bad base register, using $%d."), alpha_gp_register
);
5055 demand_empty_rest_of_line ();
5058 /* Handle the .align pseudo-op. This aligns to a power of two. It
5059 also adjusts any current instruction label. We treat this the same
5060 way the MIPS port does: .align 0 turns off auto alignment. */
5063 s_alpha_align (ignore
)
5064 int ignore ATTRIBUTE_UNUSED
;
5068 long max_alignment
= 15;
5070 align
= get_absolute_expression ();
5071 if (align
> max_alignment
)
5073 align
= max_alignment
;
5074 as_bad (_("Alignment too large: %d. assumed"), align
);
5078 as_warn (_("Alignment negative: 0 assumed"));
5082 if (*input_line_pointer
== ',')
5084 input_line_pointer
++;
5085 fill
= get_absolute_expression ();
5093 alpha_auto_align_on
= 1;
5094 alpha_align (align
, pfill
, alpha_insn_label
, 1);
5098 alpha_auto_align_on
= 0;
5101 demand_empty_rest_of_line ();
5104 /* Hook the normal string processor to reset known alignment. */
5107 s_alpha_stringer (terminate
)
5110 alpha_current_align
= 0;
5111 alpha_insn_label
= NULL
;
5112 stringer (terminate
);
5115 /* Hook the normal space processing to reset known alignment. */
5118 s_alpha_space (ignore
)
5121 alpha_current_align
= 0;
5122 alpha_insn_label
= NULL
;
5126 /* Hook into cons for auto-alignment. */
5129 alpha_cons_align (size
)
5135 while ((size
>>= 1) != 0)
5138 if (alpha_auto_align_on
&& alpha_current_align
< log_size
)
5139 alpha_align (log_size
, (char *) NULL
, alpha_insn_label
, 0);
5140 if (alpha_current_align
> log_size
)
5141 alpha_current_align
= log_size
;
5142 alpha_insn_label
= NULL
;
5145 /* Here come the .uword, .ulong, and .uquad explicitly unaligned
5146 pseudos. We just turn off auto-alignment and call down to cons. */
5149 s_alpha_ucons (bytes
)
5152 int hold
= alpha_auto_align_on
;
5153 alpha_auto_align_on
= 0;
5155 alpha_auto_align_on
= hold
;
5158 /* Switch the working cpu type. */
5161 s_alpha_arch (ignored
)
5162 int ignored ATTRIBUTE_UNUSED
;
5165 const struct cpu_type
*p
;
5168 name
= input_line_pointer
;
5169 ch
= get_symbol_end ();
5171 for (p
= cpu_types
; p
->name
; ++p
)
5172 if (strcmp (name
, p
->name
) == 0)
5174 alpha_target_name
= p
->name
, alpha_target
= p
->flags
;
5177 as_warn ("Unknown CPU identifier `%s'", name
);
5180 *input_line_pointer
= ch
;
5181 demand_empty_rest_of_line ();
5185 /* print token expression with alpha specific extension. */
5188 alpha_print_token (f
, exp
)
5190 const expressionS
*exp
;
5200 expressionS nexp
= *exp
;
5201 nexp
.X_op
= O_register
;
5202 print_expr (f
, &nexp
);
5207 print_expr (f
, exp
);
5214 /* The target specific pseudo-ops which we support. */
5216 const pseudo_typeS md_pseudo_table
[] = {
5218 {"comm", s_alpha_comm
, 0}, /* osf1 compiler does this */
5219 {"rdata", s_alpha_rdata
, 0},
5221 {"text", s_alpha_text
, 0},
5222 {"data", s_alpha_data
, 0},
5224 {"sdata", s_alpha_sdata
, 0},
5227 {"section", s_alpha_section
, 0},
5228 {"section.s", s_alpha_section
, 0},
5229 {"sect", s_alpha_section
, 0},
5230 {"sect.s", s_alpha_section
, 0},
5233 { "pdesc", s_alpha_pdesc
, 0},
5234 { "name", s_alpha_name
, 0},
5235 { "linkage", s_alpha_linkage
, 0},
5236 { "code_address", s_alpha_code_address
, 0},
5237 { "ent", s_alpha_ent
, 0},
5238 { "frame", s_alpha_frame
, 0},
5239 { "fp_save", s_alpha_fp_save
, 0},
5240 { "mask", s_alpha_mask
, 0},
5241 { "fmask", s_alpha_fmask
, 0},
5242 { "end", s_alpha_end
, 0},
5243 { "file", s_alpha_file
, 0},
5244 { "rdata", s_alpha_section
, 1},
5245 { "comm", s_alpha_comm
, 0},
5246 { "link", s_alpha_section
, 3},
5247 { "ctors", s_alpha_section
, 4},
5248 { "dtors", s_alpha_section
, 5},
5251 /* Frame related pseudos. */
5252 {"ent", s_alpha_ent
, 0},
5253 {"end", s_alpha_end
, 0},
5254 {"mask", s_alpha_mask
, 0},
5255 {"fmask", s_alpha_mask
, 1},
5256 {"frame", s_alpha_frame
, 0},
5257 {"prologue", s_alpha_prologue
, 0},
5258 {"file", s_alpha_file
, 5},
5259 {"loc", s_alpha_loc
, 9},
5260 {"stabs", s_alpha_stab
, 's'},
5261 {"stabn", s_alpha_stab
, 'n'},
5262 /* COFF debugging related pseudos. */
5263 {"begin", s_alpha_coff_wrapper
, 0},
5264 {"bend", s_alpha_coff_wrapper
, 1},
5265 {"def", s_alpha_coff_wrapper
, 2},
5266 {"dim", s_alpha_coff_wrapper
, 3},
5267 {"endef", s_alpha_coff_wrapper
, 4},
5268 {"scl", s_alpha_coff_wrapper
, 5},
5269 {"tag", s_alpha_coff_wrapper
, 6},
5270 {"val", s_alpha_coff_wrapper
, 7},
5272 {"prologue", s_ignore
, 0},
5274 {"gprel32", s_alpha_gprel32
, 0},
5275 {"t_floating", s_alpha_float_cons
, 'd'},
5276 {"s_floating", s_alpha_float_cons
, 'f'},
5277 {"f_floating", s_alpha_float_cons
, 'F'},
5278 {"g_floating", s_alpha_float_cons
, 'G'},
5279 {"d_floating", s_alpha_float_cons
, 'D'},
5281 {"proc", s_alpha_proc
, 0},
5282 {"aproc", s_alpha_proc
, 1},
5283 {"set", s_alpha_set
, 0},
5284 {"reguse", s_ignore
, 0},
5285 {"livereg", s_ignore
, 0},
5286 {"base", s_alpha_base
, 0}, /*??*/
5287 {"option", s_ignore
, 0},
5288 {"aent", s_ignore
, 0},
5289 {"ugen", s_ignore
, 0},
5290 {"eflag", s_ignore
, 0},
5292 {"align", s_alpha_align
, 0},
5293 {"double", s_alpha_float_cons
, 'd'},
5294 {"float", s_alpha_float_cons
, 'f'},
5295 {"single", s_alpha_float_cons
, 'f'},
5296 {"ascii", s_alpha_stringer
, 0},
5297 {"asciz", s_alpha_stringer
, 1},
5298 {"string", s_alpha_stringer
, 1},
5299 {"space", s_alpha_space
, 0},
5300 {"skip", s_alpha_space
, 0},
5301 {"zero", s_alpha_space
, 0},
5303 /* Unaligned data pseudos. */
5304 {"uword", s_alpha_ucons
, 2},
5305 {"ulong", s_alpha_ucons
, 4},
5306 {"uquad", s_alpha_ucons
, 8},
5309 /* Dwarf wants these versions of unaligned. */
5310 {"2byte", s_alpha_ucons
, 2},
5311 {"4byte", s_alpha_ucons
, 4},
5312 {"8byte", s_alpha_ucons
, 8},
5315 /* We don't do any optimizing, so we can safely ignore these. */
5316 {"noalias", s_ignore
, 0},
5317 {"alias", s_ignore
, 0},
5319 {"arch", s_alpha_arch
, 0},
5324 /* Build a BFD section with its flags set appropriately for the .lita,
5325 .lit8, or .lit4 sections. */
5328 create_literal_section (name
, secp
, symp
)
5333 segT current_section
= now_seg
;
5334 int current_subsec
= now_subseg
;
5337 *secp
= new_sec
= subseg_new (name
, 0);
5338 subseg_set (current_section
, current_subsec
);
5339 bfd_set_section_alignment (stdoutput
, new_sec
, 4);
5340 bfd_set_section_flags (stdoutput
, new_sec
,
5341 SEC_RELOC
| SEC_ALLOC
| SEC_LOAD
| SEC_READONLY
5344 S_CLEAR_EXTERNAL (*symp
= section_symbol (new_sec
));
5349 /* @@@ GP selection voodoo. All of this seems overly complicated and
5350 unnecessary; which is the primary reason it's for ECOFF only. */
5359 vma
= bfd_get_section_vma (foo
, sec
);
5360 if (vma
&& vma
< alpha_gp_value
)
5361 alpha_gp_value
= vma
;
5367 assert (alpha_gp_value
== 0);
5369 /* Get minus-one in whatever width... */
5373 /* Select the smallest VMA of these existing sections. */
5374 maybe_set_gp (alpha_lita_section
);
5376 /* These were disabled before -- should we use them? */
5377 maybe_set_gp (sdata
);
5378 maybe_set_gp (lit8_sec
);
5379 maybe_set_gp (lit4_sec
);
5382 /* @@ Will a simple 0x8000 work here? If not, why not? */
5383 #define GP_ADJUSTMENT (0x8000 - 0x10)
5385 alpha_gp_value
+= GP_ADJUSTMENT
;
5387 S_SET_VALUE (alpha_gp_symbol
, alpha_gp_value
);
5390 printf (_("Chose GP value of %lx\n"), alpha_gp_value
);
5393 #endif /* OBJ_ECOFF */
5396 /* Map 's' to SHF_ALPHA_GPREL. */
5399 alpha_elf_section_letter (letter
, ptr_msg
)
5404 return SHF_ALPHA_GPREL
;
5406 *ptr_msg
= _("Bad .section directive: want a,s,w,x,M,S in string");
5410 /* Map SHF_ALPHA_GPREL to SEC_SMALL_DATA. */
5413 alpha_elf_section_flags (flags
, attr
, type
)
5415 int attr
, type ATTRIBUTE_UNUSED
;
5417 if (attr
& SHF_ALPHA_GPREL
)
5418 flags
|= SEC_SMALL_DATA
;
5421 #endif /* OBJ_ELF */
5423 /* Called internally to handle all alignment needs. This takes care
5424 of eliding calls to frag_align if'n the cached current alignment
5425 says we've already got it, as well as taking care of the auto-align
5426 feature wrt labels. */
5429 alpha_align (n
, pfill
, label
, force
)
5433 int force ATTRIBUTE_UNUSED
;
5435 if (alpha_current_align
>= n
)
5440 if (subseg_text_p (now_seg
))
5441 frag_align_code (n
, 0);
5443 frag_align (n
, 0, 0);
5446 frag_align (n
, *pfill
, 0);
5448 alpha_current_align
= n
;
5450 if (label
!= NULL
&& S_GET_SEGMENT (label
) == now_seg
)
5452 symbol_set_frag (label
, frag_now
);
5453 S_SET_VALUE (label
, (valueT
) frag_now_fix ());
5456 record_alignment (now_seg
, n
);
5458 /* ??? If alpha_flag_relax && force && elf, record the requested alignment
5459 in a reloc for the linker to see. */
5462 /* This is called from HANDLE_ALIGN in write.c. Fill in the contents
5463 of an rs_align_code fragment. */
5466 alpha_handle_align (fragp
)
5469 static char const unop
[4] = { 0x00, 0x00, 0xfe, 0x2f };
5470 static char const nopunop
[8] = {
5471 0x1f, 0x04, 0xff, 0x47,
5472 0x00, 0x00, 0xfe, 0x2f
5478 if (fragp
->fr_type
!= rs_align_code
)
5481 bytes
= fragp
->fr_next
->fr_address
- fragp
->fr_address
- fragp
->fr_fix
;
5482 p
= fragp
->fr_literal
+ fragp
->fr_fix
;
5495 memcpy (p
, unop
, 4);
5501 memcpy (p
, nopunop
, 8);
5503 fragp
->fr_fix
+= fix
;
5507 /* The Alpha has support for some VAX floating point types, as well as for
5508 IEEE floating point. We consider IEEE to be the primary floating point
5509 format, and sneak in the VAX floating point support here. */
5510 #define md_atof vax_md_atof
5511 #include "config/atof-vax.c"