1 /* tc-alpha.c - Processor-specific code for the DEC Alpha AXP CPU.
2 Copyright (C) 1989, 93, 94, 95, 96, 1997, 1998 Free Software Foundation, Inc.
3 Contributed by Carnegie Mellon University, 1993.
4 Written by Alessandro Forin, based on earlier gas-1.38 target CPU files.
5 Modified by Ken Raeburn for gas-2.x and ECOFF support.
6 Modified by Richard Henderson for ELF support.
7 Modified by Klaus K"ampf for EVAX (openVMS/Alpha) support.
9 This file is part of GAS, the GNU Assembler.
11 GAS is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2, or (at your option)
16 GAS is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with GAS; see the file COPYING. If not, write to the Free
23 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
27 * Mach Operating System
28 * Copyright (c) 1993 Carnegie Mellon University
29 * All Rights Reserved.
31 * Permission to use, copy, modify and distribute this software and its
32 * documentation is hereby granted, provided that both the copyright
33 * notice and this permission notice appear in all copies of the
34 * software, derivative works or modified versions, and any portions
35 * thereof, and that both notices appear in supporting documentation.
37 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
38 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
39 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
41 * Carnegie Mellon requests users of this software to return to
43 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
44 * School of Computer Science
45 * Carnegie Mellon University
46 * Pittsburgh PA 15213-3890
48 * any improvements or extensions that they make and grant Carnegie the
49 * rights to redistribute these changes.
55 #include "opcode/alpha.h"
58 #include "elf/alpha.h"
66 #define MAX_INSN_FIXUPS 2
67 #define MAX_INSN_ARGS 5
72 bfd_reloc_code_real_type reloc
;
79 struct alpha_fixup fixups
[MAX_INSN_FIXUPS
];
84 MACRO_EOA
= 1, MACRO_IR
, MACRO_PIR
, MACRO_CPIR
, MACRO_FPR
, MACRO_EXP
90 void (*emit
) PARAMS ((const expressionS
*, int, const PTR
));
92 enum alpha_macro_arg argsets
[16];
95 /* Two extra symbols we want to see in our input. This is a blatent
96 misuse of the expressionS.X_op field. */
98 #define O_pregister (O_max+1) /* O_register, but in parentheses */
99 #define O_cpregister (O_pregister+1) /* + a leading comma */
101 /* Macros for extracting the type and number of encoded register tokens */
103 #define is_ir_num(x) (((x) & 32) == 0)
104 #define is_fpr_num(x) (((x) & 32) != 0)
105 #define regno(x) ((x) & 31)
107 /* Something odd inherited from the old assembler */
109 #define note_gpreg(R) (alpha_gprmask |= (1 << (R)))
110 #define note_fpreg(R) (alpha_fprmask |= (1 << (R)))
112 /* Predicates for 16- and 32-bit ranges */
113 /* XXX: The non-shift version appears to trigger a compiler bug when
114 cross-assembling from x86 w/ gcc 2.7.2. */
117 #define range_signed_16(x) \
118 (((offsetT)(x) >> 15) == 0 || ((offsetT)(x) >> 15) == -1)
119 #define range_signed_32(x) \
120 (((offsetT)(x) >> 31) == 0 || ((offsetT)(x) >> 31) == -1)
122 #define range_signed_16(x) ((offsetT)(x) >= -(offsetT)0x8000 && \
123 (offsetT)(x) <= (offsetT)0x7FFF)
124 #define range_signed_32(x) ((offsetT)(x) >= -(offsetT)0x80000000 && \
125 (offsetT)(x) <= (offsetT)0x7FFFFFFF)
128 /* Macros for sign extending from 16- and 32-bits. */
129 /* XXX: The cast macros will work on all the systems that I care about,
130 but really a predicate should be found to use the non-cast forms. */
133 #define sign_extend_16(x) ((short)(x))
134 #define sign_extend_32(x) ((int)(x))
136 #define sign_extend_16(x) ((offsetT)(((x) & 0xFFFF) ^ 0x8000) - 0x8000)
137 #define sign_extend_32(x) ((offsetT)(((x) & 0xFFFFFFFF) \
138 ^ 0x80000000) - 0x80000000)
141 /* Macros to build tokens */
143 #define set_tok_reg(t, r) (memset(&(t), 0, sizeof(t)), \
144 (t).X_op = O_register, \
145 (t).X_add_number = (r))
146 #define set_tok_preg(t, r) (memset(&(t), 0, sizeof(t)), \
147 (t).X_op = O_pregister, \
148 (t).X_add_number = (r))
149 #define set_tok_cpreg(t, r) (memset(&(t), 0, sizeof(t)), \
150 (t).X_op = O_cpregister, \
151 (t).X_add_number = (r))
152 #define set_tok_freg(t, r) (memset(&(t), 0, sizeof(t)), \
153 (t).X_op = O_register, \
154 (t).X_add_number = (r)+32)
155 #define set_tok_sym(t, s, a) (memset(&(t), 0, sizeof(t)), \
156 (t).X_op = O_symbol, \
157 (t).X_add_symbol = (s), \
158 (t).X_add_number = (a))
159 #define set_tok_const(t, n) (memset(&(t), 0, sizeof(t)), \
160 (t).X_op = O_constant, \
161 (t).X_add_number = (n))
164 /* Prototypes for all local functions */
166 static int tokenize_arguments
PARAMS ((char *, expressionS
*, int));
167 static const struct alpha_opcode
*find_opcode_match
168 PARAMS ((const struct alpha_opcode
*, const expressionS
*, int *, int *));
169 static const struct alpha_macro
*find_macro_match
170 PARAMS ((const struct alpha_macro
*, const expressionS
*, int *));
171 static unsigned insert_operand
172 PARAMS ((unsigned, const struct alpha_operand
*, offsetT
, char *, unsigned));
173 static void assemble_insn
174 PARAMS ((const struct alpha_opcode
*, const expressionS
*, int,
175 struct alpha_insn
*));
176 static void emit_insn
PARAMS ((struct alpha_insn
*));
177 static void assemble_tokens_to_insn
178 PARAMS ((const char *, const expressionS
*, int, struct alpha_insn
*));
179 static void assemble_tokens
180 PARAMS ((const char *, const expressionS
*, int, int));
182 static int load_expression
183 PARAMS ((int, const expressionS
*, int *, expressionS
*));
185 static void emit_ldgp
PARAMS ((const expressionS
*, int, const PTR
));
186 static void emit_division
PARAMS ((const expressionS
*, int, const PTR
));
187 static void emit_lda
PARAMS ((const expressionS
*, int, const PTR
));
188 static void emit_ldah
PARAMS ((const expressionS
*, int, const PTR
));
189 static void emit_ir_load
PARAMS ((const expressionS
*, int, const PTR
));
190 static void emit_loadstore
PARAMS ((const expressionS
*, int, const PTR
));
191 static void emit_jsrjmp
PARAMS ((const expressionS
*, int, const PTR
));
192 static void emit_ldX
PARAMS ((const expressionS
*, int, const PTR
));
193 static void emit_ldXu
PARAMS ((const expressionS
*, int, const PTR
));
194 static void emit_uldX
PARAMS ((const expressionS
*, int, const PTR
));
195 static void emit_uldXu
PARAMS ((const expressionS
*, int, const PTR
));
196 static void emit_ldil
PARAMS ((const expressionS
*, int, const PTR
));
197 static void emit_stX
PARAMS ((const expressionS
*, int, const PTR
));
198 static void emit_ustX
PARAMS ((const expressionS
*, int, const PTR
));
199 static void emit_sextX
PARAMS ((const expressionS
*, int, const PTR
));
200 static void emit_retjcr
PARAMS ((const expressionS
*, int, const PTR
));
202 static void s_alpha_text
PARAMS ((int));
203 static void s_alpha_data
PARAMS ((int));
205 static void s_alpha_comm
PARAMS ((int));
207 #if defined (OBJ_ECOFF) || defined (OBJ_EVAX)
208 static void s_alpha_rdata
PARAMS ((int));
211 static void s_alpha_sdata
PARAMS ((int));
214 static void s_alpha_section
PARAMS ((int));
217 static void s_alpha_section
PARAMS ((int));
219 static void s_alpha_gprel32
PARAMS ((int));
220 static void s_alpha_float_cons
PARAMS ((int));
221 static void s_alpha_proc
PARAMS ((int));
222 static void s_alpha_set
PARAMS ((int));
223 static void s_alpha_base
PARAMS ((int));
224 static void s_alpha_align
PARAMS ((int));
225 static void s_alpha_stringer
PARAMS ((int));
226 static void s_alpha_space
PARAMS ((int));
228 static void create_literal_section
PARAMS ((const char *, segT
*, symbolS
**));
230 static void select_gp_value
PARAMS ((void));
232 static void alpha_align
PARAMS ((int, char *, symbolS
*, int));
235 /* Generic assembler global variables which must be defined by all
238 /* These are exported to relaxing code, even though we don't do any
239 relaxing on this processor currently. */
240 int md_short_jump_size
= 4;
241 int md_long_jump_size
= 4;
243 /* Characters which always start a comment. */
244 const char comment_chars
[] = "#";
246 /* Characters which start a comment at the beginning of a line. */
247 const char line_comment_chars
[] = "#";
249 /* Characters which may be used to separate multiple commands on a
251 const char line_separator_chars
[] = ";";
253 /* Characters which are used to indicate an exponent in a floating
255 const char EXP_CHARS
[] = "eE";
257 /* Characters which mean that a number is a floating point constant,
260 const char FLT_CHARS
[] = "dD";
262 /* XXX: Do all of these really get used on the alpha?? */
263 char FLT_CHARS
[] = "rRsSfFdDxXpP";
267 const char *md_shortopts
= "Fm:g+1h:HG:";
269 const char *md_shortopts
= "Fm:gG:";
272 struct option md_longopts
[] = {
273 #define OPTION_32ADDR (OPTION_MD_BASE)
274 { "32addr", no_argument
, NULL
, OPTION_32ADDR
},
275 #define OPTION_RELAX (OPTION_32ADDR+1)
276 { "relax", no_argument
, NULL
, OPTION_RELAX
},
277 { NULL
, no_argument
, NULL
, 0 }
280 size_t md_longopts_size
= sizeof(md_longopts
);
285 #define AXP_REG_R16 16
286 #define AXP_REG_R17 17
288 #define AXP_REG_T9 22
290 #define AXP_REG_T10 23
292 #define AXP_REG_T11 24
294 #define AXP_REG_T12 25
295 #define AXP_REG_AI 25
297 #define AXP_REG_FP 29
300 #define AXP_REG_GP AXP_REG_PV
301 #endif /* OBJ_EVAX */
303 /* The cpu for which we are generating code */
304 static unsigned alpha_target
= AXP_OPCODE_BASE
;
305 static const char *alpha_target_name
= "<all>";
307 /* The hash table of instruction opcodes */
308 static struct hash_control
*alpha_opcode_hash
;
310 /* The hash table of macro opcodes */
311 static struct hash_control
*alpha_macro_hash
;
314 /* The $gp relocation symbol */
315 static symbolS
*alpha_gp_symbol
;
317 /* XXX: what is this, and why is it exported? */
318 valueT alpha_gp_value
;
321 /* The current $gp register */
322 static int alpha_gp_register
= AXP_REG_GP
;
324 /* A table of the register symbols */
325 static symbolS
*alpha_register_table
[64];
327 /* Constant sections, or sections of constants */
329 static segT alpha_lita_section
;
330 static segT alpha_lit4_section
;
333 static segT alpha_link_section
;
334 static segT alpha_ctors_section
;
335 static segT alpha_dtors_section
;
337 static segT alpha_lit8_section
;
339 /* Symbols referring to said sections. */
341 static symbolS
*alpha_lita_symbol
;
342 static symbolS
*alpha_lit4_symbol
;
345 static symbolS
*alpha_link_symbol
;
346 static symbolS
*alpha_ctors_symbol
;
347 static symbolS
*alpha_dtors_symbol
;
349 static symbolS
*alpha_lit8_symbol
;
351 /* Literal for .litX+0x8000 within .lita */
353 static offsetT alpha_lit4_literal
;
354 static offsetT alpha_lit8_literal
;
357 /* Is the assembler not allowed to use $at? */
358 static int alpha_noat_on
= 0;
360 /* Are macros enabled? */
361 static int alpha_macros_on
= 1;
363 /* Are floats disabled? */
364 static int alpha_nofloats_on
= 0;
366 /* Are addresses 32 bit? */
367 static int alpha_addr32_on
= 0;
369 /* Symbol labelling the current insn. When the Alpha gas sees
372 and the section happens to not be on an eight byte boundary, it
373 will align both the symbol and the .quad to an eight byte boundary. */
374 static symbolS
*alpha_insn_label
;
376 /* Whether we should automatically align data generation pseudo-ops.
377 .align 0 will turn this off. */
378 static int alpha_auto_align_on
= 1;
380 /* The known current alignment of the current section. */
381 static int alpha_current_align
;
383 /* These are exported to ECOFF code. */
384 unsigned long alpha_gprmask
, alpha_fprmask
;
386 /* Whether the debugging option was seen. */
387 static int alpha_debug
;
389 /* Don't fully resolve relocations, allowing code movement in the linker. */
390 static int alpha_flag_relax
;
392 /* What value to give to bfd_set_gp_size. */
393 static int g_switch_value
= 8;
396 /* Collect information about current procedure here. */
398 symbolS
*symbol
; /* proc pdesc symbol */
400 int framereg
; /* register for frame pointer */
401 int framesize
; /* size of frame */
411 static int alpha_flag_hash_long_names
= 0; /* -+ */
412 static int alpha_flag_show_after_trunc
= 0; /* -H */
414 /* If the -+ switch is given, then a hash is appended to any name that is
415 * longer than 64 characters, else longer symbol names are truncated.
420 /* A table of CPU names and opcode sets. */
422 static const struct cpu_type
428 /* Ad hoc convention: cpu number gets palcode, process code doesn't.
429 This supports usage under DU 4.0b that does ".arch ev4", and
430 usage in MILO that does -m21064. Probably something more
431 specific like -m21064-pal should be used, but oh well. */
433 { "21064", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
434 { "21064a", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
435 { "21066", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
436 { "21068", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
437 { "21164", AXP_OPCODE_BASE
|AXP_OPCODE_EV5
},
438 /* Do we have CIX extension here? */
439 { "21164a", AXP_OPCODE_BASE
|AXP_OPCODE_EV5
|AXP_OPCODE_BWX
},
440 /* Still same PALcodes? */
441 { "21164pc", (AXP_OPCODE_BASE
|AXP_OPCODE_EV5
|AXP_OPCODE_BWX
443 /* All new PALcodes? Extras? */
444 { "21264", (AXP_OPCODE_BASE
|AXP_OPCODE_BWX
445 |AXP_OPCODE_CIX
|AXP_OPCODE_MAX
) },
447 { "ev4", AXP_OPCODE_BASE
},
448 { "ev45", AXP_OPCODE_BASE
},
449 { "lca45", AXP_OPCODE_BASE
},
450 { "ev5", AXP_OPCODE_BASE
},
451 { "ev56", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
},
452 { "pca56", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
|AXP_OPCODE_MAX
},
453 { "ev6", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
|AXP_OPCODE_CIX
|AXP_OPCODE_MAX
},
455 { "all", AXP_OPCODE_BASE
},
459 /* The macro table */
461 static const struct alpha_macro alpha_macros
[] = {
462 /* Load/Store macros */
463 { "lda", emit_lda
, NULL
,
464 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
465 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
466 { "ldah", emit_ldah
, NULL
,
467 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
469 { "ldl", emit_ir_load
, "ldl",
470 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
471 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
472 { "ldl_l", emit_ir_load
, "ldl_l",
473 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
474 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
475 { "ldq", emit_ir_load
, "ldq",
476 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
477 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
478 { "ldq_l", emit_ir_load
, "ldq_l",
479 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
480 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
481 { "ldq_u", emit_ir_load
, "ldq_u",
482 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
483 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
484 { "ldf", emit_loadstore
, "ldf",
485 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
486 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
487 { "ldg", emit_loadstore
, "ldg",
488 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
489 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
490 { "lds", emit_loadstore
, "lds",
491 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
492 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
493 { "ldt", emit_loadstore
, "ldt",
494 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
495 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
497 { "ldb", emit_ldX
, (PTR
)0,
498 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
499 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
500 { "ldbu", emit_ldXu
, (PTR
)0,
501 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
502 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
503 { "ldw", emit_ldX
, (PTR
)1,
504 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
505 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
506 { "ldwu", emit_ldXu
, (PTR
)1,
507 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
508 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
510 { "uldw", emit_uldX
, (PTR
)1,
511 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
512 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
513 { "uldwu", emit_uldXu
, (PTR
)1,
514 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
515 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
516 { "uldl", emit_uldX
, (PTR
)2,
517 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
518 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
519 { "uldlu", emit_uldXu
, (PTR
)2,
520 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
521 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
522 { "uldq", emit_uldXu
, (PTR
)3,
523 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
524 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
526 { "ldgp", emit_ldgp
, NULL
,
527 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
} },
529 { "ldi", emit_lda
, NULL
,
530 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
531 { "ldil", emit_ldil
, NULL
,
532 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
533 { "ldiq", emit_lda
, NULL
,
534 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
536 { "ldif" emit_ldiq
, NULL
,
537 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
538 { "ldid" emit_ldiq
, NULL
,
539 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
540 { "ldig" emit_ldiq
, NULL
,
541 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
542 { "ldis" emit_ldiq
, NULL
,
543 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
544 { "ldit" emit_ldiq
, NULL
,
545 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
548 { "stl", emit_loadstore
, "stl",
549 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
550 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
551 { "stl_c", emit_loadstore
, "stl_c",
552 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
553 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
554 { "stq", emit_loadstore
, "stq",
555 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
556 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
557 { "stq_c", emit_loadstore
, "stq_c",
558 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
559 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
560 { "stq_u", emit_loadstore
, "stq_u",
561 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
562 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
563 { "stf", emit_loadstore
, "stf",
564 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
565 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
566 { "stg", emit_loadstore
, "stg",
567 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
568 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
569 { "sts", emit_loadstore
, "sts",
570 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
571 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
572 { "stt", emit_loadstore
, "stt",
573 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
574 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
576 { "stb", emit_stX
, (PTR
)0,
577 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
578 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
579 { "stw", emit_stX
, (PTR
)1,
580 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
581 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
582 { "ustw", emit_ustX
, (PTR
)1,
583 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
584 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
585 { "ustl", emit_ustX
, (PTR
)2,
586 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
587 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
588 { "ustq", emit_ustX
, (PTR
)3,
589 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
590 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
592 /* Arithmetic macros */
594 { "absl" emit_absl
, 1, { IR
} },
595 { "absl" emit_absl
, 2, { IR
, IR
} },
596 { "absl" emit_absl
, 2, { EXP
, IR
} },
597 { "absq" emit_absq
, 1, { IR
} },
598 { "absq" emit_absq
, 2, { IR
, IR
} },
599 { "absq" emit_absq
, 2, { EXP
, IR
} },
602 { "sextb", emit_sextX
, (PTR
)0,
603 { MACRO_IR
, MACRO_IR
, MACRO_EOA
,
605 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
606 { "sextw", emit_sextX
, (PTR
)1,
607 { MACRO_IR
, MACRO_IR
, MACRO_EOA
,
609 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
611 { "divl", emit_division
, "__divl",
612 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
613 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
614 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
615 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
616 { "divlu", emit_division
, "__divlu",
617 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
618 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
619 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
620 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
621 { "divq", emit_division
, "__divq",
622 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
623 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
624 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
625 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
626 { "divqu", emit_division
, "__divqu",
627 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
628 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
629 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
630 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
631 { "reml", emit_division
, "__reml",
632 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
633 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
634 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
635 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
636 { "remlu", emit_division
, "__remlu",
637 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
638 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
639 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
640 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
641 { "remq", emit_division
, "__remq",
642 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
643 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
644 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
645 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
646 { "remqu", emit_division
, "__remqu",
647 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
648 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
649 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
650 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
652 { "jsr", emit_jsrjmp
, "jsr",
653 { MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
654 MACRO_PIR
, MACRO_EOA
,
655 MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
656 MACRO_EXP
, MACRO_EOA
} },
657 { "jmp", emit_jsrjmp
, "jmp",
658 { MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
659 MACRO_PIR
, MACRO_EOA
,
660 MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
661 MACRO_EXP
, MACRO_EOA
} },
662 { "ret", emit_retjcr
, "ret",
663 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
665 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
666 MACRO_PIR
, MACRO_EOA
,
667 MACRO_EXP
, MACRO_EOA
,
669 { "jcr", emit_retjcr
, "jcr",
670 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
672 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
673 MACRO_PIR
, MACRO_EOA
,
674 MACRO_EXP
, MACRO_EOA
,
676 { "jsr_coroutine", emit_retjcr
, "jcr",
677 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
679 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
680 MACRO_PIR
, MACRO_EOA
,
681 MACRO_EXP
, MACRO_EOA
,
685 static const int alpha_num_macros
686 = sizeof(alpha_macros
) / sizeof(*alpha_macros
);
688 /* Public interface functions */
690 /* This function is called once, at assembler startup time. It sets
691 up all the tables, etc. that the MD part of the assembler will
692 need, that can be determined before arguments are parsed. */
699 /* Create the opcode hash table */
701 alpha_opcode_hash
= hash_new ();
702 for (i
= 0; i
< alpha_num_opcodes
; )
704 const char *name
, *retval
, *slash
;
706 name
= alpha_opcodes
[i
].name
;
707 retval
= hash_insert (alpha_opcode_hash
, name
, (PTR
)&alpha_opcodes
[i
]);
709 as_fatal (_("internal error: can't hash opcode `%s': %s"), name
, retval
);
711 /* Some opcodes include modifiers of various sorts with a "/mod"
712 syntax, like the architecture manual suggests. However, for
713 use with gcc at least, we also need access to those same opcodes
716 if ((slash
= strchr (name
, '/')) != NULL
)
718 char *p
= xmalloc (strlen (name
));
719 memcpy (p
, name
, slash
- name
);
720 strcpy (p
+ (slash
- name
), slash
+ 1);
722 (void)hash_insert(alpha_opcode_hash
, p
, (PTR
)&alpha_opcodes
[i
]);
723 /* Ignore failures -- the opcode table does duplicate some
724 variants in different forms, like "hw_stq" and "hw_st/q". */
727 while (++i
< alpha_num_opcodes
728 && (alpha_opcodes
[i
].name
== name
729 || !strcmp (alpha_opcodes
[i
].name
, name
)))
733 /* Create the macro hash table */
735 alpha_macro_hash
= hash_new ();
736 for (i
= 0; i
< alpha_num_macros
; )
738 const char *name
, *retval
;
740 name
= alpha_macros
[i
].name
;
741 retval
= hash_insert (alpha_macro_hash
, name
, (PTR
)&alpha_macros
[i
]);
743 as_fatal (_("internal error: can't hash macro `%s': %s"), name
, retval
);
745 while (++i
< alpha_num_macros
746 && (alpha_macros
[i
].name
== name
747 || !strcmp (alpha_macros
[i
].name
, name
)))
751 /* Construct symbols for each of the registers */
753 for (i
= 0; i
< 32; ++i
)
756 sprintf(name
, "$%d", i
);
757 alpha_register_table
[i
] = symbol_create(name
, reg_section
, i
,
763 sprintf(name
, "$f%d", i
-32);
764 alpha_register_table
[i
] = symbol_create(name
, reg_section
, i
,
768 /* Create the special symbols and sections we'll be using */
770 /* So .sbss will get used for tiny objects. */
771 bfd_set_gp_size (stdoutput
, g_switch_value
);
774 create_literal_section (".lita", &alpha_lita_section
, &alpha_lita_symbol
);
776 /* For handling the GP, create a symbol that won't be output in the
777 symbol table. We'll edit it out of relocs later. */
778 alpha_gp_symbol
= symbol_create ("<GP value>", alpha_lita_section
, 0x8000,
783 create_literal_section (".link", &alpha_link_section
, &alpha_link_symbol
);
791 sec
= subseg_new(".mdebug", (subsegT
)0);
792 bfd_set_section_flags(stdoutput
, sec
, SEC_HAS_CONTENTS
|SEC_READONLY
);
793 bfd_set_section_alignment(stdoutput
, sec
, 3);
796 sec
= subseg_new(".reginfo", (subsegT
)0);
797 /* The ABI says this section should be loaded so that the running
798 program can access it. */
799 bfd_set_section_flags(stdoutput
, sec
,
800 SEC_ALLOC
|SEC_LOAD
|SEC_READONLY
|SEC_DATA
);
801 bfd_set_section_alignement(stdoutput
, sec
, 3);
806 subseg_set(text_section
, 0);
809 /* The public interface to the instruction assembler. */
815 char opname
[32]; /* current maximum is 13 */
816 expressionS tok
[MAX_INSN_ARGS
];
817 int ntok
, opnamelen
, trunclen
;
819 /* split off the opcode */
820 opnamelen
= strspn (str
, "abcdefghijklmnopqrstuvwxyz_/48");
821 trunclen
= (opnamelen
< sizeof (opname
) - 1
823 : sizeof (opname
) - 1);
824 memcpy (opname
, str
, trunclen
);
825 opname
[trunclen
] = '\0';
827 /* tokenize the rest of the line */
828 if ((ntok
= tokenize_arguments (str
+ opnamelen
, tok
, MAX_INSN_ARGS
)) < 0)
830 as_bad (_("syntax error"));
835 assemble_tokens (opname
, tok
, ntok
, alpha_macros_on
);
838 /* Round up a section's size to the appropriate boundary. */
841 md_section_align (seg
, size
)
845 int align
= bfd_get_section_alignment(stdoutput
, seg
);
846 valueT mask
= ((valueT
)1 << align
) - 1;
848 return (size
+ mask
) & ~mask
;
851 /* Turn a string in input_line_pointer into a floating point constant
852 of type type, and store the appropriate bytes in *litP. The number
853 of LITTLENUMS emitted is stored in *sizeP. An error message is
854 returned, or NULL on OK. */
856 /* Equal to MAX_PRECISION in atof-ieee.c */
857 #define MAX_LITTLENUMS 6
859 extern char *vax_md_atof
PARAMS ((int, char *, int *));
862 md_atof (type
, litP
, sizeP
)
868 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
869 LITTLENUM_TYPE
*wordP
;
876 /* VAX md_atof doesn't like "G" for some reason. */
880 return vax_md_atof (type
, litP
, sizeP
);
903 return _("Bad call to MD_ATOF()");
905 t
= atof_ieee (input_line_pointer
, type
, words
);
907 input_line_pointer
= t
;
908 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
910 for (wordP
= words
+ prec
- 1; prec
--;)
912 md_number_to_chars (litP
, (long) (*wordP
--), sizeof (LITTLENUM_TYPE
));
913 litP
+= sizeof (LITTLENUM_TYPE
);
919 /* Take care of the target-specific command-line options. */
922 md_parse_option (c
, arg
)
929 alpha_nofloats_on
= 1;
941 g_switch_value
= atoi(arg
);
946 const struct cpu_type
*p
;
947 for (p
= cpu_types
; p
->name
; ++p
)
948 if (strcmp(arg
, p
->name
) == 0)
950 alpha_target_name
= p
->name
, alpha_target
= p
->flags
;
953 as_warn(_("Unknown CPU identifier `%s'"), arg
);
959 case '+': /* For g++. Hash any name > 63 chars long. */
960 alpha_flag_hash_long_names
= 1;
963 case 'H': /* Show new symbol after hash truncation */
964 alpha_flag_show_after_trunc
= 1;
967 case 'h': /* for gnu-c/vax compatibility. */
972 alpha_flag_relax
= 1;
982 /* Print a description of the command-line options that we accept. */
985 md_show_usage (stream
)
990 -32addr treat addresses as 32-bit values\n\
991 -F lack floating point instructions support\n\
992 -m21064 | -m21066 | -m21164 | -m21164a\n\
993 -mev4 | -mev45 | -mev5 | -mev56 | -mall\n\
994 specify variant of Alpha architecture\n"),
999 -+ hash encode (don't truncate) names longer than 64 characters\n\
1000 -H show new symbol after hash truncation\n"),
1005 /* Decide from what point a pc-relative relocation is relative to,
1006 relative to the pc-relative fixup. Er, relatively speaking. */
1009 md_pcrel_from (fixP
)
1012 valueT addr
= fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
1013 switch (fixP
->fx_r_type
)
1015 case BFD_RELOC_ALPHA_GPDISP
:
1016 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1017 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1020 return fixP
->fx_size
+ addr
;
1024 /* Attempt to simplify or even eliminate a fixup. The return value is
1025 ignored; perhaps it was once meaningful, but now it is historical.
1026 To indicate that a fixup has been eliminated, set fixP->fx_done.
1028 For ELF, here it is that we transform the GPDISP_HI16 reloc we used
1029 internally into the GPDISP reloc used externally. We had to do
1030 this so that we'd have the GPDISP_LO16 reloc as a tag to compute
1031 the distance to the "lda" instruction for setting the addend to
1035 md_apply_fix (fixP
, valueP
)
1039 char * const fixpos
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
1040 valueT value
= *valueP
;
1041 unsigned image
, size
;
1043 switch (fixP
->fx_r_type
)
1045 /* The GPDISP relocations are processed internally with a symbol
1046 referring to the current function; we need to drop in a value
1047 which, when added to the address of the start of the function,
1048 gives the desired GP. */
1049 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1051 fixS
*next
= fixP
->fx_next
;
1052 assert (next
->fx_r_type
== BFD_RELOC_ALPHA_GPDISP_LO16
);
1054 fixP
->fx_offset
= (next
->fx_frag
->fr_address
+ next
->fx_where
1055 - fixP
->fx_frag
->fr_address
- fixP
->fx_where
);
1057 value
= (value
- sign_extend_16 (value
)) >> 16;
1060 fixP
->fx_r_type
= BFD_RELOC_ALPHA_GPDISP
;
1064 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1065 value
= sign_extend_16 (value
);
1066 fixP
->fx_offset
= 0;
1072 fixP
->fx_addsy
= section_symbol (absolute_section
);
1073 md_number_to_chars (fixpos
, value
, 2);
1078 fixP
->fx_r_type
= BFD_RELOC_16_PCREL
;
1083 fixP
->fx_r_type
= BFD_RELOC_32_PCREL
;
1088 fixP
->fx_r_type
= BFD_RELOC_64_PCREL
;
1091 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
1093 md_number_to_chars (fixpos
, value
, size
);
1099 case BFD_RELOC_GPREL32
:
1100 assert (fixP
->fx_subsy
== alpha_gp_symbol
);
1102 /* FIXME: inherited this obliviousness of `value' -- why? */
1103 md_number_to_chars (fixpos
, -alpha_gp_value
, 4);
1107 case BFD_RELOC_GPREL32
:
1111 case BFD_RELOC_23_PCREL_S2
:
1112 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
1114 image
= bfd_getl32(fixpos
);
1115 image
= (image
& ~0x1FFFFF) | ((value
>> 2) & 0x1FFFFF);
1120 case BFD_RELOC_ALPHA_HINT
:
1121 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
1123 image
= bfd_getl32(fixpos
);
1124 image
= (image
& ~0x3FFF) | ((value
>> 2) & 0x3FFF);
1130 case BFD_RELOC_ALPHA_LITERAL
:
1131 md_number_to_chars (fixpos
, value
, 2);
1134 case BFD_RELOC_ALPHA_LITUSE
:
1138 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1139 case BFD_RELOC_ALPHA_LITUSE
:
1143 case BFD_RELOC_ALPHA_LINKAGE
:
1144 case BFD_RELOC_ALPHA_CODEADDR
:
1150 const struct alpha_operand
*operand
;
1152 if ((int)fixP
->fx_r_type
>= 0)
1153 as_fatal (_("unhandled relocation type %s"),
1154 bfd_get_reloc_code_name (fixP
->fx_r_type
));
1156 assert (-(int)fixP
->fx_r_type
< alpha_num_operands
);
1157 operand
= &alpha_operands
[-(int)fixP
->fx_r_type
];
1159 /* The rest of these fixups only exist internally during symbol
1160 resolution and have no representation in the object file.
1161 Therefore they must be completely resolved as constants. */
1163 if (fixP
->fx_addsy
!= 0
1164 && fixP
->fx_addsy
->bsym
->section
!= absolute_section
)
1165 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
1166 _("non-absolute expression in constant field"));
1168 image
= bfd_getl32(fixpos
);
1169 image
= insert_operand(image
, operand
, (offsetT
)value
,
1170 fixP
->fx_file
, fixP
->fx_line
);
1175 if (fixP
->fx_addsy
!= 0 || fixP
->fx_pcrel
!= 0)
1179 as_warn_where(fixP
->fx_file
, fixP
->fx_line
,
1180 _("type %d reloc done?\n"), (int)fixP
->fx_r_type
);
1185 md_number_to_chars(fixpos
, image
, 4);
1193 * Look for a register name in the given symbol.
1197 md_undefined_symbol(name
)
1202 int is_float
= 0, num
;
1207 if (name
[1] == 'p' && name
[2] == '\0')
1208 return alpha_register_table
[AXP_REG_FP
];
1213 if (!isdigit(*++name
))
1217 case '0': case '1': case '2': case '3': case '4':
1218 case '5': case '6': case '7': case '8': case '9':
1219 if (name
[1] == '\0')
1220 num
= name
[0] - '0';
1221 else if (name
[0] != '0' && isdigit(name
[1]) && name
[2] == '\0')
1223 num
= (name
[0] - '0') * 10 + name
[1] - '0';
1230 if (!alpha_noat_on
&& num
== AXP_REG_AT
)
1231 as_warn(_("Used $at without \".set noat\""));
1232 return alpha_register_table
[num
+ is_float
];
1235 if (name
[1] == 't' && name
[2] == '\0')
1238 as_warn(_("Used $at without \".set noat\""));
1239 return alpha_register_table
[AXP_REG_AT
];
1244 if (name
[1] == 'p' && name
[2] == '\0')
1245 return alpha_register_table
[alpha_gp_register
];
1249 if (name
[1] == 'p' && name
[2] == '\0')
1250 return alpha_register_table
[AXP_REG_SP
];
1258 /* @@@ Magic ECOFF bits. */
1261 alpha_frob_ecoff_data ()
1264 /* $zero and $f31 are read-only */
1265 alpha_gprmask
&= ~1;
1266 alpha_fprmask
&= ~1;
1270 /* Hook to remember a recently defined label so that the auto-align
1271 code can adjust the symbol after we know what alignment will be
1275 alpha_define_label (sym
)
1278 alpha_insn_label
= sym
;
1281 /* Return true if we must always emit a reloc for a type and false if
1282 there is some hope of resolving it a assembly time. */
1285 alpha_force_relocation (f
)
1288 if (alpha_flag_relax
)
1291 switch (f
->fx_r_type
)
1293 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1294 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1295 case BFD_RELOC_ALPHA_GPDISP
:
1297 case BFD_RELOC_ALPHA_LITERAL
:
1300 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1302 case BFD_RELOC_ALPHA_LITUSE
:
1303 case BFD_RELOC_GPREL32
:
1305 case BFD_RELOC_ALPHA_LINKAGE
:
1306 case BFD_RELOC_ALPHA_CODEADDR
:
1310 case BFD_RELOC_23_PCREL_S2
:
1313 case BFD_RELOC_ALPHA_HINT
:
1317 assert((int)f
->fx_r_type
< 0 && -(int)f
->fx_r_type
< alpha_num_operands
);
1322 /* Return true if we can partially resolve a relocation now. */
1325 alpha_fix_adjustable (f
)
1329 /* Prevent all adjustments to global symbols */
1330 if (S_IS_EXTERN (f
->fx_addsy
))
1334 /* Are there any relocation types for which we must generate a reloc
1335 but we can adjust the values contained within it? */
1336 switch (f
->fx_r_type
)
1338 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1339 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1340 case BFD_RELOC_ALPHA_GPDISP
:
1344 case BFD_RELOC_ALPHA_LITERAL
:
1347 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1350 case BFD_RELOC_ALPHA_LINKAGE
:
1351 case BFD_RELOC_ALPHA_CODEADDR
:
1355 case BFD_RELOC_ALPHA_LITUSE
:
1358 case BFD_RELOC_GPREL32
:
1359 case BFD_RELOC_23_PCREL_S2
:
1362 case BFD_RELOC_ALPHA_HINT
:
1366 assert ((int)f
->fx_r_type
< 0
1367 && - (int)f
->fx_r_type
< alpha_num_operands
);
1373 /* Generate the BFD reloc to be stuck in the object file from the
1374 fixup used internally in the assembler. */
1377 tc_gen_reloc (sec
, fixp
)
1383 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
1384 reloc
->sym_ptr_ptr
= &fixp
->fx_addsy
->bsym
;
1385 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
1387 /* Make sure none of our internal relocations make it this far.
1388 They'd better have been fully resolved by this point. */
1389 assert ((int)fixp
->fx_r_type
> 0);
1391 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
1392 if (reloc
->howto
== NULL
)
1394 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1395 _("cannot represent `%s' relocation in object file"),
1396 bfd_get_reloc_code_name (fixp
->fx_r_type
));
1400 if (!fixp
->fx_pcrel
!= !reloc
->howto
->pc_relative
)
1402 as_fatal (_("internal error? cannot generate `%s' relocation"),
1403 bfd_get_reloc_code_name (fixp
->fx_r_type
));
1405 assert (!fixp
->fx_pcrel
== !reloc
->howto
->pc_relative
);
1408 if (fixp
->fx_r_type
== BFD_RELOC_ALPHA_LITERAL
)
1410 /* fake out bfd_perform_relocation. sigh */
1411 reloc
->addend
= -alpha_gp_value
;
1416 reloc
->addend
= fixp
->fx_offset
;
1419 * Ohhh, this is ugly. The problem is that if this is a local global
1420 * symbol, the relocation will entirely be performed at link time, not
1421 * at assembly time. bfd_perform_reloc doesn't know about this sort
1422 * of thing, and as a result we need to fake it out here.
1424 if (S_IS_EXTERN (fixp
->fx_addsy
) && !S_IS_COMMON(fixp
->fx_addsy
))
1425 reloc
->addend
-= fixp
->fx_addsy
->bsym
->value
;
1432 /* Parse a register name off of the input_line and return a register
1433 number. Gets md_undefined_symbol above to do the register name
1436 Only called as a part of processing the ECOFF .frame directive. */
1439 tc_get_register (frame
)
1442 int framereg
= AXP_REG_SP
;
1445 if (*input_line_pointer
== '$')
1447 char *s
= input_line_pointer
;
1448 char c
= get_symbol_end ();
1449 symbolS
*sym
= md_undefined_symbol (s
);
1451 *strchr(s
, '\0') = c
;
1452 if (sym
&& (framereg
= S_GET_VALUE (sym
)) <= 31)
1455 as_warn (_("frame reg expected, using $%d."), framereg
);
1458 note_gpreg (framereg
);
1462 /* This is called before the symbol table is processed. In order to
1463 work with gcc when using mips-tfile, we must keep all local labels.
1464 However, in other cases, we want to discard them. If we were
1465 called with -g, but we didn't see any debugging information, it may
1466 mean that gcc is smuggling debugging information through to
1467 mips-tfile, in which case we must generate all local labels. */
1472 alpha_frob_file_before_adjust ()
1474 if (alpha_debug
!= 0
1475 && ! ecoff_debugging_seen
)
1476 flag_keep_locals
= 1;
1479 #endif /* OBJ_ECOFF */
1481 /* Parse the arguments to an opcode. */
1484 tokenize_arguments (str
, tok
, ntok
)
1489 expressionS
*end_tok
= tok
+ ntok
;
1490 char *old_input_line_pointer
;
1491 int saw_comma
= 0, saw_arg
= 0;
1493 memset (tok
, 0, sizeof (*tok
) * ntok
);
1495 /* Save and restore input_line_pointer around this function */
1496 old_input_line_pointer
= input_line_pointer
;
1497 input_line_pointer
= str
;
1499 while (tok
< end_tok
&& *input_line_pointer
)
1502 switch (*input_line_pointer
)
1508 ++input_line_pointer
;
1509 if (saw_comma
|| !saw_arg
)
1516 char *hold
= input_line_pointer
++;
1518 /* First try for parenthesized register ... */
1520 if (*input_line_pointer
== ')' && tok
->X_op
== O_register
)
1522 tok
->X_op
= (saw_comma
? O_cpregister
: O_pregister
);
1525 ++input_line_pointer
;
1530 /* ... then fall through to plain expression */
1531 input_line_pointer
= hold
;
1535 if (saw_arg
&& !saw_comma
)
1538 if (tok
->X_op
== O_illegal
|| tok
->X_op
== O_absent
)
1551 input_line_pointer
= old_input_line_pointer
;
1552 return ntok
- (end_tok
- tok
);
1555 input_line_pointer
= old_input_line_pointer
;
1559 /* Search forward through all variants of an opcode looking for a
1562 static const struct alpha_opcode
*
1563 find_opcode_match(first_opcode
, tok
, pntok
, pcpumatch
)
1564 const struct alpha_opcode
*first_opcode
;
1565 const expressionS
*tok
;
1569 const struct alpha_opcode
*opcode
= first_opcode
;
1571 int got_cpu_match
= 0;
1575 const unsigned char *opidx
;
1578 /* Don't match opcodes that don't exist on this architecture */
1579 if (!(opcode
->flags
& alpha_target
))
1584 for (opidx
= opcode
->operands
; *opidx
; ++opidx
)
1586 const struct alpha_operand
*operand
= &alpha_operands
[*opidx
];
1588 /* only take input from real operands */
1589 if (operand
->flags
& AXP_OPERAND_FAKE
)
1592 /* when we expect input, make sure we have it */
1595 if ((operand
->flags
& AXP_OPERAND_OPTIONAL_MASK
) == 0)
1600 /* match operand type with expression type */
1601 switch (operand
->flags
& AXP_OPERAND_TYPECHECK_MASK
)
1603 case AXP_OPERAND_IR
:
1604 if (tok
[tokidx
].X_op
!= O_register
1605 || !is_ir_num(tok
[tokidx
].X_add_number
))
1608 case AXP_OPERAND_FPR
:
1609 if (tok
[tokidx
].X_op
!= O_register
1610 || !is_fpr_num(tok
[tokidx
].X_add_number
))
1613 case AXP_OPERAND_IR
|AXP_OPERAND_PARENS
:
1614 if (tok
[tokidx
].X_op
!= O_pregister
1615 || !is_ir_num(tok
[tokidx
].X_add_number
))
1618 case AXP_OPERAND_IR
|AXP_OPERAND_PARENS
|AXP_OPERAND_COMMA
:
1619 if (tok
[tokidx
].X_op
!= O_cpregister
1620 || !is_ir_num(tok
[tokidx
].X_add_number
))
1624 case AXP_OPERAND_RELATIVE
:
1625 case AXP_OPERAND_SIGNED
:
1626 case AXP_OPERAND_UNSIGNED
:
1627 switch (tok
[tokidx
].X_op
)
1639 /* everything else should have been fake */
1645 /* possible match -- did we use all of our input? */
1654 while (++opcode
-alpha_opcodes
< alpha_num_opcodes
1655 && !strcmp(opcode
->name
, first_opcode
->name
));
1658 *pcpumatch
= got_cpu_match
;
1663 /* Search forward through all variants of a macro looking for a syntax
1666 static const struct alpha_macro
*
1667 find_macro_match(first_macro
, tok
, pntok
)
1668 const struct alpha_macro
*first_macro
;
1669 const expressionS
*tok
;
1672 const struct alpha_macro
*macro
= first_macro
;
1677 const enum alpha_macro_arg
*arg
= macro
->argsets
;
1692 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_register
1693 || !is_ir_num(tok
[tokidx
].X_add_number
))
1698 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_pregister
1699 || !is_ir_num(tok
[tokidx
].X_add_number
))
1704 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_cpregister
1705 || !is_ir_num(tok
[tokidx
].X_add_number
))
1710 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_register
1711 || !is_fpr_num(tok
[tokidx
].X_add_number
))
1719 switch (tok
[tokidx
].X_op
)
1732 while (*arg
!= MACRO_EOA
)
1740 while (++macro
-alpha_macros
< alpha_num_macros
1741 && !strcmp(macro
->name
, first_macro
->name
));
1746 /* Insert an operand value into an instruction. */
1749 insert_operand(insn
, operand
, val
, file
, line
)
1751 const struct alpha_operand
*operand
;
1756 if (operand
->bits
!= 32 && !(operand
->flags
& AXP_OPERAND_NOOVERFLOW
))
1760 if (operand
->flags
& AXP_OPERAND_SIGNED
)
1762 max
= (1 << (operand
->bits
- 1)) - 1;
1763 min
= -(1 << (operand
->bits
- 1));
1767 max
= (1 << operand
->bits
) - 1;
1771 if (val
< min
|| val
> max
)
1774 _("operand out of range (%s not between %d and %d)");
1775 char buf
[sizeof (val
) * 3 + 2];
1777 sprint_value(buf
, val
);
1779 as_warn_where(file
, line
, err
, buf
, min
, max
);
1781 as_warn(err
, buf
, min
, max
);
1785 if (operand
->insert
)
1787 const char *errmsg
= NULL
;
1789 insn
= (*operand
->insert
) (insn
, val
, &errmsg
);
1794 insn
|= ((val
& ((1 << operand
->bits
) - 1)) << operand
->shift
);
1800 * Turn an opcode description and a set of arguments into
1801 * an instruction and a fixup.
1805 assemble_insn(opcode
, tok
, ntok
, insn
)
1806 const struct alpha_opcode
*opcode
;
1807 const expressionS
*tok
;
1809 struct alpha_insn
*insn
;
1811 const unsigned char *argidx
;
1815 memset (insn
, 0, sizeof (*insn
));
1816 image
= opcode
->opcode
;
1818 for (argidx
= opcode
->operands
; *argidx
; ++argidx
)
1820 const struct alpha_operand
*operand
= &alpha_operands
[*argidx
];
1821 const expressionS
*t
;
1823 if (operand
->flags
& AXP_OPERAND_FAKE
)
1825 /* fake operands take no value and generate no fixup */
1826 image
= insert_operand(image
, operand
, 0, NULL
, 0);
1832 switch (operand
->flags
& AXP_OPERAND_OPTIONAL_MASK
)
1834 case AXP_OPERAND_DEFAULT_FIRST
:
1837 case AXP_OPERAND_DEFAULT_SECOND
:
1840 case AXP_OPERAND_DEFAULT_ZERO
:
1842 static const expressionS zero_exp
= { 0, 0, 0, O_constant
, 1 };
1858 image
= insert_operand(image
, operand
, regno(t
->X_add_number
),
1863 image
= insert_operand(image
, operand
, t
->X_add_number
, NULL
, 0);
1868 struct alpha_fixup
*fixup
;
1870 if (insn
->nfixups
>= MAX_INSN_FIXUPS
)
1871 as_fatal(_("too many fixups"));
1873 fixup
= &insn
->fixups
[insn
->nfixups
++];
1876 fixup
->reloc
= operand
->default_reloc
;
1886 * Actually output an instruction with its fixup.
1891 struct alpha_insn
*insn
;
1896 /* Take care of alignment duties */
1897 if (alpha_auto_align_on
&& alpha_current_align
< 2)
1898 alpha_align (2, (char *) NULL
, alpha_insn_label
, 0);
1899 if (alpha_current_align
> 2)
1900 alpha_current_align
= 2;
1901 alpha_insn_label
= NULL
;
1903 /* Write out the instruction. */
1905 md_number_to_chars (f
, insn
->insn
, 4);
1907 /* Apply the fixups in order */
1908 for (i
= 0; i
< insn
->nfixups
; ++i
)
1910 struct alpha_fixup
*fixup
= &insn
->fixups
[i
];
1914 /* Some fixups are only used internally and so have no howto */
1915 if ((int)fixup
->reloc
< 0)
1916 size
= 4, pcrel
= 0;
1918 /* These relocation types are only used internally. */
1919 else if (fixup
->reloc
== BFD_RELOC_ALPHA_GPDISP_HI16
1920 || fixup
->reloc
== BFD_RELOC_ALPHA_GPDISP_LO16
)
1922 size
= 2, pcrel
= 0;
1927 reloc_howto_type
*reloc_howto
1928 = bfd_reloc_type_lookup (stdoutput
, fixup
->reloc
);
1929 assert (reloc_howto
);
1931 size
= bfd_get_reloc_size (reloc_howto
);
1932 pcrel
= reloc_howto
->pc_relative
;
1934 assert (size
>= 1 && size
<= 4);
1936 fixP
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, size
,
1937 &fixup
->exp
, pcrel
, fixup
->reloc
);
1939 /* Turn off complaints that the addend is too large for some fixups */
1940 switch (fixup
->reloc
)
1942 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1944 case BFD_RELOC_ALPHA_LITERAL
:
1947 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1949 case BFD_RELOC_GPREL32
:
1950 fixP
->fx_no_overflow
= 1;
1958 /* Given an opcode name and a pre-tokenized set of arguments, assemble
1959 the insn, but do not emit it.
1961 Note that this implies no macros allowed, since we can't store more
1962 than one insn in an insn structure. */
1965 assemble_tokens_to_insn(opname
, tok
, ntok
, insn
)
1967 const expressionS
*tok
;
1969 struct alpha_insn
*insn
;
1971 const struct alpha_opcode
*opcode
;
1973 /* search opcodes */
1974 opcode
= (const struct alpha_opcode
*) hash_find (alpha_opcode_hash
, opname
);
1978 opcode
= find_opcode_match (opcode
, tok
, &ntok
, &cpumatch
);
1981 assemble_insn (opcode
, tok
, ntok
, insn
);
1985 as_bad (_("inappropriate arguments for opcode `%s'"), opname
);
1987 as_bad (_("opcode `%s' not supported for target %s"), opname
,
1991 as_bad (_("unknown opcode `%s'"), opname
);
1994 /* Given an opcode name and a pre-tokenized set of arguments, take the
1995 opcode all the way through emission. */
1998 assemble_tokens (opname
, tok
, ntok
, local_macros_on
)
2000 const expressionS
*tok
;
2002 int local_macros_on
;
2004 int found_something
= 0;
2005 const struct alpha_opcode
*opcode
;
2006 const struct alpha_macro
*macro
;
2010 if (local_macros_on
)
2012 macro
= ((const struct alpha_macro
*)
2013 hash_find (alpha_macro_hash
, opname
));
2016 found_something
= 1;
2017 macro
= find_macro_match (macro
, tok
, &ntok
);
2020 (*macro
->emit
) (tok
, ntok
, macro
->arg
);
2026 /* search opcodes */
2027 opcode
= (const struct alpha_opcode
*) hash_find (alpha_opcode_hash
, opname
);
2030 found_something
= 1;
2031 opcode
= find_opcode_match (opcode
, tok
, &ntok
, &cpumatch
);
2034 struct alpha_insn insn
;
2035 assemble_insn (opcode
, tok
, ntok
, &insn
);
2041 if (found_something
)
2043 as_bad (_("inappropriate arguments for opcode `%s'"), opname
);
2045 as_bad (_("opcode `%s' not supported for target %s"), opname
,
2048 as_bad (_("unknown opcode `%s'"), opname
);
2052 /* Some instruction sets indexed by lg(size) */
2053 static const char * const sextX_op
[] = { "sextb", "sextw", "sextl", NULL
};
2054 static const char * const insXl_op
[] = { "insbl", "inswl", "insll", "insql" };
2055 static const char * const insXh_op
[] = { NULL
, "inswh", "inslh", "insqh" };
2056 static const char * const extXl_op
[] = { "extbl", "extwl", "extll", "extql" };
2057 static const char * const extXh_op
[] = { NULL
, "extwh", "extlh", "extqh" };
2058 static const char * const mskXl_op
[] = { "mskbl", "mskwl", "mskll", "mskql" };
2059 static const char * const mskXh_op
[] = { NULL
, "mskwh", "msklh", "mskqh" };
2060 static const char * const stX_op
[] = { "stb", "stw", "stl", "stq" };
2061 static const char * const ldX_op
[] = { "ldb", "ldw", "ldll", "ldq" };
2062 static const char * const ldXu_op
[] = { "ldbu", "ldwu", NULL
, NULL
};
2064 /* Implement the ldgp macro. */
2067 emit_ldgp (tok
, ntok
, unused
)
2068 const expressionS
*tok
;
2075 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
2076 /* from "ldgp r1,n(r2)", generate "ldah r1,X(R2); lda r1,Y(r1)"
2077 with appropriate constants and relocations. */
2078 struct alpha_insn insn
;
2079 expressionS newtok
[3];
2082 /* We're going to need this symbol in md_apply_fix(). */
2083 (void) section_symbol (absolute_section
);
2086 if (regno (tok
[2].X_add_number
) == AXP_REG_PV
)
2087 ecoff_set_gp_prolog_size (0);
2091 set_tok_const (newtok
[1], 0);
2094 assemble_tokens_to_insn ("ldah", newtok
, 3, &insn
);
2099 assert (addend
.X_op
== O_constant
);
2100 addend
.X_op
= O_symbol
;
2101 addend
.X_add_symbol
= alpha_gp_symbol
;
2105 insn
.fixups
[0].exp
= addend
;
2106 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_GPDISP_HI16
;
2110 set_tok_preg (newtok
[2], tok
[0].X_add_number
);
2112 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
2115 addend
.X_add_number
+= 4;
2119 insn
.fixups
[0].exp
= addend
;
2120 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_GPDISP_LO16
;
2123 #endif /* OBJ_ECOFF || OBJ_ELF */
2128 /* Add symbol+addend to link pool.
2129 Return offset from basesym to entry in link pool.
2131 Add new fixup only if offset isn't 16bit. */
2134 add_to_link_pool (basesym
, sym
, addend
)
2139 segT current_section
= now_seg
;
2140 int current_subsec
= now_subseg
;
2142 bfd_reloc_code_real_type reloc_type
;
2144 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
2147 offset
= -basesym
->sy_obj
;
2149 /* @@ This assumes all entries in a given section will be of the same
2150 size... Probably correct, but unwise to rely on. */
2151 /* This must always be called with the same subsegment. */
2153 if (seginfo
->frchainP
)
2154 for (fixp
= seginfo
->frchainP
->fix_root
;
2155 fixp
!= (fixS
*) NULL
;
2156 fixp
= fixp
->fx_next
, offset
+= 8)
2158 if (fixp
->fx_addsy
== sym
&& fixp
->fx_offset
== addend
)
2160 if (range_signed_16 (offset
))
2167 /* Not found in 16bit signed range. */
2169 subseg_set (alpha_link_section
, 0);
2173 fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, sym
, addend
, 0,
2176 subseg_set (current_section
, current_subsec
);
2177 seginfo
->literal_pool_size
+= 8;
2181 #endif /* OBJ_EVAX */
2183 /* Load a (partial) expression into a target register.
2185 If poffset is not null, after the call it will either contain
2186 O_constant 0, or a 16-bit offset appropriate for any MEM format
2187 instruction. In addition, pbasereg will be modified to point to
2188 the base register to use in that MEM format instruction.
2190 In any case, *pbasereg should contain a base register to add to the
2191 expression. This will normally be either AXP_REG_ZERO or
2192 alpha_gp_register. Symbol addresses will always be loaded via $gp,
2193 so "foo($0)" is interpreted as adding the address of foo to $0;
2194 i.e. "ldq $targ, LIT($gp); addq $targ, $0, $targ". Odd, perhaps,
2195 but this is what OSF/1 does.
2197 Finally, the return value is true if the calling macro may emit a
2198 LITUSE reloc if otherwise appropriate. */
2201 load_expression (targreg
, exp
, pbasereg
, poffset
)
2203 const expressionS
*exp
;
2205 expressionS
*poffset
;
2207 int emit_lituse
= 0;
2208 offsetT addend
= exp
->X_add_number
;
2209 int basereg
= *pbasereg
;
2210 struct alpha_insn insn
;
2211 expressionS newtok
[3];
2220 /* attempt to reduce .lit load by splitting the offset from
2221 its symbol when possible, but don't create a situation in
2223 if (!range_signed_32 (addend
) &&
2224 (alpha_noat_on
|| targreg
== AXP_REG_AT
))
2226 lit
= add_to_literal_pool (exp
->X_add_symbol
, addend
,
2227 alpha_lita_section
, 8);
2232 lit
= add_to_literal_pool (exp
->X_add_symbol
, 0,
2233 alpha_lita_section
, 8);
2237 as_fatal (_("overflow in literal (.lita) table"));
2239 /* emit "ldq r, lit(gp)" */
2241 if (basereg
!= alpha_gp_register
&& targreg
== basereg
)
2244 as_bad (_("macro requires $at register while noat in effect"));
2245 if (targreg
== AXP_REG_AT
)
2246 as_bad (_("macro requires $at while $at in use"));
2248 set_tok_reg (newtok
[0], AXP_REG_AT
);
2251 set_tok_reg (newtok
[0], targreg
);
2252 set_tok_sym (newtok
[1], alpha_lita_symbol
, lit
);
2253 set_tok_preg (newtok
[2], alpha_gp_register
);
2255 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
2257 assert (insn
.nfixups
== 1);
2258 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITERAL
;
2259 #endif /* OBJ_ECOFF */
2261 /* emit "ldq r, gotoff(gp)" */
2263 if (basereg
!= alpha_gp_register
&& targreg
== basereg
)
2266 as_bad (_("macro requires $at register while noat in effect"));
2267 if (targreg
== AXP_REG_AT
)
2268 as_bad (_("macro requires $at while $at in use"));
2270 set_tok_reg (newtok
[0], AXP_REG_AT
);
2273 set_tok_reg (newtok
[0], targreg
);
2275 /* XXX: Disable this .got minimizing optimization so that we can get
2276 better instruction offset knowledge in the compiler. This happens
2277 very infrequently anyway. */
2278 if (1 || !range_signed_32 (addend
)
2279 && (alpha_noat_on
|| targreg
== AXP_REG_AT
))
2286 set_tok_sym (newtok
[1], exp
->X_add_symbol
, 0);
2289 set_tok_preg (newtok
[2], alpha_gp_register
);
2291 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
2293 assert (insn
.nfixups
== 1);
2294 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_ELF_LITERAL
;
2295 #endif /* OBJ_ELF */
2299 /* Find symbol or symbol pointer in link section. */
2301 if (exp
->X_add_symbol
== alpha_evax_proc
.symbol
)
2303 if (range_signed_16 (addend
))
2305 set_tok_reg (newtok
[0], targreg
);
2306 set_tok_const (newtok
[1], addend
);
2307 set_tok_preg (newtok
[2], basereg
);
2308 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
2313 set_tok_reg (newtok
[0], targreg
);
2314 set_tok_const (newtok
[1], 0);
2315 set_tok_preg (newtok
[2], basereg
);
2316 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
2321 if (!range_signed_32 (addend
))
2323 link
= add_to_link_pool (alpha_evax_proc
.symbol
,
2324 exp
->X_add_symbol
, addend
);
2329 link
= add_to_link_pool (alpha_evax_proc
.symbol
,
2330 exp
->X_add_symbol
, 0);
2332 set_tok_reg (newtok
[0], targreg
);
2333 set_tok_const (newtok
[1], link
);
2334 set_tok_preg (newtok
[2], basereg
);
2335 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
2337 #endif /* OBJ_EVAX */
2344 if (basereg
!= alpha_gp_register
&& basereg
!= AXP_REG_ZERO
)
2346 /* emit "addq r, base, r" */
2348 set_tok_reg (newtok
[1], basereg
);
2349 set_tok_reg (newtok
[2], targreg
);
2350 assemble_tokens ("addq", newtok
, 3, 0);
2362 /* Assume that this difference expression will be resolved to an
2363 absolute value and that that value will fit in 16 bits. */
2365 set_tok_reg (newtok
[0], targreg
);
2367 set_tok_preg (newtok
[2], basereg
);
2368 assemble_tokens ("lda", newtok
, 3, 0);
2371 set_tok_const (*poffset
, 0);
2375 if (exp
->X_add_number
> 0)
2376 as_bad (_("bignum invalid; zero assumed"));
2378 as_bad (_("floating point number invalid; zero assumed"));
2386 if (!range_signed_32 (addend
))
2390 /* for 64-bit addends, just put it in the literal pool */
2393 /* emit "ldq targreg, lit(basereg)" */
2394 lit
= add_to_link_pool (alpha_evax_proc
.symbol
,
2395 section_symbol (absolute_section
), addend
);
2396 set_tok_reg (newtok
[0], targreg
);
2397 set_tok_const (newtok
[1], lit
);
2398 set_tok_preg (newtok
[2], alpha_gp_register
);
2399 assemble_tokens ("ldq", newtok
, 3, 0);
2402 if (alpha_lit8_section
== NULL
)
2404 create_literal_section (".lit8",
2405 &alpha_lit8_section
,
2406 &alpha_lit8_symbol
);
2409 alpha_lit8_literal
= add_to_literal_pool (alpha_lit8_symbol
, 0x8000,
2410 alpha_lita_section
, 8);
2411 if (alpha_lit8_literal
>= 0x8000)
2412 as_fatal (_("overflow in literal (.lita) table"));
2416 lit
= add_to_literal_pool (NULL
, addend
, alpha_lit8_section
, 8) - 0x8000;
2418 as_fatal (_("overflow in literal (.lit8) table"));
2420 /* emit "lda litreg, .lit8+0x8000" */
2422 if (targreg
== basereg
)
2425 as_bad (_("macro requires $at register while noat in effect"));
2426 if (targreg
== AXP_REG_AT
)
2427 as_bad (_("macro requires $at while $at in use"));
2429 set_tok_reg (newtok
[0], AXP_REG_AT
);
2432 set_tok_reg (newtok
[0], targreg
);
2434 set_tok_sym (newtok
[1], alpha_lita_symbol
, alpha_lit8_literal
);
2437 set_tok_sym (newtok
[1], alpha_lit8_symbol
, 0x8000);
2439 set_tok_preg (newtok
[2], alpha_gp_register
);
2441 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
2443 assert (insn
.nfixups
== 1);
2445 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITERAL
;
2448 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_ELF_LITERAL
;
2453 /* emit "ldq litreg, lit(litreg)" */
2455 set_tok_const (newtok
[1], lit
);
2456 set_tok_preg (newtok
[2], newtok
[0].X_add_number
);
2458 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
2460 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
2461 if (insn
.nfixups
> 0)
2463 memmove (&insn
.fixups
[1], &insn
.fixups
[0],
2464 sizeof(struct alpha_fixup
) * insn
.nfixups
);
2467 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITUSE
;
2468 insn
.fixups
[0].exp
.X_op
= O_constant
;
2469 insn
.fixups
[0].exp
.X_add_number
= 1;
2474 /* emit "addq litreg, base, target" */
2476 if (basereg
!= AXP_REG_ZERO
)
2478 set_tok_reg (newtok
[1], basereg
);
2479 set_tok_reg (newtok
[2], targreg
);
2480 assemble_tokens ("addq", newtok
, 3, 0);
2482 #endif /* !OBJ_EVAX */
2485 set_tok_const (*poffset
, 0);
2486 *pbasereg
= targreg
;
2490 offsetT low
, high
, extra
, tmp
;
2492 /* for 32-bit operands, break up the addend */
2494 low
= sign_extend_16 (addend
);
2496 high
= sign_extend_16 (tmp
>> 16);
2498 if (tmp
- (high
<< 16))
2502 high
= sign_extend_16 (tmp
>> 16);
2507 set_tok_reg (newtok
[0], targreg
);
2508 set_tok_preg (newtok
[2], basereg
);
2512 /* emit "ldah r, extra(r) */
2513 set_tok_const (newtok
[1], extra
);
2514 assemble_tokens ("ldah", newtok
, 3, 0);
2515 set_tok_preg (newtok
[2], basereg
= targreg
);
2520 /* emit "ldah r, high(r) */
2521 set_tok_const (newtok
[1], high
);
2522 assemble_tokens ("ldah", newtok
, 3, 0);
2524 set_tok_preg (newtok
[2], basereg
);
2527 if ((low
&& !poffset
) || (!poffset
&& basereg
!= targreg
))
2529 /* emit "lda r, low(base)" */
2530 set_tok_const (newtok
[1], low
);
2531 assemble_tokens ("lda", newtok
, 3, 0);
2537 set_tok_const (*poffset
, low
);
2538 *pbasereg
= basereg
;
2544 /* The lda macro differs from the lda instruction in that it handles
2545 most simple expressions, particualrly symbol address loads and
2549 emit_lda (tok
, ntok
, unused
)
2550 const expressionS
*tok
;
2557 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
2559 basereg
= tok
[2].X_add_number
;
2561 (void) load_expression (tok
[0].X_add_number
, &tok
[1], &basereg
, NULL
);
2564 /* The ldah macro differs from the ldah instruction in that it has $31
2565 as an implied base register. */
2568 emit_ldah (tok
, ntok
, unused
)
2569 const expressionS
*tok
;
2573 expressionS newtok
[3];
2577 set_tok_preg (newtok
[2], AXP_REG_ZERO
);
2579 assemble_tokens ("ldah", newtok
, 3, 0);
2582 /* Handle all "simple" integer register loads -- ldq, ldq_l, ldq_u,
2583 etc. They differ from the real instructions in that they do simple
2584 expressions like the lda macro. */
2587 emit_ir_load (tok
, ntok
, opname
)
2588 const expressionS
*tok
;
2592 int basereg
, lituse
;
2593 expressionS newtok
[3];
2594 struct alpha_insn insn
;
2597 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
2599 basereg
= tok
[2].X_add_number
;
2601 lituse
= load_expression (tok
[0].X_add_number
, &tok
[1], &basereg
,
2605 set_tok_preg (newtok
[2], basereg
);
2607 assemble_tokens_to_insn ((const char *)opname
, newtok
, 3, &insn
);
2611 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
2612 if (insn
.nfixups
> 0)
2614 memmove (&insn
.fixups
[1], &insn
.fixups
[0],
2615 sizeof(struct alpha_fixup
) * insn
.nfixups
);
2618 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITUSE
;
2619 insn
.fixups
[0].exp
.X_op
= O_constant
;
2620 insn
.fixups
[0].exp
.X_add_number
= 1;
2626 /* Handle fp register loads, and both integer and fp register stores.
2627 Again, we handle simple expressions. */
2630 emit_loadstore (tok
, ntok
, opname
)
2631 const expressionS
*tok
;
2635 int basereg
, lituse
;
2636 expressionS newtok
[3];
2637 struct alpha_insn insn
;
2640 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
2642 basereg
= tok
[2].X_add_number
;
2644 if (tok
[1].X_op
!= O_constant
|| !range_signed_16(tok
[1].X_add_number
))
2647 as_bad (_("macro requires $at register while noat in effect"));
2649 lituse
= load_expression (AXP_REG_AT
, &tok
[1], &basereg
, &newtok
[1]);
2658 set_tok_preg (newtok
[2], basereg
);
2660 assemble_tokens_to_insn ((const char *)opname
, newtok
, 3, &insn
);
2664 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
2665 if (insn
.nfixups
> 0)
2667 memmove (&insn
.fixups
[1], &insn
.fixups
[0],
2668 sizeof(struct alpha_fixup
) * insn
.nfixups
);
2671 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITUSE
;
2672 insn
.fixups
[0].exp
.X_op
= O_constant
;
2673 insn
.fixups
[0].exp
.X_add_number
= 1;
2679 /* Load a half-word or byte as an unsigned value. */
2682 emit_ldXu (tok
, ntok
, vlgsize
)
2683 const expressionS
*tok
;
2687 if (alpha_target
& AXP_OPCODE_BWX
)
2688 emit_ir_load (tok
, ntok
, ldXu_op
[(long)vlgsize
]);
2691 expressionS newtok
[3];
2694 as_bad (_("macro requires $at register while noat in effect"));
2696 /* emit "lda $at, exp" */
2698 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
2699 newtok
[0].X_add_number
= AXP_REG_AT
;
2700 assemble_tokens ("lda", newtok
, ntok
, 1);
2702 /* emit "ldq_u targ, 0($at)" */
2705 set_tok_const (newtok
[1], 0);
2706 set_tok_preg (newtok
[2], AXP_REG_AT
);
2707 assemble_tokens ("ldq_u", newtok
, 3, 1);
2709 /* emit "extXl targ, $at, targ" */
2711 set_tok_reg (newtok
[1], AXP_REG_AT
);
2712 newtok
[2] = newtok
[0];
2713 assemble_tokens (extXl_op
[(long)vlgsize
], newtok
, 3, 1);
2717 /* Load a half-word or byte as a signed value. */
2720 emit_ldX (tok
, ntok
, vlgsize
)
2721 const expressionS
*tok
;
2725 emit_ldXu (tok
, ntok
, vlgsize
);
2726 assemble_tokens (sextX_op
[(long)vlgsize
], tok
, 1, 1);
2729 /* Load an integral value from an unaligned address as an unsigned
2733 emit_uldXu (tok
, ntok
, vlgsize
)
2734 const expressionS
*tok
;
2738 long lgsize
= (long)vlgsize
;
2739 expressionS newtok
[3];
2742 as_bad (_("macro requires $at register while noat in effect"));
2744 /* emit "lda $at, exp" */
2746 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
2747 newtok
[0].X_add_number
= AXP_REG_AT
;
2748 assemble_tokens ("lda", newtok
, ntok
, 1);
2750 /* emit "ldq_u $t9, 0($at)" */
2752 set_tok_reg (newtok
[0], AXP_REG_T9
);
2753 set_tok_const (newtok
[1], 0);
2754 set_tok_preg (newtok
[2], AXP_REG_AT
);
2755 assemble_tokens ("ldq_u", newtok
, 3, 1);
2757 /* emit "ldq_u $t10, size-1($at)" */
2759 set_tok_reg (newtok
[0], AXP_REG_T10
);
2760 set_tok_const (newtok
[1], (1<<lgsize
)-1);
2761 assemble_tokens ("ldq_u", newtok
, 3, 1);
2763 /* emit "extXl $t9, $at, $t9" */
2765 set_tok_reg (newtok
[0], AXP_REG_T9
);
2766 set_tok_reg (newtok
[1], AXP_REG_AT
);
2767 set_tok_reg (newtok
[2], AXP_REG_T9
);
2768 assemble_tokens (extXl_op
[lgsize
], newtok
, 3, 1);
2770 /* emit "extXh $t10, $at, $t10" */
2772 set_tok_reg (newtok
[0], AXP_REG_T10
);
2773 set_tok_reg (newtok
[2], AXP_REG_T10
);
2774 assemble_tokens (extXh_op
[lgsize
], newtok
, 3, 1);
2776 /* emit "or $t9, $t10, targ" */
2778 set_tok_reg (newtok
[0], AXP_REG_T9
);
2779 set_tok_reg (newtok
[1], AXP_REG_T10
);
2781 assemble_tokens ("or", newtok
, 3, 1);
2784 /* Load an integral value from an unaligned address as a signed value.
2785 Note that quads should get funneled to the unsigned load since we
2786 don't have to do the sign extension. */
2789 emit_uldX (tok
, ntok
, vlgsize
)
2790 const expressionS
*tok
;
2794 emit_uldXu (tok
, ntok
, vlgsize
);
2795 assemble_tokens (sextX_op
[(long)vlgsize
], tok
, 1, 1);
2798 /* Implement the ldil macro. */
2801 emit_ldil (tok
, ntok
, unused
)
2802 const expressionS
*tok
;
2806 expressionS newtok
[2];
2808 memcpy (newtok
, tok
, sizeof(newtok
));
2809 newtok
[1].X_add_number
= sign_extend_32 (tok
[1].X_add_number
);
2811 assemble_tokens ("lda", newtok
, ntok
, 1);
2814 /* Store a half-word or byte. */
2817 emit_stX (tok
, ntok
, vlgsize
)
2818 const expressionS
*tok
;
2822 int lgsize
= (int)(long)vlgsize
;
2824 if (alpha_target
& AXP_OPCODE_BWX
)
2825 emit_loadstore (tok
, ntok
, stX_op
[lgsize
]);
2828 expressionS newtok
[3];
2831 as_bad(_("macro requires $at register while noat in effect"));
2833 /* emit "lda $at, exp" */
2835 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
2836 newtok
[0].X_add_number
= AXP_REG_AT
;
2837 assemble_tokens ("lda", newtok
, ntok
, 1);
2839 /* emit "ldq_u $t9, 0($at)" */
2841 set_tok_reg (newtok
[0], AXP_REG_T9
);
2842 set_tok_const (newtok
[1], 0);
2843 set_tok_preg (newtok
[2], AXP_REG_AT
);
2844 assemble_tokens ("ldq_u", newtok
, 3, 1);
2846 /* emit "insXl src, $at, $t10" */
2849 set_tok_reg (newtok
[1], AXP_REG_AT
);
2850 set_tok_reg (newtok
[2], AXP_REG_T10
);
2851 assemble_tokens (insXl_op
[lgsize
], newtok
, 3, 1);
2853 /* emit "mskXl $t9, $at, $t9" */
2855 set_tok_reg (newtok
[0], AXP_REG_T9
);
2856 newtok
[2] = newtok
[0];
2857 assemble_tokens (mskXl_op
[lgsize
], newtok
, 3, 1);
2859 /* emit "or $t9, $t10, $t9" */
2861 set_tok_reg (newtok
[1], AXP_REG_T10
);
2862 assemble_tokens ("or", newtok
, 3, 1);
2864 /* emit "stq_u $t9, 0($at) */
2866 set_tok_const (newtok
[1], 0);
2867 set_tok_preg (newtok
[2], AXP_REG_AT
);
2868 assemble_tokens ("stq_u", newtok
, 3, 1);
2872 /* Store an integer to an unaligned address. */
2875 emit_ustX (tok
, ntok
, vlgsize
)
2876 const expressionS
*tok
;
2880 int lgsize
= (int)(long)vlgsize
;
2881 expressionS newtok
[3];
2883 /* emit "lda $at, exp" */
2885 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
2886 newtok
[0].X_add_number
= AXP_REG_AT
;
2887 assemble_tokens ("lda", newtok
, ntok
, 1);
2889 /* emit "ldq_u $9, 0($at)" */
2891 set_tok_reg (newtok
[0], AXP_REG_T9
);
2892 set_tok_const (newtok
[1], 0);
2893 set_tok_preg (newtok
[2], AXP_REG_AT
);
2894 assemble_tokens ("ldq_u", newtok
, 3, 1);
2896 /* emit "ldq_u $10, size-1($at)" */
2898 set_tok_reg (newtok
[0], AXP_REG_T10
);
2899 set_tok_const (newtok
[1], (1 << lgsize
)-1);
2900 assemble_tokens ("ldq_u", newtok
, 3, 1);
2902 /* emit "insXl src, $at, $t11" */
2905 set_tok_reg (newtok
[1], AXP_REG_AT
);
2906 set_tok_reg (newtok
[2], AXP_REG_T11
);
2907 assemble_tokens (insXl_op
[lgsize
], newtok
, 3, 1);
2909 /* emit "insXh src, $at, $t12" */
2911 set_tok_reg (newtok
[2], AXP_REG_T12
);
2912 assemble_tokens (insXh_op
[lgsize
], newtok
, 3, 1);
2914 /* emit "mskXl $t9, $at, $t9" */
2916 set_tok_reg (newtok
[0], AXP_REG_T9
);
2917 newtok
[2] = newtok
[0];
2918 assemble_tokens (mskXl_op
[lgsize
], newtok
, 3, 1);
2920 /* emit "mskXh $t10, $at, $t10" */
2922 set_tok_reg (newtok
[0], AXP_REG_T10
);
2923 newtok
[2] = newtok
[0];
2924 assemble_tokens (mskXh_op
[lgsize
], newtok
, 3, 1);
2926 /* emit "or $t9, $t11, $t9" */
2928 set_tok_reg (newtok
[0], AXP_REG_T9
);
2929 set_tok_reg (newtok
[1], AXP_REG_T11
);
2930 newtok
[2] = newtok
[0];
2931 assemble_tokens ("or", newtok
, 3, 1);
2933 /* emit "or $t10, $t12, $t10" */
2935 set_tok_reg (newtok
[0], AXP_REG_T10
);
2936 set_tok_reg (newtok
[1], AXP_REG_T12
);
2937 newtok
[2] = newtok
[0];
2938 assemble_tokens ("or", newtok
, 3, 1);
2940 /* emit "stq_u $t9, 0($at)" */
2942 set_tok_reg (newtok
[0], AXP_REG_T9
);
2943 set_tok_const (newtok
[1], 0);
2944 set_tok_preg (newtok
[2], AXP_REG_AT
);
2945 assemble_tokens ("stq_u", newtok
, 3, 1);
2947 /* emit "stq_u $t10, size-1($at)" */
2949 set_tok_reg (newtok
[0], AXP_REG_T10
);
2950 set_tok_const (newtok
[1], (1 << lgsize
)-1);
2951 assemble_tokens ("stq_u", newtok
, 3, 1);
2954 /* Sign extend a half-word or byte. The 32-bit sign extend is
2955 implemented as "addl $31, $r, $t" in the opcode table. */
2958 emit_sextX (tok
, ntok
, vlgsize
)
2959 const expressionS
*tok
;
2963 long lgsize
= (long)vlgsize
;
2965 if (alpha_target
& AXP_OPCODE_BWX
)
2966 assemble_tokens (sextX_op
[lgsize
], tok
, ntok
, 0);
2969 int bitshift
= 64 - 8 * (1 << lgsize
);
2970 expressionS newtok
[3];
2972 /* emit "sll src,bits,dst" */
2975 set_tok_const (newtok
[1], bitshift
);
2976 newtok
[2] = tok
[ntok
- 1];
2977 assemble_tokens ("sll", newtok
, 3, 1);
2979 /* emit "sra dst,bits,dst" */
2981 newtok
[0] = newtok
[2];
2982 assemble_tokens ("sra", newtok
, 3, 1);
2986 /* Implement the division and modulus macros. */
2990 /* Make register usage like in normal procedure call.
2991 Don't clobber PV and RA. */
2994 emit_division (tok
, ntok
, symname
)
2995 const expressionS
*tok
;
2999 /* DIVISION and MODULUS. Yech.
3004 * mov x,R16 # if x != R16
3005 * mov y,R17 # if y != R17
3010 * with appropriate optimizations if R0,R16,R17 are the registers
3011 * specified by the compiler.
3016 expressionS newtok
[3];
3018 xr
= regno (tok
[0].X_add_number
);
3019 yr
= regno (tok
[1].X_add_number
);
3024 rr
= regno (tok
[2].X_add_number
);
3026 /* Move the operands into the right place */
3027 if (yr
== AXP_REG_R16
&& xr
== AXP_REG_R17
)
3029 /* They are in exactly the wrong order -- swap through AT */
3032 as_bad (_("macro requires $at register while noat in effect"));
3034 set_tok_reg (newtok
[0], AXP_REG_R16
);
3035 set_tok_reg (newtok
[1], AXP_REG_AT
);
3036 assemble_tokens ("mov", newtok
, 2, 1);
3038 set_tok_reg (newtok
[0], AXP_REG_R17
);
3039 set_tok_reg (newtok
[1], AXP_REG_R16
);
3040 assemble_tokens ("mov", newtok
, 2, 1);
3042 set_tok_reg (newtok
[0], AXP_REG_AT
);
3043 set_tok_reg (newtok
[1], AXP_REG_R17
);
3044 assemble_tokens ("mov", newtok
, 2, 1);
3048 if (yr
== AXP_REG_R16
)
3050 set_tok_reg (newtok
[0], AXP_REG_R16
);
3051 set_tok_reg (newtok
[1], AXP_REG_R17
);
3052 assemble_tokens ("mov", newtok
, 2, 1);
3055 if (xr
!= AXP_REG_R16
)
3057 set_tok_reg (newtok
[0], xr
);
3058 set_tok_reg (newtok
[1], AXP_REG_R16
);
3059 assemble_tokens ("mov", newtok
, 2, 1);
3062 if (yr
!= AXP_REG_R16
&& yr
!= AXP_REG_R17
)
3064 set_tok_reg (newtok
[0], yr
);
3065 set_tok_reg (newtok
[1], AXP_REG_R17
);
3066 assemble_tokens ("mov", newtok
, 2, 1);
3070 sym
= symbol_find_or_make ((const char *)symname
);
3072 set_tok_reg (newtok
[0], AXP_REG_AT
);
3073 set_tok_sym (newtok
[1], sym
, 0);
3074 assemble_tokens ("lda", newtok
, 2, 1);
3076 /* Call the division routine */
3077 set_tok_reg (newtok
[0], AXP_REG_AT
);
3078 set_tok_cpreg (newtok
[1], AXP_REG_AT
);
3079 set_tok_const (newtok
[2], 0);
3080 assemble_tokens ("jsr", newtok
, 3, 1);
3082 /* Move the result to the right place */
3083 if (rr
!= AXP_REG_R0
)
3085 set_tok_reg (newtok
[0], AXP_REG_R0
);
3086 set_tok_reg (newtok
[1], rr
);
3087 assemble_tokens ("mov", newtok
, 2, 1);
3091 #else /* !OBJ_EVAX */
3094 emit_division (tok
, ntok
, symname
)
3095 const expressionS
*tok
;
3099 /* DIVISION and MODULUS. Yech.
3109 * with appropriate optimizations if t10,t11,t12 are the registers
3110 * specified by the compiler.
3115 expressionS newtok
[3];
3117 xr
= regno (tok
[0].X_add_number
);
3118 yr
= regno (tok
[1].X_add_number
);
3123 rr
= regno (tok
[2].X_add_number
);
3125 sym
= symbol_find_or_make ((const char *)symname
);
3127 /* Move the operands into the right place */
3128 if (yr
== AXP_REG_T10
&& xr
== AXP_REG_T11
)
3130 /* They are in exactly the wrong order -- swap through AT */
3133 as_bad (_("macro requires $at register while noat in effect"));
3135 set_tok_reg (newtok
[0], AXP_REG_T10
);
3136 set_tok_reg (newtok
[1], AXP_REG_AT
);
3137 assemble_tokens ("mov", newtok
, 2, 1);
3139 set_tok_reg (newtok
[0], AXP_REG_T11
);
3140 set_tok_reg (newtok
[1], AXP_REG_T10
);
3141 assemble_tokens ("mov", newtok
, 2, 1);
3143 set_tok_reg (newtok
[0], AXP_REG_AT
);
3144 set_tok_reg (newtok
[1], AXP_REG_T11
);
3145 assemble_tokens ("mov", newtok
, 2, 1);
3149 if (yr
== AXP_REG_T10
)
3151 set_tok_reg (newtok
[0], AXP_REG_T10
);
3152 set_tok_reg (newtok
[1], AXP_REG_T11
);
3153 assemble_tokens ("mov", newtok
, 2, 1);
3156 if (xr
!= AXP_REG_T10
)
3158 set_tok_reg (newtok
[0], xr
);
3159 set_tok_reg (newtok
[1], AXP_REG_T10
);
3160 assemble_tokens ("mov", newtok
, 2, 1);
3163 if (yr
!= AXP_REG_T10
&& yr
!= AXP_REG_T11
)
3165 set_tok_reg (newtok
[0], yr
);
3166 set_tok_reg (newtok
[1], AXP_REG_T11
);
3167 assemble_tokens ("mov", newtok
, 2, 1);
3171 /* Call the division routine */
3172 set_tok_reg (newtok
[0], AXP_REG_T9
);
3173 set_tok_sym (newtok
[1], sym
, 0);
3174 assemble_tokens ("jsr", newtok
, 2, 1);
3176 /* Reload the GP register */
3180 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
3181 set_tok_reg (newtok
[0], alpha_gp_register
);
3182 set_tok_const (newtok
[1], 0);
3183 set_tok_preg (newtok
[2], AXP_REG_T9
);
3184 assemble_tokens ("ldgp", newtok
, 3, 1);
3187 /* Move the result to the right place */
3188 if (rr
!= AXP_REG_T12
)
3190 set_tok_reg (newtok
[0], AXP_REG_T12
);
3191 set_tok_reg (newtok
[1], rr
);
3192 assemble_tokens ("mov", newtok
, 2, 1);
3196 #endif /* !OBJ_EVAX */
3198 /* The jsr and jmp macros differ from their instruction counterparts
3199 in that they can load the target address and default most
3203 emit_jsrjmp (tok
, ntok
, vopname
)
3204 const expressionS
*tok
;
3208 const char *opname
= (const char *) vopname
;
3209 struct alpha_insn insn
;
3210 expressionS newtok
[3];
3211 int r
, tokidx
= 0, lituse
= 0;
3213 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_register
)
3214 r
= regno (tok
[tokidx
++].X_add_number
);
3216 r
= strcmp (opname
, "jmp") == 0 ? AXP_REG_ZERO
: AXP_REG_RA
;
3218 set_tok_reg (newtok
[0], r
);
3220 if (tokidx
< ntok
&&
3221 (tok
[tokidx
].X_op
== O_pregister
|| tok
[tokidx
].X_op
== O_cpregister
))
3222 r
= regno (tok
[tokidx
++].X_add_number
);
3224 /* keep register if jsr $n.<sym> */
3228 int basereg
= alpha_gp_register
;
3229 lituse
= load_expression (r
= AXP_REG_PV
, &tok
[tokidx
], &basereg
, NULL
);
3233 set_tok_cpreg (newtok
[1], r
);
3236 /* FIXME: Add hint relocs to BFD for evax. */
3239 newtok
[2] = tok
[tokidx
];
3242 set_tok_const (newtok
[2], 0);
3244 assemble_tokens_to_insn (opname
, newtok
, 3, &insn
);
3246 /* add the LITUSE fixup */
3249 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3250 if (insn
.nfixups
> 0)
3252 memmove (&insn
.fixups
[1], &insn
.fixups
[0],
3253 sizeof(struct alpha_fixup
) * insn
.nfixups
);
3256 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITUSE
;
3257 insn
.fixups
[0].exp
.X_op
= O_constant
;
3258 insn
.fixups
[0].exp
.X_add_number
= 3;
3264 /* The ret and jcr instructions differ from their instruction
3265 counterparts in that everything can be defaulted. */
3268 emit_retjcr (tok
, ntok
, vopname
)
3269 const expressionS
*tok
;
3273 const char *opname
= (const char *)vopname
;
3274 expressionS newtok
[3];
3277 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_register
)
3278 r
= regno (tok
[tokidx
++].X_add_number
);
3282 set_tok_reg (newtok
[0], r
);
3284 if (tokidx
< ntok
&&
3285 (tok
[tokidx
].X_op
== O_pregister
|| tok
[tokidx
].X_op
== O_cpregister
))
3286 r
= regno (tok
[tokidx
++].X_add_number
);
3290 set_tok_cpreg (newtok
[1], r
);
3293 newtok
[2] = tok
[tokidx
];
3295 set_tok_const (newtok
[2], strcmp(opname
, "ret") == 0);
3297 assemble_tokens (opname
, newtok
, 3, 0);
3300 /* Assembler directives */
3302 /* Handle the .text pseudo-op. This is like the usual one, but it
3303 clears alpha_insn_label and restores auto alignment. */
3311 alpha_insn_label
= NULL
;
3312 alpha_auto_align_on
= 1;
3313 alpha_current_align
= 0;
3316 /* Handle the .data pseudo-op. This is like the usual one, but it
3317 clears alpha_insn_label and restores auto alignment. */
3324 alpha_insn_label
= NULL
;
3325 alpha_auto_align_on
= 1;
3326 alpha_current_align
= 0;
3329 #if defined (OBJ_ECOFF) || defined (OBJ_EVAX)
3331 /* Handle the OSF/1 and openVMS .comm pseudo quirks.
3332 openVMS constructs a section for every common symbol. */
3335 s_alpha_comm (ignore
)
3338 register char *name
;
3342 register symbolS
*symbolP
;
3345 segT current_section
= now_seg
;
3346 int current_subsec
= now_subseg
;
3350 name
= input_line_pointer
;
3351 c
= get_symbol_end ();
3353 /* just after name is now '\0' */
3354 p
= input_line_pointer
;
3359 /* Alpha OSF/1 compiler doesn't provide the comma, gcc does. */
3360 if (*input_line_pointer
== ',')
3362 input_line_pointer
++;
3365 if ((temp
= get_absolute_expression ()) < 0)
3367 as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) temp
);
3368 ignore_rest_of_line ();
3373 symbolP
= symbol_find_or_make (name
);
3377 /* Make a section for the common symbol. */
3378 new_seg
= subseg_new (xstrdup (name
), 0);
3381 if (S_IS_DEFINED (symbolP
) && ! S_IS_COMMON (symbolP
))
3383 as_bad (_("Ignoring attempt to re-define symbol"));
3384 ignore_rest_of_line ();
3389 if (bfd_section_size (stdoutput
, new_seg
) > 0)
3391 if (bfd_section_size (stdoutput
, new_seg
) != temp
)
3392 as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
3393 S_GET_NAME (symbolP
),
3394 (long) bfd_section_size (stdoutput
, new_seg
),
3398 if (S_GET_VALUE (symbolP
))
3400 if (S_GET_VALUE (symbolP
) != (valueT
) temp
)
3401 as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
3402 S_GET_NAME (symbolP
),
3403 (long) S_GET_VALUE (symbolP
),
3410 subseg_set (new_seg
, 0);
3411 p
= frag_more (temp
);
3412 new_seg
->flags
|= SEC_IS_COMMON
;
3413 if (! S_IS_DEFINED (symbolP
))
3414 symbolP
->bsym
->section
= new_seg
;
3416 S_SET_VALUE (symbolP
, (valueT
) temp
);
3418 S_SET_EXTERNAL (symbolP
);
3422 subseg_set (current_section
, current_subsec
);
3425 know (symbolP
->sy_frag
== &zero_address_frag
);
3427 demand_empty_rest_of_line ();
3430 #endif /* ! OBJ_ELF */
3434 /* Handle the .rdata pseudo-op. This is like the usual one, but it
3435 clears alpha_insn_label and restores auto alignment. */
3438 s_alpha_rdata (ignore
)
3443 temp
= get_absolute_expression ();
3444 subseg_new (".rdata", 0);
3445 demand_empty_rest_of_line ();
3446 alpha_insn_label
= NULL
;
3447 alpha_auto_align_on
= 1;
3448 alpha_current_align
= 0;
3455 /* Handle the .sdata pseudo-op. This is like the usual one, but it
3456 clears alpha_insn_label and restores auto alignment. */
3459 s_alpha_sdata (ignore
)
3464 temp
= get_absolute_expression ();
3465 subseg_new (".sdata", 0);
3466 demand_empty_rest_of_line ();
3467 alpha_insn_label
= NULL
;
3468 alpha_auto_align_on
= 1;
3469 alpha_current_align
= 0;
3475 /* Handle the .section pseudo-op. This is like the usual one, but it
3476 clears alpha_insn_label and restores auto alignment. */
3479 s_alpha_section (ignore
)
3482 obj_elf_section (ignore
);
3484 alpha_insn_label
= NULL
;
3485 alpha_auto_align_on
= 1;
3486 alpha_current_align
= 0;
3493 /* Handle the section specific pseudo-op. */
3496 s_alpha_section (secid
)
3500 #define EVAX_SECTION_COUNT 5
3501 static char *section_name
[EVAX_SECTION_COUNT
+1] =
3502 { "NULL", ".rdata", ".comm", ".link", ".ctors", ".dtors" };
3504 if ((secid
<= 0) || (secid
> EVAX_SECTION_COUNT
))
3506 as_fatal (_("Unknown section directive"));
3507 demand_empty_rest_of_line ();
3510 temp
= get_absolute_expression ();
3511 subseg_new (section_name
[secid
], 0);
3512 demand_empty_rest_of_line ();
3513 alpha_insn_label
= NULL
;
3514 alpha_auto_align_on
= 1;
3515 alpha_current_align
= 0;
3522 s_alpha_prologue (ignore
)
3525 demand_empty_rest_of_line ();
3531 /* Parse .ent directives. */
3534 s_alpha_ent (ignore
)
3538 expressionS symexpr
;
3540 alpha_evax_proc
.pdsckind
= 0;
3541 alpha_evax_proc
.framereg
= -1;
3542 alpha_evax_proc
.framesize
= 0;
3543 alpha_evax_proc
.rsa_offset
= 0;
3544 alpha_evax_proc
.ra_save
= AXP_REG_RA
;
3545 alpha_evax_proc
.fp_save
= -1;
3546 alpha_evax_proc
.imask
= 0;
3547 alpha_evax_proc
.fmask
= 0;
3548 alpha_evax_proc
.prologue
= 0;
3549 alpha_evax_proc
.type
= 0;
3551 expression (&symexpr
);
3553 if (symexpr
.X_op
!= O_symbol
)
3555 as_fatal (_(".ent directive has no symbol"));
3556 demand_empty_rest_of_line ();
3560 symbol
= make_expr_symbol (&symexpr
);
3561 symbol
->bsym
->flags
|= BSF_FUNCTION
;
3562 alpha_evax_proc
.symbol
= symbol
;
3564 demand_empty_rest_of_line ();
3569 /* Parse .frame <framreg>,<framesize>,RA,<rsa_offset> directives. */
3572 s_alpha_frame (ignore
)
3577 alpha_evax_proc
.framereg
= tc_get_register (1);
3580 if (*input_line_pointer
++ != ','
3581 || get_absolute_expression_and_terminator (&val
) != ',')
3583 as_warn (_("Bad .frame directive 1./2. param"));
3584 --input_line_pointer
;
3585 demand_empty_rest_of_line ();
3589 alpha_evax_proc
.framesize
= val
;
3591 (void) tc_get_register (1);
3593 if (*input_line_pointer
++ != ',')
3595 as_warn (_("Bad .frame directive 3./4. param"));
3596 --input_line_pointer
;
3597 demand_empty_rest_of_line ();
3600 alpha_evax_proc
.rsa_offset
= get_absolute_expression ();
3606 s_alpha_pdesc (ignore
)
3616 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
3618 if (now_seg
!= alpha_link_section
)
3620 as_bad (_(".pdesc directive not in link (.link) section"));
3621 demand_empty_rest_of_line ();
3625 if ((alpha_evax_proc
.symbol
== 0)
3626 || (!S_IS_DEFINED (alpha_evax_proc
.symbol
)))
3628 as_fatal (_(".pdesc has no matching .ent"));
3629 demand_empty_rest_of_line ();
3633 alpha_evax_proc
.symbol
->sy_obj
= (valueT
)seginfo
->literal_pool_size
;
3636 if (exp
.X_op
!= O_symbol
)
3638 as_warn (_(".pdesc directive has no entry symbol"));
3639 demand_empty_rest_of_line ();
3643 entry_sym
= make_expr_symbol (&exp
);
3644 /* Save bfd symbol of proc desc in function symbol. */
3645 alpha_evax_proc
.symbol
->bsym
->udata
.p
= (PTR
)entry_sym
->bsym
;
3648 if (*input_line_pointer
++ != ',')
3650 as_warn (_("No comma after .pdesc <entryname>"));
3651 demand_empty_rest_of_line ();
3656 name
= input_line_pointer
;
3657 name_end
= get_symbol_end ();
3659 if (strncmp(name
, "stack", 5) == 0)
3661 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_FP_STACK
;
3663 else if (strncmp(name
, "reg", 3) == 0)
3665 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_FP_REGISTER
;
3667 else if (strncmp(name
, "null", 4) == 0)
3669 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_NULL
;
3673 as_fatal (_("unknown procedure kind"));
3674 demand_empty_rest_of_line ();
3678 *input_line_pointer
= name_end
;
3679 demand_empty_rest_of_line ();
3681 #ifdef md_flush_pending_output
3682 md_flush_pending_output ();
3685 frag_align (3, 0, 0);
3687 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
3689 seginfo
->literal_pool_size
+= 16;
3691 *p
= alpha_evax_proc
.pdsckind
3692 | ((alpha_evax_proc
.framereg
== 29) ? PDSC_S_M_BASE_REG_IS_FP
: 0);
3693 *(p
+1) = PDSC_S_M_NATIVE
3694 | PDSC_S_M_NO_JACKET
;
3696 switch (alpha_evax_proc
.pdsckind
)
3698 case PDSC_S_K_KIND_NULL
:
3702 case PDSC_S_K_KIND_FP_REGISTER
:
3703 *(p
+2) = alpha_evax_proc
.fp_save
;
3704 *(p
+3) = alpha_evax_proc
.ra_save
;
3706 case PDSC_S_K_KIND_FP_STACK
:
3707 md_number_to_chars (p
+2, (valueT
)alpha_evax_proc
.rsa_offset
, 2);
3709 default: /* impossible */
3714 *(p
+5) = alpha_evax_proc
.type
& 0x0f;
3716 /* Signature offset. */
3717 md_number_to_chars (p
+6, (valueT
)0, 2);
3719 fix_new_exp (frag_now
, p
-frag_now
->fr_literal
+8, 8, &exp
, 0, BFD_RELOC_64
);
3721 if (alpha_evax_proc
.pdsckind
== PDSC_S_K_KIND_NULL
)
3724 /* Add dummy fix to make add_to_link_pool work. */
3726 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
3728 seginfo
->literal_pool_size
+= 8;
3730 /* pdesc+16: Size. */
3731 md_number_to_chars (p
, (valueT
)alpha_evax_proc
.framesize
, 4);
3733 md_number_to_chars (p
+4, (valueT
)0, 2);
3736 md_number_to_chars (p
+6, alpha_evax_proc
.prologue
, 2);
3738 if (alpha_evax_proc
.pdsckind
== PDSC_S_K_KIND_FP_REGISTER
)
3741 /* Add dummy fix to make add_to_link_pool work. */
3743 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
3745 seginfo
->literal_pool_size
+= 8;
3747 /* pdesc+24: register masks. */
3749 md_number_to_chars (p
, alpha_evax_proc
.imask
, 4);
3750 md_number_to_chars (p
+4, alpha_evax_proc
.fmask
, 4);
3756 /* Support for crash debug on vms. */
3759 s_alpha_name (ignore
)
3764 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
3766 if (now_seg
!= alpha_link_section
)
3768 as_bad (_(".name directive not in link (.link) section"));
3769 demand_empty_rest_of_line ();
3774 if (exp
.X_op
!= O_symbol
)
3776 as_warn (_(".name directive has no symbol"));
3777 demand_empty_rest_of_line ();
3781 demand_empty_rest_of_line ();
3783 #ifdef md_flush_pending_output
3784 md_flush_pending_output ();
3787 frag_align (3, 0, 0);
3789 seginfo
->literal_pool_size
+= 8;
3791 fix_new_exp (frag_now
, p
-frag_now
->fr_literal
, 8, &exp
, 0, BFD_RELOC_64
);
3798 s_alpha_linkage (ignore
)
3804 #ifdef md_flush_pending_output
3805 md_flush_pending_output ();
3809 if (exp
.X_op
!= O_symbol
)
3811 as_fatal (_("No symbol after .linkage"));
3815 p
= frag_more (LKP_S_K_SIZE
);
3816 memset (p
, 0, LKP_S_K_SIZE
);
3817 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, LKP_S_K_SIZE
, &exp
, 0,\
3818 BFD_RELOC_ALPHA_LINKAGE
);
3820 demand_empty_rest_of_line ();
3827 s_alpha_code_address (ignore
)
3833 #ifdef md_flush_pending_output
3834 md_flush_pending_output ();
3838 if (exp
.X_op
!= O_symbol
)
3840 as_fatal (_("No symbol after .code_address"));
3846 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 8, &exp
, 0,\
3847 BFD_RELOC_ALPHA_CODEADDR
);
3849 demand_empty_rest_of_line ();
3856 s_alpha_fp_save (ignore
)
3860 alpha_evax_proc
.fp_save
= tc_get_register (1);
3862 demand_empty_rest_of_line ();
3868 s_alpha_mask (ignore
)
3873 if (get_absolute_expression_and_terminator (&val
) != ',')
3875 as_warn (_("Bad .mask directive"));
3876 --input_line_pointer
;
3880 alpha_evax_proc
.imask
= val
;
3881 (void)get_absolute_expression ();
3883 demand_empty_rest_of_line ();
3890 s_alpha_fmask (ignore
)
3895 if (get_absolute_expression_and_terminator (&val
) != ',')
3897 as_warn (_("Bad .fmask directive"));
3898 --input_line_pointer
;
3902 alpha_evax_proc
.fmask
= val
;
3903 (void) get_absolute_expression ();
3905 demand_empty_rest_of_line ();
3911 s_alpha_end (ignore
)
3916 c
= get_symbol_end ();
3917 *input_line_pointer
= c
;
3918 demand_empty_rest_of_line ();
3919 alpha_evax_proc
.symbol
= 0;
3926 s_alpha_file (ignore
)
3931 static char case_hack
[32];
3933 extern char *demand_copy_string
PARAMS ((int *lenP
));
3935 sprintf (case_hack
, "<CASE:%01d%01d>",
3936 alpha_flag_hash_long_names
, alpha_flag_show_after_trunc
);
3938 s
= symbol_find_or_make (case_hack
);
3939 s
->bsym
->flags
|= BSF_FILE
;
3941 get_absolute_expression ();
3942 s
= symbol_find_or_make (demand_copy_string (&length
));
3943 s
->bsym
->flags
|= BSF_FILE
;
3944 demand_empty_rest_of_line ();
3948 #endif /* OBJ_EVAX */
3950 /* Handle the .gprel32 pseudo op. */
3953 s_alpha_gprel32 (ignore
)
3966 e
.X_add_symbol
= section_symbol(absolute_section
);
3979 e
.X_add_symbol
= section_symbol (absolute_section
);
3982 e
.X_op
= O_subtract
;
3983 e
.X_op_symbol
= alpha_gp_symbol
;
3991 if (alpha_auto_align_on
&& alpha_current_align
< 2)
3992 alpha_align (2, (char *) NULL
, alpha_insn_label
, 0);
3993 if (alpha_current_align
> 2)
3994 alpha_current_align
= 2;
3995 alpha_insn_label
= NULL
;
3999 fix_new_exp (frag_now
, p
-frag_now
->fr_literal
, 4,
4000 &e
, 0, BFD_RELOC_GPREL32
);
4003 /* Handle floating point allocation pseudo-ops. This is like the
4004 generic vresion, but it makes sure the current label, if any, is
4005 correctly aligned. */
4008 s_alpha_float_cons (type
)
4035 if (alpha_auto_align_on
&& alpha_current_align
< log_size
)
4036 alpha_align (log_size
, (char *) NULL
, alpha_insn_label
, 0);
4037 if (alpha_current_align
> log_size
)
4038 alpha_current_align
= log_size
;
4039 alpha_insn_label
= NULL
;
4044 /* Handle the .proc pseudo op. We don't really do much with it except
4048 s_alpha_proc (is_static
)
4057 /* Takes ".proc name,nargs" */
4059 name
= input_line_pointer
;
4060 c
= get_symbol_end ();
4061 p
= input_line_pointer
;
4062 symbolP
= symbol_find_or_make (name
);
4065 if (*input_line_pointer
!= ',')
4068 as_warn (_("Expected comma after name \"%s\""), name
);
4071 ignore_rest_of_line ();
4075 input_line_pointer
++;
4076 temp
= get_absolute_expression ();
4078 /* symbolP->sy_other = (signed char) temp; */
4079 as_warn (_("unhandled: .proc %s,%d"), name
, temp
);
4080 demand_empty_rest_of_line ();
4083 /* Handle the .set pseudo op. This is used to turn on and off most of
4084 the assembler features. */
4094 name
= input_line_pointer
;
4095 ch
= get_symbol_end ();
4098 if (s
[0] == 'n' && s
[1] == 'o')
4103 if (!strcmp ("reorder", s
))
4105 else if (!strcmp ("at", s
))
4106 alpha_noat_on
= !yesno
;
4107 else if (!strcmp ("macro", s
))
4108 alpha_macros_on
= yesno
;
4109 else if (!strcmp ("move", s
))
4111 else if (!strcmp ("volatile", s
))
4114 as_warn (_("Tried to .set unrecognized mode `%s'"), name
);
4116 *input_line_pointer
= ch
;
4117 demand_empty_rest_of_line ();
4120 /* Handle the .base pseudo op. This changes the assembler's notion of
4121 the $gp register. */
4124 s_alpha_base (ignore
)
4128 if (first_32bit_quadrant
)
4130 /* not fatal, but it might not work in the end */
4131 as_warn (_("File overrides no-base-register option."));
4132 first_32bit_quadrant
= 0;
4137 if (*input_line_pointer
== '$')
4139 input_line_pointer
++;
4140 if (*input_line_pointer
== 'r')
4141 input_line_pointer
++;
4144 alpha_gp_register
= get_absolute_expression ();
4145 if (alpha_gp_register
< 0 || alpha_gp_register
> 31)
4147 alpha_gp_register
= AXP_REG_GP
;
4148 as_warn (_("Bad base register, using $%d."), alpha_gp_register
);
4151 demand_empty_rest_of_line ();
4154 /* Handle the .align pseudo-op. This aligns to a power of two. It
4155 also adjusts any current instruction label. We treat this the same
4156 way the MIPS port does: .align 0 turns off auto alignment. */
4159 s_alpha_align (ignore
)
4164 long max_alignment
= 15;
4166 align
= get_absolute_expression ();
4167 if (align
> max_alignment
)
4169 align
= max_alignment
;
4170 as_bad (_("Alignment too large: %d. assumed"), align
);
4174 as_warn (_("Alignment negative: 0 assumed"));
4178 if (*input_line_pointer
== ',')
4180 input_line_pointer
++;
4181 fill
= get_absolute_expression ();
4189 alpha_auto_align_on
= 1;
4190 alpha_align (align
, pfill
, alpha_insn_label
, 1);
4194 alpha_auto_align_on
= 0;
4197 demand_empty_rest_of_line ();
4200 /* Hook the normal string processor to reset known alignment. */
4203 s_alpha_stringer (terminate
)
4206 alpha_current_align
= 0;
4207 alpha_insn_label
= NULL
;
4208 stringer (terminate
);
4211 /* Hook the normal space processing to reset known alignment. */
4214 s_alpha_space (ignore
)
4217 alpha_current_align
= 0;
4218 alpha_insn_label
= NULL
;
4222 /* Hook into cons for auto-alignment. */
4225 alpha_cons_align (size
)
4231 while ((size
>>= 1) != 0)
4234 if (alpha_auto_align_on
&& alpha_current_align
< log_size
)
4235 alpha_align (log_size
, (char *) NULL
, alpha_insn_label
, 0);
4236 if (alpha_current_align
> log_size
)
4237 alpha_current_align
= log_size
;
4238 alpha_insn_label
= NULL
;
4241 /* Here come the .uword, .ulong, and .uquad explicitly unaligned
4242 pseudos. We just turn off auto-alignment and call down to cons. */
4245 s_alpha_ucons (bytes
)
4248 int hold
= alpha_auto_align_on
;
4249 alpha_auto_align_on
= 0;
4251 alpha_auto_align_on
= hold
;
4254 /* Switch the working cpu type. */
4257 s_alpha_arch (ignored
)
4261 const struct cpu_type
*p
;
4264 name
= input_line_pointer
;
4265 ch
= get_symbol_end ();
4267 for (p
= cpu_types
; p
->name
; ++p
)
4268 if (strcmp(name
, p
->name
) == 0)
4270 alpha_target_name
= p
->name
, alpha_target
= p
->flags
;
4273 as_warn("Unknown CPU identifier `%s'", name
);
4276 *input_line_pointer
= ch
;
4277 demand_empty_rest_of_line ();
4283 /* print token expression with alpha specific extension. */
4286 alpha_print_token(f
, exp
)
4288 const expressionS
*exp
;
4298 expressionS nexp
= *exp
;
4299 nexp
.X_op
= O_register
;
4300 print_expr (f
, &nexp
);
4305 print_expr (f
, exp
);
4312 /* The target specific pseudo-ops which we support. */
4314 const pseudo_typeS md_pseudo_table
[] =
4317 {"comm", s_alpha_comm
, 0}, /* osf1 compiler does this */
4318 {"rdata", s_alpha_rdata
, 0},
4320 {"text", s_alpha_text
, 0},
4321 {"data", s_alpha_data
, 0},
4323 {"sdata", s_alpha_sdata
, 0},
4326 {"section", s_alpha_section
, 0},
4327 {"section.s", s_alpha_section
, 0},
4328 {"sect", s_alpha_section
, 0},
4329 {"sect.s", s_alpha_section
, 0},
4332 { "pdesc", s_alpha_pdesc
, 0},
4333 { "name", s_alpha_name
, 0},
4334 { "linkage", s_alpha_linkage
, 0},
4335 { "code_address", s_alpha_code_address
, 0},
4336 { "ent", s_alpha_ent
, 0},
4337 { "frame", s_alpha_frame
, 0},
4338 { "fp_save", s_alpha_fp_save
, 0},
4339 { "mask", s_alpha_mask
, 0},
4340 { "fmask", s_alpha_fmask
, 0},
4341 { "end", s_alpha_end
, 0},
4342 { "file", s_alpha_file
, 0},
4343 { "rdata", s_alpha_section
, 1},
4344 { "comm", s_alpha_comm
, 0},
4345 { "link", s_alpha_section
, 3},
4346 { "ctors", s_alpha_section
, 4},
4347 { "dtors", s_alpha_section
, 5},
4349 {"gprel32", s_alpha_gprel32
, 0},
4350 {"t_floating", s_alpha_float_cons
, 'd'},
4351 {"s_floating", s_alpha_float_cons
, 'f'},
4352 {"f_floating", s_alpha_float_cons
, 'F'},
4353 {"g_floating", s_alpha_float_cons
, 'G'},
4354 {"d_floating", s_alpha_float_cons
, 'D'},
4356 {"proc", s_alpha_proc
, 0},
4357 {"aproc", s_alpha_proc
, 1},
4358 {"set", s_alpha_set
, 0},
4359 {"reguse", s_ignore
, 0},
4360 {"livereg", s_ignore
, 0},
4361 {"base", s_alpha_base
, 0}, /*??*/
4362 {"option", s_ignore
, 0},
4363 {"prologue", s_ignore
, 0},
4364 {"aent", s_ignore
, 0},
4365 {"ugen", s_ignore
, 0},
4366 {"eflag", s_ignore
, 0},
4368 {"align", s_alpha_align
, 0},
4369 {"double", s_alpha_float_cons
, 'd'},
4370 {"float", s_alpha_float_cons
, 'f'},
4371 {"single", s_alpha_float_cons
, 'f'},
4372 {"ascii", s_alpha_stringer
, 0},
4373 {"asciz", s_alpha_stringer
, 1},
4374 {"string", s_alpha_stringer
, 1},
4375 {"space", s_alpha_space
, 0},
4376 {"skip", s_alpha_space
, 0},
4377 {"zero", s_alpha_space
, 0},
4379 /* Unaligned data pseudos. */
4380 {"uword", s_alpha_ucons
, 2},
4381 {"ulong", s_alpha_ucons
, 4},
4382 {"uquad", s_alpha_ucons
, 8},
4385 /* Dwarf wants these versions of unaligned. */
4386 {"2byte", s_alpha_ucons
, 2},
4387 {"4byte", s_alpha_ucons
, 4},
4388 {"8byte", s_alpha_ucons
, 8},
4391 /* We don't do any optimizing, so we can safely ignore these. */
4392 {"noalias", s_ignore
, 0},
4393 {"alias", s_ignore
, 0},
4395 {"arch", s_alpha_arch
, 0},
4401 /* Build a BFD section with its flags set appropriately for the .lita,
4402 .lit8, or .lit4 sections. */
4405 create_literal_section (name
, secp
, symp
)
4410 segT current_section
= now_seg
;
4411 int current_subsec
= now_subseg
;
4414 *secp
= new_sec
= subseg_new (name
, 0);
4415 subseg_set (current_section
, current_subsec
);
4416 bfd_set_section_alignment (stdoutput
, new_sec
, 4);
4417 bfd_set_section_flags (stdoutput
, new_sec
,
4418 SEC_RELOC
| SEC_ALLOC
| SEC_LOAD
| SEC_READONLY
4421 S_CLEAR_EXTERNAL (*symp
= section_symbol (new_sec
));
4426 /* @@@ GP selection voodoo. All of this seems overly complicated and
4427 unnecessary; which is the primary reason it's for ECOFF only. */
4436 vma
= bfd_get_section_vma (foo
, sec
);
4437 if (vma
&& vma
< alpha_gp_value
)
4438 alpha_gp_value
= vma
;
4444 assert (alpha_gp_value
== 0);
4446 /* Get minus-one in whatever width... */
4447 alpha_gp_value
= 0; alpha_gp_value
--;
4449 /* Select the smallest VMA of these existing sections. */
4450 maybe_set_gp (alpha_lita_section
);
4452 /* These were disabled before -- should we use them? */
4453 maybe_set_gp (sdata
);
4454 maybe_set_gp (lit8_sec
);
4455 maybe_set_gp (lit4_sec
);
4458 /* @@ Will a simple 0x8000 work here? If not, why not? */
4459 #define GP_ADJUSTMENT (0x8000 - 0x10)
4461 alpha_gp_value
+= GP_ADJUSTMENT
;
4463 S_SET_VALUE (alpha_gp_symbol
, alpha_gp_value
);
4466 printf (_("Chose GP value of %lx\n"), alpha_gp_value
);
4469 #endif /* OBJ_ECOFF */
4471 /* Called internally to handle all alignment needs. This takes care
4472 of eliding calls to frag_align if'n the cached current alignment
4473 says we've already got it, as well as taking care of the auto-align
4474 feature wrt labels. */
4477 alpha_align (n
, pfill
, label
, force
)
4483 if (alpha_current_align
>= n
)
4489 && (bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
) != 0)
4491 static char const unop
[4] = { 0x00, 0x00, 0xe0, 0x2f };
4492 static char const nopunop
[8] = {
4493 0x1f, 0x04, 0xff, 0x47,
4494 0x00, 0x00, 0xe0, 0x2f
4497 /* First, make sure we're on a four-byte boundary, in case
4498 someone has been putting .byte values into the text
4499 section. The DEC assembler silently fills with unaligned
4500 no-op instructions. This will zero-fill, then nop-fill
4501 with proper alignment. */
4502 if (alpha_current_align
< 2)
4503 frag_align (2, 0, 0);
4504 if (alpha_current_align
< 3)
4505 frag_align_pattern (3, unop
, sizeof unop
, 0);
4507 frag_align_pattern (n
, nopunop
, sizeof nopunop
, 0);
4510 frag_align (n
, 0, 0);
4513 frag_align (n
, *pfill
, 0);
4515 alpha_current_align
= n
;
4519 assert (S_GET_SEGMENT (label
) == now_seg
);
4520 label
->sy_frag
= frag_now
;
4521 S_SET_VALUE (label
, (valueT
) frag_now_fix ());
4524 record_alignment(now_seg
, n
);
4526 /* ??? if alpha_flag_relax && force && elf, record the requested alignment
4527 in a reloc for the linker to see. */
4530 /* The Alpha has support for some VAX floating point types, as well as for
4531 IEEE floating point. We consider IEEE to be the primary floating point
4532 format, and sneak in the VAX floating point support here. */
4533 #define md_atof vax_md_atof
4534 #include "config/atof-vax.c"