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
77 bfd_reloc_code_real_type reloc
;
83 struct alpha_fixup fixups
[MAX_INSN_FIXUPS
];
87 enum alpha_macro_arg
{
99 void (*emit
) PARAMS ((const expressionS
*, int, const PTR
));
101 enum alpha_macro_arg argsets
[16];
104 /* Extra expression types. */
106 #define O_pregister O_md1 /* O_register, in parentheses */
107 #define O_cpregister O_md2 /* + a leading comma */
109 /* The alpha_reloc_op table below depends on the ordering of these. */
110 #define O_literal O_md3 /* !literal relocation */
111 #define O_lituse_addr O_md4 /* !lituse_addr relocation */
112 #define O_lituse_base O_md5 /* !lituse_base relocation */
113 #define O_lituse_bytoff O_md6 /* !lituse_bytoff relocation */
114 #define O_lituse_jsr O_md7 /* !lituse_jsr relocation */
115 #define O_lituse_tlsgd O_md8 /* !lituse_tlsgd relocation */
116 #define O_lituse_tlsldm O_md9 /* !lituse_tlsldm relocation */
117 #define O_gpdisp O_md10 /* !gpdisp relocation */
118 #define O_gprelhigh O_md11 /* !gprelhigh relocation */
119 #define O_gprellow O_md12 /* !gprellow relocation */
120 #define O_gprel O_md13 /* !gprel relocation */
121 #define O_samegp O_md14 /* !samegp relocation */
122 #define O_tlsgd O_md15 /* !tlsgd relocation */
123 #define O_tlsldm O_md16 /* !tlsldm relocation */
124 #define O_gotdtprel O_md17 /* !gotdtprel relocation */
125 #define O_dtprelhi O_md18 /* !dtprelhi relocation */
126 #define O_dtprello O_md19 /* !dtprello relocation */
127 #define O_dtprel O_md20 /* !dtprel relocation */
128 #define O_gottprel O_md21 /* !gottprel relocation */
129 #define O_tprelhi O_md22 /* !tprelhi relocation */
130 #define O_tprello O_md23 /* !tprello relocation */
131 #define O_tprel O_md24 /* !tprel relocation */
133 #define DUMMY_RELOC_LITUSE_ADDR (BFD_RELOC_UNUSED + 1)
134 #define DUMMY_RELOC_LITUSE_BASE (BFD_RELOC_UNUSED + 2)
135 #define DUMMY_RELOC_LITUSE_BYTOFF (BFD_RELOC_UNUSED + 3)
136 #define DUMMY_RELOC_LITUSE_JSR (BFD_RELOC_UNUSED + 4)
137 #define DUMMY_RELOC_LITUSE_TLSGD (BFD_RELOC_UNUSED + 5)
138 #define DUMMY_RELOC_LITUSE_TLSLDM (BFD_RELOC_UNUSED + 6)
140 #define LITUSE_ADDR 0
141 #define LITUSE_BASE 1
142 #define LITUSE_BYTOFF 2
144 #define LITUSE_TLSGD 4
145 #define LITUSE_TLSLDM 5
147 #define USER_RELOC_P(R) ((R) >= O_literal && (R) <= O_tprel)
149 /* Macros for extracting the type and number of encoded register tokens */
151 #define is_ir_num(x) (((x) & 32) == 0)
152 #define is_fpr_num(x) (((x) & 32) != 0)
153 #define regno(x) ((x) & 31)
155 /* Something odd inherited from the old assembler */
157 #define note_gpreg(R) (alpha_gprmask |= (1 << (R)))
158 #define note_fpreg(R) (alpha_fprmask |= (1 << (R)))
160 /* Predicates for 16- and 32-bit ranges */
161 /* XXX: The non-shift version appears to trigger a compiler bug when
162 cross-assembling from x86 w/ gcc 2.7.2. */
165 #define range_signed_16(x) \
166 (((offsetT) (x) >> 15) == 0 || ((offsetT) (x) >> 15) == -1)
167 #define range_signed_32(x) \
168 (((offsetT) (x) >> 31) == 0 || ((offsetT) (x) >> 31) == -1)
170 #define range_signed_16(x) ((offsetT) (x) >= -(offsetT) 0x8000 && \
171 (offsetT) (x) <= (offsetT) 0x7FFF)
172 #define range_signed_32(x) ((offsetT) (x) >= -(offsetT) 0x80000000 && \
173 (offsetT) (x) <= (offsetT) 0x7FFFFFFF)
176 /* Macros for sign extending from 16- and 32-bits. */
177 /* XXX: The cast macros will work on all the systems that I care about,
178 but really a predicate should be found to use the non-cast forms. */
181 #define sign_extend_16(x) ((short) (x))
182 #define sign_extend_32(x) ((int) (x))
184 #define sign_extend_16(x) ((offsetT) (((x) & 0xFFFF) ^ 0x8000) - 0x8000)
185 #define sign_extend_32(x) ((offsetT) (((x) & 0xFFFFFFFF) \
186 ^ 0x80000000) - 0x80000000)
189 /* Macros to build tokens */
191 #define set_tok_reg(t, r) (memset (&(t), 0, sizeof (t)), \
192 (t).X_op = O_register, \
193 (t).X_add_number = (r))
194 #define set_tok_preg(t, r) (memset (&(t), 0, sizeof (t)), \
195 (t).X_op = O_pregister, \
196 (t).X_add_number = (r))
197 #define set_tok_cpreg(t, r) (memset (&(t), 0, sizeof (t)), \
198 (t).X_op = O_cpregister, \
199 (t).X_add_number = (r))
200 #define set_tok_freg(t, r) (memset (&(t), 0, sizeof (t)), \
201 (t).X_op = O_register, \
202 (t).X_add_number = (r) + 32)
203 #define set_tok_sym(t, s, a) (memset (&(t), 0, sizeof (t)), \
204 (t).X_op = O_symbol, \
205 (t).X_add_symbol = (s), \
206 (t).X_add_number = (a))
207 #define set_tok_const(t, n) (memset (&(t), 0, sizeof (t)), \
208 (t).X_op = O_constant, \
209 (t).X_add_number = (n))
211 /* Prototypes for all local functions */
213 static struct alpha_reloc_tag
*get_alpha_reloc_tag
PARAMS ((long));
214 static void alpha_adjust_symtab_relocs
PARAMS ((bfd
*, asection
*, PTR
));
216 static int tokenize_arguments
PARAMS ((char *, expressionS
*, int));
217 static const struct alpha_opcode
*find_opcode_match
218 PARAMS ((const struct alpha_opcode
*, const expressionS
*, int *, int *));
219 static const struct alpha_macro
*find_macro_match
220 PARAMS ((const struct alpha_macro
*, const expressionS
*, int *));
221 static unsigned insert_operand
222 PARAMS ((unsigned, const struct alpha_operand
*, offsetT
, char *, unsigned));
223 static void assemble_insn
224 PARAMS ((const struct alpha_opcode
*, const expressionS
*, int,
225 struct alpha_insn
*, bfd_reloc_code_real_type
));
226 static void emit_insn
PARAMS ((struct alpha_insn
*));
227 static void assemble_tokens_to_insn
228 PARAMS ((const char *, const expressionS
*, int, struct alpha_insn
*));
229 static void assemble_tokens
230 PARAMS ((const char *, const expressionS
*, int, int));
232 static long load_expression
233 PARAMS ((int, const expressionS
*, int *, expressionS
*));
235 static void emit_ldgp
PARAMS ((const expressionS
*, int, const PTR
));
236 static void emit_division
PARAMS ((const expressionS
*, int, const PTR
));
237 static void emit_lda
PARAMS ((const expressionS
*, int, const PTR
));
238 static void emit_ldah
PARAMS ((const expressionS
*, int, const PTR
));
239 static void emit_ir_load
PARAMS ((const expressionS
*, int, const PTR
));
240 static void emit_loadstore
PARAMS ((const expressionS
*, int, const PTR
));
241 static void emit_jsrjmp
PARAMS ((const expressionS
*, int, const PTR
));
242 static void emit_ldX
PARAMS ((const expressionS
*, int, const PTR
));
243 static void emit_ldXu
PARAMS ((const expressionS
*, int, const PTR
));
244 static void emit_uldX
PARAMS ((const expressionS
*, int, const PTR
));
245 static void emit_uldXu
PARAMS ((const expressionS
*, int, const PTR
));
246 static void emit_ldil
PARAMS ((const expressionS
*, int, const PTR
));
247 static void emit_stX
PARAMS ((const expressionS
*, int, const PTR
));
248 static void emit_ustX
PARAMS ((const expressionS
*, int, const PTR
));
249 static void emit_sextX
PARAMS ((const expressionS
*, int, const PTR
));
250 static void emit_retjcr
PARAMS ((const expressionS
*, int, const PTR
));
252 static void s_alpha_text
PARAMS ((int));
253 static void s_alpha_data
PARAMS ((int));
255 static void s_alpha_comm
PARAMS ((int));
256 static void s_alpha_rdata
PARAMS ((int));
259 static void s_alpha_sdata
PARAMS ((int));
262 static void s_alpha_section
PARAMS ((int));
263 static void s_alpha_ent
PARAMS ((int));
264 static void s_alpha_end
PARAMS ((int));
265 static void s_alpha_mask
PARAMS ((int));
266 static void s_alpha_frame
PARAMS ((int));
267 static void s_alpha_prologue
PARAMS ((int));
268 static void s_alpha_file
PARAMS ((int));
269 static void s_alpha_loc
PARAMS ((int));
270 static void s_alpha_stab
PARAMS ((int));
271 static void s_alpha_coff_wrapper
PARAMS ((int));
274 static void s_alpha_section
PARAMS ((int));
276 static void s_alpha_gprel32
PARAMS ((int));
277 static void s_alpha_float_cons
PARAMS ((int));
278 static void s_alpha_proc
PARAMS ((int));
279 static void s_alpha_set
PARAMS ((int));
280 static void s_alpha_base
PARAMS ((int));
281 static void s_alpha_align
PARAMS ((int));
282 static void s_alpha_stringer
PARAMS ((int));
283 static void s_alpha_space
PARAMS ((int));
284 static void s_alpha_ucons
PARAMS ((int));
285 static void s_alpha_arch
PARAMS ((int));
287 static void create_literal_section
PARAMS ((const char *, segT
*, symbolS
**));
289 static void select_gp_value
PARAMS ((void));
291 static void alpha_align
PARAMS ((int, char *, symbolS
*, int));
293 /* Generic assembler global variables which must be defined by all
296 /* Characters which always start a comment. */
297 const char comment_chars
[] = "#";
299 /* Characters which start a comment at the beginning of a line. */
300 const char line_comment_chars
[] = "#";
302 /* Characters which may be used to separate multiple commands on a
304 const char line_separator_chars
[] = ";";
306 /* Characters which are used to indicate an exponent in a floating
308 const char EXP_CHARS
[] = "eE";
310 /* Characters which mean that a number is a floating point constant,
313 const char FLT_CHARS
[] = "dD";
315 /* XXX: Do all of these really get used on the alpha?? */
316 char FLT_CHARS
[] = "rRsSfFdDxXpP";
320 const char *md_shortopts
= "Fm:g+1h:HG:";
322 const char *md_shortopts
= "Fm:gG:";
325 struct option md_longopts
[] = {
326 #define OPTION_32ADDR (OPTION_MD_BASE)
327 { "32addr", no_argument
, NULL
, OPTION_32ADDR
},
328 #define OPTION_RELAX (OPTION_32ADDR + 1)
329 { "relax", no_argument
, NULL
, OPTION_RELAX
},
331 #define OPTION_MDEBUG (OPTION_RELAX + 1)
332 #define OPTION_NO_MDEBUG (OPTION_MDEBUG + 1)
333 { "mdebug", no_argument
, NULL
, OPTION_MDEBUG
},
334 { "no-mdebug", no_argument
, NULL
, OPTION_NO_MDEBUG
},
336 { NULL
, no_argument
, NULL
, 0 }
339 size_t md_longopts_size
= sizeof (md_longopts
);
343 #define AXP_REG_R16 16
344 #define AXP_REG_R17 17
346 #define AXP_REG_T9 22
348 #define AXP_REG_T10 23
350 #define AXP_REG_T11 24
352 #define AXP_REG_T12 25
353 #define AXP_REG_AI 25
355 #define AXP_REG_FP 29
358 #define AXP_REG_GP AXP_REG_PV
359 #endif /* OBJ_EVAX */
361 /* The cpu for which we are generating code */
362 static unsigned alpha_target
= AXP_OPCODE_BASE
;
363 static const char *alpha_target_name
= "<all>";
365 /* The hash table of instruction opcodes */
366 static struct hash_control
*alpha_opcode_hash
;
368 /* The hash table of macro opcodes */
369 static struct hash_control
*alpha_macro_hash
;
372 /* The $gp relocation symbol */
373 static symbolS
*alpha_gp_symbol
;
375 /* XXX: what is this, and why is it exported? */
376 valueT alpha_gp_value
;
379 /* The current $gp register */
380 static int alpha_gp_register
= AXP_REG_GP
;
382 /* A table of the register symbols */
383 static symbolS
*alpha_register_table
[64];
385 /* Constant sections, or sections of constants */
387 static segT alpha_lita_section
;
388 static segT alpha_lit4_section
;
391 static segT alpha_link_section
;
392 static segT alpha_ctors_section
;
393 static segT alpha_dtors_section
;
395 static segT alpha_lit8_section
;
397 /* Symbols referring to said sections. */
399 static symbolS
*alpha_lita_symbol
;
400 static symbolS
*alpha_lit4_symbol
;
403 static symbolS
*alpha_link_symbol
;
404 static symbolS
*alpha_ctors_symbol
;
405 static symbolS
*alpha_dtors_symbol
;
407 static symbolS
*alpha_lit8_symbol
;
409 /* Literal for .litX+0x8000 within .lita */
411 static offsetT alpha_lit4_literal
;
412 static offsetT alpha_lit8_literal
;
416 /* The active .ent symbol. */
417 static symbolS
*alpha_cur_ent_sym
;
420 /* Is the assembler not allowed to use $at? */
421 static int alpha_noat_on
= 0;
423 /* Are macros enabled? */
424 static int alpha_macros_on
= 1;
426 /* Are floats disabled? */
427 static int alpha_nofloats_on
= 0;
429 /* Are addresses 32 bit? */
430 static int alpha_addr32_on
= 0;
432 /* Symbol labelling the current insn. When the Alpha gas sees
435 and the section happens to not be on an eight byte boundary, it
436 will align both the symbol and the .quad to an eight byte boundary. */
437 static symbolS
*alpha_insn_label
;
439 /* Whether we should automatically align data generation pseudo-ops.
440 .align 0 will turn this off. */
441 static int alpha_auto_align_on
= 1;
443 /* The known current alignment of the current section. */
444 static int alpha_current_align
;
446 /* These are exported to ECOFF code. */
447 unsigned long alpha_gprmask
, alpha_fprmask
;
449 /* Whether the debugging option was seen. */
450 static int alpha_debug
;
453 /* Whether we are emitting an mdebug section. */
454 int alpha_flag_mdebug
= -1;
457 /* Don't fully resolve relocations, allowing code movement in the linker. */
458 static int alpha_flag_relax
;
460 /* What value to give to bfd_set_gp_size. */
461 static int g_switch_value
= 8;
464 /* Collect information about current procedure here. */
466 symbolS
*symbol
; /* proc pdesc symbol */
468 int framereg
; /* register for frame pointer */
469 int framesize
; /* size of frame */
479 static int alpha_flag_hash_long_names
= 0; /* -+ */
480 static int alpha_flag_show_after_trunc
= 0; /* -H */
482 /* If the -+ switch is given, then a hash is appended to any name that is
483 * longer than 64 characters, else longer symbol names are truncated.
489 /* A table to map the spelling of a relocation operand into an appropriate
490 bfd_reloc_code_real_type type. The table is assumed to be ordered such
491 that op-O_literal indexes into it. */
493 #define ALPHA_RELOC_TABLE(op) \
494 (&alpha_reloc_op[ ((!USER_RELOC_P (op)) \
496 : (int) (op) - (int) O_literal) ])
498 #define DEF(NAME, RELOC, REQ, ALLOW) \
499 { #NAME, sizeof(#NAME)-1, O_##NAME, RELOC, REQ, ALLOW}
501 static const struct alpha_reloc_op_tag
{
502 const char *name
; /* string to lookup */
503 size_t length
; /* size of the string */
504 operatorT op
; /* which operator to use */
505 bfd_reloc_code_real_type reloc
; /* relocation before frob */
506 unsigned int require_seq
: 1; /* require a sequence number */
507 unsigned int allow_seq
: 1; /* allow a sequence number */
508 } alpha_reloc_op
[] = {
509 DEF(literal
, BFD_RELOC_ALPHA_ELF_LITERAL
, 0, 1),
510 DEF(lituse_addr
, DUMMY_RELOC_LITUSE_ADDR
, 1, 1),
511 DEF(lituse_base
, DUMMY_RELOC_LITUSE_BASE
, 1, 1),
512 DEF(lituse_bytoff
, DUMMY_RELOC_LITUSE_BYTOFF
, 1, 1),
513 DEF(lituse_jsr
, DUMMY_RELOC_LITUSE_JSR
, 1, 1),
514 DEF(lituse_tlsgd
, DUMMY_RELOC_LITUSE_TLSGD
, 1, 1),
515 DEF(lituse_tlsldm
, DUMMY_RELOC_LITUSE_TLSLDM
, 1, 1),
516 DEF(gpdisp
, BFD_RELOC_ALPHA_GPDISP
, 1, 1),
517 DEF(gprelhigh
, BFD_RELOC_ALPHA_GPREL_HI16
, 0, 0),
518 DEF(gprellow
, BFD_RELOC_ALPHA_GPREL_LO16
, 0, 0),
519 DEF(gprel
, BFD_RELOC_GPREL16
, 0, 0),
520 DEF(samegp
, BFD_RELOC_ALPHA_BRSGP
, 0, 0),
521 DEF(tlsgd
, BFD_RELOC_ALPHA_TLSGD
, 0, 1),
522 DEF(tlsldm
, BFD_RELOC_ALPHA_TLSLDM
, 0, 1),
523 DEF(gotdtprel
, BFD_RELOC_ALPHA_GOTDTPREL16
, 0, 0),
524 DEF(dtprelhi
, BFD_RELOC_ALPHA_DTPREL_HI16
, 0, 0),
525 DEF(dtprello
, BFD_RELOC_ALPHA_DTPREL_LO16
, 0, 0),
526 DEF(dtprel
, BFD_RELOC_ALPHA_DTPREL16
, 0, 0),
527 DEF(gottprel
, BFD_RELOC_ALPHA_GOTTPREL16
, 0, 0),
528 DEF(tprelhi
, BFD_RELOC_ALPHA_TPREL_HI16
, 0, 0),
529 DEF(tprello
, BFD_RELOC_ALPHA_TPREL_LO16
, 0, 0),
530 DEF(tprel
, BFD_RELOC_ALPHA_TPREL16
, 0, 0),
535 static const int alpha_num_reloc_op
536 = sizeof (alpha_reloc_op
) / sizeof (*alpha_reloc_op
);
537 #endif /* RELOC_OP_P */
539 /* Maximum # digits needed to hold the largest sequence # */
540 #define ALPHA_RELOC_DIGITS 25
542 /* Structure to hold explict sequence information. */
543 struct alpha_reloc_tag
545 fixS
*master
; /* the literal reloc */
546 fixS
*slaves
; /* head of linked list of lituses */
547 segT segment
; /* segment relocs are in or undefined_section*/
548 long sequence
; /* sequence # */
549 unsigned n_master
; /* # of literals */
550 unsigned n_slaves
; /* # of lituses */
551 unsigned saw_tlsgd
: 1; /* true if ... */
552 unsigned saw_tlsldm
: 1;
553 unsigned saw_lu_tlsgd
: 1;
554 unsigned saw_lu_tlsldm
: 1;
555 unsigned multi_section_p
: 1; /* true if more than one section was used */
556 char string
[1]; /* printable form of sequence to hash with */
559 /* Hash table to link up literals with the appropriate lituse */
560 static struct hash_control
*alpha_literal_hash
;
562 /* Sequence numbers for internal use by macros. */
563 static long next_sequence_num
= -1;
565 /* A table of CPU names and opcode sets. */
567 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
) },
587 { "ev4", AXP_OPCODE_BASE
},
588 { "ev45", AXP_OPCODE_BASE
},
589 { "lca45", AXP_OPCODE_BASE
},
590 { "ev5", AXP_OPCODE_BASE
},
591 { "ev56", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
},
592 { "pca56", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
|AXP_OPCODE_MAX
},
593 { "ev6", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
|AXP_OPCODE_MAX
|AXP_OPCODE_CIX
},
595 { "all", AXP_OPCODE_BASE
},
599 /* The macro table */
601 static const struct alpha_macro alpha_macros
[] = {
602 /* Load/Store macros */
603 { "lda", emit_lda
, NULL
,
604 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
605 { "ldah", emit_ldah
, NULL
,
606 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
608 { "ldl", emit_ir_load
, "ldl",
609 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
610 { "ldl_l", emit_ir_load
, "ldl_l",
611 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
612 { "ldq", emit_ir_load
, "ldq",
613 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
614 { "ldq_l", emit_ir_load
, "ldq_l",
615 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
616 { "ldq_u", emit_ir_load
, "ldq_u",
617 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
618 { "ldf", emit_loadstore
, "ldf",
619 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
620 { "ldg", emit_loadstore
, "ldg",
621 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
622 { "lds", emit_loadstore
, "lds",
623 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
624 { "ldt", emit_loadstore
, "ldt",
625 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
627 { "ldb", emit_ldX
, (PTR
) 0,
628 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
629 { "ldbu", emit_ldXu
, (PTR
) 0,
630 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
631 { "ldw", emit_ldX
, (PTR
) 1,
632 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
633 { "ldwu", emit_ldXu
, (PTR
) 1,
634 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
636 { "uldw", emit_uldX
, (PTR
) 1,
637 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
638 { "uldwu", emit_uldXu
, (PTR
) 1,
639 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
640 { "uldl", emit_uldX
, (PTR
) 2,
641 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
642 { "uldlu", emit_uldXu
, (PTR
) 2,
643 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
644 { "uldq", emit_uldXu
, (PTR
) 3,
645 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
647 { "ldgp", emit_ldgp
, NULL
,
648 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
} },
650 { "ldi", emit_lda
, NULL
,
651 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
652 { "ldil", emit_ldil
, NULL
,
653 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
654 { "ldiq", emit_lda
, NULL
,
655 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
657 { "ldif" emit_ldiq
, NULL
,
658 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
659 { "ldid" emit_ldiq
, NULL
,
660 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
661 { "ldig" emit_ldiq
, NULL
,
662 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
663 { "ldis" emit_ldiq
, NULL
,
664 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
665 { "ldit" emit_ldiq
, NULL
,
666 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
669 { "stl", emit_loadstore
, "stl",
670 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
671 { "stl_c", emit_loadstore
, "stl_c",
672 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
673 { "stq", emit_loadstore
, "stq",
674 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
675 { "stq_c", emit_loadstore
, "stq_c",
676 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
677 { "stq_u", emit_loadstore
, "stq_u",
678 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
679 { "stf", emit_loadstore
, "stf",
680 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
681 { "stg", emit_loadstore
, "stg",
682 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
683 { "sts", emit_loadstore
, "sts",
684 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
685 { "stt", emit_loadstore
, "stt",
686 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
688 { "stb", emit_stX
, (PTR
) 0,
689 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
690 { "stw", emit_stX
, (PTR
) 1,
691 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
692 { "ustw", emit_ustX
, (PTR
) 1,
693 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
694 { "ustl", emit_ustX
, (PTR
) 2,
695 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
696 { "ustq", emit_ustX
, (PTR
) 3,
697 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
699 /* Arithmetic macros */
701 { "absl" emit_absl
, 1, { IR
} },
702 { "absl" emit_absl
, 2, { IR
, IR
} },
703 { "absl" emit_absl
, 2, { EXP
, IR
} },
704 { "absq" emit_absq
, 1, { IR
} },
705 { "absq" emit_absq
, 2, { IR
, IR
} },
706 { "absq" emit_absq
, 2, { EXP
, IR
} },
709 { "sextb", emit_sextX
, (PTR
) 0,
710 { MACRO_IR
, MACRO_IR
, MACRO_EOA
,
712 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
713 { "sextw", emit_sextX
, (PTR
) 1,
714 { MACRO_IR
, MACRO_IR
, MACRO_EOA
,
716 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
718 { "divl", emit_division
, "__divl",
719 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
720 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
721 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
722 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
723 { "divlu", emit_division
, "__divlu",
724 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
725 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
726 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
727 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
728 { "divq", emit_division
, "__divq",
729 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
730 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
731 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
732 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
733 { "divqu", emit_division
, "__divqu",
734 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
735 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
736 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
737 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
738 { "reml", emit_division
, "__reml",
739 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
740 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
741 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
742 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
743 { "remlu", emit_division
, "__remlu",
744 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
745 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
746 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
747 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
748 { "remq", emit_division
, "__remq",
749 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
750 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
751 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
752 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
753 { "remqu", emit_division
, "__remqu",
754 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
755 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
756 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
757 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
759 { "jsr", emit_jsrjmp
, "jsr",
760 { MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
761 MACRO_PIR
, MACRO_EOA
,
762 MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
763 MACRO_EXP
, MACRO_EOA
} },
764 { "jmp", emit_jsrjmp
, "jmp",
765 { MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
766 MACRO_PIR
, MACRO_EOA
,
767 MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
768 MACRO_EXP
, MACRO_EOA
} },
769 { "ret", emit_retjcr
, "ret",
770 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
772 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
773 MACRO_PIR
, MACRO_EOA
,
774 MACRO_EXP
, MACRO_EOA
,
776 { "jcr", emit_retjcr
, "jcr",
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 { "jsr_coroutine", 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
,
792 static const unsigned int alpha_num_macros
793 = sizeof (alpha_macros
) / sizeof (*alpha_macros
);
795 /* Public interface functions */
797 /* This function is called once, at assembler startup time. It sets
798 up all the tables, etc. that the MD part of the assembler will
799 need, that can be determined before arguments are parsed. */
806 /* Verify that X_op field is wide enough. */
810 assert (e
.X_op
== O_max
);
813 /* Create the opcode hash table */
815 alpha_opcode_hash
= hash_new ();
816 for (i
= 0; i
< alpha_num_opcodes
;)
818 const char *name
, *retval
, *slash
;
820 name
= alpha_opcodes
[i
].name
;
821 retval
= hash_insert (alpha_opcode_hash
, name
, (PTR
) &alpha_opcodes
[i
]);
823 as_fatal (_("internal error: can't hash opcode `%s': %s"),
826 /* Some opcodes include modifiers of various sorts with a "/mod"
827 syntax, like the architecture manual suggests. However, for
828 use with gcc at least, we also need access to those same opcodes
831 if ((slash
= strchr (name
, '/')) != NULL
)
833 char *p
= xmalloc (strlen (name
));
834 memcpy (p
, name
, slash
- name
);
835 strcpy (p
+ (slash
- name
), slash
+ 1);
837 (void) hash_insert (alpha_opcode_hash
, p
, (PTR
) &alpha_opcodes
[i
]);
838 /* Ignore failures -- the opcode table does duplicate some
839 variants in different forms, like "hw_stq" and "hw_st/q". */
842 while (++i
< alpha_num_opcodes
843 && (alpha_opcodes
[i
].name
== name
844 || !strcmp (alpha_opcodes
[i
].name
, name
)))
848 /* Create the macro hash table */
850 alpha_macro_hash
= hash_new ();
851 for (i
= 0; i
< alpha_num_macros
;)
853 const char *name
, *retval
;
855 name
= alpha_macros
[i
].name
;
856 retval
= hash_insert (alpha_macro_hash
, name
, (PTR
) &alpha_macros
[i
]);
858 as_fatal (_("internal error: can't hash macro `%s': %s"),
861 while (++i
< alpha_num_macros
862 && (alpha_macros
[i
].name
== name
863 || !strcmp (alpha_macros
[i
].name
, name
)))
867 /* Construct symbols for each of the registers */
869 for (i
= 0; i
< 32; ++i
)
872 sprintf (name
, "$%d", i
);
873 alpha_register_table
[i
] = symbol_create (name
, reg_section
, i
,
879 sprintf (name
, "$f%d", i
- 32);
880 alpha_register_table
[i
] = symbol_create (name
, reg_section
, i
,
884 /* Create the special symbols and sections we'll be using */
886 /* So .sbss will get used for tiny objects. */
887 bfd_set_gp_size (stdoutput
, g_switch_value
);
890 create_literal_section (".lita", &alpha_lita_section
, &alpha_lita_symbol
);
892 /* For handling the GP, create a symbol that won't be output in the
893 symbol table. We'll edit it out of relocs later. */
894 alpha_gp_symbol
= symbol_create ("<GP value>", alpha_lita_section
, 0x8000,
899 create_literal_section (".link", &alpha_link_section
, &alpha_link_symbol
);
905 segT sec
= subseg_new (".mdebug", (subsegT
) 0);
906 bfd_set_section_flags (stdoutput
, sec
, SEC_HAS_CONTENTS
| SEC_READONLY
);
907 bfd_set_section_alignment (stdoutput
, sec
, 3);
911 /* Create literal lookup hash table. */
912 alpha_literal_hash
= hash_new ();
914 subseg_set (text_section
, 0);
917 /* The public interface to the instruction assembler. */
923 char opname
[32]; /* current maximum is 13 */
924 expressionS tok
[MAX_INSN_ARGS
];
928 /* split off the opcode */
929 opnamelen
= strspn (str
, "abcdefghijklmnopqrstuvwxyz_/46819");
930 trunclen
= (opnamelen
< sizeof (opname
) - 1
932 : sizeof (opname
) - 1);
933 memcpy (opname
, str
, trunclen
);
934 opname
[trunclen
] = '\0';
936 /* tokenize the rest of the line */
937 if ((ntok
= tokenize_arguments (str
+ opnamelen
, tok
, MAX_INSN_ARGS
)) < 0)
939 if (ntok
!= TOKENIZE_ERROR_REPORT
)
940 as_bad (_("syntax error"));
946 assemble_tokens (opname
, tok
, ntok
, alpha_macros_on
);
949 /* Round up a section's size to the appropriate boundary. */
952 md_section_align (seg
, size
)
956 int align
= bfd_get_section_alignment (stdoutput
, seg
);
957 valueT mask
= ((valueT
) 1 << align
) - 1;
959 return (size
+ mask
) & ~mask
;
962 /* Turn a string in input_line_pointer into a floating point constant
963 of type TYPE, and store the appropriate bytes in *LITP. The number
964 of LITTLENUMS emitted is stored in *SIZEP. An error message is
965 returned, or NULL on OK. */
967 /* Equal to MAX_PRECISION in atof-ieee.c */
968 #define MAX_LITTLENUMS 6
970 extern char *vax_md_atof
PARAMS ((int, char *, int *));
973 md_atof (type
, litP
, sizeP
)
979 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
980 LITTLENUM_TYPE
*wordP
;
987 /* VAX md_atof doesn't like "G" for some reason. */
991 return vax_md_atof (type
, litP
, sizeP
);
1014 return _("Bad call to MD_ATOF()");
1016 t
= atof_ieee (input_line_pointer
, type
, words
);
1018 input_line_pointer
= t
;
1019 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
1021 for (wordP
= words
+ prec
- 1; prec
--;)
1023 md_number_to_chars (litP
, (long) (*wordP
--), sizeof (LITTLENUM_TYPE
));
1024 litP
+= sizeof (LITTLENUM_TYPE
);
1030 /* Take care of the target-specific command-line options. */
1033 md_parse_option (c
, arg
)
1040 alpha_nofloats_on
= 1;
1044 alpha_addr32_on
= 1;
1052 g_switch_value
= atoi (arg
);
1057 const struct cpu_type
*p
;
1058 for (p
= cpu_types
; p
->name
; ++p
)
1059 if (strcmp (arg
, p
->name
) == 0)
1061 alpha_target_name
= p
->name
, alpha_target
= p
->flags
;
1064 as_warn (_("Unknown CPU identifier `%s'"), arg
);
1070 case '+': /* For g++. Hash any name > 63 chars long. */
1071 alpha_flag_hash_long_names
= 1;
1074 case 'H': /* Show new symbol after hash truncation */
1075 alpha_flag_show_after_trunc
= 1;
1078 case 'h': /* for gnu-c/vax compatibility. */
1083 alpha_flag_relax
= 1;
1088 alpha_flag_mdebug
= 1;
1090 case OPTION_NO_MDEBUG
:
1091 alpha_flag_mdebug
= 0;
1102 /* Print a description of the command-line options that we accept. */
1105 md_show_usage (stream
)
1110 -32addr treat addresses as 32-bit values\n\
1111 -F lack floating point instructions support\n\
1112 -mev4 | -mev45 | -mev5 | -mev56 | -mpca56 | -mev6 | -mall\n\
1113 specify variant of Alpha architecture\n\
1114 -m21064 | -m21066 | -m21164 | -m21164a | -m21164pc | -m21264\n\
1115 these variants include PALcode opcodes\n"),
1120 -+ hash encode (don't truncate) names longer than 64 characters\n\
1121 -H show new symbol after hash truncation\n"),
1126 /* Decide from what point a pc-relative relocation is relative to,
1127 relative to the pc-relative fixup. Er, relatively speaking. */
1130 md_pcrel_from (fixP
)
1133 valueT addr
= fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
1134 switch (fixP
->fx_r_type
)
1136 case BFD_RELOC_ALPHA_GPDISP
:
1137 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1138 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1141 return fixP
->fx_size
+ addr
;
1145 /* Attempt to simplify or even eliminate a fixup. The return value is
1146 ignored; perhaps it was once meaningful, but now it is historical.
1147 To indicate that a fixup has been eliminated, set fixP->fx_done.
1149 For ELF, here it is that we transform the GPDISP_HI16 reloc we used
1150 internally into the GPDISP reloc used externally. We had to do
1151 this so that we'd have the GPDISP_LO16 reloc as a tag to compute
1152 the distance to the "lda" instruction for setting the addend to
1156 md_apply_fix3 (fixP
, valP
, seg
)
1161 char * const fixpos
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
1162 valueT value
= * valP
;
1163 unsigned image
, size
;
1165 switch (fixP
->fx_r_type
)
1167 /* The GPDISP relocations are processed internally with a symbol
1168 referring to the current function; we need to drop in a value
1169 which, when added to the address of the start of the function,
1170 gives the desired GP. */
1171 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1173 fixS
*next
= fixP
->fx_next
;
1175 /* With user-specified !gpdisp relocations, we can be missing
1176 the matching LO16 reloc. We will have already issued an
1179 fixP
->fx_offset
= (next
->fx_frag
->fr_address
+ next
->fx_where
1180 - fixP
->fx_frag
->fr_address
- fixP
->fx_where
);
1182 value
= (value
- sign_extend_16 (value
)) >> 16;
1185 fixP
->fx_r_type
= BFD_RELOC_ALPHA_GPDISP
;
1189 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1190 value
= sign_extend_16 (value
);
1191 fixP
->fx_offset
= 0;
1197 fixP
->fx_addsy
= section_symbol (seg
);
1198 md_number_to_chars (fixpos
, value
, 2);
1203 fixP
->fx_r_type
= BFD_RELOC_16_PCREL
;
1208 fixP
->fx_r_type
= BFD_RELOC_32_PCREL
;
1213 fixP
->fx_r_type
= BFD_RELOC_64_PCREL
;
1216 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
1218 md_number_to_chars (fixpos
, value
, size
);
1224 case BFD_RELOC_GPREL32
:
1225 assert (fixP
->fx_subsy
== alpha_gp_symbol
);
1227 /* FIXME: inherited this obliviousness of `value' -- why? */
1228 md_number_to_chars (fixpos
, -alpha_gp_value
, 4);
1231 case BFD_RELOC_GPREL32
:
1233 case BFD_RELOC_GPREL16
:
1234 case BFD_RELOC_ALPHA_GPREL_HI16
:
1235 case BFD_RELOC_ALPHA_GPREL_LO16
:
1238 case BFD_RELOC_23_PCREL_S2
:
1239 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
1241 image
= bfd_getl32 (fixpos
);
1242 image
= (image
& ~0x1FFFFF) | ((value
>> 2) & 0x1FFFFF);
1247 case BFD_RELOC_ALPHA_HINT
:
1248 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
1250 image
= bfd_getl32 (fixpos
);
1251 image
= (image
& ~0x3FFF) | ((value
>> 2) & 0x3FFF);
1257 case BFD_RELOC_ALPHA_BRSGP
:
1258 case BFD_RELOC_ALPHA_TLSGD
:
1259 case BFD_RELOC_ALPHA_TLSLDM
:
1260 case BFD_RELOC_ALPHA_GOTDTPREL16
:
1261 case BFD_RELOC_ALPHA_DTPREL_HI16
:
1262 case BFD_RELOC_ALPHA_DTPREL_LO16
:
1263 case BFD_RELOC_ALPHA_DTPREL16
:
1264 case BFD_RELOC_ALPHA_GOTTPREL16
:
1265 case BFD_RELOC_ALPHA_TPREL_HI16
:
1266 case BFD_RELOC_ALPHA_TPREL_LO16
:
1267 case BFD_RELOC_ALPHA_TPREL16
:
1272 case BFD_RELOC_ALPHA_LITERAL
:
1273 md_number_to_chars (fixpos
, value
, 2);
1276 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1277 case BFD_RELOC_ALPHA_LITUSE
:
1278 case BFD_RELOC_ALPHA_LINKAGE
:
1279 case BFD_RELOC_ALPHA_CODEADDR
:
1282 case BFD_RELOC_VTABLE_INHERIT
:
1283 case BFD_RELOC_VTABLE_ENTRY
:
1288 const struct alpha_operand
*operand
;
1290 if ((int) fixP
->fx_r_type
>= 0)
1291 as_fatal (_("unhandled relocation type %s"),
1292 bfd_get_reloc_code_name (fixP
->fx_r_type
));
1294 assert (-(int) fixP
->fx_r_type
< (int) alpha_num_operands
);
1295 operand
= &alpha_operands
[-(int) fixP
->fx_r_type
];
1297 /* The rest of these fixups only exist internally during symbol
1298 resolution and have no representation in the object file.
1299 Therefore they must be completely resolved as constants. */
1301 if (fixP
->fx_addsy
!= 0
1302 && S_GET_SEGMENT (fixP
->fx_addsy
) != absolute_section
)
1303 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
1304 _("non-absolute expression in constant field"));
1306 image
= bfd_getl32 (fixpos
);
1307 image
= insert_operand (image
, operand
, (offsetT
) value
,
1308 fixP
->fx_file
, fixP
->fx_line
);
1313 if (fixP
->fx_addsy
!= 0 || fixP
->fx_pcrel
!= 0)
1317 as_warn_where (fixP
->fx_file
, fixP
->fx_line
,
1318 _("type %d reloc done?\n"), (int) fixP
->fx_r_type
);
1323 md_number_to_chars (fixpos
, image
, 4);
1329 /* Look for a register name in the given symbol. */
1332 md_undefined_symbol (name
)
1337 int is_float
= 0, num
;
1342 if (name
[1] == 'p' && name
[2] == '\0')
1343 return alpha_register_table
[AXP_REG_FP
];
1348 if (!ISDIGIT (*++name
))
1352 case '0': case '1': case '2': case '3': case '4':
1353 case '5': case '6': case '7': case '8': case '9':
1354 if (name
[1] == '\0')
1355 num
= name
[0] - '0';
1356 else if (name
[0] != '0' && ISDIGIT (name
[1]) && name
[2] == '\0')
1358 num
= (name
[0] - '0') * 10 + name
[1] - '0';
1365 if (!alpha_noat_on
&& (num
+ is_float
) == AXP_REG_AT
)
1366 as_warn (_("Used $at without \".set noat\""));
1367 return alpha_register_table
[num
+ is_float
];
1370 if (name
[1] == 't' && name
[2] == '\0')
1373 as_warn (_("Used $at without \".set noat\""));
1374 return alpha_register_table
[AXP_REG_AT
];
1379 if (name
[1] == 'p' && name
[2] == '\0')
1380 return alpha_register_table
[alpha_gp_register
];
1384 if (name
[1] == 'p' && name
[2] == '\0')
1385 return alpha_register_table
[AXP_REG_SP
];
1393 /* @@@ Magic ECOFF bits. */
1396 alpha_frob_ecoff_data ()
1399 /* $zero and $f31 are read-only */
1400 alpha_gprmask
&= ~1;
1401 alpha_fprmask
&= ~1;
1405 /* Hook to remember a recently defined label so that the auto-align
1406 code can adjust the symbol after we know what alignment will be
1410 alpha_define_label (sym
)
1413 alpha_insn_label
= sym
;
1416 /* If we have a BRSGP reloc to a local symbol, adjust it to BRADDR and
1417 let it get resolved at assembly time. */
1420 alpha_validate_fix (f
)
1427 if (f
->fx_r_type
!= BFD_RELOC_ALPHA_BRSGP
)
1430 if (! S_IS_DEFINED (f
->fx_addsy
))
1433 switch (S_GET_OTHER (f
->fx_addsy
) & STO_ALPHA_STD_GPLOAD
)
1435 case STO_ALPHA_NOPV
:
1437 case STO_ALPHA_STD_GPLOAD
:
1441 if (S_IS_LOCAL (f
->fx_addsy
))
1444 name
= S_GET_NAME (f
->fx_addsy
);
1445 as_bad_where (f
->fx_file
, f
->fx_line
,
1446 _("!samegp reloc against symbol without .prologue: %s"),
1451 if (! (S_IS_EXTERN (f
->fx_addsy
) || S_IS_WEAK (f
->fx_addsy
)))
1453 f
->fx_r_type
= BFD_RELOC_23_PCREL_S2
;
1454 f
->fx_offset
+= offset
;
1459 /* Return true if we must always emit a reloc for a type and false if
1460 there is some hope of resolving it at assembly time. */
1463 alpha_force_relocation (f
)
1466 if (alpha_flag_relax
)
1469 switch (f
->fx_r_type
)
1471 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1472 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1473 case BFD_RELOC_ALPHA_GPDISP
:
1474 case BFD_RELOC_ALPHA_LITERAL
:
1475 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1476 case BFD_RELOC_ALPHA_LITUSE
:
1477 case BFD_RELOC_GPREL16
:
1478 case BFD_RELOC_GPREL32
:
1479 case BFD_RELOC_ALPHA_GPREL_HI16
:
1480 case BFD_RELOC_ALPHA_GPREL_LO16
:
1481 case BFD_RELOC_ALPHA_LINKAGE
:
1482 case BFD_RELOC_ALPHA_CODEADDR
:
1483 case BFD_RELOC_ALPHA_BRSGP
:
1484 case BFD_RELOC_VTABLE_INHERIT
:
1485 case BFD_RELOC_VTABLE_ENTRY
:
1486 case BFD_RELOC_ALPHA_TLSGD
:
1487 case BFD_RELOC_ALPHA_TLSLDM
:
1488 case BFD_RELOC_ALPHA_GOTDTPREL16
:
1489 case BFD_RELOC_ALPHA_DTPREL_HI16
:
1490 case BFD_RELOC_ALPHA_DTPREL_LO16
:
1491 case BFD_RELOC_ALPHA_DTPREL16
:
1492 case BFD_RELOC_ALPHA_GOTTPREL16
:
1493 case BFD_RELOC_ALPHA_TPREL_HI16
:
1494 case BFD_RELOC_ALPHA_TPREL_LO16
:
1495 case BFD_RELOC_ALPHA_TPREL16
:
1498 case BFD_RELOC_23_PCREL_S2
:
1501 case BFD_RELOC_ALPHA_HINT
:
1509 /* Return true if we can partially resolve a relocation now. */
1512 alpha_fix_adjustable (f
)
1516 /* Prevent all adjustments to global symbols */
1517 if (S_IS_EXTERN (f
->fx_addsy
) || S_IS_WEAK (f
->fx_addsy
))
1521 /* Are there any relocation types for which we must generate a reloc
1522 but we can adjust the values contained within it? */
1523 switch (f
->fx_r_type
)
1525 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1526 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1527 case BFD_RELOC_ALPHA_GPDISP
:
1528 case BFD_RELOC_ALPHA_BRSGP
:
1531 case BFD_RELOC_ALPHA_LITERAL
:
1532 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1533 case BFD_RELOC_ALPHA_LITUSE
:
1534 case BFD_RELOC_ALPHA_LINKAGE
:
1535 case BFD_RELOC_ALPHA_CODEADDR
:
1538 case BFD_RELOC_VTABLE_ENTRY
:
1539 case BFD_RELOC_VTABLE_INHERIT
:
1542 case BFD_RELOC_GPREL16
:
1543 case BFD_RELOC_GPREL32
:
1544 case BFD_RELOC_ALPHA_GPREL_HI16
:
1545 case BFD_RELOC_ALPHA_GPREL_LO16
:
1546 case BFD_RELOC_23_PCREL_S2
:
1549 case BFD_RELOC_ALPHA_HINT
:
1552 case BFD_RELOC_ALPHA_TLSGD
:
1553 case BFD_RELOC_ALPHA_TLSLDM
:
1554 case BFD_RELOC_ALPHA_GOTDTPREL16
:
1555 case BFD_RELOC_ALPHA_DTPREL_HI16
:
1556 case BFD_RELOC_ALPHA_DTPREL_LO16
:
1557 case BFD_RELOC_ALPHA_DTPREL16
:
1558 case BFD_RELOC_ALPHA_GOTTPREL16
:
1559 case BFD_RELOC_ALPHA_TPREL_HI16
:
1560 case BFD_RELOC_ALPHA_TPREL_LO16
:
1561 case BFD_RELOC_ALPHA_TPREL16
:
1562 /* ??? No idea why we can't return a reference to .tbss+10, but
1563 we're preventing this in the other assemblers. Follow for now. */
1572 /* Generate the BFD reloc to be stuck in the object file from the
1573 fixup used internally in the assembler. */
1576 tc_gen_reloc (sec
, fixp
)
1577 asection
*sec ATTRIBUTE_UNUSED
;
1582 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
1583 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
1584 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
1585 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
1587 /* Make sure none of our internal relocations make it this far.
1588 They'd better have been fully resolved by this point. */
1589 assert ((int) fixp
->fx_r_type
> 0);
1591 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
1592 if (reloc
->howto
== NULL
)
1594 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1595 _("cannot represent `%s' relocation in object file"),
1596 bfd_get_reloc_code_name (fixp
->fx_r_type
));
1600 if (!fixp
->fx_pcrel
!= !reloc
->howto
->pc_relative
)
1602 as_fatal (_("internal error? cannot generate `%s' relocation"),
1603 bfd_get_reloc_code_name (fixp
->fx_r_type
));
1605 assert (!fixp
->fx_pcrel
== !reloc
->howto
->pc_relative
);
1608 if (fixp
->fx_r_type
== BFD_RELOC_ALPHA_LITERAL
)
1610 /* fake out bfd_perform_relocation. sigh */
1611 reloc
->addend
= -alpha_gp_value
;
1616 reloc
->addend
= fixp
->fx_offset
;
1619 * Ohhh, this is ugly. The problem is that if this is a local global
1620 * symbol, the relocation will entirely be performed at link time, not
1621 * at assembly time. bfd_perform_reloc doesn't know about this sort
1622 * of thing, and as a result we need to fake it out here.
1624 if ((S_IS_EXTERN (fixp
->fx_addsy
) || S_IS_WEAK (fixp
->fx_addsy
)
1625 || (S_GET_SEGMENT (fixp
->fx_addsy
)->flags
& SEC_MERGE
)
1626 || (S_GET_SEGMENT (fixp
->fx_addsy
)->flags
& SEC_THREAD_LOCAL
))
1627 && !S_IS_COMMON (fixp
->fx_addsy
))
1628 reloc
->addend
-= symbol_get_bfdsym (fixp
->fx_addsy
)->value
;
1635 /* Parse a register name off of the input_line and return a register
1636 number. Gets md_undefined_symbol above to do the register name
1639 Only called as a part of processing the ECOFF .frame directive. */
1642 tc_get_register (frame
)
1643 int frame ATTRIBUTE_UNUSED
;
1645 int framereg
= AXP_REG_SP
;
1648 if (*input_line_pointer
== '$')
1650 char *s
= input_line_pointer
;
1651 char c
= get_symbol_end ();
1652 symbolS
*sym
= md_undefined_symbol (s
);
1654 *strchr (s
, '\0') = c
;
1655 if (sym
&& (framereg
= S_GET_VALUE (sym
)) <= 31)
1658 as_warn (_("frame reg expected, using $%d."), framereg
);
1661 note_gpreg (framereg
);
1665 /* This is called before the symbol table is processed. In order to
1666 work with gcc when using mips-tfile, we must keep all local labels.
1667 However, in other cases, we want to discard them. If we were
1668 called with -g, but we didn't see any debugging information, it may
1669 mean that gcc is smuggling debugging information through to
1670 mips-tfile, in which case we must generate all local labels. */
1675 alpha_frob_file_before_adjust ()
1677 if (alpha_debug
!= 0
1678 && ! ecoff_debugging_seen
)
1679 flag_keep_locals
= 1;
1682 #endif /* OBJ_ECOFF */
1684 static struct alpha_reloc_tag
*
1685 get_alpha_reloc_tag (sequence
)
1688 char buffer
[ALPHA_RELOC_DIGITS
];
1689 struct alpha_reloc_tag
*info
;
1691 sprintf (buffer
, "!%ld", sequence
);
1693 info
= (struct alpha_reloc_tag
*) hash_find (alpha_literal_hash
, buffer
);
1696 size_t len
= strlen (buffer
);
1699 info
= (struct alpha_reloc_tag
*)
1700 xcalloc (sizeof (struct alpha_reloc_tag
) + len
, 1);
1702 info
->segment
= now_seg
;
1703 info
->sequence
= sequence
;
1704 strcpy (info
->string
, buffer
);
1705 errmsg
= hash_insert (alpha_literal_hash
, info
->string
, (PTR
) info
);
1713 /* Before the relocations are written, reorder them, so that user
1714 supplied !lituse relocations follow the appropriate !literal
1715 relocations, and similarly for !gpdisp relocations. */
1718 alpha_adjust_symtab ()
1720 if (alpha_literal_hash
)
1721 bfd_map_over_sections (stdoutput
, alpha_adjust_symtab_relocs
, NULL
);
1725 alpha_adjust_symtab_relocs (abfd
, sec
, ptr
)
1726 bfd
*abfd ATTRIBUTE_UNUSED
;
1728 PTR ptr ATTRIBUTE_UNUSED
;
1730 segment_info_type
*seginfo
= seg_info (sec
);
1736 /* If seginfo is NULL, we did not create this section; don't do
1737 anything with it. By using a pointer to a pointer, we can update
1738 the links in place. */
1739 if (seginfo
== NULL
)
1742 /* If there are no relocations, skip the section. */
1743 if (! seginfo
->fix_root
)
1746 /* First rebuild the fixup chain without the expicit lituse and
1747 gpdisp_lo16 relocs. */
1748 prevP
= &seginfo
->fix_root
;
1749 for (fixp
= seginfo
->fix_root
; fixp
; fixp
= next
)
1751 next
= fixp
->fx_next
;
1752 fixp
->fx_next
= (fixS
*) 0;
1754 switch (fixp
->fx_r_type
)
1756 case BFD_RELOC_ALPHA_LITUSE
:
1757 if (fixp
->tc_fix_data
.info
->n_master
== 0)
1758 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1759 _("No !literal!%ld was found"),
1760 fixp
->tc_fix_data
.info
->sequence
);
1761 if (fixp
->fx_offset
== LITUSE_TLSGD
)
1763 if (! fixp
->tc_fix_data
.info
->saw_tlsgd
)
1764 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1765 _("No !tlsgd!%ld was found"),
1766 fixp
->tc_fix_data
.info
->sequence
);
1768 else if (fixp
->fx_offset
== LITUSE_TLSLDM
)
1770 if (! fixp
->tc_fix_data
.info
->saw_tlsldm
)
1771 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1772 _("No !tlsldm!%ld was found"),
1773 fixp
->tc_fix_data
.info
->sequence
);
1777 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1778 if (fixp
->tc_fix_data
.info
->n_master
== 0)
1779 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1780 _("No ldah !gpdisp!%ld was found"),
1781 fixp
->tc_fix_data
.info
->sequence
);
1784 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1785 if (fixp
->tc_fix_data
.info
->saw_tlsgd
1786 || fixp
->tc_fix_data
.info
->saw_tlsldm
)
1792 prevP
= &fixp
->fx_next
;
1797 /* Go back and re-chain dependent relocations. They are currently
1798 linked through the next_reloc field in reverse order, so as we
1799 go through the next_reloc chain, we effectively reverse the chain
1802 Except if there is more than one !literal for a given sequence
1803 number. In that case, the programmer and/or compiler is not sure
1804 how control flows from literal to lituse, and we can't be sure to
1805 get the relaxation correct.
1807 ??? Well, actually we could, if there are enough lituses such that
1808 we can make each literal have at least one of each lituse type
1809 present. Not implemented.
1811 Also suppress the optimization if the !literals/!lituses are spread
1812 in different segments. This can happen with "intersting" uses of
1813 inline assembly; examples are present in the Linux kernel semaphores. */
1815 for (fixp
= seginfo
->fix_root
; fixp
; fixp
= next
)
1817 next
= fixp
->fx_next
;
1818 switch (fixp
->fx_r_type
)
1820 case BFD_RELOC_ALPHA_TLSGD
:
1821 case BFD_RELOC_ALPHA_TLSLDM
:
1822 if (!fixp
->tc_fix_data
.info
)
1824 if (fixp
->tc_fix_data
.info
->n_master
== 0)
1826 else if (fixp
->tc_fix_data
.info
->n_master
> 1)
1828 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1829 _("too many !literal!%ld for %s"),
1830 fixp
->tc_fix_data
.info
->sequence
,
1831 (fixp
->fx_r_type
== BFD_RELOC_ALPHA_TLSGD
1832 ? "!tlsgd" : "!tlsldm"));
1836 fixp
->tc_fix_data
.info
->master
->fx_next
= fixp
->fx_next
;
1837 fixp
->fx_next
= fixp
->tc_fix_data
.info
->master
;
1838 fixp
= fixp
->fx_next
;
1841 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1842 if (fixp
->tc_fix_data
.info
->n_master
== 1
1843 && ! fixp
->tc_fix_data
.info
->multi_section_p
)
1845 for (slave
= fixp
->tc_fix_data
.info
->slaves
;
1846 slave
!= (fixS
*) 0;
1847 slave
= slave
->tc_fix_data
.next_reloc
)
1849 slave
->fx_next
= fixp
->fx_next
;
1850 fixp
->fx_next
= slave
;
1855 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1856 if (fixp
->tc_fix_data
.info
->n_slaves
== 0)
1857 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1858 _("No lda !gpdisp!%ld was found"),
1859 fixp
->tc_fix_data
.info
->sequence
);
1862 slave
= fixp
->tc_fix_data
.info
->slaves
;
1863 slave
->fx_next
= next
;
1864 fixp
->fx_next
= slave
;
1876 debug_exp (tok
, ntok
)
1882 fprintf (stderr
, "debug_exp: %d tokens", ntok
);
1883 for (i
= 0; i
< ntok
; i
++)
1885 expressionS
*t
= &tok
[i
];
1889 default: name
= "unknown"; break;
1890 case O_illegal
: name
= "O_illegal"; break;
1891 case O_absent
: name
= "O_absent"; break;
1892 case O_constant
: name
= "O_constant"; break;
1893 case O_symbol
: name
= "O_symbol"; break;
1894 case O_symbol_rva
: name
= "O_symbol_rva"; break;
1895 case O_register
: name
= "O_register"; break;
1896 case O_big
: name
= "O_big"; break;
1897 case O_uminus
: name
= "O_uminus"; break;
1898 case O_bit_not
: name
= "O_bit_not"; break;
1899 case O_logical_not
: name
= "O_logical_not"; break;
1900 case O_multiply
: name
= "O_multiply"; break;
1901 case O_divide
: name
= "O_divide"; break;
1902 case O_modulus
: name
= "O_modulus"; break;
1903 case O_left_shift
: name
= "O_left_shift"; break;
1904 case O_right_shift
: name
= "O_right_shift"; break;
1905 case O_bit_inclusive_or
: name
= "O_bit_inclusive_or"; break;
1906 case O_bit_or_not
: name
= "O_bit_or_not"; break;
1907 case O_bit_exclusive_or
: name
= "O_bit_exclusive_or"; break;
1908 case O_bit_and
: name
= "O_bit_and"; break;
1909 case O_add
: name
= "O_add"; break;
1910 case O_subtract
: name
= "O_subtract"; break;
1911 case O_eq
: name
= "O_eq"; break;
1912 case O_ne
: name
= "O_ne"; break;
1913 case O_lt
: name
= "O_lt"; break;
1914 case O_le
: name
= "O_le"; break;
1915 case O_ge
: name
= "O_ge"; break;
1916 case O_gt
: name
= "O_gt"; break;
1917 case O_logical_and
: name
= "O_logical_and"; break;
1918 case O_logical_or
: name
= "O_logical_or"; break;
1919 case O_index
: name
= "O_index"; break;
1920 case O_pregister
: name
= "O_pregister"; break;
1921 case O_cpregister
: name
= "O_cpregister"; break;
1922 case O_literal
: name
= "O_literal"; break;
1923 case O_lituse_addr
: name
= "O_lituse_addr"; break;
1924 case O_lituse_base
: name
= "O_lituse_base"; break;
1925 case O_lituse_bytoff
: name
= "O_lituse_bytoff"; break;
1926 case O_lituse_jsr
: name
= "O_lituse_jsr"; break;
1927 case O_lituse_tlsgd
: name
= "O_lituse_tlsgd"; break;
1928 case O_lituse_tlsldm
: name
= "O_lituse_tlsldm"; break;
1929 case O_gpdisp
: name
= "O_gpdisp"; break;
1930 case O_gprelhigh
: name
= "O_gprelhigh"; break;
1931 case O_gprellow
: name
= "O_gprellow"; break;
1932 case O_gprel
: name
= "O_gprel"; break;
1933 case O_samegp
: name
= "O_samegp"; break;
1934 case O_tlsgd
: name
= "O_tlsgd"; break;
1935 case O_tlsldm
: name
= "O_tlsldm"; break;
1936 case O_gotdtprel
: name
= "O_gotdtprel"; break;
1937 case O_dtprelhi
: name
= "O_dtprelhi"; break;
1938 case O_dtprello
: name
= "O_dtprello"; break;
1939 case O_dtprel
: name
= "O_dtprel"; break;
1940 case O_gottprel
: name
= "O_gottprel"; break;
1941 case O_tprelhi
: name
= "O_tprelhi"; break;
1942 case O_tprello
: name
= "O_tprello"; break;
1943 case O_tprel
: name
= "O_tprel"; break;
1946 fprintf (stderr
, ", %s(%s, %s, %d)", name
,
1947 (t
->X_add_symbol
) ? S_GET_NAME (t
->X_add_symbol
) : "--",
1948 (t
->X_op_symbol
) ? S_GET_NAME (t
->X_op_symbol
) : "--",
1949 (int) t
->X_add_number
);
1951 fprintf (stderr
, "\n");
1956 /* Parse the arguments to an opcode. */
1959 tokenize_arguments (str
, tok
, ntok
)
1964 expressionS
*end_tok
= tok
+ ntok
;
1965 char *old_input_line_pointer
;
1966 int saw_comma
= 0, saw_arg
= 0;
1968 expressionS
*orig_tok
= tok
;
1971 const struct alpha_reloc_op_tag
*r
;
1974 int reloc_found_p
= 0;
1976 memset (tok
, 0, sizeof (*tok
) * ntok
);
1978 /* Save and restore input_line_pointer around this function */
1979 old_input_line_pointer
= input_line_pointer
;
1980 input_line_pointer
= str
;
1983 /* ??? Wrest control of ! away from the regular expression parser. */
1984 is_end_of_line
[(unsigned char) '!'] = 1;
1987 while (tok
< end_tok
&& *input_line_pointer
)
1990 switch (*input_line_pointer
)
1997 /* A relocation operand can be placed after the normal operand on an
1998 assembly language statement, and has the following form:
1999 !relocation_type!sequence_number. */
2001 { /* only support one relocation op per insn */
2002 as_bad (_("More than one relocation op per insn"));
2009 ++input_line_pointer
;
2011 p
= input_line_pointer
;
2012 c
= get_symbol_end ();
2014 /* Parse !relocation_type */
2015 len
= input_line_pointer
- p
;
2018 as_bad (_("No relocation operand"));
2022 r
= &alpha_reloc_op
[0];
2023 for (i
= alpha_num_reloc_op
- 1; i
>= 0; i
--, r
++)
2024 if (len
== r
->length
&& memcmp (p
, r
->name
, len
) == 0)
2028 as_bad (_("Unknown relocation operand: !%s"), p
);
2032 *input_line_pointer
= c
;
2034 if (*input_line_pointer
!= '!')
2038 as_bad (_("no sequence number after !%s"), p
);
2042 tok
->X_add_number
= 0;
2048 as_bad (_("!%s does not use a sequence number"), p
);
2052 input_line_pointer
++;
2054 /* Parse !sequence_number */
2056 if (tok
->X_op
!= O_constant
|| tok
->X_add_number
<= 0)
2058 as_bad (_("Bad sequence number: !%s!%s"),
2059 r
->name
, input_line_pointer
);
2068 #endif /* RELOC_OP_P */
2071 ++input_line_pointer
;
2072 if (saw_comma
|| !saw_arg
)
2079 char *hold
= input_line_pointer
++;
2081 /* First try for parenthesized register ... */
2083 if (*input_line_pointer
== ')' && tok
->X_op
== O_register
)
2085 tok
->X_op
= (saw_comma
? O_cpregister
: O_pregister
);
2088 ++input_line_pointer
;
2093 /* ... then fall through to plain expression */
2094 input_line_pointer
= hold
;
2098 if (saw_arg
&& !saw_comma
)
2102 if (tok
->X_op
== O_illegal
|| tok
->X_op
== O_absent
)
2115 input_line_pointer
= old_input_line_pointer
;
2118 debug_exp (orig_tok
, ntok
- (end_tok
- tok
));
2121 is_end_of_line
[(unsigned char) '!'] = 0;
2124 return ntok
- (end_tok
- tok
);
2128 is_end_of_line
[(unsigned char) '!'] = 0;
2130 input_line_pointer
= old_input_line_pointer
;
2131 return TOKENIZE_ERROR
;
2135 is_end_of_line
[(unsigned char) '!'] = 0;
2137 input_line_pointer
= old_input_line_pointer
;
2138 return TOKENIZE_ERROR_REPORT
;
2141 /* Search forward through all variants of an opcode looking for a
2144 static const struct alpha_opcode
*
2145 find_opcode_match (first_opcode
, tok
, pntok
, pcpumatch
)
2146 const struct alpha_opcode
*first_opcode
;
2147 const expressionS
*tok
;
2151 const struct alpha_opcode
*opcode
= first_opcode
;
2153 int got_cpu_match
= 0;
2157 const unsigned char *opidx
;
2160 /* Don't match opcodes that don't exist on this architecture */
2161 if (!(opcode
->flags
& alpha_target
))
2166 for (opidx
= opcode
->operands
; *opidx
; ++opidx
)
2168 const struct alpha_operand
*operand
= &alpha_operands
[*opidx
];
2170 /* only take input from real operands */
2171 if (operand
->flags
& AXP_OPERAND_FAKE
)
2174 /* when we expect input, make sure we have it */
2177 if ((operand
->flags
& AXP_OPERAND_OPTIONAL_MASK
) == 0)
2182 /* match operand type with expression type */
2183 switch (operand
->flags
& AXP_OPERAND_TYPECHECK_MASK
)
2185 case AXP_OPERAND_IR
:
2186 if (tok
[tokidx
].X_op
!= O_register
2187 || !is_ir_num (tok
[tokidx
].X_add_number
))
2190 case AXP_OPERAND_FPR
:
2191 if (tok
[tokidx
].X_op
!= O_register
2192 || !is_fpr_num (tok
[tokidx
].X_add_number
))
2195 case AXP_OPERAND_IR
| AXP_OPERAND_PARENS
:
2196 if (tok
[tokidx
].X_op
!= O_pregister
2197 || !is_ir_num (tok
[tokidx
].X_add_number
))
2200 case AXP_OPERAND_IR
| AXP_OPERAND_PARENS
| AXP_OPERAND_COMMA
:
2201 if (tok
[tokidx
].X_op
!= O_cpregister
2202 || !is_ir_num (tok
[tokidx
].X_add_number
))
2206 case AXP_OPERAND_RELATIVE
:
2207 case AXP_OPERAND_SIGNED
:
2208 case AXP_OPERAND_UNSIGNED
:
2209 switch (tok
[tokidx
].X_op
)
2224 /* everything else should have been fake */
2230 /* possible match -- did we use all of our input? */
2239 while (++opcode
- alpha_opcodes
< alpha_num_opcodes
2240 && !strcmp (opcode
->name
, first_opcode
->name
));
2243 *pcpumatch
= got_cpu_match
;
2248 /* Search forward through all variants of a macro looking for a syntax
2251 static const struct alpha_macro
*
2252 find_macro_match (first_macro
, tok
, pntok
)
2253 const struct alpha_macro
*first_macro
;
2254 const expressionS
*tok
;
2257 const struct alpha_macro
*macro
= first_macro
;
2262 const enum alpha_macro_arg
*arg
= macro
->argsets
;
2276 /* index register */
2278 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_register
2279 || !is_ir_num (tok
[tokidx
].X_add_number
))
2284 /* parenthesized index register */
2286 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_pregister
2287 || !is_ir_num (tok
[tokidx
].X_add_number
))
2292 /* optional parenthesized index register */
2294 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_pregister
2295 && is_ir_num (tok
[tokidx
].X_add_number
))
2299 /* leading comma with a parenthesized index register */
2301 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_cpregister
2302 || !is_ir_num (tok
[tokidx
].X_add_number
))
2307 /* floating point register */
2309 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_register
2310 || !is_fpr_num (tok
[tokidx
].X_add_number
))
2315 /* normal expression */
2319 switch (tok
[tokidx
].X_op
)
2328 case O_lituse_bytoff
:
2344 while (*arg
!= MACRO_EOA
)
2352 while (++macro
- alpha_macros
< alpha_num_macros
2353 && !strcmp (macro
->name
, first_macro
->name
));
2358 /* Insert an operand value into an instruction. */
2361 insert_operand (insn
, operand
, val
, file
, line
)
2363 const struct alpha_operand
*operand
;
2368 if (operand
->bits
!= 32 && !(operand
->flags
& AXP_OPERAND_NOOVERFLOW
))
2372 if (operand
->flags
& AXP_OPERAND_SIGNED
)
2374 max
= (1 << (operand
->bits
- 1)) - 1;
2375 min
= -(1 << (operand
->bits
- 1));
2379 max
= (1 << operand
->bits
) - 1;
2383 if (val
< min
|| val
> max
)
2386 _("operand out of range (%s not between %d and %d)");
2387 char buf
[sizeof (val
) * 3 + 2];
2389 sprint_value (buf
, val
);
2391 as_warn_where (file
, line
, err
, buf
, min
, max
);
2393 as_warn (err
, buf
, min
, max
);
2397 if (operand
->insert
)
2399 const char *errmsg
= NULL
;
2401 insn
= (*operand
->insert
) (insn
, val
, &errmsg
);
2406 insn
|= ((val
& ((1 << operand
->bits
) - 1)) << operand
->shift
);
2412 * Turn an opcode description and a set of arguments into
2413 * 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
;
2564 * Actually output an instruction with its fixup.
2569 struct alpha_insn
*insn
;
2574 /* Take care of alignment duties. */
2575 if (alpha_auto_align_on
&& alpha_current_align
< 2)
2576 alpha_align (2, (char *) NULL
, alpha_insn_label
, 0);
2577 if (alpha_current_align
> 2)
2578 alpha_current_align
= 2;
2579 alpha_insn_label
= NULL
;
2581 /* Write out the instruction. */
2583 md_number_to_chars (f
, insn
->insn
, 4);
2586 dwarf2_emit_insn (4);
2589 /* Apply the fixups in order */
2590 for (i
= 0; i
< insn
->nfixups
; ++i
)
2592 const struct alpha_operand
*operand
= (const struct alpha_operand
*) 0;
2593 struct alpha_fixup
*fixup
= &insn
->fixups
[i
];
2594 struct alpha_reloc_tag
*info
= NULL
;
2598 /* Some fixups are only used internally and so have no howto */
2599 if ((int) fixup
->reloc
< 0)
2601 operand
= &alpha_operands
[-(int) fixup
->reloc
];
2603 pcrel
= ((operand
->flags
& AXP_OPERAND_RELATIVE
) != 0);
2605 else if (fixup
->reloc
> BFD_RELOC_UNUSED
2606 || fixup
->reloc
== BFD_RELOC_ALPHA_GPDISP_HI16
2607 || fixup
->reloc
== BFD_RELOC_ALPHA_GPDISP_LO16
)
2614 reloc_howto_type
*reloc_howto
2615 = bfd_reloc_type_lookup (stdoutput
, fixup
->reloc
);
2616 assert (reloc_howto
);
2618 size
= bfd_get_reloc_size (reloc_howto
);
2619 assert (size
>= 1 && size
<= 4);
2621 pcrel
= reloc_howto
->pc_relative
;
2624 fixP
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, size
,
2625 &fixup
->exp
, pcrel
, fixup
->reloc
);
2627 /* Turn off complaints that the addend is too large for some fixups,
2628 and copy in the sequence number for the explicit relocations. */
2629 switch (fixup
->reloc
)
2631 case BFD_RELOC_ALPHA_HINT
:
2632 case BFD_RELOC_GPREL32
:
2633 case BFD_RELOC_GPREL16
:
2634 case BFD_RELOC_ALPHA_GPREL_HI16
:
2635 case BFD_RELOC_ALPHA_GPREL_LO16
:
2636 case BFD_RELOC_ALPHA_GOTDTPREL16
:
2637 case BFD_RELOC_ALPHA_DTPREL_HI16
:
2638 case BFD_RELOC_ALPHA_DTPREL_LO16
:
2639 case BFD_RELOC_ALPHA_DTPREL16
:
2640 case BFD_RELOC_ALPHA_GOTTPREL16
:
2641 case BFD_RELOC_ALPHA_TPREL_HI16
:
2642 case BFD_RELOC_ALPHA_TPREL_LO16
:
2643 case BFD_RELOC_ALPHA_TPREL16
:
2644 fixP
->fx_no_overflow
= 1;
2647 case BFD_RELOC_ALPHA_GPDISP_HI16
:
2648 fixP
->fx_no_overflow
= 1;
2649 fixP
->fx_addsy
= section_symbol (now_seg
);
2650 fixP
->fx_offset
= 0;
2652 info
= get_alpha_reloc_tag (insn
->sequence
);
2653 if (++info
->n_master
> 1)
2654 as_bad (_("too many ldah insns for !gpdisp!%ld"), insn
->sequence
);
2655 if (info
->segment
!= now_seg
)
2656 as_bad (_("both insns for !gpdisp!%ld must be in the same section"),
2658 fixP
->tc_fix_data
.info
= info
;
2661 case BFD_RELOC_ALPHA_GPDISP_LO16
:
2662 fixP
->fx_no_overflow
= 1;
2664 info
= get_alpha_reloc_tag (insn
->sequence
);
2665 if (++info
->n_slaves
> 1)
2666 as_bad (_("too many lda insns for !gpdisp!%ld"), insn
->sequence
);
2667 if (info
->segment
!= now_seg
)
2668 as_bad (_("both insns for !gpdisp!%ld must be in the same section"),
2670 fixP
->tc_fix_data
.info
= info
;
2671 info
->slaves
= fixP
;
2674 case BFD_RELOC_ALPHA_LITERAL
:
2675 case BFD_RELOC_ALPHA_ELF_LITERAL
:
2676 fixP
->fx_no_overflow
= 1;
2678 if (insn
->sequence
== 0)
2680 info
= get_alpha_reloc_tag (insn
->sequence
);
2681 info
->master
= fixP
;
2683 if (info
->segment
!= now_seg
)
2684 info
->multi_section_p
= 1;
2685 fixP
->tc_fix_data
.info
= info
;
2688 case DUMMY_RELOC_LITUSE_ADDR
:
2689 fixP
->fx_offset
= LITUSE_ADDR
;
2691 case DUMMY_RELOC_LITUSE_BASE
:
2692 fixP
->fx_offset
= LITUSE_BASE
;
2694 case DUMMY_RELOC_LITUSE_BYTOFF
:
2695 fixP
->fx_offset
= LITUSE_BYTOFF
;
2697 case DUMMY_RELOC_LITUSE_JSR
:
2698 fixP
->fx_offset
= LITUSE_JSR
;
2700 case DUMMY_RELOC_LITUSE_TLSGD
:
2701 fixP
->fx_offset
= LITUSE_TLSGD
;
2703 case DUMMY_RELOC_LITUSE_TLSLDM
:
2704 fixP
->fx_offset
= LITUSE_TLSLDM
;
2707 fixP
->fx_addsy
= section_symbol (now_seg
);
2708 fixP
->fx_r_type
= BFD_RELOC_ALPHA_LITUSE
;
2710 info
= get_alpha_reloc_tag (insn
->sequence
);
2711 if (fixup
->reloc
== DUMMY_RELOC_LITUSE_TLSGD
)
2712 info
->saw_lu_tlsgd
= 1;
2713 else if (fixup
->reloc
== DUMMY_RELOC_LITUSE_TLSLDM
)
2714 info
->saw_lu_tlsldm
= 1;
2715 if (++info
->n_slaves
> 1)
2717 if (info
->saw_lu_tlsgd
)
2718 as_bad (_("too many lituse insns for !lituse_tlsgd!%ld"),
2720 else if (info
->saw_lu_tlsldm
)
2721 as_bad (_("too many lituse insns for !lituse_tlsldm!%ld"),
2724 fixP
->tc_fix_data
.info
= info
;
2725 fixP
->tc_fix_data
.next_reloc
= info
->slaves
;
2726 info
->slaves
= fixP
;
2727 if (info
->segment
!= now_seg
)
2728 info
->multi_section_p
= 1;
2731 case BFD_RELOC_ALPHA_TLSGD
:
2732 fixP
->fx_no_overflow
= 1;
2734 if (insn
->sequence
== 0)
2736 info
= get_alpha_reloc_tag (insn
->sequence
);
2737 if (info
->saw_tlsgd
)
2738 as_bad (_("duplicate !tlsgd!%ld"), insn
->sequence
);
2739 else if (info
->saw_tlsldm
)
2740 as_bad (_("sequence number in use for !tlsldm!%ld"),
2743 info
->saw_tlsgd
= 1;
2744 fixP
->tc_fix_data
.info
= info
;
2747 case BFD_RELOC_ALPHA_TLSLDM
:
2748 fixP
->fx_no_overflow
= 1;
2750 if (insn
->sequence
== 0)
2752 info
= get_alpha_reloc_tag (insn
->sequence
);
2753 if (info
->saw_tlsldm
)
2754 as_bad (_("duplicate !tlsldm!%ld"), insn
->sequence
);
2755 else if (info
->saw_tlsgd
)
2756 as_bad (_("sequence number in use for !tlsgd!%ld"),
2759 info
->saw_tlsldm
= 1;
2760 fixP
->tc_fix_data
.info
= info
;
2764 if ((int) fixup
->reloc
< 0)
2766 if (operand
->flags
& AXP_OPERAND_NOOVERFLOW
)
2767 fixP
->fx_no_overflow
= 1;
2774 /* Given an opcode name and a pre-tokenized set of arguments, assemble
2775 the insn, but do not emit it.
2777 Note that this implies no macros allowed, since we can't store more
2778 than one insn in an insn structure. */
2781 assemble_tokens_to_insn (opname
, tok
, ntok
, insn
)
2783 const expressionS
*tok
;
2785 struct alpha_insn
*insn
;
2787 const struct alpha_opcode
*opcode
;
2789 /* search opcodes */
2790 opcode
= (const struct alpha_opcode
*) hash_find (alpha_opcode_hash
, opname
);
2794 opcode
= find_opcode_match (opcode
, tok
, &ntok
, &cpumatch
);
2797 assemble_insn (opcode
, tok
, ntok
, insn
, BFD_RELOC_UNUSED
);
2801 as_bad (_("inappropriate arguments for opcode `%s'"), opname
);
2803 as_bad (_("opcode `%s' not supported for target %s"), opname
,
2807 as_bad (_("unknown opcode `%s'"), opname
);
2810 /* Given an opcode name and a pre-tokenized set of arguments, take the
2811 opcode all the way through emission. */
2814 assemble_tokens (opname
, tok
, ntok
, local_macros_on
)
2816 const expressionS
*tok
;
2818 int local_macros_on
;
2820 int found_something
= 0;
2821 const struct alpha_opcode
*opcode
;
2822 const struct alpha_macro
*macro
;
2824 bfd_reloc_code_real_type reloc
= BFD_RELOC_UNUSED
;
2827 /* If a user-specified relocation is present, this is not a macro. */
2828 if (ntok
&& USER_RELOC_P (tok
[ntok
- 1].X_op
))
2830 reloc
= ALPHA_RELOC_TABLE (tok
[ntok
- 1].X_op
)->reloc
;
2835 if (local_macros_on
)
2837 macro
= ((const struct alpha_macro
*)
2838 hash_find (alpha_macro_hash
, opname
));
2841 found_something
= 1;
2842 macro
= find_macro_match (macro
, tok
, &ntok
);
2845 (*macro
->emit
) (tok
, ntok
, macro
->arg
);
2851 /* search opcodes */
2852 opcode
= (const struct alpha_opcode
*) hash_find (alpha_opcode_hash
, opname
);
2855 found_something
= 1;
2856 opcode
= find_opcode_match (opcode
, tok
, &ntok
, &cpumatch
);
2859 struct alpha_insn insn
;
2860 assemble_insn (opcode
, tok
, ntok
, &insn
, reloc
);
2862 /* Copy the sequence number for the reloc from the reloc token. */
2863 if (reloc
!= BFD_RELOC_UNUSED
)
2864 insn
.sequence
= tok
[ntok
].X_add_number
;
2871 if (found_something
)
2874 as_bad (_("inappropriate arguments for opcode `%s'"), opname
);
2876 as_bad (_("opcode `%s' not supported for target %s"), opname
,
2880 as_bad (_("unknown opcode `%s'"), opname
);
2883 /* Some instruction sets indexed by lg(size) */
2884 static const char * const sextX_op
[] = { "sextb", "sextw", "sextl", NULL
};
2885 static const char * const insXl_op
[] = { "insbl", "inswl", "insll", "insql" };
2886 static const char * const insXh_op
[] = { NULL
, "inswh", "inslh", "insqh" };
2887 static const char * const extXl_op
[] = { "extbl", "extwl", "extll", "extql" };
2888 static const char * const extXh_op
[] = { NULL
, "extwh", "extlh", "extqh" };
2889 static const char * const mskXl_op
[] = { "mskbl", "mskwl", "mskll", "mskql" };
2890 static const char * const mskXh_op
[] = { NULL
, "mskwh", "msklh", "mskqh" };
2891 static const char * const stX_op
[] = { "stb", "stw", "stl", "stq" };
2892 static const char * const ldXu_op
[] = { "ldbu", "ldwu", NULL
, NULL
};
2894 /* Implement the ldgp macro. */
2897 emit_ldgp (tok
, ntok
, unused
)
2898 const expressionS
*tok
;
2899 int ntok ATTRIBUTE_UNUSED
;
2900 const PTR unused ATTRIBUTE_UNUSED
;
2905 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
2906 /* from "ldgp r1,n(r2)", generate "ldah r1,X(R2); lda r1,Y(r1)"
2907 with appropriate constants and relocations. */
2908 struct alpha_insn insn
;
2909 expressionS newtok
[3];
2913 if (regno (tok
[2].X_add_number
) == AXP_REG_PV
)
2914 ecoff_set_gp_prolog_size (0);
2918 set_tok_const (newtok
[1], 0);
2921 assemble_tokens_to_insn ("ldah", newtok
, 3, &insn
);
2926 if (addend
.X_op
!= O_constant
)
2927 as_bad (_("can not resolve expression"));
2928 addend
.X_op
= O_symbol
;
2929 addend
.X_add_symbol
= alpha_gp_symbol
;
2933 insn
.fixups
[0].exp
= addend
;
2934 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_GPDISP_HI16
;
2935 insn
.sequence
= next_sequence_num
;
2939 set_tok_preg (newtok
[2], tok
[0].X_add_number
);
2941 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
2944 addend
.X_add_number
+= 4;
2948 insn
.fixups
[0].exp
= addend
;
2949 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_GPDISP_LO16
;
2950 insn
.sequence
= next_sequence_num
--;
2953 #endif /* OBJ_ECOFF || OBJ_ELF */
2958 /* Add symbol+addend to link pool.
2959 Return offset from basesym to entry in link pool.
2961 Add new fixup only if offset isn't 16bit. */
2964 add_to_link_pool (basesym
, sym
, addend
)
2969 segT current_section
= now_seg
;
2970 int current_subsec
= now_subseg
;
2972 bfd_reloc_code_real_type reloc_type
;
2974 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
2977 offset
= - *symbol_get_obj (basesym
);
2979 /* @@ This assumes all entries in a given section will be of the same
2980 size... Probably correct, but unwise to rely on. */
2981 /* This must always be called with the same subsegment. */
2983 if (seginfo
->frchainP
)
2984 for (fixp
= seginfo
->frchainP
->fix_root
;
2985 fixp
!= (fixS
*) NULL
;
2986 fixp
= fixp
->fx_next
, offset
+= 8)
2988 if (fixp
->fx_addsy
== sym
&& fixp
->fx_offset
== addend
)
2990 if (range_signed_16 (offset
))
2997 /* Not found in 16bit signed range. */
2999 subseg_set (alpha_link_section
, 0);
3003 fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, sym
, addend
, 0,
3006 subseg_set (current_section
, current_subsec
);
3007 seginfo
->literal_pool_size
+= 8;
3011 #endif /* OBJ_EVAX */
3013 /* Load a (partial) expression into a target register.
3015 If poffset is not null, after the call it will either contain
3016 O_constant 0, or a 16-bit offset appropriate for any MEM format
3017 instruction. In addition, pbasereg will be modified to point to
3018 the base register to use in that MEM format instruction.
3020 In any case, *pbasereg should contain a base register to add to the
3021 expression. This will normally be either AXP_REG_ZERO or
3022 alpha_gp_register. Symbol addresses will always be loaded via $gp,
3023 so "foo($0)" is interpreted as adding the address of foo to $0;
3024 i.e. "ldq $targ, LIT($gp); addq $targ, $0, $targ". Odd, perhaps,
3025 but this is what OSF/1 does.
3027 If explicit relocations of the form !literal!<number> are allowed,
3028 and used, then explict_reloc with be an expression pointer.
3030 Finally, the return value is nonzero if the calling macro may emit
3031 a LITUSE reloc if otherwise appropriate; the return value is the
3032 sequence number to use. */
3035 load_expression (targreg
, exp
, pbasereg
, poffset
)
3037 const expressionS
*exp
;
3039 expressionS
*poffset
;
3041 long emit_lituse
= 0;
3042 offsetT addend
= exp
->X_add_number
;
3043 int basereg
= *pbasereg
;
3044 struct alpha_insn insn
;
3045 expressionS newtok
[3];
3054 /* attempt to reduce .lit load by splitting the offset from
3055 its symbol when possible, but don't create a situation in
3057 if (!range_signed_32 (addend
) &&
3058 (alpha_noat_on
|| targreg
== AXP_REG_AT
))
3060 lit
= add_to_literal_pool (exp
->X_add_symbol
, addend
,
3061 alpha_lita_section
, 8);
3066 lit
= add_to_literal_pool (exp
->X_add_symbol
, 0,
3067 alpha_lita_section
, 8);
3071 as_fatal (_("overflow in literal (.lita) table"));
3073 /* emit "ldq r, lit(gp)" */
3075 if (basereg
!= alpha_gp_register
&& targreg
== basereg
)
3078 as_bad (_("macro requires $at register while noat in effect"));
3079 if (targreg
== AXP_REG_AT
)
3080 as_bad (_("macro requires $at while $at in use"));
3082 set_tok_reg (newtok
[0], AXP_REG_AT
);
3085 set_tok_reg (newtok
[0], targreg
);
3086 set_tok_sym (newtok
[1], alpha_lita_symbol
, lit
);
3087 set_tok_preg (newtok
[2], alpha_gp_register
);
3089 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
3091 assert (insn
.nfixups
== 1);
3092 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITERAL
;
3093 insn
.sequence
= emit_lituse
= next_sequence_num
--;
3094 #endif /* OBJ_ECOFF */
3096 /* emit "ldq r, gotoff(gp)" */
3098 if (basereg
!= alpha_gp_register
&& targreg
== basereg
)
3101 as_bad (_("macro requires $at register while noat in effect"));
3102 if (targreg
== AXP_REG_AT
)
3103 as_bad (_("macro requires $at while $at in use"));
3105 set_tok_reg (newtok
[0], AXP_REG_AT
);
3108 set_tok_reg (newtok
[0], targreg
);
3110 /* XXX: Disable this .got minimizing optimization so that we can get
3111 better instruction offset knowledge in the compiler. This happens
3112 very infrequently anyway. */
3114 || (!range_signed_32 (addend
)
3115 && (alpha_noat_on
|| targreg
== AXP_REG_AT
)))
3122 set_tok_sym (newtok
[1], exp
->X_add_symbol
, 0);
3125 set_tok_preg (newtok
[2], alpha_gp_register
);
3127 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
3129 assert (insn
.nfixups
== 1);
3130 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_ELF_LITERAL
;
3131 insn
.sequence
= emit_lituse
= next_sequence_num
--;
3132 #endif /* OBJ_ELF */
3136 /* Find symbol or symbol pointer in link section. */
3138 if (exp
->X_add_symbol
== alpha_evax_proc
.symbol
)
3140 if (range_signed_16 (addend
))
3142 set_tok_reg (newtok
[0], targreg
);
3143 set_tok_const (newtok
[1], addend
);
3144 set_tok_preg (newtok
[2], basereg
);
3145 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
3150 set_tok_reg (newtok
[0], targreg
);
3151 set_tok_const (newtok
[1], 0);
3152 set_tok_preg (newtok
[2], basereg
);
3153 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
3158 if (!range_signed_32 (addend
))
3160 link
= add_to_link_pool (alpha_evax_proc
.symbol
,
3161 exp
->X_add_symbol
, addend
);
3166 link
= add_to_link_pool (alpha_evax_proc
.symbol
,
3167 exp
->X_add_symbol
, 0);
3169 set_tok_reg (newtok
[0], targreg
);
3170 set_tok_const (newtok
[1], link
);
3171 set_tok_preg (newtok
[2], basereg
);
3172 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
3174 #endif /* OBJ_EVAX */
3179 if (basereg
!= alpha_gp_register
&& basereg
!= AXP_REG_ZERO
)
3181 /* emit "addq r, base, r" */
3183 set_tok_reg (newtok
[1], basereg
);
3184 set_tok_reg (newtok
[2], targreg
);
3185 assemble_tokens ("addq", newtok
, 3, 0);
3197 /* Assume that this difference expression will be resolved to an
3198 absolute value and that that value will fit in 16 bits. */
3200 set_tok_reg (newtok
[0], targreg
);
3202 set_tok_preg (newtok
[2], basereg
);
3203 assemble_tokens ("lda", newtok
, 3, 0);
3206 set_tok_const (*poffset
, 0);
3210 if (exp
->X_add_number
> 0)
3211 as_bad (_("bignum invalid; zero assumed"));
3213 as_bad (_("floating point number invalid; zero assumed"));
3218 as_bad (_("can't handle expression"));
3223 if (!range_signed_32 (addend
))
3226 long seq_num
= next_sequence_num
--;
3228 /* For 64-bit addends, just put it in the literal pool. */
3231 /* emit "ldq targreg, lit(basereg)" */
3232 lit
= add_to_link_pool (alpha_evax_proc
.symbol
,
3233 section_symbol (absolute_section
), addend
);
3234 set_tok_reg (newtok
[0], targreg
);
3235 set_tok_const (newtok
[1], lit
);
3236 set_tok_preg (newtok
[2], alpha_gp_register
);
3237 assemble_tokens ("ldq", newtok
, 3, 0);
3240 if (alpha_lit8_section
== NULL
)
3242 create_literal_section (".lit8",
3243 &alpha_lit8_section
,
3244 &alpha_lit8_symbol
);
3247 alpha_lit8_literal
= add_to_literal_pool (alpha_lit8_symbol
, 0x8000,
3248 alpha_lita_section
, 8);
3249 if (alpha_lit8_literal
>= 0x8000)
3250 as_fatal (_("overflow in literal (.lita) table"));
3254 lit
= add_to_literal_pool (NULL
, addend
, alpha_lit8_section
, 8) - 0x8000;
3256 as_fatal (_("overflow in literal (.lit8) table"));
3258 /* emit "lda litreg, .lit8+0x8000" */
3260 if (targreg
== basereg
)
3263 as_bad (_("macro requires $at register while noat in effect"));
3264 if (targreg
== AXP_REG_AT
)
3265 as_bad (_("macro requires $at while $at in use"));
3267 set_tok_reg (newtok
[0], AXP_REG_AT
);
3270 set_tok_reg (newtok
[0], targreg
);
3272 set_tok_sym (newtok
[1], alpha_lita_symbol
, alpha_lit8_literal
);
3275 set_tok_sym (newtok
[1], alpha_lit8_symbol
, 0x8000);
3277 set_tok_preg (newtok
[2], alpha_gp_register
);
3279 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
3281 assert (insn
.nfixups
== 1);
3283 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITERAL
;
3286 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_ELF_LITERAL
;
3288 insn
.sequence
= seq_num
;
3292 /* emit "ldq litreg, lit(litreg)" */
3294 set_tok_const (newtok
[1], lit
);
3295 set_tok_preg (newtok
[2], newtok
[0].X_add_number
);
3297 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
3299 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3300 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BASE
;
3301 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3303 insn
.sequence
= seq_num
;
3308 /* emit "addq litreg, base, target" */
3310 if (basereg
!= AXP_REG_ZERO
)
3312 set_tok_reg (newtok
[1], basereg
);
3313 set_tok_reg (newtok
[2], targreg
);
3314 assemble_tokens ("addq", newtok
, 3, 0);
3316 #endif /* !OBJ_EVAX */
3319 set_tok_const (*poffset
, 0);
3320 *pbasereg
= targreg
;
3324 offsetT low
, high
, extra
, tmp
;
3326 /* for 32-bit operands, break up the addend */
3328 low
= sign_extend_16 (addend
);
3330 high
= sign_extend_16 (tmp
>> 16);
3332 if (tmp
- (high
<< 16))
3336 high
= sign_extend_16 (tmp
>> 16);
3341 set_tok_reg (newtok
[0], targreg
);
3342 set_tok_preg (newtok
[2], basereg
);
3346 /* emit "ldah r, extra(r) */
3347 set_tok_const (newtok
[1], extra
);
3348 assemble_tokens ("ldah", newtok
, 3, 0);
3349 set_tok_preg (newtok
[2], basereg
= targreg
);
3354 /* emit "ldah r, high(r) */
3355 set_tok_const (newtok
[1], high
);
3356 assemble_tokens ("ldah", newtok
, 3, 0);
3358 set_tok_preg (newtok
[2], basereg
);
3361 if ((low
&& !poffset
) || (!poffset
&& basereg
!= targreg
))
3363 /* emit "lda r, low(base)" */
3364 set_tok_const (newtok
[1], low
);
3365 assemble_tokens ("lda", newtok
, 3, 0);
3371 set_tok_const (*poffset
, low
);
3372 *pbasereg
= basereg
;
3378 /* The lda macro differs from the lda instruction in that it handles
3379 most simple expressions, particualrly symbol address loads and
3383 emit_lda (tok
, ntok
, unused
)
3384 const expressionS
*tok
;
3386 const PTR unused ATTRIBUTE_UNUSED
;
3391 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
3393 basereg
= tok
[2].X_add_number
;
3395 (void) load_expression (tok
[0].X_add_number
, &tok
[1], &basereg
, NULL
);
3398 /* The ldah macro differs from the ldah instruction in that it has $31
3399 as an implied base register. */
3402 emit_ldah (tok
, ntok
, unused
)
3403 const expressionS
*tok
;
3404 int ntok ATTRIBUTE_UNUSED
;
3405 const PTR unused ATTRIBUTE_UNUSED
;
3407 expressionS newtok
[3];
3411 set_tok_preg (newtok
[2], AXP_REG_ZERO
);
3413 assemble_tokens ("ldah", newtok
, 3, 0);
3416 /* Handle all "simple" integer register loads -- ldq, ldq_l, ldq_u,
3417 etc. They differ from the real instructions in that they do simple
3418 expressions like the lda macro. */
3421 emit_ir_load (tok
, ntok
, opname
)
3422 const expressionS
*tok
;
3428 expressionS newtok
[3];
3429 struct alpha_insn insn
;
3432 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
3434 basereg
= tok
[2].X_add_number
;
3436 lituse
= load_expression (tok
[0].X_add_number
, &tok
[1], &basereg
,
3440 set_tok_preg (newtok
[2], basereg
);
3442 assemble_tokens_to_insn ((const char *) opname
, newtok
, 3, &insn
);
3446 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3447 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BASE
;
3448 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3450 insn
.sequence
= lituse
;
3456 /* Handle fp register loads, and both integer and fp register stores.
3457 Again, we handle simple expressions. */
3460 emit_loadstore (tok
, ntok
, opname
)
3461 const expressionS
*tok
;
3467 expressionS newtok
[3];
3468 struct alpha_insn insn
;
3471 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
3473 basereg
= tok
[2].X_add_number
;
3475 if (tok
[1].X_op
!= O_constant
|| !range_signed_16 (tok
[1].X_add_number
))
3478 as_bad (_("macro requires $at register while noat in effect"));
3480 lituse
= load_expression (AXP_REG_AT
, &tok
[1], &basereg
, &newtok
[1]);
3489 set_tok_preg (newtok
[2], basereg
);
3491 assemble_tokens_to_insn ((const char *) opname
, newtok
, 3, &insn
);
3495 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3496 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BASE
;
3497 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3499 insn
.sequence
= lituse
;
3505 /* Load a half-word or byte as an unsigned value. */
3508 emit_ldXu (tok
, ntok
, vlgsize
)
3509 const expressionS
*tok
;
3513 if (alpha_target
& AXP_OPCODE_BWX
)
3514 emit_ir_load (tok
, ntok
, ldXu_op
[(long) vlgsize
]);
3517 expressionS newtok
[3];
3518 struct alpha_insn insn
;
3523 as_bad (_("macro requires $at register while noat in effect"));
3526 basereg
= (tok
[1].X_op
== O_constant
3527 ? AXP_REG_ZERO
: alpha_gp_register
);
3529 basereg
= tok
[2].X_add_number
;
3531 /* emit "lda $at, exp" */
3533 lituse
= load_expression (AXP_REG_AT
, &tok
[1], &basereg
, NULL
);
3535 /* emit "ldq_u targ, 0($at)" */
3538 set_tok_const (newtok
[1], 0);
3539 set_tok_preg (newtok
[2], basereg
);
3540 assemble_tokens_to_insn ("ldq_u", newtok
, 3, &insn
);
3544 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3545 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BASE
;
3546 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3548 insn
.sequence
= lituse
;
3553 /* emit "extXl targ, $at, targ" */
3555 set_tok_reg (newtok
[1], basereg
);
3556 newtok
[2] = newtok
[0];
3557 assemble_tokens_to_insn (extXl_op
[(long) vlgsize
], newtok
, 3, &insn
);
3561 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3562 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BYTOFF
;
3563 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3565 insn
.sequence
= lituse
;
3572 /* Load a half-word or byte as a signed value. */
3575 emit_ldX (tok
, ntok
, vlgsize
)
3576 const expressionS
*tok
;
3580 emit_ldXu (tok
, ntok
, vlgsize
);
3581 assemble_tokens (sextX_op
[(long) vlgsize
], tok
, 1, 1);
3584 /* Load an integral value from an unaligned address as an unsigned
3588 emit_uldXu (tok
, ntok
, vlgsize
)
3589 const expressionS
*tok
;
3593 long lgsize
= (long) vlgsize
;
3594 expressionS newtok
[3];
3597 as_bad (_("macro requires $at register while noat in effect"));
3599 /* emit "lda $at, exp" */
3601 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
3602 newtok
[0].X_add_number
= AXP_REG_AT
;
3603 assemble_tokens ("lda", newtok
, ntok
, 1);
3605 /* emit "ldq_u $t9, 0($at)" */
3607 set_tok_reg (newtok
[0], AXP_REG_T9
);
3608 set_tok_const (newtok
[1], 0);
3609 set_tok_preg (newtok
[2], AXP_REG_AT
);
3610 assemble_tokens ("ldq_u", newtok
, 3, 1);
3612 /* emit "ldq_u $t10, size-1($at)" */
3614 set_tok_reg (newtok
[0], AXP_REG_T10
);
3615 set_tok_const (newtok
[1], (1 << lgsize
) - 1);
3616 assemble_tokens ("ldq_u", newtok
, 3, 1);
3618 /* emit "extXl $t9, $at, $t9" */
3620 set_tok_reg (newtok
[0], AXP_REG_T9
);
3621 set_tok_reg (newtok
[1], AXP_REG_AT
);
3622 set_tok_reg (newtok
[2], AXP_REG_T9
);
3623 assemble_tokens (extXl_op
[lgsize
], newtok
, 3, 1);
3625 /* emit "extXh $t10, $at, $t10" */
3627 set_tok_reg (newtok
[0], AXP_REG_T10
);
3628 set_tok_reg (newtok
[2], AXP_REG_T10
);
3629 assemble_tokens (extXh_op
[lgsize
], newtok
, 3, 1);
3631 /* emit "or $t9, $t10, targ" */
3633 set_tok_reg (newtok
[0], AXP_REG_T9
);
3634 set_tok_reg (newtok
[1], AXP_REG_T10
);
3636 assemble_tokens ("or", newtok
, 3, 1);
3639 /* Load an integral value from an unaligned address as a signed value.
3640 Note that quads should get funneled to the unsigned load since we
3641 don't have to do the sign extension. */
3644 emit_uldX (tok
, ntok
, vlgsize
)
3645 const expressionS
*tok
;
3649 emit_uldXu (tok
, ntok
, vlgsize
);
3650 assemble_tokens (sextX_op
[(long) vlgsize
], tok
, 1, 1);
3653 /* Implement the ldil macro. */
3656 emit_ldil (tok
, ntok
, unused
)
3657 const expressionS
*tok
;
3659 const PTR unused ATTRIBUTE_UNUSED
;
3661 expressionS newtok
[2];
3663 memcpy (newtok
, tok
, sizeof (newtok
));
3664 newtok
[1].X_add_number
= sign_extend_32 (tok
[1].X_add_number
);
3666 assemble_tokens ("lda", newtok
, ntok
, 1);
3669 /* Store a half-word or byte. */
3672 emit_stX (tok
, ntok
, vlgsize
)
3673 const expressionS
*tok
;
3677 int lgsize
= (int) (long) vlgsize
;
3679 if (alpha_target
& AXP_OPCODE_BWX
)
3680 emit_loadstore (tok
, ntok
, stX_op
[lgsize
]);
3683 expressionS newtok
[3];
3684 struct alpha_insn insn
;
3689 as_bad (_("macro requires $at register while noat in effect"));
3692 basereg
= (tok
[1].X_op
== O_constant
3693 ? AXP_REG_ZERO
: alpha_gp_register
);
3695 basereg
= tok
[2].X_add_number
;
3697 /* emit "lda $at, exp" */
3699 lituse
= load_expression (AXP_REG_AT
, &tok
[1], &basereg
, NULL
);
3701 /* emit "ldq_u $t9, 0($at)" */
3703 set_tok_reg (newtok
[0], AXP_REG_T9
);
3704 set_tok_const (newtok
[1], 0);
3705 set_tok_preg (newtok
[2], basereg
);
3706 assemble_tokens_to_insn ("ldq_u", newtok
, 3, &insn
);
3710 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3711 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BASE
;
3712 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3714 insn
.sequence
= lituse
;
3719 /* emit "insXl src, $at, $t10" */
3722 set_tok_reg (newtok
[1], basereg
);
3723 set_tok_reg (newtok
[2], AXP_REG_T10
);
3724 assemble_tokens_to_insn (insXl_op
[lgsize
], newtok
, 3, &insn
);
3728 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3729 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BYTOFF
;
3730 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3732 insn
.sequence
= lituse
;
3737 /* emit "mskXl $t9, $at, $t9" */
3739 set_tok_reg (newtok
[0], AXP_REG_T9
);
3740 newtok
[2] = newtok
[0];
3741 assemble_tokens_to_insn (mskXl_op
[lgsize
], newtok
, 3, &insn
);
3745 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3746 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BYTOFF
;
3747 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3749 insn
.sequence
= lituse
;
3754 /* emit "or $t9, $t10, $t9" */
3756 set_tok_reg (newtok
[1], AXP_REG_T10
);
3757 assemble_tokens ("or", newtok
, 3, 1);
3759 /* emit "stq_u $t9, 0($at) */
3761 set_tok_const(newtok
[1], 0);
3762 set_tok_preg (newtok
[2], AXP_REG_AT
);
3763 assemble_tokens_to_insn ("stq_u", newtok
, 3, &insn
);
3767 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3768 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BASE
;
3769 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3771 insn
.sequence
= lituse
;
3778 /* Store an integer to an unaligned address. */
3781 emit_ustX (tok
, ntok
, vlgsize
)
3782 const expressionS
*tok
;
3786 int lgsize
= (int) (long) vlgsize
;
3787 expressionS newtok
[3];
3789 /* emit "lda $at, exp" */
3791 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
3792 newtok
[0].X_add_number
= AXP_REG_AT
;
3793 assemble_tokens ("lda", newtok
, ntok
, 1);
3795 /* emit "ldq_u $9, 0($at)" */
3797 set_tok_reg (newtok
[0], AXP_REG_T9
);
3798 set_tok_const (newtok
[1], 0);
3799 set_tok_preg (newtok
[2], AXP_REG_AT
);
3800 assemble_tokens ("ldq_u", newtok
, 3, 1);
3802 /* emit "ldq_u $10, size-1($at)" */
3804 set_tok_reg (newtok
[0], AXP_REG_T10
);
3805 set_tok_const (newtok
[1], (1 << lgsize
) - 1);
3806 assemble_tokens ("ldq_u", newtok
, 3, 1);
3808 /* emit "insXl src, $at, $t11" */
3811 set_tok_reg (newtok
[1], AXP_REG_AT
);
3812 set_tok_reg (newtok
[2], AXP_REG_T11
);
3813 assemble_tokens (insXl_op
[lgsize
], newtok
, 3, 1);
3815 /* emit "insXh src, $at, $t12" */
3817 set_tok_reg (newtok
[2], AXP_REG_T12
);
3818 assemble_tokens (insXh_op
[lgsize
], newtok
, 3, 1);
3820 /* emit "mskXl $t9, $at, $t9" */
3822 set_tok_reg (newtok
[0], AXP_REG_T9
);
3823 newtok
[2] = newtok
[0];
3824 assemble_tokens (mskXl_op
[lgsize
], newtok
, 3, 1);
3826 /* emit "mskXh $t10, $at, $t10" */
3828 set_tok_reg (newtok
[0], AXP_REG_T10
);
3829 newtok
[2] = newtok
[0];
3830 assemble_tokens (mskXh_op
[lgsize
], newtok
, 3, 1);
3832 /* emit "or $t9, $t11, $t9" */
3834 set_tok_reg (newtok
[0], AXP_REG_T9
);
3835 set_tok_reg (newtok
[1], AXP_REG_T11
);
3836 newtok
[2] = newtok
[0];
3837 assemble_tokens ("or", newtok
, 3, 1);
3839 /* emit "or $t10, $t12, $t10" */
3841 set_tok_reg (newtok
[0], AXP_REG_T10
);
3842 set_tok_reg (newtok
[1], AXP_REG_T12
);
3843 newtok
[2] = newtok
[0];
3844 assemble_tokens ("or", newtok
, 3, 1);
3846 /* emit "stq_u $t9, 0($at)" */
3848 set_tok_reg (newtok
[0], AXP_REG_T9
);
3849 set_tok_const (newtok
[1], 0);
3850 set_tok_preg (newtok
[2], AXP_REG_AT
);
3851 assemble_tokens ("stq_u", newtok
, 3, 1);
3853 /* emit "stq_u $t10, size-1($at)" */
3855 set_tok_reg (newtok
[0], AXP_REG_T10
);
3856 set_tok_const (newtok
[1], (1 << lgsize
) - 1);
3857 assemble_tokens ("stq_u", newtok
, 3, 1);
3860 /* Sign extend a half-word or byte. The 32-bit sign extend is
3861 implemented as "addl $31, $r, $t" in the opcode table. */
3864 emit_sextX (tok
, ntok
, vlgsize
)
3865 const expressionS
*tok
;
3869 long lgsize
= (long) vlgsize
;
3871 if (alpha_target
& AXP_OPCODE_BWX
)
3872 assemble_tokens (sextX_op
[lgsize
], tok
, ntok
, 0);
3875 int bitshift
= 64 - 8 * (1 << lgsize
);
3876 expressionS newtok
[3];
3878 /* emit "sll src,bits,dst" */
3881 set_tok_const (newtok
[1], bitshift
);
3882 newtok
[2] = tok
[ntok
- 1];
3883 assemble_tokens ("sll", newtok
, 3, 1);
3885 /* emit "sra dst,bits,dst" */
3887 newtok
[0] = newtok
[2];
3888 assemble_tokens ("sra", newtok
, 3, 1);
3892 /* Implement the division and modulus macros. */
3896 /* Make register usage like in normal procedure call.
3897 Don't clobber PV and RA. */
3900 emit_division (tok
, ntok
, symname
)
3901 const expressionS
*tok
;
3905 /* DIVISION and MODULUS. Yech.
3910 * mov x,R16 # if x != R16
3911 * mov y,R17 # if y != R17
3916 * with appropriate optimizations if R0,R16,R17 are the registers
3917 * specified by the compiler.
3922 expressionS newtok
[3];
3924 xr
= regno (tok
[0].X_add_number
);
3925 yr
= regno (tok
[1].X_add_number
);
3930 rr
= regno (tok
[2].X_add_number
);
3932 /* Move the operands into the right place */
3933 if (yr
== AXP_REG_R16
&& xr
== AXP_REG_R17
)
3935 /* They are in exactly the wrong order -- swap through AT */
3938 as_bad (_("macro requires $at register while noat in effect"));
3940 set_tok_reg (newtok
[0], AXP_REG_R16
);
3941 set_tok_reg (newtok
[1], AXP_REG_AT
);
3942 assemble_tokens ("mov", newtok
, 2, 1);
3944 set_tok_reg (newtok
[0], AXP_REG_R17
);
3945 set_tok_reg (newtok
[1], AXP_REG_R16
);
3946 assemble_tokens ("mov", newtok
, 2, 1);
3948 set_tok_reg (newtok
[0], AXP_REG_AT
);
3949 set_tok_reg (newtok
[1], AXP_REG_R17
);
3950 assemble_tokens ("mov", newtok
, 2, 1);
3954 if (yr
== AXP_REG_R16
)
3956 set_tok_reg (newtok
[0], AXP_REG_R16
);
3957 set_tok_reg (newtok
[1], AXP_REG_R17
);
3958 assemble_tokens ("mov", newtok
, 2, 1);
3961 if (xr
!= AXP_REG_R16
)
3963 set_tok_reg (newtok
[0], xr
);
3964 set_tok_reg (newtok
[1], AXP_REG_R16
);
3965 assemble_tokens ("mov", newtok
, 2, 1);
3968 if (yr
!= AXP_REG_R16
&& yr
!= AXP_REG_R17
)
3970 set_tok_reg (newtok
[0], yr
);
3971 set_tok_reg (newtok
[1], AXP_REG_R17
);
3972 assemble_tokens ("mov", newtok
, 2, 1);
3976 sym
= symbol_find_or_make ((const char *) symname
);
3978 set_tok_reg (newtok
[0], AXP_REG_AT
);
3979 set_tok_sym (newtok
[1], sym
, 0);
3980 assemble_tokens ("lda", newtok
, 2, 1);
3982 /* Call the division routine */
3983 set_tok_reg (newtok
[0], AXP_REG_AT
);
3984 set_tok_cpreg (newtok
[1], AXP_REG_AT
);
3985 set_tok_const (newtok
[2], 0);
3986 assemble_tokens ("jsr", newtok
, 3, 1);
3988 /* Move the result to the right place */
3989 if (rr
!= AXP_REG_R0
)
3991 set_tok_reg (newtok
[0], AXP_REG_R0
);
3992 set_tok_reg (newtok
[1], rr
);
3993 assemble_tokens ("mov", newtok
, 2, 1);
3997 #else /* !OBJ_EVAX */
4000 emit_division (tok
, ntok
, symname
)
4001 const expressionS
*tok
;
4005 /* DIVISION and MODULUS. Yech.
4015 * with appropriate optimizations if t10,t11,t12 are the registers
4016 * specified by the compiler.
4021 expressionS newtok
[3];
4023 xr
= regno (tok
[0].X_add_number
);
4024 yr
= regno (tok
[1].X_add_number
);
4029 rr
= regno (tok
[2].X_add_number
);
4031 sym
= symbol_find_or_make ((const char *) symname
);
4033 /* Move the operands into the right place */
4034 if (yr
== AXP_REG_T10
&& xr
== AXP_REG_T11
)
4036 /* They are in exactly the wrong order -- swap through AT */
4039 as_bad (_("macro requires $at register while noat in effect"));
4041 set_tok_reg (newtok
[0], AXP_REG_T10
);
4042 set_tok_reg (newtok
[1], AXP_REG_AT
);
4043 assemble_tokens ("mov", newtok
, 2, 1);
4045 set_tok_reg (newtok
[0], AXP_REG_T11
);
4046 set_tok_reg (newtok
[1], AXP_REG_T10
);
4047 assemble_tokens ("mov", newtok
, 2, 1);
4049 set_tok_reg (newtok
[0], AXP_REG_AT
);
4050 set_tok_reg (newtok
[1], AXP_REG_T11
);
4051 assemble_tokens ("mov", newtok
, 2, 1);
4055 if (yr
== AXP_REG_T10
)
4057 set_tok_reg (newtok
[0], AXP_REG_T10
);
4058 set_tok_reg (newtok
[1], AXP_REG_T11
);
4059 assemble_tokens ("mov", newtok
, 2, 1);
4062 if (xr
!= AXP_REG_T10
)
4064 set_tok_reg (newtok
[0], xr
);
4065 set_tok_reg (newtok
[1], AXP_REG_T10
);
4066 assemble_tokens ("mov", newtok
, 2, 1);
4069 if (yr
!= AXP_REG_T10
&& yr
!= AXP_REG_T11
)
4071 set_tok_reg (newtok
[0], yr
);
4072 set_tok_reg (newtok
[1], AXP_REG_T11
);
4073 assemble_tokens ("mov", newtok
, 2, 1);
4077 /* Call the division routine */
4078 set_tok_reg (newtok
[0], AXP_REG_T9
);
4079 set_tok_sym (newtok
[1], sym
, 0);
4080 assemble_tokens ("jsr", newtok
, 2, 1);
4082 /* Reload the GP register */
4086 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
4087 set_tok_reg (newtok
[0], alpha_gp_register
);
4088 set_tok_const (newtok
[1], 0);
4089 set_tok_preg (newtok
[2], AXP_REG_T9
);
4090 assemble_tokens ("ldgp", newtok
, 3, 1);
4093 /* Move the result to the right place */
4094 if (rr
!= AXP_REG_T12
)
4096 set_tok_reg (newtok
[0], AXP_REG_T12
);
4097 set_tok_reg (newtok
[1], rr
);
4098 assemble_tokens ("mov", newtok
, 2, 1);
4102 #endif /* !OBJ_EVAX */
4104 /* The jsr and jmp macros differ from their instruction counterparts
4105 in that they can load the target address and default most
4109 emit_jsrjmp (tok
, ntok
, vopname
)
4110 const expressionS
*tok
;
4114 const char *opname
= (const char *) vopname
;
4115 struct alpha_insn insn
;
4116 expressionS newtok
[3];
4120 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_register
)
4121 r
= regno (tok
[tokidx
++].X_add_number
);
4123 r
= strcmp (opname
, "jmp") == 0 ? AXP_REG_ZERO
: AXP_REG_RA
;
4125 set_tok_reg (newtok
[0], r
);
4127 if (tokidx
< ntok
&&
4128 (tok
[tokidx
].X_op
== O_pregister
|| tok
[tokidx
].X_op
== O_cpregister
))
4129 r
= regno (tok
[tokidx
++].X_add_number
);
4131 /* keep register if jsr $n.<sym> */
4135 int basereg
= alpha_gp_register
;
4136 lituse
= load_expression (r
= AXP_REG_PV
, &tok
[tokidx
], &basereg
, NULL
);
4140 set_tok_cpreg (newtok
[1], r
);
4143 /* FIXME: Add hint relocs to BFD for evax. */
4146 newtok
[2] = tok
[tokidx
];
4149 set_tok_const (newtok
[2], 0);
4151 assemble_tokens_to_insn (opname
, newtok
, 3, &insn
);
4155 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
4156 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_JSR
;
4157 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
4159 insn
.sequence
= lituse
;
4165 /* The ret and jcr instructions differ from their instruction
4166 counterparts in that everything can be defaulted. */
4169 emit_retjcr (tok
, ntok
, vopname
)
4170 const expressionS
*tok
;
4174 const char *opname
= (const char *) vopname
;
4175 expressionS newtok
[3];
4178 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_register
)
4179 r
= regno (tok
[tokidx
++].X_add_number
);
4183 set_tok_reg (newtok
[0], r
);
4185 if (tokidx
< ntok
&&
4186 (tok
[tokidx
].X_op
== O_pregister
|| tok
[tokidx
].X_op
== O_cpregister
))
4187 r
= regno (tok
[tokidx
++].X_add_number
);
4191 set_tok_cpreg (newtok
[1], r
);
4194 newtok
[2] = tok
[tokidx
];
4196 set_tok_const (newtok
[2], strcmp (opname
, "ret") == 0);
4198 assemble_tokens (opname
, newtok
, 3, 0);
4201 /* Assembler directives */
4203 /* Handle the .text pseudo-op. This is like the usual one, but it
4204 clears alpha_insn_label and restores auto alignment. */
4216 alpha_insn_label
= NULL
;
4217 alpha_auto_align_on
= 1;
4218 alpha_current_align
= 0;
4221 /* Handle the .data pseudo-op. This is like the usual one, but it
4222 clears alpha_insn_label and restores auto alignment. */
4233 alpha_insn_label
= NULL
;
4234 alpha_auto_align_on
= 1;
4235 alpha_current_align
= 0;
4238 #if defined (OBJ_ECOFF) || defined (OBJ_EVAX)
4240 /* Handle the OSF/1 and openVMS .comm pseudo quirks.
4241 openVMS constructs a section for every common symbol. */
4244 s_alpha_comm (ignore
)
4247 register char *name
;
4251 register symbolS
*symbolP
;
4254 segT current_section
= now_seg
;
4255 int current_subsec
= now_subseg
;
4259 name
= input_line_pointer
;
4260 c
= get_symbol_end ();
4262 /* just after name is now '\0' */
4263 p
= input_line_pointer
;
4268 /* Alpha OSF/1 compiler doesn't provide the comma, gcc does. */
4269 if (*input_line_pointer
== ',')
4271 input_line_pointer
++;
4274 if ((temp
= get_absolute_expression ()) < 0)
4276 as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) temp
);
4277 ignore_rest_of_line ();
4282 symbolP
= symbol_find_or_make (name
);
4285 /* Make a section for the common symbol. */
4286 new_seg
= subseg_new (xstrdup (name
), 0);
4292 /* alignment might follow */
4293 if (*input_line_pointer
== ',')
4297 input_line_pointer
++;
4298 align
= get_absolute_expression ();
4299 bfd_set_section_alignment (stdoutput
, new_seg
, align
);
4303 if (S_IS_DEFINED (symbolP
) && ! S_IS_COMMON (symbolP
))
4305 as_bad (_("Ignoring attempt to re-define symbol"));
4306 ignore_rest_of_line ();
4311 if (bfd_section_size (stdoutput
, new_seg
) > 0)
4313 if (bfd_section_size (stdoutput
, new_seg
) != temp
)
4314 as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
4315 S_GET_NAME (symbolP
),
4316 (long) bfd_section_size (stdoutput
, new_seg
),
4320 if (S_GET_VALUE (symbolP
))
4322 if (S_GET_VALUE (symbolP
) != (valueT
) temp
)
4323 as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
4324 S_GET_NAME (symbolP
),
4325 (long) S_GET_VALUE (symbolP
),
4332 subseg_set (new_seg
, 0);
4333 p
= frag_more (temp
);
4334 new_seg
->flags
|= SEC_IS_COMMON
;
4335 if (! S_IS_DEFINED (symbolP
))
4336 S_SET_SEGMENT (symbolP
, new_seg
);
4338 S_SET_VALUE (symbolP
, (valueT
) temp
);
4340 S_SET_EXTERNAL (symbolP
);
4344 subseg_set (current_section
, current_subsec
);
4347 know (symbol_get_frag (symbolP
) == &zero_address_frag
);
4349 demand_empty_rest_of_line ();
4352 #endif /* ! OBJ_ELF */
4356 /* Handle the .rdata pseudo-op. This is like the usual one, but it
4357 clears alpha_insn_label and restores auto alignment. */
4360 s_alpha_rdata (ignore
)
4365 temp
= get_absolute_expression ();
4366 subseg_new (".rdata", 0);
4367 demand_empty_rest_of_line ();
4368 alpha_insn_label
= NULL
;
4369 alpha_auto_align_on
= 1;
4370 alpha_current_align
= 0;
4377 /* Handle the .sdata pseudo-op. This is like the usual one, but it
4378 clears alpha_insn_label and restores auto alignment. */
4381 s_alpha_sdata (ignore
)
4386 temp
= get_absolute_expression ();
4387 subseg_new (".sdata", 0);
4388 demand_empty_rest_of_line ();
4389 alpha_insn_label
= NULL
;
4390 alpha_auto_align_on
= 1;
4391 alpha_current_align
= 0;
4397 /* Handle the .section pseudo-op. This is like the usual one, but it
4398 clears alpha_insn_label and restores auto alignment. */
4401 s_alpha_section (ignore
)
4404 obj_elf_section (ignore
);
4406 alpha_insn_label
= NULL
;
4407 alpha_auto_align_on
= 1;
4408 alpha_current_align
= 0;
4413 int dummy ATTRIBUTE_UNUSED
;
4415 if (ECOFF_DEBUGGING
)
4416 ecoff_directive_ent (0);
4419 char *name
, name_end
;
4420 name
= input_line_pointer
;
4421 name_end
= get_symbol_end ();
4423 if (! is_name_beginner (*name
))
4425 as_warn (_(".ent directive has no name"));
4426 *input_line_pointer
= name_end
;
4432 if (alpha_cur_ent_sym
)
4433 as_warn (_("nested .ent directives"));
4435 sym
= symbol_find_or_make (name
);
4436 symbol_get_bfdsym (sym
)->flags
|= BSF_FUNCTION
;
4437 alpha_cur_ent_sym
= sym
;
4439 /* The .ent directive is sometimes followed by a number. Not sure
4440 what it really means, but ignore it. */
4441 *input_line_pointer
= name_end
;
4443 if (*input_line_pointer
== ',')
4445 input_line_pointer
++;
4448 if (ISDIGIT (*input_line_pointer
) || *input_line_pointer
== '-')
4449 (void) get_absolute_expression ();
4451 demand_empty_rest_of_line ();
4457 int dummy ATTRIBUTE_UNUSED
;
4459 if (ECOFF_DEBUGGING
)
4460 ecoff_directive_end (0);
4463 char *name
, name_end
;
4464 name
= input_line_pointer
;
4465 name_end
= get_symbol_end ();
4467 if (! is_name_beginner (*name
))
4469 as_warn (_(".end directive has no name"));
4470 *input_line_pointer
= name_end
;
4476 sym
= symbol_find (name
);
4477 if (sym
!= alpha_cur_ent_sym
)
4478 as_warn (_(".end directive names different symbol than .ent"));
4480 /* Create an expression to calculate the size of the function. */
4483 symbol_get_obj (sym
)->size
=
4484 (expressionS
*) xmalloc (sizeof (expressionS
));
4485 symbol_get_obj (sym
)->size
->X_op
= O_subtract
;
4486 symbol_get_obj (sym
)->size
->X_add_symbol
4487 = symbol_new ("L0\001", now_seg
, frag_now_fix (), frag_now
);
4488 symbol_get_obj (sym
)->size
->X_op_symbol
= sym
;
4489 symbol_get_obj (sym
)->size
->X_add_number
= 0;
4492 alpha_cur_ent_sym
= NULL
;
4494 *input_line_pointer
= name_end
;
4496 demand_empty_rest_of_line ();
4504 if (ECOFF_DEBUGGING
)
4507 ecoff_directive_fmask (0);
4509 ecoff_directive_mask (0);
4512 discard_rest_of_line ();
4516 s_alpha_frame (dummy
)
4517 int dummy ATTRIBUTE_UNUSED
;
4519 if (ECOFF_DEBUGGING
)
4520 ecoff_directive_frame (0);
4522 discard_rest_of_line ();
4526 s_alpha_prologue (ignore
)
4527 int ignore ATTRIBUTE_UNUSED
;
4532 arg
= get_absolute_expression ();
4533 demand_empty_rest_of_line ();
4535 if (ECOFF_DEBUGGING
)
4536 sym
= ecoff_get_cur_proc_sym ();
4538 sym
= alpha_cur_ent_sym
;
4543 case 0: /* No PV required. */
4544 S_SET_OTHER (sym
, STO_ALPHA_NOPV
4545 | (S_GET_OTHER (sym
) & ~STO_ALPHA_STD_GPLOAD
));
4547 case 1: /* Std GP load. */
4548 S_SET_OTHER (sym
, STO_ALPHA_STD_GPLOAD
4549 | (S_GET_OTHER (sym
) & ~STO_ALPHA_STD_GPLOAD
));
4551 case 2: /* Non-std use of PV. */
4555 as_bad (_("Invalid argument %d to .prologue."), arg
);
4560 static char *first_file_directive
;
4563 s_alpha_file (ignore
)
4564 int ignore ATTRIBUTE_UNUSED
;
4566 /* Save the first .file directive we see, so that we can change our
4567 minds about whether ecoff debugging should or shouldn't be enabled. */
4568 if (alpha_flag_mdebug
< 0 && ! first_file_directive
)
4570 char *start
= input_line_pointer
;
4573 discard_rest_of_line ();
4575 len
= input_line_pointer
- start
;
4576 first_file_directive
= xmalloc (len
+ 1);
4577 memcpy (first_file_directive
, start
, len
);
4578 first_file_directive
[len
] = '\0';
4580 input_line_pointer
= start
;
4583 if (ECOFF_DEBUGGING
)
4584 ecoff_directive_file (0);
4586 dwarf2_directive_file (0);
4590 s_alpha_loc (ignore
)
4591 int ignore ATTRIBUTE_UNUSED
;
4593 if (ECOFF_DEBUGGING
)
4594 ecoff_directive_loc (0);
4596 dwarf2_directive_loc (0);
4603 /* If we've been undecided about mdebug, make up our minds in favour. */
4604 if (alpha_flag_mdebug
< 0)
4606 segT sec
= subseg_new (".mdebug", 0);
4607 bfd_set_section_flags (stdoutput
, sec
, SEC_HAS_CONTENTS
| SEC_READONLY
);
4608 bfd_set_section_alignment (stdoutput
, sec
, 3);
4610 ecoff_read_begin_hook ();
4612 if (first_file_directive
)
4614 char *save_ilp
= input_line_pointer
;
4615 input_line_pointer
= first_file_directive
;
4616 ecoff_directive_file (0);
4617 input_line_pointer
= save_ilp
;
4618 free (first_file_directive
);
4621 alpha_flag_mdebug
= 1;
4627 s_alpha_coff_wrapper (which
)
4630 static void (* const fns
[]) PARAMS ((int)) = {
4631 ecoff_directive_begin
,
4632 ecoff_directive_bend
,
4633 ecoff_directive_def
,
4634 ecoff_directive_dim
,
4635 ecoff_directive_endef
,
4636 ecoff_directive_scl
,
4637 ecoff_directive_tag
,
4638 ecoff_directive_val
,
4641 assert (which
>= 0 && which
< (int) (sizeof (fns
)/sizeof (*fns
)));
4643 if (ECOFF_DEBUGGING
)
4647 as_bad (_("ECOFF debugging is disabled."));
4648 ignore_rest_of_line ();
4651 #endif /* OBJ_ELF */
4655 /* Handle the section specific pseudo-op. */
4658 s_alpha_section (secid
)
4662 #define EVAX_SECTION_COUNT 5
4663 static char *section_name
[EVAX_SECTION_COUNT
+ 1] =
4664 { "NULL", ".rdata", ".comm", ".link", ".ctors", ".dtors" };
4666 if ((secid
<= 0) || (secid
> EVAX_SECTION_COUNT
))
4668 as_fatal (_("Unknown section directive"));
4669 demand_empty_rest_of_line ();
4672 temp
= get_absolute_expression ();
4673 subseg_new (section_name
[secid
], 0);
4674 demand_empty_rest_of_line ();
4675 alpha_insn_label
= NULL
;
4676 alpha_auto_align_on
= 1;
4677 alpha_current_align
= 0;
4680 /* Parse .ent directives. */
4683 s_alpha_ent (ignore
)
4687 expressionS symexpr
;
4689 alpha_evax_proc
.pdsckind
= 0;
4690 alpha_evax_proc
.framereg
= -1;
4691 alpha_evax_proc
.framesize
= 0;
4692 alpha_evax_proc
.rsa_offset
= 0;
4693 alpha_evax_proc
.ra_save
= AXP_REG_RA
;
4694 alpha_evax_proc
.fp_save
= -1;
4695 alpha_evax_proc
.imask
= 0;
4696 alpha_evax_proc
.fmask
= 0;
4697 alpha_evax_proc
.prologue
= 0;
4698 alpha_evax_proc
.type
= 0;
4700 expression (&symexpr
);
4702 if (symexpr
.X_op
!= O_symbol
)
4704 as_fatal (_(".ent directive has no symbol"));
4705 demand_empty_rest_of_line ();
4709 symbol
= make_expr_symbol (&symexpr
);
4710 symbol_get_bfdsym (symbol
)->flags
|= BSF_FUNCTION
;
4711 alpha_evax_proc
.symbol
= symbol
;
4713 demand_empty_rest_of_line ();
4717 /* Parse .frame <framreg>,<framesize>,RA,<rsa_offset> directives. */
4720 s_alpha_frame (ignore
)
4725 alpha_evax_proc
.framereg
= tc_get_register (1);
4728 if (*input_line_pointer
++ != ','
4729 || get_absolute_expression_and_terminator (&val
) != ',')
4731 as_warn (_("Bad .frame directive 1./2. param"));
4732 --input_line_pointer
;
4733 demand_empty_rest_of_line ();
4737 alpha_evax_proc
.framesize
= val
;
4739 (void) tc_get_register (1);
4741 if (*input_line_pointer
++ != ',')
4743 as_warn (_("Bad .frame directive 3./4. param"));
4744 --input_line_pointer
;
4745 demand_empty_rest_of_line ();
4748 alpha_evax_proc
.rsa_offset
= get_absolute_expression ();
4754 s_alpha_pdesc (ignore
)
4764 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
4766 if (now_seg
!= alpha_link_section
)
4768 as_bad (_(".pdesc directive not in link (.link) section"));
4769 demand_empty_rest_of_line ();
4773 if ((alpha_evax_proc
.symbol
== 0)
4774 || (!S_IS_DEFINED (alpha_evax_proc
.symbol
)))
4776 as_fatal (_(".pdesc has no matching .ent"));
4777 demand_empty_rest_of_line ();
4781 *symbol_get_obj (alpha_evax_proc
.symbol
) =
4782 (valueT
) seginfo
->literal_pool_size
;
4785 if (exp
.X_op
!= O_symbol
)
4787 as_warn (_(".pdesc directive has no entry symbol"));
4788 demand_empty_rest_of_line ();
4792 entry_sym
= make_expr_symbol (&exp
);
4793 /* Save bfd symbol of proc desc in function symbol. */
4794 symbol_get_bfdsym (alpha_evax_proc
.symbol
)->udata
.p
4795 = symbol_get_bfdsym (entry_sym
);
4798 if (*input_line_pointer
++ != ',')
4800 as_warn (_("No comma after .pdesc <entryname>"));
4801 demand_empty_rest_of_line ();
4806 name
= input_line_pointer
;
4807 name_end
= get_symbol_end ();
4809 if (strncmp (name
, "stack", 5) == 0)
4811 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_FP_STACK
;
4813 else if (strncmp (name
, "reg", 3) == 0)
4815 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_FP_REGISTER
;
4817 else if (strncmp (name
, "null", 4) == 0)
4819 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_NULL
;
4823 as_fatal (_("unknown procedure kind"));
4824 demand_empty_rest_of_line ();
4828 *input_line_pointer
= name_end
;
4829 demand_empty_rest_of_line ();
4831 #ifdef md_flush_pending_output
4832 md_flush_pending_output ();
4835 frag_align (3, 0, 0);
4837 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
4839 seginfo
->literal_pool_size
+= 16;
4841 *p
= alpha_evax_proc
.pdsckind
4842 | ((alpha_evax_proc
.framereg
== 29) ? PDSC_S_M_BASE_REG_IS_FP
: 0);
4843 *(p
+ 1) = PDSC_S_M_NATIVE
| PDSC_S_M_NO_JACKET
;
4845 switch (alpha_evax_proc
.pdsckind
)
4847 case PDSC_S_K_KIND_NULL
:
4851 case PDSC_S_K_KIND_FP_REGISTER
:
4852 *(p
+ 2) = alpha_evax_proc
.fp_save
;
4853 *(p
+ 3) = alpha_evax_proc
.ra_save
;
4855 case PDSC_S_K_KIND_FP_STACK
:
4856 md_number_to_chars (p
+ 2, (valueT
) alpha_evax_proc
.rsa_offset
, 2);
4858 default: /* impossible */
4863 *(p
+ 5) = alpha_evax_proc
.type
& 0x0f;
4865 /* Signature offset. */
4866 md_number_to_chars (p
+ 6, (valueT
) 0, 2);
4868 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
+8, 8, &exp
, 0, BFD_RELOC_64
);
4870 if (alpha_evax_proc
.pdsckind
== PDSC_S_K_KIND_NULL
)
4873 /* Add dummy fix to make add_to_link_pool work. */
4875 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
4877 seginfo
->literal_pool_size
+= 8;
4879 /* pdesc+16: Size. */
4880 md_number_to_chars (p
, (valueT
) alpha_evax_proc
.framesize
, 4);
4882 md_number_to_chars (p
+ 4, (valueT
) 0, 2);
4885 md_number_to_chars (p
+ 6, alpha_evax_proc
.prologue
, 2);
4887 if (alpha_evax_proc
.pdsckind
== PDSC_S_K_KIND_FP_REGISTER
)
4890 /* Add dummy fix to make add_to_link_pool work. */
4892 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
4894 seginfo
->literal_pool_size
+= 8;
4896 /* pdesc+24: register masks. */
4898 md_number_to_chars (p
, alpha_evax_proc
.imask
, 4);
4899 md_number_to_chars (p
+ 4, alpha_evax_proc
.fmask
, 4);
4904 /* Support for crash debug on vms. */
4907 s_alpha_name (ignore
)
4912 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
4914 if (now_seg
!= alpha_link_section
)
4916 as_bad (_(".name directive not in link (.link) section"));
4917 demand_empty_rest_of_line ();
4922 if (exp
.X_op
!= O_symbol
)
4924 as_warn (_(".name directive has no symbol"));
4925 demand_empty_rest_of_line ();
4929 demand_empty_rest_of_line ();
4931 #ifdef md_flush_pending_output
4932 md_flush_pending_output ();
4935 frag_align (3, 0, 0);
4937 seginfo
->literal_pool_size
+= 8;
4939 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 8, &exp
, 0, BFD_RELOC_64
);
4945 s_alpha_linkage (ignore
)
4951 #ifdef md_flush_pending_output
4952 md_flush_pending_output ();
4956 if (exp
.X_op
!= O_symbol
)
4958 as_fatal (_("No symbol after .linkage"));
4962 p
= frag_more (LKP_S_K_SIZE
);
4963 memset (p
, 0, LKP_S_K_SIZE
);
4964 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, LKP_S_K_SIZE
, &exp
, 0,\
4965 BFD_RELOC_ALPHA_LINKAGE
);
4967 demand_empty_rest_of_line ();
4973 s_alpha_code_address (ignore
)
4979 #ifdef md_flush_pending_output
4980 md_flush_pending_output ();
4984 if (exp
.X_op
!= O_symbol
)
4986 as_fatal (_("No symbol after .code_address"));
4992 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 8, &exp
, 0,\
4993 BFD_RELOC_ALPHA_CODEADDR
);
4995 demand_empty_rest_of_line ();
5001 s_alpha_fp_save (ignore
)
5005 alpha_evax_proc
.fp_save
= tc_get_register (1);
5007 demand_empty_rest_of_line ();
5012 s_alpha_mask (ignore
)
5017 if (get_absolute_expression_and_terminator (&val
) != ',')
5019 as_warn (_("Bad .mask directive"));
5020 --input_line_pointer
;
5024 alpha_evax_proc
.imask
= val
;
5025 (void) get_absolute_expression ();
5027 demand_empty_rest_of_line ();
5033 s_alpha_fmask (ignore
)
5038 if (get_absolute_expression_and_terminator (&val
) != ',')
5040 as_warn (_("Bad .fmask directive"));
5041 --input_line_pointer
;
5045 alpha_evax_proc
.fmask
= val
;
5046 (void) get_absolute_expression ();
5048 demand_empty_rest_of_line ();
5054 s_alpha_end (ignore
)
5059 c
= get_symbol_end ();
5060 *input_line_pointer
= c
;
5061 demand_empty_rest_of_line ();
5062 alpha_evax_proc
.symbol
= 0;
5068 s_alpha_file (ignore
)
5073 static char case_hack
[32];
5075 extern char *demand_copy_string
PARAMS ((int *lenP
));
5077 sprintf (case_hack
, "<CASE:%01d%01d>",
5078 alpha_flag_hash_long_names
, alpha_flag_show_after_trunc
);
5080 s
= symbol_find_or_make (case_hack
);
5081 symbol_get_bfdsym (s
)->flags
|= BSF_FILE
;
5083 get_absolute_expression ();
5084 s
= symbol_find_or_make (demand_copy_string (&length
));
5085 symbol_get_bfdsym (s
)->flags
|= BSF_FILE
;
5086 demand_empty_rest_of_line ();
5090 #endif /* OBJ_EVAX */
5092 /* Handle the .gprel32 pseudo op. */
5095 s_alpha_gprel32 (ignore
)
5096 int ignore ATTRIBUTE_UNUSED
;
5108 e
.X_add_symbol
= section_symbol (absolute_section
);
5121 e
.X_add_symbol
= section_symbol (absolute_section
);
5124 e
.X_op
= O_subtract
;
5125 e
.X_op_symbol
= alpha_gp_symbol
;
5133 if (alpha_auto_align_on
&& alpha_current_align
< 2)
5134 alpha_align (2, (char *) NULL
, alpha_insn_label
, 0);
5135 if (alpha_current_align
> 2)
5136 alpha_current_align
= 2;
5137 alpha_insn_label
= NULL
;
5141 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 4,
5142 &e
, 0, BFD_RELOC_GPREL32
);
5145 /* Handle floating point allocation pseudo-ops. This is like the
5146 generic vresion, but it makes sure the current label, if any, is
5147 correctly aligned. */
5150 s_alpha_float_cons (type
)
5177 if (alpha_auto_align_on
&& alpha_current_align
< log_size
)
5178 alpha_align (log_size
, (char *) NULL
, alpha_insn_label
, 0);
5179 if (alpha_current_align
> log_size
)
5180 alpha_current_align
= log_size
;
5181 alpha_insn_label
= NULL
;
5186 /* Handle the .proc pseudo op. We don't really do much with it except
5190 s_alpha_proc (is_static
)
5191 int is_static ATTRIBUTE_UNUSED
;
5199 /* Takes ".proc name,nargs" */
5201 name
= input_line_pointer
;
5202 c
= get_symbol_end ();
5203 p
= input_line_pointer
;
5204 symbolP
= symbol_find_or_make (name
);
5207 if (*input_line_pointer
!= ',')
5210 as_warn (_("Expected comma after name \"%s\""), name
);
5213 ignore_rest_of_line ();
5217 input_line_pointer
++;
5218 temp
= get_absolute_expression ();
5220 /* *symbol_get_obj (symbolP) = (signed char) temp; */
5221 as_warn (_("unhandled: .proc %s,%d"), name
, temp
);
5222 demand_empty_rest_of_line ();
5225 /* Handle the .set pseudo op. This is used to turn on and off most of
5226 the assembler features. */
5230 int x ATTRIBUTE_UNUSED
;
5236 name
= input_line_pointer
;
5237 ch
= get_symbol_end ();
5240 if (s
[0] == 'n' && s
[1] == 'o')
5245 if (!strcmp ("reorder", s
))
5247 else if (!strcmp ("at", s
))
5248 alpha_noat_on
= !yesno
;
5249 else if (!strcmp ("macro", s
))
5250 alpha_macros_on
= yesno
;
5251 else if (!strcmp ("move", s
))
5253 else if (!strcmp ("volatile", s
))
5256 as_warn (_("Tried to .set unrecognized mode `%s'"), name
);
5258 *input_line_pointer
= ch
;
5259 demand_empty_rest_of_line ();
5262 /* Handle the .base pseudo op. This changes the assembler's notion of
5263 the $gp register. */
5266 s_alpha_base (ignore
)
5267 int ignore ATTRIBUTE_UNUSED
;
5270 if (first_32bit_quadrant
)
5272 /* not fatal, but it might not work in the end */
5273 as_warn (_("File overrides no-base-register option."));
5274 first_32bit_quadrant
= 0;
5279 if (*input_line_pointer
== '$')
5281 input_line_pointer
++;
5282 if (*input_line_pointer
== 'r')
5283 input_line_pointer
++;
5286 alpha_gp_register
= get_absolute_expression ();
5287 if (alpha_gp_register
< 0 || alpha_gp_register
> 31)
5289 alpha_gp_register
= AXP_REG_GP
;
5290 as_warn (_("Bad base register, using $%d."), alpha_gp_register
);
5293 demand_empty_rest_of_line ();
5296 /* Handle the .align pseudo-op. This aligns to a power of two. It
5297 also adjusts any current instruction label. We treat this the same
5298 way the MIPS port does: .align 0 turns off auto alignment. */
5301 s_alpha_align (ignore
)
5302 int ignore ATTRIBUTE_UNUSED
;
5306 long max_alignment
= 15;
5308 align
= get_absolute_expression ();
5309 if (align
> max_alignment
)
5311 align
= max_alignment
;
5312 as_bad (_("Alignment too large: %d. assumed"), align
);
5316 as_warn (_("Alignment negative: 0 assumed"));
5320 if (*input_line_pointer
== ',')
5322 input_line_pointer
++;
5323 fill
= get_absolute_expression ();
5331 alpha_auto_align_on
= 1;
5332 alpha_align (align
, pfill
, alpha_insn_label
, 1);
5336 alpha_auto_align_on
= 0;
5339 demand_empty_rest_of_line ();
5342 /* Hook the normal string processor to reset known alignment. */
5345 s_alpha_stringer (terminate
)
5348 alpha_current_align
= 0;
5349 alpha_insn_label
= NULL
;
5350 stringer (terminate
);
5353 /* Hook the normal space processing to reset known alignment. */
5356 s_alpha_space (ignore
)
5359 alpha_current_align
= 0;
5360 alpha_insn_label
= NULL
;
5364 /* Hook into cons for auto-alignment. */
5367 alpha_cons_align (size
)
5373 while ((size
>>= 1) != 0)
5376 if (alpha_auto_align_on
&& alpha_current_align
< log_size
)
5377 alpha_align (log_size
, (char *) NULL
, alpha_insn_label
, 0);
5378 if (alpha_current_align
> log_size
)
5379 alpha_current_align
= log_size
;
5380 alpha_insn_label
= NULL
;
5383 /* Here come the .uword, .ulong, and .uquad explicitly unaligned
5384 pseudos. We just turn off auto-alignment and call down to cons. */
5387 s_alpha_ucons (bytes
)
5390 int hold
= alpha_auto_align_on
;
5391 alpha_auto_align_on
= 0;
5393 alpha_auto_align_on
= hold
;
5396 /* Switch the working cpu type. */
5399 s_alpha_arch (ignored
)
5400 int ignored ATTRIBUTE_UNUSED
;
5403 const struct cpu_type
*p
;
5406 name
= input_line_pointer
;
5407 ch
= get_symbol_end ();
5409 for (p
= cpu_types
; p
->name
; ++p
)
5410 if (strcmp (name
, p
->name
) == 0)
5412 alpha_target_name
= p
->name
, alpha_target
= p
->flags
;
5415 as_warn ("Unknown CPU identifier `%s'", name
);
5418 *input_line_pointer
= ch
;
5419 demand_empty_rest_of_line ();
5423 /* print token expression with alpha specific extension. */
5426 alpha_print_token (f
, exp
)
5428 const expressionS
*exp
;
5438 expressionS nexp
= *exp
;
5439 nexp
.X_op
= O_register
;
5440 print_expr (f
, &nexp
);
5445 print_expr (f
, exp
);
5452 /* The target specific pseudo-ops which we support. */
5454 const pseudo_typeS md_pseudo_table
[] = {
5456 {"comm", s_alpha_comm
, 0}, /* osf1 compiler does this */
5457 {"rdata", s_alpha_rdata
, 0},
5459 {"text", s_alpha_text
, 0},
5460 {"data", s_alpha_data
, 0},
5462 {"sdata", s_alpha_sdata
, 0},
5465 {"section", s_alpha_section
, 0},
5466 {"section.s", s_alpha_section
, 0},
5467 {"sect", s_alpha_section
, 0},
5468 {"sect.s", s_alpha_section
, 0},
5471 { "pdesc", s_alpha_pdesc
, 0},
5472 { "name", s_alpha_name
, 0},
5473 { "linkage", s_alpha_linkage
, 0},
5474 { "code_address", s_alpha_code_address
, 0},
5475 { "ent", s_alpha_ent
, 0},
5476 { "frame", s_alpha_frame
, 0},
5477 { "fp_save", s_alpha_fp_save
, 0},
5478 { "mask", s_alpha_mask
, 0},
5479 { "fmask", s_alpha_fmask
, 0},
5480 { "end", s_alpha_end
, 0},
5481 { "file", s_alpha_file
, 0},
5482 { "rdata", s_alpha_section
, 1},
5483 { "comm", s_alpha_comm
, 0},
5484 { "link", s_alpha_section
, 3},
5485 { "ctors", s_alpha_section
, 4},
5486 { "dtors", s_alpha_section
, 5},
5489 /* Frame related pseudos. */
5490 {"ent", s_alpha_ent
, 0},
5491 {"end", s_alpha_end
, 0},
5492 {"mask", s_alpha_mask
, 0},
5493 {"fmask", s_alpha_mask
, 1},
5494 {"frame", s_alpha_frame
, 0},
5495 {"prologue", s_alpha_prologue
, 0},
5496 {"file", s_alpha_file
, 5},
5497 {"loc", s_alpha_loc
, 9},
5498 {"stabs", s_alpha_stab
, 's'},
5499 {"stabn", s_alpha_stab
, 'n'},
5500 /* COFF debugging related pseudos. */
5501 {"begin", s_alpha_coff_wrapper
, 0},
5502 {"bend", s_alpha_coff_wrapper
, 1},
5503 {"def", s_alpha_coff_wrapper
, 2},
5504 {"dim", s_alpha_coff_wrapper
, 3},
5505 {"endef", s_alpha_coff_wrapper
, 4},
5506 {"scl", s_alpha_coff_wrapper
, 5},
5507 {"tag", s_alpha_coff_wrapper
, 6},
5508 {"val", s_alpha_coff_wrapper
, 7},
5510 {"prologue", s_ignore
, 0},
5512 {"gprel32", s_alpha_gprel32
, 0},
5513 {"t_floating", s_alpha_float_cons
, 'd'},
5514 {"s_floating", s_alpha_float_cons
, 'f'},
5515 {"f_floating", s_alpha_float_cons
, 'F'},
5516 {"g_floating", s_alpha_float_cons
, 'G'},
5517 {"d_floating", s_alpha_float_cons
, 'D'},
5519 {"proc", s_alpha_proc
, 0},
5520 {"aproc", s_alpha_proc
, 1},
5521 {"set", s_alpha_set
, 0},
5522 {"reguse", s_ignore
, 0},
5523 {"livereg", s_ignore
, 0},
5524 {"base", s_alpha_base
, 0}, /*??*/
5525 {"option", s_ignore
, 0},
5526 {"aent", s_ignore
, 0},
5527 {"ugen", s_ignore
, 0},
5528 {"eflag", s_ignore
, 0},
5530 {"align", s_alpha_align
, 0},
5531 {"double", s_alpha_float_cons
, 'd'},
5532 {"float", s_alpha_float_cons
, 'f'},
5533 {"single", s_alpha_float_cons
, 'f'},
5534 {"ascii", s_alpha_stringer
, 0},
5535 {"asciz", s_alpha_stringer
, 1},
5536 {"string", s_alpha_stringer
, 1},
5537 {"space", s_alpha_space
, 0},
5538 {"skip", s_alpha_space
, 0},
5539 {"zero", s_alpha_space
, 0},
5541 /* Unaligned data pseudos. */
5542 {"uword", s_alpha_ucons
, 2},
5543 {"ulong", s_alpha_ucons
, 4},
5544 {"uquad", s_alpha_ucons
, 8},
5547 /* Dwarf wants these versions of unaligned. */
5548 {"2byte", s_alpha_ucons
, 2},
5549 {"4byte", s_alpha_ucons
, 4},
5550 {"8byte", s_alpha_ucons
, 8},
5553 /* We don't do any optimizing, so we can safely ignore these. */
5554 {"noalias", s_ignore
, 0},
5555 {"alias", s_ignore
, 0},
5557 {"arch", s_alpha_arch
, 0},
5562 /* Build a BFD section with its flags set appropriately for the .lita,
5563 .lit8, or .lit4 sections. */
5566 create_literal_section (name
, secp
, symp
)
5571 segT current_section
= now_seg
;
5572 int current_subsec
= now_subseg
;
5575 *secp
= new_sec
= subseg_new (name
, 0);
5576 subseg_set (current_section
, current_subsec
);
5577 bfd_set_section_alignment (stdoutput
, new_sec
, 4);
5578 bfd_set_section_flags (stdoutput
, new_sec
,
5579 SEC_RELOC
| SEC_ALLOC
| SEC_LOAD
| SEC_READONLY
5582 S_CLEAR_EXTERNAL (*symp
= section_symbol (new_sec
));
5587 /* @@@ GP selection voodoo. All of this seems overly complicated and
5588 unnecessary; which is the primary reason it's for ECOFF only. */
5597 vma
= bfd_get_section_vma (foo
, sec
);
5598 if (vma
&& vma
< alpha_gp_value
)
5599 alpha_gp_value
= vma
;
5605 assert (alpha_gp_value
== 0);
5607 /* Get minus-one in whatever width... */
5611 /* Select the smallest VMA of these existing sections. */
5612 maybe_set_gp (alpha_lita_section
);
5614 /* These were disabled before -- should we use them? */
5615 maybe_set_gp (sdata
);
5616 maybe_set_gp (lit8_sec
);
5617 maybe_set_gp (lit4_sec
);
5620 /* @@ Will a simple 0x8000 work here? If not, why not? */
5621 #define GP_ADJUSTMENT (0x8000 - 0x10)
5623 alpha_gp_value
+= GP_ADJUSTMENT
;
5625 S_SET_VALUE (alpha_gp_symbol
, alpha_gp_value
);
5628 printf (_("Chose GP value of %lx\n"), alpha_gp_value
);
5631 #endif /* OBJ_ECOFF */
5634 /* Map 's' to SHF_ALPHA_GPREL. */
5637 alpha_elf_section_letter (letter
, ptr_msg
)
5642 return SHF_ALPHA_GPREL
;
5644 *ptr_msg
= _("Bad .section directive: want a,s,w,x,M,S,G,T in string");
5648 /* Map SHF_ALPHA_GPREL to SEC_SMALL_DATA. */
5651 alpha_elf_section_flags (flags
, attr
, type
)
5653 int attr
, type ATTRIBUTE_UNUSED
;
5655 if (attr
& SHF_ALPHA_GPREL
)
5656 flags
|= SEC_SMALL_DATA
;
5659 #endif /* OBJ_ELF */
5661 /* Called internally to handle all alignment needs. This takes care
5662 of eliding calls to frag_align if'n the cached current alignment
5663 says we've already got it, as well as taking care of the auto-align
5664 feature wrt labels. */
5667 alpha_align (n
, pfill
, label
, force
)
5671 int force ATTRIBUTE_UNUSED
;
5673 if (alpha_current_align
>= n
)
5678 if (subseg_text_p (now_seg
))
5679 frag_align_code (n
, 0);
5681 frag_align (n
, 0, 0);
5684 frag_align (n
, *pfill
, 0);
5686 alpha_current_align
= n
;
5688 if (label
!= NULL
&& S_GET_SEGMENT (label
) == now_seg
)
5690 symbol_set_frag (label
, frag_now
);
5691 S_SET_VALUE (label
, (valueT
) frag_now_fix ());
5694 record_alignment (now_seg
, n
);
5696 /* ??? If alpha_flag_relax && force && elf, record the requested alignment
5697 in a reloc for the linker to see. */
5700 /* This is called from HANDLE_ALIGN in write.c. Fill in the contents
5701 of an rs_align_code fragment. */
5704 alpha_handle_align (fragp
)
5707 static char const unop
[4] = { 0x00, 0x00, 0xfe, 0x2f };
5708 static char const nopunop
[8] = {
5709 0x1f, 0x04, 0xff, 0x47,
5710 0x00, 0x00, 0xfe, 0x2f
5716 if (fragp
->fr_type
!= rs_align_code
)
5719 bytes
= fragp
->fr_next
->fr_address
- fragp
->fr_address
- fragp
->fr_fix
;
5720 p
= fragp
->fr_literal
+ fragp
->fr_fix
;
5733 memcpy (p
, unop
, 4);
5739 memcpy (p
, nopunop
, 8);
5741 fragp
->fr_fix
+= fix
;
5745 /* The Alpha has support for some VAX floating point types, as well as for
5746 IEEE floating point. We consider IEEE to be the primary floating point
5747 format, and sneak in the VAX floating point support here. */
5748 #define md_atof vax_md_atof
5749 #include "config/atof-vax.c"