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);
1054 fixP
->fx_r_type
= BFD_RELOC_16_PCREL
;
1059 fixP
->fx_r_type
= BFD_RELOC_32_PCREL
;
1064 fixP
->fx_r_type
= BFD_RELOC_64_PCREL
;
1067 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
1069 md_number_to_chars (fixpos
, value
, size
);
1075 case BFD_RELOC_GPREL32
:
1076 assert (fixP
->fx_subsy
== alpha_gp_symbol
);
1078 /* FIXME: inherited this obliviousness of `value' -- why? */
1079 md_number_to_chars (fixpos
, -alpha_gp_value
, 4);
1083 case BFD_RELOC_GPREL32
:
1087 case BFD_RELOC_23_PCREL_S2
:
1088 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
1090 image
= bfd_getl32(fixpos
);
1091 image
= (image
& ~0x1FFFFF) | ((value
>> 2) & 0x1FFFFF);
1096 case BFD_RELOC_ALPHA_HINT
:
1097 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
1099 image
= bfd_getl32(fixpos
);
1100 image
= (image
& ~0x3FFF) | ((value
>> 2) & 0x3FFF);
1106 case BFD_RELOC_ALPHA_LITERAL
:
1107 md_number_to_chars (fixpos
, value
, 2);
1110 case BFD_RELOC_ALPHA_LITUSE
:
1114 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1115 case BFD_RELOC_ALPHA_LITUSE
:
1119 case BFD_RELOC_ALPHA_LINKAGE
:
1120 case BFD_RELOC_ALPHA_CODEADDR
:
1126 const struct alpha_operand
*operand
;
1128 if ((int)fixP
->fx_r_type
>= 0)
1129 as_fatal ("unhandled relocation type %s",
1130 bfd_get_reloc_code_name (fixP
->fx_r_type
));
1132 assert (-(int)fixP
->fx_r_type
< alpha_num_operands
);
1133 operand
= &alpha_operands
[-(int)fixP
->fx_r_type
];
1135 /* The rest of these fixups only exist internally during symbol
1136 resolution and have no representation in the object file.
1137 Therefore they must be completely resolved as constants. */
1139 if (fixP
->fx_addsy
!= 0
1140 && fixP
->fx_addsy
->bsym
->section
!= absolute_section
)
1141 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
1142 "non-absolute expression in constant field");
1144 image
= bfd_getl32(fixpos
);
1145 image
= insert_operand(image
, operand
, (offsetT
)value
,
1146 fixP
->fx_file
, fixP
->fx_line
);
1151 if (fixP
->fx_addsy
!= 0 || fixP
->fx_pcrel
!= 0)
1155 as_warn_where(fixP
->fx_file
, fixP
->fx_line
,
1156 "type %d reloc done?\n", (int)fixP
->fx_r_type
);
1161 md_number_to_chars(fixpos
, image
, 4);
1169 * Look for a register name in the given symbol.
1173 md_undefined_symbol(name
)
1178 int is_float
= 0, num
;
1183 if (name
[1] == 'p' && name
[2] == '\0')
1184 return alpha_register_table
[AXP_REG_FP
];
1189 if (!isdigit(*++name
))
1193 case '0': case '1': case '2': case '3': case '4':
1194 case '5': case '6': case '7': case '8': case '9':
1195 if (name
[1] == '\0')
1196 num
= name
[0] - '0';
1197 else if (name
[0] != '0' && isdigit(name
[1]) && name
[2] == '\0')
1199 num
= (name
[0] - '0') * 10 + name
[1] - '0';
1206 if (!alpha_noat_on
&& num
== AXP_REG_AT
)
1207 as_warn("Used $at without \".set noat\"");
1208 return alpha_register_table
[num
+ is_float
];
1211 if (name
[1] == 't' && name
[2] == '\0')
1214 as_warn("Used $at without \".set noat\"");
1215 return alpha_register_table
[AXP_REG_AT
];
1220 if (name
[1] == 'p' && name
[2] == '\0')
1221 return alpha_register_table
[alpha_gp_register
];
1225 if (name
[1] == 'p' && name
[2] == '\0')
1226 return alpha_register_table
[AXP_REG_SP
];
1234 /* @@@ Magic ECOFF bits. */
1237 alpha_frob_ecoff_data ()
1240 /* $zero and $f31 are read-only */
1241 alpha_gprmask
&= ~1;
1242 alpha_fprmask
&= ~1;
1246 /* Hook to remember a recently defined label so that the auto-align
1247 code can adjust the symbol after we know what alignment will be
1251 alpha_define_label (sym
)
1254 alpha_insn_label
= sym
;
1257 /* Return true if we must always emit a reloc for a type and false if
1258 there is some hope of resolving it a assembly time. */
1261 alpha_force_relocation (f
)
1264 switch (f
->fx_r_type
)
1266 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1267 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1268 case BFD_RELOC_ALPHA_GPDISP
:
1270 case BFD_RELOC_ALPHA_LITERAL
:
1273 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1275 case BFD_RELOC_ALPHA_LITUSE
:
1276 case BFD_RELOC_GPREL32
:
1278 case BFD_RELOC_ALPHA_LINKAGE
:
1279 case BFD_RELOC_ALPHA_CODEADDR
:
1283 case BFD_RELOC_23_PCREL_S2
:
1286 case BFD_RELOC_ALPHA_HINT
:
1290 assert((int)f
->fx_r_type
< 0 && -(int)f
->fx_r_type
< alpha_num_operands
);
1295 /* Return true if we can partially resolve a relocation now. */
1298 alpha_fix_adjustable (f
)
1302 /* Prevent all adjustments to global symbols */
1303 if (S_IS_EXTERN (f
->fx_addsy
))
1307 /* Are there any relocation types for which we must generate a reloc
1308 but we can adjust the values contained within it? */
1309 switch (f
->fx_r_type
)
1311 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1312 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1313 case BFD_RELOC_ALPHA_GPDISP
:
1317 case BFD_RELOC_ALPHA_LITERAL
:
1320 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1323 case BFD_RELOC_ALPHA_LINKAGE
:
1324 case BFD_RELOC_ALPHA_CODEADDR
:
1328 case BFD_RELOC_ALPHA_LITUSE
:
1331 case BFD_RELOC_GPREL32
:
1332 case BFD_RELOC_23_PCREL_S2
:
1335 case BFD_RELOC_ALPHA_HINT
:
1339 assert ((int)f
->fx_r_type
< 0
1340 && - (int)f
->fx_r_type
< alpha_num_operands
);
1346 /* Generate the BFD reloc to be stuck in the object file from the
1347 fixup used internally in the assembler. */
1350 tc_gen_reloc (sec
, fixp
)
1356 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
1357 reloc
->sym_ptr_ptr
= &fixp
->fx_addsy
->bsym
;
1358 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
1360 /* Make sure none of our internal relocations make it this far.
1361 They'd better have been fully resolved by this point. */
1362 assert ((int)fixp
->fx_r_type
> 0);
1364 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
1365 if (reloc
->howto
== NULL
)
1367 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1368 "cannot represent `%s' relocation in object file",
1369 bfd_get_reloc_code_name (fixp
->fx_r_type
));
1373 if (!fixp
->fx_pcrel
!= !reloc
->howto
->pc_relative
)
1375 as_fatal ("internal error? cannot generate `%s' relocation",
1376 bfd_get_reloc_code_name (fixp
->fx_r_type
));
1378 assert (!fixp
->fx_pcrel
== !reloc
->howto
->pc_relative
);
1381 if (fixp
->fx_r_type
== BFD_RELOC_ALPHA_LITERAL
)
1383 /* fake out bfd_perform_relocation. sigh */
1384 reloc
->addend
= -alpha_gp_value
;
1389 reloc
->addend
= fixp
->fx_offset
;
1392 * Ohhh, this is ugly. The problem is that if this is a local global
1393 * symbol, the relocation will entirely be performed at link time, not
1394 * at assembly time. bfd_perform_reloc doesn't know about this sort
1395 * of thing, and as a result we need to fake it out here.
1397 if (S_IS_EXTERN (fixp
->fx_addsy
) && !S_IS_COMMON(fixp
->fx_addsy
))
1398 reloc
->addend
-= fixp
->fx_addsy
->bsym
->value
;
1405 /* Parse a register name off of the input_line and return a register
1406 number. Gets md_undefined_symbol above to do the register name
1409 Only called as a part of processing the ECOFF .frame directive. */
1412 tc_get_register (frame
)
1415 int framereg
= AXP_REG_SP
;
1418 if (*input_line_pointer
== '$')
1420 char *s
= input_line_pointer
;
1421 char c
= get_symbol_end ();
1422 symbolS
*sym
= md_undefined_symbol (s
);
1424 *strchr(s
, '\0') = c
;
1425 if (sym
&& (framereg
= S_GET_VALUE (sym
)) <= 31)
1428 as_warn ("frame reg expected, using $%d.", framereg
);
1431 note_gpreg (framereg
);
1435 /* This is called before the symbol table is processed. In order to
1436 work with gcc when using mips-tfile, we must keep all local labels.
1437 However, in other cases, we want to discard them. If we were
1438 called with -g, but we didn't see any debugging information, it may
1439 mean that gcc is smuggling debugging information through to
1440 mips-tfile, in which case we must generate all local labels. */
1445 alpha_frob_file_before_adjust ()
1447 if (alpha_debug
!= 0
1448 && ! ecoff_debugging_seen
)
1449 flag_keep_locals
= 1;
1452 #endif /* OBJ_ECOFF */
1454 /* Parse the arguments to an opcode. */
1457 tokenize_arguments (str
, tok
, ntok
)
1462 expressionS
*end_tok
= tok
+ ntok
;
1463 char *old_input_line_pointer
;
1464 int saw_comma
= 0, saw_arg
= 0;
1466 memset (tok
, 0, sizeof (*tok
) * ntok
);
1468 /* Save and restore input_line_pointer around this function */
1469 old_input_line_pointer
= input_line_pointer
;
1470 input_line_pointer
= str
;
1472 while (tok
< end_tok
&& *input_line_pointer
)
1475 switch (*input_line_pointer
)
1481 ++input_line_pointer
;
1482 if (saw_comma
|| !saw_arg
)
1489 char *hold
= input_line_pointer
++;
1491 /* First try for parenthesized register ... */
1493 if (*input_line_pointer
== ')' && tok
->X_op
== O_register
)
1495 tok
->X_op
= (saw_comma
? O_cpregister
: O_pregister
);
1498 ++input_line_pointer
;
1503 /* ... then fall through to plain expression */
1504 input_line_pointer
= hold
;
1508 if (saw_arg
&& !saw_comma
)
1511 if (tok
->X_op
== O_illegal
|| tok
->X_op
== O_absent
)
1524 input_line_pointer
= old_input_line_pointer
;
1525 return ntok
- (end_tok
- tok
);
1528 input_line_pointer
= old_input_line_pointer
;
1532 /* Search forward through all variants of an opcode looking for a
1535 static const struct alpha_opcode
*
1536 find_opcode_match(first_opcode
, tok
, pntok
, pcpumatch
)
1537 const struct alpha_opcode
*first_opcode
;
1538 const expressionS
*tok
;
1542 const struct alpha_opcode
*opcode
= first_opcode
;
1544 int got_cpu_match
= 0;
1548 const unsigned char *opidx
;
1551 /* Don't match opcodes that don't exist on this architecture */
1552 if (!(opcode
->flags
& alpha_target
))
1557 for (opidx
= opcode
->operands
; *opidx
; ++opidx
)
1559 const struct alpha_operand
*operand
= &alpha_operands
[*opidx
];
1561 /* only take input from real operands */
1562 if (operand
->flags
& AXP_OPERAND_FAKE
)
1565 /* when we expect input, make sure we have it */
1568 if ((operand
->flags
& AXP_OPERAND_OPTIONAL_MASK
) == 0)
1573 /* match operand type with expression type */
1574 switch (operand
->flags
& AXP_OPERAND_TYPECHECK_MASK
)
1576 case AXP_OPERAND_IR
:
1577 if (tok
[tokidx
].X_op
!= O_register
1578 || !is_ir_num(tok
[tokidx
].X_add_number
))
1581 case AXP_OPERAND_FPR
:
1582 if (tok
[tokidx
].X_op
!= O_register
1583 || !is_fpr_num(tok
[tokidx
].X_add_number
))
1586 case AXP_OPERAND_IR
|AXP_OPERAND_PARENS
:
1587 if (tok
[tokidx
].X_op
!= O_pregister
1588 || !is_ir_num(tok
[tokidx
].X_add_number
))
1591 case AXP_OPERAND_IR
|AXP_OPERAND_PARENS
|AXP_OPERAND_COMMA
:
1592 if (tok
[tokidx
].X_op
!= O_cpregister
1593 || !is_ir_num(tok
[tokidx
].X_add_number
))
1597 case AXP_OPERAND_RELATIVE
:
1598 case AXP_OPERAND_SIGNED
:
1599 case AXP_OPERAND_UNSIGNED
:
1600 switch (tok
[tokidx
].X_op
)
1612 /* everything else should have been fake */
1618 /* possible match -- did we use all of our input? */
1627 while (++opcode
-alpha_opcodes
< alpha_num_opcodes
1628 && !strcmp(opcode
->name
, first_opcode
->name
));
1631 *pcpumatch
= got_cpu_match
;
1636 /* Search forward through all variants of a macro looking for a syntax
1639 static const struct alpha_macro
*
1640 find_macro_match(first_macro
, tok
, pntok
)
1641 const struct alpha_macro
*first_macro
;
1642 const expressionS
*tok
;
1645 const struct alpha_macro
*macro
= first_macro
;
1650 const enum alpha_macro_arg
*arg
= macro
->argsets
;
1665 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_register
1666 || !is_ir_num(tok
[tokidx
].X_add_number
))
1671 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_pregister
1672 || !is_ir_num(tok
[tokidx
].X_add_number
))
1677 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_cpregister
1678 || !is_ir_num(tok
[tokidx
].X_add_number
))
1683 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_register
1684 || !is_fpr_num(tok
[tokidx
].X_add_number
))
1692 switch (tok
[tokidx
].X_op
)
1705 while (*arg
!= MACRO_EOA
)
1713 while (++macro
-alpha_macros
< alpha_num_macros
1714 && !strcmp(macro
->name
, first_macro
->name
));
1719 /* Insert an operand value into an instruction. */
1722 insert_operand(insn
, operand
, val
, file
, line
)
1724 const struct alpha_operand
*operand
;
1729 if (operand
->bits
!= 32 && !(operand
->flags
& AXP_OPERAND_NOOVERFLOW
))
1733 if (operand
->flags
& AXP_OPERAND_SIGNED
)
1735 max
= (1 << (operand
->bits
- 1)) - 1;
1736 min
= -(1 << (operand
->bits
- 1));
1740 max
= (1 << operand
->bits
) - 1;
1744 if (val
< min
|| val
> max
)
1747 "operand out of range (%s not between %d and %d)";
1748 char buf
[sizeof (val
) * 3 + 2];
1750 sprint_value(buf
, val
);
1752 as_warn_where(file
, line
, err
, buf
, min
, max
);
1754 as_warn(err
, buf
, min
, max
);
1758 if (operand
->insert
)
1760 const char *errmsg
= NULL
;
1762 insn
= (*operand
->insert
) (insn
, val
, &errmsg
);
1767 insn
|= ((val
& ((1 << operand
->bits
) - 1)) << operand
->shift
);
1773 * Turn an opcode description and a set of arguments into
1774 * an instruction and a fixup.
1778 assemble_insn(opcode
, tok
, ntok
, insn
)
1779 const struct alpha_opcode
*opcode
;
1780 const expressionS
*tok
;
1782 struct alpha_insn
*insn
;
1784 const unsigned char *argidx
;
1788 memset (insn
, 0, sizeof (*insn
));
1789 image
= opcode
->opcode
;
1791 for (argidx
= opcode
->operands
; *argidx
; ++argidx
)
1793 const struct alpha_operand
*operand
= &alpha_operands
[*argidx
];
1794 const expressionS
*t
;
1796 if (operand
->flags
& AXP_OPERAND_FAKE
)
1798 /* fake operands take no value and generate no fixup */
1799 image
= insert_operand(image
, operand
, 0, NULL
, 0);
1805 switch (operand
->flags
& AXP_OPERAND_OPTIONAL_MASK
)
1807 case AXP_OPERAND_DEFAULT_FIRST
:
1810 case AXP_OPERAND_DEFAULT_SECOND
:
1813 case AXP_OPERAND_DEFAULT_ZERO
:
1815 static const expressionS zero_exp
= { 0, 0, 0, O_constant
, 1 };
1831 image
= insert_operand(image
, operand
, regno(t
->X_add_number
),
1836 image
= insert_operand(image
, operand
, t
->X_add_number
, NULL
, 0);
1841 struct alpha_fixup
*fixup
;
1843 if (insn
->nfixups
>= MAX_INSN_FIXUPS
)
1844 as_fatal("too many fixups");
1846 fixup
= &insn
->fixups
[insn
->nfixups
++];
1849 fixup
->reloc
= operand
->default_reloc
;
1859 * Actually output an instruction with its fixup.
1864 struct alpha_insn
*insn
;
1869 /* Take care of alignment duties */
1870 if (alpha_auto_align_on
&& alpha_current_align
< 2)
1871 alpha_align (2, (char *) NULL
, alpha_insn_label
);
1872 if (alpha_current_align
> 2)
1873 alpha_current_align
= 2;
1874 alpha_insn_label
= NULL
;
1876 /* Write out the instruction. */
1878 md_number_to_chars (f
, insn
->insn
, 4);
1880 /* Apply the fixups in order */
1881 for (i
= 0; i
< insn
->nfixups
; ++i
)
1883 struct alpha_fixup
*fixup
= &insn
->fixups
[i
];
1887 /* Some fixups are only used internally and so have no howto */
1888 if ((int)fixup
->reloc
< 0)
1889 size
= 4, pcrel
= 0;
1891 /* These relocation types are only used internally. */
1892 else if (fixup
->reloc
== BFD_RELOC_ALPHA_GPDISP_HI16
1893 || fixup
->reloc
== BFD_RELOC_ALPHA_GPDISP_LO16
)
1895 size
= 2, pcrel
= 0;
1900 reloc_howto_type
*reloc_howto
1901 = bfd_reloc_type_lookup (stdoutput
, fixup
->reloc
);
1902 assert (reloc_howto
);
1904 size
= bfd_get_reloc_size (reloc_howto
);
1905 pcrel
= reloc_howto
->pc_relative
;
1907 assert (size
>= 1 && size
<= 4);
1909 fixP
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, size
,
1910 &fixup
->exp
, pcrel
, fixup
->reloc
);
1912 /* Turn off complaints that the addend is too large for some fixups */
1913 switch (fixup
->reloc
)
1915 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1917 case BFD_RELOC_ALPHA_LITERAL
:
1920 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1922 case BFD_RELOC_GPREL32
:
1923 fixP
->fx_no_overflow
= 1;
1931 /* Given an opcode name and a pre-tokenized set of arguments, assemble
1932 the insn, but do not emit it.
1934 Note that this implies no macros allowed, since we can't store more
1935 than one insn in an insn structure. */
1938 assemble_tokens_to_insn(opname
, tok
, ntok
, insn
)
1940 const expressionS
*tok
;
1942 struct alpha_insn
*insn
;
1944 const struct alpha_opcode
*opcode
;
1946 /* search opcodes */
1947 opcode
= (const struct alpha_opcode
*) hash_find (alpha_opcode_hash
, opname
);
1951 opcode
= find_opcode_match (opcode
, tok
, &ntok
, &cpumatch
);
1954 assemble_insn (opcode
, tok
, ntok
, insn
);
1958 as_bad ("inappropriate arguments for opcode `%s'", opname
);
1960 as_bad ("opcode `%s' not supported for target %s", opname
,
1964 as_bad ("unknown opcode `%s'", opname
);
1967 /* Given an opcode name and a pre-tokenized set of arguments, take the
1968 opcode all the way through emission. */
1971 assemble_tokens (opname
, tok
, ntok
, local_macros_on
)
1973 const expressionS
*tok
;
1975 int local_macros_on
;
1977 int found_something
= 0;
1978 const struct alpha_opcode
*opcode
;
1979 const struct alpha_macro
*macro
;
1983 if (local_macros_on
)
1985 macro
= ((const struct alpha_macro
*)
1986 hash_find (alpha_macro_hash
, opname
));
1989 found_something
= 1;
1990 macro
= find_macro_match (macro
, tok
, &ntok
);
1993 (*macro
->emit
) (tok
, ntok
, macro
->arg
);
1999 /* search opcodes */
2000 opcode
= (const struct alpha_opcode
*) hash_find (alpha_opcode_hash
, opname
);
2003 found_something
= 1;
2004 opcode
= find_opcode_match (opcode
, tok
, &ntok
, &cpumatch
);
2007 struct alpha_insn insn
;
2008 assemble_insn (opcode
, tok
, ntok
, &insn
);
2014 if (found_something
)
2016 as_bad ("inappropriate arguments for opcode `%s'", opname
);
2018 as_bad ("opcode `%s' not supported for target %s", opname
,
2021 as_bad ("unknown opcode `%s'", opname
);
2025 /* Some instruction sets indexed by lg(size) */
2026 static const char * const sextX_op
[] = { "sextb", "sextw", "sextl", NULL
};
2027 static const char * const insXl_op
[] = { "insbl", "inswl", "insll", "insql" };
2028 static const char * const insXh_op
[] = { NULL
, "inswh", "inslh", "insqh" };
2029 static const char * const extXl_op
[] = { "extbl", "extwl", "extll", "extql" };
2030 static const char * const extXh_op
[] = { NULL
, "extwh", "extlh", "extqh" };
2031 static const char * const mskXl_op
[] = { "mskbl", "mskwl", "mskll", "mskql" };
2032 static const char * const mskXh_op
[] = { NULL
, "mskwh", "msklh", "mskqh" };
2033 static const char * const stX_op
[] = { "stb", "stw", "stl", "stq" };
2034 static const char * const ldX_op
[] = { "ldb", "ldw", "ldll", "ldq" };
2035 static const char * const ldXu_op
[] = { "ldbu", "ldwu", NULL
, NULL
};
2037 /* Implement the ldgp macro. */
2040 emit_ldgp (tok
, ntok
, unused
)
2041 const expressionS
*tok
;
2048 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
2049 /* from "ldgp r1,n(r2)", generate "ldah r1,X(R2); lda r1,Y(r1)"
2050 with appropriate constants and relocations. */
2051 struct alpha_insn insn
;
2052 expressionS newtok
[3];
2055 /* We're going to need this symbol in md_apply_fix(). */
2056 (void) section_symbol (absolute_section
);
2059 if (regno (tok
[2].X_add_number
) == AXP_REG_PV
)
2060 ecoff_set_gp_prolog_size (0);
2064 set_tok_const (newtok
[1], 0);
2067 assemble_tokens_to_insn ("ldah", newtok
, 3, &insn
);
2072 assert (addend
.X_op
== O_constant
);
2073 addend
.X_op
= O_symbol
;
2074 addend
.X_add_symbol
= alpha_gp_symbol
;
2078 insn
.fixups
[0].exp
= addend
;
2079 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_GPDISP_HI16
;
2083 set_tok_preg (newtok
[2], tok
[0].X_add_number
);
2085 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
2088 addend
.X_add_number
+= 4;
2092 insn
.fixups
[0].exp
= addend
;
2093 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_GPDISP_LO16
;
2096 #endif /* OBJ_ECOFF || OBJ_ELF */
2101 /* Add symbol+addend to link pool.
2102 Return offset from basesym to entry in link pool.
2104 Add new fixup only if offset isn't 16bit. */
2107 add_to_link_pool (basesym
, sym
, addend
)
2112 segT current_section
= now_seg
;
2113 int current_subsec
= now_subseg
;
2115 bfd_reloc_code_real_type reloc_type
;
2117 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
2120 offset
= -basesym
->sy_obj
;
2122 /* @@ This assumes all entries in a given section will be of the same
2123 size... Probably correct, but unwise to rely on. */
2124 /* This must always be called with the same subsegment. */
2126 if (seginfo
->frchainP
)
2127 for (fixp
= seginfo
->frchainP
->fix_root
;
2128 fixp
!= (fixS
*) NULL
;
2129 fixp
= fixp
->fx_next
, offset
+= 8)
2131 if (fixp
->fx_addsy
== sym
&& fixp
->fx_offset
== addend
)
2133 if (range_signed_16 (offset
))
2140 /* Not found in 16bit signed range. */
2142 subseg_set (alpha_link_section
, 0);
2146 fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, sym
, addend
, 0,
2149 subseg_set (current_section
, current_subsec
);
2150 seginfo
->literal_pool_size
+= 8;
2154 #endif /* OBJ_EVAX */
2156 /* Load a (partial) expression into a target register.
2158 If poffset is not null, after the call it will either contain
2159 O_constant 0, or a 16-bit offset appropriate for any MEM format
2160 instruction. In addition, pbasereg will be modified to point to
2161 the base register to use in that MEM format instruction.
2163 In any case, *pbasereg should contain a base register to add to the
2164 expression. This will normally be either AXP_REG_ZERO or
2165 alpha_gp_register. Symbol addresses will always be loaded via $gp,
2166 so "foo($0)" is interpreted as adding the address of foo to $0;
2167 i.e. "ldq $targ, LIT($gp); addq $targ, $0, $targ". Odd, perhaps,
2168 but this is what OSF/1 does.
2170 Finally, the return value is true if the calling macro may emit a
2171 LITUSE reloc if otherwise appropriate. */
2174 load_expression (targreg
, exp
, pbasereg
, poffset
)
2176 const expressionS
*exp
;
2178 expressionS
*poffset
;
2180 int emit_lituse
= 0;
2181 offsetT addend
= exp
->X_add_number
;
2182 int basereg
= *pbasereg
;
2183 struct alpha_insn insn
;
2184 expressionS newtok
[3];
2193 /* attempt to reduce .lit load by splitting the offset from
2194 its symbol when possible, but don't create a situation in
2196 if (!range_signed_32 (addend
) &&
2197 (alpha_noat_on
|| targreg
== AXP_REG_AT
))
2199 lit
= add_to_literal_pool (exp
->X_add_symbol
, addend
,
2200 alpha_lita_section
, 8);
2205 lit
= add_to_literal_pool (exp
->X_add_symbol
, 0,
2206 alpha_lita_section
, 8);
2210 as_fatal ("overflow in literal (.lita) table");
2212 /* emit "ldq r, lit(gp)" */
2214 if (basereg
!= alpha_gp_register
&& targreg
== basereg
)
2217 as_bad ("macro requires $at register while noat in effect");
2218 if (targreg
== AXP_REG_AT
)
2219 as_bad ("macro requires $at while $at in use");
2221 set_tok_reg (newtok
[0], AXP_REG_AT
);
2224 set_tok_reg (newtok
[0], targreg
);
2225 set_tok_sym (newtok
[1], alpha_lita_symbol
, lit
);
2226 set_tok_preg (newtok
[2], alpha_gp_register
);
2228 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
2230 assert (insn
.nfixups
== 1);
2231 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITERAL
;
2232 #endif /* OBJ_ECOFF */
2234 /* emit "ldq r, gotoff(gp)" */
2236 if (basereg
!= alpha_gp_register
&& targreg
== basereg
)
2239 as_bad ("macro requires $at register while noat in effect");
2240 if (targreg
== AXP_REG_AT
)
2241 as_bad ("macro requires $at while $at in use");
2243 set_tok_reg (newtok
[0], AXP_REG_AT
);
2246 set_tok_reg (newtok
[0], targreg
);
2248 /* XXX: Disable this .got minimizing optimization so that we can get
2249 better instruction offset knowledge in the compiler. This happens
2250 very infrequently anyway. */
2251 if (1 || !range_signed_32 (addend
)
2252 && (alpha_noat_on
|| targreg
== AXP_REG_AT
))
2259 set_tok_sym (newtok
[1], exp
->X_add_symbol
, 0);
2262 set_tok_preg (newtok
[2], alpha_gp_register
);
2264 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
2266 assert (insn
.nfixups
== 1);
2267 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_ELF_LITERAL
;
2268 #endif /* OBJ_ELF */
2272 if (alpha_basereg_clobbered
)
2274 /* no basereg, reload basreg from 0(FP). */
2275 set_tok_reg (newtok
[0], targreg
);
2276 set_tok_const (newtok
[1], 0);
2277 set_tok_preg (newtok
[2], AXP_REG_FP
);
2279 assemble_tokens ("ldq", newtok
, 3, 0);
2282 /* Find symbol or symbol pointer in link section. */
2284 if (exp
->X_add_symbol
== alpha_evax_proc
.symbol
)
2286 if (range_signed_16 (addend
))
2288 set_tok_reg (newtok
[0], targreg
);
2289 set_tok_const (newtok
[1], addend
);
2290 set_tok_preg (newtok
[2], basereg
);
2291 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
2296 set_tok_reg (newtok
[0], targreg
);
2297 set_tok_const (newtok
[1], 0);
2298 set_tok_preg (newtok
[2], basereg
);
2299 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
2304 if (!range_signed_32 (addend
))
2306 link
= add_to_link_pool (alpha_evax_proc
.symbol
,
2307 exp
->X_add_symbol
, addend
);
2312 link
= add_to_link_pool (alpha_evax_proc
.symbol
,
2313 exp
->X_add_symbol
, 0);
2315 set_tok_reg (newtok
[0], targreg
);
2316 set_tok_const (newtok
[1], link
);
2317 set_tok_preg (newtok
[2], basereg
);
2318 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
2320 #endif /* OBJ_EVAX */
2327 if (basereg
!= alpha_gp_register
&& basereg
!= AXP_REG_ZERO
)
2329 /* emit "addq r, base, r" */
2331 set_tok_reg (newtok
[1], basereg
);
2332 set_tok_reg (newtok
[2], targreg
);
2333 assemble_tokens ("addq", newtok
, 3, 0);
2345 /* Assume that this difference expression will be resolved to an
2346 absolute value and that that value will fit in 16 bits. */
2348 set_tok_reg (newtok
[0], targreg
);
2350 set_tok_preg (newtok
[2], basereg
);
2351 assemble_tokens ("lda", newtok
, 3, 0);
2354 set_tok_const (*poffset
, 0);
2358 as_bad ("%s number invalid; zero assumed",
2359 exp
->X_add_number
> 0 ? "bignum" : "floating point");
2367 if (!range_signed_32 (addend
))
2371 /* for 64-bit addends, just put it in the literal pool */
2374 /* emit "ldq targreg, lit(basereg)" */
2375 lit
= add_to_link_pool (alpha_evax_proc
.symbol
,
2376 section_symbol (absolute_section
), addend
);
2377 set_tok_reg (newtok
[0], targreg
);
2378 set_tok_const (newtok
[1], lit
);
2379 set_tok_preg (newtok
[2], alpha_gp_register
);
2380 assemble_tokens ("ldq", newtok
, 3, 0);
2383 if (alpha_lit8_section
== NULL
)
2385 create_literal_section (".lit8",
2386 &alpha_lit8_section
,
2387 &alpha_lit8_symbol
);
2390 alpha_lit8_literal
= add_to_literal_pool (alpha_lit8_symbol
, 0x8000,
2391 alpha_lita_section
, 8);
2392 if (alpha_lit8_literal
>= 0x8000)
2393 as_fatal ("overflow in literal (.lita) table");
2397 lit
= add_to_literal_pool (NULL
, addend
, alpha_lit8_section
, 8) - 0x8000;
2399 as_fatal ("overflow in literal (.lit8) table");
2401 /* emit "lda litreg, .lit8+0x8000" */
2403 if (targreg
== basereg
)
2406 as_bad ("macro requires $at register while noat in effect");
2407 if (targreg
== AXP_REG_AT
)
2408 as_bad ("macro requires $at while $at in use");
2410 set_tok_reg (newtok
[0], AXP_REG_AT
);
2413 set_tok_reg (newtok
[0], targreg
);
2415 set_tok_sym (newtok
[1], alpha_lita_symbol
, alpha_lit8_literal
);
2418 set_tok_sym (newtok
[1], alpha_lit8_symbol
, 0x8000);
2420 set_tok_preg (newtok
[2], alpha_gp_register
);
2422 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
2424 assert (insn
.nfixups
== 1);
2426 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITERAL
;
2429 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_ELF_LITERAL
;
2434 /* emit "ldq litreg, lit(litreg)" */
2436 set_tok_const (newtok
[1], lit
);
2437 set_tok_preg (newtok
[2], newtok
[0].X_add_number
);
2439 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
2441 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
2442 if (insn
.nfixups
> 0)
2444 memmove (&insn
.fixups
[1], &insn
.fixups
[0],
2445 sizeof(struct alpha_fixup
) * insn
.nfixups
);
2448 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITUSE
;
2449 insn
.fixups
[0].exp
.X_op
= O_constant
;
2450 insn
.fixups
[0].exp
.X_add_number
= 1;
2455 /* emit "addq litreg, base, target" */
2457 if (basereg
!= AXP_REG_ZERO
)
2459 set_tok_reg (newtok
[1], basereg
);
2460 set_tok_reg (newtok
[2], targreg
);
2461 assemble_tokens ("addq", newtok
, 3, 0);
2463 #endif /* !OBJ_EVAX */
2466 set_tok_const (*poffset
, 0);
2467 *pbasereg
= targreg
;
2471 offsetT low
, high
, extra
, tmp
;
2473 /* for 32-bit operands, break up the addend */
2475 low
= sign_extend_16 (addend
);
2477 high
= sign_extend_16 (tmp
>> 16);
2479 if (tmp
- (high
<< 16))
2483 high
= sign_extend_16 (tmp
>> 16);
2488 set_tok_reg (newtok
[0], targreg
);
2489 set_tok_preg (newtok
[2], basereg
);
2493 /* emit "ldah r, extra(r) */
2494 set_tok_const (newtok
[1], extra
);
2495 assemble_tokens ("ldah", newtok
, 3, 0);
2496 set_tok_preg (newtok
[2], basereg
= targreg
);
2501 /* emit "ldah r, high(r) */
2502 set_tok_const (newtok
[1], high
);
2503 assemble_tokens ("ldah", newtok
, 3, 0);
2505 set_tok_preg (newtok
[2], basereg
);
2508 if ((low
&& !poffset
) || (!poffset
&& basereg
!= targreg
))
2510 /* emit "lda r, low(base)" */
2511 set_tok_const (newtok
[1], low
);
2512 assemble_tokens ("lda", newtok
, 3, 0);
2518 set_tok_const (*poffset
, low
);
2519 *pbasereg
= basereg
;
2525 /* The lda macro differs from the lda instruction in that it handles
2526 most simple expressions, particualrly symbol address loads and
2530 emit_lda (tok
, ntok
, unused
)
2531 const expressionS
*tok
;
2538 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
2540 basereg
= tok
[2].X_add_number
;
2542 (void) load_expression (tok
[0].X_add_number
, &tok
[1], &basereg
, NULL
);
2545 /* The ldah macro differs from the ldah instruction in that it has $31
2546 as an implied base register. */
2549 emit_ldah (tok
, ntok
, unused
)
2550 const expressionS
*tok
;
2554 expressionS newtok
[3];
2558 set_tok_preg (newtok
[2], AXP_REG_ZERO
);
2560 assemble_tokens ("ldah", newtok
, 3, 0);
2563 /* Handle all "simple" integer register loads -- ldq, ldq_l, ldq_u,
2564 etc. They differ from the real instructions in that they do simple
2565 expressions like the lda macro. */
2568 emit_ir_load (tok
, ntok
, opname
)
2569 const expressionS
*tok
;
2573 int basereg
, lituse
;
2574 expressionS newtok
[3];
2575 struct alpha_insn insn
;
2578 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
2580 basereg
= tok
[2].X_add_number
;
2582 lituse
= load_expression (tok
[0].X_add_number
, &tok
[1], &basereg
,
2586 set_tok_preg (newtok
[2], basereg
);
2588 assemble_tokens_to_insn ((const char *)opname
, newtok
, 3, &insn
);
2592 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
2593 if (insn
.nfixups
> 0)
2595 memmove (&insn
.fixups
[1], &insn
.fixups
[0],
2596 sizeof(struct alpha_fixup
) * insn
.nfixups
);
2599 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITUSE
;
2600 insn
.fixups
[0].exp
.X_op
= O_constant
;
2601 insn
.fixups
[0].exp
.X_add_number
= 1;
2606 /* special hack. If the basereg is clobbered for a call
2607 all lda's before the call don't have a basereg. */
2608 if ((tok
[0].X_op
== O_register
)
2609 && (tok
[0].X_add_number
== alpha_gp_register
))
2611 alpha_basereg_clobbered
= 1;
2616 /* Handle fp register loads, and both integer and fp register stores.
2617 Again, we handle simple expressions. */
2620 emit_loadstore (tok
, ntok
, opname
)
2621 const expressionS
*tok
;
2625 int basereg
, lituse
;
2626 expressionS newtok
[3];
2627 struct alpha_insn insn
;
2630 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
2632 basereg
= tok
[2].X_add_number
;
2634 if (tok
[1].X_op
!= O_constant
|| !range_signed_16(tok
[1].X_add_number
))
2637 as_bad ("macro requires $at register while noat in effect");
2639 lituse
= load_expression (AXP_REG_AT
, &tok
[1], &basereg
, &newtok
[1]);
2648 set_tok_preg (newtok
[2], basereg
);
2650 assemble_tokens_to_insn ((const char *)opname
, newtok
, 3, &insn
);
2654 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
2655 if (insn
.nfixups
> 0)
2657 memmove (&insn
.fixups
[1], &insn
.fixups
[0],
2658 sizeof(struct alpha_fixup
) * insn
.nfixups
);
2661 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITUSE
;
2662 insn
.fixups
[0].exp
.X_op
= O_constant
;
2663 insn
.fixups
[0].exp
.X_add_number
= 1;
2669 /* Load a half-word or byte as an unsigned value. */
2672 emit_ldXu (tok
, ntok
, vlgsize
)
2673 const expressionS
*tok
;
2677 if (alpha_target
& AXP_OPCODE_BWX
)
2678 emit_ir_load (tok
, ntok
, ldXu_op
[(long)vlgsize
]);
2681 expressionS newtok
[3];
2684 as_bad ("macro requires $at register while noat in effect");
2686 /* emit "lda $at, exp" */
2688 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
2689 newtok
[0].X_add_number
= AXP_REG_AT
;
2690 assemble_tokens ("lda", newtok
, ntok
, 1);
2692 /* emit "ldq_u targ, 0($at)" */
2695 set_tok_const (newtok
[1], 0);
2696 set_tok_preg (newtok
[2], AXP_REG_AT
);
2697 assemble_tokens ("ldq_u", newtok
, 3, 1);
2699 /* emit "extXl targ, $at, targ" */
2701 set_tok_reg (newtok
[1], AXP_REG_AT
);
2702 newtok
[2] = newtok
[0];
2703 assemble_tokens (extXl_op
[(long)vlgsize
], newtok
, 3, 1);
2707 /* Load a half-word or byte as a signed value. */
2710 emit_ldX (tok
, ntok
, vlgsize
)
2711 const expressionS
*tok
;
2715 emit_ldXu (tok
, ntok
, vlgsize
);
2716 assemble_tokens (sextX_op
[(long)vlgsize
], tok
, 1, 1);
2719 /* Load an integral value from an unaligned address as an unsigned
2723 emit_uldXu (tok
, ntok
, vlgsize
)
2724 const expressionS
*tok
;
2728 long lgsize
= (long)vlgsize
;
2729 expressionS newtok
[3];
2732 as_bad ("macro requires $at register while noat in effect");
2734 /* emit "lda $at, exp" */
2736 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
2737 newtok
[0].X_add_number
= AXP_REG_AT
;
2738 assemble_tokens ("lda", newtok
, ntok
, 1);
2740 /* emit "ldq_u $t9, 0($at)" */
2742 set_tok_reg (newtok
[0], AXP_REG_T9
);
2743 set_tok_const (newtok
[1], 0);
2744 set_tok_preg (newtok
[2], AXP_REG_AT
);
2745 assemble_tokens ("ldq_u", newtok
, 3, 1);
2747 /* emit "ldq_u $t10, size-1($at)" */
2749 set_tok_reg (newtok
[0], AXP_REG_T10
);
2750 set_tok_const (newtok
[1], (1<<lgsize
)-1);
2751 assemble_tokens ("ldq_u", newtok
, 3, 1);
2753 /* emit "extXl $t9, $at, $t9" */
2755 set_tok_reg (newtok
[0], AXP_REG_T9
);
2756 set_tok_reg (newtok
[1], AXP_REG_AT
);
2757 set_tok_reg (newtok
[2], AXP_REG_T9
);
2758 assemble_tokens (extXl_op
[lgsize
], newtok
, 3, 1);
2760 /* emit "extXh $t10, $at, $t10" */
2762 set_tok_reg (newtok
[0], AXP_REG_T10
);
2763 set_tok_reg (newtok
[2], AXP_REG_T10
);
2764 assemble_tokens (extXh_op
[lgsize
], newtok
, 3, 1);
2766 /* emit "or $t9, $t10, targ" */
2768 set_tok_reg (newtok
[0], AXP_REG_T9
);
2769 set_tok_reg (newtok
[1], AXP_REG_T10
);
2771 assemble_tokens ("or", newtok
, 3, 1);
2774 /* Load an integral value from an unaligned address as a signed value.
2775 Note that quads should get funneled to the unsigned load since we
2776 don't have to do the sign extension. */
2779 emit_uldX (tok
, ntok
, vlgsize
)
2780 const expressionS
*tok
;
2784 emit_uldXu (tok
, ntok
, vlgsize
);
2785 assemble_tokens (sextX_op
[(long)vlgsize
], tok
, 1, 1);
2788 /* Implement the ldil macro. */
2791 emit_ldil (tok
, ntok
, unused
)
2792 const expressionS
*tok
;
2796 expressionS newtok
[2];
2798 memcpy (newtok
, tok
, sizeof(newtok
));
2799 newtok
[1].X_add_number
= sign_extend_32 (tok
[1].X_add_number
);
2801 assemble_tokens ("lda", newtok
, ntok
, 1);
2804 /* Store a half-word or byte. */
2807 emit_stX (tok
, ntok
, vlgsize
)
2808 const expressionS
*tok
;
2812 int lgsize
= (int)(long)vlgsize
;
2814 if (alpha_target
& AXP_OPCODE_BWX
)
2815 emit_loadstore (tok
, ntok
, stX_op
[lgsize
]);
2818 expressionS newtok
[3];
2821 as_bad("macro requires $at register while noat in effect");
2823 /* emit "lda $at, exp" */
2825 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
2826 newtok
[0].X_add_number
= AXP_REG_AT
;
2827 assemble_tokens ("lda", newtok
, ntok
, 1);
2829 /* emit "ldq_u $t9, 0($at)" */
2831 set_tok_reg (newtok
[0], AXP_REG_T9
);
2832 set_tok_const (newtok
[1], 0);
2833 set_tok_preg (newtok
[2], AXP_REG_AT
);
2834 assemble_tokens ("ldq_u", newtok
, 3, 1);
2836 /* emit "insXl src, $at, $t10" */
2839 set_tok_reg (newtok
[1], AXP_REG_AT
);
2840 set_tok_reg (newtok
[2], AXP_REG_T10
);
2841 assemble_tokens (insXl_op
[lgsize
], newtok
, 3, 1);
2843 /* emit "mskXl $t9, $at, $t9" */
2845 set_tok_reg (newtok
[0], AXP_REG_T9
);
2846 newtok
[2] = newtok
[0];
2847 assemble_tokens (mskXl_op
[lgsize
], newtok
, 3, 1);
2849 /* emit "or $t9, $t10, $t9" */
2851 set_tok_reg (newtok
[1], AXP_REG_T10
);
2852 assemble_tokens ("or", newtok
, 3, 1);
2854 /* emit "stq_u $t9, 0($at) */
2856 set_tok_const (newtok
[1], 0);
2857 set_tok_preg (newtok
[2], AXP_REG_AT
);
2858 assemble_tokens ("stq_u", newtok
, 3, 1);
2862 /* Store an integer to an unaligned address. */
2865 emit_ustX (tok
, ntok
, vlgsize
)
2866 const expressionS
*tok
;
2870 int lgsize
= (int)(long)vlgsize
;
2871 expressionS newtok
[3];
2873 /* emit "lda $at, exp" */
2875 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
2876 newtok
[0].X_add_number
= AXP_REG_AT
;
2877 assemble_tokens ("lda", newtok
, ntok
, 1);
2879 /* emit "ldq_u $9, 0($at)" */
2881 set_tok_reg (newtok
[0], AXP_REG_T9
);
2882 set_tok_const (newtok
[1], 0);
2883 set_tok_preg (newtok
[2], AXP_REG_AT
);
2884 assemble_tokens ("ldq_u", newtok
, 3, 1);
2886 /* emit "ldq_u $10, size-1($at)" */
2888 set_tok_reg (newtok
[0], AXP_REG_T10
);
2889 set_tok_const (newtok
[1], (1 << lgsize
)-1);
2890 assemble_tokens ("ldq_u", newtok
, 3, 1);
2892 /* emit "insXl src, $at, $t11" */
2895 set_tok_reg (newtok
[1], AXP_REG_AT
);
2896 set_tok_reg (newtok
[2], AXP_REG_T11
);
2897 assemble_tokens (insXl_op
[lgsize
], newtok
, 3, 1);
2899 /* emit "insXh src, $at, $t12" */
2901 set_tok_reg (newtok
[2], AXP_REG_T12
);
2902 assemble_tokens (insXh_op
[lgsize
], newtok
, 3, 1);
2904 /* emit "mskXl $t9, $at, $t9" */
2906 set_tok_reg (newtok
[0], AXP_REG_T9
);
2907 newtok
[2] = newtok
[0];
2908 assemble_tokens (mskXl_op
[lgsize
], newtok
, 3, 1);
2910 /* emit "mskXh $t10, $at, $t10" */
2912 set_tok_reg (newtok
[0], AXP_REG_T10
);
2913 newtok
[2] = newtok
[0];
2914 assemble_tokens (mskXh_op
[lgsize
], newtok
, 3, 1);
2916 /* emit "or $t9, $t11, $t9" */
2918 set_tok_reg (newtok
[0], AXP_REG_T9
);
2919 set_tok_reg (newtok
[1], AXP_REG_T11
);
2920 newtok
[2] = newtok
[0];
2921 assemble_tokens ("or", newtok
, 3, 1);
2923 /* emit "or $t10, $t12, $t10" */
2925 set_tok_reg (newtok
[0], AXP_REG_T10
);
2926 set_tok_reg (newtok
[1], AXP_REG_T12
);
2927 newtok
[2] = newtok
[0];
2928 assemble_tokens ("or", newtok
, 3, 1);
2930 /* emit "stq_u $t9, 0($at)" */
2932 set_tok_reg (newtok
[0], AXP_REG_T9
);
2933 set_tok_const (newtok
[1], 0);
2934 set_tok_preg (newtok
[2], AXP_REG_AT
);
2935 assemble_tokens ("stq_u", newtok
, 3, 1);
2937 /* emit "stq_u $t10, size-1($at)" */
2939 set_tok_reg (newtok
[0], AXP_REG_T10
);
2940 set_tok_const (newtok
[1], (1 << lgsize
)-1);
2941 assemble_tokens ("stq_u", newtok
, 3, 1);
2944 /* Sign extend a half-word or byte. The 32-bit sign extend is
2945 implemented as "addl $31, $r, $t" in the opcode table. */
2948 emit_sextX (tok
, ntok
, vlgsize
)
2949 const expressionS
*tok
;
2953 long lgsize
= (long)vlgsize
;
2955 if (alpha_target
& AXP_OPCODE_BWX
)
2956 assemble_tokens (sextX_op
[lgsize
], tok
, ntok
, 0);
2959 int bitshift
= 64 - 8 * (1 << lgsize
);
2960 expressionS newtok
[3];
2962 /* emit "sll src,bits,dst" */
2965 set_tok_const (newtok
[1], bitshift
);
2966 newtok
[2] = tok
[ntok
- 1];
2967 assemble_tokens ("sll", newtok
, 3, 1);
2969 /* emit "sra dst,bits,dst" */
2971 newtok
[0] = newtok
[2];
2972 assemble_tokens ("sra", newtok
, 3, 1);
2976 /* Implement the division and modulus macros. */
2980 /* Make register usage like in normal procedure call.
2981 Don't clobber PV and RA. */
2984 emit_division (tok
, ntok
, symname
)
2985 const expressionS
*tok
;
2989 /* DIVISION and MODULUS. Yech.
2994 * mov x,R16 # if x != R16
2995 * mov y,R17 # if y != R17
3000 * with appropriate optimizations if R0,R16,R17 are the registers
3001 * specified by the compiler.
3006 expressionS newtok
[3];
3008 xr
= regno (tok
[0].X_add_number
);
3009 yr
= regno (tok
[1].X_add_number
);
3014 rr
= regno (tok
[2].X_add_number
);
3016 /* Move the operands into the right place */
3017 if (yr
== AXP_REG_R16
&& xr
== AXP_REG_R17
)
3019 /* They are in exactly the wrong order -- swap through AT */
3022 as_bad ("macro requires $at register while noat in effect");
3024 set_tok_reg (newtok
[0], AXP_REG_R16
);
3025 set_tok_reg (newtok
[1], AXP_REG_AT
);
3026 assemble_tokens ("mov", newtok
, 2, 1);
3028 set_tok_reg (newtok
[0], AXP_REG_R17
);
3029 set_tok_reg (newtok
[1], AXP_REG_R16
);
3030 assemble_tokens ("mov", newtok
, 2, 1);
3032 set_tok_reg (newtok
[0], AXP_REG_AT
);
3033 set_tok_reg (newtok
[1], AXP_REG_R17
);
3034 assemble_tokens ("mov", newtok
, 2, 1);
3038 if (yr
== AXP_REG_R16
)
3040 set_tok_reg (newtok
[0], AXP_REG_R16
);
3041 set_tok_reg (newtok
[1], AXP_REG_R17
);
3042 assemble_tokens ("mov", newtok
, 2, 1);
3045 if (xr
!= AXP_REG_R16
)
3047 set_tok_reg (newtok
[0], xr
);
3048 set_tok_reg (newtok
[1], AXP_REG_R16
);
3049 assemble_tokens ("mov", newtok
, 2, 1);
3052 if (yr
!= AXP_REG_R16
&& yr
!= AXP_REG_R17
)
3054 set_tok_reg (newtok
[0], yr
);
3055 set_tok_reg (newtok
[1], AXP_REG_R17
);
3056 assemble_tokens ("mov", newtok
, 2, 1);
3060 sym
= symbol_find_or_make ((const char *)symname
);
3062 set_tok_reg (newtok
[0], AXP_REG_AT
);
3063 set_tok_sym (newtok
[1], sym
, 0);
3064 assemble_tokens ("lda", newtok
, 2, 1);
3066 /* Call the division routine */
3067 set_tok_reg (newtok
[0], AXP_REG_AT
);
3068 set_tok_cpreg (newtok
[1], AXP_REG_AT
);
3069 set_tok_const (newtok
[2], 0);
3070 assemble_tokens ("jsr", newtok
, 3, 1);
3072 /* Move the result to the right place */
3073 if (rr
!= AXP_REG_R0
)
3075 set_tok_reg (newtok
[0], AXP_REG_R0
);
3076 set_tok_reg (newtok
[1], rr
);
3077 assemble_tokens ("mov", newtok
, 2, 1);
3081 #else /* !OBJ_EVAX */
3084 emit_division (tok
, ntok
, symname
)
3085 const expressionS
*tok
;
3089 /* DIVISION and MODULUS. Yech.
3099 * with appropriate optimizations if t10,t11,t12 are the registers
3100 * specified by the compiler.
3105 expressionS newtok
[3];
3107 xr
= regno (tok
[0].X_add_number
);
3108 yr
= regno (tok
[1].X_add_number
);
3113 rr
= regno (tok
[2].X_add_number
);
3115 sym
= symbol_find_or_make ((const char *)symname
);
3117 /* Move the operands into the right place */
3118 if (yr
== AXP_REG_T10
&& xr
== AXP_REG_T11
)
3120 /* They are in exactly the wrong order -- swap through AT */
3123 as_bad ("macro requires $at register while noat in effect");
3125 set_tok_reg (newtok
[0], AXP_REG_T10
);
3126 set_tok_reg (newtok
[1], AXP_REG_AT
);
3127 assemble_tokens ("mov", newtok
, 2, 1);
3129 set_tok_reg (newtok
[0], AXP_REG_T11
);
3130 set_tok_reg (newtok
[1], AXP_REG_T10
);
3131 assemble_tokens ("mov", newtok
, 2, 1);
3133 set_tok_reg (newtok
[0], AXP_REG_AT
);
3134 set_tok_reg (newtok
[1], AXP_REG_T11
);
3135 assemble_tokens ("mov", newtok
, 2, 1);
3139 if (yr
== AXP_REG_T10
)
3141 set_tok_reg (newtok
[0], AXP_REG_T10
);
3142 set_tok_reg (newtok
[1], AXP_REG_T11
);
3143 assemble_tokens ("mov", newtok
, 2, 1);
3146 if (xr
!= AXP_REG_T10
)
3148 set_tok_reg (newtok
[0], xr
);
3149 set_tok_reg (newtok
[1], AXP_REG_T10
);
3150 assemble_tokens ("mov", newtok
, 2, 1);
3153 if (yr
!= AXP_REG_T10
&& yr
!= AXP_REG_T11
)
3155 set_tok_reg (newtok
[0], yr
);
3156 set_tok_reg (newtok
[1], AXP_REG_T11
);
3157 assemble_tokens ("mov", newtok
, 2, 1);
3161 /* Call the division routine */
3162 set_tok_reg (newtok
[0], AXP_REG_T9
);
3163 set_tok_sym (newtok
[1], sym
, 0);
3164 assemble_tokens ("jsr", newtok
, 2, 1);
3166 /* Reload the GP register */
3170 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
3171 set_tok_reg (newtok
[0], alpha_gp_register
);
3172 set_tok_const (newtok
[1], 0);
3173 set_tok_preg (newtok
[2], AXP_REG_T9
);
3174 assemble_tokens ("ldgp", newtok
, 3, 1);
3177 /* Move the result to the right place */
3178 if (rr
!= AXP_REG_T12
)
3180 set_tok_reg (newtok
[0], AXP_REG_T12
);
3181 set_tok_reg (newtok
[1], rr
);
3182 assemble_tokens ("mov", newtok
, 2, 1);
3186 #endif /* !OBJ_EVAX */
3188 /* The jsr and jmp macros differ from their instruction counterparts
3189 in that they can load the target address and default most
3193 emit_jsrjmp (tok
, ntok
, vopname
)
3194 const expressionS
*tok
;
3198 const char *opname
= (const char *) vopname
;
3199 struct alpha_insn insn
;
3200 expressionS newtok
[3];
3201 int r
, tokidx
= 0, lituse
= 0;
3203 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_register
)
3204 r
= regno (tok
[tokidx
++].X_add_number
);
3206 r
= strcmp (opname
, "jmp") == 0 ? AXP_REG_ZERO
: AXP_REG_RA
;
3208 set_tok_reg (newtok
[0], r
);
3210 if (tokidx
< ntok
&&
3211 (tok
[tokidx
].X_op
== O_pregister
|| tok
[tokidx
].X_op
== O_cpregister
))
3212 r
= regno (tok
[tokidx
++].X_add_number
);
3214 /* keep register if jsr $n.<sym> */
3218 int basereg
= alpha_gp_register
;
3219 lituse
= load_expression (r
= AXP_REG_PV
, &tok
[tokidx
], &basereg
, NULL
);
3223 set_tok_cpreg (newtok
[1], r
);
3226 /* FIXME: Add hint relocs to BFD for evax. */
3229 newtok
[2] = tok
[tokidx
];
3232 set_tok_const (newtok
[2], 0);
3234 assemble_tokens_to_insn (opname
, newtok
, 3, &insn
);
3236 /* add the LITUSE fixup */
3239 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3240 if (insn
.nfixups
> 0)
3242 memmove (&insn
.fixups
[1], &insn
.fixups
[0],
3243 sizeof(struct alpha_fixup
) * insn
.nfixups
);
3246 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITUSE
;
3247 insn
.fixups
[0].exp
.X_op
= O_constant
;
3248 insn
.fixups
[0].exp
.X_add_number
= 3;
3254 alpha_basereg_clobbered
= 0;
3256 /* reload PV from 0(FP) if it is our current base register. */
3257 if (alpha_gp_register
== AXP_REG_PV
)
3259 set_tok_reg (newtok
[0], AXP_REG_PV
);
3260 set_tok_const (newtok
[1], 0);
3261 set_tok_preg (newtok
[2], AXP_REG_FP
);
3262 assemble_tokens ("ldq", newtok
, 3, 0);
3267 /* The ret and jcr instructions differ from their instruction
3268 counterparts in that everything can be defaulted. */
3271 emit_retjcr (tok
, ntok
, vopname
)
3272 const expressionS
*tok
;
3276 const char *opname
= (const char *)vopname
;
3277 expressionS newtok
[3];
3280 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_register
)
3281 r
= regno (tok
[tokidx
++].X_add_number
);
3285 set_tok_reg (newtok
[0], r
);
3287 if (tokidx
< ntok
&&
3288 (tok
[tokidx
].X_op
== O_pregister
|| tok
[tokidx
].X_op
== O_cpregister
))
3289 r
= regno (tok
[tokidx
++].X_add_number
);
3293 set_tok_cpreg (newtok
[1], r
);
3296 newtok
[2] = tok
[tokidx
];
3298 set_tok_const (newtok
[2], strcmp(opname
, "ret") == 0);
3300 assemble_tokens (opname
, newtok
, 3, 0);
3303 /* Assembler directives */
3305 /* Handle the .text pseudo-op. This is like the usual one, but it
3306 clears alpha_insn_label and restores auto alignment. */
3314 alpha_insn_label
= NULL
;
3315 alpha_auto_align_on
= 1;
3316 alpha_current_align
= 0;
3319 /* Handle the .data pseudo-op. This is like the usual one, but it
3320 clears alpha_insn_label and restores auto alignment. */
3327 alpha_insn_label
= NULL
;
3328 alpha_auto_align_on
= 1;
3329 alpha_current_align
= 0;
3334 /* Handle the OSF/1 .comm pseudo quirks. */
3337 s_alpha_comm (ignore
)
3340 register char *name
;
3344 register symbolS
*symbolP
;
3346 name
= input_line_pointer
;
3347 c
= get_symbol_end ();
3349 /* just after name is now '\0' */
3350 p
= input_line_pointer
;
3355 /* Alpha OSF/1 compiler doesn't provide the comma, gcc does. */
3356 if (*input_line_pointer
== ',')
3358 input_line_pointer
++;
3361 if ((temp
= get_absolute_expression ()) < 0)
3363 as_warn (".COMMon length (%ld.) <0! Ignored.", (long) temp
);
3364 ignore_rest_of_line ();
3369 symbolP
= symbol_find_or_make (name
);
3372 if (S_IS_DEFINED (symbolP
) && ! S_IS_COMMON (symbolP
))
3374 as_bad ("Ignoring attempt to re-define symbol");
3375 ignore_rest_of_line ();
3379 if (S_GET_VALUE (symbolP
))
3381 if (S_GET_VALUE (symbolP
) != (valueT
) temp
)
3382 as_bad ("Length of .comm \"%s\" is already %ld. Not changed to %ld.",
3383 S_GET_NAME (symbolP
),
3384 (long) S_GET_VALUE (symbolP
),
3389 S_SET_VALUE (symbolP
, (valueT
) temp
);
3390 S_SET_EXTERNAL (symbolP
);
3393 know (symbolP
->sy_frag
== &zero_address_frag
);
3395 demand_empty_rest_of_line ();
3398 #endif /* ! OBJ_ELF */
3402 /* Handle the .rdata pseudo-op. This is like the usual one, but it
3403 clears alpha_insn_label and restores auto alignment. */
3406 s_alpha_rdata (ignore
)
3411 temp
= get_absolute_expression ();
3412 subseg_new (".rdata", 0);
3413 demand_empty_rest_of_line ();
3414 alpha_insn_label
= NULL
;
3415 alpha_auto_align_on
= 1;
3416 alpha_current_align
= 0;
3423 /* Handle the .sdata pseudo-op. This is like the usual one, but it
3424 clears alpha_insn_label and restores auto alignment. */
3427 s_alpha_sdata (ignore
)
3432 temp
= get_absolute_expression ();
3433 subseg_new (".sdata", 0);
3434 demand_empty_rest_of_line ();
3435 alpha_insn_label
= NULL
;
3436 alpha_auto_align_on
= 1;
3437 alpha_current_align
= 0;
3443 /* Handle the .section pseudo-op. This is like the usual one, but it
3444 clears alpha_insn_label and restores auto alignment. */
3447 s_alpha_section (ignore
)
3450 obj_elf_section (ignore
);
3452 alpha_insn_label
= NULL
;
3453 alpha_auto_align_on
= 1;
3454 alpha_current_align
= 0;
3461 /* Handle the section specific pseudo-op. */
3464 s_alpha_section (secid
)
3468 #define EVAX_SECTION_COUNT 6
3469 static char *section_name
[EVAX_SECTION_COUNT
+1] =
3470 { "NULL", ".rdata", ".comm", ".link", ".ctors", ".dtors", ".lcomm" };
3472 if ((secid
<= 0) || (secid
> EVAX_SECTION_COUNT
))
3474 as_fatal ("Unknown section directive");
3475 demand_empty_rest_of_line ();
3478 temp
= get_absolute_expression ();
3479 subseg_new (section_name
[secid
], 0);
3480 demand_empty_rest_of_line ();
3481 alpha_insn_label
= NULL
;
3482 alpha_auto_align_on
= 1;
3483 alpha_current_align
= 0;
3490 s_alpha_prologue (ignore
)
3493 alpha_basereg_clobbered
= 0;
3494 demand_empty_rest_of_line ();
3500 /* Parse .ent directives. */
3503 s_alpha_ent (ignore
)
3507 expressionS symexpr
;
3509 alpha_evax_proc
.pdsckind
= 0;
3510 alpha_evax_proc
.framereg
= -1;
3511 alpha_evax_proc
.framesize
= 0;
3512 alpha_evax_proc
.rsa_offset
= 0;
3513 alpha_evax_proc
.ra_save
= AXP_REG_RA
;
3514 alpha_evax_proc
.fp_save
= -1;
3515 alpha_evax_proc
.imask
= 0;
3516 alpha_evax_proc
.fmask
= 0;
3517 alpha_evax_proc
.prologue
= 0;
3518 alpha_evax_proc
.type
= 0;
3520 expression (&symexpr
);
3522 if (symexpr
.X_op
!= O_symbol
)
3524 as_fatal (".ent directive has no symbol");
3525 demand_empty_rest_of_line ();
3529 symbol
= make_expr_symbol (&symexpr
);
3530 symbol
->bsym
->flags
|= BSF_FUNCTION
;
3531 alpha_evax_proc
.symbol
= symbol
;
3533 demand_empty_rest_of_line ();
3538 /* Parse .frame <framreg>,<framesize>,RA,<rsa_offset> directives. */
3541 s_alpha_frame (ignore
)
3546 alpha_evax_proc
.framereg
= tc_get_register (1);
3549 if (*input_line_pointer
++ != ','
3550 || get_absolute_expression_and_terminator (&val
) != ',')
3552 as_warn ("Bad .frame directive 1./2. param");
3553 --input_line_pointer
;
3554 demand_empty_rest_of_line ();
3558 alpha_evax_proc
.framesize
= val
;
3560 (void) tc_get_register (1);
3562 if (*input_line_pointer
++ != ',')
3564 as_warn ("Bad .frame directive 3./4. param");
3565 --input_line_pointer
;
3566 demand_empty_rest_of_line ();
3569 alpha_evax_proc
.rsa_offset
= get_absolute_expression ();
3575 s_alpha_pdesc (ignore
)
3585 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
3587 if (now_seg
!= alpha_link_section
)
3589 as_bad (".pdesc directive not in link (.link) section");
3590 demand_empty_rest_of_line ();
3594 if ((alpha_evax_proc
.symbol
== 0)
3595 || (!S_IS_DEFINED (alpha_evax_proc
.symbol
)))
3597 as_fatal (".pdesc has no matching .ent");
3598 demand_empty_rest_of_line ();
3602 alpha_evax_proc
.symbol
->sy_obj
= (valueT
)seginfo
->literal_pool_size
;
3605 if (exp
.X_op
!= O_symbol
)
3607 as_warn (".pdesc directive has no entry symbol");
3608 demand_empty_rest_of_line ();
3612 entry_sym
= make_expr_symbol (&exp
);
3613 /* Save bfd symbol of proc desc in function symbol. */
3614 alpha_evax_proc
.symbol
->bsym
->udata
.p
= (PTR
)entry_sym
->bsym
;
3617 if (*input_line_pointer
++ != ',')
3619 as_warn ("No comma after .pdesc <entryname>");
3620 demand_empty_rest_of_line ();
3625 name
= input_line_pointer
;
3626 name_end
= get_symbol_end ();
3628 if (strncmp(name
, "stack", 5) == 0)
3630 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_FP_STACK
;
3632 else if (strncmp(name
, "reg", 3) == 0)
3634 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_FP_REGISTER
;
3636 else if (strncmp(name
, "null", 4) == 0)
3638 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_NULL
;
3642 as_fatal ("unknown procedure kind");
3643 demand_empty_rest_of_line ();
3647 *input_line_pointer
= name_end
;
3648 demand_empty_rest_of_line ();
3650 #ifdef md_flush_pending_output
3651 md_flush_pending_output ();
3654 frag_align (3, 0, 0);
3656 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
3658 seginfo
->literal_pool_size
+= 16;
3660 *p
= alpha_evax_proc
.pdsckind
3661 | ((alpha_evax_proc
.framereg
== 29) ? PDSC_S_M_BASE_REG_IS_FP
: 0);
3662 *(p
+1) = PDSC_S_M_NATIVE
3663 | PDSC_S_M_NO_JACKET
;
3665 switch (alpha_evax_proc
.pdsckind
)
3667 case PDSC_S_K_KIND_NULL
:
3671 case PDSC_S_K_KIND_FP_REGISTER
:
3672 *(p
+2) = alpha_evax_proc
.fp_save
;
3673 *(p
+3) = alpha_evax_proc
.ra_save
;
3675 case PDSC_S_K_KIND_FP_STACK
:
3676 md_number_to_chars (p
+2, (valueT
)alpha_evax_proc
.rsa_offset
, 2);
3678 default: /* impossible */
3683 *(p
+5) = alpha_evax_proc
.type
& 0x0f;
3685 /* Signature offset. */
3686 md_number_to_chars (p
+6, (valueT
)0, 2);
3688 fix_new_exp (frag_now
, p
-frag_now
->fr_literal
+8, 8, &exp
, 0, BFD_RELOC_64
);
3690 if (alpha_evax_proc
.pdsckind
== PDSC_S_K_KIND_NULL
)
3693 /* Add dummy fix to make add_to_link_pool work. */
3695 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
3697 seginfo
->literal_pool_size
+= 8;
3699 /* pdesc+16: Size. */
3700 md_number_to_chars (p
, (valueT
)alpha_evax_proc
.framesize
, 4);
3702 md_number_to_chars (p
+4, (valueT
)0, 2);
3705 md_number_to_chars (p
+6, alpha_evax_proc
.prologue
, 2);
3707 if (alpha_evax_proc
.pdsckind
== PDSC_S_K_KIND_FP_REGISTER
)
3710 /* Add dummy fix to make add_to_link_pool work. */
3712 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
3714 seginfo
->literal_pool_size
+= 8;
3716 /* pdesc+24: register masks. */
3718 md_number_to_chars (p
, alpha_evax_proc
.imask
, 4);
3719 md_number_to_chars (p
+4, alpha_evax_proc
.fmask
, 4);
3725 /* Support for crash debug on vms. */
3728 s_alpha_name (ignore
)
3733 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
3735 if (now_seg
!= alpha_link_section
)
3737 as_bad (".name directive not in link (.link) section");
3738 demand_empty_rest_of_line ();
3743 if (exp
.X_op
!= O_symbol
)
3745 as_warn (".name directive has no symbol");
3746 demand_empty_rest_of_line ();
3750 demand_empty_rest_of_line ();
3752 #ifdef md_flush_pending_output
3753 md_flush_pending_output ();
3756 frag_align (3, 0, 0);
3758 seginfo
->literal_pool_size
+= 8;
3760 fix_new_exp (frag_now
, p
-frag_now
->fr_literal
, 8, &exp
, 0, BFD_RELOC_64
);
3767 s_alpha_linkage (ignore
)
3773 #ifdef md_flush_pending_output
3774 md_flush_pending_output ();
3778 if (exp
.X_op
!= O_symbol
)
3780 as_fatal ("No symbol after .linkage");
3784 p
= frag_more (LKP_S_K_SIZE
);
3785 memset (p
, 0, LKP_S_K_SIZE
);
3786 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, LKP_S_K_SIZE
, &exp
, 0,\
3787 BFD_RELOC_ALPHA_LINKAGE
);
3789 demand_empty_rest_of_line ();
3796 s_alpha_code_address (ignore
)
3802 #ifdef md_flush_pending_output
3803 md_flush_pending_output ();
3807 if (exp
.X_op
!= O_symbol
)
3809 as_fatal ("No symbol after .code_address");
3815 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 8, &exp
, 0,\
3816 BFD_RELOC_ALPHA_CODEADDR
);
3818 demand_empty_rest_of_line ();
3825 s_alpha_fp_save (ignore
)
3829 alpha_evax_proc
.fp_save
= tc_get_register (1);
3831 demand_empty_rest_of_line ();
3837 s_alpha_mask (ignore
)
3842 if (get_absolute_expression_and_terminator (&val
) != ',')
3844 as_warn ("Bad .mask directive");
3845 --input_line_pointer
;
3849 alpha_evax_proc
.imask
= val
;
3850 (void)get_absolute_expression ();
3852 demand_empty_rest_of_line ();
3859 s_alpha_fmask (ignore
)
3864 if (get_absolute_expression_and_terminator (&val
) != ',')
3866 as_warn ("Bad .fmask directive");
3867 --input_line_pointer
;
3871 alpha_evax_proc
.fmask
= val
;
3872 (void) get_absolute_expression ();
3874 demand_empty_rest_of_line ();
3880 s_alpha_end (ignore
)
3885 c
= get_symbol_end ();
3886 *input_line_pointer
= c
;
3887 demand_empty_rest_of_line ();
3888 alpha_evax_proc
.symbol
= 0;
3889 alpha_basereg_clobbered
= 0;
3896 s_alpha_file (ignore
)
3901 static char case_hack
[32];
3903 extern char *demand_copy_string
PARAMS ((int *lenP
));
3905 sprintf (case_hack
, "<CASE:%01d%01d>",
3906 alpha_flag_hash_long_names
, alpha_flag_show_after_trunc
);
3908 s
= symbol_find_or_make (case_hack
);
3909 s
->bsym
->flags
|= BSF_FILE
;
3911 get_absolute_expression ();
3912 s
= symbol_find_or_make (demand_copy_string (&length
));
3913 s
->bsym
->flags
|= BSF_FILE
;
3914 demand_empty_rest_of_line ();
3918 #endif /* OBJ_EVAX */
3920 /* Handle the .gprel32 pseudo op. */
3923 s_alpha_gprel32 (ignore
)
3936 e
.X_add_symbol
= section_symbol(absolute_section
);
3949 e
.X_add_symbol
= section_symbol (absolute_section
);
3952 e
.X_op
= O_subtract
;
3953 e
.X_op_symbol
= alpha_gp_symbol
;
3961 if (alpha_auto_align_on
&& alpha_current_align
< 2)
3962 alpha_align (2, (char *) NULL
, alpha_insn_label
);
3963 if (alpha_current_align
> 2)
3964 alpha_current_align
= 2;
3965 alpha_insn_label
= NULL
;
3969 fix_new_exp (frag_now
, p
-frag_now
->fr_literal
, 4,
3970 &e
, 0, BFD_RELOC_GPREL32
);
3973 /* Handle floating point allocation pseudo-ops. This is like the
3974 generic vresion, but it makes sure the current label, if any, is
3975 correctly aligned. */
3978 s_alpha_float_cons (type
)
4005 if (alpha_auto_align_on
&& alpha_current_align
< log_size
)
4006 alpha_align (log_size
, (char *) NULL
, alpha_insn_label
);
4007 if (alpha_current_align
> log_size
)
4008 alpha_current_align
= log_size
;
4009 alpha_insn_label
= NULL
;
4014 /* Handle the .proc pseudo op. We don't really do much with it except
4018 s_alpha_proc (is_static
)
4027 /* Takes ".proc name,nargs" */
4029 name
= input_line_pointer
;
4030 c
= get_symbol_end ();
4031 p
= input_line_pointer
;
4032 symbolP
= symbol_find_or_make (name
);
4035 if (*input_line_pointer
!= ',')
4038 as_warn ("Expected comma after name \"%s\"", name
);
4041 ignore_rest_of_line ();
4045 input_line_pointer
++;
4046 temp
= get_absolute_expression ();
4048 /* symbolP->sy_other = (signed char) temp; */
4049 as_warn ("unhandled: .proc %s,%d", name
, temp
);
4050 demand_empty_rest_of_line ();
4053 /* Handle the .set pseudo op. This is used to turn on and off most of
4054 the assembler features. */
4064 name
= input_line_pointer
;
4065 ch
= get_symbol_end ();
4068 if (s
[0] == 'n' && s
[1] == 'o')
4073 if (!strcmp ("reorder", s
))
4075 else if (!strcmp ("at", s
))
4076 alpha_noat_on
= !yesno
;
4077 else if (!strcmp ("macro", s
))
4078 alpha_macros_on
= yesno
;
4079 else if (!strcmp ("move", s
))
4081 else if (!strcmp ("volatile", s
))
4084 as_warn ("Tried to .set unrecognized mode `%s'", name
);
4086 *input_line_pointer
= ch
;
4087 demand_empty_rest_of_line ();
4090 /* Handle the .base pseudo op. This changes the assembler's notion of
4091 the $gp register. */
4094 s_alpha_base (ignore
)
4098 if (first_32bit_quadrant
)
4100 /* not fatal, but it might not work in the end */
4101 as_warn ("File overrides no-base-register option.");
4102 first_32bit_quadrant
= 0;
4107 if (*input_line_pointer
== '$')
4109 input_line_pointer
++;
4110 if (*input_line_pointer
== 'r')
4111 input_line_pointer
++;
4114 alpha_gp_register
= get_absolute_expression ();
4115 if (alpha_gp_register
< 0 || alpha_gp_register
> 31)
4117 alpha_gp_register
= AXP_REG_GP
;
4118 as_warn ("Bad base register, using $%d.", alpha_gp_register
);
4121 demand_empty_rest_of_line ();
4124 /* Handle the .align pseudo-op. This aligns to a power of two. It
4125 also adjusts any current instruction label. We treat this the same
4126 way the MIPS port does: .align 0 turns off auto alignment. */
4129 s_alpha_align (ignore
)
4134 long max_alignment
= 15;
4136 align
= get_absolute_expression ();
4137 if (align
> max_alignment
)
4139 align
= max_alignment
;
4140 as_bad ("Alignment too large: %d. assumed", align
);
4144 as_warn ("Alignment negative: 0 assumed");
4148 if (*input_line_pointer
== ',')
4150 input_line_pointer
++;
4151 fill
= get_absolute_expression ();
4159 alpha_auto_align_on
= 1;
4160 alpha_align (align
, pfill
, alpha_insn_label
);
4164 alpha_auto_align_on
= 0;
4167 demand_empty_rest_of_line ();
4170 /* Hook the normal string processor to reset known alignment. */
4173 s_alpha_stringer (terminate
)
4176 alpha_current_align
= 0;
4177 alpha_insn_label
= NULL
;
4178 stringer (terminate
);
4181 /* Hook the normal space processing to reset known alignment. */
4184 s_alpha_space (ignore
)
4187 alpha_current_align
= 0;
4188 alpha_insn_label
= NULL
;
4192 /* Hook into cons for auto-alignment. */
4195 alpha_cons_align (size
)
4201 while ((size
>>= 1) != 0)
4204 if (alpha_auto_align_on
&& alpha_current_align
< log_size
)
4205 alpha_align (log_size
, (char *) NULL
, alpha_insn_label
);
4206 if (alpha_current_align
> log_size
)
4207 alpha_current_align
= log_size
;
4208 alpha_insn_label
= NULL
;
4211 /* Here come the .uword, .ulong, and .uquad explicitly unaligned
4212 pseudos. We just turn off auto-alignment and call down to cons. */
4215 s_alpha_ucons (bytes
)
4218 int hold
= alpha_auto_align_on
;
4219 alpha_auto_align_on
= 0;
4221 alpha_auto_align_on
= hold
;
4224 /* Switch the working cpu type. */
4227 s_alpha_arch (ignored
)
4231 const struct cpu_type
*p
;
4234 name
= input_line_pointer
;
4235 ch
= get_symbol_end ();
4237 for (p
= cpu_types
; p
->name
; ++p
)
4238 if (strcmp(name
, p
->name
) == 0)
4240 alpha_target_name
= p
->name
, alpha_target
= p
->flags
;
4243 as_warn("Unknown CPU identifier `%s'", name
);
4246 *input_line_pointer
= ch
;
4247 demand_empty_rest_of_line ();
4253 /* print token expression with alpha specific extension. */
4256 alpha_print_token(f
, exp
)
4258 const expressionS
*exp
;
4268 expressionS nexp
= *exp
;
4269 nexp
.X_op
= O_register
;
4270 print_expr (f
, &nexp
);
4275 print_expr (f
, exp
);
4282 /* The target specific pseudo-ops which we support. */
4284 const pseudo_typeS md_pseudo_table
[] =
4286 {"common", s_comm
, 0}, /* is this used? */
4288 {"comm", s_alpha_comm
, 0}, /* osf1 compiler does this */
4289 {"rdata", s_alpha_rdata
, 0},
4291 {"text", s_alpha_text
, 0},
4292 {"data", s_alpha_data
, 0},
4294 {"sdata", s_alpha_sdata
, 0},
4297 {"section", s_alpha_section
, 0},
4298 {"section.s", s_alpha_section
, 0},
4299 {"sect", s_alpha_section
, 0},
4300 {"sect.s", s_alpha_section
, 0},
4303 { "pdesc", s_alpha_pdesc
, 0},
4304 { "name", s_alpha_name
, 0},
4305 { "linkage", s_alpha_linkage
, 0},
4306 { "code_address", s_alpha_code_address
, 0},
4307 { "ent", s_alpha_ent
, 0},
4308 { "frame", s_alpha_frame
, 0},
4309 { "fp_save", s_alpha_fp_save
, 0},
4310 { "mask", s_alpha_mask
, 0},
4311 { "fmask", s_alpha_fmask
, 0},
4312 { "end", s_alpha_end
, 0},
4313 { "file", s_alpha_file
, 0},
4314 { "rdata", s_alpha_section
, 1},
4315 { "comm", s_alpha_section
, 2},
4316 { "link", s_alpha_section
, 3},
4317 { "ctors", s_alpha_section
, 4},
4318 { "dtors", s_alpha_section
, 5},
4319 { "lcomm", s_alpha_section
, 6},
4321 {"gprel32", s_alpha_gprel32
, 0},
4322 {"t_floating", s_alpha_float_cons
, 'd'},
4323 {"s_floating", s_alpha_float_cons
, 'f'},
4324 {"f_floating", s_alpha_float_cons
, 'F'},
4325 {"g_floating", s_alpha_float_cons
, 'G'},
4326 {"d_floating", s_alpha_float_cons
, 'D'},
4328 {"proc", s_alpha_proc
, 0},
4329 {"aproc", s_alpha_proc
, 1},
4330 {"set", s_alpha_set
, 0},
4331 {"reguse", s_ignore
, 0},
4332 {"livereg", s_ignore
, 0},
4333 {"base", s_alpha_base
, 0}, /*??*/
4334 {"option", s_ignore
, 0},
4335 {"prologue", s_ignore
, 0},
4336 {"aent", s_ignore
, 0},
4337 {"ugen", s_ignore
, 0},
4338 {"eflag", s_ignore
, 0},
4340 {"align", s_alpha_align
, 0},
4341 {"double", s_alpha_float_cons
, 'd'},
4342 {"float", s_alpha_float_cons
, 'f'},
4343 {"single", s_alpha_float_cons
, 'f'},
4344 {"ascii", s_alpha_stringer
, 0},
4345 {"asciz", s_alpha_stringer
, 1},
4346 {"string", s_alpha_stringer
, 1},
4347 {"space", s_alpha_space
, 0},
4348 {"skip", s_alpha_space
, 0},
4349 {"zero", s_alpha_space
, 0},
4351 /* Unaligned data pseudos. */
4352 {"uword", s_alpha_ucons
, 2},
4353 {"ulong", s_alpha_ucons
, 4},
4354 {"uquad", s_alpha_ucons
, 8},
4357 /* Dwarf wants these versions of unaligned. */
4358 {"2byte", s_alpha_ucons
, 2},
4359 {"4byte", s_alpha_ucons
, 4},
4360 {"8byte", s_alpha_ucons
, 8},
4363 /* We don't do any optimizing, so we can safely ignore these. */
4364 {"noalias", s_ignore
, 0},
4365 {"alias", s_ignore
, 0},
4367 {"arch", s_alpha_arch
, 0},
4373 /* Build a BFD section with its flags set appropriately for the .lita,
4374 .lit8, or .lit4 sections. */
4377 create_literal_section (name
, secp
, symp
)
4382 segT current_section
= now_seg
;
4383 int current_subsec
= now_subseg
;
4386 *secp
= new_sec
= subseg_new (name
, 0);
4387 subseg_set (current_section
, current_subsec
);
4388 bfd_set_section_alignment (stdoutput
, new_sec
, 4);
4389 bfd_set_section_flags (stdoutput
, new_sec
,
4390 SEC_RELOC
| SEC_ALLOC
| SEC_LOAD
| SEC_READONLY
4393 S_CLEAR_EXTERNAL (*symp
= section_symbol (new_sec
));
4398 /* @@@ GP selection voodoo. All of this seems overly complicated and
4399 unnecessary; which is the primary reason it's for ECOFF only. */
4408 vma
= bfd_get_section_vma (foo
, sec
);
4409 if (vma
&& vma
< alpha_gp_value
)
4410 alpha_gp_value
= vma
;
4416 assert (alpha_gp_value
== 0);
4418 /* Get minus-one in whatever width... */
4419 alpha_gp_value
= 0; alpha_gp_value
--;
4421 /* Select the smallest VMA of these existing sections. */
4422 maybe_set_gp (alpha_lita_section
);
4424 /* These were disabled before -- should we use them? */
4425 maybe_set_gp (sdata
);
4426 maybe_set_gp (lit8_sec
);
4427 maybe_set_gp (lit4_sec
);
4430 /* @@ Will a simple 0x8000 work here? If not, why not? */
4431 #define GP_ADJUSTMENT (0x8000 - 0x10)
4433 alpha_gp_value
+= GP_ADJUSTMENT
;
4435 S_SET_VALUE (alpha_gp_symbol
, alpha_gp_value
);
4438 printf ("Chose GP value of %lx\n", alpha_gp_value
);
4441 #endif /* OBJ_ECOFF */
4443 /* Called internally to handle all alignment needs. This takes care
4444 of eliding calls to frag_align if'n the cached current alignment
4445 says we've already got it, as well as taking care of the auto-align
4446 feature wrt labels. */
4449 alpha_align (n
, pfill
, label
)
4454 if (alpha_current_align
>= n
)
4460 && (bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
) != 0)
4462 static char const nop
[4] = { 0x1f, 0x04, 0xff, 0x47 };
4464 /* First, make sure we're on a four-byte boundary, in case
4465 someone has been putting .byte values into the text
4466 section. The DEC assembler silently fills with unaligned
4467 no-op instructions. This will zero-fill, then nop-fill
4468 with proper alignment. */
4469 if (alpha_current_align
< 2)
4470 frag_align (2, 0, 0);
4471 frag_align_pattern (n
, nop
, sizeof nop
, 0);
4474 frag_align (n
, 0, 0);
4477 frag_align (n
, *pfill
, 0);
4479 alpha_current_align
= n
;
4483 assert (S_GET_SEGMENT (label
) == now_seg
);
4484 label
->sy_frag
= frag_now
;
4485 S_SET_VALUE (label
, (valueT
) frag_now_fix ());
4488 record_alignment(now_seg
, n
);
4491 /* The Alpha has support for some VAX floating point types, as well as for
4492 IEEE floating point. We consider IEEE to be the primary floating point
4493 format, and sneak in the VAX floating point support here. */
4494 #define md_atof vax_md_atof
4495 #include "config/atof-vax.c"