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 USER_RELOC_P(R) ((R) >= O_literal && (R) <= O_tprel)
142 /* Macros for extracting the type and number of encoded register tokens */
144 #define is_ir_num(x) (((x) & 32) == 0)
145 #define is_fpr_num(x) (((x) & 32) != 0)
146 #define regno(x) ((x) & 31)
148 /* Something odd inherited from the old assembler */
150 #define note_gpreg(R) (alpha_gprmask |= (1 << (R)))
151 #define note_fpreg(R) (alpha_fprmask |= (1 << (R)))
153 /* Predicates for 16- and 32-bit ranges */
154 /* XXX: The non-shift version appears to trigger a compiler bug when
155 cross-assembling from x86 w/ gcc 2.7.2. */
158 #define range_signed_16(x) \
159 (((offsetT) (x) >> 15) == 0 || ((offsetT) (x) >> 15) == -1)
160 #define range_signed_32(x) \
161 (((offsetT) (x) >> 31) == 0 || ((offsetT) (x) >> 31) == -1)
163 #define range_signed_16(x) ((offsetT) (x) >= -(offsetT) 0x8000 && \
164 (offsetT) (x) <= (offsetT) 0x7FFF)
165 #define range_signed_32(x) ((offsetT) (x) >= -(offsetT) 0x80000000 && \
166 (offsetT) (x) <= (offsetT) 0x7FFFFFFF)
169 /* Macros for sign extending from 16- and 32-bits. */
170 /* XXX: The cast macros will work on all the systems that I care about,
171 but really a predicate should be found to use the non-cast forms. */
174 #define sign_extend_16(x) ((short) (x))
175 #define sign_extend_32(x) ((int) (x))
177 #define sign_extend_16(x) ((offsetT) (((x) & 0xFFFF) ^ 0x8000) - 0x8000)
178 #define sign_extend_32(x) ((offsetT) (((x) & 0xFFFFFFFF) \
179 ^ 0x80000000) - 0x80000000)
182 /* Macros to build tokens */
184 #define set_tok_reg(t, r) (memset (&(t), 0, sizeof (t)), \
185 (t).X_op = O_register, \
186 (t).X_add_number = (r))
187 #define set_tok_preg(t, r) (memset (&(t), 0, sizeof (t)), \
188 (t).X_op = O_pregister, \
189 (t).X_add_number = (r))
190 #define set_tok_cpreg(t, r) (memset (&(t), 0, sizeof (t)), \
191 (t).X_op = O_cpregister, \
192 (t).X_add_number = (r))
193 #define set_tok_freg(t, r) (memset (&(t), 0, sizeof (t)), \
194 (t).X_op = O_register, \
195 (t).X_add_number = (r) + 32)
196 #define set_tok_sym(t, s, a) (memset (&(t), 0, sizeof (t)), \
197 (t).X_op = O_symbol, \
198 (t).X_add_symbol = (s), \
199 (t).X_add_number = (a))
200 #define set_tok_const(t, n) (memset (&(t), 0, sizeof (t)), \
201 (t).X_op = O_constant, \
202 (t).X_add_number = (n))
204 /* Prototypes for all local functions */
206 static struct alpha_reloc_tag
*get_alpha_reloc_tag
PARAMS ((long));
207 static void alpha_adjust_symtab_relocs
PARAMS ((bfd
*, asection
*, PTR
));
209 static int tokenize_arguments
PARAMS ((char *, expressionS
*, int));
210 static const struct alpha_opcode
*find_opcode_match
211 PARAMS ((const struct alpha_opcode
*, const expressionS
*, int *, int *));
212 static const struct alpha_macro
*find_macro_match
213 PARAMS ((const struct alpha_macro
*, const expressionS
*, int *));
214 static unsigned insert_operand
215 PARAMS ((unsigned, const struct alpha_operand
*, offsetT
, char *, unsigned));
216 static void assemble_insn
217 PARAMS ((const struct alpha_opcode
*, const expressionS
*, int,
218 struct alpha_insn
*, bfd_reloc_code_real_type
));
219 static void emit_insn
PARAMS ((struct alpha_insn
*));
220 static void assemble_tokens_to_insn
221 PARAMS ((const char *, const expressionS
*, int, struct alpha_insn
*));
222 static void assemble_tokens
223 PARAMS ((const char *, const expressionS
*, int, int));
225 static long load_expression
226 PARAMS ((int, const expressionS
*, int *, expressionS
*));
228 static void emit_ldgp
PARAMS ((const expressionS
*, int, const PTR
));
229 static void emit_division
PARAMS ((const expressionS
*, int, const PTR
));
230 static void emit_lda
PARAMS ((const expressionS
*, int, const PTR
));
231 static void emit_ldah
PARAMS ((const expressionS
*, int, const PTR
));
232 static void emit_ir_load
PARAMS ((const expressionS
*, int, const PTR
));
233 static void emit_loadstore
PARAMS ((const expressionS
*, int, const PTR
));
234 static void emit_jsrjmp
PARAMS ((const expressionS
*, int, const PTR
));
235 static void emit_ldX
PARAMS ((const expressionS
*, int, const PTR
));
236 static void emit_ldXu
PARAMS ((const expressionS
*, int, const PTR
));
237 static void emit_uldX
PARAMS ((const expressionS
*, int, const PTR
));
238 static void emit_uldXu
PARAMS ((const expressionS
*, int, const PTR
));
239 static void emit_ldil
PARAMS ((const expressionS
*, int, const PTR
));
240 static void emit_stX
PARAMS ((const expressionS
*, int, const PTR
));
241 static void emit_ustX
PARAMS ((const expressionS
*, int, const PTR
));
242 static void emit_sextX
PARAMS ((const expressionS
*, int, const PTR
));
243 static void emit_retjcr
PARAMS ((const expressionS
*, int, const PTR
));
245 static void s_alpha_text
PARAMS ((int));
246 static void s_alpha_data
PARAMS ((int));
248 static void s_alpha_comm
PARAMS ((int));
249 static void s_alpha_rdata
PARAMS ((int));
252 static void s_alpha_sdata
PARAMS ((int));
255 static void s_alpha_section
PARAMS ((int));
256 static void s_alpha_ent
PARAMS ((int));
257 static void s_alpha_end
PARAMS ((int));
258 static void s_alpha_mask
PARAMS ((int));
259 static void s_alpha_frame
PARAMS ((int));
260 static void s_alpha_prologue
PARAMS ((int));
261 static void s_alpha_file
PARAMS ((int));
262 static void s_alpha_loc
PARAMS ((int));
263 static void s_alpha_stab
PARAMS ((int));
264 static void s_alpha_coff_wrapper
PARAMS ((int));
267 static void s_alpha_section
PARAMS ((int));
269 static void s_alpha_gprel32
PARAMS ((int));
270 static void s_alpha_float_cons
PARAMS ((int));
271 static void s_alpha_proc
PARAMS ((int));
272 static void s_alpha_set
PARAMS ((int));
273 static void s_alpha_base
PARAMS ((int));
274 static void s_alpha_align
PARAMS ((int));
275 static void s_alpha_stringer
PARAMS ((int));
276 static void s_alpha_space
PARAMS ((int));
277 static void s_alpha_ucons
PARAMS ((int));
278 static void s_alpha_arch
PARAMS ((int));
280 static void create_literal_section
PARAMS ((const char *, segT
*, symbolS
**));
282 static void select_gp_value
PARAMS ((void));
284 static void alpha_align
PARAMS ((int, char *, symbolS
*, int));
286 /* Generic assembler global variables which must be defined by all
289 /* Characters which always start a comment. */
290 const char comment_chars
[] = "#";
292 /* Characters which start a comment at the beginning of a line. */
293 const char line_comment_chars
[] = "#";
295 /* Characters which may be used to separate multiple commands on a
297 const char line_separator_chars
[] = ";";
299 /* Characters which are used to indicate an exponent in a floating
301 const char EXP_CHARS
[] = "eE";
303 /* Characters which mean that a number is a floating point constant,
306 const char FLT_CHARS
[] = "dD";
308 /* XXX: Do all of these really get used on the alpha?? */
309 char FLT_CHARS
[] = "rRsSfFdDxXpP";
313 const char *md_shortopts
= "Fm:g+1h:HG:";
315 const char *md_shortopts
= "Fm:gG:";
318 struct option md_longopts
[] = {
319 #define OPTION_32ADDR (OPTION_MD_BASE)
320 { "32addr", no_argument
, NULL
, OPTION_32ADDR
},
321 #define OPTION_RELAX (OPTION_32ADDR + 1)
322 { "relax", no_argument
, NULL
, OPTION_RELAX
},
324 #define OPTION_MDEBUG (OPTION_RELAX + 1)
325 #define OPTION_NO_MDEBUG (OPTION_MDEBUG + 1)
326 { "mdebug", no_argument
, NULL
, OPTION_MDEBUG
},
327 { "no-mdebug", no_argument
, NULL
, OPTION_NO_MDEBUG
},
329 { NULL
, no_argument
, NULL
, 0 }
332 size_t md_longopts_size
= sizeof (md_longopts
);
336 #define AXP_REG_R16 16
337 #define AXP_REG_R17 17
339 #define AXP_REG_T9 22
341 #define AXP_REG_T10 23
343 #define AXP_REG_T11 24
345 #define AXP_REG_T12 25
346 #define AXP_REG_AI 25
348 #define AXP_REG_FP 29
351 #define AXP_REG_GP AXP_REG_PV
352 #endif /* OBJ_EVAX */
354 /* The cpu for which we are generating code */
355 static unsigned alpha_target
= AXP_OPCODE_BASE
;
356 static const char *alpha_target_name
= "<all>";
358 /* The hash table of instruction opcodes */
359 static struct hash_control
*alpha_opcode_hash
;
361 /* The hash table of macro opcodes */
362 static struct hash_control
*alpha_macro_hash
;
365 /* The $gp relocation symbol */
366 static symbolS
*alpha_gp_symbol
;
368 /* XXX: what is this, and why is it exported? */
369 valueT alpha_gp_value
;
372 /* The current $gp register */
373 static int alpha_gp_register
= AXP_REG_GP
;
375 /* A table of the register symbols */
376 static symbolS
*alpha_register_table
[64];
378 /* Constant sections, or sections of constants */
380 static segT alpha_lita_section
;
381 static segT alpha_lit4_section
;
384 static segT alpha_link_section
;
385 static segT alpha_ctors_section
;
386 static segT alpha_dtors_section
;
388 static segT alpha_lit8_section
;
390 /* Symbols referring to said sections. */
392 static symbolS
*alpha_lita_symbol
;
393 static symbolS
*alpha_lit4_symbol
;
396 static symbolS
*alpha_link_symbol
;
397 static symbolS
*alpha_ctors_symbol
;
398 static symbolS
*alpha_dtors_symbol
;
400 static symbolS
*alpha_lit8_symbol
;
402 /* Literal for .litX+0x8000 within .lita */
404 static offsetT alpha_lit4_literal
;
405 static offsetT alpha_lit8_literal
;
409 /* The active .ent symbol. */
410 static symbolS
*alpha_cur_ent_sym
;
413 /* Is the assembler not allowed to use $at? */
414 static int alpha_noat_on
= 0;
416 /* Are macros enabled? */
417 static int alpha_macros_on
= 1;
419 /* Are floats disabled? */
420 static int alpha_nofloats_on
= 0;
422 /* Are addresses 32 bit? */
423 static int alpha_addr32_on
= 0;
425 /* Symbol labelling the current insn. When the Alpha gas sees
428 and the section happens to not be on an eight byte boundary, it
429 will align both the symbol and the .quad to an eight byte boundary. */
430 static symbolS
*alpha_insn_label
;
432 /* Whether we should automatically align data generation pseudo-ops.
433 .align 0 will turn this off. */
434 static int alpha_auto_align_on
= 1;
436 /* The known current alignment of the current section. */
437 static int alpha_current_align
;
439 /* These are exported to ECOFF code. */
440 unsigned long alpha_gprmask
, alpha_fprmask
;
442 /* Whether the debugging option was seen. */
443 static int alpha_debug
;
446 /* Whether we are emitting an mdebug section. */
447 int alpha_flag_mdebug
= -1;
450 /* Don't fully resolve relocations, allowing code movement in the linker. */
451 static int alpha_flag_relax
;
453 /* What value to give to bfd_set_gp_size. */
454 static int g_switch_value
= 8;
457 /* Collect information about current procedure here. */
459 symbolS
*symbol
; /* proc pdesc symbol */
461 int framereg
; /* register for frame pointer */
462 int framesize
; /* size of frame */
472 static int alpha_flag_hash_long_names
= 0; /* -+ */
473 static int alpha_flag_show_after_trunc
= 0; /* -H */
475 /* If the -+ switch is given, then a hash is appended to any name that is
476 * longer than 64 characters, else longer symbol names are truncated.
482 /* A table to map the spelling of a relocation operand into an appropriate
483 bfd_reloc_code_real_type type. The table is assumed to be ordered such
484 that op-O_literal indexes into it. */
486 #define ALPHA_RELOC_TABLE(op) \
487 (&alpha_reloc_op[ ((!USER_RELOC_P (op)) \
489 : (int) (op) - (int) O_literal) ])
491 #define DEF(NAME, RELOC, REQ, ALLOW) \
492 { #NAME, sizeof(#NAME)-1, O_##NAME, RELOC, REQ, ALLOW}
494 static const struct alpha_reloc_op_tag
{
495 const char *name
; /* string to lookup */
496 size_t length
; /* size of the string */
497 operatorT op
; /* which operator to use */
498 bfd_reloc_code_real_type reloc
; /* relocation before frob */
499 unsigned int require_seq
: 1; /* require a sequence number */
500 unsigned int allow_seq
: 1; /* allow a sequence number */
501 } alpha_reloc_op
[] = {
502 DEF(literal
, BFD_RELOC_ALPHA_ELF_LITERAL
, 0, 1),
503 DEF(lituse_addr
, DUMMY_RELOC_LITUSE_ADDR
, 1, 1),
504 DEF(lituse_base
, DUMMY_RELOC_LITUSE_BASE
, 1, 1),
505 DEF(lituse_bytoff
, DUMMY_RELOC_LITUSE_BYTOFF
, 1, 1),
506 DEF(lituse_jsr
, DUMMY_RELOC_LITUSE_JSR
, 1, 1),
507 DEF(lituse_tlsgd
, DUMMY_RELOC_LITUSE_TLSGD
, 1, 1),
508 DEF(lituse_tlsldm
, DUMMY_RELOC_LITUSE_TLSLDM
, 1, 1),
509 DEF(gpdisp
, BFD_RELOC_ALPHA_GPDISP
, 1, 1),
510 DEF(gprelhigh
, BFD_RELOC_ALPHA_GPREL_HI16
, 0, 0),
511 DEF(gprellow
, BFD_RELOC_ALPHA_GPREL_LO16
, 0, 0),
512 DEF(gprel
, BFD_RELOC_GPREL16
, 0, 0),
513 DEF(samegp
, BFD_RELOC_ALPHA_BRSGP
, 0, 0),
514 DEF(tlsgd
, BFD_RELOC_ALPHA_TLSGD
, 0, 1),
515 DEF(tlsldm
, BFD_RELOC_ALPHA_TLSLDM
, 0, 1),
516 DEF(gotdtprel
, BFD_RELOC_ALPHA_GOTDTPREL16
, 0, 0),
517 DEF(dtprelhi
, BFD_RELOC_ALPHA_DTPREL_HI16
, 0, 0),
518 DEF(dtprello
, BFD_RELOC_ALPHA_DTPREL_LO16
, 0, 0),
519 DEF(dtprel
, BFD_RELOC_ALPHA_DTPREL16
, 0, 0),
520 DEF(gottprel
, BFD_RELOC_ALPHA_GOTTPREL16
, 0, 0),
521 DEF(tprelhi
, BFD_RELOC_ALPHA_TPREL_HI16
, 0, 0),
522 DEF(tprello
, BFD_RELOC_ALPHA_TPREL_LO16
, 0, 0),
523 DEF(tprel
, BFD_RELOC_ALPHA_TPREL16
, 0, 0),
528 static const int alpha_num_reloc_op
529 = sizeof (alpha_reloc_op
) / sizeof (*alpha_reloc_op
);
530 #endif /* RELOC_OP_P */
532 /* Maximum # digits needed to hold the largest sequence # */
533 #define ALPHA_RELOC_DIGITS 25
535 /* Structure to hold explict sequence information. */
536 struct alpha_reloc_tag
538 fixS
*master
; /* the literal reloc */
539 fixS
*slaves
; /* head of linked list of lituses */
540 segT segment
; /* segment relocs are in or undefined_section*/
541 long sequence
; /* sequence # */
542 unsigned n_master
; /* # of literals */
543 unsigned n_slaves
; /* # of lituses */
544 unsigned saw_tlsgd
: 1; /* true if ... */
545 unsigned saw_tlsldm
: 1;
546 unsigned saw_lu_tlsgd
: 1;
547 unsigned saw_lu_tlsldm
: 1;
548 unsigned multi_section_p
: 1; /* true if more than one section was used */
549 char string
[1]; /* printable form of sequence to hash with */
552 /* Hash table to link up literals with the appropriate lituse */
553 static struct hash_control
*alpha_literal_hash
;
555 /* Sequence numbers for internal use by macros. */
556 static long next_sequence_num
= -1;
558 /* A table of CPU names and opcode sets. */
560 static const struct cpu_type
{
564 /* Ad hoc convention: cpu number gets palcode, process code doesn't.
565 This supports usage under DU 4.0b that does ".arch ev4", and
566 usage in MILO that does -m21064. Probably something more
567 specific like -m21064-pal should be used, but oh well. */
569 { "21064", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
570 { "21064a", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
571 { "21066", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
572 { "21068", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
573 { "21164", AXP_OPCODE_BASE
|AXP_OPCODE_EV5
},
574 { "21164a", AXP_OPCODE_BASE
|AXP_OPCODE_EV5
|AXP_OPCODE_BWX
},
575 { "21164pc", (AXP_OPCODE_BASE
|AXP_OPCODE_EV5
|AXP_OPCODE_BWX
577 { "21264", (AXP_OPCODE_BASE
|AXP_OPCODE_EV6
|AXP_OPCODE_BWX
578 |AXP_OPCODE_MAX
|AXP_OPCODE_CIX
) },
580 { "ev4", AXP_OPCODE_BASE
},
581 { "ev45", AXP_OPCODE_BASE
},
582 { "lca45", AXP_OPCODE_BASE
},
583 { "ev5", AXP_OPCODE_BASE
},
584 { "ev56", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
},
585 { "pca56", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
|AXP_OPCODE_MAX
},
586 { "ev6", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
|AXP_OPCODE_MAX
|AXP_OPCODE_CIX
},
588 { "all", AXP_OPCODE_BASE
},
592 /* The macro table */
594 static const struct alpha_macro alpha_macros
[] = {
595 /* Load/Store macros */
596 { "lda", emit_lda
, NULL
,
597 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
598 { "ldah", emit_ldah
, NULL
,
599 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
601 { "ldl", emit_ir_load
, "ldl",
602 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
603 { "ldl_l", emit_ir_load
, "ldl_l",
604 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
605 { "ldq", emit_ir_load
, "ldq",
606 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
607 { "ldq_l", emit_ir_load
, "ldq_l",
608 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
609 { "ldq_u", emit_ir_load
, "ldq_u",
610 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
611 { "ldf", emit_loadstore
, "ldf",
612 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
613 { "ldg", emit_loadstore
, "ldg",
614 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
615 { "lds", emit_loadstore
, "lds",
616 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
617 { "ldt", emit_loadstore
, "ldt",
618 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
620 { "ldb", emit_ldX
, (PTR
) 0,
621 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
622 { "ldbu", emit_ldXu
, (PTR
) 0,
623 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
624 { "ldw", emit_ldX
, (PTR
) 1,
625 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
626 { "ldwu", emit_ldXu
, (PTR
) 1,
627 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
629 { "uldw", emit_uldX
, (PTR
) 1,
630 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
631 { "uldwu", emit_uldXu
, (PTR
) 1,
632 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
633 { "uldl", emit_uldX
, (PTR
) 2,
634 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
635 { "uldlu", emit_uldXu
, (PTR
) 2,
636 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
637 { "uldq", emit_uldXu
, (PTR
) 3,
638 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
640 { "ldgp", emit_ldgp
, NULL
,
641 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
} },
643 { "ldi", emit_lda
, NULL
,
644 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
645 { "ldil", emit_ldil
, NULL
,
646 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
647 { "ldiq", emit_lda
, NULL
,
648 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
650 { "ldif" emit_ldiq
, NULL
,
651 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
652 { "ldid" emit_ldiq
, NULL
,
653 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
654 { "ldig" emit_ldiq
, NULL
,
655 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
656 { "ldis" emit_ldiq
, NULL
,
657 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
658 { "ldit" emit_ldiq
, NULL
,
659 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
662 { "stl", emit_loadstore
, "stl",
663 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
664 { "stl_c", emit_loadstore
, "stl_c",
665 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
666 { "stq", emit_loadstore
, "stq",
667 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
668 { "stq_c", emit_loadstore
, "stq_c",
669 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
670 { "stq_u", emit_loadstore
, "stq_u",
671 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
672 { "stf", emit_loadstore
, "stf",
673 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
674 { "stg", emit_loadstore
, "stg",
675 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
676 { "sts", emit_loadstore
, "sts",
677 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
678 { "stt", emit_loadstore
, "stt",
679 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
681 { "stb", emit_stX
, (PTR
) 0,
682 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
683 { "stw", emit_stX
, (PTR
) 1,
684 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
685 { "ustw", emit_ustX
, (PTR
) 1,
686 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
687 { "ustl", emit_ustX
, (PTR
) 2,
688 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
689 { "ustq", emit_ustX
, (PTR
) 3,
690 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
692 /* Arithmetic macros */
694 { "absl" emit_absl
, 1, { IR
} },
695 { "absl" emit_absl
, 2, { IR
, IR
} },
696 { "absl" emit_absl
, 2, { EXP
, IR
} },
697 { "absq" emit_absq
, 1, { IR
} },
698 { "absq" emit_absq
, 2, { IR
, IR
} },
699 { "absq" emit_absq
, 2, { EXP
, IR
} },
702 { "sextb", emit_sextX
, (PTR
) 0,
703 { MACRO_IR
, MACRO_IR
, MACRO_EOA
,
705 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
706 { "sextw", emit_sextX
, (PTR
) 1,
707 { MACRO_IR
, MACRO_IR
, MACRO_EOA
,
709 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
711 { "divl", emit_division
, "__divl",
712 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
713 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
714 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
715 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
716 { "divlu", emit_division
, "__divlu",
717 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
718 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
719 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
720 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
721 { "divq", emit_division
, "__divq",
722 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
723 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
724 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
725 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
726 { "divqu", emit_division
, "__divqu",
727 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
728 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
729 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
730 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
731 { "reml", emit_division
, "__reml",
732 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
733 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
734 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
735 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
736 { "remlu", emit_division
, "__remlu",
737 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
738 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
739 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
740 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
741 { "remq", emit_division
, "__remq",
742 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
743 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
744 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
745 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
746 { "remqu", emit_division
, "__remqu",
747 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
748 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
749 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
750 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
752 { "jsr", emit_jsrjmp
, "jsr",
753 { MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
754 MACRO_PIR
, MACRO_EOA
,
755 MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
756 MACRO_EXP
, MACRO_EOA
} },
757 { "jmp", emit_jsrjmp
, "jmp",
758 { MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
759 MACRO_PIR
, MACRO_EOA
,
760 MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
761 MACRO_EXP
, MACRO_EOA
} },
762 { "ret", emit_retjcr
, "ret",
763 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
765 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
766 MACRO_PIR
, MACRO_EOA
,
767 MACRO_EXP
, MACRO_EOA
,
769 { "jcr", emit_retjcr
, "jcr",
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 { "jsr_coroutine", 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
,
785 static const unsigned int alpha_num_macros
786 = sizeof (alpha_macros
) / sizeof (*alpha_macros
);
788 /* Public interface functions */
790 /* This function is called once, at assembler startup time. It sets
791 up all the tables, etc. that the MD part of the assembler will
792 need, that can be determined before arguments are parsed. */
799 /* Verify that X_op field is wide enough. */
803 assert (e
.X_op
== O_max
);
806 /* Create the opcode hash table */
808 alpha_opcode_hash
= hash_new ();
809 for (i
= 0; i
< alpha_num_opcodes
;)
811 const char *name
, *retval
, *slash
;
813 name
= alpha_opcodes
[i
].name
;
814 retval
= hash_insert (alpha_opcode_hash
, name
, (PTR
) &alpha_opcodes
[i
]);
816 as_fatal (_("internal error: can't hash opcode `%s': %s"),
819 /* Some opcodes include modifiers of various sorts with a "/mod"
820 syntax, like the architecture manual suggests. However, for
821 use with gcc at least, we also need access to those same opcodes
824 if ((slash
= strchr (name
, '/')) != NULL
)
826 char *p
= xmalloc (strlen (name
));
827 memcpy (p
, name
, slash
- name
);
828 strcpy (p
+ (slash
- name
), slash
+ 1);
830 (void) hash_insert (alpha_opcode_hash
, p
, (PTR
) &alpha_opcodes
[i
]);
831 /* Ignore failures -- the opcode table does duplicate some
832 variants in different forms, like "hw_stq" and "hw_st/q". */
835 while (++i
< alpha_num_opcodes
836 && (alpha_opcodes
[i
].name
== name
837 || !strcmp (alpha_opcodes
[i
].name
, name
)))
841 /* Create the macro hash table */
843 alpha_macro_hash
= hash_new ();
844 for (i
= 0; i
< alpha_num_macros
;)
846 const char *name
, *retval
;
848 name
= alpha_macros
[i
].name
;
849 retval
= hash_insert (alpha_macro_hash
, name
, (PTR
) &alpha_macros
[i
]);
851 as_fatal (_("internal error: can't hash macro `%s': %s"),
854 while (++i
< alpha_num_macros
855 && (alpha_macros
[i
].name
== name
856 || !strcmp (alpha_macros
[i
].name
, name
)))
860 /* Construct symbols for each of the registers */
862 for (i
= 0; i
< 32; ++i
)
865 sprintf (name
, "$%d", i
);
866 alpha_register_table
[i
] = symbol_create (name
, reg_section
, i
,
872 sprintf (name
, "$f%d", i
- 32);
873 alpha_register_table
[i
] = symbol_create (name
, reg_section
, i
,
877 /* Create the special symbols and sections we'll be using */
879 /* So .sbss will get used for tiny objects. */
880 bfd_set_gp_size (stdoutput
, g_switch_value
);
883 create_literal_section (".lita", &alpha_lita_section
, &alpha_lita_symbol
);
885 /* For handling the GP, create a symbol that won't be output in the
886 symbol table. We'll edit it out of relocs later. */
887 alpha_gp_symbol
= symbol_create ("<GP value>", alpha_lita_section
, 0x8000,
892 create_literal_section (".link", &alpha_link_section
, &alpha_link_symbol
);
898 segT sec
= subseg_new (".mdebug", (subsegT
) 0);
899 bfd_set_section_flags (stdoutput
, sec
, SEC_HAS_CONTENTS
| SEC_READONLY
);
900 bfd_set_section_alignment (stdoutput
, sec
, 3);
904 /* Create literal lookup hash table. */
905 alpha_literal_hash
= hash_new ();
907 subseg_set (text_section
, 0);
910 /* The public interface to the instruction assembler. */
916 char opname
[32]; /* current maximum is 13 */
917 expressionS tok
[MAX_INSN_ARGS
];
921 /* split off the opcode */
922 opnamelen
= strspn (str
, "abcdefghijklmnopqrstuvwxyz_/46819");
923 trunclen
= (opnamelen
< sizeof (opname
) - 1
925 : sizeof (opname
) - 1);
926 memcpy (opname
, str
, trunclen
);
927 opname
[trunclen
] = '\0';
929 /* tokenize the rest of the line */
930 if ((ntok
= tokenize_arguments (str
+ opnamelen
, tok
, MAX_INSN_ARGS
)) < 0)
932 if (ntok
!= TOKENIZE_ERROR_REPORT
)
933 as_bad (_("syntax error"));
939 assemble_tokens (opname
, tok
, ntok
, alpha_macros_on
);
942 /* Round up a section's size to the appropriate boundary. */
945 md_section_align (seg
, size
)
949 int align
= bfd_get_section_alignment (stdoutput
, seg
);
950 valueT mask
= ((valueT
) 1 << align
) - 1;
952 return (size
+ mask
) & ~mask
;
955 /* Turn a string in input_line_pointer into a floating point constant
956 of type TYPE, and store the appropriate bytes in *LITP. The number
957 of LITTLENUMS emitted is stored in *SIZEP. An error message is
958 returned, or NULL on OK. */
960 /* Equal to MAX_PRECISION in atof-ieee.c */
961 #define MAX_LITTLENUMS 6
963 extern char *vax_md_atof
PARAMS ((int, char *, int *));
966 md_atof (type
, litP
, sizeP
)
972 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
973 LITTLENUM_TYPE
*wordP
;
980 /* VAX md_atof doesn't like "G" for some reason. */
984 return vax_md_atof (type
, litP
, sizeP
);
1007 return _("Bad call to MD_ATOF()");
1009 t
= atof_ieee (input_line_pointer
, type
, words
);
1011 input_line_pointer
= t
;
1012 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
1014 for (wordP
= words
+ prec
- 1; prec
--;)
1016 md_number_to_chars (litP
, (long) (*wordP
--), sizeof (LITTLENUM_TYPE
));
1017 litP
+= sizeof (LITTLENUM_TYPE
);
1023 /* Take care of the target-specific command-line options. */
1026 md_parse_option (c
, arg
)
1033 alpha_nofloats_on
= 1;
1037 alpha_addr32_on
= 1;
1045 g_switch_value
= atoi (arg
);
1050 const struct cpu_type
*p
;
1051 for (p
= cpu_types
; p
->name
; ++p
)
1052 if (strcmp (arg
, p
->name
) == 0)
1054 alpha_target_name
= p
->name
, alpha_target
= p
->flags
;
1057 as_warn (_("Unknown CPU identifier `%s'"), arg
);
1063 case '+': /* For g++. Hash any name > 63 chars long. */
1064 alpha_flag_hash_long_names
= 1;
1067 case 'H': /* Show new symbol after hash truncation */
1068 alpha_flag_show_after_trunc
= 1;
1071 case 'h': /* for gnu-c/vax compatibility. */
1076 alpha_flag_relax
= 1;
1081 alpha_flag_mdebug
= 1;
1083 case OPTION_NO_MDEBUG
:
1084 alpha_flag_mdebug
= 0;
1095 /* Print a description of the command-line options that we accept. */
1098 md_show_usage (stream
)
1103 -32addr treat addresses as 32-bit values\n\
1104 -F lack floating point instructions support\n\
1105 -mev4 | -mev45 | -mev5 | -mev56 | -mpca56 | -mev6 | -mall\n\
1106 specify variant of Alpha architecture\n\
1107 -m21064 | -m21066 | -m21164 | -m21164a | -m21164pc | -m21264\n\
1108 these variants include PALcode opcodes\n"),
1113 -+ hash encode (don't truncate) names longer than 64 characters\n\
1114 -H show new symbol after hash truncation\n"),
1119 /* Decide from what point a pc-relative relocation is relative to,
1120 relative to the pc-relative fixup. Er, relatively speaking. */
1123 md_pcrel_from (fixP
)
1126 valueT addr
= fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
1127 switch (fixP
->fx_r_type
)
1129 case BFD_RELOC_ALPHA_GPDISP
:
1130 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1131 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1134 return fixP
->fx_size
+ addr
;
1138 /* Attempt to simplify or even eliminate a fixup. The return value is
1139 ignored; perhaps it was once meaningful, but now it is historical.
1140 To indicate that a fixup has been eliminated, set fixP->fx_done.
1142 For ELF, here it is that we transform the GPDISP_HI16 reloc we used
1143 internally into the GPDISP reloc used externally. We had to do
1144 this so that we'd have the GPDISP_LO16 reloc as a tag to compute
1145 the distance to the "lda" instruction for setting the addend to
1149 md_apply_fix3 (fixP
, valP
, seg
)
1154 char * const fixpos
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
1155 valueT value
= * valP
;
1156 unsigned image
, size
;
1158 switch (fixP
->fx_r_type
)
1160 /* The GPDISP relocations are processed internally with a symbol
1161 referring to the current function; we need to drop in a value
1162 which, when added to the address of the start of the function,
1163 gives the desired GP. */
1164 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1166 fixS
*next
= fixP
->fx_next
;
1168 /* With user-specified !gpdisp relocations, we can be missing
1169 the matching LO16 reloc. We will have already issued an
1172 fixP
->fx_offset
= (next
->fx_frag
->fr_address
+ next
->fx_where
1173 - fixP
->fx_frag
->fr_address
- fixP
->fx_where
);
1175 value
= (value
- sign_extend_16 (value
)) >> 16;
1178 fixP
->fx_r_type
= BFD_RELOC_ALPHA_GPDISP
;
1182 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1183 value
= sign_extend_16 (value
);
1184 fixP
->fx_offset
= 0;
1190 fixP
->fx_addsy
= section_symbol (seg
);
1191 md_number_to_chars (fixpos
, value
, 2);
1196 fixP
->fx_r_type
= BFD_RELOC_16_PCREL
;
1201 fixP
->fx_r_type
= BFD_RELOC_32_PCREL
;
1206 fixP
->fx_r_type
= BFD_RELOC_64_PCREL
;
1209 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
1211 md_number_to_chars (fixpos
, value
, size
);
1217 case BFD_RELOC_GPREL32
:
1218 assert (fixP
->fx_subsy
== alpha_gp_symbol
);
1220 /* FIXME: inherited this obliviousness of `value' -- why? */
1221 md_number_to_chars (fixpos
, -alpha_gp_value
, 4);
1224 case BFD_RELOC_GPREL32
:
1226 case BFD_RELOC_GPREL16
:
1227 case BFD_RELOC_ALPHA_GPREL_HI16
:
1228 case BFD_RELOC_ALPHA_GPREL_LO16
:
1231 case BFD_RELOC_23_PCREL_S2
:
1232 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
1234 image
= bfd_getl32 (fixpos
);
1235 image
= (image
& ~0x1FFFFF) | ((value
>> 2) & 0x1FFFFF);
1240 case BFD_RELOC_ALPHA_HINT
:
1241 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
1243 image
= bfd_getl32 (fixpos
);
1244 image
= (image
& ~0x3FFF) | ((value
>> 2) & 0x3FFF);
1250 case BFD_RELOC_ALPHA_BRSGP
:
1251 case BFD_RELOC_ALPHA_TLSGD
:
1252 case BFD_RELOC_ALPHA_TLSLDM
:
1253 case BFD_RELOC_ALPHA_GOTDTPREL16
:
1254 case BFD_RELOC_ALPHA_DTPREL_HI16
:
1255 case BFD_RELOC_ALPHA_DTPREL_LO16
:
1256 case BFD_RELOC_ALPHA_DTPREL16
:
1257 case BFD_RELOC_ALPHA_GOTTPREL16
:
1258 case BFD_RELOC_ALPHA_TPREL_HI16
:
1259 case BFD_RELOC_ALPHA_TPREL_LO16
:
1260 case BFD_RELOC_ALPHA_TPREL16
:
1265 case BFD_RELOC_ALPHA_LITERAL
:
1266 md_number_to_chars (fixpos
, value
, 2);
1269 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1270 case BFD_RELOC_ALPHA_LITUSE
:
1271 case BFD_RELOC_ALPHA_LINKAGE
:
1272 case BFD_RELOC_ALPHA_CODEADDR
:
1275 case BFD_RELOC_VTABLE_INHERIT
:
1276 case BFD_RELOC_VTABLE_ENTRY
:
1281 const struct alpha_operand
*operand
;
1283 if ((int) fixP
->fx_r_type
>= 0)
1284 as_fatal (_("unhandled relocation type %s"),
1285 bfd_get_reloc_code_name (fixP
->fx_r_type
));
1287 assert (-(int) fixP
->fx_r_type
< (int) alpha_num_operands
);
1288 operand
= &alpha_operands
[-(int) fixP
->fx_r_type
];
1290 /* The rest of these fixups only exist internally during symbol
1291 resolution and have no representation in the object file.
1292 Therefore they must be completely resolved as constants. */
1294 if (fixP
->fx_addsy
!= 0
1295 && S_GET_SEGMENT (fixP
->fx_addsy
) != absolute_section
)
1296 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
1297 _("non-absolute expression in constant field"));
1299 image
= bfd_getl32 (fixpos
);
1300 image
= insert_operand (image
, operand
, (offsetT
) value
,
1301 fixP
->fx_file
, fixP
->fx_line
);
1306 if (fixP
->fx_addsy
!= 0 || fixP
->fx_pcrel
!= 0)
1310 as_warn_where (fixP
->fx_file
, fixP
->fx_line
,
1311 _("type %d reloc done?\n"), (int) fixP
->fx_r_type
);
1316 md_number_to_chars (fixpos
, image
, 4);
1322 /* Look for a register name in the given symbol. */
1325 md_undefined_symbol (name
)
1330 int is_float
= 0, num
;
1335 if (name
[1] == 'p' && name
[2] == '\0')
1336 return alpha_register_table
[AXP_REG_FP
];
1341 if (!ISDIGIT (*++name
))
1345 case '0': case '1': case '2': case '3': case '4':
1346 case '5': case '6': case '7': case '8': case '9':
1347 if (name
[1] == '\0')
1348 num
= name
[0] - '0';
1349 else if (name
[0] != '0' && ISDIGIT (name
[1]) && name
[2] == '\0')
1351 num
= (name
[0] - '0') * 10 + name
[1] - '0';
1358 if (!alpha_noat_on
&& (num
+ is_float
) == AXP_REG_AT
)
1359 as_warn (_("Used $at without \".set noat\""));
1360 return alpha_register_table
[num
+ is_float
];
1363 if (name
[1] == 't' && name
[2] == '\0')
1366 as_warn (_("Used $at without \".set noat\""));
1367 return alpha_register_table
[AXP_REG_AT
];
1372 if (name
[1] == 'p' && name
[2] == '\0')
1373 return alpha_register_table
[alpha_gp_register
];
1377 if (name
[1] == 'p' && name
[2] == '\0')
1378 return alpha_register_table
[AXP_REG_SP
];
1386 /* @@@ Magic ECOFF bits. */
1389 alpha_frob_ecoff_data ()
1392 /* $zero and $f31 are read-only */
1393 alpha_gprmask
&= ~1;
1394 alpha_fprmask
&= ~1;
1398 /* Hook to remember a recently defined label so that the auto-align
1399 code can adjust the symbol after we know what alignment will be
1403 alpha_define_label (sym
)
1406 alpha_insn_label
= sym
;
1409 /* If we have a BRSGP reloc to a local symbol, adjust it to BRADDR and
1410 let it get resolved at assembly time. */
1413 alpha_validate_fix (f
)
1420 if (f
->fx_r_type
!= BFD_RELOC_ALPHA_BRSGP
)
1423 if (! S_IS_DEFINED (f
->fx_addsy
))
1426 switch (S_GET_OTHER (f
->fx_addsy
) & STO_ALPHA_STD_GPLOAD
)
1428 case STO_ALPHA_NOPV
:
1430 case STO_ALPHA_STD_GPLOAD
:
1434 if (S_IS_LOCAL (f
->fx_addsy
))
1437 name
= S_GET_NAME (f
->fx_addsy
);
1438 as_bad_where (f
->fx_file
, f
->fx_line
,
1439 _("!samegp reloc against symbol without .prologue: %s"),
1444 if (! (S_IS_EXTERN (f
->fx_addsy
) || S_IS_WEAK (f
->fx_addsy
)))
1446 f
->fx_r_type
= BFD_RELOC_23_PCREL_S2
;
1447 f
->fx_offset
+= offset
;
1452 /* Return true if we must always emit a reloc for a type and false if
1453 there is some hope of resolving it at assembly time. */
1456 alpha_force_relocation (f
)
1459 if (alpha_flag_relax
)
1462 switch (f
->fx_r_type
)
1464 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1465 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1466 case BFD_RELOC_ALPHA_GPDISP
:
1467 case BFD_RELOC_ALPHA_LITERAL
:
1468 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1469 case BFD_RELOC_ALPHA_LITUSE
:
1470 case BFD_RELOC_GPREL16
:
1471 case BFD_RELOC_GPREL32
:
1472 case BFD_RELOC_ALPHA_GPREL_HI16
:
1473 case BFD_RELOC_ALPHA_GPREL_LO16
:
1474 case BFD_RELOC_ALPHA_LINKAGE
:
1475 case BFD_RELOC_ALPHA_CODEADDR
:
1476 case BFD_RELOC_ALPHA_BRSGP
:
1477 case BFD_RELOC_VTABLE_INHERIT
:
1478 case BFD_RELOC_VTABLE_ENTRY
:
1479 case BFD_RELOC_ALPHA_TLSGD
:
1480 case BFD_RELOC_ALPHA_TLSLDM
:
1481 case BFD_RELOC_ALPHA_GOTDTPREL16
:
1482 case BFD_RELOC_ALPHA_DTPREL_HI16
:
1483 case BFD_RELOC_ALPHA_DTPREL_LO16
:
1484 case BFD_RELOC_ALPHA_DTPREL16
:
1485 case BFD_RELOC_ALPHA_GOTTPREL16
:
1486 case BFD_RELOC_ALPHA_TPREL_HI16
:
1487 case BFD_RELOC_ALPHA_TPREL_LO16
:
1488 case BFD_RELOC_ALPHA_TPREL16
:
1491 case BFD_RELOC_23_PCREL_S2
:
1494 case BFD_RELOC_ALPHA_HINT
:
1502 /* Return true if we can partially resolve a relocation now. */
1505 alpha_fix_adjustable (f
)
1509 /* Prevent all adjustments to global symbols */
1510 if (S_IS_EXTERN (f
->fx_addsy
) || S_IS_WEAK (f
->fx_addsy
))
1514 /* Are there any relocation types for which we must generate a reloc
1515 but we can adjust the values contained within it? */
1516 switch (f
->fx_r_type
)
1518 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1519 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1520 case BFD_RELOC_ALPHA_GPDISP
:
1521 case BFD_RELOC_ALPHA_BRSGP
:
1524 case BFD_RELOC_ALPHA_LITERAL
:
1525 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1526 case BFD_RELOC_ALPHA_LITUSE
:
1527 case BFD_RELOC_ALPHA_LINKAGE
:
1528 case BFD_RELOC_ALPHA_CODEADDR
:
1531 case BFD_RELOC_VTABLE_ENTRY
:
1532 case BFD_RELOC_VTABLE_INHERIT
:
1535 case BFD_RELOC_GPREL16
:
1536 case BFD_RELOC_GPREL32
:
1537 case BFD_RELOC_ALPHA_GPREL_HI16
:
1538 case BFD_RELOC_ALPHA_GPREL_LO16
:
1539 case BFD_RELOC_23_PCREL_S2
:
1542 case BFD_RELOC_ALPHA_HINT
:
1545 case BFD_RELOC_ALPHA_TLSGD
:
1546 case BFD_RELOC_ALPHA_TLSLDM
:
1547 case BFD_RELOC_ALPHA_GOTDTPREL16
:
1548 case BFD_RELOC_ALPHA_DTPREL_HI16
:
1549 case BFD_RELOC_ALPHA_DTPREL_LO16
:
1550 case BFD_RELOC_ALPHA_DTPREL16
:
1551 case BFD_RELOC_ALPHA_GOTTPREL16
:
1552 case BFD_RELOC_ALPHA_TPREL_HI16
:
1553 case BFD_RELOC_ALPHA_TPREL_LO16
:
1554 case BFD_RELOC_ALPHA_TPREL16
:
1555 /* ??? No idea why we can't return a reference to .tbss+10, but
1556 we're preventing this in the other assemblers. Follow for now. */
1565 /* Generate the BFD reloc to be stuck in the object file from the
1566 fixup used internally in the assembler. */
1569 tc_gen_reloc (sec
, fixp
)
1570 asection
*sec ATTRIBUTE_UNUSED
;
1575 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
1576 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
1577 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
1578 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
1580 /* Make sure none of our internal relocations make it this far.
1581 They'd better have been fully resolved by this point. */
1582 assert ((int) fixp
->fx_r_type
> 0);
1584 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
1585 if (reloc
->howto
== NULL
)
1587 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1588 _("cannot represent `%s' relocation in object file"),
1589 bfd_get_reloc_code_name (fixp
->fx_r_type
));
1593 if (!fixp
->fx_pcrel
!= !reloc
->howto
->pc_relative
)
1595 as_fatal (_("internal error? cannot generate `%s' relocation"),
1596 bfd_get_reloc_code_name (fixp
->fx_r_type
));
1598 assert (!fixp
->fx_pcrel
== !reloc
->howto
->pc_relative
);
1601 if (fixp
->fx_r_type
== BFD_RELOC_ALPHA_LITERAL
)
1603 /* fake out bfd_perform_relocation. sigh */
1604 reloc
->addend
= -alpha_gp_value
;
1609 reloc
->addend
= fixp
->fx_offset
;
1612 * Ohhh, this is ugly. The problem is that if this is a local global
1613 * symbol, the relocation will entirely be performed at link time, not
1614 * at assembly time. bfd_perform_reloc doesn't know about this sort
1615 * of thing, and as a result we need to fake it out here.
1617 if ((S_IS_EXTERN (fixp
->fx_addsy
) || S_IS_WEAK (fixp
->fx_addsy
)
1618 || (S_GET_SEGMENT (fixp
->fx_addsy
)->flags
& SEC_MERGE
)
1619 || (S_GET_SEGMENT (fixp
->fx_addsy
)->flags
& SEC_THREAD_LOCAL
))
1620 && !S_IS_COMMON (fixp
->fx_addsy
))
1621 reloc
->addend
-= symbol_get_bfdsym (fixp
->fx_addsy
)->value
;
1628 /* Parse a register name off of the input_line and return a register
1629 number. Gets md_undefined_symbol above to do the register name
1632 Only called as a part of processing the ECOFF .frame directive. */
1635 tc_get_register (frame
)
1636 int frame ATTRIBUTE_UNUSED
;
1638 int framereg
= AXP_REG_SP
;
1641 if (*input_line_pointer
== '$')
1643 char *s
= input_line_pointer
;
1644 char c
= get_symbol_end ();
1645 symbolS
*sym
= md_undefined_symbol (s
);
1647 *strchr (s
, '\0') = c
;
1648 if (sym
&& (framereg
= S_GET_VALUE (sym
)) <= 31)
1651 as_warn (_("frame reg expected, using $%d."), framereg
);
1654 note_gpreg (framereg
);
1658 /* This is called before the symbol table is processed. In order to
1659 work with gcc when using mips-tfile, we must keep all local labels.
1660 However, in other cases, we want to discard them. If we were
1661 called with -g, but we didn't see any debugging information, it may
1662 mean that gcc is smuggling debugging information through to
1663 mips-tfile, in which case we must generate all local labels. */
1668 alpha_frob_file_before_adjust ()
1670 if (alpha_debug
!= 0
1671 && ! ecoff_debugging_seen
)
1672 flag_keep_locals
= 1;
1675 #endif /* OBJ_ECOFF */
1677 static struct alpha_reloc_tag
*
1678 get_alpha_reloc_tag (sequence
)
1681 char buffer
[ALPHA_RELOC_DIGITS
];
1682 struct alpha_reloc_tag
*info
;
1684 sprintf (buffer
, "!%ld", sequence
);
1686 info
= (struct alpha_reloc_tag
*) hash_find (alpha_literal_hash
, buffer
);
1689 size_t len
= strlen (buffer
);
1692 info
= (struct alpha_reloc_tag
*)
1693 xcalloc (sizeof (struct alpha_reloc_tag
) + len
, 1);
1695 info
->segment
= now_seg
;
1696 info
->sequence
= sequence
;
1697 strcpy (info
->string
, buffer
);
1698 errmsg
= hash_insert (alpha_literal_hash
, info
->string
, (PTR
) info
);
1706 /* Before the relocations are written, reorder them, so that user
1707 supplied !lituse relocations follow the appropriate !literal
1708 relocations, and similarly for !gpdisp relocations. */
1711 alpha_adjust_symtab ()
1713 if (alpha_literal_hash
)
1714 bfd_map_over_sections (stdoutput
, alpha_adjust_symtab_relocs
, NULL
);
1718 alpha_adjust_symtab_relocs (abfd
, sec
, ptr
)
1719 bfd
*abfd ATTRIBUTE_UNUSED
;
1721 PTR ptr ATTRIBUTE_UNUSED
;
1723 segment_info_type
*seginfo
= seg_info (sec
);
1729 /* If seginfo is NULL, we did not create this section; don't do
1730 anything with it. By using a pointer to a pointer, we can update
1731 the links in place. */
1732 if (seginfo
== NULL
)
1735 /* If there are no relocations, skip the section. */
1736 if (! seginfo
->fix_root
)
1739 /* First rebuild the fixup chain without the expicit lituse and
1740 gpdisp_lo16 relocs. */
1741 prevP
= &seginfo
->fix_root
;
1742 for (fixp
= seginfo
->fix_root
; fixp
; fixp
= next
)
1744 next
= fixp
->fx_next
;
1745 fixp
->fx_next
= (fixS
*) 0;
1747 switch (fixp
->fx_r_type
)
1749 case BFD_RELOC_ALPHA_LITUSE
:
1750 if (fixp
->tc_fix_data
.info
->n_master
== 0)
1751 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1752 _("No !literal!%ld was found"),
1753 fixp
->tc_fix_data
.info
->sequence
);
1754 if (fixp
->fx_offset
== LITUSE_ALPHA_TLSGD
)
1756 if (! fixp
->tc_fix_data
.info
->saw_tlsgd
)
1757 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1758 _("No !tlsgd!%ld was found"),
1759 fixp
->tc_fix_data
.info
->sequence
);
1761 else if (fixp
->fx_offset
== LITUSE_ALPHA_TLSLDM
)
1763 if (! fixp
->tc_fix_data
.info
->saw_tlsldm
)
1764 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1765 _("No !tlsldm!%ld was found"),
1766 fixp
->tc_fix_data
.info
->sequence
);
1770 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1771 if (fixp
->tc_fix_data
.info
->n_master
== 0)
1772 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1773 _("No ldah !gpdisp!%ld was found"),
1774 fixp
->tc_fix_data
.info
->sequence
);
1777 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1778 if (fixp
->tc_fix_data
.info
->saw_tlsgd
1779 || fixp
->tc_fix_data
.info
->saw_tlsldm
)
1785 prevP
= &fixp
->fx_next
;
1790 /* Go back and re-chain dependent relocations. They are currently
1791 linked through the next_reloc field in reverse order, so as we
1792 go through the next_reloc chain, we effectively reverse the chain
1795 Except if there is more than one !literal for a given sequence
1796 number. In that case, the programmer and/or compiler is not sure
1797 how control flows from literal to lituse, and we can't be sure to
1798 get the relaxation correct.
1800 ??? Well, actually we could, if there are enough lituses such that
1801 we can make each literal have at least one of each lituse type
1802 present. Not implemented.
1804 Also suppress the optimization if the !literals/!lituses are spread
1805 in different segments. This can happen with "intersting" uses of
1806 inline assembly; examples are present in the Linux kernel semaphores. */
1808 for (fixp
= seginfo
->fix_root
; fixp
; fixp
= next
)
1810 next
= fixp
->fx_next
;
1811 switch (fixp
->fx_r_type
)
1813 case BFD_RELOC_ALPHA_TLSGD
:
1814 case BFD_RELOC_ALPHA_TLSLDM
:
1815 if (!fixp
->tc_fix_data
.info
)
1817 if (fixp
->tc_fix_data
.info
->n_master
== 0)
1819 else if (fixp
->tc_fix_data
.info
->n_master
> 1)
1821 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1822 _("too many !literal!%ld for %s"),
1823 fixp
->tc_fix_data
.info
->sequence
,
1824 (fixp
->fx_r_type
== BFD_RELOC_ALPHA_TLSGD
1825 ? "!tlsgd" : "!tlsldm"));
1829 fixp
->tc_fix_data
.info
->master
->fx_next
= fixp
->fx_next
;
1830 fixp
->fx_next
= fixp
->tc_fix_data
.info
->master
;
1831 fixp
= fixp
->fx_next
;
1834 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1835 if (fixp
->tc_fix_data
.info
->n_master
== 1
1836 && ! fixp
->tc_fix_data
.info
->multi_section_p
)
1838 for (slave
= fixp
->tc_fix_data
.info
->slaves
;
1839 slave
!= (fixS
*) 0;
1840 slave
= slave
->tc_fix_data
.next_reloc
)
1842 slave
->fx_next
= fixp
->fx_next
;
1843 fixp
->fx_next
= slave
;
1848 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1849 if (fixp
->tc_fix_data
.info
->n_slaves
== 0)
1850 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1851 _("No lda !gpdisp!%ld was found"),
1852 fixp
->tc_fix_data
.info
->sequence
);
1855 slave
= fixp
->tc_fix_data
.info
->slaves
;
1856 slave
->fx_next
= next
;
1857 fixp
->fx_next
= slave
;
1869 debug_exp (tok
, ntok
)
1875 fprintf (stderr
, "debug_exp: %d tokens", ntok
);
1876 for (i
= 0; i
< ntok
; i
++)
1878 expressionS
*t
= &tok
[i
];
1882 default: name
= "unknown"; break;
1883 case O_illegal
: name
= "O_illegal"; break;
1884 case O_absent
: name
= "O_absent"; break;
1885 case O_constant
: name
= "O_constant"; break;
1886 case O_symbol
: name
= "O_symbol"; break;
1887 case O_symbol_rva
: name
= "O_symbol_rva"; break;
1888 case O_register
: name
= "O_register"; break;
1889 case O_big
: name
= "O_big"; break;
1890 case O_uminus
: name
= "O_uminus"; break;
1891 case O_bit_not
: name
= "O_bit_not"; break;
1892 case O_logical_not
: name
= "O_logical_not"; break;
1893 case O_multiply
: name
= "O_multiply"; break;
1894 case O_divide
: name
= "O_divide"; break;
1895 case O_modulus
: name
= "O_modulus"; break;
1896 case O_left_shift
: name
= "O_left_shift"; break;
1897 case O_right_shift
: name
= "O_right_shift"; break;
1898 case O_bit_inclusive_or
: name
= "O_bit_inclusive_or"; break;
1899 case O_bit_or_not
: name
= "O_bit_or_not"; break;
1900 case O_bit_exclusive_or
: name
= "O_bit_exclusive_or"; break;
1901 case O_bit_and
: name
= "O_bit_and"; break;
1902 case O_add
: name
= "O_add"; break;
1903 case O_subtract
: name
= "O_subtract"; break;
1904 case O_eq
: name
= "O_eq"; break;
1905 case O_ne
: name
= "O_ne"; break;
1906 case O_lt
: name
= "O_lt"; break;
1907 case O_le
: name
= "O_le"; break;
1908 case O_ge
: name
= "O_ge"; break;
1909 case O_gt
: name
= "O_gt"; break;
1910 case O_logical_and
: name
= "O_logical_and"; break;
1911 case O_logical_or
: name
= "O_logical_or"; break;
1912 case O_index
: name
= "O_index"; break;
1913 case O_pregister
: name
= "O_pregister"; break;
1914 case O_cpregister
: name
= "O_cpregister"; break;
1915 case O_literal
: name
= "O_literal"; break;
1916 case O_lituse_addr
: name
= "O_lituse_addr"; break;
1917 case O_lituse_base
: name
= "O_lituse_base"; break;
1918 case O_lituse_bytoff
: name
= "O_lituse_bytoff"; break;
1919 case O_lituse_jsr
: name
= "O_lituse_jsr"; break;
1920 case O_lituse_tlsgd
: name
= "O_lituse_tlsgd"; break;
1921 case O_lituse_tlsldm
: name
= "O_lituse_tlsldm"; break;
1922 case O_gpdisp
: name
= "O_gpdisp"; break;
1923 case O_gprelhigh
: name
= "O_gprelhigh"; break;
1924 case O_gprellow
: name
= "O_gprellow"; break;
1925 case O_gprel
: name
= "O_gprel"; break;
1926 case O_samegp
: name
= "O_samegp"; break;
1927 case O_tlsgd
: name
= "O_tlsgd"; break;
1928 case O_tlsldm
: name
= "O_tlsldm"; break;
1929 case O_gotdtprel
: name
= "O_gotdtprel"; break;
1930 case O_dtprelhi
: name
= "O_dtprelhi"; break;
1931 case O_dtprello
: name
= "O_dtprello"; break;
1932 case O_dtprel
: name
= "O_dtprel"; break;
1933 case O_gottprel
: name
= "O_gottprel"; break;
1934 case O_tprelhi
: name
= "O_tprelhi"; break;
1935 case O_tprello
: name
= "O_tprello"; break;
1936 case O_tprel
: name
= "O_tprel"; break;
1939 fprintf (stderr
, ", %s(%s, %s, %d)", name
,
1940 (t
->X_add_symbol
) ? S_GET_NAME (t
->X_add_symbol
) : "--",
1941 (t
->X_op_symbol
) ? S_GET_NAME (t
->X_op_symbol
) : "--",
1942 (int) t
->X_add_number
);
1944 fprintf (stderr
, "\n");
1949 /* Parse the arguments to an opcode. */
1952 tokenize_arguments (str
, tok
, ntok
)
1957 expressionS
*end_tok
= tok
+ ntok
;
1958 char *old_input_line_pointer
;
1959 int saw_comma
= 0, saw_arg
= 0;
1961 expressionS
*orig_tok
= tok
;
1964 const struct alpha_reloc_op_tag
*r
;
1967 int reloc_found_p
= 0;
1969 memset (tok
, 0, sizeof (*tok
) * ntok
);
1971 /* Save and restore input_line_pointer around this function */
1972 old_input_line_pointer
= input_line_pointer
;
1973 input_line_pointer
= str
;
1976 /* ??? Wrest control of ! away from the regular expression parser. */
1977 is_end_of_line
[(unsigned char) '!'] = 1;
1980 while (tok
< end_tok
&& *input_line_pointer
)
1983 switch (*input_line_pointer
)
1990 /* A relocation operand can be placed after the normal operand on an
1991 assembly language statement, and has the following form:
1992 !relocation_type!sequence_number. */
1994 { /* only support one relocation op per insn */
1995 as_bad (_("More than one relocation op per insn"));
2002 ++input_line_pointer
;
2004 p
= input_line_pointer
;
2005 c
= get_symbol_end ();
2007 /* Parse !relocation_type */
2008 len
= input_line_pointer
- p
;
2011 as_bad (_("No relocation operand"));
2015 r
= &alpha_reloc_op
[0];
2016 for (i
= alpha_num_reloc_op
- 1; i
>= 0; i
--, r
++)
2017 if (len
== r
->length
&& memcmp (p
, r
->name
, len
) == 0)
2021 as_bad (_("Unknown relocation operand: !%s"), p
);
2025 *input_line_pointer
= c
;
2027 if (*input_line_pointer
!= '!')
2031 as_bad (_("no sequence number after !%s"), p
);
2035 tok
->X_add_number
= 0;
2041 as_bad (_("!%s does not use a sequence number"), p
);
2045 input_line_pointer
++;
2047 /* Parse !sequence_number */
2049 if (tok
->X_op
!= O_constant
|| tok
->X_add_number
<= 0)
2051 as_bad (_("Bad sequence number: !%s!%s"),
2052 r
->name
, input_line_pointer
);
2061 #endif /* RELOC_OP_P */
2064 ++input_line_pointer
;
2065 if (saw_comma
|| !saw_arg
)
2072 char *hold
= input_line_pointer
++;
2074 /* First try for parenthesized register ... */
2076 if (*input_line_pointer
== ')' && tok
->X_op
== O_register
)
2078 tok
->X_op
= (saw_comma
? O_cpregister
: O_pregister
);
2081 ++input_line_pointer
;
2086 /* ... then fall through to plain expression */
2087 input_line_pointer
= hold
;
2091 if (saw_arg
&& !saw_comma
)
2095 if (tok
->X_op
== O_illegal
|| tok
->X_op
== O_absent
)
2108 input_line_pointer
= old_input_line_pointer
;
2111 debug_exp (orig_tok
, ntok
- (end_tok
- tok
));
2114 is_end_of_line
[(unsigned char) '!'] = 0;
2117 return ntok
- (end_tok
- tok
);
2121 is_end_of_line
[(unsigned char) '!'] = 0;
2123 input_line_pointer
= old_input_line_pointer
;
2124 return TOKENIZE_ERROR
;
2128 is_end_of_line
[(unsigned char) '!'] = 0;
2130 input_line_pointer
= old_input_line_pointer
;
2131 return TOKENIZE_ERROR_REPORT
;
2134 /* Search forward through all variants of an opcode looking for a
2137 static const struct alpha_opcode
*
2138 find_opcode_match (first_opcode
, tok
, pntok
, pcpumatch
)
2139 const struct alpha_opcode
*first_opcode
;
2140 const expressionS
*tok
;
2144 const struct alpha_opcode
*opcode
= first_opcode
;
2146 int got_cpu_match
= 0;
2150 const unsigned char *opidx
;
2153 /* Don't match opcodes that don't exist on this architecture */
2154 if (!(opcode
->flags
& alpha_target
))
2159 for (opidx
= opcode
->operands
; *opidx
; ++opidx
)
2161 const struct alpha_operand
*operand
= &alpha_operands
[*opidx
];
2163 /* only take input from real operands */
2164 if (operand
->flags
& AXP_OPERAND_FAKE
)
2167 /* when we expect input, make sure we have it */
2170 if ((operand
->flags
& AXP_OPERAND_OPTIONAL_MASK
) == 0)
2175 /* match operand type with expression type */
2176 switch (operand
->flags
& AXP_OPERAND_TYPECHECK_MASK
)
2178 case AXP_OPERAND_IR
:
2179 if (tok
[tokidx
].X_op
!= O_register
2180 || !is_ir_num (tok
[tokidx
].X_add_number
))
2183 case AXP_OPERAND_FPR
:
2184 if (tok
[tokidx
].X_op
!= O_register
2185 || !is_fpr_num (tok
[tokidx
].X_add_number
))
2188 case AXP_OPERAND_IR
| AXP_OPERAND_PARENS
:
2189 if (tok
[tokidx
].X_op
!= O_pregister
2190 || !is_ir_num (tok
[tokidx
].X_add_number
))
2193 case AXP_OPERAND_IR
| AXP_OPERAND_PARENS
| AXP_OPERAND_COMMA
:
2194 if (tok
[tokidx
].X_op
!= O_cpregister
2195 || !is_ir_num (tok
[tokidx
].X_add_number
))
2199 case AXP_OPERAND_RELATIVE
:
2200 case AXP_OPERAND_SIGNED
:
2201 case AXP_OPERAND_UNSIGNED
:
2202 switch (tok
[tokidx
].X_op
)
2217 /* everything else should have been fake */
2223 /* possible match -- did we use all of our input? */
2232 while (++opcode
- alpha_opcodes
< alpha_num_opcodes
2233 && !strcmp (opcode
->name
, first_opcode
->name
));
2236 *pcpumatch
= got_cpu_match
;
2241 /* Search forward through all variants of a macro looking for a syntax
2244 static const struct alpha_macro
*
2245 find_macro_match (first_macro
, tok
, pntok
)
2246 const struct alpha_macro
*first_macro
;
2247 const expressionS
*tok
;
2250 const struct alpha_macro
*macro
= first_macro
;
2255 const enum alpha_macro_arg
*arg
= macro
->argsets
;
2269 /* index register */
2271 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_register
2272 || !is_ir_num (tok
[tokidx
].X_add_number
))
2277 /* parenthesized index register */
2279 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_pregister
2280 || !is_ir_num (tok
[tokidx
].X_add_number
))
2285 /* optional parenthesized index register */
2287 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_pregister
2288 && is_ir_num (tok
[tokidx
].X_add_number
))
2292 /* leading comma with a parenthesized index register */
2294 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_cpregister
2295 || !is_ir_num (tok
[tokidx
].X_add_number
))
2300 /* floating point register */
2302 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_register
2303 || !is_fpr_num (tok
[tokidx
].X_add_number
))
2308 /* normal expression */
2312 switch (tok
[tokidx
].X_op
)
2321 case O_lituse_bytoff
:
2337 while (*arg
!= MACRO_EOA
)
2345 while (++macro
- alpha_macros
< alpha_num_macros
2346 && !strcmp (macro
->name
, first_macro
->name
));
2351 /* Insert an operand value into an instruction. */
2354 insert_operand (insn
, operand
, val
, file
, line
)
2356 const struct alpha_operand
*operand
;
2361 if (operand
->bits
!= 32 && !(operand
->flags
& AXP_OPERAND_NOOVERFLOW
))
2365 if (operand
->flags
& AXP_OPERAND_SIGNED
)
2367 max
= (1 << (operand
->bits
- 1)) - 1;
2368 min
= -(1 << (operand
->bits
- 1));
2372 max
= (1 << operand
->bits
) - 1;
2376 if (val
< min
|| val
> max
)
2379 _("operand out of range (%s not between %d and %d)");
2380 char buf
[sizeof (val
) * 3 + 2];
2382 sprint_value (buf
, val
);
2384 as_warn_where (file
, line
, err
, buf
, min
, max
);
2386 as_warn (err
, buf
, min
, max
);
2390 if (operand
->insert
)
2392 const char *errmsg
= NULL
;
2394 insn
= (*operand
->insert
) (insn
, val
, &errmsg
);
2399 insn
|= ((val
& ((1 << operand
->bits
) - 1)) << operand
->shift
);
2405 * Turn an opcode description and a set of arguments into
2406 * an instruction and a fixup.
2410 assemble_insn (opcode
, tok
, ntok
, insn
, reloc
)
2411 const struct alpha_opcode
*opcode
;
2412 const expressionS
*tok
;
2414 struct alpha_insn
*insn
;
2415 bfd_reloc_code_real_type reloc
;
2417 const struct alpha_operand
*reloc_operand
= NULL
;
2418 const expressionS
*reloc_exp
= NULL
;
2419 const unsigned char *argidx
;
2423 memset (insn
, 0, sizeof (*insn
));
2424 image
= opcode
->opcode
;
2426 for (argidx
= opcode
->operands
; *argidx
; ++argidx
)
2428 const struct alpha_operand
*operand
= &alpha_operands
[*argidx
];
2429 const expressionS
*t
= (const expressionS
*) 0;
2431 if (operand
->flags
& AXP_OPERAND_FAKE
)
2433 /* fake operands take no value and generate no fixup */
2434 image
= insert_operand (image
, operand
, 0, NULL
, 0);
2440 switch (operand
->flags
& AXP_OPERAND_OPTIONAL_MASK
)
2442 case AXP_OPERAND_DEFAULT_FIRST
:
2445 case AXP_OPERAND_DEFAULT_SECOND
:
2448 case AXP_OPERAND_DEFAULT_ZERO
:
2450 static expressionS zero_exp
;
2452 zero_exp
.X_op
= O_constant
;
2453 zero_exp
.X_unsigned
= 1;
2468 image
= insert_operand (image
, operand
, regno (t
->X_add_number
),
2473 image
= insert_operand (image
, operand
, t
->X_add_number
, NULL
, 0);
2474 assert (reloc_operand
== NULL
);
2475 reloc_operand
= operand
;
2480 /* This is only 0 for fields that should contain registers,
2481 which means this pattern shouldn't have matched. */
2482 if (operand
->default_reloc
== 0)
2485 /* There is one special case for which an insn receives two
2486 relocations, and thus the user-supplied reloc does not
2487 override the operand reloc. */
2488 if (operand
->default_reloc
== BFD_RELOC_ALPHA_HINT
)
2490 struct alpha_fixup
*fixup
;
2492 if (insn
->nfixups
>= MAX_INSN_FIXUPS
)
2493 as_fatal (_("too many fixups"));
2495 fixup
= &insn
->fixups
[insn
->nfixups
++];
2497 fixup
->reloc
= BFD_RELOC_ALPHA_HINT
;
2501 if (reloc
== BFD_RELOC_UNUSED
)
2502 reloc
= operand
->default_reloc
;
2504 assert (reloc_operand
== NULL
);
2505 reloc_operand
= operand
;
2512 if (reloc
!= BFD_RELOC_UNUSED
)
2514 struct alpha_fixup
*fixup
;
2516 if (insn
->nfixups
>= MAX_INSN_FIXUPS
)
2517 as_fatal (_("too many fixups"));
2519 /* ??? My but this is hacky. But the OSF/1 assembler uses the same
2520 relocation tag for both ldah and lda with gpdisp. Choose the
2521 correct internal relocation based on the opcode. */
2522 if (reloc
== BFD_RELOC_ALPHA_GPDISP
)
2524 if (strcmp (opcode
->name
, "ldah") == 0)
2525 reloc
= BFD_RELOC_ALPHA_GPDISP_HI16
;
2526 else if (strcmp (opcode
->name
, "lda") == 0)
2527 reloc
= BFD_RELOC_ALPHA_GPDISP_LO16
;
2529 as_bad (_("invalid relocation for instruction"));
2532 /* If this is a real relocation (as opposed to a lituse hint), then
2533 the relocation width should match the operand width. */
2534 else if (reloc
< BFD_RELOC_UNUSED
)
2536 reloc_howto_type
*reloc_howto
2537 = bfd_reloc_type_lookup (stdoutput
, reloc
);
2538 if (reloc_howto
->bitsize
!= reloc_operand
->bits
)
2540 as_bad (_("invalid relocation for field"));
2545 fixup
= &insn
->fixups
[insn
->nfixups
++];
2547 fixup
->exp
= *reloc_exp
;
2549 fixup
->exp
.X_op
= O_absent
;
2550 fixup
->reloc
= reloc
;
2557 * Actually output an instruction with its fixup.
2562 struct alpha_insn
*insn
;
2567 /* Take care of alignment duties. */
2568 if (alpha_auto_align_on
&& alpha_current_align
< 2)
2569 alpha_align (2, (char *) NULL
, alpha_insn_label
, 0);
2570 if (alpha_current_align
> 2)
2571 alpha_current_align
= 2;
2572 alpha_insn_label
= NULL
;
2574 /* Write out the instruction. */
2576 md_number_to_chars (f
, insn
->insn
, 4);
2579 dwarf2_emit_insn (4);
2582 /* Apply the fixups in order */
2583 for (i
= 0; i
< insn
->nfixups
; ++i
)
2585 const struct alpha_operand
*operand
= (const struct alpha_operand
*) 0;
2586 struct alpha_fixup
*fixup
= &insn
->fixups
[i
];
2587 struct alpha_reloc_tag
*info
= NULL
;
2591 /* Some fixups are only used internally and so have no howto */
2592 if ((int) fixup
->reloc
< 0)
2594 operand
= &alpha_operands
[-(int) fixup
->reloc
];
2596 pcrel
= ((operand
->flags
& AXP_OPERAND_RELATIVE
) != 0);
2598 else if (fixup
->reloc
> BFD_RELOC_UNUSED
2599 || fixup
->reloc
== BFD_RELOC_ALPHA_GPDISP_HI16
2600 || fixup
->reloc
== BFD_RELOC_ALPHA_GPDISP_LO16
)
2607 reloc_howto_type
*reloc_howto
2608 = bfd_reloc_type_lookup (stdoutput
, fixup
->reloc
);
2609 assert (reloc_howto
);
2611 size
= bfd_get_reloc_size (reloc_howto
);
2612 assert (size
>= 1 && size
<= 4);
2614 pcrel
= reloc_howto
->pc_relative
;
2617 fixP
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, size
,
2618 &fixup
->exp
, pcrel
, fixup
->reloc
);
2620 /* Turn off complaints that the addend is too large for some fixups,
2621 and copy in the sequence number for the explicit relocations. */
2622 switch (fixup
->reloc
)
2624 case BFD_RELOC_ALPHA_HINT
:
2625 case BFD_RELOC_GPREL32
:
2626 case BFD_RELOC_GPREL16
:
2627 case BFD_RELOC_ALPHA_GPREL_HI16
:
2628 case BFD_RELOC_ALPHA_GPREL_LO16
:
2629 case BFD_RELOC_ALPHA_GOTDTPREL16
:
2630 case BFD_RELOC_ALPHA_DTPREL_HI16
:
2631 case BFD_RELOC_ALPHA_DTPREL_LO16
:
2632 case BFD_RELOC_ALPHA_DTPREL16
:
2633 case BFD_RELOC_ALPHA_GOTTPREL16
:
2634 case BFD_RELOC_ALPHA_TPREL_HI16
:
2635 case BFD_RELOC_ALPHA_TPREL_LO16
:
2636 case BFD_RELOC_ALPHA_TPREL16
:
2637 fixP
->fx_no_overflow
= 1;
2640 case BFD_RELOC_ALPHA_GPDISP_HI16
:
2641 fixP
->fx_no_overflow
= 1;
2642 fixP
->fx_addsy
= section_symbol (now_seg
);
2643 fixP
->fx_offset
= 0;
2645 info
= get_alpha_reloc_tag (insn
->sequence
);
2646 if (++info
->n_master
> 1)
2647 as_bad (_("too many ldah insns for !gpdisp!%ld"), insn
->sequence
);
2648 if (info
->segment
!= now_seg
)
2649 as_bad (_("both insns for !gpdisp!%ld must be in the same section"),
2651 fixP
->tc_fix_data
.info
= info
;
2654 case BFD_RELOC_ALPHA_GPDISP_LO16
:
2655 fixP
->fx_no_overflow
= 1;
2657 info
= get_alpha_reloc_tag (insn
->sequence
);
2658 if (++info
->n_slaves
> 1)
2659 as_bad (_("too many lda insns for !gpdisp!%ld"), insn
->sequence
);
2660 if (info
->segment
!= now_seg
)
2661 as_bad (_("both insns for !gpdisp!%ld must be in the same section"),
2663 fixP
->tc_fix_data
.info
= info
;
2664 info
->slaves
= fixP
;
2667 case BFD_RELOC_ALPHA_LITERAL
:
2668 case BFD_RELOC_ALPHA_ELF_LITERAL
:
2669 fixP
->fx_no_overflow
= 1;
2671 if (insn
->sequence
== 0)
2673 info
= get_alpha_reloc_tag (insn
->sequence
);
2674 info
->master
= fixP
;
2676 if (info
->segment
!= now_seg
)
2677 info
->multi_section_p
= 1;
2678 fixP
->tc_fix_data
.info
= info
;
2681 case DUMMY_RELOC_LITUSE_ADDR
:
2682 fixP
->fx_offset
= LITUSE_ALPHA_ADDR
;
2684 case DUMMY_RELOC_LITUSE_BASE
:
2685 fixP
->fx_offset
= LITUSE_ALPHA_BASE
;
2687 case DUMMY_RELOC_LITUSE_BYTOFF
:
2688 fixP
->fx_offset
= LITUSE_ALPHA_BYTOFF
;
2690 case DUMMY_RELOC_LITUSE_JSR
:
2691 fixP
->fx_offset
= LITUSE_ALPHA_JSR
;
2693 case DUMMY_RELOC_LITUSE_TLSGD
:
2694 fixP
->fx_offset
= LITUSE_ALPHA_TLSGD
;
2696 case DUMMY_RELOC_LITUSE_TLSLDM
:
2697 fixP
->fx_offset
= LITUSE_ALPHA_TLSLDM
;
2700 fixP
->fx_addsy
= section_symbol (now_seg
);
2701 fixP
->fx_r_type
= BFD_RELOC_ALPHA_LITUSE
;
2703 info
= get_alpha_reloc_tag (insn
->sequence
);
2704 if (fixup
->reloc
== DUMMY_RELOC_LITUSE_TLSGD
)
2705 info
->saw_lu_tlsgd
= 1;
2706 else if (fixup
->reloc
== DUMMY_RELOC_LITUSE_TLSLDM
)
2707 info
->saw_lu_tlsldm
= 1;
2708 if (++info
->n_slaves
> 1)
2710 if (info
->saw_lu_tlsgd
)
2711 as_bad (_("too many lituse insns for !lituse_tlsgd!%ld"),
2713 else if (info
->saw_lu_tlsldm
)
2714 as_bad (_("too many lituse insns for !lituse_tlsldm!%ld"),
2717 fixP
->tc_fix_data
.info
= info
;
2718 fixP
->tc_fix_data
.next_reloc
= info
->slaves
;
2719 info
->slaves
= fixP
;
2720 if (info
->segment
!= now_seg
)
2721 info
->multi_section_p
= 1;
2724 case BFD_RELOC_ALPHA_TLSGD
:
2725 fixP
->fx_no_overflow
= 1;
2727 if (insn
->sequence
== 0)
2729 info
= get_alpha_reloc_tag (insn
->sequence
);
2730 if (info
->saw_tlsgd
)
2731 as_bad (_("duplicate !tlsgd!%ld"), insn
->sequence
);
2732 else if (info
->saw_tlsldm
)
2733 as_bad (_("sequence number in use for !tlsldm!%ld"),
2736 info
->saw_tlsgd
= 1;
2737 fixP
->tc_fix_data
.info
= info
;
2740 case BFD_RELOC_ALPHA_TLSLDM
:
2741 fixP
->fx_no_overflow
= 1;
2743 if (insn
->sequence
== 0)
2745 info
= get_alpha_reloc_tag (insn
->sequence
);
2746 if (info
->saw_tlsldm
)
2747 as_bad (_("duplicate !tlsldm!%ld"), insn
->sequence
);
2748 else if (info
->saw_tlsgd
)
2749 as_bad (_("sequence number in use for !tlsgd!%ld"),
2752 info
->saw_tlsldm
= 1;
2753 fixP
->tc_fix_data
.info
= info
;
2757 if ((int) fixup
->reloc
< 0)
2759 if (operand
->flags
& AXP_OPERAND_NOOVERFLOW
)
2760 fixP
->fx_no_overflow
= 1;
2767 /* Given an opcode name and a pre-tokenized set of arguments, assemble
2768 the insn, but do not emit it.
2770 Note that this implies no macros allowed, since we can't store more
2771 than one insn in an insn structure. */
2774 assemble_tokens_to_insn (opname
, tok
, ntok
, insn
)
2776 const expressionS
*tok
;
2778 struct alpha_insn
*insn
;
2780 const struct alpha_opcode
*opcode
;
2782 /* search opcodes */
2783 opcode
= (const struct alpha_opcode
*) hash_find (alpha_opcode_hash
, opname
);
2787 opcode
= find_opcode_match (opcode
, tok
, &ntok
, &cpumatch
);
2790 assemble_insn (opcode
, tok
, ntok
, insn
, BFD_RELOC_UNUSED
);
2794 as_bad (_("inappropriate arguments for opcode `%s'"), opname
);
2796 as_bad (_("opcode `%s' not supported for target %s"), opname
,
2800 as_bad (_("unknown opcode `%s'"), opname
);
2803 /* Given an opcode name and a pre-tokenized set of arguments, take the
2804 opcode all the way through emission. */
2807 assemble_tokens (opname
, tok
, ntok
, local_macros_on
)
2809 const expressionS
*tok
;
2811 int local_macros_on
;
2813 int found_something
= 0;
2814 const struct alpha_opcode
*opcode
;
2815 const struct alpha_macro
*macro
;
2817 bfd_reloc_code_real_type reloc
= BFD_RELOC_UNUSED
;
2820 /* If a user-specified relocation is present, this is not a macro. */
2821 if (ntok
&& USER_RELOC_P (tok
[ntok
- 1].X_op
))
2823 reloc
= ALPHA_RELOC_TABLE (tok
[ntok
- 1].X_op
)->reloc
;
2828 if (local_macros_on
)
2830 macro
= ((const struct alpha_macro
*)
2831 hash_find (alpha_macro_hash
, opname
));
2834 found_something
= 1;
2835 macro
= find_macro_match (macro
, tok
, &ntok
);
2838 (*macro
->emit
) (tok
, ntok
, macro
->arg
);
2844 /* search opcodes */
2845 opcode
= (const struct alpha_opcode
*) hash_find (alpha_opcode_hash
, opname
);
2848 found_something
= 1;
2849 opcode
= find_opcode_match (opcode
, tok
, &ntok
, &cpumatch
);
2852 struct alpha_insn insn
;
2853 assemble_insn (opcode
, tok
, ntok
, &insn
, reloc
);
2855 /* Copy the sequence number for the reloc from the reloc token. */
2856 if (reloc
!= BFD_RELOC_UNUSED
)
2857 insn
.sequence
= tok
[ntok
].X_add_number
;
2864 if (found_something
)
2867 as_bad (_("inappropriate arguments for opcode `%s'"), opname
);
2869 as_bad (_("opcode `%s' not supported for target %s"), opname
,
2873 as_bad (_("unknown opcode `%s'"), opname
);
2876 /* Some instruction sets indexed by lg(size) */
2877 static const char * const sextX_op
[] = { "sextb", "sextw", "sextl", NULL
};
2878 static const char * const insXl_op
[] = { "insbl", "inswl", "insll", "insql" };
2879 static const char * const insXh_op
[] = { NULL
, "inswh", "inslh", "insqh" };
2880 static const char * const extXl_op
[] = { "extbl", "extwl", "extll", "extql" };
2881 static const char * const extXh_op
[] = { NULL
, "extwh", "extlh", "extqh" };
2882 static const char * const mskXl_op
[] = { "mskbl", "mskwl", "mskll", "mskql" };
2883 static const char * const mskXh_op
[] = { NULL
, "mskwh", "msklh", "mskqh" };
2884 static const char * const stX_op
[] = { "stb", "stw", "stl", "stq" };
2885 static const char * const ldXu_op
[] = { "ldbu", "ldwu", NULL
, NULL
};
2887 /* Implement the ldgp macro. */
2890 emit_ldgp (tok
, ntok
, unused
)
2891 const expressionS
*tok
;
2892 int ntok ATTRIBUTE_UNUSED
;
2893 const PTR unused ATTRIBUTE_UNUSED
;
2898 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
2899 /* from "ldgp r1,n(r2)", generate "ldah r1,X(R2); lda r1,Y(r1)"
2900 with appropriate constants and relocations. */
2901 struct alpha_insn insn
;
2902 expressionS newtok
[3];
2906 if (regno (tok
[2].X_add_number
) == AXP_REG_PV
)
2907 ecoff_set_gp_prolog_size (0);
2911 set_tok_const (newtok
[1], 0);
2914 assemble_tokens_to_insn ("ldah", newtok
, 3, &insn
);
2919 if (addend
.X_op
!= O_constant
)
2920 as_bad (_("can not resolve expression"));
2921 addend
.X_op
= O_symbol
;
2922 addend
.X_add_symbol
= alpha_gp_symbol
;
2926 insn
.fixups
[0].exp
= addend
;
2927 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_GPDISP_HI16
;
2928 insn
.sequence
= next_sequence_num
;
2932 set_tok_preg (newtok
[2], tok
[0].X_add_number
);
2934 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
2937 addend
.X_add_number
+= 4;
2941 insn
.fixups
[0].exp
= addend
;
2942 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_GPDISP_LO16
;
2943 insn
.sequence
= next_sequence_num
--;
2946 #endif /* OBJ_ECOFF || OBJ_ELF */
2951 /* Add symbol+addend to link pool.
2952 Return offset from basesym to entry in link pool.
2954 Add new fixup only if offset isn't 16bit. */
2957 add_to_link_pool (basesym
, sym
, addend
)
2962 segT current_section
= now_seg
;
2963 int current_subsec
= now_subseg
;
2965 bfd_reloc_code_real_type reloc_type
;
2967 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
2970 offset
= - *symbol_get_obj (basesym
);
2972 /* @@ This assumes all entries in a given section will be of the same
2973 size... Probably correct, but unwise to rely on. */
2974 /* This must always be called with the same subsegment. */
2976 if (seginfo
->frchainP
)
2977 for (fixp
= seginfo
->frchainP
->fix_root
;
2978 fixp
!= (fixS
*) NULL
;
2979 fixp
= fixp
->fx_next
, offset
+= 8)
2981 if (fixp
->fx_addsy
== sym
&& fixp
->fx_offset
== addend
)
2983 if (range_signed_16 (offset
))
2990 /* Not found in 16bit signed range. */
2992 subseg_set (alpha_link_section
, 0);
2996 fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, sym
, addend
, 0,
2999 subseg_set (current_section
, current_subsec
);
3000 seginfo
->literal_pool_size
+= 8;
3004 #endif /* OBJ_EVAX */
3006 /* Load a (partial) expression into a target register.
3008 If poffset is not null, after the call it will either contain
3009 O_constant 0, or a 16-bit offset appropriate for any MEM format
3010 instruction. In addition, pbasereg will be modified to point to
3011 the base register to use in that MEM format instruction.
3013 In any case, *pbasereg should contain a base register to add to the
3014 expression. This will normally be either AXP_REG_ZERO or
3015 alpha_gp_register. Symbol addresses will always be loaded via $gp,
3016 so "foo($0)" is interpreted as adding the address of foo to $0;
3017 i.e. "ldq $targ, LIT($gp); addq $targ, $0, $targ". Odd, perhaps,
3018 but this is what OSF/1 does.
3020 If explicit relocations of the form !literal!<number> are allowed,
3021 and used, then explict_reloc with be an expression pointer.
3023 Finally, the return value is nonzero if the calling macro may emit
3024 a LITUSE reloc if otherwise appropriate; the return value is the
3025 sequence number to use. */
3028 load_expression (targreg
, exp
, pbasereg
, poffset
)
3030 const expressionS
*exp
;
3032 expressionS
*poffset
;
3034 long emit_lituse
= 0;
3035 offsetT addend
= exp
->X_add_number
;
3036 int basereg
= *pbasereg
;
3037 struct alpha_insn insn
;
3038 expressionS newtok
[3];
3047 /* attempt to reduce .lit load by splitting the offset from
3048 its symbol when possible, but don't create a situation in
3050 if (!range_signed_32 (addend
) &&
3051 (alpha_noat_on
|| targreg
== AXP_REG_AT
))
3053 lit
= add_to_literal_pool (exp
->X_add_symbol
, addend
,
3054 alpha_lita_section
, 8);
3059 lit
= add_to_literal_pool (exp
->X_add_symbol
, 0,
3060 alpha_lita_section
, 8);
3064 as_fatal (_("overflow in literal (.lita) table"));
3066 /* emit "ldq r, lit(gp)" */
3068 if (basereg
!= alpha_gp_register
&& targreg
== basereg
)
3071 as_bad (_("macro requires $at register while noat in effect"));
3072 if (targreg
== AXP_REG_AT
)
3073 as_bad (_("macro requires $at while $at in use"));
3075 set_tok_reg (newtok
[0], AXP_REG_AT
);
3078 set_tok_reg (newtok
[0], targreg
);
3079 set_tok_sym (newtok
[1], alpha_lita_symbol
, lit
);
3080 set_tok_preg (newtok
[2], alpha_gp_register
);
3082 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
3084 assert (insn
.nfixups
== 1);
3085 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITERAL
;
3086 insn
.sequence
= emit_lituse
= next_sequence_num
--;
3087 #endif /* OBJ_ECOFF */
3089 /* emit "ldq r, gotoff(gp)" */
3091 if (basereg
!= alpha_gp_register
&& targreg
== basereg
)
3094 as_bad (_("macro requires $at register while noat in effect"));
3095 if (targreg
== AXP_REG_AT
)
3096 as_bad (_("macro requires $at while $at in use"));
3098 set_tok_reg (newtok
[0], AXP_REG_AT
);
3101 set_tok_reg (newtok
[0], targreg
);
3103 /* XXX: Disable this .got minimizing optimization so that we can get
3104 better instruction offset knowledge in the compiler. This happens
3105 very infrequently anyway. */
3107 || (!range_signed_32 (addend
)
3108 && (alpha_noat_on
|| targreg
== AXP_REG_AT
)))
3115 set_tok_sym (newtok
[1], exp
->X_add_symbol
, 0);
3118 set_tok_preg (newtok
[2], alpha_gp_register
);
3120 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
3122 assert (insn
.nfixups
== 1);
3123 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_ELF_LITERAL
;
3124 insn
.sequence
= emit_lituse
= next_sequence_num
--;
3125 #endif /* OBJ_ELF */
3129 /* Find symbol or symbol pointer in link section. */
3131 if (exp
->X_add_symbol
== alpha_evax_proc
.symbol
)
3133 if (range_signed_16 (addend
))
3135 set_tok_reg (newtok
[0], targreg
);
3136 set_tok_const (newtok
[1], addend
);
3137 set_tok_preg (newtok
[2], basereg
);
3138 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
3143 set_tok_reg (newtok
[0], targreg
);
3144 set_tok_const (newtok
[1], 0);
3145 set_tok_preg (newtok
[2], basereg
);
3146 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
3151 if (!range_signed_32 (addend
))
3153 link
= add_to_link_pool (alpha_evax_proc
.symbol
,
3154 exp
->X_add_symbol
, addend
);
3159 link
= add_to_link_pool (alpha_evax_proc
.symbol
,
3160 exp
->X_add_symbol
, 0);
3162 set_tok_reg (newtok
[0], targreg
);
3163 set_tok_const (newtok
[1], link
);
3164 set_tok_preg (newtok
[2], basereg
);
3165 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
3167 #endif /* OBJ_EVAX */
3172 if (basereg
!= alpha_gp_register
&& basereg
!= AXP_REG_ZERO
)
3174 /* emit "addq r, base, r" */
3176 set_tok_reg (newtok
[1], basereg
);
3177 set_tok_reg (newtok
[2], targreg
);
3178 assemble_tokens ("addq", newtok
, 3, 0);
3190 /* Assume that this difference expression will be resolved to an
3191 absolute value and that that value will fit in 16 bits. */
3193 set_tok_reg (newtok
[0], targreg
);
3195 set_tok_preg (newtok
[2], basereg
);
3196 assemble_tokens ("lda", newtok
, 3, 0);
3199 set_tok_const (*poffset
, 0);
3203 if (exp
->X_add_number
> 0)
3204 as_bad (_("bignum invalid; zero assumed"));
3206 as_bad (_("floating point number invalid; zero assumed"));
3211 as_bad (_("can't handle expression"));
3216 if (!range_signed_32 (addend
))
3219 long seq_num
= next_sequence_num
--;
3221 /* For 64-bit addends, just put it in the literal pool. */
3224 /* emit "ldq targreg, lit(basereg)" */
3225 lit
= add_to_link_pool (alpha_evax_proc
.symbol
,
3226 section_symbol (absolute_section
), addend
);
3227 set_tok_reg (newtok
[0], targreg
);
3228 set_tok_const (newtok
[1], lit
);
3229 set_tok_preg (newtok
[2], alpha_gp_register
);
3230 assemble_tokens ("ldq", newtok
, 3, 0);
3233 if (alpha_lit8_section
== NULL
)
3235 create_literal_section (".lit8",
3236 &alpha_lit8_section
,
3237 &alpha_lit8_symbol
);
3240 alpha_lit8_literal
= add_to_literal_pool (alpha_lit8_symbol
, 0x8000,
3241 alpha_lita_section
, 8);
3242 if (alpha_lit8_literal
>= 0x8000)
3243 as_fatal (_("overflow in literal (.lita) table"));
3247 lit
= add_to_literal_pool (NULL
, addend
, alpha_lit8_section
, 8) - 0x8000;
3249 as_fatal (_("overflow in literal (.lit8) table"));
3251 /* emit "lda litreg, .lit8+0x8000" */
3253 if (targreg
== basereg
)
3256 as_bad (_("macro requires $at register while noat in effect"));
3257 if (targreg
== AXP_REG_AT
)
3258 as_bad (_("macro requires $at while $at in use"));
3260 set_tok_reg (newtok
[0], AXP_REG_AT
);
3263 set_tok_reg (newtok
[0], targreg
);
3265 set_tok_sym (newtok
[1], alpha_lita_symbol
, alpha_lit8_literal
);
3268 set_tok_sym (newtok
[1], alpha_lit8_symbol
, 0x8000);
3270 set_tok_preg (newtok
[2], alpha_gp_register
);
3272 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
3274 assert (insn
.nfixups
== 1);
3276 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITERAL
;
3279 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_ELF_LITERAL
;
3281 insn
.sequence
= seq_num
;
3285 /* emit "ldq litreg, lit(litreg)" */
3287 set_tok_const (newtok
[1], lit
);
3288 set_tok_preg (newtok
[2], newtok
[0].X_add_number
);
3290 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
3292 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3293 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BASE
;
3294 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3296 insn
.sequence
= seq_num
;
3301 /* emit "addq litreg, base, target" */
3303 if (basereg
!= AXP_REG_ZERO
)
3305 set_tok_reg (newtok
[1], basereg
);
3306 set_tok_reg (newtok
[2], targreg
);
3307 assemble_tokens ("addq", newtok
, 3, 0);
3309 #endif /* !OBJ_EVAX */
3312 set_tok_const (*poffset
, 0);
3313 *pbasereg
= targreg
;
3317 offsetT low
, high
, extra
, tmp
;
3319 /* for 32-bit operands, break up the addend */
3321 low
= sign_extend_16 (addend
);
3323 high
= sign_extend_16 (tmp
>> 16);
3325 if (tmp
- (high
<< 16))
3329 high
= sign_extend_16 (tmp
>> 16);
3334 set_tok_reg (newtok
[0], targreg
);
3335 set_tok_preg (newtok
[2], basereg
);
3339 /* emit "ldah r, extra(r) */
3340 set_tok_const (newtok
[1], extra
);
3341 assemble_tokens ("ldah", newtok
, 3, 0);
3342 set_tok_preg (newtok
[2], basereg
= targreg
);
3347 /* emit "ldah r, high(r) */
3348 set_tok_const (newtok
[1], high
);
3349 assemble_tokens ("ldah", newtok
, 3, 0);
3351 set_tok_preg (newtok
[2], basereg
);
3354 if ((low
&& !poffset
) || (!poffset
&& basereg
!= targreg
))
3356 /* emit "lda r, low(base)" */
3357 set_tok_const (newtok
[1], low
);
3358 assemble_tokens ("lda", newtok
, 3, 0);
3364 set_tok_const (*poffset
, low
);
3365 *pbasereg
= basereg
;
3371 /* The lda macro differs from the lda instruction in that it handles
3372 most simple expressions, particualrly symbol address loads and
3376 emit_lda (tok
, ntok
, unused
)
3377 const expressionS
*tok
;
3379 const PTR unused ATTRIBUTE_UNUSED
;
3384 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
3386 basereg
= tok
[2].X_add_number
;
3388 (void) load_expression (tok
[0].X_add_number
, &tok
[1], &basereg
, NULL
);
3391 /* The ldah macro differs from the ldah instruction in that it has $31
3392 as an implied base register. */
3395 emit_ldah (tok
, ntok
, unused
)
3396 const expressionS
*tok
;
3397 int ntok ATTRIBUTE_UNUSED
;
3398 const PTR unused ATTRIBUTE_UNUSED
;
3400 expressionS newtok
[3];
3404 set_tok_preg (newtok
[2], AXP_REG_ZERO
);
3406 assemble_tokens ("ldah", newtok
, 3, 0);
3409 /* Handle all "simple" integer register loads -- ldq, ldq_l, ldq_u,
3410 etc. They differ from the real instructions in that they do simple
3411 expressions like the lda macro. */
3414 emit_ir_load (tok
, ntok
, opname
)
3415 const expressionS
*tok
;
3421 expressionS newtok
[3];
3422 struct alpha_insn insn
;
3425 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
3427 basereg
= tok
[2].X_add_number
;
3429 lituse
= load_expression (tok
[0].X_add_number
, &tok
[1], &basereg
,
3433 set_tok_preg (newtok
[2], basereg
);
3435 assemble_tokens_to_insn ((const char *) opname
, newtok
, 3, &insn
);
3439 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3440 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BASE
;
3441 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3443 insn
.sequence
= lituse
;
3449 /* Handle fp register loads, and both integer and fp register stores.
3450 Again, we handle simple expressions. */
3453 emit_loadstore (tok
, ntok
, opname
)
3454 const expressionS
*tok
;
3460 expressionS newtok
[3];
3461 struct alpha_insn insn
;
3464 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
3466 basereg
= tok
[2].X_add_number
;
3468 if (tok
[1].X_op
!= O_constant
|| !range_signed_16 (tok
[1].X_add_number
))
3471 as_bad (_("macro requires $at register while noat in effect"));
3473 lituse
= load_expression (AXP_REG_AT
, &tok
[1], &basereg
, &newtok
[1]);
3482 set_tok_preg (newtok
[2], basereg
);
3484 assemble_tokens_to_insn ((const char *) opname
, newtok
, 3, &insn
);
3488 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3489 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BASE
;
3490 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3492 insn
.sequence
= lituse
;
3498 /* Load a half-word or byte as an unsigned value. */
3501 emit_ldXu (tok
, ntok
, vlgsize
)
3502 const expressionS
*tok
;
3506 if (alpha_target
& AXP_OPCODE_BWX
)
3507 emit_ir_load (tok
, ntok
, ldXu_op
[(long) vlgsize
]);
3510 expressionS newtok
[3];
3511 struct alpha_insn insn
;
3516 as_bad (_("macro requires $at register while noat in effect"));
3519 basereg
= (tok
[1].X_op
== O_constant
3520 ? AXP_REG_ZERO
: alpha_gp_register
);
3522 basereg
= tok
[2].X_add_number
;
3524 /* emit "lda $at, exp" */
3526 lituse
= load_expression (AXP_REG_AT
, &tok
[1], &basereg
, NULL
);
3528 /* emit "ldq_u targ, 0($at)" */
3531 set_tok_const (newtok
[1], 0);
3532 set_tok_preg (newtok
[2], basereg
);
3533 assemble_tokens_to_insn ("ldq_u", newtok
, 3, &insn
);
3537 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3538 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BASE
;
3539 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3541 insn
.sequence
= lituse
;
3546 /* emit "extXl targ, $at, targ" */
3548 set_tok_reg (newtok
[1], basereg
);
3549 newtok
[2] = newtok
[0];
3550 assemble_tokens_to_insn (extXl_op
[(long) vlgsize
], newtok
, 3, &insn
);
3554 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3555 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BYTOFF
;
3556 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3558 insn
.sequence
= lituse
;
3565 /* Load a half-word or byte as a signed value. */
3568 emit_ldX (tok
, ntok
, vlgsize
)
3569 const expressionS
*tok
;
3573 emit_ldXu (tok
, ntok
, vlgsize
);
3574 assemble_tokens (sextX_op
[(long) vlgsize
], tok
, 1, 1);
3577 /* Load an integral value from an unaligned address as an unsigned
3581 emit_uldXu (tok
, ntok
, vlgsize
)
3582 const expressionS
*tok
;
3586 long lgsize
= (long) vlgsize
;
3587 expressionS newtok
[3];
3590 as_bad (_("macro requires $at register while noat in effect"));
3592 /* emit "lda $at, exp" */
3594 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
3595 newtok
[0].X_add_number
= AXP_REG_AT
;
3596 assemble_tokens ("lda", newtok
, ntok
, 1);
3598 /* emit "ldq_u $t9, 0($at)" */
3600 set_tok_reg (newtok
[0], AXP_REG_T9
);
3601 set_tok_const (newtok
[1], 0);
3602 set_tok_preg (newtok
[2], AXP_REG_AT
);
3603 assemble_tokens ("ldq_u", newtok
, 3, 1);
3605 /* emit "ldq_u $t10, size-1($at)" */
3607 set_tok_reg (newtok
[0], AXP_REG_T10
);
3608 set_tok_const (newtok
[1], (1 << lgsize
) - 1);
3609 assemble_tokens ("ldq_u", newtok
, 3, 1);
3611 /* emit "extXl $t9, $at, $t9" */
3613 set_tok_reg (newtok
[0], AXP_REG_T9
);
3614 set_tok_reg (newtok
[1], AXP_REG_AT
);
3615 set_tok_reg (newtok
[2], AXP_REG_T9
);
3616 assemble_tokens (extXl_op
[lgsize
], newtok
, 3, 1);
3618 /* emit "extXh $t10, $at, $t10" */
3620 set_tok_reg (newtok
[0], AXP_REG_T10
);
3621 set_tok_reg (newtok
[2], AXP_REG_T10
);
3622 assemble_tokens (extXh_op
[lgsize
], newtok
, 3, 1);
3624 /* emit "or $t9, $t10, targ" */
3626 set_tok_reg (newtok
[0], AXP_REG_T9
);
3627 set_tok_reg (newtok
[1], AXP_REG_T10
);
3629 assemble_tokens ("or", newtok
, 3, 1);
3632 /* Load an integral value from an unaligned address as a signed value.
3633 Note that quads should get funneled to the unsigned load since we
3634 don't have to do the sign extension. */
3637 emit_uldX (tok
, ntok
, vlgsize
)
3638 const expressionS
*tok
;
3642 emit_uldXu (tok
, ntok
, vlgsize
);
3643 assemble_tokens (sextX_op
[(long) vlgsize
], tok
, 1, 1);
3646 /* Implement the ldil macro. */
3649 emit_ldil (tok
, ntok
, unused
)
3650 const expressionS
*tok
;
3652 const PTR unused ATTRIBUTE_UNUSED
;
3654 expressionS newtok
[2];
3656 memcpy (newtok
, tok
, sizeof (newtok
));
3657 newtok
[1].X_add_number
= sign_extend_32 (tok
[1].X_add_number
);
3659 assemble_tokens ("lda", newtok
, ntok
, 1);
3662 /* Store a half-word or byte. */
3665 emit_stX (tok
, ntok
, vlgsize
)
3666 const expressionS
*tok
;
3670 int lgsize
= (int) (long) vlgsize
;
3672 if (alpha_target
& AXP_OPCODE_BWX
)
3673 emit_loadstore (tok
, ntok
, stX_op
[lgsize
]);
3676 expressionS newtok
[3];
3677 struct alpha_insn insn
;
3682 as_bad (_("macro requires $at register while noat in effect"));
3685 basereg
= (tok
[1].X_op
== O_constant
3686 ? AXP_REG_ZERO
: alpha_gp_register
);
3688 basereg
= tok
[2].X_add_number
;
3690 /* emit "lda $at, exp" */
3692 lituse
= load_expression (AXP_REG_AT
, &tok
[1], &basereg
, NULL
);
3694 /* emit "ldq_u $t9, 0($at)" */
3696 set_tok_reg (newtok
[0], AXP_REG_T9
);
3697 set_tok_const (newtok
[1], 0);
3698 set_tok_preg (newtok
[2], basereg
);
3699 assemble_tokens_to_insn ("ldq_u", newtok
, 3, &insn
);
3703 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3704 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BASE
;
3705 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3707 insn
.sequence
= lituse
;
3712 /* emit "insXl src, $at, $t10" */
3715 set_tok_reg (newtok
[1], basereg
);
3716 set_tok_reg (newtok
[2], AXP_REG_T10
);
3717 assemble_tokens_to_insn (insXl_op
[lgsize
], newtok
, 3, &insn
);
3721 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3722 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BYTOFF
;
3723 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3725 insn
.sequence
= lituse
;
3730 /* emit "mskXl $t9, $at, $t9" */
3732 set_tok_reg (newtok
[0], AXP_REG_T9
);
3733 newtok
[2] = newtok
[0];
3734 assemble_tokens_to_insn (mskXl_op
[lgsize
], newtok
, 3, &insn
);
3738 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3739 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BYTOFF
;
3740 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3742 insn
.sequence
= lituse
;
3747 /* emit "or $t9, $t10, $t9" */
3749 set_tok_reg (newtok
[1], AXP_REG_T10
);
3750 assemble_tokens ("or", newtok
, 3, 1);
3752 /* emit "stq_u $t9, 0($at) */
3754 set_tok_const(newtok
[1], 0);
3755 set_tok_preg (newtok
[2], AXP_REG_AT
);
3756 assemble_tokens_to_insn ("stq_u", newtok
, 3, &insn
);
3760 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3761 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BASE
;
3762 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
3764 insn
.sequence
= lituse
;
3771 /* Store an integer to an unaligned address. */
3774 emit_ustX (tok
, ntok
, vlgsize
)
3775 const expressionS
*tok
;
3779 int lgsize
= (int) (long) vlgsize
;
3780 expressionS newtok
[3];
3782 /* emit "lda $at, exp" */
3784 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
3785 newtok
[0].X_add_number
= AXP_REG_AT
;
3786 assemble_tokens ("lda", newtok
, ntok
, 1);
3788 /* emit "ldq_u $9, 0($at)" */
3790 set_tok_reg (newtok
[0], AXP_REG_T9
);
3791 set_tok_const (newtok
[1], 0);
3792 set_tok_preg (newtok
[2], AXP_REG_AT
);
3793 assemble_tokens ("ldq_u", newtok
, 3, 1);
3795 /* emit "ldq_u $10, size-1($at)" */
3797 set_tok_reg (newtok
[0], AXP_REG_T10
);
3798 set_tok_const (newtok
[1], (1 << lgsize
) - 1);
3799 assemble_tokens ("ldq_u", newtok
, 3, 1);
3801 /* emit "insXl src, $at, $t11" */
3804 set_tok_reg (newtok
[1], AXP_REG_AT
);
3805 set_tok_reg (newtok
[2], AXP_REG_T11
);
3806 assemble_tokens (insXl_op
[lgsize
], newtok
, 3, 1);
3808 /* emit "insXh src, $at, $t12" */
3810 set_tok_reg (newtok
[2], AXP_REG_T12
);
3811 assemble_tokens (insXh_op
[lgsize
], newtok
, 3, 1);
3813 /* emit "mskXl $t9, $at, $t9" */
3815 set_tok_reg (newtok
[0], AXP_REG_T9
);
3816 newtok
[2] = newtok
[0];
3817 assemble_tokens (mskXl_op
[lgsize
], newtok
, 3, 1);
3819 /* emit "mskXh $t10, $at, $t10" */
3821 set_tok_reg (newtok
[0], AXP_REG_T10
);
3822 newtok
[2] = newtok
[0];
3823 assemble_tokens (mskXh_op
[lgsize
], newtok
, 3, 1);
3825 /* emit "or $t9, $t11, $t9" */
3827 set_tok_reg (newtok
[0], AXP_REG_T9
);
3828 set_tok_reg (newtok
[1], AXP_REG_T11
);
3829 newtok
[2] = newtok
[0];
3830 assemble_tokens ("or", newtok
, 3, 1);
3832 /* emit "or $t10, $t12, $t10" */
3834 set_tok_reg (newtok
[0], AXP_REG_T10
);
3835 set_tok_reg (newtok
[1], AXP_REG_T12
);
3836 newtok
[2] = newtok
[0];
3837 assemble_tokens ("or", newtok
, 3, 1);
3839 /* emit "stq_u $t9, 0($at)" */
3841 set_tok_reg (newtok
[0], AXP_REG_T9
);
3842 set_tok_const (newtok
[1], 0);
3843 set_tok_preg (newtok
[2], AXP_REG_AT
);
3844 assemble_tokens ("stq_u", newtok
, 3, 1);
3846 /* emit "stq_u $t10, size-1($at)" */
3848 set_tok_reg (newtok
[0], AXP_REG_T10
);
3849 set_tok_const (newtok
[1], (1 << lgsize
) - 1);
3850 assemble_tokens ("stq_u", newtok
, 3, 1);
3853 /* Sign extend a half-word or byte. The 32-bit sign extend is
3854 implemented as "addl $31, $r, $t" in the opcode table. */
3857 emit_sextX (tok
, ntok
, vlgsize
)
3858 const expressionS
*tok
;
3862 long lgsize
= (long) vlgsize
;
3864 if (alpha_target
& AXP_OPCODE_BWX
)
3865 assemble_tokens (sextX_op
[lgsize
], tok
, ntok
, 0);
3868 int bitshift
= 64 - 8 * (1 << lgsize
);
3869 expressionS newtok
[3];
3871 /* emit "sll src,bits,dst" */
3874 set_tok_const (newtok
[1], bitshift
);
3875 newtok
[2] = tok
[ntok
- 1];
3876 assemble_tokens ("sll", newtok
, 3, 1);
3878 /* emit "sra dst,bits,dst" */
3880 newtok
[0] = newtok
[2];
3881 assemble_tokens ("sra", newtok
, 3, 1);
3885 /* Implement the division and modulus macros. */
3889 /* Make register usage like in normal procedure call.
3890 Don't clobber PV and RA. */
3893 emit_division (tok
, ntok
, symname
)
3894 const expressionS
*tok
;
3898 /* DIVISION and MODULUS. Yech.
3903 * mov x,R16 # if x != R16
3904 * mov y,R17 # if y != R17
3909 * with appropriate optimizations if R0,R16,R17 are the registers
3910 * specified by the compiler.
3915 expressionS newtok
[3];
3917 xr
= regno (tok
[0].X_add_number
);
3918 yr
= regno (tok
[1].X_add_number
);
3923 rr
= regno (tok
[2].X_add_number
);
3925 /* Move the operands into the right place */
3926 if (yr
== AXP_REG_R16
&& xr
== AXP_REG_R17
)
3928 /* They are in exactly the wrong order -- swap through AT */
3931 as_bad (_("macro requires $at register while noat in effect"));
3933 set_tok_reg (newtok
[0], AXP_REG_R16
);
3934 set_tok_reg (newtok
[1], AXP_REG_AT
);
3935 assemble_tokens ("mov", newtok
, 2, 1);
3937 set_tok_reg (newtok
[0], AXP_REG_R17
);
3938 set_tok_reg (newtok
[1], AXP_REG_R16
);
3939 assemble_tokens ("mov", newtok
, 2, 1);
3941 set_tok_reg (newtok
[0], AXP_REG_AT
);
3942 set_tok_reg (newtok
[1], AXP_REG_R17
);
3943 assemble_tokens ("mov", newtok
, 2, 1);
3947 if (yr
== AXP_REG_R16
)
3949 set_tok_reg (newtok
[0], AXP_REG_R16
);
3950 set_tok_reg (newtok
[1], AXP_REG_R17
);
3951 assemble_tokens ("mov", newtok
, 2, 1);
3954 if (xr
!= AXP_REG_R16
)
3956 set_tok_reg (newtok
[0], xr
);
3957 set_tok_reg (newtok
[1], AXP_REG_R16
);
3958 assemble_tokens ("mov", newtok
, 2, 1);
3961 if (yr
!= AXP_REG_R16
&& yr
!= AXP_REG_R17
)
3963 set_tok_reg (newtok
[0], yr
);
3964 set_tok_reg (newtok
[1], AXP_REG_R17
);
3965 assemble_tokens ("mov", newtok
, 2, 1);
3969 sym
= symbol_find_or_make ((const char *) symname
);
3971 set_tok_reg (newtok
[0], AXP_REG_AT
);
3972 set_tok_sym (newtok
[1], sym
, 0);
3973 assemble_tokens ("lda", newtok
, 2, 1);
3975 /* Call the division routine */
3976 set_tok_reg (newtok
[0], AXP_REG_AT
);
3977 set_tok_cpreg (newtok
[1], AXP_REG_AT
);
3978 set_tok_const (newtok
[2], 0);
3979 assemble_tokens ("jsr", newtok
, 3, 1);
3981 /* Move the result to the right place */
3982 if (rr
!= AXP_REG_R0
)
3984 set_tok_reg (newtok
[0], AXP_REG_R0
);
3985 set_tok_reg (newtok
[1], rr
);
3986 assemble_tokens ("mov", newtok
, 2, 1);
3990 #else /* !OBJ_EVAX */
3993 emit_division (tok
, ntok
, symname
)
3994 const expressionS
*tok
;
3998 /* DIVISION and MODULUS. Yech.
4008 * with appropriate optimizations if t10,t11,t12 are the registers
4009 * specified by the compiler.
4014 expressionS newtok
[3];
4016 xr
= regno (tok
[0].X_add_number
);
4017 yr
= regno (tok
[1].X_add_number
);
4022 rr
= regno (tok
[2].X_add_number
);
4024 sym
= symbol_find_or_make ((const char *) symname
);
4026 /* Move the operands into the right place */
4027 if (yr
== AXP_REG_T10
&& xr
== AXP_REG_T11
)
4029 /* They are in exactly the wrong order -- swap through AT */
4032 as_bad (_("macro requires $at register while noat in effect"));
4034 set_tok_reg (newtok
[0], AXP_REG_T10
);
4035 set_tok_reg (newtok
[1], AXP_REG_AT
);
4036 assemble_tokens ("mov", newtok
, 2, 1);
4038 set_tok_reg (newtok
[0], AXP_REG_T11
);
4039 set_tok_reg (newtok
[1], AXP_REG_T10
);
4040 assemble_tokens ("mov", newtok
, 2, 1);
4042 set_tok_reg (newtok
[0], AXP_REG_AT
);
4043 set_tok_reg (newtok
[1], AXP_REG_T11
);
4044 assemble_tokens ("mov", newtok
, 2, 1);
4048 if (yr
== AXP_REG_T10
)
4050 set_tok_reg (newtok
[0], AXP_REG_T10
);
4051 set_tok_reg (newtok
[1], AXP_REG_T11
);
4052 assemble_tokens ("mov", newtok
, 2, 1);
4055 if (xr
!= AXP_REG_T10
)
4057 set_tok_reg (newtok
[0], xr
);
4058 set_tok_reg (newtok
[1], AXP_REG_T10
);
4059 assemble_tokens ("mov", newtok
, 2, 1);
4062 if (yr
!= AXP_REG_T10
&& yr
!= AXP_REG_T11
)
4064 set_tok_reg (newtok
[0], yr
);
4065 set_tok_reg (newtok
[1], AXP_REG_T11
);
4066 assemble_tokens ("mov", newtok
, 2, 1);
4070 /* Call the division routine */
4071 set_tok_reg (newtok
[0], AXP_REG_T9
);
4072 set_tok_sym (newtok
[1], sym
, 0);
4073 assemble_tokens ("jsr", newtok
, 2, 1);
4075 /* Reload the GP register */
4079 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
4080 set_tok_reg (newtok
[0], alpha_gp_register
);
4081 set_tok_const (newtok
[1], 0);
4082 set_tok_preg (newtok
[2], AXP_REG_T9
);
4083 assemble_tokens ("ldgp", newtok
, 3, 1);
4086 /* Move the result to the right place */
4087 if (rr
!= AXP_REG_T12
)
4089 set_tok_reg (newtok
[0], AXP_REG_T12
);
4090 set_tok_reg (newtok
[1], rr
);
4091 assemble_tokens ("mov", newtok
, 2, 1);
4095 #endif /* !OBJ_EVAX */
4097 /* The jsr and jmp macros differ from their instruction counterparts
4098 in that they can load the target address and default most
4102 emit_jsrjmp (tok
, ntok
, vopname
)
4103 const expressionS
*tok
;
4107 const char *opname
= (const char *) vopname
;
4108 struct alpha_insn insn
;
4109 expressionS newtok
[3];
4113 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_register
)
4114 r
= regno (tok
[tokidx
++].X_add_number
);
4116 r
= strcmp (opname
, "jmp") == 0 ? AXP_REG_ZERO
: AXP_REG_RA
;
4118 set_tok_reg (newtok
[0], r
);
4120 if (tokidx
< ntok
&&
4121 (tok
[tokidx
].X_op
== O_pregister
|| tok
[tokidx
].X_op
== O_cpregister
))
4122 r
= regno (tok
[tokidx
++].X_add_number
);
4124 /* keep register if jsr $n.<sym> */
4128 int basereg
= alpha_gp_register
;
4129 lituse
= load_expression (r
= AXP_REG_PV
, &tok
[tokidx
], &basereg
, NULL
);
4133 set_tok_cpreg (newtok
[1], r
);
4136 /* FIXME: Add hint relocs to BFD for evax. */
4139 newtok
[2] = tok
[tokidx
];
4142 set_tok_const (newtok
[2], 0);
4144 assemble_tokens_to_insn (opname
, newtok
, 3, &insn
);
4148 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
4149 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_JSR
;
4150 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
4152 insn
.sequence
= lituse
;
4158 /* The ret and jcr instructions differ from their instruction
4159 counterparts in that everything can be defaulted. */
4162 emit_retjcr (tok
, ntok
, vopname
)
4163 const expressionS
*tok
;
4167 const char *opname
= (const char *) vopname
;
4168 expressionS newtok
[3];
4171 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_register
)
4172 r
= regno (tok
[tokidx
++].X_add_number
);
4176 set_tok_reg (newtok
[0], r
);
4178 if (tokidx
< ntok
&&
4179 (tok
[tokidx
].X_op
== O_pregister
|| tok
[tokidx
].X_op
== O_cpregister
))
4180 r
= regno (tok
[tokidx
++].X_add_number
);
4184 set_tok_cpreg (newtok
[1], r
);
4187 newtok
[2] = tok
[tokidx
];
4189 set_tok_const (newtok
[2], strcmp (opname
, "ret") == 0);
4191 assemble_tokens (opname
, newtok
, 3, 0);
4194 /* Assembler directives */
4196 /* Handle the .text pseudo-op. This is like the usual one, but it
4197 clears alpha_insn_label and restores auto alignment. */
4209 alpha_insn_label
= NULL
;
4210 alpha_auto_align_on
= 1;
4211 alpha_current_align
= 0;
4214 /* Handle the .data pseudo-op. This is like the usual one, but it
4215 clears alpha_insn_label and restores auto alignment. */
4226 alpha_insn_label
= NULL
;
4227 alpha_auto_align_on
= 1;
4228 alpha_current_align
= 0;
4231 #if defined (OBJ_ECOFF) || defined (OBJ_EVAX)
4233 /* Handle the OSF/1 and openVMS .comm pseudo quirks.
4234 openVMS constructs a section for every common symbol. */
4237 s_alpha_comm (ignore
)
4240 register char *name
;
4244 register symbolS
*symbolP
;
4247 segT current_section
= now_seg
;
4248 int current_subsec
= now_subseg
;
4252 name
= input_line_pointer
;
4253 c
= get_symbol_end ();
4255 /* just after name is now '\0' */
4256 p
= input_line_pointer
;
4261 /* Alpha OSF/1 compiler doesn't provide the comma, gcc does. */
4262 if (*input_line_pointer
== ',')
4264 input_line_pointer
++;
4267 if ((temp
= get_absolute_expression ()) < 0)
4269 as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) temp
);
4270 ignore_rest_of_line ();
4275 symbolP
= symbol_find_or_make (name
);
4278 /* Make a section for the common symbol. */
4279 new_seg
= subseg_new (xstrdup (name
), 0);
4285 /* alignment might follow */
4286 if (*input_line_pointer
== ',')
4290 input_line_pointer
++;
4291 align
= get_absolute_expression ();
4292 bfd_set_section_alignment (stdoutput
, new_seg
, align
);
4296 if (S_IS_DEFINED (symbolP
) && ! S_IS_COMMON (symbolP
))
4298 as_bad (_("Ignoring attempt to re-define symbol"));
4299 ignore_rest_of_line ();
4304 if (bfd_section_size (stdoutput
, new_seg
) > 0)
4306 if (bfd_section_size (stdoutput
, new_seg
) != temp
)
4307 as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
4308 S_GET_NAME (symbolP
),
4309 (long) bfd_section_size (stdoutput
, new_seg
),
4313 if (S_GET_VALUE (symbolP
))
4315 if (S_GET_VALUE (symbolP
) != (valueT
) temp
)
4316 as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
4317 S_GET_NAME (symbolP
),
4318 (long) S_GET_VALUE (symbolP
),
4325 subseg_set (new_seg
, 0);
4326 p
= frag_more (temp
);
4327 new_seg
->flags
|= SEC_IS_COMMON
;
4328 if (! S_IS_DEFINED (symbolP
))
4329 S_SET_SEGMENT (symbolP
, new_seg
);
4331 S_SET_VALUE (symbolP
, (valueT
) temp
);
4333 S_SET_EXTERNAL (symbolP
);
4337 subseg_set (current_section
, current_subsec
);
4340 know (symbol_get_frag (symbolP
) == &zero_address_frag
);
4342 demand_empty_rest_of_line ();
4345 #endif /* ! OBJ_ELF */
4349 /* Handle the .rdata pseudo-op. This is like the usual one, but it
4350 clears alpha_insn_label and restores auto alignment. */
4353 s_alpha_rdata (ignore
)
4358 temp
= get_absolute_expression ();
4359 subseg_new (".rdata", 0);
4360 demand_empty_rest_of_line ();
4361 alpha_insn_label
= NULL
;
4362 alpha_auto_align_on
= 1;
4363 alpha_current_align
= 0;
4370 /* Handle the .sdata pseudo-op. This is like the usual one, but it
4371 clears alpha_insn_label and restores auto alignment. */
4374 s_alpha_sdata (ignore
)
4379 temp
= get_absolute_expression ();
4380 subseg_new (".sdata", 0);
4381 demand_empty_rest_of_line ();
4382 alpha_insn_label
= NULL
;
4383 alpha_auto_align_on
= 1;
4384 alpha_current_align
= 0;
4390 /* Handle the .section pseudo-op. This is like the usual one, but it
4391 clears alpha_insn_label and restores auto alignment. */
4394 s_alpha_section (ignore
)
4397 obj_elf_section (ignore
);
4399 alpha_insn_label
= NULL
;
4400 alpha_auto_align_on
= 1;
4401 alpha_current_align
= 0;
4406 int dummy ATTRIBUTE_UNUSED
;
4408 if (ECOFF_DEBUGGING
)
4409 ecoff_directive_ent (0);
4412 char *name
, name_end
;
4413 name
= input_line_pointer
;
4414 name_end
= get_symbol_end ();
4416 if (! is_name_beginner (*name
))
4418 as_warn (_(".ent directive has no name"));
4419 *input_line_pointer
= name_end
;
4425 if (alpha_cur_ent_sym
)
4426 as_warn (_("nested .ent directives"));
4428 sym
= symbol_find_or_make (name
);
4429 symbol_get_bfdsym (sym
)->flags
|= BSF_FUNCTION
;
4430 alpha_cur_ent_sym
= sym
;
4432 /* The .ent directive is sometimes followed by a number. Not sure
4433 what it really means, but ignore it. */
4434 *input_line_pointer
= name_end
;
4436 if (*input_line_pointer
== ',')
4438 input_line_pointer
++;
4441 if (ISDIGIT (*input_line_pointer
) || *input_line_pointer
== '-')
4442 (void) get_absolute_expression ();
4444 demand_empty_rest_of_line ();
4450 int dummy ATTRIBUTE_UNUSED
;
4452 if (ECOFF_DEBUGGING
)
4453 ecoff_directive_end (0);
4456 char *name
, name_end
;
4457 name
= input_line_pointer
;
4458 name_end
= get_symbol_end ();
4460 if (! is_name_beginner (*name
))
4462 as_warn (_(".end directive has no name"));
4463 *input_line_pointer
= name_end
;
4469 sym
= symbol_find (name
);
4470 if (sym
!= alpha_cur_ent_sym
)
4471 as_warn (_(".end directive names different symbol than .ent"));
4473 /* Create an expression to calculate the size of the function. */
4476 symbol_get_obj (sym
)->size
=
4477 (expressionS
*) xmalloc (sizeof (expressionS
));
4478 symbol_get_obj (sym
)->size
->X_op
= O_subtract
;
4479 symbol_get_obj (sym
)->size
->X_add_symbol
4480 = symbol_new ("L0\001", now_seg
, frag_now_fix (), frag_now
);
4481 symbol_get_obj (sym
)->size
->X_op_symbol
= sym
;
4482 symbol_get_obj (sym
)->size
->X_add_number
= 0;
4485 alpha_cur_ent_sym
= NULL
;
4487 *input_line_pointer
= name_end
;
4489 demand_empty_rest_of_line ();
4497 if (ECOFF_DEBUGGING
)
4500 ecoff_directive_fmask (0);
4502 ecoff_directive_mask (0);
4505 discard_rest_of_line ();
4509 s_alpha_frame (dummy
)
4510 int dummy ATTRIBUTE_UNUSED
;
4512 if (ECOFF_DEBUGGING
)
4513 ecoff_directive_frame (0);
4515 discard_rest_of_line ();
4519 s_alpha_prologue (ignore
)
4520 int ignore ATTRIBUTE_UNUSED
;
4525 arg
= get_absolute_expression ();
4526 demand_empty_rest_of_line ();
4528 if (ECOFF_DEBUGGING
)
4529 sym
= ecoff_get_cur_proc_sym ();
4531 sym
= alpha_cur_ent_sym
;
4536 case 0: /* No PV required. */
4537 S_SET_OTHER (sym
, STO_ALPHA_NOPV
4538 | (S_GET_OTHER (sym
) & ~STO_ALPHA_STD_GPLOAD
));
4540 case 1: /* Std GP load. */
4541 S_SET_OTHER (sym
, STO_ALPHA_STD_GPLOAD
4542 | (S_GET_OTHER (sym
) & ~STO_ALPHA_STD_GPLOAD
));
4544 case 2: /* Non-std use of PV. */
4548 as_bad (_("Invalid argument %d to .prologue."), arg
);
4553 static char *first_file_directive
;
4556 s_alpha_file (ignore
)
4557 int ignore ATTRIBUTE_UNUSED
;
4559 /* Save the first .file directive we see, so that we can change our
4560 minds about whether ecoff debugging should or shouldn't be enabled. */
4561 if (alpha_flag_mdebug
< 0 && ! first_file_directive
)
4563 char *start
= input_line_pointer
;
4566 discard_rest_of_line ();
4568 len
= input_line_pointer
- start
;
4569 first_file_directive
= xmalloc (len
+ 1);
4570 memcpy (first_file_directive
, start
, len
);
4571 first_file_directive
[len
] = '\0';
4573 input_line_pointer
= start
;
4576 if (ECOFF_DEBUGGING
)
4577 ecoff_directive_file (0);
4579 dwarf2_directive_file (0);
4583 s_alpha_loc (ignore
)
4584 int ignore ATTRIBUTE_UNUSED
;
4586 if (ECOFF_DEBUGGING
)
4587 ecoff_directive_loc (0);
4589 dwarf2_directive_loc (0);
4596 /* If we've been undecided about mdebug, make up our minds in favour. */
4597 if (alpha_flag_mdebug
< 0)
4599 segT sec
= subseg_new (".mdebug", 0);
4600 bfd_set_section_flags (stdoutput
, sec
, SEC_HAS_CONTENTS
| SEC_READONLY
);
4601 bfd_set_section_alignment (stdoutput
, sec
, 3);
4603 ecoff_read_begin_hook ();
4605 if (first_file_directive
)
4607 char *save_ilp
= input_line_pointer
;
4608 input_line_pointer
= first_file_directive
;
4609 ecoff_directive_file (0);
4610 input_line_pointer
= save_ilp
;
4611 free (first_file_directive
);
4614 alpha_flag_mdebug
= 1;
4620 s_alpha_coff_wrapper (which
)
4623 static void (* const fns
[]) PARAMS ((int)) = {
4624 ecoff_directive_begin
,
4625 ecoff_directive_bend
,
4626 ecoff_directive_def
,
4627 ecoff_directive_dim
,
4628 ecoff_directive_endef
,
4629 ecoff_directive_scl
,
4630 ecoff_directive_tag
,
4631 ecoff_directive_val
,
4634 assert (which
>= 0 && which
< (int) (sizeof (fns
)/sizeof (*fns
)));
4636 if (ECOFF_DEBUGGING
)
4640 as_bad (_("ECOFF debugging is disabled."));
4641 ignore_rest_of_line ();
4644 #endif /* OBJ_ELF */
4648 /* Handle the section specific pseudo-op. */
4651 s_alpha_section (secid
)
4655 #define EVAX_SECTION_COUNT 5
4656 static char *section_name
[EVAX_SECTION_COUNT
+ 1] =
4657 { "NULL", ".rdata", ".comm", ".link", ".ctors", ".dtors" };
4659 if ((secid
<= 0) || (secid
> EVAX_SECTION_COUNT
))
4661 as_fatal (_("Unknown section directive"));
4662 demand_empty_rest_of_line ();
4665 temp
= get_absolute_expression ();
4666 subseg_new (section_name
[secid
], 0);
4667 demand_empty_rest_of_line ();
4668 alpha_insn_label
= NULL
;
4669 alpha_auto_align_on
= 1;
4670 alpha_current_align
= 0;
4673 /* Parse .ent directives. */
4676 s_alpha_ent (ignore
)
4680 expressionS symexpr
;
4682 alpha_evax_proc
.pdsckind
= 0;
4683 alpha_evax_proc
.framereg
= -1;
4684 alpha_evax_proc
.framesize
= 0;
4685 alpha_evax_proc
.rsa_offset
= 0;
4686 alpha_evax_proc
.ra_save
= AXP_REG_RA
;
4687 alpha_evax_proc
.fp_save
= -1;
4688 alpha_evax_proc
.imask
= 0;
4689 alpha_evax_proc
.fmask
= 0;
4690 alpha_evax_proc
.prologue
= 0;
4691 alpha_evax_proc
.type
= 0;
4693 expression (&symexpr
);
4695 if (symexpr
.X_op
!= O_symbol
)
4697 as_fatal (_(".ent directive has no symbol"));
4698 demand_empty_rest_of_line ();
4702 symbol
= make_expr_symbol (&symexpr
);
4703 symbol_get_bfdsym (symbol
)->flags
|= BSF_FUNCTION
;
4704 alpha_evax_proc
.symbol
= symbol
;
4706 demand_empty_rest_of_line ();
4710 /* Parse .frame <framreg>,<framesize>,RA,<rsa_offset> directives. */
4713 s_alpha_frame (ignore
)
4718 alpha_evax_proc
.framereg
= tc_get_register (1);
4721 if (*input_line_pointer
++ != ','
4722 || get_absolute_expression_and_terminator (&val
) != ',')
4724 as_warn (_("Bad .frame directive 1./2. param"));
4725 --input_line_pointer
;
4726 demand_empty_rest_of_line ();
4730 alpha_evax_proc
.framesize
= val
;
4732 (void) tc_get_register (1);
4734 if (*input_line_pointer
++ != ',')
4736 as_warn (_("Bad .frame directive 3./4. param"));
4737 --input_line_pointer
;
4738 demand_empty_rest_of_line ();
4741 alpha_evax_proc
.rsa_offset
= get_absolute_expression ();
4747 s_alpha_pdesc (ignore
)
4757 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
4759 if (now_seg
!= alpha_link_section
)
4761 as_bad (_(".pdesc directive not in link (.link) section"));
4762 demand_empty_rest_of_line ();
4766 if ((alpha_evax_proc
.symbol
== 0)
4767 || (!S_IS_DEFINED (alpha_evax_proc
.symbol
)))
4769 as_fatal (_(".pdesc has no matching .ent"));
4770 demand_empty_rest_of_line ();
4774 *symbol_get_obj (alpha_evax_proc
.symbol
) =
4775 (valueT
) seginfo
->literal_pool_size
;
4778 if (exp
.X_op
!= O_symbol
)
4780 as_warn (_(".pdesc directive has no entry symbol"));
4781 demand_empty_rest_of_line ();
4785 entry_sym
= make_expr_symbol (&exp
);
4786 /* Save bfd symbol of proc desc in function symbol. */
4787 symbol_get_bfdsym (alpha_evax_proc
.symbol
)->udata
.p
4788 = symbol_get_bfdsym (entry_sym
);
4791 if (*input_line_pointer
++ != ',')
4793 as_warn (_("No comma after .pdesc <entryname>"));
4794 demand_empty_rest_of_line ();
4799 name
= input_line_pointer
;
4800 name_end
= get_symbol_end ();
4802 if (strncmp (name
, "stack", 5) == 0)
4804 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_FP_STACK
;
4806 else if (strncmp (name
, "reg", 3) == 0)
4808 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_FP_REGISTER
;
4810 else if (strncmp (name
, "null", 4) == 0)
4812 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_NULL
;
4816 as_fatal (_("unknown procedure kind"));
4817 demand_empty_rest_of_line ();
4821 *input_line_pointer
= name_end
;
4822 demand_empty_rest_of_line ();
4824 #ifdef md_flush_pending_output
4825 md_flush_pending_output ();
4828 frag_align (3, 0, 0);
4830 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
4832 seginfo
->literal_pool_size
+= 16;
4834 *p
= alpha_evax_proc
.pdsckind
4835 | ((alpha_evax_proc
.framereg
== 29) ? PDSC_S_M_BASE_REG_IS_FP
: 0);
4836 *(p
+ 1) = PDSC_S_M_NATIVE
| PDSC_S_M_NO_JACKET
;
4838 switch (alpha_evax_proc
.pdsckind
)
4840 case PDSC_S_K_KIND_NULL
:
4844 case PDSC_S_K_KIND_FP_REGISTER
:
4845 *(p
+ 2) = alpha_evax_proc
.fp_save
;
4846 *(p
+ 3) = alpha_evax_proc
.ra_save
;
4848 case PDSC_S_K_KIND_FP_STACK
:
4849 md_number_to_chars (p
+ 2, (valueT
) alpha_evax_proc
.rsa_offset
, 2);
4851 default: /* impossible */
4856 *(p
+ 5) = alpha_evax_proc
.type
& 0x0f;
4858 /* Signature offset. */
4859 md_number_to_chars (p
+ 6, (valueT
) 0, 2);
4861 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
+8, 8, &exp
, 0, BFD_RELOC_64
);
4863 if (alpha_evax_proc
.pdsckind
== PDSC_S_K_KIND_NULL
)
4866 /* Add dummy fix to make add_to_link_pool work. */
4868 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
4870 seginfo
->literal_pool_size
+= 8;
4872 /* pdesc+16: Size. */
4873 md_number_to_chars (p
, (valueT
) alpha_evax_proc
.framesize
, 4);
4875 md_number_to_chars (p
+ 4, (valueT
) 0, 2);
4878 md_number_to_chars (p
+ 6, alpha_evax_proc
.prologue
, 2);
4880 if (alpha_evax_proc
.pdsckind
== PDSC_S_K_KIND_FP_REGISTER
)
4883 /* Add dummy fix to make add_to_link_pool work. */
4885 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
4887 seginfo
->literal_pool_size
+= 8;
4889 /* pdesc+24: register masks. */
4891 md_number_to_chars (p
, alpha_evax_proc
.imask
, 4);
4892 md_number_to_chars (p
+ 4, alpha_evax_proc
.fmask
, 4);
4897 /* Support for crash debug on vms. */
4900 s_alpha_name (ignore
)
4905 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
4907 if (now_seg
!= alpha_link_section
)
4909 as_bad (_(".name directive not in link (.link) section"));
4910 demand_empty_rest_of_line ();
4915 if (exp
.X_op
!= O_symbol
)
4917 as_warn (_(".name directive has no symbol"));
4918 demand_empty_rest_of_line ();
4922 demand_empty_rest_of_line ();
4924 #ifdef md_flush_pending_output
4925 md_flush_pending_output ();
4928 frag_align (3, 0, 0);
4930 seginfo
->literal_pool_size
+= 8;
4932 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 8, &exp
, 0, BFD_RELOC_64
);
4938 s_alpha_linkage (ignore
)
4944 #ifdef md_flush_pending_output
4945 md_flush_pending_output ();
4949 if (exp
.X_op
!= O_symbol
)
4951 as_fatal (_("No symbol after .linkage"));
4955 p
= frag_more (LKP_S_K_SIZE
);
4956 memset (p
, 0, LKP_S_K_SIZE
);
4957 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, LKP_S_K_SIZE
, &exp
, 0,\
4958 BFD_RELOC_ALPHA_LINKAGE
);
4960 demand_empty_rest_of_line ();
4966 s_alpha_code_address (ignore
)
4972 #ifdef md_flush_pending_output
4973 md_flush_pending_output ();
4977 if (exp
.X_op
!= O_symbol
)
4979 as_fatal (_("No symbol after .code_address"));
4985 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 8, &exp
, 0,\
4986 BFD_RELOC_ALPHA_CODEADDR
);
4988 demand_empty_rest_of_line ();
4994 s_alpha_fp_save (ignore
)
4998 alpha_evax_proc
.fp_save
= tc_get_register (1);
5000 demand_empty_rest_of_line ();
5005 s_alpha_mask (ignore
)
5010 if (get_absolute_expression_and_terminator (&val
) != ',')
5012 as_warn (_("Bad .mask directive"));
5013 --input_line_pointer
;
5017 alpha_evax_proc
.imask
= val
;
5018 (void) get_absolute_expression ();
5020 demand_empty_rest_of_line ();
5026 s_alpha_fmask (ignore
)
5031 if (get_absolute_expression_and_terminator (&val
) != ',')
5033 as_warn (_("Bad .fmask directive"));
5034 --input_line_pointer
;
5038 alpha_evax_proc
.fmask
= val
;
5039 (void) get_absolute_expression ();
5041 demand_empty_rest_of_line ();
5047 s_alpha_end (ignore
)
5052 c
= get_symbol_end ();
5053 *input_line_pointer
= c
;
5054 demand_empty_rest_of_line ();
5055 alpha_evax_proc
.symbol
= 0;
5061 s_alpha_file (ignore
)
5066 static char case_hack
[32];
5068 extern char *demand_copy_string
PARAMS ((int *lenP
));
5070 sprintf (case_hack
, "<CASE:%01d%01d>",
5071 alpha_flag_hash_long_names
, alpha_flag_show_after_trunc
);
5073 s
= symbol_find_or_make (case_hack
);
5074 symbol_get_bfdsym (s
)->flags
|= BSF_FILE
;
5076 get_absolute_expression ();
5077 s
= symbol_find_or_make (demand_copy_string (&length
));
5078 symbol_get_bfdsym (s
)->flags
|= BSF_FILE
;
5079 demand_empty_rest_of_line ();
5083 #endif /* OBJ_EVAX */
5085 /* Handle the .gprel32 pseudo op. */
5088 s_alpha_gprel32 (ignore
)
5089 int ignore ATTRIBUTE_UNUSED
;
5101 e
.X_add_symbol
= section_symbol (absolute_section
);
5114 e
.X_add_symbol
= section_symbol (absolute_section
);
5117 e
.X_op
= O_subtract
;
5118 e
.X_op_symbol
= alpha_gp_symbol
;
5126 if (alpha_auto_align_on
&& alpha_current_align
< 2)
5127 alpha_align (2, (char *) NULL
, alpha_insn_label
, 0);
5128 if (alpha_current_align
> 2)
5129 alpha_current_align
= 2;
5130 alpha_insn_label
= NULL
;
5134 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 4,
5135 &e
, 0, BFD_RELOC_GPREL32
);
5138 /* Handle floating point allocation pseudo-ops. This is like the
5139 generic vresion, but it makes sure the current label, if any, is
5140 correctly aligned. */
5143 s_alpha_float_cons (type
)
5170 if (alpha_auto_align_on
&& alpha_current_align
< log_size
)
5171 alpha_align (log_size
, (char *) NULL
, alpha_insn_label
, 0);
5172 if (alpha_current_align
> log_size
)
5173 alpha_current_align
= log_size
;
5174 alpha_insn_label
= NULL
;
5179 /* Handle the .proc pseudo op. We don't really do much with it except
5183 s_alpha_proc (is_static
)
5184 int is_static ATTRIBUTE_UNUSED
;
5192 /* Takes ".proc name,nargs" */
5194 name
= input_line_pointer
;
5195 c
= get_symbol_end ();
5196 p
= input_line_pointer
;
5197 symbolP
= symbol_find_or_make (name
);
5200 if (*input_line_pointer
!= ',')
5203 as_warn (_("Expected comma after name \"%s\""), name
);
5206 ignore_rest_of_line ();
5210 input_line_pointer
++;
5211 temp
= get_absolute_expression ();
5213 /* *symbol_get_obj (symbolP) = (signed char) temp; */
5214 as_warn (_("unhandled: .proc %s,%d"), name
, temp
);
5215 demand_empty_rest_of_line ();
5218 /* Handle the .set pseudo op. This is used to turn on and off most of
5219 the assembler features. */
5223 int x ATTRIBUTE_UNUSED
;
5229 name
= input_line_pointer
;
5230 ch
= get_symbol_end ();
5233 if (s
[0] == 'n' && s
[1] == 'o')
5238 if (!strcmp ("reorder", s
))
5240 else if (!strcmp ("at", s
))
5241 alpha_noat_on
= !yesno
;
5242 else if (!strcmp ("macro", s
))
5243 alpha_macros_on
= yesno
;
5244 else if (!strcmp ("move", s
))
5246 else if (!strcmp ("volatile", s
))
5249 as_warn (_("Tried to .set unrecognized mode `%s'"), name
);
5251 *input_line_pointer
= ch
;
5252 demand_empty_rest_of_line ();
5255 /* Handle the .base pseudo op. This changes the assembler's notion of
5256 the $gp register. */
5259 s_alpha_base (ignore
)
5260 int ignore ATTRIBUTE_UNUSED
;
5263 if (first_32bit_quadrant
)
5265 /* not fatal, but it might not work in the end */
5266 as_warn (_("File overrides no-base-register option."));
5267 first_32bit_quadrant
= 0;
5272 if (*input_line_pointer
== '$')
5274 input_line_pointer
++;
5275 if (*input_line_pointer
== 'r')
5276 input_line_pointer
++;
5279 alpha_gp_register
= get_absolute_expression ();
5280 if (alpha_gp_register
< 0 || alpha_gp_register
> 31)
5282 alpha_gp_register
= AXP_REG_GP
;
5283 as_warn (_("Bad base register, using $%d."), alpha_gp_register
);
5286 demand_empty_rest_of_line ();
5289 /* Handle the .align pseudo-op. This aligns to a power of two. It
5290 also adjusts any current instruction label. We treat this the same
5291 way the MIPS port does: .align 0 turns off auto alignment. */
5294 s_alpha_align (ignore
)
5295 int ignore ATTRIBUTE_UNUSED
;
5299 long max_alignment
= 15;
5301 align
= get_absolute_expression ();
5302 if (align
> max_alignment
)
5304 align
= max_alignment
;
5305 as_bad (_("Alignment too large: %d. assumed"), align
);
5309 as_warn (_("Alignment negative: 0 assumed"));
5313 if (*input_line_pointer
== ',')
5315 input_line_pointer
++;
5316 fill
= get_absolute_expression ();
5324 alpha_auto_align_on
= 1;
5325 alpha_align (align
, pfill
, alpha_insn_label
, 1);
5329 alpha_auto_align_on
= 0;
5332 demand_empty_rest_of_line ();
5335 /* Hook the normal string processor to reset known alignment. */
5338 s_alpha_stringer (terminate
)
5341 alpha_current_align
= 0;
5342 alpha_insn_label
= NULL
;
5343 stringer (terminate
);
5346 /* Hook the normal space processing to reset known alignment. */
5349 s_alpha_space (ignore
)
5352 alpha_current_align
= 0;
5353 alpha_insn_label
= NULL
;
5357 /* Hook into cons for auto-alignment. */
5360 alpha_cons_align (size
)
5366 while ((size
>>= 1) != 0)
5369 if (alpha_auto_align_on
&& alpha_current_align
< log_size
)
5370 alpha_align (log_size
, (char *) NULL
, alpha_insn_label
, 0);
5371 if (alpha_current_align
> log_size
)
5372 alpha_current_align
= log_size
;
5373 alpha_insn_label
= NULL
;
5376 /* Here come the .uword, .ulong, and .uquad explicitly unaligned
5377 pseudos. We just turn off auto-alignment and call down to cons. */
5380 s_alpha_ucons (bytes
)
5383 int hold
= alpha_auto_align_on
;
5384 alpha_auto_align_on
= 0;
5386 alpha_auto_align_on
= hold
;
5389 /* Switch the working cpu type. */
5392 s_alpha_arch (ignored
)
5393 int ignored ATTRIBUTE_UNUSED
;
5396 const struct cpu_type
*p
;
5399 name
= input_line_pointer
;
5400 ch
= get_symbol_end ();
5402 for (p
= cpu_types
; p
->name
; ++p
)
5403 if (strcmp (name
, p
->name
) == 0)
5405 alpha_target_name
= p
->name
, alpha_target
= p
->flags
;
5408 as_warn ("Unknown CPU identifier `%s'", name
);
5411 *input_line_pointer
= ch
;
5412 demand_empty_rest_of_line ();
5416 /* print token expression with alpha specific extension. */
5419 alpha_print_token (f
, exp
)
5421 const expressionS
*exp
;
5431 expressionS nexp
= *exp
;
5432 nexp
.X_op
= O_register
;
5433 print_expr (f
, &nexp
);
5438 print_expr (f
, exp
);
5445 /* The target specific pseudo-ops which we support. */
5447 const pseudo_typeS md_pseudo_table
[] = {
5449 {"comm", s_alpha_comm
, 0}, /* osf1 compiler does this */
5450 {"rdata", s_alpha_rdata
, 0},
5452 {"text", s_alpha_text
, 0},
5453 {"data", s_alpha_data
, 0},
5455 {"sdata", s_alpha_sdata
, 0},
5458 {"section", s_alpha_section
, 0},
5459 {"section.s", s_alpha_section
, 0},
5460 {"sect", s_alpha_section
, 0},
5461 {"sect.s", s_alpha_section
, 0},
5464 { "pdesc", s_alpha_pdesc
, 0},
5465 { "name", s_alpha_name
, 0},
5466 { "linkage", s_alpha_linkage
, 0},
5467 { "code_address", s_alpha_code_address
, 0},
5468 { "ent", s_alpha_ent
, 0},
5469 { "frame", s_alpha_frame
, 0},
5470 { "fp_save", s_alpha_fp_save
, 0},
5471 { "mask", s_alpha_mask
, 0},
5472 { "fmask", s_alpha_fmask
, 0},
5473 { "end", s_alpha_end
, 0},
5474 { "file", s_alpha_file
, 0},
5475 { "rdata", s_alpha_section
, 1},
5476 { "comm", s_alpha_comm
, 0},
5477 { "link", s_alpha_section
, 3},
5478 { "ctors", s_alpha_section
, 4},
5479 { "dtors", s_alpha_section
, 5},
5482 /* Frame related pseudos. */
5483 {"ent", s_alpha_ent
, 0},
5484 {"end", s_alpha_end
, 0},
5485 {"mask", s_alpha_mask
, 0},
5486 {"fmask", s_alpha_mask
, 1},
5487 {"frame", s_alpha_frame
, 0},
5488 {"prologue", s_alpha_prologue
, 0},
5489 {"file", s_alpha_file
, 5},
5490 {"loc", s_alpha_loc
, 9},
5491 {"stabs", s_alpha_stab
, 's'},
5492 {"stabn", s_alpha_stab
, 'n'},
5493 /* COFF debugging related pseudos. */
5494 {"begin", s_alpha_coff_wrapper
, 0},
5495 {"bend", s_alpha_coff_wrapper
, 1},
5496 {"def", s_alpha_coff_wrapper
, 2},
5497 {"dim", s_alpha_coff_wrapper
, 3},
5498 {"endef", s_alpha_coff_wrapper
, 4},
5499 {"scl", s_alpha_coff_wrapper
, 5},
5500 {"tag", s_alpha_coff_wrapper
, 6},
5501 {"val", s_alpha_coff_wrapper
, 7},
5503 {"prologue", s_ignore
, 0},
5505 {"gprel32", s_alpha_gprel32
, 0},
5506 {"t_floating", s_alpha_float_cons
, 'd'},
5507 {"s_floating", s_alpha_float_cons
, 'f'},
5508 {"f_floating", s_alpha_float_cons
, 'F'},
5509 {"g_floating", s_alpha_float_cons
, 'G'},
5510 {"d_floating", s_alpha_float_cons
, 'D'},
5512 {"proc", s_alpha_proc
, 0},
5513 {"aproc", s_alpha_proc
, 1},
5514 {"set", s_alpha_set
, 0},
5515 {"reguse", s_ignore
, 0},
5516 {"livereg", s_ignore
, 0},
5517 {"base", s_alpha_base
, 0}, /*??*/
5518 {"option", s_ignore
, 0},
5519 {"aent", s_ignore
, 0},
5520 {"ugen", s_ignore
, 0},
5521 {"eflag", s_ignore
, 0},
5523 {"align", s_alpha_align
, 0},
5524 {"double", s_alpha_float_cons
, 'd'},
5525 {"float", s_alpha_float_cons
, 'f'},
5526 {"single", s_alpha_float_cons
, 'f'},
5527 {"ascii", s_alpha_stringer
, 0},
5528 {"asciz", s_alpha_stringer
, 1},
5529 {"string", s_alpha_stringer
, 1},
5530 {"space", s_alpha_space
, 0},
5531 {"skip", s_alpha_space
, 0},
5532 {"zero", s_alpha_space
, 0},
5534 /* Unaligned data pseudos. */
5535 {"uword", s_alpha_ucons
, 2},
5536 {"ulong", s_alpha_ucons
, 4},
5537 {"uquad", s_alpha_ucons
, 8},
5540 /* Dwarf wants these versions of unaligned. */
5541 {"2byte", s_alpha_ucons
, 2},
5542 {"4byte", s_alpha_ucons
, 4},
5543 {"8byte", s_alpha_ucons
, 8},
5546 /* We don't do any optimizing, so we can safely ignore these. */
5547 {"noalias", s_ignore
, 0},
5548 {"alias", s_ignore
, 0},
5550 {"arch", s_alpha_arch
, 0},
5555 /* Build a BFD section with its flags set appropriately for the .lita,
5556 .lit8, or .lit4 sections. */
5559 create_literal_section (name
, secp
, symp
)
5564 segT current_section
= now_seg
;
5565 int current_subsec
= now_subseg
;
5568 *secp
= new_sec
= subseg_new (name
, 0);
5569 subseg_set (current_section
, current_subsec
);
5570 bfd_set_section_alignment (stdoutput
, new_sec
, 4);
5571 bfd_set_section_flags (stdoutput
, new_sec
,
5572 SEC_RELOC
| SEC_ALLOC
| SEC_LOAD
| SEC_READONLY
5575 S_CLEAR_EXTERNAL (*symp
= section_symbol (new_sec
));
5580 /* @@@ GP selection voodoo. All of this seems overly complicated and
5581 unnecessary; which is the primary reason it's for ECOFF only. */
5590 vma
= bfd_get_section_vma (foo
, sec
);
5591 if (vma
&& vma
< alpha_gp_value
)
5592 alpha_gp_value
= vma
;
5598 assert (alpha_gp_value
== 0);
5600 /* Get minus-one in whatever width... */
5604 /* Select the smallest VMA of these existing sections. */
5605 maybe_set_gp (alpha_lita_section
);
5607 /* These were disabled before -- should we use them? */
5608 maybe_set_gp (sdata
);
5609 maybe_set_gp (lit8_sec
);
5610 maybe_set_gp (lit4_sec
);
5613 /* @@ Will a simple 0x8000 work here? If not, why not? */
5614 #define GP_ADJUSTMENT (0x8000 - 0x10)
5616 alpha_gp_value
+= GP_ADJUSTMENT
;
5618 S_SET_VALUE (alpha_gp_symbol
, alpha_gp_value
);
5621 printf (_("Chose GP value of %lx\n"), alpha_gp_value
);
5624 #endif /* OBJ_ECOFF */
5627 /* Map 's' to SHF_ALPHA_GPREL. */
5630 alpha_elf_section_letter (letter
, ptr_msg
)
5635 return SHF_ALPHA_GPREL
;
5637 *ptr_msg
= _("Bad .section directive: want a,s,w,x,M,S,G,T in string");
5641 /* Map SHF_ALPHA_GPREL to SEC_SMALL_DATA. */
5644 alpha_elf_section_flags (flags
, attr
, type
)
5646 int attr
, type ATTRIBUTE_UNUSED
;
5648 if (attr
& SHF_ALPHA_GPREL
)
5649 flags
|= SEC_SMALL_DATA
;
5652 #endif /* OBJ_ELF */
5654 /* Called internally to handle all alignment needs. This takes care
5655 of eliding calls to frag_align if'n the cached current alignment
5656 says we've already got it, as well as taking care of the auto-align
5657 feature wrt labels. */
5660 alpha_align (n
, pfill
, label
, force
)
5664 int force ATTRIBUTE_UNUSED
;
5666 if (alpha_current_align
>= n
)
5671 if (subseg_text_p (now_seg
))
5672 frag_align_code (n
, 0);
5674 frag_align (n
, 0, 0);
5677 frag_align (n
, *pfill
, 0);
5679 alpha_current_align
= n
;
5681 if (label
!= NULL
&& S_GET_SEGMENT (label
) == now_seg
)
5683 symbol_set_frag (label
, frag_now
);
5684 S_SET_VALUE (label
, (valueT
) frag_now_fix ());
5687 record_alignment (now_seg
, n
);
5689 /* ??? If alpha_flag_relax && force && elf, record the requested alignment
5690 in a reloc for the linker to see. */
5693 /* This is called from HANDLE_ALIGN in write.c. Fill in the contents
5694 of an rs_align_code fragment. */
5697 alpha_handle_align (fragp
)
5700 static char const unop
[4] = { 0x00, 0x00, 0xfe, 0x2f };
5701 static char const nopunop
[8] = {
5702 0x1f, 0x04, 0xff, 0x47,
5703 0x00, 0x00, 0xfe, 0x2f
5709 if (fragp
->fr_type
!= rs_align_code
)
5712 bytes
= fragp
->fr_next
->fr_address
- fragp
->fr_address
- fragp
->fr_fix
;
5713 p
= fragp
->fr_literal
+ fragp
->fr_fix
;
5726 memcpy (p
, unop
, 4);
5732 memcpy (p
, nopunop
, 8);
5734 fragp
->fr_fix
+= fix
;
5738 /* The Alpha has support for some VAX floating point types, as well as for
5739 IEEE floating point. We consider IEEE to be the primary floating point
5740 format, and sneak in the VAX floating point support here. */
5741 #define md_atof vax_md_atof
5742 #include "config/atof-vax.c"