1 /* tc-alpha.c - Processor-specific code for the DEC Alpha AXP CPU.
2 Copyright (C) 1989, 93-98, 1999, 2000, 2001 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_stab
PARAMS ((int));
252 static void s_alpha_coff_wrapper
PARAMS ((int));
255 static void s_alpha_section
PARAMS ((int));
257 static void s_alpha_gprel32
PARAMS ((int));
258 static void s_alpha_float_cons
PARAMS ((int));
259 static void s_alpha_proc
PARAMS ((int));
260 static void s_alpha_set
PARAMS ((int));
261 static void s_alpha_base
PARAMS ((int));
262 static void s_alpha_align
PARAMS ((int));
263 static void s_alpha_stringer
PARAMS ((int));
264 static void s_alpha_space
PARAMS ((int));
266 static void create_literal_section
PARAMS ((const char *, segT
*, symbolS
**));
268 static void select_gp_value
PARAMS ((void));
270 static void alpha_align
PARAMS ((int, char *, symbolS
*, int));
273 static void alpha_adjust_symtab_relocs
PARAMS ((bfd
*, asection
*, PTR
));
277 /* Generic assembler global variables which must be defined by all
280 /* Characters which always start a comment. */
281 const char comment_chars
[] = "#";
283 /* Characters which start a comment at the beginning of a line. */
284 const char line_comment_chars
[] = "#";
286 /* Characters which may be used to separate multiple commands on a
288 const char line_separator_chars
[] = ";";
290 /* Characters which are used to indicate an exponent in a floating
292 const char EXP_CHARS
[] = "eE";
294 /* Characters which mean that a number is a floating point constant,
297 const char FLT_CHARS
[] = "dD";
299 /* XXX: Do all of these really get used on the alpha?? */
300 char FLT_CHARS
[] = "rRsSfFdDxXpP";
304 const char *md_shortopts
= "Fm:g+1h:HG:";
306 const char *md_shortopts
= "Fm:gG:";
309 struct option md_longopts
[] = {
310 #define OPTION_32ADDR (OPTION_MD_BASE)
311 { "32addr", no_argument
, NULL
, OPTION_32ADDR
},
312 #define OPTION_RELAX (OPTION_32ADDR+1)
313 { "relax", no_argument
, NULL
, OPTION_RELAX
},
315 #define OPTION_MDEBUG (OPTION_RELAX+1)
316 #define OPTION_NO_MDEBUG (OPTION_MDEBUG+1)
317 { "mdebug", no_argument
, NULL
, OPTION_MDEBUG
},
318 { "no-mdebug", no_argument
, NULL
, OPTION_NO_MDEBUG
},
320 { NULL
, no_argument
, NULL
, 0 }
323 size_t md_longopts_size
= sizeof (md_longopts
);
328 #define AXP_REG_R16 16
329 #define AXP_REG_R17 17
331 #define AXP_REG_T9 22
333 #define AXP_REG_T10 23
335 #define AXP_REG_T11 24
337 #define AXP_REG_T12 25
338 #define AXP_REG_AI 25
340 #define AXP_REG_FP 29
343 #define AXP_REG_GP AXP_REG_PV
344 #endif /* OBJ_EVAX */
346 /* The cpu for which we are generating code */
347 static unsigned alpha_target
= AXP_OPCODE_BASE
;
348 static const char *alpha_target_name
= "<all>";
350 /* The hash table of instruction opcodes */
351 static struct hash_control
*alpha_opcode_hash
;
353 /* The hash table of macro opcodes */
354 static struct hash_control
*alpha_macro_hash
;
357 /* The $gp relocation symbol */
358 static symbolS
*alpha_gp_symbol
;
360 /* XXX: what is this, and why is it exported? */
361 valueT alpha_gp_value
;
364 /* The current $gp register */
365 static int alpha_gp_register
= AXP_REG_GP
;
367 /* A table of the register symbols */
368 static symbolS
*alpha_register_table
[64];
370 /* Constant sections, or sections of constants */
372 static segT alpha_lita_section
;
373 static segT alpha_lit4_section
;
376 static segT alpha_link_section
;
377 static segT alpha_ctors_section
;
378 static segT alpha_dtors_section
;
380 static segT alpha_lit8_section
;
382 /* Symbols referring to said sections. */
384 static symbolS
*alpha_lita_symbol
;
385 static symbolS
*alpha_lit4_symbol
;
388 static symbolS
*alpha_link_symbol
;
389 static symbolS
*alpha_ctors_symbol
;
390 static symbolS
*alpha_dtors_symbol
;
392 static symbolS
*alpha_lit8_symbol
;
394 /* Literal for .litX+0x8000 within .lita */
396 static offsetT alpha_lit4_literal
;
397 static offsetT alpha_lit8_literal
;
401 /* The active .ent symbol. */
402 static symbolS
*alpha_cur_ent_sym
;
405 /* Is the assembler not allowed to use $at? */
406 static int alpha_noat_on
= 0;
408 /* Are macros enabled? */
409 static int alpha_macros_on
= 1;
411 /* Are floats disabled? */
412 static int alpha_nofloats_on
= 0;
414 /* Are addresses 32 bit? */
415 static int alpha_addr32_on
= 0;
417 /* Symbol labelling the current insn. When the Alpha gas sees
420 and the section happens to not be on an eight byte boundary, it
421 will align both the symbol and the .quad to an eight byte boundary. */
422 static symbolS
*alpha_insn_label
;
424 /* Whether we should automatically align data generation pseudo-ops.
425 .align 0 will turn this off. */
426 static int alpha_auto_align_on
= 1;
428 /* The known current alignment of the current section. */
429 static int alpha_current_align
;
431 /* These are exported to ECOFF code. */
432 unsigned long alpha_gprmask
, alpha_fprmask
;
434 /* Whether the debugging option was seen. */
435 static int alpha_debug
;
438 /* Whether we are emitting an mdebug section. */
439 int alpha_flag_mdebug
= -1;
442 /* Don't fully resolve relocations, allowing code movement in the linker. */
443 static int alpha_flag_relax
;
445 /* What value to give to bfd_set_gp_size. */
446 static int g_switch_value
= 8;
449 /* Collect information about current procedure here. */
451 symbolS
*symbol
; /* proc pdesc symbol */
453 int framereg
; /* register for frame pointer */
454 int framesize
; /* size of frame */
464 static int alpha_flag_hash_long_names
= 0; /* -+ */
465 static int alpha_flag_show_after_trunc
= 0; /* -H */
467 /* If the -+ switch is given, then a hash is appended to any name that is
468 * longer than 64 characters, else longer symbol names are truncated.
474 /* A table to map the spelling of a relocation operand into an appropriate
475 bfd_reloc_code_real_type type. The table is assumed to be ordered such
476 that op-O_literal indexes into it. */
478 #define ALPHA_RELOC_TABLE(op) \
479 &alpha_reloc_op[ ((!USER_RELOC_P (op)) \
481 : (int) (op) - (int)O_literal) ]
483 #define LITUSE_BASE 1
484 #define LITUSE_BYTOFF 2
487 static const struct alpha_reloc_op_tag
{
488 const char *name
; /* string to lookup */
489 size_t length
; /* size of the string */
490 bfd_reloc_code_real_type reloc
; /* relocation before frob */
491 operatorT op
; /* which operator to use */
492 int lituse
; /* addened to specify lituse */
493 } alpha_reloc_op
[] = {
496 "literal", /* name */
497 sizeof ("literal")-1, /* length */
498 BFD_RELOC_ALPHA_USER_LITERAL
, /* reloc */
504 "lituse_base", /* name */
505 sizeof ("lituse_base")-1, /* length */
506 BFD_RELOC_ALPHA_USER_LITUSE_BASE
, /* reloc */
507 O_lituse_base
, /* op */
508 LITUSE_BASE
, /* lituse */
512 "lituse_bytoff", /* name */
513 sizeof ("lituse_bytoff")-1, /* length */
514 BFD_RELOC_ALPHA_USER_LITUSE_BYTOFF
, /* reloc */
515 O_lituse_bytoff
, /* op */
516 LITUSE_BYTOFF
, /* lituse */
520 "lituse_jsr", /* name */
521 sizeof ("lituse_jsr")-1, /* length */
522 BFD_RELOC_ALPHA_USER_LITUSE_JSR
, /* reloc */
523 O_lituse_jsr
, /* op */
524 LITUSE_JSR
, /* lituse */
529 sizeof ("gpdisp")-1, /* length */
530 BFD_RELOC_ALPHA_USER_GPDISP
, /* reloc */
536 "gprelhigh", /* name */
537 sizeof ("gprelhigh")-1, /* length */
538 BFD_RELOC_ALPHA_USER_GPRELHIGH
, /* reloc */
539 O_gprelhigh
, /* op */
544 "gprellow", /* name */
545 sizeof ("gprellow")-1, /* length */
546 BFD_RELOC_ALPHA_USER_GPRELLOW
, /* reloc */
552 static const int alpha_num_reloc_op
553 = sizeof (alpha_reloc_op
) / sizeof (*alpha_reloc_op
);
555 /* Maximum # digits needed to hold the largest sequence # */
556 #define ALPHA_RELOC_DIGITS 25
558 /* Whether a sequence number is valid. */
559 #define ALPHA_RELOC_SEQUENCE_OK(X) ((X) > 0 && ((unsigned) (X)) == (X))
561 /* Structure to hold explict sequence information. */
562 struct alpha_literal_tag
564 fixS
*lituse
; /* head of linked list of !literals */
565 segT segment
; /* segment relocs are in or undefined_section*/
566 int multi_section_p
; /* True if more than one section was used */
567 unsigned sequence
; /* sequence # */
568 unsigned n_literals
; /* # of literals */
569 unsigned n_lituses
; /* # of lituses */
570 char string
[1]; /* printable form of sequence to hash with */
573 /* Hash table to link up literals with the appropriate lituse */
574 static struct hash_control
*alpha_literal_hash
;
577 /* A table of CPU names and opcode sets. */
579 static const struct cpu_type
585 /* Ad hoc convention: cpu number gets palcode, process code doesn't.
586 This supports usage under DU 4.0b that does ".arch ev4", and
587 usage in MILO that does -m21064. Probably something more
588 specific like -m21064-pal should be used, but oh well. */
590 { "21064", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
591 { "21064a", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
592 { "21066", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
593 { "21068", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
594 { "21164", AXP_OPCODE_BASE
|AXP_OPCODE_EV5
},
595 { "21164a", AXP_OPCODE_BASE
|AXP_OPCODE_EV5
|AXP_OPCODE_BWX
},
596 { "21164pc", (AXP_OPCODE_BASE
|AXP_OPCODE_EV5
|AXP_OPCODE_BWX
598 { "21264", (AXP_OPCODE_BASE
|AXP_OPCODE_EV6
|AXP_OPCODE_BWX
599 |AXP_OPCODE_MAX
|AXP_OPCODE_CIX
) },
601 { "ev4", AXP_OPCODE_BASE
},
602 { "ev45", AXP_OPCODE_BASE
},
603 { "lca45", AXP_OPCODE_BASE
},
604 { "ev5", AXP_OPCODE_BASE
},
605 { "ev56", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
},
606 { "pca56", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
|AXP_OPCODE_MAX
},
607 { "ev6", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
|AXP_OPCODE_MAX
|AXP_OPCODE_CIX
},
609 { "all", AXP_OPCODE_BASE
},
613 /* The macro table */
615 static const struct alpha_macro alpha_macros
[] = {
616 /* Load/Store macros */
617 { "lda", emit_lda
, NULL
,
618 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_LITERAL
, MACRO_BASE
, MACRO_EOA
} },
619 { "ldah", emit_ldah
, NULL
,
620 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
622 { "ldl", emit_ir_load
, "ldl",
623 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
624 { "ldl_l", emit_ir_load
, "ldl_l",
625 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
626 { "ldq", emit_ir_load
, "ldq",
627 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_LITERAL
, MACRO_EOA
} },
628 { "ldq_l", emit_ir_load
, "ldq_l",
629 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
630 { "ldq_u", emit_ir_load
, "ldq_u",
631 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
632 { "ldf", emit_loadstore
, "ldf",
633 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
634 { "ldg", emit_loadstore
, "ldg",
635 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
636 { "lds", emit_loadstore
, "lds",
637 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
638 { "ldt", emit_loadstore
, "ldt",
639 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
641 { "ldb", emit_ldX
, (PTR
)0,
642 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
643 { "ldbu", emit_ldXu
, (PTR
)0,
644 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
645 { "ldw", emit_ldX
, (PTR
)1,
646 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
647 { "ldwu", emit_ldXu
, (PTR
)1,
648 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
650 { "uldw", emit_uldX
, (PTR
)1,
651 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
652 { "uldwu", emit_uldXu
, (PTR
)1,
653 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
654 { "uldl", emit_uldX
, (PTR
)2,
655 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
656 { "uldlu", emit_uldXu
, (PTR
)2,
657 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
658 { "uldq", emit_uldXu
, (PTR
)3,
659 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
661 { "ldgp", emit_ldgp
, NULL
,
662 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
} },
664 { "ldi", emit_lda
, NULL
,
665 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
666 { "ldil", emit_ldil
, NULL
,
667 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
668 { "ldiq", emit_lda
, NULL
,
669 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
671 { "ldif" emit_ldiq
, NULL
,
672 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
673 { "ldid" emit_ldiq
, NULL
,
674 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
675 { "ldig" emit_ldiq
, NULL
,
676 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
677 { "ldis" emit_ldiq
, NULL
,
678 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
679 { "ldit" emit_ldiq
, NULL
,
680 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
683 { "stl", emit_loadstore
, "stl",
684 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
685 { "stl_c", emit_loadstore
, "stl_c",
686 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
687 { "stq", emit_loadstore
, "stq",
688 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
689 { "stq_c", emit_loadstore
, "stq_c",
690 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
691 { "stq_u", emit_loadstore
, "stq_u",
692 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
693 { "stf", emit_loadstore
, "stf",
694 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
695 { "stg", emit_loadstore
, "stg",
696 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
697 { "sts", emit_loadstore
, "sts",
698 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
699 { "stt", emit_loadstore
, "stt",
700 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
702 { "stb", emit_stX
, (PTR
)0,
703 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
704 { "stw", emit_stX
, (PTR
)1,
705 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
706 { "ustw", emit_ustX
, (PTR
)1,
707 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
708 { "ustl", emit_ustX
, (PTR
)2,
709 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
710 { "ustq", emit_ustX
, (PTR
)3,
711 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_BASE
, MACRO_EOA
} },
713 /* Arithmetic macros */
715 { "absl" emit_absl
, 1, { IR
} },
716 { "absl" emit_absl
, 2, { IR
, IR
} },
717 { "absl" emit_absl
, 2, { EXP
, IR
} },
718 { "absq" emit_absq
, 1, { IR
} },
719 { "absq" emit_absq
, 2, { IR
, IR
} },
720 { "absq" emit_absq
, 2, { EXP
, IR
} },
723 { "sextb", emit_sextX
, (PTR
)0,
724 { MACRO_IR
, MACRO_IR
, MACRO_EOA
,
726 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
727 { "sextw", emit_sextX
, (PTR
)1,
728 { MACRO_IR
, MACRO_IR
, MACRO_EOA
,
730 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
732 { "divl", emit_division
, "__divl",
733 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
734 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
735 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
736 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
737 { "divlu", emit_division
, "__divlu",
738 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
739 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
740 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
741 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
742 { "divq", emit_division
, "__divq",
743 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
744 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
745 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
746 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
747 { "divqu", emit_division
, "__divqu",
748 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
749 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
750 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
751 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
752 { "reml", emit_division
, "__reml",
753 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
754 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
755 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
756 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
757 { "remlu", emit_division
, "__remlu",
758 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
759 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
760 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
761 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
762 { "remq", emit_division
, "__remq",
763 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
764 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
765 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
766 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
767 { "remqu", emit_division
, "__remqu",
768 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
769 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
770 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
771 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
773 { "jsr", emit_jsrjmp
, "jsr",
774 { MACRO_PIR
, MACRO_EXP
, MACRO_JSR
, MACRO_EOA
,
775 MACRO_PIR
, MACRO_JSR
, MACRO_EOA
,
776 MACRO_IR
, MACRO_EXP
, MACRO_JSR
, MACRO_EOA
,
777 MACRO_EXP
, MACRO_JSR
, MACRO_EOA
} },
778 { "jmp", emit_jsrjmp
, "jmp",
779 { MACRO_PIR
, MACRO_EXP
, MACRO_JSR
, MACRO_EOA
,
780 MACRO_PIR
, MACRO_JSR
, MACRO_EOA
,
781 MACRO_IR
, MACRO_EXP
, MACRO_JSR
, MACRO_EOA
,
782 MACRO_EXP
, MACRO_JSR
, MACRO_EOA
} },
783 { "ret", emit_retjcr
, "ret",
784 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
786 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
787 MACRO_PIR
, MACRO_EOA
,
788 MACRO_EXP
, MACRO_EOA
,
790 { "jcr", emit_retjcr
, "jcr",
791 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
793 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
794 MACRO_PIR
, MACRO_EOA
,
795 MACRO_EXP
, MACRO_EOA
,
797 { "jsr_coroutine", emit_retjcr
, "jcr",
798 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
800 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
801 MACRO_PIR
, MACRO_EOA
,
802 MACRO_EXP
, MACRO_EOA
,
806 static const unsigned int alpha_num_macros
807 = sizeof (alpha_macros
) / sizeof (*alpha_macros
);
809 /* Public interface functions */
811 /* This function is called once, at assembler startup time. It sets
812 up all the tables, etc. that the MD part of the assembler will
813 need, that can be determined before arguments are parsed. */
820 /* Verify that X_op field is wide enough. */
824 assert (e
.X_op
== O_max
);
827 /* Create the opcode hash table */
829 alpha_opcode_hash
= hash_new ();
830 for (i
= 0; i
< alpha_num_opcodes
; )
832 const char *name
, *retval
, *slash
;
834 name
= alpha_opcodes
[i
].name
;
835 retval
= hash_insert (alpha_opcode_hash
, name
, (PTR
)&alpha_opcodes
[i
]);
837 as_fatal (_("internal error: can't hash opcode `%s': %s"), name
, retval
);
839 /* Some opcodes include modifiers of various sorts with a "/mod"
840 syntax, like the architecture manual suggests. However, for
841 use with gcc at least, we also need access to those same opcodes
844 if ((slash
= strchr (name
, '/')) != NULL
)
846 char *p
= xmalloc (strlen (name
));
847 memcpy (p
, name
, slash
- name
);
848 strcpy (p
+ (slash
- name
), slash
+ 1);
850 (void)hash_insert(alpha_opcode_hash
, p
, (PTR
)&alpha_opcodes
[i
]);
851 /* Ignore failures -- the opcode table does duplicate some
852 variants in different forms, like "hw_stq" and "hw_st/q". */
855 while (++i
< alpha_num_opcodes
856 && (alpha_opcodes
[i
].name
== name
857 || !strcmp (alpha_opcodes
[i
].name
, name
)))
861 /* Create the macro hash table */
863 alpha_macro_hash
= hash_new ();
864 for (i
= 0; i
< alpha_num_macros
; )
866 const char *name
, *retval
;
868 name
= alpha_macros
[i
].name
;
869 retval
= hash_insert (alpha_macro_hash
, name
, (PTR
)&alpha_macros
[i
]);
871 as_fatal (_("internal error: can't hash macro `%s': %s"), name
, retval
);
873 while (++i
< alpha_num_macros
874 && (alpha_macros
[i
].name
== name
875 || !strcmp (alpha_macros
[i
].name
, name
)))
879 /* Construct symbols for each of the registers */
881 for (i
= 0; i
< 32; ++i
)
884 sprintf (name
, "$%d", i
);
885 alpha_register_table
[i
] = symbol_create(name
, reg_section
, i
,
891 sprintf (name
, "$f%d", i
-32);
892 alpha_register_table
[i
] = symbol_create(name
, reg_section
, i
,
896 /* Create the special symbols and sections we'll be using */
898 /* So .sbss will get used for tiny objects. */
899 bfd_set_gp_size (stdoutput
, g_switch_value
);
902 create_literal_section (".lita", &alpha_lita_section
, &alpha_lita_symbol
);
904 /* For handling the GP, create a symbol that won't be output in the
905 symbol table. We'll edit it out of relocs later. */
906 alpha_gp_symbol
= symbol_create ("<GP value>", alpha_lita_section
, 0x8000,
911 create_literal_section (".link", &alpha_link_section
, &alpha_link_symbol
);
917 segT sec
= subseg_new(".mdebug", (subsegT
)0);
918 bfd_set_section_flags(stdoutput
, sec
, SEC_HAS_CONTENTS
|SEC_READONLY
);
919 bfd_set_section_alignment(stdoutput
, sec
, 3);
923 subseg_set(text_section
, 0);
926 /* Create literal lookup hash table. */
927 alpha_literal_hash
= hash_new();
931 /* The public interface to the instruction assembler. */
937 char opname
[32]; /* current maximum is 13 */
938 expressionS tok
[MAX_INSN_ARGS
];
942 /* split off the opcode */
943 opnamelen
= strspn (str
, "abcdefghijklmnopqrstuvwxyz_/46819");
944 trunclen
= (opnamelen
< sizeof (opname
) - 1
946 : sizeof (opname
) - 1);
947 memcpy (opname
, str
, trunclen
);
948 opname
[trunclen
] = '\0';
950 /* tokenize the rest of the line */
951 if ((ntok
= tokenize_arguments (str
+ opnamelen
, tok
, MAX_INSN_ARGS
)) < 0)
953 if (ntok
!= TOKENIZE_ERROR_REPORT
)
954 as_bad (_("syntax error"));
960 assemble_tokens (opname
, tok
, ntok
, alpha_macros_on
);
963 /* Round up a section's size to the appropriate boundary. */
966 md_section_align (seg
, size
)
970 int align
= bfd_get_section_alignment(stdoutput
, seg
);
971 valueT mask
= ((valueT
)1 << align
) - 1;
973 return (size
+ mask
) & ~mask
;
976 /* Turn a string in input_line_pointer into a floating point constant
977 of type TYPE, and store the appropriate bytes in *LITP. The number
978 of LITTLENUMS emitted is stored in *SIZEP. An error message is
979 returned, or NULL on OK. */
981 /* Equal to MAX_PRECISION in atof-ieee.c */
982 #define MAX_LITTLENUMS 6
984 extern char *vax_md_atof
PARAMS ((int, char *, int *));
987 md_atof (type
, litP
, sizeP
)
993 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
994 LITTLENUM_TYPE
*wordP
;
1001 /* VAX md_atof doesn't like "G" for some reason. */
1005 return vax_md_atof (type
, litP
, sizeP
);
1028 return _("Bad call to MD_ATOF()");
1030 t
= atof_ieee (input_line_pointer
, type
, words
);
1032 input_line_pointer
= t
;
1033 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
1035 for (wordP
= words
+ prec
- 1; prec
--;)
1037 md_number_to_chars (litP
, (long) (*wordP
--), sizeof (LITTLENUM_TYPE
));
1038 litP
+= sizeof (LITTLENUM_TYPE
);
1044 /* Take care of the target-specific command-line options. */
1047 md_parse_option (c
, arg
)
1054 alpha_nofloats_on
= 1;
1058 alpha_addr32_on
= 1;
1066 g_switch_value
= atoi(arg
);
1071 const struct cpu_type
*p
;
1072 for (p
= cpu_types
; p
->name
; ++p
)
1073 if (strcmp(arg
, p
->name
) == 0)
1075 alpha_target_name
= p
->name
, alpha_target
= p
->flags
;
1078 as_warn(_("Unknown CPU identifier `%s'"), arg
);
1084 case '+': /* For g++. Hash any name > 63 chars long. */
1085 alpha_flag_hash_long_names
= 1;
1088 case 'H': /* Show new symbol after hash truncation */
1089 alpha_flag_show_after_trunc
= 1;
1092 case 'h': /* for gnu-c/vax compatibility. */
1097 alpha_flag_relax
= 1;
1102 alpha_flag_mdebug
= 1;
1104 case OPTION_NO_MDEBUG
:
1105 alpha_flag_mdebug
= 0;
1116 /* Print a description of the command-line options that we accept. */
1119 md_show_usage (stream
)
1124 -32addr treat addresses as 32-bit values\n\
1125 -F lack floating point instructions support\n\
1126 -mev4 | -mev45 | -mev5 | -mev56 | -mpca56 | -mev6 | -mall\n\
1127 specify variant of Alpha architecture\n\
1128 -m21064 | -m21066 | -m21164 | -m21164a | -m21164pc | -m21264\n\
1129 these variants include PALcode opcodes\n"),
1134 -+ hash encode (don't truncate) names longer than 64 characters\n\
1135 -H show new symbol after hash truncation\n"),
1140 /* Decide from what point a pc-relative relocation is relative to,
1141 relative to the pc-relative fixup. Er, relatively speaking. */
1144 md_pcrel_from (fixP
)
1147 valueT addr
= fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
1148 switch (fixP
->fx_r_type
)
1150 case BFD_RELOC_ALPHA_GPDISP
:
1151 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1152 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1155 return fixP
->fx_size
+ addr
;
1159 /* Attempt to simplify or even eliminate a fixup. The return value is
1160 ignored; perhaps it was once meaningful, but now it is historical.
1161 To indicate that a fixup has been eliminated, set fixP->fx_done.
1163 For ELF, here it is that we transform the GPDISP_HI16 reloc we used
1164 internally into the GPDISP reloc used externally. We had to do
1165 this so that we'd have the GPDISP_LO16 reloc as a tag to compute
1166 the distance to the "lda" instruction for setting the addend to
1170 md_apply_fix (fixP
, valueP
)
1174 char * const fixpos
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
1175 valueT value
= *valueP
;
1176 unsigned image
, size
;
1178 switch (fixP
->fx_r_type
)
1180 /* The GPDISP relocations are processed internally with a symbol
1181 referring to the current function; we need to drop in a value
1182 which, when added to the address of the start of the function,
1183 gives the desired GP. */
1184 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1186 fixS
*next
= fixP
->fx_next
;
1187 assert (next
->fx_r_type
== BFD_RELOC_ALPHA_GPDISP_LO16
);
1189 fixP
->fx_offset
= (next
->fx_frag
->fr_address
+ next
->fx_where
1190 - fixP
->fx_frag
->fr_address
- fixP
->fx_where
);
1192 value
= (value
- sign_extend_16 (value
)) >> 16;
1195 fixP
->fx_r_type
= BFD_RELOC_ALPHA_GPDISP
;
1199 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1200 value
= sign_extend_16 (value
);
1201 fixP
->fx_offset
= 0;
1207 fixP
->fx_addsy
= section_symbol (now_seg
);
1208 md_number_to_chars (fixpos
, value
, 2);
1213 fixP
->fx_r_type
= BFD_RELOC_16_PCREL
;
1218 fixP
->fx_r_type
= BFD_RELOC_32_PCREL
;
1223 fixP
->fx_r_type
= BFD_RELOC_64_PCREL
;
1226 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
1228 md_number_to_chars (fixpos
, value
, size
);
1234 case BFD_RELOC_GPREL32
:
1235 assert (fixP
->fx_subsy
== alpha_gp_symbol
);
1237 /* FIXME: inherited this obliviousness of `value' -- why? */
1238 md_number_to_chars (fixpos
, -alpha_gp_value
, 4);
1242 case BFD_RELOC_GPREL32
:
1246 case BFD_RELOC_23_PCREL_S2
:
1247 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
1249 image
= bfd_getl32(fixpos
);
1250 image
= (image
& ~0x1FFFFF) | ((value
>> 2) & 0x1FFFFF);
1255 case BFD_RELOC_ALPHA_HINT
:
1256 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
1258 image
= bfd_getl32(fixpos
);
1259 image
= (image
& ~0x3FFF) | ((value
>> 2) & 0x3FFF);
1265 case BFD_RELOC_ALPHA_LITERAL
:
1266 md_number_to_chars (fixpos
, value
, 2);
1269 case BFD_RELOC_ALPHA_LITUSE
:
1273 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1274 case BFD_RELOC_ALPHA_LITUSE
:
1278 case BFD_RELOC_ALPHA_LINKAGE
:
1279 case BFD_RELOC_ALPHA_CODEADDR
:
1284 case BFD_RELOC_ALPHA_USER_LITERAL
:
1285 case BFD_RELOC_ALPHA_USER_LITUSE_BASE
:
1286 case BFD_RELOC_ALPHA_USER_LITUSE_BYTOFF
:
1287 case BFD_RELOC_ALPHA_USER_LITUSE_JSR
:
1290 case BFD_RELOC_ALPHA_USER_GPDISP
:
1291 case BFD_RELOC_ALPHA_USER_GPRELHIGH
:
1292 case BFD_RELOC_ALPHA_USER_GPRELLOW
:
1296 case BFD_RELOC_VTABLE_INHERIT
:
1297 case BFD_RELOC_VTABLE_ENTRY
:
1302 const struct alpha_operand
*operand
;
1304 if ((int)fixP
->fx_r_type
>= 0)
1305 as_fatal (_("unhandled relocation type %s"),
1306 bfd_get_reloc_code_name (fixP
->fx_r_type
));
1308 assert (-(int)fixP
->fx_r_type
< (int)alpha_num_operands
);
1309 operand
= &alpha_operands
[-(int)fixP
->fx_r_type
];
1311 /* The rest of these fixups only exist internally during symbol
1312 resolution and have no representation in the object file.
1313 Therefore they must be completely resolved as constants. */
1315 if (fixP
->fx_addsy
!= 0
1316 && S_GET_SEGMENT (fixP
->fx_addsy
) != absolute_section
)
1317 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
1318 _("non-absolute expression in constant field"));
1320 image
= bfd_getl32(fixpos
);
1321 image
= insert_operand(image
, operand
, (offsetT
)value
,
1322 fixP
->fx_file
, fixP
->fx_line
);
1327 if (fixP
->fx_addsy
!= 0 || fixP
->fx_pcrel
!= 0)
1331 as_warn_where(fixP
->fx_file
, fixP
->fx_line
,
1332 _("type %d reloc done?\n"), (int)fixP
->fx_r_type
);
1337 md_number_to_chars(fixpos
, image
, 4);
1345 * Look for a register name in the given symbol.
1349 md_undefined_symbol(name
)
1354 int is_float
= 0, num
;
1359 if (name
[1] == 'p' && name
[2] == '\0')
1360 return alpha_register_table
[AXP_REG_FP
];
1365 if (!isdigit(*++name
))
1369 case '0': case '1': case '2': case '3': case '4':
1370 case '5': case '6': case '7': case '8': case '9':
1371 if (name
[1] == '\0')
1372 num
= name
[0] - '0';
1373 else if (name
[0] != '0' && isdigit(name
[1]) && name
[2] == '\0')
1375 num
= (name
[0] - '0') * 10 + name
[1] - '0';
1382 if (!alpha_noat_on
&& (num
+ is_float
) == AXP_REG_AT
)
1383 as_warn(_("Used $at without \".set noat\""));
1384 return alpha_register_table
[num
+ is_float
];
1387 if (name
[1] == 't' && name
[2] == '\0')
1390 as_warn(_("Used $at without \".set noat\""));
1391 return alpha_register_table
[AXP_REG_AT
];
1396 if (name
[1] == 'p' && name
[2] == '\0')
1397 return alpha_register_table
[alpha_gp_register
];
1401 if (name
[1] == 'p' && name
[2] == '\0')
1402 return alpha_register_table
[AXP_REG_SP
];
1410 /* @@@ Magic ECOFF bits. */
1413 alpha_frob_ecoff_data ()
1416 /* $zero and $f31 are read-only */
1417 alpha_gprmask
&= ~1;
1418 alpha_fprmask
&= ~1;
1422 /* Hook to remember a recently defined label so that the auto-align
1423 code can adjust the symbol after we know what alignment will be
1427 alpha_define_label (sym
)
1430 alpha_insn_label
= sym
;
1433 /* Return true if we must always emit a reloc for a type and false if
1434 there is some hope of resolving it a assembly time. */
1437 alpha_force_relocation (f
)
1440 if (alpha_flag_relax
)
1443 switch (f
->fx_r_type
)
1445 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1446 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1447 case BFD_RELOC_ALPHA_GPDISP
:
1449 case BFD_RELOC_ALPHA_LITERAL
:
1452 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1454 case BFD_RELOC_ALPHA_LITUSE
:
1455 case BFD_RELOC_GPREL32
:
1457 case BFD_RELOC_ALPHA_LINKAGE
:
1458 case BFD_RELOC_ALPHA_CODEADDR
:
1461 case BFD_RELOC_ALPHA_USER_LITERAL
:
1462 case BFD_RELOC_ALPHA_USER_LITUSE_BASE
:
1463 case BFD_RELOC_ALPHA_USER_LITUSE_BYTOFF
:
1464 case BFD_RELOC_ALPHA_USER_LITUSE_JSR
:
1465 case BFD_RELOC_ALPHA_USER_GPDISP
:
1466 case BFD_RELOC_ALPHA_USER_GPRELHIGH
:
1467 case BFD_RELOC_ALPHA_USER_GPRELLOW
:
1469 case BFD_RELOC_VTABLE_INHERIT
:
1470 case BFD_RELOC_VTABLE_ENTRY
:
1473 case BFD_RELOC_23_PCREL_S2
:
1476 case BFD_RELOC_ALPHA_HINT
:
1480 assert((int)f
->fx_r_type
< 0 && -(int)f
->fx_r_type
< (int)alpha_num_operands
);
1485 /* Return true if we can partially resolve a relocation now. */
1488 alpha_fix_adjustable (f
)
1492 /* Prevent all adjustments to global symbols */
1493 if (S_IS_EXTERN (f
->fx_addsy
) || S_IS_WEAK (f
->fx_addsy
))
1497 /* Are there any relocation types for which we must generate a reloc
1498 but we can adjust the values contained within it? */
1499 switch (f
->fx_r_type
)
1501 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1502 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1503 case BFD_RELOC_ALPHA_GPDISP
:
1507 case BFD_RELOC_ALPHA_LITERAL
:
1510 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1513 case BFD_RELOC_ALPHA_USER_LITERAL
:
1516 case BFD_RELOC_ALPHA_LINKAGE
:
1517 case BFD_RELOC_ALPHA_CODEADDR
:
1521 case BFD_RELOC_ALPHA_LITUSE
:
1523 case BFD_RELOC_ALPHA_USER_LITUSE_BASE
:
1524 case BFD_RELOC_ALPHA_USER_LITUSE_BYTOFF
:
1525 case BFD_RELOC_ALPHA_USER_LITUSE_JSR
:
1526 case BFD_RELOC_ALPHA_USER_GPDISP
:
1527 case BFD_RELOC_ALPHA_USER_GPRELHIGH
:
1528 case BFD_RELOC_ALPHA_USER_GPRELLOW
:
1530 case BFD_RELOC_VTABLE_ENTRY
:
1531 case BFD_RELOC_VTABLE_INHERIT
:
1534 case BFD_RELOC_GPREL32
:
1535 case BFD_RELOC_23_PCREL_S2
:
1538 case BFD_RELOC_ALPHA_HINT
:
1542 assert ((int)f
->fx_r_type
< 0
1543 && - (int)f
->fx_r_type
< (int)alpha_num_operands
);
1549 /* Generate the BFD reloc to be stuck in the object file from the
1550 fixup used internally in the assembler. */
1553 tc_gen_reloc (sec
, fixp
)
1554 asection
*sec ATTRIBUTE_UNUSED
;
1559 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
1560 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
1561 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
1562 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
1564 /* Make sure none of our internal relocations make it this far.
1565 They'd better have been fully resolved by this point. */
1566 assert ((int)fixp
->fx_r_type
> 0);
1568 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
1569 if (reloc
->howto
== NULL
)
1571 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1572 _("cannot represent `%s' relocation in object file"),
1573 bfd_get_reloc_code_name (fixp
->fx_r_type
));
1577 if (!fixp
->fx_pcrel
!= !reloc
->howto
->pc_relative
)
1579 as_fatal (_("internal error? cannot generate `%s' relocation"),
1580 bfd_get_reloc_code_name (fixp
->fx_r_type
));
1582 assert (!fixp
->fx_pcrel
== !reloc
->howto
->pc_relative
);
1585 if (fixp
->fx_r_type
== BFD_RELOC_ALPHA_LITERAL
)
1587 /* fake out bfd_perform_relocation. sigh */
1588 reloc
->addend
= -alpha_gp_value
;
1593 reloc
->addend
= fixp
->fx_offset
;
1596 * Ohhh, this is ugly. The problem is that if this is a local global
1597 * symbol, the relocation will entirely be performed at link time, not
1598 * at assembly time. bfd_perform_reloc doesn't know about this sort
1599 * of thing, and as a result we need to fake it out here.
1601 if ((S_IS_EXTERN (fixp
->fx_addsy
) || S_IS_WEAK (fixp
->fx_addsy
))
1602 && !S_IS_COMMON(fixp
->fx_addsy
))
1603 reloc
->addend
-= symbol_get_bfdsym (fixp
->fx_addsy
)->value
;
1610 /* Parse a register name off of the input_line and return a register
1611 number. Gets md_undefined_symbol above to do the register name
1614 Only called as a part of processing the ECOFF .frame directive. */
1617 tc_get_register (frame
)
1618 int frame ATTRIBUTE_UNUSED
;
1620 int framereg
= AXP_REG_SP
;
1623 if (*input_line_pointer
== '$')
1625 char *s
= input_line_pointer
;
1626 char c
= get_symbol_end ();
1627 symbolS
*sym
= md_undefined_symbol (s
);
1629 *strchr(s
, '\0') = c
;
1630 if (sym
&& (framereg
= S_GET_VALUE (sym
)) <= 31)
1633 as_warn (_("frame reg expected, using $%d."), framereg
);
1636 note_gpreg (framereg
);
1640 /* This is called before the symbol table is processed. In order to
1641 work with gcc when using mips-tfile, we must keep all local labels.
1642 However, in other cases, we want to discard them. If we were
1643 called with -g, but we didn't see any debugging information, it may
1644 mean that gcc is smuggling debugging information through to
1645 mips-tfile, in which case we must generate all local labels. */
1650 alpha_frob_file_before_adjust ()
1652 if (alpha_debug
!= 0
1653 && ! ecoff_debugging_seen
)
1654 flag_keep_locals
= 1;
1657 #endif /* OBJ_ECOFF */
1661 /* Before the relocations are written, reorder them, so that user supplied
1662 !lituse relocations follow the appropriate !literal relocations. Also
1663 convert the gas-internal relocations to the appropriate linker relocations.
1667 alpha_adjust_symtab ()
1669 if (alpha_literal_hash
)
1672 fprintf (stderr
, "alpha_adjust_symtab called\n");
1675 /* Go over each section, reordering the relocations so that all of the
1676 explicit LITUSE's are adjacent to the explicit LITERAL's */
1677 bfd_map_over_sections (stdoutput
, alpha_adjust_symtab_relocs
, (char *) 0);
1682 /* Inner function to move LITUSE's next to the LITERAL. */
1685 alpha_adjust_symtab_relocs (abfd
, sec
, ptr
)
1686 bfd
*abfd ATTRIBUTE_UNUSED
;
1688 PTR ptr ATTRIBUTE_UNUSED
;
1690 segment_info_type
*seginfo
= seg_info (sec
);
1700 int n_dup_literals
= 0;
1703 /* If seginfo is NULL, we did not create this section; don't do anything with
1704 it. By using a pointer to a pointer, we can update the links in place. */
1705 if (seginfo
== NULL
)
1708 /* If there are no relocations, skip the section. */
1709 if (! seginfo
->fix_root
)
1712 /* First rebuild the fixup chain without the expicit lituse's. */
1713 prevP
= &(seginfo
->fix_root
);
1714 for (fixp
= seginfo
->fix_root
; fixp
; fixp
= next
)
1716 next
= fixp
->fx_next
;
1717 fixp
->fx_next
= (fixS
*)0;
1722 switch (fixp
->fx_r_type
)
1726 prevP
= &(fixp
->fx_next
);
1729 "alpha_adjust_symtab_relocs: 0x%lx, other relocation %s\n",
1731 bfd_get_reloc_code_name (fixp
->fx_r_type
));
1735 case BFD_RELOC_ALPHA_USER_LITERAL
:
1737 prevP
= &(fixp
->fx_next
);
1738 /* prevent assembler from trying to adjust the offset */
1741 if (fixp
->tc_fix_data
.info
->n_literals
!= 1)
1744 "alpha_adjust_symtab_relocs: 0x%lx, !literal!%.6d, # literals = %2d\n",
1746 fixp
->tc_fix_data
.info
->sequence
,
1747 fixp
->tc_fix_data
.info
->n_literals
);
1751 /* do not link in lituse's */
1752 case BFD_RELOC_ALPHA_USER_LITUSE_BASE
:
1753 case BFD_RELOC_ALPHA_USER_LITUSE_BYTOFF
:
1754 case BFD_RELOC_ALPHA_USER_LITUSE_JSR
:
1756 if (fixp
->tc_fix_data
.info
->n_literals
== 0)
1757 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1758 _("No !literal!%d was found"),
1759 fixp
->tc_fix_data
.info
->sequence
);
1762 "alpha_adjust_symtab_relocs: 0x%lx, !lituse !%.6d, # lituses = %2d, next_lituse = 0x%lx\n",
1764 fixp
->tc_fix_data
.info
->sequence
,
1765 fixp
->tc_fix_data
.info
->n_lituses
,
1766 (long)fixp
->tc_fix_data
.next_lituse
);
1772 /* If there were any lituses, go and add them to the chain, unless there is
1773 more than one !literal for a given sequence number. They are linked
1774 through the next_lituse field in reverse order, so as we go through the
1775 next_lituse chain, we effectively reverse the chain once again. If there
1776 was more than one !literal, we fall back to loading up the address w/o
1777 optimization. Also, if the !literals/!lituses are spread in different
1778 segments (happens in the Linux kernel semaphores), suppress the
1782 for (fixp
= seginfo
->fix_root
; fixp
; fixp
= fixp
->fx_next
)
1784 switch (fixp
->fx_r_type
)
1789 case BFD_RELOC_ALPHA_USER_LITERAL
:
1791 fixp
->fx_r_type
= BFD_RELOC_ALPHA_ELF_LITERAL
;
1793 fixp
->fx_r_type
= BFD_RELOC_ALPHA_LITERAL
; /* XXX check this */
1795 if (fixp
->tc_fix_data
.info
->n_literals
== 1
1796 && ! fixp
->tc_fix_data
.info
->multi_section_p
)
1798 for (lituse
= fixp
->tc_fix_data
.info
->lituse
;
1799 lituse
!= (fixS
*)0;
1800 lituse
= lituse
->tc_fix_data
.next_lituse
)
1802 lituse
->fx_next
= fixp
->fx_next
;
1803 fixp
->fx_next
= lituse
;
1808 case BFD_RELOC_ALPHA_USER_LITUSE_BASE
:
1809 case BFD_RELOC_ALPHA_USER_LITUSE_BYTOFF
:
1810 case BFD_RELOC_ALPHA_USER_LITUSE_JSR
:
1811 fixp
->fx_r_type
= BFD_RELOC_ALPHA_LITUSE
;
1818 fprintf (stderr
, "alpha_adjust_symtab_relocs: %s, %d literal%s, %d duplicate literal%s, %d lituse%s\n\n",
1820 n_literals
, (n_literals
== 1) ? "" : "s",
1821 n_dup_literals
, (n_dup_literals
== 1) ? "" : "s",
1822 n_lituses
, (n_lituses
== 1) ? "" : "s");
1826 #endif /* RELOC_OP_P */
1831 debug_exp (tok
, ntok
)
1837 fprintf (stderr
, "debug_exp: %d tokens", ntok
);
1838 for (i
= 0; i
< ntok
; i
++)
1840 expressionS
*t
= &tok
[i
];
1844 default: name
= "unknown"; break;
1845 case O_illegal
: name
= "O_illegal"; break;
1846 case O_absent
: name
= "O_absent"; break;
1847 case O_constant
: name
= "O_constant"; break;
1848 case O_symbol
: name
= "O_symbol"; break;
1849 case O_symbol_rva
: name
= "O_symbol_rva"; break;
1850 case O_register
: name
= "O_register"; break;
1851 case O_big
: name
= "O_big"; break;
1852 case O_uminus
: name
= "O_uminus"; break;
1853 case O_bit_not
: name
= "O_bit_not"; break;
1854 case O_logical_not
: name
= "O_logical_not"; break;
1855 case O_multiply
: name
= "O_multiply"; break;
1856 case O_divide
: name
= "O_divide"; break;
1857 case O_modulus
: name
= "O_modulus"; break;
1858 case O_left_shift
: name
= "O_left_shift"; break;
1859 case O_right_shift
: name
= "O_right_shift"; break;
1860 case O_bit_inclusive_or
: name
= "O_bit_inclusive_or"; break;
1861 case O_bit_or_not
: name
= "O_bit_or_not"; break;
1862 case O_bit_exclusive_or
: name
= "O_bit_exclusive_or"; break;
1863 case O_bit_and
: name
= "O_bit_and"; break;
1864 case O_add
: name
= "O_add"; break;
1865 case O_subtract
: name
= "O_subtract"; break;
1866 case O_eq
: name
= "O_eq"; break;
1867 case O_ne
: name
= "O_ne"; break;
1868 case O_lt
: name
= "O_lt"; break;
1869 case O_le
: name
= "O_le"; break;
1870 case O_ge
: name
= "O_ge"; break;
1871 case O_gt
: name
= "O_gt"; break;
1872 case O_logical_and
: name
= "O_logical_and"; break;
1873 case O_logical_or
: name
= "O_logical_or"; break;
1874 case O_index
: name
= "O_index"; break;
1875 case O_pregister
: name
= "O_pregister"; break;
1876 case O_cpregister
: name
= "O_cpregister"; break;
1877 case O_literal
: name
= "O_literal"; break;
1878 case O_lituse_base
: name
= "O_lituse_base"; break;
1879 case O_lituse_bytoff
: name
= "O_lituse_bytoff"; break;
1880 case O_lituse_jsr
: name
= "O_lituse_jsr"; break;
1881 case O_gpdisp
: name
= "O_gpdisp"; break;
1882 case O_gprelhigh
: name
= "O_gprelhigh"; break;
1883 case O_gprellow
: name
= "O_gprellow"; break;
1884 case O_md10
: name
= "O_md10"; break;
1885 case O_md11
: name
= "O_md11"; break;
1886 case O_md12
: name
= "O_md12"; break;
1887 case O_md13
: name
= "O_md13"; break;
1888 case O_md14
: name
= "O_md14"; break;
1889 case O_md15
: name
= "O_md15"; break;
1890 case O_md16
: name
= "O_md16"; break;
1893 fprintf (stderr
, ", %s(%s, %s, %d)", name
,
1894 (t
->X_add_symbol
) ? S_GET_NAME (t
->X_add_symbol
) : "--",
1895 (t
->X_op_symbol
) ? S_GET_NAME (t
->X_op_symbol
) : "--",
1896 (int)t
->X_add_number
);
1898 fprintf (stderr
, "\n");
1903 /* Parse the arguments to an opcode. */
1906 tokenize_arguments (str
, tok
, ntok
)
1911 expressionS
*end_tok
= tok
+ ntok
;
1912 char *old_input_line_pointer
;
1913 int saw_comma
= 0, saw_arg
= 0;
1915 expressionS
*orig_tok
= tok
;
1919 const struct alpha_reloc_op_tag
*r
;
1922 int reloc_found_p
= 0;
1925 memset (tok
, 0, sizeof (*tok
) * ntok
);
1927 /* Save and restore input_line_pointer around this function */
1928 old_input_line_pointer
= input_line_pointer
;
1929 input_line_pointer
= str
;
1931 while (tok
< end_tok
&& *input_line_pointer
)
1934 switch (*input_line_pointer
)
1941 /* A relocation operand can be placed after the normal operand on an
1942 assembly language statement, and has the following form:
1943 !relocation_type!sequence_number. */
1945 { /* only support one relocation op per insn */
1946 as_bad (_("More than one relocation op per insn"));
1953 for (p
= ++input_line_pointer
;
1954 ((c
= *p
) != '!' && c
!= ';' && c
!= '#' && c
!= ','
1955 && !is_end_of_line
[c
]);
1959 /* Parse !relocation_type */
1960 len
= p
- input_line_pointer
;
1963 as_bad (_("No relocation operand"));
1969 as_bad (_("No !sequence-number after !%s"), input_line_pointer
);
1973 r
= &alpha_reloc_op
[0];
1974 for (i
= alpha_num_reloc_op
-1; i
>= 0; i
--, r
++)
1976 if (len
== r
->length
1977 && memcmp (input_line_pointer
, r
->name
, len
) == 0)
1982 as_bad (_("Unknown relocation operand: !%s"), input_line_pointer
);
1986 input_line_pointer
= ++p
;
1988 /* Parse !sequence_number */
1989 memset (tok
, '\0', sizeof (expressionS
));
1992 if (tok
->X_op
!= O_constant
1993 || ! ALPHA_RELOC_SEQUENCE_OK (tok
->X_add_number
))
1995 as_bad (_("Bad sequence number: !%s!%s"), r
->name
, input_line_pointer
);
2006 ++input_line_pointer
;
2007 if (saw_comma
|| !saw_arg
)
2014 char *hold
= input_line_pointer
++;
2016 /* First try for parenthesized register ... */
2018 if (*input_line_pointer
== ')' && tok
->X_op
== O_register
)
2020 tok
->X_op
= (saw_comma
? O_cpregister
: O_pregister
);
2023 ++input_line_pointer
;
2028 /* ... then fall through to plain expression */
2029 input_line_pointer
= hold
;
2033 if (saw_arg
&& !saw_comma
)
2037 if (tok
->X_op
== O_illegal
|| tok
->X_op
== O_absent
)
2050 input_line_pointer
= old_input_line_pointer
;
2053 debug_exp (orig_tok
, ntok
- (end_tok
- tok
));
2056 return ntok
- (end_tok
- tok
);
2059 input_line_pointer
= old_input_line_pointer
;
2060 return TOKENIZE_ERROR
;
2064 input_line_pointer
= old_input_line_pointer
;
2065 return TOKENIZE_ERROR_REPORT
;
2069 /* Search forward through all variants of an opcode looking for a
2072 static const struct alpha_opcode
*
2073 find_opcode_match(first_opcode
, tok
, pntok
, pcpumatch
)
2074 const struct alpha_opcode
*first_opcode
;
2075 const expressionS
*tok
;
2079 const struct alpha_opcode
*opcode
= first_opcode
;
2081 int got_cpu_match
= 0;
2085 const unsigned char *opidx
;
2088 /* Don't match opcodes that don't exist on this architecture */
2089 if (!(opcode
->flags
& alpha_target
))
2094 for (opidx
= opcode
->operands
; *opidx
; ++opidx
)
2096 const struct alpha_operand
*operand
= &alpha_operands
[*opidx
];
2098 /* only take input from real operands */
2099 if (operand
->flags
& AXP_OPERAND_FAKE
)
2102 /* when we expect input, make sure we have it */
2105 if ((operand
->flags
& AXP_OPERAND_OPTIONAL_MASK
) == 0)
2110 /* match operand type with expression type */
2111 switch (operand
->flags
& AXP_OPERAND_TYPECHECK_MASK
)
2113 case AXP_OPERAND_IR
:
2114 if (tok
[tokidx
].X_op
!= O_register
2115 || !is_ir_num(tok
[tokidx
].X_add_number
))
2118 case AXP_OPERAND_FPR
:
2119 if (tok
[tokidx
].X_op
!= O_register
2120 || !is_fpr_num(tok
[tokidx
].X_add_number
))
2123 case AXP_OPERAND_IR
|AXP_OPERAND_PARENS
:
2124 if (tok
[tokidx
].X_op
!= O_pregister
2125 || !is_ir_num(tok
[tokidx
].X_add_number
))
2128 case AXP_OPERAND_IR
|AXP_OPERAND_PARENS
|AXP_OPERAND_COMMA
:
2129 if (tok
[tokidx
].X_op
!= O_cpregister
2130 || !is_ir_num(tok
[tokidx
].X_add_number
))
2134 case AXP_OPERAND_RELATIVE
:
2135 case AXP_OPERAND_SIGNED
:
2136 case AXP_OPERAND_UNSIGNED
:
2137 switch (tok
[tokidx
].X_op
)
2152 /* everything else should have been fake */
2158 /* possible match -- did we use all of our input? */
2167 while (++opcode
-alpha_opcodes
< alpha_num_opcodes
2168 && !strcmp(opcode
->name
, first_opcode
->name
));
2171 *pcpumatch
= got_cpu_match
;
2176 /* Search forward through all variants of a macro looking for a syntax
2179 static const struct alpha_macro
*
2180 find_macro_match(first_macro
, tok
, pntok
)
2181 const struct alpha_macro
*first_macro
;
2182 const expressionS
*tok
;
2185 const struct alpha_macro
*macro
= first_macro
;
2190 const enum alpha_macro_arg
*arg
= macro
->argsets
;
2204 /* index register */
2206 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_register
2207 || !is_ir_num(tok
[tokidx
].X_add_number
))
2212 /* parenthesized index register */
2214 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_pregister
2215 || !is_ir_num(tok
[tokidx
].X_add_number
))
2220 /* optional parenthesized index register */
2222 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_pregister
2223 && is_ir_num(tok
[tokidx
].X_add_number
))
2227 /* leading comma with a parenthesized index register */
2229 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_cpregister
2230 || !is_ir_num(tok
[tokidx
].X_add_number
))
2235 /* floating point register */
2237 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_register
2238 || !is_fpr_num(tok
[tokidx
].X_add_number
))
2243 /* normal expression */
2247 switch (tok
[tokidx
].X_op
)
2257 case O_lituse_bytoff
:
2271 /* optional !literal!<number> */
2274 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_literal
)
2279 /* optional !lituse_base!<number> */
2282 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_lituse_base
)
2287 /* optional !lituse_bytoff!<number> */
2290 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_lituse_bytoff
)
2295 /* optional !lituse_jsr!<number> */
2298 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_lituse_jsr
)
2304 while (*arg
!= MACRO_EOA
)
2312 while (++macro
-alpha_macros
< alpha_num_macros
2313 && !strcmp(macro
->name
, first_macro
->name
));
2318 /* Insert an operand value into an instruction. */
2321 insert_operand(insn
, operand
, val
, file
, line
)
2323 const struct alpha_operand
*operand
;
2328 if (operand
->bits
!= 32 && !(operand
->flags
& AXP_OPERAND_NOOVERFLOW
))
2332 if (operand
->flags
& AXP_OPERAND_SIGNED
)
2334 max
= (1 << (operand
->bits
- 1)) - 1;
2335 min
= -(1 << (operand
->bits
- 1));
2339 max
= (1 << operand
->bits
) - 1;
2343 if (val
< min
|| val
> max
)
2346 _("operand out of range (%s not between %d and %d)");
2347 char buf
[sizeof (val
) * 3 + 2];
2349 sprint_value(buf
, val
);
2351 as_warn_where(file
, line
, err
, buf
, min
, max
);
2353 as_warn(err
, buf
, min
, max
);
2357 if (operand
->insert
)
2359 const char *errmsg
= NULL
;
2361 insn
= (*operand
->insert
) (insn
, val
, &errmsg
);
2366 insn
|= ((val
& ((1 << operand
->bits
) - 1)) << operand
->shift
);
2372 * Turn an opcode description and a set of arguments into
2373 * an instruction and a fixup.
2377 assemble_insn(opcode
, tok
, ntok
, insn
)
2378 const struct alpha_opcode
*opcode
;
2379 const expressionS
*tok
;
2381 struct alpha_insn
*insn
;
2383 const unsigned char *argidx
;
2387 memset (insn
, 0, sizeof (*insn
));
2388 image
= opcode
->opcode
;
2390 for (argidx
= opcode
->operands
; *argidx
; ++argidx
)
2392 const struct alpha_operand
*operand
= &alpha_operands
[*argidx
];
2393 const expressionS
*t
= (const expressionS
*)0;
2395 if (operand
->flags
& AXP_OPERAND_FAKE
)
2397 /* fake operands take no value and generate no fixup */
2398 image
= insert_operand(image
, operand
, 0, NULL
, 0);
2404 switch (operand
->flags
& AXP_OPERAND_OPTIONAL_MASK
)
2406 case AXP_OPERAND_DEFAULT_FIRST
:
2409 case AXP_OPERAND_DEFAULT_SECOND
:
2412 case AXP_OPERAND_DEFAULT_ZERO
:
2414 static expressionS zero_exp
;
2416 zero_exp
.X_op
= O_constant
;
2417 zero_exp
.X_unsigned
= 1;
2432 image
= insert_operand(image
, operand
, regno(t
->X_add_number
),
2437 image
= insert_operand(image
, operand
, t
->X_add_number
, NULL
, 0);
2442 struct alpha_fixup
*fixup
;
2444 if (insn
->nfixups
>= MAX_INSN_FIXUPS
)
2445 as_fatal(_("too many fixups"));
2447 fixup
= &insn
->fixups
[insn
->nfixups
++];
2450 fixup
->reloc
= operand
->default_reloc
;
2460 * Actually output an instruction with its fixup.
2465 struct alpha_insn
*insn
;
2470 /* Take care of alignment duties */
2471 if (alpha_auto_align_on
&& alpha_current_align
< 2)
2472 alpha_align (2, (char *) NULL
, alpha_insn_label
, 0);
2473 if (alpha_current_align
> 2)
2474 alpha_current_align
= 2;
2475 alpha_insn_label
= NULL
;
2477 /* Write out the instruction. */
2479 md_number_to_chars (f
, insn
->insn
, 4);
2482 dwarf2_emit_insn (4);
2485 /* Apply the fixups in order */
2486 for (i
= 0; i
< insn
->nfixups
; ++i
)
2488 const struct alpha_operand
*operand
= (const struct alpha_operand
*)0;
2489 struct alpha_fixup
*fixup
= &insn
->fixups
[i
];
2493 char buffer
[ALPHA_RELOC_DIGITS
];
2494 struct alpha_literal_tag
*info
;
2497 /* Some fixups are only used internally and so have no howto */
2498 if ((int)fixup
->reloc
< 0)
2500 operand
= &alpha_operands
[-(int)fixup
->reloc
];
2502 pcrel
= ((operand
->flags
& AXP_OPERAND_RELATIVE
) != 0);
2504 else switch (fixup
->reloc
)
2507 /* These relocation types are only used internally. */
2508 case BFD_RELOC_ALPHA_GPDISP_HI16
:
2509 case BFD_RELOC_ALPHA_GPDISP_LO16
:
2515 /* and these also are internal only relocations */
2516 case BFD_RELOC_ALPHA_USER_LITERAL
:
2517 case BFD_RELOC_ALPHA_USER_LITUSE_BASE
:
2518 case BFD_RELOC_ALPHA_USER_LITUSE_BYTOFF
:
2519 case BFD_RELOC_ALPHA_USER_LITUSE_JSR
:
2520 case BFD_RELOC_ALPHA_USER_GPDISP
:
2521 case BFD_RELOC_ALPHA_USER_GPRELHIGH
:
2522 case BFD_RELOC_ALPHA_USER_GPRELLOW
:
2530 reloc_howto_type
*reloc_howto
2531 = bfd_reloc_type_lookup (stdoutput
, fixup
->reloc
);
2532 assert (reloc_howto
);
2534 size
= bfd_get_reloc_size (reloc_howto
);
2535 pcrel
= reloc_howto
->pc_relative
;
2537 assert (size
>= 1 && size
<= 4);
2541 fixP
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, size
,
2542 &fixup
->exp
, pcrel
, fixup
->reloc
);
2544 /* Turn off complaints that the addend is too large for some fixups,
2545 and copy in the sequence number for the explicit relocations. */
2546 switch (fixup
->reloc
)
2548 case BFD_RELOC_ALPHA_GPDISP_LO16
:
2550 case BFD_RELOC_ALPHA_LITERAL
:
2553 case BFD_RELOC_ALPHA_ELF_LITERAL
:
2555 case BFD_RELOC_GPREL32
:
2556 fixP
->fx_no_overflow
= 1;
2560 case BFD_RELOC_ALPHA_USER_LITERAL
:
2561 fixP
->fx_no_overflow
= 1;
2562 sprintf (buffer
, "!%u", insn
->sequence
[i
]);
2563 info
= ((struct alpha_literal_tag
*)
2564 hash_find (alpha_literal_hash
, buffer
));
2568 size_t len
= strlen (buffer
);
2571 info
= ((struct alpha_literal_tag
*)
2572 xcalloc (sizeof (struct alpha_literal_tag
) + len
, 1));
2574 info
->segment
= now_seg
;
2575 info
->sequence
= insn
->sequence
[i
];
2576 strcpy (info
->string
, buffer
);
2577 errmsg
= hash_insert (alpha_literal_hash
, info
->string
, (PTR
)info
);
2584 if (info
->segment
!= now_seg
)
2585 info
->multi_section_p
= 1;
2587 fixP
->tc_fix_data
.info
= info
;
2590 case BFD_RELOC_ALPHA_USER_LITUSE_BASE
:
2591 case BFD_RELOC_ALPHA_USER_LITUSE_BYTOFF
:
2592 case BFD_RELOC_ALPHA_USER_LITUSE_JSR
:
2593 sprintf (buffer
, "!%u", insn
->sequence
[i
]);
2594 info
= ((struct alpha_literal_tag
*)
2595 hash_find (alpha_literal_hash
, buffer
));
2599 size_t len
= strlen (buffer
);
2602 info
= ((struct alpha_literal_tag
*)
2603 xcalloc (sizeof (struct alpha_literal_tag
) + len
, 1));
2605 info
->segment
= now_seg
;
2606 info
->sequence
= insn
->sequence
[i
];
2607 strcpy (info
->string
, buffer
);
2608 errmsg
= hash_insert (alpha_literal_hash
, info
->string
, (PTR
)info
);
2613 fixP
->tc_fix_data
.info
= info
;
2614 fixP
->tc_fix_data
.next_lituse
= info
->lituse
;
2615 info
->lituse
= fixP
;
2616 if (info
->segment
!= now_seg
)
2617 info
->multi_section_p
= 1;
2623 if ((int)fixup
->reloc
< 0)
2625 if (operand
->flags
& AXP_OPERAND_NOOVERFLOW
)
2626 fixP
->fx_no_overflow
= 1;
2633 /* Given an opcode name and a pre-tokenized set of arguments, assemble
2634 the insn, but do not emit it.
2636 Note that this implies no macros allowed, since we can't store more
2637 than one insn in an insn structure. */
2640 assemble_tokens_to_insn(opname
, tok
, ntok
, insn
)
2642 const expressionS
*tok
;
2644 struct alpha_insn
*insn
;
2646 const struct alpha_opcode
*opcode
;
2648 /* search opcodes */
2649 opcode
= (const struct alpha_opcode
*) hash_find (alpha_opcode_hash
, opname
);
2653 opcode
= find_opcode_match (opcode
, tok
, &ntok
, &cpumatch
);
2656 assemble_insn (opcode
, tok
, ntok
, insn
);
2660 as_bad (_("inappropriate arguments for opcode `%s'"), opname
);
2662 as_bad (_("opcode `%s' not supported for target %s"), opname
,
2666 as_bad (_("unknown opcode `%s'"), opname
);
2669 /* Given an opcode name and a pre-tokenized set of arguments, take the
2670 opcode all the way through emission. */
2673 assemble_tokens (opname
, tok
, ntok
, local_macros_on
)
2675 const expressionS
*tok
;
2677 int local_macros_on
;
2679 int found_something
= 0;
2680 const struct alpha_opcode
*opcode
;
2681 const struct alpha_macro
*macro
;
2685 if (local_macros_on
)
2687 macro
= ((const struct alpha_macro
*)
2688 hash_find (alpha_macro_hash
, opname
));
2691 found_something
= 1;
2692 macro
= find_macro_match (macro
, tok
, &ntok
);
2695 (*macro
->emit
) (tok
, ntok
, macro
->arg
);
2702 if (ntok
&& USER_RELOC_P (tok
[ntok
-1].X_op
))
2704 const expressionS
*reloc_exp
= &tok
[ntok
-1];
2705 const struct alpha_reloc_op_tag
*r
= ALPHA_RELOC_TABLE (reloc_exp
->X_op
);
2706 as_bad (_("Cannot use !%s!%d with %s"), r
->name
,
2707 (int)reloc_exp
->X_add_number
, opname
);
2712 /* search opcodes */
2713 opcode
= (const struct alpha_opcode
*) hash_find (alpha_opcode_hash
, opname
);
2716 found_something
= 1;
2717 opcode
= find_opcode_match (opcode
, tok
, &ntok
, &cpumatch
);
2720 struct alpha_insn insn
;
2721 assemble_insn (opcode
, tok
, ntok
, &insn
);
2727 if (found_something
)
2729 as_bad (_("inappropriate arguments for opcode `%s'"), opname
);
2731 as_bad (_("opcode `%s' not supported for target %s"), opname
,
2734 as_bad (_("unknown opcode `%s'"), opname
);
2738 /* Some instruction sets indexed by lg(size) */
2739 static const char * const sextX_op
[] = { "sextb", "sextw", "sextl", NULL
};
2740 static const char * const insXl_op
[] = { "insbl", "inswl", "insll", "insql" };
2741 static const char * const insXh_op
[] = { NULL
, "inswh", "inslh", "insqh" };
2742 static const char * const extXl_op
[] = { "extbl", "extwl", "extll", "extql" };
2743 static const char * const extXh_op
[] = { NULL
, "extwh", "extlh", "extqh" };
2744 static const char * const mskXl_op
[] = { "mskbl", "mskwl", "mskll", "mskql" };
2745 static const char * const mskXh_op
[] = { NULL
, "mskwh", "msklh", "mskqh" };
2746 static const char * const stX_op
[] = { "stb", "stw", "stl", "stq" };
2747 static const char * const ldX_op
[] = { "ldb", "ldw", "ldll", "ldq" };
2748 static const char * const ldXu_op
[] = { "ldbu", "ldwu", NULL
, NULL
};
2750 /* Implement the ldgp macro. */
2753 emit_ldgp (tok
, ntok
, unused
)
2754 const expressionS
*tok
;
2755 int ntok ATTRIBUTE_UNUSED
;
2756 const PTR unused ATTRIBUTE_UNUSED
;
2761 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
2762 /* from "ldgp r1,n(r2)", generate "ldah r1,X(R2); lda r1,Y(r1)"
2763 with appropriate constants and relocations. */
2764 struct alpha_insn insn
;
2765 expressionS newtok
[3];
2769 if (ntok
&& USER_RELOC_P (tok
[ntok
-1].X_op
))
2771 const expressionS
*reloc_exp
= &tok
[ntok
-1];
2772 const struct alpha_reloc_op_tag
*r
= ALPHA_RELOC_TABLE (reloc_exp
->X_op
);
2773 as_bad (_("Cannot use !%s!%d with %s"), r
->name
,
2774 (int)reloc_exp
->X_add_number
, "ldgp");
2780 if (regno (tok
[2].X_add_number
) == AXP_REG_PV
)
2781 ecoff_set_gp_prolog_size (0);
2785 set_tok_const (newtok
[1], 0);
2788 assemble_tokens_to_insn ("ldah", newtok
, 3, &insn
);
2793 if (addend
.X_op
!= O_constant
)
2794 as_bad (_("can not resolve expression"));
2795 addend
.X_op
= O_symbol
;
2796 addend
.X_add_symbol
= alpha_gp_symbol
;
2800 insn
.fixups
[0].exp
= addend
;
2801 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_GPDISP_HI16
;
2805 set_tok_preg (newtok
[2], tok
[0].X_add_number
);
2807 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
2810 addend
.X_add_number
+= 4;
2814 insn
.fixups
[0].exp
= addend
;
2815 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_GPDISP_LO16
;
2818 #endif /* OBJ_ECOFF || OBJ_ELF */
2823 /* Add symbol+addend to link pool.
2824 Return offset from basesym to entry in link pool.
2826 Add new fixup only if offset isn't 16bit. */
2829 add_to_link_pool (basesym
, sym
, addend
)
2834 segT current_section
= now_seg
;
2835 int current_subsec
= now_subseg
;
2837 bfd_reloc_code_real_type reloc_type
;
2839 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
2842 offset
= - *symbol_get_obj (basesym
);
2844 /* @@ This assumes all entries in a given section will be of the same
2845 size... Probably correct, but unwise to rely on. */
2846 /* This must always be called with the same subsegment. */
2848 if (seginfo
->frchainP
)
2849 for (fixp
= seginfo
->frchainP
->fix_root
;
2850 fixp
!= (fixS
*) NULL
;
2851 fixp
= fixp
->fx_next
, offset
+= 8)
2853 if (fixp
->fx_addsy
== sym
&& fixp
->fx_offset
== addend
)
2855 if (range_signed_16 (offset
))
2862 /* Not found in 16bit signed range. */
2864 subseg_set (alpha_link_section
, 0);
2868 fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, sym
, addend
, 0,
2871 subseg_set (current_section
, current_subsec
);
2872 seginfo
->literal_pool_size
+= 8;
2876 #endif /* OBJ_EVAX */
2878 /* Load a (partial) expression into a target register.
2880 If poffset is not null, after the call it will either contain
2881 O_constant 0, or a 16-bit offset appropriate for any MEM format
2882 instruction. In addition, pbasereg will be modified to point to
2883 the base register to use in that MEM format instruction.
2885 In any case, *pbasereg should contain a base register to add to the
2886 expression. This will normally be either AXP_REG_ZERO or
2887 alpha_gp_register. Symbol addresses will always be loaded via $gp,
2888 so "foo($0)" is interpreted as adding the address of foo to $0;
2889 i.e. "ldq $targ, LIT($gp); addq $targ, $0, $targ". Odd, perhaps,
2890 but this is what OSF/1 does.
2892 If explicit relocations of the form !literal!<number> are allowed,
2893 and used, then explict_reloc with be an expression pointer.
2895 Finally, the return value is true if the calling macro may emit a
2896 LITUSE reloc if otherwise appropriate. */
2899 load_expression (targreg
, exp
, pbasereg
, poffset
, explicit_reloc
)
2901 const expressionS
*exp
;
2903 expressionS
*poffset
;
2904 const expressionS
*explicit_reloc
;
2906 int emit_lituse
= 0;
2907 offsetT addend
= exp
->X_add_number
;
2908 int basereg
= *pbasereg
;
2909 struct alpha_insn insn
;
2910 expressionS newtok
[3];
2919 /* attempt to reduce .lit load by splitting the offset from
2920 its symbol when possible, but don't create a situation in
2922 if (!range_signed_32 (addend
) &&
2923 (alpha_noat_on
|| targreg
== AXP_REG_AT
))
2925 lit
= add_to_literal_pool (exp
->X_add_symbol
, addend
,
2926 alpha_lita_section
, 8);
2931 lit
= add_to_literal_pool (exp
->X_add_symbol
, 0,
2932 alpha_lita_section
, 8);
2936 as_fatal (_("overflow in literal (.lita) table"));
2938 /* emit "ldq r, lit(gp)" */
2940 if (basereg
!= alpha_gp_register
&& targreg
== basereg
)
2943 as_bad (_("macro requires $at register while noat in effect"));
2944 if (targreg
== AXP_REG_AT
)
2945 as_bad (_("macro requires $at while $at in use"));
2947 set_tok_reg (newtok
[0], AXP_REG_AT
);
2950 set_tok_reg (newtok
[0], targreg
);
2951 set_tok_sym (newtok
[1], alpha_lita_symbol
, lit
);
2952 set_tok_preg (newtok
[2], alpha_gp_register
);
2954 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
2956 assert (explicit_reloc
== (const expressionS
*)0);
2957 assert (insn
.nfixups
== 1);
2958 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITERAL
;
2959 #endif /* OBJ_ECOFF */
2961 /* emit "ldq r, gotoff(gp)" */
2963 if (basereg
!= alpha_gp_register
&& targreg
== basereg
)
2966 as_bad (_("macro requires $at register while noat in effect"));
2967 if (targreg
== AXP_REG_AT
)
2968 as_bad (_("macro requires $at while $at in use"));
2970 set_tok_reg (newtok
[0], AXP_REG_AT
);
2973 set_tok_reg (newtok
[0], targreg
);
2975 /* XXX: Disable this .got minimizing optimization so that we can get
2976 better instruction offset knowledge in the compiler. This happens
2977 very infrequently anyway. */
2978 if (1 || (!range_signed_32 (addend
)
2979 && (alpha_noat_on
|| targreg
== AXP_REG_AT
)))
2986 set_tok_sym (newtok
[1], exp
->X_add_symbol
, 0);
2989 set_tok_preg (newtok
[2], alpha_gp_register
);
2991 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
2993 assert (insn
.nfixups
== 1);
2994 if (!explicit_reloc
)
2995 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_ELF_LITERAL
;
2999 insn
.fixups
[0].reloc
3000 = (ALPHA_RELOC_TABLE (explicit_reloc
->X_op
))->reloc
;
3001 insn
.sequence
[0] = explicit_reloc
->X_add_number
;
3006 #endif /* OBJ_ELF */
3010 /* Find symbol or symbol pointer in link section. */
3012 assert (explicit_reloc
== (const expressionS
*)0);
3013 if (exp
->X_add_symbol
== alpha_evax_proc
.symbol
)
3015 if (range_signed_16 (addend
))
3017 set_tok_reg (newtok
[0], targreg
);
3018 set_tok_const (newtok
[1], addend
);
3019 set_tok_preg (newtok
[2], basereg
);
3020 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
3025 set_tok_reg (newtok
[0], targreg
);
3026 set_tok_const (newtok
[1], 0);
3027 set_tok_preg (newtok
[2], basereg
);
3028 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
3033 if (!range_signed_32 (addend
))
3035 link
= add_to_link_pool (alpha_evax_proc
.symbol
,
3036 exp
->X_add_symbol
, addend
);
3041 link
= add_to_link_pool (alpha_evax_proc
.symbol
,
3042 exp
->X_add_symbol
, 0);
3044 set_tok_reg (newtok
[0], targreg
);
3045 set_tok_const (newtok
[1], link
);
3046 set_tok_preg (newtok
[2], basereg
);
3047 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
3049 #endif /* OBJ_EVAX */
3056 if (basereg
!= alpha_gp_register
&& basereg
!= AXP_REG_ZERO
)
3058 /* emit "addq r, base, r" */
3060 set_tok_reg (newtok
[1], basereg
);
3061 set_tok_reg (newtok
[2], targreg
);
3062 assemble_tokens ("addq", newtok
, 3, 0);
3071 assert (explicit_reloc
== (const expressionS
*)0);
3075 /* Assume that this difference expression will be resolved to an
3076 absolute value and that that value will fit in 16 bits. */
3078 assert (explicit_reloc
== (const expressionS
*)0);
3079 set_tok_reg (newtok
[0], targreg
);
3081 set_tok_preg (newtok
[2], basereg
);
3082 assemble_tokens ("lda", newtok
, 3, 0);
3085 set_tok_const (*poffset
, 0);
3089 if (exp
->X_add_number
> 0)
3090 as_bad (_("bignum invalid; zero assumed"));
3092 as_bad (_("floating point number invalid; zero assumed"));
3097 as_bad (_("can't handle expression"));
3102 if (!range_signed_32 (addend
))
3106 /* for 64-bit addends, just put it in the literal pool */
3109 /* emit "ldq targreg, lit(basereg)" */
3110 lit
= add_to_link_pool (alpha_evax_proc
.symbol
,
3111 section_symbol (absolute_section
), addend
);
3112 set_tok_reg (newtok
[0], targreg
);
3113 set_tok_const (newtok
[1], lit
);
3114 set_tok_preg (newtok
[2], alpha_gp_register
);
3115 assemble_tokens ("ldq", newtok
, 3, 0);
3118 if (alpha_lit8_section
== NULL
)
3120 create_literal_section (".lit8",
3121 &alpha_lit8_section
,
3122 &alpha_lit8_symbol
);
3125 alpha_lit8_literal
= add_to_literal_pool (alpha_lit8_symbol
, 0x8000,
3126 alpha_lita_section
, 8);
3127 if (alpha_lit8_literal
>= 0x8000)
3128 as_fatal (_("overflow in literal (.lita) table"));
3132 lit
= add_to_literal_pool (NULL
, addend
, alpha_lit8_section
, 8) - 0x8000;
3134 as_fatal (_("overflow in literal (.lit8) table"));
3136 /* emit "lda litreg, .lit8+0x8000" */
3138 if (targreg
== basereg
)
3141 as_bad (_("macro requires $at register while noat in effect"));
3142 if (targreg
== AXP_REG_AT
)
3143 as_bad (_("macro requires $at while $at in use"));
3145 set_tok_reg (newtok
[0], AXP_REG_AT
);
3148 set_tok_reg (newtok
[0], targreg
);
3150 set_tok_sym (newtok
[1], alpha_lita_symbol
, alpha_lit8_literal
);
3153 set_tok_sym (newtok
[1], alpha_lit8_symbol
, 0x8000);
3155 set_tok_preg (newtok
[2], alpha_gp_register
);
3157 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
3159 assert (insn
.nfixups
== 1);
3161 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITERAL
;
3164 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_ELF_LITERAL
;
3169 /* emit "ldq litreg, lit(litreg)" */
3171 set_tok_const (newtok
[1], lit
);
3172 set_tok_preg (newtok
[2], newtok
[0].X_add_number
);
3174 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
3176 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3177 if (insn
.nfixups
> 0)
3179 memmove (&insn
.fixups
[1], &insn
.fixups
[0],
3180 sizeof (struct alpha_fixup
) * insn
.nfixups
);
3183 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITUSE
;
3184 insn
.fixups
[0].exp
.X_op
= O_symbol
;
3185 insn
.fixups
[0].exp
.X_add_symbol
= section_symbol (now_seg
);
3186 insn
.fixups
[0].exp
.X_add_number
= LITUSE_BASE
;
3191 /* emit "addq litreg, base, target" */
3193 if (basereg
!= AXP_REG_ZERO
)
3195 set_tok_reg (newtok
[1], basereg
);
3196 set_tok_reg (newtok
[2], targreg
);
3197 assemble_tokens ("addq", newtok
, 3, 0);
3199 #endif /* !OBJ_EVAX */
3202 set_tok_const (*poffset
, 0);
3203 *pbasereg
= targreg
;
3207 offsetT low
, high
, extra
, tmp
;
3209 /* for 32-bit operands, break up the addend */
3211 low
= sign_extend_16 (addend
);
3213 high
= sign_extend_16 (tmp
>> 16);
3215 if (tmp
- (high
<< 16))
3219 high
= sign_extend_16 (tmp
>> 16);
3224 set_tok_reg (newtok
[0], targreg
);
3225 set_tok_preg (newtok
[2], basereg
);
3229 /* emit "ldah r, extra(r) */
3230 set_tok_const (newtok
[1], extra
);
3231 assemble_tokens ("ldah", newtok
, 3, 0);
3232 set_tok_preg (newtok
[2], basereg
= targreg
);
3237 /* emit "ldah r, high(r) */
3238 set_tok_const (newtok
[1], high
);
3239 assemble_tokens ("ldah", newtok
, 3, 0);
3241 set_tok_preg (newtok
[2], basereg
);
3244 if ((low
&& !poffset
) || (!poffset
&& basereg
!= targreg
))
3246 /* emit "lda r, low(base)" */
3247 set_tok_const (newtok
[1], low
);
3248 assemble_tokens ("lda", newtok
, 3, 0);
3254 set_tok_const (*poffset
, low
);
3255 *pbasereg
= basereg
;
3261 /* The lda macro differs from the lda instruction in that it handles
3262 most simple expressions, particualrly symbol address loads and
3266 emit_lda (tok
, ntok
, opname
)
3267 const expressionS
*tok
;
3272 const expressionS
*reloc
= (const expressionS
*)0;
3275 if (ntok
&& USER_RELOC_P (tok
[ntok
-1].X_op
))
3277 const struct alpha_reloc_op_tag
*r
;
3279 reloc
= &tok
[ntok
-1];
3280 r
= ALPHA_RELOC_TABLE (reloc
->X_op
);
3281 switch (reloc
->X_op
)
3284 as_bad (_("Cannot use !%s!%d with %s"), r
->name
,
3285 (int)reloc
->X_add_number
, (const char *)opname
);
3287 reloc
= (const expressionS
*)0;
3295 /* For lda $x,0($x)!lituse_base!y, don't use load_expression, since
3296 it is really too general for our needs. Instead just generate the
3300 || tok
[0].X_op
!= O_register
3301 || !is_ir_num(tok
[0].X_add_number
)
3302 || tok
[1].X_op
!= O_constant
3303 || tok
[2].X_op
!= O_pregister
3304 || !is_ir_num(tok
[2].X_add_number
))
3306 as_bad (_("bad instruction format for lda !%s!%ld"), r
->name
,
3307 (long) reloc
->X_add_number
);
3309 reloc
= (const expressionS
*)0;
3314 emit_loadstore (tok
, ntok
, "lda");
3321 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
3323 basereg
= tok
[2].X_add_number
;
3325 (void) load_expression (tok
[0].X_add_number
, &tok
[1], &basereg
, NULL
, reloc
);
3328 /* The ldah macro differs from the ldah instruction in that it has $31
3329 as an implied base register. */
3332 emit_ldah (tok
, ntok
, unused
)
3333 const expressionS
*tok
;
3334 int ntok ATTRIBUTE_UNUSED
;
3335 const PTR unused ATTRIBUTE_UNUSED
;
3337 expressionS newtok
[3];
3340 if (ntok
&& USER_RELOC_P (tok
[ntok
-1].X_op
))
3342 const expressionS
*reloc_exp
= &tok
[ntok
-1];
3343 const struct alpha_reloc_op_tag
*r
= ALPHA_RELOC_TABLE (reloc_exp
->X_op
);
3344 as_bad (_("Cannot use !%s!%d with %s"), r
->name
,
3345 (int)reloc_exp
->X_add_number
, "ldah");
3352 set_tok_preg (newtok
[2], AXP_REG_ZERO
);
3354 assemble_tokens ("ldah", newtok
, 3, 0);
3357 /* Handle all "simple" integer register loads -- ldq, ldq_l, ldq_u,
3358 etc. They differ from the real instructions in that they do simple
3359 expressions like the lda macro. */
3362 emit_ir_load (tok
, ntok
, opname
)
3363 const expressionS
*tok
;
3367 int basereg
, lituse
;
3368 expressionS newtok
[3];
3369 struct alpha_insn insn
;
3372 const expressionS
*reloc
= (const expressionS
*)0;
3374 if (ntok
&& USER_RELOC_P (tok
[ntok
-1].X_op
))
3376 const struct alpha_reloc_op_tag
*r
;
3378 reloc
= &tok
[ntok
-1];
3379 switch (reloc
->X_op
)
3386 if (strcmp ((const char *)opname
, "ldq") == 0)
3388 emit_lda (tok
, ntok
, opname
);
3395 r
= ALPHA_RELOC_TABLE (reloc
->X_op
);
3396 as_bad (_("Cannot use !%s!%d with %s"), r
->name
,
3397 (int)reloc
->X_add_number
, (const char *)opname
);
3403 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
3405 basereg
= tok
[2].X_add_number
;
3407 lituse
= load_expression (tok
[0].X_add_number
, &tok
[1], &basereg
,
3408 &newtok
[1], (const expressionS
*)0);
3411 set_tok_preg (newtok
[2], basereg
);
3413 assemble_tokens_to_insn ((const char *)opname
, newtok
, 3, &insn
);
3418 int nfixups
= insn
.nfixups
;
3419 const struct alpha_reloc_op_tag
*r
= ALPHA_RELOC_TABLE (reloc
->X_op
);
3421 assert (nfixups
< MAX_INSN_FIXUPS
);
3422 insn
.fixups
[nfixups
].reloc
= r
->reloc
;
3423 insn
.fixups
[nfixups
].exp
.X_op
= O_symbol
;
3424 insn
.fixups
[nfixups
].exp
.X_add_symbol
= section_symbol (now_seg
);
3425 insn
.fixups
[nfixups
].exp
.X_add_number
= r
->lituse
;
3426 insn
.sequence
[nfixups
] = reloc
->X_add_number
;
3433 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3434 if (insn
.nfixups
> 0)
3436 memmove (&insn
.fixups
[1], &insn
.fixups
[0],
3437 sizeof (struct alpha_fixup
) * insn
.nfixups
);
3440 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITUSE
;
3441 insn
.fixups
[0].exp
.X_op
= O_symbol
;
3442 insn
.fixups
[0].exp
.X_add_symbol
= section_symbol (now_seg
);
3443 insn
.fixups
[0].exp
.X_add_number
= LITUSE_BASE
;
3449 /* Handle fp register loads, and both integer and fp register stores.
3450 Again, we handle simple expressions. */
3453 emit_loadstore (tok
, ntok
, opname
)
3454 const expressionS
*tok
;
3458 int basereg
, lituse
;
3459 expressionS newtok
[3];
3460 struct alpha_insn insn
;
3463 const expressionS
*reloc
= (const expressionS
*)0;
3465 if (ntok
&& USER_RELOC_P (tok
[ntok
-1].X_op
))
3467 reloc
= &tok
[--ntok
];
3468 if (reloc
->X_op
!= O_lituse_base
)
3470 const struct alpha_reloc_op_tag
*r
= &alpha_reloc_op
[ reloc
->X_md
];
3471 as_bad (_("Cannot use !%s!%d with %s"), r
->name
,
3472 (int)reloc
->X_add_number
, (const char *)opname
);
3478 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
3480 basereg
= tok
[2].X_add_number
;
3482 if (tok
[1].X_op
!= O_constant
|| !range_signed_16(tok
[1].X_add_number
))
3485 as_bad (_("macro requires $at register while noat in effect"));
3487 lituse
= load_expression (AXP_REG_AT
, &tok
[1], &basereg
, &newtok
[1],
3488 (const expressionS
*)0);
3497 set_tok_preg (newtok
[2], basereg
);
3499 assemble_tokens_to_insn ((const char *)opname
, newtok
, 3, &insn
);
3504 int nfixups
= insn
.nfixups
;
3505 const struct alpha_reloc_op_tag
*r
= ALPHA_RELOC_TABLE (reloc
->X_op
);
3507 assert (nfixups
< MAX_INSN_FIXUPS
);
3508 insn
.fixups
[nfixups
].reloc
= r
->reloc
;
3509 insn
.fixups
[nfixups
].exp
.X_op
= O_symbol
;
3510 insn
.fixups
[nfixups
].exp
.X_add_symbol
= section_symbol (now_seg
);
3511 insn
.fixups
[nfixups
].exp
.X_add_number
= r
->lituse
;
3512 insn
.sequence
[nfixups
] = reloc
->X_add_number
;
3519 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3520 if (insn
.nfixups
> 0)
3522 memmove (&insn
.fixups
[1], &insn
.fixups
[0],
3523 sizeof (struct alpha_fixup
) * insn
.nfixups
);
3526 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITUSE
;
3527 insn
.fixups
[0].exp
.X_op
= O_symbol
;
3528 insn
.fixups
[0].exp
.X_add_symbol
= section_symbol (now_seg
);
3529 insn
.fixups
[0].exp
.X_add_number
= LITUSE_BASE
;
3535 /* Load a half-word or byte as an unsigned value. */
3538 emit_ldXu (tok
, ntok
, vlgsize
)
3539 const expressionS
*tok
;
3543 if (alpha_target
& AXP_OPCODE_BWX
)
3544 emit_ir_load (tok
, ntok
, ldXu_op
[(long)vlgsize
]);
3547 expressionS newtok
[3];
3550 if (ntok
&& USER_RELOC_P (tok
[ntok
-1].X_op
))
3552 const expressionS
*reloc_exp
= &tok
[ntok
-1];
3553 const struct alpha_reloc_op_tag
*r
3554 = ALPHA_RELOC_TABLE (reloc_exp
->X_op
);
3556 as_bad (_("Cannot use !%s!%d with %s"), r
->name
,
3557 (int)reloc_exp
->X_add_number
, "ldbu/ldwu");
3563 as_bad (_("macro requires $at register while noat in effect"));
3565 /* emit "lda $at, exp" */
3567 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
3568 newtok
[0].X_add_number
= AXP_REG_AT
;
3569 assemble_tokens ("lda", newtok
, ntok
, 1);
3571 /* emit "ldq_u targ, 0($at)" */
3574 set_tok_const (newtok
[1], 0);
3575 set_tok_preg (newtok
[2], AXP_REG_AT
);
3576 assemble_tokens ("ldq_u", newtok
, 3, 1);
3578 /* emit "extXl targ, $at, targ" */
3580 set_tok_reg (newtok
[1], AXP_REG_AT
);
3581 newtok
[2] = newtok
[0];
3582 assemble_tokens (extXl_op
[(long)vlgsize
], newtok
, 3, 1);
3586 /* Load a half-word or byte as a signed value. */
3589 emit_ldX (tok
, ntok
, vlgsize
)
3590 const expressionS
*tok
;
3594 emit_ldXu (tok
, ntok
, vlgsize
);
3595 assemble_tokens (sextX_op
[(long)vlgsize
], tok
, 1, 1);
3598 /* Load an integral value from an unaligned address as an unsigned
3602 emit_uldXu (tok
, ntok
, vlgsize
)
3603 const expressionS
*tok
;
3607 long lgsize
= (long)vlgsize
;
3608 expressionS newtok
[3];
3611 as_bad (_("macro requires $at register while noat in effect"));
3613 /* emit "lda $at, exp" */
3615 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
3616 newtok
[0].X_add_number
= AXP_REG_AT
;
3617 assemble_tokens ("lda", newtok
, ntok
, 1);
3619 /* emit "ldq_u $t9, 0($at)" */
3621 set_tok_reg (newtok
[0], AXP_REG_T9
);
3622 set_tok_const (newtok
[1], 0);
3623 set_tok_preg (newtok
[2], AXP_REG_AT
);
3624 assemble_tokens ("ldq_u", newtok
, 3, 1);
3626 /* emit "ldq_u $t10, size-1($at)" */
3628 set_tok_reg (newtok
[0], AXP_REG_T10
);
3629 set_tok_const (newtok
[1], (1<<lgsize
)-1);
3630 assemble_tokens ("ldq_u", newtok
, 3, 1);
3632 /* emit "extXl $t9, $at, $t9" */
3634 set_tok_reg (newtok
[0], AXP_REG_T9
);
3635 set_tok_reg (newtok
[1], AXP_REG_AT
);
3636 set_tok_reg (newtok
[2], AXP_REG_T9
);
3637 assemble_tokens (extXl_op
[lgsize
], newtok
, 3, 1);
3639 /* emit "extXh $t10, $at, $t10" */
3641 set_tok_reg (newtok
[0], AXP_REG_T10
);
3642 set_tok_reg (newtok
[2], AXP_REG_T10
);
3643 assemble_tokens (extXh_op
[lgsize
], newtok
, 3, 1);
3645 /* emit "or $t9, $t10, targ" */
3647 set_tok_reg (newtok
[0], AXP_REG_T9
);
3648 set_tok_reg (newtok
[1], AXP_REG_T10
);
3650 assemble_tokens ("or", newtok
, 3, 1);
3653 /* Load an integral value from an unaligned address as a signed value.
3654 Note that quads should get funneled to the unsigned load since we
3655 don't have to do the sign extension. */
3658 emit_uldX (tok
, ntok
, vlgsize
)
3659 const expressionS
*tok
;
3663 emit_uldXu (tok
, ntok
, vlgsize
);
3664 assemble_tokens (sextX_op
[(long)vlgsize
], tok
, 1, 1);
3667 /* Implement the ldil macro. */
3670 emit_ldil (tok
, ntok
, unused
)
3671 const expressionS
*tok
;
3673 const PTR unused ATTRIBUTE_UNUSED
;
3675 expressionS newtok
[2];
3678 if (ntok
&& USER_RELOC_P (tok
[ntok
-1].X_op
))
3680 const expressionS
*reloc_exp
= &tok
[ntok
-1];
3681 const struct alpha_reloc_op_tag
*r
= ALPHA_RELOC_TABLE (reloc_exp
->X_op
);
3682 as_bad (_("Cannot use !%s!%d with %s"), r
->name
,
3683 (int)reloc_exp
->X_add_number
, "ldil");
3688 memcpy (newtok
, tok
, sizeof (newtok
));
3689 newtok
[1].X_add_number
= sign_extend_32 (tok
[1].X_add_number
);
3691 assemble_tokens ("lda", newtok
, ntok
, 1);
3694 /* Store a half-word or byte. */
3697 emit_stX (tok
, ntok
, vlgsize
)
3698 const expressionS
*tok
;
3702 int lgsize
= (int) (long)vlgsize
;
3704 if (alpha_target
& AXP_OPCODE_BWX
)
3705 emit_loadstore (tok
, ntok
, stX_op
[lgsize
]);
3708 expressionS newtok
[3];
3711 as_bad(_("macro requires $at register while noat in effect"));
3713 /* emit "lda $at, exp" */
3715 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
3716 newtok
[0].X_add_number
= AXP_REG_AT
;
3717 assemble_tokens ("lda", newtok
, ntok
, 1);
3719 /* emit "ldq_u $t9, 0($at)" */
3721 set_tok_reg (newtok
[0], AXP_REG_T9
);
3722 set_tok_const (newtok
[1], 0);
3723 set_tok_preg (newtok
[2], AXP_REG_AT
);
3724 assemble_tokens ("ldq_u", newtok
, 3, 1);
3726 /* emit "insXl src, $at, $t10" */
3729 set_tok_reg (newtok
[1], AXP_REG_AT
);
3730 set_tok_reg (newtok
[2], AXP_REG_T10
);
3731 assemble_tokens (insXl_op
[lgsize
], newtok
, 3, 1);
3733 /* emit "mskXl $t9, $at, $t9" */
3735 set_tok_reg (newtok
[0], AXP_REG_T9
);
3736 newtok
[2] = newtok
[0];
3737 assemble_tokens (mskXl_op
[lgsize
], newtok
, 3, 1);
3739 /* emit "or $t9, $t10, $t9" */
3741 set_tok_reg (newtok
[1], AXP_REG_T10
);
3742 assemble_tokens ("or", newtok
, 3, 1);
3744 /* emit "stq_u $t9, 0($at) */
3746 set_tok_const (newtok
[1], 0);
3747 set_tok_preg (newtok
[2], AXP_REG_AT
);
3748 assemble_tokens ("stq_u", newtok
, 3, 1);
3752 /* Store an integer to an unaligned address. */
3755 emit_ustX (tok
, ntok
, vlgsize
)
3756 const expressionS
*tok
;
3760 int lgsize
= (int) (long)vlgsize
;
3761 expressionS newtok
[3];
3763 /* emit "lda $at, exp" */
3765 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
3766 newtok
[0].X_add_number
= AXP_REG_AT
;
3767 assemble_tokens ("lda", newtok
, ntok
, 1);
3769 /* emit "ldq_u $9, 0($at)" */
3771 set_tok_reg (newtok
[0], AXP_REG_T9
);
3772 set_tok_const (newtok
[1], 0);
3773 set_tok_preg (newtok
[2], AXP_REG_AT
);
3774 assemble_tokens ("ldq_u", newtok
, 3, 1);
3776 /* emit "ldq_u $10, size-1($at)" */
3778 set_tok_reg (newtok
[0], AXP_REG_T10
);
3779 set_tok_const (newtok
[1], (1 << lgsize
)-1);
3780 assemble_tokens ("ldq_u", newtok
, 3, 1);
3782 /* emit "insXl src, $at, $t11" */
3785 set_tok_reg (newtok
[1], AXP_REG_AT
);
3786 set_tok_reg (newtok
[2], AXP_REG_T11
);
3787 assemble_tokens (insXl_op
[lgsize
], newtok
, 3, 1);
3789 /* emit "insXh src, $at, $t12" */
3791 set_tok_reg (newtok
[2], AXP_REG_T12
);
3792 assemble_tokens (insXh_op
[lgsize
], newtok
, 3, 1);
3794 /* emit "mskXl $t9, $at, $t9" */
3796 set_tok_reg (newtok
[0], AXP_REG_T9
);
3797 newtok
[2] = newtok
[0];
3798 assemble_tokens (mskXl_op
[lgsize
], newtok
, 3, 1);
3800 /* emit "mskXh $t10, $at, $t10" */
3802 set_tok_reg (newtok
[0], AXP_REG_T10
);
3803 newtok
[2] = newtok
[0];
3804 assemble_tokens (mskXh_op
[lgsize
], newtok
, 3, 1);
3806 /* emit "or $t9, $t11, $t9" */
3808 set_tok_reg (newtok
[0], AXP_REG_T9
);
3809 set_tok_reg (newtok
[1], AXP_REG_T11
);
3810 newtok
[2] = newtok
[0];
3811 assemble_tokens ("or", newtok
, 3, 1);
3813 /* emit "or $t10, $t12, $t10" */
3815 set_tok_reg (newtok
[0], AXP_REG_T10
);
3816 set_tok_reg (newtok
[1], AXP_REG_T12
);
3817 newtok
[2] = newtok
[0];
3818 assemble_tokens ("or", newtok
, 3, 1);
3820 /* emit "stq_u $t9, 0($at)" */
3822 set_tok_reg (newtok
[0], AXP_REG_T9
);
3823 set_tok_const (newtok
[1], 0);
3824 set_tok_preg (newtok
[2], AXP_REG_AT
);
3825 assemble_tokens ("stq_u", newtok
, 3, 1);
3827 /* emit "stq_u $t10, size-1($at)" */
3829 set_tok_reg (newtok
[0], AXP_REG_T10
);
3830 set_tok_const (newtok
[1], (1 << lgsize
)-1);
3831 assemble_tokens ("stq_u", newtok
, 3, 1);
3834 /* Sign extend a half-word or byte. The 32-bit sign extend is
3835 implemented as "addl $31, $r, $t" in the opcode table. */
3838 emit_sextX (tok
, ntok
, vlgsize
)
3839 const expressionS
*tok
;
3843 long lgsize
= (long)vlgsize
;
3845 if (alpha_target
& AXP_OPCODE_BWX
)
3846 assemble_tokens (sextX_op
[lgsize
], tok
, ntok
, 0);
3849 int bitshift
= 64 - 8 * (1 << lgsize
);
3850 expressionS newtok
[3];
3853 if (ntok
&& USER_RELOC_P (tok
[ntok
-1].X_op
))
3855 const expressionS
*reloc_exp
= &tok
[ntok
-1];
3856 const struct alpha_reloc_op_tag
*r
3857 = ALPHA_RELOC_TABLE (reloc_exp
->X_op
);
3859 as_bad (_("Cannot use !%s!%d with %s"), r
->name
,
3860 (int)reloc_exp
->X_add_number
, "setxt");
3865 /* emit "sll src,bits,dst" */
3868 set_tok_const (newtok
[1], bitshift
);
3869 newtok
[2] = tok
[ntok
- 1];
3870 assemble_tokens ("sll", newtok
, 3, 1);
3872 /* emit "sra dst,bits,dst" */
3874 newtok
[0] = newtok
[2];
3875 assemble_tokens ("sra", newtok
, 3, 1);
3879 /* Implement the division and modulus macros. */
3883 /* Make register usage like in normal procedure call.
3884 Don't clobber PV and RA. */
3887 emit_division (tok
, ntok
, symname
)
3888 const expressionS
*tok
;
3892 /* DIVISION and MODULUS. Yech.
3897 * mov x,R16 # if x != R16
3898 * mov y,R17 # if y != R17
3903 * with appropriate optimizations if R0,R16,R17 are the registers
3904 * specified by the compiler.
3909 expressionS newtok
[3];
3912 if (ntok
&& USER_RELOC_P (tok
[ntok
-1].X_op
))
3914 const expressionS
*reloc_exp
= &tok
[ntok
-1];
3915 const struct alpha_reloc_op_tag
*r
= ALPHA_RELOC_TABLE (reloc_exp
->X_op
);
3916 as_bad (_("Cannot use !%s!%d with %s"), r
->name
,
3917 (int)reloc_exp
->X_add_number
, (char char *)symname
);
3922 xr
= regno (tok
[0].X_add_number
);
3923 yr
= regno (tok
[1].X_add_number
);
3928 rr
= regno (tok
[2].X_add_number
);
3930 /* Move the operands into the right place */
3931 if (yr
== AXP_REG_R16
&& xr
== AXP_REG_R17
)
3933 /* They are in exactly the wrong order -- swap through AT */
3936 as_bad (_("macro requires $at register while noat in effect"));
3938 set_tok_reg (newtok
[0], AXP_REG_R16
);
3939 set_tok_reg (newtok
[1], AXP_REG_AT
);
3940 assemble_tokens ("mov", newtok
, 2, 1);
3942 set_tok_reg (newtok
[0], AXP_REG_R17
);
3943 set_tok_reg (newtok
[1], AXP_REG_R16
);
3944 assemble_tokens ("mov", newtok
, 2, 1);
3946 set_tok_reg (newtok
[0], AXP_REG_AT
);
3947 set_tok_reg (newtok
[1], AXP_REG_R17
);
3948 assemble_tokens ("mov", newtok
, 2, 1);
3952 if (yr
== AXP_REG_R16
)
3954 set_tok_reg (newtok
[0], AXP_REG_R16
);
3955 set_tok_reg (newtok
[1], AXP_REG_R17
);
3956 assemble_tokens ("mov", newtok
, 2, 1);
3959 if (xr
!= AXP_REG_R16
)
3961 set_tok_reg (newtok
[0], xr
);
3962 set_tok_reg (newtok
[1], AXP_REG_R16
);
3963 assemble_tokens ("mov", newtok
, 2, 1);
3966 if (yr
!= AXP_REG_R16
&& yr
!= AXP_REG_R17
)
3968 set_tok_reg (newtok
[0], yr
);
3969 set_tok_reg (newtok
[1], AXP_REG_R17
);
3970 assemble_tokens ("mov", newtok
, 2, 1);
3974 sym
= symbol_find_or_make ((const char *)symname
);
3976 set_tok_reg (newtok
[0], AXP_REG_AT
);
3977 set_tok_sym (newtok
[1], sym
, 0);
3978 assemble_tokens ("lda", newtok
, 2, 1);
3980 /* Call the division routine */
3981 set_tok_reg (newtok
[0], AXP_REG_AT
);
3982 set_tok_cpreg (newtok
[1], AXP_REG_AT
);
3983 set_tok_const (newtok
[2], 0);
3984 assemble_tokens ("jsr", newtok
, 3, 1);
3986 /* Move the result to the right place */
3987 if (rr
!= AXP_REG_R0
)
3989 set_tok_reg (newtok
[0], AXP_REG_R0
);
3990 set_tok_reg (newtok
[1], rr
);
3991 assemble_tokens ("mov", newtok
, 2, 1);
3995 #else /* !OBJ_EVAX */
3998 emit_division (tok
, ntok
, symname
)
3999 const expressionS
*tok
;
4003 /* DIVISION and MODULUS. Yech.
4013 * with appropriate optimizations if t10,t11,t12 are the registers
4014 * specified by the compiler.
4019 expressionS newtok
[3];
4022 if (ntok
&& USER_RELOC_P (tok
[ntok
-1].X_op
))
4024 const expressionS
*reloc_exp
= &tok
[ntok
-1];
4025 const struct alpha_reloc_op_tag
*r
= ALPHA_RELOC_TABLE (reloc_exp
->X_op
);
4026 as_bad (_("Cannot use !%s!%d with %s"), r
->name
,
4027 (int)reloc_exp
->X_add_number
, (const char *)symname
);
4032 xr
= regno (tok
[0].X_add_number
);
4033 yr
= regno (tok
[1].X_add_number
);
4038 rr
= regno (tok
[2].X_add_number
);
4040 sym
= symbol_find_or_make ((const char *)symname
);
4042 /* Move the operands into the right place */
4043 if (yr
== AXP_REG_T10
&& xr
== AXP_REG_T11
)
4045 /* They are in exactly the wrong order -- swap through AT */
4048 as_bad (_("macro requires $at register while noat in effect"));
4050 set_tok_reg (newtok
[0], AXP_REG_T10
);
4051 set_tok_reg (newtok
[1], AXP_REG_AT
);
4052 assemble_tokens ("mov", newtok
, 2, 1);
4054 set_tok_reg (newtok
[0], AXP_REG_T11
);
4055 set_tok_reg (newtok
[1], AXP_REG_T10
);
4056 assemble_tokens ("mov", newtok
, 2, 1);
4058 set_tok_reg (newtok
[0], AXP_REG_AT
);
4059 set_tok_reg (newtok
[1], AXP_REG_T11
);
4060 assemble_tokens ("mov", newtok
, 2, 1);
4064 if (yr
== AXP_REG_T10
)
4066 set_tok_reg (newtok
[0], AXP_REG_T10
);
4067 set_tok_reg (newtok
[1], AXP_REG_T11
);
4068 assemble_tokens ("mov", newtok
, 2, 1);
4071 if (xr
!= AXP_REG_T10
)
4073 set_tok_reg (newtok
[0], xr
);
4074 set_tok_reg (newtok
[1], AXP_REG_T10
);
4075 assemble_tokens ("mov", newtok
, 2, 1);
4078 if (yr
!= AXP_REG_T10
&& yr
!= AXP_REG_T11
)
4080 set_tok_reg (newtok
[0], yr
);
4081 set_tok_reg (newtok
[1], AXP_REG_T11
);
4082 assemble_tokens ("mov", newtok
, 2, 1);
4086 /* Call the division routine */
4087 set_tok_reg (newtok
[0], AXP_REG_T9
);
4088 set_tok_sym (newtok
[1], sym
, 0);
4089 assemble_tokens ("jsr", newtok
, 2, 1);
4091 /* Reload the GP register */
4095 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
4096 set_tok_reg (newtok
[0], alpha_gp_register
);
4097 set_tok_const (newtok
[1], 0);
4098 set_tok_preg (newtok
[2], AXP_REG_T9
);
4099 assemble_tokens ("ldgp", newtok
, 3, 1);
4102 /* Move the result to the right place */
4103 if (rr
!= AXP_REG_T12
)
4105 set_tok_reg (newtok
[0], AXP_REG_T12
);
4106 set_tok_reg (newtok
[1], rr
);
4107 assemble_tokens ("mov", newtok
, 2, 1);
4111 #endif /* !OBJ_EVAX */
4113 /* The jsr and jmp macros differ from their instruction counterparts
4114 in that they can load the target address and default most
4118 emit_jsrjmp (tok
, ntok
, vopname
)
4119 const expressionS
*tok
;
4123 const char *opname
= (const char *) vopname
;
4124 struct alpha_insn insn
;
4125 expressionS newtok
[3];
4126 int r
, tokidx
= 0, lituse
= 0;
4129 if (ntok
&& USER_RELOC_P (tok
[ntok
-1].X_op
))
4131 const expressionS
*reloc_exp
= &tok
[ntok
-1];
4132 const struct alpha_reloc_op_tag
*r
= ALPHA_RELOC_TABLE (reloc_exp
->X_op
);
4133 as_bad (_("Cannot use !%s!%d with %s"), r
->name
,
4134 (int)reloc_exp
->X_add_number
, opname
);
4139 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_register
)
4140 r
= regno (tok
[tokidx
++].X_add_number
);
4142 r
= strcmp (opname
, "jmp") == 0 ? AXP_REG_ZERO
: AXP_REG_RA
;
4144 set_tok_reg (newtok
[0], r
);
4146 if (tokidx
< ntok
&&
4147 (tok
[tokidx
].X_op
== O_pregister
|| tok
[tokidx
].X_op
== O_cpregister
))
4148 r
= regno (tok
[tokidx
++].X_add_number
);
4150 /* keep register if jsr $n.<sym> */
4154 int basereg
= alpha_gp_register
;
4155 lituse
= load_expression (r
= AXP_REG_PV
, &tok
[tokidx
], &basereg
, NULL
,
4156 (const expressionS
*)0);
4160 set_tok_cpreg (newtok
[1], r
);
4163 /* FIXME: Add hint relocs to BFD for evax. */
4166 newtok
[2] = tok
[tokidx
];
4169 set_tok_const (newtok
[2], 0);
4171 assemble_tokens_to_insn (opname
, newtok
, 3, &insn
);
4173 /* add the LITUSE fixup */
4176 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
4177 if (insn
.nfixups
> 0)
4179 memmove (&insn
.fixups
[1], &insn
.fixups
[0],
4180 sizeof (struct alpha_fixup
) * insn
.nfixups
);
4183 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITUSE
;
4184 insn
.fixups
[0].exp
.X_op
= O_symbol
;
4185 insn
.fixups
[0].exp
.X_add_symbol
= section_symbol (now_seg
);
4186 insn
.fixups
[0].exp
.X_add_number
= LITUSE_JSR
;
4192 /* The ret and jcr instructions differ from their instruction
4193 counterparts in that everything can be defaulted. */
4196 emit_retjcr (tok
, ntok
, vopname
)
4197 const expressionS
*tok
;
4201 const char *opname
= (const char *)vopname
;
4202 expressionS newtok
[3];
4206 if (ntok
&& USER_RELOC_P (tok
[ntok
-1].X_op
))
4208 const expressionS
*reloc_exp
= &tok
[ntok
-1];
4209 const struct alpha_reloc_op_tag
*r
= ALPHA_RELOC_TABLE (reloc_exp
->X_op
);
4210 as_bad (_("Cannot use !%s!%d with %s"), r
->name
,
4211 (int)reloc_exp
->X_add_number
, opname
);
4216 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_register
)
4217 r
= regno (tok
[tokidx
++].X_add_number
);
4221 set_tok_reg (newtok
[0], r
);
4223 if (tokidx
< ntok
&&
4224 (tok
[tokidx
].X_op
== O_pregister
|| tok
[tokidx
].X_op
== O_cpregister
))
4225 r
= regno (tok
[tokidx
++].X_add_number
);
4229 set_tok_cpreg (newtok
[1], r
);
4232 newtok
[2] = tok
[tokidx
];
4234 set_tok_const (newtok
[2], strcmp(opname
, "ret") == 0);
4236 assemble_tokens (opname
, newtok
, 3, 0);
4239 /* Assembler directives */
4241 /* Handle the .text pseudo-op. This is like the usual one, but it
4242 clears alpha_insn_label and restores auto alignment. */
4250 alpha_insn_label
= NULL
;
4251 alpha_auto_align_on
= 1;
4252 alpha_current_align
= 0;
4255 /* Handle the .data pseudo-op. This is like the usual one, but it
4256 clears alpha_insn_label and restores auto alignment. */
4263 alpha_insn_label
= NULL
;
4264 alpha_auto_align_on
= 1;
4265 alpha_current_align
= 0;
4268 #if defined (OBJ_ECOFF) || defined (OBJ_EVAX)
4270 /* Handle the OSF/1 and openVMS .comm pseudo quirks.
4271 openVMS constructs a section for every common symbol. */
4274 s_alpha_comm (ignore
)
4277 register char *name
;
4281 register symbolS
*symbolP
;
4284 segT current_section
= now_seg
;
4285 int current_subsec
= now_subseg
;
4289 name
= input_line_pointer
;
4290 c
= get_symbol_end ();
4292 /* just after name is now '\0' */
4293 p
= input_line_pointer
;
4298 /* Alpha OSF/1 compiler doesn't provide the comma, gcc does. */
4299 if (*input_line_pointer
== ',')
4301 input_line_pointer
++;
4304 if ((temp
= get_absolute_expression ()) < 0)
4306 as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) temp
);
4307 ignore_rest_of_line ();
4312 symbolP
= symbol_find_or_make (name
);
4315 /* Make a section for the common symbol. */
4316 new_seg
= subseg_new (xstrdup (name
), 0);
4322 /* alignment might follow */
4323 if (*input_line_pointer
== ',')
4327 input_line_pointer
++;
4328 align
= get_absolute_expression ();
4329 bfd_set_section_alignment (stdoutput
, new_seg
, align
);
4333 if (S_IS_DEFINED (symbolP
) && ! S_IS_COMMON (symbolP
))
4335 as_bad (_("Ignoring attempt to re-define symbol"));
4336 ignore_rest_of_line ();
4341 if (bfd_section_size (stdoutput
, new_seg
) > 0)
4343 if (bfd_section_size (stdoutput
, new_seg
) != temp
)
4344 as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
4345 S_GET_NAME (symbolP
),
4346 (long) bfd_section_size (stdoutput
, new_seg
),
4350 if (S_GET_VALUE (symbolP
))
4352 if (S_GET_VALUE (symbolP
) != (valueT
) temp
)
4353 as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
4354 S_GET_NAME (symbolP
),
4355 (long) S_GET_VALUE (symbolP
),
4362 subseg_set (new_seg
, 0);
4363 p
= frag_more (temp
);
4364 new_seg
->flags
|= SEC_IS_COMMON
;
4365 if (! S_IS_DEFINED (symbolP
))
4366 S_SET_SEGMENT (symbolP
, new_seg
);
4368 S_SET_VALUE (symbolP
, (valueT
) temp
);
4370 S_SET_EXTERNAL (symbolP
);
4374 subseg_set (current_section
, current_subsec
);
4377 know (symbol_get_frag (symbolP
) == &zero_address_frag
);
4379 demand_empty_rest_of_line ();
4382 #endif /* ! OBJ_ELF */
4386 /* Handle the .rdata pseudo-op. This is like the usual one, but it
4387 clears alpha_insn_label and restores auto alignment. */
4390 s_alpha_rdata (ignore
)
4395 temp
= get_absolute_expression ();
4396 subseg_new (".rdata", 0);
4397 demand_empty_rest_of_line ();
4398 alpha_insn_label
= NULL
;
4399 alpha_auto_align_on
= 1;
4400 alpha_current_align
= 0;
4407 /* Handle the .sdata pseudo-op. This is like the usual one, but it
4408 clears alpha_insn_label and restores auto alignment. */
4411 s_alpha_sdata (ignore
)
4416 temp
= get_absolute_expression ();
4417 subseg_new (".sdata", 0);
4418 demand_empty_rest_of_line ();
4419 alpha_insn_label
= NULL
;
4420 alpha_auto_align_on
= 1;
4421 alpha_current_align
= 0;
4427 /* Handle the .section pseudo-op. This is like the usual one, but it
4428 clears alpha_insn_label and restores auto alignment. */
4431 s_alpha_section (ignore
)
4434 obj_elf_section (ignore
);
4436 alpha_insn_label
= NULL
;
4437 alpha_auto_align_on
= 1;
4438 alpha_current_align
= 0;
4443 int dummy ATTRIBUTE_UNUSED
;
4445 if (ECOFF_DEBUGGING
)
4446 ecoff_directive_ent (0);
4449 char *name
, name_end
;
4450 name
= input_line_pointer
;
4451 name_end
= get_symbol_end ();
4453 if (! is_name_beginner (*name
))
4455 as_warn (_(".ent directive has no name"));
4456 *input_line_pointer
= name_end
;
4462 if (alpha_cur_ent_sym
)
4463 as_warn (_("nested .ent directives"));
4465 sym
= symbol_find_or_make (name
);
4466 symbol_get_bfdsym (sym
)->flags
|= BSF_FUNCTION
;
4467 alpha_cur_ent_sym
= sym
;
4469 /* The .ent directive is sometimes followed by a number. Not sure
4470 what it really means, but ignore it. */
4471 *input_line_pointer
= name_end
;
4473 if (*input_line_pointer
== ',')
4475 input_line_pointer
++;
4478 if (isdigit (*input_line_pointer
) || *input_line_pointer
== '-')
4479 (void) get_absolute_expression ();
4481 demand_empty_rest_of_line ();
4487 int dummy ATTRIBUTE_UNUSED
;
4489 if (ECOFF_DEBUGGING
)
4490 ecoff_directive_end (0);
4493 char *name
, name_end
;
4494 name
= input_line_pointer
;
4495 name_end
= get_symbol_end ();
4497 if (! is_name_beginner (*name
))
4499 as_warn (_(".end directive has no name"));
4500 *input_line_pointer
= name_end
;
4506 sym
= symbol_find (name
);
4507 if (sym
!= alpha_cur_ent_sym
)
4508 as_warn (_(".end directive names different symbol than .ent"));
4510 /* Create an expression to calculate the size of the function. */
4513 symbol_get_obj (sym
)->size
=
4514 (expressionS
*) xmalloc (sizeof (expressionS
));
4515 symbol_get_obj (sym
)->size
->X_op
= O_subtract
;
4516 symbol_get_obj (sym
)->size
->X_add_symbol
4517 = symbol_new ("L0\001", now_seg
, frag_now_fix (), frag_now
);
4518 symbol_get_obj (sym
)->size
->X_op_symbol
= sym
;
4519 symbol_get_obj (sym
)->size
->X_add_number
= 0;
4522 alpha_cur_ent_sym
= NULL
;
4524 *input_line_pointer
= name_end
;
4526 demand_empty_rest_of_line ();
4534 if (ECOFF_DEBUGGING
)
4537 ecoff_directive_fmask (0);
4539 ecoff_directive_mask (0);
4542 discard_rest_of_line ();
4546 s_alpha_frame (dummy
)
4547 int dummy ATTRIBUTE_UNUSED
;
4549 if (ECOFF_DEBUGGING
)
4550 ecoff_directive_frame (0);
4552 discard_rest_of_line ();
4556 s_alpha_prologue (ignore
)
4557 int ignore ATTRIBUTE_UNUSED
;
4562 arg
= get_absolute_expression ();
4563 demand_empty_rest_of_line ();
4565 if (ECOFF_DEBUGGING
)
4566 sym
= ecoff_get_cur_proc_sym ();
4568 sym
= alpha_cur_ent_sym
;
4573 case 0: /* No PV required. */
4574 S_SET_OTHER (sym
, STO_ALPHA_NOPV
4575 | (S_GET_OTHER (sym
) & ~STO_ALPHA_STD_GPLOAD
));
4577 case 1: /* Std GP load. */
4578 S_SET_OTHER (sym
, STO_ALPHA_STD_GPLOAD
4579 | (S_GET_OTHER (sym
) & ~STO_ALPHA_STD_GPLOAD
));
4581 case 2: /* Non-std use of PV. */
4585 as_bad (_("Invalid argument %d to .prologue."), arg
);
4590 static char * first_file_directive
;
4593 s_alpha_file (ignore
)
4594 int ignore ATTRIBUTE_UNUSED
;
4596 /* Save the first .file directive we see, so that we can change our
4597 minds about whether ecoff debugging should or shouldn't be enabled. */
4598 if (alpha_flag_mdebug
< 0 && ! first_file_directive
)
4600 char *start
= input_line_pointer
;
4603 discard_rest_of_line ();
4605 len
= input_line_pointer
- start
;
4606 first_file_directive
= xmalloc (len
+ 1);
4607 memcpy (first_file_directive
, start
, len
);
4608 first_file_directive
[len
] = '\0';
4610 input_line_pointer
= start
;
4613 if (ECOFF_DEBUGGING
)
4614 ecoff_directive_file (0);
4616 dwarf2_directive_file (0);
4620 s_alpha_loc (ignore
)
4621 int ignore ATTRIBUTE_UNUSED
;
4623 if (ECOFF_DEBUGGING
)
4624 ecoff_directive_loc (0);
4626 dwarf2_directive_loc (0);
4633 /* If we've been undecided about mdebug, make up our minds in favour. */
4634 if (alpha_flag_mdebug
< 0)
4636 segT sec
= subseg_new(".mdebug", 0);
4637 bfd_set_section_flags(stdoutput
, sec
, SEC_HAS_CONTENTS
|SEC_READONLY
);
4638 bfd_set_section_alignment(stdoutput
, sec
, 3);
4640 ecoff_read_begin_hook ();
4642 if (first_file_directive
)
4644 char *save_ilp
= input_line_pointer
;
4645 input_line_pointer
= first_file_directive
;
4646 ecoff_directive_file (0);
4647 input_line_pointer
= save_ilp
;
4648 free (first_file_directive
);
4651 alpha_flag_mdebug
= 1;
4657 s_alpha_coff_wrapper (which
)
4660 static void (* const fns
[]) PARAMS ((int)) = {
4661 ecoff_directive_begin
,
4662 ecoff_directive_bend
,
4663 ecoff_directive_def
,
4664 ecoff_directive_dim
,
4665 ecoff_directive_endef
,
4666 ecoff_directive_scl
,
4667 ecoff_directive_tag
,
4668 ecoff_directive_val
,
4671 assert (which
>= 0 && which
< (int) (sizeof (fns
)/sizeof (*fns
)));
4673 if (ECOFF_DEBUGGING
)
4677 as_bad (_("ECOFF debugging is disabled."));
4678 ignore_rest_of_line ();
4681 #endif /* OBJ_ELF */
4685 /* Handle the section specific pseudo-op. */
4688 s_alpha_section (secid
)
4692 #define EVAX_SECTION_COUNT 5
4693 static char *section_name
[EVAX_SECTION_COUNT
+1] =
4694 { "NULL", ".rdata", ".comm", ".link", ".ctors", ".dtors" };
4696 if ((secid
<= 0) || (secid
> EVAX_SECTION_COUNT
))
4698 as_fatal (_("Unknown section directive"));
4699 demand_empty_rest_of_line ();
4702 temp
= get_absolute_expression ();
4703 subseg_new (section_name
[secid
], 0);
4704 demand_empty_rest_of_line ();
4705 alpha_insn_label
= NULL
;
4706 alpha_auto_align_on
= 1;
4707 alpha_current_align
= 0;
4710 /* Parse .ent directives. */
4713 s_alpha_ent (ignore
)
4717 expressionS symexpr
;
4719 alpha_evax_proc
.pdsckind
= 0;
4720 alpha_evax_proc
.framereg
= -1;
4721 alpha_evax_proc
.framesize
= 0;
4722 alpha_evax_proc
.rsa_offset
= 0;
4723 alpha_evax_proc
.ra_save
= AXP_REG_RA
;
4724 alpha_evax_proc
.fp_save
= -1;
4725 alpha_evax_proc
.imask
= 0;
4726 alpha_evax_proc
.fmask
= 0;
4727 alpha_evax_proc
.prologue
= 0;
4728 alpha_evax_proc
.type
= 0;
4730 expression (&symexpr
);
4732 if (symexpr
.X_op
!= O_symbol
)
4734 as_fatal (_(".ent directive has no symbol"));
4735 demand_empty_rest_of_line ();
4739 symbol
= make_expr_symbol (&symexpr
);
4740 symbol_get_bfdsym (symbol
)->flags
|= BSF_FUNCTION
;
4741 alpha_evax_proc
.symbol
= symbol
;
4743 demand_empty_rest_of_line ();
4747 /* Parse .frame <framreg>,<framesize>,RA,<rsa_offset> directives. */
4750 s_alpha_frame (ignore
)
4755 alpha_evax_proc
.framereg
= tc_get_register (1);
4758 if (*input_line_pointer
++ != ','
4759 || get_absolute_expression_and_terminator (&val
) != ',')
4761 as_warn (_("Bad .frame directive 1./2. param"));
4762 --input_line_pointer
;
4763 demand_empty_rest_of_line ();
4767 alpha_evax_proc
.framesize
= val
;
4769 (void) tc_get_register (1);
4771 if (*input_line_pointer
++ != ',')
4773 as_warn (_("Bad .frame directive 3./4. param"));
4774 --input_line_pointer
;
4775 demand_empty_rest_of_line ();
4778 alpha_evax_proc
.rsa_offset
= get_absolute_expression ();
4784 s_alpha_pdesc (ignore
)
4794 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
4796 if (now_seg
!= alpha_link_section
)
4798 as_bad (_(".pdesc directive not in link (.link) section"));
4799 demand_empty_rest_of_line ();
4803 if ((alpha_evax_proc
.symbol
== 0)
4804 || (!S_IS_DEFINED (alpha_evax_proc
.symbol
)))
4806 as_fatal (_(".pdesc has no matching .ent"));
4807 demand_empty_rest_of_line ();
4811 *symbol_get_obj (alpha_evax_proc
.symbol
) =
4812 (valueT
) seginfo
->literal_pool_size
;
4815 if (exp
.X_op
!= O_symbol
)
4817 as_warn (_(".pdesc directive has no entry symbol"));
4818 demand_empty_rest_of_line ();
4822 entry_sym
= make_expr_symbol (&exp
);
4823 /* Save bfd symbol of proc desc in function symbol. */
4824 symbol_get_bfdsym (alpha_evax_proc
.symbol
)->udata
.p
4825 = symbol_get_bfdsym (entry_sym
);
4828 if (*input_line_pointer
++ != ',')
4830 as_warn (_("No comma after .pdesc <entryname>"));
4831 demand_empty_rest_of_line ();
4836 name
= input_line_pointer
;
4837 name_end
= get_symbol_end ();
4839 if (strncmp(name
, "stack", 5) == 0)
4841 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_FP_STACK
;
4843 else if (strncmp(name
, "reg", 3) == 0)
4845 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_FP_REGISTER
;
4847 else if (strncmp(name
, "null", 4) == 0)
4849 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_NULL
;
4853 as_fatal (_("unknown procedure kind"));
4854 demand_empty_rest_of_line ();
4858 *input_line_pointer
= name_end
;
4859 demand_empty_rest_of_line ();
4861 #ifdef md_flush_pending_output
4862 md_flush_pending_output ();
4865 frag_align (3, 0, 0);
4867 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
4869 seginfo
->literal_pool_size
+= 16;
4871 *p
= alpha_evax_proc
.pdsckind
4872 | ((alpha_evax_proc
.framereg
== 29) ? PDSC_S_M_BASE_REG_IS_FP
: 0);
4873 *(p
+1) = PDSC_S_M_NATIVE
4874 | PDSC_S_M_NO_JACKET
;
4876 switch (alpha_evax_proc
.pdsckind
)
4878 case PDSC_S_K_KIND_NULL
:
4882 case PDSC_S_K_KIND_FP_REGISTER
:
4883 *(p
+2) = alpha_evax_proc
.fp_save
;
4884 *(p
+3) = alpha_evax_proc
.ra_save
;
4886 case PDSC_S_K_KIND_FP_STACK
:
4887 md_number_to_chars (p
+2, (valueT
)alpha_evax_proc
.rsa_offset
, 2);
4889 default: /* impossible */
4894 *(p
+5) = alpha_evax_proc
.type
& 0x0f;
4896 /* Signature offset. */
4897 md_number_to_chars (p
+6, (valueT
)0, 2);
4899 fix_new_exp (frag_now
, p
-frag_now
->fr_literal
+8, 8, &exp
, 0, BFD_RELOC_64
);
4901 if (alpha_evax_proc
.pdsckind
== PDSC_S_K_KIND_NULL
)
4904 /* Add dummy fix to make add_to_link_pool work. */
4906 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
4908 seginfo
->literal_pool_size
+= 8;
4910 /* pdesc+16: Size. */
4911 md_number_to_chars (p
, (valueT
)alpha_evax_proc
.framesize
, 4);
4913 md_number_to_chars (p
+4, (valueT
)0, 2);
4916 md_number_to_chars (p
+6, alpha_evax_proc
.prologue
, 2);
4918 if (alpha_evax_proc
.pdsckind
== PDSC_S_K_KIND_FP_REGISTER
)
4921 /* Add dummy fix to make add_to_link_pool work. */
4923 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
4925 seginfo
->literal_pool_size
+= 8;
4927 /* pdesc+24: register masks. */
4929 md_number_to_chars (p
, alpha_evax_proc
.imask
, 4);
4930 md_number_to_chars (p
+4, alpha_evax_proc
.fmask
, 4);
4935 /* Support for crash debug on vms. */
4938 s_alpha_name (ignore
)
4943 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
4945 if (now_seg
!= alpha_link_section
)
4947 as_bad (_(".name directive not in link (.link) section"));
4948 demand_empty_rest_of_line ();
4953 if (exp
.X_op
!= O_symbol
)
4955 as_warn (_(".name directive has no symbol"));
4956 demand_empty_rest_of_line ();
4960 demand_empty_rest_of_line ();
4962 #ifdef md_flush_pending_output
4963 md_flush_pending_output ();
4966 frag_align (3, 0, 0);
4968 seginfo
->literal_pool_size
+= 8;
4970 fix_new_exp (frag_now
, p
-frag_now
->fr_literal
, 8, &exp
, 0, BFD_RELOC_64
);
4976 s_alpha_linkage (ignore
)
4982 #ifdef md_flush_pending_output
4983 md_flush_pending_output ();
4987 if (exp
.X_op
!= O_symbol
)
4989 as_fatal (_("No symbol after .linkage"));
4993 p
= frag_more (LKP_S_K_SIZE
);
4994 memset (p
, 0, LKP_S_K_SIZE
);
4995 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, LKP_S_K_SIZE
, &exp
, 0,\
4996 BFD_RELOC_ALPHA_LINKAGE
);
4998 demand_empty_rest_of_line ();
5004 s_alpha_code_address (ignore
)
5010 #ifdef md_flush_pending_output
5011 md_flush_pending_output ();
5015 if (exp
.X_op
!= O_symbol
)
5017 as_fatal (_("No symbol after .code_address"));
5023 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 8, &exp
, 0,\
5024 BFD_RELOC_ALPHA_CODEADDR
);
5026 demand_empty_rest_of_line ();
5032 s_alpha_fp_save (ignore
)
5036 alpha_evax_proc
.fp_save
= tc_get_register (1);
5038 demand_empty_rest_of_line ();
5043 s_alpha_mask (ignore
)
5048 if (get_absolute_expression_and_terminator (&val
) != ',')
5050 as_warn (_("Bad .mask directive"));
5051 --input_line_pointer
;
5055 alpha_evax_proc
.imask
= val
;
5056 (void)get_absolute_expression ();
5058 demand_empty_rest_of_line ();
5064 s_alpha_fmask (ignore
)
5069 if (get_absolute_expression_and_terminator (&val
) != ',')
5071 as_warn (_("Bad .fmask directive"));
5072 --input_line_pointer
;
5076 alpha_evax_proc
.fmask
= val
;
5077 (void) get_absolute_expression ();
5079 demand_empty_rest_of_line ();
5085 s_alpha_end (ignore
)
5090 c
= get_symbol_end ();
5091 *input_line_pointer
= c
;
5092 demand_empty_rest_of_line ();
5093 alpha_evax_proc
.symbol
= 0;
5099 s_alpha_file (ignore
)
5104 static char case_hack
[32];
5106 extern char *demand_copy_string
PARAMS ((int *lenP
));
5108 sprintf (case_hack
, "<CASE:%01d%01d>",
5109 alpha_flag_hash_long_names
, alpha_flag_show_after_trunc
);
5111 s
= symbol_find_or_make (case_hack
);
5112 symbol_get_bfdsym (s
)->flags
|= BSF_FILE
;
5114 get_absolute_expression ();
5115 s
= symbol_find_or_make (demand_copy_string (&length
));
5116 symbol_get_bfdsym (s
)->flags
|= BSF_FILE
;
5117 demand_empty_rest_of_line ();
5121 #endif /* OBJ_EVAX */
5123 /* Handle the .gprel32 pseudo op. */
5126 s_alpha_gprel32 (ignore
)
5127 int ignore ATTRIBUTE_UNUSED
;
5139 e
.X_add_symbol
= section_symbol(absolute_section
);
5152 e
.X_add_symbol
= section_symbol (absolute_section
);
5155 e
.X_op
= O_subtract
;
5156 e
.X_op_symbol
= alpha_gp_symbol
;
5164 if (alpha_auto_align_on
&& alpha_current_align
< 2)
5165 alpha_align (2, (char *) NULL
, alpha_insn_label
, 0);
5166 if (alpha_current_align
> 2)
5167 alpha_current_align
= 2;
5168 alpha_insn_label
= NULL
;
5172 fix_new_exp (frag_now
, p
-frag_now
->fr_literal
, 4,
5173 &e
, 0, BFD_RELOC_GPREL32
);
5176 /* Handle floating point allocation pseudo-ops. This is like the
5177 generic vresion, but it makes sure the current label, if any, is
5178 correctly aligned. */
5181 s_alpha_float_cons (type
)
5208 if (alpha_auto_align_on
&& alpha_current_align
< log_size
)
5209 alpha_align (log_size
, (char *) NULL
, alpha_insn_label
, 0);
5210 if (alpha_current_align
> log_size
)
5211 alpha_current_align
= log_size
;
5212 alpha_insn_label
= NULL
;
5217 /* Handle the .proc pseudo op. We don't really do much with it except
5221 s_alpha_proc (is_static
)
5222 int is_static ATTRIBUTE_UNUSED
;
5230 /* Takes ".proc name,nargs" */
5232 name
= input_line_pointer
;
5233 c
= get_symbol_end ();
5234 p
= input_line_pointer
;
5235 symbolP
= symbol_find_or_make (name
);
5238 if (*input_line_pointer
!= ',')
5241 as_warn (_("Expected comma after name \"%s\""), name
);
5244 ignore_rest_of_line ();
5248 input_line_pointer
++;
5249 temp
= get_absolute_expression ();
5251 /* *symbol_get_obj (symbolP) = (signed char) temp; */
5252 as_warn (_("unhandled: .proc %s,%d"), name
, temp
);
5253 demand_empty_rest_of_line ();
5256 /* Handle the .set pseudo op. This is used to turn on and off most of
5257 the assembler features. */
5261 int x ATTRIBUTE_UNUSED
;
5267 name
= input_line_pointer
;
5268 ch
= get_symbol_end ();
5271 if (s
[0] == 'n' && s
[1] == 'o')
5276 if (!strcmp ("reorder", s
))
5278 else if (!strcmp ("at", s
))
5279 alpha_noat_on
= !yesno
;
5280 else if (!strcmp ("macro", s
))
5281 alpha_macros_on
= yesno
;
5282 else if (!strcmp ("move", s
))
5284 else if (!strcmp ("volatile", s
))
5287 as_warn (_("Tried to .set unrecognized mode `%s'"), name
);
5289 *input_line_pointer
= ch
;
5290 demand_empty_rest_of_line ();
5293 /* Handle the .base pseudo op. This changes the assembler's notion of
5294 the $gp register. */
5297 s_alpha_base (ignore
)
5298 int ignore ATTRIBUTE_UNUSED
;
5301 if (first_32bit_quadrant
)
5303 /* not fatal, but it might not work in the end */
5304 as_warn (_("File overrides no-base-register option."));
5305 first_32bit_quadrant
= 0;
5310 if (*input_line_pointer
== '$')
5312 input_line_pointer
++;
5313 if (*input_line_pointer
== 'r')
5314 input_line_pointer
++;
5317 alpha_gp_register
= get_absolute_expression ();
5318 if (alpha_gp_register
< 0 || alpha_gp_register
> 31)
5320 alpha_gp_register
= AXP_REG_GP
;
5321 as_warn (_("Bad base register, using $%d."), alpha_gp_register
);
5324 demand_empty_rest_of_line ();
5327 /* Handle the .align pseudo-op. This aligns to a power of two. It
5328 also adjusts any current instruction label. We treat this the same
5329 way the MIPS port does: .align 0 turns off auto alignment. */
5332 s_alpha_align (ignore
)
5333 int ignore ATTRIBUTE_UNUSED
;
5337 long max_alignment
= 15;
5339 align
= get_absolute_expression ();
5340 if (align
> max_alignment
)
5342 align
= max_alignment
;
5343 as_bad (_("Alignment too large: %d. assumed"), align
);
5347 as_warn (_("Alignment negative: 0 assumed"));
5351 if (*input_line_pointer
== ',')
5353 input_line_pointer
++;
5354 fill
= get_absolute_expression ();
5362 alpha_auto_align_on
= 1;
5363 alpha_align (align
, pfill
, alpha_insn_label
, 1);
5367 alpha_auto_align_on
= 0;
5370 demand_empty_rest_of_line ();
5373 /* Hook the normal string processor to reset known alignment. */
5376 s_alpha_stringer (terminate
)
5379 alpha_current_align
= 0;
5380 alpha_insn_label
= NULL
;
5381 stringer (terminate
);
5384 /* Hook the normal space processing to reset known alignment. */
5387 s_alpha_space (ignore
)
5390 alpha_current_align
= 0;
5391 alpha_insn_label
= NULL
;
5395 /* Hook into cons for auto-alignment. */
5398 alpha_cons_align (size
)
5404 while ((size
>>= 1) != 0)
5407 if (alpha_auto_align_on
&& alpha_current_align
< log_size
)
5408 alpha_align (log_size
, (char *) NULL
, alpha_insn_label
, 0);
5409 if (alpha_current_align
> log_size
)
5410 alpha_current_align
= log_size
;
5411 alpha_insn_label
= NULL
;
5414 /* Here come the .uword, .ulong, and .uquad explicitly unaligned
5415 pseudos. We just turn off auto-alignment and call down to cons. */
5418 s_alpha_ucons (bytes
)
5421 int hold
= alpha_auto_align_on
;
5422 alpha_auto_align_on
= 0;
5424 alpha_auto_align_on
= hold
;
5427 /* Switch the working cpu type. */
5430 s_alpha_arch (ignored
)
5431 int ignored ATTRIBUTE_UNUSED
;
5434 const struct cpu_type
*p
;
5437 name
= input_line_pointer
;
5438 ch
= get_symbol_end ();
5440 for (p
= cpu_types
; p
->name
; ++p
)
5441 if (strcmp(name
, p
->name
) == 0)
5443 alpha_target_name
= p
->name
, alpha_target
= p
->flags
;
5446 as_warn("Unknown CPU identifier `%s'", name
);
5449 *input_line_pointer
= ch
;
5450 demand_empty_rest_of_line ();
5456 /* print token expression with alpha specific extension. */
5459 alpha_print_token(f
, exp
)
5461 const expressionS
*exp
;
5471 expressionS nexp
= *exp
;
5472 nexp
.X_op
= O_register
;
5473 print_expr (f
, &nexp
);
5478 print_expr (f
, exp
);
5485 /* The target specific pseudo-ops which we support. */
5487 const pseudo_typeS md_pseudo_table
[] =
5490 {"comm", s_alpha_comm
, 0}, /* osf1 compiler does this */
5491 {"rdata", s_alpha_rdata
, 0},
5493 {"text", s_alpha_text
, 0},
5494 {"data", s_alpha_data
, 0},
5496 {"sdata", s_alpha_sdata
, 0},
5499 {"section", s_alpha_section
, 0},
5500 {"section.s", s_alpha_section
, 0},
5501 {"sect", s_alpha_section
, 0},
5502 {"sect.s", s_alpha_section
, 0},
5505 { "pdesc", s_alpha_pdesc
, 0},
5506 { "name", s_alpha_name
, 0},
5507 { "linkage", s_alpha_linkage
, 0},
5508 { "code_address", s_alpha_code_address
, 0},
5509 { "ent", s_alpha_ent
, 0},
5510 { "frame", s_alpha_frame
, 0},
5511 { "fp_save", s_alpha_fp_save
, 0},
5512 { "mask", s_alpha_mask
, 0},
5513 { "fmask", s_alpha_fmask
, 0},
5514 { "end", s_alpha_end
, 0},
5515 { "file", s_alpha_file
, 0},
5516 { "rdata", s_alpha_section
, 1},
5517 { "comm", s_alpha_comm
, 0},
5518 { "link", s_alpha_section
, 3},
5519 { "ctors", s_alpha_section
, 4},
5520 { "dtors", s_alpha_section
, 5},
5523 /* Frame related pseudos. */
5524 {"ent", s_alpha_ent
, 0},
5525 {"end", s_alpha_end
, 0},
5526 {"mask", s_alpha_mask
, 0},
5527 {"fmask", s_alpha_mask
, 1},
5528 {"frame", s_alpha_frame
, 0},
5529 {"prologue", s_alpha_prologue
, 0},
5530 {"file", s_alpha_file
, 5},
5531 {"loc", s_alpha_loc
, 9},
5532 {"stabs", s_alpha_stab
, 's'},
5533 {"stabn", s_alpha_stab
, 'n'},
5534 /* COFF debugging related pseudos. */
5535 {"begin", s_alpha_coff_wrapper
, 0},
5536 {"bend", s_alpha_coff_wrapper
, 1},
5537 {"def", s_alpha_coff_wrapper
, 2},
5538 {"dim", s_alpha_coff_wrapper
, 3},
5539 {"endef", s_alpha_coff_wrapper
, 4},
5540 {"scl", s_alpha_coff_wrapper
, 5},
5541 {"tag", s_alpha_coff_wrapper
, 6},
5542 {"val", s_alpha_coff_wrapper
, 7},
5544 {"prologue", s_ignore
, 0},
5546 {"gprel32", s_alpha_gprel32
, 0},
5547 {"t_floating", s_alpha_float_cons
, 'd'},
5548 {"s_floating", s_alpha_float_cons
, 'f'},
5549 {"f_floating", s_alpha_float_cons
, 'F'},
5550 {"g_floating", s_alpha_float_cons
, 'G'},
5551 {"d_floating", s_alpha_float_cons
, 'D'},
5553 {"proc", s_alpha_proc
, 0},
5554 {"aproc", s_alpha_proc
, 1},
5555 {"set", s_alpha_set
, 0},
5556 {"reguse", s_ignore
, 0},
5557 {"livereg", s_ignore
, 0},
5558 {"base", s_alpha_base
, 0}, /*??*/
5559 {"option", s_ignore
, 0},
5560 {"aent", s_ignore
, 0},
5561 {"ugen", s_ignore
, 0},
5562 {"eflag", s_ignore
, 0},
5564 {"align", s_alpha_align
, 0},
5565 {"double", s_alpha_float_cons
, 'd'},
5566 {"float", s_alpha_float_cons
, 'f'},
5567 {"single", s_alpha_float_cons
, 'f'},
5568 {"ascii", s_alpha_stringer
, 0},
5569 {"asciz", s_alpha_stringer
, 1},
5570 {"string", s_alpha_stringer
, 1},
5571 {"space", s_alpha_space
, 0},
5572 {"skip", s_alpha_space
, 0},
5573 {"zero", s_alpha_space
, 0},
5575 /* Unaligned data pseudos. */
5576 {"uword", s_alpha_ucons
, 2},
5577 {"ulong", s_alpha_ucons
, 4},
5578 {"uquad", s_alpha_ucons
, 8},
5581 /* Dwarf wants these versions of unaligned. */
5582 {"2byte", s_alpha_ucons
, 2},
5583 {"4byte", s_alpha_ucons
, 4},
5584 {"8byte", s_alpha_ucons
, 8},
5587 /* We don't do any optimizing, so we can safely ignore these. */
5588 {"noalias", s_ignore
, 0},
5589 {"alias", s_ignore
, 0},
5591 {"arch", s_alpha_arch
, 0},
5597 /* Build a BFD section with its flags set appropriately for the .lita,
5598 .lit8, or .lit4 sections. */
5601 create_literal_section (name
, secp
, symp
)
5606 segT current_section
= now_seg
;
5607 int current_subsec
= now_subseg
;
5610 *secp
= new_sec
= subseg_new (name
, 0);
5611 subseg_set (current_section
, current_subsec
);
5612 bfd_set_section_alignment (stdoutput
, new_sec
, 4);
5613 bfd_set_section_flags (stdoutput
, new_sec
,
5614 SEC_RELOC
| SEC_ALLOC
| SEC_LOAD
| SEC_READONLY
5617 S_CLEAR_EXTERNAL (*symp
= section_symbol (new_sec
));
5622 /* @@@ GP selection voodoo. All of this seems overly complicated and
5623 unnecessary; which is the primary reason it's for ECOFF only. */
5632 vma
= bfd_get_section_vma (foo
, sec
);
5633 if (vma
&& vma
< alpha_gp_value
)
5634 alpha_gp_value
= vma
;
5640 assert (alpha_gp_value
== 0);
5642 /* Get minus-one in whatever width... */
5643 alpha_gp_value
= 0; alpha_gp_value
--;
5645 /* Select the smallest VMA of these existing sections. */
5646 maybe_set_gp (alpha_lita_section
);
5648 /* These were disabled before -- should we use them? */
5649 maybe_set_gp (sdata
);
5650 maybe_set_gp (lit8_sec
);
5651 maybe_set_gp (lit4_sec
);
5654 /* @@ Will a simple 0x8000 work here? If not, why not? */
5655 #define GP_ADJUSTMENT (0x8000 - 0x10)
5657 alpha_gp_value
+= GP_ADJUSTMENT
;
5659 S_SET_VALUE (alpha_gp_symbol
, alpha_gp_value
);
5662 printf (_("Chose GP value of %lx\n"), alpha_gp_value
);
5665 #endif /* OBJ_ECOFF */
5667 /* Called internally to handle all alignment needs. This takes care
5668 of eliding calls to frag_align if'n the cached current alignment
5669 says we've already got it, as well as taking care of the auto-align
5670 feature wrt labels. */
5673 alpha_align (n
, pfill
, label
, force
)
5677 int force ATTRIBUTE_UNUSED
;
5679 if (alpha_current_align
>= n
)
5684 if (subseg_text_p (now_seg
))
5685 frag_align_code (n
, 0);
5687 frag_align (n
, 0, 0);
5690 frag_align (n
, *pfill
, 0);
5692 alpha_current_align
= n
;
5694 if (label
!= NULL
&& S_GET_SEGMENT (label
) == now_seg
)
5696 symbol_set_frag (label
, frag_now
);
5697 S_SET_VALUE (label
, (valueT
) frag_now_fix ());
5700 record_alignment (now_seg
, n
);
5702 /* ??? If alpha_flag_relax && force && elf, record the requested alignment
5703 in a reloc for the linker to see. */
5706 /* This is called from HANDLE_ALIGN in write.c. Fill in the contents
5707 of an rs_align_code fragment. */
5710 alpha_handle_align (fragp
)
5713 static char const unop
[4] = { 0x00, 0x00, 0xe0, 0x2f };
5714 static char const nopunop
[8] = {
5715 0x1f, 0x04, 0xff, 0x47,
5716 0x00, 0x00, 0xe0, 0x2f
5722 if (fragp
->fr_type
!= rs_align_code
)
5725 bytes
= fragp
->fr_next
->fr_address
- fragp
->fr_address
- fragp
->fr_fix
;
5726 p
= fragp
->fr_literal
+ fragp
->fr_fix
;
5739 memcpy (p
, unop
, 4);
5745 memcpy (p
, nopunop
, 8);
5747 fragp
->fr_fix
+= fix
;
5751 /* The Alpha has support for some VAX floating point types, as well as for
5752 IEEE floating point. We consider IEEE to be the primary floating point
5753 format, and sneak in the VAX floating point support here. */
5754 #define md_atof vax_md_atof
5755 #include "config/atof-vax.c"