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.
401 static int alpha_basereg_clobbered
;
404 /* A table of CPU names and opcode sets. */
406 static const struct cpu_type
412 /* Ad hoc convention: cpu number gets palcode, process code doesn't.
413 This supports usage under DU 4.0b that does ".arch ev4", and
414 usage in MILO that does -m21064. Probably something more
415 specific like -m21064-pal should be used, but oh well. */
417 { "21064", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
418 { "21064a", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
419 { "21066", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
420 { "21068", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
421 { "21164", AXP_OPCODE_BASE
|AXP_OPCODE_EV5
},
422 /* Do we have CIX extension here? */
423 { "21164a", AXP_OPCODE_BASE
|AXP_OPCODE_EV5
|AXP_OPCODE_BWX
},
424 /* Still same PALcodes? */
425 { "21164pc", (AXP_OPCODE_BASE
|AXP_OPCODE_EV5
|AXP_OPCODE_BWX
426 |AXP_OPCODE_CIX
|AXP_OPCODE_MAX
) },
427 /* All new PALcodes? Extras? */
428 { "21264", (AXP_OPCODE_BASE
|AXP_OPCODE_BWX
429 |AXP_OPCODE_CIX
|AXP_OPCODE_MAX
) },
431 { "ev4", AXP_OPCODE_BASE
},
432 { "ev45", AXP_OPCODE_BASE
},
433 { "lca45", AXP_OPCODE_BASE
},
434 { "ev5", AXP_OPCODE_BASE
},
435 { "ev56", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
},
436 { "pca56", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
|AXP_OPCODE_CIX
|AXP_OPCODE_MAX
},
437 { "ev6", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
|AXP_OPCODE_CIX
|AXP_OPCODE_MAX
},
439 { "all", AXP_OPCODE_BASE
},
443 /* The macro table */
445 static const struct alpha_macro alpha_macros
[] = {
446 /* Load/Store macros */
447 { "lda", emit_lda
, NULL
,
448 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
449 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
450 { "ldah", emit_ldah
, NULL
,
451 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
453 { "ldl", emit_ir_load
, "ldl",
454 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
455 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
456 { "ldl_l", emit_ir_load
, "ldl_l",
457 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
458 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
459 { "ldq", emit_ir_load
, "ldq",
460 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
461 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
462 { "ldq_l", emit_ir_load
, "ldq_l",
463 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
464 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
465 { "ldq_u", emit_ir_load
, "ldq_u",
466 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
467 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
468 { "ldf", emit_loadstore
, "ldf",
469 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
470 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
471 { "ldg", emit_loadstore
, "ldg",
472 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
473 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
474 { "lds", emit_loadstore
, "lds",
475 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
476 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
477 { "ldt", emit_loadstore
, "ldt",
478 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
479 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
481 { "ldb", emit_ldX
, (PTR
)0,
482 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
483 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
484 { "ldbu", emit_ldXu
, (PTR
)0,
485 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
486 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
487 { "ldw", emit_ldX
, (PTR
)1,
488 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
489 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
490 { "ldwu", emit_ldXu
, (PTR
)1,
491 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
492 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
494 { "uldw", emit_uldX
, (PTR
)1,
495 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
496 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
497 { "uldwu", emit_uldXu
, (PTR
)1,
498 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
499 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
500 { "uldl", emit_uldX
, (PTR
)2,
501 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
502 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
503 { "uldlu", emit_uldXu
, (PTR
)2,
504 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
505 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
506 { "uldq", emit_uldXu
, (PTR
)3,
507 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
508 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
510 { "ldgp", emit_ldgp
, NULL
,
511 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
} },
513 { "ldi", emit_lda
, NULL
,
514 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
515 { "ldil", emit_ldil
, NULL
,
516 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
517 { "ldiq", emit_lda
, NULL
,
518 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
520 { "ldif" emit_ldiq
, NULL
,
521 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
522 { "ldid" emit_ldiq
, NULL
,
523 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
524 { "ldig" emit_ldiq
, NULL
,
525 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
526 { "ldis" emit_ldiq
, NULL
,
527 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
528 { "ldit" emit_ldiq
, NULL
,
529 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
532 { "stl", emit_loadstore
, "stl",
533 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
534 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
535 { "stl_c", emit_loadstore
, "stl_c",
536 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
537 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
538 { "stq", emit_loadstore
, "stq",
539 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
540 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
541 { "stq_c", emit_loadstore
, "stq_c",
542 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
543 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
544 { "stq_u", emit_loadstore
, "stq_u",
545 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
546 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
547 { "stf", emit_loadstore
, "stf",
548 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
549 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
550 { "stg", emit_loadstore
, "stg",
551 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
552 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
553 { "sts", emit_loadstore
, "sts",
554 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
555 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
556 { "stt", emit_loadstore
, "stt",
557 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
558 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
560 { "stb", emit_stX
, (PTR
)0,
561 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
562 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
563 { "stw", emit_stX
, (PTR
)1,
564 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
565 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
566 { "ustw", emit_ustX
, (PTR
)1,
567 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
568 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
569 { "ustl", emit_ustX
, (PTR
)2,
570 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
571 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
572 { "ustq", emit_ustX
, (PTR
)3,
573 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
574 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
576 /* Arithmetic macros */
578 { "absl" emit_absl
, 1, { IR
} },
579 { "absl" emit_absl
, 2, { IR
, IR
} },
580 { "absl" emit_absl
, 2, { EXP
, IR
} },
581 { "absq" emit_absq
, 1, { IR
} },
582 { "absq" emit_absq
, 2, { IR
, IR
} },
583 { "absq" emit_absq
, 2, { EXP
, IR
} },
586 { "sextb", emit_sextX
, (PTR
)0,
587 { MACRO_IR
, MACRO_IR
, MACRO_EOA
,
589 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
590 { "sextw", emit_sextX
, (PTR
)1,
591 { MACRO_IR
, MACRO_IR
, MACRO_EOA
,
593 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
595 { "divl", emit_division
, "__divl",
596 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
597 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
598 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
599 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
600 { "divlu", emit_division
, "__divlu",
601 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
602 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
603 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
604 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
605 { "divq", emit_division
, "__divq",
606 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
607 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
608 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
609 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
610 { "divqu", emit_division
, "__divqu",
611 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
612 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
613 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
614 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
615 { "reml", emit_division
, "__reml",
616 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
617 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
618 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
619 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
620 { "remlu", emit_division
, "__remlu",
621 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
622 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
623 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
624 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
625 { "remq", emit_division
, "__remq",
626 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
627 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
628 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
629 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
630 { "remqu", emit_division
, "__remqu",
631 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
632 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
633 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
634 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
636 { "jsr", emit_jsrjmp
, "jsr",
637 { MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
638 MACRO_PIR
, MACRO_EOA
,
639 MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
640 MACRO_EXP
, MACRO_EOA
} },
641 { "jmp", emit_jsrjmp
, "jmp",
642 { MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
643 MACRO_PIR
, MACRO_EOA
,
644 MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
645 MACRO_EXP
, MACRO_EOA
} },
646 { "ret", emit_retjcr
, "ret",
647 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
649 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
650 MACRO_PIR
, MACRO_EOA
,
651 MACRO_EXP
, MACRO_EOA
,
653 { "jcr", emit_retjcr
, "jcr",
654 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
656 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
657 MACRO_PIR
, MACRO_EOA
,
658 MACRO_EXP
, MACRO_EOA
,
660 { "jsr_coroutine", emit_retjcr
, "jcr",
661 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
663 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
664 MACRO_PIR
, MACRO_EOA
,
665 MACRO_EXP
, MACRO_EOA
,
669 static const int alpha_num_macros
670 = sizeof(alpha_macros
) / sizeof(*alpha_macros
);
672 /* Public interface functions */
674 /* This function is called once, at assembler startup time. It sets
675 up all the tables, etc. that the MD part of the assembler will
676 need, that can be determined before arguments are parsed. */
683 /* Create the opcode hash table */
685 alpha_opcode_hash
= hash_new ();
686 for (i
= 0; i
< alpha_num_opcodes
; )
688 const char *name
, *retval
, *slash
;
690 name
= alpha_opcodes
[i
].name
;
691 retval
= hash_insert (alpha_opcode_hash
, name
, (PTR
)&alpha_opcodes
[i
]);
693 as_fatal ("internal error: can't hash opcode `%s': %s", name
, retval
);
695 /* Some opcodes include modifiers of various sorts with a "/mod"
696 syntax, like the architecture manual suggests. However, for
697 use with gcc at least, we also need access to those same opcodes
700 if ((slash
= strchr (name
, '/')) != NULL
)
702 char *p
= xmalloc (strlen (name
));
703 memcpy (p
, name
, slash
- name
);
704 strcpy (p
+ (slash
- name
), slash
+ 1);
706 (void)hash_insert(alpha_opcode_hash
, p
, (PTR
)&alpha_opcodes
[i
]);
707 /* Ignore failures -- the opcode table does duplicate some
708 variants in different forms, like "hw_stq" and "hw_st/q". */
711 while (++i
< alpha_num_opcodes
712 && (alpha_opcodes
[i
].name
== name
713 || !strcmp (alpha_opcodes
[i
].name
, name
)))
717 /* Create the macro hash table */
719 alpha_macro_hash
= hash_new ();
720 for (i
= 0; i
< alpha_num_macros
; )
722 const char *name
, *retval
;
724 name
= alpha_macros
[i
].name
;
725 retval
= hash_insert (alpha_macro_hash
, name
, (PTR
)&alpha_macros
[i
]);
727 as_fatal ("internal error: can't hash macro `%s': %s", name
, retval
);
729 while (++i
< alpha_num_macros
730 && (alpha_macros
[i
].name
== name
731 || !strcmp (alpha_macros
[i
].name
, name
)))
735 /* Construct symbols for each of the registers */
737 for (i
= 0; i
< 32; ++i
)
740 sprintf(name
, "$%d", i
);
741 alpha_register_table
[i
] = symbol_create(name
, reg_section
, i
,
747 sprintf(name
, "$f%d", i
-32);
748 alpha_register_table
[i
] = symbol_create(name
, reg_section
, i
,
752 /* Create the special symbols and sections we'll be using */
754 /* So .sbss will get used for tiny objects. */
755 bfd_set_gp_size (stdoutput
, 8);
758 create_literal_section (".lita", &alpha_lita_section
, &alpha_lita_symbol
);
760 /* For handling the GP, create a symbol that won't be output in the
761 symbol table. We'll edit it out of relocs later. */
762 alpha_gp_symbol
= symbol_create ("<GP value>", alpha_lita_section
, 0x8000,
767 create_literal_section (".link", &alpha_link_section
, &alpha_link_symbol
);
775 sec
= subseg_new(".mdebug", (subsegT
)0);
776 bfd_set_section_flags(stdoutput
, sec
, SEC_HAS_CONTENTS
|SEC_READONLY
);
777 bfd_set_section_alignment(stdoutput
, sec
, 3);
780 sec
= subseg_new(".reginfo", (subsegT
)0);
781 /* The ABI says this section should be loaded so that the running
782 program can access it. */
783 bfd_set_section_flags(stdoutput
, sec
,
784 SEC_ALLOC
|SEC_LOAD
|SEC_READONLY
|SEC_DATA
);
785 bfd_set_section_alignement(stdoutput
, sec
, 3);
790 subseg_set(text_section
, 0);
793 /* The public interface to the instruction assembler. */
799 char opname
[32]; /* current maximum is 13 */
800 expressionS tok
[MAX_INSN_ARGS
];
801 int ntok
, opnamelen
, trunclen
;
803 /* split off the opcode */
804 opnamelen
= strspn (str
, "abcdefghijklmnopqrstuvwxyz_/48");
805 trunclen
= (opnamelen
< sizeof (opname
) - 1
807 : sizeof (opname
) - 1);
808 memcpy (opname
, str
, trunclen
);
809 opname
[trunclen
] = '\0';
811 /* tokenize the rest of the line */
812 if ((ntok
= tokenize_arguments (str
+ opnamelen
, tok
, MAX_INSN_ARGS
)) < 0)
814 as_bad ("syntax error");
819 assemble_tokens (opname
, tok
, ntok
, alpha_macros_on
);
822 /* Round up a section's size to the appropriate boundary. */
825 md_section_align (seg
, size
)
829 int align
= bfd_get_section_alignment(stdoutput
, seg
);
830 valueT mask
= ((valueT
)1 << align
) - 1;
832 return (size
+ mask
) & ~mask
;
835 /* Turn a string in input_line_pointer into a floating point constant
836 of type type, and store the appropriate bytes in *litP. The number
837 of LITTLENUMS emitted is stored in *sizeP. An error message is
838 returned, or NULL on OK. */
840 /* Equal to MAX_PRECISION in atof-ieee.c */
841 #define MAX_LITTLENUMS 6
843 extern char *vax_md_atof
PARAMS ((int, char *, int *));
846 md_atof (type
, litP
, sizeP
)
852 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
853 LITTLENUM_TYPE
*wordP
;
860 /* VAX md_atof doesn't like "G" for some reason. */
864 return vax_md_atof (type
, litP
, sizeP
);
887 return "Bad call to MD_ATOF()";
889 t
= atof_ieee (input_line_pointer
, type
, words
);
891 input_line_pointer
= t
;
892 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
894 for (wordP
= words
+ prec
- 1; prec
--;)
896 md_number_to_chars (litP
, (long) (*wordP
--), sizeof (LITTLENUM_TYPE
));
897 litP
+= sizeof (LITTLENUM_TYPE
);
903 /* Take care of the target-specific command-line options. */
906 md_parse_option (c
, arg
)
913 alpha_nofloats_on
= 1;
926 const struct cpu_type
*p
;
927 for (p
= cpu_types
; p
->name
; ++p
)
928 if (strcmp(arg
, p
->name
) == 0)
930 alpha_target_name
= p
->name
, alpha_target
= p
->flags
;
933 as_warn("Unknown CPU identifier `%s'", arg
);
939 case '+': /* For g++. Hash any name > 63 chars long. */
940 alpha_flag_hash_long_names
= 1;
943 case 'H': /* Show new symbol after hash truncation */
944 alpha_flag_show_after_trunc
= 1;
947 case 'h': /* for gnu-c/vax compatibility. */
958 /* Print a description of the command-line options that we accept. */
961 md_show_usage (stream
)
966 -32addr treat addresses as 32-bit values\n\
967 -F lack floating point instructions support\n\
968 -m21064 | -m21066 | -m21164 | -m21164a\n\
969 -mev4 | -mev45 | -mev5 | -mev56 | -mall\n\
970 specify variant of Alpha architecture\n",
975 -+ hash encode (don't truncate) names longer than 64 characters\n\
976 -H show new symbol after hash truncation\n",
981 /* Decide from what point a pc-relative relocation is relative to,
982 relative to the pc-relative fixup. Er, relatively speaking. */
988 valueT addr
= fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
989 switch (fixP
->fx_r_type
)
991 case BFD_RELOC_ALPHA_GPDISP
:
992 case BFD_RELOC_ALPHA_GPDISP_HI16
:
993 case BFD_RELOC_ALPHA_GPDISP_LO16
:
996 return fixP
->fx_size
+ addr
;
1000 /* Attempt to simplify or even eliminate a fixup. The return value is
1001 ignored; perhaps it was once meaningful, but now it is historical.
1002 To indicate that a fixup has been eliminated, set fixP->fx_done.
1004 For ELF, here it is that we transform the GPDISP_HI16 reloc we used
1005 internally into the GPDISP reloc used externally. We had to do
1006 this so that we'd have the GPDISP_LO16 reloc as a tag to compute
1007 the distance to the "lda" instruction for setting the addend to
1011 md_apply_fix (fixP
, valueP
)
1015 char * const fixpos
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
1016 valueT value
= *valueP
;
1017 unsigned image
, size
;
1019 switch (fixP
->fx_r_type
)
1021 /* The GPDISP relocations are processed internally with a symbol
1022 referring to the current function; we need to drop in a value
1023 which, when added to the address of the start of the function,
1024 gives the desired GP. */
1025 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1027 fixS
*next
= fixP
->fx_next
;
1028 assert (next
->fx_r_type
== BFD_RELOC_ALPHA_GPDISP_LO16
);
1030 fixP
->fx_offset
= (next
->fx_frag
->fr_address
+ next
->fx_where
1031 - fixP
->fx_frag
->fr_address
- fixP
->fx_where
);
1033 value
= (value
- sign_extend_16 (value
)) >> 16;
1036 fixP
->fx_r_type
= BFD_RELOC_ALPHA_GPDISP
;
1040 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1041 value
= sign_extend_16 (value
);
1042 fixP
->fx_offset
= 0;
1048 fixP
->fx_addsy
= section_symbol (absolute_section
);
1049 md_number_to_chars (fixpos
, value
, 2);
1061 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
1063 md_number_to_chars (fixpos
, value
, size
);
1069 case BFD_RELOC_GPREL32
:
1070 assert (fixP
->fx_subsy
== alpha_gp_symbol
);
1072 /* FIXME: inherited this obliviousness of `value' -- why? */
1073 md_number_to_chars (fixpos
, -alpha_gp_value
, 4);
1077 case BFD_RELOC_GPREL32
:
1081 case BFD_RELOC_23_PCREL_S2
:
1082 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
1084 image
= bfd_getl32(fixpos
);
1085 image
= (image
& ~0x1FFFFF) | ((value
>> 2) & 0x1FFFFF);
1090 case BFD_RELOC_ALPHA_HINT
:
1091 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
1093 image
= bfd_getl32(fixpos
);
1094 image
= (image
& ~0x3FFF) | ((value
>> 2) & 0x3FFF);
1100 case BFD_RELOC_ALPHA_LITERAL
:
1101 md_number_to_chars (fixpos
, value
, 2);
1104 case BFD_RELOC_ALPHA_LITUSE
:
1108 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1109 case BFD_RELOC_ALPHA_LITUSE
:
1113 case BFD_RELOC_ALPHA_LINKAGE
:
1114 case BFD_RELOC_ALPHA_CODEADDR
:
1120 const struct alpha_operand
*operand
;
1122 if ((int)fixP
->fx_r_type
>= 0)
1123 as_fatal ("unhandled relocation type %s",
1124 bfd_get_reloc_code_name (fixP
->fx_r_type
));
1126 assert (-(int)fixP
->fx_r_type
< alpha_num_operands
);
1127 operand
= &alpha_operands
[-(int)fixP
->fx_r_type
];
1129 /* The rest of these fixups only exist internally during symbol
1130 resolution and have no representation in the object file.
1131 Therefore they must be completely resolved as constants. */
1133 if (fixP
->fx_addsy
!= 0
1134 && fixP
->fx_addsy
->bsym
->section
!= absolute_section
)
1135 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
1136 "non-absolute expression in constant field");
1138 image
= bfd_getl32(fixpos
);
1139 image
= insert_operand(image
, operand
, (offsetT
)value
,
1140 fixP
->fx_file
, fixP
->fx_line
);
1145 if (fixP
->fx_addsy
!= 0 || fixP
->fx_pcrel
!= 0)
1149 as_warn_where(fixP
->fx_file
, fixP
->fx_line
,
1150 "type %d reloc done?\n", (int)fixP
->fx_r_type
);
1155 md_number_to_chars(fixpos
, image
, 4);
1163 * Look for a register name in the given symbol.
1167 md_undefined_symbol(name
)
1172 int is_float
= 0, num
;
1177 if (name
[1] == 'p' && name
[2] == '\0')
1178 return alpha_register_table
[AXP_REG_FP
];
1183 if (!isdigit(*++name
))
1187 case '0': case '1': case '2': case '3': case '4':
1188 case '5': case '6': case '7': case '8': case '9':
1189 if (name
[1] == '\0')
1190 num
= name
[0] - '0';
1191 else if (name
[0] != '0' && isdigit(name
[1]) && name
[2] == '\0')
1193 num
= (name
[0] - '0') * 10 + name
[1] - '0';
1200 if (!alpha_noat_on
&& num
== AXP_REG_AT
)
1201 as_warn("Used $at without \".set noat\"");
1202 return alpha_register_table
[num
+ is_float
];
1205 if (name
[1] == 't' && name
[2] == '\0')
1208 as_warn("Used $at without \".set noat\"");
1209 return alpha_register_table
[AXP_REG_AT
];
1214 if (name
[1] == 'p' && name
[2] == '\0')
1215 return alpha_register_table
[alpha_gp_register
];
1219 if (name
[1] == 'p' && name
[2] == '\0')
1220 return alpha_register_table
[AXP_REG_SP
];
1228 /* @@@ Magic ECOFF bits. */
1231 alpha_frob_ecoff_data ()
1234 /* $zero and $f31 are read-only */
1235 alpha_gprmask
&= ~1;
1236 alpha_fprmask
&= ~1;
1240 /* Hook to remember a recently defined label so that the auto-align
1241 code can adjust the symbol after we know what alignment will be
1245 alpha_define_label (sym
)
1248 alpha_insn_label
= sym
;
1251 /* Return true if we must always emit a reloc for a type and false if
1252 there is some hope of resolving it a assembly time. */
1255 alpha_force_relocation (f
)
1258 switch (f
->fx_r_type
)
1260 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1261 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1262 case BFD_RELOC_ALPHA_GPDISP
:
1264 case BFD_RELOC_ALPHA_LITERAL
:
1267 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1269 case BFD_RELOC_ALPHA_LITUSE
:
1270 case BFD_RELOC_GPREL32
:
1272 case BFD_RELOC_ALPHA_LINKAGE
:
1273 case BFD_RELOC_ALPHA_CODEADDR
:
1277 case BFD_RELOC_23_PCREL_S2
:
1280 case BFD_RELOC_ALPHA_HINT
:
1284 assert((int)f
->fx_r_type
< 0 && -(int)f
->fx_r_type
< alpha_num_operands
);
1289 /* Return true if we can partially resolve a relocation now. */
1292 alpha_fix_adjustable (f
)
1296 /* Prevent all adjustments to global symbols */
1297 if (S_IS_EXTERN (f
->fx_addsy
))
1301 /* Are there any relocation types for which we must generate a reloc
1302 but we can adjust the values contained within it? */
1303 switch (f
->fx_r_type
)
1305 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1306 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1307 case BFD_RELOC_ALPHA_GPDISP
:
1311 case BFD_RELOC_ALPHA_LITERAL
:
1314 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1317 case BFD_RELOC_ALPHA_LINKAGE
:
1318 case BFD_RELOC_ALPHA_CODEADDR
:
1322 case BFD_RELOC_ALPHA_LITUSE
:
1325 case BFD_RELOC_GPREL32
:
1326 case BFD_RELOC_23_PCREL_S2
:
1329 case BFD_RELOC_ALPHA_HINT
:
1333 assert ((int)f
->fx_r_type
< 0
1334 && - (int)f
->fx_r_type
< alpha_num_operands
);
1340 /* Generate the BFD reloc to be stuck in the object file from the
1341 fixup used internally in the assembler. */
1344 tc_gen_reloc (sec
, fixp
)
1350 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
1351 reloc
->sym_ptr_ptr
= &fixp
->fx_addsy
->bsym
;
1352 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
1354 /* Make sure none of our internal relocations make it this far.
1355 They'd better have been fully resolved by this point. */
1356 assert ((int)fixp
->fx_r_type
> 0);
1358 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
1359 if (reloc
->howto
== NULL
)
1361 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1362 "cannot represent `%s' relocation in object file",
1363 bfd_get_reloc_code_name (fixp
->fx_r_type
));
1367 if (!fixp
->fx_pcrel
!= !reloc
->howto
->pc_relative
)
1369 as_fatal ("internal error? cannot generate `%s' relocation",
1370 bfd_get_reloc_code_name (fixp
->fx_r_type
));
1372 assert (!fixp
->fx_pcrel
== !reloc
->howto
->pc_relative
);
1375 if (fixp
->fx_r_type
== BFD_RELOC_ALPHA_LITERAL
)
1377 /* fake out bfd_perform_relocation. sigh */
1378 reloc
->addend
= -alpha_gp_value
;
1383 reloc
->addend
= fixp
->fx_offset
;
1386 * Ohhh, this is ugly. The problem is that if this is a local global
1387 * symbol, the relocation will entirely be performed at link time, not
1388 * at assembly time. bfd_perform_reloc doesn't know about this sort
1389 * of thing, and as a result we need to fake it out here.
1391 if (S_IS_EXTERN (fixp
->fx_addsy
) && !S_IS_COMMON(fixp
->fx_addsy
))
1392 reloc
->addend
-= fixp
->fx_addsy
->bsym
->value
;
1399 /* Parse a register name off of the input_line and return a register
1400 number. Gets md_undefined_symbol above to do the register name
1403 Only called as a part of processing the ECOFF .frame directive. */
1406 tc_get_register (frame
)
1409 int framereg
= AXP_REG_SP
;
1412 if (*input_line_pointer
== '$')
1414 char *s
= input_line_pointer
;
1415 char c
= get_symbol_end ();
1416 symbolS
*sym
= md_undefined_symbol (s
);
1418 *strchr(s
, '\0') = c
;
1419 if (sym
&& (framereg
= S_GET_VALUE (sym
)) <= 31)
1422 as_warn ("frame reg expected, using $%d.", framereg
);
1425 note_gpreg (framereg
);
1429 /* This is called before the symbol table is processed. In order to
1430 work with gcc when using mips-tfile, we must keep all local labels.
1431 However, in other cases, we want to discard them. If we were
1432 called with -g, but we didn't see any debugging information, it may
1433 mean that gcc is smuggling debugging information through to
1434 mips-tfile, in which case we must generate all local labels. */
1439 alpha_frob_file_before_adjust ()
1441 if (alpha_debug
!= 0
1442 && ! ecoff_debugging_seen
)
1443 flag_keep_locals
= 1;
1446 #endif /* OBJ_ECOFF */
1448 /* Parse the arguments to an opcode. */
1451 tokenize_arguments (str
, tok
, ntok
)
1456 expressionS
*end_tok
= tok
+ ntok
;
1457 char *old_input_line_pointer
;
1458 int saw_comma
= 0, saw_arg
= 0;
1460 memset (tok
, 0, sizeof (*tok
) * ntok
);
1462 /* Save and restore input_line_pointer around this function */
1463 old_input_line_pointer
= input_line_pointer
;
1464 input_line_pointer
= str
;
1466 while (tok
< end_tok
&& *input_line_pointer
)
1469 switch (*input_line_pointer
)
1475 ++input_line_pointer
;
1476 if (saw_comma
|| !saw_arg
)
1483 char *hold
= input_line_pointer
++;
1485 /* First try for parenthesized register ... */
1487 if (*input_line_pointer
== ')' && tok
->X_op
== O_register
)
1489 tok
->X_op
= (saw_comma
? O_cpregister
: O_pregister
);
1492 ++input_line_pointer
;
1497 /* ... then fall through to plain expression */
1498 input_line_pointer
= hold
;
1502 if (saw_arg
&& !saw_comma
)
1505 if (tok
->X_op
== O_illegal
|| tok
->X_op
== O_absent
)
1518 input_line_pointer
= old_input_line_pointer
;
1519 return ntok
- (end_tok
- tok
);
1522 input_line_pointer
= old_input_line_pointer
;
1526 /* Search forward through all variants of an opcode looking for a
1529 static const struct alpha_opcode
*
1530 find_opcode_match(first_opcode
, tok
, pntok
, pcpumatch
)
1531 const struct alpha_opcode
*first_opcode
;
1532 const expressionS
*tok
;
1536 const struct alpha_opcode
*opcode
= first_opcode
;
1538 int got_cpu_match
= 0;
1542 const unsigned char *opidx
;
1545 /* Don't match opcodes that don't exist on this architecture */
1546 if (!(opcode
->flags
& alpha_target
))
1551 for (opidx
= opcode
->operands
; *opidx
; ++opidx
)
1553 const struct alpha_operand
*operand
= &alpha_operands
[*opidx
];
1555 /* only take input from real operands */
1556 if (operand
->flags
& AXP_OPERAND_FAKE
)
1559 /* when we expect input, make sure we have it */
1562 if ((operand
->flags
& AXP_OPERAND_OPTIONAL_MASK
) == 0)
1567 /* match operand type with expression type */
1568 switch (operand
->flags
& AXP_OPERAND_TYPECHECK_MASK
)
1570 case AXP_OPERAND_IR
:
1571 if (tok
[tokidx
].X_op
!= O_register
1572 || !is_ir_num(tok
[tokidx
].X_add_number
))
1575 case AXP_OPERAND_FPR
:
1576 if (tok
[tokidx
].X_op
!= O_register
1577 || !is_fpr_num(tok
[tokidx
].X_add_number
))
1580 case AXP_OPERAND_IR
|AXP_OPERAND_PARENS
:
1581 if (tok
[tokidx
].X_op
!= O_pregister
1582 || !is_ir_num(tok
[tokidx
].X_add_number
))
1585 case AXP_OPERAND_IR
|AXP_OPERAND_PARENS
|AXP_OPERAND_COMMA
:
1586 if (tok
[tokidx
].X_op
!= O_cpregister
1587 || !is_ir_num(tok
[tokidx
].X_add_number
))
1591 case AXP_OPERAND_RELATIVE
:
1592 case AXP_OPERAND_SIGNED
:
1593 case AXP_OPERAND_UNSIGNED
:
1594 switch (tok
[tokidx
].X_op
)
1606 /* everything else should have been fake */
1612 /* possible match -- did we use all of our input? */
1621 while (++opcode
-alpha_opcodes
< alpha_num_opcodes
1622 && !strcmp(opcode
->name
, first_opcode
->name
));
1625 *pcpumatch
= got_cpu_match
;
1630 /* Search forward through all variants of a macro looking for a syntax
1633 static const struct alpha_macro
*
1634 find_macro_match(first_macro
, tok
, pntok
)
1635 const struct alpha_macro
*first_macro
;
1636 const expressionS
*tok
;
1639 const struct alpha_macro
*macro
= first_macro
;
1644 const enum alpha_macro_arg
*arg
= macro
->argsets
;
1659 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_register
1660 || !is_ir_num(tok
[tokidx
].X_add_number
))
1665 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_pregister
1666 || !is_ir_num(tok
[tokidx
].X_add_number
))
1671 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_cpregister
1672 || !is_ir_num(tok
[tokidx
].X_add_number
))
1677 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_register
1678 || !is_fpr_num(tok
[tokidx
].X_add_number
))
1686 switch (tok
[tokidx
].X_op
)
1699 while (*arg
!= MACRO_EOA
)
1707 while (++macro
-alpha_macros
< alpha_num_macros
1708 && !strcmp(macro
->name
, first_macro
->name
));
1713 /* Insert an operand value into an instruction. */
1716 insert_operand(insn
, operand
, val
, file
, line
)
1718 const struct alpha_operand
*operand
;
1723 if (operand
->bits
!= 32 && !(operand
->flags
& AXP_OPERAND_NOOVERFLOW
))
1727 if (operand
->flags
& AXP_OPERAND_SIGNED
)
1729 max
= (1 << (operand
->bits
- 1)) - 1;
1730 min
= -(1 << (operand
->bits
- 1));
1734 max
= (1 << operand
->bits
) - 1;
1738 if (val
< min
|| val
> max
)
1741 "operand out of range (%s not between %d and %d)";
1742 char buf
[sizeof (val
) * 3 + 2];
1744 sprint_value(buf
, val
);
1746 as_warn_where(file
, line
, err
, buf
, min
, max
);
1748 as_warn(err
, buf
, min
, max
);
1752 if (operand
->insert
)
1754 const char *errmsg
= NULL
;
1756 insn
= (*operand
->insert
) (insn
, val
, &errmsg
);
1761 insn
|= ((val
& ((1 << operand
->bits
) - 1)) << operand
->shift
);
1767 * Turn an opcode description and a set of arguments into
1768 * an instruction and a fixup.
1772 assemble_insn(opcode
, tok
, ntok
, insn
)
1773 const struct alpha_opcode
*opcode
;
1774 const expressionS
*tok
;
1776 struct alpha_insn
*insn
;
1778 const unsigned char *argidx
;
1782 memset (insn
, 0, sizeof (*insn
));
1783 image
= opcode
->opcode
;
1785 for (argidx
= opcode
->operands
; *argidx
; ++argidx
)
1787 const struct alpha_operand
*operand
= &alpha_operands
[*argidx
];
1788 const expressionS
*t
;
1790 if (operand
->flags
& AXP_OPERAND_FAKE
)
1792 /* fake operands take no value and generate no fixup */
1793 image
= insert_operand(image
, operand
, 0, NULL
, 0);
1799 switch (operand
->flags
& AXP_OPERAND_OPTIONAL_MASK
)
1801 case AXP_OPERAND_DEFAULT_FIRST
:
1804 case AXP_OPERAND_DEFAULT_SECOND
:
1807 case AXP_OPERAND_DEFAULT_ZERO
:
1809 static const expressionS zero_exp
= { 0, 0, 0, O_constant
, 1 };
1825 image
= insert_operand(image
, operand
, regno(t
->X_add_number
),
1830 image
= insert_operand(image
, operand
, t
->X_add_number
, NULL
, 0);
1835 struct alpha_fixup
*fixup
;
1837 if (insn
->nfixups
>= MAX_INSN_FIXUPS
)
1838 as_fatal("too many fixups");
1840 fixup
= &insn
->fixups
[insn
->nfixups
++];
1843 fixup
->reloc
= operand
->default_reloc
;
1853 * Actually output an instruction with its fixup.
1858 struct alpha_insn
*insn
;
1863 /* Take care of alignment duties */
1864 if (alpha_auto_align_on
&& alpha_current_align
< 2)
1865 alpha_align (2, (char *) NULL
, alpha_insn_label
);
1866 if (alpha_current_align
> 2)
1867 alpha_current_align
= 2;
1868 alpha_insn_label
= NULL
;
1870 /* Write out the instruction. */
1872 md_number_to_chars (f
, insn
->insn
, 4);
1874 /* Apply the fixups in order */
1875 for (i
= 0; i
< insn
->nfixups
; ++i
)
1877 struct alpha_fixup
*fixup
= &insn
->fixups
[i
];
1881 /* Some fixups are only used internally and so have no howto */
1882 if ((int)fixup
->reloc
< 0)
1883 size
= 4, pcrel
= 0;
1885 /* These relocation types are only used internally. */
1886 else if (fixup
->reloc
== BFD_RELOC_ALPHA_GPDISP_HI16
1887 || fixup
->reloc
== BFD_RELOC_ALPHA_GPDISP_LO16
)
1889 size
= 2, pcrel
= 0;
1894 reloc_howto_type
*reloc_howto
1895 = bfd_reloc_type_lookup (stdoutput
, fixup
->reloc
);
1896 assert (reloc_howto
);
1898 size
= bfd_get_reloc_size (reloc_howto
);
1899 pcrel
= reloc_howto
->pc_relative
;
1901 assert (size
>= 1 && size
<= 4);
1903 fixP
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, size
,
1904 &fixup
->exp
, pcrel
, fixup
->reloc
);
1906 /* Turn off complaints that the addend is too large for some fixups */
1907 switch (fixup
->reloc
)
1909 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1911 case BFD_RELOC_ALPHA_LITERAL
:
1914 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1916 case BFD_RELOC_GPREL32
:
1917 fixP
->fx_no_overflow
= 1;
1925 /* Given an opcode name and a pre-tokenized set of arguments, assemble
1926 the insn, but do not emit it.
1928 Note that this implies no macros allowed, since we can't store more
1929 than one insn in an insn structure. */
1932 assemble_tokens_to_insn(opname
, tok
, ntok
, insn
)
1934 const expressionS
*tok
;
1936 struct alpha_insn
*insn
;
1938 const struct alpha_opcode
*opcode
;
1940 /* search opcodes */
1941 opcode
= (const struct alpha_opcode
*) hash_find (alpha_opcode_hash
, opname
);
1945 opcode
= find_opcode_match (opcode
, tok
, &ntok
, &cpumatch
);
1948 assemble_insn (opcode
, tok
, ntok
, insn
);
1952 as_bad ("inappropriate arguments for opcode `%s'", opname
);
1954 as_bad ("opcode `%s' not supported for target %s", opname
,
1958 as_bad ("unknown opcode `%s'", opname
);
1961 /* Given an opcode name and a pre-tokenized set of arguments, take the
1962 opcode all the way through emission. */
1965 assemble_tokens (opname
, tok
, ntok
, local_macros_on
)
1967 const expressionS
*tok
;
1969 int local_macros_on
;
1971 int found_something
= 0;
1972 const struct alpha_opcode
*opcode
;
1973 const struct alpha_macro
*macro
;
1977 if (local_macros_on
)
1979 macro
= ((const struct alpha_macro
*)
1980 hash_find (alpha_macro_hash
, opname
));
1983 found_something
= 1;
1984 macro
= find_macro_match (macro
, tok
, &ntok
);
1987 (*macro
->emit
) (tok
, ntok
, macro
->arg
);
1993 /* search opcodes */
1994 opcode
= (const struct alpha_opcode
*) hash_find (alpha_opcode_hash
, opname
);
1997 found_something
= 1;
1998 opcode
= find_opcode_match (opcode
, tok
, &ntok
, &cpumatch
);
2001 struct alpha_insn insn
;
2002 assemble_insn (opcode
, tok
, ntok
, &insn
);
2008 if (found_something
)
2010 as_bad ("inappropriate arguments for opcode `%s'", opname
);
2012 as_bad ("opcode `%s' not supported for target %s", opname
,
2015 as_bad ("unknown opcode `%s'", opname
);
2019 /* Some instruction sets indexed by lg(size) */
2020 static const char * const sextX_op
[] = { "sextb", "sextw", "sextl", NULL
};
2021 static const char * const insXl_op
[] = { "insbl", "inswl", "insll", "insql" };
2022 static const char * const insXh_op
[] = { NULL
, "inswh", "inslh", "insqh" };
2023 static const char * const extXl_op
[] = { "extbl", "extwl", "extll", "extql" };
2024 static const char * const extXh_op
[] = { NULL
, "extwh", "extlh", "extqh" };
2025 static const char * const mskXl_op
[] = { "mskbl", "mskwl", "mskll", "mskql" };
2026 static const char * const mskXh_op
[] = { NULL
, "mskwh", "msklh", "mskqh" };
2027 static const char * const stX_op
[] = { "stb", "stw", "stl", "stq" };
2028 static const char * const ldX_op
[] = { "ldb", "ldw", "ldll", "ldq" };
2029 static const char * const ldXu_op
[] = { "ldbu", "ldwu", NULL
, NULL
};
2031 /* Implement the ldgp macro. */
2034 emit_ldgp (tok
, ntok
, unused
)
2035 const expressionS
*tok
;
2042 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
2043 /* from "ldgp r1,n(r2)", generate "ldah r1,X(R2); lda r1,Y(r1)"
2044 with appropriate constants and relocations. */
2045 struct alpha_insn insn
;
2046 expressionS newtok
[3];
2049 /* We're going to need this symbol in md_apply_fix(). */
2050 (void) section_symbol (absolute_section
);
2053 if (regno (tok
[2].X_add_number
) == AXP_REG_PV
)
2054 ecoff_set_gp_prolog_size (0);
2058 set_tok_const (newtok
[1], 0);
2061 assemble_tokens_to_insn ("ldah", newtok
, 3, &insn
);
2066 assert (addend
.X_op
== O_constant
);
2067 addend
.X_op
= O_symbol
;
2068 addend
.X_add_symbol
= alpha_gp_symbol
;
2072 insn
.fixups
[0].exp
= addend
;
2073 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_GPDISP_HI16
;
2077 set_tok_preg (newtok
[2], tok
[0].X_add_number
);
2079 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
2082 addend
.X_add_number
+= 4;
2086 insn
.fixups
[0].exp
= addend
;
2087 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_GPDISP_LO16
;
2090 #endif /* OBJ_ECOFF || OBJ_ELF */
2095 /* Add symbol+addend to link pool.
2096 Return offset from basesym to entry in link pool.
2098 Add new fixup only if offset isn't 16bit. */
2101 add_to_link_pool (basesym
, sym
, addend
)
2106 segT current_section
= now_seg
;
2107 int current_subsec
= now_subseg
;
2109 bfd_reloc_code_real_type reloc_type
;
2111 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
2114 offset
= -basesym
->sy_obj
;
2116 /* @@ This assumes all entries in a given section will be of the same
2117 size... Probably correct, but unwise to rely on. */
2118 /* This must always be called with the same subsegment. */
2120 if (seginfo
->frchainP
)
2121 for (fixp
= seginfo
->frchainP
->fix_root
;
2122 fixp
!= (fixS
*) NULL
;
2123 fixp
= fixp
->fx_next
, offset
+= 8)
2125 if (fixp
->fx_addsy
== sym
&& fixp
->fx_offset
== addend
)
2127 if (range_signed_16 (offset
))
2134 /* Not found in 16bit signed range. */
2136 subseg_set (alpha_link_section
, 0);
2140 fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, sym
, addend
, 0,
2143 subseg_set (current_section
, current_subsec
);
2144 seginfo
->literal_pool_size
+= 8;
2148 #endif /* OBJ_EVAX */
2150 /* Load a (partial) expression into a target register.
2152 If poffset is not null, after the call it will either contain
2153 O_constant 0, or a 16-bit offset appropriate for any MEM format
2154 instruction. In addition, pbasereg will be modified to point to
2155 the base register to use in that MEM format instruction.
2157 In any case, *pbasereg should contain a base register to add to the
2158 expression. This will normally be either AXP_REG_ZERO or
2159 alpha_gp_register. Symbol addresses will always be loaded via $gp,
2160 so "foo($0)" is interpreted as adding the address of foo to $0;
2161 i.e. "ldq $targ, LIT($gp); addq $targ, $0, $targ". Odd, perhaps,
2162 but this is what OSF/1 does.
2164 Finally, the return value is true if the calling macro may emit a
2165 LITUSE reloc if otherwise appropriate. */
2168 load_expression (targreg
, exp
, pbasereg
, poffset
)
2170 const expressionS
*exp
;
2172 expressionS
*poffset
;
2174 int emit_lituse
= 0;
2175 offsetT addend
= exp
->X_add_number
;
2176 int basereg
= *pbasereg
;
2177 struct alpha_insn insn
;
2178 expressionS newtok
[3];
2187 /* attempt to reduce .lit load by splitting the offset from
2188 its symbol when possible, but don't create a situation in
2190 if (!range_signed_32 (addend
) &&
2191 (alpha_noat_on
|| targreg
== AXP_REG_AT
))
2193 lit
= add_to_literal_pool (exp
->X_add_symbol
, addend
,
2194 alpha_lita_section
, 8);
2199 lit
= add_to_literal_pool (exp
->X_add_symbol
, 0,
2200 alpha_lita_section
, 8);
2204 as_fatal ("overflow in literal (.lita) table");
2206 /* emit "ldq r, lit(gp)" */
2208 if (basereg
!= alpha_gp_register
&& targreg
== basereg
)
2211 as_bad ("macro requires $at register while noat in effect");
2212 if (targreg
== AXP_REG_AT
)
2213 as_bad ("macro requires $at while $at in use");
2215 set_tok_reg (newtok
[0], AXP_REG_AT
);
2218 set_tok_reg (newtok
[0], targreg
);
2219 set_tok_sym (newtok
[1], alpha_lita_symbol
, lit
);
2220 set_tok_preg (newtok
[2], alpha_gp_register
);
2222 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
2224 assert (insn
.nfixups
== 1);
2225 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITERAL
;
2226 #endif /* OBJ_ECOFF */
2228 /* emit "ldq r, gotoff(gp)" */
2230 if (basereg
!= alpha_gp_register
&& targreg
== basereg
)
2233 as_bad ("macro requires $at register while noat in effect");
2234 if (targreg
== AXP_REG_AT
)
2235 as_bad ("macro requires $at while $at in use");
2237 set_tok_reg (newtok
[0], AXP_REG_AT
);
2240 set_tok_reg (newtok
[0], targreg
);
2242 /* XXX: Disable this .got minimizing optimization so that we can get
2243 better instruction offset knowledge in the compiler. This happens
2244 very infrequently anyway. */
2245 if (1 || !range_signed_32 (addend
)
2246 && (alpha_noat_on
|| targreg
== AXP_REG_AT
))
2253 set_tok_sym (newtok
[1], exp
->X_add_symbol
, 0);
2256 set_tok_preg (newtok
[2], alpha_gp_register
);
2258 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
2260 assert (insn
.nfixups
== 1);
2261 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_ELF_LITERAL
;
2262 #endif /* OBJ_ELF */
2266 if (alpha_basereg_clobbered
)
2268 /* no basereg, reload basreg from 0(FP). */
2269 set_tok_reg (newtok
[0], targreg
);
2270 set_tok_const (newtok
[1], 0);
2271 set_tok_preg (newtok
[2], AXP_REG_FP
);
2273 assemble_tokens ("ldq", newtok
, 3, 0);
2276 /* Find symbol or symbol pointer in link section. */
2278 if (exp
->X_add_symbol
== alpha_evax_proc
.symbol
)
2280 if (range_signed_16 (addend
))
2282 set_tok_reg (newtok
[0], targreg
);
2283 set_tok_const (newtok
[1], addend
);
2284 set_tok_preg (newtok
[2], basereg
);
2285 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
2290 set_tok_reg (newtok
[0], targreg
);
2291 set_tok_const (newtok
[1], 0);
2292 set_tok_preg (newtok
[2], basereg
);
2293 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
2298 if (!range_signed_32 (addend
))
2300 link
= add_to_link_pool (alpha_evax_proc
.symbol
,
2301 exp
->X_add_symbol
, addend
);
2306 link
= add_to_link_pool (alpha_evax_proc
.symbol
,
2307 exp
->X_add_symbol
, 0);
2309 set_tok_reg (newtok
[0], targreg
);
2310 set_tok_const (newtok
[1], link
);
2311 set_tok_preg (newtok
[2], basereg
);
2312 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
2314 #endif /* OBJ_EVAX */
2321 if (basereg
!= alpha_gp_register
&& basereg
!= AXP_REG_ZERO
)
2323 /* emit "addq r, base, r" */
2325 set_tok_reg (newtok
[1], basereg
);
2326 set_tok_reg (newtok
[2], targreg
);
2327 assemble_tokens ("addq", newtok
, 3, 0);
2339 /* Assume that this difference expression will be resolved to an
2340 absolute value and that that value will fit in 16 bits. */
2342 set_tok_reg (newtok
[0], targreg
);
2344 set_tok_preg (newtok
[2], basereg
);
2345 assemble_tokens ("lda", newtok
, 3, 0);
2348 set_tok_const (*poffset
, 0);
2352 as_bad ("%s number invalid; zero assumed",
2353 exp
->X_add_number
> 0 ? "bignum" : "floating point");
2361 if (!range_signed_32 (addend
))
2365 /* for 64-bit addends, just put it in the literal pool */
2368 /* emit "ldq targreg, lit(basereg)" */
2369 lit
= add_to_link_pool (alpha_evax_proc
.symbol
,
2370 section_symbol (absolute_section
), addend
);
2371 set_tok_reg (newtok
[0], targreg
);
2372 set_tok_const (newtok
[1], lit
);
2373 set_tok_preg (newtok
[2], alpha_gp_register
);
2374 assemble_tokens ("ldq", newtok
, 3, 0);
2377 if (alpha_lit8_section
== NULL
)
2379 create_literal_section (".lit8",
2380 &alpha_lit8_section
,
2381 &alpha_lit8_symbol
);
2384 alpha_lit8_literal
= add_to_literal_pool (alpha_lit8_symbol
, 0x8000,
2385 alpha_lita_section
, 8);
2386 if (alpha_lit8_literal
>= 0x8000)
2387 as_fatal ("overflow in literal (.lita) table");
2391 lit
= add_to_literal_pool (NULL
, addend
, alpha_lit8_section
, 8) - 0x8000;
2393 as_fatal ("overflow in literal (.lit8) table");
2395 /* emit "lda litreg, .lit8+0x8000" */
2397 if (targreg
== basereg
)
2400 as_bad ("macro requires $at register while noat in effect");
2401 if (targreg
== AXP_REG_AT
)
2402 as_bad ("macro requires $at while $at in use");
2404 set_tok_reg (newtok
[0], AXP_REG_AT
);
2407 set_tok_reg (newtok
[0], targreg
);
2409 set_tok_sym (newtok
[1], alpha_lita_symbol
, alpha_lit8_literal
);
2412 set_tok_sym (newtok
[1], alpha_lit8_symbol
, 0x8000);
2414 set_tok_preg (newtok
[2], alpha_gp_register
);
2416 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
2418 assert (insn
.nfixups
== 1);
2420 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITERAL
;
2423 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_ELF_LITERAL
;
2428 /* emit "ldq litreg, lit(litreg)" */
2430 set_tok_const (newtok
[1], lit
);
2431 set_tok_preg (newtok
[2], newtok
[0].X_add_number
);
2433 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
2435 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
2436 if (insn
.nfixups
> 0)
2438 memmove (&insn
.fixups
[1], &insn
.fixups
[0],
2439 sizeof(struct alpha_fixup
) * insn
.nfixups
);
2442 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITUSE
;
2443 insn
.fixups
[0].exp
.X_op
= O_constant
;
2444 insn
.fixups
[0].exp
.X_add_number
= 1;
2449 /* emit "addq litreg, base, target" */
2451 if (basereg
!= AXP_REG_ZERO
)
2453 set_tok_reg (newtok
[1], basereg
);
2454 set_tok_reg (newtok
[2], targreg
);
2455 assemble_tokens ("addq", newtok
, 3, 0);
2457 #endif /* !OBJ_EVAX */
2460 set_tok_const (*poffset
, 0);
2461 *pbasereg
= targreg
;
2465 offsetT low
, high
, extra
, tmp
;
2467 /* for 32-bit operands, break up the addend */
2469 low
= sign_extend_16 (addend
);
2471 high
= sign_extend_16 (tmp
>> 16);
2473 if (tmp
- (high
<< 16))
2477 high
= sign_extend_16 (tmp
>> 16);
2482 set_tok_reg (newtok
[0], targreg
);
2483 set_tok_preg (newtok
[2], basereg
);
2487 /* emit "ldah r, extra(r) */
2488 set_tok_const (newtok
[1], extra
);
2489 assemble_tokens ("ldah", newtok
, 3, 0);
2490 set_tok_preg (newtok
[2], basereg
= targreg
);
2495 /* emit "ldah r, high(r) */
2496 set_tok_const (newtok
[1], high
);
2497 assemble_tokens ("ldah", newtok
, 3, 0);
2499 set_tok_preg (newtok
[2], basereg
);
2502 if ((low
&& !poffset
) || (!poffset
&& basereg
!= targreg
))
2504 /* emit "lda r, low(base)" */
2505 set_tok_const (newtok
[1], low
);
2506 assemble_tokens ("lda", newtok
, 3, 0);
2512 set_tok_const (*poffset
, low
);
2513 *pbasereg
= basereg
;
2519 /* The lda macro differs from the lda instruction in that it handles
2520 most simple expressions, particualrly symbol address loads and
2524 emit_lda (tok
, ntok
, unused
)
2525 const expressionS
*tok
;
2532 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
2534 basereg
= tok
[2].X_add_number
;
2536 (void) load_expression (tok
[0].X_add_number
, &tok
[1], &basereg
, NULL
);
2539 /* The ldah macro differs from the ldah instruction in that it has $31
2540 as an implied base register. */
2543 emit_ldah (tok
, ntok
, unused
)
2544 const expressionS
*tok
;
2548 expressionS newtok
[3];
2552 set_tok_preg (newtok
[2], AXP_REG_ZERO
);
2554 assemble_tokens ("ldah", newtok
, 3, 0);
2557 /* Handle all "simple" integer register loads -- ldq, ldq_l, ldq_u,
2558 etc. They differ from the real instructions in that they do simple
2559 expressions like the lda macro. */
2562 emit_ir_load (tok
, ntok
, opname
)
2563 const expressionS
*tok
;
2567 int basereg
, lituse
;
2568 expressionS newtok
[3];
2569 struct alpha_insn insn
;
2572 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
2574 basereg
= tok
[2].X_add_number
;
2576 lituse
= load_expression (tok
[0].X_add_number
, &tok
[1], &basereg
,
2580 set_tok_preg (newtok
[2], basereg
);
2582 assemble_tokens_to_insn ((const char *)opname
, newtok
, 3, &insn
);
2586 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
2587 if (insn
.nfixups
> 0)
2589 memmove (&insn
.fixups
[1], &insn
.fixups
[0],
2590 sizeof(struct alpha_fixup
) * insn
.nfixups
);
2593 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITUSE
;
2594 insn
.fixups
[0].exp
.X_op
= O_constant
;
2595 insn
.fixups
[0].exp
.X_add_number
= 1;
2600 /* special hack. If the basereg is clobbered for a call
2601 all lda's before the call don't have a basereg. */
2602 if ((tok
[0].X_op
== O_register
)
2603 && (tok
[0].X_add_number
== alpha_gp_register
))
2605 alpha_basereg_clobbered
= 1;
2610 /* Handle fp register loads, and both integer and fp register stores.
2611 Again, we handle simple expressions. */
2614 emit_loadstore (tok
, ntok
, opname
)
2615 const expressionS
*tok
;
2619 int basereg
, lituse
;
2620 expressionS newtok
[3];
2621 struct alpha_insn insn
;
2624 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
2626 basereg
= tok
[2].X_add_number
;
2628 if (tok
[1].X_op
!= O_constant
|| !range_signed_16(tok
[1].X_add_number
))
2631 as_bad ("macro requires $at register while noat in effect");
2633 lituse
= load_expression (AXP_REG_AT
, &tok
[1], &basereg
, &newtok
[1]);
2642 set_tok_preg (newtok
[2], basereg
);
2644 assemble_tokens_to_insn ((const char *)opname
, newtok
, 3, &insn
);
2648 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
2649 if (insn
.nfixups
> 0)
2651 memmove (&insn
.fixups
[1], &insn
.fixups
[0],
2652 sizeof(struct alpha_fixup
) * insn
.nfixups
);
2655 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITUSE
;
2656 insn
.fixups
[0].exp
.X_op
= O_constant
;
2657 insn
.fixups
[0].exp
.X_add_number
= 1;
2663 /* Load a half-word or byte as an unsigned value. */
2666 emit_ldXu (tok
, ntok
, vlgsize
)
2667 const expressionS
*tok
;
2671 if (alpha_target
& AXP_OPCODE_BWX
)
2672 emit_ir_load (tok
, ntok
, ldXu_op
[(long)vlgsize
]);
2675 expressionS newtok
[3];
2678 as_bad ("macro requires $at register while noat in effect");
2680 /* emit "lda $at, exp" */
2682 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
2683 newtok
[0].X_add_number
= AXP_REG_AT
;
2684 assemble_tokens ("lda", newtok
, ntok
, 1);
2686 /* emit "ldq_u targ, 0($at)" */
2689 set_tok_const (newtok
[1], 0);
2690 set_tok_preg (newtok
[2], AXP_REG_AT
);
2691 assemble_tokens ("ldq_u", newtok
, 3, 1);
2693 /* emit "extXl targ, $at, targ" */
2695 set_tok_reg (newtok
[1], AXP_REG_AT
);
2696 newtok
[2] = newtok
[0];
2697 assemble_tokens (extXl_op
[(long)vlgsize
], newtok
, 3, 1);
2701 /* Load a half-word or byte as a signed value. */
2704 emit_ldX (tok
, ntok
, vlgsize
)
2705 const expressionS
*tok
;
2709 emit_ldXu (tok
, ntok
, vlgsize
);
2710 assemble_tokens (sextX_op
[(long)vlgsize
], tok
, 1, 1);
2713 /* Load an integral value from an unaligned address as an unsigned
2717 emit_uldXu (tok
, ntok
, vlgsize
)
2718 const expressionS
*tok
;
2722 long lgsize
= (long)vlgsize
;
2723 expressionS newtok
[3];
2726 as_bad ("macro requires $at register while noat in effect");
2728 /* emit "lda $at, exp" */
2730 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
2731 newtok
[0].X_add_number
= AXP_REG_AT
;
2732 assemble_tokens ("lda", newtok
, ntok
, 1);
2734 /* emit "ldq_u $t9, 0($at)" */
2736 set_tok_reg (newtok
[0], AXP_REG_T9
);
2737 set_tok_const (newtok
[1], 0);
2738 set_tok_preg (newtok
[2], AXP_REG_AT
);
2739 assemble_tokens ("ldq_u", newtok
, 3, 1);
2741 /* emit "ldq_u $t10, size-1($at)" */
2743 set_tok_reg (newtok
[0], AXP_REG_T10
);
2744 set_tok_const (newtok
[1], (1<<lgsize
)-1);
2745 assemble_tokens ("ldq_u", newtok
, 3, 1);
2747 /* emit "extXl $t9, $at, $t9" */
2749 set_tok_reg (newtok
[0], AXP_REG_T9
);
2750 set_tok_reg (newtok
[1], AXP_REG_AT
);
2751 set_tok_reg (newtok
[2], AXP_REG_T9
);
2752 assemble_tokens (extXl_op
[lgsize
], newtok
, 3, 1);
2754 /* emit "extXh $t10, $at, $t10" */
2756 set_tok_reg (newtok
[0], AXP_REG_T10
);
2757 set_tok_reg (newtok
[2], AXP_REG_T10
);
2758 assemble_tokens (extXh_op
[lgsize
], newtok
, 3, 1);
2760 /* emit "or $t9, $t10, targ" */
2762 set_tok_reg (newtok
[0], AXP_REG_T9
);
2763 set_tok_reg (newtok
[1], AXP_REG_T10
);
2765 assemble_tokens ("or", newtok
, 3, 1);
2768 /* Load an integral value from an unaligned address as a signed value.
2769 Note that quads should get funneled to the unsigned load since we
2770 don't have to do the sign extension. */
2773 emit_uldX (tok
, ntok
, vlgsize
)
2774 const expressionS
*tok
;
2778 emit_uldXu (tok
, ntok
, vlgsize
);
2779 assemble_tokens (sextX_op
[(long)vlgsize
], tok
, 1, 1);
2782 /* Implement the ldil macro. */
2785 emit_ldil (tok
, ntok
, unused
)
2786 const expressionS
*tok
;
2790 expressionS newtok
[2];
2792 memcpy (newtok
, tok
, sizeof(newtok
));
2793 newtok
[1].X_add_number
= sign_extend_32 (tok
[1].X_add_number
);
2795 assemble_tokens ("lda", newtok
, ntok
, 1);
2798 /* Store a half-word or byte. */
2801 emit_stX (tok
, ntok
, vlgsize
)
2802 const expressionS
*tok
;
2806 int lgsize
= (int)(long)vlgsize
;
2808 if (alpha_target
& AXP_OPCODE_BWX
)
2809 emit_loadstore (tok
, ntok
, stX_op
[lgsize
]);
2812 expressionS newtok
[3];
2815 as_bad("macro requires $at register while noat in effect");
2817 /* emit "lda $at, exp" */
2819 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
2820 newtok
[0].X_add_number
= AXP_REG_AT
;
2821 assemble_tokens ("lda", newtok
, ntok
, 1);
2823 /* emit "ldq_u $t9, 0($at)" */
2825 set_tok_reg (newtok
[0], AXP_REG_T9
);
2826 set_tok_const (newtok
[1], 0);
2827 set_tok_preg (newtok
[2], AXP_REG_AT
);
2828 assemble_tokens ("ldq_u", newtok
, 3, 1);
2830 /* emit "insXl src, $at, $t10" */
2833 set_tok_reg (newtok
[1], AXP_REG_AT
);
2834 set_tok_reg (newtok
[2], AXP_REG_T10
);
2835 assemble_tokens (insXl_op
[lgsize
], newtok
, 3, 1);
2837 /* emit "mskXl $t9, $at, $t9" */
2839 set_tok_reg (newtok
[0], AXP_REG_T9
);
2840 newtok
[2] = newtok
[0];
2841 assemble_tokens (mskXl_op
[lgsize
], newtok
, 3, 1);
2843 /* emit "or $t9, $t10, $t9" */
2845 set_tok_reg (newtok
[1], AXP_REG_T10
);
2846 assemble_tokens ("or", newtok
, 3, 1);
2848 /* emit "stq_u $t9, 0($at) */
2850 set_tok_const (newtok
[1], 0);
2851 set_tok_preg (newtok
[2], AXP_REG_AT
);
2852 assemble_tokens ("stq_u", newtok
, 3, 1);
2856 /* Store an integer to an unaligned address. */
2859 emit_ustX (tok
, ntok
, vlgsize
)
2860 const expressionS
*tok
;
2864 int lgsize
= (int)(long)vlgsize
;
2865 expressionS newtok
[3];
2867 /* emit "lda $at, exp" */
2869 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
2870 newtok
[0].X_add_number
= AXP_REG_AT
;
2871 assemble_tokens ("lda", newtok
, ntok
, 1);
2873 /* emit "ldq_u $9, 0($at)" */
2875 set_tok_reg (newtok
[0], AXP_REG_T9
);
2876 set_tok_const (newtok
[1], 0);
2877 set_tok_preg (newtok
[2], AXP_REG_AT
);
2878 assemble_tokens ("ldq_u", newtok
, 3, 1);
2880 /* emit "ldq_u $10, size-1($at)" */
2882 set_tok_reg (newtok
[0], AXP_REG_T10
);
2883 set_tok_const (newtok
[1], (1 << lgsize
)-1);
2884 assemble_tokens ("ldq_u", newtok
, 3, 1);
2886 /* emit "insXl src, $at, $t11" */
2889 set_tok_reg (newtok
[1], AXP_REG_AT
);
2890 set_tok_reg (newtok
[2], AXP_REG_T11
);
2891 assemble_tokens (insXl_op
[lgsize
], newtok
, 3, 1);
2893 /* emit "insXh src, $at, $t12" */
2895 set_tok_reg (newtok
[2], AXP_REG_T12
);
2896 assemble_tokens (insXh_op
[lgsize
], newtok
, 3, 1);
2898 /* emit "mskXl $t9, $at, $t9" */
2900 set_tok_reg (newtok
[0], AXP_REG_T9
);
2901 newtok
[2] = newtok
[0];
2902 assemble_tokens (mskXl_op
[lgsize
], newtok
, 3, 1);
2904 /* emit "mskXh $t10, $at, $t10" */
2906 set_tok_reg (newtok
[0], AXP_REG_T10
);
2907 newtok
[2] = newtok
[0];
2908 assemble_tokens (mskXh_op
[lgsize
], newtok
, 3, 1);
2910 /* emit "or $t9, $t11, $t9" */
2912 set_tok_reg (newtok
[0], AXP_REG_T9
);
2913 set_tok_reg (newtok
[1], AXP_REG_T11
);
2914 newtok
[2] = newtok
[0];
2915 assemble_tokens ("or", newtok
, 3, 1);
2917 /* emit "or $t10, $t12, $t10" */
2919 set_tok_reg (newtok
[0], AXP_REG_T10
);
2920 set_tok_reg (newtok
[1], AXP_REG_T12
);
2921 newtok
[2] = newtok
[0];
2922 assemble_tokens ("or", newtok
, 3, 1);
2924 /* emit "stq_u $t9, 0($at)" */
2926 set_tok_reg (newtok
[0], AXP_REG_T9
);
2927 set_tok_const (newtok
[1], 0);
2928 set_tok_preg (newtok
[2], AXP_REG_AT
);
2929 assemble_tokens ("stq_u", newtok
, 3, 1);
2931 /* emit "stq_u $t10, size-1($at)" */
2933 set_tok_reg (newtok
[0], AXP_REG_T10
);
2934 set_tok_const (newtok
[1], (1 << lgsize
)-1);
2935 assemble_tokens ("stq_u", newtok
, 3, 1);
2938 /* Sign extend a half-word or byte. The 32-bit sign extend is
2939 implemented as "addl $31, $r, $t" in the opcode table. */
2942 emit_sextX (tok
, ntok
, vlgsize
)
2943 const expressionS
*tok
;
2947 long lgsize
= (long)vlgsize
;
2949 if (alpha_target
& AXP_OPCODE_BWX
)
2950 assemble_tokens (sextX_op
[lgsize
], tok
, ntok
, 0);
2953 int bitshift
= 64 - 8 * (1 << lgsize
);
2954 expressionS newtok
[3];
2956 /* emit "sll src,bits,dst" */
2959 set_tok_const (newtok
[1], bitshift
);
2960 newtok
[2] = tok
[ntok
- 1];
2961 assemble_tokens ("sll", newtok
, 3, 1);
2963 /* emit "sra dst,bits,dst" */
2965 newtok
[0] = newtok
[2];
2966 assemble_tokens ("sra", newtok
, 3, 1);
2970 /* Implement the division and modulus macros. */
2974 /* Make register usage like in normal procedure call.
2975 Don't clobber PV and RA. */
2978 emit_division (tok
, ntok
, symname
)
2979 const expressionS
*tok
;
2983 /* DIVISION and MODULUS. Yech.
2988 * mov x,R16 # if x != R16
2989 * mov y,R17 # if y != R17
2994 * with appropriate optimizations if R0,R16,R17 are the registers
2995 * specified by the compiler.
3000 expressionS newtok
[3];
3002 xr
= regno (tok
[0].X_add_number
);
3003 yr
= regno (tok
[1].X_add_number
);
3008 rr
= regno (tok
[2].X_add_number
);
3010 /* Move the operands into the right place */
3011 if (yr
== AXP_REG_R16
&& xr
== AXP_REG_R17
)
3013 /* They are in exactly the wrong order -- swap through AT */
3016 as_bad ("macro requires $at register while noat in effect");
3018 set_tok_reg (newtok
[0], AXP_REG_R16
);
3019 set_tok_reg (newtok
[1], AXP_REG_AT
);
3020 assemble_tokens ("mov", newtok
, 2, 1);
3022 set_tok_reg (newtok
[0], AXP_REG_R17
);
3023 set_tok_reg (newtok
[1], AXP_REG_R16
);
3024 assemble_tokens ("mov", newtok
, 2, 1);
3026 set_tok_reg (newtok
[0], AXP_REG_AT
);
3027 set_tok_reg (newtok
[1], AXP_REG_R17
);
3028 assemble_tokens ("mov", newtok
, 2, 1);
3032 if (yr
== AXP_REG_R16
)
3034 set_tok_reg (newtok
[0], AXP_REG_R16
);
3035 set_tok_reg (newtok
[1], AXP_REG_R17
);
3036 assemble_tokens ("mov", newtok
, 2, 1);
3039 if (xr
!= AXP_REG_R16
)
3041 set_tok_reg (newtok
[0], xr
);
3042 set_tok_reg (newtok
[1], AXP_REG_R16
);
3043 assemble_tokens ("mov", newtok
, 2, 1);
3046 if (yr
!= AXP_REG_R16
&& yr
!= AXP_REG_R17
)
3048 set_tok_reg (newtok
[0], yr
);
3049 set_tok_reg (newtok
[1], AXP_REG_R17
);
3050 assemble_tokens ("mov", newtok
, 2, 1);
3054 sym
= symbol_find_or_make ((const char *)symname
);
3056 set_tok_reg (newtok
[0], AXP_REG_AT
);
3057 set_tok_sym (newtok
[1], sym
, 0);
3058 assemble_tokens ("lda", newtok
, 2, 1);
3060 /* Call the division routine */
3061 set_tok_reg (newtok
[0], AXP_REG_AT
);
3062 set_tok_cpreg (newtok
[1], AXP_REG_AT
);
3063 set_tok_const (newtok
[2], 0);
3064 assemble_tokens ("jsr", newtok
, 3, 1);
3066 /* Move the result to the right place */
3067 if (rr
!= AXP_REG_R0
)
3069 set_tok_reg (newtok
[0], AXP_REG_R0
);
3070 set_tok_reg (newtok
[1], rr
);
3071 assemble_tokens ("mov", newtok
, 2, 1);
3075 #else /* !OBJ_EVAX */
3078 emit_division (tok
, ntok
, symname
)
3079 const expressionS
*tok
;
3083 /* DIVISION and MODULUS. Yech.
3093 * with appropriate optimizations if t10,t11,t12 are the registers
3094 * specified by the compiler.
3099 expressionS newtok
[3];
3101 xr
= regno (tok
[0].X_add_number
);
3102 yr
= regno (tok
[1].X_add_number
);
3107 rr
= regno (tok
[2].X_add_number
);
3109 sym
= symbol_find_or_make ((const char *)symname
);
3111 /* Move the operands into the right place */
3112 if (yr
== AXP_REG_T10
&& xr
== AXP_REG_T11
)
3114 /* They are in exactly the wrong order -- swap through AT */
3117 as_bad ("macro requires $at register while noat in effect");
3119 set_tok_reg (newtok
[0], AXP_REG_T10
);
3120 set_tok_reg (newtok
[1], AXP_REG_AT
);
3121 assemble_tokens ("mov", newtok
, 2, 1);
3123 set_tok_reg (newtok
[0], AXP_REG_T11
);
3124 set_tok_reg (newtok
[1], AXP_REG_T10
);
3125 assemble_tokens ("mov", newtok
, 2, 1);
3127 set_tok_reg (newtok
[0], AXP_REG_AT
);
3128 set_tok_reg (newtok
[1], AXP_REG_T11
);
3129 assemble_tokens ("mov", newtok
, 2, 1);
3133 if (yr
== AXP_REG_T10
)
3135 set_tok_reg (newtok
[0], AXP_REG_T10
);
3136 set_tok_reg (newtok
[1], AXP_REG_T11
);
3137 assemble_tokens ("mov", newtok
, 2, 1);
3140 if (xr
!= AXP_REG_T10
)
3142 set_tok_reg (newtok
[0], xr
);
3143 set_tok_reg (newtok
[1], AXP_REG_T10
);
3144 assemble_tokens ("mov", newtok
, 2, 1);
3147 if (yr
!= AXP_REG_T10
&& yr
!= AXP_REG_T11
)
3149 set_tok_reg (newtok
[0], yr
);
3150 set_tok_reg (newtok
[1], AXP_REG_T11
);
3151 assemble_tokens ("mov", newtok
, 2, 1);
3155 /* Call the division routine */
3156 set_tok_reg (newtok
[0], AXP_REG_T9
);
3157 set_tok_sym (newtok
[1], sym
, 0);
3158 assemble_tokens ("jsr", newtok
, 2, 1);
3160 /* Reload the GP register */
3164 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
3165 set_tok_reg (newtok
[0], alpha_gp_register
);
3166 set_tok_const (newtok
[1], 0);
3167 set_tok_preg (newtok
[2], AXP_REG_T9
);
3168 assemble_tokens ("ldgp", newtok
, 3, 1);
3171 /* Move the result to the right place */
3172 if (rr
!= AXP_REG_T12
)
3174 set_tok_reg (newtok
[0], AXP_REG_T12
);
3175 set_tok_reg (newtok
[1], rr
);
3176 assemble_tokens ("mov", newtok
, 2, 1);
3180 #endif /* !OBJ_EVAX */
3182 /* The jsr and jmp macros differ from their instruction counterparts
3183 in that they can load the target address and default most
3187 emit_jsrjmp (tok
, ntok
, vopname
)
3188 const expressionS
*tok
;
3192 const char *opname
= (const char *) vopname
;
3193 struct alpha_insn insn
;
3194 expressionS newtok
[3];
3195 int r
, tokidx
= 0, lituse
= 0;
3197 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_register
)
3198 r
= regno (tok
[tokidx
++].X_add_number
);
3200 r
= strcmp (opname
, "jmp") == 0 ? AXP_REG_ZERO
: AXP_REG_RA
;
3202 set_tok_reg (newtok
[0], r
);
3204 if (tokidx
< ntok
&&
3205 (tok
[tokidx
].X_op
== O_pregister
|| tok
[tokidx
].X_op
== O_cpregister
))
3206 r
= regno (tok
[tokidx
++].X_add_number
);
3208 /* keep register if jsr $n.<sym> */
3212 int basereg
= alpha_gp_register
;
3213 lituse
= load_expression (r
= AXP_REG_PV
, &tok
[tokidx
], &basereg
, NULL
);
3217 set_tok_cpreg (newtok
[1], r
);
3220 /* FIXME: Add hint relocs to BFD for evax. */
3223 newtok
[2] = tok
[tokidx
];
3226 set_tok_const (newtok
[2], 0);
3228 assemble_tokens_to_insn (opname
, newtok
, 3, &insn
);
3230 /* add the LITUSE fixup */
3233 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3234 if (insn
.nfixups
> 0)
3236 memmove (&insn
.fixups
[1], &insn
.fixups
[0],
3237 sizeof(struct alpha_fixup
) * insn
.nfixups
);
3240 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITUSE
;
3241 insn
.fixups
[0].exp
.X_op
= O_constant
;
3242 insn
.fixups
[0].exp
.X_add_number
= 3;
3248 alpha_basereg_clobbered
= 0;
3250 /* reload PV from 0(FP) if it is our current base register. */
3251 if (alpha_gp_register
== AXP_REG_PV
)
3253 set_tok_reg (newtok
[0], AXP_REG_PV
);
3254 set_tok_const (newtok
[1], 0);
3255 set_tok_preg (newtok
[2], AXP_REG_FP
);
3256 assemble_tokens ("ldq", newtok
, 3, 0);
3261 /* The ret and jcr instructions differ from their instruction
3262 counterparts in that everything can be defaulted. */
3265 emit_retjcr (tok
, ntok
, vopname
)
3266 const expressionS
*tok
;
3270 const char *opname
= (const char *)vopname
;
3271 expressionS newtok
[3];
3274 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_register
)
3275 r
= regno (tok
[tokidx
++].X_add_number
);
3279 set_tok_reg (newtok
[0], r
);
3281 if (tokidx
< ntok
&&
3282 (tok
[tokidx
].X_op
== O_pregister
|| tok
[tokidx
].X_op
== O_cpregister
))
3283 r
= regno (tok
[tokidx
++].X_add_number
);
3287 set_tok_cpreg (newtok
[1], r
);
3290 newtok
[2] = tok
[tokidx
];
3292 set_tok_const (newtok
[2], strcmp(opname
, "ret") == 0);
3294 assemble_tokens (opname
, newtok
, 3, 0);
3297 /* Assembler directives */
3299 /* Handle the .text pseudo-op. This is like the usual one, but it
3300 clears alpha_insn_label and restores auto alignment. */
3308 alpha_insn_label
= NULL
;
3309 alpha_auto_align_on
= 1;
3310 alpha_current_align
= 0;
3313 /* Handle the .data pseudo-op. This is like the usual one, but it
3314 clears alpha_insn_label and restores auto alignment. */
3321 alpha_insn_label
= NULL
;
3322 alpha_auto_align_on
= 1;
3323 alpha_current_align
= 0;
3328 /* Handle the OSF/1 .comm pseudo quirks. */
3331 s_alpha_comm (ignore
)
3334 register char *name
;
3338 register symbolS
*symbolP
;
3340 name
= input_line_pointer
;
3341 c
= get_symbol_end ();
3343 /* just after name is now '\0' */
3344 p
= input_line_pointer
;
3349 /* Alpha OSF/1 compiler doesn't provide the comma, gcc does. */
3350 if (*input_line_pointer
== ',')
3352 input_line_pointer
++;
3355 if ((temp
= get_absolute_expression ()) < 0)
3357 as_warn (".COMMon length (%ld.) <0! Ignored.", (long) temp
);
3358 ignore_rest_of_line ();
3363 symbolP
= symbol_find_or_make (name
);
3366 if (S_IS_DEFINED (symbolP
) && ! S_IS_COMMON (symbolP
))
3368 as_bad ("Ignoring attempt to re-define symbol");
3369 ignore_rest_of_line ();
3373 if (S_GET_VALUE (symbolP
))
3375 if (S_GET_VALUE (symbolP
) != (valueT
) temp
)
3376 as_bad ("Length of .comm \"%s\" is already %ld. Not changed to %ld.",
3377 S_GET_NAME (symbolP
),
3378 (long) S_GET_VALUE (symbolP
),
3383 S_SET_VALUE (symbolP
, (valueT
) temp
);
3384 S_SET_EXTERNAL (symbolP
);
3387 know (symbolP
->sy_frag
== &zero_address_frag
);
3389 demand_empty_rest_of_line ();
3392 #endif /* ! OBJ_ELF */
3396 /* Handle the .rdata pseudo-op. This is like the usual one, but it
3397 clears alpha_insn_label and restores auto alignment. */
3400 s_alpha_rdata (ignore
)
3405 temp
= get_absolute_expression ();
3406 subseg_new (".rdata", 0);
3407 demand_empty_rest_of_line ();
3408 alpha_insn_label
= NULL
;
3409 alpha_auto_align_on
= 1;
3410 alpha_current_align
= 0;
3417 /* Handle the .sdata pseudo-op. This is like the usual one, but it
3418 clears alpha_insn_label and restores auto alignment. */
3421 s_alpha_sdata (ignore
)
3426 temp
= get_absolute_expression ();
3427 subseg_new (".sdata", 0);
3428 demand_empty_rest_of_line ();
3429 alpha_insn_label
= NULL
;
3430 alpha_auto_align_on
= 1;
3431 alpha_current_align
= 0;
3437 /* Handle the .section pseudo-op. This is like the usual one, but it
3438 clears alpha_insn_label and restores auto alignment. */
3441 s_alpha_section (ignore
)
3444 obj_elf_section (ignore
);
3446 alpha_insn_label
= NULL
;
3447 alpha_auto_align_on
= 1;
3448 alpha_current_align
= 0;
3455 /* Handle the section specific pseudo-op. */
3458 s_alpha_section (secid
)
3462 #define EVAX_SECTION_COUNT 6
3463 static char *section_name
[EVAX_SECTION_COUNT
+1] =
3464 { "NULL", ".rdata", ".comm", ".link", ".ctors", ".dtors", ".lcomm" };
3466 if ((secid
<= 0) || (secid
> EVAX_SECTION_COUNT
))
3468 as_fatal ("Unknown section directive");
3469 demand_empty_rest_of_line ();
3472 temp
= get_absolute_expression ();
3473 subseg_new (section_name
[secid
], 0);
3474 demand_empty_rest_of_line ();
3475 alpha_insn_label
= NULL
;
3476 alpha_auto_align_on
= 1;
3477 alpha_current_align
= 0;
3484 s_alpha_prologue (ignore
)
3487 alpha_basereg_clobbered
= 0;
3488 demand_empty_rest_of_line ();
3494 /* Parse .ent directives. */
3497 s_alpha_ent (ignore
)
3501 expressionS symexpr
;
3503 alpha_evax_proc
.pdsckind
= 0;
3504 alpha_evax_proc
.framereg
= -1;
3505 alpha_evax_proc
.framesize
= 0;
3506 alpha_evax_proc
.rsa_offset
= 0;
3507 alpha_evax_proc
.ra_save
= AXP_REG_RA
;
3508 alpha_evax_proc
.fp_save
= -1;
3509 alpha_evax_proc
.imask
= 0;
3510 alpha_evax_proc
.fmask
= 0;
3511 alpha_evax_proc
.prologue
= 0;
3512 alpha_evax_proc
.type
= 0;
3514 expression (&symexpr
);
3516 if (symexpr
.X_op
!= O_symbol
)
3518 as_fatal (".ent directive has no symbol");
3519 demand_empty_rest_of_line ();
3523 symbol
= make_expr_symbol (&symexpr
);
3524 symbol
->bsym
->flags
|= BSF_FUNCTION
;
3525 alpha_evax_proc
.symbol
= symbol
;
3527 demand_empty_rest_of_line ();
3532 /* Parse .frame <framreg>,<framesize>,RA,<rsa_offset> directives. */
3535 s_alpha_frame (ignore
)
3540 alpha_evax_proc
.framereg
= tc_get_register (1);
3543 if (*input_line_pointer
++ != ','
3544 || get_absolute_expression_and_terminator (&val
) != ',')
3546 as_warn ("Bad .frame directive 1./2. param");
3547 --input_line_pointer
;
3548 demand_empty_rest_of_line ();
3552 alpha_evax_proc
.framesize
= val
;
3554 (void) tc_get_register (1);
3556 if (*input_line_pointer
++ != ',')
3558 as_warn ("Bad .frame directive 3./4. param");
3559 --input_line_pointer
;
3560 demand_empty_rest_of_line ();
3563 alpha_evax_proc
.rsa_offset
= get_absolute_expression ();
3569 s_alpha_pdesc (ignore
)
3579 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
3581 if (now_seg
!= alpha_link_section
)
3583 as_bad (".pdesc directive not in link (.link) section");
3584 demand_empty_rest_of_line ();
3588 if ((alpha_evax_proc
.symbol
== 0)
3589 || (!S_IS_DEFINED (alpha_evax_proc
.symbol
)))
3591 as_fatal (".pdesc has no matching .ent");
3592 demand_empty_rest_of_line ();
3596 alpha_evax_proc
.symbol
->sy_obj
= (valueT
)seginfo
->literal_pool_size
;
3599 if (exp
.X_op
!= O_symbol
)
3601 as_warn (".pdesc directive has no entry symbol");
3602 demand_empty_rest_of_line ();
3606 entry_sym
= make_expr_symbol (&exp
);
3607 /* Save bfd symbol of proc desc in function symbol. */
3608 alpha_evax_proc
.symbol
->bsym
->udata
.p
= (PTR
)entry_sym
->bsym
;
3611 if (*input_line_pointer
++ != ',')
3613 as_warn ("No comma after .pdesc <entryname>");
3614 demand_empty_rest_of_line ();
3619 name
= input_line_pointer
;
3620 name_end
= get_symbol_end ();
3622 if (strncmp(name
, "stack", 5) == 0)
3624 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_FP_STACK
;
3626 else if (strncmp(name
, "reg", 3) == 0)
3628 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_FP_REGISTER
;
3630 else if (strncmp(name
, "null", 4) == 0)
3632 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_NULL
;
3636 as_fatal ("unknown procedure kind");
3637 demand_empty_rest_of_line ();
3641 *input_line_pointer
= name_end
;
3642 demand_empty_rest_of_line ();
3644 #ifdef md_flush_pending_output
3645 md_flush_pending_output ();
3648 frag_align (3, 0, 0);
3650 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
3652 seginfo
->literal_pool_size
+= 16;
3654 *p
= alpha_evax_proc
.pdsckind
3655 | ((alpha_evax_proc
.framereg
== 29) ? PDSC_S_M_BASE_REG_IS_FP
: 0);
3656 *(p
+1) = PDSC_S_M_NATIVE
3657 | PDSC_S_M_NO_JACKET
;
3659 switch (alpha_evax_proc
.pdsckind
)
3661 case PDSC_S_K_KIND_NULL
:
3665 case PDSC_S_K_KIND_FP_REGISTER
:
3666 *(p
+2) = alpha_evax_proc
.fp_save
;
3667 *(p
+3) = alpha_evax_proc
.ra_save
;
3669 case PDSC_S_K_KIND_FP_STACK
:
3670 md_number_to_chars (p
+2, (valueT
)alpha_evax_proc
.rsa_offset
, 2);
3672 default: /* impossible */
3677 *(p
+5) = alpha_evax_proc
.type
& 0x0f;
3679 /* Signature offset. */
3680 md_number_to_chars (p
+6, (valueT
)0, 2);
3682 fix_new_exp (frag_now
, p
-frag_now
->fr_literal
+8, 8, &exp
, 0, BFD_RELOC_64
);
3684 if (alpha_evax_proc
.pdsckind
== PDSC_S_K_KIND_NULL
)
3687 /* Add dummy fix to make add_to_link_pool work. */
3689 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
3691 seginfo
->literal_pool_size
+= 8;
3693 /* pdesc+16: Size. */
3694 md_number_to_chars (p
, (valueT
)alpha_evax_proc
.framesize
, 4);
3696 md_number_to_chars (p
+4, (valueT
)0, 2);
3699 md_number_to_chars (p
+6, alpha_evax_proc
.prologue
, 2);
3701 if (alpha_evax_proc
.pdsckind
== PDSC_S_K_KIND_FP_REGISTER
)
3704 /* Add dummy fix to make add_to_link_pool work. */
3706 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
3708 seginfo
->literal_pool_size
+= 8;
3710 /* pdesc+24: register masks. */
3712 md_number_to_chars (p
, alpha_evax_proc
.imask
, 4);
3713 md_number_to_chars (p
+4, alpha_evax_proc
.fmask
, 4);
3719 /* Support for crash debug on vms. */
3722 s_alpha_name (ignore
)
3727 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
3729 if (now_seg
!= alpha_link_section
)
3731 as_bad (".name directive not in link (.link) section");
3732 demand_empty_rest_of_line ();
3737 if (exp
.X_op
!= O_symbol
)
3739 as_warn (".name directive has no symbol");
3740 demand_empty_rest_of_line ();
3744 demand_empty_rest_of_line ();
3746 #ifdef md_flush_pending_output
3747 md_flush_pending_output ();
3750 frag_align (3, 0, 0);
3752 seginfo
->literal_pool_size
+= 8;
3754 fix_new_exp (frag_now
, p
-frag_now
->fr_literal
, 8, &exp
, 0, BFD_RELOC_64
);
3761 s_alpha_linkage (ignore
)
3767 #ifdef md_flush_pending_output
3768 md_flush_pending_output ();
3772 if (exp
.X_op
!= O_symbol
)
3774 as_fatal ("No symbol after .linkage");
3778 p
= frag_more (LKP_S_K_SIZE
);
3779 memset (p
, 0, LKP_S_K_SIZE
);
3780 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, LKP_S_K_SIZE
, &exp
, 0,\
3781 BFD_RELOC_ALPHA_LINKAGE
);
3783 demand_empty_rest_of_line ();
3790 s_alpha_code_address (ignore
)
3796 #ifdef md_flush_pending_output
3797 md_flush_pending_output ();
3801 if (exp
.X_op
!= O_symbol
)
3803 as_fatal ("No symbol after .code_address");
3809 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 8, &exp
, 0,\
3810 BFD_RELOC_ALPHA_CODEADDR
);
3812 demand_empty_rest_of_line ();
3819 s_alpha_fp_save (ignore
)
3823 alpha_evax_proc
.fp_save
= tc_get_register (1);
3825 demand_empty_rest_of_line ();
3831 s_alpha_mask (ignore
)
3836 if (get_absolute_expression_and_terminator (&val
) != ',')
3838 as_warn ("Bad .mask directive");
3839 --input_line_pointer
;
3843 alpha_evax_proc
.imask
= val
;
3844 (void)get_absolute_expression ();
3846 demand_empty_rest_of_line ();
3853 s_alpha_fmask (ignore
)
3858 if (get_absolute_expression_and_terminator (&val
) != ',')
3860 as_warn ("Bad .fmask directive");
3861 --input_line_pointer
;
3865 alpha_evax_proc
.fmask
= val
;
3866 (void) get_absolute_expression ();
3868 demand_empty_rest_of_line ();
3874 s_alpha_end (ignore
)
3879 c
= get_symbol_end ();
3880 *input_line_pointer
= c
;
3881 demand_empty_rest_of_line ();
3882 alpha_evax_proc
.symbol
= 0;
3883 alpha_basereg_clobbered
= 0;
3890 s_alpha_file (ignore
)
3895 static char case_hack
[32];
3897 extern char *demand_copy_string
PARAMS ((int *lenP
));
3899 sprintf (case_hack
, "<CASE:%01d%01d>",
3900 alpha_flag_hash_long_names
, alpha_flag_show_after_trunc
);
3902 s
= symbol_find_or_make (case_hack
);
3903 s
->bsym
->flags
|= BSF_FILE
;
3905 get_absolute_expression ();
3906 s
= symbol_find_or_make (demand_copy_string (&length
));
3907 s
->bsym
->flags
|= BSF_FILE
;
3908 demand_empty_rest_of_line ();
3912 #endif /* OBJ_EVAX */
3914 /* Handle the .gprel32 pseudo op. */
3917 s_alpha_gprel32 (ignore
)
3930 e
.X_add_symbol
= section_symbol(absolute_section
);
3943 e
.X_add_symbol
= section_symbol (absolute_section
);
3946 e
.X_op
= O_subtract
;
3947 e
.X_op_symbol
= alpha_gp_symbol
;
3955 if (alpha_auto_align_on
&& alpha_current_align
< 2)
3956 alpha_align (2, (char *) NULL
, alpha_insn_label
);
3957 if (alpha_current_align
> 2)
3958 alpha_current_align
= 2;
3959 alpha_insn_label
= NULL
;
3963 fix_new_exp (frag_now
, p
-frag_now
->fr_literal
, 4,
3964 &e
, 0, BFD_RELOC_GPREL32
);
3967 /* Handle floating point allocation pseudo-ops. This is like the
3968 generic vresion, but it makes sure the current label, if any, is
3969 correctly aligned. */
3972 s_alpha_float_cons (type
)
3999 if (alpha_auto_align_on
&& alpha_current_align
< log_size
)
4000 alpha_align (log_size
, (char *) NULL
, alpha_insn_label
);
4001 if (alpha_current_align
> log_size
)
4002 alpha_current_align
= log_size
;
4003 alpha_insn_label
= NULL
;
4008 /* Handle the .proc pseudo op. We don't really do much with it except
4012 s_alpha_proc (is_static
)
4021 /* Takes ".proc name,nargs" */
4023 name
= input_line_pointer
;
4024 c
= get_symbol_end ();
4025 p
= input_line_pointer
;
4026 symbolP
= symbol_find_or_make (name
);
4029 if (*input_line_pointer
!= ',')
4032 as_warn ("Expected comma after name \"%s\"", name
);
4035 ignore_rest_of_line ();
4039 input_line_pointer
++;
4040 temp
= get_absolute_expression ();
4042 /* symbolP->sy_other = (signed char) temp; */
4043 as_warn ("unhandled: .proc %s,%d", name
, temp
);
4044 demand_empty_rest_of_line ();
4047 /* Handle the .set pseudo op. This is used to turn on and off most of
4048 the assembler features. */
4058 name
= input_line_pointer
;
4059 ch
= get_symbol_end ();
4062 if (s
[0] == 'n' && s
[1] == 'o')
4067 if (!strcmp ("reorder", s
))
4069 else if (!strcmp ("at", s
))
4070 alpha_noat_on
= !yesno
;
4071 else if (!strcmp ("macro", s
))
4072 alpha_macros_on
= yesno
;
4073 else if (!strcmp ("move", s
))
4075 else if (!strcmp ("volatile", s
))
4078 as_warn ("Tried to .set unrecognized mode `%s'", name
);
4080 *input_line_pointer
= ch
;
4081 demand_empty_rest_of_line ();
4084 /* Handle the .base pseudo op. This changes the assembler's notion of
4085 the $gp register. */
4088 s_alpha_base (ignore
)
4092 if (first_32bit_quadrant
)
4094 /* not fatal, but it might not work in the end */
4095 as_warn ("File overrides no-base-register option.");
4096 first_32bit_quadrant
= 0;
4101 if (*input_line_pointer
== '$')
4103 input_line_pointer
++;
4104 if (*input_line_pointer
== 'r')
4105 input_line_pointer
++;
4108 alpha_gp_register
= get_absolute_expression ();
4109 if (alpha_gp_register
< 0 || alpha_gp_register
> 31)
4111 alpha_gp_register
= AXP_REG_GP
;
4112 as_warn ("Bad base register, using $%d.", alpha_gp_register
);
4115 demand_empty_rest_of_line ();
4118 /* Handle the .align pseudo-op. This aligns to a power of two. It
4119 also adjusts any current instruction label. We treat this the same
4120 way the MIPS port does: .align 0 turns off auto alignment. */
4123 s_alpha_align (ignore
)
4128 long max_alignment
= 15;
4130 align
= get_absolute_expression ();
4131 if (align
> max_alignment
)
4133 align
= max_alignment
;
4134 as_bad ("Alignment too large: %d. assumed", align
);
4138 as_warn ("Alignment negative: 0 assumed");
4142 if (*input_line_pointer
== ',')
4144 input_line_pointer
++;
4145 fill
= get_absolute_expression ();
4153 alpha_auto_align_on
= 1;
4154 alpha_align (align
, pfill
, alpha_insn_label
);
4158 alpha_auto_align_on
= 0;
4161 demand_empty_rest_of_line ();
4164 /* Hook the normal string processor to reset known alignment. */
4167 s_alpha_stringer (terminate
)
4170 alpha_current_align
= 0;
4171 alpha_insn_label
= NULL
;
4172 stringer (terminate
);
4175 /* Hook the normal space processing to reset known alignment. */
4178 s_alpha_space (ignore
)
4181 alpha_current_align
= 0;
4182 alpha_insn_label
= NULL
;
4186 /* Hook into cons for auto-alignment. */
4189 alpha_cons_align (size
)
4195 while ((size
>>= 1) != 0)
4198 if (alpha_auto_align_on
&& alpha_current_align
< log_size
)
4199 alpha_align (log_size
, (char *) NULL
, alpha_insn_label
);
4200 if (alpha_current_align
> log_size
)
4201 alpha_current_align
= log_size
;
4202 alpha_insn_label
= NULL
;
4205 /* Here come the .uword, .ulong, and .uquad explicitly unaligned
4206 pseudos. We just turn off auto-alignment and call down to cons. */
4209 s_alpha_ucons (bytes
)
4212 int hold
= alpha_auto_align_on
;
4213 alpha_auto_align_on
= 0;
4215 alpha_auto_align_on
= hold
;
4218 /* Switch the working cpu type. */
4221 s_alpha_arch (ignored
)
4225 const struct cpu_type
*p
;
4228 name
= input_line_pointer
;
4229 ch
= get_symbol_end ();
4231 for (p
= cpu_types
; p
->name
; ++p
)
4232 if (strcmp(name
, p
->name
) == 0)
4234 alpha_target_name
= p
->name
, alpha_target
= p
->flags
;
4237 as_warn("Unknown CPU identifier `%s'", name
);
4240 *input_line_pointer
= ch
;
4241 demand_empty_rest_of_line ();
4247 /* print token expression with alpha specific extension. */
4250 alpha_print_token(f
, exp
)
4252 const expressionS
*exp
;
4262 expressionS nexp
= *exp
;
4263 nexp
.X_op
= O_register
;
4264 print_expr (f
, &nexp
);
4269 print_expr (f
, exp
);
4276 /* The target specific pseudo-ops which we support. */
4278 const pseudo_typeS md_pseudo_table
[] =
4280 {"common", s_comm
, 0}, /* is this used? */
4282 {"comm", s_alpha_comm
, 0}, /* osf1 compiler does this */
4283 {"rdata", s_alpha_rdata
, 0},
4285 {"text", s_alpha_text
, 0},
4286 {"data", s_alpha_data
, 0},
4288 {"sdata", s_alpha_sdata
, 0},
4291 {"section", s_alpha_section
, 0},
4292 {"section.s", s_alpha_section
, 0},
4293 {"sect", s_alpha_section
, 0},
4294 {"sect.s", s_alpha_section
, 0},
4297 { "pdesc", s_alpha_pdesc
, 0},
4298 { "name", s_alpha_name
, 0},
4299 { "linkage", s_alpha_linkage
, 0},
4300 { "code_address", s_alpha_code_address
, 0},
4301 { "ent", s_alpha_ent
, 0},
4302 { "frame", s_alpha_frame
, 0},
4303 { "fp_save", s_alpha_fp_save
, 0},
4304 { "mask", s_alpha_mask
, 0},
4305 { "fmask", s_alpha_fmask
, 0},
4306 { "end", s_alpha_end
, 0},
4307 { "file", s_alpha_file
, 0},
4308 { "rdata", s_alpha_section
, 1},
4309 { "comm", s_alpha_section
, 2},
4310 { "link", s_alpha_section
, 3},
4311 { "ctors", s_alpha_section
, 4},
4312 { "dtors", s_alpha_section
, 5},
4313 { "lcomm", s_alpha_section
, 6},
4315 {"gprel32", s_alpha_gprel32
, 0},
4316 {"t_floating", s_alpha_float_cons
, 'd'},
4317 {"s_floating", s_alpha_float_cons
, 'f'},
4318 {"f_floating", s_alpha_float_cons
, 'F'},
4319 {"g_floating", s_alpha_float_cons
, 'G'},
4320 {"d_floating", s_alpha_float_cons
, 'D'},
4322 {"proc", s_alpha_proc
, 0},
4323 {"aproc", s_alpha_proc
, 1},
4324 {"set", s_alpha_set
, 0},
4325 {"reguse", s_ignore
, 0},
4326 {"livereg", s_ignore
, 0},
4327 {"base", s_alpha_base
, 0}, /*??*/
4328 {"option", s_ignore
, 0},
4329 {"prologue", s_ignore
, 0},
4330 {"aent", s_ignore
, 0},
4331 {"ugen", s_ignore
, 0},
4332 {"eflag", s_ignore
, 0},
4334 {"align", s_alpha_align
, 0},
4335 {"double", s_alpha_float_cons
, 'd'},
4336 {"float", s_alpha_float_cons
, 'f'},
4337 {"single", s_alpha_float_cons
, 'f'},
4338 {"ascii", s_alpha_stringer
, 0},
4339 {"asciz", s_alpha_stringer
, 1},
4340 {"string", s_alpha_stringer
, 1},
4341 {"space", s_alpha_space
, 0},
4342 {"skip", s_alpha_space
, 0},
4343 {"zero", s_alpha_space
, 0},
4345 /* Unaligned data pseudos. */
4346 {"uword", s_alpha_ucons
, 2},
4347 {"ulong", s_alpha_ucons
, 4},
4348 {"uquad", s_alpha_ucons
, 8},
4351 /* Dwarf wants these versions of unaligned. */
4352 {"2byte", s_alpha_ucons
, 2},
4353 {"4byte", s_alpha_ucons
, 4},
4354 {"8byte", s_alpha_ucons
, 8},
4357 /* We don't do any optimizing, so we can safely ignore these. */
4358 {"noalias", s_ignore
, 0},
4359 {"alias", s_ignore
, 0},
4361 {"arch", s_alpha_arch
, 0},
4367 /* Build a BFD section with its flags set appropriately for the .lita,
4368 .lit8, or .lit4 sections. */
4371 create_literal_section (name
, secp
, symp
)
4376 segT current_section
= now_seg
;
4377 int current_subsec
= now_subseg
;
4380 *secp
= new_sec
= subseg_new (name
, 0);
4381 subseg_set (current_section
, current_subsec
);
4382 bfd_set_section_alignment (stdoutput
, new_sec
, 4);
4383 bfd_set_section_flags (stdoutput
, new_sec
,
4384 SEC_RELOC
| SEC_ALLOC
| SEC_LOAD
| SEC_READONLY
4387 S_CLEAR_EXTERNAL (*symp
= section_symbol (new_sec
));
4392 /* @@@ GP selection voodoo. All of this seems overly complicated and
4393 unnecessary; which is the primary reason it's for ECOFF only. */
4402 vma
= bfd_get_section_vma (foo
, sec
);
4403 if (vma
&& vma
< alpha_gp_value
)
4404 alpha_gp_value
= vma
;
4410 assert (alpha_gp_value
== 0);
4412 /* Get minus-one in whatever width... */
4413 alpha_gp_value
= 0; alpha_gp_value
--;
4415 /* Select the smallest VMA of these existing sections. */
4416 maybe_set_gp (alpha_lita_section
);
4418 /* These were disabled before -- should we use them? */
4419 maybe_set_gp (sdata
);
4420 maybe_set_gp (lit8_sec
);
4421 maybe_set_gp (lit4_sec
);
4424 /* @@ Will a simple 0x8000 work here? If not, why not? */
4425 #define GP_ADJUSTMENT (0x8000 - 0x10)
4427 alpha_gp_value
+= GP_ADJUSTMENT
;
4429 S_SET_VALUE (alpha_gp_symbol
, alpha_gp_value
);
4432 printf ("Chose GP value of %lx\n", alpha_gp_value
);
4435 #endif /* OBJ_ECOFF */
4437 /* Called internally to handle all alignment needs. This takes care
4438 of eliding calls to frag_align if'n the cached current alignment
4439 says we've already got it, as well as taking care of the auto-align
4440 feature wrt labels. */
4443 alpha_align (n
, pfill
, label
)
4448 if (alpha_current_align
>= n
)
4454 && (bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
) != 0)
4456 static char const nop
[4] = { 0x1f, 0x04, 0xff, 0x47 };
4458 /* First, make sure we're on a four-byte boundary, in case
4459 someone has been putting .byte values into the text
4460 section. The DEC assembler silently fills with unaligned
4461 no-op instructions. This will zero-fill, then nop-fill
4462 with proper alignment. */
4463 if (alpha_current_align
< 2)
4464 frag_align (2, 0, 0);
4465 frag_align_pattern (n
, nop
, sizeof nop
, 0);
4468 frag_align (n
, 0, 0);
4471 frag_align (n
, *pfill
, 0);
4473 alpha_current_align
= n
;
4477 assert (S_GET_SEGMENT (label
) == now_seg
);
4478 label
->sy_frag
= frag_now
;
4479 S_SET_VALUE (label
, (valueT
) frag_now_fix ());
4482 record_alignment(now_seg
, n
);
4485 /* The Alpha has support for some VAX floating point types, as well as for
4486 IEEE floating point. We consider IEEE to be the primary floating point
4487 format, and sneak in the VAX floating point support here. */
4488 #define md_atof vax_md_atof
4489 #include "config/atof-vax.c"