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_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_23_PCREL_S2
:
1143 case BFD_RELOC_ALPHA_HINT
:
1144 case BFD_RELOC_ALPHA_BRSGP
:
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's section; we need to drop
1175 in a value which, when added to the address of the start of
1176 the function, 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
:
1508 return S_FORCE_RELOC (f
->fx_addsy
);
1511 /* Return true if we can partially resolve a relocation now. */
1514 alpha_fix_adjustable (f
)
1517 /* Are there any relocation types for which we must generate a reloc
1518 but we can adjust the values contained within it? */
1519 switch (f
->fx_r_type
)
1521 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1522 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1523 case BFD_RELOC_ALPHA_GPDISP
:
1524 case BFD_RELOC_ALPHA_BRSGP
:
1527 case BFD_RELOC_ALPHA_LITERAL
:
1528 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1529 case BFD_RELOC_ALPHA_LITUSE
:
1530 case BFD_RELOC_ALPHA_LINKAGE
:
1531 case BFD_RELOC_ALPHA_CODEADDR
:
1534 case BFD_RELOC_VTABLE_ENTRY
:
1535 case BFD_RELOC_VTABLE_INHERIT
:
1538 case BFD_RELOC_GPREL16
:
1539 case BFD_RELOC_GPREL32
:
1540 case BFD_RELOC_ALPHA_GPREL_HI16
:
1541 case BFD_RELOC_ALPHA_GPREL_LO16
:
1542 case BFD_RELOC_23_PCREL_S2
:
1545 case BFD_RELOC_ALPHA_HINT
:
1548 case BFD_RELOC_ALPHA_TLSGD
:
1549 case BFD_RELOC_ALPHA_TLSLDM
:
1550 case BFD_RELOC_ALPHA_GOTDTPREL16
:
1551 case BFD_RELOC_ALPHA_DTPREL_HI16
:
1552 case BFD_RELOC_ALPHA_DTPREL_LO16
:
1553 case BFD_RELOC_ALPHA_DTPREL16
:
1554 case BFD_RELOC_ALPHA_GOTTPREL16
:
1555 case BFD_RELOC_ALPHA_TPREL_HI16
:
1556 case BFD_RELOC_ALPHA_TPREL_LO16
:
1557 case BFD_RELOC_ALPHA_TPREL16
:
1558 /* ??? No idea why we can't return a reference to .tbss+10, but
1559 we're preventing this in the other assemblers. Follow for now. */
1568 /* Generate the BFD reloc to be stuck in the object file from the
1569 fixup used internally in the assembler. */
1572 tc_gen_reloc (sec
, fixp
)
1573 asection
*sec ATTRIBUTE_UNUSED
;
1578 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
1579 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
1580 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
1581 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
1583 /* Make sure none of our internal relocations make it this far.
1584 They'd better have been fully resolved by this point. */
1585 assert ((int) fixp
->fx_r_type
> 0);
1587 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
1588 if (reloc
->howto
== NULL
)
1590 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1591 _("cannot represent `%s' relocation in object file"),
1592 bfd_get_reloc_code_name (fixp
->fx_r_type
));
1596 if (!fixp
->fx_pcrel
!= !reloc
->howto
->pc_relative
)
1598 as_fatal (_("internal error? cannot generate `%s' relocation"),
1599 bfd_get_reloc_code_name (fixp
->fx_r_type
));
1601 assert (!fixp
->fx_pcrel
== !reloc
->howto
->pc_relative
);
1604 if (fixp
->fx_r_type
== BFD_RELOC_ALPHA_LITERAL
)
1606 /* Fake out bfd_perform_relocation. sigh. */
1607 reloc
->addend
= -alpha_gp_value
;
1612 reloc
->addend
= fixp
->fx_offset
;
1614 /* Ohhh, this is ugly. The problem is that if this is a local global
1615 symbol, the relocation will entirely be performed at link time, not
1616 at assembly time. bfd_perform_reloc doesn't know about this sort
1617 of thing, and as a result we need to fake it out here. */
1618 if ((S_IS_EXTERN (fixp
->fx_addsy
) || S_IS_WEAK (fixp
->fx_addsy
)
1619 || (S_GET_SEGMENT (fixp
->fx_addsy
)->flags
& SEC_MERGE
)
1620 || (S_GET_SEGMENT (fixp
->fx_addsy
)->flags
& SEC_THREAD_LOCAL
))
1621 && !S_IS_COMMON (fixp
->fx_addsy
))
1622 reloc
->addend
-= symbol_get_bfdsym (fixp
->fx_addsy
)->value
;
1629 /* Parse a register name off of the input_line and return a register
1630 number. Gets md_undefined_symbol above to do the register name
1633 Only called as a part of processing the ECOFF .frame directive. */
1636 tc_get_register (frame
)
1637 int frame ATTRIBUTE_UNUSED
;
1639 int framereg
= AXP_REG_SP
;
1642 if (*input_line_pointer
== '$')
1644 char *s
= input_line_pointer
;
1645 char c
= get_symbol_end ();
1646 symbolS
*sym
= md_undefined_symbol (s
);
1648 *strchr (s
, '\0') = c
;
1649 if (sym
&& (framereg
= S_GET_VALUE (sym
)) <= 31)
1652 as_warn (_("frame reg expected, using $%d."), framereg
);
1655 note_gpreg (framereg
);
1659 /* This is called before the symbol table is processed. In order to
1660 work with gcc when using mips-tfile, we must keep all local labels.
1661 However, in other cases, we want to discard them. If we were
1662 called with -g, but we didn't see any debugging information, it may
1663 mean that gcc is smuggling debugging information through to
1664 mips-tfile, in which case we must generate all local labels. */
1669 alpha_frob_file_before_adjust ()
1671 if (alpha_debug
!= 0
1672 && ! ecoff_debugging_seen
)
1673 flag_keep_locals
= 1;
1676 #endif /* OBJ_ECOFF */
1678 static struct alpha_reloc_tag
*
1679 get_alpha_reloc_tag (sequence
)
1682 char buffer
[ALPHA_RELOC_DIGITS
];
1683 struct alpha_reloc_tag
*info
;
1685 sprintf (buffer
, "!%ld", sequence
);
1687 info
= (struct alpha_reloc_tag
*) hash_find (alpha_literal_hash
, buffer
);
1690 size_t len
= strlen (buffer
);
1693 info
= (struct alpha_reloc_tag
*)
1694 xcalloc (sizeof (struct alpha_reloc_tag
) + len
, 1);
1696 info
->segment
= now_seg
;
1697 info
->sequence
= sequence
;
1698 strcpy (info
->string
, buffer
);
1699 errmsg
= hash_insert (alpha_literal_hash
, info
->string
, (PTR
) info
);
1707 /* Before the relocations are written, reorder them, so that user
1708 supplied !lituse relocations follow the appropriate !literal
1709 relocations, and similarly for !gpdisp relocations. */
1714 if (alpha_literal_hash
)
1715 bfd_map_over_sections (stdoutput
, alpha_adjust_relocs
, NULL
);
1719 alpha_adjust_relocs (abfd
, sec
, ptr
)
1720 bfd
*abfd ATTRIBUTE_UNUSED
;
1722 PTR ptr ATTRIBUTE_UNUSED
;
1724 segment_info_type
*seginfo
= seg_info (sec
);
1730 /* If seginfo is NULL, we did not create this section; don't do
1731 anything with it. By using a pointer to a pointer, we can update
1732 the links in place. */
1733 if (seginfo
== NULL
)
1736 /* If there are no relocations, skip the section. */
1737 if (! seginfo
->fix_root
)
1740 /* First rebuild the fixup chain without the expicit lituse and
1741 gpdisp_lo16 relocs. */
1742 prevP
= &seginfo
->fix_root
;
1743 for (fixp
= seginfo
->fix_root
; fixp
; fixp
= next
)
1745 next
= fixp
->fx_next
;
1746 fixp
->fx_next
= (fixS
*) 0;
1748 switch (fixp
->fx_r_type
)
1750 case BFD_RELOC_ALPHA_LITUSE
:
1751 if (fixp
->tc_fix_data
.info
->n_master
== 0)
1752 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1753 _("No !literal!%ld was found"),
1754 fixp
->tc_fix_data
.info
->sequence
);
1756 if (fixp
->fx_offset
== LITUSE_ALPHA_TLSGD
)
1758 if (! fixp
->tc_fix_data
.info
->saw_tlsgd
)
1759 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1760 _("No !tlsgd!%ld was found"),
1761 fixp
->tc_fix_data
.info
->sequence
);
1763 else if (fixp
->fx_offset
== LITUSE_ALPHA_TLSLDM
)
1765 if (! fixp
->tc_fix_data
.info
->saw_tlsldm
)
1766 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1767 _("No !tlsldm!%ld was found"),
1768 fixp
->tc_fix_data
.info
->sequence
);
1773 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1774 if (fixp
->tc_fix_data
.info
->n_master
== 0)
1775 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1776 _("No ldah !gpdisp!%ld was found"),
1777 fixp
->tc_fix_data
.info
->sequence
);
1780 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1781 if (fixp
->tc_fix_data
.info
1782 && (fixp
->tc_fix_data
.info
->saw_tlsgd
1783 || fixp
->tc_fix_data
.info
->saw_tlsldm
))
1789 prevP
= &fixp
->fx_next
;
1794 /* Go back and re-chain dependent relocations. They are currently
1795 linked through the next_reloc field in reverse order, so as we
1796 go through the next_reloc chain, we effectively reverse the chain
1799 Except if there is more than one !literal for a given sequence
1800 number. In that case, the programmer and/or compiler is not sure
1801 how control flows from literal to lituse, and we can't be sure to
1802 get the relaxation correct.
1804 ??? Well, actually we could, if there are enough lituses such that
1805 we can make each literal have at least one of each lituse type
1806 present. Not implemented.
1808 Also suppress the optimization if the !literals/!lituses are spread
1809 in different segments. This can happen with "intersting" uses of
1810 inline assembly; examples are present in the Linux kernel semaphores. */
1812 for (fixp
= seginfo
->fix_root
; fixp
; fixp
= next
)
1814 next
= fixp
->fx_next
;
1815 switch (fixp
->fx_r_type
)
1817 case BFD_RELOC_ALPHA_TLSGD
:
1818 case BFD_RELOC_ALPHA_TLSLDM
:
1819 if (!fixp
->tc_fix_data
.info
)
1821 if (fixp
->tc_fix_data
.info
->n_master
== 0)
1823 else if (fixp
->tc_fix_data
.info
->n_master
> 1)
1825 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1826 _("too many !literal!%ld for %s"),
1827 fixp
->tc_fix_data
.info
->sequence
,
1828 (fixp
->fx_r_type
== BFD_RELOC_ALPHA_TLSGD
1829 ? "!tlsgd" : "!tlsldm"));
1833 fixp
->tc_fix_data
.info
->master
->fx_next
= fixp
->fx_next
;
1834 fixp
->fx_next
= fixp
->tc_fix_data
.info
->master
;
1835 fixp
= fixp
->fx_next
;
1838 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1839 if (fixp
->tc_fix_data
.info
1840 && fixp
->tc_fix_data
.info
->n_master
== 1
1841 && ! fixp
->tc_fix_data
.info
->multi_section_p
)
1843 for (slave
= fixp
->tc_fix_data
.info
->slaves
;
1844 slave
!= (fixS
*) 0;
1845 slave
= slave
->tc_fix_data
.next_reloc
)
1847 slave
->fx_next
= fixp
->fx_next
;
1848 fixp
->fx_next
= slave
;
1853 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1854 if (fixp
->tc_fix_data
.info
->n_slaves
== 0)
1855 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1856 _("No lda !gpdisp!%ld was found"),
1857 fixp
->tc_fix_data
.info
->sequence
);
1860 slave
= fixp
->tc_fix_data
.info
->slaves
;
1861 slave
->fx_next
= next
;
1862 fixp
->fx_next
= slave
;
1874 debug_exp (tok
, ntok
)
1880 fprintf (stderr
, "debug_exp: %d tokens", ntok
);
1881 for (i
= 0; i
< ntok
; i
++)
1883 expressionS
*t
= &tok
[i
];
1888 default: name
= "unknown"; break;
1889 case O_illegal
: name
= "O_illegal"; break;
1890 case O_absent
: name
= "O_absent"; break;
1891 case O_constant
: name
= "O_constant"; break;
1892 case O_symbol
: name
= "O_symbol"; break;
1893 case O_symbol_rva
: name
= "O_symbol_rva"; break;
1894 case O_register
: name
= "O_register"; break;
1895 case O_big
: name
= "O_big"; break;
1896 case O_uminus
: name
= "O_uminus"; break;
1897 case O_bit_not
: name
= "O_bit_not"; break;
1898 case O_logical_not
: name
= "O_logical_not"; break;
1899 case O_multiply
: name
= "O_multiply"; break;
1900 case O_divide
: name
= "O_divide"; break;
1901 case O_modulus
: name
= "O_modulus"; break;
1902 case O_left_shift
: name
= "O_left_shift"; break;
1903 case O_right_shift
: name
= "O_right_shift"; break;
1904 case O_bit_inclusive_or
: name
= "O_bit_inclusive_or"; break;
1905 case O_bit_or_not
: name
= "O_bit_or_not"; break;
1906 case O_bit_exclusive_or
: name
= "O_bit_exclusive_or"; break;
1907 case O_bit_and
: name
= "O_bit_and"; break;
1908 case O_add
: name
= "O_add"; break;
1909 case O_subtract
: name
= "O_subtract"; break;
1910 case O_eq
: name
= "O_eq"; break;
1911 case O_ne
: name
= "O_ne"; break;
1912 case O_lt
: name
= "O_lt"; break;
1913 case O_le
: name
= "O_le"; break;
1914 case O_ge
: name
= "O_ge"; break;
1915 case O_gt
: name
= "O_gt"; break;
1916 case O_logical_and
: name
= "O_logical_and"; break;
1917 case O_logical_or
: name
= "O_logical_or"; break;
1918 case O_index
: name
= "O_index"; break;
1919 case O_pregister
: name
= "O_pregister"; break;
1920 case O_cpregister
: name
= "O_cpregister"; break;
1921 case O_literal
: name
= "O_literal"; break;
1922 case O_lituse_addr
: name
= "O_lituse_addr"; break;
1923 case O_lituse_base
: name
= "O_lituse_base"; break;
1924 case O_lituse_bytoff
: name
= "O_lituse_bytoff"; break;
1925 case O_lituse_jsr
: name
= "O_lituse_jsr"; break;
1926 case O_lituse_tlsgd
: name
= "O_lituse_tlsgd"; break;
1927 case O_lituse_tlsldm
: name
= "O_lituse_tlsldm"; break;
1928 case O_gpdisp
: name
= "O_gpdisp"; break;
1929 case O_gprelhigh
: name
= "O_gprelhigh"; break;
1930 case O_gprellow
: name
= "O_gprellow"; break;
1931 case O_gprel
: name
= "O_gprel"; break;
1932 case O_samegp
: name
= "O_samegp"; break;
1933 case O_tlsgd
: name
= "O_tlsgd"; break;
1934 case O_tlsldm
: name
= "O_tlsldm"; break;
1935 case O_gotdtprel
: name
= "O_gotdtprel"; break;
1936 case O_dtprelhi
: name
= "O_dtprelhi"; break;
1937 case O_dtprello
: name
= "O_dtprello"; break;
1938 case O_dtprel
: name
= "O_dtprel"; break;
1939 case O_gottprel
: name
= "O_gottprel"; break;
1940 case O_tprelhi
: name
= "O_tprelhi"; break;
1941 case O_tprello
: name
= "O_tprello"; break;
1942 case O_tprel
: name
= "O_tprel"; break;
1945 fprintf (stderr
, ", %s(%s, %s, %d)", name
,
1946 (t
->X_add_symbol
) ? S_GET_NAME (t
->X_add_symbol
) : "--",
1947 (t
->X_op_symbol
) ? S_GET_NAME (t
->X_op_symbol
) : "--",
1948 (int) t
->X_add_number
);
1950 fprintf (stderr
, "\n");
1955 /* Parse the arguments to an opcode. */
1958 tokenize_arguments (str
, tok
, ntok
)
1963 expressionS
*end_tok
= tok
+ ntok
;
1964 char *old_input_line_pointer
;
1965 int saw_comma
= 0, saw_arg
= 0;
1967 expressionS
*orig_tok
= tok
;
1971 const struct alpha_reloc_op_tag
*r
;
1974 int reloc_found_p
= 0;
1977 memset (tok
, 0, sizeof (*tok
) * ntok
);
1979 /* Save and restore input_line_pointer around this function. */
1980 old_input_line_pointer
= input_line_pointer
;
1981 input_line_pointer
= str
;
1984 /* ??? Wrest control of ! away from the regular expression parser. */
1985 is_end_of_line
[(unsigned char) '!'] = 1;
1988 while (tok
< end_tok
&& *input_line_pointer
)
1991 switch (*input_line_pointer
)
1998 /* A relocation operand can be placed after the normal operand on an
1999 assembly language statement, and has the following form:
2000 !relocation_type!sequence_number. */
2003 /* Only support one relocation op per insn. */
2004 as_bad (_("More than one relocation op per insn"));
2011 ++input_line_pointer
;
2013 p
= input_line_pointer
;
2014 c
= get_symbol_end ();
2016 /* Parse !relocation_type. */
2017 len
= input_line_pointer
- p
;
2020 as_bad (_("No relocation operand"));
2024 r
= &alpha_reloc_op
[0];
2025 for (i
= alpha_num_reloc_op
- 1; i
>= 0; i
--, r
++)
2026 if (len
== r
->length
&& memcmp (p
, r
->name
, len
) == 0)
2030 as_bad (_("Unknown relocation operand: !%s"), p
);
2034 *input_line_pointer
= c
;
2036 if (*input_line_pointer
!= '!')
2040 as_bad (_("no sequence number after !%s"), p
);
2044 tok
->X_add_number
= 0;
2050 as_bad (_("!%s does not use a sequence number"), p
);
2054 input_line_pointer
++;
2056 /* Parse !sequence_number. */
2058 if (tok
->X_op
!= O_constant
|| tok
->X_add_number
<= 0)
2060 as_bad (_("Bad sequence number: !%s!%s"),
2061 r
->name
, input_line_pointer
);
2070 #endif /* RELOC_OP_P */
2073 ++input_line_pointer
;
2074 if (saw_comma
|| !saw_arg
)
2081 char *hold
= input_line_pointer
++;
2083 /* First try for parenthesized register ... */
2085 if (*input_line_pointer
== ')' && tok
->X_op
== O_register
)
2087 tok
->X_op
= (saw_comma
? O_cpregister
: O_pregister
);
2090 ++input_line_pointer
;
2095 /* ... then fall through to plain expression. */
2096 input_line_pointer
= hold
;
2100 if (saw_arg
&& !saw_comma
)
2104 if (tok
->X_op
== O_illegal
|| tok
->X_op
== O_absent
)
2117 input_line_pointer
= old_input_line_pointer
;
2120 debug_exp (orig_tok
, ntok
- (end_tok
- tok
));
2123 is_end_of_line
[(unsigned char) '!'] = 0;
2126 return ntok
- (end_tok
- tok
);
2130 is_end_of_line
[(unsigned char) '!'] = 0;
2132 input_line_pointer
= old_input_line_pointer
;
2133 return TOKENIZE_ERROR
;
2137 is_end_of_line
[(unsigned char) '!'] = 0;
2139 input_line_pointer
= old_input_line_pointer
;
2140 return TOKENIZE_ERROR_REPORT
;
2143 /* Search forward through all variants of an opcode looking for a
2146 static const struct alpha_opcode
*
2147 find_opcode_match (first_opcode
, tok
, pntok
, pcpumatch
)
2148 const struct alpha_opcode
*first_opcode
;
2149 const expressionS
*tok
;
2153 const struct alpha_opcode
*opcode
= first_opcode
;
2155 int got_cpu_match
= 0;
2159 const unsigned char *opidx
;
2162 /* Don't match opcodes that don't exist on this architecture. */
2163 if (!(opcode
->flags
& alpha_target
))
2168 for (opidx
= opcode
->operands
; *opidx
; ++opidx
)
2170 const struct alpha_operand
*operand
= &alpha_operands
[*opidx
];
2172 /* Only take input from real operands. */
2173 if (operand
->flags
& AXP_OPERAND_FAKE
)
2176 /* When we expect input, make sure we have it. */
2179 if ((operand
->flags
& AXP_OPERAND_OPTIONAL_MASK
) == 0)
2184 /* Match operand type with expression type. */
2185 switch (operand
->flags
& AXP_OPERAND_TYPECHECK_MASK
)
2187 case AXP_OPERAND_IR
:
2188 if (tok
[tokidx
].X_op
!= O_register
2189 || !is_ir_num (tok
[tokidx
].X_add_number
))
2192 case AXP_OPERAND_FPR
:
2193 if (tok
[tokidx
].X_op
!= O_register
2194 || !is_fpr_num (tok
[tokidx
].X_add_number
))
2197 case AXP_OPERAND_IR
| AXP_OPERAND_PARENS
:
2198 if (tok
[tokidx
].X_op
!= O_pregister
2199 || !is_ir_num (tok
[tokidx
].X_add_number
))
2202 case AXP_OPERAND_IR
| AXP_OPERAND_PARENS
| AXP_OPERAND_COMMA
:
2203 if (tok
[tokidx
].X_op
!= O_cpregister
2204 || !is_ir_num (tok
[tokidx
].X_add_number
))
2208 case AXP_OPERAND_RELATIVE
:
2209 case AXP_OPERAND_SIGNED
:
2210 case AXP_OPERAND_UNSIGNED
:
2211 switch (tok
[tokidx
].X_op
)
2226 /* Everything else should have been fake. */
2232 /* Possible match -- did we use all of our input? */
2241 while (++opcode
- alpha_opcodes
< (int) alpha_num_opcodes
2242 && !strcmp (opcode
->name
, first_opcode
->name
));
2245 *pcpumatch
= got_cpu_match
;
2250 /* Search forward through all variants of a macro looking for a syntax
2253 static const struct alpha_macro
*
2254 find_macro_match (first_macro
, tok
, pntok
)
2255 const struct alpha_macro
*first_macro
;
2256 const expressionS
*tok
;
2259 const struct alpha_macro
*macro
= first_macro
;
2264 const enum alpha_macro_arg
*arg
= macro
->argsets
;
2278 /* Index register. */
2280 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_register
2281 || !is_ir_num (tok
[tokidx
].X_add_number
))
2286 /* Parenthesized index register. */
2288 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_pregister
2289 || !is_ir_num (tok
[tokidx
].X_add_number
))
2294 /* Optional parenthesized index register. */
2296 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_pregister
2297 && is_ir_num (tok
[tokidx
].X_add_number
))
2301 /* Leading comma with a parenthesized index register. */
2303 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_cpregister
2304 || !is_ir_num (tok
[tokidx
].X_add_number
))
2309 /* Floating point register. */
2311 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_register
2312 || !is_fpr_num (tok
[tokidx
].X_add_number
))
2317 /* Normal expression. */
2321 switch (tok
[tokidx
].X_op
)
2330 case O_lituse_bytoff
:
2346 while (*arg
!= MACRO_EOA
)
2354 while (++macro
- alpha_macros
< (int) alpha_num_macros
2355 && !strcmp (macro
->name
, first_macro
->name
));
2360 /* Insert an operand value into an instruction. */
2363 insert_operand (insn
, operand
, val
, file
, line
)
2365 const struct alpha_operand
*operand
;
2370 if (operand
->bits
!= 32 && !(operand
->flags
& AXP_OPERAND_NOOVERFLOW
))
2374 if (operand
->flags
& AXP_OPERAND_SIGNED
)
2376 max
= (1 << (operand
->bits
- 1)) - 1;
2377 min
= -(1 << (operand
->bits
- 1));
2381 max
= (1 << operand
->bits
) - 1;
2385 if (val
< min
|| val
> max
)
2388 _("operand out of range (%s not between %d and %d)");
2389 char buf
[sizeof (val
) * 3 + 2];
2391 sprint_value (buf
, val
);
2393 as_warn_where (file
, line
, err
, buf
, min
, max
);
2395 as_warn (err
, buf
, min
, max
);
2399 if (operand
->insert
)
2401 const char *errmsg
= NULL
;
2403 insn
= (*operand
->insert
) (insn
, val
, &errmsg
);
2408 insn
|= ((val
& ((1 << operand
->bits
) - 1)) << operand
->shift
);
2413 /* Turn an opcode description and a set of arguments into
2414 an instruction and a fixup. */
2417 assemble_insn (opcode
, tok
, ntok
, insn
, reloc
)
2418 const struct alpha_opcode
*opcode
;
2419 const expressionS
*tok
;
2421 struct alpha_insn
*insn
;
2422 bfd_reloc_code_real_type reloc
;
2424 const struct alpha_operand
*reloc_operand
= NULL
;
2425 const expressionS
*reloc_exp
= NULL
;
2426 const unsigned char *argidx
;
2430 memset (insn
, 0, sizeof (*insn
));
2431 image
= opcode
->opcode
;
2433 for (argidx
= opcode
->operands
; *argidx
; ++argidx
)
2435 const struct alpha_operand
*operand
= &alpha_operands
[*argidx
];
2436 const expressionS
*t
= (const expressionS
*) 0;
2438 if (operand
->flags
& AXP_OPERAND_FAKE
)
2440 /* fake operands take no value and generate no fixup */
2441 image
= insert_operand (image
, operand
, 0, NULL
, 0);
2447 switch (operand
->flags
& AXP_OPERAND_OPTIONAL_MASK
)
2449 case AXP_OPERAND_DEFAULT_FIRST
:
2452 case AXP_OPERAND_DEFAULT_SECOND
:
2455 case AXP_OPERAND_DEFAULT_ZERO
:
2457 static expressionS zero_exp
;
2459 zero_exp
.X_op
= O_constant
;
2460 zero_exp
.X_unsigned
= 1;
2475 image
= insert_operand (image
, operand
, regno (t
->X_add_number
),
2480 image
= insert_operand (image
, operand
, t
->X_add_number
, NULL
, 0);
2481 assert (reloc_operand
== NULL
);
2482 reloc_operand
= operand
;
2487 /* This is only 0 for fields that should contain registers,
2488 which means this pattern shouldn't have matched. */
2489 if (operand
->default_reloc
== 0)
2492 /* There is one special case for which an insn receives two
2493 relocations, and thus the user-supplied reloc does not
2494 override the operand reloc. */
2495 if (operand
->default_reloc
== BFD_RELOC_ALPHA_HINT
)
2497 struct alpha_fixup
*fixup
;
2499 if (insn
->nfixups
>= MAX_INSN_FIXUPS
)
2500 as_fatal (_("too many fixups"));
2502 fixup
= &insn
->fixups
[insn
->nfixups
++];
2504 fixup
->reloc
= BFD_RELOC_ALPHA_HINT
;
2508 if (reloc
== BFD_RELOC_UNUSED
)
2509 reloc
= operand
->default_reloc
;
2511 assert (reloc_operand
== NULL
);
2512 reloc_operand
= operand
;
2519 if (reloc
!= BFD_RELOC_UNUSED
)
2521 struct alpha_fixup
*fixup
;
2523 if (insn
->nfixups
>= MAX_INSN_FIXUPS
)
2524 as_fatal (_("too many fixups"));
2526 /* ??? My but this is hacky. But the OSF/1 assembler uses the same
2527 relocation tag for both ldah and lda with gpdisp. Choose the
2528 correct internal relocation based on the opcode. */
2529 if (reloc
== BFD_RELOC_ALPHA_GPDISP
)
2531 if (strcmp (opcode
->name
, "ldah") == 0)
2532 reloc
= BFD_RELOC_ALPHA_GPDISP_HI16
;
2533 else if (strcmp (opcode
->name
, "lda") == 0)
2534 reloc
= BFD_RELOC_ALPHA_GPDISP_LO16
;
2536 as_bad (_("invalid relocation for instruction"));
2539 /* If this is a real relocation (as opposed to a lituse hint), then
2540 the relocation width should match the operand width. */
2541 else if (reloc
< BFD_RELOC_UNUSED
)
2543 reloc_howto_type
*reloc_howto
2544 = bfd_reloc_type_lookup (stdoutput
, reloc
);
2545 if (reloc_howto
->bitsize
!= reloc_operand
->bits
)
2547 as_bad (_("invalid relocation for field"));
2552 fixup
= &insn
->fixups
[insn
->nfixups
++];
2554 fixup
->exp
= *reloc_exp
;
2556 fixup
->exp
.X_op
= O_absent
;
2557 fixup
->reloc
= reloc
;
2563 /* Actually output an instruction with its fixup. */
2567 struct alpha_insn
*insn
;
2572 /* Take care of alignment duties. */
2573 if (alpha_auto_align_on
&& alpha_current_align
< 2)
2574 alpha_align (2, (char *) NULL
, alpha_insn_label
, 0);
2575 if (alpha_current_align
> 2)
2576 alpha_current_align
= 2;
2577 alpha_insn_label
= NULL
;
2579 /* Write out the instruction. */
2581 md_number_to_chars (f
, insn
->insn
, 4);
2584 dwarf2_emit_insn (4);
2587 /* Apply the fixups in order. */
2588 for (i
= 0; i
< insn
->nfixups
; ++i
)
2590 const struct alpha_operand
*operand
= (const struct alpha_operand
*) 0;
2591 struct alpha_fixup
*fixup
= &insn
->fixups
[i
];
2592 struct alpha_reloc_tag
*info
= NULL
;
2596 /* Some fixups are only used internally and so have no howto. */
2597 if ((int) fixup
->reloc
< 0)
2599 operand
= &alpha_operands
[-(int) fixup
->reloc
];
2601 pcrel
= ((operand
->flags
& AXP_OPERAND_RELATIVE
) != 0);
2603 else if (fixup
->reloc
> BFD_RELOC_UNUSED
2604 || fixup
->reloc
== BFD_RELOC_ALPHA_GPDISP_HI16
2605 || fixup
->reloc
== BFD_RELOC_ALPHA_GPDISP_LO16
)
2612 reloc_howto_type
*reloc_howto
2613 = bfd_reloc_type_lookup (stdoutput
, fixup
->reloc
);
2614 assert (reloc_howto
);
2616 size
= bfd_get_reloc_size (reloc_howto
);
2617 assert (size
>= 1 && size
<= 4);
2619 pcrel
= reloc_howto
->pc_relative
;
2622 fixP
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, size
,
2623 &fixup
->exp
, pcrel
, fixup
->reloc
);
2625 /* Turn off complaints that the addend is too large for some fixups,
2626 and copy in the sequence number for the explicit relocations. */
2627 switch (fixup
->reloc
)
2629 case BFD_RELOC_ALPHA_HINT
:
2630 case BFD_RELOC_GPREL32
:
2631 case BFD_RELOC_GPREL16
:
2632 case BFD_RELOC_ALPHA_GPREL_HI16
:
2633 case BFD_RELOC_ALPHA_GPREL_LO16
:
2634 case BFD_RELOC_ALPHA_GOTDTPREL16
:
2635 case BFD_RELOC_ALPHA_DTPREL_HI16
:
2636 case BFD_RELOC_ALPHA_DTPREL_LO16
:
2637 case BFD_RELOC_ALPHA_DTPREL16
:
2638 case BFD_RELOC_ALPHA_GOTTPREL16
:
2639 case BFD_RELOC_ALPHA_TPREL_HI16
:
2640 case BFD_RELOC_ALPHA_TPREL_LO16
:
2641 case BFD_RELOC_ALPHA_TPREL16
:
2642 fixP
->fx_no_overflow
= 1;
2645 case BFD_RELOC_ALPHA_GPDISP_HI16
:
2646 fixP
->fx_no_overflow
= 1;
2647 fixP
->fx_addsy
= section_symbol (now_seg
);
2648 fixP
->fx_offset
= 0;
2650 info
= get_alpha_reloc_tag (insn
->sequence
);
2651 if (++info
->n_master
> 1)
2652 as_bad (_("too many ldah insns for !gpdisp!%ld"), insn
->sequence
);
2653 if (info
->segment
!= now_seg
)
2654 as_bad (_("both insns for !gpdisp!%ld must be in the same section"),
2656 fixP
->tc_fix_data
.info
= info
;
2659 case BFD_RELOC_ALPHA_GPDISP_LO16
:
2660 fixP
->fx_no_overflow
= 1;
2662 info
= get_alpha_reloc_tag (insn
->sequence
);
2663 if (++info
->n_slaves
> 1)
2664 as_bad (_("too many lda insns for !gpdisp!%ld"), insn
->sequence
);
2665 if (info
->segment
!= now_seg
)
2666 as_bad (_("both insns for !gpdisp!%ld must be in the same section"),
2668 fixP
->tc_fix_data
.info
= info
;
2669 info
->slaves
= fixP
;
2672 case BFD_RELOC_ALPHA_LITERAL
:
2673 case BFD_RELOC_ALPHA_ELF_LITERAL
:
2674 fixP
->fx_no_overflow
= 1;
2676 if (insn
->sequence
== 0)
2678 info
= get_alpha_reloc_tag (insn
->sequence
);
2679 info
->master
= fixP
;
2681 if (info
->segment
!= now_seg
)
2682 info
->multi_section_p
= 1;
2683 fixP
->tc_fix_data
.info
= info
;
2687 case DUMMY_RELOC_LITUSE_ADDR
:
2688 fixP
->fx_offset
= LITUSE_ALPHA_ADDR
;
2690 case DUMMY_RELOC_LITUSE_BASE
:
2691 fixP
->fx_offset
= LITUSE_ALPHA_BASE
;
2693 case DUMMY_RELOC_LITUSE_BYTOFF
:
2694 fixP
->fx_offset
= LITUSE_ALPHA_BYTOFF
;
2696 case DUMMY_RELOC_LITUSE_JSR
:
2697 fixP
->fx_offset
= LITUSE_ALPHA_JSR
;
2699 case DUMMY_RELOC_LITUSE_TLSGD
:
2700 fixP
->fx_offset
= LITUSE_ALPHA_TLSGD
;
2702 case DUMMY_RELOC_LITUSE_TLSLDM
:
2703 fixP
->fx_offset
= LITUSE_ALPHA_TLSLDM
;
2706 fixP
->fx_addsy
= section_symbol (now_seg
);
2707 fixP
->fx_r_type
= BFD_RELOC_ALPHA_LITUSE
;
2709 info
= get_alpha_reloc_tag (insn
->sequence
);
2710 if (fixup
->reloc
== DUMMY_RELOC_LITUSE_TLSGD
)
2711 info
->saw_lu_tlsgd
= 1;
2712 else if (fixup
->reloc
== DUMMY_RELOC_LITUSE_TLSLDM
)
2713 info
->saw_lu_tlsldm
= 1;
2714 if (++info
->n_slaves
> 1)
2716 if (info
->saw_lu_tlsgd
)
2717 as_bad (_("too many lituse insns for !lituse_tlsgd!%ld"),
2719 else if (info
->saw_lu_tlsldm
)
2720 as_bad (_("too many lituse insns for !lituse_tlsldm!%ld"),
2723 fixP
->tc_fix_data
.info
= info
;
2724 fixP
->tc_fix_data
.next_reloc
= info
->slaves
;
2725 info
->slaves
= fixP
;
2726 if (info
->segment
!= now_seg
)
2727 info
->multi_section_p
= 1;
2730 case BFD_RELOC_ALPHA_TLSGD
:
2731 fixP
->fx_no_overflow
= 1;
2733 if (insn
->sequence
== 0)
2735 info
= get_alpha_reloc_tag (insn
->sequence
);
2736 if (info
->saw_tlsgd
)
2737 as_bad (_("duplicate !tlsgd!%ld"), insn
->sequence
);
2738 else if (info
->saw_tlsldm
)
2739 as_bad (_("sequence number in use for !tlsldm!%ld"),
2742 info
->saw_tlsgd
= 1;
2743 fixP
->tc_fix_data
.info
= info
;
2746 case BFD_RELOC_ALPHA_TLSLDM
:
2747 fixP
->fx_no_overflow
= 1;
2749 if (insn
->sequence
== 0)
2751 info
= get_alpha_reloc_tag (insn
->sequence
);
2752 if (info
->saw_tlsldm
)
2753 as_bad (_("duplicate !tlsldm!%ld"), insn
->sequence
);
2754 else if (info
->saw_tlsgd
)
2755 as_bad (_("sequence number in use for !tlsgd!%ld"),
2758 info
->saw_tlsldm
= 1;
2759 fixP
->tc_fix_data
.info
= info
;
2763 if ((int) fixup
->reloc
< 0)
2765 if (operand
->flags
& AXP_OPERAND_NOOVERFLOW
)
2766 fixP
->fx_no_overflow
= 1;
2773 /* Given an opcode name and a pre-tokenized set of arguments, assemble
2774 the insn, but do not emit it.
2776 Note that this implies no macros allowed, since we can't store more
2777 than one insn in an insn structure. */
2780 assemble_tokens_to_insn (opname
, tok
, ntok
, insn
)
2782 const expressionS
*tok
;
2784 struct alpha_insn
*insn
;
2786 const struct alpha_opcode
*opcode
;
2788 /* search opcodes */
2789 opcode
= (const struct alpha_opcode
*) hash_find (alpha_opcode_hash
, opname
);
2793 opcode
= find_opcode_match (opcode
, tok
, &ntok
, &cpumatch
);
2796 assemble_insn (opcode
, tok
, ntok
, insn
, BFD_RELOC_UNUSED
);
2800 as_bad (_("inappropriate arguments for opcode `%s'"), opname
);
2802 as_bad (_("opcode `%s' not supported for target %s"), opname
,
2806 as_bad (_("unknown opcode `%s'"), opname
);
2809 /* Given an opcode name and a pre-tokenized set of arguments, take the
2810 opcode all the way through emission. */
2813 assemble_tokens (opname
, tok
, ntok
, local_macros_on
)
2815 const expressionS
*tok
;
2817 int local_macros_on
;
2819 int found_something
= 0;
2820 const struct alpha_opcode
*opcode
;
2821 const struct alpha_macro
*macro
;
2823 bfd_reloc_code_real_type reloc
= BFD_RELOC_UNUSED
;
2826 /* If a user-specified relocation is present, this is not a macro. */
2827 if (ntok
&& USER_RELOC_P (tok
[ntok
- 1].X_op
))
2829 reloc
= ALPHA_RELOC_TABLE (tok
[ntok
- 1].X_op
)->reloc
;
2834 if (local_macros_on
)
2836 macro
= ((const struct alpha_macro
*)
2837 hash_find (alpha_macro_hash
, opname
));
2840 found_something
= 1;
2841 macro
= find_macro_match (macro
, tok
, &ntok
);
2844 (*macro
->emit
) (tok
, ntok
, macro
->arg
);
2850 /* Search opcodes. */
2851 opcode
= (const struct alpha_opcode
*) hash_find (alpha_opcode_hash
, opname
);
2854 found_something
= 1;
2855 opcode
= find_opcode_match (opcode
, tok
, &ntok
, &cpumatch
);
2858 struct alpha_insn insn
;
2859 assemble_insn (opcode
, tok
, ntok
, &insn
, reloc
);
2861 /* Copy the sequence number for the reloc from the reloc token. */
2862 if (reloc
!= BFD_RELOC_UNUSED
)
2863 insn
.sequence
= tok
[ntok
].X_add_number
;
2870 if (found_something
)
2873 as_bad (_("inappropriate arguments for opcode `%s'"), opname
);
2875 as_bad (_("opcode `%s' not supported for target %s"), opname
,
2879 as_bad (_("unknown opcode `%s'"), opname
);
2882 /* Some instruction sets indexed by lg(size). */
2883 static const char * const sextX_op
[] = { "sextb", "sextw", "sextl", NULL
};
2884 static const char * const insXl_op
[] = { "insbl", "inswl", "insll", "insql" };
2885 static const char * const insXh_op
[] = { NULL
, "inswh", "inslh", "insqh" };
2886 static const char * const extXl_op
[] = { "extbl", "extwl", "extll", "extql" };
2887 static const char * const extXh_op
[] = { NULL
, "extwh", "extlh", "extqh" };
2888 static const char * const mskXl_op
[] = { "mskbl", "mskwl", "mskll", "mskql" };
2889 static const char * const mskXh_op
[] = { NULL
, "mskwh", "msklh", "mskqh" };
2890 static const char * const stX_op
[] = { "stb", "stw", "stl", "stq" };
2891 static const char * const ldXu_op
[] = { "ldbu", "ldwu", NULL
, NULL
};
2893 /* Implement the ldgp macro. */
2896 emit_ldgp (tok
, ntok
, unused
)
2897 const expressionS
*tok
;
2898 int ntok ATTRIBUTE_UNUSED
;
2899 const PTR unused ATTRIBUTE_UNUSED
;
2904 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
2905 /* from "ldgp r1,n(r2)", generate "ldah r1,X(R2); lda r1,Y(r1)"
2906 with appropriate constants and relocations. */
2907 struct alpha_insn insn
;
2908 expressionS newtok
[3];
2912 if (regno (tok
[2].X_add_number
) == AXP_REG_PV
)
2913 ecoff_set_gp_prolog_size (0);
2917 set_tok_const (newtok
[1], 0);
2920 assemble_tokens_to_insn ("ldah", newtok
, 3, &insn
);
2925 if (addend
.X_op
!= O_constant
)
2926 as_bad (_("can not resolve expression"));
2927 addend
.X_op
= O_symbol
;
2928 addend
.X_add_symbol
= alpha_gp_symbol
;
2932 insn
.fixups
[0].exp
= addend
;
2933 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_GPDISP_HI16
;
2934 insn
.sequence
= next_sequence_num
;
2938 set_tok_preg (newtok
[2], tok
[0].X_add_number
);
2940 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
2943 addend
.X_add_number
+= 4;
2947 insn
.fixups
[0].exp
= addend
;
2948 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_GPDISP_LO16
;
2949 insn
.sequence
= next_sequence_num
--;
2952 #endif /* OBJ_ECOFF || OBJ_ELF */
2957 /* Add symbol+addend to link pool.
2958 Return offset from basesym to entry in link pool.
2960 Add new fixup only if offset isn't 16bit. */
2963 add_to_link_pool (basesym
, sym
, addend
)
2968 segT current_section
= now_seg
;
2969 int current_subsec
= now_subseg
;
2971 bfd_reloc_code_real_type reloc_type
;
2973 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
2976 offset
= - *symbol_get_obj (basesym
);
2978 /* @@ This assumes all entries in a given section will be of the same
2979 size... Probably correct, but unwise to rely on. */
2980 /* This must always be called with the same subsegment. */
2982 if (seginfo
->frchainP
)
2983 for (fixp
= seginfo
->frchainP
->fix_root
;
2984 fixp
!= (fixS
*) NULL
;
2985 fixp
= fixp
->fx_next
, offset
+= 8)
2987 if (fixp
->fx_addsy
== sym
&& fixp
->fx_offset
== addend
)
2989 if (range_signed_16 (offset
))
2996 /* Not found in 16bit signed range. */
2998 subseg_set (alpha_link_section
, 0);
3002 fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, sym
, addend
, 0,
3005 subseg_set (current_section
, current_subsec
);
3006 seginfo
->literal_pool_size
+= 8;
3010 #endif /* OBJ_EVAX */
3012 /* Load a (partial) expression into a target register.
3014 If poffset is not null, after the call it will either contain
3015 O_constant 0, or a 16-bit offset appropriate for any MEM format
3016 instruction. In addition, pbasereg will be modified to point to
3017 the base register to use in that MEM format instruction.
3019 In any case, *pbasereg should contain a base register to add to the
3020 expression. This will normally be either AXP_REG_ZERO or
3021 alpha_gp_register. Symbol addresses will always be loaded via $gp,
3022 so "foo($0)" is interpreted as adding the address of foo to $0;
3023 i.e. "ldq $targ, LIT($gp); addq $targ, $0, $targ". Odd, perhaps,
3024 but this is what OSF/1 does.
3026 If explicit relocations of the form !literal!<number> are allowed,
3027 and used, then explict_reloc with be an expression pointer.
3029 Finally, the return value is nonzero if the calling macro may emit
3030 a LITUSE reloc if otherwise appropriate; the return value is the
3031 sequence number to use. */
3034 load_expression (targreg
, exp
, pbasereg
, poffset
)
3036 const expressionS
*exp
;
3038 expressionS
*poffset
;
3040 long emit_lituse
= 0;
3041 offsetT addend
= exp
->X_add_number
;
3042 int basereg
= *pbasereg
;
3043 struct alpha_insn insn
;
3044 expressionS newtok
[3];
3053 /* Attempt to reduce .lit load by splitting the offset from
3054 its symbol when possible, but don't create a situation in
3056 if (!range_signed_32 (addend
) &&
3057 (alpha_noat_on
|| targreg
== AXP_REG_AT
))
3059 lit
= add_to_literal_pool (exp
->X_add_symbol
, addend
,
3060 alpha_lita_section
, 8);
3065 lit
= add_to_literal_pool (exp
->X_add_symbol
, 0,
3066 alpha_lita_section
, 8);
3070 as_fatal (_("overflow in literal (.lita) table"));
3072 /* emit "ldq r, lit(gp)" */
3074 if (basereg
!= alpha_gp_register
&& targreg
== basereg
)
3077 as_bad (_("macro requires $at register while noat in effect"));
3078 if (targreg
== AXP_REG_AT
)
3079 as_bad (_("macro requires $at while $at in use"));
3081 set_tok_reg (newtok
[0], AXP_REG_AT
);
3084 set_tok_reg (newtok
[0], targreg
);
3085 set_tok_sym (newtok
[1], alpha_lita_symbol
, lit
);
3086 set_tok_preg (newtok
[2], alpha_gp_register
);
3088 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
3090 assert (insn
.nfixups
== 1);
3091 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITERAL
;
3092 insn
.sequence
= emit_lituse
= next_sequence_num
--;
3093 #endif /* OBJ_ECOFF */
3095 /* emit "ldq r, gotoff(gp)" */
3097 if (basereg
!= alpha_gp_register
&& targreg
== basereg
)
3100 as_bad (_("macro requires $at register while noat in effect"));
3101 if (targreg
== AXP_REG_AT
)
3102 as_bad (_("macro requires $at while $at in use"));
3104 set_tok_reg (newtok
[0], AXP_REG_AT
);
3107 set_tok_reg (newtok
[0], targreg
);
3109 /* XXX: Disable this .got minimizing optimization so that we can get
3110 better instruction offset knowledge in the compiler. This happens
3111 very infrequently anyway. */
3113 || (!range_signed_32 (addend
)
3114 && (alpha_noat_on
|| targreg
== AXP_REG_AT
)))
3121 set_tok_sym (newtok
[1], exp
->X_add_symbol
, 0);
3124 set_tok_preg (newtok
[2], alpha_gp_register
);
3126 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
3128 assert (insn
.nfixups
== 1);
3129 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_ELF_LITERAL
;
3130 insn
.sequence
= emit_lituse
= next_sequence_num
--;
3131 #endif /* OBJ_ELF */
3135 /* Find symbol or symbol pointer in link section. */
3137 if (exp
->X_add_symbol
== alpha_evax_proc
.symbol
)
3139 if (range_signed_16 (addend
))
3141 set_tok_reg (newtok
[0], targreg
);
3142 set_tok_const (newtok
[1], addend
);
3143 set_tok_preg (newtok
[2], basereg
);
3144 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
3149 set_tok_reg (newtok
[0], targreg
);
3150 set_tok_const (newtok
[1], 0);
3151 set_tok_preg (newtok
[2], basereg
);
3152 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
3157 if (!range_signed_32 (addend
))
3159 link
= add_to_link_pool (alpha_evax_proc
.symbol
,
3160 exp
->X_add_symbol
, addend
);
3165 link
= add_to_link_pool (alpha_evax_proc
.symbol
,
3166 exp
->X_add_symbol
, 0);
3168 set_tok_reg (newtok
[0], targreg
);
3169 set_tok_const (newtok
[1], link
);
3170 set_tok_preg (newtok
[2], basereg
);
3171 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
3173 #endif /* OBJ_EVAX */
3178 if (basereg
!= alpha_gp_register
&& basereg
!= AXP_REG_ZERO
)
3180 /* emit "addq r, base, r" */
3182 set_tok_reg (newtok
[1], basereg
);
3183 set_tok_reg (newtok
[2], targreg
);
3184 assemble_tokens ("addq", newtok
, 3, 0);
3196 /* Assume that this difference expression will be resolved to an
3197 absolute value and that that value will fit in 16 bits. */
3199 set_tok_reg (newtok
[0], targreg
);
3201 set_tok_preg (newtok
[2], basereg
);
3202 assemble_tokens ("lda", newtok
, 3, 0);
3205 set_tok_const (*poffset
, 0);
3209 if (exp
->X_add_number
> 0)
3210 as_bad (_("bignum invalid; zero assumed"));
3212 as_bad (_("floating point number invalid; zero assumed"));
3217 as_bad (_("can't handle expression"));
3222 if (!range_signed_32 (addend
))
3225 long seq_num
= next_sequence_num
--;
3227 /* For 64-bit addends, just put it in the literal pool. */
3230 /* emit "ldq targreg, lit(basereg)" */
3231 lit
= add_to_link_pool (alpha_evax_proc
.symbol
,
3232 section_symbol (absolute_section
), addend
);
3233 set_tok_reg (newtok
[0], targreg
);
3234 set_tok_const (newtok
[1], lit
);
3235 set_tok_preg (newtok
[2], alpha_gp_register
);
3236 assemble_tokens ("ldq", newtok
, 3, 0);
3239 if (alpha_lit8_section
== NULL
)
3241 create_literal_section (".lit8",
3242 &alpha_lit8_section
,
3243 &alpha_lit8_symbol
);
3246 alpha_lit8_literal
= add_to_literal_pool (alpha_lit8_symbol
, 0x8000,
3247 alpha_lita_section
, 8);
3248 if (alpha_lit8_literal
>= 0x8000)
3249 as_fatal (_("overflow in literal (.lita) table"));
3253 lit
= add_to_literal_pool (NULL
, addend
, alpha_lit8_section
, 8) - 0x8000;
3255 as_fatal (_("overflow in literal (.lit8) table"));
3257 /* emit "lda litreg, .lit8+0x8000" */
3259 if (targreg
== basereg
)
3262 as_bad (_("macro requires $at register while noat in effect"));
3263 if (targreg
== AXP_REG_AT
)
3264 as_bad (_("macro requires $at while $at in use"));
3266 set_tok_reg (newtok
[0], AXP_REG_AT
);
3269 set_tok_reg (newtok
[0], targreg
);
3271 set_tok_sym (newtok
[1], alpha_lita_symbol
, alpha_lit8_literal
);
3274 set_tok_sym (newtok
[1], alpha_lit8_symbol
, 0x8000);
3276 set_tok_preg (newtok
[2], alpha_gp_register
);
3278 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
3280 assert (insn
.nfixups
== 1);
3282 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITERAL
;
3285 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_ELF_LITERAL
;
3287 insn
.sequence
= seq_num
;
3291 /* emit "ldq litreg, lit(litreg)" */
3293 set_tok_const (newtok
[1], lit
);
3294 set_tok_preg (newtok
[2], newtok
[0].X_add_number
);
3296 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
3298 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3299 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BASE
;
3300 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3302 insn
.sequence
= seq_num
;
3307 /* emit "addq litreg, base, target" */
3309 if (basereg
!= AXP_REG_ZERO
)
3311 set_tok_reg (newtok
[1], basereg
);
3312 set_tok_reg (newtok
[2], targreg
);
3313 assemble_tokens ("addq", newtok
, 3, 0);
3315 #endif /* !OBJ_EVAX */
3318 set_tok_const (*poffset
, 0);
3319 *pbasereg
= targreg
;
3323 offsetT low
, high
, extra
, tmp
;
3325 /* for 32-bit operands, break up the addend */
3327 low
= sign_extend_16 (addend
);
3329 high
= sign_extend_16 (tmp
>> 16);
3331 if (tmp
- (high
<< 16))
3335 high
= sign_extend_16 (tmp
>> 16);
3340 set_tok_reg (newtok
[0], targreg
);
3341 set_tok_preg (newtok
[2], basereg
);
3345 /* emit "ldah r, extra(r) */
3346 set_tok_const (newtok
[1], extra
);
3347 assemble_tokens ("ldah", newtok
, 3, 0);
3348 set_tok_preg (newtok
[2], basereg
= targreg
);
3353 /* emit "ldah r, high(r) */
3354 set_tok_const (newtok
[1], high
);
3355 assemble_tokens ("ldah", newtok
, 3, 0);
3357 set_tok_preg (newtok
[2], basereg
);
3360 if ((low
&& !poffset
) || (!poffset
&& basereg
!= targreg
))
3362 /* emit "lda r, low(base)" */
3363 set_tok_const (newtok
[1], low
);
3364 assemble_tokens ("lda", newtok
, 3, 0);
3370 set_tok_const (*poffset
, low
);
3371 *pbasereg
= basereg
;
3377 /* The lda macro differs from the lda instruction in that it handles
3378 most simple expressions, particualrly symbol address loads and
3382 emit_lda (tok
, ntok
, unused
)
3383 const expressionS
*tok
;
3385 const PTR unused ATTRIBUTE_UNUSED
;
3390 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
3392 basereg
= tok
[2].X_add_number
;
3394 (void) load_expression (tok
[0].X_add_number
, &tok
[1], &basereg
, NULL
);
3397 /* The ldah macro differs from the ldah instruction in that it has $31
3398 as an implied base register. */
3401 emit_ldah (tok
, ntok
, unused
)
3402 const expressionS
*tok
;
3403 int ntok ATTRIBUTE_UNUSED
;
3404 const PTR unused ATTRIBUTE_UNUSED
;
3406 expressionS newtok
[3];
3410 set_tok_preg (newtok
[2], AXP_REG_ZERO
);
3412 assemble_tokens ("ldah", newtok
, 3, 0);
3415 /* Handle all "simple" integer register loads -- ldq, ldq_l, ldq_u,
3416 etc. They differ from the real instructions in that they do simple
3417 expressions like the lda macro. */
3420 emit_ir_load (tok
, ntok
, opname
)
3421 const expressionS
*tok
;
3427 expressionS newtok
[3];
3428 struct alpha_insn insn
;
3431 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
3433 basereg
= tok
[2].X_add_number
;
3435 lituse
= load_expression (tok
[0].X_add_number
, &tok
[1], &basereg
,
3439 set_tok_preg (newtok
[2], basereg
);
3441 assemble_tokens_to_insn ((const char *) opname
, newtok
, 3, &insn
);
3445 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3446 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BASE
;
3447 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3449 insn
.sequence
= lituse
;
3455 /* Handle fp register loads, and both integer and fp register stores.
3456 Again, we handle simple expressions. */
3459 emit_loadstore (tok
, ntok
, opname
)
3460 const expressionS
*tok
;
3466 expressionS newtok
[3];
3467 struct alpha_insn insn
;
3470 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
3472 basereg
= tok
[2].X_add_number
;
3474 if (tok
[1].X_op
!= O_constant
|| !range_signed_16 (tok
[1].X_add_number
))
3477 as_bad (_("macro requires $at register while noat in effect"));
3479 lituse
= load_expression (AXP_REG_AT
, &tok
[1], &basereg
, &newtok
[1]);
3488 set_tok_preg (newtok
[2], basereg
);
3490 assemble_tokens_to_insn ((const char *) opname
, newtok
, 3, &insn
);
3494 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3495 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BASE
;
3496 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3498 insn
.sequence
= lituse
;
3504 /* Load a half-word or byte as an unsigned value. */
3507 emit_ldXu (tok
, ntok
, vlgsize
)
3508 const expressionS
*tok
;
3512 if (alpha_target
& AXP_OPCODE_BWX
)
3513 emit_ir_load (tok
, ntok
, ldXu_op
[(long) vlgsize
]);
3516 expressionS newtok
[3];
3517 struct alpha_insn insn
;
3522 as_bad (_("macro requires $at register while noat in effect"));
3525 basereg
= (tok
[1].X_op
== O_constant
3526 ? AXP_REG_ZERO
: alpha_gp_register
);
3528 basereg
= tok
[2].X_add_number
;
3530 /* emit "lda $at, exp" */
3532 lituse
= load_expression (AXP_REG_AT
, &tok
[1], &basereg
, NULL
);
3534 /* emit "ldq_u targ, 0($at)" */
3537 set_tok_const (newtok
[1], 0);
3538 set_tok_preg (newtok
[2], basereg
);
3539 assemble_tokens_to_insn ("ldq_u", newtok
, 3, &insn
);
3543 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3544 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BASE
;
3545 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3547 insn
.sequence
= lituse
;
3552 /* emit "extXl targ, $at, targ" */
3554 set_tok_reg (newtok
[1], basereg
);
3555 newtok
[2] = newtok
[0];
3556 assemble_tokens_to_insn (extXl_op
[(long) vlgsize
], newtok
, 3, &insn
);
3560 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3561 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BYTOFF
;
3562 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3564 insn
.sequence
= lituse
;
3571 /* Load a half-word or byte as a signed value. */
3574 emit_ldX (tok
, ntok
, vlgsize
)
3575 const expressionS
*tok
;
3579 emit_ldXu (tok
, ntok
, vlgsize
);
3580 assemble_tokens (sextX_op
[(long) vlgsize
], tok
, 1, 1);
3583 /* Load an integral value from an unaligned address as an unsigned
3587 emit_uldXu (tok
, ntok
, vlgsize
)
3588 const expressionS
*tok
;
3592 long lgsize
= (long) vlgsize
;
3593 expressionS newtok
[3];
3596 as_bad (_("macro requires $at register while noat in effect"));
3598 /* emit "lda $at, exp" */
3600 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
3601 newtok
[0].X_add_number
= AXP_REG_AT
;
3602 assemble_tokens ("lda", newtok
, ntok
, 1);
3604 /* emit "ldq_u $t9, 0($at)" */
3606 set_tok_reg (newtok
[0], AXP_REG_T9
);
3607 set_tok_const (newtok
[1], 0);
3608 set_tok_preg (newtok
[2], AXP_REG_AT
);
3609 assemble_tokens ("ldq_u", newtok
, 3, 1);
3611 /* emit "ldq_u $t10, size-1($at)" */
3613 set_tok_reg (newtok
[0], AXP_REG_T10
);
3614 set_tok_const (newtok
[1], (1 << lgsize
) - 1);
3615 assemble_tokens ("ldq_u", newtok
, 3, 1);
3617 /* emit "extXl $t9, $at, $t9" */
3619 set_tok_reg (newtok
[0], AXP_REG_T9
);
3620 set_tok_reg (newtok
[1], AXP_REG_AT
);
3621 set_tok_reg (newtok
[2], AXP_REG_T9
);
3622 assemble_tokens (extXl_op
[lgsize
], newtok
, 3, 1);
3624 /* emit "extXh $t10, $at, $t10" */
3626 set_tok_reg (newtok
[0], AXP_REG_T10
);
3627 set_tok_reg (newtok
[2], AXP_REG_T10
);
3628 assemble_tokens (extXh_op
[lgsize
], newtok
, 3, 1);
3630 /* emit "or $t9, $t10, targ" */
3632 set_tok_reg (newtok
[0], AXP_REG_T9
);
3633 set_tok_reg (newtok
[1], AXP_REG_T10
);
3635 assemble_tokens ("or", newtok
, 3, 1);
3638 /* Load an integral value from an unaligned address as a signed value.
3639 Note that quads should get funneled to the unsigned load since we
3640 don't have to do the sign extension. */
3643 emit_uldX (tok
, ntok
, vlgsize
)
3644 const expressionS
*tok
;
3648 emit_uldXu (tok
, ntok
, vlgsize
);
3649 assemble_tokens (sextX_op
[(long) vlgsize
], tok
, 1, 1);
3652 /* Implement the ldil macro. */
3655 emit_ldil (tok
, ntok
, unused
)
3656 const expressionS
*tok
;
3658 const PTR unused ATTRIBUTE_UNUSED
;
3660 expressionS newtok
[2];
3662 memcpy (newtok
, tok
, sizeof (newtok
));
3663 newtok
[1].X_add_number
= sign_extend_32 (tok
[1].X_add_number
);
3665 assemble_tokens ("lda", newtok
, ntok
, 1);
3668 /* Store a half-word or byte. */
3671 emit_stX (tok
, ntok
, vlgsize
)
3672 const expressionS
*tok
;
3676 int lgsize
= (int) (long) vlgsize
;
3678 if (alpha_target
& AXP_OPCODE_BWX
)
3679 emit_loadstore (tok
, ntok
, stX_op
[lgsize
]);
3682 expressionS newtok
[3];
3683 struct alpha_insn insn
;
3688 as_bad (_("macro requires $at register while noat in effect"));
3691 basereg
= (tok
[1].X_op
== O_constant
3692 ? AXP_REG_ZERO
: alpha_gp_register
);
3694 basereg
= tok
[2].X_add_number
;
3696 /* emit "lda $at, exp" */
3698 lituse
= load_expression (AXP_REG_AT
, &tok
[1], &basereg
, NULL
);
3700 /* emit "ldq_u $t9, 0($at)" */
3702 set_tok_reg (newtok
[0], AXP_REG_T9
);
3703 set_tok_const (newtok
[1], 0);
3704 set_tok_preg (newtok
[2], basereg
);
3705 assemble_tokens_to_insn ("ldq_u", newtok
, 3, &insn
);
3709 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3710 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BASE
;
3711 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3713 insn
.sequence
= lituse
;
3718 /* emit "insXl src, $at, $t10" */
3721 set_tok_reg (newtok
[1], basereg
);
3722 set_tok_reg (newtok
[2], AXP_REG_T10
);
3723 assemble_tokens_to_insn (insXl_op
[lgsize
], newtok
, 3, &insn
);
3727 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3728 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BYTOFF
;
3729 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3731 insn
.sequence
= lituse
;
3736 /* emit "mskXl $t9, $at, $t9" */
3738 set_tok_reg (newtok
[0], AXP_REG_T9
);
3739 newtok
[2] = newtok
[0];
3740 assemble_tokens_to_insn (mskXl_op
[lgsize
], newtok
, 3, &insn
);
3744 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3745 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BYTOFF
;
3746 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3748 insn
.sequence
= lituse
;
3753 /* emit "or $t9, $t10, $t9" */
3755 set_tok_reg (newtok
[1], AXP_REG_T10
);
3756 assemble_tokens ("or", newtok
, 3, 1);
3758 /* emit "stq_u $t9, 0($at) */
3760 set_tok_const(newtok
[1], 0);
3761 set_tok_preg (newtok
[2], AXP_REG_AT
);
3762 assemble_tokens_to_insn ("stq_u", newtok
, 3, &insn
);
3766 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3767 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BASE
;
3768 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3770 insn
.sequence
= lituse
;
3777 /* Store an integer to an unaligned address. */
3780 emit_ustX (tok
, ntok
, vlgsize
)
3781 const expressionS
*tok
;
3785 int lgsize
= (int) (long) vlgsize
;
3786 expressionS newtok
[3];
3788 /* emit "lda $at, exp" */
3790 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
3791 newtok
[0].X_add_number
= AXP_REG_AT
;
3792 assemble_tokens ("lda", newtok
, ntok
, 1);
3794 /* emit "ldq_u $9, 0($at)" */
3796 set_tok_reg (newtok
[0], AXP_REG_T9
);
3797 set_tok_const (newtok
[1], 0);
3798 set_tok_preg (newtok
[2], AXP_REG_AT
);
3799 assemble_tokens ("ldq_u", newtok
, 3, 1);
3801 /* emit "ldq_u $10, size-1($at)" */
3803 set_tok_reg (newtok
[0], AXP_REG_T10
);
3804 set_tok_const (newtok
[1], (1 << lgsize
) - 1);
3805 assemble_tokens ("ldq_u", newtok
, 3, 1);
3807 /* emit "insXl src, $at, $t11" */
3810 set_tok_reg (newtok
[1], AXP_REG_AT
);
3811 set_tok_reg (newtok
[2], AXP_REG_T11
);
3812 assemble_tokens (insXl_op
[lgsize
], newtok
, 3, 1);
3814 /* emit "insXh src, $at, $t12" */
3816 set_tok_reg (newtok
[2], AXP_REG_T12
);
3817 assemble_tokens (insXh_op
[lgsize
], newtok
, 3, 1);
3819 /* emit "mskXl $t9, $at, $t9" */
3821 set_tok_reg (newtok
[0], AXP_REG_T9
);
3822 newtok
[2] = newtok
[0];
3823 assemble_tokens (mskXl_op
[lgsize
], newtok
, 3, 1);
3825 /* emit "mskXh $t10, $at, $t10" */
3827 set_tok_reg (newtok
[0], AXP_REG_T10
);
3828 newtok
[2] = newtok
[0];
3829 assemble_tokens (mskXh_op
[lgsize
], newtok
, 3, 1);
3831 /* emit "or $t9, $t11, $t9" */
3833 set_tok_reg (newtok
[0], AXP_REG_T9
);
3834 set_tok_reg (newtok
[1], AXP_REG_T11
);
3835 newtok
[2] = newtok
[0];
3836 assemble_tokens ("or", newtok
, 3, 1);
3838 /* emit "or $t10, $t12, $t10" */
3840 set_tok_reg (newtok
[0], AXP_REG_T10
);
3841 set_tok_reg (newtok
[1], AXP_REG_T12
);
3842 newtok
[2] = newtok
[0];
3843 assemble_tokens ("or", newtok
, 3, 1);
3845 /* emit "stq_u $t9, 0($at)" */
3847 set_tok_reg (newtok
[0], AXP_REG_T9
);
3848 set_tok_const (newtok
[1], 0);
3849 set_tok_preg (newtok
[2], AXP_REG_AT
);
3850 assemble_tokens ("stq_u", newtok
, 3, 1);
3852 /* emit "stq_u $t10, size-1($at)" */
3854 set_tok_reg (newtok
[0], AXP_REG_T10
);
3855 set_tok_const (newtok
[1], (1 << lgsize
) - 1);
3856 assemble_tokens ("stq_u", newtok
, 3, 1);
3859 /* Sign extend a half-word or byte. The 32-bit sign extend is
3860 implemented as "addl $31, $r, $t" in the opcode table. */
3863 emit_sextX (tok
, ntok
, vlgsize
)
3864 const expressionS
*tok
;
3868 long lgsize
= (long) vlgsize
;
3870 if (alpha_target
& AXP_OPCODE_BWX
)
3871 assemble_tokens (sextX_op
[lgsize
], tok
, ntok
, 0);
3874 int bitshift
= 64 - 8 * (1 << lgsize
);
3875 expressionS newtok
[3];
3877 /* emit "sll src,bits,dst" */
3880 set_tok_const (newtok
[1], bitshift
);
3881 newtok
[2] = tok
[ntok
- 1];
3882 assemble_tokens ("sll", newtok
, 3, 1);
3884 /* emit "sra dst,bits,dst" */
3886 newtok
[0] = newtok
[2];
3887 assemble_tokens ("sra", newtok
, 3, 1);
3891 /* Implement the division and modulus macros. */
3895 /* Make register usage like in normal procedure call.
3896 Don't clobber PV and RA. */
3899 emit_division (tok
, ntok
, symname
)
3900 const expressionS
*tok
;
3904 /* DIVISION and MODULUS. Yech.
3909 mov x,R16 # if x != R16
3910 mov y,R17 # if y != R17
3915 with appropriate optimizations if R0,R16,R17 are the registers
3916 specified by the compiler. */
3920 expressionS newtok
[3];
3922 xr
= regno (tok
[0].X_add_number
);
3923 yr
= regno (tok
[1].X_add_number
);
3928 rr
= regno (tok
[2].X_add_number
);
3930 /* Move the operands into the right place. */
3931 if (yr
== AXP_REG_R16
&& xr
== AXP_REG_R17
)
3933 /* They are in exactly the wrong order -- swap through AT. */
3936 as_bad (_("macro requires $at register while noat in effect"));
3938 set_tok_reg (newtok
[0], AXP_REG_R16
);
3939 set_tok_reg (newtok
[1], AXP_REG_AT
);
3940 assemble_tokens ("mov", newtok
, 2, 1);
3942 set_tok_reg (newtok
[0], AXP_REG_R17
);
3943 set_tok_reg (newtok
[1], AXP_REG_R16
);
3944 assemble_tokens ("mov", newtok
, 2, 1);
3946 set_tok_reg (newtok
[0], AXP_REG_AT
);
3947 set_tok_reg (newtok
[1], AXP_REG_R17
);
3948 assemble_tokens ("mov", newtok
, 2, 1);
3952 if (yr
== AXP_REG_R16
)
3954 set_tok_reg (newtok
[0], AXP_REG_R16
);
3955 set_tok_reg (newtok
[1], AXP_REG_R17
);
3956 assemble_tokens ("mov", newtok
, 2, 1);
3959 if (xr
!= AXP_REG_R16
)
3961 set_tok_reg (newtok
[0], xr
);
3962 set_tok_reg (newtok
[1], AXP_REG_R16
);
3963 assemble_tokens ("mov", newtok
, 2, 1);
3966 if (yr
!= AXP_REG_R16
&& yr
!= AXP_REG_R17
)
3968 set_tok_reg (newtok
[0], yr
);
3969 set_tok_reg (newtok
[1], AXP_REG_R17
);
3970 assemble_tokens ("mov", newtok
, 2, 1);
3974 sym
= symbol_find_or_make ((const char *) symname
);
3976 set_tok_reg (newtok
[0], AXP_REG_AT
);
3977 set_tok_sym (newtok
[1], sym
, 0);
3978 assemble_tokens ("lda", newtok
, 2, 1);
3980 /* Call the division routine. */
3981 set_tok_reg (newtok
[0], AXP_REG_AT
);
3982 set_tok_cpreg (newtok
[1], AXP_REG_AT
);
3983 set_tok_const (newtok
[2], 0);
3984 assemble_tokens ("jsr", newtok
, 3, 1);
3986 /* Move the result to the right place. */
3987 if (rr
!= AXP_REG_R0
)
3989 set_tok_reg (newtok
[0], AXP_REG_R0
);
3990 set_tok_reg (newtok
[1], rr
);
3991 assemble_tokens ("mov", newtok
, 2, 1);
3995 #else /* !OBJ_EVAX */
3998 emit_division (tok
, ntok
, symname
)
3999 const expressionS
*tok
;
4003 /* DIVISION and MODULUS. Yech.
4013 with appropriate optimizations if t10,t11,t12 are the registers
4014 specified by the compiler. */
4018 expressionS newtok
[3];
4020 xr
= regno (tok
[0].X_add_number
);
4021 yr
= regno (tok
[1].X_add_number
);
4026 rr
= regno (tok
[2].X_add_number
);
4028 sym
= symbol_find_or_make ((const char *) symname
);
4030 /* Move the operands into the right place. */
4031 if (yr
== AXP_REG_T10
&& xr
== AXP_REG_T11
)
4033 /* They are in exactly the wrong order -- swap through AT. */
4035 as_bad (_("macro requires $at register while noat in effect"));
4037 set_tok_reg (newtok
[0], AXP_REG_T10
);
4038 set_tok_reg (newtok
[1], AXP_REG_AT
);
4039 assemble_tokens ("mov", newtok
, 2, 1);
4041 set_tok_reg (newtok
[0], AXP_REG_T11
);
4042 set_tok_reg (newtok
[1], AXP_REG_T10
);
4043 assemble_tokens ("mov", newtok
, 2, 1);
4045 set_tok_reg (newtok
[0], AXP_REG_AT
);
4046 set_tok_reg (newtok
[1], AXP_REG_T11
);
4047 assemble_tokens ("mov", newtok
, 2, 1);
4051 if (yr
== AXP_REG_T10
)
4053 set_tok_reg (newtok
[0], AXP_REG_T10
);
4054 set_tok_reg (newtok
[1], AXP_REG_T11
);
4055 assemble_tokens ("mov", newtok
, 2, 1);
4058 if (xr
!= AXP_REG_T10
)
4060 set_tok_reg (newtok
[0], xr
);
4061 set_tok_reg (newtok
[1], AXP_REG_T10
);
4062 assemble_tokens ("mov", newtok
, 2, 1);
4065 if (yr
!= AXP_REG_T10
&& yr
!= AXP_REG_T11
)
4067 set_tok_reg (newtok
[0], yr
);
4068 set_tok_reg (newtok
[1], AXP_REG_T11
);
4069 assemble_tokens ("mov", newtok
, 2, 1);
4073 /* Call the division routine. */
4074 set_tok_reg (newtok
[0], AXP_REG_T9
);
4075 set_tok_sym (newtok
[1], sym
, 0);
4076 assemble_tokens ("jsr", newtok
, 2, 1);
4078 /* Reload the GP register. */
4082 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
4083 set_tok_reg (newtok
[0], alpha_gp_register
);
4084 set_tok_const (newtok
[1], 0);
4085 set_tok_preg (newtok
[2], AXP_REG_T9
);
4086 assemble_tokens ("ldgp", newtok
, 3, 1);
4089 /* Move the result to the right place. */
4090 if (rr
!= AXP_REG_T12
)
4092 set_tok_reg (newtok
[0], AXP_REG_T12
);
4093 set_tok_reg (newtok
[1], rr
);
4094 assemble_tokens ("mov", newtok
, 2, 1);
4098 #endif /* !OBJ_EVAX */
4100 /* The jsr and jmp macros differ from their instruction counterparts
4101 in that they can load the target address and default most
4105 emit_jsrjmp (tok
, ntok
, vopname
)
4106 const expressionS
*tok
;
4110 const char *opname
= (const char *) vopname
;
4111 struct alpha_insn insn
;
4112 expressionS newtok
[3];
4116 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_register
)
4117 r
= regno (tok
[tokidx
++].X_add_number
);
4119 r
= strcmp (opname
, "jmp") == 0 ? AXP_REG_ZERO
: AXP_REG_RA
;
4121 set_tok_reg (newtok
[0], r
);
4123 if (tokidx
< ntok
&&
4124 (tok
[tokidx
].X_op
== O_pregister
|| tok
[tokidx
].X_op
== O_cpregister
))
4125 r
= regno (tok
[tokidx
++].X_add_number
);
4127 /* keep register if jsr $n.<sym> */
4131 int basereg
= alpha_gp_register
;
4132 lituse
= load_expression (r
= AXP_REG_PV
, &tok
[tokidx
], &basereg
, NULL
);
4136 set_tok_cpreg (newtok
[1], r
);
4139 /* FIXME: Add hint relocs to BFD for evax. */
4142 newtok
[2] = tok
[tokidx
];
4145 set_tok_const (newtok
[2], 0);
4147 assemble_tokens_to_insn (opname
, newtok
, 3, &insn
);
4151 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
4152 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_JSR
;
4153 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
4155 insn
.sequence
= lituse
;
4161 /* The ret and jcr instructions differ from their instruction
4162 counterparts in that everything can be defaulted. */
4165 emit_retjcr (tok
, ntok
, vopname
)
4166 const expressionS
*tok
;
4170 const char *opname
= (const char *) vopname
;
4171 expressionS newtok
[3];
4174 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_register
)
4175 r
= regno (tok
[tokidx
++].X_add_number
);
4179 set_tok_reg (newtok
[0], r
);
4181 if (tokidx
< ntok
&&
4182 (tok
[tokidx
].X_op
== O_pregister
|| tok
[tokidx
].X_op
== O_cpregister
))
4183 r
= regno (tok
[tokidx
++].X_add_number
);
4187 set_tok_cpreg (newtok
[1], r
);
4190 newtok
[2] = tok
[tokidx
];
4192 set_tok_const (newtok
[2], strcmp (opname
, "ret") == 0);
4194 assemble_tokens (opname
, newtok
, 3, 0);
4197 /* Assembler directives. */
4199 /* Handle the .text pseudo-op. This is like the usual one, but it
4200 clears alpha_insn_label and restores auto alignment. */
4212 alpha_insn_label
= NULL
;
4213 alpha_auto_align_on
= 1;
4214 alpha_current_align
= 0;
4217 /* Handle the .data pseudo-op. This is like the usual one, but it
4218 clears alpha_insn_label and restores auto alignment. */
4229 alpha_insn_label
= NULL
;
4230 alpha_auto_align_on
= 1;
4231 alpha_current_align
= 0;
4234 #if defined (OBJ_ECOFF) || defined (OBJ_EVAX)
4236 /* Handle the OSF/1 and openVMS .comm pseudo quirks.
4237 openVMS constructs a section for every common symbol. */
4240 s_alpha_comm (ignore
)
4241 int ignore ATTRIBUTE_UNUSED
;
4243 register char *name
;
4247 register symbolS
*symbolP
;
4250 segT current_section
= now_seg
;
4251 int current_subsec
= now_subseg
;
4255 name
= input_line_pointer
;
4256 c
= get_symbol_end ();
4258 /* just after name is now '\0' */
4259 p
= input_line_pointer
;
4264 /* Alpha OSF/1 compiler doesn't provide the comma, gcc does. */
4265 if (*input_line_pointer
== ',')
4267 input_line_pointer
++;
4270 if ((temp
= get_absolute_expression ()) < 0)
4272 as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) temp
);
4273 ignore_rest_of_line ();
4278 symbolP
= symbol_find_or_make (name
);
4281 /* Make a section for the common symbol. */
4282 new_seg
= subseg_new (xstrdup (name
), 0);
4288 /* alignment might follow */
4289 if (*input_line_pointer
== ',')
4293 input_line_pointer
++;
4294 align
= get_absolute_expression ();
4295 bfd_set_section_alignment (stdoutput
, new_seg
, align
);
4299 if (S_IS_DEFINED (symbolP
) && ! S_IS_COMMON (symbolP
))
4301 as_bad (_("Ignoring attempt to re-define symbol"));
4302 ignore_rest_of_line ();
4307 if (bfd_section_size (stdoutput
, new_seg
) > 0)
4309 if (bfd_section_size (stdoutput
, new_seg
) != temp
)
4310 as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
4311 S_GET_NAME (symbolP
),
4312 (long) bfd_section_size (stdoutput
, new_seg
),
4316 if (S_GET_VALUE (symbolP
))
4318 if (S_GET_VALUE (symbolP
) != (valueT
) temp
)
4319 as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
4320 S_GET_NAME (symbolP
),
4321 (long) S_GET_VALUE (symbolP
),
4328 subseg_set (new_seg
, 0);
4329 p
= frag_more (temp
);
4330 new_seg
->flags
|= SEC_IS_COMMON
;
4331 if (! S_IS_DEFINED (symbolP
))
4332 S_SET_SEGMENT (symbolP
, new_seg
);
4334 S_SET_VALUE (symbolP
, (valueT
) temp
);
4336 S_SET_EXTERNAL (symbolP
);
4340 subseg_set (current_section
, current_subsec
);
4343 know (symbol_get_frag (symbolP
) == &zero_address_frag
);
4345 demand_empty_rest_of_line ();
4348 #endif /* ! OBJ_ELF */
4352 /* Handle the .rdata pseudo-op. This is like the usual one, but it
4353 clears alpha_insn_label and restores auto alignment. */
4356 s_alpha_rdata (ignore
)
4357 int ignore ATTRIBUTE_UNUSED
;
4361 temp
= get_absolute_expression ();
4362 subseg_new (".rdata", 0);
4363 demand_empty_rest_of_line ();
4364 alpha_insn_label
= NULL
;
4365 alpha_auto_align_on
= 1;
4366 alpha_current_align
= 0;
4373 /* Handle the .sdata pseudo-op. This is like the usual one, but it
4374 clears alpha_insn_label and restores auto alignment. */
4377 s_alpha_sdata (ignore
)
4378 int ignore ATTRIBUTE_UNUSED
;
4382 temp
= get_absolute_expression ();
4383 subseg_new (".sdata", 0);
4384 demand_empty_rest_of_line ();
4385 alpha_insn_label
= NULL
;
4386 alpha_auto_align_on
= 1;
4387 alpha_current_align
= 0;
4393 /* Handle the .section pseudo-op. This is like the usual one, but it
4394 clears alpha_insn_label and restores auto alignment. */
4397 s_alpha_section (ignore
)
4398 int ignore ATTRIBUTE_UNUSED
;
4400 obj_elf_section (ignore
);
4402 alpha_insn_label
= NULL
;
4403 alpha_auto_align_on
= 1;
4404 alpha_current_align
= 0;
4409 int dummy ATTRIBUTE_UNUSED
;
4411 if (ECOFF_DEBUGGING
)
4412 ecoff_directive_ent (0);
4415 char *name
, name_end
;
4416 name
= input_line_pointer
;
4417 name_end
= get_symbol_end ();
4419 if (! is_name_beginner (*name
))
4421 as_warn (_(".ent directive has no name"));
4422 *input_line_pointer
= name_end
;
4428 if (alpha_cur_ent_sym
)
4429 as_warn (_("nested .ent directives"));
4431 sym
= symbol_find_or_make (name
);
4432 symbol_get_bfdsym (sym
)->flags
|= BSF_FUNCTION
;
4433 alpha_cur_ent_sym
= sym
;
4435 /* The .ent directive is sometimes followed by a number. Not sure
4436 what it really means, but ignore it. */
4437 *input_line_pointer
= name_end
;
4439 if (*input_line_pointer
== ',')
4441 input_line_pointer
++;
4444 if (ISDIGIT (*input_line_pointer
) || *input_line_pointer
== '-')
4445 (void) get_absolute_expression ();
4447 demand_empty_rest_of_line ();
4453 int dummy ATTRIBUTE_UNUSED
;
4455 if (ECOFF_DEBUGGING
)
4456 ecoff_directive_end (0);
4459 char *name
, name_end
;
4460 name
= input_line_pointer
;
4461 name_end
= get_symbol_end ();
4463 if (! is_name_beginner (*name
))
4465 as_warn (_(".end directive has no name"));
4466 *input_line_pointer
= name_end
;
4472 sym
= symbol_find (name
);
4473 if (sym
!= alpha_cur_ent_sym
)
4474 as_warn (_(".end directive names different symbol than .ent"));
4476 /* Create an expression to calculate the size of the function. */
4479 symbol_get_obj (sym
)->size
=
4480 (expressionS
*) xmalloc (sizeof (expressionS
));
4481 symbol_get_obj (sym
)->size
->X_op
= O_subtract
;
4482 symbol_get_obj (sym
)->size
->X_add_symbol
4483 = symbol_new ("L0\001", now_seg
, frag_now_fix (), frag_now
);
4484 symbol_get_obj (sym
)->size
->X_op_symbol
= sym
;
4485 symbol_get_obj (sym
)->size
->X_add_number
= 0;
4488 alpha_cur_ent_sym
= NULL
;
4490 *input_line_pointer
= name_end
;
4492 demand_empty_rest_of_line ();
4500 if (ECOFF_DEBUGGING
)
4503 ecoff_directive_fmask (0);
4505 ecoff_directive_mask (0);
4508 discard_rest_of_line ();
4512 s_alpha_frame (dummy
)
4513 int dummy ATTRIBUTE_UNUSED
;
4515 if (ECOFF_DEBUGGING
)
4516 ecoff_directive_frame (0);
4518 discard_rest_of_line ();
4522 s_alpha_prologue (ignore
)
4523 int ignore ATTRIBUTE_UNUSED
;
4528 arg
= get_absolute_expression ();
4529 demand_empty_rest_of_line ();
4531 if (ECOFF_DEBUGGING
)
4532 sym
= ecoff_get_cur_proc_sym ();
4534 sym
= alpha_cur_ent_sym
;
4539 case 0: /* No PV required. */
4540 S_SET_OTHER (sym
, STO_ALPHA_NOPV
4541 | (S_GET_OTHER (sym
) & ~STO_ALPHA_STD_GPLOAD
));
4543 case 1: /* Std GP load. */
4544 S_SET_OTHER (sym
, STO_ALPHA_STD_GPLOAD
4545 | (S_GET_OTHER (sym
) & ~STO_ALPHA_STD_GPLOAD
));
4547 case 2: /* Non-std use of PV. */
4551 as_bad (_("Invalid argument %d to .prologue."), arg
);
4556 static char *first_file_directive
;
4559 s_alpha_file (ignore
)
4560 int ignore ATTRIBUTE_UNUSED
;
4562 /* Save the first .file directive we see, so that we can change our
4563 minds about whether ecoff debugging should or shouldn't be enabled. */
4564 if (alpha_flag_mdebug
< 0 && ! first_file_directive
)
4566 char *start
= input_line_pointer
;
4569 discard_rest_of_line ();
4571 len
= input_line_pointer
- start
;
4572 first_file_directive
= xmalloc (len
+ 1);
4573 memcpy (first_file_directive
, start
, len
);
4574 first_file_directive
[len
] = '\0';
4576 input_line_pointer
= start
;
4579 if (ECOFF_DEBUGGING
)
4580 ecoff_directive_file (0);
4582 dwarf2_directive_file (0);
4586 s_alpha_loc (ignore
)
4587 int ignore ATTRIBUTE_UNUSED
;
4589 if (ECOFF_DEBUGGING
)
4590 ecoff_directive_loc (0);
4592 dwarf2_directive_loc (0);
4599 /* If we've been undecided about mdebug, make up our minds in favour. */
4600 if (alpha_flag_mdebug
< 0)
4602 segT sec
= subseg_new (".mdebug", 0);
4603 bfd_set_section_flags (stdoutput
, sec
, SEC_HAS_CONTENTS
| SEC_READONLY
);
4604 bfd_set_section_alignment (stdoutput
, sec
, 3);
4606 ecoff_read_begin_hook ();
4608 if (first_file_directive
)
4610 char *save_ilp
= input_line_pointer
;
4611 input_line_pointer
= first_file_directive
;
4612 ecoff_directive_file (0);
4613 input_line_pointer
= save_ilp
;
4614 free (first_file_directive
);
4617 alpha_flag_mdebug
= 1;
4623 s_alpha_coff_wrapper (which
)
4626 static void (* const fns
[]) PARAMS ((int)) = {
4627 ecoff_directive_begin
,
4628 ecoff_directive_bend
,
4629 ecoff_directive_def
,
4630 ecoff_directive_dim
,
4631 ecoff_directive_endef
,
4632 ecoff_directive_scl
,
4633 ecoff_directive_tag
,
4634 ecoff_directive_val
,
4637 assert (which
>= 0 && which
< (int) (sizeof (fns
)/sizeof (*fns
)));
4639 if (ECOFF_DEBUGGING
)
4643 as_bad (_("ECOFF debugging is disabled."));
4644 ignore_rest_of_line ();
4647 #endif /* OBJ_ELF */
4651 /* Handle the section specific pseudo-op. */
4654 s_alpha_section (secid
)
4658 #define EVAX_SECTION_COUNT 5
4659 static char *section_name
[EVAX_SECTION_COUNT
+ 1] =
4660 { "NULL", ".rdata", ".comm", ".link", ".ctors", ".dtors" };
4662 if ((secid
<= 0) || (secid
> EVAX_SECTION_COUNT
))
4664 as_fatal (_("Unknown section directive"));
4665 demand_empty_rest_of_line ();
4668 temp
= get_absolute_expression ();
4669 subseg_new (section_name
[secid
], 0);
4670 demand_empty_rest_of_line ();
4671 alpha_insn_label
= NULL
;
4672 alpha_auto_align_on
= 1;
4673 alpha_current_align
= 0;
4676 /* Parse .ent directives. */
4679 s_alpha_ent (ignore
)
4680 int ignore ATTRIBUTE_UNUSED
;
4683 expressionS symexpr
;
4685 alpha_evax_proc
.pdsckind
= 0;
4686 alpha_evax_proc
.framereg
= -1;
4687 alpha_evax_proc
.framesize
= 0;
4688 alpha_evax_proc
.rsa_offset
= 0;
4689 alpha_evax_proc
.ra_save
= AXP_REG_RA
;
4690 alpha_evax_proc
.fp_save
= -1;
4691 alpha_evax_proc
.imask
= 0;
4692 alpha_evax_proc
.fmask
= 0;
4693 alpha_evax_proc
.prologue
= 0;
4694 alpha_evax_proc
.type
= 0;
4696 expression (&symexpr
);
4698 if (symexpr
.X_op
!= O_symbol
)
4700 as_fatal (_(".ent directive has no symbol"));
4701 demand_empty_rest_of_line ();
4705 symbol
= make_expr_symbol (&symexpr
);
4706 symbol_get_bfdsym (symbol
)->flags
|= BSF_FUNCTION
;
4707 alpha_evax_proc
.symbol
= symbol
;
4709 demand_empty_rest_of_line ();
4713 /* Parse .frame <framreg>,<framesize>,RA,<rsa_offset> directives. */
4716 s_alpha_frame (ignore
)
4717 int ignore ATTRIBUTE_UNUSED
;
4721 alpha_evax_proc
.framereg
= tc_get_register (1);
4724 if (*input_line_pointer
++ != ','
4725 || get_absolute_expression_and_terminator (&val
) != ',')
4727 as_warn (_("Bad .frame directive 1./2. param"));
4728 --input_line_pointer
;
4729 demand_empty_rest_of_line ();
4733 alpha_evax_proc
.framesize
= val
;
4735 (void) tc_get_register (1);
4737 if (*input_line_pointer
++ != ',')
4739 as_warn (_("Bad .frame directive 3./4. param"));
4740 --input_line_pointer
;
4741 demand_empty_rest_of_line ();
4744 alpha_evax_proc
.rsa_offset
= get_absolute_expression ();
4750 s_alpha_pdesc (ignore
)
4751 int ignore ATTRIBUTE_UNUSED
;
4760 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
4762 if (now_seg
!= alpha_link_section
)
4764 as_bad (_(".pdesc directive not in link (.link) section"));
4765 demand_empty_rest_of_line ();
4769 if ((alpha_evax_proc
.symbol
== 0)
4770 || (!S_IS_DEFINED (alpha_evax_proc
.symbol
)))
4772 as_fatal (_(".pdesc has no matching .ent"));
4773 demand_empty_rest_of_line ();
4777 *symbol_get_obj (alpha_evax_proc
.symbol
) =
4778 (valueT
) seginfo
->literal_pool_size
;
4781 if (exp
.X_op
!= O_symbol
)
4783 as_warn (_(".pdesc directive has no entry symbol"));
4784 demand_empty_rest_of_line ();
4788 entry_sym
= make_expr_symbol (&exp
);
4789 /* Save bfd symbol of proc desc in function symbol. */
4790 symbol_get_bfdsym (alpha_evax_proc
.symbol
)->udata
.p
4791 = symbol_get_bfdsym (entry_sym
);
4794 if (*input_line_pointer
++ != ',')
4796 as_warn (_("No comma after .pdesc <entryname>"));
4797 demand_empty_rest_of_line ();
4802 name
= input_line_pointer
;
4803 name_end
= get_symbol_end ();
4805 if (strncmp (name
, "stack", 5) == 0)
4807 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_FP_STACK
;
4809 else if (strncmp (name
, "reg", 3) == 0)
4811 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_FP_REGISTER
;
4813 else if (strncmp (name
, "null", 4) == 0)
4815 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_NULL
;
4819 as_fatal (_("unknown procedure kind"));
4820 demand_empty_rest_of_line ();
4824 *input_line_pointer
= name_end
;
4825 demand_empty_rest_of_line ();
4827 #ifdef md_flush_pending_output
4828 md_flush_pending_output ();
4831 frag_align (3, 0, 0);
4833 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
4835 seginfo
->literal_pool_size
+= 16;
4837 *p
= alpha_evax_proc
.pdsckind
4838 | ((alpha_evax_proc
.framereg
== 29) ? PDSC_S_M_BASE_REG_IS_FP
: 0);
4839 *(p
+ 1) = PDSC_S_M_NATIVE
| PDSC_S_M_NO_JACKET
;
4841 switch (alpha_evax_proc
.pdsckind
)
4843 case PDSC_S_K_KIND_NULL
:
4847 case PDSC_S_K_KIND_FP_REGISTER
:
4848 *(p
+ 2) = alpha_evax_proc
.fp_save
;
4849 *(p
+ 3) = alpha_evax_proc
.ra_save
;
4851 case PDSC_S_K_KIND_FP_STACK
:
4852 md_number_to_chars (p
+ 2, (valueT
) alpha_evax_proc
.rsa_offset
, 2);
4854 default: /* impossible */
4859 *(p
+ 5) = alpha_evax_proc
.type
& 0x0f;
4861 /* Signature offset. */
4862 md_number_to_chars (p
+ 6, (valueT
) 0, 2);
4864 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
+8, 8, &exp
, 0, BFD_RELOC_64
);
4866 if (alpha_evax_proc
.pdsckind
== PDSC_S_K_KIND_NULL
)
4869 /* Add dummy fix to make add_to_link_pool work. */
4871 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
4873 seginfo
->literal_pool_size
+= 8;
4875 /* pdesc+16: Size. */
4876 md_number_to_chars (p
, (valueT
) alpha_evax_proc
.framesize
, 4);
4878 md_number_to_chars (p
+ 4, (valueT
) 0, 2);
4881 md_number_to_chars (p
+ 6, alpha_evax_proc
.prologue
, 2);
4883 if (alpha_evax_proc
.pdsckind
== PDSC_S_K_KIND_FP_REGISTER
)
4886 /* Add dummy fix to make add_to_link_pool work. */
4888 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
4890 seginfo
->literal_pool_size
+= 8;
4892 /* pdesc+24: register masks. */
4894 md_number_to_chars (p
, alpha_evax_proc
.imask
, 4);
4895 md_number_to_chars (p
+ 4, alpha_evax_proc
.fmask
, 4);
4900 /* Support for crash debug on vms. */
4903 s_alpha_name (ignore
)
4904 int ignore ATTRIBUTE_UNUSED
;
4908 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
4910 if (now_seg
!= alpha_link_section
)
4912 as_bad (_(".name directive not in link (.link) section"));
4913 demand_empty_rest_of_line ();
4918 if (exp
.X_op
!= O_symbol
)
4920 as_warn (_(".name directive has no symbol"));
4921 demand_empty_rest_of_line ();
4925 demand_empty_rest_of_line ();
4927 #ifdef md_flush_pending_output
4928 md_flush_pending_output ();
4931 frag_align (3, 0, 0);
4933 seginfo
->literal_pool_size
+= 8;
4935 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 8, &exp
, 0, BFD_RELOC_64
);
4941 s_alpha_linkage (ignore
)
4942 int ignore ATTRIBUTE_UNUSED
;
4947 #ifdef md_flush_pending_output
4948 md_flush_pending_output ();
4952 if (exp
.X_op
!= O_symbol
)
4954 as_fatal (_("No symbol after .linkage"));
4958 p
= frag_more (LKP_S_K_SIZE
);
4959 memset (p
, 0, LKP_S_K_SIZE
);
4960 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, LKP_S_K_SIZE
, &exp
, 0,\
4961 BFD_RELOC_ALPHA_LINKAGE
);
4963 demand_empty_rest_of_line ();
4969 s_alpha_code_address (ignore
)
4970 int ignore ATTRIBUTE_UNUSED
;
4975 #ifdef md_flush_pending_output
4976 md_flush_pending_output ();
4980 if (exp
.X_op
!= O_symbol
)
4982 as_fatal (_("No symbol after .code_address"));
4988 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 8, &exp
, 0,\
4989 BFD_RELOC_ALPHA_CODEADDR
);
4991 demand_empty_rest_of_line ();
4997 s_alpha_fp_save (ignore
)
4998 int ignore ATTRIBUTE_UNUSED
;
5001 alpha_evax_proc
.fp_save
= tc_get_register (1);
5003 demand_empty_rest_of_line ();
5008 s_alpha_mask (ignore
)
5009 int ignore ATTRIBUTE_UNUSED
;
5013 if (get_absolute_expression_and_terminator (&val
) != ',')
5015 as_warn (_("Bad .mask directive"));
5016 --input_line_pointer
;
5020 alpha_evax_proc
.imask
= val
;
5021 (void) get_absolute_expression ();
5023 demand_empty_rest_of_line ();
5029 s_alpha_fmask (ignore
)
5030 int ignore ATTRIBUTE_UNUSED
;
5034 if (get_absolute_expression_and_terminator (&val
) != ',')
5036 as_warn (_("Bad .fmask directive"));
5037 --input_line_pointer
;
5041 alpha_evax_proc
.fmask
= val
;
5042 (void) get_absolute_expression ();
5044 demand_empty_rest_of_line ();
5050 s_alpha_end (ignore
)
5051 int ignore ATTRIBUTE_UNUSED
;
5055 c
= get_symbol_end ();
5056 *input_line_pointer
= c
;
5057 demand_empty_rest_of_line ();
5058 alpha_evax_proc
.symbol
= 0;
5064 s_alpha_file (ignore
)
5065 int ignore ATTRIBUTE_UNUSED
;
5069 static char case_hack
[32];
5071 extern char *demand_copy_string
PARAMS ((int *lenP
));
5073 sprintf (case_hack
, "<CASE:%01d%01d>",
5074 alpha_flag_hash_long_names
, alpha_flag_show_after_trunc
);
5076 s
= symbol_find_or_make (case_hack
);
5077 symbol_get_bfdsym (s
)->flags
|= BSF_FILE
;
5079 get_absolute_expression ();
5080 s
= symbol_find_or_make (demand_copy_string (&length
));
5081 symbol_get_bfdsym (s
)->flags
|= BSF_FILE
;
5082 demand_empty_rest_of_line ();
5086 #endif /* OBJ_EVAX */
5088 /* Handle the .gprel32 pseudo op. */
5091 s_alpha_gprel32 (ignore
)
5092 int ignore ATTRIBUTE_UNUSED
;
5104 e
.X_add_symbol
= section_symbol (absolute_section
);
5117 e
.X_add_symbol
= section_symbol (absolute_section
);
5120 e
.X_op
= O_subtract
;
5121 e
.X_op_symbol
= alpha_gp_symbol
;
5129 if (alpha_auto_align_on
&& alpha_current_align
< 2)
5130 alpha_align (2, (char *) NULL
, alpha_insn_label
, 0);
5131 if (alpha_current_align
> 2)
5132 alpha_current_align
= 2;
5133 alpha_insn_label
= NULL
;
5137 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 4,
5138 &e
, 0, BFD_RELOC_GPREL32
);
5141 /* Handle floating point allocation pseudo-ops. This is like the
5142 generic vresion, but it makes sure the current label, if any, is
5143 correctly aligned. */
5146 s_alpha_float_cons (type
)
5173 if (alpha_auto_align_on
&& alpha_current_align
< log_size
)
5174 alpha_align (log_size
, (char *) NULL
, alpha_insn_label
, 0);
5175 if (alpha_current_align
> log_size
)
5176 alpha_current_align
= log_size
;
5177 alpha_insn_label
= NULL
;
5182 /* Handle the .proc pseudo op. We don't really do much with it except
5186 s_alpha_proc (is_static
)
5187 int is_static ATTRIBUTE_UNUSED
;
5195 /* Takes ".proc name,nargs" */
5197 name
= input_line_pointer
;
5198 c
= get_symbol_end ();
5199 p
= input_line_pointer
;
5200 symbolP
= symbol_find_or_make (name
);
5203 if (*input_line_pointer
!= ',')
5206 as_warn (_("Expected comma after name \"%s\""), name
);
5209 ignore_rest_of_line ();
5213 input_line_pointer
++;
5214 temp
= get_absolute_expression ();
5216 /* *symbol_get_obj (symbolP) = (signed char) temp; */
5217 as_warn (_("unhandled: .proc %s,%d"), name
, temp
);
5218 demand_empty_rest_of_line ();
5221 /* Handle the .set pseudo op. This is used to turn on and off most of
5222 the assembler features. */
5226 int x ATTRIBUTE_UNUSED
;
5232 name
= input_line_pointer
;
5233 ch
= get_symbol_end ();
5236 if (s
[0] == 'n' && s
[1] == 'o')
5241 if (!strcmp ("reorder", s
))
5243 else if (!strcmp ("at", s
))
5244 alpha_noat_on
= !yesno
;
5245 else if (!strcmp ("macro", s
))
5246 alpha_macros_on
= yesno
;
5247 else if (!strcmp ("move", s
))
5249 else if (!strcmp ("volatile", s
))
5252 as_warn (_("Tried to .set unrecognized mode `%s'"), name
);
5254 *input_line_pointer
= ch
;
5255 demand_empty_rest_of_line ();
5258 /* Handle the .base pseudo op. This changes the assembler's notion of
5259 the $gp register. */
5262 s_alpha_base (ignore
)
5263 int ignore ATTRIBUTE_UNUSED
;
5266 if (first_32bit_quadrant
)
5268 /* not fatal, but it might not work in the end */
5269 as_warn (_("File overrides no-base-register option."));
5270 first_32bit_quadrant
= 0;
5275 if (*input_line_pointer
== '$')
5277 input_line_pointer
++;
5278 if (*input_line_pointer
== 'r')
5279 input_line_pointer
++;
5282 alpha_gp_register
= get_absolute_expression ();
5283 if (alpha_gp_register
< 0 || alpha_gp_register
> 31)
5285 alpha_gp_register
= AXP_REG_GP
;
5286 as_warn (_("Bad base register, using $%d."), alpha_gp_register
);
5289 demand_empty_rest_of_line ();
5292 /* Handle the .align pseudo-op. This aligns to a power of two. It
5293 also adjusts any current instruction label. We treat this the same
5294 way the MIPS port does: .align 0 turns off auto alignment. */
5297 s_alpha_align (ignore
)
5298 int ignore ATTRIBUTE_UNUSED
;
5302 long max_alignment
= 15;
5304 align
= get_absolute_expression ();
5305 if (align
> max_alignment
)
5307 align
= max_alignment
;
5308 as_bad (_("Alignment too large: %d. assumed"), align
);
5312 as_warn (_("Alignment negative: 0 assumed"));
5316 if (*input_line_pointer
== ',')
5318 input_line_pointer
++;
5319 fill
= get_absolute_expression ();
5327 alpha_auto_align_on
= 1;
5328 alpha_align (align
, pfill
, alpha_insn_label
, 1);
5332 alpha_auto_align_on
= 0;
5335 demand_empty_rest_of_line ();
5338 /* Hook the normal string processor to reset known alignment. */
5341 s_alpha_stringer (terminate
)
5344 alpha_current_align
= 0;
5345 alpha_insn_label
= NULL
;
5346 stringer (terminate
);
5349 /* Hook the normal space processing to reset known alignment. */
5352 s_alpha_space (ignore
)
5355 alpha_current_align
= 0;
5356 alpha_insn_label
= NULL
;
5360 /* Hook into cons for auto-alignment. */
5363 alpha_cons_align (size
)
5369 while ((size
>>= 1) != 0)
5372 if (alpha_auto_align_on
&& alpha_current_align
< log_size
)
5373 alpha_align (log_size
, (char *) NULL
, alpha_insn_label
, 0);
5374 if (alpha_current_align
> log_size
)
5375 alpha_current_align
= log_size
;
5376 alpha_insn_label
= NULL
;
5379 /* Here come the .uword, .ulong, and .uquad explicitly unaligned
5380 pseudos. We just turn off auto-alignment and call down to cons. */
5383 s_alpha_ucons (bytes
)
5386 int hold
= alpha_auto_align_on
;
5387 alpha_auto_align_on
= 0;
5389 alpha_auto_align_on
= hold
;
5392 /* Switch the working cpu type. */
5395 s_alpha_arch (ignored
)
5396 int ignored ATTRIBUTE_UNUSED
;
5399 const struct cpu_type
*p
;
5402 name
= input_line_pointer
;
5403 ch
= get_symbol_end ();
5405 for (p
= cpu_types
; p
->name
; ++p
)
5406 if (strcmp (name
, p
->name
) == 0)
5408 alpha_target_name
= p
->name
, alpha_target
= p
->flags
;
5411 as_warn ("Unknown CPU identifier `%s'", name
);
5414 *input_line_pointer
= ch
;
5415 demand_empty_rest_of_line ();
5419 /* print token expression with alpha specific extension. */
5422 alpha_print_token (f
, exp
)
5424 const expressionS
*exp
;
5434 expressionS nexp
= *exp
;
5435 nexp
.X_op
= O_register
;
5436 print_expr (f
, &nexp
);
5441 print_expr (f
, exp
);
5448 /* The target specific pseudo-ops which we support. */
5450 const pseudo_typeS md_pseudo_table
[] = {
5452 {"comm", s_alpha_comm
, 0}, /* osf1 compiler does this */
5453 {"rdata", s_alpha_rdata
, 0},
5455 {"text", s_alpha_text
, 0},
5456 {"data", s_alpha_data
, 0},
5458 {"sdata", s_alpha_sdata
, 0},
5461 {"section", s_alpha_section
, 0},
5462 {"section.s", s_alpha_section
, 0},
5463 {"sect", s_alpha_section
, 0},
5464 {"sect.s", s_alpha_section
, 0},
5467 { "pdesc", s_alpha_pdesc
, 0},
5468 { "name", s_alpha_name
, 0},
5469 { "linkage", s_alpha_linkage
, 0},
5470 { "code_address", s_alpha_code_address
, 0},
5471 { "ent", s_alpha_ent
, 0},
5472 { "frame", s_alpha_frame
, 0},
5473 { "fp_save", s_alpha_fp_save
, 0},
5474 { "mask", s_alpha_mask
, 0},
5475 { "fmask", s_alpha_fmask
, 0},
5476 { "end", s_alpha_end
, 0},
5477 { "file", s_alpha_file
, 0},
5478 { "rdata", s_alpha_section
, 1},
5479 { "comm", s_alpha_comm
, 0},
5480 { "link", s_alpha_section
, 3},
5481 { "ctors", s_alpha_section
, 4},
5482 { "dtors", s_alpha_section
, 5},
5485 /* Frame related pseudos. */
5486 {"ent", s_alpha_ent
, 0},
5487 {"end", s_alpha_end
, 0},
5488 {"mask", s_alpha_mask
, 0},
5489 {"fmask", s_alpha_mask
, 1},
5490 {"frame", s_alpha_frame
, 0},
5491 {"prologue", s_alpha_prologue
, 0},
5492 {"file", s_alpha_file
, 5},
5493 {"loc", s_alpha_loc
, 9},
5494 {"stabs", s_alpha_stab
, 's'},
5495 {"stabn", s_alpha_stab
, 'n'},
5496 /* COFF debugging related pseudos. */
5497 {"begin", s_alpha_coff_wrapper
, 0},
5498 {"bend", s_alpha_coff_wrapper
, 1},
5499 {"def", s_alpha_coff_wrapper
, 2},
5500 {"dim", s_alpha_coff_wrapper
, 3},
5501 {"endef", s_alpha_coff_wrapper
, 4},
5502 {"scl", s_alpha_coff_wrapper
, 5},
5503 {"tag", s_alpha_coff_wrapper
, 6},
5504 {"val", s_alpha_coff_wrapper
, 7},
5506 {"prologue", s_ignore
, 0},
5508 {"gprel32", s_alpha_gprel32
, 0},
5509 {"t_floating", s_alpha_float_cons
, 'd'},
5510 {"s_floating", s_alpha_float_cons
, 'f'},
5511 {"f_floating", s_alpha_float_cons
, 'F'},
5512 {"g_floating", s_alpha_float_cons
, 'G'},
5513 {"d_floating", s_alpha_float_cons
, 'D'},
5515 {"proc", s_alpha_proc
, 0},
5516 {"aproc", s_alpha_proc
, 1},
5517 {"set", s_alpha_set
, 0},
5518 {"reguse", s_ignore
, 0},
5519 {"livereg", s_ignore
, 0},
5520 {"base", s_alpha_base
, 0}, /*??*/
5521 {"option", s_ignore
, 0},
5522 {"aent", s_ignore
, 0},
5523 {"ugen", s_ignore
, 0},
5524 {"eflag", s_ignore
, 0},
5526 {"align", s_alpha_align
, 0},
5527 {"double", s_alpha_float_cons
, 'd'},
5528 {"float", s_alpha_float_cons
, 'f'},
5529 {"single", s_alpha_float_cons
, 'f'},
5530 {"ascii", s_alpha_stringer
, 0},
5531 {"asciz", s_alpha_stringer
, 1},
5532 {"string", s_alpha_stringer
, 1},
5533 {"space", s_alpha_space
, 0},
5534 {"skip", s_alpha_space
, 0},
5535 {"zero", s_alpha_space
, 0},
5537 /* Unaligned data pseudos. */
5538 {"uword", s_alpha_ucons
, 2},
5539 {"ulong", s_alpha_ucons
, 4},
5540 {"uquad", s_alpha_ucons
, 8},
5543 /* Dwarf wants these versions of unaligned. */
5544 {"2byte", s_alpha_ucons
, 2},
5545 {"4byte", s_alpha_ucons
, 4},
5546 {"8byte", s_alpha_ucons
, 8},
5549 /* We don't do any optimizing, so we can safely ignore these. */
5550 {"noalias", s_ignore
, 0},
5551 {"alias", s_ignore
, 0},
5553 {"arch", s_alpha_arch
, 0},
5558 /* Build a BFD section with its flags set appropriately for the .lita,
5559 .lit8, or .lit4 sections. */
5562 create_literal_section (name
, secp
, symp
)
5567 segT current_section
= now_seg
;
5568 int current_subsec
= now_subseg
;
5571 *secp
= new_sec
= subseg_new (name
, 0);
5572 subseg_set (current_section
, current_subsec
);
5573 bfd_set_section_alignment (stdoutput
, new_sec
, 4);
5574 bfd_set_section_flags (stdoutput
, new_sec
,
5575 SEC_RELOC
| SEC_ALLOC
| SEC_LOAD
| SEC_READONLY
5578 S_CLEAR_EXTERNAL (*symp
= section_symbol (new_sec
));
5583 /* @@@ GP selection voodoo. All of this seems overly complicated and
5584 unnecessary; which is the primary reason it's for ECOFF only. */
5585 static inline void maybe_set_gp
PARAMS ((asection
*));
5594 vma
= bfd_get_section_vma (foo
, sec
);
5595 if (vma
&& vma
< alpha_gp_value
)
5596 alpha_gp_value
= vma
;
5602 assert (alpha_gp_value
== 0);
5604 /* Get minus-one in whatever width... */
5608 /* Select the smallest VMA of these existing sections. */
5609 maybe_set_gp (alpha_lita_section
);
5611 /* These were disabled before -- should we use them? */
5612 maybe_set_gp (sdata
);
5613 maybe_set_gp (lit8_sec
);
5614 maybe_set_gp (lit4_sec
);
5617 /* @@ Will a simple 0x8000 work here? If not, why not? */
5618 #define GP_ADJUSTMENT (0x8000 - 0x10)
5620 alpha_gp_value
+= GP_ADJUSTMENT
;
5622 S_SET_VALUE (alpha_gp_symbol
, alpha_gp_value
);
5625 printf (_("Chose GP value of %lx\n"), alpha_gp_value
);
5628 #endif /* OBJ_ECOFF */
5631 /* Map 's' to SHF_ALPHA_GPREL. */
5634 alpha_elf_section_letter (letter
, ptr_msg
)
5639 return SHF_ALPHA_GPREL
;
5641 *ptr_msg
= _("Bad .section directive: want a,s,w,x,M,S,G,T in string");
5645 /* Map SHF_ALPHA_GPREL to SEC_SMALL_DATA. */
5648 alpha_elf_section_flags (flags
, attr
, type
)
5650 int attr
, type ATTRIBUTE_UNUSED
;
5652 if (attr
& SHF_ALPHA_GPREL
)
5653 flags
|= SEC_SMALL_DATA
;
5656 #endif /* OBJ_ELF */
5658 /* Called internally to handle all alignment needs. This takes care
5659 of eliding calls to frag_align if'n the cached current alignment
5660 says we've already got it, as well as taking care of the auto-align
5661 feature wrt labels. */
5664 alpha_align (n
, pfill
, label
, force
)
5668 int force ATTRIBUTE_UNUSED
;
5670 if (alpha_current_align
>= n
)
5675 if (subseg_text_p (now_seg
))
5676 frag_align_code (n
, 0);
5678 frag_align (n
, 0, 0);
5681 frag_align (n
, *pfill
, 0);
5683 alpha_current_align
= n
;
5685 if (label
!= NULL
&& S_GET_SEGMENT (label
) == now_seg
)
5687 symbol_set_frag (label
, frag_now
);
5688 S_SET_VALUE (label
, (valueT
) frag_now_fix ());
5691 record_alignment (now_seg
, n
);
5693 /* ??? If alpha_flag_relax && force && elf, record the requested alignment
5694 in a reloc for the linker to see. */
5697 /* This is called from HANDLE_ALIGN in write.c. Fill in the contents
5698 of an rs_align_code fragment. */
5701 alpha_handle_align (fragp
)
5704 static char const unop
[4] = { 0x00, 0x00, 0xfe, 0x2f };
5705 static char const nopunop
[8] = {
5706 0x1f, 0x04, 0xff, 0x47,
5707 0x00, 0x00, 0xfe, 0x2f
5713 if (fragp
->fr_type
!= rs_align_code
)
5716 bytes
= fragp
->fr_next
->fr_address
- fragp
->fr_address
- fragp
->fr_fix
;
5717 p
= fragp
->fr_literal
+ fragp
->fr_fix
;
5730 memcpy (p
, unop
, 4);
5736 memcpy (p
, nopunop
, 8);
5738 fragp
->fr_fix
+= fix
;
5742 /* The Alpha has support for some VAX floating point types, as well as for
5743 IEEE floating point. We consider IEEE to be the primary floating point
5744 format, and sneak in the VAX floating point support here. */
5745 #define md_atof vax_md_atof
5746 #include "config/atof-vax.c"