1 /* tc-alpha.c - Processor-specific code for the DEC Alpha AXP CPU.
2 Copyright (C) 1989, 93, 94, 95, 96, 1997 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 */
114 #define range_signed_16(x) ((offsetT)(x) >= -(offsetT)0x8000 && \
115 (offsetT)(x) <= (offsetT)0x7FFF)
116 #define range_signed_32(x) ((offsetT)(x) >= -(offsetT)0x80000000 && \
117 (offsetT)(x) <= (offsetT)0x7FFFFFFF)
119 /* Macros for sign extending from 16- and 32-bits. */
120 /* XXX: The cast macros will work on all the systems that I care about,
121 but really a predicate should be found to use the non-cast forms. */
124 #define sign_extend_16(x) ((short)(x))
125 #define sign_extend_32(x) ((int)(x))
127 #define sign_extend_16(x) ((offsetT)(((x) & 0xFFFF) ^ 0x8000) - 0x8000)
128 #define sign_extend_32(x) ((offsetT)(((x) & 0xFFFFFFFF) \
129 ^ 0x80000000) - 0x80000000)
132 /* Macros to build tokens */
134 #define set_tok_reg(t, r) (memset(&(t), 0, sizeof(t)), \
135 (t).X_op = O_register, \
136 (t).X_add_number = (r))
137 #define set_tok_preg(t, r) (memset(&(t), 0, sizeof(t)), \
138 (t).X_op = O_pregister, \
139 (t).X_add_number = (r))
140 #define set_tok_cpreg(t, r) (memset(&(t), 0, sizeof(t)), \
141 (t).X_op = O_cpregister, \
142 (t).X_add_number = (r))
143 #define set_tok_freg(t, r) (memset(&(t), 0, sizeof(t)), \
144 (t).X_op = O_register, \
145 (t).X_add_number = (r)+32)
146 #define set_tok_sym(t, s, a) (memset(&(t), 0, sizeof(t)), \
147 (t).X_op = O_symbol, \
148 (t).X_add_symbol = (s), \
149 (t).X_add_number = (a))
150 #define set_tok_const(t, n) (memset(&(t), 0, sizeof(t)), \
151 (t).X_op = O_constant, \
152 (t).X_add_number = (n))
155 /* Prototypes for all local functions */
157 static int tokenize_arguments
PARAMS ((char *, expressionS
*, int));
158 static const struct alpha_opcode
*find_opcode_match
159 PARAMS ((const struct alpha_opcode
*, const expressionS
*, int *, int *));
160 static const struct alpha_macro
*find_macro_match
161 PARAMS ((const struct alpha_macro
*, const expressionS
*, int *));
162 static unsigned insert_operand
163 PARAMS ((unsigned, const struct alpha_operand
*, offsetT
, char *, unsigned));
164 static void assemble_insn
165 PARAMS ((const struct alpha_opcode
*, const expressionS
*, int,
166 struct alpha_insn
*));
167 static void emit_insn
PARAMS ((struct alpha_insn
*));
168 static void assemble_tokens_to_insn
169 PARAMS ((const char *, const expressionS
*, int, struct alpha_insn
*));
170 static void assemble_tokens
171 PARAMS ((const char *, const expressionS
*, int, int));
173 static int load_expression
174 PARAMS ((int, const expressionS
*, int *, expressionS
*));
176 static void emit_ldgp
PARAMS ((const expressionS
*, int, const PTR
));
177 static void emit_division
PARAMS ((const expressionS
*, int, const PTR
));
178 static void emit_lda
PARAMS ((const expressionS
*, int, const PTR
));
179 static void emit_ldah
PARAMS ((const expressionS
*, int, const PTR
));
180 static void emit_ir_load
PARAMS ((const expressionS
*, int, const PTR
));
181 static void emit_loadstore
PARAMS ((const expressionS
*, int, const PTR
));
182 static void emit_jsrjmp
PARAMS ((const expressionS
*, int, const PTR
));
183 static void emit_ldX
PARAMS ((const expressionS
*, int, const PTR
));
184 static void emit_ldXu
PARAMS ((const expressionS
*, int, const PTR
));
185 static void emit_uldX
PARAMS ((const expressionS
*, int, const PTR
));
186 static void emit_uldXu
PARAMS ((const expressionS
*, int, const PTR
));
187 static void emit_ldil
PARAMS ((const expressionS
*, int, const PTR
));
188 static void emit_stX
PARAMS ((const expressionS
*, int, const PTR
));
189 static void emit_ustX
PARAMS ((const expressionS
*, int, const PTR
));
190 static void emit_sextX
PARAMS ((const expressionS
*, int, const PTR
));
191 static void emit_retjcr
PARAMS ((const expressionS
*, int, const PTR
));
193 static void s_alpha_text
PARAMS ((int));
194 static void s_alpha_data
PARAMS ((int));
196 static void s_alpha_comm
PARAMS ((int));
198 #if defined (OBJ_ECOFF) || defined (OBJ_EVAX)
199 static void s_alpha_rdata
PARAMS ((int));
202 static void s_alpha_sdata
PARAMS ((int));
205 static void s_alpha_section
PARAMS ((int));
208 static void s_alpha_section
PARAMS ((int));
210 static void s_alpha_gprel32
PARAMS ((int));
211 static void s_alpha_float_cons
PARAMS ((int));
212 static void s_alpha_proc
PARAMS ((int));
213 static void s_alpha_set
PARAMS ((int));
214 static void s_alpha_base
PARAMS ((int));
215 static void s_alpha_align
PARAMS ((int));
216 static void s_alpha_stringer
PARAMS ((int));
217 static void s_alpha_space
PARAMS ((int));
219 static void create_literal_section
PARAMS ((const char *, segT
*, symbolS
**));
221 static void select_gp_value
PARAMS ((void));
223 static void alpha_align
PARAMS ((int, char *, symbolS
*));
226 /* Generic assembler global variables which must be defined by all
229 /* These are exported to relaxing code, even though we don't do any
230 relaxing on this processor currently. */
231 int md_short_jump_size
= 4;
232 int md_long_jump_size
= 4;
234 /* Characters which always start a comment. */
235 const char comment_chars
[] = "#";
237 /* Characters which start a comment at the beginning of a line. */
238 const char line_comment_chars
[] = "#";
240 /* Characters which may be used to separate multiple commands on a
242 const char line_separator_chars
[] = ";";
244 /* Characters which are used to indicate an exponent in a floating
246 const char EXP_CHARS
[] = "eE";
248 /* Characters which mean that a number is a floating point constant,
251 const char FLT_CHARS
[] = "dD";
253 /* XXX: Do all of these really get used on the alpha?? */
254 char FLT_CHARS
[] = "rRsSfFdDxXpP";
258 const char *md_shortopts
= "Fm:g+1h:H";
260 const char *md_shortopts
= "Fm:g";
263 struct option md_longopts
[] = {
264 #define OPTION_32ADDR (OPTION_MD_BASE)
265 { "32addr", no_argument
, NULL
, OPTION_32ADDR
},
266 { NULL
, no_argument
, NULL
, 0 }
269 size_t md_longopts_size
= sizeof(md_longopts
);
274 #define AXP_REG_R16 16
275 #define AXP_REG_R17 17
277 #define AXP_REG_T9 22
279 #define AXP_REG_T10 23
281 #define AXP_REG_T11 24
283 #define AXP_REG_T12 25
284 #define AXP_REG_AI 25
286 #define AXP_REG_FP 29
289 #define AXP_REG_GP AXP_REG_PV
290 #endif /* OBJ_EVAX */
292 /* The cpu for which we are generating code */
293 static unsigned alpha_target
= AXP_OPCODE_BASE
;
294 static const char *alpha_target_name
= "<all>";
296 /* The hash table of instruction opcodes */
297 static struct hash_control
*alpha_opcode_hash
;
299 /* The hash table of macro opcodes */
300 static struct hash_control
*alpha_macro_hash
;
303 /* The $gp relocation symbol */
304 static symbolS
*alpha_gp_symbol
;
306 /* XXX: what is this, and why is it exported? */
307 valueT alpha_gp_value
;
310 /* The current $gp register */
311 static int alpha_gp_register
= AXP_REG_GP
;
313 /* A table of the register symbols */
314 static symbolS
*alpha_register_table
[64];
316 /* Constant sections, or sections of constants */
318 static segT alpha_lita_section
;
319 static segT alpha_lit4_section
;
322 static segT alpha_link_section
;
323 static segT alpha_ctors_section
;
324 static segT alpha_dtors_section
;
326 static segT alpha_lit8_section
;
328 /* Symbols referring to said sections. */
330 static symbolS
*alpha_lita_symbol
;
331 static symbolS
*alpha_lit4_symbol
;
334 static symbolS
*alpha_link_symbol
;
335 static symbolS
*alpha_ctors_symbol
;
336 static symbolS
*alpha_dtors_symbol
;
338 static symbolS
*alpha_lit8_symbol
;
340 /* Literal for .litX+0x8000 within .lita */
342 static offsetT alpha_lit4_literal
;
343 static offsetT alpha_lit8_literal
;
346 /* Is the assembler not allowed to use $at? */
347 static int alpha_noat_on
= 0;
349 /* Are macros enabled? */
350 static int alpha_macros_on
= 1;
352 /* Are floats disabled? */
353 static int alpha_nofloats_on
= 0;
355 /* Are addresses 32 bit? */
356 static int alpha_addr32_on
= 0;
358 /* Symbol labelling the current insn. When the Alpha gas sees
361 and the section happens to not be on an eight byte boundary, it
362 will align both the symbol and the .quad to an eight byte boundary. */
363 static symbolS
*alpha_insn_label
;
365 /* Whether we should automatically align data generation pseudo-ops.
366 .align 0 will turn this off. */
367 static int alpha_auto_align_on
= 1;
369 /* The known current alignment of the current section. */
370 static int alpha_current_align
;
372 /* These are exported to ECOFF code. */
373 unsigned long alpha_gprmask
, alpha_fprmask
;
375 /* Whether the debugging option was seen. */
376 static int alpha_debug
;
379 /* Collect information about current procedure here. */
381 symbolS
*symbol
; /* proc pdesc symbol */
383 int framereg
; /* register for frame pointer */
384 int framesize
; /* size of frame */
394 static int alpha_flag_hash_long_names
= 0; /* -+ */
395 static int alpha_flag_show_after_trunc
= 0; /* -H */
397 /* If the -+ switch is given, then a hash is appended to any name that is
398 * longer than 64 characters, else longer symbol names are truncated.
403 /* A table of CPU names and opcode sets. */
405 static const struct cpu_type
411 /* Ad hoc convention: cpu number gets palcode, process code doesn't.
412 This supports usage under DU 4.0b that does ".arch ev4", and
413 usage in MILO that does -m21064. Probably something more
414 specific like -m21064-pal should be used, but oh well. */
416 { "21064", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
417 { "21064a", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
418 { "21066", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
419 { "21068", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
420 { "21164", AXP_OPCODE_BASE
|AXP_OPCODE_EV5
},
421 /* Do we have CIX extension here? */
422 { "21164a", AXP_OPCODE_BASE
|AXP_OPCODE_EV5
|AXP_OPCODE_BWX
},
423 /* Still same PALcodes? */
424 { "21164pc", (AXP_OPCODE_BASE
|AXP_OPCODE_EV5
|AXP_OPCODE_BWX
425 |AXP_OPCODE_CIX
|AXP_OPCODE_MAX
) },
426 /* All new PALcodes? Extras? */
427 { "21264", (AXP_OPCODE_BASE
|AXP_OPCODE_BWX
428 |AXP_OPCODE_CIX
|AXP_OPCODE_MAX
) },
430 { "ev4", AXP_OPCODE_BASE
},
431 { "ev45", AXP_OPCODE_BASE
},
432 { "lca45", AXP_OPCODE_BASE
},
433 { "ev5", AXP_OPCODE_BASE
},
434 { "ev56", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
},
435 { "pca56", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
|AXP_OPCODE_CIX
|AXP_OPCODE_MAX
},
436 { "ev6", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
|AXP_OPCODE_CIX
|AXP_OPCODE_MAX
},
438 { "all", AXP_OPCODE_BASE
},
442 /* The macro table */
444 static const struct alpha_macro alpha_macros
[] = {
445 /* Load/Store macros */
446 { "lda", emit_lda
, NULL
,
447 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
448 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
449 { "ldah", emit_ldah
, NULL
,
450 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
452 { "ldl", emit_ir_load
, "ldl",
453 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
454 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
455 { "ldl_l", emit_ir_load
, "ldl_l",
456 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
457 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
458 { "ldq", emit_ir_load
, "ldq",
459 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
460 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
461 { "ldq_l", emit_ir_load
, "ldq_l",
462 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
463 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
464 { "ldq_u", emit_ir_load
, "ldq_u",
465 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
466 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
467 { "ldf", emit_loadstore
, "ldf",
468 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
469 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
470 { "ldg", emit_loadstore
, "ldg",
471 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
472 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
473 { "lds", emit_loadstore
, "lds",
474 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
475 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
476 { "ldt", emit_loadstore
, "ldt",
477 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
478 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
480 { "ldb", emit_ldX
, (PTR
)0,
481 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
482 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
483 { "ldbu", emit_ldXu
, (PTR
)0,
484 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
485 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
486 { "ldw", emit_ldX
, (PTR
)1,
487 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
488 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
489 { "ldwu", emit_ldXu
, (PTR
)1,
490 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
491 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
493 { "uldw", emit_uldX
, (PTR
)1,
494 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
495 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
496 { "uldwu", emit_uldXu
, (PTR
)1,
497 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
498 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
499 { "uldl", emit_uldX
, (PTR
)2,
500 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
501 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
502 { "uldlu", emit_uldXu
, (PTR
)2,
503 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
504 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
505 { "uldq", emit_uldXu
, (PTR
)3,
506 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
507 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
509 { "ldgp", emit_ldgp
, NULL
,
510 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
} },
512 { "ldi", emit_lda
, NULL
,
513 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
514 { "ldil", emit_ldil
, NULL
,
515 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
516 { "ldiq", emit_lda
, NULL
,
517 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
519 { "ldif" emit_ldiq
, NULL
,
520 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
521 { "ldid" emit_ldiq
, NULL
,
522 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
523 { "ldig" emit_ldiq
, NULL
,
524 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
525 { "ldis" emit_ldiq
, NULL
,
526 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
527 { "ldit" emit_ldiq
, NULL
,
528 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
531 { "stl", emit_loadstore
, "stl",
532 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
533 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
534 { "stl_c", emit_loadstore
, "stl_c",
535 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
536 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
537 { "stq", emit_loadstore
, "stq",
538 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
539 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
540 { "stq_c", emit_loadstore
, "stq_c",
541 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
542 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
543 { "stq_u", emit_loadstore
, "stq_u",
544 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
545 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
546 { "stf", emit_loadstore
, "stf",
547 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
548 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
549 { "stg", emit_loadstore
, "stg",
550 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
551 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
552 { "sts", emit_loadstore
, "sts",
553 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
554 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
555 { "stt", emit_loadstore
, "stt",
556 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
557 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
559 { "stb", emit_stX
, (PTR
)0,
560 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
561 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
562 { "stw", emit_stX
, (PTR
)1,
563 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
564 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
565 { "ustw", emit_ustX
, (PTR
)1,
566 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
567 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
568 { "ustl", emit_ustX
, (PTR
)2,
569 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
570 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
571 { "ustq", emit_ustX
, (PTR
)3,
572 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
573 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
575 /* Arithmetic macros */
577 { "absl" emit_absl
, 1, { IR
} },
578 { "absl" emit_absl
, 2, { IR
, IR
} },
579 { "absl" emit_absl
, 2, { EXP
, IR
} },
580 { "absq" emit_absq
, 1, { IR
} },
581 { "absq" emit_absq
, 2, { IR
, IR
} },
582 { "absq" emit_absq
, 2, { EXP
, IR
} },
585 { "sextb", emit_sextX
, (PTR
)0,
586 { MACRO_IR
, MACRO_IR
, MACRO_EOA
,
588 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
589 { "sextw", emit_sextX
, (PTR
)1,
590 { MACRO_IR
, MACRO_IR
, MACRO_EOA
,
592 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
594 { "divl", emit_division
, "__divl",
595 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
596 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
597 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
598 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
599 { "divlu", emit_division
, "__divlu",
600 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
601 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
602 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
603 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
604 { "divq", emit_division
, "__divq",
605 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
606 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
607 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
608 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
609 { "divqu", emit_division
, "__divqu",
610 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
611 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
612 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
613 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
614 { "reml", emit_division
, "__reml",
615 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
616 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
617 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
618 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
619 { "remlu", emit_division
, "__remlu",
620 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
621 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
622 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
623 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
624 { "remq", emit_division
, "__remq",
625 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
626 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
627 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
628 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
629 { "remqu", emit_division
, "__remqu",
630 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
631 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
632 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
633 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
635 { "jsr", emit_jsrjmp
, "jsr",
636 { MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
637 MACRO_PIR
, MACRO_EOA
,
638 MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
639 MACRO_EXP
, MACRO_EOA
} },
640 { "jmp", emit_jsrjmp
, "jmp",
641 { MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
642 MACRO_PIR
, MACRO_EOA
,
643 MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
644 MACRO_EXP
, MACRO_EOA
} },
645 { "ret", emit_retjcr
, "ret",
646 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
648 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
649 MACRO_PIR
, MACRO_EOA
,
650 MACRO_EXP
, MACRO_EOA
,
652 { "jcr", emit_retjcr
, "jcr",
653 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
655 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
656 MACRO_PIR
, MACRO_EOA
,
657 MACRO_EXP
, MACRO_EOA
,
659 { "jsr_coroutine", emit_retjcr
, "jcr",
660 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
662 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
663 MACRO_PIR
, MACRO_EOA
,
664 MACRO_EXP
, MACRO_EOA
,
668 static const int alpha_num_macros
669 = sizeof(alpha_macros
) / sizeof(*alpha_macros
);
671 /* Public interface functions */
673 /* This function is called once, at assembler startup time. It sets
674 up all the tables, etc. that the MD part of the assembler will
675 need, that can be determined before arguments are parsed. */
682 /* Create the opcode hash table */
684 alpha_opcode_hash
= hash_new ();
685 for (i
= 0; i
< alpha_num_opcodes
; )
687 const char *name
, *retval
, *slash
;
689 name
= alpha_opcodes
[i
].name
;
690 retval
= hash_insert (alpha_opcode_hash
, name
, (PTR
)&alpha_opcodes
[i
]);
692 as_fatal ("internal error: can't hash opcode `%s': %s", name
, retval
);
694 /* Some opcodes include modifiers of various sorts with a "/mod"
695 syntax, like the architecture manual suggests. However, for
696 use with gcc at least, we also need access to those same opcodes
699 if ((slash
= strchr (name
, '/')) != NULL
)
701 char *p
= xmalloc (strlen (name
));
702 memcpy (p
, name
, slash
- name
);
703 strcpy (p
+ (slash
- name
), slash
+ 1);
705 (void)hash_insert(alpha_opcode_hash
, p
, (PTR
)&alpha_opcodes
[i
]);
706 /* Ignore failures -- the opcode table does duplicate some
707 variants in different forms, like "hw_stq" and "hw_st/q". */
710 while (++i
< alpha_num_opcodes
711 && (alpha_opcodes
[i
].name
== name
712 || !strcmp (alpha_opcodes
[i
].name
, name
)))
716 /* Create the macro hash table */
718 alpha_macro_hash
= hash_new ();
719 for (i
= 0; i
< alpha_num_macros
; )
721 const char *name
, *retval
;
723 name
= alpha_macros
[i
].name
;
724 retval
= hash_insert (alpha_macro_hash
, name
, (PTR
)&alpha_macros
[i
]);
726 as_fatal ("internal error: can't hash macro `%s': %s", name
, retval
);
728 while (++i
< alpha_num_macros
729 && (alpha_macros
[i
].name
== name
730 || !strcmp (alpha_macros
[i
].name
, name
)))
734 /* Construct symbols for each of the registers */
736 for (i
= 0; i
< 32; ++i
)
739 sprintf(name
, "$%d", i
);
740 alpha_register_table
[i
] = symbol_create(name
, reg_section
, i
,
746 sprintf(name
, "$f%d", i
-32);
747 alpha_register_table
[i
] = symbol_create(name
, reg_section
, i
,
751 /* Create the special symbols and sections we'll be using */
753 /* So .sbss will get used for tiny objects. */
754 bfd_set_gp_size (stdoutput
, 8);
757 create_literal_section (".lita", &alpha_lita_section
, &alpha_lita_symbol
);
759 /* For handling the GP, create a symbol that won't be output in the
760 symbol table. We'll edit it out of relocs later. */
761 alpha_gp_symbol
= symbol_create ("<GP value>", alpha_lita_section
, 0x8000,
766 create_literal_section (".link", &alpha_link_section
, &alpha_link_symbol
);
774 sec
= subseg_new(".mdebug", (subsegT
)0);
775 bfd_set_section_flags(stdoutput
, sec
, SEC_HAS_CONTENTS
|SEC_READONLY
);
776 bfd_set_section_alignment(stdoutput
, sec
, 3);
779 sec
= subseg_new(".reginfo", (subsegT
)0);
780 /* The ABI says this section should be loaded so that the running
781 program can access it. */
782 bfd_set_section_flags(stdoutput
, sec
,
783 SEC_ALLOC
|SEC_LOAD
|SEC_READONLY
|SEC_DATA
);
784 bfd_set_section_alignement(stdoutput
, sec
, 3);
789 subseg_set(text_section
, 0);
792 /* The public interface to the instruction assembler. */
798 char opname
[32]; /* current maximum is 13 */
799 expressionS tok
[MAX_INSN_ARGS
];
800 int ntok
, opnamelen
, trunclen
;
802 /* split off the opcode */
803 opnamelen
= strspn (str
, "abcdefghijklmnopqrstuvwxyz_/48");
804 trunclen
= (opnamelen
< sizeof (opname
) - 1
806 : sizeof (opname
) - 1);
807 memcpy (opname
, str
, trunclen
);
808 opname
[trunclen
] = '\0';
810 /* tokenize the rest of the line */
811 if ((ntok
= tokenize_arguments (str
+ opnamelen
, tok
, MAX_INSN_ARGS
)) < 0)
813 as_bad ("syntax error");
818 assemble_tokens (opname
, tok
, ntok
, alpha_macros_on
);
821 /* Round up a section's size to the appropriate boundary. */
824 md_section_align (seg
, size
)
828 int align
= bfd_get_section_alignment(stdoutput
, seg
);
829 valueT mask
= ((valueT
)1 << align
) - 1;
831 return (size
+ mask
) & ~mask
;
834 /* Turn a string in input_line_pointer into a floating point constant
835 of type type, and store the appropriate bytes in *litP. The number
836 of LITTLENUMS emitted is stored in *sizeP. An error message is
837 returned, or NULL on OK. */
839 /* Equal to MAX_PRECISION in atof-ieee.c */
840 #define MAX_LITTLENUMS 6
842 extern char *vax_md_atof
PARAMS ((int, char *, int *));
845 md_atof (type
, litP
, sizeP
)
851 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
852 LITTLENUM_TYPE
*wordP
;
859 /* VAX md_atof doesn't like "G" for some reason. */
863 return vax_md_atof (type
, litP
, sizeP
);
886 return "Bad call to MD_ATOF()";
888 t
= atof_ieee (input_line_pointer
, type
, words
);
890 input_line_pointer
= t
;
891 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
893 for (wordP
= words
+ prec
- 1; prec
--;)
895 md_number_to_chars (litP
, (long) (*wordP
--), sizeof (LITTLENUM_TYPE
));
896 litP
+= sizeof (LITTLENUM_TYPE
);
902 /* Take care of the target-specific command-line options. */
905 md_parse_option (c
, arg
)
912 alpha_nofloats_on
= 1;
925 const struct cpu_type
*p
;
926 for (p
= cpu_types
; p
->name
; ++p
)
927 if (strcmp(arg
, p
->name
) == 0)
929 alpha_target_name
= p
->name
, alpha_target
= p
->flags
;
932 as_warn("Unknown CPU identifier `%s'", arg
);
938 case '+': /* For g++. Hash any name > 63 chars long. */
939 alpha_flag_hash_long_names
= 1;
942 case 'H': /* Show new symbol after hash truncation */
943 alpha_flag_show_after_trunc
= 1;
946 case 'h': /* for gnu-c/vax compatibility. */
957 /* Print a description of the command-line options that we accept. */
960 md_show_usage (stream
)
965 -32addr treat addresses as 32-bit values\n\
966 -F lack floating point instructions support\n\
967 -m21064 | -m21066 | -m21164 | -m21164a\n\
968 -mev4 | -mev45 | -mev5 | -mev56 | -mall\n\
969 specify variant of Alpha architecture\n",
974 -+ hash encode (don't truncate) names longer than 64 characters\n\
975 -H show new symbol after hash truncation\n",
980 /* Decide from what point a pc-relative relocation is relative to,
981 relative to the pc-relative fixup. Er, relatively speaking. */
987 valueT addr
= fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
988 switch (fixP
->fx_r_type
)
990 case BFD_RELOC_ALPHA_GPDISP
:
991 case BFD_RELOC_ALPHA_GPDISP_HI16
:
992 case BFD_RELOC_ALPHA_GPDISP_LO16
:
995 return fixP
->fx_size
+ addr
;
999 /* Attempt to simplify or even eliminate a fixup. The return value is
1000 ignored; perhaps it was once meaningful, but now it is historical.
1001 To indicate that a fixup has been eliminated, set fixP->fx_done.
1003 For ELF, here it is that we transform the GPDISP_HI16 reloc we used
1004 internally into the GPDISP reloc used externally. We had to do
1005 this so that we'd have the GPDISP_LO16 reloc as a tag to compute
1006 the distance to the "lda" instruction for setting the addend to
1010 md_apply_fix (fixP
, valueP
)
1014 char * const fixpos
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
1015 valueT value
= *valueP
;
1016 unsigned image
, size
;
1018 switch (fixP
->fx_r_type
)
1020 /* The GPDISP relocations are processed internally with a symbol
1021 referring to the current function; we need to drop in a value
1022 which, when added to the address of the start of the function,
1023 gives the desired GP. */
1024 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1026 fixS
*next
= fixP
->fx_next
;
1027 assert (next
->fx_r_type
== BFD_RELOC_ALPHA_GPDISP_LO16
);
1029 fixP
->fx_offset
= (next
->fx_frag
->fr_address
+ next
->fx_where
1030 - fixP
->fx_frag
->fr_address
- fixP
->fx_where
);
1032 value
= (value
- sign_extend_16 (value
)) >> 16;
1035 fixP
->fx_r_type
= BFD_RELOC_ALPHA_GPDISP
;
1039 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1040 value
= sign_extend_16 (value
);
1041 fixP
->fx_offset
= 0;
1047 fixP
->fx_addsy
= section_symbol (absolute_section
);
1048 md_number_to_chars (fixpos
, value
, 2);
1053 fixP
->fx_r_type
= BFD_RELOC_16_PCREL
;
1058 fixP
->fx_r_type
= BFD_RELOC_32_PCREL
;
1063 fixP
->fx_r_type
= BFD_RELOC_64_PCREL
;
1066 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
1068 md_number_to_chars (fixpos
, value
, size
);
1074 case BFD_RELOC_GPREL32
:
1075 assert (fixP
->fx_subsy
== alpha_gp_symbol
);
1077 /* FIXME: inherited this obliviousness of `value' -- why? */
1078 md_number_to_chars (fixpos
, -alpha_gp_value
, 4);
1082 case BFD_RELOC_GPREL32
:
1086 case BFD_RELOC_23_PCREL_S2
:
1087 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
1089 image
= bfd_getl32(fixpos
);
1090 image
= (image
& ~0x1FFFFF) | ((value
>> 2) & 0x1FFFFF);
1095 case BFD_RELOC_ALPHA_HINT
:
1096 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
1098 image
= bfd_getl32(fixpos
);
1099 image
= (image
& ~0x3FFF) | ((value
>> 2) & 0x3FFF);
1105 case BFD_RELOC_ALPHA_LITERAL
:
1106 md_number_to_chars (fixpos
, value
, 2);
1109 case BFD_RELOC_ALPHA_LITUSE
:
1113 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1114 case BFD_RELOC_ALPHA_LITUSE
:
1118 case BFD_RELOC_ALPHA_LINKAGE
:
1119 case BFD_RELOC_ALPHA_CODEADDR
:
1125 const struct alpha_operand
*operand
;
1127 if ((int)fixP
->fx_r_type
>= 0)
1128 as_fatal ("unhandled relocation type %s",
1129 bfd_get_reloc_code_name (fixP
->fx_r_type
));
1131 assert (-(int)fixP
->fx_r_type
< alpha_num_operands
);
1132 operand
= &alpha_operands
[-(int)fixP
->fx_r_type
];
1134 /* The rest of these fixups only exist internally during symbol
1135 resolution and have no representation in the object file.
1136 Therefore they must be completely resolved as constants. */
1138 if (fixP
->fx_addsy
!= 0
1139 && fixP
->fx_addsy
->bsym
->section
!= absolute_section
)
1140 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
1141 "non-absolute expression in constant field");
1143 image
= bfd_getl32(fixpos
);
1144 image
= insert_operand(image
, operand
, (offsetT
)value
,
1145 fixP
->fx_file
, fixP
->fx_line
);
1150 if (fixP
->fx_addsy
!= 0 || fixP
->fx_pcrel
!= 0)
1154 as_warn_where(fixP
->fx_file
, fixP
->fx_line
,
1155 "type %d reloc done?\n", (int)fixP
->fx_r_type
);
1160 md_number_to_chars(fixpos
, image
, 4);
1168 * Look for a register name in the given symbol.
1172 md_undefined_symbol(name
)
1177 int is_float
= 0, num
;
1182 if (name
[1] == 'p' && name
[2] == '\0')
1183 return alpha_register_table
[AXP_REG_FP
];
1188 if (!isdigit(*++name
))
1192 case '0': case '1': case '2': case '3': case '4':
1193 case '5': case '6': case '7': case '8': case '9':
1194 if (name
[1] == '\0')
1195 num
= name
[0] - '0';
1196 else if (name
[0] != '0' && isdigit(name
[1]) && name
[2] == '\0')
1198 num
= (name
[0] - '0') * 10 + name
[1] - '0';
1205 if (!alpha_noat_on
&& num
== AXP_REG_AT
)
1206 as_warn("Used $at without \".set noat\"");
1207 return alpha_register_table
[num
+ is_float
];
1210 if (name
[1] == 't' && name
[2] == '\0')
1213 as_warn("Used $at without \".set noat\"");
1214 return alpha_register_table
[AXP_REG_AT
];
1219 if (name
[1] == 'p' && name
[2] == '\0')
1220 return alpha_register_table
[alpha_gp_register
];
1224 if (name
[1] == 'p' && name
[2] == '\0')
1225 return alpha_register_table
[AXP_REG_SP
];
1233 /* @@@ Magic ECOFF bits. */
1236 alpha_frob_ecoff_data ()
1239 /* $zero and $f31 are read-only */
1240 alpha_gprmask
&= ~1;
1241 alpha_fprmask
&= ~1;
1245 /* Hook to remember a recently defined label so that the auto-align
1246 code can adjust the symbol after we know what alignment will be
1250 alpha_define_label (sym
)
1253 alpha_insn_label
= sym
;
1256 /* Return true if we must always emit a reloc for a type and false if
1257 there is some hope of resolving it a assembly time. */
1260 alpha_force_relocation (f
)
1263 switch (f
->fx_r_type
)
1265 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1266 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1267 case BFD_RELOC_ALPHA_GPDISP
:
1269 case BFD_RELOC_ALPHA_LITERAL
:
1272 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1274 case BFD_RELOC_ALPHA_LITUSE
:
1275 case BFD_RELOC_GPREL32
:
1277 case BFD_RELOC_ALPHA_LINKAGE
:
1278 case BFD_RELOC_ALPHA_CODEADDR
:
1282 case BFD_RELOC_23_PCREL_S2
:
1285 case BFD_RELOC_ALPHA_HINT
:
1289 assert((int)f
->fx_r_type
< 0 && -(int)f
->fx_r_type
< alpha_num_operands
);
1294 /* Return true if we can partially resolve a relocation now. */
1297 alpha_fix_adjustable (f
)
1301 /* Prevent all adjustments to global symbols */
1302 if (S_IS_EXTERN (f
->fx_addsy
))
1306 /* Are there any relocation types for which we must generate a reloc
1307 but we can adjust the values contained within it? */
1308 switch (f
->fx_r_type
)
1310 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1311 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1312 case BFD_RELOC_ALPHA_GPDISP
:
1316 case BFD_RELOC_ALPHA_LITERAL
:
1319 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1322 case BFD_RELOC_ALPHA_LINKAGE
:
1323 case BFD_RELOC_ALPHA_CODEADDR
:
1327 case BFD_RELOC_ALPHA_LITUSE
:
1330 case BFD_RELOC_GPREL32
:
1331 case BFD_RELOC_23_PCREL_S2
:
1334 case BFD_RELOC_ALPHA_HINT
:
1338 assert ((int)f
->fx_r_type
< 0
1339 && - (int)f
->fx_r_type
< alpha_num_operands
);
1345 /* Generate the BFD reloc to be stuck in the object file from the
1346 fixup used internally in the assembler. */
1349 tc_gen_reloc (sec
, fixp
)
1355 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
1356 reloc
->sym_ptr_ptr
= &fixp
->fx_addsy
->bsym
;
1357 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
1359 /* Make sure none of our internal relocations make it this far.
1360 They'd better have been fully resolved by this point. */
1361 assert ((int)fixp
->fx_r_type
> 0);
1363 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
1364 if (reloc
->howto
== NULL
)
1366 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1367 "cannot represent `%s' relocation in object file",
1368 bfd_get_reloc_code_name (fixp
->fx_r_type
));
1372 if (!fixp
->fx_pcrel
!= !reloc
->howto
->pc_relative
)
1374 as_fatal ("internal error? cannot generate `%s' relocation",
1375 bfd_get_reloc_code_name (fixp
->fx_r_type
));
1377 assert (!fixp
->fx_pcrel
== !reloc
->howto
->pc_relative
);
1380 if (fixp
->fx_r_type
== BFD_RELOC_ALPHA_LITERAL
)
1382 /* fake out bfd_perform_relocation. sigh */
1383 reloc
->addend
= -alpha_gp_value
;
1388 reloc
->addend
= fixp
->fx_offset
;
1391 * Ohhh, this is ugly. The problem is that if this is a local global
1392 * symbol, the relocation will entirely be performed at link time, not
1393 * at assembly time. bfd_perform_reloc doesn't know about this sort
1394 * of thing, and as a result we need to fake it out here.
1396 if (S_IS_EXTERN (fixp
->fx_addsy
) && !S_IS_COMMON(fixp
->fx_addsy
))
1397 reloc
->addend
-= fixp
->fx_addsy
->bsym
->value
;
1404 /* Parse a register name off of the input_line and return a register
1405 number. Gets md_undefined_symbol above to do the register name
1408 Only called as a part of processing the ECOFF .frame directive. */
1411 tc_get_register (frame
)
1414 int framereg
= AXP_REG_SP
;
1417 if (*input_line_pointer
== '$')
1419 char *s
= input_line_pointer
;
1420 char c
= get_symbol_end ();
1421 symbolS
*sym
= md_undefined_symbol (s
);
1423 *strchr(s
, '\0') = c
;
1424 if (sym
&& (framereg
= S_GET_VALUE (sym
)) <= 31)
1427 as_warn ("frame reg expected, using $%d.", framereg
);
1430 note_gpreg (framereg
);
1434 /* This is called before the symbol table is processed. In order to
1435 work with gcc when using mips-tfile, we must keep all local labels.
1436 However, in other cases, we want to discard them. If we were
1437 called with -g, but we didn't see any debugging information, it may
1438 mean that gcc is smuggling debugging information through to
1439 mips-tfile, in which case we must generate all local labels. */
1444 alpha_frob_file_before_adjust ()
1446 if (alpha_debug
!= 0
1447 && ! ecoff_debugging_seen
)
1448 flag_keep_locals
= 1;
1451 #endif /* OBJ_ECOFF */
1453 /* Parse the arguments to an opcode. */
1456 tokenize_arguments (str
, tok
, ntok
)
1461 expressionS
*end_tok
= tok
+ ntok
;
1462 char *old_input_line_pointer
;
1463 int saw_comma
= 0, saw_arg
= 0;
1465 memset (tok
, 0, sizeof (*tok
) * ntok
);
1467 /* Save and restore input_line_pointer around this function */
1468 old_input_line_pointer
= input_line_pointer
;
1469 input_line_pointer
= str
;
1471 while (tok
< end_tok
&& *input_line_pointer
)
1474 switch (*input_line_pointer
)
1480 ++input_line_pointer
;
1481 if (saw_comma
|| !saw_arg
)
1488 char *hold
= input_line_pointer
++;
1490 /* First try for parenthesized register ... */
1492 if (*input_line_pointer
== ')' && tok
->X_op
== O_register
)
1494 tok
->X_op
= (saw_comma
? O_cpregister
: O_pregister
);
1497 ++input_line_pointer
;
1502 /* ... then fall through to plain expression */
1503 input_line_pointer
= hold
;
1507 if (saw_arg
&& !saw_comma
)
1510 if (tok
->X_op
== O_illegal
|| tok
->X_op
== O_absent
)
1523 input_line_pointer
= old_input_line_pointer
;
1524 return ntok
- (end_tok
- tok
);
1527 input_line_pointer
= old_input_line_pointer
;
1531 /* Search forward through all variants of an opcode looking for a
1534 static const struct alpha_opcode
*
1535 find_opcode_match(first_opcode
, tok
, pntok
, pcpumatch
)
1536 const struct alpha_opcode
*first_opcode
;
1537 const expressionS
*tok
;
1541 const struct alpha_opcode
*opcode
= first_opcode
;
1543 int got_cpu_match
= 0;
1547 const unsigned char *opidx
;
1550 /* Don't match opcodes that don't exist on this architecture */
1551 if (!(opcode
->flags
& alpha_target
))
1556 for (opidx
= opcode
->operands
; *opidx
; ++opidx
)
1558 const struct alpha_operand
*operand
= &alpha_operands
[*opidx
];
1560 /* only take input from real operands */
1561 if (operand
->flags
& AXP_OPERAND_FAKE
)
1564 /* when we expect input, make sure we have it */
1567 if ((operand
->flags
& AXP_OPERAND_OPTIONAL_MASK
) == 0)
1572 /* match operand type with expression type */
1573 switch (operand
->flags
& AXP_OPERAND_TYPECHECK_MASK
)
1575 case AXP_OPERAND_IR
:
1576 if (tok
[tokidx
].X_op
!= O_register
1577 || !is_ir_num(tok
[tokidx
].X_add_number
))
1580 case AXP_OPERAND_FPR
:
1581 if (tok
[tokidx
].X_op
!= O_register
1582 || !is_fpr_num(tok
[tokidx
].X_add_number
))
1585 case AXP_OPERAND_IR
|AXP_OPERAND_PARENS
:
1586 if (tok
[tokidx
].X_op
!= O_pregister
1587 || !is_ir_num(tok
[tokidx
].X_add_number
))
1590 case AXP_OPERAND_IR
|AXP_OPERAND_PARENS
|AXP_OPERAND_COMMA
:
1591 if (tok
[tokidx
].X_op
!= O_cpregister
1592 || !is_ir_num(tok
[tokidx
].X_add_number
))
1596 case AXP_OPERAND_RELATIVE
:
1597 case AXP_OPERAND_SIGNED
:
1598 case AXP_OPERAND_UNSIGNED
:
1599 switch (tok
[tokidx
].X_op
)
1611 /* everything else should have been fake */
1617 /* possible match -- did we use all of our input? */
1626 while (++opcode
-alpha_opcodes
< alpha_num_opcodes
1627 && !strcmp(opcode
->name
, first_opcode
->name
));
1630 *pcpumatch
= got_cpu_match
;
1635 /* Search forward through all variants of a macro looking for a syntax
1638 static const struct alpha_macro
*
1639 find_macro_match(first_macro
, tok
, pntok
)
1640 const struct alpha_macro
*first_macro
;
1641 const expressionS
*tok
;
1644 const struct alpha_macro
*macro
= first_macro
;
1649 const enum alpha_macro_arg
*arg
= macro
->argsets
;
1664 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_register
1665 || !is_ir_num(tok
[tokidx
].X_add_number
))
1670 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_pregister
1671 || !is_ir_num(tok
[tokidx
].X_add_number
))
1676 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_cpregister
1677 || !is_ir_num(tok
[tokidx
].X_add_number
))
1682 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_register
1683 || !is_fpr_num(tok
[tokidx
].X_add_number
))
1691 switch (tok
[tokidx
].X_op
)
1704 while (*arg
!= MACRO_EOA
)
1712 while (++macro
-alpha_macros
< alpha_num_macros
1713 && !strcmp(macro
->name
, first_macro
->name
));
1718 /* Insert an operand value into an instruction. */
1721 insert_operand(insn
, operand
, val
, file
, line
)
1723 const struct alpha_operand
*operand
;
1728 if (operand
->bits
!= 32 && !(operand
->flags
& AXP_OPERAND_NOOVERFLOW
))
1732 if (operand
->flags
& AXP_OPERAND_SIGNED
)
1734 max
= (1 << (operand
->bits
- 1)) - 1;
1735 min
= -(1 << (operand
->bits
- 1));
1739 max
= (1 << operand
->bits
) - 1;
1743 if (val
< min
|| val
> max
)
1746 "operand out of range (%s not between %d and %d)";
1747 char buf
[sizeof (val
) * 3 + 2];
1749 sprint_value(buf
, val
);
1751 as_warn_where(file
, line
, err
, buf
, min
, max
);
1753 as_warn(err
, buf
, min
, max
);
1757 if (operand
->insert
)
1759 const char *errmsg
= NULL
;
1761 insn
= (*operand
->insert
) (insn
, val
, &errmsg
);
1766 insn
|= ((val
& ((1 << operand
->bits
) - 1)) << operand
->shift
);
1772 * Turn an opcode description and a set of arguments into
1773 * an instruction and a fixup.
1777 assemble_insn(opcode
, tok
, ntok
, insn
)
1778 const struct alpha_opcode
*opcode
;
1779 const expressionS
*tok
;
1781 struct alpha_insn
*insn
;
1783 const unsigned char *argidx
;
1787 memset (insn
, 0, sizeof (*insn
));
1788 image
= opcode
->opcode
;
1790 for (argidx
= opcode
->operands
; *argidx
; ++argidx
)
1792 const struct alpha_operand
*operand
= &alpha_operands
[*argidx
];
1793 const expressionS
*t
;
1795 if (operand
->flags
& AXP_OPERAND_FAKE
)
1797 /* fake operands take no value and generate no fixup */
1798 image
= insert_operand(image
, operand
, 0, NULL
, 0);
1804 switch (operand
->flags
& AXP_OPERAND_OPTIONAL_MASK
)
1806 case AXP_OPERAND_DEFAULT_FIRST
:
1809 case AXP_OPERAND_DEFAULT_SECOND
:
1812 case AXP_OPERAND_DEFAULT_ZERO
:
1814 static const expressionS zero_exp
= { 0, 0, 0, O_constant
, 1 };
1830 image
= insert_operand(image
, operand
, regno(t
->X_add_number
),
1835 image
= insert_operand(image
, operand
, t
->X_add_number
, NULL
, 0);
1840 struct alpha_fixup
*fixup
;
1842 if (insn
->nfixups
>= MAX_INSN_FIXUPS
)
1843 as_fatal("too many fixups");
1845 fixup
= &insn
->fixups
[insn
->nfixups
++];
1848 fixup
->reloc
= operand
->default_reloc
;
1858 * Actually output an instruction with its fixup.
1863 struct alpha_insn
*insn
;
1868 /* Take care of alignment duties */
1869 if (alpha_auto_align_on
&& alpha_current_align
< 2)
1870 alpha_align (2, (char *) NULL
, alpha_insn_label
);
1871 if (alpha_current_align
> 2)
1872 alpha_current_align
= 2;
1873 alpha_insn_label
= NULL
;
1875 /* Write out the instruction. */
1877 md_number_to_chars (f
, insn
->insn
, 4);
1879 /* Apply the fixups in order */
1880 for (i
= 0; i
< insn
->nfixups
; ++i
)
1882 struct alpha_fixup
*fixup
= &insn
->fixups
[i
];
1886 /* Some fixups are only used internally and so have no howto */
1887 if ((int)fixup
->reloc
< 0)
1888 size
= 4, pcrel
= 0;
1890 /* These relocation types are only used internally. */
1891 else if (fixup
->reloc
== BFD_RELOC_ALPHA_GPDISP_HI16
1892 || fixup
->reloc
== BFD_RELOC_ALPHA_GPDISP_LO16
)
1894 size
= 2, pcrel
= 0;
1899 reloc_howto_type
*reloc_howto
1900 = bfd_reloc_type_lookup (stdoutput
, fixup
->reloc
);
1901 assert (reloc_howto
);
1903 size
= bfd_get_reloc_size (reloc_howto
);
1904 pcrel
= reloc_howto
->pc_relative
;
1906 assert (size
>= 1 && size
<= 4);
1908 fixP
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, size
,
1909 &fixup
->exp
, pcrel
, fixup
->reloc
);
1911 /* Turn off complaints that the addend is too large for some fixups */
1912 switch (fixup
->reloc
)
1914 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1916 case BFD_RELOC_ALPHA_LITERAL
:
1919 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1921 case BFD_RELOC_GPREL32
:
1922 fixP
->fx_no_overflow
= 1;
1930 /* Given an opcode name and a pre-tokenized set of arguments, assemble
1931 the insn, but do not emit it.
1933 Note that this implies no macros allowed, since we can't store more
1934 than one insn in an insn structure. */
1937 assemble_tokens_to_insn(opname
, tok
, ntok
, insn
)
1939 const expressionS
*tok
;
1941 struct alpha_insn
*insn
;
1943 const struct alpha_opcode
*opcode
;
1945 /* search opcodes */
1946 opcode
= (const struct alpha_opcode
*) hash_find (alpha_opcode_hash
, opname
);
1950 opcode
= find_opcode_match (opcode
, tok
, &ntok
, &cpumatch
);
1953 assemble_insn (opcode
, tok
, ntok
, insn
);
1957 as_bad ("inappropriate arguments for opcode `%s'", opname
);
1959 as_bad ("opcode `%s' not supported for target %s", opname
,
1963 as_bad ("unknown opcode `%s'", opname
);
1966 /* Given an opcode name and a pre-tokenized set of arguments, take the
1967 opcode all the way through emission. */
1970 assemble_tokens (opname
, tok
, ntok
, local_macros_on
)
1972 const expressionS
*tok
;
1974 int local_macros_on
;
1976 int found_something
= 0;
1977 const struct alpha_opcode
*opcode
;
1978 const struct alpha_macro
*macro
;
1982 if (local_macros_on
)
1984 macro
= ((const struct alpha_macro
*)
1985 hash_find (alpha_macro_hash
, opname
));
1988 found_something
= 1;
1989 macro
= find_macro_match (macro
, tok
, &ntok
);
1992 (*macro
->emit
) (tok
, ntok
, macro
->arg
);
1998 /* search opcodes */
1999 opcode
= (const struct alpha_opcode
*) hash_find (alpha_opcode_hash
, opname
);
2002 found_something
= 1;
2003 opcode
= find_opcode_match (opcode
, tok
, &ntok
, &cpumatch
);
2006 struct alpha_insn insn
;
2007 assemble_insn (opcode
, tok
, ntok
, &insn
);
2013 if (found_something
)
2015 as_bad ("inappropriate arguments for opcode `%s'", opname
);
2017 as_bad ("opcode `%s' not supported for target %s", opname
,
2020 as_bad ("unknown opcode `%s'", opname
);
2024 /* Some instruction sets indexed by lg(size) */
2025 static const char * const sextX_op
[] = { "sextb", "sextw", "sextl", NULL
};
2026 static const char * const insXl_op
[] = { "insbl", "inswl", "insll", "insql" };
2027 static const char * const insXh_op
[] = { NULL
, "inswh", "inslh", "insqh" };
2028 static const char * const extXl_op
[] = { "extbl", "extwl", "extll", "extql" };
2029 static const char * const extXh_op
[] = { NULL
, "extwh", "extlh", "extqh" };
2030 static const char * const mskXl_op
[] = { "mskbl", "mskwl", "mskll", "mskql" };
2031 static const char * const mskXh_op
[] = { NULL
, "mskwh", "msklh", "mskqh" };
2032 static const char * const stX_op
[] = { "stb", "stw", "stl", "stq" };
2033 static const char * const ldX_op
[] = { "ldb", "ldw", "ldll", "ldq" };
2034 static const char * const ldXu_op
[] = { "ldbu", "ldwu", NULL
, NULL
};
2036 /* Implement the ldgp macro. */
2039 emit_ldgp (tok
, ntok
, unused
)
2040 const expressionS
*tok
;
2047 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
2048 /* from "ldgp r1,n(r2)", generate "ldah r1,X(R2); lda r1,Y(r1)"
2049 with appropriate constants and relocations. */
2050 struct alpha_insn insn
;
2051 expressionS newtok
[3];
2054 /* We're going to need this symbol in md_apply_fix(). */
2055 (void) section_symbol (absolute_section
);
2058 if (regno (tok
[2].X_add_number
) == AXP_REG_PV
)
2059 ecoff_set_gp_prolog_size (0);
2063 set_tok_const (newtok
[1], 0);
2066 assemble_tokens_to_insn ("ldah", newtok
, 3, &insn
);
2071 assert (addend
.X_op
== O_constant
);
2072 addend
.X_op
= O_symbol
;
2073 addend
.X_add_symbol
= alpha_gp_symbol
;
2077 insn
.fixups
[0].exp
= addend
;
2078 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_GPDISP_HI16
;
2082 set_tok_preg (newtok
[2], tok
[0].X_add_number
);
2084 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
2087 addend
.X_add_number
+= 4;
2091 insn
.fixups
[0].exp
= addend
;
2092 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_GPDISP_LO16
;
2095 #endif /* OBJ_ECOFF || OBJ_ELF */
2100 /* Add symbol+addend to link pool.
2101 Return offset from basesym to entry in link pool.
2103 Add new fixup only if offset isn't 16bit. */
2106 add_to_link_pool (basesym
, sym
, addend
)
2111 segT current_section
= now_seg
;
2112 int current_subsec
= now_subseg
;
2114 bfd_reloc_code_real_type reloc_type
;
2116 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
2119 offset
= -basesym
->sy_obj
;
2121 /* @@ This assumes all entries in a given section will be of the same
2122 size... Probably correct, but unwise to rely on. */
2123 /* This must always be called with the same subsegment. */
2125 if (seginfo
->frchainP
)
2126 for (fixp
= seginfo
->frchainP
->fix_root
;
2127 fixp
!= (fixS
*) NULL
;
2128 fixp
= fixp
->fx_next
, offset
+= 8)
2130 if (fixp
->fx_addsy
== sym
&& fixp
->fx_offset
== addend
)
2132 if (range_signed_16 (offset
))
2139 /* Not found in 16bit signed range. */
2141 subseg_set (alpha_link_section
, 0);
2145 fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, sym
, addend
, 0,
2148 subseg_set (current_section
, current_subsec
);
2149 seginfo
->literal_pool_size
+= 8;
2153 #endif /* OBJ_EVAX */
2155 /* Load a (partial) expression into a target register.
2157 If poffset is not null, after the call it will either contain
2158 O_constant 0, or a 16-bit offset appropriate for any MEM format
2159 instruction. In addition, pbasereg will be modified to point to
2160 the base register to use in that MEM format instruction.
2162 In any case, *pbasereg should contain a base register to add to the
2163 expression. This will normally be either AXP_REG_ZERO or
2164 alpha_gp_register. Symbol addresses will always be loaded via $gp,
2165 so "foo($0)" is interpreted as adding the address of foo to $0;
2166 i.e. "ldq $targ, LIT($gp); addq $targ, $0, $targ". Odd, perhaps,
2167 but this is what OSF/1 does.
2169 Finally, the return value is true if the calling macro may emit a
2170 LITUSE reloc if otherwise appropriate. */
2173 load_expression (targreg
, exp
, pbasereg
, poffset
)
2175 const expressionS
*exp
;
2177 expressionS
*poffset
;
2179 int emit_lituse
= 0;
2180 offsetT addend
= exp
->X_add_number
;
2181 int basereg
= *pbasereg
;
2182 struct alpha_insn insn
;
2183 expressionS newtok
[3];
2192 /* attempt to reduce .lit load by splitting the offset from
2193 its symbol when possible, but don't create a situation in
2195 if (!range_signed_32 (addend
) &&
2196 (alpha_noat_on
|| targreg
== AXP_REG_AT
))
2198 lit
= add_to_literal_pool (exp
->X_add_symbol
, addend
,
2199 alpha_lita_section
, 8);
2204 lit
= add_to_literal_pool (exp
->X_add_symbol
, 0,
2205 alpha_lita_section
, 8);
2209 as_fatal ("overflow in literal (.lita) table");
2211 /* emit "ldq r, lit(gp)" */
2213 if (basereg
!= alpha_gp_register
&& targreg
== basereg
)
2216 as_bad ("macro requires $at register while noat in effect");
2217 if (targreg
== AXP_REG_AT
)
2218 as_bad ("macro requires $at while $at in use");
2220 set_tok_reg (newtok
[0], AXP_REG_AT
);
2223 set_tok_reg (newtok
[0], targreg
);
2224 set_tok_sym (newtok
[1], alpha_lita_symbol
, lit
);
2225 set_tok_preg (newtok
[2], alpha_gp_register
);
2227 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
2229 assert (insn
.nfixups
== 1);
2230 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITERAL
;
2231 #endif /* OBJ_ECOFF */
2233 /* emit "ldq r, gotoff(gp)" */
2235 if (basereg
!= alpha_gp_register
&& targreg
== basereg
)
2238 as_bad ("macro requires $at register while noat in effect");
2239 if (targreg
== AXP_REG_AT
)
2240 as_bad ("macro requires $at while $at in use");
2242 set_tok_reg (newtok
[0], AXP_REG_AT
);
2245 set_tok_reg (newtok
[0], targreg
);
2247 /* XXX: Disable this .got minimizing optimization so that we can get
2248 better instruction offset knowledge in the compiler. This happens
2249 very infrequently anyway. */
2250 if (1 || !range_signed_32 (addend
)
2251 && (alpha_noat_on
|| targreg
== AXP_REG_AT
))
2258 set_tok_sym (newtok
[1], exp
->X_add_symbol
, 0);
2261 set_tok_preg (newtok
[2], alpha_gp_register
);
2263 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
2265 assert (insn
.nfixups
== 1);
2266 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_ELF_LITERAL
;
2267 #endif /* OBJ_ELF */
2271 /* Find symbol or symbol pointer in link section. */
2273 if (exp
->X_add_symbol
== alpha_evax_proc
.symbol
)
2275 if (range_signed_16 (addend
))
2277 set_tok_reg (newtok
[0], targreg
);
2278 set_tok_const (newtok
[1], addend
);
2279 set_tok_preg (newtok
[2], basereg
);
2280 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
2285 set_tok_reg (newtok
[0], targreg
);
2286 set_tok_const (newtok
[1], 0);
2287 set_tok_preg (newtok
[2], basereg
);
2288 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
2293 if (!range_signed_32 (addend
))
2295 link
= add_to_link_pool (alpha_evax_proc
.symbol
,
2296 exp
->X_add_symbol
, addend
);
2301 link
= add_to_link_pool (alpha_evax_proc
.symbol
,
2302 exp
->X_add_symbol
, 0);
2304 set_tok_reg (newtok
[0], targreg
);
2305 set_tok_const (newtok
[1], link
);
2306 set_tok_preg (newtok
[2], basereg
);
2307 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
2309 #endif /* OBJ_EVAX */
2316 if (basereg
!= alpha_gp_register
&& basereg
!= AXP_REG_ZERO
)
2318 /* emit "addq r, base, r" */
2320 set_tok_reg (newtok
[1], basereg
);
2321 set_tok_reg (newtok
[2], targreg
);
2322 assemble_tokens ("addq", newtok
, 3, 0);
2334 /* Assume that this difference expression will be resolved to an
2335 absolute value and that that value will fit in 16 bits. */
2337 set_tok_reg (newtok
[0], targreg
);
2339 set_tok_preg (newtok
[2], basereg
);
2340 assemble_tokens ("lda", newtok
, 3, 0);
2343 set_tok_const (*poffset
, 0);
2347 as_bad ("%s number invalid; zero assumed",
2348 exp
->X_add_number
> 0 ? "bignum" : "floating point");
2356 if (!range_signed_32 (addend
))
2360 /* for 64-bit addends, just put it in the literal pool */
2363 /* emit "ldq targreg, lit(basereg)" */
2364 lit
= add_to_link_pool (alpha_evax_proc
.symbol
,
2365 section_symbol (absolute_section
), addend
);
2366 set_tok_reg (newtok
[0], targreg
);
2367 set_tok_const (newtok
[1], lit
);
2368 set_tok_preg (newtok
[2], alpha_gp_register
);
2369 assemble_tokens ("ldq", newtok
, 3, 0);
2372 if (alpha_lit8_section
== NULL
)
2374 create_literal_section (".lit8",
2375 &alpha_lit8_section
,
2376 &alpha_lit8_symbol
);
2379 alpha_lit8_literal
= add_to_literal_pool (alpha_lit8_symbol
, 0x8000,
2380 alpha_lita_section
, 8);
2381 if (alpha_lit8_literal
>= 0x8000)
2382 as_fatal ("overflow in literal (.lita) table");
2386 lit
= add_to_literal_pool (NULL
, addend
, alpha_lit8_section
, 8) - 0x8000;
2388 as_fatal ("overflow in literal (.lit8) table");
2390 /* emit "lda litreg, .lit8+0x8000" */
2392 if (targreg
== basereg
)
2395 as_bad ("macro requires $at register while noat in effect");
2396 if (targreg
== AXP_REG_AT
)
2397 as_bad ("macro requires $at while $at in use");
2399 set_tok_reg (newtok
[0], AXP_REG_AT
);
2402 set_tok_reg (newtok
[0], targreg
);
2404 set_tok_sym (newtok
[1], alpha_lita_symbol
, alpha_lit8_literal
);
2407 set_tok_sym (newtok
[1], alpha_lit8_symbol
, 0x8000);
2409 set_tok_preg (newtok
[2], alpha_gp_register
);
2411 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
2413 assert (insn
.nfixups
== 1);
2415 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITERAL
;
2418 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_ELF_LITERAL
;
2423 /* emit "ldq litreg, lit(litreg)" */
2425 set_tok_const (newtok
[1], lit
);
2426 set_tok_preg (newtok
[2], newtok
[0].X_add_number
);
2428 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
2430 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
2431 if (insn
.nfixups
> 0)
2433 memmove (&insn
.fixups
[1], &insn
.fixups
[0],
2434 sizeof(struct alpha_fixup
) * insn
.nfixups
);
2437 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITUSE
;
2438 insn
.fixups
[0].exp
.X_op
= O_constant
;
2439 insn
.fixups
[0].exp
.X_add_number
= 1;
2444 /* emit "addq litreg, base, target" */
2446 if (basereg
!= AXP_REG_ZERO
)
2448 set_tok_reg (newtok
[1], basereg
);
2449 set_tok_reg (newtok
[2], targreg
);
2450 assemble_tokens ("addq", newtok
, 3, 0);
2452 #endif /* !OBJ_EVAX */
2455 set_tok_const (*poffset
, 0);
2456 *pbasereg
= targreg
;
2460 offsetT low
, high
, extra
, tmp
;
2462 /* for 32-bit operands, break up the addend */
2464 low
= sign_extend_16 (addend
);
2466 high
= sign_extend_16 (tmp
>> 16);
2468 if (tmp
- (high
<< 16))
2472 high
= sign_extend_16 (tmp
>> 16);
2477 set_tok_reg (newtok
[0], targreg
);
2478 set_tok_preg (newtok
[2], basereg
);
2482 /* emit "ldah r, extra(r) */
2483 set_tok_const (newtok
[1], extra
);
2484 assemble_tokens ("ldah", newtok
, 3, 0);
2485 set_tok_preg (newtok
[2], basereg
= targreg
);
2490 /* emit "ldah r, high(r) */
2491 set_tok_const (newtok
[1], high
);
2492 assemble_tokens ("ldah", newtok
, 3, 0);
2494 set_tok_preg (newtok
[2], basereg
);
2497 if ((low
&& !poffset
) || (!poffset
&& basereg
!= targreg
))
2499 /* emit "lda r, low(base)" */
2500 set_tok_const (newtok
[1], low
);
2501 assemble_tokens ("lda", newtok
, 3, 0);
2507 set_tok_const (*poffset
, low
);
2508 *pbasereg
= basereg
;
2514 /* The lda macro differs from the lda instruction in that it handles
2515 most simple expressions, particualrly symbol address loads and
2519 emit_lda (tok
, ntok
, unused
)
2520 const expressionS
*tok
;
2527 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
2529 basereg
= tok
[2].X_add_number
;
2531 (void) load_expression (tok
[0].X_add_number
, &tok
[1], &basereg
, NULL
);
2534 /* The ldah macro differs from the ldah instruction in that it has $31
2535 as an implied base register. */
2538 emit_ldah (tok
, ntok
, unused
)
2539 const expressionS
*tok
;
2543 expressionS newtok
[3];
2547 set_tok_preg (newtok
[2], AXP_REG_ZERO
);
2549 assemble_tokens ("ldah", newtok
, 3, 0);
2552 /* Handle all "simple" integer register loads -- ldq, ldq_l, ldq_u,
2553 etc. They differ from the real instructions in that they do simple
2554 expressions like the lda macro. */
2557 emit_ir_load (tok
, ntok
, opname
)
2558 const expressionS
*tok
;
2562 int basereg
, lituse
;
2563 expressionS newtok
[3];
2564 struct alpha_insn insn
;
2567 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
2569 basereg
= tok
[2].X_add_number
;
2571 lituse
= load_expression (tok
[0].X_add_number
, &tok
[1], &basereg
,
2575 set_tok_preg (newtok
[2], basereg
);
2577 assemble_tokens_to_insn ((const char *)opname
, newtok
, 3, &insn
);
2581 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
2582 if (insn
.nfixups
> 0)
2584 memmove (&insn
.fixups
[1], &insn
.fixups
[0],
2585 sizeof(struct alpha_fixup
) * insn
.nfixups
);
2588 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITUSE
;
2589 insn
.fixups
[0].exp
.X_op
= O_constant
;
2590 insn
.fixups
[0].exp
.X_add_number
= 1;
2596 /* Handle fp register loads, and both integer and fp register stores.
2597 Again, we handle simple expressions. */
2600 emit_loadstore (tok
, ntok
, opname
)
2601 const expressionS
*tok
;
2605 int basereg
, lituse
;
2606 expressionS newtok
[3];
2607 struct alpha_insn insn
;
2610 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
2612 basereg
= tok
[2].X_add_number
;
2614 if (tok
[1].X_op
!= O_constant
|| !range_signed_16(tok
[1].X_add_number
))
2617 as_bad ("macro requires $at register while noat in effect");
2619 lituse
= load_expression (AXP_REG_AT
, &tok
[1], &basereg
, &newtok
[1]);
2628 set_tok_preg (newtok
[2], basereg
);
2630 assemble_tokens_to_insn ((const char *)opname
, newtok
, 3, &insn
);
2634 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
2635 if (insn
.nfixups
> 0)
2637 memmove (&insn
.fixups
[1], &insn
.fixups
[0],
2638 sizeof(struct alpha_fixup
) * insn
.nfixups
);
2641 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITUSE
;
2642 insn
.fixups
[0].exp
.X_op
= O_constant
;
2643 insn
.fixups
[0].exp
.X_add_number
= 1;
2649 /* Load a half-word or byte as an unsigned value. */
2652 emit_ldXu (tok
, ntok
, vlgsize
)
2653 const expressionS
*tok
;
2657 if (alpha_target
& AXP_OPCODE_BWX
)
2658 emit_ir_load (tok
, ntok
, ldXu_op
[(long)vlgsize
]);
2661 expressionS newtok
[3];
2664 as_bad ("macro requires $at register while noat in effect");
2666 /* emit "lda $at, exp" */
2668 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
2669 newtok
[0].X_add_number
= AXP_REG_AT
;
2670 assemble_tokens ("lda", newtok
, ntok
, 1);
2672 /* emit "ldq_u targ, 0($at)" */
2675 set_tok_const (newtok
[1], 0);
2676 set_tok_preg (newtok
[2], AXP_REG_AT
);
2677 assemble_tokens ("ldq_u", newtok
, 3, 1);
2679 /* emit "extXl targ, $at, targ" */
2681 set_tok_reg (newtok
[1], AXP_REG_AT
);
2682 newtok
[2] = newtok
[0];
2683 assemble_tokens (extXl_op
[(long)vlgsize
], newtok
, 3, 1);
2687 /* Load a half-word or byte as a signed value. */
2690 emit_ldX (tok
, ntok
, vlgsize
)
2691 const expressionS
*tok
;
2695 emit_ldXu (tok
, ntok
, vlgsize
);
2696 assemble_tokens (sextX_op
[(long)vlgsize
], tok
, 1, 1);
2699 /* Load an integral value from an unaligned address as an unsigned
2703 emit_uldXu (tok
, ntok
, vlgsize
)
2704 const expressionS
*tok
;
2708 long lgsize
= (long)vlgsize
;
2709 expressionS newtok
[3];
2712 as_bad ("macro requires $at register while noat in effect");
2714 /* emit "lda $at, exp" */
2716 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
2717 newtok
[0].X_add_number
= AXP_REG_AT
;
2718 assemble_tokens ("lda", newtok
, ntok
, 1);
2720 /* emit "ldq_u $t9, 0($at)" */
2722 set_tok_reg (newtok
[0], AXP_REG_T9
);
2723 set_tok_const (newtok
[1], 0);
2724 set_tok_preg (newtok
[2], AXP_REG_AT
);
2725 assemble_tokens ("ldq_u", newtok
, 3, 1);
2727 /* emit "ldq_u $t10, size-1($at)" */
2729 set_tok_reg (newtok
[0], AXP_REG_T10
);
2730 set_tok_const (newtok
[1], (1<<lgsize
)-1);
2731 assemble_tokens ("ldq_u", newtok
, 3, 1);
2733 /* emit "extXl $t9, $at, $t9" */
2735 set_tok_reg (newtok
[0], AXP_REG_T9
);
2736 set_tok_reg (newtok
[1], AXP_REG_AT
);
2737 set_tok_reg (newtok
[2], AXP_REG_T9
);
2738 assemble_tokens (extXl_op
[lgsize
], newtok
, 3, 1);
2740 /* emit "extXh $t10, $at, $t10" */
2742 set_tok_reg (newtok
[0], AXP_REG_T10
);
2743 set_tok_reg (newtok
[2], AXP_REG_T10
);
2744 assemble_tokens (extXh_op
[lgsize
], newtok
, 3, 1);
2746 /* emit "or $t9, $t10, targ" */
2748 set_tok_reg (newtok
[0], AXP_REG_T9
);
2749 set_tok_reg (newtok
[1], AXP_REG_T10
);
2751 assemble_tokens ("or", newtok
, 3, 1);
2754 /* Load an integral value from an unaligned address as a signed value.
2755 Note that quads should get funneled to the unsigned load since we
2756 don't have to do the sign extension. */
2759 emit_uldX (tok
, ntok
, vlgsize
)
2760 const expressionS
*tok
;
2764 emit_uldXu (tok
, ntok
, vlgsize
);
2765 assemble_tokens (sextX_op
[(long)vlgsize
], tok
, 1, 1);
2768 /* Implement the ldil macro. */
2771 emit_ldil (tok
, ntok
, unused
)
2772 const expressionS
*tok
;
2776 expressionS newtok
[2];
2778 memcpy (newtok
, tok
, sizeof(newtok
));
2779 newtok
[1].X_add_number
= sign_extend_32 (tok
[1].X_add_number
);
2781 assemble_tokens ("lda", newtok
, ntok
, 1);
2784 /* Store a half-word or byte. */
2787 emit_stX (tok
, ntok
, vlgsize
)
2788 const expressionS
*tok
;
2792 int lgsize
= (int)(long)vlgsize
;
2794 if (alpha_target
& AXP_OPCODE_BWX
)
2795 emit_loadstore (tok
, ntok
, stX_op
[lgsize
]);
2798 expressionS newtok
[3];
2801 as_bad("macro requires $at register while noat in effect");
2803 /* emit "lda $at, exp" */
2805 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
2806 newtok
[0].X_add_number
= AXP_REG_AT
;
2807 assemble_tokens ("lda", newtok
, ntok
, 1);
2809 /* emit "ldq_u $t9, 0($at)" */
2811 set_tok_reg (newtok
[0], AXP_REG_T9
);
2812 set_tok_const (newtok
[1], 0);
2813 set_tok_preg (newtok
[2], AXP_REG_AT
);
2814 assemble_tokens ("ldq_u", newtok
, 3, 1);
2816 /* emit "insXl src, $at, $t10" */
2819 set_tok_reg (newtok
[1], AXP_REG_AT
);
2820 set_tok_reg (newtok
[2], AXP_REG_T10
);
2821 assemble_tokens (insXl_op
[lgsize
], newtok
, 3, 1);
2823 /* emit "mskXl $t9, $at, $t9" */
2825 set_tok_reg (newtok
[0], AXP_REG_T9
);
2826 newtok
[2] = newtok
[0];
2827 assemble_tokens (mskXl_op
[lgsize
], newtok
, 3, 1);
2829 /* emit "or $t9, $t10, $t9" */
2831 set_tok_reg (newtok
[1], AXP_REG_T10
);
2832 assemble_tokens ("or", newtok
, 3, 1);
2834 /* emit "stq_u $t9, 0($at) */
2836 set_tok_const (newtok
[1], 0);
2837 set_tok_preg (newtok
[2], AXP_REG_AT
);
2838 assemble_tokens ("stq_u", newtok
, 3, 1);
2842 /* Store an integer to an unaligned address. */
2845 emit_ustX (tok
, ntok
, vlgsize
)
2846 const expressionS
*tok
;
2850 int lgsize
= (int)(long)vlgsize
;
2851 expressionS newtok
[3];
2853 /* emit "lda $at, exp" */
2855 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
2856 newtok
[0].X_add_number
= AXP_REG_AT
;
2857 assemble_tokens ("lda", newtok
, ntok
, 1);
2859 /* emit "ldq_u $9, 0($at)" */
2861 set_tok_reg (newtok
[0], AXP_REG_T9
);
2862 set_tok_const (newtok
[1], 0);
2863 set_tok_preg (newtok
[2], AXP_REG_AT
);
2864 assemble_tokens ("ldq_u", newtok
, 3, 1);
2866 /* emit "ldq_u $10, size-1($at)" */
2868 set_tok_reg (newtok
[0], AXP_REG_T10
);
2869 set_tok_const (newtok
[1], (1 << lgsize
)-1);
2870 assemble_tokens ("ldq_u", newtok
, 3, 1);
2872 /* emit "insXl src, $at, $t11" */
2875 set_tok_reg (newtok
[1], AXP_REG_AT
);
2876 set_tok_reg (newtok
[2], AXP_REG_T11
);
2877 assemble_tokens (insXl_op
[lgsize
], newtok
, 3, 1);
2879 /* emit "insXh src, $at, $t12" */
2881 set_tok_reg (newtok
[2], AXP_REG_T12
);
2882 assemble_tokens (insXh_op
[lgsize
], newtok
, 3, 1);
2884 /* emit "mskXl $t9, $at, $t9" */
2886 set_tok_reg (newtok
[0], AXP_REG_T9
);
2887 newtok
[2] = newtok
[0];
2888 assemble_tokens (mskXl_op
[lgsize
], newtok
, 3, 1);
2890 /* emit "mskXh $t10, $at, $t10" */
2892 set_tok_reg (newtok
[0], AXP_REG_T10
);
2893 newtok
[2] = newtok
[0];
2894 assemble_tokens (mskXh_op
[lgsize
], newtok
, 3, 1);
2896 /* emit "or $t9, $t11, $t9" */
2898 set_tok_reg (newtok
[0], AXP_REG_T9
);
2899 set_tok_reg (newtok
[1], AXP_REG_T11
);
2900 newtok
[2] = newtok
[0];
2901 assemble_tokens ("or", newtok
, 3, 1);
2903 /* emit "or $t10, $t12, $t10" */
2905 set_tok_reg (newtok
[0], AXP_REG_T10
);
2906 set_tok_reg (newtok
[1], AXP_REG_T12
);
2907 newtok
[2] = newtok
[0];
2908 assemble_tokens ("or", newtok
, 3, 1);
2910 /* emit "stq_u $t9, 0($at)" */
2912 set_tok_reg (newtok
[0], AXP_REG_T9
);
2913 set_tok_const (newtok
[1], 0);
2914 set_tok_preg (newtok
[2], AXP_REG_AT
);
2915 assemble_tokens ("stq_u", newtok
, 3, 1);
2917 /* emit "stq_u $t10, size-1($at)" */
2919 set_tok_reg (newtok
[0], AXP_REG_T10
);
2920 set_tok_const (newtok
[1], (1 << lgsize
)-1);
2921 assemble_tokens ("stq_u", newtok
, 3, 1);
2924 /* Sign extend a half-word or byte. The 32-bit sign extend is
2925 implemented as "addl $31, $r, $t" in the opcode table. */
2928 emit_sextX (tok
, ntok
, vlgsize
)
2929 const expressionS
*tok
;
2933 long lgsize
= (long)vlgsize
;
2935 if (alpha_target
& AXP_OPCODE_BWX
)
2936 assemble_tokens (sextX_op
[lgsize
], tok
, ntok
, 0);
2939 int bitshift
= 64 - 8 * (1 << lgsize
);
2940 expressionS newtok
[3];
2942 /* emit "sll src,bits,dst" */
2945 set_tok_const (newtok
[1], bitshift
);
2946 newtok
[2] = tok
[ntok
- 1];
2947 assemble_tokens ("sll", newtok
, 3, 1);
2949 /* emit "sra dst,bits,dst" */
2951 newtok
[0] = newtok
[2];
2952 assemble_tokens ("sra", newtok
, 3, 1);
2956 /* Implement the division and modulus macros. */
2960 /* Make register usage like in normal procedure call.
2961 Don't clobber PV and RA. */
2964 emit_division (tok
, ntok
, symname
)
2965 const expressionS
*tok
;
2969 /* DIVISION and MODULUS. Yech.
2974 * mov x,R16 # if x != R16
2975 * mov y,R17 # if y != R17
2980 * with appropriate optimizations if R0,R16,R17 are the registers
2981 * specified by the compiler.
2986 expressionS newtok
[3];
2988 xr
= regno (tok
[0].X_add_number
);
2989 yr
= regno (tok
[1].X_add_number
);
2994 rr
= regno (tok
[2].X_add_number
);
2996 /* Move the operands into the right place */
2997 if (yr
== AXP_REG_R16
&& xr
== AXP_REG_R17
)
2999 /* They are in exactly the wrong order -- swap through AT */
3002 as_bad ("macro requires $at register while noat in effect");
3004 set_tok_reg (newtok
[0], AXP_REG_R16
);
3005 set_tok_reg (newtok
[1], AXP_REG_AT
);
3006 assemble_tokens ("mov", newtok
, 2, 1);
3008 set_tok_reg (newtok
[0], AXP_REG_R17
);
3009 set_tok_reg (newtok
[1], AXP_REG_R16
);
3010 assemble_tokens ("mov", newtok
, 2, 1);
3012 set_tok_reg (newtok
[0], AXP_REG_AT
);
3013 set_tok_reg (newtok
[1], AXP_REG_R17
);
3014 assemble_tokens ("mov", newtok
, 2, 1);
3018 if (yr
== AXP_REG_R16
)
3020 set_tok_reg (newtok
[0], AXP_REG_R16
);
3021 set_tok_reg (newtok
[1], AXP_REG_R17
);
3022 assemble_tokens ("mov", newtok
, 2, 1);
3025 if (xr
!= AXP_REG_R16
)
3027 set_tok_reg (newtok
[0], xr
);
3028 set_tok_reg (newtok
[1], AXP_REG_R16
);
3029 assemble_tokens ("mov", newtok
, 2, 1);
3032 if (yr
!= AXP_REG_R16
&& yr
!= AXP_REG_R17
)
3034 set_tok_reg (newtok
[0], yr
);
3035 set_tok_reg (newtok
[1], AXP_REG_R17
);
3036 assemble_tokens ("mov", newtok
, 2, 1);
3040 sym
= symbol_find_or_make ((const char *)symname
);
3042 set_tok_reg (newtok
[0], AXP_REG_AT
);
3043 set_tok_sym (newtok
[1], sym
, 0);
3044 assemble_tokens ("lda", newtok
, 2, 1);
3046 /* Call the division routine */
3047 set_tok_reg (newtok
[0], AXP_REG_AT
);
3048 set_tok_cpreg (newtok
[1], AXP_REG_AT
);
3049 set_tok_const (newtok
[2], 0);
3050 assemble_tokens ("jsr", newtok
, 3, 1);
3052 /* Move the result to the right place */
3053 if (rr
!= AXP_REG_R0
)
3055 set_tok_reg (newtok
[0], AXP_REG_R0
);
3056 set_tok_reg (newtok
[1], rr
);
3057 assemble_tokens ("mov", newtok
, 2, 1);
3061 #else /* !OBJ_EVAX */
3064 emit_division (tok
, ntok
, symname
)
3065 const expressionS
*tok
;
3069 /* DIVISION and MODULUS. Yech.
3079 * with appropriate optimizations if t10,t11,t12 are the registers
3080 * specified by the compiler.
3085 expressionS newtok
[3];
3087 xr
= regno (tok
[0].X_add_number
);
3088 yr
= regno (tok
[1].X_add_number
);
3093 rr
= regno (tok
[2].X_add_number
);
3095 sym
= symbol_find_or_make ((const char *)symname
);
3097 /* Move the operands into the right place */
3098 if (yr
== AXP_REG_T10
&& xr
== AXP_REG_T11
)
3100 /* They are in exactly the wrong order -- swap through AT */
3103 as_bad ("macro requires $at register while noat in effect");
3105 set_tok_reg (newtok
[0], AXP_REG_T10
);
3106 set_tok_reg (newtok
[1], AXP_REG_AT
);
3107 assemble_tokens ("mov", newtok
, 2, 1);
3109 set_tok_reg (newtok
[0], AXP_REG_T11
);
3110 set_tok_reg (newtok
[1], AXP_REG_T10
);
3111 assemble_tokens ("mov", newtok
, 2, 1);
3113 set_tok_reg (newtok
[0], AXP_REG_AT
);
3114 set_tok_reg (newtok
[1], AXP_REG_T11
);
3115 assemble_tokens ("mov", newtok
, 2, 1);
3119 if (yr
== AXP_REG_T10
)
3121 set_tok_reg (newtok
[0], AXP_REG_T10
);
3122 set_tok_reg (newtok
[1], AXP_REG_T11
);
3123 assemble_tokens ("mov", newtok
, 2, 1);
3126 if (xr
!= AXP_REG_T10
)
3128 set_tok_reg (newtok
[0], xr
);
3129 set_tok_reg (newtok
[1], AXP_REG_T10
);
3130 assemble_tokens ("mov", newtok
, 2, 1);
3133 if (yr
!= AXP_REG_T10
&& yr
!= AXP_REG_T11
)
3135 set_tok_reg (newtok
[0], yr
);
3136 set_tok_reg (newtok
[1], AXP_REG_T11
);
3137 assemble_tokens ("mov", newtok
, 2, 1);
3141 /* Call the division routine */
3142 set_tok_reg (newtok
[0], AXP_REG_T9
);
3143 set_tok_sym (newtok
[1], sym
, 0);
3144 assemble_tokens ("jsr", newtok
, 2, 1);
3146 /* Reload the GP register */
3150 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
3151 set_tok_reg (newtok
[0], alpha_gp_register
);
3152 set_tok_const (newtok
[1], 0);
3153 set_tok_preg (newtok
[2], AXP_REG_T9
);
3154 assemble_tokens ("ldgp", newtok
, 3, 1);
3157 /* Move the result to the right place */
3158 if (rr
!= AXP_REG_T12
)
3160 set_tok_reg (newtok
[0], AXP_REG_T12
);
3161 set_tok_reg (newtok
[1], rr
);
3162 assemble_tokens ("mov", newtok
, 2, 1);
3166 #endif /* !OBJ_EVAX */
3168 /* The jsr and jmp macros differ from their instruction counterparts
3169 in that they can load the target address and default most
3173 emit_jsrjmp (tok
, ntok
, vopname
)
3174 const expressionS
*tok
;
3178 const char *opname
= (const char *) vopname
;
3179 struct alpha_insn insn
;
3180 expressionS newtok
[3];
3181 int r
, tokidx
= 0, lituse
= 0;
3183 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_register
)
3184 r
= regno (tok
[tokidx
++].X_add_number
);
3186 r
= strcmp (opname
, "jmp") == 0 ? AXP_REG_ZERO
: AXP_REG_RA
;
3188 set_tok_reg (newtok
[0], r
);
3190 if (tokidx
< ntok
&&
3191 (tok
[tokidx
].X_op
== O_pregister
|| tok
[tokidx
].X_op
== O_cpregister
))
3192 r
= regno (tok
[tokidx
++].X_add_number
);
3194 /* keep register if jsr $n.<sym> */
3198 int basereg
= alpha_gp_register
;
3199 lituse
= load_expression (r
= AXP_REG_PV
, &tok
[tokidx
], &basereg
, NULL
);
3203 set_tok_cpreg (newtok
[1], r
);
3206 /* FIXME: Add hint relocs to BFD for evax. */
3209 newtok
[2] = tok
[tokidx
];
3212 set_tok_const (newtok
[2], 0);
3214 assemble_tokens_to_insn (opname
, newtok
, 3, &insn
);
3216 /* add the LITUSE fixup */
3219 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3220 if (insn
.nfixups
> 0)
3222 memmove (&insn
.fixups
[1], &insn
.fixups
[0],
3223 sizeof(struct alpha_fixup
) * insn
.nfixups
);
3226 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITUSE
;
3227 insn
.fixups
[0].exp
.X_op
= O_constant
;
3228 insn
.fixups
[0].exp
.X_add_number
= 3;
3234 /* The ret and jcr instructions differ from their instruction
3235 counterparts in that everything can be defaulted. */
3238 emit_retjcr (tok
, ntok
, vopname
)
3239 const expressionS
*tok
;
3243 const char *opname
= (const char *)vopname
;
3244 expressionS newtok
[3];
3247 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_register
)
3248 r
= regno (tok
[tokidx
++].X_add_number
);
3252 set_tok_reg (newtok
[0], r
);
3254 if (tokidx
< ntok
&&
3255 (tok
[tokidx
].X_op
== O_pregister
|| tok
[tokidx
].X_op
== O_cpregister
))
3256 r
= regno (tok
[tokidx
++].X_add_number
);
3260 set_tok_cpreg (newtok
[1], r
);
3263 newtok
[2] = tok
[tokidx
];
3265 set_tok_const (newtok
[2], strcmp(opname
, "ret") == 0);
3267 assemble_tokens (opname
, newtok
, 3, 0);
3270 /* Assembler directives */
3272 /* Handle the .text pseudo-op. This is like the usual one, but it
3273 clears alpha_insn_label and restores auto alignment. */
3281 alpha_insn_label
= NULL
;
3282 alpha_auto_align_on
= 1;
3283 alpha_current_align
= 0;
3286 /* Handle the .data pseudo-op. This is like the usual one, but it
3287 clears alpha_insn_label and restores auto alignment. */
3294 alpha_insn_label
= NULL
;
3295 alpha_auto_align_on
= 1;
3296 alpha_current_align
= 0;
3299 #if defined (OBJ_ECOFF) || defined (OBJ_EVAX)
3301 /* Handle the OSF/1 and openVMS .comm pseudo quirks.
3302 openVMS constructs a section for every common symbol. */
3305 s_alpha_comm (ignore
)
3308 register char *name
;
3312 register symbolS
*symbolP
;
3315 segT current_section
= now_seg
;
3316 int current_subsec
= now_subseg
;
3320 name
= input_line_pointer
;
3321 c
= get_symbol_end ();
3323 /* just after name is now '\0' */
3324 p
= input_line_pointer
;
3329 /* Alpha OSF/1 compiler doesn't provide the comma, gcc does. */
3330 if (*input_line_pointer
== ',')
3332 input_line_pointer
++;
3335 if ((temp
= get_absolute_expression ()) < 0)
3337 as_warn (".COMMon length (%ld.) <0! Ignored.", (long) temp
);
3338 ignore_rest_of_line ();
3343 symbolP
= symbol_find_or_make (name
);
3347 /* Make a section for the common symbol. */
3348 new_seg
= subseg_new (xstrdup (name
), 0);
3351 if (S_IS_DEFINED (symbolP
) && ! S_IS_COMMON (symbolP
))
3353 as_bad ("Ignoring attempt to re-define symbol");
3354 ignore_rest_of_line ();
3359 if (bfd_section_size (stdoutput
, new_seg
) > 0)
3361 if (bfd_section_size (stdoutput
, new_seg
) != temp
)
3362 as_bad ("Length of .comm \"%s\" is already %ld. Not changed to %ld.",
3363 S_GET_NAME (symbolP
),
3364 (long) bfd_section_size (stdoutput
, new_seg
),
3368 if (S_GET_VALUE (symbolP
))
3370 if (S_GET_VALUE (symbolP
) != (valueT
) temp
)
3371 as_bad ("Length of .comm \"%s\" is already %ld. Not changed to %ld.",
3372 S_GET_NAME (symbolP
),
3373 (long) S_GET_VALUE (symbolP
),
3380 subseg_set (new_seg
, 0);
3381 p
= frag_more (temp
);
3382 new_seg
->flags
|= SEC_IS_COMMON
;
3383 if (! S_IS_DEFINED (symbolP
))
3384 symbolP
->bsym
->section
= new_seg
;
3386 S_SET_VALUE (symbolP
, (valueT
) temp
);
3388 S_SET_EXTERNAL (symbolP
);
3392 subseg_set (current_section
, current_subsec
);
3395 know (symbolP
->sy_frag
== &zero_address_frag
);
3397 demand_empty_rest_of_line ();
3400 #endif /* ! OBJ_ELF */
3404 /* Handle the .rdata pseudo-op. This is like the usual one, but it
3405 clears alpha_insn_label and restores auto alignment. */
3408 s_alpha_rdata (ignore
)
3413 temp
= get_absolute_expression ();
3414 subseg_new (".rdata", 0);
3415 demand_empty_rest_of_line ();
3416 alpha_insn_label
= NULL
;
3417 alpha_auto_align_on
= 1;
3418 alpha_current_align
= 0;
3425 /* Handle the .sdata pseudo-op. This is like the usual one, but it
3426 clears alpha_insn_label and restores auto alignment. */
3429 s_alpha_sdata (ignore
)
3434 temp
= get_absolute_expression ();
3435 subseg_new (".sdata", 0);
3436 demand_empty_rest_of_line ();
3437 alpha_insn_label
= NULL
;
3438 alpha_auto_align_on
= 1;
3439 alpha_current_align
= 0;
3445 /* Handle the .section pseudo-op. This is like the usual one, but it
3446 clears alpha_insn_label and restores auto alignment. */
3449 s_alpha_section (ignore
)
3452 obj_elf_section (ignore
);
3454 alpha_insn_label
= NULL
;
3455 alpha_auto_align_on
= 1;
3456 alpha_current_align
= 0;
3463 /* Handle the section specific pseudo-op. */
3466 s_alpha_section (secid
)
3470 #define EVAX_SECTION_COUNT 6
3471 static char *section_name
[EVAX_SECTION_COUNT
+1] =
3472 { "NULL", ".rdata", ".comm", ".link", ".ctors", ".dtors", ".lcomm" };
3474 if ((secid
<= 0) || (secid
> EVAX_SECTION_COUNT
))
3476 as_fatal ("Unknown section directive");
3477 demand_empty_rest_of_line ();
3480 temp
= get_absolute_expression ();
3481 subseg_new (section_name
[secid
], 0);
3482 demand_empty_rest_of_line ();
3483 alpha_insn_label
= NULL
;
3484 alpha_auto_align_on
= 1;
3485 alpha_current_align
= 0;
3492 s_alpha_prologue (ignore
)
3495 demand_empty_rest_of_line ();
3501 /* Parse .ent directives. */
3504 s_alpha_ent (ignore
)
3508 expressionS symexpr
;
3510 alpha_evax_proc
.pdsckind
= 0;
3511 alpha_evax_proc
.framereg
= -1;
3512 alpha_evax_proc
.framesize
= 0;
3513 alpha_evax_proc
.rsa_offset
= 0;
3514 alpha_evax_proc
.ra_save
= AXP_REG_RA
;
3515 alpha_evax_proc
.fp_save
= -1;
3516 alpha_evax_proc
.imask
= 0;
3517 alpha_evax_proc
.fmask
= 0;
3518 alpha_evax_proc
.prologue
= 0;
3519 alpha_evax_proc
.type
= 0;
3521 expression (&symexpr
);
3523 if (symexpr
.X_op
!= O_symbol
)
3525 as_fatal (".ent directive has no symbol");
3526 demand_empty_rest_of_line ();
3530 symbol
= make_expr_symbol (&symexpr
);
3531 symbol
->bsym
->flags
|= BSF_FUNCTION
;
3532 alpha_evax_proc
.symbol
= symbol
;
3534 demand_empty_rest_of_line ();
3539 /* Parse .frame <framreg>,<framesize>,RA,<rsa_offset> directives. */
3542 s_alpha_frame (ignore
)
3547 alpha_evax_proc
.framereg
= tc_get_register (1);
3550 if (*input_line_pointer
++ != ','
3551 || get_absolute_expression_and_terminator (&val
) != ',')
3553 as_warn ("Bad .frame directive 1./2. param");
3554 --input_line_pointer
;
3555 demand_empty_rest_of_line ();
3559 alpha_evax_proc
.framesize
= val
;
3561 (void) tc_get_register (1);
3563 if (*input_line_pointer
++ != ',')
3565 as_warn ("Bad .frame directive 3./4. param");
3566 --input_line_pointer
;
3567 demand_empty_rest_of_line ();
3570 alpha_evax_proc
.rsa_offset
= get_absolute_expression ();
3576 s_alpha_pdesc (ignore
)
3586 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
3588 if (now_seg
!= alpha_link_section
)
3590 as_bad (".pdesc directive not in link (.link) section");
3591 demand_empty_rest_of_line ();
3595 if ((alpha_evax_proc
.symbol
== 0)
3596 || (!S_IS_DEFINED (alpha_evax_proc
.symbol
)))
3598 as_fatal (".pdesc has no matching .ent");
3599 demand_empty_rest_of_line ();
3603 alpha_evax_proc
.symbol
->sy_obj
= (valueT
)seginfo
->literal_pool_size
;
3606 if (exp
.X_op
!= O_symbol
)
3608 as_warn (".pdesc directive has no entry symbol");
3609 demand_empty_rest_of_line ();
3613 entry_sym
= make_expr_symbol (&exp
);
3614 /* Save bfd symbol of proc desc in function symbol. */
3615 alpha_evax_proc
.symbol
->bsym
->udata
.p
= (PTR
)entry_sym
->bsym
;
3618 if (*input_line_pointer
++ != ',')
3620 as_warn ("No comma after .pdesc <entryname>");
3621 demand_empty_rest_of_line ();
3626 name
= input_line_pointer
;
3627 name_end
= get_symbol_end ();
3629 if (strncmp(name
, "stack", 5) == 0)
3631 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_FP_STACK
;
3633 else if (strncmp(name
, "reg", 3) == 0)
3635 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_FP_REGISTER
;
3637 else if (strncmp(name
, "null", 4) == 0)
3639 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_NULL
;
3643 as_fatal ("unknown procedure kind");
3644 demand_empty_rest_of_line ();
3648 *input_line_pointer
= name_end
;
3649 demand_empty_rest_of_line ();
3651 #ifdef md_flush_pending_output
3652 md_flush_pending_output ();
3655 frag_align (3, 0, 0);
3657 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
3659 seginfo
->literal_pool_size
+= 16;
3661 *p
= alpha_evax_proc
.pdsckind
3662 | ((alpha_evax_proc
.framereg
== 29) ? PDSC_S_M_BASE_REG_IS_FP
: 0);
3663 *(p
+1) = PDSC_S_M_NATIVE
3664 | PDSC_S_M_NO_JACKET
;
3666 switch (alpha_evax_proc
.pdsckind
)
3668 case PDSC_S_K_KIND_NULL
:
3672 case PDSC_S_K_KIND_FP_REGISTER
:
3673 *(p
+2) = alpha_evax_proc
.fp_save
;
3674 *(p
+3) = alpha_evax_proc
.ra_save
;
3676 case PDSC_S_K_KIND_FP_STACK
:
3677 md_number_to_chars (p
+2, (valueT
)alpha_evax_proc
.rsa_offset
, 2);
3679 default: /* impossible */
3684 *(p
+5) = alpha_evax_proc
.type
& 0x0f;
3686 /* Signature offset. */
3687 md_number_to_chars (p
+6, (valueT
)0, 2);
3689 fix_new_exp (frag_now
, p
-frag_now
->fr_literal
+8, 8, &exp
, 0, BFD_RELOC_64
);
3691 if (alpha_evax_proc
.pdsckind
== PDSC_S_K_KIND_NULL
)
3694 /* Add dummy fix to make add_to_link_pool work. */
3696 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
3698 seginfo
->literal_pool_size
+= 8;
3700 /* pdesc+16: Size. */
3701 md_number_to_chars (p
, (valueT
)alpha_evax_proc
.framesize
, 4);
3703 md_number_to_chars (p
+4, (valueT
)0, 2);
3706 md_number_to_chars (p
+6, alpha_evax_proc
.prologue
, 2);
3708 if (alpha_evax_proc
.pdsckind
== PDSC_S_K_KIND_FP_REGISTER
)
3711 /* Add dummy fix to make add_to_link_pool work. */
3713 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
3715 seginfo
->literal_pool_size
+= 8;
3717 /* pdesc+24: register masks. */
3719 md_number_to_chars (p
, alpha_evax_proc
.imask
, 4);
3720 md_number_to_chars (p
+4, alpha_evax_proc
.fmask
, 4);
3726 /* Support for crash debug on vms. */
3729 s_alpha_name (ignore
)
3734 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
3736 if (now_seg
!= alpha_link_section
)
3738 as_bad (".name directive not in link (.link) section");
3739 demand_empty_rest_of_line ();
3744 if (exp
.X_op
!= O_symbol
)
3746 as_warn (".name directive has no symbol");
3747 demand_empty_rest_of_line ();
3751 demand_empty_rest_of_line ();
3753 #ifdef md_flush_pending_output
3754 md_flush_pending_output ();
3757 frag_align (3, 0, 0);
3759 seginfo
->literal_pool_size
+= 8;
3761 fix_new_exp (frag_now
, p
-frag_now
->fr_literal
, 8, &exp
, 0, BFD_RELOC_64
);
3768 s_alpha_linkage (ignore
)
3774 #ifdef md_flush_pending_output
3775 md_flush_pending_output ();
3779 if (exp
.X_op
!= O_symbol
)
3781 as_fatal ("No symbol after .linkage");
3785 p
= frag_more (LKP_S_K_SIZE
);
3786 memset (p
, 0, LKP_S_K_SIZE
);
3787 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, LKP_S_K_SIZE
, &exp
, 0,\
3788 BFD_RELOC_ALPHA_LINKAGE
);
3790 demand_empty_rest_of_line ();
3797 s_alpha_code_address (ignore
)
3803 #ifdef md_flush_pending_output
3804 md_flush_pending_output ();
3808 if (exp
.X_op
!= O_symbol
)
3810 as_fatal ("No symbol after .code_address");
3816 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 8, &exp
, 0,\
3817 BFD_RELOC_ALPHA_CODEADDR
);
3819 demand_empty_rest_of_line ();
3826 s_alpha_fp_save (ignore
)
3830 alpha_evax_proc
.fp_save
= tc_get_register (1);
3832 demand_empty_rest_of_line ();
3838 s_alpha_mask (ignore
)
3843 if (get_absolute_expression_and_terminator (&val
) != ',')
3845 as_warn ("Bad .mask directive");
3846 --input_line_pointer
;
3850 alpha_evax_proc
.imask
= val
;
3851 (void)get_absolute_expression ();
3853 demand_empty_rest_of_line ();
3860 s_alpha_fmask (ignore
)
3865 if (get_absolute_expression_and_terminator (&val
) != ',')
3867 as_warn ("Bad .fmask directive");
3868 --input_line_pointer
;
3872 alpha_evax_proc
.fmask
= val
;
3873 (void) get_absolute_expression ();
3875 demand_empty_rest_of_line ();
3881 s_alpha_end (ignore
)
3886 c
= get_symbol_end ();
3887 *input_line_pointer
= c
;
3888 demand_empty_rest_of_line ();
3889 alpha_evax_proc
.symbol
= 0;
3896 s_alpha_file (ignore
)
3901 static char case_hack
[32];
3903 extern char *demand_copy_string
PARAMS ((int *lenP
));
3905 sprintf (case_hack
, "<CASE:%01d%01d>",
3906 alpha_flag_hash_long_names
, alpha_flag_show_after_trunc
);
3908 s
= symbol_find_or_make (case_hack
);
3909 s
->bsym
->flags
|= BSF_FILE
;
3911 get_absolute_expression ();
3912 s
= symbol_find_or_make (demand_copy_string (&length
));
3913 s
->bsym
->flags
|= BSF_FILE
;
3914 demand_empty_rest_of_line ();
3918 #endif /* OBJ_EVAX */
3920 /* Handle the .gprel32 pseudo op. */
3923 s_alpha_gprel32 (ignore
)
3936 e
.X_add_symbol
= section_symbol(absolute_section
);
3949 e
.X_add_symbol
= section_symbol (absolute_section
);
3952 e
.X_op
= O_subtract
;
3953 e
.X_op_symbol
= alpha_gp_symbol
;
3961 if (alpha_auto_align_on
&& alpha_current_align
< 2)
3962 alpha_align (2, (char *) NULL
, alpha_insn_label
);
3963 if (alpha_current_align
> 2)
3964 alpha_current_align
= 2;
3965 alpha_insn_label
= NULL
;
3969 fix_new_exp (frag_now
, p
-frag_now
->fr_literal
, 4,
3970 &e
, 0, BFD_RELOC_GPREL32
);
3973 /* Handle floating point allocation pseudo-ops. This is like the
3974 generic vresion, but it makes sure the current label, if any, is
3975 correctly aligned. */
3978 s_alpha_float_cons (type
)
4005 if (alpha_auto_align_on
&& alpha_current_align
< log_size
)
4006 alpha_align (log_size
, (char *) NULL
, alpha_insn_label
);
4007 if (alpha_current_align
> log_size
)
4008 alpha_current_align
= log_size
;
4009 alpha_insn_label
= NULL
;
4014 /* Handle the .proc pseudo op. We don't really do much with it except
4018 s_alpha_proc (is_static
)
4027 /* Takes ".proc name,nargs" */
4029 name
= input_line_pointer
;
4030 c
= get_symbol_end ();
4031 p
= input_line_pointer
;
4032 symbolP
= symbol_find_or_make (name
);
4035 if (*input_line_pointer
!= ',')
4038 as_warn ("Expected comma after name \"%s\"", name
);
4041 ignore_rest_of_line ();
4045 input_line_pointer
++;
4046 temp
= get_absolute_expression ();
4048 /* symbolP->sy_other = (signed char) temp; */
4049 as_warn ("unhandled: .proc %s,%d", name
, temp
);
4050 demand_empty_rest_of_line ();
4053 /* Handle the .set pseudo op. This is used to turn on and off most of
4054 the assembler features. */
4064 name
= input_line_pointer
;
4065 ch
= get_symbol_end ();
4068 if (s
[0] == 'n' && s
[1] == 'o')
4073 if (!strcmp ("reorder", s
))
4075 else if (!strcmp ("at", s
))
4076 alpha_noat_on
= !yesno
;
4077 else if (!strcmp ("macro", s
))
4078 alpha_macros_on
= yesno
;
4079 else if (!strcmp ("move", s
))
4081 else if (!strcmp ("volatile", s
))
4084 as_warn ("Tried to .set unrecognized mode `%s'", name
);
4086 *input_line_pointer
= ch
;
4087 demand_empty_rest_of_line ();
4090 /* Handle the .base pseudo op. This changes the assembler's notion of
4091 the $gp register. */
4094 s_alpha_base (ignore
)
4098 if (first_32bit_quadrant
)
4100 /* not fatal, but it might not work in the end */
4101 as_warn ("File overrides no-base-register option.");
4102 first_32bit_quadrant
= 0;
4107 if (*input_line_pointer
== '$')
4109 input_line_pointer
++;
4110 if (*input_line_pointer
== 'r')
4111 input_line_pointer
++;
4114 alpha_gp_register
= get_absolute_expression ();
4115 if (alpha_gp_register
< 0 || alpha_gp_register
> 31)
4117 alpha_gp_register
= AXP_REG_GP
;
4118 as_warn ("Bad base register, using $%d.", alpha_gp_register
);
4121 demand_empty_rest_of_line ();
4124 /* Handle the .align pseudo-op. This aligns to a power of two. It
4125 also adjusts any current instruction label. We treat this the same
4126 way the MIPS port does: .align 0 turns off auto alignment. */
4129 s_alpha_align (ignore
)
4134 long max_alignment
= 15;
4136 align
= get_absolute_expression ();
4137 if (align
> max_alignment
)
4139 align
= max_alignment
;
4140 as_bad ("Alignment too large: %d. assumed", align
);
4144 as_warn ("Alignment negative: 0 assumed");
4148 if (*input_line_pointer
== ',')
4150 input_line_pointer
++;
4151 fill
= get_absolute_expression ();
4159 alpha_auto_align_on
= 1;
4160 alpha_align (align
, pfill
, alpha_insn_label
);
4164 alpha_auto_align_on
= 0;
4167 demand_empty_rest_of_line ();
4170 /* Hook the normal string processor to reset known alignment. */
4173 s_alpha_stringer (terminate
)
4176 alpha_current_align
= 0;
4177 alpha_insn_label
= NULL
;
4178 stringer (terminate
);
4181 /* Hook the normal space processing to reset known alignment. */
4184 s_alpha_space (ignore
)
4187 alpha_current_align
= 0;
4188 alpha_insn_label
= NULL
;
4192 /* Hook into cons for auto-alignment. */
4195 alpha_cons_align (size
)
4201 while ((size
>>= 1) != 0)
4204 if (alpha_auto_align_on
&& alpha_current_align
< log_size
)
4205 alpha_align (log_size
, (char *) NULL
, alpha_insn_label
);
4206 if (alpha_current_align
> log_size
)
4207 alpha_current_align
= log_size
;
4208 alpha_insn_label
= NULL
;
4211 /* Here come the .uword, .ulong, and .uquad explicitly unaligned
4212 pseudos. We just turn off auto-alignment and call down to cons. */
4215 s_alpha_ucons (bytes
)
4218 int hold
= alpha_auto_align_on
;
4219 alpha_auto_align_on
= 0;
4221 alpha_auto_align_on
= hold
;
4224 /* Switch the working cpu type. */
4227 s_alpha_arch (ignored
)
4231 const struct cpu_type
*p
;
4234 name
= input_line_pointer
;
4235 ch
= get_symbol_end ();
4237 for (p
= cpu_types
; p
->name
; ++p
)
4238 if (strcmp(name
, p
->name
) == 0)
4240 alpha_target_name
= p
->name
, alpha_target
= p
->flags
;
4243 as_warn("Unknown CPU identifier `%s'", name
);
4246 *input_line_pointer
= ch
;
4247 demand_empty_rest_of_line ();
4253 /* print token expression with alpha specific extension. */
4256 alpha_print_token(f
, exp
)
4258 const expressionS
*exp
;
4268 expressionS nexp
= *exp
;
4269 nexp
.X_op
= O_register
;
4270 print_expr (f
, &nexp
);
4275 print_expr (f
, exp
);
4282 /* The target specific pseudo-ops which we support. */
4284 const pseudo_typeS md_pseudo_table
[] =
4286 {"common", s_comm
, 0}, /* is this used? */
4288 {"comm", s_alpha_comm
, 0}, /* osf1 compiler does this */
4289 {"rdata", s_alpha_rdata
, 0},
4291 {"text", s_alpha_text
, 0},
4292 {"data", s_alpha_data
, 0},
4294 {"sdata", s_alpha_sdata
, 0},
4297 {"section", s_alpha_section
, 0},
4298 {"section.s", s_alpha_section
, 0},
4299 {"sect", s_alpha_section
, 0},
4300 {"sect.s", s_alpha_section
, 0},
4303 { "pdesc", s_alpha_pdesc
, 0},
4304 { "name", s_alpha_name
, 0},
4305 { "linkage", s_alpha_linkage
, 0},
4306 { "code_address", s_alpha_code_address
, 0},
4307 { "ent", s_alpha_ent
, 0},
4308 { "frame", s_alpha_frame
, 0},
4309 { "fp_save", s_alpha_fp_save
, 0},
4310 { "mask", s_alpha_mask
, 0},
4311 { "fmask", s_alpha_fmask
, 0},
4312 { "end", s_alpha_end
, 0},
4313 { "file", s_alpha_file
, 0},
4314 { "rdata", s_alpha_section
, 1},
4315 { "comm", s_alpha_comm
, 0},
4316 { "link", s_alpha_section
, 3},
4317 { "ctors", s_alpha_section
, 4},
4318 { "dtors", s_alpha_section
, 5},
4319 { "lcomm", s_alpha_section
, 6},
4321 {"gprel32", s_alpha_gprel32
, 0},
4322 {"t_floating", s_alpha_float_cons
, 'd'},
4323 {"s_floating", s_alpha_float_cons
, 'f'},
4324 {"f_floating", s_alpha_float_cons
, 'F'},
4325 {"g_floating", s_alpha_float_cons
, 'G'},
4326 {"d_floating", s_alpha_float_cons
, 'D'},
4328 {"proc", s_alpha_proc
, 0},
4329 {"aproc", s_alpha_proc
, 1},
4330 {"set", s_alpha_set
, 0},
4331 {"reguse", s_ignore
, 0},
4332 {"livereg", s_ignore
, 0},
4333 {"base", s_alpha_base
, 0}, /*??*/
4334 {"option", s_ignore
, 0},
4335 {"prologue", s_ignore
, 0},
4336 {"aent", s_ignore
, 0},
4337 {"ugen", s_ignore
, 0},
4338 {"eflag", s_ignore
, 0},
4340 {"align", s_alpha_align
, 0},
4341 {"double", s_alpha_float_cons
, 'd'},
4342 {"float", s_alpha_float_cons
, 'f'},
4343 {"single", s_alpha_float_cons
, 'f'},
4344 {"ascii", s_alpha_stringer
, 0},
4345 {"asciz", s_alpha_stringer
, 1},
4346 {"string", s_alpha_stringer
, 1},
4347 {"space", s_alpha_space
, 0},
4348 {"skip", s_alpha_space
, 0},
4349 {"zero", s_alpha_space
, 0},
4351 /* Unaligned data pseudos. */
4352 {"uword", s_alpha_ucons
, 2},
4353 {"ulong", s_alpha_ucons
, 4},
4354 {"uquad", s_alpha_ucons
, 8},
4357 /* Dwarf wants these versions of unaligned. */
4358 {"2byte", s_alpha_ucons
, 2},
4359 {"4byte", s_alpha_ucons
, 4},
4360 {"8byte", s_alpha_ucons
, 8},
4363 /* We don't do any optimizing, so we can safely ignore these. */
4364 {"noalias", s_ignore
, 0},
4365 {"alias", s_ignore
, 0},
4367 {"arch", s_alpha_arch
, 0},
4373 /* Build a BFD section with its flags set appropriately for the .lita,
4374 .lit8, or .lit4 sections. */
4377 create_literal_section (name
, secp
, symp
)
4382 segT current_section
= now_seg
;
4383 int current_subsec
= now_subseg
;
4386 *secp
= new_sec
= subseg_new (name
, 0);
4387 subseg_set (current_section
, current_subsec
);
4388 bfd_set_section_alignment (stdoutput
, new_sec
, 4);
4389 bfd_set_section_flags (stdoutput
, new_sec
,
4390 SEC_RELOC
| SEC_ALLOC
| SEC_LOAD
| SEC_READONLY
4393 S_CLEAR_EXTERNAL (*symp
= section_symbol (new_sec
));
4398 /* @@@ GP selection voodoo. All of this seems overly complicated and
4399 unnecessary; which is the primary reason it's for ECOFF only. */
4408 vma
= bfd_get_section_vma (foo
, sec
);
4409 if (vma
&& vma
< alpha_gp_value
)
4410 alpha_gp_value
= vma
;
4416 assert (alpha_gp_value
== 0);
4418 /* Get minus-one in whatever width... */
4419 alpha_gp_value
= 0; alpha_gp_value
--;
4421 /* Select the smallest VMA of these existing sections. */
4422 maybe_set_gp (alpha_lita_section
);
4424 /* These were disabled before -- should we use them? */
4425 maybe_set_gp (sdata
);
4426 maybe_set_gp (lit8_sec
);
4427 maybe_set_gp (lit4_sec
);
4430 /* @@ Will a simple 0x8000 work here? If not, why not? */
4431 #define GP_ADJUSTMENT (0x8000 - 0x10)
4433 alpha_gp_value
+= GP_ADJUSTMENT
;
4435 S_SET_VALUE (alpha_gp_symbol
, alpha_gp_value
);
4438 printf ("Chose GP value of %lx\n", alpha_gp_value
);
4441 #endif /* OBJ_ECOFF */
4443 /* Called internally to handle all alignment needs. This takes care
4444 of eliding calls to frag_align if'n the cached current alignment
4445 says we've already got it, as well as taking care of the auto-align
4446 feature wrt labels. */
4449 alpha_align (n
, pfill
, label
)
4454 if (alpha_current_align
>= n
)
4460 && (bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
) != 0)
4462 static char const nop
[4] = { 0x1f, 0x04, 0xff, 0x47 };
4464 /* First, make sure we're on a four-byte boundary, in case
4465 someone has been putting .byte values into the text
4466 section. The DEC assembler silently fills with unaligned
4467 no-op instructions. This will zero-fill, then nop-fill
4468 with proper alignment. */
4469 if (alpha_current_align
< 2)
4470 frag_align (2, 0, 0);
4471 frag_align_pattern (n
, nop
, sizeof nop
, 0);
4474 frag_align (n
, 0, 0);
4477 frag_align (n
, *pfill
, 0);
4479 alpha_current_align
= n
;
4483 assert (S_GET_SEGMENT (label
) == now_seg
);
4484 label
->sy_frag
= frag_now
;
4485 S_SET_VALUE (label
, (valueT
) frag_now_fix ());
4488 record_alignment(now_seg
, n
);
4491 /* The Alpha has support for some VAX floating point types, as well as for
4492 IEEE floating point. We consider IEEE to be the primary floating point
4493 format, and sneak in the VAX floating point support here. */
4494 #define md_atof vax_md_atof
4495 #include "config/atof-vax.c"