1 /* tc-alpha.c - Processor-specific code for the DEC Alpha AXP CPU.
2 Copyright (C) 1989, 93-98, 1999, 2000 Free Software Foundation, Inc.
3 Contributed by Carnegie Mellon University, 1993.
4 Written by Alessandro Forin, based on earlier gas-1.38 target CPU files.
5 Modified by Ken Raeburn for gas-2.x and ECOFF support.
6 Modified by Richard Henderson for ELF support.
7 Modified by Klaus K"ampf for EVAX (OpenVMS/Alpha) support.
9 This file is part of GAS, the GNU Assembler.
11 GAS is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2, or (at your option)
16 GAS is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with GAS; see the file COPYING. If not, write to the Free
23 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
27 * Mach Operating System
28 * Copyright (c) 1993 Carnegie Mellon University
29 * All Rights Reserved.
31 * Permission to use, copy, modify and distribute this software and its
32 * documentation is hereby granted, provided that both the copyright
33 * notice and this permission notice appear in all copies of the
34 * software, derivative works or modified versions, and any portions
35 * thereof, and that both notices appear in supporting documentation.
37 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
38 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
39 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
41 * Carnegie Mellon requests users of this software to return to
43 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
44 * School of Computer Science
45 * Carnegie Mellon University
46 * Pittsburgh PA 15213-3890
48 * any improvements or extensions that they make and grant Carnegie the
49 * rights to redistribute these changes.
54 #include "struc-symbol.h"
57 #include "opcode/alpha.h"
60 #include "elf/alpha.h"
61 #include "dwarf2dbg.h"
69 #define TOKENIZE_ERROR -1
70 #define TOKENIZE_ERROR_REPORT -2
72 #define MAX_INSN_FIXUPS 2
73 #define MAX_INSN_ARGS 5
78 bfd_reloc_code_real_type reloc
;
85 struct alpha_fixup fixups
[MAX_INSN_FIXUPS
];
86 unsigned sequence
[MAX_INSN_FIXUPS
];
107 void (*emit
) PARAMS ((const expressionS
*, int, const PTR
));
109 enum alpha_macro_arg argsets
[16];
112 /* Extra expression types. */
114 #define O_pregister O_md1 /* O_register, in parentheses */
115 #define O_cpregister O_md2 /* + a leading comma */
118 /* Note, the alpha_reloc_op table below depends on the ordering
119 of O_literal .. O_gprelow. */
120 #define O_literal O_md3 /* !literal relocation */
121 #define O_lituse_base O_md4 /* !lituse_base relocation */
122 #define O_lituse_bytoff O_md5 /* !lituse_bytoff relocation */
123 #define O_lituse_jsr O_md6 /* !lituse_jsr relocation */
124 #define O_gpdisp O_md7 /* !gpdisp relocation */
125 #define O_gprelhigh O_md8 /* !gprelhigh relocation */
126 #define O_gprellow O_md9 /* !gprellow relocation */
128 #define USER_RELOC_P(R) ((R) >= O_literal && (R) <= O_gprellow)
131 /* Macros for extracting the type and number of encoded register tokens */
133 #define is_ir_num(x) (((x) & 32) == 0)
134 #define is_fpr_num(x) (((x) & 32) != 0)
135 #define regno(x) ((x) & 31)
137 /* Something odd inherited from the old assembler */
139 #define note_gpreg(R) (alpha_gprmask |= (1 << (R)))
140 #define note_fpreg(R) (alpha_fprmask |= (1 << (R)))
142 /* Predicates for 16- and 32-bit ranges */
143 /* XXX: The non-shift version appears to trigger a compiler bug when
144 cross-assembling from x86 w/ gcc 2.7.2. */
147 #define range_signed_16(x) \
148 (((offsetT)(x) >> 15) == 0 || ((offsetT)(x) >> 15) == -1)
149 #define range_signed_32(x) \
150 (((offsetT)(x) >> 31) == 0 || ((offsetT)(x) >> 31) == -1)
152 #define range_signed_16(x) ((offsetT)(x) >= -(offsetT)0x8000 && \
153 (offsetT)(x) <= (offsetT)0x7FFF)
154 #define range_signed_32(x) ((offsetT)(x) >= -(offsetT)0x80000000 && \
155 (offsetT)(x) <= (offsetT)0x7FFFFFFF)
158 /* Macros for sign extending from 16- and 32-bits. */
159 /* XXX: The cast macros will work on all the systems that I care about,
160 but really a predicate should be found to use the non-cast forms. */
163 #define sign_extend_16(x) ((short)(x))
164 #define sign_extend_32(x) ((int)(x))
166 #define sign_extend_16(x) ((offsetT)(((x) & 0xFFFF) ^ 0x8000) - 0x8000)
167 #define sign_extend_32(x) ((offsetT)(((x) & 0xFFFFFFFF) \
168 ^ 0x80000000) - 0x80000000)
171 /* Macros to build tokens */
173 #define set_tok_reg(t, r) (memset(&(t), 0, sizeof(t)), \
174 (t).X_op = O_register, \
175 (t).X_add_number = (r))
176 #define set_tok_preg(t, r) (memset(&(t), 0, sizeof(t)), \
177 (t).X_op = O_pregister, \
178 (t).X_add_number = (r))
179 #define set_tok_cpreg(t, r) (memset(&(t), 0, sizeof(t)), \
180 (t).X_op = O_cpregister, \
181 (t).X_add_number = (r))
182 #define set_tok_freg(t, r) (memset(&(t), 0, sizeof(t)), \
183 (t).X_op = O_register, \
184 (t).X_add_number = (r)+32)
185 #define set_tok_sym(t, s, a) (memset(&(t), 0, sizeof(t)), \
186 (t).X_op = O_symbol, \
187 (t).X_add_symbol = (s), \
188 (t).X_add_number = (a))
189 #define set_tok_const(t, n) (memset(&(t), 0, sizeof(t)), \
190 (t).X_op = O_constant, \
191 (t).X_add_number = (n))
194 /* Prototypes for all local functions */
196 static int tokenize_arguments
PARAMS ((char *, expressionS
*, int));
197 static const struct alpha_opcode
*find_opcode_match
198 PARAMS ((const struct alpha_opcode
*, const expressionS
*, int *, int *));
199 static const struct alpha_macro
*find_macro_match
200 PARAMS ((const struct alpha_macro
*, const expressionS
*, int *));
201 static unsigned insert_operand
202 PARAMS ((unsigned, const struct alpha_operand
*, offsetT
, char *, unsigned));
203 static void assemble_insn
204 PARAMS ((const struct alpha_opcode
*, const expressionS
*, int,
205 struct alpha_insn
*));
206 static void emit_insn
PARAMS ((struct alpha_insn
*));
207 static void assemble_tokens_to_insn
208 PARAMS ((const char *, const expressionS
*, int, struct alpha_insn
*));
209 static void assemble_tokens
210 PARAMS ((const char *, const expressionS
*, int, int));
212 static int load_expression
213 PARAMS ((int, const expressionS
*, int *, expressionS
*,
214 const expressionS
*));
216 static void emit_ldgp
PARAMS ((const expressionS
*, int, const PTR
));
217 static void emit_division
PARAMS ((const expressionS
*, int, const PTR
));
218 static void emit_lda
PARAMS ((const expressionS
*, int, const PTR
));
219 static void emit_ldah
PARAMS ((const expressionS
*, int, const PTR
));
220 static void emit_ir_load
PARAMS ((const expressionS
*, int, const PTR
));
221 static void emit_loadstore
PARAMS ((const expressionS
*, int, const PTR
));
222 static void emit_jsrjmp
PARAMS ((const expressionS
*, int, const PTR
));
223 static void emit_ldX
PARAMS ((const expressionS
*, int, const PTR
));
224 static void emit_ldXu
PARAMS ((const expressionS
*, int, const PTR
));
225 static void emit_uldX
PARAMS ((const expressionS
*, int, const PTR
));
226 static void emit_uldXu
PARAMS ((const expressionS
*, int, const PTR
));
227 static void emit_ldil
PARAMS ((const expressionS
*, int, const PTR
));
228 static void emit_stX
PARAMS ((const expressionS
*, int, const PTR
));
229 static void emit_ustX
PARAMS ((const expressionS
*, int, const PTR
));
230 static void emit_sextX
PARAMS ((const expressionS
*, int, const PTR
));
231 static void emit_retjcr
PARAMS ((const expressionS
*, int, const PTR
));
233 static void s_alpha_text
PARAMS ((int));
234 static void s_alpha_data
PARAMS ((int));
236 static void s_alpha_comm
PARAMS ((int));
237 static void s_alpha_rdata
PARAMS ((int));
240 static void s_alpha_sdata
PARAMS ((int));
243 static void s_alpha_section
PARAMS ((int));
244 static void s_alpha_ent
PARAMS ((int));
245 static void s_alpha_end
PARAMS ((int));
246 static void s_alpha_mask
PARAMS ((int));
247 static void s_alpha_frame
PARAMS ((int));
248 static void s_alpha_prologue
PARAMS ((int));
249 static void s_alpha_file
PARAMS ((int));
250 static void s_alpha_loc
PARAMS ((int));
251 static void s_alpha_coff_wrapper
PARAMS ((int));
254 static void s_alpha_section
PARAMS ((int));
256 static void s_alpha_gprel32
PARAMS ((int));
257 static void s_alpha_float_cons
PARAMS ((int));
258 static void s_alpha_proc
PARAMS ((int));
259 static void s_alpha_set
PARAMS ((int));
260 static void s_alpha_base
PARAMS ((int));
261 static void s_alpha_align
PARAMS ((int));
262 static void s_alpha_stringer
PARAMS ((int));
263 static void s_alpha_space
PARAMS ((int));
265 static void create_literal_section
PARAMS ((const char *, segT
*, symbolS
**));
267 static void select_gp_value
PARAMS ((void));
269 static void alpha_align
PARAMS ((int, char *, symbolS
*, int));
272 static void alpha_adjust_symtab_relocs
PARAMS ((bfd
*, asection
*, PTR
));
276 /* Generic assembler global variables which must be defined by all
279 /* Characters which always start a comment. */
280 const char comment_chars
[] = "#";
282 /* Characters which start a comment at the beginning of a line. */
283 const char line_comment_chars
[] = "#";
285 /* Characters which may be used to separate multiple commands on a
287 const char line_separator_chars
[] = ";";
289 /* Characters which are used to indicate an exponent in a floating
291 const char EXP_CHARS
[] = "eE";
293 /* Characters which mean that a number is a floating point constant,
296 const char FLT_CHARS
[] = "dD";
298 /* XXX: Do all of these really get used on the alpha?? */
299 char FLT_CHARS
[] = "rRsSfFdDxXpP";
303 const char *md_shortopts
= "Fm:g+1h:HG:";
305 const char *md_shortopts
= "Fm:gG:";
308 struct option md_longopts
[] = {
309 #define OPTION_32ADDR (OPTION_MD_BASE)
310 { "32addr", no_argument
, NULL
, OPTION_32ADDR
},
311 #define OPTION_RELAX (OPTION_32ADDR+1)
312 { "relax", no_argument
, NULL
, OPTION_RELAX
},
314 #define OPTION_MDEBUG (OPTION_RELAX+1)
315 #define OPTION_NO_MDEBUG (OPTION_MDEBUG+1)
316 { "mdebug", no_argument
, NULL
, OPTION_MDEBUG
},
317 { "no-mdebug", no_argument
, NULL
, OPTION_NO_MDEBUG
},
319 { NULL
, no_argument
, NULL
, 0 }
322 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 LITUSE_BASE 1
483 #define LITUSE_BYTOFF 2
486 static const struct alpha_reloc_op_tag
{
487 const char *name
; /* string to lookup */
488 size_t length
; /* size of the string */
489 bfd_reloc_code_real_type reloc
; /* relocation before frob */
490 operatorT op
; /* which operator to use */
491 int lituse
; /* addened to specify lituse */
492 } alpha_reloc_op
[] = {
495 "literal", /* name */
496 sizeof ("literal")-1, /* length */
497 BFD_RELOC_ALPHA_USER_LITERAL
, /* reloc */
503 "lituse_base", /* name */
504 sizeof ("lituse_base")-1, /* length */
505 BFD_RELOC_ALPHA_USER_LITUSE_BASE
, /* reloc */
506 O_lituse_base
, /* op */
507 LITUSE_BASE
, /* lituse */
511 "lituse_bytoff", /* name */
512 sizeof ("lituse_bytoff")-1, /* length */
513 BFD_RELOC_ALPHA_USER_LITUSE_BYTOFF
, /* reloc */
514 O_lituse_bytoff
, /* op */
515 LITUSE_BYTOFF
, /* lituse */
519 "lituse_jsr", /* name */
520 sizeof ("lituse_jsr")-1, /* length */
521 BFD_RELOC_ALPHA_USER_LITUSE_JSR
, /* reloc */
522 O_lituse_jsr
, /* op */
523 LITUSE_JSR
, /* lituse */
528 sizeof ("gpdisp")-1, /* length */
529 BFD_RELOC_ALPHA_USER_GPDISP
, /* reloc */
535 "gprelhigh", /* name */
536 sizeof ("gprelhigh")-1, /* length */
537 BFD_RELOC_ALPHA_USER_GPRELHIGH
, /* reloc */
538 O_gprelhigh
, /* op */
543 "gprellow", /* name */
544 sizeof ("gprellow")-1, /* length */
545 BFD_RELOC_ALPHA_USER_GPRELLOW
, /* reloc */
551 static const int alpha_num_reloc_op
552 = sizeof(alpha_reloc_op
) / sizeof(*alpha_reloc_op
);
554 /* Maximum # digits needed to hold the largest sequence # */
555 #define ALPHA_RELOC_DIGITS 25
557 /* Whether a sequence number is valid. */
558 #define ALPHA_RELOC_SEQUENCE_OK(X) ((X) > 0 && ((unsigned)(X)) == (X))
560 /* Structure to hold explict sequence information. */
561 struct alpha_literal_tag
563 fixS
*lituse
; /* head of linked list of !literals */
564 segT segment
; /* segment relocs are in or undefined_section*/
565 int multi_section_p
; /* True if more than one section was used */
566 unsigned sequence
; /* sequence # */
567 unsigned n_literals
; /* # of literals */
568 unsigned n_lituses
; /* # of lituses */
569 char string
[1]; /* printable form of sequence to hash with */
572 /* Hash table to link up literals with the appropriate lituse */
573 static struct hash_control
*alpha_literal_hash
;
576 /* A table of CPU names and opcode sets. */
578 static const struct cpu_type
584 /* Ad hoc convention: cpu number gets palcode, process code doesn't.
585 This supports usage under DU 4.0b that does ".arch ev4", and
586 usage in MILO that does -m21064. Probably something more
587 specific like -m21064-pal should be used, but oh well. */
589 { "21064", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
590 { "21064a", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
591 { "21066", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
592 { "21068", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
593 { "21164", AXP_OPCODE_BASE
|AXP_OPCODE_EV5
},
594 { "21164a", AXP_OPCODE_BASE
|AXP_OPCODE_EV5
|AXP_OPCODE_BWX
},
595 { "21164pc", (AXP_OPCODE_BASE
|AXP_OPCODE_EV5
|AXP_OPCODE_BWX
597 { "21264", (AXP_OPCODE_BASE
|AXP_OPCODE_EV6
|AXP_OPCODE_BWX
598 |AXP_OPCODE_MAX
|AXP_OPCODE_CIX
) },
600 { "ev4", AXP_OPCODE_BASE
},
601 { "ev45", AXP_OPCODE_BASE
},
602 { "lca45", AXP_OPCODE_BASE
},
603 { "ev5", AXP_OPCODE_BASE
},
604 { "ev56", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
},
605 { "pca56", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
|AXP_OPCODE_MAX
},
606 { "ev6", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
|AXP_OPCODE_MAX
|AXP_OPCODE_CIX
},
608 { "all", AXP_OPCODE_BASE
},
612 /* The macro table */
614 static const struct alpha_macro alpha_macros
[] = {
615 /* Load/Store macros */
616 { "lda", emit_lda
, NULL
,
617 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_LITERAL
, MACRO_BASE
, MACRO_EOA
} },
618 { "ldah", emit_ldah
, NULL
,
619 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
621 { "ldl", emit_ir_load
, "ldl",
622 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
623 { "ldl_l", emit_ir_load
, "ldl_l",
624 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
625 { "ldq", emit_ir_load
, "ldq",
626 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_LITERAL
, MACRO_EOA
} },
627 { "ldq_l", emit_ir_load
, "ldq_l",
628 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
629 { "ldq_u", emit_ir_load
, "ldq_u",
630 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
631 { "ldf", emit_loadstore
, "ldf",
632 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
633 { "ldg", emit_loadstore
, "ldg",
634 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
635 { "lds", emit_loadstore
, "lds",
636 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
637 { "ldt", emit_loadstore
, "ldt",
638 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
640 { "ldb", emit_ldX
, (PTR
)0,
641 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
642 { "ldbu", emit_ldXu
, (PTR
)0,
643 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
644 { "ldw", emit_ldX
, (PTR
)1,
645 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
646 { "ldwu", emit_ldXu
, (PTR
)1,
647 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
649 { "uldw", emit_uldX
, (PTR
)1,
650 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
651 { "uldwu", emit_uldXu
, (PTR
)1,
652 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
653 { "uldl", emit_uldX
, (PTR
)2,
654 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
655 { "uldlu", emit_uldXu
, (PTR
)2,
656 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
657 { "uldq", emit_uldXu
, (PTR
)3,
658 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
660 { "ldgp", emit_ldgp
, NULL
,
661 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
} },
663 { "ldi", emit_lda
, NULL
,
664 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
665 { "ldil", emit_ldil
, NULL
,
666 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
667 { "ldiq", emit_lda
, NULL
,
668 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
670 { "ldif" emit_ldiq
, NULL
,
671 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
672 { "ldid" emit_ldiq
, NULL
,
673 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
674 { "ldig" emit_ldiq
, NULL
,
675 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
676 { "ldis" emit_ldiq
, NULL
,
677 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
678 { "ldit" emit_ldiq
, NULL
,
679 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
682 { "stl", emit_loadstore
, "stl",
683 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
684 { "stl_c", emit_loadstore
, "stl_c",
685 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
686 { "stq", emit_loadstore
, "stq",
687 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
688 { "stq_c", emit_loadstore
, "stq_c",
689 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
690 { "stq_u", emit_loadstore
, "stq_u",
691 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
692 { "stf", emit_loadstore
, "stf",
693 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
694 { "stg", emit_loadstore
, "stg",
695 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
696 { "sts", emit_loadstore
, "sts",
697 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
698 { "stt", emit_loadstore
, "stt",
699 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
701 { "stb", emit_stX
, (PTR
)0,
702 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
703 { "stw", emit_stX
, (PTR
)1,
704 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
705 { "ustw", emit_ustX
, (PTR
)1,
706 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
707 { "ustl", emit_ustX
, (PTR
)2,
708 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
709 { "ustq", emit_ustX
, (PTR
)3,
710 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
712 /* Arithmetic macros */
714 { "absl" emit_absl
, 1, { IR
} },
715 { "absl" emit_absl
, 2, { IR
, IR
} },
716 { "absl" emit_absl
, 2, { EXP
, IR
} },
717 { "absq" emit_absq
, 1, { IR
} },
718 { "absq" emit_absq
, 2, { IR
, IR
} },
719 { "absq" emit_absq
, 2, { EXP
, IR
} },
722 { "sextb", emit_sextX
, (PTR
)0,
723 { MACRO_IR
, MACRO_IR
, MACRO_EOA
,
725 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
726 { "sextw", emit_sextX
, (PTR
)1,
727 { MACRO_IR
, MACRO_IR
, MACRO_EOA
,
729 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
731 { "divl", emit_division
, "__divl",
732 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
733 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
734 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
735 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
736 { "divlu", emit_division
, "__divlu",
737 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
738 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
739 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
740 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
741 { "divq", emit_division
, "__divq",
742 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
743 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
744 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
745 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
746 { "divqu", emit_division
, "__divqu",
747 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
748 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
749 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
750 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
751 { "reml", emit_division
, "__reml",
752 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
753 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
754 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
755 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
756 { "remlu", emit_division
, "__remlu",
757 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
758 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
759 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
760 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
761 { "remq", emit_division
, "__remq",
762 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
763 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
764 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
765 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
766 { "remqu", emit_division
, "__remqu",
767 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
768 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
769 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
770 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
772 { "jsr", emit_jsrjmp
, "jsr",
773 { MACRO_PIR
, MACRO_EXP
, MACRO_JSR
, MACRO_EOA
,
774 MACRO_PIR
, MACRO_JSR
, MACRO_EOA
,
775 MACRO_IR
, MACRO_EXP
, MACRO_JSR
, MACRO_EOA
,
776 MACRO_EXP
, MACRO_JSR
, MACRO_EOA
} },
777 { "jmp", emit_jsrjmp
, "jmp",
778 { MACRO_PIR
, MACRO_EXP
, MACRO_JSR
, MACRO_EOA
,
779 MACRO_PIR
, MACRO_JSR
, MACRO_EOA
,
780 MACRO_IR
, MACRO_EXP
, MACRO_JSR
, MACRO_EOA
,
781 MACRO_EXP
, MACRO_JSR
, MACRO_EOA
} },
782 { "ret", emit_retjcr
, "ret",
783 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
785 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
786 MACRO_PIR
, MACRO_EOA
,
787 MACRO_EXP
, MACRO_EOA
,
789 { "jcr", emit_retjcr
, "jcr",
790 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
792 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
793 MACRO_PIR
, MACRO_EOA
,
794 MACRO_EXP
, MACRO_EOA
,
796 { "jsr_coroutine", emit_retjcr
, "jcr",
797 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
799 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
800 MACRO_PIR
, MACRO_EOA
,
801 MACRO_EXP
, MACRO_EOA
,
805 static const unsigned int alpha_num_macros
806 = sizeof(alpha_macros
) / sizeof(*alpha_macros
);
808 /* Public interface functions */
810 /* This function is called once, at assembler startup time. It sets
811 up all the tables, etc. that the MD part of the assembler will
812 need, that can be determined before arguments are parsed. */
819 /* Verify that X_op field is wide enough. */
823 assert (e
.X_op
== O_max
);
826 /* Create the opcode hash table */
828 alpha_opcode_hash
= hash_new ();
829 for (i
= 0; i
< alpha_num_opcodes
; )
831 const char *name
, *retval
, *slash
;
833 name
= alpha_opcodes
[i
].name
;
834 retval
= hash_insert (alpha_opcode_hash
, name
, (PTR
)&alpha_opcodes
[i
]);
836 as_fatal (_("internal error: can't hash opcode `%s': %s"), name
, retval
);
838 /* Some opcodes include modifiers of various sorts with a "/mod"
839 syntax, like the architecture manual suggests. However, for
840 use with gcc at least, we also need access to those same opcodes
843 if ((slash
= strchr (name
, '/')) != NULL
)
845 char *p
= xmalloc (strlen (name
));
846 memcpy (p
, name
, slash
- name
);
847 strcpy (p
+ (slash
- name
), slash
+ 1);
849 (void)hash_insert(alpha_opcode_hash
, p
, (PTR
)&alpha_opcodes
[i
]);
850 /* Ignore failures -- the opcode table does duplicate some
851 variants in different forms, like "hw_stq" and "hw_st/q". */
854 while (++i
< alpha_num_opcodes
855 && (alpha_opcodes
[i
].name
== name
856 || !strcmp (alpha_opcodes
[i
].name
, name
)))
860 /* Create the macro hash table */
862 alpha_macro_hash
= hash_new ();
863 for (i
= 0; i
< alpha_num_macros
; )
865 const char *name
, *retval
;
867 name
= alpha_macros
[i
].name
;
868 retval
= hash_insert (alpha_macro_hash
, name
, (PTR
)&alpha_macros
[i
]);
870 as_fatal (_("internal error: can't hash macro `%s': %s"), name
, retval
);
872 while (++i
< alpha_num_macros
873 && (alpha_macros
[i
].name
== name
874 || !strcmp (alpha_macros
[i
].name
, name
)))
878 /* Construct symbols for each of the registers */
880 for (i
= 0; i
< 32; ++i
)
883 sprintf(name
, "$%d", i
);
884 alpha_register_table
[i
] = symbol_create(name
, reg_section
, i
,
890 sprintf(name
, "$f%d", i
-32);
891 alpha_register_table
[i
] = symbol_create(name
, reg_section
, i
,
895 /* Create the special symbols and sections we'll be using */
897 /* So .sbss will get used for tiny objects. */
898 bfd_set_gp_size (stdoutput
, g_switch_value
);
901 create_literal_section (".lita", &alpha_lita_section
, &alpha_lita_symbol
);
903 /* For handling the GP, create a symbol that won't be output in the
904 symbol table. We'll edit it out of relocs later. */
905 alpha_gp_symbol
= symbol_create ("<GP value>", alpha_lita_section
, 0x8000,
910 create_literal_section (".link", &alpha_link_section
, &alpha_link_symbol
);
916 segT sec
= subseg_new(".mdebug", (subsegT
)0);
917 bfd_set_section_flags(stdoutput
, sec
, SEC_HAS_CONTENTS
|SEC_READONLY
);
918 bfd_set_section_alignment(stdoutput
, sec
, 3);
922 subseg_set(text_section
, 0);
925 /* Create literal lookup hash table. */
926 alpha_literal_hash
= hash_new();
930 /* The public interface to the instruction assembler. */
936 char opname
[32]; /* current maximum is 13 */
937 expressionS tok
[MAX_INSN_ARGS
];
941 /* split off the opcode */
942 opnamelen
= strspn (str
, "abcdefghijklmnopqrstuvwxyz_/46819");
943 trunclen
= (opnamelen
< sizeof (opname
) - 1
945 : sizeof (opname
) - 1);
946 memcpy (opname
, str
, trunclen
);
947 opname
[trunclen
] = '\0';
949 /* tokenize the rest of the line */
950 if ((ntok
= tokenize_arguments (str
+ opnamelen
, tok
, MAX_INSN_ARGS
)) < 0)
952 if (ntok
!= TOKENIZE_ERROR_REPORT
)
953 as_bad (_("syntax error"));
959 assemble_tokens (opname
, tok
, ntok
, alpha_macros_on
);
962 /* Round up a section's size to the appropriate boundary. */
965 md_section_align (seg
, size
)
969 int align
= bfd_get_section_alignment(stdoutput
, seg
);
970 valueT mask
= ((valueT
)1 << align
) - 1;
972 return (size
+ mask
) & ~mask
;
975 /* Turn a string in input_line_pointer into a floating point constant
976 of type TYPE, and store the appropriate bytes in *LITP. The number
977 of LITTLENUMS emitted is stored in *SIZEP. An error message is
978 returned, or NULL on OK. */
980 /* Equal to MAX_PRECISION in atof-ieee.c */
981 #define MAX_LITTLENUMS 6
983 extern char *vax_md_atof
PARAMS ((int, char *, int *));
986 md_atof (type
, litP
, sizeP
)
992 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
993 LITTLENUM_TYPE
*wordP
;
1000 /* VAX md_atof doesn't like "G" for some reason. */
1004 return vax_md_atof (type
, litP
, sizeP
);
1027 return _("Bad call to MD_ATOF()");
1029 t
= atof_ieee (input_line_pointer
, type
, words
);
1031 input_line_pointer
= t
;
1032 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
1034 for (wordP
= words
+ prec
- 1; prec
--;)
1036 md_number_to_chars (litP
, (long) (*wordP
--), sizeof (LITTLENUM_TYPE
));
1037 litP
+= sizeof (LITTLENUM_TYPE
);
1043 /* Take care of the target-specific command-line options. */
1046 md_parse_option (c
, arg
)
1053 alpha_nofloats_on
= 1;
1057 alpha_addr32_on
= 1;
1065 g_switch_value
= atoi(arg
);
1070 const struct cpu_type
*p
;
1071 for (p
= cpu_types
; p
->name
; ++p
)
1072 if (strcmp(arg
, p
->name
) == 0)
1074 alpha_target_name
= p
->name
, alpha_target
= p
->flags
;
1077 as_warn(_("Unknown CPU identifier `%s'"), arg
);
1083 case '+': /* For g++. Hash any name > 63 chars long. */
1084 alpha_flag_hash_long_names
= 1;
1087 case 'H': /* Show new symbol after hash truncation */
1088 alpha_flag_show_after_trunc
= 1;
1091 case 'h': /* for gnu-c/vax compatibility. */
1096 alpha_flag_relax
= 1;
1101 alpha_flag_mdebug
= 1;
1103 case OPTION_NO_MDEBUG
:
1104 alpha_flag_mdebug
= 0;
1115 /* Print a description of the command-line options that we accept. */
1118 md_show_usage (stream
)
1123 -32addr treat addresses as 32-bit values\n\
1124 -F lack floating point instructions support\n\
1125 -mev4 | -mev45 | -mev5 | -mev56 | -mpca56 | -mev6 | -mall\n\
1126 specify variant of Alpha architecture\n\
1127 -m21064 | -m21066 | -m21164 | -m21164a | -m21164pc | -m21264\n\
1128 these variants include PALcode opcodes\n"),
1133 -+ hash encode (don't truncate) names longer than 64 characters\n\
1134 -H show new symbol after hash truncation\n"),
1139 /* Decide from what point a pc-relative relocation is relative to,
1140 relative to the pc-relative fixup. Er, relatively speaking. */
1143 md_pcrel_from (fixP
)
1146 valueT addr
= fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
1147 switch (fixP
->fx_r_type
)
1149 case BFD_RELOC_ALPHA_GPDISP
:
1150 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1151 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1154 return fixP
->fx_size
+ addr
;
1158 /* Attempt to simplify or even eliminate a fixup. The return value is
1159 ignored; perhaps it was once meaningful, but now it is historical.
1160 To indicate that a fixup has been eliminated, set fixP->fx_done.
1162 For ELF, here it is that we transform the GPDISP_HI16 reloc we used
1163 internally into the GPDISP reloc used externally. We had to do
1164 this so that we'd have the GPDISP_LO16 reloc as a tag to compute
1165 the distance to the "lda" instruction for setting the addend to
1169 md_apply_fix (fixP
, valueP
)
1173 char * const fixpos
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
1174 valueT value
= *valueP
;
1175 unsigned image
, size
;
1177 switch (fixP
->fx_r_type
)
1179 /* The GPDISP relocations are processed internally with a symbol
1180 referring to the current function; we need to drop in a value
1181 which, when added to the address of the start of the function,
1182 gives the desired GP. */
1183 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1185 fixS
*next
= fixP
->fx_next
;
1186 assert (next
->fx_r_type
== BFD_RELOC_ALPHA_GPDISP_LO16
);
1188 fixP
->fx_offset
= (next
->fx_frag
->fr_address
+ next
->fx_where
1189 - fixP
->fx_frag
->fr_address
- fixP
->fx_where
);
1191 value
= (value
- sign_extend_16 (value
)) >> 16;
1194 fixP
->fx_r_type
= BFD_RELOC_ALPHA_GPDISP
;
1198 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1199 value
= sign_extend_16 (value
);
1200 fixP
->fx_offset
= 0;
1206 fixP
->fx_addsy
= section_symbol (now_seg
);
1207 md_number_to_chars (fixpos
, value
, 2);
1212 fixP
->fx_r_type
= BFD_RELOC_16_PCREL
;
1217 fixP
->fx_r_type
= BFD_RELOC_32_PCREL
;
1222 fixP
->fx_r_type
= BFD_RELOC_64_PCREL
;
1225 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
1227 md_number_to_chars (fixpos
, value
, size
);
1233 case BFD_RELOC_GPREL32
:
1234 assert (fixP
->fx_subsy
== alpha_gp_symbol
);
1236 /* FIXME: inherited this obliviousness of `value' -- why? */
1237 md_number_to_chars (fixpos
, -alpha_gp_value
, 4);
1241 case BFD_RELOC_GPREL32
:
1245 case BFD_RELOC_23_PCREL_S2
:
1246 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
1248 image
= bfd_getl32(fixpos
);
1249 image
= (image
& ~0x1FFFFF) | ((value
>> 2) & 0x1FFFFF);
1254 case BFD_RELOC_ALPHA_HINT
:
1255 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
1257 image
= bfd_getl32(fixpos
);
1258 image
= (image
& ~0x3FFF) | ((value
>> 2) & 0x3FFF);
1264 case BFD_RELOC_ALPHA_LITERAL
:
1265 md_number_to_chars (fixpos
, value
, 2);
1268 case BFD_RELOC_ALPHA_LITUSE
:
1272 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1273 case BFD_RELOC_ALPHA_LITUSE
:
1277 case BFD_RELOC_ALPHA_LINKAGE
:
1278 case BFD_RELOC_ALPHA_CODEADDR
:
1283 case BFD_RELOC_ALPHA_USER_LITERAL
:
1284 case BFD_RELOC_ALPHA_USER_LITUSE_BASE
:
1285 case BFD_RELOC_ALPHA_USER_LITUSE_BYTOFF
:
1286 case BFD_RELOC_ALPHA_USER_LITUSE_JSR
:
1289 case BFD_RELOC_ALPHA_USER_GPDISP
:
1290 case BFD_RELOC_ALPHA_USER_GPRELHIGH
:
1291 case BFD_RELOC_ALPHA_USER_GPRELLOW
:
1297 const struct alpha_operand
*operand
;
1299 if ((int)fixP
->fx_r_type
>= 0)
1300 as_fatal (_("unhandled relocation type %s"),
1301 bfd_get_reloc_code_name (fixP
->fx_r_type
));
1303 assert (-(int)fixP
->fx_r_type
< (int)alpha_num_operands
);
1304 operand
= &alpha_operands
[-(int)fixP
->fx_r_type
];
1306 /* The rest of these fixups only exist internally during symbol
1307 resolution and have no representation in the object file.
1308 Therefore they must be completely resolved as constants. */
1310 if (fixP
->fx_addsy
!= 0
1311 && S_GET_SEGMENT (fixP
->fx_addsy
) != absolute_section
)
1312 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
1313 _("non-absolute expression in constant field"));
1315 image
= bfd_getl32(fixpos
);
1316 image
= insert_operand(image
, operand
, (offsetT
)value
,
1317 fixP
->fx_file
, fixP
->fx_line
);
1322 if (fixP
->fx_addsy
!= 0 || fixP
->fx_pcrel
!= 0)
1326 as_warn_where(fixP
->fx_file
, fixP
->fx_line
,
1327 _("type %d reloc done?\n"), (int)fixP
->fx_r_type
);
1332 md_number_to_chars(fixpos
, image
, 4);
1340 * Look for a register name in the given symbol.
1344 md_undefined_symbol(name
)
1349 int is_float
= 0, num
;
1354 if (name
[1] == 'p' && name
[2] == '\0')
1355 return alpha_register_table
[AXP_REG_FP
];
1360 if (!isdigit(*++name
))
1364 case '0': case '1': case '2': case '3': case '4':
1365 case '5': case '6': case '7': case '8': case '9':
1366 if (name
[1] == '\0')
1367 num
= name
[0] - '0';
1368 else if (name
[0] != '0' && isdigit(name
[1]) && name
[2] == '\0')
1370 num
= (name
[0] - '0') * 10 + name
[1] - '0';
1377 if (!alpha_noat_on
&& (num
+ is_float
) == AXP_REG_AT
)
1378 as_warn(_("Used $at without \".set noat\""));
1379 return alpha_register_table
[num
+ is_float
];
1382 if (name
[1] == 't' && name
[2] == '\0')
1385 as_warn(_("Used $at without \".set noat\""));
1386 return alpha_register_table
[AXP_REG_AT
];
1391 if (name
[1] == 'p' && name
[2] == '\0')
1392 return alpha_register_table
[alpha_gp_register
];
1396 if (name
[1] == 'p' && name
[2] == '\0')
1397 return alpha_register_table
[AXP_REG_SP
];
1405 /* @@@ Magic ECOFF bits. */
1408 alpha_frob_ecoff_data ()
1411 /* $zero and $f31 are read-only */
1412 alpha_gprmask
&= ~1;
1413 alpha_fprmask
&= ~1;
1417 /* Hook to remember a recently defined label so that the auto-align
1418 code can adjust the symbol after we know what alignment will be
1422 alpha_define_label (sym
)
1425 alpha_insn_label
= sym
;
1428 /* Return true if we must always emit a reloc for a type and false if
1429 there is some hope of resolving it a assembly time. */
1432 alpha_force_relocation (f
)
1435 if (alpha_flag_relax
)
1438 switch (f
->fx_r_type
)
1440 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1441 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1442 case BFD_RELOC_ALPHA_GPDISP
:
1444 case BFD_RELOC_ALPHA_LITERAL
:
1447 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1449 case BFD_RELOC_ALPHA_LITUSE
:
1450 case BFD_RELOC_GPREL32
:
1452 case BFD_RELOC_ALPHA_LINKAGE
:
1453 case BFD_RELOC_ALPHA_CODEADDR
:
1456 case BFD_RELOC_ALPHA_USER_LITERAL
:
1457 case BFD_RELOC_ALPHA_USER_LITUSE_BASE
:
1458 case BFD_RELOC_ALPHA_USER_LITUSE_BYTOFF
:
1459 case BFD_RELOC_ALPHA_USER_LITUSE_JSR
:
1460 case BFD_RELOC_ALPHA_USER_GPDISP
:
1461 case BFD_RELOC_ALPHA_USER_GPRELHIGH
:
1462 case BFD_RELOC_ALPHA_USER_GPRELLOW
:
1466 case BFD_RELOC_23_PCREL_S2
:
1469 case BFD_RELOC_ALPHA_HINT
:
1473 assert((int)f
->fx_r_type
< 0 && -(int)f
->fx_r_type
< (int)alpha_num_operands
);
1478 /* Return true if we can partially resolve a relocation now. */
1481 alpha_fix_adjustable (f
)
1485 /* Prevent all adjustments to global symbols */
1486 if (S_IS_EXTERN (f
->fx_addsy
) || S_IS_WEAK (f
->fx_addsy
))
1490 /* Are there any relocation types for which we must generate a reloc
1491 but we can adjust the values contained within it? */
1492 switch (f
->fx_r_type
)
1494 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1495 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1496 case BFD_RELOC_ALPHA_GPDISP
:
1500 case BFD_RELOC_ALPHA_LITERAL
:
1503 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1506 case BFD_RELOC_ALPHA_USER_LITERAL
:
1509 case BFD_RELOC_ALPHA_LINKAGE
:
1510 case BFD_RELOC_ALPHA_CODEADDR
:
1514 case BFD_RELOC_ALPHA_LITUSE
:
1516 case BFD_RELOC_ALPHA_USER_LITUSE_BASE
:
1517 case BFD_RELOC_ALPHA_USER_LITUSE_BYTOFF
:
1518 case BFD_RELOC_ALPHA_USER_LITUSE_JSR
:
1519 case BFD_RELOC_ALPHA_USER_GPDISP
:
1520 case BFD_RELOC_ALPHA_USER_GPRELHIGH
:
1521 case BFD_RELOC_ALPHA_USER_GPRELLOW
:
1525 case BFD_RELOC_GPREL32
:
1526 case BFD_RELOC_23_PCREL_S2
:
1529 case BFD_RELOC_ALPHA_HINT
:
1533 assert ((int)f
->fx_r_type
< 0
1534 && - (int)f
->fx_r_type
< (int)alpha_num_operands
);
1540 /* Generate the BFD reloc to be stuck in the object file from the
1541 fixup used internally in the assembler. */
1544 tc_gen_reloc (sec
, fixp
)
1545 asection
*sec ATTRIBUTE_UNUSED
;
1550 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
1551 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
1552 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
1553 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
1555 /* Make sure none of our internal relocations make it this far.
1556 They'd better have been fully resolved by this point. */
1557 assert ((int)fixp
->fx_r_type
> 0);
1559 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
1560 if (reloc
->howto
== NULL
)
1562 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1563 _("cannot represent `%s' relocation in object file"),
1564 bfd_get_reloc_code_name (fixp
->fx_r_type
));
1568 if (!fixp
->fx_pcrel
!= !reloc
->howto
->pc_relative
)
1570 as_fatal (_("internal error? cannot generate `%s' relocation"),
1571 bfd_get_reloc_code_name (fixp
->fx_r_type
));
1573 assert (!fixp
->fx_pcrel
== !reloc
->howto
->pc_relative
);
1576 if (fixp
->fx_r_type
== BFD_RELOC_ALPHA_LITERAL
)
1578 /* fake out bfd_perform_relocation. sigh */
1579 reloc
->addend
= -alpha_gp_value
;
1584 reloc
->addend
= fixp
->fx_offset
;
1587 * Ohhh, this is ugly. The problem is that if this is a local global
1588 * symbol, the relocation will entirely be performed at link time, not
1589 * at assembly time. bfd_perform_reloc doesn't know about this sort
1590 * of thing, and as a result we need to fake it out here.
1592 if ((S_IS_EXTERN (fixp
->fx_addsy
) || S_IS_WEAK (fixp
->fx_addsy
))
1593 && !S_IS_COMMON(fixp
->fx_addsy
))
1594 reloc
->addend
-= symbol_get_bfdsym (fixp
->fx_addsy
)->value
;
1601 /* Parse a register name off of the input_line and return a register
1602 number. Gets md_undefined_symbol above to do the register name
1605 Only called as a part of processing the ECOFF .frame directive. */
1608 tc_get_register (frame
)
1609 int frame ATTRIBUTE_UNUSED
;
1611 int framereg
= AXP_REG_SP
;
1614 if (*input_line_pointer
== '$')
1616 char *s
= input_line_pointer
;
1617 char c
= get_symbol_end ();
1618 symbolS
*sym
= md_undefined_symbol (s
);
1620 *strchr(s
, '\0') = c
;
1621 if (sym
&& (framereg
= S_GET_VALUE (sym
)) <= 31)
1624 as_warn (_("frame reg expected, using $%d."), framereg
);
1627 note_gpreg (framereg
);
1631 /* This is called before the symbol table is processed. In order to
1632 work with gcc when using mips-tfile, we must keep all local labels.
1633 However, in other cases, we want to discard them. If we were
1634 called with -g, but we didn't see any debugging information, it may
1635 mean that gcc is smuggling debugging information through to
1636 mips-tfile, in which case we must generate all local labels. */
1641 alpha_frob_file_before_adjust ()
1643 if (alpha_debug
!= 0
1644 && ! ecoff_debugging_seen
)
1645 flag_keep_locals
= 1;
1648 #endif /* OBJ_ECOFF */
1652 /* Before the relocations are written, reorder them, so that user supplied
1653 !lituse relocations follow the appropriate !literal relocations. Also
1654 convert the gas-internal relocations to the appropriate linker relocations.
1658 alpha_adjust_symtab ()
1660 if (alpha_literal_hash
)
1663 fprintf (stderr
, "alpha_adjust_symtab called\n");
1666 /* Go over each section, reordering the relocations so that all of the
1667 explicit LITUSE's are adjacent to the explicit LITERAL's */
1668 bfd_map_over_sections (stdoutput
, alpha_adjust_symtab_relocs
, (char *) 0);
1673 /* Inner function to move LITUSE's next to the LITERAL. */
1676 alpha_adjust_symtab_relocs (abfd
, sec
, ptr
)
1677 bfd
*abfd ATTRIBUTE_UNUSED
;
1679 PTR ptr ATTRIBUTE_UNUSED
;
1681 segment_info_type
*seginfo
= seg_info (sec
);
1691 int n_dup_literals
= 0;
1694 /* If seginfo is NULL, we did not create this section; don't do anything with
1695 it. By using a pointer to a pointer, we can update the links in place. */
1696 if (seginfo
== NULL
)
1699 /* If there are no relocations, skip the section. */
1700 if (! seginfo
->fix_root
)
1703 /* First rebuild the fixup chain without the expicit lituse's. */
1704 prevP
= &(seginfo
->fix_root
);
1705 for (fixp
= seginfo
->fix_root
; fixp
; fixp
= next
)
1707 next
= fixp
->fx_next
;
1708 fixp
->fx_next
= (fixS
*)0;
1713 switch (fixp
->fx_r_type
)
1717 prevP
= &(fixp
->fx_next
);
1720 "alpha_adjust_symtab_relocs: 0x%lx, other relocation %s\n",
1722 bfd_get_reloc_code_name (fixp
->fx_r_type
));
1726 case BFD_RELOC_ALPHA_USER_LITERAL
:
1728 prevP
= &(fixp
->fx_next
);
1729 /* prevent assembler from trying to adjust the offset */
1732 if (fixp
->tc_fix_data
.info
->n_literals
!= 1)
1735 "alpha_adjust_symtab_relocs: 0x%lx, !literal!%.6d, # literals = %2d\n",
1737 fixp
->tc_fix_data
.info
->sequence
,
1738 fixp
->tc_fix_data
.info
->n_literals
);
1742 /* do not link in lituse's */
1743 case BFD_RELOC_ALPHA_USER_LITUSE_BASE
:
1744 case BFD_RELOC_ALPHA_USER_LITUSE_BYTOFF
:
1745 case BFD_RELOC_ALPHA_USER_LITUSE_JSR
:
1747 if (fixp
->tc_fix_data
.info
->n_literals
== 0)
1748 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1749 _("No !literal!%d was found"),
1750 fixp
->tc_fix_data
.info
->sequence
);
1753 "alpha_adjust_symtab_relocs: 0x%lx, !lituse !%.6d, # lituses = %2d, next_lituse = 0x%lx\n",
1755 fixp
->tc_fix_data
.info
->sequence
,
1756 fixp
->tc_fix_data
.info
->n_lituses
,
1757 (long)fixp
->tc_fix_data
.next_lituse
);
1763 /* If there were any lituses, go and add them to the chain, unless there is
1764 more than one !literal for a given sequence number. They are linked
1765 through the next_lituse field in reverse order, so as we go through the
1766 next_lituse chain, we effectively reverse the chain once again. If there
1767 was more than one !literal, we fall back to loading up the address w/o
1768 optimization. Also, if the !literals/!lituses are spread in different
1769 segments (happens in the Linux kernel semaphores), suppress the
1773 for (fixp
= seginfo
->fix_root
; fixp
; fixp
= fixp
->fx_next
)
1775 switch (fixp
->fx_r_type
)
1780 case BFD_RELOC_ALPHA_USER_LITERAL
:
1782 fixp
->fx_r_type
= BFD_RELOC_ALPHA_ELF_LITERAL
;
1784 fixp
->fx_r_type
= BFD_RELOC_ALPHA_LITERAL
; /* XXX check this */
1786 if (fixp
->tc_fix_data
.info
->n_literals
== 1
1787 && ! fixp
->tc_fix_data
.info
->multi_section_p
)
1789 for (lituse
= fixp
->tc_fix_data
.info
->lituse
;
1790 lituse
!= (fixS
*)0;
1791 lituse
= lituse
->tc_fix_data
.next_lituse
)
1793 lituse
->fx_next
= fixp
->fx_next
;
1794 fixp
->fx_next
= lituse
;
1799 case BFD_RELOC_ALPHA_USER_LITUSE_BASE
:
1800 case BFD_RELOC_ALPHA_USER_LITUSE_BYTOFF
:
1801 case BFD_RELOC_ALPHA_USER_LITUSE_JSR
:
1802 fixp
->fx_r_type
= BFD_RELOC_ALPHA_LITUSE
;
1809 fprintf (stderr
, "alpha_adjust_symtab_relocs: %s, %d literal%s, %d duplicate literal%s, %d lituse%s\n\n",
1811 n_literals
, (n_literals
== 1) ? "" : "s",
1812 n_dup_literals
, (n_dup_literals
== 1) ? "" : "s",
1813 n_lituses
, (n_lituses
== 1) ? "" : "s");
1817 #endif /* RELOC_OP_P */
1822 debug_exp (tok
, ntok
)
1828 fprintf (stderr
, "debug_exp: %d tokens", ntok
);
1829 for (i
= 0; i
< ntok
; i
++)
1831 expressionS
*t
= &tok
[i
];
1835 default: name
= "unknown"; break;
1836 case O_illegal
: name
= "O_illegal"; break;
1837 case O_absent
: name
= "O_absent"; break;
1838 case O_constant
: name
= "O_constant"; break;
1839 case O_symbol
: name
= "O_symbol"; break;
1840 case O_symbol_rva
: name
= "O_symbol_rva"; break;
1841 case O_register
: name
= "O_register"; break;
1842 case O_big
: name
= "O_big"; break;
1843 case O_uminus
: name
= "O_uminus"; break;
1844 case O_bit_not
: name
= "O_bit_not"; break;
1845 case O_logical_not
: name
= "O_logical_not"; break;
1846 case O_multiply
: name
= "O_multiply"; break;
1847 case O_divide
: name
= "O_divide"; break;
1848 case O_modulus
: name
= "O_modulus"; break;
1849 case O_left_shift
: name
= "O_left_shift"; break;
1850 case O_right_shift
: name
= "O_right_shift"; break;
1851 case O_bit_inclusive_or
: name
= "O_bit_inclusive_or"; break;
1852 case O_bit_or_not
: name
= "O_bit_or_not"; break;
1853 case O_bit_exclusive_or
: name
= "O_bit_exclusive_or"; break;
1854 case O_bit_and
: name
= "O_bit_and"; break;
1855 case O_add
: name
= "O_add"; break;
1856 case O_subtract
: name
= "O_subtract"; break;
1857 case O_eq
: name
= "O_eq"; break;
1858 case O_ne
: name
= "O_ne"; break;
1859 case O_lt
: name
= "O_lt"; break;
1860 case O_le
: name
= "O_le"; break;
1861 case O_ge
: name
= "O_ge"; break;
1862 case O_gt
: name
= "O_gt"; break;
1863 case O_logical_and
: name
= "O_logical_and"; break;
1864 case O_logical_or
: name
= "O_logical_or"; break;
1865 case O_index
: name
= "O_index"; break;
1866 case O_pregister
: name
= "O_pregister"; break;
1867 case O_cpregister
: name
= "O_cpregister"; break;
1868 case O_literal
: name
= "O_literal"; break;
1869 case O_lituse_base
: name
= "O_lituse_base"; break;
1870 case O_lituse_bytoff
: name
= "O_lituse_bytoff"; break;
1871 case O_lituse_jsr
: name
= "O_lituse_jsr"; break;
1872 case O_gpdisp
: name
= "O_gpdisp"; break;
1873 case O_gprelhigh
: name
= "O_gprelhigh"; break;
1874 case O_gprellow
: name
= "O_gprellow"; break;
1875 case O_md10
: name
= "O_md10"; break;
1876 case O_md11
: name
= "O_md11"; break;
1877 case O_md12
: name
= "O_md12"; break;
1878 case O_md13
: name
= "O_md13"; break;
1879 case O_md14
: name
= "O_md14"; break;
1880 case O_md15
: name
= "O_md15"; break;
1881 case O_md16
: name
= "O_md16"; break;
1884 fprintf (stderr
, ", %s(%s, %s, %d)", name
,
1885 (t
->X_add_symbol
) ? S_GET_NAME (t
->X_add_symbol
) : "--",
1886 (t
->X_op_symbol
) ? S_GET_NAME (t
->X_op_symbol
) : "--",
1887 (int)t
->X_add_number
);
1889 fprintf (stderr
, "\n");
1894 /* Parse the arguments to an opcode. */
1897 tokenize_arguments (str
, tok
, ntok
)
1902 expressionS
*end_tok
= tok
+ ntok
;
1903 char *old_input_line_pointer
;
1904 int saw_comma
= 0, saw_arg
= 0;
1906 expressionS
*orig_tok
= tok
;
1910 const struct alpha_reloc_op_tag
*r
;
1913 int reloc_found_p
= 0;
1916 memset (tok
, 0, sizeof (*tok
) * ntok
);
1918 /* Save and restore input_line_pointer around this function */
1919 old_input_line_pointer
= input_line_pointer
;
1920 input_line_pointer
= str
;
1922 while (tok
< end_tok
&& *input_line_pointer
)
1925 switch (*input_line_pointer
)
1932 /* A relocation operand can be placed after the normal operand on an
1933 assembly language statement, and has the following form:
1934 !relocation_type!sequence_number. */
1936 { /* only support one relocation op per insn */
1937 as_bad (_("More than one relocation op per insn"));
1944 for (p
= ++input_line_pointer
;
1945 ((c
= *p
) != '!' && c
!= ';' && c
!= '#' && c
!= ','
1946 && !is_end_of_line
[c
]);
1950 /* Parse !relocation_type */
1951 len
= p
- input_line_pointer
;
1954 as_bad (_("No relocation operand"));
1960 as_bad (_("No !sequence-number after !%s"), input_line_pointer
);
1964 r
= &alpha_reloc_op
[0];
1965 for (i
= alpha_num_reloc_op
-1; i
>= 0; i
--, r
++)
1967 if (len
== r
->length
1968 && memcmp (input_line_pointer
, r
->name
, len
) == 0)
1973 as_bad (_("Unknown relocation operand: !%s"), input_line_pointer
);
1977 input_line_pointer
= ++p
;
1979 /* Parse !sequence_number */
1980 memset (tok
, '\0', sizeof (expressionS
));
1983 if (tok
->X_op
!= O_constant
1984 || ! ALPHA_RELOC_SEQUENCE_OK (tok
->X_add_number
))
1986 as_bad (_("Bad sequence number: !%s!%s"), r
->name
, input_line_pointer
);
1997 ++input_line_pointer
;
1998 if (saw_comma
|| !saw_arg
)
2005 char *hold
= input_line_pointer
++;
2007 /* First try for parenthesized register ... */
2009 if (*input_line_pointer
== ')' && tok
->X_op
== O_register
)
2011 tok
->X_op
= (saw_comma
? O_cpregister
: O_pregister
);
2014 ++input_line_pointer
;
2019 /* ... then fall through to plain expression */
2020 input_line_pointer
= hold
;
2024 if (saw_arg
&& !saw_comma
)
2028 if (tok
->X_op
== O_illegal
|| tok
->X_op
== O_absent
)
2041 input_line_pointer
= old_input_line_pointer
;
2044 debug_exp (orig_tok
, ntok
- (end_tok
- tok
));
2047 return ntok
- (end_tok
- tok
);
2050 input_line_pointer
= old_input_line_pointer
;
2051 return TOKENIZE_ERROR
;
2055 input_line_pointer
= old_input_line_pointer
;
2056 return TOKENIZE_ERROR_REPORT
;
2060 /* Search forward through all variants of an opcode looking for a
2063 static const struct alpha_opcode
*
2064 find_opcode_match(first_opcode
, tok
, pntok
, pcpumatch
)
2065 const struct alpha_opcode
*first_opcode
;
2066 const expressionS
*tok
;
2070 const struct alpha_opcode
*opcode
= first_opcode
;
2072 int got_cpu_match
= 0;
2076 const unsigned char *opidx
;
2079 /* Don't match opcodes that don't exist on this architecture */
2080 if (!(opcode
->flags
& alpha_target
))
2085 for (opidx
= opcode
->operands
; *opidx
; ++opidx
)
2087 const struct alpha_operand
*operand
= &alpha_operands
[*opidx
];
2089 /* only take input from real operands */
2090 if (operand
->flags
& AXP_OPERAND_FAKE
)
2093 /* when we expect input, make sure we have it */
2096 if ((operand
->flags
& AXP_OPERAND_OPTIONAL_MASK
) == 0)
2101 /* match operand type with expression type */
2102 switch (operand
->flags
& AXP_OPERAND_TYPECHECK_MASK
)
2104 case AXP_OPERAND_IR
:
2105 if (tok
[tokidx
].X_op
!= O_register
2106 || !is_ir_num(tok
[tokidx
].X_add_number
))
2109 case AXP_OPERAND_FPR
:
2110 if (tok
[tokidx
].X_op
!= O_register
2111 || !is_fpr_num(tok
[tokidx
].X_add_number
))
2114 case AXP_OPERAND_IR
|AXP_OPERAND_PARENS
:
2115 if (tok
[tokidx
].X_op
!= O_pregister
2116 || !is_ir_num(tok
[tokidx
].X_add_number
))
2119 case AXP_OPERAND_IR
|AXP_OPERAND_PARENS
|AXP_OPERAND_COMMA
:
2120 if (tok
[tokidx
].X_op
!= O_cpregister
2121 || !is_ir_num(tok
[tokidx
].X_add_number
))
2125 case AXP_OPERAND_RELATIVE
:
2126 case AXP_OPERAND_SIGNED
:
2127 case AXP_OPERAND_UNSIGNED
:
2128 switch (tok
[tokidx
].X_op
)
2143 /* everything else should have been fake */
2149 /* possible match -- did we use all of our input? */
2158 while (++opcode
-alpha_opcodes
< alpha_num_opcodes
2159 && !strcmp(opcode
->name
, first_opcode
->name
));
2162 *pcpumatch
= got_cpu_match
;
2167 /* Search forward through all variants of a macro looking for a syntax
2170 static const struct alpha_macro
*
2171 find_macro_match(first_macro
, tok
, pntok
)
2172 const struct alpha_macro
*first_macro
;
2173 const expressionS
*tok
;
2176 const struct alpha_macro
*macro
= first_macro
;
2181 const enum alpha_macro_arg
*arg
= macro
->argsets
;
2195 /* index register */
2197 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_register
2198 || !is_ir_num(tok
[tokidx
].X_add_number
))
2203 /* parenthesized index register */
2205 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_pregister
2206 || !is_ir_num(tok
[tokidx
].X_add_number
))
2211 /* optional parenthesized index register */
2213 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_pregister
2214 && is_ir_num(tok
[tokidx
].X_add_number
))
2218 /* leading comma with a parenthesized index register */
2220 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_cpregister
2221 || !is_ir_num(tok
[tokidx
].X_add_number
))
2226 /* floating point register */
2228 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_register
2229 || !is_fpr_num(tok
[tokidx
].X_add_number
))
2234 /* normal expression */
2238 switch (tok
[tokidx
].X_op
)
2248 case O_lituse_bytoff
:
2262 /* optional !literal!<number> */
2265 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_literal
)
2270 /* optional !lituse_base!<number> */
2273 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_lituse_base
)
2278 /* optional !lituse_bytoff!<number> */
2281 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_lituse_bytoff
)
2286 /* optional !lituse_jsr!<number> */
2289 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_lituse_jsr
)
2295 while (*arg
!= MACRO_EOA
)
2303 while (++macro
-alpha_macros
< alpha_num_macros
2304 && !strcmp(macro
->name
, first_macro
->name
));
2309 /* Insert an operand value into an instruction. */
2312 insert_operand(insn
, operand
, val
, file
, line
)
2314 const struct alpha_operand
*operand
;
2319 if (operand
->bits
!= 32 && !(operand
->flags
& AXP_OPERAND_NOOVERFLOW
))
2323 if (operand
->flags
& AXP_OPERAND_SIGNED
)
2325 max
= (1 << (operand
->bits
- 1)) - 1;
2326 min
= -(1 << (operand
->bits
- 1));
2330 max
= (1 << operand
->bits
) - 1;
2334 if (val
< min
|| val
> max
)
2337 _("operand out of range (%s not between %d and %d)");
2338 char buf
[sizeof (val
) * 3 + 2];
2340 sprint_value(buf
, val
);
2342 as_warn_where(file
, line
, err
, buf
, min
, max
);
2344 as_warn(err
, buf
, min
, max
);
2348 if (operand
->insert
)
2350 const char *errmsg
= NULL
;
2352 insn
= (*operand
->insert
) (insn
, val
, &errmsg
);
2357 insn
|= ((val
& ((1 << operand
->bits
) - 1)) << operand
->shift
);
2363 * Turn an opcode description and a set of arguments into
2364 * an instruction and a fixup.
2368 assemble_insn(opcode
, tok
, ntok
, insn
)
2369 const struct alpha_opcode
*opcode
;
2370 const expressionS
*tok
;
2372 struct alpha_insn
*insn
;
2374 const unsigned char *argidx
;
2378 memset (insn
, 0, sizeof (*insn
));
2379 image
= opcode
->opcode
;
2381 for (argidx
= opcode
->operands
; *argidx
; ++argidx
)
2383 const struct alpha_operand
*operand
= &alpha_operands
[*argidx
];
2384 const expressionS
*t
= (const expressionS
*)0;
2386 if (operand
->flags
& AXP_OPERAND_FAKE
)
2388 /* fake operands take no value and generate no fixup */
2389 image
= insert_operand(image
, operand
, 0, NULL
, 0);
2395 switch (operand
->flags
& AXP_OPERAND_OPTIONAL_MASK
)
2397 case AXP_OPERAND_DEFAULT_FIRST
:
2400 case AXP_OPERAND_DEFAULT_SECOND
:
2403 case AXP_OPERAND_DEFAULT_ZERO
:
2405 static expressionS zero_exp
;
2407 zero_exp
.X_op
= O_constant
;
2408 zero_exp
.X_unsigned
= 1;
2423 image
= insert_operand(image
, operand
, regno(t
->X_add_number
),
2428 image
= insert_operand(image
, operand
, t
->X_add_number
, NULL
, 0);
2433 struct alpha_fixup
*fixup
;
2435 if (insn
->nfixups
>= MAX_INSN_FIXUPS
)
2436 as_fatal(_("too many fixups"));
2438 fixup
= &insn
->fixups
[insn
->nfixups
++];
2441 fixup
->reloc
= operand
->default_reloc
;
2451 * Actually output an instruction with its fixup.
2456 struct alpha_insn
*insn
;
2461 /* Take care of alignment duties */
2462 if (alpha_auto_align_on
&& alpha_current_align
< 2)
2463 alpha_align (2, (char *) NULL
, alpha_insn_label
, 0);
2464 if (alpha_current_align
> 2)
2465 alpha_current_align
= 2;
2466 alpha_insn_label
= NULL
;
2468 /* Write out the instruction. */
2470 md_number_to_chars (f
, insn
->insn
, 4);
2473 dwarf2_emit_insn (4);
2476 /* Apply the fixups in order */
2477 for (i
= 0; i
< insn
->nfixups
; ++i
)
2479 const struct alpha_operand
*operand
= (const struct alpha_operand
*)0;
2480 struct alpha_fixup
*fixup
= &insn
->fixups
[i
];
2484 char buffer
[ALPHA_RELOC_DIGITS
];
2485 struct alpha_literal_tag
*info
;
2488 /* Some fixups are only used internally and so have no howto */
2489 if ((int)fixup
->reloc
< 0)
2491 operand
= &alpha_operands
[-(int)fixup
->reloc
];
2493 pcrel
= ((operand
->flags
& AXP_OPERAND_RELATIVE
) != 0);
2495 else switch (fixup
->reloc
)
2498 /* These relocation types are only used internally. */
2499 case BFD_RELOC_ALPHA_GPDISP_HI16
:
2500 case BFD_RELOC_ALPHA_GPDISP_LO16
:
2506 /* and these also are internal only relocations */
2507 case BFD_RELOC_ALPHA_USER_LITERAL
:
2508 case BFD_RELOC_ALPHA_USER_LITUSE_BASE
:
2509 case BFD_RELOC_ALPHA_USER_LITUSE_BYTOFF
:
2510 case BFD_RELOC_ALPHA_USER_LITUSE_JSR
:
2511 case BFD_RELOC_ALPHA_USER_GPDISP
:
2512 case BFD_RELOC_ALPHA_USER_GPRELHIGH
:
2513 case BFD_RELOC_ALPHA_USER_GPRELLOW
:
2521 reloc_howto_type
*reloc_howto
2522 = bfd_reloc_type_lookup (stdoutput
, fixup
->reloc
);
2523 assert (reloc_howto
);
2525 size
= bfd_get_reloc_size (reloc_howto
);
2526 pcrel
= reloc_howto
->pc_relative
;
2528 assert (size
>= 1 && size
<= 4);
2532 fixP
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, size
,
2533 &fixup
->exp
, pcrel
, fixup
->reloc
);
2535 /* Turn off complaints that the addend is too large for some fixups,
2536 and copy in the sequence number for the explicit relocations. */
2537 switch (fixup
->reloc
)
2539 case BFD_RELOC_ALPHA_GPDISP_LO16
:
2541 case BFD_RELOC_ALPHA_LITERAL
:
2544 case BFD_RELOC_ALPHA_ELF_LITERAL
:
2546 case BFD_RELOC_GPREL32
:
2547 fixP
->fx_no_overflow
= 1;
2551 case BFD_RELOC_ALPHA_USER_LITERAL
:
2552 fixP
->fx_no_overflow
= 1;
2553 sprintf (buffer
, "!%u", insn
->sequence
[i
]);
2554 info
= ((struct alpha_literal_tag
*)
2555 hash_find (alpha_literal_hash
, buffer
));
2559 size_t len
= strlen (buffer
);
2562 info
= ((struct alpha_literal_tag
*)
2563 xcalloc (sizeof (struct alpha_literal_tag
) + len
, 1));
2565 info
->segment
= now_seg
;
2566 info
->sequence
= insn
->sequence
[i
];
2567 strcpy (info
->string
, buffer
);
2568 errmsg
= hash_insert (alpha_literal_hash
, info
->string
, (PTR
)info
);
2575 if (info
->segment
!= now_seg
)
2576 info
->multi_section_p
= 1;
2578 fixP
->tc_fix_data
.info
= info
;
2581 case BFD_RELOC_ALPHA_USER_LITUSE_BASE
:
2582 case BFD_RELOC_ALPHA_USER_LITUSE_BYTOFF
:
2583 case BFD_RELOC_ALPHA_USER_LITUSE_JSR
:
2584 sprintf (buffer
, "!%u", insn
->sequence
[i
]);
2585 info
= ((struct alpha_literal_tag
*)
2586 hash_find (alpha_literal_hash
, buffer
));
2590 size_t len
= strlen (buffer
);
2593 info
= ((struct alpha_literal_tag
*)
2594 xcalloc (sizeof (struct alpha_literal_tag
) + len
, 1));
2596 info
->segment
= now_seg
;
2597 info
->sequence
= insn
->sequence
[i
];
2598 strcpy (info
->string
, buffer
);
2599 errmsg
= hash_insert (alpha_literal_hash
, info
->string
, (PTR
)info
);
2604 fixP
->tc_fix_data
.info
= info
;
2605 fixP
->tc_fix_data
.next_lituse
= info
->lituse
;
2606 info
->lituse
= fixP
;
2607 if (info
->segment
!= now_seg
)
2608 info
->multi_section_p
= 1;
2614 if ((int)fixup
->reloc
< 0)
2616 if (operand
->flags
& AXP_OPERAND_NOOVERFLOW
)
2617 fixP
->fx_no_overflow
= 1;
2624 /* Given an opcode name and a pre-tokenized set of arguments, assemble
2625 the insn, but do not emit it.
2627 Note that this implies no macros allowed, since we can't store more
2628 than one insn in an insn structure. */
2631 assemble_tokens_to_insn(opname
, tok
, ntok
, insn
)
2633 const expressionS
*tok
;
2635 struct alpha_insn
*insn
;
2637 const struct alpha_opcode
*opcode
;
2639 /* search opcodes */
2640 opcode
= (const struct alpha_opcode
*) hash_find (alpha_opcode_hash
, opname
);
2644 opcode
= find_opcode_match (opcode
, tok
, &ntok
, &cpumatch
);
2647 assemble_insn (opcode
, tok
, ntok
, insn
);
2651 as_bad (_("inappropriate arguments for opcode `%s'"), opname
);
2653 as_bad (_("opcode `%s' not supported for target %s"), opname
,
2657 as_bad (_("unknown opcode `%s'"), opname
);
2660 /* Given an opcode name and a pre-tokenized set of arguments, take the
2661 opcode all the way through emission. */
2664 assemble_tokens (opname
, tok
, ntok
, local_macros_on
)
2666 const expressionS
*tok
;
2668 int local_macros_on
;
2670 int found_something
= 0;
2671 const struct alpha_opcode
*opcode
;
2672 const struct alpha_macro
*macro
;
2676 if (local_macros_on
)
2678 macro
= ((const struct alpha_macro
*)
2679 hash_find (alpha_macro_hash
, opname
));
2682 found_something
= 1;
2683 macro
= find_macro_match (macro
, tok
, &ntok
);
2686 (*macro
->emit
) (tok
, ntok
, macro
->arg
);
2693 if (ntok
&& USER_RELOC_P (tok
[ntok
-1].X_op
))
2695 const expressionS
*reloc_exp
= &tok
[ntok
-1];
2696 const struct alpha_reloc_op_tag
*r
= ALPHA_RELOC_TABLE (reloc_exp
->X_op
);
2697 as_bad (_("Cannot use !%s!%d with %s"), r
->name
,
2698 (int)reloc_exp
->X_add_number
, opname
);
2703 /* search opcodes */
2704 opcode
= (const struct alpha_opcode
*) hash_find (alpha_opcode_hash
, opname
);
2707 found_something
= 1;
2708 opcode
= find_opcode_match (opcode
, tok
, &ntok
, &cpumatch
);
2711 struct alpha_insn insn
;
2712 assemble_insn (opcode
, tok
, ntok
, &insn
);
2718 if (found_something
)
2720 as_bad (_("inappropriate arguments for opcode `%s'"), opname
);
2722 as_bad (_("opcode `%s' not supported for target %s"), opname
,
2725 as_bad (_("unknown opcode `%s'"), opname
);
2729 /* Some instruction sets indexed by lg(size) */
2730 static const char * const sextX_op
[] = { "sextb", "sextw", "sextl", NULL
};
2731 static const char * const insXl_op
[] = { "insbl", "inswl", "insll", "insql" };
2732 static const char * const insXh_op
[] = { NULL
, "inswh", "inslh", "insqh" };
2733 static const char * const extXl_op
[] = { "extbl", "extwl", "extll", "extql" };
2734 static const char * const extXh_op
[] = { NULL
, "extwh", "extlh", "extqh" };
2735 static const char * const mskXl_op
[] = { "mskbl", "mskwl", "mskll", "mskql" };
2736 static const char * const mskXh_op
[] = { NULL
, "mskwh", "msklh", "mskqh" };
2737 static const char * const stX_op
[] = { "stb", "stw", "stl", "stq" };
2738 static const char * const ldX_op
[] = { "ldb", "ldw", "ldll", "ldq" };
2739 static const char * const ldXu_op
[] = { "ldbu", "ldwu", NULL
, NULL
};
2741 /* Implement the ldgp macro. */
2744 emit_ldgp (tok
, ntok
, unused
)
2745 const expressionS
*tok
;
2746 int ntok ATTRIBUTE_UNUSED
;
2747 const PTR unused ATTRIBUTE_UNUSED
;
2752 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
2753 /* from "ldgp r1,n(r2)", generate "ldah r1,X(R2); lda r1,Y(r1)"
2754 with appropriate constants and relocations. */
2755 struct alpha_insn insn
;
2756 expressionS newtok
[3];
2760 if (ntok
&& USER_RELOC_P (tok
[ntok
-1].X_op
))
2762 const expressionS
*reloc_exp
= &tok
[ntok
-1];
2763 const struct alpha_reloc_op_tag
*r
= ALPHA_RELOC_TABLE (reloc_exp
->X_op
);
2764 as_bad (_("Cannot use !%s!%d with %s"), r
->name
,
2765 (int)reloc_exp
->X_add_number
, "ldgp");
2771 if (regno (tok
[2].X_add_number
) == AXP_REG_PV
)
2772 ecoff_set_gp_prolog_size (0);
2776 set_tok_const (newtok
[1], 0);
2779 assemble_tokens_to_insn ("ldah", newtok
, 3, &insn
);
2784 if (addend
.X_op
!= O_constant
)
2785 as_bad (_("can not resolve expression"));
2786 addend
.X_op
= O_symbol
;
2787 addend
.X_add_symbol
= alpha_gp_symbol
;
2791 insn
.fixups
[0].exp
= addend
;
2792 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_GPDISP_HI16
;
2796 set_tok_preg (newtok
[2], tok
[0].X_add_number
);
2798 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
2801 addend
.X_add_number
+= 4;
2805 insn
.fixups
[0].exp
= addend
;
2806 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_GPDISP_LO16
;
2809 #endif /* OBJ_ECOFF || OBJ_ELF */
2814 /* Add symbol+addend to link pool.
2815 Return offset from basesym to entry in link pool.
2817 Add new fixup only if offset isn't 16bit. */
2820 add_to_link_pool (basesym
, sym
, addend
)
2825 segT current_section
= now_seg
;
2826 int current_subsec
= now_subseg
;
2828 bfd_reloc_code_real_type reloc_type
;
2830 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
2833 offset
= - *symbol_get_obj (basesym
);
2835 /* @@ This assumes all entries in a given section will be of the same
2836 size... Probably correct, but unwise to rely on. */
2837 /* This must always be called with the same subsegment. */
2839 if (seginfo
->frchainP
)
2840 for (fixp
= seginfo
->frchainP
->fix_root
;
2841 fixp
!= (fixS
*) NULL
;
2842 fixp
= fixp
->fx_next
, offset
+= 8)
2844 if (fixp
->fx_addsy
== sym
&& fixp
->fx_offset
== addend
)
2846 if (range_signed_16 (offset
))
2853 /* Not found in 16bit signed range. */
2855 subseg_set (alpha_link_section
, 0);
2859 fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, sym
, addend
, 0,
2862 subseg_set (current_section
, current_subsec
);
2863 seginfo
->literal_pool_size
+= 8;
2867 #endif /* OBJ_EVAX */
2869 /* Load a (partial) expression into a target register.
2871 If poffset is not null, after the call it will either contain
2872 O_constant 0, or a 16-bit offset appropriate for any MEM format
2873 instruction. In addition, pbasereg will be modified to point to
2874 the base register to use in that MEM format instruction.
2876 In any case, *pbasereg should contain a base register to add to the
2877 expression. This will normally be either AXP_REG_ZERO or
2878 alpha_gp_register. Symbol addresses will always be loaded via $gp,
2879 so "foo($0)" is interpreted as adding the address of foo to $0;
2880 i.e. "ldq $targ, LIT($gp); addq $targ, $0, $targ". Odd, perhaps,
2881 but this is what OSF/1 does.
2883 If explicit relocations of the form !literal!<number> are allowed,
2884 and used, then explict_reloc with be an expression pointer.
2886 Finally, the return value is true if the calling macro may emit a
2887 LITUSE reloc if otherwise appropriate. */
2890 load_expression (targreg
, exp
, pbasereg
, poffset
, explicit_reloc
)
2892 const expressionS
*exp
;
2894 expressionS
*poffset
;
2895 const expressionS
*explicit_reloc
;
2897 int emit_lituse
= 0;
2898 offsetT addend
= exp
->X_add_number
;
2899 int basereg
= *pbasereg
;
2900 struct alpha_insn insn
;
2901 expressionS newtok
[3];
2910 /* attempt to reduce .lit load by splitting the offset from
2911 its symbol when possible, but don't create a situation in
2913 if (!range_signed_32 (addend
) &&
2914 (alpha_noat_on
|| targreg
== AXP_REG_AT
))
2916 lit
= add_to_literal_pool (exp
->X_add_symbol
, addend
,
2917 alpha_lita_section
, 8);
2922 lit
= add_to_literal_pool (exp
->X_add_symbol
, 0,
2923 alpha_lita_section
, 8);
2927 as_fatal (_("overflow in literal (.lita) table"));
2929 /* emit "ldq r, lit(gp)" */
2931 if (basereg
!= alpha_gp_register
&& targreg
== basereg
)
2934 as_bad (_("macro requires $at register while noat in effect"));
2935 if (targreg
== AXP_REG_AT
)
2936 as_bad (_("macro requires $at while $at in use"));
2938 set_tok_reg (newtok
[0], AXP_REG_AT
);
2941 set_tok_reg (newtok
[0], targreg
);
2942 set_tok_sym (newtok
[1], alpha_lita_symbol
, lit
);
2943 set_tok_preg (newtok
[2], alpha_gp_register
);
2945 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
2947 assert (explicit_reloc
== (const expressionS
*)0);
2948 assert (insn
.nfixups
== 1);
2949 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITERAL
;
2950 #endif /* OBJ_ECOFF */
2952 /* emit "ldq r, gotoff(gp)" */
2954 if (basereg
!= alpha_gp_register
&& targreg
== basereg
)
2957 as_bad (_("macro requires $at register while noat in effect"));
2958 if (targreg
== AXP_REG_AT
)
2959 as_bad (_("macro requires $at while $at in use"));
2961 set_tok_reg (newtok
[0], AXP_REG_AT
);
2964 set_tok_reg (newtok
[0], targreg
);
2966 /* XXX: Disable this .got minimizing optimization so that we can get
2967 better instruction offset knowledge in the compiler. This happens
2968 very infrequently anyway. */
2969 if (1 || (!range_signed_32 (addend
)
2970 && (alpha_noat_on
|| targreg
== AXP_REG_AT
)))
2977 set_tok_sym (newtok
[1], exp
->X_add_symbol
, 0);
2980 set_tok_preg (newtok
[2], alpha_gp_register
);
2982 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
2984 assert (insn
.nfixups
== 1);
2985 if (!explicit_reloc
)
2986 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_ELF_LITERAL
;
2990 insn
.fixups
[0].reloc
2991 = (ALPHA_RELOC_TABLE (explicit_reloc
->X_op
))->reloc
;
2992 insn
.sequence
[0] = explicit_reloc
->X_add_number
;
2997 #endif /* OBJ_ELF */
3001 /* Find symbol or symbol pointer in link section. */
3003 assert (explicit_reloc
== (const expressionS
*)0);
3004 if (exp
->X_add_symbol
== alpha_evax_proc
.symbol
)
3006 if (range_signed_16 (addend
))
3008 set_tok_reg (newtok
[0], targreg
);
3009 set_tok_const (newtok
[1], addend
);
3010 set_tok_preg (newtok
[2], basereg
);
3011 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
3016 set_tok_reg (newtok
[0], targreg
);
3017 set_tok_const (newtok
[1], 0);
3018 set_tok_preg (newtok
[2], basereg
);
3019 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
3024 if (!range_signed_32 (addend
))
3026 link
= add_to_link_pool (alpha_evax_proc
.symbol
,
3027 exp
->X_add_symbol
, addend
);
3032 link
= add_to_link_pool (alpha_evax_proc
.symbol
,
3033 exp
->X_add_symbol
, 0);
3035 set_tok_reg (newtok
[0], targreg
);
3036 set_tok_const (newtok
[1], link
);
3037 set_tok_preg (newtok
[2], basereg
);
3038 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
3040 #endif /* OBJ_EVAX */
3047 if (basereg
!= alpha_gp_register
&& basereg
!= AXP_REG_ZERO
)
3049 /* emit "addq r, base, r" */
3051 set_tok_reg (newtok
[1], basereg
);
3052 set_tok_reg (newtok
[2], targreg
);
3053 assemble_tokens ("addq", newtok
, 3, 0);
3062 assert (explicit_reloc
== (const expressionS
*)0);
3066 /* Assume that this difference expression will be resolved to an
3067 absolute value and that that value will fit in 16 bits. */
3069 assert (explicit_reloc
== (const expressionS
*)0);
3070 set_tok_reg (newtok
[0], targreg
);
3072 set_tok_preg (newtok
[2], basereg
);
3073 assemble_tokens ("lda", newtok
, 3, 0);
3076 set_tok_const (*poffset
, 0);
3080 if (exp
->X_add_number
> 0)
3081 as_bad (_("bignum invalid; zero assumed"));
3083 as_bad (_("floating point number invalid; zero assumed"));
3088 as_bad (_("can't handle expression"));
3093 if (!range_signed_32 (addend
))
3097 /* for 64-bit addends, just put it in the literal pool */
3100 /* emit "ldq targreg, lit(basereg)" */
3101 lit
= add_to_link_pool (alpha_evax_proc
.symbol
,
3102 section_symbol (absolute_section
), addend
);
3103 set_tok_reg (newtok
[0], targreg
);
3104 set_tok_const (newtok
[1], lit
);
3105 set_tok_preg (newtok
[2], alpha_gp_register
);
3106 assemble_tokens ("ldq", newtok
, 3, 0);
3109 if (alpha_lit8_section
== NULL
)
3111 create_literal_section (".lit8",
3112 &alpha_lit8_section
,
3113 &alpha_lit8_symbol
);
3116 alpha_lit8_literal
= add_to_literal_pool (alpha_lit8_symbol
, 0x8000,
3117 alpha_lita_section
, 8);
3118 if (alpha_lit8_literal
>= 0x8000)
3119 as_fatal (_("overflow in literal (.lita) table"));
3123 lit
= add_to_literal_pool (NULL
, addend
, alpha_lit8_section
, 8) - 0x8000;
3125 as_fatal (_("overflow in literal (.lit8) table"));
3127 /* emit "lda litreg, .lit8+0x8000" */
3129 if (targreg
== basereg
)
3132 as_bad (_("macro requires $at register while noat in effect"));
3133 if (targreg
== AXP_REG_AT
)
3134 as_bad (_("macro requires $at while $at in use"));
3136 set_tok_reg (newtok
[0], AXP_REG_AT
);
3139 set_tok_reg (newtok
[0], targreg
);
3141 set_tok_sym (newtok
[1], alpha_lita_symbol
, alpha_lit8_literal
);
3144 set_tok_sym (newtok
[1], alpha_lit8_symbol
, 0x8000);
3146 set_tok_preg (newtok
[2], alpha_gp_register
);
3148 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
3150 assert (insn
.nfixups
== 1);
3152 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITERAL
;
3155 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_ELF_LITERAL
;
3160 /* emit "ldq litreg, lit(litreg)" */
3162 set_tok_const (newtok
[1], lit
);
3163 set_tok_preg (newtok
[2], newtok
[0].X_add_number
);
3165 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
3167 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3168 if (insn
.nfixups
> 0)
3170 memmove (&insn
.fixups
[1], &insn
.fixups
[0],
3171 sizeof(struct alpha_fixup
) * insn
.nfixups
);
3174 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITUSE
;
3175 insn
.fixups
[0].exp
.X_op
= O_symbol
;
3176 insn
.fixups
[0].exp
.X_add_symbol
= section_symbol (now_seg
);
3177 insn
.fixups
[0].exp
.X_add_number
= LITUSE_BASE
;
3182 /* emit "addq litreg, base, target" */
3184 if (basereg
!= AXP_REG_ZERO
)
3186 set_tok_reg (newtok
[1], basereg
);
3187 set_tok_reg (newtok
[2], targreg
);
3188 assemble_tokens ("addq", newtok
, 3, 0);
3190 #endif /* !OBJ_EVAX */
3193 set_tok_const (*poffset
, 0);
3194 *pbasereg
= targreg
;
3198 offsetT low
, high
, extra
, tmp
;
3200 /* for 32-bit operands, break up the addend */
3202 low
= sign_extend_16 (addend
);
3204 high
= sign_extend_16 (tmp
>> 16);
3206 if (tmp
- (high
<< 16))
3210 high
= sign_extend_16 (tmp
>> 16);
3215 set_tok_reg (newtok
[0], targreg
);
3216 set_tok_preg (newtok
[2], basereg
);
3220 /* emit "ldah r, extra(r) */
3221 set_tok_const (newtok
[1], extra
);
3222 assemble_tokens ("ldah", newtok
, 3, 0);
3223 set_tok_preg (newtok
[2], basereg
= targreg
);
3228 /* emit "ldah r, high(r) */
3229 set_tok_const (newtok
[1], high
);
3230 assemble_tokens ("ldah", newtok
, 3, 0);
3232 set_tok_preg (newtok
[2], basereg
);
3235 if ((low
&& !poffset
) || (!poffset
&& basereg
!= targreg
))
3237 /* emit "lda r, low(base)" */
3238 set_tok_const (newtok
[1], low
);
3239 assemble_tokens ("lda", newtok
, 3, 0);
3245 set_tok_const (*poffset
, low
);
3246 *pbasereg
= basereg
;
3252 /* The lda macro differs from the lda instruction in that it handles
3253 most simple expressions, particualrly symbol address loads and
3257 emit_lda (tok
, ntok
, opname
)
3258 const expressionS
*tok
;
3263 const expressionS
*reloc
= (const expressionS
*)0;
3266 if (ntok
&& USER_RELOC_P (tok
[ntok
-1].X_op
))
3268 const struct alpha_reloc_op_tag
*r
;
3270 reloc
= &tok
[ntok
-1];
3271 r
= ALPHA_RELOC_TABLE (reloc
->X_op
);
3272 switch (reloc
->X_op
)
3275 as_bad (_("Cannot use !%s!%d with %s"), r
->name
,
3276 (int)reloc
->X_add_number
, (const char *)opname
);
3278 reloc
= (const expressionS
*)0;
3286 /* For lda $x,0($x)!lituse_base!y, don't use load_expression, since
3287 it is really too general for our needs. Instead just generate the
3291 || tok
[0].X_op
!= O_register
3292 || !is_ir_num(tok
[0].X_add_number
)
3293 || tok
[1].X_op
!= O_constant
3294 || tok
[2].X_op
!= O_pregister
3295 || !is_ir_num(tok
[2].X_add_number
))
3297 as_bad (_("bad instruction format for lda !%s!%ld"), r
->name
,
3298 (long) reloc
->X_add_number
);
3300 reloc
= (const expressionS
*)0;
3305 emit_loadstore (tok
, ntok
, "lda");
3312 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
3314 basereg
= tok
[2].X_add_number
;
3316 (void) load_expression (tok
[0].X_add_number
, &tok
[1], &basereg
, NULL
, reloc
);
3319 /* The ldah macro differs from the ldah instruction in that it has $31
3320 as an implied base register. */
3323 emit_ldah (tok
, ntok
, unused
)
3324 const expressionS
*tok
;
3325 int ntok ATTRIBUTE_UNUSED
;
3326 const PTR unused ATTRIBUTE_UNUSED
;
3328 expressionS newtok
[3];
3331 if (ntok
&& USER_RELOC_P (tok
[ntok
-1].X_op
))
3333 const expressionS
*reloc_exp
= &tok
[ntok
-1];
3334 const struct alpha_reloc_op_tag
*r
= ALPHA_RELOC_TABLE (reloc_exp
->X_op
);
3335 as_bad (_("Cannot use !%s!%d with %s"), r
->name
,
3336 (int)reloc_exp
->X_add_number
, "ldah");
3343 set_tok_preg (newtok
[2], AXP_REG_ZERO
);
3345 assemble_tokens ("ldah", newtok
, 3, 0);
3348 /* Handle all "simple" integer register loads -- ldq, ldq_l, ldq_u,
3349 etc. They differ from the real instructions in that they do simple
3350 expressions like the lda macro. */
3353 emit_ir_load (tok
, ntok
, opname
)
3354 const expressionS
*tok
;
3358 int basereg
, lituse
;
3359 expressionS newtok
[3];
3360 struct alpha_insn insn
;
3363 const expressionS
*reloc
= (const expressionS
*)0;
3365 if (ntok
&& USER_RELOC_P (tok
[ntok
-1].X_op
))
3367 const struct alpha_reloc_op_tag
*r
;
3369 reloc
= &tok
[ntok
-1];
3370 switch (reloc
->X_op
)
3377 if (strcmp ((const char *)opname
, "ldq") == 0)
3379 emit_lda (tok
, ntok
, opname
);
3386 r
= ALPHA_RELOC_TABLE (reloc
->X_op
);
3387 as_bad (_("Cannot use !%s!%d with %s"), r
->name
,
3388 (int)reloc
->X_add_number
, (const char *)opname
);
3394 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
3396 basereg
= tok
[2].X_add_number
;
3398 lituse
= load_expression (tok
[0].X_add_number
, &tok
[1], &basereg
,
3399 &newtok
[1], (const expressionS
*)0);
3402 set_tok_preg (newtok
[2], basereg
);
3404 assemble_tokens_to_insn ((const char *)opname
, newtok
, 3, &insn
);
3409 int nfixups
= insn
.nfixups
;
3410 const struct alpha_reloc_op_tag
*r
= ALPHA_RELOC_TABLE (reloc
->X_op
);
3412 assert (nfixups
< MAX_INSN_FIXUPS
);
3413 insn
.fixups
[nfixups
].reloc
= r
->reloc
;
3414 insn
.fixups
[nfixups
].exp
.X_op
= O_symbol
;
3415 insn
.fixups
[nfixups
].exp
.X_add_symbol
= section_symbol (now_seg
);
3416 insn
.fixups
[nfixups
].exp
.X_add_number
= r
->lituse
;
3417 insn
.sequence
[nfixups
] = reloc
->X_add_number
;
3424 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3425 if (insn
.nfixups
> 0)
3427 memmove (&insn
.fixups
[1], &insn
.fixups
[0],
3428 sizeof(struct alpha_fixup
) * insn
.nfixups
);
3431 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITUSE
;
3432 insn
.fixups
[0].exp
.X_op
= O_symbol
;
3433 insn
.fixups
[0].exp
.X_add_symbol
= section_symbol (now_seg
);
3434 insn
.fixups
[0].exp
.X_add_number
= LITUSE_BASE
;
3440 /* Handle fp register loads, and both integer and fp register stores.
3441 Again, we handle simple expressions. */
3444 emit_loadstore (tok
, ntok
, opname
)
3445 const expressionS
*tok
;
3449 int basereg
, lituse
;
3450 expressionS newtok
[3];
3451 struct alpha_insn insn
;
3454 const expressionS
*reloc
= (const expressionS
*)0;
3456 if (ntok
&& USER_RELOC_P (tok
[ntok
-1].X_op
))
3458 reloc
= &tok
[--ntok
];
3459 if (reloc
->X_op
!= O_lituse_base
)
3461 const struct alpha_reloc_op_tag
*r
= &alpha_reloc_op
[ reloc
->X_md
];
3462 as_bad (_("Cannot use !%s!%d with %s"), r
->name
,
3463 (int)reloc
->X_add_number
, (const char *)opname
);
3469 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
3471 basereg
= tok
[2].X_add_number
;
3473 if (tok
[1].X_op
!= O_constant
|| !range_signed_16(tok
[1].X_add_number
))
3476 as_bad (_("macro requires $at register while noat in effect"));
3478 lituse
= load_expression (AXP_REG_AT
, &tok
[1], &basereg
, &newtok
[1],
3479 (const expressionS
*)0);
3488 set_tok_preg (newtok
[2], basereg
);
3490 assemble_tokens_to_insn ((const char *)opname
, newtok
, 3, &insn
);
3495 int nfixups
= insn
.nfixups
;
3496 const struct alpha_reloc_op_tag
*r
= ALPHA_RELOC_TABLE (reloc
->X_op
);
3498 assert (nfixups
< MAX_INSN_FIXUPS
);
3499 insn
.fixups
[nfixups
].reloc
= r
->reloc
;
3500 insn
.fixups
[nfixups
].exp
.X_op
= O_symbol
;
3501 insn
.fixups
[nfixups
].exp
.X_add_symbol
= section_symbol (now_seg
);
3502 insn
.fixups
[nfixups
].exp
.X_add_number
= r
->lituse
;
3503 insn
.sequence
[nfixups
] = reloc
->X_add_number
;
3510 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3511 if (insn
.nfixups
> 0)
3513 memmove (&insn
.fixups
[1], &insn
.fixups
[0],
3514 sizeof(struct alpha_fixup
) * insn
.nfixups
);
3517 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITUSE
;
3518 insn
.fixups
[0].exp
.X_op
= O_symbol
;
3519 insn
.fixups
[0].exp
.X_add_symbol
= section_symbol (now_seg
);
3520 insn
.fixups
[0].exp
.X_add_number
= LITUSE_BASE
;
3526 /* Load a half-word or byte as an unsigned value. */
3529 emit_ldXu (tok
, ntok
, vlgsize
)
3530 const expressionS
*tok
;
3534 if (alpha_target
& AXP_OPCODE_BWX
)
3535 emit_ir_load (tok
, ntok
, ldXu_op
[(long)vlgsize
]);
3538 expressionS newtok
[3];
3541 if (ntok
&& USER_RELOC_P (tok
[ntok
-1].X_op
))
3543 const expressionS
*reloc_exp
= &tok
[ntok
-1];
3544 const struct alpha_reloc_op_tag
*r
3545 = ALPHA_RELOC_TABLE (reloc_exp
->X_op
);
3547 as_bad (_("Cannot use !%s!%d with %s"), r
->name
,
3548 (int)reloc_exp
->X_add_number
, "ldbu/ldwu");
3554 as_bad (_("macro requires $at register while noat in effect"));
3556 /* emit "lda $at, exp" */
3558 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
3559 newtok
[0].X_add_number
= AXP_REG_AT
;
3560 assemble_tokens ("lda", newtok
, ntok
, 1);
3562 /* emit "ldq_u targ, 0($at)" */
3565 set_tok_const (newtok
[1], 0);
3566 set_tok_preg (newtok
[2], AXP_REG_AT
);
3567 assemble_tokens ("ldq_u", newtok
, 3, 1);
3569 /* emit "extXl targ, $at, targ" */
3571 set_tok_reg (newtok
[1], AXP_REG_AT
);
3572 newtok
[2] = newtok
[0];
3573 assemble_tokens (extXl_op
[(long)vlgsize
], newtok
, 3, 1);
3577 /* Load a half-word or byte as a signed value. */
3580 emit_ldX (tok
, ntok
, vlgsize
)
3581 const expressionS
*tok
;
3585 emit_ldXu (tok
, ntok
, vlgsize
);
3586 assemble_tokens (sextX_op
[(long)vlgsize
], tok
, 1, 1);
3589 /* Load an integral value from an unaligned address as an unsigned
3593 emit_uldXu (tok
, ntok
, vlgsize
)
3594 const expressionS
*tok
;
3598 long lgsize
= (long)vlgsize
;
3599 expressionS newtok
[3];
3602 as_bad (_("macro requires $at register while noat in effect"));
3604 /* emit "lda $at, exp" */
3606 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
3607 newtok
[0].X_add_number
= AXP_REG_AT
;
3608 assemble_tokens ("lda", newtok
, ntok
, 1);
3610 /* emit "ldq_u $t9, 0($at)" */
3612 set_tok_reg (newtok
[0], AXP_REG_T9
);
3613 set_tok_const (newtok
[1], 0);
3614 set_tok_preg (newtok
[2], AXP_REG_AT
);
3615 assemble_tokens ("ldq_u", newtok
, 3, 1);
3617 /* emit "ldq_u $t10, size-1($at)" */
3619 set_tok_reg (newtok
[0], AXP_REG_T10
);
3620 set_tok_const (newtok
[1], (1<<lgsize
)-1);
3621 assemble_tokens ("ldq_u", newtok
, 3, 1);
3623 /* emit "extXl $t9, $at, $t9" */
3625 set_tok_reg (newtok
[0], AXP_REG_T9
);
3626 set_tok_reg (newtok
[1], AXP_REG_AT
);
3627 set_tok_reg (newtok
[2], AXP_REG_T9
);
3628 assemble_tokens (extXl_op
[lgsize
], newtok
, 3, 1);
3630 /* emit "extXh $t10, $at, $t10" */
3632 set_tok_reg (newtok
[0], AXP_REG_T10
);
3633 set_tok_reg (newtok
[2], AXP_REG_T10
);
3634 assemble_tokens (extXh_op
[lgsize
], newtok
, 3, 1);
3636 /* emit "or $t9, $t10, targ" */
3638 set_tok_reg (newtok
[0], AXP_REG_T9
);
3639 set_tok_reg (newtok
[1], AXP_REG_T10
);
3641 assemble_tokens ("or", newtok
, 3, 1);
3644 /* Load an integral value from an unaligned address as a signed value.
3645 Note that quads should get funneled to the unsigned load since we
3646 don't have to do the sign extension. */
3649 emit_uldX (tok
, ntok
, vlgsize
)
3650 const expressionS
*tok
;
3654 emit_uldXu (tok
, ntok
, vlgsize
);
3655 assemble_tokens (sextX_op
[(long)vlgsize
], tok
, 1, 1);
3658 /* Implement the ldil macro. */
3661 emit_ldil (tok
, ntok
, unused
)
3662 const expressionS
*tok
;
3664 const PTR unused ATTRIBUTE_UNUSED
;
3666 expressionS newtok
[2];
3669 if (ntok
&& USER_RELOC_P (tok
[ntok
-1].X_op
))
3671 const expressionS
*reloc_exp
= &tok
[ntok
-1];
3672 const struct alpha_reloc_op_tag
*r
= ALPHA_RELOC_TABLE (reloc_exp
->X_op
);
3673 as_bad (_("Cannot use !%s!%d with %s"), r
->name
,
3674 (int)reloc_exp
->X_add_number
, "ldil");
3679 memcpy (newtok
, tok
, sizeof(newtok
));
3680 newtok
[1].X_add_number
= sign_extend_32 (tok
[1].X_add_number
);
3682 assemble_tokens ("lda", newtok
, ntok
, 1);
3685 /* Store a half-word or byte. */
3688 emit_stX (tok
, ntok
, vlgsize
)
3689 const expressionS
*tok
;
3693 int lgsize
= (int)(long)vlgsize
;
3695 if (alpha_target
& AXP_OPCODE_BWX
)
3696 emit_loadstore (tok
, ntok
, stX_op
[lgsize
]);
3699 expressionS newtok
[3];
3702 as_bad(_("macro requires $at register while noat in effect"));
3704 /* emit "lda $at, exp" */
3706 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
3707 newtok
[0].X_add_number
= AXP_REG_AT
;
3708 assemble_tokens ("lda", newtok
, ntok
, 1);
3710 /* emit "ldq_u $t9, 0($at)" */
3712 set_tok_reg (newtok
[0], AXP_REG_T9
);
3713 set_tok_const (newtok
[1], 0);
3714 set_tok_preg (newtok
[2], AXP_REG_AT
);
3715 assemble_tokens ("ldq_u", newtok
, 3, 1);
3717 /* emit "insXl src, $at, $t10" */
3720 set_tok_reg (newtok
[1], AXP_REG_AT
);
3721 set_tok_reg (newtok
[2], AXP_REG_T10
);
3722 assemble_tokens (insXl_op
[lgsize
], newtok
, 3, 1);
3724 /* emit "mskXl $t9, $at, $t9" */
3726 set_tok_reg (newtok
[0], AXP_REG_T9
);
3727 newtok
[2] = newtok
[0];
3728 assemble_tokens (mskXl_op
[lgsize
], newtok
, 3, 1);
3730 /* emit "or $t9, $t10, $t9" */
3732 set_tok_reg (newtok
[1], AXP_REG_T10
);
3733 assemble_tokens ("or", newtok
, 3, 1);
3735 /* emit "stq_u $t9, 0($at) */
3737 set_tok_const (newtok
[1], 0);
3738 set_tok_preg (newtok
[2], AXP_REG_AT
);
3739 assemble_tokens ("stq_u", newtok
, 3, 1);
3743 /* Store an integer to an unaligned address. */
3746 emit_ustX (tok
, ntok
, vlgsize
)
3747 const expressionS
*tok
;
3751 int lgsize
= (int)(long)vlgsize
;
3752 expressionS newtok
[3];
3754 /* emit "lda $at, exp" */
3756 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
3757 newtok
[0].X_add_number
= AXP_REG_AT
;
3758 assemble_tokens ("lda", newtok
, ntok
, 1);
3760 /* emit "ldq_u $9, 0($at)" */
3762 set_tok_reg (newtok
[0], AXP_REG_T9
);
3763 set_tok_const (newtok
[1], 0);
3764 set_tok_preg (newtok
[2], AXP_REG_AT
);
3765 assemble_tokens ("ldq_u", newtok
, 3, 1);
3767 /* emit "ldq_u $10, size-1($at)" */
3769 set_tok_reg (newtok
[0], AXP_REG_T10
);
3770 set_tok_const (newtok
[1], (1 << lgsize
)-1);
3771 assemble_tokens ("ldq_u", newtok
, 3, 1);
3773 /* emit "insXl src, $at, $t11" */
3776 set_tok_reg (newtok
[1], AXP_REG_AT
);
3777 set_tok_reg (newtok
[2], AXP_REG_T11
);
3778 assemble_tokens (insXl_op
[lgsize
], newtok
, 3, 1);
3780 /* emit "insXh src, $at, $t12" */
3782 set_tok_reg (newtok
[2], AXP_REG_T12
);
3783 assemble_tokens (insXh_op
[lgsize
], newtok
, 3, 1);
3785 /* emit "mskXl $t9, $at, $t9" */
3787 set_tok_reg (newtok
[0], AXP_REG_T9
);
3788 newtok
[2] = newtok
[0];
3789 assemble_tokens (mskXl_op
[lgsize
], newtok
, 3, 1);
3791 /* emit "mskXh $t10, $at, $t10" */
3793 set_tok_reg (newtok
[0], AXP_REG_T10
);
3794 newtok
[2] = newtok
[0];
3795 assemble_tokens (mskXh_op
[lgsize
], newtok
, 3, 1);
3797 /* emit "or $t9, $t11, $t9" */
3799 set_tok_reg (newtok
[0], AXP_REG_T9
);
3800 set_tok_reg (newtok
[1], AXP_REG_T11
);
3801 newtok
[2] = newtok
[0];
3802 assemble_tokens ("or", newtok
, 3, 1);
3804 /* emit "or $t10, $t12, $t10" */
3806 set_tok_reg (newtok
[0], AXP_REG_T10
);
3807 set_tok_reg (newtok
[1], AXP_REG_T12
);
3808 newtok
[2] = newtok
[0];
3809 assemble_tokens ("or", newtok
, 3, 1);
3811 /* emit "stq_u $t9, 0($at)" */
3813 set_tok_reg (newtok
[0], AXP_REG_T9
);
3814 set_tok_const (newtok
[1], 0);
3815 set_tok_preg (newtok
[2], AXP_REG_AT
);
3816 assemble_tokens ("stq_u", newtok
, 3, 1);
3818 /* emit "stq_u $t10, size-1($at)" */
3820 set_tok_reg (newtok
[0], AXP_REG_T10
);
3821 set_tok_const (newtok
[1], (1 << lgsize
)-1);
3822 assemble_tokens ("stq_u", newtok
, 3, 1);
3825 /* Sign extend a half-word or byte. The 32-bit sign extend is
3826 implemented as "addl $31, $r, $t" in the opcode table. */
3829 emit_sextX (tok
, ntok
, vlgsize
)
3830 const expressionS
*tok
;
3834 long lgsize
= (long)vlgsize
;
3836 if (alpha_target
& AXP_OPCODE_BWX
)
3837 assemble_tokens (sextX_op
[lgsize
], tok
, ntok
, 0);
3840 int bitshift
= 64 - 8 * (1 << lgsize
);
3841 expressionS newtok
[3];
3844 if (ntok
&& USER_RELOC_P (tok
[ntok
-1].X_op
))
3846 const expressionS
*reloc_exp
= &tok
[ntok
-1];
3847 const struct alpha_reloc_op_tag
*r
3848 = ALPHA_RELOC_TABLE (reloc_exp
->X_op
);
3850 as_bad (_("Cannot use !%s!%d with %s"), r
->name
,
3851 (int)reloc_exp
->X_add_number
, "setxt");
3856 /* emit "sll src,bits,dst" */
3859 set_tok_const (newtok
[1], bitshift
);
3860 newtok
[2] = tok
[ntok
- 1];
3861 assemble_tokens ("sll", newtok
, 3, 1);
3863 /* emit "sra dst,bits,dst" */
3865 newtok
[0] = newtok
[2];
3866 assemble_tokens ("sra", newtok
, 3, 1);
3870 /* Implement the division and modulus macros. */
3874 /* Make register usage like in normal procedure call.
3875 Don't clobber PV and RA. */
3878 emit_division (tok
, ntok
, symname
)
3879 const expressionS
*tok
;
3883 /* DIVISION and MODULUS. Yech.
3888 * mov x,R16 # if x != R16
3889 * mov y,R17 # if y != R17
3894 * with appropriate optimizations if R0,R16,R17 are the registers
3895 * specified by the compiler.
3900 expressionS newtok
[3];
3903 if (ntok
&& USER_RELOC_P (tok
[ntok
-1].X_op
))
3905 const expressionS
*reloc_exp
= &tok
[ntok
-1];
3906 const struct alpha_reloc_op_tag
*r
= ALPHA_RELOC_TABLE (reloc_exp
->X_op
);
3907 as_bad (_("Cannot use !%s!%d with %s"), r
->name
,
3908 (int)reloc_exp
->X_add_number
, (char char *)symname
);
3913 xr
= regno (tok
[0].X_add_number
);
3914 yr
= regno (tok
[1].X_add_number
);
3919 rr
= regno (tok
[2].X_add_number
);
3921 /* Move the operands into the right place */
3922 if (yr
== AXP_REG_R16
&& xr
== AXP_REG_R17
)
3924 /* They are in exactly the wrong order -- swap through AT */
3927 as_bad (_("macro requires $at register while noat in effect"));
3929 set_tok_reg (newtok
[0], AXP_REG_R16
);
3930 set_tok_reg (newtok
[1], AXP_REG_AT
);
3931 assemble_tokens ("mov", newtok
, 2, 1);
3933 set_tok_reg (newtok
[0], AXP_REG_R17
);
3934 set_tok_reg (newtok
[1], AXP_REG_R16
);
3935 assemble_tokens ("mov", newtok
, 2, 1);
3937 set_tok_reg (newtok
[0], AXP_REG_AT
);
3938 set_tok_reg (newtok
[1], AXP_REG_R17
);
3939 assemble_tokens ("mov", newtok
, 2, 1);
3943 if (yr
== AXP_REG_R16
)
3945 set_tok_reg (newtok
[0], AXP_REG_R16
);
3946 set_tok_reg (newtok
[1], AXP_REG_R17
);
3947 assemble_tokens ("mov", newtok
, 2, 1);
3950 if (xr
!= AXP_REG_R16
)
3952 set_tok_reg (newtok
[0], xr
);
3953 set_tok_reg (newtok
[1], AXP_REG_R16
);
3954 assemble_tokens ("mov", newtok
, 2, 1);
3957 if (yr
!= AXP_REG_R16
&& yr
!= AXP_REG_R17
)
3959 set_tok_reg (newtok
[0], yr
);
3960 set_tok_reg (newtok
[1], AXP_REG_R17
);
3961 assemble_tokens ("mov", newtok
, 2, 1);
3965 sym
= symbol_find_or_make ((const char *)symname
);
3967 set_tok_reg (newtok
[0], AXP_REG_AT
);
3968 set_tok_sym (newtok
[1], sym
, 0);
3969 assemble_tokens ("lda", newtok
, 2, 1);
3971 /* Call the division routine */
3972 set_tok_reg (newtok
[0], AXP_REG_AT
);
3973 set_tok_cpreg (newtok
[1], AXP_REG_AT
);
3974 set_tok_const (newtok
[2], 0);
3975 assemble_tokens ("jsr", newtok
, 3, 1);
3977 /* Move the result to the right place */
3978 if (rr
!= AXP_REG_R0
)
3980 set_tok_reg (newtok
[0], AXP_REG_R0
);
3981 set_tok_reg (newtok
[1], rr
);
3982 assemble_tokens ("mov", newtok
, 2, 1);
3986 #else /* !OBJ_EVAX */
3989 emit_division (tok
, ntok
, symname
)
3990 const expressionS
*tok
;
3994 /* DIVISION and MODULUS. Yech.
4004 * with appropriate optimizations if t10,t11,t12 are the registers
4005 * specified by the compiler.
4010 expressionS newtok
[3];
4013 if (ntok
&& USER_RELOC_P (tok
[ntok
-1].X_op
))
4015 const expressionS
*reloc_exp
= &tok
[ntok
-1];
4016 const struct alpha_reloc_op_tag
*r
= ALPHA_RELOC_TABLE (reloc_exp
->X_op
);
4017 as_bad (_("Cannot use !%s!%d with %s"), r
->name
,
4018 (int)reloc_exp
->X_add_number
, (const char *)symname
);
4023 xr
= regno (tok
[0].X_add_number
);
4024 yr
= regno (tok
[1].X_add_number
);
4029 rr
= regno (tok
[2].X_add_number
);
4031 sym
= symbol_find_or_make ((const char *)symname
);
4033 /* Move the operands into the right place */
4034 if (yr
== AXP_REG_T10
&& xr
== AXP_REG_T11
)
4036 /* They are in exactly the wrong order -- swap through AT */
4039 as_bad (_("macro requires $at register while noat in effect"));
4041 set_tok_reg (newtok
[0], AXP_REG_T10
);
4042 set_tok_reg (newtok
[1], AXP_REG_AT
);
4043 assemble_tokens ("mov", newtok
, 2, 1);
4045 set_tok_reg (newtok
[0], AXP_REG_T11
);
4046 set_tok_reg (newtok
[1], AXP_REG_T10
);
4047 assemble_tokens ("mov", newtok
, 2, 1);
4049 set_tok_reg (newtok
[0], AXP_REG_AT
);
4050 set_tok_reg (newtok
[1], AXP_REG_T11
);
4051 assemble_tokens ("mov", newtok
, 2, 1);
4055 if (yr
== AXP_REG_T10
)
4057 set_tok_reg (newtok
[0], AXP_REG_T10
);
4058 set_tok_reg (newtok
[1], AXP_REG_T11
);
4059 assemble_tokens ("mov", newtok
, 2, 1);
4062 if (xr
!= AXP_REG_T10
)
4064 set_tok_reg (newtok
[0], xr
);
4065 set_tok_reg (newtok
[1], AXP_REG_T10
);
4066 assemble_tokens ("mov", newtok
, 2, 1);
4069 if (yr
!= AXP_REG_T10
&& yr
!= AXP_REG_T11
)
4071 set_tok_reg (newtok
[0], yr
);
4072 set_tok_reg (newtok
[1], AXP_REG_T11
);
4073 assemble_tokens ("mov", newtok
, 2, 1);
4077 /* Call the division routine */
4078 set_tok_reg (newtok
[0], AXP_REG_T9
);
4079 set_tok_sym (newtok
[1], sym
, 0);
4080 assemble_tokens ("jsr", newtok
, 2, 1);
4082 /* Reload the GP register */
4086 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
4087 set_tok_reg (newtok
[0], alpha_gp_register
);
4088 set_tok_const (newtok
[1], 0);
4089 set_tok_preg (newtok
[2], AXP_REG_T9
);
4090 assemble_tokens ("ldgp", newtok
, 3, 1);
4093 /* Move the result to the right place */
4094 if (rr
!= AXP_REG_T12
)
4096 set_tok_reg (newtok
[0], AXP_REG_T12
);
4097 set_tok_reg (newtok
[1], rr
);
4098 assemble_tokens ("mov", newtok
, 2, 1);
4102 #endif /* !OBJ_EVAX */
4104 /* The jsr and jmp macros differ from their instruction counterparts
4105 in that they can load the target address and default most
4109 emit_jsrjmp (tok
, ntok
, vopname
)
4110 const expressionS
*tok
;
4114 const char *opname
= (const char *) vopname
;
4115 struct alpha_insn insn
;
4116 expressionS newtok
[3];
4117 int r
, tokidx
= 0, lituse
= 0;
4120 if (ntok
&& USER_RELOC_P (tok
[ntok
-1].X_op
))
4122 const expressionS
*reloc_exp
= &tok
[ntok
-1];
4123 const struct alpha_reloc_op_tag
*r
= ALPHA_RELOC_TABLE (reloc_exp
->X_op
);
4124 as_bad (_("Cannot use !%s!%d with %s"), r
->name
,
4125 (int)reloc_exp
->X_add_number
, opname
);
4130 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_register
)
4131 r
= regno (tok
[tokidx
++].X_add_number
);
4133 r
= strcmp (opname
, "jmp") == 0 ? AXP_REG_ZERO
: AXP_REG_RA
;
4135 set_tok_reg (newtok
[0], r
);
4137 if (tokidx
< ntok
&&
4138 (tok
[tokidx
].X_op
== O_pregister
|| tok
[tokidx
].X_op
== O_cpregister
))
4139 r
= regno (tok
[tokidx
++].X_add_number
);
4141 /* keep register if jsr $n.<sym> */
4145 int basereg
= alpha_gp_register
;
4146 lituse
= load_expression (r
= AXP_REG_PV
, &tok
[tokidx
], &basereg
, NULL
,
4147 (const expressionS
*)0);
4151 set_tok_cpreg (newtok
[1], r
);
4154 /* FIXME: Add hint relocs to BFD for evax. */
4157 newtok
[2] = tok
[tokidx
];
4160 set_tok_const (newtok
[2], 0);
4162 assemble_tokens_to_insn (opname
, newtok
, 3, &insn
);
4164 /* add the LITUSE fixup */
4167 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
4168 if (insn
.nfixups
> 0)
4170 memmove (&insn
.fixups
[1], &insn
.fixups
[0],
4171 sizeof(struct alpha_fixup
) * insn
.nfixups
);
4174 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITUSE
;
4175 insn
.fixups
[0].exp
.X_op
= O_symbol
;
4176 insn
.fixups
[0].exp
.X_add_symbol
= section_symbol (now_seg
);
4177 insn
.fixups
[0].exp
.X_add_number
= LITUSE_JSR
;
4183 /* The ret and jcr instructions differ from their instruction
4184 counterparts in that everything can be defaulted. */
4187 emit_retjcr (tok
, ntok
, vopname
)
4188 const expressionS
*tok
;
4192 const char *opname
= (const char *)vopname
;
4193 expressionS newtok
[3];
4197 if (ntok
&& USER_RELOC_P (tok
[ntok
-1].X_op
))
4199 const expressionS
*reloc_exp
= &tok
[ntok
-1];
4200 const struct alpha_reloc_op_tag
*r
= ALPHA_RELOC_TABLE (reloc_exp
->X_op
);
4201 as_bad (_("Cannot use !%s!%d with %s"), r
->name
,
4202 (int)reloc_exp
->X_add_number
, opname
);
4207 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_register
)
4208 r
= regno (tok
[tokidx
++].X_add_number
);
4212 set_tok_reg (newtok
[0], r
);
4214 if (tokidx
< ntok
&&
4215 (tok
[tokidx
].X_op
== O_pregister
|| tok
[tokidx
].X_op
== O_cpregister
))
4216 r
= regno (tok
[tokidx
++].X_add_number
);
4220 set_tok_cpreg (newtok
[1], r
);
4223 newtok
[2] = tok
[tokidx
];
4225 set_tok_const (newtok
[2], strcmp(opname
, "ret") == 0);
4227 assemble_tokens (opname
, newtok
, 3, 0);
4230 /* Assembler directives */
4232 /* Handle the .text pseudo-op. This is like the usual one, but it
4233 clears alpha_insn_label and restores auto alignment. */
4241 alpha_insn_label
= NULL
;
4242 alpha_auto_align_on
= 1;
4243 alpha_current_align
= 0;
4246 /* Handle the .data pseudo-op. This is like the usual one, but it
4247 clears alpha_insn_label and restores auto alignment. */
4254 alpha_insn_label
= NULL
;
4255 alpha_auto_align_on
= 1;
4256 alpha_current_align
= 0;
4259 #if defined (OBJ_ECOFF) || defined (OBJ_EVAX)
4261 /* Handle the OSF/1 and openVMS .comm pseudo quirks.
4262 openVMS constructs a section for every common symbol. */
4265 s_alpha_comm (ignore
)
4268 register char *name
;
4272 register symbolS
*symbolP
;
4275 segT current_section
= now_seg
;
4276 int current_subsec
= now_subseg
;
4280 name
= input_line_pointer
;
4281 c
= get_symbol_end ();
4283 /* just after name is now '\0' */
4284 p
= input_line_pointer
;
4289 /* Alpha OSF/1 compiler doesn't provide the comma, gcc does. */
4290 if (*input_line_pointer
== ',')
4292 input_line_pointer
++;
4295 if ((temp
= get_absolute_expression ()) < 0)
4297 as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) temp
);
4298 ignore_rest_of_line ();
4303 symbolP
= symbol_find_or_make (name
);
4306 /* Make a section for the common symbol. */
4307 new_seg
= subseg_new (xstrdup (name
), 0);
4313 /* alignment might follow */
4314 if (*input_line_pointer
== ',')
4318 input_line_pointer
++;
4319 align
= get_absolute_expression ();
4320 bfd_set_section_alignment (stdoutput
, new_seg
, align
);
4324 if (S_IS_DEFINED (symbolP
) && ! S_IS_COMMON (symbolP
))
4326 as_bad (_("Ignoring attempt to re-define symbol"));
4327 ignore_rest_of_line ();
4332 if (bfd_section_size (stdoutput
, new_seg
) > 0)
4334 if (bfd_section_size (stdoutput
, new_seg
) != temp
)
4335 as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
4336 S_GET_NAME (symbolP
),
4337 (long) bfd_section_size (stdoutput
, new_seg
),
4341 if (S_GET_VALUE (symbolP
))
4343 if (S_GET_VALUE (symbolP
) != (valueT
) temp
)
4344 as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
4345 S_GET_NAME (symbolP
),
4346 (long) S_GET_VALUE (symbolP
),
4353 subseg_set (new_seg
, 0);
4354 p
= frag_more (temp
);
4355 new_seg
->flags
|= SEC_IS_COMMON
;
4356 if (! S_IS_DEFINED (symbolP
))
4357 S_SET_SEGMENT (symbolP
, new_seg
);
4359 S_SET_VALUE (symbolP
, (valueT
) temp
);
4361 S_SET_EXTERNAL (symbolP
);
4365 subseg_set (current_section
, current_subsec
);
4368 know (symbol_get_frag (symbolP
) == &zero_address_frag
);
4370 demand_empty_rest_of_line ();
4373 #endif /* ! OBJ_ELF */
4377 /* Handle the .rdata pseudo-op. This is like the usual one, but it
4378 clears alpha_insn_label and restores auto alignment. */
4381 s_alpha_rdata (ignore
)
4386 temp
= get_absolute_expression ();
4387 subseg_new (".rdata", 0);
4388 demand_empty_rest_of_line ();
4389 alpha_insn_label
= NULL
;
4390 alpha_auto_align_on
= 1;
4391 alpha_current_align
= 0;
4398 /* Handle the .sdata pseudo-op. This is like the usual one, but it
4399 clears alpha_insn_label and restores auto alignment. */
4402 s_alpha_sdata (ignore
)
4407 temp
= get_absolute_expression ();
4408 subseg_new (".sdata", 0);
4409 demand_empty_rest_of_line ();
4410 alpha_insn_label
= NULL
;
4411 alpha_auto_align_on
= 1;
4412 alpha_current_align
= 0;
4418 /* Handle the .section pseudo-op. This is like the usual one, but it
4419 clears alpha_insn_label and restores auto alignment. */
4422 s_alpha_section (ignore
)
4425 obj_elf_section (ignore
);
4427 alpha_insn_label
= NULL
;
4428 alpha_auto_align_on
= 1;
4429 alpha_current_align
= 0;
4434 int dummy ATTRIBUTE_UNUSED
;
4436 if (ECOFF_DEBUGGING
)
4437 ecoff_directive_ent (0);
4440 char *name
, name_end
;
4441 name
= input_line_pointer
;
4442 name_end
= get_symbol_end ();
4444 if (! is_name_beginner (*name
))
4446 as_warn (_(".ent directive has no name"));
4447 *input_line_pointer
= name_end
;
4453 if (alpha_cur_ent_sym
)
4454 as_warn (_("nested .ent directives"));
4456 sym
= symbol_find_or_make (name
);
4457 symbol_get_bfdsym (sym
)->flags
|= BSF_FUNCTION
;
4458 alpha_cur_ent_sym
= sym
;
4460 /* The .ent directive is sometimes followed by a number. Not sure
4461 what it really means, but ignore it. */
4462 *input_line_pointer
= name_end
;
4464 if (*input_line_pointer
== ',')
4466 input_line_pointer
++;
4469 if (isdigit (*input_line_pointer
) || *input_line_pointer
== '-')
4470 (void) get_absolute_expression ();
4472 demand_empty_rest_of_line ();
4478 int dummy ATTRIBUTE_UNUSED
;
4480 if (ECOFF_DEBUGGING
)
4481 ecoff_directive_end (0);
4484 char *name
, name_end
;
4485 name
= input_line_pointer
;
4486 name_end
= get_symbol_end ();
4488 if (! is_name_beginner (*name
))
4490 as_warn (_(".end directive has no name"));
4491 *input_line_pointer
= name_end
;
4497 sym
= symbol_find (name
);
4498 if (sym
!= alpha_cur_ent_sym
)
4499 as_warn (_(".end directive names different symbol than .ent"));
4501 /* Create an expression to calculate the size of the function. */
4504 symbol_get_obj (sym
)->size
=
4505 (expressionS
*) xmalloc (sizeof (expressionS
));
4506 symbol_get_obj (sym
)->size
->X_op
= O_subtract
;
4507 symbol_get_obj (sym
)->size
->X_add_symbol
4508 = symbol_new ("L0\001", now_seg
, frag_now_fix (), frag_now
);
4509 symbol_get_obj (sym
)->size
->X_op_symbol
= sym
;
4510 symbol_get_obj (sym
)->size
->X_add_number
= 0;
4513 alpha_cur_ent_sym
= NULL
;
4515 *input_line_pointer
= name_end
;
4517 demand_empty_rest_of_line ();
4525 if (ECOFF_DEBUGGING
)
4528 ecoff_directive_fmask (0);
4530 ecoff_directive_mask (0);
4533 discard_rest_of_line ();
4537 s_alpha_frame (dummy
)
4538 int dummy ATTRIBUTE_UNUSED
;
4540 if (ECOFF_DEBUGGING
)
4541 ecoff_directive_frame (0);
4543 discard_rest_of_line ();
4547 s_alpha_prologue (ignore
)
4548 int ignore ATTRIBUTE_UNUSED
;
4553 arg
= get_absolute_expression ();
4554 demand_empty_rest_of_line ();
4556 if (ECOFF_DEBUGGING
)
4557 sym
= ecoff_get_cur_proc_sym ();
4559 sym
= alpha_cur_ent_sym
;
4564 case 0: /* No PV required. */
4565 S_SET_OTHER (sym
, STO_ALPHA_NOPV
4566 | (S_GET_OTHER (sym
) & ~STO_ALPHA_STD_GPLOAD
));
4568 case 1: /* Std GP load. */
4569 S_SET_OTHER (sym
, STO_ALPHA_STD_GPLOAD
4570 | (S_GET_OTHER (sym
) & ~STO_ALPHA_STD_GPLOAD
));
4572 case 2: /* Non-std use of PV. */
4576 as_bad (_("Invalid argument %d to .prologue."), arg
);
4582 s_alpha_file (ignore
)
4583 int ignore ATTRIBUTE_UNUSED
;
4585 if (ECOFF_DEBUGGING
)
4586 ecoff_directive_file (0);
4588 dwarf2_directive_file (0);
4592 s_alpha_loc (ignore
)
4593 int ignore ATTRIBUTE_UNUSED
;
4595 if (ECOFF_DEBUGGING
)
4596 ecoff_directive_loc (0);
4598 dwarf2_directive_loc (0);
4602 s_alpha_coff_wrapper (which
)
4605 static void (* const fns
[]) PARAMS ((int)) = {
4606 ecoff_directive_begin
,
4607 ecoff_directive_bend
,
4608 ecoff_directive_def
,
4609 ecoff_directive_dim
,
4610 ecoff_directive_endef
,
4611 ecoff_directive_scl
,
4612 ecoff_directive_tag
,
4613 ecoff_directive_val
,
4616 assert (which
>= 0 && which
< (int)(sizeof(fns
)/sizeof(*fns
)));
4618 if (ECOFF_DEBUGGING
)
4622 as_bad (_("ECOFF debugging is disabled."));
4623 ignore_rest_of_line ();
4626 #endif /* OBJ_ELF */
4630 /* Handle the section specific pseudo-op. */
4633 s_alpha_section (secid
)
4637 #define EVAX_SECTION_COUNT 5
4638 static char *section_name
[EVAX_SECTION_COUNT
+1] =
4639 { "NULL", ".rdata", ".comm", ".link", ".ctors", ".dtors" };
4641 if ((secid
<= 0) || (secid
> EVAX_SECTION_COUNT
))
4643 as_fatal (_("Unknown section directive"));
4644 demand_empty_rest_of_line ();
4647 temp
= get_absolute_expression ();
4648 subseg_new (section_name
[secid
], 0);
4649 demand_empty_rest_of_line ();
4650 alpha_insn_label
= NULL
;
4651 alpha_auto_align_on
= 1;
4652 alpha_current_align
= 0;
4655 /* Parse .ent directives. */
4658 s_alpha_ent (ignore
)
4662 expressionS symexpr
;
4664 alpha_evax_proc
.pdsckind
= 0;
4665 alpha_evax_proc
.framereg
= -1;
4666 alpha_evax_proc
.framesize
= 0;
4667 alpha_evax_proc
.rsa_offset
= 0;
4668 alpha_evax_proc
.ra_save
= AXP_REG_RA
;
4669 alpha_evax_proc
.fp_save
= -1;
4670 alpha_evax_proc
.imask
= 0;
4671 alpha_evax_proc
.fmask
= 0;
4672 alpha_evax_proc
.prologue
= 0;
4673 alpha_evax_proc
.type
= 0;
4675 expression (&symexpr
);
4677 if (symexpr
.X_op
!= O_symbol
)
4679 as_fatal (_(".ent directive has no symbol"));
4680 demand_empty_rest_of_line ();
4684 symbol
= make_expr_symbol (&symexpr
);
4685 symbol_get_bfdsym (symbol
)->flags
|= BSF_FUNCTION
;
4686 alpha_evax_proc
.symbol
= symbol
;
4688 demand_empty_rest_of_line ();
4692 /* Parse .frame <framreg>,<framesize>,RA,<rsa_offset> directives. */
4695 s_alpha_frame (ignore
)
4700 alpha_evax_proc
.framereg
= tc_get_register (1);
4703 if (*input_line_pointer
++ != ','
4704 || get_absolute_expression_and_terminator (&val
) != ',')
4706 as_warn (_("Bad .frame directive 1./2. param"));
4707 --input_line_pointer
;
4708 demand_empty_rest_of_line ();
4712 alpha_evax_proc
.framesize
= val
;
4714 (void) tc_get_register (1);
4716 if (*input_line_pointer
++ != ',')
4718 as_warn (_("Bad .frame directive 3./4. param"));
4719 --input_line_pointer
;
4720 demand_empty_rest_of_line ();
4723 alpha_evax_proc
.rsa_offset
= get_absolute_expression ();
4729 s_alpha_pdesc (ignore
)
4739 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
4741 if (now_seg
!= alpha_link_section
)
4743 as_bad (_(".pdesc directive not in link (.link) section"));
4744 demand_empty_rest_of_line ();
4748 if ((alpha_evax_proc
.symbol
== 0)
4749 || (!S_IS_DEFINED (alpha_evax_proc
.symbol
)))
4751 as_fatal (_(".pdesc has no matching .ent"));
4752 demand_empty_rest_of_line ();
4756 *symbol_get_obj (alpha_evax_proc
.symbol
) =
4757 (valueT
) seginfo
->literal_pool_size
;
4760 if (exp
.X_op
!= O_symbol
)
4762 as_warn (_(".pdesc directive has no entry symbol"));
4763 demand_empty_rest_of_line ();
4767 entry_sym
= make_expr_symbol (&exp
);
4768 /* Save bfd symbol of proc desc in function symbol. */
4769 symbol_get_bfdsym (alpha_evax_proc
.symbol
)->udata
.p
4770 = symbol_get_bfdsym (entry_sym
);
4773 if (*input_line_pointer
++ != ',')
4775 as_warn (_("No comma after .pdesc <entryname>"));
4776 demand_empty_rest_of_line ();
4781 name
= input_line_pointer
;
4782 name_end
= get_symbol_end ();
4784 if (strncmp(name
, "stack", 5) == 0)
4786 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_FP_STACK
;
4788 else if (strncmp(name
, "reg", 3) == 0)
4790 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_FP_REGISTER
;
4792 else if (strncmp(name
, "null", 4) == 0)
4794 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_NULL
;
4798 as_fatal (_("unknown procedure kind"));
4799 demand_empty_rest_of_line ();
4803 *input_line_pointer
= name_end
;
4804 demand_empty_rest_of_line ();
4806 #ifdef md_flush_pending_output
4807 md_flush_pending_output ();
4810 frag_align (3, 0, 0);
4812 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
4814 seginfo
->literal_pool_size
+= 16;
4816 *p
= alpha_evax_proc
.pdsckind
4817 | ((alpha_evax_proc
.framereg
== 29) ? PDSC_S_M_BASE_REG_IS_FP
: 0);
4818 *(p
+1) = PDSC_S_M_NATIVE
4819 | PDSC_S_M_NO_JACKET
;
4821 switch (alpha_evax_proc
.pdsckind
)
4823 case PDSC_S_K_KIND_NULL
:
4827 case PDSC_S_K_KIND_FP_REGISTER
:
4828 *(p
+2) = alpha_evax_proc
.fp_save
;
4829 *(p
+3) = alpha_evax_proc
.ra_save
;
4831 case PDSC_S_K_KIND_FP_STACK
:
4832 md_number_to_chars (p
+2, (valueT
)alpha_evax_proc
.rsa_offset
, 2);
4834 default: /* impossible */
4839 *(p
+5) = alpha_evax_proc
.type
& 0x0f;
4841 /* Signature offset. */
4842 md_number_to_chars (p
+6, (valueT
)0, 2);
4844 fix_new_exp (frag_now
, p
-frag_now
->fr_literal
+8, 8, &exp
, 0, BFD_RELOC_64
);
4846 if (alpha_evax_proc
.pdsckind
== PDSC_S_K_KIND_NULL
)
4849 /* Add dummy fix to make add_to_link_pool work. */
4851 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
4853 seginfo
->literal_pool_size
+= 8;
4855 /* pdesc+16: Size. */
4856 md_number_to_chars (p
, (valueT
)alpha_evax_proc
.framesize
, 4);
4858 md_number_to_chars (p
+4, (valueT
)0, 2);
4861 md_number_to_chars (p
+6, alpha_evax_proc
.prologue
, 2);
4863 if (alpha_evax_proc
.pdsckind
== PDSC_S_K_KIND_FP_REGISTER
)
4866 /* Add dummy fix to make add_to_link_pool work. */
4868 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
4870 seginfo
->literal_pool_size
+= 8;
4872 /* pdesc+24: register masks. */
4874 md_number_to_chars (p
, alpha_evax_proc
.imask
, 4);
4875 md_number_to_chars (p
+4, alpha_evax_proc
.fmask
, 4);
4880 /* Support for crash debug on vms. */
4883 s_alpha_name (ignore
)
4888 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
4890 if (now_seg
!= alpha_link_section
)
4892 as_bad (_(".name directive not in link (.link) section"));
4893 demand_empty_rest_of_line ();
4898 if (exp
.X_op
!= O_symbol
)
4900 as_warn (_(".name directive has no symbol"));
4901 demand_empty_rest_of_line ();
4905 demand_empty_rest_of_line ();
4907 #ifdef md_flush_pending_output
4908 md_flush_pending_output ();
4911 frag_align (3, 0, 0);
4913 seginfo
->literal_pool_size
+= 8;
4915 fix_new_exp (frag_now
, p
-frag_now
->fr_literal
, 8, &exp
, 0, BFD_RELOC_64
);
4921 s_alpha_linkage (ignore
)
4927 #ifdef md_flush_pending_output
4928 md_flush_pending_output ();
4932 if (exp
.X_op
!= O_symbol
)
4934 as_fatal (_("No symbol after .linkage"));
4938 p
= frag_more (LKP_S_K_SIZE
);
4939 memset (p
, 0, LKP_S_K_SIZE
);
4940 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, LKP_S_K_SIZE
, &exp
, 0,\
4941 BFD_RELOC_ALPHA_LINKAGE
);
4943 demand_empty_rest_of_line ();
4949 s_alpha_code_address (ignore
)
4955 #ifdef md_flush_pending_output
4956 md_flush_pending_output ();
4960 if (exp
.X_op
!= O_symbol
)
4962 as_fatal (_("No symbol after .code_address"));
4968 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 8, &exp
, 0,\
4969 BFD_RELOC_ALPHA_CODEADDR
);
4971 demand_empty_rest_of_line ();
4977 s_alpha_fp_save (ignore
)
4981 alpha_evax_proc
.fp_save
= tc_get_register (1);
4983 demand_empty_rest_of_line ();
4988 s_alpha_mask (ignore
)
4993 if (get_absolute_expression_and_terminator (&val
) != ',')
4995 as_warn (_("Bad .mask directive"));
4996 --input_line_pointer
;
5000 alpha_evax_proc
.imask
= val
;
5001 (void)get_absolute_expression ();
5003 demand_empty_rest_of_line ();
5009 s_alpha_fmask (ignore
)
5014 if (get_absolute_expression_and_terminator (&val
) != ',')
5016 as_warn (_("Bad .fmask directive"));
5017 --input_line_pointer
;
5021 alpha_evax_proc
.fmask
= val
;
5022 (void) get_absolute_expression ();
5024 demand_empty_rest_of_line ();
5030 s_alpha_end (ignore
)
5035 c
= get_symbol_end ();
5036 *input_line_pointer
= c
;
5037 demand_empty_rest_of_line ();
5038 alpha_evax_proc
.symbol
= 0;
5044 s_alpha_file (ignore
)
5049 static char case_hack
[32];
5051 extern char *demand_copy_string
PARAMS ((int *lenP
));
5053 sprintf (case_hack
, "<CASE:%01d%01d>",
5054 alpha_flag_hash_long_names
, alpha_flag_show_after_trunc
);
5056 s
= symbol_find_or_make (case_hack
);
5057 symbol_get_bfdsym (s
)->flags
|= BSF_FILE
;
5059 get_absolute_expression ();
5060 s
= symbol_find_or_make (demand_copy_string (&length
));
5061 symbol_get_bfdsym (s
)->flags
|= BSF_FILE
;
5062 demand_empty_rest_of_line ();
5066 #endif /* OBJ_EVAX */
5068 /* Handle the .gprel32 pseudo op. */
5071 s_alpha_gprel32 (ignore
)
5072 int ignore ATTRIBUTE_UNUSED
;
5084 e
.X_add_symbol
= section_symbol(absolute_section
);
5097 e
.X_add_symbol
= section_symbol (absolute_section
);
5100 e
.X_op
= O_subtract
;
5101 e
.X_op_symbol
= alpha_gp_symbol
;
5109 if (alpha_auto_align_on
&& alpha_current_align
< 2)
5110 alpha_align (2, (char *) NULL
, alpha_insn_label
, 0);
5111 if (alpha_current_align
> 2)
5112 alpha_current_align
= 2;
5113 alpha_insn_label
= NULL
;
5117 fix_new_exp (frag_now
, p
-frag_now
->fr_literal
, 4,
5118 &e
, 0, BFD_RELOC_GPREL32
);
5121 /* Handle floating point allocation pseudo-ops. This is like the
5122 generic vresion, but it makes sure the current label, if any, is
5123 correctly aligned. */
5126 s_alpha_float_cons (type
)
5153 if (alpha_auto_align_on
&& alpha_current_align
< log_size
)
5154 alpha_align (log_size
, (char *) NULL
, alpha_insn_label
, 0);
5155 if (alpha_current_align
> log_size
)
5156 alpha_current_align
= log_size
;
5157 alpha_insn_label
= NULL
;
5162 /* Handle the .proc pseudo op. We don't really do much with it except
5166 s_alpha_proc (is_static
)
5167 int is_static ATTRIBUTE_UNUSED
;
5175 /* Takes ".proc name,nargs" */
5177 name
= input_line_pointer
;
5178 c
= get_symbol_end ();
5179 p
= input_line_pointer
;
5180 symbolP
= symbol_find_or_make (name
);
5183 if (*input_line_pointer
!= ',')
5186 as_warn (_("Expected comma after name \"%s\""), name
);
5189 ignore_rest_of_line ();
5193 input_line_pointer
++;
5194 temp
= get_absolute_expression ();
5196 /* *symbol_get_obj (symbolP) = (signed char) temp; */
5197 as_warn (_("unhandled: .proc %s,%d"), name
, temp
);
5198 demand_empty_rest_of_line ();
5201 /* Handle the .set pseudo op. This is used to turn on and off most of
5202 the assembler features. */
5206 int x ATTRIBUTE_UNUSED
;
5212 name
= input_line_pointer
;
5213 ch
= get_symbol_end ();
5216 if (s
[0] == 'n' && s
[1] == 'o')
5221 if (!strcmp ("reorder", s
))
5223 else if (!strcmp ("at", s
))
5224 alpha_noat_on
= !yesno
;
5225 else if (!strcmp ("macro", s
))
5226 alpha_macros_on
= yesno
;
5227 else if (!strcmp ("move", s
))
5229 else if (!strcmp ("volatile", s
))
5232 as_warn (_("Tried to .set unrecognized mode `%s'"), name
);
5234 *input_line_pointer
= ch
;
5235 demand_empty_rest_of_line ();
5238 /* Handle the .base pseudo op. This changes the assembler's notion of
5239 the $gp register. */
5242 s_alpha_base (ignore
)
5243 int ignore ATTRIBUTE_UNUSED
;
5246 if (first_32bit_quadrant
)
5248 /* not fatal, but it might not work in the end */
5249 as_warn (_("File overrides no-base-register option."));
5250 first_32bit_quadrant
= 0;
5255 if (*input_line_pointer
== '$')
5257 input_line_pointer
++;
5258 if (*input_line_pointer
== 'r')
5259 input_line_pointer
++;
5262 alpha_gp_register
= get_absolute_expression ();
5263 if (alpha_gp_register
< 0 || alpha_gp_register
> 31)
5265 alpha_gp_register
= AXP_REG_GP
;
5266 as_warn (_("Bad base register, using $%d."), alpha_gp_register
);
5269 demand_empty_rest_of_line ();
5272 /* Handle the .align pseudo-op. This aligns to a power of two. It
5273 also adjusts any current instruction label. We treat this the same
5274 way the MIPS port does: .align 0 turns off auto alignment. */
5277 s_alpha_align (ignore
)
5278 int ignore ATTRIBUTE_UNUSED
;
5282 long max_alignment
= 15;
5284 align
= get_absolute_expression ();
5285 if (align
> max_alignment
)
5287 align
= max_alignment
;
5288 as_bad (_("Alignment too large: %d. assumed"), align
);
5292 as_warn (_("Alignment negative: 0 assumed"));
5296 if (*input_line_pointer
== ',')
5298 input_line_pointer
++;
5299 fill
= get_absolute_expression ();
5307 alpha_auto_align_on
= 1;
5308 alpha_align (align
, pfill
, alpha_insn_label
, 1);
5312 alpha_auto_align_on
= 0;
5315 demand_empty_rest_of_line ();
5318 /* Hook the normal string processor to reset known alignment. */
5321 s_alpha_stringer (terminate
)
5324 alpha_current_align
= 0;
5325 alpha_insn_label
= NULL
;
5326 stringer (terminate
);
5329 /* Hook the normal space processing to reset known alignment. */
5332 s_alpha_space (ignore
)
5335 alpha_current_align
= 0;
5336 alpha_insn_label
= NULL
;
5340 /* Hook into cons for auto-alignment. */
5343 alpha_cons_align (size
)
5349 while ((size
>>= 1) != 0)
5352 if (alpha_auto_align_on
&& alpha_current_align
< log_size
)
5353 alpha_align (log_size
, (char *) NULL
, alpha_insn_label
, 0);
5354 if (alpha_current_align
> log_size
)
5355 alpha_current_align
= log_size
;
5356 alpha_insn_label
= NULL
;
5359 /* Here come the .uword, .ulong, and .uquad explicitly unaligned
5360 pseudos. We just turn off auto-alignment and call down to cons. */
5363 s_alpha_ucons (bytes
)
5366 int hold
= alpha_auto_align_on
;
5367 alpha_auto_align_on
= 0;
5369 alpha_auto_align_on
= hold
;
5372 /* Switch the working cpu type. */
5375 s_alpha_arch (ignored
)
5376 int ignored ATTRIBUTE_UNUSED
;
5379 const struct cpu_type
*p
;
5382 name
= input_line_pointer
;
5383 ch
= get_symbol_end ();
5385 for (p
= cpu_types
; p
->name
; ++p
)
5386 if (strcmp(name
, p
->name
) == 0)
5388 alpha_target_name
= p
->name
, alpha_target
= p
->flags
;
5391 as_warn("Unknown CPU identifier `%s'", name
);
5394 *input_line_pointer
= ch
;
5395 demand_empty_rest_of_line ();
5401 /* print token expression with alpha specific extension. */
5404 alpha_print_token(f
, exp
)
5406 const expressionS
*exp
;
5416 expressionS nexp
= *exp
;
5417 nexp
.X_op
= O_register
;
5418 print_expr (f
, &nexp
);
5423 print_expr (f
, exp
);
5430 /* The target specific pseudo-ops which we support. */
5432 const pseudo_typeS md_pseudo_table
[] =
5435 {"comm", s_alpha_comm
, 0}, /* osf1 compiler does this */
5436 {"rdata", s_alpha_rdata
, 0},
5438 {"text", s_alpha_text
, 0},
5439 {"data", s_alpha_data
, 0},
5441 {"sdata", s_alpha_sdata
, 0},
5444 {"section", s_alpha_section
, 0},
5445 {"section.s", s_alpha_section
, 0},
5446 {"sect", s_alpha_section
, 0},
5447 {"sect.s", s_alpha_section
, 0},
5450 { "pdesc", s_alpha_pdesc
, 0},
5451 { "name", s_alpha_name
, 0},
5452 { "linkage", s_alpha_linkage
, 0},
5453 { "code_address", s_alpha_code_address
, 0},
5454 { "ent", s_alpha_ent
, 0},
5455 { "frame", s_alpha_frame
, 0},
5456 { "fp_save", s_alpha_fp_save
, 0},
5457 { "mask", s_alpha_mask
, 0},
5458 { "fmask", s_alpha_fmask
, 0},
5459 { "end", s_alpha_end
, 0},
5460 { "file", s_alpha_file
, 0},
5461 { "rdata", s_alpha_section
, 1},
5462 { "comm", s_alpha_comm
, 0},
5463 { "link", s_alpha_section
, 3},
5464 { "ctors", s_alpha_section
, 4},
5465 { "dtors", s_alpha_section
, 5},
5468 /* Frame related pseudos. */
5469 {"ent", s_alpha_ent
, 0},
5470 {"end", s_alpha_end
, 0},
5471 {"mask", s_alpha_mask
, 0},
5472 {"fmask", s_alpha_mask
, 1},
5473 {"frame", s_alpha_frame
, 0},
5474 {"prologue", s_alpha_prologue
, 0},
5475 {"file", s_alpha_file
, 5},
5476 {"loc", s_alpha_loc
, 9},
5477 /* COFF debugging related pseudos. */
5478 {"begin", s_alpha_coff_wrapper
, 0},
5479 {"bend", s_alpha_coff_wrapper
, 1},
5480 {"def", s_alpha_coff_wrapper
, 2},
5481 {"dim", s_alpha_coff_wrapper
, 3},
5482 {"endef", s_alpha_coff_wrapper
, 4},
5483 {"scl", s_alpha_coff_wrapper
, 5},
5484 {"tag", s_alpha_coff_wrapper
, 6},
5485 {"val", s_alpha_coff_wrapper
, 7},
5487 {"prologue", s_ignore
, 0},
5489 {"gprel32", s_alpha_gprel32
, 0},
5490 {"t_floating", s_alpha_float_cons
, 'd'},
5491 {"s_floating", s_alpha_float_cons
, 'f'},
5492 {"f_floating", s_alpha_float_cons
, 'F'},
5493 {"g_floating", s_alpha_float_cons
, 'G'},
5494 {"d_floating", s_alpha_float_cons
, 'D'},
5496 {"proc", s_alpha_proc
, 0},
5497 {"aproc", s_alpha_proc
, 1},
5498 {"set", s_alpha_set
, 0},
5499 {"reguse", s_ignore
, 0},
5500 {"livereg", s_ignore
, 0},
5501 {"base", s_alpha_base
, 0}, /*??*/
5502 {"option", s_ignore
, 0},
5503 {"aent", s_ignore
, 0},
5504 {"ugen", s_ignore
, 0},
5505 {"eflag", s_ignore
, 0},
5507 {"align", s_alpha_align
, 0},
5508 {"double", s_alpha_float_cons
, 'd'},
5509 {"float", s_alpha_float_cons
, 'f'},
5510 {"single", s_alpha_float_cons
, 'f'},
5511 {"ascii", s_alpha_stringer
, 0},
5512 {"asciz", s_alpha_stringer
, 1},
5513 {"string", s_alpha_stringer
, 1},
5514 {"space", s_alpha_space
, 0},
5515 {"skip", s_alpha_space
, 0},
5516 {"zero", s_alpha_space
, 0},
5518 /* Unaligned data pseudos. */
5519 {"uword", s_alpha_ucons
, 2},
5520 {"ulong", s_alpha_ucons
, 4},
5521 {"uquad", s_alpha_ucons
, 8},
5524 /* Dwarf wants these versions of unaligned. */
5525 {"2byte", s_alpha_ucons
, 2},
5526 {"4byte", s_alpha_ucons
, 4},
5527 {"8byte", s_alpha_ucons
, 8},
5530 /* We don't do any optimizing, so we can safely ignore these. */
5531 {"noalias", s_ignore
, 0},
5532 {"alias", s_ignore
, 0},
5534 {"arch", s_alpha_arch
, 0},
5540 /* Build a BFD section with its flags set appropriately for the .lita,
5541 .lit8, or .lit4 sections. */
5544 create_literal_section (name
, secp
, symp
)
5549 segT current_section
= now_seg
;
5550 int current_subsec
= now_subseg
;
5553 *secp
= new_sec
= subseg_new (name
, 0);
5554 subseg_set (current_section
, current_subsec
);
5555 bfd_set_section_alignment (stdoutput
, new_sec
, 4);
5556 bfd_set_section_flags (stdoutput
, new_sec
,
5557 SEC_RELOC
| SEC_ALLOC
| SEC_LOAD
| SEC_READONLY
5560 S_CLEAR_EXTERNAL (*symp
= section_symbol (new_sec
));
5565 /* @@@ GP selection voodoo. All of this seems overly complicated and
5566 unnecessary; which is the primary reason it's for ECOFF only. */
5575 vma
= bfd_get_section_vma (foo
, sec
);
5576 if (vma
&& vma
< alpha_gp_value
)
5577 alpha_gp_value
= vma
;
5583 assert (alpha_gp_value
== 0);
5585 /* Get minus-one in whatever width... */
5586 alpha_gp_value
= 0; alpha_gp_value
--;
5588 /* Select the smallest VMA of these existing sections. */
5589 maybe_set_gp (alpha_lita_section
);
5591 /* These were disabled before -- should we use them? */
5592 maybe_set_gp (sdata
);
5593 maybe_set_gp (lit8_sec
);
5594 maybe_set_gp (lit4_sec
);
5597 /* @@ Will a simple 0x8000 work here? If not, why not? */
5598 #define GP_ADJUSTMENT (0x8000 - 0x10)
5600 alpha_gp_value
+= GP_ADJUSTMENT
;
5602 S_SET_VALUE (alpha_gp_symbol
, alpha_gp_value
);
5605 printf (_("Chose GP value of %lx\n"), alpha_gp_value
);
5608 #endif /* OBJ_ECOFF */
5610 /* Called internally to handle all alignment needs. This takes care
5611 of eliding calls to frag_align if'n the cached current alignment
5612 says we've already got it, as well as taking care of the auto-align
5613 feature wrt labels. */
5616 alpha_align (n
, pfill
, label
, force
)
5620 int force ATTRIBUTE_UNUSED
;
5622 if (alpha_current_align
>= n
)
5628 && (bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
) != 0)
5630 static char const unop
[4] = { 0x00, 0x00, 0xe0, 0x2f };
5631 static char const nopunop
[8] = {
5632 0x1f, 0x04, 0xff, 0x47,
5633 0x00, 0x00, 0xe0, 0x2f
5636 /* First, make sure we're on a four-byte boundary, in case
5637 someone has been putting .byte values into the text
5638 section. The DEC assembler silently fills with unaligned
5639 no-op instructions. This will zero-fill, then nop-fill
5640 with proper alignment. */
5641 if (alpha_current_align
< 2)
5642 frag_align (2, 0, 0);
5643 if (alpha_current_align
< 3)
5644 frag_align_pattern (3, unop
, sizeof unop
, 0);
5646 frag_align_pattern (n
, nopunop
, sizeof nopunop
, 0);
5649 frag_align (n
, 0, 0);
5652 frag_align (n
, *pfill
, 0);
5654 alpha_current_align
= n
;
5656 if (label
!= NULL
&& S_GET_SEGMENT (label
) == now_seg
)
5658 symbol_set_frag (label
, frag_now
);
5659 S_SET_VALUE (label
, (valueT
) frag_now_fix ());
5662 record_alignment (now_seg
, n
);
5664 /* ??? if alpha_flag_relax && force && elf, record the requested alignment
5665 in a reloc for the linker to see. */
5668 /* The Alpha has support for some VAX floating point types, as well as for
5669 IEEE floating point. We consider IEEE to be the primary floating point
5670 format, and sneak in the VAX floating point support here. */
5671 #define md_atof vax_md_atof
5672 #include "config/atof-vax.c"