1 /* tc-alpha.c - Processor-specific code for the DEC Alpha AXP CPU.
2 Copyright 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 2001, 2002 Free Software Foundation, Inc.
4 Contributed by Carnegie Mellon University, 1993.
5 Written by Alessandro Forin, based on earlier gas-1.38 target CPU files.
6 Modified by Ken Raeburn for gas-2.x and ECOFF support.
7 Modified by Richard Henderson for ELF support.
8 Modified by Klaus K"ampf for EVAX (OpenVMS/Alpha) support.
10 This file is part of GAS, the GNU Assembler.
12 GAS is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2, or (at your option)
17 GAS is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
22 You should have received a copy of the GNU General Public License
23 along with GAS; see the file COPYING. If not, write to the Free
24 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
28 * Mach Operating System
29 * Copyright (c) 1993 Carnegie Mellon University
30 * All Rights Reserved.
32 * Permission to use, copy, modify and distribute this software and its
33 * documentation is hereby granted, provided that both the copyright
34 * notice and this permission notice appear in all copies of the
35 * software, derivative works or modified versions, and any portions
36 * thereof, and that both notices appear in supporting documentation.
38 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
39 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
40 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
42 * Carnegie Mellon requests users of this software to return to
44 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
45 * School of Computer Science
46 * Carnegie Mellon University
47 * Pittsburgh PA 15213-3890
49 * any improvements or extensions that they make and grant Carnegie the
50 * rights to redistribute these changes.
55 #include "struc-symbol.h"
58 #include "opcode/alpha.h"
61 #include "elf/alpha.h"
62 #include "dwarf2dbg.h"
65 #include "safe-ctype.h"
69 #define TOKENIZE_ERROR -1
70 #define TOKENIZE_ERROR_REPORT -2
72 #define MAX_INSN_FIXUPS 2
73 #define MAX_INSN_ARGS 5
78 bfd_reloc_code_real_type reloc
;
85 struct alpha_fixup fixups
[MAX_INSN_FIXUPS
];
103 void (*emit
) PARAMS ((const expressionS
*, int, const PTR
));
105 enum alpha_macro_arg argsets
[16];
108 /* Extra expression types. */
110 #define O_pregister O_md1 /* O_register, in parentheses */
111 #define O_cpregister O_md2 /* + a leading comma */
113 /* The alpha_reloc_op table below depends on the ordering of these. */
114 #define O_literal O_md3 /* !literal relocation */
115 #define O_lituse_addr O_md4 /* !lituse_addr relocation */
116 #define O_lituse_base O_md5 /* !lituse_base relocation */
117 #define O_lituse_bytoff O_md6 /* !lituse_bytoff relocation */
118 #define O_lituse_jsr O_md7 /* !lituse_jsr relocation */
119 #define O_lituse_tlsgd O_md8 /* !lituse_tlsgd relocation */
120 #define O_lituse_tlsldm O_md9 /* !lituse_tlsldm relocation */
121 #define O_gpdisp O_md10 /* !gpdisp relocation */
122 #define O_gprelhigh O_md11 /* !gprelhigh relocation */
123 #define O_gprellow O_md12 /* !gprellow relocation */
124 #define O_gprel O_md13 /* !gprel relocation */
125 #define O_samegp O_md14 /* !samegp relocation */
126 #define O_tlsgd O_md15 /* !tlsgd relocation */
127 #define O_tlsldm O_md16 /* !tlsldm relocation */
128 #define O_gotdtprel O_md17 /* !gotdtprel relocation */
129 #define O_dtprelhi O_md18 /* !dtprelhi relocation */
130 #define O_dtprello O_md19 /* !dtprello relocation */
131 #define O_dtprel O_md20 /* !dtprel relocation */
132 #define O_gottprel O_md21 /* !gottprel relocation */
133 #define O_tprelhi O_md22 /* !tprelhi relocation */
134 #define O_tprello O_md23 /* !tprello relocation */
135 #define O_tprel O_md24 /* !tprel relocation */
137 #define DUMMY_RELOC_LITUSE_ADDR (BFD_RELOC_UNUSED + 1)
138 #define DUMMY_RELOC_LITUSE_BASE (BFD_RELOC_UNUSED + 2)
139 #define DUMMY_RELOC_LITUSE_BYTOFF (BFD_RELOC_UNUSED + 3)
140 #define DUMMY_RELOC_LITUSE_JSR (BFD_RELOC_UNUSED + 4)
141 #define DUMMY_RELOC_LITUSE_TLSGD (BFD_RELOC_UNUSED + 5)
142 #define DUMMY_RELOC_LITUSE_TLSLDM (BFD_RELOC_UNUSED + 6)
144 #define USER_RELOC_P(R) ((R) >= O_literal && (R) <= O_tprel)
146 /* Macros for extracting the type and number of encoded register tokens. */
148 #define is_ir_num(x) (((x) & 32) == 0)
149 #define is_fpr_num(x) (((x) & 32) != 0)
150 #define regno(x) ((x) & 31)
152 /* Something odd inherited from the old assembler. */
154 #define note_gpreg(R) (alpha_gprmask |= (1 << (R)))
155 #define note_fpreg(R) (alpha_fprmask |= (1 << (R)))
157 /* Predicates for 16- and 32-bit ranges */
158 /* XXX: The non-shift version appears to trigger a compiler bug when
159 cross-assembling from x86 w/ gcc 2.7.2. */
162 #define range_signed_16(x) \
163 (((offsetT) (x) >> 15) == 0 || ((offsetT) (x) >> 15) == -1)
164 #define range_signed_32(x) \
165 (((offsetT) (x) >> 31) == 0 || ((offsetT) (x) >> 31) == -1)
167 #define range_signed_16(x) ((offsetT) (x) >= -(offsetT) 0x8000 && \
168 (offsetT) (x) <= (offsetT) 0x7FFF)
169 #define range_signed_32(x) ((offsetT) (x) >= -(offsetT) 0x80000000 && \
170 (offsetT) (x) <= (offsetT) 0x7FFFFFFF)
173 /* Macros for sign extending from 16- and 32-bits. */
174 /* XXX: The cast macros will work on all the systems that I care about,
175 but really a predicate should be found to use the non-cast forms. */
178 #define sign_extend_16(x) ((short) (x))
179 #define sign_extend_32(x) ((int) (x))
181 #define sign_extend_16(x) ((offsetT) (((x) & 0xFFFF) ^ 0x8000) - 0x8000)
182 #define sign_extend_32(x) ((offsetT) (((x) & 0xFFFFFFFF) \
183 ^ 0x80000000) - 0x80000000)
186 /* Macros to build tokens. */
188 #define set_tok_reg(t, r) (memset (&(t), 0, sizeof (t)), \
189 (t).X_op = O_register, \
190 (t).X_add_number = (r))
191 #define set_tok_preg(t, r) (memset (&(t), 0, sizeof (t)), \
192 (t).X_op = O_pregister, \
193 (t).X_add_number = (r))
194 #define set_tok_cpreg(t, r) (memset (&(t), 0, sizeof (t)), \
195 (t).X_op = O_cpregister, \
196 (t).X_add_number = (r))
197 #define set_tok_freg(t, r) (memset (&(t), 0, sizeof (t)), \
198 (t).X_op = O_register, \
199 (t).X_add_number = (r) + 32)
200 #define set_tok_sym(t, s, a) (memset (&(t), 0, sizeof (t)), \
201 (t).X_op = O_symbol, \
202 (t).X_add_symbol = (s), \
203 (t).X_add_number = (a))
204 #define set_tok_const(t, n) (memset (&(t), 0, sizeof (t)), \
205 (t).X_op = O_constant, \
206 (t).X_add_number = (n))
208 /* Prototypes for all local functions. */
210 static struct alpha_reloc_tag
*get_alpha_reloc_tag
PARAMS ((long));
211 static void alpha_adjust_symtab_relocs
PARAMS ((bfd
*, asection
*, PTR
));
213 static int tokenize_arguments
PARAMS ((char *, expressionS
*, int));
214 static const struct alpha_opcode
*find_opcode_match
215 PARAMS ((const struct alpha_opcode
*, const expressionS
*, int *, int *));
216 static const struct alpha_macro
*find_macro_match
217 PARAMS ((const struct alpha_macro
*, const expressionS
*, int *));
218 static unsigned insert_operand
219 PARAMS ((unsigned, const struct alpha_operand
*, offsetT
, char *, unsigned));
220 static void assemble_insn
221 PARAMS ((const struct alpha_opcode
*, const expressionS
*, int,
222 struct alpha_insn
*, bfd_reloc_code_real_type
));
223 static void emit_insn
PARAMS ((struct alpha_insn
*));
224 static void assemble_tokens_to_insn
225 PARAMS ((const char *, const expressionS
*, int, struct alpha_insn
*));
226 static void assemble_tokens
227 PARAMS ((const char *, const expressionS
*, int, int));
229 static long load_expression
230 PARAMS ((int, const expressionS
*, int *, expressionS
*));
232 static void emit_ldgp
PARAMS ((const expressionS
*, int, const PTR
));
233 static void emit_division
PARAMS ((const expressionS
*, int, const PTR
));
234 static void emit_lda
PARAMS ((const expressionS
*, int, const PTR
));
235 static void emit_ldah
PARAMS ((const expressionS
*, int, const PTR
));
236 static void emit_ir_load
PARAMS ((const expressionS
*, int, const PTR
));
237 static void emit_loadstore
PARAMS ((const expressionS
*, int, const PTR
));
238 static void emit_jsrjmp
PARAMS ((const expressionS
*, int, const PTR
));
239 static void emit_ldX
PARAMS ((const expressionS
*, int, const PTR
));
240 static void emit_ldXu
PARAMS ((const expressionS
*, int, const PTR
));
241 static void emit_uldX
PARAMS ((const expressionS
*, int, const PTR
));
242 static void emit_uldXu
PARAMS ((const expressionS
*, int, const PTR
));
243 static void emit_ldil
PARAMS ((const expressionS
*, int, const PTR
));
244 static void emit_stX
PARAMS ((const expressionS
*, int, const PTR
));
245 static void emit_ustX
PARAMS ((const expressionS
*, int, const PTR
));
246 static void emit_sextX
PARAMS ((const expressionS
*, int, const PTR
));
247 static void emit_retjcr
PARAMS ((const expressionS
*, int, const PTR
));
249 static void s_alpha_text
PARAMS ((int));
250 static void s_alpha_data
PARAMS ((int));
252 static void s_alpha_comm
PARAMS ((int));
253 static void s_alpha_rdata
PARAMS ((int));
256 static void s_alpha_sdata
PARAMS ((int));
259 static void s_alpha_section
PARAMS ((int));
260 static void s_alpha_ent
PARAMS ((int));
261 static void s_alpha_end
PARAMS ((int));
262 static void s_alpha_mask
PARAMS ((int));
263 static void s_alpha_frame
PARAMS ((int));
264 static void s_alpha_prologue
PARAMS ((int));
265 static void s_alpha_file
PARAMS ((int));
266 static void s_alpha_loc
PARAMS ((int));
267 static void s_alpha_stab
PARAMS ((int));
268 static void s_alpha_coff_wrapper
PARAMS ((int));
271 static void s_alpha_section
PARAMS ((int));
273 static void s_alpha_gprel32
PARAMS ((int));
274 static void s_alpha_float_cons
PARAMS ((int));
275 static void s_alpha_proc
PARAMS ((int));
276 static void s_alpha_set
PARAMS ((int));
277 static void s_alpha_base
PARAMS ((int));
278 static void s_alpha_align
PARAMS ((int));
279 static void s_alpha_stringer
PARAMS ((int));
280 static void s_alpha_space
PARAMS ((int));
281 static void s_alpha_ucons
PARAMS ((int));
282 static void s_alpha_arch
PARAMS ((int));
284 static void create_literal_section
PARAMS ((const char *, segT
*, symbolS
**));
286 static void select_gp_value
PARAMS ((void));
288 static void alpha_align
PARAMS ((int, char *, symbolS
*, int));
290 /* Generic assembler global variables which must be defined by all
293 /* Characters which always start a comment. */
294 const char comment_chars
[] = "#";
296 /* Characters which start a comment at the beginning of a line. */
297 const char line_comment_chars
[] = "#";
299 /* Characters which may be used to separate multiple commands on a
301 const char line_separator_chars
[] = ";";
303 /* Characters which are used to indicate an exponent in a floating
305 const char EXP_CHARS
[] = "eE";
307 /* Characters which mean that a number is a floating point constant,
310 const char FLT_CHARS
[] = "dD";
312 /* XXX: Do all of these really get used on the alpha?? */
313 char FLT_CHARS
[] = "rRsSfFdDxXpP";
317 const char *md_shortopts
= "Fm:g+1h:HG:";
319 const char *md_shortopts
= "Fm:gG:";
322 struct option md_longopts
[] =
324 #define OPTION_32ADDR (OPTION_MD_BASE)
325 { "32addr", no_argument
, NULL
, OPTION_32ADDR
},
326 #define OPTION_RELAX (OPTION_32ADDR + 1)
327 { "relax", no_argument
, NULL
, OPTION_RELAX
},
329 #define OPTION_MDEBUG (OPTION_RELAX + 1)
330 #define OPTION_NO_MDEBUG (OPTION_MDEBUG + 1)
331 { "mdebug", no_argument
, NULL
, OPTION_MDEBUG
},
332 { "no-mdebug", no_argument
, NULL
, OPTION_NO_MDEBUG
},
334 { NULL
, no_argument
, NULL
, 0 }
337 size_t md_longopts_size
= sizeof (md_longopts
);
341 #define AXP_REG_R16 16
342 #define AXP_REG_R17 17
344 #define AXP_REG_T9 22
346 #define AXP_REG_T10 23
348 #define AXP_REG_T11 24
350 #define AXP_REG_T12 25
351 #define AXP_REG_AI 25
353 #define AXP_REG_FP 29
356 #define AXP_REG_GP AXP_REG_PV
357 #endif /* OBJ_EVAX */
359 /* The cpu for which we are generating code. */
360 static unsigned alpha_target
= AXP_OPCODE_BASE
;
361 static const char *alpha_target_name
= "<all>";
363 /* The hash table of instruction opcodes. */
364 static struct hash_control
*alpha_opcode_hash
;
366 /* The hash table of macro opcodes. */
367 static struct hash_control
*alpha_macro_hash
;
370 /* The $gp relocation symbol. */
371 static symbolS
*alpha_gp_symbol
;
373 /* XXX: what is this, and why is it exported? */
374 valueT alpha_gp_value
;
377 /* The current $gp register. */
378 static int alpha_gp_register
= AXP_REG_GP
;
380 /* A table of the register symbols. */
381 static symbolS
*alpha_register_table
[64];
383 /* Constant sections, or sections of constants. */
385 static segT alpha_lita_section
;
388 static segT alpha_link_section
;
389 static segT alpha_ctors_section
;
390 static segT alpha_dtors_section
;
392 static segT alpha_lit8_section
;
394 /* Symbols referring to said sections. */
396 static symbolS
*alpha_lita_symbol
;
399 static symbolS
*alpha_link_symbol
;
400 static symbolS
*alpha_ctors_symbol
;
401 static symbolS
*alpha_dtors_symbol
;
403 static symbolS
*alpha_lit8_symbol
;
405 /* Literal for .litX+0x8000 within .lita. */
407 static offsetT alpha_lit8_literal
;
411 /* The active .ent symbol. */
412 static symbolS
*alpha_cur_ent_sym
;
415 /* Is the assembler not allowed to use $at? */
416 static int alpha_noat_on
= 0;
418 /* Are macros enabled? */
419 static int alpha_macros_on
= 1;
421 /* Are floats disabled? */
422 static int alpha_nofloats_on
= 0;
424 /* Are addresses 32 bit? */
425 static int alpha_addr32_on
= 0;
427 /* Symbol labelling the current insn. When the Alpha gas sees
430 and the section happens to not be on an eight byte boundary, it
431 will align both the symbol and the .quad to an eight byte boundary. */
432 static symbolS
*alpha_insn_label
;
434 /* Whether we should automatically align data generation pseudo-ops.
435 .align 0 will turn this off. */
436 static int alpha_auto_align_on
= 1;
438 /* The known current alignment of the current section. */
439 static int alpha_current_align
;
441 /* These are exported to ECOFF code. */
442 unsigned long alpha_gprmask
, alpha_fprmask
;
444 /* Whether the debugging option was seen. */
445 static int alpha_debug
;
448 /* Whether we are emitting an mdebug section. */
449 int alpha_flag_mdebug
= -1;
452 /* Don't fully resolve relocations, allowing code movement in the linker. */
453 static int alpha_flag_relax
;
455 /* What value to give to bfd_set_gp_size. */
456 static int g_switch_value
= 8;
459 /* Collect information about current procedure here. */
461 symbolS
*symbol
; /* proc pdesc symbol */
463 int framereg
; /* register for frame pointer */
464 int framesize
; /* size of frame */
474 static int alpha_flag_hash_long_names
= 0; /* -+ */
475 static int alpha_flag_show_after_trunc
= 0; /* -H */
477 /* If the -+ switch is given, then a hash is appended to any name that is
478 longer than 64 characters, else longer symbol names are truncated. */
483 /* A table to map the spelling of a relocation operand into an appropriate
484 bfd_reloc_code_real_type type. The table is assumed to be ordered such
485 that op-O_literal indexes into it. */
487 #define ALPHA_RELOC_TABLE(op) \
488 (&alpha_reloc_op[ ((!USER_RELOC_P (op)) \
490 : (int) (op) - (int) O_literal) ])
492 #define DEF(NAME, RELOC, REQ, ALLOW) \
493 { #NAME, sizeof(#NAME)-1, O_##NAME, RELOC, REQ, ALLOW}
495 static const struct alpha_reloc_op_tag
497 const char *name
; /* string to lookup */
498 size_t length
; /* size of the string */
499 operatorT op
; /* which operator to use */
500 bfd_reloc_code_real_type reloc
; /* relocation before frob */
501 unsigned int require_seq
: 1; /* require a sequence number */
502 unsigned int allow_seq
: 1; /* allow a sequence number */
506 DEF(literal
, BFD_RELOC_ALPHA_ELF_LITERAL
, 0, 1),
507 DEF(lituse_addr
, DUMMY_RELOC_LITUSE_ADDR
, 1, 1),
508 DEF(lituse_base
, DUMMY_RELOC_LITUSE_BASE
, 1, 1),
509 DEF(lituse_bytoff
, DUMMY_RELOC_LITUSE_BYTOFF
, 1, 1),
510 DEF(lituse_jsr
, DUMMY_RELOC_LITUSE_JSR
, 1, 1),
511 DEF(lituse_tlsgd
, DUMMY_RELOC_LITUSE_TLSGD
, 1, 1),
512 DEF(lituse_tlsldm
, DUMMY_RELOC_LITUSE_TLSLDM
, 1, 1),
513 DEF(gpdisp
, BFD_RELOC_ALPHA_GPDISP
, 1, 1),
514 DEF(gprelhigh
, BFD_RELOC_ALPHA_GPREL_HI16
, 0, 0),
515 DEF(gprellow
, BFD_RELOC_ALPHA_GPREL_LO16
, 0, 0),
516 DEF(gprel
, BFD_RELOC_GPREL16
, 0, 0),
517 DEF(samegp
, BFD_RELOC_ALPHA_BRSGP
, 0, 0),
518 DEF(tlsgd
, BFD_RELOC_ALPHA_TLSGD
, 0, 1),
519 DEF(tlsldm
, BFD_RELOC_ALPHA_TLSLDM
, 0, 1),
520 DEF(gotdtprel
, BFD_RELOC_ALPHA_GOTDTPREL16
, 0, 0),
521 DEF(dtprelhi
, BFD_RELOC_ALPHA_DTPREL_HI16
, 0, 0),
522 DEF(dtprello
, BFD_RELOC_ALPHA_DTPREL_LO16
, 0, 0),
523 DEF(dtprel
, BFD_RELOC_ALPHA_DTPREL16
, 0, 0),
524 DEF(gottprel
, BFD_RELOC_ALPHA_GOTTPREL16
, 0, 0),
525 DEF(tprelhi
, BFD_RELOC_ALPHA_TPREL_HI16
, 0, 0),
526 DEF(tprello
, BFD_RELOC_ALPHA_TPREL_LO16
, 0, 0),
527 DEF(tprel
, BFD_RELOC_ALPHA_TPREL16
, 0, 0),
532 static const int alpha_num_reloc_op
533 = sizeof (alpha_reloc_op
) / sizeof (*alpha_reloc_op
);
534 #endif /* RELOC_OP_P */
536 /* Maximum # digits needed to hold the largest sequence # */
537 #define ALPHA_RELOC_DIGITS 25
539 /* Structure to hold explict sequence information. */
540 struct alpha_reloc_tag
542 fixS
*master
; /* the literal reloc */
543 fixS
*slaves
; /* head of linked list of lituses */
544 segT segment
; /* segment relocs are in or undefined_section*/
545 long sequence
; /* sequence # */
546 unsigned n_master
; /* # of literals */
547 unsigned n_slaves
; /* # of lituses */
548 unsigned saw_tlsgd
: 1; /* true if ... */
549 unsigned saw_tlsldm
: 1;
550 unsigned saw_lu_tlsgd
: 1;
551 unsigned saw_lu_tlsldm
: 1;
552 unsigned multi_section_p
: 1; /* true if more than one section was used */
553 char string
[1]; /* printable form of sequence to hash with */
556 /* Hash table to link up literals with the appropriate lituse */
557 static struct hash_control
*alpha_literal_hash
;
559 /* Sequence numbers for internal use by macros. */
560 static long next_sequence_num
= -1;
562 /* A table of CPU names and opcode sets. */
564 static const struct cpu_type
571 /* Ad hoc convention: cpu number gets palcode, process code doesn't.
572 This supports usage under DU 4.0b that does ".arch ev4", and
573 usage in MILO that does -m21064. Probably something more
574 specific like -m21064-pal should be used, but oh well. */
576 { "21064", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
577 { "21064a", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
578 { "21066", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
579 { "21068", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
580 { "21164", AXP_OPCODE_BASE
|AXP_OPCODE_EV5
},
581 { "21164a", AXP_OPCODE_BASE
|AXP_OPCODE_EV5
|AXP_OPCODE_BWX
},
582 { "21164pc", (AXP_OPCODE_BASE
|AXP_OPCODE_EV5
|AXP_OPCODE_BWX
584 { "21264", (AXP_OPCODE_BASE
|AXP_OPCODE_EV6
|AXP_OPCODE_BWX
585 |AXP_OPCODE_MAX
|AXP_OPCODE_CIX
) },
586 { "21264a", (AXP_OPCODE_BASE
|AXP_OPCODE_EV6
|AXP_OPCODE_BWX
587 |AXP_OPCODE_MAX
|AXP_OPCODE_CIX
) },
588 { "21264b", (AXP_OPCODE_BASE
|AXP_OPCODE_EV6
|AXP_OPCODE_BWX
589 |AXP_OPCODE_MAX
|AXP_OPCODE_CIX
) },
591 { "ev4", AXP_OPCODE_BASE
},
592 { "ev45", AXP_OPCODE_BASE
},
593 { "lca45", AXP_OPCODE_BASE
},
594 { "ev5", AXP_OPCODE_BASE
},
595 { "ev56", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
},
596 { "pca56", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
|AXP_OPCODE_MAX
},
597 { "ev6", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
|AXP_OPCODE_MAX
|AXP_OPCODE_CIX
},
598 { "ev67", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
|AXP_OPCODE_MAX
|AXP_OPCODE_CIX
},
599 { "ev68", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
|AXP_OPCODE_MAX
|AXP_OPCODE_CIX
},
601 { "all", AXP_OPCODE_BASE
},
605 /* The macro table */
607 static const struct alpha_macro alpha_macros
[] =
609 /* Load/Store macros */
610 { "lda", emit_lda
, NULL
,
611 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
612 { "ldah", emit_ldah
, NULL
,
613 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
615 { "ldl", emit_ir_load
, "ldl",
616 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
617 { "ldl_l", emit_ir_load
, "ldl_l",
618 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
619 { "ldq", emit_ir_load
, "ldq",
620 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
621 { "ldq_l", emit_ir_load
, "ldq_l",
622 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
623 { "ldq_u", emit_ir_load
, "ldq_u",
624 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
625 { "ldf", emit_loadstore
, "ldf",
626 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
627 { "ldg", emit_loadstore
, "ldg",
628 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
629 { "lds", emit_loadstore
, "lds",
630 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
631 { "ldt", emit_loadstore
, "ldt",
632 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
634 { "ldb", emit_ldX
, (PTR
) 0,
635 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
636 { "ldbu", emit_ldXu
, (PTR
) 0,
637 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
638 { "ldw", emit_ldX
, (PTR
) 1,
639 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
640 { "ldwu", emit_ldXu
, (PTR
) 1,
641 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
643 { "uldw", emit_uldX
, (PTR
) 1,
644 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
645 { "uldwu", emit_uldXu
, (PTR
) 1,
646 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
647 { "uldl", emit_uldX
, (PTR
) 2,
648 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
649 { "uldlu", emit_uldXu
, (PTR
) 2,
650 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
651 { "uldq", emit_uldXu
, (PTR
) 3,
652 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
654 { "ldgp", emit_ldgp
, NULL
,
655 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
} },
657 { "ldi", emit_lda
, NULL
,
658 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
659 { "ldil", emit_ldil
, NULL
,
660 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
661 { "ldiq", emit_lda
, NULL
,
662 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
664 { "ldif" emit_ldiq
, NULL
,
665 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
666 { "ldid" emit_ldiq
, NULL
,
667 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
668 { "ldig" emit_ldiq
, NULL
,
669 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
670 { "ldis" emit_ldiq
, NULL
,
671 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
672 { "ldit" emit_ldiq
, NULL
,
673 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
676 { "stl", emit_loadstore
, "stl",
677 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
678 { "stl_c", emit_loadstore
, "stl_c",
679 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
680 { "stq", emit_loadstore
, "stq",
681 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
682 { "stq_c", emit_loadstore
, "stq_c",
683 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
684 { "stq_u", emit_loadstore
, "stq_u",
685 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
686 { "stf", emit_loadstore
, "stf",
687 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
688 { "stg", emit_loadstore
, "stg",
689 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
690 { "sts", emit_loadstore
, "sts",
691 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
692 { "stt", emit_loadstore
, "stt",
693 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
695 { "stb", emit_stX
, (PTR
) 0,
696 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
697 { "stw", emit_stX
, (PTR
) 1,
698 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
699 { "ustw", emit_ustX
, (PTR
) 1,
700 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
701 { "ustl", emit_ustX
, (PTR
) 2,
702 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
703 { "ustq", emit_ustX
, (PTR
) 3,
704 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
706 /* Arithmetic macros */
708 { "absl" emit_absl
, 1, { IR
} },
709 { "absl" emit_absl
, 2, { IR
, IR
} },
710 { "absl" emit_absl
, 2, { EXP
, IR
} },
711 { "absq" emit_absq
, 1, { IR
} },
712 { "absq" emit_absq
, 2, { IR
, IR
} },
713 { "absq" emit_absq
, 2, { EXP
, IR
} },
716 { "sextb", emit_sextX
, (PTR
) 0,
717 { MACRO_IR
, MACRO_IR
, MACRO_EOA
,
719 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
720 { "sextw", emit_sextX
, (PTR
) 1,
721 { MACRO_IR
, MACRO_IR
, MACRO_EOA
,
723 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
725 { "divl", emit_division
, "__divl",
726 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
727 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
728 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
729 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
730 { "divlu", emit_division
, "__divlu",
731 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
732 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
733 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
734 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
735 { "divq", emit_division
, "__divq",
736 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
737 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
738 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
739 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
740 { "divqu", emit_division
, "__divqu",
741 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
742 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
743 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
744 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
745 { "reml", emit_division
, "__reml",
746 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
747 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
748 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
749 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
750 { "remlu", emit_division
, "__remlu",
751 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
752 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
753 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
754 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
755 { "remq", emit_division
, "__remq",
756 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
757 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
758 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
759 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
760 { "remqu", emit_division
, "__remqu",
761 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
762 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
763 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
764 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
766 { "jsr", emit_jsrjmp
, "jsr",
767 { MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
768 MACRO_PIR
, MACRO_EOA
,
769 MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
770 MACRO_EXP
, MACRO_EOA
} },
771 { "jmp", emit_jsrjmp
, "jmp",
772 { MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
773 MACRO_PIR
, MACRO_EOA
,
774 MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
775 MACRO_EXP
, MACRO_EOA
} },
776 { "ret", emit_retjcr
, "ret",
777 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
779 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
780 MACRO_PIR
, MACRO_EOA
,
781 MACRO_EXP
, MACRO_EOA
,
783 { "jcr", emit_retjcr
, "jcr",
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 { "jsr_coroutine", 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
,
799 static const unsigned int alpha_num_macros
800 = sizeof (alpha_macros
) / sizeof (*alpha_macros
);
802 /* Public interface functions */
804 /* This function is called once, at assembler startup time. It sets
805 up all the tables, etc. that the MD part of the assembler will
806 need, that can be determined before arguments are parsed. */
813 /* Verify that X_op field is wide enough. */
817 assert (e
.X_op
== O_max
);
820 /* Create the opcode hash table. */
821 alpha_opcode_hash
= hash_new ();
822 for (i
= 0; i
< alpha_num_opcodes
;)
824 const char *name
, *retval
, *slash
;
826 name
= alpha_opcodes
[i
].name
;
827 retval
= hash_insert (alpha_opcode_hash
, name
, (PTR
) &alpha_opcodes
[i
]);
829 as_fatal (_("internal error: can't hash opcode `%s': %s"),
832 /* Some opcodes include modifiers of various sorts with a "/mod"
833 syntax, like the architecture manual suggests. However, for
834 use with gcc at least, we also need access to those same opcodes
837 if ((slash
= strchr (name
, '/')) != NULL
)
839 char *p
= xmalloc (strlen (name
));
840 memcpy (p
, name
, slash
- name
);
841 strcpy (p
+ (slash
- name
), slash
+ 1);
843 (void) hash_insert (alpha_opcode_hash
, p
, (PTR
) &alpha_opcodes
[i
]);
844 /* Ignore failures -- the opcode table does duplicate some
845 variants in different forms, like "hw_stq" and "hw_st/q". */
848 while (++i
< alpha_num_opcodes
849 && (alpha_opcodes
[i
].name
== name
850 || !strcmp (alpha_opcodes
[i
].name
, name
)))
854 /* Create the macro hash table. */
855 alpha_macro_hash
= hash_new ();
856 for (i
= 0; i
< alpha_num_macros
;)
858 const char *name
, *retval
;
860 name
= alpha_macros
[i
].name
;
861 retval
= hash_insert (alpha_macro_hash
, name
, (PTR
) &alpha_macros
[i
]);
863 as_fatal (_("internal error: can't hash macro `%s': %s"),
866 while (++i
< alpha_num_macros
867 && (alpha_macros
[i
].name
== name
868 || !strcmp (alpha_macros
[i
].name
, name
)))
872 /* Construct symbols for each of the registers. */
873 for (i
= 0; i
< 32; ++i
)
877 sprintf (name
, "$%d", i
);
878 alpha_register_table
[i
] = symbol_create (name
, reg_section
, i
,
885 sprintf (name
, "$f%d", i
- 32);
886 alpha_register_table
[i
] = symbol_create (name
, reg_section
, i
,
890 /* Create the special symbols and sections we'll be using. */
892 /* So .sbss will get used for tiny objects. */
893 bfd_set_gp_size (stdoutput
, g_switch_value
);
896 create_literal_section (".lita", &alpha_lita_section
, &alpha_lita_symbol
);
898 /* For handling the GP, create a symbol that won't be output in the
899 symbol table. We'll edit it out of relocs later. */
900 alpha_gp_symbol
= symbol_create ("<GP value>", alpha_lita_section
, 0x8000,
905 create_literal_section (".link", &alpha_link_section
, &alpha_link_symbol
);
911 segT sec
= subseg_new (".mdebug", (subsegT
) 0);
912 bfd_set_section_flags (stdoutput
, sec
, SEC_HAS_CONTENTS
| SEC_READONLY
);
913 bfd_set_section_alignment (stdoutput
, sec
, 3);
917 /* Create literal lookup hash table. */
918 alpha_literal_hash
= hash_new ();
920 subseg_set (text_section
, 0);
923 /* The public interface to the instruction assembler. */
929 char opname
[32]; /* Current maximum is 13. */
930 expressionS tok
[MAX_INSN_ARGS
];
934 /* Split off the opcode. */
935 opnamelen
= strspn (str
, "abcdefghijklmnopqrstuvwxyz_/46819");
936 trunclen
= (opnamelen
< sizeof (opname
) - 1
938 : sizeof (opname
) - 1);
939 memcpy (opname
, str
, trunclen
);
940 opname
[trunclen
] = '\0';
942 /* Tokenize the rest of the line. */
943 if ((ntok
= tokenize_arguments (str
+ opnamelen
, tok
, MAX_INSN_ARGS
)) < 0)
945 if (ntok
!= TOKENIZE_ERROR_REPORT
)
946 as_bad (_("syntax error"));
952 assemble_tokens (opname
, tok
, ntok
, alpha_macros_on
);
955 /* Round up a section's size to the appropriate boundary. */
958 md_section_align (seg
, size
)
962 int align
= bfd_get_section_alignment (stdoutput
, seg
);
963 valueT mask
= ((valueT
) 1 << align
) - 1;
965 return (size
+ mask
) & ~mask
;
968 /* Turn a string in input_line_pointer into a floating point constant
969 of type TYPE, and store the appropriate bytes in *LITP. The number
970 of LITTLENUMS emitted is stored in *SIZEP. An error message is
971 returned, or NULL on OK. */
973 /* Equal to MAX_PRECISION in atof-ieee.c. */
974 #define MAX_LITTLENUMS 6
976 extern char *vax_md_atof
PARAMS ((int, char *, int *));
979 md_atof (type
, litP
, sizeP
)
985 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
986 LITTLENUM_TYPE
*wordP
;
993 /* VAX md_atof doesn't like "G" for some reason. */
997 return vax_md_atof (type
, litP
, sizeP
);
1020 return _("Bad call to MD_ATOF()");
1022 t
= atof_ieee (input_line_pointer
, type
, words
);
1024 input_line_pointer
= t
;
1025 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
1027 for (wordP
= words
+ prec
- 1; prec
--;)
1029 md_number_to_chars (litP
, (long) (*wordP
--), sizeof (LITTLENUM_TYPE
));
1030 litP
+= sizeof (LITTLENUM_TYPE
);
1036 /* Take care of the target-specific command-line options. */
1039 md_parse_option (c
, arg
)
1046 alpha_nofloats_on
= 1;
1050 alpha_addr32_on
= 1;
1058 g_switch_value
= atoi (arg
);
1063 const struct cpu_type
*p
;
1064 for (p
= cpu_types
; p
->name
; ++p
)
1065 if (strcmp (arg
, p
->name
) == 0)
1067 alpha_target_name
= p
->name
, alpha_target
= p
->flags
;
1070 as_warn (_("Unknown CPU identifier `%s'"), arg
);
1076 case '+': /* For g++. Hash any name > 63 chars long. */
1077 alpha_flag_hash_long_names
= 1;
1080 case 'H': /* Show new symbol after hash truncation */
1081 alpha_flag_show_after_trunc
= 1;
1084 case 'h': /* for gnu-c/vax compatibility. */
1089 alpha_flag_relax
= 1;
1094 alpha_flag_mdebug
= 1;
1096 case OPTION_NO_MDEBUG
:
1097 alpha_flag_mdebug
= 0;
1108 /* Print a description of the command-line options that we accept. */
1111 md_show_usage (stream
)
1116 -32addr treat addresses as 32-bit values\n\
1117 -F lack floating point instructions support\n\
1118 -mev4 | -mev45 | -mev5 | -mev56 | -mpca56 | -mev6 | -mev67 | -mev68 | -mall\n\
1119 specify variant of Alpha architecture\n\
1120 -m21064 | -m21066 | -m21164 | -m21164a | -m21164pc | -m21264 | -m21264a | -m21264b\n\
1121 these variants include PALcode opcodes\n"),
1126 -+ hash encode (don't truncate) names longer than 64 characters\n\
1127 -H show new symbol after hash truncation\n"),
1132 /* Decide from what point a pc-relative relocation is relative to,
1133 relative to the pc-relative fixup. Er, relatively speaking. */
1136 md_pcrel_from (fixP
)
1139 valueT addr
= fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
1140 switch (fixP
->fx_r_type
)
1142 case BFD_RELOC_ALPHA_GPDISP
:
1143 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1144 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1147 return fixP
->fx_size
+ addr
;
1151 /* Attempt to simplify or even eliminate a fixup. The return value is
1152 ignored; perhaps it was once meaningful, but now it is historical.
1153 To indicate that a fixup has been eliminated, set fixP->fx_done.
1155 For ELF, here it is that we transform the GPDISP_HI16 reloc we used
1156 internally into the GPDISP reloc used externally. We had to do
1157 this so that we'd have the GPDISP_LO16 reloc as a tag to compute
1158 the distance to the "lda" instruction for setting the addend to
1162 md_apply_fix3 (fixP
, valP
, seg
)
1167 char * const fixpos
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
1168 valueT value
= * valP
;
1169 unsigned image
, size
;
1171 switch (fixP
->fx_r_type
)
1173 /* The GPDISP relocations are processed internally with a symbol
1174 referring to the current function; we need to drop in a value
1175 which, when added to the address of the start of the function,
1176 gives the desired GP. */
1177 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1179 fixS
*next
= fixP
->fx_next
;
1181 /* With user-specified !gpdisp relocations, we can be missing
1182 the matching LO16 reloc. We will have already issued an
1185 fixP
->fx_offset
= (next
->fx_frag
->fr_address
+ next
->fx_where
1186 - fixP
->fx_frag
->fr_address
- fixP
->fx_where
);
1188 value
= (value
- sign_extend_16 (value
)) >> 16;
1191 fixP
->fx_r_type
= BFD_RELOC_ALPHA_GPDISP
;
1195 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1196 value
= sign_extend_16 (value
);
1197 fixP
->fx_offset
= 0;
1203 fixP
->fx_addsy
= section_symbol (seg
);
1204 md_number_to_chars (fixpos
, value
, 2);
1209 fixP
->fx_r_type
= BFD_RELOC_16_PCREL
;
1214 fixP
->fx_r_type
= BFD_RELOC_32_PCREL
;
1219 fixP
->fx_r_type
= BFD_RELOC_64_PCREL
;
1222 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
1224 md_number_to_chars (fixpos
, value
, size
);
1230 case BFD_RELOC_GPREL32
:
1231 assert (fixP
->fx_subsy
== alpha_gp_symbol
);
1233 /* FIXME: inherited this obliviousness of `value' -- why? */
1234 md_number_to_chars (fixpos
, -alpha_gp_value
, 4);
1237 case BFD_RELOC_GPREL32
:
1239 case BFD_RELOC_GPREL16
:
1240 case BFD_RELOC_ALPHA_GPREL_HI16
:
1241 case BFD_RELOC_ALPHA_GPREL_LO16
:
1244 case BFD_RELOC_23_PCREL_S2
:
1245 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
1247 image
= bfd_getl32 (fixpos
);
1248 image
= (image
& ~0x1FFFFF) | ((value
>> 2) & 0x1FFFFF);
1253 case BFD_RELOC_ALPHA_HINT
:
1254 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
1256 image
= bfd_getl32 (fixpos
);
1257 image
= (image
& ~0x3FFF) | ((value
>> 2) & 0x3FFF);
1263 case BFD_RELOC_ALPHA_BRSGP
:
1264 case BFD_RELOC_ALPHA_TLSGD
:
1265 case BFD_RELOC_ALPHA_TLSLDM
:
1266 case BFD_RELOC_ALPHA_GOTDTPREL16
:
1267 case BFD_RELOC_ALPHA_DTPREL_HI16
:
1268 case BFD_RELOC_ALPHA_DTPREL_LO16
:
1269 case BFD_RELOC_ALPHA_DTPREL16
:
1270 case BFD_RELOC_ALPHA_GOTTPREL16
:
1271 case BFD_RELOC_ALPHA_TPREL_HI16
:
1272 case BFD_RELOC_ALPHA_TPREL_LO16
:
1273 case BFD_RELOC_ALPHA_TPREL16
:
1278 case BFD_RELOC_ALPHA_LITERAL
:
1279 md_number_to_chars (fixpos
, value
, 2);
1282 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1283 case BFD_RELOC_ALPHA_LITUSE
:
1284 case BFD_RELOC_ALPHA_LINKAGE
:
1285 case BFD_RELOC_ALPHA_CODEADDR
:
1288 case BFD_RELOC_VTABLE_INHERIT
:
1289 case BFD_RELOC_VTABLE_ENTRY
:
1294 const struct alpha_operand
*operand
;
1296 if ((int) fixP
->fx_r_type
>= 0)
1297 as_fatal (_("unhandled relocation type %s"),
1298 bfd_get_reloc_code_name (fixP
->fx_r_type
));
1300 assert (-(int) fixP
->fx_r_type
< (int) alpha_num_operands
);
1301 operand
= &alpha_operands
[-(int) fixP
->fx_r_type
];
1303 /* The rest of these fixups only exist internally during symbol
1304 resolution and have no representation in the object file.
1305 Therefore they must be completely resolved as constants. */
1307 if (fixP
->fx_addsy
!= 0
1308 && S_GET_SEGMENT (fixP
->fx_addsy
) != absolute_section
)
1309 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
1310 _("non-absolute expression in constant field"));
1312 image
= bfd_getl32 (fixpos
);
1313 image
= insert_operand (image
, operand
, (offsetT
) value
,
1314 fixP
->fx_file
, fixP
->fx_line
);
1319 if (fixP
->fx_addsy
!= 0 || fixP
->fx_pcrel
!= 0)
1323 as_warn_where (fixP
->fx_file
, fixP
->fx_line
,
1324 _("type %d reloc done?\n"), (int) fixP
->fx_r_type
);
1329 md_number_to_chars (fixpos
, image
, 4);
1335 /* Look for a register name in the given symbol. */
1338 md_undefined_symbol (name
)
1343 int is_float
= 0, num
;
1348 if (name
[1] == 'p' && name
[2] == '\0')
1349 return alpha_register_table
[AXP_REG_FP
];
1354 if (!ISDIGIT (*++name
))
1358 case '0': case '1': case '2': case '3': case '4':
1359 case '5': case '6': case '7': case '8': case '9':
1360 if (name
[1] == '\0')
1361 num
= name
[0] - '0';
1362 else if (name
[0] != '0' && ISDIGIT (name
[1]) && name
[2] == '\0')
1364 num
= (name
[0] - '0') * 10 + name
[1] - '0';
1371 if (!alpha_noat_on
&& (num
+ is_float
) == AXP_REG_AT
)
1372 as_warn (_("Used $at without \".set noat\""));
1373 return alpha_register_table
[num
+ is_float
];
1376 if (name
[1] == 't' && name
[2] == '\0')
1379 as_warn (_("Used $at without \".set noat\""));
1380 return alpha_register_table
[AXP_REG_AT
];
1385 if (name
[1] == 'p' && name
[2] == '\0')
1386 return alpha_register_table
[alpha_gp_register
];
1390 if (name
[1] == 'p' && name
[2] == '\0')
1391 return alpha_register_table
[AXP_REG_SP
];
1399 /* @@@ Magic ECOFF bits. */
1402 alpha_frob_ecoff_data ()
1405 /* $zero and $f31 are read-only */
1406 alpha_gprmask
&= ~1;
1407 alpha_fprmask
&= ~1;
1411 /* Hook to remember a recently defined label so that the auto-align
1412 code can adjust the symbol after we know what alignment will be
1416 alpha_define_label (sym
)
1419 alpha_insn_label
= sym
;
1422 /* If we have a BRSGP reloc to a local symbol, adjust it to BRADDR and
1423 let it get resolved at assembly time. */
1427 alpha_validate_fix (f
)
1433 if (f
->fx_r_type
!= BFD_RELOC_ALPHA_BRSGP
)
1436 if (! S_IS_DEFINED (f
->fx_addsy
))
1439 switch (S_GET_OTHER (f
->fx_addsy
) & STO_ALPHA_STD_GPLOAD
)
1441 case STO_ALPHA_NOPV
:
1443 case STO_ALPHA_STD_GPLOAD
:
1447 if (S_IS_LOCAL (f
->fx_addsy
))
1450 name
= S_GET_NAME (f
->fx_addsy
);
1451 as_bad_where (f
->fx_file
, f
->fx_line
,
1452 _("!samegp reloc against symbol without .prologue: %s"),
1457 if (! (S_IS_EXTERN (f
->fx_addsy
) || S_IS_WEAK (f
->fx_addsy
)))
1459 f
->fx_r_type
= BFD_RELOC_23_PCREL_S2
;
1460 f
->fx_offset
+= offset
;
1465 /* Return true if we must always emit a reloc for a type and false if
1466 there is some hope of resolving it at assembly time. */
1469 alpha_force_relocation (f
)
1472 if (alpha_flag_relax
)
1475 switch (f
->fx_r_type
)
1477 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1478 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1479 case BFD_RELOC_ALPHA_GPDISP
:
1480 case BFD_RELOC_ALPHA_LITERAL
:
1481 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1482 case BFD_RELOC_ALPHA_LITUSE
:
1483 case BFD_RELOC_GPREL16
:
1484 case BFD_RELOC_GPREL32
:
1485 case BFD_RELOC_ALPHA_GPREL_HI16
:
1486 case BFD_RELOC_ALPHA_GPREL_LO16
:
1487 case BFD_RELOC_ALPHA_LINKAGE
:
1488 case BFD_RELOC_ALPHA_CODEADDR
:
1489 case BFD_RELOC_ALPHA_BRSGP
:
1490 case BFD_RELOC_VTABLE_INHERIT
:
1491 case BFD_RELOC_VTABLE_ENTRY
:
1492 case BFD_RELOC_ALPHA_TLSGD
:
1493 case BFD_RELOC_ALPHA_TLSLDM
:
1494 case BFD_RELOC_ALPHA_GOTDTPREL16
:
1495 case BFD_RELOC_ALPHA_DTPREL_HI16
:
1496 case BFD_RELOC_ALPHA_DTPREL_LO16
:
1497 case BFD_RELOC_ALPHA_DTPREL16
:
1498 case BFD_RELOC_ALPHA_GOTTPREL16
:
1499 case BFD_RELOC_ALPHA_TPREL_HI16
:
1500 case BFD_RELOC_ALPHA_TPREL_LO16
:
1501 case BFD_RELOC_ALPHA_TPREL16
:
1504 case BFD_RELOC_23_PCREL_S2
:
1507 case BFD_RELOC_ALPHA_HINT
:
1515 /* Return true if we can partially resolve a relocation now. */
1518 alpha_fix_adjustable (f
)
1522 /* Prevent all adjustments to global symbols */
1523 if (S_IS_EXTERN (f
->fx_addsy
) || S_IS_WEAK (f
->fx_addsy
))
1527 /* Are there any relocation types for which we must generate a reloc
1528 but we can adjust the values contained within it? */
1529 switch (f
->fx_r_type
)
1531 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1532 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1533 case BFD_RELOC_ALPHA_GPDISP
:
1534 case BFD_RELOC_ALPHA_BRSGP
:
1537 case BFD_RELOC_ALPHA_LITERAL
:
1538 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1539 case BFD_RELOC_ALPHA_LITUSE
:
1540 case BFD_RELOC_ALPHA_LINKAGE
:
1541 case BFD_RELOC_ALPHA_CODEADDR
:
1544 case BFD_RELOC_VTABLE_ENTRY
:
1545 case BFD_RELOC_VTABLE_INHERIT
:
1548 case BFD_RELOC_GPREL16
:
1549 case BFD_RELOC_GPREL32
:
1550 case BFD_RELOC_ALPHA_GPREL_HI16
:
1551 case BFD_RELOC_ALPHA_GPREL_LO16
:
1552 case BFD_RELOC_23_PCREL_S2
:
1555 case BFD_RELOC_ALPHA_HINT
:
1558 case BFD_RELOC_ALPHA_TLSGD
:
1559 case BFD_RELOC_ALPHA_TLSLDM
:
1560 case BFD_RELOC_ALPHA_GOTDTPREL16
:
1561 case BFD_RELOC_ALPHA_DTPREL_HI16
:
1562 case BFD_RELOC_ALPHA_DTPREL_LO16
:
1563 case BFD_RELOC_ALPHA_DTPREL16
:
1564 case BFD_RELOC_ALPHA_GOTTPREL16
:
1565 case BFD_RELOC_ALPHA_TPREL_HI16
:
1566 case BFD_RELOC_ALPHA_TPREL_LO16
:
1567 case BFD_RELOC_ALPHA_TPREL16
:
1568 /* ??? No idea why we can't return a reference to .tbss+10, but
1569 we're preventing this in the other assemblers. Follow for now. */
1578 /* Generate the BFD reloc to be stuck in the object file from the
1579 fixup used internally in the assembler. */
1582 tc_gen_reloc (sec
, fixp
)
1583 asection
*sec ATTRIBUTE_UNUSED
;
1588 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
1589 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
1590 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
1591 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
1593 /* Make sure none of our internal relocations make it this far.
1594 They'd better have been fully resolved by this point. */
1595 assert ((int) fixp
->fx_r_type
> 0);
1597 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
1598 if (reloc
->howto
== NULL
)
1600 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1601 _("cannot represent `%s' relocation in object file"),
1602 bfd_get_reloc_code_name (fixp
->fx_r_type
));
1606 if (!fixp
->fx_pcrel
!= !reloc
->howto
->pc_relative
)
1608 as_fatal (_("internal error? cannot generate `%s' relocation"),
1609 bfd_get_reloc_code_name (fixp
->fx_r_type
));
1611 assert (!fixp
->fx_pcrel
== !reloc
->howto
->pc_relative
);
1614 if (fixp
->fx_r_type
== BFD_RELOC_ALPHA_LITERAL
)
1616 /* Fake out bfd_perform_relocation. sigh. */
1617 reloc
->addend
= -alpha_gp_value
;
1622 reloc
->addend
= fixp
->fx_offset
;
1624 /* Ohhh, this is ugly. The problem is that if this is a local global
1625 symbol, the relocation will entirely be performed at link time, not
1626 at assembly time. bfd_perform_reloc doesn't know about this sort
1627 of thing, and as a result we need to fake it out here. */
1628 if ((S_IS_EXTERN (fixp
->fx_addsy
) || S_IS_WEAK (fixp
->fx_addsy
)
1629 || (S_GET_SEGMENT (fixp
->fx_addsy
)->flags
& SEC_MERGE
)
1630 || (S_GET_SEGMENT (fixp
->fx_addsy
)->flags
& SEC_THREAD_LOCAL
))
1631 && !S_IS_COMMON (fixp
->fx_addsy
))
1632 reloc
->addend
-= symbol_get_bfdsym (fixp
->fx_addsy
)->value
;
1639 /* Parse a register name off of the input_line and return a register
1640 number. Gets md_undefined_symbol above to do the register name
1643 Only called as a part of processing the ECOFF .frame directive. */
1646 tc_get_register (frame
)
1647 int frame ATTRIBUTE_UNUSED
;
1649 int framereg
= AXP_REG_SP
;
1652 if (*input_line_pointer
== '$')
1654 char *s
= input_line_pointer
;
1655 char c
= get_symbol_end ();
1656 symbolS
*sym
= md_undefined_symbol (s
);
1658 *strchr (s
, '\0') = c
;
1659 if (sym
&& (framereg
= S_GET_VALUE (sym
)) <= 31)
1662 as_warn (_("frame reg expected, using $%d."), framereg
);
1665 note_gpreg (framereg
);
1669 /* This is called before the symbol table is processed. In order to
1670 work with gcc when using mips-tfile, we must keep all local labels.
1671 However, in other cases, we want to discard them. If we were
1672 called with -g, but we didn't see any debugging information, it may
1673 mean that gcc is smuggling debugging information through to
1674 mips-tfile, in which case we must generate all local labels. */
1679 alpha_frob_file_before_adjust ()
1681 if (alpha_debug
!= 0
1682 && ! ecoff_debugging_seen
)
1683 flag_keep_locals
= 1;
1686 #endif /* OBJ_ECOFF */
1688 static struct alpha_reloc_tag
*
1689 get_alpha_reloc_tag (sequence
)
1692 char buffer
[ALPHA_RELOC_DIGITS
];
1693 struct alpha_reloc_tag
*info
;
1695 sprintf (buffer
, "!%ld", sequence
);
1697 info
= (struct alpha_reloc_tag
*) hash_find (alpha_literal_hash
, buffer
);
1700 size_t len
= strlen (buffer
);
1703 info
= (struct alpha_reloc_tag
*)
1704 xcalloc (sizeof (struct alpha_reloc_tag
) + len
, 1);
1706 info
->segment
= now_seg
;
1707 info
->sequence
= sequence
;
1708 strcpy (info
->string
, buffer
);
1709 errmsg
= hash_insert (alpha_literal_hash
, info
->string
, (PTR
) info
);
1717 /* Before the relocations are written, reorder them, so that user
1718 supplied !lituse relocations follow the appropriate !literal
1719 relocations, and similarly for !gpdisp relocations. */
1722 alpha_adjust_symtab ()
1724 if (alpha_literal_hash
)
1725 bfd_map_over_sections (stdoutput
, alpha_adjust_symtab_relocs
, NULL
);
1729 alpha_adjust_symtab_relocs (abfd
, sec
, ptr
)
1730 bfd
*abfd ATTRIBUTE_UNUSED
;
1732 PTR ptr ATTRIBUTE_UNUSED
;
1734 segment_info_type
*seginfo
= seg_info (sec
);
1740 /* If seginfo is NULL, we did not create this section; don't do
1741 anything with it. By using a pointer to a pointer, we can update
1742 the links in place. */
1743 if (seginfo
== NULL
)
1746 /* If there are no relocations, skip the section. */
1747 if (! seginfo
->fix_root
)
1750 /* First rebuild the fixup chain without the expicit lituse and
1751 gpdisp_lo16 relocs. */
1752 prevP
= &seginfo
->fix_root
;
1753 for (fixp
= seginfo
->fix_root
; fixp
; fixp
= next
)
1755 next
= fixp
->fx_next
;
1756 fixp
->fx_next
= (fixS
*) 0;
1758 switch (fixp
->fx_r_type
)
1760 case BFD_RELOC_ALPHA_LITUSE
:
1761 if (fixp
->tc_fix_data
.info
->n_master
== 0)
1762 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1763 _("No !literal!%ld was found"),
1764 fixp
->tc_fix_data
.info
->sequence
);
1766 if (fixp
->fx_offset
== LITUSE_ALPHA_TLSGD
)
1768 if (! fixp
->tc_fix_data
.info
->saw_tlsgd
)
1769 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1770 _("No !tlsgd!%ld was found"),
1771 fixp
->tc_fix_data
.info
->sequence
);
1773 else if (fixp
->fx_offset
== LITUSE_ALPHA_TLSLDM
)
1775 if (! fixp
->tc_fix_data
.info
->saw_tlsldm
)
1776 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1777 _("No !tlsldm!%ld was found"),
1778 fixp
->tc_fix_data
.info
->sequence
);
1783 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1784 if (fixp
->tc_fix_data
.info
->n_master
== 0)
1785 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1786 _("No ldah !gpdisp!%ld was found"),
1787 fixp
->tc_fix_data
.info
->sequence
);
1790 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1791 if (fixp
->tc_fix_data
.info
1792 && (fixp
->tc_fix_data
.info
->saw_tlsgd
1793 || fixp
->tc_fix_data
.info
->saw_tlsldm
))
1799 prevP
= &fixp
->fx_next
;
1804 /* Go back and re-chain dependent relocations. They are currently
1805 linked through the next_reloc field in reverse order, so as we
1806 go through the next_reloc chain, we effectively reverse the chain
1809 Except if there is more than one !literal for a given sequence
1810 number. In that case, the programmer and/or compiler is not sure
1811 how control flows from literal to lituse, and we can't be sure to
1812 get the relaxation correct.
1814 ??? Well, actually we could, if there are enough lituses such that
1815 we can make each literal have at least one of each lituse type
1816 present. Not implemented.
1818 Also suppress the optimization if the !literals/!lituses are spread
1819 in different segments. This can happen with "intersting" uses of
1820 inline assembly; examples are present in the Linux kernel semaphores. */
1822 for (fixp
= seginfo
->fix_root
; fixp
; fixp
= next
)
1824 next
= fixp
->fx_next
;
1825 switch (fixp
->fx_r_type
)
1827 case BFD_RELOC_ALPHA_TLSGD
:
1828 case BFD_RELOC_ALPHA_TLSLDM
:
1829 if (!fixp
->tc_fix_data
.info
)
1831 if (fixp
->tc_fix_data
.info
->n_master
== 0)
1833 else if (fixp
->tc_fix_data
.info
->n_master
> 1)
1835 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1836 _("too many !literal!%ld for %s"),
1837 fixp
->tc_fix_data
.info
->sequence
,
1838 (fixp
->fx_r_type
== BFD_RELOC_ALPHA_TLSGD
1839 ? "!tlsgd" : "!tlsldm"));
1843 fixp
->tc_fix_data
.info
->master
->fx_next
= fixp
->fx_next
;
1844 fixp
->fx_next
= fixp
->tc_fix_data
.info
->master
;
1845 fixp
= fixp
->fx_next
;
1848 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1849 if (fixp
->tc_fix_data
.info
1850 && fixp
->tc_fix_data
.info
->n_master
== 1
1851 && ! fixp
->tc_fix_data
.info
->multi_section_p
)
1853 for (slave
= fixp
->tc_fix_data
.info
->slaves
;
1854 slave
!= (fixS
*) 0;
1855 slave
= slave
->tc_fix_data
.next_reloc
)
1857 slave
->fx_next
= fixp
->fx_next
;
1858 fixp
->fx_next
= slave
;
1863 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1864 if (fixp
->tc_fix_data
.info
->n_slaves
== 0)
1865 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1866 _("No lda !gpdisp!%ld was found"),
1867 fixp
->tc_fix_data
.info
->sequence
);
1870 slave
= fixp
->tc_fix_data
.info
->slaves
;
1871 slave
->fx_next
= next
;
1872 fixp
->fx_next
= slave
;
1884 debug_exp (tok
, ntok
)
1890 fprintf (stderr
, "debug_exp: %d tokens", ntok
);
1891 for (i
= 0; i
< ntok
; i
++)
1893 expressionS
*t
= &tok
[i
];
1898 default: name
= "unknown"; break;
1899 case O_illegal
: name
= "O_illegal"; break;
1900 case O_absent
: name
= "O_absent"; break;
1901 case O_constant
: name
= "O_constant"; break;
1902 case O_symbol
: name
= "O_symbol"; break;
1903 case O_symbol_rva
: name
= "O_symbol_rva"; break;
1904 case O_register
: name
= "O_register"; break;
1905 case O_big
: name
= "O_big"; break;
1906 case O_uminus
: name
= "O_uminus"; break;
1907 case O_bit_not
: name
= "O_bit_not"; break;
1908 case O_logical_not
: name
= "O_logical_not"; break;
1909 case O_multiply
: name
= "O_multiply"; break;
1910 case O_divide
: name
= "O_divide"; break;
1911 case O_modulus
: name
= "O_modulus"; break;
1912 case O_left_shift
: name
= "O_left_shift"; break;
1913 case O_right_shift
: name
= "O_right_shift"; break;
1914 case O_bit_inclusive_or
: name
= "O_bit_inclusive_or"; break;
1915 case O_bit_or_not
: name
= "O_bit_or_not"; break;
1916 case O_bit_exclusive_or
: name
= "O_bit_exclusive_or"; break;
1917 case O_bit_and
: name
= "O_bit_and"; break;
1918 case O_add
: name
= "O_add"; break;
1919 case O_subtract
: name
= "O_subtract"; break;
1920 case O_eq
: name
= "O_eq"; break;
1921 case O_ne
: name
= "O_ne"; break;
1922 case O_lt
: name
= "O_lt"; break;
1923 case O_le
: name
= "O_le"; break;
1924 case O_ge
: name
= "O_ge"; break;
1925 case O_gt
: name
= "O_gt"; break;
1926 case O_logical_and
: name
= "O_logical_and"; break;
1927 case O_logical_or
: name
= "O_logical_or"; break;
1928 case O_index
: name
= "O_index"; break;
1929 case O_pregister
: name
= "O_pregister"; break;
1930 case O_cpregister
: name
= "O_cpregister"; break;
1931 case O_literal
: name
= "O_literal"; break;
1932 case O_lituse_addr
: name
= "O_lituse_addr"; break;
1933 case O_lituse_base
: name
= "O_lituse_base"; break;
1934 case O_lituse_bytoff
: name
= "O_lituse_bytoff"; break;
1935 case O_lituse_jsr
: name
= "O_lituse_jsr"; break;
1936 case O_lituse_tlsgd
: name
= "O_lituse_tlsgd"; break;
1937 case O_lituse_tlsldm
: name
= "O_lituse_tlsldm"; break;
1938 case O_gpdisp
: name
= "O_gpdisp"; break;
1939 case O_gprelhigh
: name
= "O_gprelhigh"; break;
1940 case O_gprellow
: name
= "O_gprellow"; break;
1941 case O_gprel
: name
= "O_gprel"; break;
1942 case O_samegp
: name
= "O_samegp"; break;
1943 case O_tlsgd
: name
= "O_tlsgd"; break;
1944 case O_tlsldm
: name
= "O_tlsldm"; break;
1945 case O_gotdtprel
: name
= "O_gotdtprel"; break;
1946 case O_dtprelhi
: name
= "O_dtprelhi"; break;
1947 case O_dtprello
: name
= "O_dtprello"; break;
1948 case O_dtprel
: name
= "O_dtprel"; break;
1949 case O_gottprel
: name
= "O_gottprel"; break;
1950 case O_tprelhi
: name
= "O_tprelhi"; break;
1951 case O_tprello
: name
= "O_tprello"; break;
1952 case O_tprel
: name
= "O_tprel"; break;
1955 fprintf (stderr
, ", %s(%s, %s, %d)", name
,
1956 (t
->X_add_symbol
) ? S_GET_NAME (t
->X_add_symbol
) : "--",
1957 (t
->X_op_symbol
) ? S_GET_NAME (t
->X_op_symbol
) : "--",
1958 (int) t
->X_add_number
);
1960 fprintf (stderr
, "\n");
1965 /* Parse the arguments to an opcode. */
1968 tokenize_arguments (str
, tok
, ntok
)
1973 expressionS
*end_tok
= tok
+ ntok
;
1974 char *old_input_line_pointer
;
1975 int saw_comma
= 0, saw_arg
= 0;
1977 expressionS
*orig_tok
= tok
;
1981 const struct alpha_reloc_op_tag
*r
;
1984 int reloc_found_p
= 0;
1987 memset (tok
, 0, sizeof (*tok
) * ntok
);
1989 /* Save and restore input_line_pointer around this function. */
1990 old_input_line_pointer
= input_line_pointer
;
1991 input_line_pointer
= str
;
1994 /* ??? Wrest control of ! away from the regular expression parser. */
1995 is_end_of_line
[(unsigned char) '!'] = 1;
1998 while (tok
< end_tok
&& *input_line_pointer
)
2001 switch (*input_line_pointer
)
2008 /* A relocation operand can be placed after the normal operand on an
2009 assembly language statement, and has the following form:
2010 !relocation_type!sequence_number. */
2013 /* Only support one relocation op per insn. */
2014 as_bad (_("More than one relocation op per insn"));
2021 ++input_line_pointer
;
2023 p
= input_line_pointer
;
2024 c
= get_symbol_end ();
2026 /* Parse !relocation_type. */
2027 len
= input_line_pointer
- p
;
2030 as_bad (_("No relocation operand"));
2034 r
= &alpha_reloc_op
[0];
2035 for (i
= alpha_num_reloc_op
- 1; i
>= 0; i
--, r
++)
2036 if (len
== r
->length
&& memcmp (p
, r
->name
, len
) == 0)
2040 as_bad (_("Unknown relocation operand: !%s"), p
);
2044 *input_line_pointer
= c
;
2046 if (*input_line_pointer
!= '!')
2050 as_bad (_("no sequence number after !%s"), p
);
2054 tok
->X_add_number
= 0;
2060 as_bad (_("!%s does not use a sequence number"), p
);
2064 input_line_pointer
++;
2066 /* Parse !sequence_number. */
2068 if (tok
->X_op
!= O_constant
|| tok
->X_add_number
<= 0)
2070 as_bad (_("Bad sequence number: !%s!%s"),
2071 r
->name
, input_line_pointer
);
2080 #endif /* RELOC_OP_P */
2083 ++input_line_pointer
;
2084 if (saw_comma
|| !saw_arg
)
2091 char *hold
= input_line_pointer
++;
2093 /* First try for parenthesized register ... */
2095 if (*input_line_pointer
== ')' && tok
->X_op
== O_register
)
2097 tok
->X_op
= (saw_comma
? O_cpregister
: O_pregister
);
2100 ++input_line_pointer
;
2105 /* ... then fall through to plain expression. */
2106 input_line_pointer
= hold
;
2110 if (saw_arg
&& !saw_comma
)
2114 if (tok
->X_op
== O_illegal
|| tok
->X_op
== O_absent
)
2127 input_line_pointer
= old_input_line_pointer
;
2130 debug_exp (orig_tok
, ntok
- (end_tok
- tok
));
2133 is_end_of_line
[(unsigned char) '!'] = 0;
2136 return ntok
- (end_tok
- tok
);
2140 is_end_of_line
[(unsigned char) '!'] = 0;
2142 input_line_pointer
= old_input_line_pointer
;
2143 return TOKENIZE_ERROR
;
2147 is_end_of_line
[(unsigned char) '!'] = 0;
2149 input_line_pointer
= old_input_line_pointer
;
2150 return TOKENIZE_ERROR_REPORT
;
2153 /* Search forward through all variants of an opcode looking for a
2156 static const struct alpha_opcode
*
2157 find_opcode_match (first_opcode
, tok
, pntok
, pcpumatch
)
2158 const struct alpha_opcode
*first_opcode
;
2159 const expressionS
*tok
;
2163 const struct alpha_opcode
*opcode
= first_opcode
;
2165 int got_cpu_match
= 0;
2169 const unsigned char *opidx
;
2172 /* Don't match opcodes that don't exist on this architecture. */
2173 if (!(opcode
->flags
& alpha_target
))
2178 for (opidx
= opcode
->operands
; *opidx
; ++opidx
)
2180 const struct alpha_operand
*operand
= &alpha_operands
[*opidx
];
2182 /* Only take input from real operands. */
2183 if (operand
->flags
& AXP_OPERAND_FAKE
)
2186 /* When we expect input, make sure we have it. */
2189 if ((operand
->flags
& AXP_OPERAND_OPTIONAL_MASK
) == 0)
2194 /* Match operand type with expression type. */
2195 switch (operand
->flags
& AXP_OPERAND_TYPECHECK_MASK
)
2197 case AXP_OPERAND_IR
:
2198 if (tok
[tokidx
].X_op
!= O_register
2199 || !is_ir_num (tok
[tokidx
].X_add_number
))
2202 case AXP_OPERAND_FPR
:
2203 if (tok
[tokidx
].X_op
!= O_register
2204 || !is_fpr_num (tok
[tokidx
].X_add_number
))
2207 case AXP_OPERAND_IR
| AXP_OPERAND_PARENS
:
2208 if (tok
[tokidx
].X_op
!= O_pregister
2209 || !is_ir_num (tok
[tokidx
].X_add_number
))
2212 case AXP_OPERAND_IR
| AXP_OPERAND_PARENS
| AXP_OPERAND_COMMA
:
2213 if (tok
[tokidx
].X_op
!= O_cpregister
2214 || !is_ir_num (tok
[tokidx
].X_add_number
))
2218 case AXP_OPERAND_RELATIVE
:
2219 case AXP_OPERAND_SIGNED
:
2220 case AXP_OPERAND_UNSIGNED
:
2221 switch (tok
[tokidx
].X_op
)
2236 /* Everything else should have been fake. */
2242 /* Possible match -- did we use all of our input? */
2251 while (++opcode
- alpha_opcodes
< (int) alpha_num_opcodes
2252 && !strcmp (opcode
->name
, first_opcode
->name
));
2255 *pcpumatch
= got_cpu_match
;
2260 /* Search forward through all variants of a macro looking for a syntax
2263 static const struct alpha_macro
*
2264 find_macro_match (first_macro
, tok
, pntok
)
2265 const struct alpha_macro
*first_macro
;
2266 const expressionS
*tok
;
2269 const struct alpha_macro
*macro
= first_macro
;
2274 const enum alpha_macro_arg
*arg
= macro
->argsets
;
2288 /* Index register. */
2290 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_register
2291 || !is_ir_num (tok
[tokidx
].X_add_number
))
2296 /* Parenthesized index register. */
2298 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_pregister
2299 || !is_ir_num (tok
[tokidx
].X_add_number
))
2304 /* Optional parenthesized index register. */
2306 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_pregister
2307 && is_ir_num (tok
[tokidx
].X_add_number
))
2311 /* Leading comma with a parenthesized index register. */
2313 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_cpregister
2314 || !is_ir_num (tok
[tokidx
].X_add_number
))
2319 /* Floating point register. */
2321 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_register
2322 || !is_fpr_num (tok
[tokidx
].X_add_number
))
2327 /* Normal expression. */
2331 switch (tok
[tokidx
].X_op
)
2340 case O_lituse_bytoff
:
2356 while (*arg
!= MACRO_EOA
)
2364 while (++macro
- alpha_macros
< (int) alpha_num_macros
2365 && !strcmp (macro
->name
, first_macro
->name
));
2370 /* Insert an operand value into an instruction. */
2373 insert_operand (insn
, operand
, val
, file
, line
)
2375 const struct alpha_operand
*operand
;
2380 if (operand
->bits
!= 32 && !(operand
->flags
& AXP_OPERAND_NOOVERFLOW
))
2384 if (operand
->flags
& AXP_OPERAND_SIGNED
)
2386 max
= (1 << (operand
->bits
- 1)) - 1;
2387 min
= -(1 << (operand
->bits
- 1));
2391 max
= (1 << operand
->bits
) - 1;
2395 if (val
< min
|| val
> max
)
2398 _("operand out of range (%s not between %d and %d)");
2399 char buf
[sizeof (val
) * 3 + 2];
2401 sprint_value (buf
, val
);
2403 as_warn_where (file
, line
, err
, buf
, min
, max
);
2405 as_warn (err
, buf
, min
, max
);
2409 if (operand
->insert
)
2411 const char *errmsg
= NULL
;
2413 insn
= (*operand
->insert
) (insn
, val
, &errmsg
);
2418 insn
|= ((val
& ((1 << operand
->bits
) - 1)) << operand
->shift
);
2423 /* Turn an opcode description and a set of arguments into
2424 an instruction and a fixup. */
2427 assemble_insn (opcode
, tok
, ntok
, insn
, reloc
)
2428 const struct alpha_opcode
*opcode
;
2429 const expressionS
*tok
;
2431 struct alpha_insn
*insn
;
2432 bfd_reloc_code_real_type reloc
;
2434 const struct alpha_operand
*reloc_operand
= NULL
;
2435 const expressionS
*reloc_exp
= NULL
;
2436 const unsigned char *argidx
;
2440 memset (insn
, 0, sizeof (*insn
));
2441 image
= opcode
->opcode
;
2443 for (argidx
= opcode
->operands
; *argidx
; ++argidx
)
2445 const struct alpha_operand
*operand
= &alpha_operands
[*argidx
];
2446 const expressionS
*t
= (const expressionS
*) 0;
2448 if (operand
->flags
& AXP_OPERAND_FAKE
)
2450 /* fake operands take no value and generate no fixup */
2451 image
= insert_operand (image
, operand
, 0, NULL
, 0);
2457 switch (operand
->flags
& AXP_OPERAND_OPTIONAL_MASK
)
2459 case AXP_OPERAND_DEFAULT_FIRST
:
2462 case AXP_OPERAND_DEFAULT_SECOND
:
2465 case AXP_OPERAND_DEFAULT_ZERO
:
2467 static expressionS zero_exp
;
2469 zero_exp
.X_op
= O_constant
;
2470 zero_exp
.X_unsigned
= 1;
2485 image
= insert_operand (image
, operand
, regno (t
->X_add_number
),
2490 image
= insert_operand (image
, operand
, t
->X_add_number
, NULL
, 0);
2491 assert (reloc_operand
== NULL
);
2492 reloc_operand
= operand
;
2497 /* This is only 0 for fields that should contain registers,
2498 which means this pattern shouldn't have matched. */
2499 if (operand
->default_reloc
== 0)
2502 /* There is one special case for which an insn receives two
2503 relocations, and thus the user-supplied reloc does not
2504 override the operand reloc. */
2505 if (operand
->default_reloc
== BFD_RELOC_ALPHA_HINT
)
2507 struct alpha_fixup
*fixup
;
2509 if (insn
->nfixups
>= MAX_INSN_FIXUPS
)
2510 as_fatal (_("too many fixups"));
2512 fixup
= &insn
->fixups
[insn
->nfixups
++];
2514 fixup
->reloc
= BFD_RELOC_ALPHA_HINT
;
2518 if (reloc
== BFD_RELOC_UNUSED
)
2519 reloc
= operand
->default_reloc
;
2521 assert (reloc_operand
== NULL
);
2522 reloc_operand
= operand
;
2529 if (reloc
!= BFD_RELOC_UNUSED
)
2531 struct alpha_fixup
*fixup
;
2533 if (insn
->nfixups
>= MAX_INSN_FIXUPS
)
2534 as_fatal (_("too many fixups"));
2536 /* ??? My but this is hacky. But the OSF/1 assembler uses the same
2537 relocation tag for both ldah and lda with gpdisp. Choose the
2538 correct internal relocation based on the opcode. */
2539 if (reloc
== BFD_RELOC_ALPHA_GPDISP
)
2541 if (strcmp (opcode
->name
, "ldah") == 0)
2542 reloc
= BFD_RELOC_ALPHA_GPDISP_HI16
;
2543 else if (strcmp (opcode
->name
, "lda") == 0)
2544 reloc
= BFD_RELOC_ALPHA_GPDISP_LO16
;
2546 as_bad (_("invalid relocation for instruction"));
2549 /* If this is a real relocation (as opposed to a lituse hint), then
2550 the relocation width should match the operand width. */
2551 else if (reloc
< BFD_RELOC_UNUSED
)
2553 reloc_howto_type
*reloc_howto
2554 = bfd_reloc_type_lookup (stdoutput
, reloc
);
2555 if (reloc_howto
->bitsize
!= reloc_operand
->bits
)
2557 as_bad (_("invalid relocation for field"));
2562 fixup
= &insn
->fixups
[insn
->nfixups
++];
2564 fixup
->exp
= *reloc_exp
;
2566 fixup
->exp
.X_op
= O_absent
;
2567 fixup
->reloc
= reloc
;
2573 /* Actually output an instruction with its fixup. */
2577 struct alpha_insn
*insn
;
2582 /* Take care of alignment duties. */
2583 if (alpha_auto_align_on
&& alpha_current_align
< 2)
2584 alpha_align (2, (char *) NULL
, alpha_insn_label
, 0);
2585 if (alpha_current_align
> 2)
2586 alpha_current_align
= 2;
2587 alpha_insn_label
= NULL
;
2589 /* Write out the instruction. */
2591 md_number_to_chars (f
, insn
->insn
, 4);
2594 dwarf2_emit_insn (4);
2597 /* Apply the fixups in order. */
2598 for (i
= 0; i
< insn
->nfixups
; ++i
)
2600 const struct alpha_operand
*operand
= (const struct alpha_operand
*) 0;
2601 struct alpha_fixup
*fixup
= &insn
->fixups
[i
];
2602 struct alpha_reloc_tag
*info
= NULL
;
2606 /* Some fixups are only used internally and so have no howto. */
2607 if ((int) fixup
->reloc
< 0)
2609 operand
= &alpha_operands
[-(int) fixup
->reloc
];
2611 pcrel
= ((operand
->flags
& AXP_OPERAND_RELATIVE
) != 0);
2613 else if (fixup
->reloc
> BFD_RELOC_UNUSED
2614 || fixup
->reloc
== BFD_RELOC_ALPHA_GPDISP_HI16
2615 || fixup
->reloc
== BFD_RELOC_ALPHA_GPDISP_LO16
)
2622 reloc_howto_type
*reloc_howto
2623 = bfd_reloc_type_lookup (stdoutput
, fixup
->reloc
);
2624 assert (reloc_howto
);
2626 size
= bfd_get_reloc_size (reloc_howto
);
2627 assert (size
>= 1 && size
<= 4);
2629 pcrel
= reloc_howto
->pc_relative
;
2632 fixP
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, size
,
2633 &fixup
->exp
, pcrel
, fixup
->reloc
);
2635 /* Turn off complaints that the addend is too large for some fixups,
2636 and copy in the sequence number for the explicit relocations. */
2637 switch (fixup
->reloc
)
2639 case BFD_RELOC_ALPHA_HINT
:
2640 case BFD_RELOC_GPREL32
:
2641 case BFD_RELOC_GPREL16
:
2642 case BFD_RELOC_ALPHA_GPREL_HI16
:
2643 case BFD_RELOC_ALPHA_GPREL_LO16
:
2644 case BFD_RELOC_ALPHA_GOTDTPREL16
:
2645 case BFD_RELOC_ALPHA_DTPREL_HI16
:
2646 case BFD_RELOC_ALPHA_DTPREL_LO16
:
2647 case BFD_RELOC_ALPHA_DTPREL16
:
2648 case BFD_RELOC_ALPHA_GOTTPREL16
:
2649 case BFD_RELOC_ALPHA_TPREL_HI16
:
2650 case BFD_RELOC_ALPHA_TPREL_LO16
:
2651 case BFD_RELOC_ALPHA_TPREL16
:
2652 fixP
->fx_no_overflow
= 1;
2655 case BFD_RELOC_ALPHA_GPDISP_HI16
:
2656 fixP
->fx_no_overflow
= 1;
2657 fixP
->fx_addsy
= section_symbol (now_seg
);
2658 fixP
->fx_offset
= 0;
2660 info
= get_alpha_reloc_tag (insn
->sequence
);
2661 if (++info
->n_master
> 1)
2662 as_bad (_("too many ldah insns for !gpdisp!%ld"), insn
->sequence
);
2663 if (info
->segment
!= now_seg
)
2664 as_bad (_("both insns for !gpdisp!%ld must be in the same section"),
2666 fixP
->tc_fix_data
.info
= info
;
2669 case BFD_RELOC_ALPHA_GPDISP_LO16
:
2670 fixP
->fx_no_overflow
= 1;
2672 info
= get_alpha_reloc_tag (insn
->sequence
);
2673 if (++info
->n_slaves
> 1)
2674 as_bad (_("too many lda insns for !gpdisp!%ld"), insn
->sequence
);
2675 if (info
->segment
!= now_seg
)
2676 as_bad (_("both insns for !gpdisp!%ld must be in the same section"),
2678 fixP
->tc_fix_data
.info
= info
;
2679 info
->slaves
= fixP
;
2682 case BFD_RELOC_ALPHA_LITERAL
:
2683 case BFD_RELOC_ALPHA_ELF_LITERAL
:
2684 fixP
->fx_no_overflow
= 1;
2686 if (insn
->sequence
== 0)
2688 info
= get_alpha_reloc_tag (insn
->sequence
);
2689 info
->master
= fixP
;
2691 if (info
->segment
!= now_seg
)
2692 info
->multi_section_p
= 1;
2693 fixP
->tc_fix_data
.info
= info
;
2697 case DUMMY_RELOC_LITUSE_ADDR
:
2698 fixP
->fx_offset
= LITUSE_ALPHA_ADDR
;
2700 case DUMMY_RELOC_LITUSE_BASE
:
2701 fixP
->fx_offset
= LITUSE_ALPHA_BASE
;
2703 case DUMMY_RELOC_LITUSE_BYTOFF
:
2704 fixP
->fx_offset
= LITUSE_ALPHA_BYTOFF
;
2706 case DUMMY_RELOC_LITUSE_JSR
:
2707 fixP
->fx_offset
= LITUSE_ALPHA_JSR
;
2709 case DUMMY_RELOC_LITUSE_TLSGD
:
2710 fixP
->fx_offset
= LITUSE_ALPHA_TLSGD
;
2712 case DUMMY_RELOC_LITUSE_TLSLDM
:
2713 fixP
->fx_offset
= LITUSE_ALPHA_TLSLDM
;
2716 fixP
->fx_addsy
= section_symbol (now_seg
);
2717 fixP
->fx_r_type
= BFD_RELOC_ALPHA_LITUSE
;
2719 info
= get_alpha_reloc_tag (insn
->sequence
);
2720 if (fixup
->reloc
== DUMMY_RELOC_LITUSE_TLSGD
)
2721 info
->saw_lu_tlsgd
= 1;
2722 else if (fixup
->reloc
== DUMMY_RELOC_LITUSE_TLSLDM
)
2723 info
->saw_lu_tlsldm
= 1;
2724 if (++info
->n_slaves
> 1)
2726 if (info
->saw_lu_tlsgd
)
2727 as_bad (_("too many lituse insns for !lituse_tlsgd!%ld"),
2729 else if (info
->saw_lu_tlsldm
)
2730 as_bad (_("too many lituse insns for !lituse_tlsldm!%ld"),
2733 fixP
->tc_fix_data
.info
= info
;
2734 fixP
->tc_fix_data
.next_reloc
= info
->slaves
;
2735 info
->slaves
= fixP
;
2736 if (info
->segment
!= now_seg
)
2737 info
->multi_section_p
= 1;
2740 case BFD_RELOC_ALPHA_TLSGD
:
2741 fixP
->fx_no_overflow
= 1;
2743 if (insn
->sequence
== 0)
2745 info
= get_alpha_reloc_tag (insn
->sequence
);
2746 if (info
->saw_tlsgd
)
2747 as_bad (_("duplicate !tlsgd!%ld"), insn
->sequence
);
2748 else if (info
->saw_tlsldm
)
2749 as_bad (_("sequence number in use for !tlsldm!%ld"),
2752 info
->saw_tlsgd
= 1;
2753 fixP
->tc_fix_data
.info
= info
;
2756 case BFD_RELOC_ALPHA_TLSLDM
:
2757 fixP
->fx_no_overflow
= 1;
2759 if (insn
->sequence
== 0)
2761 info
= get_alpha_reloc_tag (insn
->sequence
);
2762 if (info
->saw_tlsldm
)
2763 as_bad (_("duplicate !tlsldm!%ld"), insn
->sequence
);
2764 else if (info
->saw_tlsgd
)
2765 as_bad (_("sequence number in use for !tlsgd!%ld"),
2768 info
->saw_tlsldm
= 1;
2769 fixP
->tc_fix_data
.info
= info
;
2773 if ((int) fixup
->reloc
< 0)
2775 if (operand
->flags
& AXP_OPERAND_NOOVERFLOW
)
2776 fixP
->fx_no_overflow
= 1;
2783 /* Given an opcode name and a pre-tokenized set of arguments, assemble
2784 the insn, but do not emit it.
2786 Note that this implies no macros allowed, since we can't store more
2787 than one insn in an insn structure. */
2790 assemble_tokens_to_insn (opname
, tok
, ntok
, insn
)
2792 const expressionS
*tok
;
2794 struct alpha_insn
*insn
;
2796 const struct alpha_opcode
*opcode
;
2798 /* search opcodes */
2799 opcode
= (const struct alpha_opcode
*) hash_find (alpha_opcode_hash
, opname
);
2803 opcode
= find_opcode_match (opcode
, tok
, &ntok
, &cpumatch
);
2806 assemble_insn (opcode
, tok
, ntok
, insn
, BFD_RELOC_UNUSED
);
2810 as_bad (_("inappropriate arguments for opcode `%s'"), opname
);
2812 as_bad (_("opcode `%s' not supported for target %s"), opname
,
2816 as_bad (_("unknown opcode `%s'"), opname
);
2819 /* Given an opcode name and a pre-tokenized set of arguments, take the
2820 opcode all the way through emission. */
2823 assemble_tokens (opname
, tok
, ntok
, local_macros_on
)
2825 const expressionS
*tok
;
2827 int local_macros_on
;
2829 int found_something
= 0;
2830 const struct alpha_opcode
*opcode
;
2831 const struct alpha_macro
*macro
;
2833 bfd_reloc_code_real_type reloc
= BFD_RELOC_UNUSED
;
2836 /* If a user-specified relocation is present, this is not a macro. */
2837 if (ntok
&& USER_RELOC_P (tok
[ntok
- 1].X_op
))
2839 reloc
= ALPHA_RELOC_TABLE (tok
[ntok
- 1].X_op
)->reloc
;
2844 if (local_macros_on
)
2846 macro
= ((const struct alpha_macro
*)
2847 hash_find (alpha_macro_hash
, opname
));
2850 found_something
= 1;
2851 macro
= find_macro_match (macro
, tok
, &ntok
);
2854 (*macro
->emit
) (tok
, ntok
, macro
->arg
);
2860 /* Search opcodes. */
2861 opcode
= (const struct alpha_opcode
*) hash_find (alpha_opcode_hash
, opname
);
2864 found_something
= 1;
2865 opcode
= find_opcode_match (opcode
, tok
, &ntok
, &cpumatch
);
2868 struct alpha_insn insn
;
2869 assemble_insn (opcode
, tok
, ntok
, &insn
, reloc
);
2871 /* Copy the sequence number for the reloc from the reloc token. */
2872 if (reloc
!= BFD_RELOC_UNUSED
)
2873 insn
.sequence
= tok
[ntok
].X_add_number
;
2880 if (found_something
)
2883 as_bad (_("inappropriate arguments for opcode `%s'"), opname
);
2885 as_bad (_("opcode `%s' not supported for target %s"), opname
,
2889 as_bad (_("unknown opcode `%s'"), opname
);
2892 /* Some instruction sets indexed by lg(size). */
2893 static const char * const sextX_op
[] = { "sextb", "sextw", "sextl", NULL
};
2894 static const char * const insXl_op
[] = { "insbl", "inswl", "insll", "insql" };
2895 static const char * const insXh_op
[] = { NULL
, "inswh", "inslh", "insqh" };
2896 static const char * const extXl_op
[] = { "extbl", "extwl", "extll", "extql" };
2897 static const char * const extXh_op
[] = { NULL
, "extwh", "extlh", "extqh" };
2898 static const char * const mskXl_op
[] = { "mskbl", "mskwl", "mskll", "mskql" };
2899 static const char * const mskXh_op
[] = { NULL
, "mskwh", "msklh", "mskqh" };
2900 static const char * const stX_op
[] = { "stb", "stw", "stl", "stq" };
2901 static const char * const ldXu_op
[] = { "ldbu", "ldwu", NULL
, NULL
};
2903 /* Implement the ldgp macro. */
2906 emit_ldgp (tok
, ntok
, unused
)
2907 const expressionS
*tok
;
2908 int ntok ATTRIBUTE_UNUSED
;
2909 const PTR unused ATTRIBUTE_UNUSED
;
2914 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
2915 /* from "ldgp r1,n(r2)", generate "ldah r1,X(R2); lda r1,Y(r1)"
2916 with appropriate constants and relocations. */
2917 struct alpha_insn insn
;
2918 expressionS newtok
[3];
2922 if (regno (tok
[2].X_add_number
) == AXP_REG_PV
)
2923 ecoff_set_gp_prolog_size (0);
2927 set_tok_const (newtok
[1], 0);
2930 assemble_tokens_to_insn ("ldah", newtok
, 3, &insn
);
2935 if (addend
.X_op
!= O_constant
)
2936 as_bad (_("can not resolve expression"));
2937 addend
.X_op
= O_symbol
;
2938 addend
.X_add_symbol
= alpha_gp_symbol
;
2942 insn
.fixups
[0].exp
= addend
;
2943 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_GPDISP_HI16
;
2944 insn
.sequence
= next_sequence_num
;
2948 set_tok_preg (newtok
[2], tok
[0].X_add_number
);
2950 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
2953 addend
.X_add_number
+= 4;
2957 insn
.fixups
[0].exp
= addend
;
2958 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_GPDISP_LO16
;
2959 insn
.sequence
= next_sequence_num
--;
2962 #endif /* OBJ_ECOFF || OBJ_ELF */
2967 /* Add symbol+addend to link pool.
2968 Return offset from basesym to entry in link pool.
2970 Add new fixup only if offset isn't 16bit. */
2973 add_to_link_pool (basesym
, sym
, addend
)
2978 segT current_section
= now_seg
;
2979 int current_subsec
= now_subseg
;
2981 bfd_reloc_code_real_type reloc_type
;
2983 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
2986 offset
= - *symbol_get_obj (basesym
);
2988 /* @@ This assumes all entries in a given section will be of the same
2989 size... Probably correct, but unwise to rely on. */
2990 /* This must always be called with the same subsegment. */
2992 if (seginfo
->frchainP
)
2993 for (fixp
= seginfo
->frchainP
->fix_root
;
2994 fixp
!= (fixS
*) NULL
;
2995 fixp
= fixp
->fx_next
, offset
+= 8)
2997 if (fixp
->fx_addsy
== sym
&& fixp
->fx_offset
== addend
)
2999 if (range_signed_16 (offset
))
3006 /* Not found in 16bit signed range. */
3008 subseg_set (alpha_link_section
, 0);
3012 fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, sym
, addend
, 0,
3015 subseg_set (current_section
, current_subsec
);
3016 seginfo
->literal_pool_size
+= 8;
3020 #endif /* OBJ_EVAX */
3022 /* Load a (partial) expression into a target register.
3024 If poffset is not null, after the call it will either contain
3025 O_constant 0, or a 16-bit offset appropriate for any MEM format
3026 instruction. In addition, pbasereg will be modified to point to
3027 the base register to use in that MEM format instruction.
3029 In any case, *pbasereg should contain a base register to add to the
3030 expression. This will normally be either AXP_REG_ZERO or
3031 alpha_gp_register. Symbol addresses will always be loaded via $gp,
3032 so "foo($0)" is interpreted as adding the address of foo to $0;
3033 i.e. "ldq $targ, LIT($gp); addq $targ, $0, $targ". Odd, perhaps,
3034 but this is what OSF/1 does.
3036 If explicit relocations of the form !literal!<number> are allowed,
3037 and used, then explict_reloc with be an expression pointer.
3039 Finally, the return value is nonzero if the calling macro may emit
3040 a LITUSE reloc if otherwise appropriate; the return value is the
3041 sequence number to use. */
3044 load_expression (targreg
, exp
, pbasereg
, poffset
)
3046 const expressionS
*exp
;
3048 expressionS
*poffset
;
3050 long emit_lituse
= 0;
3051 offsetT addend
= exp
->X_add_number
;
3052 int basereg
= *pbasereg
;
3053 struct alpha_insn insn
;
3054 expressionS newtok
[3];
3063 /* Attempt to reduce .lit load by splitting the offset from
3064 its symbol when possible, but don't create a situation in
3066 if (!range_signed_32 (addend
) &&
3067 (alpha_noat_on
|| targreg
== AXP_REG_AT
))
3069 lit
= add_to_literal_pool (exp
->X_add_symbol
, addend
,
3070 alpha_lita_section
, 8);
3075 lit
= add_to_literal_pool (exp
->X_add_symbol
, 0,
3076 alpha_lita_section
, 8);
3080 as_fatal (_("overflow in literal (.lita) table"));
3082 /* emit "ldq r, lit(gp)" */
3084 if (basereg
!= alpha_gp_register
&& targreg
== basereg
)
3087 as_bad (_("macro requires $at register while noat in effect"));
3088 if (targreg
== AXP_REG_AT
)
3089 as_bad (_("macro requires $at while $at in use"));
3091 set_tok_reg (newtok
[0], AXP_REG_AT
);
3094 set_tok_reg (newtok
[0], targreg
);
3095 set_tok_sym (newtok
[1], alpha_lita_symbol
, lit
);
3096 set_tok_preg (newtok
[2], alpha_gp_register
);
3098 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
3100 assert (insn
.nfixups
== 1);
3101 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITERAL
;
3102 insn
.sequence
= emit_lituse
= next_sequence_num
--;
3103 #endif /* OBJ_ECOFF */
3105 /* emit "ldq r, gotoff(gp)" */
3107 if (basereg
!= alpha_gp_register
&& targreg
== basereg
)
3110 as_bad (_("macro requires $at register while noat in effect"));
3111 if (targreg
== AXP_REG_AT
)
3112 as_bad (_("macro requires $at while $at in use"));
3114 set_tok_reg (newtok
[0], AXP_REG_AT
);
3117 set_tok_reg (newtok
[0], targreg
);
3119 /* XXX: Disable this .got minimizing optimization so that we can get
3120 better instruction offset knowledge in the compiler. This happens
3121 very infrequently anyway. */
3123 || (!range_signed_32 (addend
)
3124 && (alpha_noat_on
|| targreg
== AXP_REG_AT
)))
3131 set_tok_sym (newtok
[1], exp
->X_add_symbol
, 0);
3134 set_tok_preg (newtok
[2], alpha_gp_register
);
3136 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
3138 assert (insn
.nfixups
== 1);
3139 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_ELF_LITERAL
;
3140 insn
.sequence
= emit_lituse
= next_sequence_num
--;
3141 #endif /* OBJ_ELF */
3145 /* Find symbol or symbol pointer in link section. */
3147 if (exp
->X_add_symbol
== alpha_evax_proc
.symbol
)
3149 if (range_signed_16 (addend
))
3151 set_tok_reg (newtok
[0], targreg
);
3152 set_tok_const (newtok
[1], addend
);
3153 set_tok_preg (newtok
[2], basereg
);
3154 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
3159 set_tok_reg (newtok
[0], targreg
);
3160 set_tok_const (newtok
[1], 0);
3161 set_tok_preg (newtok
[2], basereg
);
3162 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
3167 if (!range_signed_32 (addend
))
3169 link
= add_to_link_pool (alpha_evax_proc
.symbol
,
3170 exp
->X_add_symbol
, addend
);
3175 link
= add_to_link_pool (alpha_evax_proc
.symbol
,
3176 exp
->X_add_symbol
, 0);
3178 set_tok_reg (newtok
[0], targreg
);
3179 set_tok_const (newtok
[1], link
);
3180 set_tok_preg (newtok
[2], basereg
);
3181 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
3183 #endif /* OBJ_EVAX */
3188 if (basereg
!= alpha_gp_register
&& basereg
!= AXP_REG_ZERO
)
3190 /* emit "addq r, base, r" */
3192 set_tok_reg (newtok
[1], basereg
);
3193 set_tok_reg (newtok
[2], targreg
);
3194 assemble_tokens ("addq", newtok
, 3, 0);
3206 /* Assume that this difference expression will be resolved to an
3207 absolute value and that that value will fit in 16 bits. */
3209 set_tok_reg (newtok
[0], targreg
);
3211 set_tok_preg (newtok
[2], basereg
);
3212 assemble_tokens ("lda", newtok
, 3, 0);
3215 set_tok_const (*poffset
, 0);
3219 if (exp
->X_add_number
> 0)
3220 as_bad (_("bignum invalid; zero assumed"));
3222 as_bad (_("floating point number invalid; zero assumed"));
3227 as_bad (_("can't handle expression"));
3232 if (!range_signed_32 (addend
))
3235 long seq_num
= next_sequence_num
--;
3237 /* For 64-bit addends, just put it in the literal pool. */
3240 /* emit "ldq targreg, lit(basereg)" */
3241 lit
= add_to_link_pool (alpha_evax_proc
.symbol
,
3242 section_symbol (absolute_section
), addend
);
3243 set_tok_reg (newtok
[0], targreg
);
3244 set_tok_const (newtok
[1], lit
);
3245 set_tok_preg (newtok
[2], alpha_gp_register
);
3246 assemble_tokens ("ldq", newtok
, 3, 0);
3249 if (alpha_lit8_section
== NULL
)
3251 create_literal_section (".lit8",
3252 &alpha_lit8_section
,
3253 &alpha_lit8_symbol
);
3256 alpha_lit8_literal
= add_to_literal_pool (alpha_lit8_symbol
, 0x8000,
3257 alpha_lita_section
, 8);
3258 if (alpha_lit8_literal
>= 0x8000)
3259 as_fatal (_("overflow in literal (.lita) table"));
3263 lit
= add_to_literal_pool (NULL
, addend
, alpha_lit8_section
, 8) - 0x8000;
3265 as_fatal (_("overflow in literal (.lit8) table"));
3267 /* emit "lda litreg, .lit8+0x8000" */
3269 if (targreg
== basereg
)
3272 as_bad (_("macro requires $at register while noat in effect"));
3273 if (targreg
== AXP_REG_AT
)
3274 as_bad (_("macro requires $at while $at in use"));
3276 set_tok_reg (newtok
[0], AXP_REG_AT
);
3279 set_tok_reg (newtok
[0], targreg
);
3281 set_tok_sym (newtok
[1], alpha_lita_symbol
, alpha_lit8_literal
);
3284 set_tok_sym (newtok
[1], alpha_lit8_symbol
, 0x8000);
3286 set_tok_preg (newtok
[2], alpha_gp_register
);
3288 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
3290 assert (insn
.nfixups
== 1);
3292 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITERAL
;
3295 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_ELF_LITERAL
;
3297 insn
.sequence
= seq_num
;
3301 /* emit "ldq litreg, lit(litreg)" */
3303 set_tok_const (newtok
[1], lit
);
3304 set_tok_preg (newtok
[2], newtok
[0].X_add_number
);
3306 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
3308 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3309 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BASE
;
3310 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3312 insn
.sequence
= seq_num
;
3317 /* emit "addq litreg, base, target" */
3319 if (basereg
!= AXP_REG_ZERO
)
3321 set_tok_reg (newtok
[1], basereg
);
3322 set_tok_reg (newtok
[2], targreg
);
3323 assemble_tokens ("addq", newtok
, 3, 0);
3325 #endif /* !OBJ_EVAX */
3328 set_tok_const (*poffset
, 0);
3329 *pbasereg
= targreg
;
3333 offsetT low
, high
, extra
, tmp
;
3335 /* for 32-bit operands, break up the addend */
3337 low
= sign_extend_16 (addend
);
3339 high
= sign_extend_16 (tmp
>> 16);
3341 if (tmp
- (high
<< 16))
3345 high
= sign_extend_16 (tmp
>> 16);
3350 set_tok_reg (newtok
[0], targreg
);
3351 set_tok_preg (newtok
[2], basereg
);
3355 /* emit "ldah r, extra(r) */
3356 set_tok_const (newtok
[1], extra
);
3357 assemble_tokens ("ldah", newtok
, 3, 0);
3358 set_tok_preg (newtok
[2], basereg
= targreg
);
3363 /* emit "ldah r, high(r) */
3364 set_tok_const (newtok
[1], high
);
3365 assemble_tokens ("ldah", newtok
, 3, 0);
3367 set_tok_preg (newtok
[2], basereg
);
3370 if ((low
&& !poffset
) || (!poffset
&& basereg
!= targreg
))
3372 /* emit "lda r, low(base)" */
3373 set_tok_const (newtok
[1], low
);
3374 assemble_tokens ("lda", newtok
, 3, 0);
3380 set_tok_const (*poffset
, low
);
3381 *pbasereg
= basereg
;
3387 /* The lda macro differs from the lda instruction in that it handles
3388 most simple expressions, particualrly symbol address loads and
3392 emit_lda (tok
, ntok
, unused
)
3393 const expressionS
*tok
;
3395 const PTR unused ATTRIBUTE_UNUSED
;
3400 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
3402 basereg
= tok
[2].X_add_number
;
3404 (void) load_expression (tok
[0].X_add_number
, &tok
[1], &basereg
, NULL
);
3407 /* The ldah macro differs from the ldah instruction in that it has $31
3408 as an implied base register. */
3411 emit_ldah (tok
, ntok
, unused
)
3412 const expressionS
*tok
;
3413 int ntok ATTRIBUTE_UNUSED
;
3414 const PTR unused ATTRIBUTE_UNUSED
;
3416 expressionS newtok
[3];
3420 set_tok_preg (newtok
[2], AXP_REG_ZERO
);
3422 assemble_tokens ("ldah", newtok
, 3, 0);
3425 /* Handle all "simple" integer register loads -- ldq, ldq_l, ldq_u,
3426 etc. They differ from the real instructions in that they do simple
3427 expressions like the lda macro. */
3430 emit_ir_load (tok
, ntok
, opname
)
3431 const expressionS
*tok
;
3437 expressionS newtok
[3];
3438 struct alpha_insn insn
;
3441 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
3443 basereg
= tok
[2].X_add_number
;
3445 lituse
= load_expression (tok
[0].X_add_number
, &tok
[1], &basereg
,
3449 set_tok_preg (newtok
[2], basereg
);
3451 assemble_tokens_to_insn ((const char *) opname
, newtok
, 3, &insn
);
3455 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3456 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BASE
;
3457 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3459 insn
.sequence
= lituse
;
3465 /* Handle fp register loads, and both integer and fp register stores.
3466 Again, we handle simple expressions. */
3469 emit_loadstore (tok
, ntok
, opname
)
3470 const expressionS
*tok
;
3476 expressionS newtok
[3];
3477 struct alpha_insn insn
;
3480 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
3482 basereg
= tok
[2].X_add_number
;
3484 if (tok
[1].X_op
!= O_constant
|| !range_signed_16 (tok
[1].X_add_number
))
3487 as_bad (_("macro requires $at register while noat in effect"));
3489 lituse
= load_expression (AXP_REG_AT
, &tok
[1], &basereg
, &newtok
[1]);
3498 set_tok_preg (newtok
[2], basereg
);
3500 assemble_tokens_to_insn ((const char *) opname
, newtok
, 3, &insn
);
3504 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3505 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BASE
;
3506 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3508 insn
.sequence
= lituse
;
3514 /* Load a half-word or byte as an unsigned value. */
3517 emit_ldXu (tok
, ntok
, vlgsize
)
3518 const expressionS
*tok
;
3522 if (alpha_target
& AXP_OPCODE_BWX
)
3523 emit_ir_load (tok
, ntok
, ldXu_op
[(long) vlgsize
]);
3526 expressionS newtok
[3];
3527 struct alpha_insn insn
;
3532 as_bad (_("macro requires $at register while noat in effect"));
3535 basereg
= (tok
[1].X_op
== O_constant
3536 ? AXP_REG_ZERO
: alpha_gp_register
);
3538 basereg
= tok
[2].X_add_number
;
3540 /* emit "lda $at, exp" */
3542 lituse
= load_expression (AXP_REG_AT
, &tok
[1], &basereg
, NULL
);
3544 /* emit "ldq_u targ, 0($at)" */
3547 set_tok_const (newtok
[1], 0);
3548 set_tok_preg (newtok
[2], basereg
);
3549 assemble_tokens_to_insn ("ldq_u", newtok
, 3, &insn
);
3553 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3554 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BASE
;
3555 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3557 insn
.sequence
= lituse
;
3562 /* emit "extXl targ, $at, targ" */
3564 set_tok_reg (newtok
[1], basereg
);
3565 newtok
[2] = newtok
[0];
3566 assemble_tokens_to_insn (extXl_op
[(long) vlgsize
], newtok
, 3, &insn
);
3570 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3571 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BYTOFF
;
3572 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3574 insn
.sequence
= lituse
;
3581 /* Load a half-word or byte as a signed value. */
3584 emit_ldX (tok
, ntok
, vlgsize
)
3585 const expressionS
*tok
;
3589 emit_ldXu (tok
, ntok
, vlgsize
);
3590 assemble_tokens (sextX_op
[(long) vlgsize
], tok
, 1, 1);
3593 /* Load an integral value from an unaligned address as an unsigned
3597 emit_uldXu (tok
, ntok
, vlgsize
)
3598 const expressionS
*tok
;
3602 long lgsize
= (long) vlgsize
;
3603 expressionS newtok
[3];
3606 as_bad (_("macro requires $at register while noat in effect"));
3608 /* emit "lda $at, exp" */
3610 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
3611 newtok
[0].X_add_number
= AXP_REG_AT
;
3612 assemble_tokens ("lda", newtok
, ntok
, 1);
3614 /* emit "ldq_u $t9, 0($at)" */
3616 set_tok_reg (newtok
[0], AXP_REG_T9
);
3617 set_tok_const (newtok
[1], 0);
3618 set_tok_preg (newtok
[2], AXP_REG_AT
);
3619 assemble_tokens ("ldq_u", newtok
, 3, 1);
3621 /* emit "ldq_u $t10, size-1($at)" */
3623 set_tok_reg (newtok
[0], AXP_REG_T10
);
3624 set_tok_const (newtok
[1], (1 << lgsize
) - 1);
3625 assemble_tokens ("ldq_u", newtok
, 3, 1);
3627 /* emit "extXl $t9, $at, $t9" */
3629 set_tok_reg (newtok
[0], AXP_REG_T9
);
3630 set_tok_reg (newtok
[1], AXP_REG_AT
);
3631 set_tok_reg (newtok
[2], AXP_REG_T9
);
3632 assemble_tokens (extXl_op
[lgsize
], newtok
, 3, 1);
3634 /* emit "extXh $t10, $at, $t10" */
3636 set_tok_reg (newtok
[0], AXP_REG_T10
);
3637 set_tok_reg (newtok
[2], AXP_REG_T10
);
3638 assemble_tokens (extXh_op
[lgsize
], newtok
, 3, 1);
3640 /* emit "or $t9, $t10, targ" */
3642 set_tok_reg (newtok
[0], AXP_REG_T9
);
3643 set_tok_reg (newtok
[1], AXP_REG_T10
);
3645 assemble_tokens ("or", newtok
, 3, 1);
3648 /* Load an integral value from an unaligned address as a signed value.
3649 Note that quads should get funneled to the unsigned load since we
3650 don't have to do the sign extension. */
3653 emit_uldX (tok
, ntok
, vlgsize
)
3654 const expressionS
*tok
;
3658 emit_uldXu (tok
, ntok
, vlgsize
);
3659 assemble_tokens (sextX_op
[(long) vlgsize
], tok
, 1, 1);
3662 /* Implement the ldil macro. */
3665 emit_ldil (tok
, ntok
, unused
)
3666 const expressionS
*tok
;
3668 const PTR unused ATTRIBUTE_UNUSED
;
3670 expressionS newtok
[2];
3672 memcpy (newtok
, tok
, sizeof (newtok
));
3673 newtok
[1].X_add_number
= sign_extend_32 (tok
[1].X_add_number
);
3675 assemble_tokens ("lda", newtok
, ntok
, 1);
3678 /* Store a half-word or byte. */
3681 emit_stX (tok
, ntok
, vlgsize
)
3682 const expressionS
*tok
;
3686 int lgsize
= (int) (long) vlgsize
;
3688 if (alpha_target
& AXP_OPCODE_BWX
)
3689 emit_loadstore (tok
, ntok
, stX_op
[lgsize
]);
3692 expressionS newtok
[3];
3693 struct alpha_insn insn
;
3698 as_bad (_("macro requires $at register while noat in effect"));
3701 basereg
= (tok
[1].X_op
== O_constant
3702 ? AXP_REG_ZERO
: alpha_gp_register
);
3704 basereg
= tok
[2].X_add_number
;
3706 /* emit "lda $at, exp" */
3708 lituse
= load_expression (AXP_REG_AT
, &tok
[1], &basereg
, NULL
);
3710 /* emit "ldq_u $t9, 0($at)" */
3712 set_tok_reg (newtok
[0], AXP_REG_T9
);
3713 set_tok_const (newtok
[1], 0);
3714 set_tok_preg (newtok
[2], basereg
);
3715 assemble_tokens_to_insn ("ldq_u", newtok
, 3, &insn
);
3719 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3720 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BASE
;
3721 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3723 insn
.sequence
= lituse
;
3728 /* emit "insXl src, $at, $t10" */
3731 set_tok_reg (newtok
[1], basereg
);
3732 set_tok_reg (newtok
[2], AXP_REG_T10
);
3733 assemble_tokens_to_insn (insXl_op
[lgsize
], newtok
, 3, &insn
);
3737 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3738 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BYTOFF
;
3739 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3741 insn
.sequence
= lituse
;
3746 /* emit "mskXl $t9, $at, $t9" */
3748 set_tok_reg (newtok
[0], AXP_REG_T9
);
3749 newtok
[2] = newtok
[0];
3750 assemble_tokens_to_insn (mskXl_op
[lgsize
], newtok
, 3, &insn
);
3754 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3755 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BYTOFF
;
3756 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3758 insn
.sequence
= lituse
;
3763 /* emit "or $t9, $t10, $t9" */
3765 set_tok_reg (newtok
[1], AXP_REG_T10
);
3766 assemble_tokens ("or", newtok
, 3, 1);
3768 /* emit "stq_u $t9, 0($at) */
3770 set_tok_const(newtok
[1], 0);
3771 set_tok_preg (newtok
[2], AXP_REG_AT
);
3772 assemble_tokens_to_insn ("stq_u", newtok
, 3, &insn
);
3776 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3777 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BASE
;
3778 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3780 insn
.sequence
= lituse
;
3787 /* Store an integer to an unaligned address. */
3790 emit_ustX (tok
, ntok
, vlgsize
)
3791 const expressionS
*tok
;
3795 int lgsize
= (int) (long) vlgsize
;
3796 expressionS newtok
[3];
3798 /* emit "lda $at, exp" */
3800 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
3801 newtok
[0].X_add_number
= AXP_REG_AT
;
3802 assemble_tokens ("lda", newtok
, ntok
, 1);
3804 /* emit "ldq_u $9, 0($at)" */
3806 set_tok_reg (newtok
[0], AXP_REG_T9
);
3807 set_tok_const (newtok
[1], 0);
3808 set_tok_preg (newtok
[2], AXP_REG_AT
);
3809 assemble_tokens ("ldq_u", newtok
, 3, 1);
3811 /* emit "ldq_u $10, size-1($at)" */
3813 set_tok_reg (newtok
[0], AXP_REG_T10
);
3814 set_tok_const (newtok
[1], (1 << lgsize
) - 1);
3815 assemble_tokens ("ldq_u", newtok
, 3, 1);
3817 /* emit "insXl src, $at, $t11" */
3820 set_tok_reg (newtok
[1], AXP_REG_AT
);
3821 set_tok_reg (newtok
[2], AXP_REG_T11
);
3822 assemble_tokens (insXl_op
[lgsize
], newtok
, 3, 1);
3824 /* emit "insXh src, $at, $t12" */
3826 set_tok_reg (newtok
[2], AXP_REG_T12
);
3827 assemble_tokens (insXh_op
[lgsize
], newtok
, 3, 1);
3829 /* emit "mskXl $t9, $at, $t9" */
3831 set_tok_reg (newtok
[0], AXP_REG_T9
);
3832 newtok
[2] = newtok
[0];
3833 assemble_tokens (mskXl_op
[lgsize
], newtok
, 3, 1);
3835 /* emit "mskXh $t10, $at, $t10" */
3837 set_tok_reg (newtok
[0], AXP_REG_T10
);
3838 newtok
[2] = newtok
[0];
3839 assemble_tokens (mskXh_op
[lgsize
], newtok
, 3, 1);
3841 /* emit "or $t9, $t11, $t9" */
3843 set_tok_reg (newtok
[0], AXP_REG_T9
);
3844 set_tok_reg (newtok
[1], AXP_REG_T11
);
3845 newtok
[2] = newtok
[0];
3846 assemble_tokens ("or", newtok
, 3, 1);
3848 /* emit "or $t10, $t12, $t10" */
3850 set_tok_reg (newtok
[0], AXP_REG_T10
);
3851 set_tok_reg (newtok
[1], AXP_REG_T12
);
3852 newtok
[2] = newtok
[0];
3853 assemble_tokens ("or", newtok
, 3, 1);
3855 /* emit "stq_u $t9, 0($at)" */
3857 set_tok_reg (newtok
[0], AXP_REG_T9
);
3858 set_tok_const (newtok
[1], 0);
3859 set_tok_preg (newtok
[2], AXP_REG_AT
);
3860 assemble_tokens ("stq_u", newtok
, 3, 1);
3862 /* emit "stq_u $t10, size-1($at)" */
3864 set_tok_reg (newtok
[0], AXP_REG_T10
);
3865 set_tok_const (newtok
[1], (1 << lgsize
) - 1);
3866 assemble_tokens ("stq_u", newtok
, 3, 1);
3869 /* Sign extend a half-word or byte. The 32-bit sign extend is
3870 implemented as "addl $31, $r, $t" in the opcode table. */
3873 emit_sextX (tok
, ntok
, vlgsize
)
3874 const expressionS
*tok
;
3878 long lgsize
= (long) vlgsize
;
3880 if (alpha_target
& AXP_OPCODE_BWX
)
3881 assemble_tokens (sextX_op
[lgsize
], tok
, ntok
, 0);
3884 int bitshift
= 64 - 8 * (1 << lgsize
);
3885 expressionS newtok
[3];
3887 /* emit "sll src,bits,dst" */
3890 set_tok_const (newtok
[1], bitshift
);
3891 newtok
[2] = tok
[ntok
- 1];
3892 assemble_tokens ("sll", newtok
, 3, 1);
3894 /* emit "sra dst,bits,dst" */
3896 newtok
[0] = newtok
[2];
3897 assemble_tokens ("sra", newtok
, 3, 1);
3901 /* Implement the division and modulus macros. */
3905 /* Make register usage like in normal procedure call.
3906 Don't clobber PV and RA. */
3909 emit_division (tok
, ntok
, symname
)
3910 const expressionS
*tok
;
3914 /* DIVISION and MODULUS. Yech.
3919 mov x,R16 # if x != R16
3920 mov y,R17 # if y != R17
3925 with appropriate optimizations if R0,R16,R17 are the registers
3926 specified by the compiler. */
3930 expressionS newtok
[3];
3932 xr
= regno (tok
[0].X_add_number
);
3933 yr
= regno (tok
[1].X_add_number
);
3938 rr
= regno (tok
[2].X_add_number
);
3940 /* Move the operands into the right place. */
3941 if (yr
== AXP_REG_R16
&& xr
== AXP_REG_R17
)
3943 /* They are in exactly the wrong order -- swap through AT. */
3946 as_bad (_("macro requires $at register while noat in effect"));
3948 set_tok_reg (newtok
[0], AXP_REG_R16
);
3949 set_tok_reg (newtok
[1], AXP_REG_AT
);
3950 assemble_tokens ("mov", newtok
, 2, 1);
3952 set_tok_reg (newtok
[0], AXP_REG_R17
);
3953 set_tok_reg (newtok
[1], AXP_REG_R16
);
3954 assemble_tokens ("mov", newtok
, 2, 1);
3956 set_tok_reg (newtok
[0], AXP_REG_AT
);
3957 set_tok_reg (newtok
[1], AXP_REG_R17
);
3958 assemble_tokens ("mov", newtok
, 2, 1);
3962 if (yr
== AXP_REG_R16
)
3964 set_tok_reg (newtok
[0], AXP_REG_R16
);
3965 set_tok_reg (newtok
[1], AXP_REG_R17
);
3966 assemble_tokens ("mov", newtok
, 2, 1);
3969 if (xr
!= AXP_REG_R16
)
3971 set_tok_reg (newtok
[0], xr
);
3972 set_tok_reg (newtok
[1], AXP_REG_R16
);
3973 assemble_tokens ("mov", newtok
, 2, 1);
3976 if (yr
!= AXP_REG_R16
&& yr
!= AXP_REG_R17
)
3978 set_tok_reg (newtok
[0], yr
);
3979 set_tok_reg (newtok
[1], AXP_REG_R17
);
3980 assemble_tokens ("mov", newtok
, 2, 1);
3984 sym
= symbol_find_or_make ((const char *) symname
);
3986 set_tok_reg (newtok
[0], AXP_REG_AT
);
3987 set_tok_sym (newtok
[1], sym
, 0);
3988 assemble_tokens ("lda", newtok
, 2, 1);
3990 /* Call the division routine. */
3991 set_tok_reg (newtok
[0], AXP_REG_AT
);
3992 set_tok_cpreg (newtok
[1], AXP_REG_AT
);
3993 set_tok_const (newtok
[2], 0);
3994 assemble_tokens ("jsr", newtok
, 3, 1);
3996 /* Move the result to the right place. */
3997 if (rr
!= AXP_REG_R0
)
3999 set_tok_reg (newtok
[0], AXP_REG_R0
);
4000 set_tok_reg (newtok
[1], rr
);
4001 assemble_tokens ("mov", newtok
, 2, 1);
4005 #else /* !OBJ_EVAX */
4008 emit_division (tok
, ntok
, symname
)
4009 const expressionS
*tok
;
4013 /* DIVISION and MODULUS. Yech.
4023 with appropriate optimizations if t10,t11,t12 are the registers
4024 specified by the compiler. */
4028 expressionS newtok
[3];
4030 xr
= regno (tok
[0].X_add_number
);
4031 yr
= regno (tok
[1].X_add_number
);
4036 rr
= regno (tok
[2].X_add_number
);
4038 sym
= symbol_find_or_make ((const char *) symname
);
4040 /* Move the operands into the right place. */
4041 if (yr
== AXP_REG_T10
&& xr
== AXP_REG_T11
)
4043 /* They are in exactly the wrong order -- swap through AT. */
4045 as_bad (_("macro requires $at register while noat in effect"));
4047 set_tok_reg (newtok
[0], AXP_REG_T10
);
4048 set_tok_reg (newtok
[1], AXP_REG_AT
);
4049 assemble_tokens ("mov", newtok
, 2, 1);
4051 set_tok_reg (newtok
[0], AXP_REG_T11
);
4052 set_tok_reg (newtok
[1], AXP_REG_T10
);
4053 assemble_tokens ("mov", newtok
, 2, 1);
4055 set_tok_reg (newtok
[0], AXP_REG_AT
);
4056 set_tok_reg (newtok
[1], AXP_REG_T11
);
4057 assemble_tokens ("mov", newtok
, 2, 1);
4061 if (yr
== AXP_REG_T10
)
4063 set_tok_reg (newtok
[0], AXP_REG_T10
);
4064 set_tok_reg (newtok
[1], AXP_REG_T11
);
4065 assemble_tokens ("mov", newtok
, 2, 1);
4068 if (xr
!= AXP_REG_T10
)
4070 set_tok_reg (newtok
[0], xr
);
4071 set_tok_reg (newtok
[1], AXP_REG_T10
);
4072 assemble_tokens ("mov", newtok
, 2, 1);
4075 if (yr
!= AXP_REG_T10
&& yr
!= AXP_REG_T11
)
4077 set_tok_reg (newtok
[0], yr
);
4078 set_tok_reg (newtok
[1], AXP_REG_T11
);
4079 assemble_tokens ("mov", newtok
, 2, 1);
4083 /* Call the division routine. */
4084 set_tok_reg (newtok
[0], AXP_REG_T9
);
4085 set_tok_sym (newtok
[1], sym
, 0);
4086 assemble_tokens ("jsr", newtok
, 2, 1);
4088 /* Reload the GP register. */
4092 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
4093 set_tok_reg (newtok
[0], alpha_gp_register
);
4094 set_tok_const (newtok
[1], 0);
4095 set_tok_preg (newtok
[2], AXP_REG_T9
);
4096 assemble_tokens ("ldgp", newtok
, 3, 1);
4099 /* Move the result to the right place. */
4100 if (rr
!= AXP_REG_T12
)
4102 set_tok_reg (newtok
[0], AXP_REG_T12
);
4103 set_tok_reg (newtok
[1], rr
);
4104 assemble_tokens ("mov", newtok
, 2, 1);
4108 #endif /* !OBJ_EVAX */
4110 /* The jsr and jmp macros differ from their instruction counterparts
4111 in that they can load the target address and default most
4115 emit_jsrjmp (tok
, ntok
, vopname
)
4116 const expressionS
*tok
;
4120 const char *opname
= (const char *) vopname
;
4121 struct alpha_insn insn
;
4122 expressionS newtok
[3];
4126 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_register
)
4127 r
= regno (tok
[tokidx
++].X_add_number
);
4129 r
= strcmp (opname
, "jmp") == 0 ? AXP_REG_ZERO
: AXP_REG_RA
;
4131 set_tok_reg (newtok
[0], r
);
4133 if (tokidx
< ntok
&&
4134 (tok
[tokidx
].X_op
== O_pregister
|| tok
[tokidx
].X_op
== O_cpregister
))
4135 r
= regno (tok
[tokidx
++].X_add_number
);
4137 /* keep register if jsr $n.<sym> */
4141 int basereg
= alpha_gp_register
;
4142 lituse
= load_expression (r
= AXP_REG_PV
, &tok
[tokidx
], &basereg
, NULL
);
4146 set_tok_cpreg (newtok
[1], r
);
4149 /* FIXME: Add hint relocs to BFD for evax. */
4152 newtok
[2] = tok
[tokidx
];
4155 set_tok_const (newtok
[2], 0);
4157 assemble_tokens_to_insn (opname
, newtok
, 3, &insn
);
4161 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
4162 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_JSR
;
4163 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
4165 insn
.sequence
= lituse
;
4171 /* The ret and jcr instructions differ from their instruction
4172 counterparts in that everything can be defaulted. */
4175 emit_retjcr (tok
, ntok
, vopname
)
4176 const expressionS
*tok
;
4180 const char *opname
= (const char *) vopname
;
4181 expressionS newtok
[3];
4184 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_register
)
4185 r
= regno (tok
[tokidx
++].X_add_number
);
4189 set_tok_reg (newtok
[0], r
);
4191 if (tokidx
< ntok
&&
4192 (tok
[tokidx
].X_op
== O_pregister
|| tok
[tokidx
].X_op
== O_cpregister
))
4193 r
= regno (tok
[tokidx
++].X_add_number
);
4197 set_tok_cpreg (newtok
[1], r
);
4200 newtok
[2] = tok
[tokidx
];
4202 set_tok_const (newtok
[2], strcmp (opname
, "ret") == 0);
4204 assemble_tokens (opname
, newtok
, 3, 0);
4207 /* Assembler directives. */
4209 /* Handle the .text pseudo-op. This is like the usual one, but it
4210 clears alpha_insn_label and restores auto alignment. */
4222 alpha_insn_label
= NULL
;
4223 alpha_auto_align_on
= 1;
4224 alpha_current_align
= 0;
4227 /* Handle the .data pseudo-op. This is like the usual one, but it
4228 clears alpha_insn_label and restores auto alignment. */
4239 alpha_insn_label
= NULL
;
4240 alpha_auto_align_on
= 1;
4241 alpha_current_align
= 0;
4244 #if defined (OBJ_ECOFF) || defined (OBJ_EVAX)
4246 /* Handle the OSF/1 and openVMS .comm pseudo quirks.
4247 openVMS constructs a section for every common symbol. */
4250 s_alpha_comm (ignore
)
4251 int ignore ATTRIBUTE_UNUSED
;
4253 register char *name
;
4257 register symbolS
*symbolP
;
4260 segT current_section
= now_seg
;
4261 int current_subsec
= now_subseg
;
4265 name
= input_line_pointer
;
4266 c
= get_symbol_end ();
4268 /* just after name is now '\0' */
4269 p
= input_line_pointer
;
4274 /* Alpha OSF/1 compiler doesn't provide the comma, gcc does. */
4275 if (*input_line_pointer
== ',')
4277 input_line_pointer
++;
4280 if ((temp
= get_absolute_expression ()) < 0)
4282 as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) temp
);
4283 ignore_rest_of_line ();
4288 symbolP
= symbol_find_or_make (name
);
4291 /* Make a section for the common symbol. */
4292 new_seg
= subseg_new (xstrdup (name
), 0);
4298 /* alignment might follow */
4299 if (*input_line_pointer
== ',')
4303 input_line_pointer
++;
4304 align
= get_absolute_expression ();
4305 bfd_set_section_alignment (stdoutput
, new_seg
, align
);
4309 if (S_IS_DEFINED (symbolP
) && ! S_IS_COMMON (symbolP
))
4311 as_bad (_("Ignoring attempt to re-define symbol"));
4312 ignore_rest_of_line ();
4317 if (bfd_section_size (stdoutput
, new_seg
) > 0)
4319 if (bfd_section_size (stdoutput
, new_seg
) != temp
)
4320 as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
4321 S_GET_NAME (symbolP
),
4322 (long) bfd_section_size (stdoutput
, new_seg
),
4326 if (S_GET_VALUE (symbolP
))
4328 if (S_GET_VALUE (symbolP
) != (valueT
) temp
)
4329 as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
4330 S_GET_NAME (symbolP
),
4331 (long) S_GET_VALUE (symbolP
),
4338 subseg_set (new_seg
, 0);
4339 p
= frag_more (temp
);
4340 new_seg
->flags
|= SEC_IS_COMMON
;
4341 if (! S_IS_DEFINED (symbolP
))
4342 S_SET_SEGMENT (symbolP
, new_seg
);
4344 S_SET_VALUE (symbolP
, (valueT
) temp
);
4346 S_SET_EXTERNAL (symbolP
);
4350 subseg_set (current_section
, current_subsec
);
4353 know (symbol_get_frag (symbolP
) == &zero_address_frag
);
4355 demand_empty_rest_of_line ();
4358 #endif /* ! OBJ_ELF */
4362 /* Handle the .rdata pseudo-op. This is like the usual one, but it
4363 clears alpha_insn_label and restores auto alignment. */
4366 s_alpha_rdata (ignore
)
4367 int ignore ATTRIBUTE_UNUSED
;
4371 temp
= get_absolute_expression ();
4372 subseg_new (".rdata", 0);
4373 demand_empty_rest_of_line ();
4374 alpha_insn_label
= NULL
;
4375 alpha_auto_align_on
= 1;
4376 alpha_current_align
= 0;
4383 /* Handle the .sdata pseudo-op. This is like the usual one, but it
4384 clears alpha_insn_label and restores auto alignment. */
4387 s_alpha_sdata (ignore
)
4388 int ignore ATTRIBUTE_UNUSED
;
4392 temp
= get_absolute_expression ();
4393 subseg_new (".sdata", 0);
4394 demand_empty_rest_of_line ();
4395 alpha_insn_label
= NULL
;
4396 alpha_auto_align_on
= 1;
4397 alpha_current_align
= 0;
4403 /* Handle the .section pseudo-op. This is like the usual one, but it
4404 clears alpha_insn_label and restores auto alignment. */
4407 s_alpha_section (ignore
)
4408 int ignore ATTRIBUTE_UNUSED
;
4410 obj_elf_section (ignore
);
4412 alpha_insn_label
= NULL
;
4413 alpha_auto_align_on
= 1;
4414 alpha_current_align
= 0;
4419 int dummy ATTRIBUTE_UNUSED
;
4421 if (ECOFF_DEBUGGING
)
4422 ecoff_directive_ent (0);
4425 char *name
, name_end
;
4426 name
= input_line_pointer
;
4427 name_end
= get_symbol_end ();
4429 if (! is_name_beginner (*name
))
4431 as_warn (_(".ent directive has no name"));
4432 *input_line_pointer
= name_end
;
4438 if (alpha_cur_ent_sym
)
4439 as_warn (_("nested .ent directives"));
4441 sym
= symbol_find_or_make (name
);
4442 symbol_get_bfdsym (sym
)->flags
|= BSF_FUNCTION
;
4443 alpha_cur_ent_sym
= sym
;
4445 /* The .ent directive is sometimes followed by a number. Not sure
4446 what it really means, but ignore it. */
4447 *input_line_pointer
= name_end
;
4449 if (*input_line_pointer
== ',')
4451 input_line_pointer
++;
4454 if (ISDIGIT (*input_line_pointer
) || *input_line_pointer
== '-')
4455 (void) get_absolute_expression ();
4457 demand_empty_rest_of_line ();
4463 int dummy ATTRIBUTE_UNUSED
;
4465 if (ECOFF_DEBUGGING
)
4466 ecoff_directive_end (0);
4469 char *name
, name_end
;
4470 name
= input_line_pointer
;
4471 name_end
= get_symbol_end ();
4473 if (! is_name_beginner (*name
))
4475 as_warn (_(".end directive has no name"));
4476 *input_line_pointer
= name_end
;
4482 sym
= symbol_find (name
);
4483 if (sym
!= alpha_cur_ent_sym
)
4484 as_warn (_(".end directive names different symbol than .ent"));
4486 /* Create an expression to calculate the size of the function. */
4489 symbol_get_obj (sym
)->size
=
4490 (expressionS
*) xmalloc (sizeof (expressionS
));
4491 symbol_get_obj (sym
)->size
->X_op
= O_subtract
;
4492 symbol_get_obj (sym
)->size
->X_add_symbol
4493 = symbol_new ("L0\001", now_seg
, frag_now_fix (), frag_now
);
4494 symbol_get_obj (sym
)->size
->X_op_symbol
= sym
;
4495 symbol_get_obj (sym
)->size
->X_add_number
= 0;
4498 alpha_cur_ent_sym
= NULL
;
4500 *input_line_pointer
= name_end
;
4502 demand_empty_rest_of_line ();
4510 if (ECOFF_DEBUGGING
)
4513 ecoff_directive_fmask (0);
4515 ecoff_directive_mask (0);
4518 discard_rest_of_line ();
4522 s_alpha_frame (dummy
)
4523 int dummy ATTRIBUTE_UNUSED
;
4525 if (ECOFF_DEBUGGING
)
4526 ecoff_directive_frame (0);
4528 discard_rest_of_line ();
4532 s_alpha_prologue (ignore
)
4533 int ignore ATTRIBUTE_UNUSED
;
4538 arg
= get_absolute_expression ();
4539 demand_empty_rest_of_line ();
4541 if (ECOFF_DEBUGGING
)
4542 sym
= ecoff_get_cur_proc_sym ();
4544 sym
= alpha_cur_ent_sym
;
4549 case 0: /* No PV required. */
4550 S_SET_OTHER (sym
, STO_ALPHA_NOPV
4551 | (S_GET_OTHER (sym
) & ~STO_ALPHA_STD_GPLOAD
));
4553 case 1: /* Std GP load. */
4554 S_SET_OTHER (sym
, STO_ALPHA_STD_GPLOAD
4555 | (S_GET_OTHER (sym
) & ~STO_ALPHA_STD_GPLOAD
));
4557 case 2: /* Non-std use of PV. */
4561 as_bad (_("Invalid argument %d to .prologue."), arg
);
4566 static char *first_file_directive
;
4569 s_alpha_file (ignore
)
4570 int ignore ATTRIBUTE_UNUSED
;
4572 /* Save the first .file directive we see, so that we can change our
4573 minds about whether ecoff debugging should or shouldn't be enabled. */
4574 if (alpha_flag_mdebug
< 0 && ! first_file_directive
)
4576 char *start
= input_line_pointer
;
4579 discard_rest_of_line ();
4581 len
= input_line_pointer
- start
;
4582 first_file_directive
= xmalloc (len
+ 1);
4583 memcpy (first_file_directive
, start
, len
);
4584 first_file_directive
[len
] = '\0';
4586 input_line_pointer
= start
;
4589 if (ECOFF_DEBUGGING
)
4590 ecoff_directive_file (0);
4592 dwarf2_directive_file (0);
4596 s_alpha_loc (ignore
)
4597 int ignore ATTRIBUTE_UNUSED
;
4599 if (ECOFF_DEBUGGING
)
4600 ecoff_directive_loc (0);
4602 dwarf2_directive_loc (0);
4609 /* If we've been undecided about mdebug, make up our minds in favour. */
4610 if (alpha_flag_mdebug
< 0)
4612 segT sec
= subseg_new (".mdebug", 0);
4613 bfd_set_section_flags (stdoutput
, sec
, SEC_HAS_CONTENTS
| SEC_READONLY
);
4614 bfd_set_section_alignment (stdoutput
, sec
, 3);
4616 ecoff_read_begin_hook ();
4618 if (first_file_directive
)
4620 char *save_ilp
= input_line_pointer
;
4621 input_line_pointer
= first_file_directive
;
4622 ecoff_directive_file (0);
4623 input_line_pointer
= save_ilp
;
4624 free (first_file_directive
);
4627 alpha_flag_mdebug
= 1;
4633 s_alpha_coff_wrapper (which
)
4636 static void (* const fns
[]) PARAMS ((int)) = {
4637 ecoff_directive_begin
,
4638 ecoff_directive_bend
,
4639 ecoff_directive_def
,
4640 ecoff_directive_dim
,
4641 ecoff_directive_endef
,
4642 ecoff_directive_scl
,
4643 ecoff_directive_tag
,
4644 ecoff_directive_val
,
4647 assert (which
>= 0 && which
< (int) (sizeof (fns
)/sizeof (*fns
)));
4649 if (ECOFF_DEBUGGING
)
4653 as_bad (_("ECOFF debugging is disabled."));
4654 ignore_rest_of_line ();
4657 #endif /* OBJ_ELF */
4661 /* Handle the section specific pseudo-op. */
4664 s_alpha_section (secid
)
4668 #define EVAX_SECTION_COUNT 5
4669 static char *section_name
[EVAX_SECTION_COUNT
+ 1] =
4670 { "NULL", ".rdata", ".comm", ".link", ".ctors", ".dtors" };
4672 if ((secid
<= 0) || (secid
> EVAX_SECTION_COUNT
))
4674 as_fatal (_("Unknown section directive"));
4675 demand_empty_rest_of_line ();
4678 temp
= get_absolute_expression ();
4679 subseg_new (section_name
[secid
], 0);
4680 demand_empty_rest_of_line ();
4681 alpha_insn_label
= NULL
;
4682 alpha_auto_align_on
= 1;
4683 alpha_current_align
= 0;
4686 /* Parse .ent directives. */
4689 s_alpha_ent (ignore
)
4690 int ignore ATTRIBUTE_UNUSED
;
4693 expressionS symexpr
;
4695 alpha_evax_proc
.pdsckind
= 0;
4696 alpha_evax_proc
.framereg
= -1;
4697 alpha_evax_proc
.framesize
= 0;
4698 alpha_evax_proc
.rsa_offset
= 0;
4699 alpha_evax_proc
.ra_save
= AXP_REG_RA
;
4700 alpha_evax_proc
.fp_save
= -1;
4701 alpha_evax_proc
.imask
= 0;
4702 alpha_evax_proc
.fmask
= 0;
4703 alpha_evax_proc
.prologue
= 0;
4704 alpha_evax_proc
.type
= 0;
4706 expression (&symexpr
);
4708 if (symexpr
.X_op
!= O_symbol
)
4710 as_fatal (_(".ent directive has no symbol"));
4711 demand_empty_rest_of_line ();
4715 symbol
= make_expr_symbol (&symexpr
);
4716 symbol_get_bfdsym (symbol
)->flags
|= BSF_FUNCTION
;
4717 alpha_evax_proc
.symbol
= symbol
;
4719 demand_empty_rest_of_line ();
4723 /* Parse .frame <framreg>,<framesize>,RA,<rsa_offset> directives. */
4726 s_alpha_frame (ignore
)
4727 int ignore ATTRIBUTE_UNUSED
;
4731 alpha_evax_proc
.framereg
= tc_get_register (1);
4734 if (*input_line_pointer
++ != ','
4735 || get_absolute_expression_and_terminator (&val
) != ',')
4737 as_warn (_("Bad .frame directive 1./2. param"));
4738 --input_line_pointer
;
4739 demand_empty_rest_of_line ();
4743 alpha_evax_proc
.framesize
= val
;
4745 (void) tc_get_register (1);
4747 if (*input_line_pointer
++ != ',')
4749 as_warn (_("Bad .frame directive 3./4. param"));
4750 --input_line_pointer
;
4751 demand_empty_rest_of_line ();
4754 alpha_evax_proc
.rsa_offset
= get_absolute_expression ();
4760 s_alpha_pdesc (ignore
)
4761 int ignore ATTRIBUTE_UNUSED
;
4770 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
4772 if (now_seg
!= alpha_link_section
)
4774 as_bad (_(".pdesc directive not in link (.link) section"));
4775 demand_empty_rest_of_line ();
4779 if ((alpha_evax_proc
.symbol
== 0)
4780 || (!S_IS_DEFINED (alpha_evax_proc
.symbol
)))
4782 as_fatal (_(".pdesc has no matching .ent"));
4783 demand_empty_rest_of_line ();
4787 *symbol_get_obj (alpha_evax_proc
.symbol
) =
4788 (valueT
) seginfo
->literal_pool_size
;
4791 if (exp
.X_op
!= O_symbol
)
4793 as_warn (_(".pdesc directive has no entry symbol"));
4794 demand_empty_rest_of_line ();
4798 entry_sym
= make_expr_symbol (&exp
);
4799 /* Save bfd symbol of proc desc in function symbol. */
4800 symbol_get_bfdsym (alpha_evax_proc
.symbol
)->udata
.p
4801 = symbol_get_bfdsym (entry_sym
);
4804 if (*input_line_pointer
++ != ',')
4806 as_warn (_("No comma after .pdesc <entryname>"));
4807 demand_empty_rest_of_line ();
4812 name
= input_line_pointer
;
4813 name_end
= get_symbol_end ();
4815 if (strncmp (name
, "stack", 5) == 0)
4817 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_FP_STACK
;
4819 else if (strncmp (name
, "reg", 3) == 0)
4821 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_FP_REGISTER
;
4823 else if (strncmp (name
, "null", 4) == 0)
4825 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_NULL
;
4829 as_fatal (_("unknown procedure kind"));
4830 demand_empty_rest_of_line ();
4834 *input_line_pointer
= name_end
;
4835 demand_empty_rest_of_line ();
4837 #ifdef md_flush_pending_output
4838 md_flush_pending_output ();
4841 frag_align (3, 0, 0);
4843 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
4845 seginfo
->literal_pool_size
+= 16;
4847 *p
= alpha_evax_proc
.pdsckind
4848 | ((alpha_evax_proc
.framereg
== 29) ? PDSC_S_M_BASE_REG_IS_FP
: 0);
4849 *(p
+ 1) = PDSC_S_M_NATIVE
| PDSC_S_M_NO_JACKET
;
4851 switch (alpha_evax_proc
.pdsckind
)
4853 case PDSC_S_K_KIND_NULL
:
4857 case PDSC_S_K_KIND_FP_REGISTER
:
4858 *(p
+ 2) = alpha_evax_proc
.fp_save
;
4859 *(p
+ 3) = alpha_evax_proc
.ra_save
;
4861 case PDSC_S_K_KIND_FP_STACK
:
4862 md_number_to_chars (p
+ 2, (valueT
) alpha_evax_proc
.rsa_offset
, 2);
4864 default: /* impossible */
4869 *(p
+ 5) = alpha_evax_proc
.type
& 0x0f;
4871 /* Signature offset. */
4872 md_number_to_chars (p
+ 6, (valueT
) 0, 2);
4874 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
+8, 8, &exp
, 0, BFD_RELOC_64
);
4876 if (alpha_evax_proc
.pdsckind
== PDSC_S_K_KIND_NULL
)
4879 /* Add dummy fix to make add_to_link_pool work. */
4881 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
4883 seginfo
->literal_pool_size
+= 8;
4885 /* pdesc+16: Size. */
4886 md_number_to_chars (p
, (valueT
) alpha_evax_proc
.framesize
, 4);
4888 md_number_to_chars (p
+ 4, (valueT
) 0, 2);
4891 md_number_to_chars (p
+ 6, alpha_evax_proc
.prologue
, 2);
4893 if (alpha_evax_proc
.pdsckind
== PDSC_S_K_KIND_FP_REGISTER
)
4896 /* Add dummy fix to make add_to_link_pool work. */
4898 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
4900 seginfo
->literal_pool_size
+= 8;
4902 /* pdesc+24: register masks. */
4904 md_number_to_chars (p
, alpha_evax_proc
.imask
, 4);
4905 md_number_to_chars (p
+ 4, alpha_evax_proc
.fmask
, 4);
4910 /* Support for crash debug on vms. */
4913 s_alpha_name (ignore
)
4914 int ignore ATTRIBUTE_UNUSED
;
4918 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
4920 if (now_seg
!= alpha_link_section
)
4922 as_bad (_(".name directive not in link (.link) section"));
4923 demand_empty_rest_of_line ();
4928 if (exp
.X_op
!= O_symbol
)
4930 as_warn (_(".name directive has no symbol"));
4931 demand_empty_rest_of_line ();
4935 demand_empty_rest_of_line ();
4937 #ifdef md_flush_pending_output
4938 md_flush_pending_output ();
4941 frag_align (3, 0, 0);
4943 seginfo
->literal_pool_size
+= 8;
4945 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 8, &exp
, 0, BFD_RELOC_64
);
4951 s_alpha_linkage (ignore
)
4952 int ignore ATTRIBUTE_UNUSED
;
4957 #ifdef md_flush_pending_output
4958 md_flush_pending_output ();
4962 if (exp
.X_op
!= O_symbol
)
4964 as_fatal (_("No symbol after .linkage"));
4968 p
= frag_more (LKP_S_K_SIZE
);
4969 memset (p
, 0, LKP_S_K_SIZE
);
4970 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, LKP_S_K_SIZE
, &exp
, 0,\
4971 BFD_RELOC_ALPHA_LINKAGE
);
4973 demand_empty_rest_of_line ();
4979 s_alpha_code_address (ignore
)
4980 int ignore ATTRIBUTE_UNUSED
;
4985 #ifdef md_flush_pending_output
4986 md_flush_pending_output ();
4990 if (exp
.X_op
!= O_symbol
)
4992 as_fatal (_("No symbol after .code_address"));
4998 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 8, &exp
, 0,\
4999 BFD_RELOC_ALPHA_CODEADDR
);
5001 demand_empty_rest_of_line ();
5007 s_alpha_fp_save (ignore
)
5008 int ignore ATTRIBUTE_UNUSED
;
5011 alpha_evax_proc
.fp_save
= tc_get_register (1);
5013 demand_empty_rest_of_line ();
5018 s_alpha_mask (ignore
)
5019 int ignore ATTRIBUTE_UNUSED
;
5023 if (get_absolute_expression_and_terminator (&val
) != ',')
5025 as_warn (_("Bad .mask directive"));
5026 --input_line_pointer
;
5030 alpha_evax_proc
.imask
= val
;
5031 (void) get_absolute_expression ();
5033 demand_empty_rest_of_line ();
5039 s_alpha_fmask (ignore
)
5040 int ignore ATTRIBUTE_UNUSED
;
5044 if (get_absolute_expression_and_terminator (&val
) != ',')
5046 as_warn (_("Bad .fmask directive"));
5047 --input_line_pointer
;
5051 alpha_evax_proc
.fmask
= val
;
5052 (void) get_absolute_expression ();
5054 demand_empty_rest_of_line ();
5060 s_alpha_end (ignore
)
5061 int ignore ATTRIBUTE_UNUSED
;
5065 c
= get_symbol_end ();
5066 *input_line_pointer
= c
;
5067 demand_empty_rest_of_line ();
5068 alpha_evax_proc
.symbol
= 0;
5074 s_alpha_file (ignore
)
5075 int ignore ATTRIBUTE_UNUSED
;
5079 static char case_hack
[32];
5081 extern char *demand_copy_string
PARAMS ((int *lenP
));
5083 sprintf (case_hack
, "<CASE:%01d%01d>",
5084 alpha_flag_hash_long_names
, alpha_flag_show_after_trunc
);
5086 s
= symbol_find_or_make (case_hack
);
5087 symbol_get_bfdsym (s
)->flags
|= BSF_FILE
;
5089 get_absolute_expression ();
5090 s
= symbol_find_or_make (demand_copy_string (&length
));
5091 symbol_get_bfdsym (s
)->flags
|= BSF_FILE
;
5092 demand_empty_rest_of_line ();
5096 #endif /* OBJ_EVAX */
5098 /* Handle the .gprel32 pseudo op. */
5101 s_alpha_gprel32 (ignore
)
5102 int ignore ATTRIBUTE_UNUSED
;
5114 e
.X_add_symbol
= section_symbol (absolute_section
);
5127 e
.X_add_symbol
= section_symbol (absolute_section
);
5130 e
.X_op
= O_subtract
;
5131 e
.X_op_symbol
= alpha_gp_symbol
;
5139 if (alpha_auto_align_on
&& alpha_current_align
< 2)
5140 alpha_align (2, (char *) NULL
, alpha_insn_label
, 0);
5141 if (alpha_current_align
> 2)
5142 alpha_current_align
= 2;
5143 alpha_insn_label
= NULL
;
5147 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 4,
5148 &e
, 0, BFD_RELOC_GPREL32
);
5151 /* Handle floating point allocation pseudo-ops. This is like the
5152 generic vresion, but it makes sure the current label, if any, is
5153 correctly aligned. */
5156 s_alpha_float_cons (type
)
5183 if (alpha_auto_align_on
&& alpha_current_align
< log_size
)
5184 alpha_align (log_size
, (char *) NULL
, alpha_insn_label
, 0);
5185 if (alpha_current_align
> log_size
)
5186 alpha_current_align
= log_size
;
5187 alpha_insn_label
= NULL
;
5192 /* Handle the .proc pseudo op. We don't really do much with it except
5196 s_alpha_proc (is_static
)
5197 int is_static ATTRIBUTE_UNUSED
;
5205 /* Takes ".proc name,nargs" */
5207 name
= input_line_pointer
;
5208 c
= get_symbol_end ();
5209 p
= input_line_pointer
;
5210 symbolP
= symbol_find_or_make (name
);
5213 if (*input_line_pointer
!= ',')
5216 as_warn (_("Expected comma after name \"%s\""), name
);
5219 ignore_rest_of_line ();
5223 input_line_pointer
++;
5224 temp
= get_absolute_expression ();
5226 /* *symbol_get_obj (symbolP) = (signed char) temp; */
5227 as_warn (_("unhandled: .proc %s,%d"), name
, temp
);
5228 demand_empty_rest_of_line ();
5231 /* Handle the .set pseudo op. This is used to turn on and off most of
5232 the assembler features. */
5236 int x ATTRIBUTE_UNUSED
;
5242 name
= input_line_pointer
;
5243 ch
= get_symbol_end ();
5246 if (s
[0] == 'n' && s
[1] == 'o')
5251 if (!strcmp ("reorder", s
))
5253 else if (!strcmp ("at", s
))
5254 alpha_noat_on
= !yesno
;
5255 else if (!strcmp ("macro", s
))
5256 alpha_macros_on
= yesno
;
5257 else if (!strcmp ("move", s
))
5259 else if (!strcmp ("volatile", s
))
5262 as_warn (_("Tried to .set unrecognized mode `%s'"), name
);
5264 *input_line_pointer
= ch
;
5265 demand_empty_rest_of_line ();
5268 /* Handle the .base pseudo op. This changes the assembler's notion of
5269 the $gp register. */
5272 s_alpha_base (ignore
)
5273 int ignore ATTRIBUTE_UNUSED
;
5276 if (first_32bit_quadrant
)
5278 /* not fatal, but it might not work in the end */
5279 as_warn (_("File overrides no-base-register option."));
5280 first_32bit_quadrant
= 0;
5285 if (*input_line_pointer
== '$')
5287 input_line_pointer
++;
5288 if (*input_line_pointer
== 'r')
5289 input_line_pointer
++;
5292 alpha_gp_register
= get_absolute_expression ();
5293 if (alpha_gp_register
< 0 || alpha_gp_register
> 31)
5295 alpha_gp_register
= AXP_REG_GP
;
5296 as_warn (_("Bad base register, using $%d."), alpha_gp_register
);
5299 demand_empty_rest_of_line ();
5302 /* Handle the .align pseudo-op. This aligns to a power of two. It
5303 also adjusts any current instruction label. We treat this the same
5304 way the MIPS port does: .align 0 turns off auto alignment. */
5307 s_alpha_align (ignore
)
5308 int ignore ATTRIBUTE_UNUSED
;
5312 long max_alignment
= 15;
5314 align
= get_absolute_expression ();
5315 if (align
> max_alignment
)
5317 align
= max_alignment
;
5318 as_bad (_("Alignment too large: %d. assumed"), align
);
5322 as_warn (_("Alignment negative: 0 assumed"));
5326 if (*input_line_pointer
== ',')
5328 input_line_pointer
++;
5329 fill
= get_absolute_expression ();
5337 alpha_auto_align_on
= 1;
5338 alpha_align (align
, pfill
, alpha_insn_label
, 1);
5342 alpha_auto_align_on
= 0;
5345 demand_empty_rest_of_line ();
5348 /* Hook the normal string processor to reset known alignment. */
5351 s_alpha_stringer (terminate
)
5354 alpha_current_align
= 0;
5355 alpha_insn_label
= NULL
;
5356 stringer (terminate
);
5359 /* Hook the normal space processing to reset known alignment. */
5362 s_alpha_space (ignore
)
5365 alpha_current_align
= 0;
5366 alpha_insn_label
= NULL
;
5370 /* Hook into cons for auto-alignment. */
5373 alpha_cons_align (size
)
5379 while ((size
>>= 1) != 0)
5382 if (alpha_auto_align_on
&& alpha_current_align
< log_size
)
5383 alpha_align (log_size
, (char *) NULL
, alpha_insn_label
, 0);
5384 if (alpha_current_align
> log_size
)
5385 alpha_current_align
= log_size
;
5386 alpha_insn_label
= NULL
;
5389 /* Here come the .uword, .ulong, and .uquad explicitly unaligned
5390 pseudos. We just turn off auto-alignment and call down to cons. */
5393 s_alpha_ucons (bytes
)
5396 int hold
= alpha_auto_align_on
;
5397 alpha_auto_align_on
= 0;
5399 alpha_auto_align_on
= hold
;
5402 /* Switch the working cpu type. */
5405 s_alpha_arch (ignored
)
5406 int ignored ATTRIBUTE_UNUSED
;
5409 const struct cpu_type
*p
;
5412 name
= input_line_pointer
;
5413 ch
= get_symbol_end ();
5415 for (p
= cpu_types
; p
->name
; ++p
)
5416 if (strcmp (name
, p
->name
) == 0)
5418 alpha_target_name
= p
->name
, alpha_target
= p
->flags
;
5421 as_warn ("Unknown CPU identifier `%s'", name
);
5424 *input_line_pointer
= ch
;
5425 demand_empty_rest_of_line ();
5429 /* print token expression with alpha specific extension. */
5432 alpha_print_token (f
, exp
)
5434 const expressionS
*exp
;
5444 expressionS nexp
= *exp
;
5445 nexp
.X_op
= O_register
;
5446 print_expr (f
, &nexp
);
5451 print_expr (f
, exp
);
5458 /* The target specific pseudo-ops which we support. */
5460 const pseudo_typeS md_pseudo_table
[] = {
5462 {"comm", s_alpha_comm
, 0}, /* osf1 compiler does this */
5463 {"rdata", s_alpha_rdata
, 0},
5465 {"text", s_alpha_text
, 0},
5466 {"data", s_alpha_data
, 0},
5468 {"sdata", s_alpha_sdata
, 0},
5471 {"section", s_alpha_section
, 0},
5472 {"section.s", s_alpha_section
, 0},
5473 {"sect", s_alpha_section
, 0},
5474 {"sect.s", s_alpha_section
, 0},
5477 { "pdesc", s_alpha_pdesc
, 0},
5478 { "name", s_alpha_name
, 0},
5479 { "linkage", s_alpha_linkage
, 0},
5480 { "code_address", s_alpha_code_address
, 0},
5481 { "ent", s_alpha_ent
, 0},
5482 { "frame", s_alpha_frame
, 0},
5483 { "fp_save", s_alpha_fp_save
, 0},
5484 { "mask", s_alpha_mask
, 0},
5485 { "fmask", s_alpha_fmask
, 0},
5486 { "end", s_alpha_end
, 0},
5487 { "file", s_alpha_file
, 0},
5488 { "rdata", s_alpha_section
, 1},
5489 { "comm", s_alpha_comm
, 0},
5490 { "link", s_alpha_section
, 3},
5491 { "ctors", s_alpha_section
, 4},
5492 { "dtors", s_alpha_section
, 5},
5495 /* Frame related pseudos. */
5496 {"ent", s_alpha_ent
, 0},
5497 {"end", s_alpha_end
, 0},
5498 {"mask", s_alpha_mask
, 0},
5499 {"fmask", s_alpha_mask
, 1},
5500 {"frame", s_alpha_frame
, 0},
5501 {"prologue", s_alpha_prologue
, 0},
5502 {"file", s_alpha_file
, 5},
5503 {"loc", s_alpha_loc
, 9},
5504 {"stabs", s_alpha_stab
, 's'},
5505 {"stabn", s_alpha_stab
, 'n'},
5506 /* COFF debugging related pseudos. */
5507 {"begin", s_alpha_coff_wrapper
, 0},
5508 {"bend", s_alpha_coff_wrapper
, 1},
5509 {"def", s_alpha_coff_wrapper
, 2},
5510 {"dim", s_alpha_coff_wrapper
, 3},
5511 {"endef", s_alpha_coff_wrapper
, 4},
5512 {"scl", s_alpha_coff_wrapper
, 5},
5513 {"tag", s_alpha_coff_wrapper
, 6},
5514 {"val", s_alpha_coff_wrapper
, 7},
5516 {"prologue", s_ignore
, 0},
5518 {"gprel32", s_alpha_gprel32
, 0},
5519 {"t_floating", s_alpha_float_cons
, 'd'},
5520 {"s_floating", s_alpha_float_cons
, 'f'},
5521 {"f_floating", s_alpha_float_cons
, 'F'},
5522 {"g_floating", s_alpha_float_cons
, 'G'},
5523 {"d_floating", s_alpha_float_cons
, 'D'},
5525 {"proc", s_alpha_proc
, 0},
5526 {"aproc", s_alpha_proc
, 1},
5527 {"set", s_alpha_set
, 0},
5528 {"reguse", s_ignore
, 0},
5529 {"livereg", s_ignore
, 0},
5530 {"base", s_alpha_base
, 0}, /*??*/
5531 {"option", s_ignore
, 0},
5532 {"aent", s_ignore
, 0},
5533 {"ugen", s_ignore
, 0},
5534 {"eflag", s_ignore
, 0},
5536 {"align", s_alpha_align
, 0},
5537 {"double", s_alpha_float_cons
, 'd'},
5538 {"float", s_alpha_float_cons
, 'f'},
5539 {"single", s_alpha_float_cons
, 'f'},
5540 {"ascii", s_alpha_stringer
, 0},
5541 {"asciz", s_alpha_stringer
, 1},
5542 {"string", s_alpha_stringer
, 1},
5543 {"space", s_alpha_space
, 0},
5544 {"skip", s_alpha_space
, 0},
5545 {"zero", s_alpha_space
, 0},
5547 /* Unaligned data pseudos. */
5548 {"uword", s_alpha_ucons
, 2},
5549 {"ulong", s_alpha_ucons
, 4},
5550 {"uquad", s_alpha_ucons
, 8},
5553 /* Dwarf wants these versions of unaligned. */
5554 {"2byte", s_alpha_ucons
, 2},
5555 {"4byte", s_alpha_ucons
, 4},
5556 {"8byte", s_alpha_ucons
, 8},
5559 /* We don't do any optimizing, so we can safely ignore these. */
5560 {"noalias", s_ignore
, 0},
5561 {"alias", s_ignore
, 0},
5563 {"arch", s_alpha_arch
, 0},
5568 /* Build a BFD section with its flags set appropriately for the .lita,
5569 .lit8, or .lit4 sections. */
5572 create_literal_section (name
, secp
, symp
)
5577 segT current_section
= now_seg
;
5578 int current_subsec
= now_subseg
;
5581 *secp
= new_sec
= subseg_new (name
, 0);
5582 subseg_set (current_section
, current_subsec
);
5583 bfd_set_section_alignment (stdoutput
, new_sec
, 4);
5584 bfd_set_section_flags (stdoutput
, new_sec
,
5585 SEC_RELOC
| SEC_ALLOC
| SEC_LOAD
| SEC_READONLY
5588 S_CLEAR_EXTERNAL (*symp
= section_symbol (new_sec
));
5593 /* @@@ GP selection voodoo. All of this seems overly complicated and
5594 unnecessary; which is the primary reason it's for ECOFF only. */
5595 static inline void maybe_set_gp
PARAMS ((asection
*));
5604 vma
= bfd_get_section_vma (foo
, sec
);
5605 if (vma
&& vma
< alpha_gp_value
)
5606 alpha_gp_value
= vma
;
5612 assert (alpha_gp_value
== 0);
5614 /* Get minus-one in whatever width... */
5618 /* Select the smallest VMA of these existing sections. */
5619 maybe_set_gp (alpha_lita_section
);
5621 /* These were disabled before -- should we use them? */
5622 maybe_set_gp (sdata
);
5623 maybe_set_gp (lit8_sec
);
5624 maybe_set_gp (lit4_sec
);
5627 /* @@ Will a simple 0x8000 work here? If not, why not? */
5628 #define GP_ADJUSTMENT (0x8000 - 0x10)
5630 alpha_gp_value
+= GP_ADJUSTMENT
;
5632 S_SET_VALUE (alpha_gp_symbol
, alpha_gp_value
);
5635 printf (_("Chose GP value of %lx\n"), alpha_gp_value
);
5638 #endif /* OBJ_ECOFF */
5641 /* Map 's' to SHF_ALPHA_GPREL. */
5644 alpha_elf_section_letter (letter
, ptr_msg
)
5649 return SHF_ALPHA_GPREL
;
5651 *ptr_msg
= _("Bad .section directive: want a,s,w,x,M,S,G,T in string");
5655 /* Map SHF_ALPHA_GPREL to SEC_SMALL_DATA. */
5658 alpha_elf_section_flags (flags
, attr
, type
)
5660 int attr
, type ATTRIBUTE_UNUSED
;
5662 if (attr
& SHF_ALPHA_GPREL
)
5663 flags
|= SEC_SMALL_DATA
;
5666 #endif /* OBJ_ELF */
5668 /* Called internally to handle all alignment needs. This takes care
5669 of eliding calls to frag_align if'n the cached current alignment
5670 says we've already got it, as well as taking care of the auto-align
5671 feature wrt labels. */
5674 alpha_align (n
, pfill
, label
, force
)
5678 int force ATTRIBUTE_UNUSED
;
5680 if (alpha_current_align
>= n
)
5685 if (subseg_text_p (now_seg
))
5686 frag_align_code (n
, 0);
5688 frag_align (n
, 0, 0);
5691 frag_align (n
, *pfill
, 0);
5693 alpha_current_align
= n
;
5695 if (label
!= NULL
&& S_GET_SEGMENT (label
) == now_seg
)
5697 symbol_set_frag (label
, frag_now
);
5698 S_SET_VALUE (label
, (valueT
) frag_now_fix ());
5701 record_alignment (now_seg
, n
);
5703 /* ??? If alpha_flag_relax && force && elf, record the requested alignment
5704 in a reloc for the linker to see. */
5707 /* This is called from HANDLE_ALIGN in write.c. Fill in the contents
5708 of an rs_align_code fragment. */
5711 alpha_handle_align (fragp
)
5714 static char const unop
[4] = { 0x00, 0x00, 0xfe, 0x2f };
5715 static char const nopunop
[8] = {
5716 0x1f, 0x04, 0xff, 0x47,
5717 0x00, 0x00, 0xfe, 0x2f
5723 if (fragp
->fr_type
!= rs_align_code
)
5726 bytes
= fragp
->fr_next
->fr_address
- fragp
->fr_address
- fragp
->fr_fix
;
5727 p
= fragp
->fr_literal
+ fragp
->fr_fix
;
5740 memcpy (p
, unop
, 4);
5746 memcpy (p
, nopunop
, 8);
5748 fragp
->fr_fix
+= fix
;
5752 /* The Alpha has support for some VAX floating point types, as well as for
5753 IEEE floating point. We consider IEEE to be the primary floating point
5754 format, and sneak in the VAX floating point support here. */
5755 #define md_atof vax_md_atof
5756 #include "config/atof-vax.c"