1 /* tc-alpha.c - Processor-specific code for the DEC Alpha AXP CPU.
2 Copyright (C) 1989, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
3 Contributed by Carnegie Mellon University, 1993.
4 Written by Alessandro Forin, based on earlier gas-1.38 target CPU files.
5 Modified by Ken Raeburn for gas-2.x and ECOFF support.
6 Modified by Richard Henderson for ELF support.
7 Modified by Klaus K"ampf for EVAX (openVMS/Alpha) support.
9 This file is part of GAS, the GNU Assembler.
11 GAS is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2, or (at your option)
16 GAS is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with GAS; see the file COPYING. If not, write to the Free
23 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
27 * Mach Operating System
28 * Copyright (c) 1993 Carnegie Mellon University
29 * All Rights Reserved.
31 * Permission to use, copy, modify and distribute this software and its
32 * documentation is hereby granted, provided that both the copyright
33 * notice and this permission notice appear in all copies of the
34 * software, derivative works or modified versions, and any portions
35 * thereof, and that both notices appear in supporting documentation.
37 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
38 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
39 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
41 * Carnegie Mellon requests users of this software to return to
43 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
44 * School of Computer Science
45 * Carnegie Mellon University
46 * Pittsburgh PA 15213-3890
48 * any improvements or extensions that they make and grant Carnegie the
49 * rights to redistribute these changes.
55 #include "opcode/alpha.h"
58 #include "elf/alpha.h"
66 #define MAX_INSN_FIXUPS 2
67 #define MAX_INSN_ARGS 5
72 bfd_reloc_code_real_type reloc
;
79 struct alpha_fixup fixups
[MAX_INSN_FIXUPS
];
84 MACRO_EOA
= 1, MACRO_IR
, MACRO_PIR
, MACRO_CPIR
, MACRO_FPR
, MACRO_EXP
90 void (*emit
) PARAMS ((const expressionS
*, int, const PTR
));
92 enum alpha_macro_arg argsets
[16];
95 /* Two extra symbols we want to see in our input. This is a blatent
96 misuse of the expressionS.X_op field. */
98 #define O_pregister (O_max+1) /* O_register, but in parentheses */
99 #define O_cpregister (O_pregister+1) /* + a leading comma */
101 /* Macros for extracting the type and number of encoded register tokens */
103 #define is_ir_num(x) (((x) & 32) == 0)
104 #define is_fpr_num(x) (((x) & 32) != 0)
105 #define regno(x) ((x) & 31)
107 /* Something odd inherited from the old assembler */
109 #define note_gpreg(R) (alpha_gprmask |= (1 << (R)))
110 #define note_fpreg(R) (alpha_fprmask |= (1 << (R)))
112 /* Predicates for 16- and 32-bit ranges */
113 /* XXX: The non-shift version appears to trigger a compiler bug when
114 cross-assembling from x86 w/ gcc 2.7.2. */
117 #define range_signed_16(x) \
118 (((offsetT)(x) >> 15) == 0 || ((offsetT)(x) >> 15) == -1)
119 #define range_signed_32(x) \
120 (((offsetT)(x) >> 31) == 0 || ((offsetT)(x) >> 31) == -1)
122 #define range_signed_16(x) ((offsetT)(x) >= -(offsetT)0x8000 && \
123 (offsetT)(x) <= (offsetT)0x7FFF)
124 #define range_signed_32(x) ((offsetT)(x) >= -(offsetT)0x80000000 && \
125 (offsetT)(x) <= (offsetT)0x7FFFFFFF)
128 /* Macros for sign extending from 16- and 32-bits. */
129 /* XXX: The cast macros will work on all the systems that I care about,
130 but really a predicate should be found to use the non-cast forms. */
133 #define sign_extend_16(x) ((short)(x))
134 #define sign_extend_32(x) ((int)(x))
136 #define sign_extend_16(x) ((offsetT)(((x) & 0xFFFF) ^ 0x8000) - 0x8000)
137 #define sign_extend_32(x) ((offsetT)(((x) & 0xFFFFFFFF) \
138 ^ 0x80000000) - 0x80000000)
141 /* Macros to build tokens */
143 #define set_tok_reg(t, r) (memset(&(t), 0, sizeof(t)), \
144 (t).X_op = O_register, \
145 (t).X_add_number = (r))
146 #define set_tok_preg(t, r) (memset(&(t), 0, sizeof(t)), \
147 (t).X_op = O_pregister, \
148 (t).X_add_number = (r))
149 #define set_tok_cpreg(t, r) (memset(&(t), 0, sizeof(t)), \
150 (t).X_op = O_cpregister, \
151 (t).X_add_number = (r))
152 #define set_tok_freg(t, r) (memset(&(t), 0, sizeof(t)), \
153 (t).X_op = O_register, \
154 (t).X_add_number = (r)+32)
155 #define set_tok_sym(t, s, a) (memset(&(t), 0, sizeof(t)), \
156 (t).X_op = O_symbol, \
157 (t).X_add_symbol = (s), \
158 (t).X_add_number = (a))
159 #define set_tok_const(t, n) (memset(&(t), 0, sizeof(t)), \
160 (t).X_op = O_constant, \
161 (t).X_add_number = (n))
164 /* Prototypes for all local functions */
166 static int tokenize_arguments
PARAMS ((char *, expressionS
*, int));
167 static const struct alpha_opcode
*find_opcode_match
168 PARAMS ((const struct alpha_opcode
*, const expressionS
*, int *, int *));
169 static const struct alpha_macro
*find_macro_match
170 PARAMS ((const struct alpha_macro
*, const expressionS
*, int *));
171 static unsigned insert_operand
172 PARAMS ((unsigned, const struct alpha_operand
*, offsetT
, char *, unsigned));
173 static void assemble_insn
174 PARAMS ((const struct alpha_opcode
*, const expressionS
*, int,
175 struct alpha_insn
*));
176 static void emit_insn
PARAMS ((struct alpha_insn
*));
177 static void assemble_tokens_to_insn
178 PARAMS ((const char *, const expressionS
*, int, struct alpha_insn
*));
179 static void assemble_tokens
180 PARAMS ((const char *, const expressionS
*, int, int));
182 static int load_expression
183 PARAMS ((int, const expressionS
*, int *, expressionS
*));
185 static void emit_ldgp
PARAMS ((const expressionS
*, int, const PTR
));
186 static void emit_division
PARAMS ((const expressionS
*, int, const PTR
));
187 static void emit_lda
PARAMS ((const expressionS
*, int, const PTR
));
188 static void emit_ldah
PARAMS ((const expressionS
*, int, const PTR
));
189 static void emit_ir_load
PARAMS ((const expressionS
*, int, const PTR
));
190 static void emit_loadstore
PARAMS ((const expressionS
*, int, const PTR
));
191 static void emit_jsrjmp
PARAMS ((const expressionS
*, int, const PTR
));
192 static void emit_ldX
PARAMS ((const expressionS
*, int, const PTR
));
193 static void emit_ldXu
PARAMS ((const expressionS
*, int, const PTR
));
194 static void emit_uldX
PARAMS ((const expressionS
*, int, const PTR
));
195 static void emit_uldXu
PARAMS ((const expressionS
*, int, const PTR
));
196 static void emit_ldil
PARAMS ((const expressionS
*, int, const PTR
));
197 static void emit_stX
PARAMS ((const expressionS
*, int, const PTR
));
198 static void emit_ustX
PARAMS ((const expressionS
*, int, const PTR
));
199 static void emit_sextX
PARAMS ((const expressionS
*, int, const PTR
));
200 static void emit_retjcr
PARAMS ((const expressionS
*, int, const PTR
));
202 static void s_alpha_text
PARAMS ((int));
203 static void s_alpha_data
PARAMS ((int));
205 static void s_alpha_comm
PARAMS ((int));
206 static void s_alpha_rdata
PARAMS ((int));
209 static void s_alpha_sdata
PARAMS ((int));
212 static void s_alpha_section
PARAMS ((int));
213 static void s_alpha_prologue
PARAMS ((int));
216 static void s_alpha_section
PARAMS ((int));
218 static void s_alpha_gprel32
PARAMS ((int));
219 static void s_alpha_float_cons
PARAMS ((int));
220 static void s_alpha_proc
PARAMS ((int));
221 static void s_alpha_set
PARAMS ((int));
222 static void s_alpha_base
PARAMS ((int));
223 static void s_alpha_align
PARAMS ((int));
224 static void s_alpha_stringer
PARAMS ((int));
225 static void s_alpha_space
PARAMS ((int));
227 static void create_literal_section
PARAMS ((const char *, segT
*, symbolS
**));
229 static void select_gp_value
PARAMS ((void));
231 static void alpha_align
PARAMS ((int, char *, symbolS
*, int));
234 /* Generic assembler global variables which must be defined by all
237 /* Characters which always start a comment. */
238 const char comment_chars
[] = "#";
240 /* Characters which start a comment at the beginning of a line. */
241 const char line_comment_chars
[] = "#";
243 /* Characters which may be used to separate multiple commands on a
245 const char line_separator_chars
[] = ";";
247 /* Characters which are used to indicate an exponent in a floating
249 const char EXP_CHARS
[] = "eE";
251 /* Characters which mean that a number is a floating point constant,
254 const char FLT_CHARS
[] = "dD";
256 /* XXX: Do all of these really get used on the alpha?? */
257 char FLT_CHARS
[] = "rRsSfFdDxXpP";
261 const char *md_shortopts
= "Fm:g+1h:HG:";
263 const char *md_shortopts
= "Fm:gG:";
266 struct option md_longopts
[] = {
267 #define OPTION_32ADDR (OPTION_MD_BASE)
268 { "32addr", no_argument
, NULL
, OPTION_32ADDR
},
269 #define OPTION_RELAX (OPTION_32ADDR+1)
270 { "relax", no_argument
, NULL
, OPTION_RELAX
},
271 { NULL
, no_argument
, NULL
, 0 }
274 size_t md_longopts_size
= sizeof(md_longopts
);
279 #define AXP_REG_R16 16
280 #define AXP_REG_R17 17
282 #define AXP_REG_T9 22
284 #define AXP_REG_T10 23
286 #define AXP_REG_T11 24
288 #define AXP_REG_T12 25
289 #define AXP_REG_AI 25
291 #define AXP_REG_FP 29
294 #define AXP_REG_GP AXP_REG_PV
295 #endif /* OBJ_EVAX */
297 /* The cpu for which we are generating code */
298 static unsigned alpha_target
= AXP_OPCODE_BASE
;
299 static const char *alpha_target_name
= "<all>";
301 /* The hash table of instruction opcodes */
302 static struct hash_control
*alpha_opcode_hash
;
304 /* The hash table of macro opcodes */
305 static struct hash_control
*alpha_macro_hash
;
308 /* The $gp relocation symbol */
309 static symbolS
*alpha_gp_symbol
;
311 /* XXX: what is this, and why is it exported? */
312 valueT alpha_gp_value
;
315 /* The current $gp register */
316 static int alpha_gp_register
= AXP_REG_GP
;
318 /* A table of the register symbols */
319 static symbolS
*alpha_register_table
[64];
321 /* Constant sections, or sections of constants */
323 static segT alpha_lita_section
;
324 static segT alpha_lit4_section
;
327 static segT alpha_link_section
;
328 static segT alpha_ctors_section
;
329 static segT alpha_dtors_section
;
331 static segT alpha_lit8_section
;
333 /* Symbols referring to said sections. */
335 static symbolS
*alpha_lita_symbol
;
336 static symbolS
*alpha_lit4_symbol
;
339 static symbolS
*alpha_link_symbol
;
340 static symbolS
*alpha_ctors_symbol
;
341 static symbolS
*alpha_dtors_symbol
;
343 static symbolS
*alpha_lit8_symbol
;
345 /* Literal for .litX+0x8000 within .lita */
347 static offsetT alpha_lit4_literal
;
348 static offsetT alpha_lit8_literal
;
351 /* Is the assembler not allowed to use $at? */
352 static int alpha_noat_on
= 0;
354 /* Are macros enabled? */
355 static int alpha_macros_on
= 1;
357 /* Are floats disabled? */
358 static int alpha_nofloats_on
= 0;
360 /* Are addresses 32 bit? */
361 static int alpha_addr32_on
= 0;
363 /* Symbol labelling the current insn. When the Alpha gas sees
366 and the section happens to not be on an eight byte boundary, it
367 will align both the symbol and the .quad to an eight byte boundary. */
368 static symbolS
*alpha_insn_label
;
370 /* Whether we should automatically align data generation pseudo-ops.
371 .align 0 will turn this off. */
372 static int alpha_auto_align_on
= 1;
374 /* The known current alignment of the current section. */
375 static int alpha_current_align
;
377 /* These are exported to ECOFF code. */
378 unsigned long alpha_gprmask
, alpha_fprmask
;
380 /* Whether the debugging option was seen. */
381 static int alpha_debug
;
383 /* Don't fully resolve relocations, allowing code movement in the linker. */
384 static int alpha_flag_relax
;
386 /* What value to give to bfd_set_gp_size. */
387 static int g_switch_value
= 8;
390 /* Collect information about current procedure here. */
392 symbolS
*symbol
; /* proc pdesc symbol */
394 int framereg
; /* register for frame pointer */
395 int framesize
; /* size of frame */
405 static int alpha_flag_hash_long_names
= 0; /* -+ */
406 static int alpha_flag_show_after_trunc
= 0; /* -H */
408 /* If the -+ switch is given, then a hash is appended to any name that is
409 * longer than 64 characters, else longer symbol names are truncated.
414 /* A table of CPU names and opcode sets. */
416 static const struct cpu_type
422 /* Ad hoc convention: cpu number gets palcode, process code doesn't.
423 This supports usage under DU 4.0b that does ".arch ev4", and
424 usage in MILO that does -m21064. Probably something more
425 specific like -m21064-pal should be used, but oh well. */
427 { "21064", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
428 { "21064a", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
429 { "21066", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
430 { "21068", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
431 { "21164", AXP_OPCODE_BASE
|AXP_OPCODE_EV5
},
432 /* Do we have CIX extension here? */
433 { "21164a", AXP_OPCODE_BASE
|AXP_OPCODE_EV5
|AXP_OPCODE_BWX
},
434 /* Still same PALcodes? */
435 { "21164pc", (AXP_OPCODE_BASE
|AXP_OPCODE_EV5
|AXP_OPCODE_BWX
437 /* All new PALcodes? Extras? */
438 { "21264", (AXP_OPCODE_BASE
|AXP_OPCODE_BWX
439 |AXP_OPCODE_CIX
|AXP_OPCODE_MAX
) },
441 { "ev4", AXP_OPCODE_BASE
},
442 { "ev45", AXP_OPCODE_BASE
},
443 { "lca45", AXP_OPCODE_BASE
},
444 { "ev5", AXP_OPCODE_BASE
},
445 { "ev56", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
},
446 { "pca56", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
|AXP_OPCODE_MAX
},
447 { "ev6", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
|AXP_OPCODE_CIX
|AXP_OPCODE_MAX
},
449 { "all", AXP_OPCODE_BASE
},
453 /* The macro table */
455 static const struct alpha_macro alpha_macros
[] = {
456 /* Load/Store macros */
457 { "lda", emit_lda
, NULL
,
458 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
459 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
460 { "ldah", emit_ldah
, NULL
,
461 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
463 { "ldl", emit_ir_load
, "ldl",
464 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
465 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
466 { "ldl_l", emit_ir_load
, "ldl_l",
467 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
468 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
469 { "ldq", emit_ir_load
, "ldq",
470 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
471 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
472 { "ldq_l", emit_ir_load
, "ldq_l",
473 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
474 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
475 { "ldq_u", emit_ir_load
, "ldq_u",
476 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
477 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
478 { "ldf", emit_loadstore
, "ldf",
479 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
480 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
481 { "ldg", emit_loadstore
, "ldg",
482 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
483 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
484 { "lds", emit_loadstore
, "lds",
485 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
486 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
487 { "ldt", emit_loadstore
, "ldt",
488 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
489 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
491 { "ldb", emit_ldX
, (PTR
)0,
492 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
493 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
494 { "ldbu", emit_ldXu
, (PTR
)0,
495 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
496 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
497 { "ldw", emit_ldX
, (PTR
)1,
498 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
499 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
500 { "ldwu", emit_ldXu
, (PTR
)1,
501 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
502 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
504 { "uldw", emit_uldX
, (PTR
)1,
505 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
506 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
507 { "uldwu", emit_uldXu
, (PTR
)1,
508 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
509 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
510 { "uldl", emit_uldX
, (PTR
)2,
511 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
512 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
513 { "uldlu", emit_uldXu
, (PTR
)2,
514 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
515 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
516 { "uldq", emit_uldXu
, (PTR
)3,
517 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
518 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
520 { "ldgp", emit_ldgp
, NULL
,
521 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
} },
523 { "ldi", emit_lda
, NULL
,
524 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
525 { "ldil", emit_ldil
, NULL
,
526 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
527 { "ldiq", emit_lda
, NULL
,
528 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
530 { "ldif" emit_ldiq
, NULL
,
531 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
532 { "ldid" emit_ldiq
, NULL
,
533 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
534 { "ldig" emit_ldiq
, NULL
,
535 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
536 { "ldis" emit_ldiq
, NULL
,
537 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
538 { "ldit" emit_ldiq
, NULL
,
539 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
542 { "stl", emit_loadstore
, "stl",
543 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
544 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
545 { "stl_c", emit_loadstore
, "stl_c",
546 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
547 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
548 { "stq", emit_loadstore
, "stq",
549 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
550 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
551 { "stq_c", emit_loadstore
, "stq_c",
552 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
553 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
554 { "stq_u", emit_loadstore
, "stq_u",
555 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
556 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
557 { "stf", emit_loadstore
, "stf",
558 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
559 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
560 { "stg", emit_loadstore
, "stg",
561 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
562 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
563 { "sts", emit_loadstore
, "sts",
564 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
565 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
566 { "stt", emit_loadstore
, "stt",
567 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
568 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
570 { "stb", emit_stX
, (PTR
)0,
571 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
572 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
573 { "stw", emit_stX
, (PTR
)1,
574 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
575 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
576 { "ustw", emit_ustX
, (PTR
)1,
577 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
578 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
579 { "ustl", emit_ustX
, (PTR
)2,
580 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
581 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
582 { "ustq", emit_ustX
, (PTR
)3,
583 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
584 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
586 /* Arithmetic macros */
588 { "absl" emit_absl
, 1, { IR
} },
589 { "absl" emit_absl
, 2, { IR
, IR
} },
590 { "absl" emit_absl
, 2, { EXP
, IR
} },
591 { "absq" emit_absq
, 1, { IR
} },
592 { "absq" emit_absq
, 2, { IR
, IR
} },
593 { "absq" emit_absq
, 2, { EXP
, IR
} },
596 { "sextb", emit_sextX
, (PTR
)0,
597 { MACRO_IR
, MACRO_IR
, MACRO_EOA
,
599 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
600 { "sextw", emit_sextX
, (PTR
)1,
601 { MACRO_IR
, MACRO_IR
, MACRO_EOA
,
603 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
605 { "divl", emit_division
, "__divl",
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 { "divlu", emit_division
, "__divlu",
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 { "divq", emit_division
, "__divq",
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 { "divqu", emit_division
, "__divqu",
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 { "reml", emit_division
, "__reml",
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 { "remlu", emit_division
, "__remlu",
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 */ } },
635 { "remq", emit_division
, "__remq",
636 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
637 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
638 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
639 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
640 { "remqu", emit_division
, "__remqu",
641 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
642 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
643 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
644 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
646 { "jsr", emit_jsrjmp
, "jsr",
647 { MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
648 MACRO_PIR
, MACRO_EOA
,
649 MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
650 MACRO_EXP
, MACRO_EOA
} },
651 { "jmp", emit_jsrjmp
, "jmp",
652 { MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
653 MACRO_PIR
, MACRO_EOA
,
654 MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
655 MACRO_EXP
, MACRO_EOA
} },
656 { "ret", emit_retjcr
, "ret",
657 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
659 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
660 MACRO_PIR
, MACRO_EOA
,
661 MACRO_EXP
, MACRO_EOA
,
663 { "jcr", emit_retjcr
, "jcr",
664 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
666 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
667 MACRO_PIR
, MACRO_EOA
,
668 MACRO_EXP
, MACRO_EOA
,
670 { "jsr_coroutine", emit_retjcr
, "jcr",
671 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
673 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
674 MACRO_PIR
, MACRO_EOA
,
675 MACRO_EXP
, MACRO_EOA
,
679 static const int alpha_num_macros
680 = sizeof(alpha_macros
) / sizeof(*alpha_macros
);
682 /* Public interface functions */
684 /* This function is called once, at assembler startup time. It sets
685 up all the tables, etc. that the MD part of the assembler will
686 need, that can be determined before arguments are parsed. */
693 /* Create the opcode hash table */
695 alpha_opcode_hash
= hash_new ();
696 for (i
= 0; i
< alpha_num_opcodes
; )
698 const char *name
, *retval
, *slash
;
700 name
= alpha_opcodes
[i
].name
;
701 retval
= hash_insert (alpha_opcode_hash
, name
, (PTR
)&alpha_opcodes
[i
]);
703 as_fatal (_("internal error: can't hash opcode `%s': %s"), name
, retval
);
705 /* Some opcodes include modifiers of various sorts with a "/mod"
706 syntax, like the architecture manual suggests. However, for
707 use with gcc at least, we also need access to those same opcodes
710 if ((slash
= strchr (name
, '/')) != NULL
)
712 char *p
= xmalloc (strlen (name
));
713 memcpy (p
, name
, slash
- name
);
714 strcpy (p
+ (slash
- name
), slash
+ 1);
716 (void)hash_insert(alpha_opcode_hash
, p
, (PTR
)&alpha_opcodes
[i
]);
717 /* Ignore failures -- the opcode table does duplicate some
718 variants in different forms, like "hw_stq" and "hw_st/q". */
721 while (++i
< alpha_num_opcodes
722 && (alpha_opcodes
[i
].name
== name
723 || !strcmp (alpha_opcodes
[i
].name
, name
)))
727 /* Create the macro hash table */
729 alpha_macro_hash
= hash_new ();
730 for (i
= 0; i
< alpha_num_macros
; )
732 const char *name
, *retval
;
734 name
= alpha_macros
[i
].name
;
735 retval
= hash_insert (alpha_macro_hash
, name
, (PTR
)&alpha_macros
[i
]);
737 as_fatal (_("internal error: can't hash macro `%s': %s"), name
, retval
);
739 while (++i
< alpha_num_macros
740 && (alpha_macros
[i
].name
== name
741 || !strcmp (alpha_macros
[i
].name
, name
)))
745 /* Construct symbols for each of the registers */
747 for (i
= 0; i
< 32; ++i
)
750 sprintf(name
, "$%d", i
);
751 alpha_register_table
[i
] = symbol_create(name
, reg_section
, i
,
757 sprintf(name
, "$f%d", i
-32);
758 alpha_register_table
[i
] = symbol_create(name
, reg_section
, i
,
762 /* Create the special symbols and sections we'll be using */
764 /* So .sbss will get used for tiny objects. */
765 bfd_set_gp_size (stdoutput
, g_switch_value
);
768 create_literal_section (".lita", &alpha_lita_section
, &alpha_lita_symbol
);
770 /* For handling the GP, create a symbol that won't be output in the
771 symbol table. We'll edit it out of relocs later. */
772 alpha_gp_symbol
= symbol_create ("<GP value>", alpha_lita_section
, 0x8000,
777 create_literal_section (".link", &alpha_link_section
, &alpha_link_symbol
);
785 sec
= subseg_new(".mdebug", (subsegT
)0);
786 bfd_set_section_flags(stdoutput
, sec
, SEC_HAS_CONTENTS
|SEC_READONLY
);
787 bfd_set_section_alignment(stdoutput
, sec
, 3);
790 sec
= subseg_new(".reginfo", (subsegT
)0);
791 /* The ABI says this section should be loaded so that the running
792 program can access it. */
793 bfd_set_section_flags(stdoutput
, sec
,
794 SEC_ALLOC
|SEC_LOAD
|SEC_READONLY
|SEC_DATA
);
795 bfd_set_section_alignement(stdoutput
, sec
, 3);
800 subseg_set(text_section
, 0);
803 /* The public interface to the instruction assembler. */
809 char opname
[32]; /* current maximum is 13 */
810 expressionS tok
[MAX_INSN_ARGS
];
811 int ntok
, opnamelen
, trunclen
;
813 /* split off the opcode */
814 opnamelen
= strspn (str
, "abcdefghijklmnopqrstuvwxyz_/48");
815 trunclen
= (opnamelen
< sizeof (opname
) - 1
817 : sizeof (opname
) - 1);
818 memcpy (opname
, str
, trunclen
);
819 opname
[trunclen
] = '\0';
821 /* tokenize the rest of the line */
822 if ((ntok
= tokenize_arguments (str
+ opnamelen
, tok
, MAX_INSN_ARGS
)) < 0)
824 as_bad (_("syntax error"));
829 assemble_tokens (opname
, tok
, ntok
, alpha_macros_on
);
832 /* Round up a section's size to the appropriate boundary. */
835 md_section_align (seg
, size
)
839 int align
= bfd_get_section_alignment(stdoutput
, seg
);
840 valueT mask
= ((valueT
)1 << align
) - 1;
842 return (size
+ mask
) & ~mask
;
845 /* Turn a string in input_line_pointer into a floating point constant
846 of type type, and store the appropriate bytes in *litP. The number
847 of LITTLENUMS emitted is stored in *sizeP. An error message is
848 returned, or NULL on OK. */
850 /* Equal to MAX_PRECISION in atof-ieee.c */
851 #define MAX_LITTLENUMS 6
853 extern char *vax_md_atof
PARAMS ((int, char *, int *));
856 md_atof (type
, litP
, sizeP
)
862 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
863 LITTLENUM_TYPE
*wordP
;
870 /* VAX md_atof doesn't like "G" for some reason. */
874 return vax_md_atof (type
, litP
, sizeP
);
897 return _("Bad call to MD_ATOF()");
899 t
= atof_ieee (input_line_pointer
, type
, words
);
901 input_line_pointer
= t
;
902 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
904 for (wordP
= words
+ prec
- 1; prec
--;)
906 md_number_to_chars (litP
, (long) (*wordP
--), sizeof (LITTLENUM_TYPE
));
907 litP
+= sizeof (LITTLENUM_TYPE
);
913 /* Take care of the target-specific command-line options. */
916 md_parse_option (c
, arg
)
923 alpha_nofloats_on
= 1;
935 g_switch_value
= atoi(arg
);
940 const struct cpu_type
*p
;
941 for (p
= cpu_types
; p
->name
; ++p
)
942 if (strcmp(arg
, p
->name
) == 0)
944 alpha_target_name
= p
->name
, alpha_target
= p
->flags
;
947 as_warn(_("Unknown CPU identifier `%s'"), arg
);
953 case '+': /* For g++. Hash any name > 63 chars long. */
954 alpha_flag_hash_long_names
= 1;
957 case 'H': /* Show new symbol after hash truncation */
958 alpha_flag_show_after_trunc
= 1;
961 case 'h': /* for gnu-c/vax compatibility. */
966 alpha_flag_relax
= 1;
976 /* Print a description of the command-line options that we accept. */
979 md_show_usage (stream
)
984 -32addr treat addresses as 32-bit values\n\
985 -F lack floating point instructions support\n\
986 -m21064 | -m21066 | -m21164 | -m21164a\n\
987 -mev4 | -mev45 | -mev5 | -mev56 | -mall\n\
988 specify variant of Alpha architecture\n"),
993 -+ hash encode (don't truncate) names longer than 64 characters\n\
994 -H show new symbol after hash truncation\n"),
999 /* Decide from what point a pc-relative relocation is relative to,
1000 relative to the pc-relative fixup. Er, relatively speaking. */
1003 md_pcrel_from (fixP
)
1006 valueT addr
= fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
1007 switch (fixP
->fx_r_type
)
1009 case BFD_RELOC_ALPHA_GPDISP
:
1010 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1011 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1014 return fixP
->fx_size
+ addr
;
1018 /* Attempt to simplify or even eliminate a fixup. The return value is
1019 ignored; perhaps it was once meaningful, but now it is historical.
1020 To indicate that a fixup has been eliminated, set fixP->fx_done.
1022 For ELF, here it is that we transform the GPDISP_HI16 reloc we used
1023 internally into the GPDISP reloc used externally. We had to do
1024 this so that we'd have the GPDISP_LO16 reloc as a tag to compute
1025 the distance to the "lda" instruction for setting the addend to
1029 md_apply_fix (fixP
, valueP
)
1033 char * const fixpos
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
1034 valueT value
= *valueP
;
1035 unsigned image
, size
;
1037 switch (fixP
->fx_r_type
)
1039 /* The GPDISP relocations are processed internally with a symbol
1040 referring to the current function; we need to drop in a value
1041 which, when added to the address of the start of the function,
1042 gives the desired GP. */
1043 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1045 fixS
*next
= fixP
->fx_next
;
1046 assert (next
->fx_r_type
== BFD_RELOC_ALPHA_GPDISP_LO16
);
1048 fixP
->fx_offset
= (next
->fx_frag
->fr_address
+ next
->fx_where
1049 - fixP
->fx_frag
->fr_address
- fixP
->fx_where
);
1051 value
= (value
- sign_extend_16 (value
)) >> 16;
1054 fixP
->fx_r_type
= BFD_RELOC_ALPHA_GPDISP
;
1058 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1059 value
= sign_extend_16 (value
);
1060 fixP
->fx_offset
= 0;
1066 fixP
->fx_addsy
= section_symbol (absolute_section
);
1067 md_number_to_chars (fixpos
, value
, 2);
1072 fixP
->fx_r_type
= BFD_RELOC_16_PCREL
;
1077 fixP
->fx_r_type
= BFD_RELOC_32_PCREL
;
1082 fixP
->fx_r_type
= BFD_RELOC_64_PCREL
;
1085 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
1087 md_number_to_chars (fixpos
, value
, size
);
1093 case BFD_RELOC_GPREL32
:
1094 assert (fixP
->fx_subsy
== alpha_gp_symbol
);
1096 /* FIXME: inherited this obliviousness of `value' -- why? */
1097 md_number_to_chars (fixpos
, -alpha_gp_value
, 4);
1101 case BFD_RELOC_GPREL32
:
1105 case BFD_RELOC_23_PCREL_S2
:
1106 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
1108 image
= bfd_getl32(fixpos
);
1109 image
= (image
& ~0x1FFFFF) | ((value
>> 2) & 0x1FFFFF);
1114 case BFD_RELOC_ALPHA_HINT
:
1115 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
1117 image
= bfd_getl32(fixpos
);
1118 image
= (image
& ~0x3FFF) | ((value
>> 2) & 0x3FFF);
1124 case BFD_RELOC_ALPHA_LITERAL
:
1125 md_number_to_chars (fixpos
, value
, 2);
1128 case BFD_RELOC_ALPHA_LITUSE
:
1132 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1133 case BFD_RELOC_ALPHA_LITUSE
:
1137 case BFD_RELOC_ALPHA_LINKAGE
:
1138 case BFD_RELOC_ALPHA_CODEADDR
:
1144 const struct alpha_operand
*operand
;
1146 if ((int)fixP
->fx_r_type
>= 0)
1147 as_fatal (_("unhandled relocation type %s"),
1148 bfd_get_reloc_code_name (fixP
->fx_r_type
));
1150 assert (-(int)fixP
->fx_r_type
< alpha_num_operands
);
1151 operand
= &alpha_operands
[-(int)fixP
->fx_r_type
];
1153 /* The rest of these fixups only exist internally during symbol
1154 resolution and have no representation in the object file.
1155 Therefore they must be completely resolved as constants. */
1157 if (fixP
->fx_addsy
!= 0
1158 && fixP
->fx_addsy
->bsym
->section
!= absolute_section
)
1159 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
1160 _("non-absolute expression in constant field"));
1162 image
= bfd_getl32(fixpos
);
1163 image
= insert_operand(image
, operand
, (offsetT
)value
,
1164 fixP
->fx_file
, fixP
->fx_line
);
1169 if (fixP
->fx_addsy
!= 0 || fixP
->fx_pcrel
!= 0)
1173 as_warn_where(fixP
->fx_file
, fixP
->fx_line
,
1174 _("type %d reloc done?\n"), (int)fixP
->fx_r_type
);
1179 md_number_to_chars(fixpos
, image
, 4);
1187 * Look for a register name in the given symbol.
1191 md_undefined_symbol(name
)
1196 int is_float
= 0, num
;
1201 if (name
[1] == 'p' && name
[2] == '\0')
1202 return alpha_register_table
[AXP_REG_FP
];
1207 if (!isdigit(*++name
))
1211 case '0': case '1': case '2': case '3': case '4':
1212 case '5': case '6': case '7': case '8': case '9':
1213 if (name
[1] == '\0')
1214 num
= name
[0] - '0';
1215 else if (name
[0] != '0' && isdigit(name
[1]) && name
[2] == '\0')
1217 num
= (name
[0] - '0') * 10 + name
[1] - '0';
1224 if (!alpha_noat_on
&& num
== AXP_REG_AT
)
1225 as_warn(_("Used $at without \".set noat\""));
1226 return alpha_register_table
[num
+ is_float
];
1229 if (name
[1] == 't' && name
[2] == '\0')
1232 as_warn(_("Used $at without \".set noat\""));
1233 return alpha_register_table
[AXP_REG_AT
];
1238 if (name
[1] == 'p' && name
[2] == '\0')
1239 return alpha_register_table
[alpha_gp_register
];
1243 if (name
[1] == 'p' && name
[2] == '\0')
1244 return alpha_register_table
[AXP_REG_SP
];
1252 /* @@@ Magic ECOFF bits. */
1255 alpha_frob_ecoff_data ()
1258 /* $zero and $f31 are read-only */
1259 alpha_gprmask
&= ~1;
1260 alpha_fprmask
&= ~1;
1264 /* Hook to remember a recently defined label so that the auto-align
1265 code can adjust the symbol after we know what alignment will be
1269 alpha_define_label (sym
)
1272 alpha_insn_label
= sym
;
1275 /* Return true if we must always emit a reloc for a type and false if
1276 there is some hope of resolving it a assembly time. */
1279 alpha_force_relocation (f
)
1282 if (alpha_flag_relax
)
1285 switch (f
->fx_r_type
)
1287 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1288 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1289 case BFD_RELOC_ALPHA_GPDISP
:
1291 case BFD_RELOC_ALPHA_LITERAL
:
1294 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1296 case BFD_RELOC_ALPHA_LITUSE
:
1297 case BFD_RELOC_GPREL32
:
1299 case BFD_RELOC_ALPHA_LINKAGE
:
1300 case BFD_RELOC_ALPHA_CODEADDR
:
1304 case BFD_RELOC_23_PCREL_S2
:
1307 case BFD_RELOC_ALPHA_HINT
:
1311 assert((int)f
->fx_r_type
< 0 && -(int)f
->fx_r_type
< alpha_num_operands
);
1316 /* Return true if we can partially resolve a relocation now. */
1319 alpha_fix_adjustable (f
)
1323 /* Prevent all adjustments to global symbols */
1324 if (S_IS_EXTERN (f
->fx_addsy
))
1328 /* Are there any relocation types for which we must generate a reloc
1329 but we can adjust the values contained within it? */
1330 switch (f
->fx_r_type
)
1332 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1333 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1334 case BFD_RELOC_ALPHA_GPDISP
:
1338 case BFD_RELOC_ALPHA_LITERAL
:
1341 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1344 case BFD_RELOC_ALPHA_LINKAGE
:
1345 case BFD_RELOC_ALPHA_CODEADDR
:
1349 case BFD_RELOC_ALPHA_LITUSE
:
1352 case BFD_RELOC_GPREL32
:
1353 case BFD_RELOC_23_PCREL_S2
:
1356 case BFD_RELOC_ALPHA_HINT
:
1360 assert ((int)f
->fx_r_type
< 0
1361 && - (int)f
->fx_r_type
< alpha_num_operands
);
1367 /* Generate the BFD reloc to be stuck in the object file from the
1368 fixup used internally in the assembler. */
1371 tc_gen_reloc (sec
, fixp
)
1377 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
1378 reloc
->sym_ptr_ptr
= &fixp
->fx_addsy
->bsym
;
1379 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
1381 /* Make sure none of our internal relocations make it this far.
1382 They'd better have been fully resolved by this point. */
1383 assert ((int)fixp
->fx_r_type
> 0);
1385 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
1386 if (reloc
->howto
== NULL
)
1388 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1389 _("cannot represent `%s' relocation in object file"),
1390 bfd_get_reloc_code_name (fixp
->fx_r_type
));
1394 if (!fixp
->fx_pcrel
!= !reloc
->howto
->pc_relative
)
1396 as_fatal (_("internal error? cannot generate `%s' relocation"),
1397 bfd_get_reloc_code_name (fixp
->fx_r_type
));
1399 assert (!fixp
->fx_pcrel
== !reloc
->howto
->pc_relative
);
1402 if (fixp
->fx_r_type
== BFD_RELOC_ALPHA_LITERAL
)
1404 /* fake out bfd_perform_relocation. sigh */
1405 reloc
->addend
= -alpha_gp_value
;
1410 reloc
->addend
= fixp
->fx_offset
;
1413 * Ohhh, this is ugly. The problem is that if this is a local global
1414 * symbol, the relocation will entirely be performed at link time, not
1415 * at assembly time. bfd_perform_reloc doesn't know about this sort
1416 * of thing, and as a result we need to fake it out here.
1418 if (S_IS_EXTERN (fixp
->fx_addsy
) && !S_IS_COMMON(fixp
->fx_addsy
))
1419 reloc
->addend
-= fixp
->fx_addsy
->bsym
->value
;
1426 /* Parse a register name off of the input_line and return a register
1427 number. Gets md_undefined_symbol above to do the register name
1430 Only called as a part of processing the ECOFF .frame directive. */
1433 tc_get_register (frame
)
1436 int framereg
= AXP_REG_SP
;
1439 if (*input_line_pointer
== '$')
1441 char *s
= input_line_pointer
;
1442 char c
= get_symbol_end ();
1443 symbolS
*sym
= md_undefined_symbol (s
);
1445 *strchr(s
, '\0') = c
;
1446 if (sym
&& (framereg
= S_GET_VALUE (sym
)) <= 31)
1449 as_warn (_("frame reg expected, using $%d."), framereg
);
1452 note_gpreg (framereg
);
1456 /* This is called before the symbol table is processed. In order to
1457 work with gcc when using mips-tfile, we must keep all local labels.
1458 However, in other cases, we want to discard them. If we were
1459 called with -g, but we didn't see any debugging information, it may
1460 mean that gcc is smuggling debugging information through to
1461 mips-tfile, in which case we must generate all local labels. */
1466 alpha_frob_file_before_adjust ()
1468 if (alpha_debug
!= 0
1469 && ! ecoff_debugging_seen
)
1470 flag_keep_locals
= 1;
1473 #endif /* OBJ_ECOFF */
1475 /* Parse the arguments to an opcode. */
1478 tokenize_arguments (str
, tok
, ntok
)
1483 expressionS
*end_tok
= tok
+ ntok
;
1484 char *old_input_line_pointer
;
1485 int saw_comma
= 0, saw_arg
= 0;
1487 memset (tok
, 0, sizeof (*tok
) * ntok
);
1489 /* Save and restore input_line_pointer around this function */
1490 old_input_line_pointer
= input_line_pointer
;
1491 input_line_pointer
= str
;
1493 while (tok
< end_tok
&& *input_line_pointer
)
1496 switch (*input_line_pointer
)
1502 ++input_line_pointer
;
1503 if (saw_comma
|| !saw_arg
)
1510 char *hold
= input_line_pointer
++;
1512 /* First try for parenthesized register ... */
1514 if (*input_line_pointer
== ')' && tok
->X_op
== O_register
)
1516 tok
->X_op
= (saw_comma
? O_cpregister
: O_pregister
);
1519 ++input_line_pointer
;
1524 /* ... then fall through to plain expression */
1525 input_line_pointer
= hold
;
1529 if (saw_arg
&& !saw_comma
)
1532 if (tok
->X_op
== O_illegal
|| tok
->X_op
== O_absent
)
1545 input_line_pointer
= old_input_line_pointer
;
1546 return ntok
- (end_tok
- tok
);
1549 input_line_pointer
= old_input_line_pointer
;
1553 /* Search forward through all variants of an opcode looking for a
1556 static const struct alpha_opcode
*
1557 find_opcode_match(first_opcode
, tok
, pntok
, pcpumatch
)
1558 const struct alpha_opcode
*first_opcode
;
1559 const expressionS
*tok
;
1563 const struct alpha_opcode
*opcode
= first_opcode
;
1565 int got_cpu_match
= 0;
1569 const unsigned char *opidx
;
1572 /* Don't match opcodes that don't exist on this architecture */
1573 if (!(opcode
->flags
& alpha_target
))
1578 for (opidx
= opcode
->operands
; *opidx
; ++opidx
)
1580 const struct alpha_operand
*operand
= &alpha_operands
[*opidx
];
1582 /* only take input from real operands */
1583 if (operand
->flags
& AXP_OPERAND_FAKE
)
1586 /* when we expect input, make sure we have it */
1589 if ((operand
->flags
& AXP_OPERAND_OPTIONAL_MASK
) == 0)
1594 /* match operand type with expression type */
1595 switch (operand
->flags
& AXP_OPERAND_TYPECHECK_MASK
)
1597 case AXP_OPERAND_IR
:
1598 if (tok
[tokidx
].X_op
!= O_register
1599 || !is_ir_num(tok
[tokidx
].X_add_number
))
1602 case AXP_OPERAND_FPR
:
1603 if (tok
[tokidx
].X_op
!= O_register
1604 || !is_fpr_num(tok
[tokidx
].X_add_number
))
1607 case AXP_OPERAND_IR
|AXP_OPERAND_PARENS
:
1608 if (tok
[tokidx
].X_op
!= O_pregister
1609 || !is_ir_num(tok
[tokidx
].X_add_number
))
1612 case AXP_OPERAND_IR
|AXP_OPERAND_PARENS
|AXP_OPERAND_COMMA
:
1613 if (tok
[tokidx
].X_op
!= O_cpregister
1614 || !is_ir_num(tok
[tokidx
].X_add_number
))
1618 case AXP_OPERAND_RELATIVE
:
1619 case AXP_OPERAND_SIGNED
:
1620 case AXP_OPERAND_UNSIGNED
:
1621 switch (tok
[tokidx
].X_op
)
1633 /* everything else should have been fake */
1639 /* possible match -- did we use all of our input? */
1648 while (++opcode
-alpha_opcodes
< alpha_num_opcodes
1649 && !strcmp(opcode
->name
, first_opcode
->name
));
1652 *pcpumatch
= got_cpu_match
;
1657 /* Search forward through all variants of a macro looking for a syntax
1660 static const struct alpha_macro
*
1661 find_macro_match(first_macro
, tok
, pntok
)
1662 const struct alpha_macro
*first_macro
;
1663 const expressionS
*tok
;
1666 const struct alpha_macro
*macro
= first_macro
;
1671 const enum alpha_macro_arg
*arg
= macro
->argsets
;
1686 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_register
1687 || !is_ir_num(tok
[tokidx
].X_add_number
))
1692 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_pregister
1693 || !is_ir_num(tok
[tokidx
].X_add_number
))
1698 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_cpregister
1699 || !is_ir_num(tok
[tokidx
].X_add_number
))
1704 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_register
1705 || !is_fpr_num(tok
[tokidx
].X_add_number
))
1713 switch (tok
[tokidx
].X_op
)
1726 while (*arg
!= MACRO_EOA
)
1734 while (++macro
-alpha_macros
< alpha_num_macros
1735 && !strcmp(macro
->name
, first_macro
->name
));
1740 /* Insert an operand value into an instruction. */
1743 insert_operand(insn
, operand
, val
, file
, line
)
1745 const struct alpha_operand
*operand
;
1750 if (operand
->bits
!= 32 && !(operand
->flags
& AXP_OPERAND_NOOVERFLOW
))
1754 if (operand
->flags
& AXP_OPERAND_SIGNED
)
1756 max
= (1 << (operand
->bits
- 1)) - 1;
1757 min
= -(1 << (operand
->bits
- 1));
1761 max
= (1 << operand
->bits
) - 1;
1765 if (val
< min
|| val
> max
)
1768 _("operand out of range (%s not between %d and %d)");
1769 char buf
[sizeof (val
) * 3 + 2];
1771 sprint_value(buf
, val
);
1773 as_warn_where(file
, line
, err
, buf
, min
, max
);
1775 as_warn(err
, buf
, min
, max
);
1779 if (operand
->insert
)
1781 const char *errmsg
= NULL
;
1783 insn
= (*operand
->insert
) (insn
, val
, &errmsg
);
1788 insn
|= ((val
& ((1 << operand
->bits
) - 1)) << operand
->shift
);
1794 * Turn an opcode description and a set of arguments into
1795 * an instruction and a fixup.
1799 assemble_insn(opcode
, tok
, ntok
, insn
)
1800 const struct alpha_opcode
*opcode
;
1801 const expressionS
*tok
;
1803 struct alpha_insn
*insn
;
1805 const unsigned char *argidx
;
1809 memset (insn
, 0, sizeof (*insn
));
1810 image
= opcode
->opcode
;
1812 for (argidx
= opcode
->operands
; *argidx
; ++argidx
)
1814 const struct alpha_operand
*operand
= &alpha_operands
[*argidx
];
1815 const expressionS
*t
;
1817 if (operand
->flags
& AXP_OPERAND_FAKE
)
1819 /* fake operands take no value and generate no fixup */
1820 image
= insert_operand(image
, operand
, 0, NULL
, 0);
1826 switch (operand
->flags
& AXP_OPERAND_OPTIONAL_MASK
)
1828 case AXP_OPERAND_DEFAULT_FIRST
:
1831 case AXP_OPERAND_DEFAULT_SECOND
:
1834 case AXP_OPERAND_DEFAULT_ZERO
:
1836 static const expressionS zero_exp
= { 0, 0, 0, O_constant
, 1 };
1852 image
= insert_operand(image
, operand
, regno(t
->X_add_number
),
1857 image
= insert_operand(image
, operand
, t
->X_add_number
, NULL
, 0);
1862 struct alpha_fixup
*fixup
;
1864 if (insn
->nfixups
>= MAX_INSN_FIXUPS
)
1865 as_fatal(_("too many fixups"));
1867 fixup
= &insn
->fixups
[insn
->nfixups
++];
1870 fixup
->reloc
= operand
->default_reloc
;
1880 * Actually output an instruction with its fixup.
1885 struct alpha_insn
*insn
;
1890 /* Take care of alignment duties */
1891 if (alpha_auto_align_on
&& alpha_current_align
< 2)
1892 alpha_align (2, (char *) NULL
, alpha_insn_label
, 0);
1893 if (alpha_current_align
> 2)
1894 alpha_current_align
= 2;
1895 alpha_insn_label
= NULL
;
1897 /* Write out the instruction. */
1899 md_number_to_chars (f
, insn
->insn
, 4);
1901 /* Apply the fixups in order */
1902 for (i
= 0; i
< insn
->nfixups
; ++i
)
1904 struct alpha_fixup
*fixup
= &insn
->fixups
[i
];
1908 /* Some fixups are only used internally and so have no howto */
1909 if ((int)fixup
->reloc
< 0)
1910 size
= 4, pcrel
= 0;
1912 /* These relocation types are only used internally. */
1913 else if (fixup
->reloc
== BFD_RELOC_ALPHA_GPDISP_HI16
1914 || fixup
->reloc
== BFD_RELOC_ALPHA_GPDISP_LO16
)
1916 size
= 2, pcrel
= 0;
1921 reloc_howto_type
*reloc_howto
1922 = bfd_reloc_type_lookup (stdoutput
, fixup
->reloc
);
1923 assert (reloc_howto
);
1925 size
= bfd_get_reloc_size (reloc_howto
);
1926 pcrel
= reloc_howto
->pc_relative
;
1928 assert (size
>= 1 && size
<= 4);
1930 fixP
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, size
,
1931 &fixup
->exp
, pcrel
, fixup
->reloc
);
1933 /* Turn off complaints that the addend is too large for some fixups */
1934 switch (fixup
->reloc
)
1936 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1938 case BFD_RELOC_ALPHA_LITERAL
:
1941 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1943 case BFD_RELOC_GPREL32
:
1944 fixP
->fx_no_overflow
= 1;
1952 /* Given an opcode name and a pre-tokenized set of arguments, assemble
1953 the insn, but do not emit it.
1955 Note that this implies no macros allowed, since we can't store more
1956 than one insn in an insn structure. */
1959 assemble_tokens_to_insn(opname
, tok
, ntok
, insn
)
1961 const expressionS
*tok
;
1963 struct alpha_insn
*insn
;
1965 const struct alpha_opcode
*opcode
;
1967 /* search opcodes */
1968 opcode
= (const struct alpha_opcode
*) hash_find (alpha_opcode_hash
, opname
);
1972 opcode
= find_opcode_match (opcode
, tok
, &ntok
, &cpumatch
);
1975 assemble_insn (opcode
, tok
, ntok
, insn
);
1979 as_bad (_("inappropriate arguments for opcode `%s'"), opname
);
1981 as_bad (_("opcode `%s' not supported for target %s"), opname
,
1985 as_bad (_("unknown opcode `%s'"), opname
);
1988 /* Given an opcode name and a pre-tokenized set of arguments, take the
1989 opcode all the way through emission. */
1992 assemble_tokens (opname
, tok
, ntok
, local_macros_on
)
1994 const expressionS
*tok
;
1996 int local_macros_on
;
1998 int found_something
= 0;
1999 const struct alpha_opcode
*opcode
;
2000 const struct alpha_macro
*macro
;
2004 if (local_macros_on
)
2006 macro
= ((const struct alpha_macro
*)
2007 hash_find (alpha_macro_hash
, opname
));
2010 found_something
= 1;
2011 macro
= find_macro_match (macro
, tok
, &ntok
);
2014 (*macro
->emit
) (tok
, ntok
, macro
->arg
);
2020 /* search opcodes */
2021 opcode
= (const struct alpha_opcode
*) hash_find (alpha_opcode_hash
, opname
);
2024 found_something
= 1;
2025 opcode
= find_opcode_match (opcode
, tok
, &ntok
, &cpumatch
);
2028 struct alpha_insn insn
;
2029 assemble_insn (opcode
, tok
, ntok
, &insn
);
2035 if (found_something
)
2037 as_bad (_("inappropriate arguments for opcode `%s'"), opname
);
2039 as_bad (_("opcode `%s' not supported for target %s"), opname
,
2042 as_bad (_("unknown opcode `%s'"), opname
);
2046 /* Some instruction sets indexed by lg(size) */
2047 static const char * const sextX_op
[] = { "sextb", "sextw", "sextl", NULL
};
2048 static const char * const insXl_op
[] = { "insbl", "inswl", "insll", "insql" };
2049 static const char * const insXh_op
[] = { NULL
, "inswh", "inslh", "insqh" };
2050 static const char * const extXl_op
[] = { "extbl", "extwl", "extll", "extql" };
2051 static const char * const extXh_op
[] = { NULL
, "extwh", "extlh", "extqh" };
2052 static const char * const mskXl_op
[] = { "mskbl", "mskwl", "mskll", "mskql" };
2053 static const char * const mskXh_op
[] = { NULL
, "mskwh", "msklh", "mskqh" };
2054 static const char * const stX_op
[] = { "stb", "stw", "stl", "stq" };
2055 static const char * const ldX_op
[] = { "ldb", "ldw", "ldll", "ldq" };
2056 static const char * const ldXu_op
[] = { "ldbu", "ldwu", NULL
, NULL
};
2058 /* Implement the ldgp macro. */
2061 emit_ldgp (tok
, ntok
, unused
)
2062 const expressionS
*tok
;
2069 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
2070 /* from "ldgp r1,n(r2)", generate "ldah r1,X(R2); lda r1,Y(r1)"
2071 with appropriate constants and relocations. */
2072 struct alpha_insn insn
;
2073 expressionS newtok
[3];
2076 /* We're going to need this symbol in md_apply_fix(). */
2077 (void) section_symbol (absolute_section
);
2080 if (regno (tok
[2].X_add_number
) == AXP_REG_PV
)
2081 ecoff_set_gp_prolog_size (0);
2085 set_tok_const (newtok
[1], 0);
2088 assemble_tokens_to_insn ("ldah", newtok
, 3, &insn
);
2093 assert (addend
.X_op
== O_constant
);
2094 addend
.X_op
= O_symbol
;
2095 addend
.X_add_symbol
= alpha_gp_symbol
;
2099 insn
.fixups
[0].exp
= addend
;
2100 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_GPDISP_HI16
;
2104 set_tok_preg (newtok
[2], tok
[0].X_add_number
);
2106 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
2109 addend
.X_add_number
+= 4;
2113 insn
.fixups
[0].exp
= addend
;
2114 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_GPDISP_LO16
;
2117 #endif /* OBJ_ECOFF || OBJ_ELF */
2122 /* Add symbol+addend to link pool.
2123 Return offset from basesym to entry in link pool.
2125 Add new fixup only if offset isn't 16bit. */
2128 add_to_link_pool (basesym
, sym
, addend
)
2133 segT current_section
= now_seg
;
2134 int current_subsec
= now_subseg
;
2136 bfd_reloc_code_real_type reloc_type
;
2138 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
2141 offset
= -basesym
->sy_obj
;
2143 /* @@ This assumes all entries in a given section will be of the same
2144 size... Probably correct, but unwise to rely on. */
2145 /* This must always be called with the same subsegment. */
2147 if (seginfo
->frchainP
)
2148 for (fixp
= seginfo
->frchainP
->fix_root
;
2149 fixp
!= (fixS
*) NULL
;
2150 fixp
= fixp
->fx_next
, offset
+= 8)
2152 if (fixp
->fx_addsy
== sym
&& fixp
->fx_offset
== addend
)
2154 if (range_signed_16 (offset
))
2161 /* Not found in 16bit signed range. */
2163 subseg_set (alpha_link_section
, 0);
2167 fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, sym
, addend
, 0,
2170 subseg_set (current_section
, current_subsec
);
2171 seginfo
->literal_pool_size
+= 8;
2175 #endif /* OBJ_EVAX */
2177 /* Load a (partial) expression into a target register.
2179 If poffset is not null, after the call it will either contain
2180 O_constant 0, or a 16-bit offset appropriate for any MEM format
2181 instruction. In addition, pbasereg will be modified to point to
2182 the base register to use in that MEM format instruction.
2184 In any case, *pbasereg should contain a base register to add to the
2185 expression. This will normally be either AXP_REG_ZERO or
2186 alpha_gp_register. Symbol addresses will always be loaded via $gp,
2187 so "foo($0)" is interpreted as adding the address of foo to $0;
2188 i.e. "ldq $targ, LIT($gp); addq $targ, $0, $targ". Odd, perhaps,
2189 but this is what OSF/1 does.
2191 Finally, the return value is true if the calling macro may emit a
2192 LITUSE reloc if otherwise appropriate. */
2195 load_expression (targreg
, exp
, pbasereg
, poffset
)
2197 const expressionS
*exp
;
2199 expressionS
*poffset
;
2201 int emit_lituse
= 0;
2202 offsetT addend
= exp
->X_add_number
;
2203 int basereg
= *pbasereg
;
2204 struct alpha_insn insn
;
2205 expressionS newtok
[3];
2214 /* attempt to reduce .lit load by splitting the offset from
2215 its symbol when possible, but don't create a situation in
2217 if (!range_signed_32 (addend
) &&
2218 (alpha_noat_on
|| targreg
== AXP_REG_AT
))
2220 lit
= add_to_literal_pool (exp
->X_add_symbol
, addend
,
2221 alpha_lita_section
, 8);
2226 lit
= add_to_literal_pool (exp
->X_add_symbol
, 0,
2227 alpha_lita_section
, 8);
2231 as_fatal (_("overflow in literal (.lita) table"));
2233 /* emit "ldq r, lit(gp)" */
2235 if (basereg
!= alpha_gp_register
&& targreg
== basereg
)
2238 as_bad (_("macro requires $at register while noat in effect"));
2239 if (targreg
== AXP_REG_AT
)
2240 as_bad (_("macro requires $at while $at in use"));
2242 set_tok_reg (newtok
[0], AXP_REG_AT
);
2245 set_tok_reg (newtok
[0], targreg
);
2246 set_tok_sym (newtok
[1], alpha_lita_symbol
, lit
);
2247 set_tok_preg (newtok
[2], alpha_gp_register
);
2249 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
2251 assert (insn
.nfixups
== 1);
2252 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITERAL
;
2253 #endif /* OBJ_ECOFF */
2255 /* emit "ldq r, gotoff(gp)" */
2257 if (basereg
!= alpha_gp_register
&& targreg
== basereg
)
2260 as_bad (_("macro requires $at register while noat in effect"));
2261 if (targreg
== AXP_REG_AT
)
2262 as_bad (_("macro requires $at while $at in use"));
2264 set_tok_reg (newtok
[0], AXP_REG_AT
);
2267 set_tok_reg (newtok
[0], targreg
);
2269 /* XXX: Disable this .got minimizing optimization so that we can get
2270 better instruction offset knowledge in the compiler. This happens
2271 very infrequently anyway. */
2272 if (1 || !range_signed_32 (addend
)
2273 && (alpha_noat_on
|| targreg
== AXP_REG_AT
))
2280 set_tok_sym (newtok
[1], exp
->X_add_symbol
, 0);
2283 set_tok_preg (newtok
[2], alpha_gp_register
);
2285 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
2287 assert (insn
.nfixups
== 1);
2288 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_ELF_LITERAL
;
2289 #endif /* OBJ_ELF */
2293 /* Find symbol or symbol pointer in link section. */
2295 if (exp
->X_add_symbol
== alpha_evax_proc
.symbol
)
2297 if (range_signed_16 (addend
))
2299 set_tok_reg (newtok
[0], targreg
);
2300 set_tok_const (newtok
[1], addend
);
2301 set_tok_preg (newtok
[2], basereg
);
2302 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
2307 set_tok_reg (newtok
[0], targreg
);
2308 set_tok_const (newtok
[1], 0);
2309 set_tok_preg (newtok
[2], basereg
);
2310 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
2315 if (!range_signed_32 (addend
))
2317 link
= add_to_link_pool (alpha_evax_proc
.symbol
,
2318 exp
->X_add_symbol
, addend
);
2323 link
= add_to_link_pool (alpha_evax_proc
.symbol
,
2324 exp
->X_add_symbol
, 0);
2326 set_tok_reg (newtok
[0], targreg
);
2327 set_tok_const (newtok
[1], link
);
2328 set_tok_preg (newtok
[2], basereg
);
2329 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
2331 #endif /* OBJ_EVAX */
2338 if (basereg
!= alpha_gp_register
&& basereg
!= AXP_REG_ZERO
)
2340 /* emit "addq r, base, r" */
2342 set_tok_reg (newtok
[1], basereg
);
2343 set_tok_reg (newtok
[2], targreg
);
2344 assemble_tokens ("addq", newtok
, 3, 0);
2356 /* Assume that this difference expression will be resolved to an
2357 absolute value and that that value will fit in 16 bits. */
2359 set_tok_reg (newtok
[0], targreg
);
2361 set_tok_preg (newtok
[2], basereg
);
2362 assemble_tokens ("lda", newtok
, 3, 0);
2365 set_tok_const (*poffset
, 0);
2369 if (exp
->X_add_number
> 0)
2370 as_bad (_("bignum invalid; zero assumed"));
2372 as_bad (_("floating point number invalid; zero assumed"));
2380 if (!range_signed_32 (addend
))
2384 /* for 64-bit addends, just put it in the literal pool */
2387 /* emit "ldq targreg, lit(basereg)" */
2388 lit
= add_to_link_pool (alpha_evax_proc
.symbol
,
2389 section_symbol (absolute_section
), addend
);
2390 set_tok_reg (newtok
[0], targreg
);
2391 set_tok_const (newtok
[1], lit
);
2392 set_tok_preg (newtok
[2], alpha_gp_register
);
2393 assemble_tokens ("ldq", newtok
, 3, 0);
2396 if (alpha_lit8_section
== NULL
)
2398 create_literal_section (".lit8",
2399 &alpha_lit8_section
,
2400 &alpha_lit8_symbol
);
2403 alpha_lit8_literal
= add_to_literal_pool (alpha_lit8_symbol
, 0x8000,
2404 alpha_lita_section
, 8);
2405 if (alpha_lit8_literal
>= 0x8000)
2406 as_fatal (_("overflow in literal (.lita) table"));
2410 lit
= add_to_literal_pool (NULL
, addend
, alpha_lit8_section
, 8) - 0x8000;
2412 as_fatal (_("overflow in literal (.lit8) table"));
2414 /* emit "lda litreg, .lit8+0x8000" */
2416 if (targreg
== basereg
)
2419 as_bad (_("macro requires $at register while noat in effect"));
2420 if (targreg
== AXP_REG_AT
)
2421 as_bad (_("macro requires $at while $at in use"));
2423 set_tok_reg (newtok
[0], AXP_REG_AT
);
2426 set_tok_reg (newtok
[0], targreg
);
2428 set_tok_sym (newtok
[1], alpha_lita_symbol
, alpha_lit8_literal
);
2431 set_tok_sym (newtok
[1], alpha_lit8_symbol
, 0x8000);
2433 set_tok_preg (newtok
[2], alpha_gp_register
);
2435 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
2437 assert (insn
.nfixups
== 1);
2439 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITERAL
;
2442 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_ELF_LITERAL
;
2447 /* emit "ldq litreg, lit(litreg)" */
2449 set_tok_const (newtok
[1], lit
);
2450 set_tok_preg (newtok
[2], newtok
[0].X_add_number
);
2452 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
2454 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
2455 if (insn
.nfixups
> 0)
2457 memmove (&insn
.fixups
[1], &insn
.fixups
[0],
2458 sizeof(struct alpha_fixup
) * insn
.nfixups
);
2461 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITUSE
;
2462 insn
.fixups
[0].exp
.X_op
= O_constant
;
2463 insn
.fixups
[0].exp
.X_add_number
= 1;
2468 /* emit "addq litreg, base, target" */
2470 if (basereg
!= AXP_REG_ZERO
)
2472 set_tok_reg (newtok
[1], basereg
);
2473 set_tok_reg (newtok
[2], targreg
);
2474 assemble_tokens ("addq", newtok
, 3, 0);
2476 #endif /* !OBJ_EVAX */
2479 set_tok_const (*poffset
, 0);
2480 *pbasereg
= targreg
;
2484 offsetT low
, high
, extra
, tmp
;
2486 /* for 32-bit operands, break up the addend */
2488 low
= sign_extend_16 (addend
);
2490 high
= sign_extend_16 (tmp
>> 16);
2492 if (tmp
- (high
<< 16))
2496 high
= sign_extend_16 (tmp
>> 16);
2501 set_tok_reg (newtok
[0], targreg
);
2502 set_tok_preg (newtok
[2], basereg
);
2506 /* emit "ldah r, extra(r) */
2507 set_tok_const (newtok
[1], extra
);
2508 assemble_tokens ("ldah", newtok
, 3, 0);
2509 set_tok_preg (newtok
[2], basereg
= targreg
);
2514 /* emit "ldah r, high(r) */
2515 set_tok_const (newtok
[1], high
);
2516 assemble_tokens ("ldah", newtok
, 3, 0);
2518 set_tok_preg (newtok
[2], basereg
);
2521 if ((low
&& !poffset
) || (!poffset
&& basereg
!= targreg
))
2523 /* emit "lda r, low(base)" */
2524 set_tok_const (newtok
[1], low
);
2525 assemble_tokens ("lda", newtok
, 3, 0);
2531 set_tok_const (*poffset
, low
);
2532 *pbasereg
= basereg
;
2538 /* The lda macro differs from the lda instruction in that it handles
2539 most simple expressions, particualrly symbol address loads and
2543 emit_lda (tok
, ntok
, unused
)
2544 const expressionS
*tok
;
2551 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
2553 basereg
= tok
[2].X_add_number
;
2555 (void) load_expression (tok
[0].X_add_number
, &tok
[1], &basereg
, NULL
);
2558 /* The ldah macro differs from the ldah instruction in that it has $31
2559 as an implied base register. */
2562 emit_ldah (tok
, ntok
, unused
)
2563 const expressionS
*tok
;
2567 expressionS newtok
[3];
2571 set_tok_preg (newtok
[2], AXP_REG_ZERO
);
2573 assemble_tokens ("ldah", newtok
, 3, 0);
2576 /* Handle all "simple" integer register loads -- ldq, ldq_l, ldq_u,
2577 etc. They differ from the real instructions in that they do simple
2578 expressions like the lda macro. */
2581 emit_ir_load (tok
, ntok
, opname
)
2582 const expressionS
*tok
;
2586 int basereg
, lituse
;
2587 expressionS newtok
[3];
2588 struct alpha_insn insn
;
2591 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
2593 basereg
= tok
[2].X_add_number
;
2595 lituse
= load_expression (tok
[0].X_add_number
, &tok
[1], &basereg
,
2599 set_tok_preg (newtok
[2], basereg
);
2601 assemble_tokens_to_insn ((const char *)opname
, newtok
, 3, &insn
);
2605 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
2606 if (insn
.nfixups
> 0)
2608 memmove (&insn
.fixups
[1], &insn
.fixups
[0],
2609 sizeof(struct alpha_fixup
) * insn
.nfixups
);
2612 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITUSE
;
2613 insn
.fixups
[0].exp
.X_op
= O_constant
;
2614 insn
.fixups
[0].exp
.X_add_number
= 1;
2620 /* Handle fp register loads, and both integer and fp register stores.
2621 Again, we handle simple expressions. */
2624 emit_loadstore (tok
, ntok
, opname
)
2625 const expressionS
*tok
;
2629 int basereg
, lituse
;
2630 expressionS newtok
[3];
2631 struct alpha_insn insn
;
2634 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
2636 basereg
= tok
[2].X_add_number
;
2638 if (tok
[1].X_op
!= O_constant
|| !range_signed_16(tok
[1].X_add_number
))
2641 as_bad (_("macro requires $at register while noat in effect"));
2643 lituse
= load_expression (AXP_REG_AT
, &tok
[1], &basereg
, &newtok
[1]);
2652 set_tok_preg (newtok
[2], basereg
);
2654 assemble_tokens_to_insn ((const char *)opname
, newtok
, 3, &insn
);
2658 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
2659 if (insn
.nfixups
> 0)
2661 memmove (&insn
.fixups
[1], &insn
.fixups
[0],
2662 sizeof(struct alpha_fixup
) * insn
.nfixups
);
2665 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITUSE
;
2666 insn
.fixups
[0].exp
.X_op
= O_constant
;
2667 insn
.fixups
[0].exp
.X_add_number
= 1;
2673 /* Load a half-word or byte as an unsigned value. */
2676 emit_ldXu (tok
, ntok
, vlgsize
)
2677 const expressionS
*tok
;
2681 if (alpha_target
& AXP_OPCODE_BWX
)
2682 emit_ir_load (tok
, ntok
, ldXu_op
[(long)vlgsize
]);
2685 expressionS newtok
[3];
2688 as_bad (_("macro requires $at register while noat in effect"));
2690 /* emit "lda $at, exp" */
2692 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
2693 newtok
[0].X_add_number
= AXP_REG_AT
;
2694 assemble_tokens ("lda", newtok
, ntok
, 1);
2696 /* emit "ldq_u targ, 0($at)" */
2699 set_tok_const (newtok
[1], 0);
2700 set_tok_preg (newtok
[2], AXP_REG_AT
);
2701 assemble_tokens ("ldq_u", newtok
, 3, 1);
2703 /* emit "extXl targ, $at, targ" */
2705 set_tok_reg (newtok
[1], AXP_REG_AT
);
2706 newtok
[2] = newtok
[0];
2707 assemble_tokens (extXl_op
[(long)vlgsize
], newtok
, 3, 1);
2711 /* Load a half-word or byte as a signed value. */
2714 emit_ldX (tok
, ntok
, vlgsize
)
2715 const expressionS
*tok
;
2719 emit_ldXu (tok
, ntok
, vlgsize
);
2720 assemble_tokens (sextX_op
[(long)vlgsize
], tok
, 1, 1);
2723 /* Load an integral value from an unaligned address as an unsigned
2727 emit_uldXu (tok
, ntok
, vlgsize
)
2728 const expressionS
*tok
;
2732 long lgsize
= (long)vlgsize
;
2733 expressionS newtok
[3];
2736 as_bad (_("macro requires $at register while noat in effect"));
2738 /* emit "lda $at, exp" */
2740 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
2741 newtok
[0].X_add_number
= AXP_REG_AT
;
2742 assemble_tokens ("lda", newtok
, ntok
, 1);
2744 /* emit "ldq_u $t9, 0($at)" */
2746 set_tok_reg (newtok
[0], AXP_REG_T9
);
2747 set_tok_const (newtok
[1], 0);
2748 set_tok_preg (newtok
[2], AXP_REG_AT
);
2749 assemble_tokens ("ldq_u", newtok
, 3, 1);
2751 /* emit "ldq_u $t10, size-1($at)" */
2753 set_tok_reg (newtok
[0], AXP_REG_T10
);
2754 set_tok_const (newtok
[1], (1<<lgsize
)-1);
2755 assemble_tokens ("ldq_u", newtok
, 3, 1);
2757 /* emit "extXl $t9, $at, $t9" */
2759 set_tok_reg (newtok
[0], AXP_REG_T9
);
2760 set_tok_reg (newtok
[1], AXP_REG_AT
);
2761 set_tok_reg (newtok
[2], AXP_REG_T9
);
2762 assemble_tokens (extXl_op
[lgsize
], newtok
, 3, 1);
2764 /* emit "extXh $t10, $at, $t10" */
2766 set_tok_reg (newtok
[0], AXP_REG_T10
);
2767 set_tok_reg (newtok
[2], AXP_REG_T10
);
2768 assemble_tokens (extXh_op
[lgsize
], newtok
, 3, 1);
2770 /* emit "or $t9, $t10, targ" */
2772 set_tok_reg (newtok
[0], AXP_REG_T9
);
2773 set_tok_reg (newtok
[1], AXP_REG_T10
);
2775 assemble_tokens ("or", newtok
, 3, 1);
2778 /* Load an integral value from an unaligned address as a signed value.
2779 Note that quads should get funneled to the unsigned load since we
2780 don't have to do the sign extension. */
2783 emit_uldX (tok
, ntok
, vlgsize
)
2784 const expressionS
*tok
;
2788 emit_uldXu (tok
, ntok
, vlgsize
);
2789 assemble_tokens (sextX_op
[(long)vlgsize
], tok
, 1, 1);
2792 /* Implement the ldil macro. */
2795 emit_ldil (tok
, ntok
, unused
)
2796 const expressionS
*tok
;
2800 expressionS newtok
[2];
2802 memcpy (newtok
, tok
, sizeof(newtok
));
2803 newtok
[1].X_add_number
= sign_extend_32 (tok
[1].X_add_number
);
2805 assemble_tokens ("lda", newtok
, ntok
, 1);
2808 /* Store a half-word or byte. */
2811 emit_stX (tok
, ntok
, vlgsize
)
2812 const expressionS
*tok
;
2816 int lgsize
= (int)(long)vlgsize
;
2818 if (alpha_target
& AXP_OPCODE_BWX
)
2819 emit_loadstore (tok
, ntok
, stX_op
[lgsize
]);
2822 expressionS newtok
[3];
2825 as_bad(_("macro requires $at register while noat in effect"));
2827 /* emit "lda $at, exp" */
2829 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
2830 newtok
[0].X_add_number
= AXP_REG_AT
;
2831 assemble_tokens ("lda", newtok
, ntok
, 1);
2833 /* emit "ldq_u $t9, 0($at)" */
2835 set_tok_reg (newtok
[0], AXP_REG_T9
);
2836 set_tok_const (newtok
[1], 0);
2837 set_tok_preg (newtok
[2], AXP_REG_AT
);
2838 assemble_tokens ("ldq_u", newtok
, 3, 1);
2840 /* emit "insXl src, $at, $t10" */
2843 set_tok_reg (newtok
[1], AXP_REG_AT
);
2844 set_tok_reg (newtok
[2], AXP_REG_T10
);
2845 assemble_tokens (insXl_op
[lgsize
], newtok
, 3, 1);
2847 /* emit "mskXl $t9, $at, $t9" */
2849 set_tok_reg (newtok
[0], AXP_REG_T9
);
2850 newtok
[2] = newtok
[0];
2851 assemble_tokens (mskXl_op
[lgsize
], newtok
, 3, 1);
2853 /* emit "or $t9, $t10, $t9" */
2855 set_tok_reg (newtok
[1], AXP_REG_T10
);
2856 assemble_tokens ("or", newtok
, 3, 1);
2858 /* emit "stq_u $t9, 0($at) */
2860 set_tok_const (newtok
[1], 0);
2861 set_tok_preg (newtok
[2], AXP_REG_AT
);
2862 assemble_tokens ("stq_u", newtok
, 3, 1);
2866 /* Store an integer to an unaligned address. */
2869 emit_ustX (tok
, ntok
, vlgsize
)
2870 const expressionS
*tok
;
2874 int lgsize
= (int)(long)vlgsize
;
2875 expressionS newtok
[3];
2877 /* emit "lda $at, exp" */
2879 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
2880 newtok
[0].X_add_number
= AXP_REG_AT
;
2881 assemble_tokens ("lda", newtok
, ntok
, 1);
2883 /* emit "ldq_u $9, 0($at)" */
2885 set_tok_reg (newtok
[0], AXP_REG_T9
);
2886 set_tok_const (newtok
[1], 0);
2887 set_tok_preg (newtok
[2], AXP_REG_AT
);
2888 assemble_tokens ("ldq_u", newtok
, 3, 1);
2890 /* emit "ldq_u $10, size-1($at)" */
2892 set_tok_reg (newtok
[0], AXP_REG_T10
);
2893 set_tok_const (newtok
[1], (1 << lgsize
)-1);
2894 assemble_tokens ("ldq_u", newtok
, 3, 1);
2896 /* emit "insXl src, $at, $t11" */
2899 set_tok_reg (newtok
[1], AXP_REG_AT
);
2900 set_tok_reg (newtok
[2], AXP_REG_T11
);
2901 assemble_tokens (insXl_op
[lgsize
], newtok
, 3, 1);
2903 /* emit "insXh src, $at, $t12" */
2905 set_tok_reg (newtok
[2], AXP_REG_T12
);
2906 assemble_tokens (insXh_op
[lgsize
], newtok
, 3, 1);
2908 /* emit "mskXl $t9, $at, $t9" */
2910 set_tok_reg (newtok
[0], AXP_REG_T9
);
2911 newtok
[2] = newtok
[0];
2912 assemble_tokens (mskXl_op
[lgsize
], newtok
, 3, 1);
2914 /* emit "mskXh $t10, $at, $t10" */
2916 set_tok_reg (newtok
[0], AXP_REG_T10
);
2917 newtok
[2] = newtok
[0];
2918 assemble_tokens (mskXh_op
[lgsize
], newtok
, 3, 1);
2920 /* emit "or $t9, $t11, $t9" */
2922 set_tok_reg (newtok
[0], AXP_REG_T9
);
2923 set_tok_reg (newtok
[1], AXP_REG_T11
);
2924 newtok
[2] = newtok
[0];
2925 assemble_tokens ("or", newtok
, 3, 1);
2927 /* emit "or $t10, $t12, $t10" */
2929 set_tok_reg (newtok
[0], AXP_REG_T10
);
2930 set_tok_reg (newtok
[1], AXP_REG_T12
);
2931 newtok
[2] = newtok
[0];
2932 assemble_tokens ("or", newtok
, 3, 1);
2934 /* emit "stq_u $t9, 0($at)" */
2936 set_tok_reg (newtok
[0], AXP_REG_T9
);
2937 set_tok_const (newtok
[1], 0);
2938 set_tok_preg (newtok
[2], AXP_REG_AT
);
2939 assemble_tokens ("stq_u", newtok
, 3, 1);
2941 /* emit "stq_u $t10, size-1($at)" */
2943 set_tok_reg (newtok
[0], AXP_REG_T10
);
2944 set_tok_const (newtok
[1], (1 << lgsize
)-1);
2945 assemble_tokens ("stq_u", newtok
, 3, 1);
2948 /* Sign extend a half-word or byte. The 32-bit sign extend is
2949 implemented as "addl $31, $r, $t" in the opcode table. */
2952 emit_sextX (tok
, ntok
, vlgsize
)
2953 const expressionS
*tok
;
2957 long lgsize
= (long)vlgsize
;
2959 if (alpha_target
& AXP_OPCODE_BWX
)
2960 assemble_tokens (sextX_op
[lgsize
], tok
, ntok
, 0);
2963 int bitshift
= 64 - 8 * (1 << lgsize
);
2964 expressionS newtok
[3];
2966 /* emit "sll src,bits,dst" */
2969 set_tok_const (newtok
[1], bitshift
);
2970 newtok
[2] = tok
[ntok
- 1];
2971 assemble_tokens ("sll", newtok
, 3, 1);
2973 /* emit "sra dst,bits,dst" */
2975 newtok
[0] = newtok
[2];
2976 assemble_tokens ("sra", newtok
, 3, 1);
2980 /* Implement the division and modulus macros. */
2984 /* Make register usage like in normal procedure call.
2985 Don't clobber PV and RA. */
2988 emit_division (tok
, ntok
, symname
)
2989 const expressionS
*tok
;
2993 /* DIVISION and MODULUS. Yech.
2998 * mov x,R16 # if x != R16
2999 * mov y,R17 # if y != R17
3004 * with appropriate optimizations if R0,R16,R17 are the registers
3005 * specified by the compiler.
3010 expressionS newtok
[3];
3012 xr
= regno (tok
[0].X_add_number
);
3013 yr
= regno (tok
[1].X_add_number
);
3018 rr
= regno (tok
[2].X_add_number
);
3020 /* Move the operands into the right place */
3021 if (yr
== AXP_REG_R16
&& xr
== AXP_REG_R17
)
3023 /* They are in exactly the wrong order -- swap through AT */
3026 as_bad (_("macro requires $at register while noat in effect"));
3028 set_tok_reg (newtok
[0], AXP_REG_R16
);
3029 set_tok_reg (newtok
[1], AXP_REG_AT
);
3030 assemble_tokens ("mov", newtok
, 2, 1);
3032 set_tok_reg (newtok
[0], AXP_REG_R17
);
3033 set_tok_reg (newtok
[1], AXP_REG_R16
);
3034 assemble_tokens ("mov", newtok
, 2, 1);
3036 set_tok_reg (newtok
[0], AXP_REG_AT
);
3037 set_tok_reg (newtok
[1], AXP_REG_R17
);
3038 assemble_tokens ("mov", newtok
, 2, 1);
3042 if (yr
== AXP_REG_R16
)
3044 set_tok_reg (newtok
[0], AXP_REG_R16
);
3045 set_tok_reg (newtok
[1], AXP_REG_R17
);
3046 assemble_tokens ("mov", newtok
, 2, 1);
3049 if (xr
!= AXP_REG_R16
)
3051 set_tok_reg (newtok
[0], xr
);
3052 set_tok_reg (newtok
[1], AXP_REG_R16
);
3053 assemble_tokens ("mov", newtok
, 2, 1);
3056 if (yr
!= AXP_REG_R16
&& yr
!= AXP_REG_R17
)
3058 set_tok_reg (newtok
[0], yr
);
3059 set_tok_reg (newtok
[1], AXP_REG_R17
);
3060 assemble_tokens ("mov", newtok
, 2, 1);
3064 sym
= symbol_find_or_make ((const char *)symname
);
3066 set_tok_reg (newtok
[0], AXP_REG_AT
);
3067 set_tok_sym (newtok
[1], sym
, 0);
3068 assemble_tokens ("lda", newtok
, 2, 1);
3070 /* Call the division routine */
3071 set_tok_reg (newtok
[0], AXP_REG_AT
);
3072 set_tok_cpreg (newtok
[1], AXP_REG_AT
);
3073 set_tok_const (newtok
[2], 0);
3074 assemble_tokens ("jsr", newtok
, 3, 1);
3076 /* Move the result to the right place */
3077 if (rr
!= AXP_REG_R0
)
3079 set_tok_reg (newtok
[0], AXP_REG_R0
);
3080 set_tok_reg (newtok
[1], rr
);
3081 assemble_tokens ("mov", newtok
, 2, 1);
3085 #else /* !OBJ_EVAX */
3088 emit_division (tok
, ntok
, symname
)
3089 const expressionS
*tok
;
3093 /* DIVISION and MODULUS. Yech.
3103 * with appropriate optimizations if t10,t11,t12 are the registers
3104 * specified by the compiler.
3109 expressionS newtok
[3];
3111 xr
= regno (tok
[0].X_add_number
);
3112 yr
= regno (tok
[1].X_add_number
);
3117 rr
= regno (tok
[2].X_add_number
);
3119 sym
= symbol_find_or_make ((const char *)symname
);
3121 /* Move the operands into the right place */
3122 if (yr
== AXP_REG_T10
&& xr
== AXP_REG_T11
)
3124 /* They are in exactly the wrong order -- swap through AT */
3127 as_bad (_("macro requires $at register while noat in effect"));
3129 set_tok_reg (newtok
[0], AXP_REG_T10
);
3130 set_tok_reg (newtok
[1], AXP_REG_AT
);
3131 assemble_tokens ("mov", newtok
, 2, 1);
3133 set_tok_reg (newtok
[0], AXP_REG_T11
);
3134 set_tok_reg (newtok
[1], AXP_REG_T10
);
3135 assemble_tokens ("mov", newtok
, 2, 1);
3137 set_tok_reg (newtok
[0], AXP_REG_AT
);
3138 set_tok_reg (newtok
[1], AXP_REG_T11
);
3139 assemble_tokens ("mov", newtok
, 2, 1);
3143 if (yr
== AXP_REG_T10
)
3145 set_tok_reg (newtok
[0], AXP_REG_T10
);
3146 set_tok_reg (newtok
[1], AXP_REG_T11
);
3147 assemble_tokens ("mov", newtok
, 2, 1);
3150 if (xr
!= AXP_REG_T10
)
3152 set_tok_reg (newtok
[0], xr
);
3153 set_tok_reg (newtok
[1], AXP_REG_T10
);
3154 assemble_tokens ("mov", newtok
, 2, 1);
3157 if (yr
!= AXP_REG_T10
&& yr
!= AXP_REG_T11
)
3159 set_tok_reg (newtok
[0], yr
);
3160 set_tok_reg (newtok
[1], AXP_REG_T11
);
3161 assemble_tokens ("mov", newtok
, 2, 1);
3165 /* Call the division routine */
3166 set_tok_reg (newtok
[0], AXP_REG_T9
);
3167 set_tok_sym (newtok
[1], sym
, 0);
3168 assemble_tokens ("jsr", newtok
, 2, 1);
3170 /* Reload the GP register */
3174 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
3175 set_tok_reg (newtok
[0], alpha_gp_register
);
3176 set_tok_const (newtok
[1], 0);
3177 set_tok_preg (newtok
[2], AXP_REG_T9
);
3178 assemble_tokens ("ldgp", newtok
, 3, 1);
3181 /* Move the result to the right place */
3182 if (rr
!= AXP_REG_T12
)
3184 set_tok_reg (newtok
[0], AXP_REG_T12
);
3185 set_tok_reg (newtok
[1], rr
);
3186 assemble_tokens ("mov", newtok
, 2, 1);
3190 #endif /* !OBJ_EVAX */
3192 /* The jsr and jmp macros differ from their instruction counterparts
3193 in that they can load the target address and default most
3197 emit_jsrjmp (tok
, ntok
, vopname
)
3198 const expressionS
*tok
;
3202 const char *opname
= (const char *) vopname
;
3203 struct alpha_insn insn
;
3204 expressionS newtok
[3];
3205 int r
, tokidx
= 0, lituse
= 0;
3207 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_register
)
3208 r
= regno (tok
[tokidx
++].X_add_number
);
3210 r
= strcmp (opname
, "jmp") == 0 ? AXP_REG_ZERO
: AXP_REG_RA
;
3212 set_tok_reg (newtok
[0], r
);
3214 if (tokidx
< ntok
&&
3215 (tok
[tokidx
].X_op
== O_pregister
|| tok
[tokidx
].X_op
== O_cpregister
))
3216 r
= regno (tok
[tokidx
++].X_add_number
);
3218 /* keep register if jsr $n.<sym> */
3222 int basereg
= alpha_gp_register
;
3223 lituse
= load_expression (r
= AXP_REG_PV
, &tok
[tokidx
], &basereg
, NULL
);
3227 set_tok_cpreg (newtok
[1], r
);
3230 /* FIXME: Add hint relocs to BFD for evax. */
3233 newtok
[2] = tok
[tokidx
];
3236 set_tok_const (newtok
[2], 0);
3238 assemble_tokens_to_insn (opname
, newtok
, 3, &insn
);
3240 /* add the LITUSE fixup */
3243 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3244 if (insn
.nfixups
> 0)
3246 memmove (&insn
.fixups
[1], &insn
.fixups
[0],
3247 sizeof(struct alpha_fixup
) * insn
.nfixups
);
3250 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITUSE
;
3251 insn
.fixups
[0].exp
.X_op
= O_constant
;
3252 insn
.fixups
[0].exp
.X_add_number
= 3;
3258 /* The ret and jcr instructions differ from their instruction
3259 counterparts in that everything can be defaulted. */
3262 emit_retjcr (tok
, ntok
, vopname
)
3263 const expressionS
*tok
;
3267 const char *opname
= (const char *)vopname
;
3268 expressionS newtok
[3];
3271 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_register
)
3272 r
= regno (tok
[tokidx
++].X_add_number
);
3276 set_tok_reg (newtok
[0], r
);
3278 if (tokidx
< ntok
&&
3279 (tok
[tokidx
].X_op
== O_pregister
|| tok
[tokidx
].X_op
== O_cpregister
))
3280 r
= regno (tok
[tokidx
++].X_add_number
);
3284 set_tok_cpreg (newtok
[1], r
);
3287 newtok
[2] = tok
[tokidx
];
3289 set_tok_const (newtok
[2], strcmp(opname
, "ret") == 0);
3291 assemble_tokens (opname
, newtok
, 3, 0);
3294 /* Assembler directives */
3296 /* Handle the .text pseudo-op. This is like the usual one, but it
3297 clears alpha_insn_label and restores auto alignment. */
3305 alpha_insn_label
= NULL
;
3306 alpha_auto_align_on
= 1;
3307 alpha_current_align
= 0;
3310 /* Handle the .data pseudo-op. This is like the usual one, but it
3311 clears alpha_insn_label and restores auto alignment. */
3318 alpha_insn_label
= NULL
;
3319 alpha_auto_align_on
= 1;
3320 alpha_current_align
= 0;
3323 #if defined (OBJ_ECOFF) || defined (OBJ_EVAX)
3325 /* Handle the OSF/1 and openVMS .comm pseudo quirks.
3326 openVMS constructs a section for every common symbol. */
3329 s_alpha_comm (ignore
)
3332 register char *name
;
3336 register symbolS
*symbolP
;
3339 segT current_section
= now_seg
;
3340 int current_subsec
= now_subseg
;
3344 name
= input_line_pointer
;
3345 c
= get_symbol_end ();
3347 /* just after name is now '\0' */
3348 p
= input_line_pointer
;
3353 /* Alpha OSF/1 compiler doesn't provide the comma, gcc does. */
3354 if (*input_line_pointer
== ',')
3356 input_line_pointer
++;
3359 if ((temp
= get_absolute_expression ()) < 0)
3361 as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) temp
);
3362 ignore_rest_of_line ();
3367 symbolP
= symbol_find_or_make (name
);
3371 /* Make a section for the common symbol. */
3372 new_seg
= subseg_new (xstrdup (name
), 0);
3375 if (S_IS_DEFINED (symbolP
) && ! S_IS_COMMON (symbolP
))
3377 as_bad (_("Ignoring attempt to re-define symbol"));
3378 ignore_rest_of_line ();
3383 if (bfd_section_size (stdoutput
, new_seg
) > 0)
3385 if (bfd_section_size (stdoutput
, new_seg
) != temp
)
3386 as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
3387 S_GET_NAME (symbolP
),
3388 (long) bfd_section_size (stdoutput
, new_seg
),
3392 if (S_GET_VALUE (symbolP
))
3394 if (S_GET_VALUE (symbolP
) != (valueT
) temp
)
3395 as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
3396 S_GET_NAME (symbolP
),
3397 (long) S_GET_VALUE (symbolP
),
3404 subseg_set (new_seg
, 0);
3405 p
= frag_more (temp
);
3406 new_seg
->flags
|= SEC_IS_COMMON
;
3407 if (! S_IS_DEFINED (symbolP
))
3408 symbolP
->bsym
->section
= new_seg
;
3410 S_SET_VALUE (symbolP
, (valueT
) temp
);
3412 S_SET_EXTERNAL (symbolP
);
3416 subseg_set (current_section
, current_subsec
);
3419 know (symbolP
->sy_frag
== &zero_address_frag
);
3421 demand_empty_rest_of_line ();
3424 #endif /* ! OBJ_ELF */
3428 /* Handle the .rdata pseudo-op. This is like the usual one, but it
3429 clears alpha_insn_label and restores auto alignment. */
3432 s_alpha_rdata (ignore
)
3437 temp
= get_absolute_expression ();
3438 subseg_new (".rdata", 0);
3439 demand_empty_rest_of_line ();
3440 alpha_insn_label
= NULL
;
3441 alpha_auto_align_on
= 1;
3442 alpha_current_align
= 0;
3449 /* Handle the .sdata pseudo-op. This is like the usual one, but it
3450 clears alpha_insn_label and restores auto alignment. */
3453 s_alpha_sdata (ignore
)
3458 temp
= get_absolute_expression ();
3459 subseg_new (".sdata", 0);
3460 demand_empty_rest_of_line ();
3461 alpha_insn_label
= NULL
;
3462 alpha_auto_align_on
= 1;
3463 alpha_current_align
= 0;
3469 /* Handle the .section pseudo-op. This is like the usual one, but it
3470 clears alpha_insn_label and restores auto alignment. */
3473 s_alpha_section (ignore
)
3476 obj_elf_section (ignore
);
3478 alpha_insn_label
= NULL
;
3479 alpha_auto_align_on
= 1;
3480 alpha_current_align
= 0;
3484 s_alpha_prologue (ignore
)
3490 arg
= get_absolute_expression ();
3491 demand_empty_rest_of_line ();
3493 sym
= ecoff_get_cur_proc_sym ();
3498 case 0: /* No PV required. */
3499 S_SET_OTHER (sym
, STO_ALPHA_NOPV
);
3501 case 1: /* Std GP load. */
3502 S_SET_OTHER (sym
, STO_ALPHA_STD_GPLOAD
);
3504 case 2: /* Non-std use of PV. */
3508 as_bad (_("Invalid argument %d to .prologue."), arg
);
3517 /* Handle the section specific pseudo-op. */
3520 s_alpha_section (secid
)
3524 #define EVAX_SECTION_COUNT 5
3525 static char *section_name
[EVAX_SECTION_COUNT
+1] =
3526 { "NULL", ".rdata", ".comm", ".link", ".ctors", ".dtors" };
3528 if ((secid
<= 0) || (secid
> EVAX_SECTION_COUNT
))
3530 as_fatal (_("Unknown section directive"));
3531 demand_empty_rest_of_line ();
3534 temp
= get_absolute_expression ();
3535 subseg_new (section_name
[secid
], 0);
3536 demand_empty_rest_of_line ();
3537 alpha_insn_label
= NULL
;
3538 alpha_auto_align_on
= 1;
3539 alpha_current_align
= 0;
3543 /* Parse .ent directives. */
3546 s_alpha_ent (ignore
)
3550 expressionS symexpr
;
3552 alpha_evax_proc
.pdsckind
= 0;
3553 alpha_evax_proc
.framereg
= -1;
3554 alpha_evax_proc
.framesize
= 0;
3555 alpha_evax_proc
.rsa_offset
= 0;
3556 alpha_evax_proc
.ra_save
= AXP_REG_RA
;
3557 alpha_evax_proc
.fp_save
= -1;
3558 alpha_evax_proc
.imask
= 0;
3559 alpha_evax_proc
.fmask
= 0;
3560 alpha_evax_proc
.prologue
= 0;
3561 alpha_evax_proc
.type
= 0;
3563 expression (&symexpr
);
3565 if (symexpr
.X_op
!= O_symbol
)
3567 as_fatal (_(".ent directive has no symbol"));
3568 demand_empty_rest_of_line ();
3572 symbol
= make_expr_symbol (&symexpr
);
3573 symbol
->bsym
->flags
|= BSF_FUNCTION
;
3574 alpha_evax_proc
.symbol
= symbol
;
3576 demand_empty_rest_of_line ();
3581 /* Parse .frame <framreg>,<framesize>,RA,<rsa_offset> directives. */
3584 s_alpha_frame (ignore
)
3589 alpha_evax_proc
.framereg
= tc_get_register (1);
3592 if (*input_line_pointer
++ != ','
3593 || get_absolute_expression_and_terminator (&val
) != ',')
3595 as_warn (_("Bad .frame directive 1./2. param"));
3596 --input_line_pointer
;
3597 demand_empty_rest_of_line ();
3601 alpha_evax_proc
.framesize
= val
;
3603 (void) tc_get_register (1);
3605 if (*input_line_pointer
++ != ',')
3607 as_warn (_("Bad .frame directive 3./4. param"));
3608 --input_line_pointer
;
3609 demand_empty_rest_of_line ();
3612 alpha_evax_proc
.rsa_offset
= get_absolute_expression ();
3618 s_alpha_pdesc (ignore
)
3628 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
3630 if (now_seg
!= alpha_link_section
)
3632 as_bad (_(".pdesc directive not in link (.link) section"));
3633 demand_empty_rest_of_line ();
3637 if ((alpha_evax_proc
.symbol
== 0)
3638 || (!S_IS_DEFINED (alpha_evax_proc
.symbol
)))
3640 as_fatal (_(".pdesc has no matching .ent"));
3641 demand_empty_rest_of_line ();
3645 alpha_evax_proc
.symbol
->sy_obj
= (valueT
)seginfo
->literal_pool_size
;
3648 if (exp
.X_op
!= O_symbol
)
3650 as_warn (_(".pdesc directive has no entry symbol"));
3651 demand_empty_rest_of_line ();
3655 entry_sym
= make_expr_symbol (&exp
);
3656 /* Save bfd symbol of proc desc in function symbol. */
3657 alpha_evax_proc
.symbol
->bsym
->udata
.p
= (PTR
)entry_sym
->bsym
;
3660 if (*input_line_pointer
++ != ',')
3662 as_warn (_("No comma after .pdesc <entryname>"));
3663 demand_empty_rest_of_line ();
3668 name
= input_line_pointer
;
3669 name_end
= get_symbol_end ();
3671 if (strncmp(name
, "stack", 5) == 0)
3673 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_FP_STACK
;
3675 else if (strncmp(name
, "reg", 3) == 0)
3677 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_FP_REGISTER
;
3679 else if (strncmp(name
, "null", 4) == 0)
3681 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_NULL
;
3685 as_fatal (_("unknown procedure kind"));
3686 demand_empty_rest_of_line ();
3690 *input_line_pointer
= name_end
;
3691 demand_empty_rest_of_line ();
3693 #ifdef md_flush_pending_output
3694 md_flush_pending_output ();
3697 frag_align (3, 0, 0);
3699 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
3701 seginfo
->literal_pool_size
+= 16;
3703 *p
= alpha_evax_proc
.pdsckind
3704 | ((alpha_evax_proc
.framereg
== 29) ? PDSC_S_M_BASE_REG_IS_FP
: 0);
3705 *(p
+1) = PDSC_S_M_NATIVE
3706 | PDSC_S_M_NO_JACKET
;
3708 switch (alpha_evax_proc
.pdsckind
)
3710 case PDSC_S_K_KIND_NULL
:
3714 case PDSC_S_K_KIND_FP_REGISTER
:
3715 *(p
+2) = alpha_evax_proc
.fp_save
;
3716 *(p
+3) = alpha_evax_proc
.ra_save
;
3718 case PDSC_S_K_KIND_FP_STACK
:
3719 md_number_to_chars (p
+2, (valueT
)alpha_evax_proc
.rsa_offset
, 2);
3721 default: /* impossible */
3726 *(p
+5) = alpha_evax_proc
.type
& 0x0f;
3728 /* Signature offset. */
3729 md_number_to_chars (p
+6, (valueT
)0, 2);
3731 fix_new_exp (frag_now
, p
-frag_now
->fr_literal
+8, 8, &exp
, 0, BFD_RELOC_64
);
3733 if (alpha_evax_proc
.pdsckind
== PDSC_S_K_KIND_NULL
)
3736 /* Add dummy fix to make add_to_link_pool work. */
3738 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
3740 seginfo
->literal_pool_size
+= 8;
3742 /* pdesc+16: Size. */
3743 md_number_to_chars (p
, (valueT
)alpha_evax_proc
.framesize
, 4);
3745 md_number_to_chars (p
+4, (valueT
)0, 2);
3748 md_number_to_chars (p
+6, alpha_evax_proc
.prologue
, 2);
3750 if (alpha_evax_proc
.pdsckind
== PDSC_S_K_KIND_FP_REGISTER
)
3753 /* Add dummy fix to make add_to_link_pool work. */
3755 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
3757 seginfo
->literal_pool_size
+= 8;
3759 /* pdesc+24: register masks. */
3761 md_number_to_chars (p
, alpha_evax_proc
.imask
, 4);
3762 md_number_to_chars (p
+4, alpha_evax_proc
.fmask
, 4);
3768 /* Support for crash debug on vms. */
3771 s_alpha_name (ignore
)
3776 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
3778 if (now_seg
!= alpha_link_section
)
3780 as_bad (_(".name directive not in link (.link) section"));
3781 demand_empty_rest_of_line ();
3786 if (exp
.X_op
!= O_symbol
)
3788 as_warn (_(".name directive has no symbol"));
3789 demand_empty_rest_of_line ();
3793 demand_empty_rest_of_line ();
3795 #ifdef md_flush_pending_output
3796 md_flush_pending_output ();
3799 frag_align (3, 0, 0);
3801 seginfo
->literal_pool_size
+= 8;
3803 fix_new_exp (frag_now
, p
-frag_now
->fr_literal
, 8, &exp
, 0, BFD_RELOC_64
);
3810 s_alpha_linkage (ignore
)
3816 #ifdef md_flush_pending_output
3817 md_flush_pending_output ();
3821 if (exp
.X_op
!= O_symbol
)
3823 as_fatal (_("No symbol after .linkage"));
3827 p
= frag_more (LKP_S_K_SIZE
);
3828 memset (p
, 0, LKP_S_K_SIZE
);
3829 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, LKP_S_K_SIZE
, &exp
, 0,\
3830 BFD_RELOC_ALPHA_LINKAGE
);
3832 demand_empty_rest_of_line ();
3839 s_alpha_code_address (ignore
)
3845 #ifdef md_flush_pending_output
3846 md_flush_pending_output ();
3850 if (exp
.X_op
!= O_symbol
)
3852 as_fatal (_("No symbol after .code_address"));
3858 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 8, &exp
, 0,\
3859 BFD_RELOC_ALPHA_CODEADDR
);
3861 demand_empty_rest_of_line ();
3868 s_alpha_fp_save (ignore
)
3872 alpha_evax_proc
.fp_save
= tc_get_register (1);
3874 demand_empty_rest_of_line ();
3880 s_alpha_mask (ignore
)
3885 if (get_absolute_expression_and_terminator (&val
) != ',')
3887 as_warn (_("Bad .mask directive"));
3888 --input_line_pointer
;
3892 alpha_evax_proc
.imask
= val
;
3893 (void)get_absolute_expression ();
3895 demand_empty_rest_of_line ();
3902 s_alpha_fmask (ignore
)
3907 if (get_absolute_expression_and_terminator (&val
) != ',')
3909 as_warn (_("Bad .fmask directive"));
3910 --input_line_pointer
;
3914 alpha_evax_proc
.fmask
= val
;
3915 (void) get_absolute_expression ();
3917 demand_empty_rest_of_line ();
3923 s_alpha_end (ignore
)
3928 c
= get_symbol_end ();
3929 *input_line_pointer
= c
;
3930 demand_empty_rest_of_line ();
3931 alpha_evax_proc
.symbol
= 0;
3938 s_alpha_file (ignore
)
3943 static char case_hack
[32];
3945 extern char *demand_copy_string
PARAMS ((int *lenP
));
3947 sprintf (case_hack
, "<CASE:%01d%01d>",
3948 alpha_flag_hash_long_names
, alpha_flag_show_after_trunc
);
3950 s
= symbol_find_or_make (case_hack
);
3951 s
->bsym
->flags
|= BSF_FILE
;
3953 get_absolute_expression ();
3954 s
= symbol_find_or_make (demand_copy_string (&length
));
3955 s
->bsym
->flags
|= BSF_FILE
;
3956 demand_empty_rest_of_line ();
3960 #endif /* OBJ_EVAX */
3962 /* Handle the .gprel32 pseudo op. */
3965 s_alpha_gprel32 (ignore
)
3978 e
.X_add_symbol
= section_symbol(absolute_section
);
3991 e
.X_add_symbol
= section_symbol (absolute_section
);
3994 e
.X_op
= O_subtract
;
3995 e
.X_op_symbol
= alpha_gp_symbol
;
4003 if (alpha_auto_align_on
&& alpha_current_align
< 2)
4004 alpha_align (2, (char *) NULL
, alpha_insn_label
, 0);
4005 if (alpha_current_align
> 2)
4006 alpha_current_align
= 2;
4007 alpha_insn_label
= NULL
;
4011 fix_new_exp (frag_now
, p
-frag_now
->fr_literal
, 4,
4012 &e
, 0, BFD_RELOC_GPREL32
);
4015 /* Handle floating point allocation pseudo-ops. This is like the
4016 generic vresion, but it makes sure the current label, if any, is
4017 correctly aligned. */
4020 s_alpha_float_cons (type
)
4047 if (alpha_auto_align_on
&& alpha_current_align
< log_size
)
4048 alpha_align (log_size
, (char *) NULL
, alpha_insn_label
, 0);
4049 if (alpha_current_align
> log_size
)
4050 alpha_current_align
= log_size
;
4051 alpha_insn_label
= NULL
;
4056 /* Handle the .proc pseudo op. We don't really do much with it except
4060 s_alpha_proc (is_static
)
4069 /* Takes ".proc name,nargs" */
4071 name
= input_line_pointer
;
4072 c
= get_symbol_end ();
4073 p
= input_line_pointer
;
4074 symbolP
= symbol_find_or_make (name
);
4077 if (*input_line_pointer
!= ',')
4080 as_warn (_("Expected comma after name \"%s\""), name
);
4083 ignore_rest_of_line ();
4087 input_line_pointer
++;
4088 temp
= get_absolute_expression ();
4090 /* symbolP->sy_other = (signed char) temp; */
4091 as_warn (_("unhandled: .proc %s,%d"), name
, temp
);
4092 demand_empty_rest_of_line ();
4095 /* Handle the .set pseudo op. This is used to turn on and off most of
4096 the assembler features. */
4106 name
= input_line_pointer
;
4107 ch
= get_symbol_end ();
4110 if (s
[0] == 'n' && s
[1] == 'o')
4115 if (!strcmp ("reorder", s
))
4117 else if (!strcmp ("at", s
))
4118 alpha_noat_on
= !yesno
;
4119 else if (!strcmp ("macro", s
))
4120 alpha_macros_on
= yesno
;
4121 else if (!strcmp ("move", s
))
4123 else if (!strcmp ("volatile", s
))
4126 as_warn (_("Tried to .set unrecognized mode `%s'"), name
);
4128 *input_line_pointer
= ch
;
4129 demand_empty_rest_of_line ();
4132 /* Handle the .base pseudo op. This changes the assembler's notion of
4133 the $gp register. */
4136 s_alpha_base (ignore
)
4140 if (first_32bit_quadrant
)
4142 /* not fatal, but it might not work in the end */
4143 as_warn (_("File overrides no-base-register option."));
4144 first_32bit_quadrant
= 0;
4149 if (*input_line_pointer
== '$')
4151 input_line_pointer
++;
4152 if (*input_line_pointer
== 'r')
4153 input_line_pointer
++;
4156 alpha_gp_register
= get_absolute_expression ();
4157 if (alpha_gp_register
< 0 || alpha_gp_register
> 31)
4159 alpha_gp_register
= AXP_REG_GP
;
4160 as_warn (_("Bad base register, using $%d."), alpha_gp_register
);
4163 demand_empty_rest_of_line ();
4166 /* Handle the .align pseudo-op. This aligns to a power of two. It
4167 also adjusts any current instruction label. We treat this the same
4168 way the MIPS port does: .align 0 turns off auto alignment. */
4171 s_alpha_align (ignore
)
4176 long max_alignment
= 15;
4178 align
= get_absolute_expression ();
4179 if (align
> max_alignment
)
4181 align
= max_alignment
;
4182 as_bad (_("Alignment too large: %d. assumed"), align
);
4186 as_warn (_("Alignment negative: 0 assumed"));
4190 if (*input_line_pointer
== ',')
4192 input_line_pointer
++;
4193 fill
= get_absolute_expression ();
4201 alpha_auto_align_on
= 1;
4202 alpha_align (align
, pfill
, alpha_insn_label
, 1);
4206 alpha_auto_align_on
= 0;
4209 demand_empty_rest_of_line ();
4212 /* Hook the normal string processor to reset known alignment. */
4215 s_alpha_stringer (terminate
)
4218 alpha_current_align
= 0;
4219 alpha_insn_label
= NULL
;
4220 stringer (terminate
);
4223 /* Hook the normal space processing to reset known alignment. */
4226 s_alpha_space (ignore
)
4229 alpha_current_align
= 0;
4230 alpha_insn_label
= NULL
;
4234 /* Hook into cons for auto-alignment. */
4237 alpha_cons_align (size
)
4243 while ((size
>>= 1) != 0)
4246 if (alpha_auto_align_on
&& alpha_current_align
< log_size
)
4247 alpha_align (log_size
, (char *) NULL
, alpha_insn_label
, 0);
4248 if (alpha_current_align
> log_size
)
4249 alpha_current_align
= log_size
;
4250 alpha_insn_label
= NULL
;
4253 /* Here come the .uword, .ulong, and .uquad explicitly unaligned
4254 pseudos. We just turn off auto-alignment and call down to cons. */
4257 s_alpha_ucons (bytes
)
4260 int hold
= alpha_auto_align_on
;
4261 alpha_auto_align_on
= 0;
4263 alpha_auto_align_on
= hold
;
4266 /* Switch the working cpu type. */
4269 s_alpha_arch (ignored
)
4273 const struct cpu_type
*p
;
4276 name
= input_line_pointer
;
4277 ch
= get_symbol_end ();
4279 for (p
= cpu_types
; p
->name
; ++p
)
4280 if (strcmp(name
, p
->name
) == 0)
4282 alpha_target_name
= p
->name
, alpha_target
= p
->flags
;
4285 as_warn("Unknown CPU identifier `%s'", name
);
4288 *input_line_pointer
= ch
;
4289 demand_empty_rest_of_line ();
4295 /* print token expression with alpha specific extension. */
4298 alpha_print_token(f
, exp
)
4300 const expressionS
*exp
;
4310 expressionS nexp
= *exp
;
4311 nexp
.X_op
= O_register
;
4312 print_expr (f
, &nexp
);
4317 print_expr (f
, exp
);
4324 /* The target specific pseudo-ops which we support. */
4326 const pseudo_typeS md_pseudo_table
[] =
4329 {"comm", s_alpha_comm
, 0}, /* osf1 compiler does this */
4330 {"rdata", s_alpha_rdata
, 0},
4332 {"text", s_alpha_text
, 0},
4333 {"data", s_alpha_data
, 0},
4335 {"sdata", s_alpha_sdata
, 0},
4338 {"section", s_alpha_section
, 0},
4339 {"section.s", s_alpha_section
, 0},
4340 {"sect", s_alpha_section
, 0},
4341 {"sect.s", s_alpha_section
, 0},
4344 { "pdesc", s_alpha_pdesc
, 0},
4345 { "name", s_alpha_name
, 0},
4346 { "linkage", s_alpha_linkage
, 0},
4347 { "code_address", s_alpha_code_address
, 0},
4348 { "ent", s_alpha_ent
, 0},
4349 { "frame", s_alpha_frame
, 0},
4350 { "fp_save", s_alpha_fp_save
, 0},
4351 { "mask", s_alpha_mask
, 0},
4352 { "fmask", s_alpha_fmask
, 0},
4353 { "end", s_alpha_end
, 0},
4354 { "file", s_alpha_file
, 0},
4355 { "rdata", s_alpha_section
, 1},
4356 { "comm", s_alpha_comm
, 0},
4357 { "link", s_alpha_section
, 3},
4358 { "ctors", s_alpha_section
, 4},
4359 { "dtors", s_alpha_section
, 5},
4362 {"prologue", s_alpha_prologue
, 0},
4364 {"prologue", s_ignore
, 0},
4366 {"gprel32", s_alpha_gprel32
, 0},
4367 {"t_floating", s_alpha_float_cons
, 'd'},
4368 {"s_floating", s_alpha_float_cons
, 'f'},
4369 {"f_floating", s_alpha_float_cons
, 'F'},
4370 {"g_floating", s_alpha_float_cons
, 'G'},
4371 {"d_floating", s_alpha_float_cons
, 'D'},
4373 {"proc", s_alpha_proc
, 0},
4374 {"aproc", s_alpha_proc
, 1},
4375 {"set", s_alpha_set
, 0},
4376 {"reguse", s_ignore
, 0},
4377 {"livereg", s_ignore
, 0},
4378 {"base", s_alpha_base
, 0}, /*??*/
4379 {"option", s_ignore
, 0},
4380 {"aent", s_ignore
, 0},
4381 {"ugen", s_ignore
, 0},
4382 {"eflag", s_ignore
, 0},
4384 {"align", s_alpha_align
, 0},
4385 {"double", s_alpha_float_cons
, 'd'},
4386 {"float", s_alpha_float_cons
, 'f'},
4387 {"single", s_alpha_float_cons
, 'f'},
4388 {"ascii", s_alpha_stringer
, 0},
4389 {"asciz", s_alpha_stringer
, 1},
4390 {"string", s_alpha_stringer
, 1},
4391 {"space", s_alpha_space
, 0},
4392 {"skip", s_alpha_space
, 0},
4393 {"zero", s_alpha_space
, 0},
4395 /* Unaligned data pseudos. */
4396 {"uword", s_alpha_ucons
, 2},
4397 {"ulong", s_alpha_ucons
, 4},
4398 {"uquad", s_alpha_ucons
, 8},
4401 /* Dwarf wants these versions of unaligned. */
4402 {"2byte", s_alpha_ucons
, 2},
4403 {"4byte", s_alpha_ucons
, 4},
4404 {"8byte", s_alpha_ucons
, 8},
4407 /* We don't do any optimizing, so we can safely ignore these. */
4408 {"noalias", s_ignore
, 0},
4409 {"alias", s_ignore
, 0},
4411 {"arch", s_alpha_arch
, 0},
4417 /* Build a BFD section with its flags set appropriately for the .lita,
4418 .lit8, or .lit4 sections. */
4421 create_literal_section (name
, secp
, symp
)
4426 segT current_section
= now_seg
;
4427 int current_subsec
= now_subseg
;
4430 *secp
= new_sec
= subseg_new (name
, 0);
4431 subseg_set (current_section
, current_subsec
);
4432 bfd_set_section_alignment (stdoutput
, new_sec
, 4);
4433 bfd_set_section_flags (stdoutput
, new_sec
,
4434 SEC_RELOC
| SEC_ALLOC
| SEC_LOAD
| SEC_READONLY
4437 S_CLEAR_EXTERNAL (*symp
= section_symbol (new_sec
));
4442 /* @@@ GP selection voodoo. All of this seems overly complicated and
4443 unnecessary; which is the primary reason it's for ECOFF only. */
4452 vma
= bfd_get_section_vma (foo
, sec
);
4453 if (vma
&& vma
< alpha_gp_value
)
4454 alpha_gp_value
= vma
;
4460 assert (alpha_gp_value
== 0);
4462 /* Get minus-one in whatever width... */
4463 alpha_gp_value
= 0; alpha_gp_value
--;
4465 /* Select the smallest VMA of these existing sections. */
4466 maybe_set_gp (alpha_lita_section
);
4468 /* These were disabled before -- should we use them? */
4469 maybe_set_gp (sdata
);
4470 maybe_set_gp (lit8_sec
);
4471 maybe_set_gp (lit4_sec
);
4474 /* @@ Will a simple 0x8000 work here? If not, why not? */
4475 #define GP_ADJUSTMENT (0x8000 - 0x10)
4477 alpha_gp_value
+= GP_ADJUSTMENT
;
4479 S_SET_VALUE (alpha_gp_symbol
, alpha_gp_value
);
4482 printf (_("Chose GP value of %lx\n"), alpha_gp_value
);
4485 #endif /* OBJ_ECOFF */
4487 /* Called internally to handle all alignment needs. This takes care
4488 of eliding calls to frag_align if'n the cached current alignment
4489 says we've already got it, as well as taking care of the auto-align
4490 feature wrt labels. */
4493 alpha_align (n
, pfill
, label
, force
)
4499 if (alpha_current_align
>= n
)
4505 && (bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
) != 0)
4507 static char const unop
[4] = { 0x00, 0x00, 0xe0, 0x2f };
4508 static char const nopunop
[8] = {
4509 0x1f, 0x04, 0xff, 0x47,
4510 0x00, 0x00, 0xe0, 0x2f
4513 /* First, make sure we're on a four-byte boundary, in case
4514 someone has been putting .byte values into the text
4515 section. The DEC assembler silently fills with unaligned
4516 no-op instructions. This will zero-fill, then nop-fill
4517 with proper alignment. */
4518 if (alpha_current_align
< 2)
4519 frag_align (2, 0, 0);
4520 if (alpha_current_align
< 3)
4521 frag_align_pattern (3, unop
, sizeof unop
, 0);
4523 frag_align_pattern (n
, nopunop
, sizeof nopunop
, 0);
4526 frag_align (n
, 0, 0);
4529 frag_align (n
, *pfill
, 0);
4531 alpha_current_align
= n
;
4535 assert (S_GET_SEGMENT (label
) == now_seg
);
4536 label
->sy_frag
= frag_now
;
4537 S_SET_VALUE (label
, (valueT
) frag_now_fix ());
4540 record_alignment(now_seg
, n
);
4542 /* ??? if alpha_flag_relax && force && elf, record the requested alignment
4543 in a reloc for the linker to see. */
4546 /* The Alpha has support for some VAX floating point types, as well as for
4547 IEEE floating point. We consider IEEE to be the primary floating point
4548 format, and sneak in the VAX floating point support here. */
4549 #define md_atof vax_md_atof
4550 #include "config/atof-vax.c"