1 /* tc-alpha.c - Processor-specific code for the DEC Alpha AXP CPU.
2 Copyright (C) 1989, 93, 94, 95, 1996 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 Kaempf 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, void *));
92 enum alpha_macro_arg argsets
[16];
95 /* Two extra symbols we want to see in our input. This is a blatent
96 misuse of the expressionS.X_op field. */
98 #define O_pregister (O_max+1) /* O_register, but in parentheses */
99 #define O_cpregister (O_pregister+1) /* + a leading comma */
101 /* Macros for extracting the type and number of encoded register tokens */
103 #define is_ir_num(x) (((x) & 32) == 0)
104 #define is_fpr_num(x) (((x) & 32) != 0)
105 #define regno(x) ((x) & 31)
107 /* Something odd inherited from the old assembler */
109 #define note_gpreg(R) (alpha_gprmask |= (1 << (R)))
110 #define note_fpreg(R) (alpha_fprmask |= (1 << (R)))
112 /* Predicates for 16- and 32-bit ranges */
114 #define range_signed_16(x) ((offsetT)(x) >= -(offsetT)0x8000 && \
115 (offsetT)(x) <= (offsetT)0x7FFF)
116 #define range_signed_32(x) ((offsetT)(x) >= -(offsetT)0x80000000 && \
117 (offsetT)(x) <= (offsetT)0x7FFFFFFF)
119 /* Macros for sign extending from 16- and 32-bits. */
120 /* XXX: The cast macros will work on all the systems that I care about,
121 but really a predicate should be found to use the non-cast forms. */
124 #define sign_extend_16(x) ((short)(x))
125 #define sign_extend_32(x) ((int)(x))
127 #define sign_extend_16(x) ((offsetT)(((x) & 0xFFFF) ^ 0x8000) - 0x8000)
128 #define sign_extend_32(x) ((offsetT)(((x) & 0xFFFFFFFF) \
129 ^ 0x80000000) - 0x80000000)
132 /* Macros to build tokens */
134 #define set_tok_reg(t, r) (memset(&(t), 0, sizeof(t)), \
135 (t).X_op = O_register, \
136 (t).X_add_number = (r))
137 #define set_tok_preg(t, r) (memset(&(t), 0, sizeof(t)), \
138 (t).X_op = O_pregister, \
139 (t).X_add_number = (r))
140 #define set_tok_cpreg(t, r) (memset(&(t), 0, sizeof(t)), \
141 (t).X_op = O_cpregister, \
142 (t).X_add_number = (r))
143 #define set_tok_freg(t, r) (memset(&(t), 0, sizeof(t)), \
144 (t).X_op = O_register, \
145 (t).X_add_number = (r)+32)
146 #define set_tok_sym(t, s, a) (memset(&(t), 0, sizeof(t)), \
147 (t).X_op = O_symbol, \
148 (t).X_add_symbol = (s), \
149 (t).X_add_number = (a))
150 #define set_tok_const(t, n) (memset(&(t), 0, sizeof(t)), \
151 (t).X_op = O_constant, \
152 (t).X_add_number = (n))
155 /* Prototypes for all local functions */
157 static int tokenize_arguments
PARAMS((char *, expressionS
*, int));
158 static const struct alpha_opcode
*find_opcode_match
159 PARAMS((const struct alpha_opcode
*, const expressionS
*, int*, int*));
160 static const struct alpha_macro
*find_macro_match
161 PARAMS((const struct alpha_macro
*, const expressionS
*, int*));
162 static unsigned insert_operand
PARAMS((unsigned, const struct alpha_operand
*,
163 offsetT
, char *, unsigned));
164 static void assemble_insn
PARAMS((const struct alpha_opcode
*,
165 const expressionS
*, int,
166 struct alpha_insn
*));
167 static void emit_insn
PARAMS((struct alpha_insn
*));
168 static void assemble_tokens_to_insn
PARAMS((const char *, const expressionS
*,
169 int, struct alpha_insn
*));
170 static void assemble_tokens
PARAMS((const char *, const expressionS
*,
173 static int load_expression
PARAMS((int, const expressionS
*, int *,
176 static void emit_ldgp
PARAMS((const expressionS
*, int, void*));
177 static void emit_division
PARAMS((const expressionS
*, int, void*));
178 static void emit_lda
PARAMS((const expressionS
*, int, void*));
179 static void emit_ldah
PARAMS((const expressionS
*, int, void*));
180 static void emit_ir_load
PARAMS((const expressionS
*, int, void*));
181 static void emit_loadstore
PARAMS((const expressionS
*, int, void*));
182 static void emit_jsrjmp
PARAMS((const expressionS
*, int, void*));
183 static void emit_ldX
PARAMS((const expressionS
*, int, void*));
184 static void emit_ldXu
PARAMS((const expressionS
*, int, void*));
185 static void emit_uldX
PARAMS((const expressionS
*, int, void*));
186 static void emit_uldXu
PARAMS((const expressionS
*, int, void*));
187 static void emit_ldil
PARAMS((const expressionS
*, int, void*));
188 static void emit_stX
PARAMS((const expressionS
*, int, void*));
189 static void emit_ustX
PARAMS((const expressionS
*, int, void*));
190 static void emit_sextX
PARAMS((const expressionS
*, int, void*));
191 static void emit_retjcr
PARAMS((const expressionS
*, int, void*));
193 static void s_alpha_text
PARAMS((int));
194 static void s_alpha_data
PARAMS((int));
196 static void s_alpha_comm
PARAMS((int));
198 #if defined (OBJ_ECOFF) || defined (OBJ_EVAX)
199 static void s_alpha_rdata
PARAMS((int));
202 static void s_alpha_sdata
PARAMS((int));
205 static void s_alpha_section
PARAMS((int));
207 static void s_alpha_gprel32
PARAMS((int));
208 static void s_alpha_float_cons
PARAMS((int));
209 static void s_alpha_proc
PARAMS((int));
210 static void s_alpha_set
PARAMS((int));
211 static void s_alpha_base
PARAMS((int));
212 static void s_alpha_align
PARAMS((int));
213 static void s_alpha_stringer
PARAMS((int));
214 static void s_alpha_space
PARAMS((int));
216 static void create_literal_section
PARAMS((const char *, segT
*, symbolS
**));
218 static void select_gp_value
PARAMS((void));
220 static void alpha_align
PARAMS((int, char *, symbolS
*));
223 /* Generic assembler global variables which must be defined by all
226 /* These are exported to relaxing code, even though we don't do any
227 relaxing on this processor currently. */
228 int md_short_jump_size
= 4;
229 int md_long_jump_size
= 4;
231 /* Characters which always start a comment. */
232 const char comment_chars
[] = "#";
234 /* Characters which start a comment at the beginning of a line. */
235 const char line_comment_chars
[] = "#";
237 /* Characters which may be used to separate multiple commands on a
239 const char line_separator_chars
[] = ";";
241 /* Characters which are used to indicate an exponent in a floating
243 const char EXP_CHARS
[] = "eE";
245 /* Characters which mean that a number is a floating point constant,
248 const char FLT_CHARS
[] = "dD";
250 /* XXX: Do all of these really get used on the alpha?? */
251 char FLT_CHARS
[] = "rRsSfFdDxXpP";
255 const char *md_shortopts
= "Fm:g+1h:H";
257 const char *md_shortopts
= "Fm:g";
260 struct option md_longopts
[] = {
261 #define OPTION_32ADDR (OPTION_MD_BASE)
262 { "32addr", no_argument
, NULL
, OPTION_32ADDR
},
263 { NULL
, no_argument
, NULL
, 0 }
266 size_t md_longopts_size
= sizeof(md_longopts
);
271 #define AXP_REG_R16 16
272 #define AXP_REG_R17 17
274 #define AXP_REG_T9 22
276 #define AXP_REG_T10 23
278 #define AXP_REG_T11 24
280 #define AXP_REG_T12 25
281 #define AXP_REG_AI 25
283 #define AXP_REG_FP 29
286 #define AXP_REG_GP AXP_REG_PV
287 #endif /* OBJ_EVAX */
289 /* The cpu for which we are generating code */
290 static unsigned alpha_target
= AXP_OPCODE_ALL
;
291 static const char *alpha_target_name
= "<all>";
293 /* The hash table of instruction opcodes */
294 static struct hash_control
*alpha_opcode_hash
;
296 /* The hash table of macro opcodes */
297 static struct hash_control
*alpha_macro_hash
;
300 /* The $gp relocation symbol */
301 static symbolS
*alpha_gp_symbol
;
303 /* XXX: what is this, and why is it exported? */
304 valueT alpha_gp_value
;
307 /* The current $gp register */
308 static int alpha_gp_register
= AXP_REG_GP
;
310 /* A table of the register symbols */
311 static symbolS
*alpha_register_table
[64];
313 /* Constant sections, or sections of constants */
315 static segT alpha_lita_section
;
316 static segT alpha_lit4_section
;
319 static segT alpha_link_section
;
321 static segT alpha_lit8_section
;
323 /* Symbols referring to said sections. */
325 static symbolS
*alpha_lita_symbol
;
326 static symbolS
*alpha_lit4_symbol
;
329 static symbolS
*alpha_link_symbol
;
331 static symbolS
*alpha_lit8_symbol
;
333 /* Is the assembler not allowed to use $at? */
334 static int alpha_noat_on
= 0;
336 /* Are macros enabled? */
337 static int alpha_macros_on
= 1;
339 /* Are floats disabled? */
340 static int alpha_nofloats_on
= 0;
342 /* Are addresses 32 bit? */
343 static int alpha_addr32_on
= 0;
345 /* Symbol labelling the current insn. When the Alpha gas sees
348 and the section happens to not be on an eight byte boundary, it
349 will align both the symbol and the .quad to an eight byte boundary. */
350 static symbolS
*alpha_insn_label
;
352 /* Whether we should automatically align data generation pseudo-ops.
353 .align 0 will turn this off. */
354 static int alpha_auto_align_on
= 1;
356 /* The known current alignment of the current section. */
357 static int alpha_current_align
;
359 /* These are exported to ECOFF code. */
360 unsigned long alpha_gprmask
, alpha_fprmask
;
363 /* Collect information about current procedure here. */
365 symbolS
*symbol
; /* proc pdesc symbol */
367 int framereg
; /* register for frame pointer */
368 int framesize
; /* size of frame */
378 static int alpha_flag_hash_long_names
= 0; /* -+ */
379 static int alpha_flag_show_after_trunc
= 0; /* -H */
380 static int alpha_flag_no_hash_mixed_case
= 0; /* -h NUM */
382 /* Flag that determines how we map names. This takes several values, and
383 * is set with the -h switch. A value of zero implies names should be
384 * upper case, and the presence of the -h switch inhibits the case hack.
385 * No -h switch at all sets alpha_vms_name_mapping to 0, and allows case hacking.
386 * A value of 2 (set with -h2) implies names should be
387 * all lower case, with no case hack. A value of 3 (set with -h3) implies
388 * that case should be preserved. */
390 /* If the -+ switch is given, then the hash is appended to any name that is
391 * longer than 31 characters, regardless of the setting of the -h switch.
394 static char alpha_vms_name_mapping
= 0;
396 static int alpha_basereg_clobbered
;
399 /* The macro table */
401 static const struct alpha_macro alpha_macros
[] = {
402 /* Load/Store macros */
403 { "lda", emit_lda
, NULL
,
404 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
405 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
406 { "ldah", emit_ldah
, NULL
,
407 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
409 { "ldl", emit_ir_load
, "ldl",
410 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
411 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
412 { "ldl_l", emit_ir_load
, "ldl_l",
413 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
414 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
415 { "ldq", emit_ir_load
, "ldq",
416 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
417 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
418 { "ldq_l", emit_ir_load
, "ldq_l",
419 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
420 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
421 { "ldq_u", emit_ir_load
, "ldq_u",
422 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
423 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
424 { "ldf", emit_loadstore
, "ldf",
425 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
426 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
427 { "ldg", emit_loadstore
, "ldg",
428 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
429 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
430 { "lds", emit_loadstore
, "lds",
431 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
432 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
433 { "ldt", emit_loadstore
, "ldt",
434 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
435 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
437 { "ldb", emit_ldX
, (void *)0,
438 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
439 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
440 { "ldbu", emit_ldXu
, (void *)0,
441 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
442 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
443 { "ldw", emit_ldX
, (void *)1,
444 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
445 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
446 { "ldwu", emit_ldXu
, (void *)1,
447 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
448 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
450 { "uldw", emit_uldX
, (void*)1,
451 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
452 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
453 { "uldwu", emit_uldXu
, (void*)1,
454 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
455 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
456 { "uldl", emit_uldX
, (void*)2,
457 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
458 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
459 { "uldlu", emit_uldXu
, (void*)2,
460 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
461 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
462 { "uldq", emit_uldXu
, (void*)3,
463 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
464 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
466 { "ldgp", emit_ldgp
, NULL
,
467 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
} },
469 { "ldi", emit_lda
, NULL
,
470 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
471 { "ldil", emit_ldil
, NULL
,
472 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
473 { "ldiq", emit_lda
, NULL
,
474 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
476 { "ldif" emit_ldiq
, NULL
,
477 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
478 { "ldid" emit_ldiq
, NULL
,
479 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
480 { "ldig" emit_ldiq
, NULL
,
481 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
482 { "ldis" emit_ldiq
, NULL
,
483 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
484 { "ldit" emit_ldiq
, NULL
,
485 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
488 { "stl", emit_loadstore
, "stl",
489 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
490 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
491 { "stl_c", emit_loadstore
, "stl_c",
492 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
493 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
494 { "stq", emit_loadstore
, "stq",
495 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
496 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
497 { "stq_c", emit_loadstore
, "stq_c",
498 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
499 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
500 { "stq_u", emit_loadstore
, "stq_u",
501 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
502 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
503 { "stf", emit_loadstore
, "stf",
504 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
505 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
506 { "stg", emit_loadstore
, "stg",
507 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
508 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
509 { "sts", emit_loadstore
, "sts",
510 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
511 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
512 { "stt", emit_loadstore
, "stt",
513 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
514 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
516 { "stb", emit_stX
, (void*)0,
517 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
518 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
519 { "stw", emit_stX
, (void*)1,
520 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
521 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
522 { "ustw", emit_ustX
, (void*)1,
523 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
524 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
525 { "ustl", emit_ustX
, (void*)2,
526 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
527 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
528 { "ustq", emit_ustX
, (void*)3,
529 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
530 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
532 /* Arithmetic macros */
534 { "absl" emit_absl
, 1, { IR
} },
535 { "absl" emit_absl
, 2, { IR
, IR
} },
536 { "absl" emit_absl
, 2, { EXP
, IR
} },
537 { "absq" emit_absq
, 1, { IR
} },
538 { "absq" emit_absq
, 2, { IR
, IR
} },
539 { "absq" emit_absq
, 2, { EXP
, IR
} },
542 { "sextb", emit_sextX
, (void *)0,
543 { MACRO_IR
, MACRO_IR
, MACRO_EOA
,
545 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
546 { "sextw", emit_sextX
, (void *)1,
547 { MACRO_IR
, MACRO_IR
, MACRO_EOA
,
549 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
551 { "divl", emit_division
, "__divl",
552 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
553 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
554 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
555 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
556 { "divlu", emit_division
, "__divlu",
557 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
558 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
559 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
560 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
561 { "divq", emit_division
, "__divq",
562 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
563 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
564 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
565 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
566 { "divqu", emit_division
, "__divqu",
567 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
568 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
569 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
570 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
571 { "reml", emit_division
, "__reml",
572 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
573 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
574 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
575 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
576 { "remlu", emit_division
, "__remlu",
577 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
578 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
579 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
580 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
581 { "remq", emit_division
, "__remq",
582 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
583 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
584 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
585 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
586 { "remqu", emit_division
, "__remqu",
587 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
588 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
589 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
590 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
592 { "jsr", emit_jsrjmp
, "jsr",
593 { MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
594 MACRO_PIR
, MACRO_EOA
,
595 MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
596 MACRO_EXP
, MACRO_EOA
} },
597 { "jmp", emit_jsrjmp
, "jmp",
598 { MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
599 MACRO_PIR
, MACRO_EOA
,
600 MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
601 MACRO_EXP
, MACRO_EOA
} },
602 { "ret", emit_retjcr
, "ret",
603 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
605 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
606 MACRO_PIR
, MACRO_EOA
,
607 MACRO_EXP
, MACRO_EOA
,
609 { "jcr", emit_retjcr
, "jcr",
610 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
612 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
613 MACRO_PIR
, MACRO_EOA
,
614 MACRO_EXP
, MACRO_EOA
,
616 { "jsr_coroutine", emit_retjcr
, "jcr",
617 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
619 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
620 MACRO_PIR
, MACRO_EOA
,
621 MACRO_EXP
, MACRO_EOA
,
625 static const int alpha_num_macros
626 = sizeof(alpha_macros
) / sizeof(*alpha_macros
);
628 /* Public interface functions */
630 /* This function is called once, at assembler startup time. It sets
631 up all the tables, etc. that the MD part of the assembler will
632 need, that can be determined before arguments are parsed. */
639 /* Create the opcode hash table */
641 alpha_opcode_hash
= hash_new ();
642 for (i
= 0; i
< alpha_num_opcodes
; )
644 const char *name
, *retval
;
646 name
= alpha_opcodes
[i
].name
;
647 retval
= hash_insert (alpha_opcode_hash
, name
, (PTR
)&alpha_opcodes
[i
]);
649 as_fatal ("internal error: can't hash opcode `%s': %s", name
, retval
);
651 while (++i
< alpha_num_opcodes
652 && (alpha_opcodes
[i
].name
== name
653 || !strcmp (alpha_opcodes
[i
].name
, name
)))
657 /* Some opcodes include modifiers of various sorts with a "/mod" syntax,
658 like the architecture manual suggests. However, for use with gcc at
659 least, we also need access to those same opcodes without the "/". */
660 for (i
= 0; i
< alpha_num_opcodes
; )
662 const char *name
, *slash
;
663 name
= alpha_opcodes
[i
].name
;
664 if ((slash
= strchr(name
, '/')) != NULL
)
666 char *p
= xmalloc (strlen (name
));
667 memcpy(p
, name
, slash
-name
);
668 strcpy(p
+(slash
-name
), slash
+1);
670 (void)hash_insert(alpha_opcode_hash
, p
, (PTR
)&alpha_opcodes
[i
]);
671 /* Ignore failures -- the opcode table does duplicate some
672 variants in different forms, like "hw_stq" and "hw_st/q". */
675 while (++i
< alpha_num_opcodes
676 && (alpha_opcodes
[i
].name
== name
677 || !strcmp (alpha_opcodes
[i
].name
, name
)))
681 /* Create the macro hash table */
683 alpha_macro_hash
= hash_new ();
684 for (i
= 0; i
< alpha_num_macros
; )
686 const char *name
, *retval
;
688 name
= alpha_macros
[i
].name
;
689 retval
= hash_insert (alpha_macro_hash
, name
, (PTR
)&alpha_macros
[i
]);
691 as_fatal ("internal error: can't hash macro `%s': %s", name
, retval
);
693 while (++i
< alpha_num_macros
694 && (alpha_macros
[i
].name
== name
695 || !strcmp (alpha_macros
[i
].name
, name
)))
699 /* Construct symbols for each of the registers */
701 for (i
= 0; i
< 32; ++i
)
704 sprintf(name
, "$%d", i
);
705 alpha_register_table
[i
] = symbol_create(name
, reg_section
, i
,
711 sprintf(name
, "$f%d", i
-32);
712 alpha_register_table
[i
] = symbol_create(name
, reg_section
, i
,
716 /* Create the special symbols and sections we'll be using */
718 /* So .sbss will get used for tiny objects. */
719 bfd_set_gp_size (stdoutput
, 8);
722 create_literal_section (".lita", &alpha_lita_section
, &alpha_lita_symbol
);
724 /* For handling the GP, create a symbol that won't be output in the
725 symbol table. We'll edit it out of relocs later. */
726 alpha_gp_symbol
= symbol_create ("<GP value>", alpha_lita_section
, 0x8000,
731 create_literal_section (".link", &alpha_link_section
, &alpha_link_symbol
);
739 sec
= subseg_new(".mdebug", (subsegT
)0);
740 bfd_set_section_flags(stdoutput
, sec
, SEC_HAS_CONTENTS
|SEC_READONLY
);
741 bfd_set_section_alignment(stdoutput
, sec
, 3);
744 sec
= subseg_new(".reginfo", (subsegT
)0);
745 /* The ABI says this section should be loaded so that the running
746 program can access it. */
747 bfd_set_section_flags(stdoutput
, sec
,
748 SEC_ALLOC
|SEC_LOAD
|SEC_READONLY
|SEC_DATA
);
749 bfd_set_section_alignement(stdoutput
, sec
, 3);
754 subseg_set(text_section
, 0);
757 /* The public interface to the instruction assembler. */
763 char opname
[32]; /* current maximum is 13 */
764 expressionS tok
[MAX_INSN_ARGS
];
765 int ntok
, opnamelen
, trunclen
;
767 /* split off the opcode */
768 opnamelen
= strspn (str
, "abcdefghijklmnopqrstuvwxyz_/48");
769 trunclen
= (opnamelen
< sizeof (opname
) - 1
771 : sizeof (opname
) - 1);
772 memcpy (opname
, str
, trunclen
);
773 opname
[trunclen
] = '\0';
775 /* tokenize the rest of the line */
776 if ((ntok
= tokenize_arguments (str
+ opnamelen
, tok
, MAX_INSN_ARGS
)) < 0)
778 as_bad ("syntax error");
783 assemble_tokens (opname
, tok
, ntok
, alpha_macros_on
);
786 /* Round up a section's size to the appropriate boundary. */
789 md_section_align (seg
, size
)
793 int align
= bfd_get_section_alignment(stdoutput
, seg
);
794 valueT mask
= ((valueT
)1 << align
) - 1;
796 return (size
+ mask
) & ~mask
;
799 /* Turn a string in input_line_pointer into a floating point constant
800 of type type, and store the appropriate bytes in *litP. The number
801 of LITTLENUMS emitted is stored in *sizeP. An error message is
802 returned, or NULL on OK. */
804 /* Equal to MAX_PRECISION in atof-ieee.c */
805 #define MAX_LITTLENUMS 6
808 md_atof (type
, litP
, sizeP
)
814 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
815 LITTLENUM_TYPE
*wordP
;
817 char *atof_ieee (), *vax_md_atof ();
823 /* VAX md_atof doesn't like "G" for some reason. */
827 return vax_md_atof (type
, litP
, sizeP
);
850 return "Bad call to MD_ATOF()";
852 t
= atof_ieee (input_line_pointer
, type
, words
);
854 input_line_pointer
= t
;
855 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
857 for (wordP
= words
+ prec
- 1; prec
--;)
859 md_number_to_chars (litP
, (long) (*wordP
--), sizeof (LITTLENUM_TYPE
));
860 litP
+= sizeof (LITTLENUM_TYPE
);
866 /* Take care of the target-specific command-line options. */
869 md_parse_option (c
, arg
)
876 alpha_nofloats_on
= 1;
884 /* Ignore `-g' so gcc can provide this option to the Digital
885 UNIX assembler, which otherwise would throw away info that
891 static const struct machine
897 { "21064", AXP_OPCODE_EV4
|AXP_OPCODE_ALL
},
898 { "21066", AXP_OPCODE_EV4
|AXP_OPCODE_ALL
},
899 { "21164", AXP_OPCODE_EV5
|AXP_OPCODE_ALL
},
900 { "21164a", AXP_OPCODE_EV56
|AXP_OPCODE_ALL
},
901 { "ev4", AXP_OPCODE_EV4
|AXP_OPCODE_ALL
},
902 { "ev45", AXP_OPCODE_EV4
|AXP_OPCODE_ALL
},
903 { "ev5", AXP_OPCODE_EV5
|AXP_OPCODE_ALL
},
904 { "ev56", AXP_OPCODE_EV56
|AXP_OPCODE_ALL
},
905 { "all", AXP_OPCODE_ALL
},
909 for (p
= m
; p
->name
; ++p
)
910 if (strcmp(arg
, p
->name
) == 0)
912 alpha_target_name
= p
->name
, alpha_target
= p
->flags
;
915 as_warn("Unknown CPU identifier `%s'", arg
);
921 case '+': /* For g++. Hash any name > 31 chars long. */
922 alpha_flag_hash_long_names
= 1;
925 case 'H': /* Show new symbol after hash truncation */
926 alpha_flag_show_after_trunc
= 1;
929 case 'h': /* No hashing of mixed-case names */
931 alpha_vms_name_mapping
= atoi (arg
);
932 alpha_flag_no_hash_mixed_case
= 1;
944 /* Print a description of the command-line options that we accept. */
947 md_show_usage (stream
)
952 -32addr treat addresses as 32-bit values\n\
953 -F lack floating point instructions support\n\
954 -m21064 | -m21066 | -m21164 | -m21164a\n\
955 -mev4 | -mev45 | -mev5 | -mev56 | -mall\n\
956 specify variant of Alpha architecture\n",
961 -+ hash encode names longer than 31 characters\n\
962 -H show new symbol after hash truncation\n\
963 -h NUM don't hash mixed-case names, and adjust case:\n\
964 0 = upper, 2 = lower, 3 = preserve case\n",
969 /* Decide from what point a pc-relative relocation is relative to,
970 relative to the pc-relative fixup. Er, relatively speaking. */
976 valueT addr
= fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
977 switch (fixP
->fx_r_type
)
979 case BFD_RELOC_ALPHA_GPDISP
:
980 case BFD_RELOC_ALPHA_GPDISP_HI16
:
981 case BFD_RELOC_ALPHA_GPDISP_LO16
:
984 return fixP
->fx_size
+ addr
;
988 /* Attempt to simplify or even eliminate a fixup. The return value is
989 ignored; perhaps it was once meaningful, but now it is historical.
990 To indicate that a fixup has been eliminated, set fixP->fx_done.
992 For ELF, here it is that we transform the GPDISP_HI16 reloc we used
993 internally into the GPDISP reloc used externally. We had to do
994 this so that we'd have the GPDISP_LO16 reloc as a tag to compute
995 the distance to the "lda" instruction for setting the addend to
999 md_apply_fix (fixP
, valueP
)
1003 char * const fixpos
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
1004 valueT value
= *valueP
;
1005 unsigned image
, size
;
1007 switch (fixP
->fx_r_type
)
1009 /* The GPDISP relocations are processed internally with a symbol
1010 referring to the current function; we need to drop in a value
1011 which, when added to the address of the start of the function,
1012 gives the desired GP. */
1013 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1015 fixS
*next
= fixP
->fx_next
;
1016 assert (next
->fx_r_type
== BFD_RELOC_ALPHA_GPDISP_LO16
);
1018 fixP
->fx_offset
= (next
->fx_frag
->fr_address
+ next
->fx_where
1019 - fixP
->fx_frag
->fr_address
- fixP
->fx_where
);
1021 value
= (value
- sign_extend_16 (value
)) >> 16;
1024 fixP
->fx_r_type
= BFD_RELOC_ALPHA_GPDISP
;
1028 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1029 value
= sign_extend_16 (value
);
1030 fixP
->fx_offset
= 0;
1036 fixP
->fx_addsy
= section_symbol (absolute_section
);
1037 md_number_to_chars (fixpos
, value
, 2);
1049 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
1051 md_number_to_chars (fixpos
, value
, size
);
1057 case BFD_RELOC_GPREL32
:
1058 assert (fixP
->fx_subsy
== alpha_gp_symbol
);
1060 /* FIXME: inherited this obliviousness of `value' -- why? */
1061 md_number_to_chars (fixpos
, -alpha_gp_value
, 4);
1065 case BFD_RELOC_GPREL32
:
1069 case BFD_RELOC_23_PCREL_S2
:
1070 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
1072 image
= bfd_getl32(fixpos
);
1073 image
= (image
& ~0x1FFFFF) | ((value
>> 2) & 0x1FFFFF);
1078 case BFD_RELOC_ALPHA_HINT
:
1079 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
1081 image
= bfd_getl32(fixpos
);
1082 image
= (image
& ~0x3FFF) | ((value
>> 2) & 0x3FFF);
1088 case BFD_RELOC_ALPHA_LITERAL
:
1089 md_number_to_chars (fixpos
, value
, 2);
1092 case BFD_RELOC_ALPHA_LITUSE
:
1096 case BFD_RELOC_ALPHA_LITERAL
:
1097 case BFD_RELOC_ALPHA_LITUSE
:
1101 case BFD_RELOC_ALPHA_LINKAGE
:
1107 const struct alpha_operand
*operand
;
1109 if (fixP
->fx_r_type
<= BFD_RELOC_UNUSED
)
1110 as_fatal ("unhandled relocation type %s",
1111 bfd_get_reloc_code_name (fixP
->fx_r_type
));
1113 assert (fixP
->fx_r_type
< BFD_RELOC_UNUSED
+ alpha_num_operands
);
1114 operand
= &alpha_operands
[fixP
->fx_r_type
- BFD_RELOC_UNUSED
];
1116 /* The rest of these fixups only exist internally during symbol
1117 resolution and have no representation in the object file.
1118 Therefore they must be completely resolved as constants. */
1120 if (fixP
->fx_addsy
!= 0
1121 && fixP
->fx_addsy
->bsym
->section
!= absolute_section
)
1122 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
1123 "non-absolute expression in constant field");
1125 image
= bfd_getl32(fixpos
);
1126 image
= insert_operand(image
, operand
, (offsetT
)value
,
1127 fixP
->fx_file
, fixP
->fx_line
);
1132 if (fixP
->fx_addsy
!= 0 || fixP
->fx_pcrel
!= 0)
1136 as_warn_where(fixP
->fx_file
, fixP
->fx_line
,
1137 "type %d reloc done?\n", fixP
->fx_r_type
);
1142 md_number_to_chars(fixpos
, image
, 4);
1150 * Look for a register name in the given symbol.
1154 md_undefined_symbol(name
)
1159 int is_float
= 0, num
;
1164 if (name
[1] == 'p' && name
[2] == '\0')
1165 return alpha_register_table
[AXP_REG_FP
];
1170 if (!isdigit(*++name
))
1174 case '0': case '1': case '2': case '3': case '4':
1175 case '5': case '6': case '7': case '8': case '9':
1176 if (name
[1] == '\0')
1177 num
= name
[0] - '0';
1178 else if (name
[0] != '0' && isdigit(name
[1]) && name
[2] == '\0')
1180 num
= (name
[0] - '0')*10 + name
[1] - '0';
1187 if (!alpha_noat_on
&& num
== AXP_REG_AT
)
1188 as_warn("Used $at without \".set noat\"");
1189 return alpha_register_table
[num
+ is_float
];
1192 if (name
[1] == 't' && name
[2] == '\0')
1195 as_warn("Used $at without \".set noat\"");
1196 return alpha_register_table
[AXP_REG_AT
];
1201 if (name
[1] == 'p' && name
[2] == '\0')
1202 return alpha_register_table
[alpha_gp_register
];
1206 if (name
[1] == 'p' && name
[2] == '\0')
1207 return alpha_register_table
[AXP_REG_SP
];
1215 /* @@@ Magic ECOFF bits. */
1218 alpha_frob_ecoff_data ()
1221 /* $zero and $f31 are read-only */
1222 alpha_gprmask
&= ~1;
1223 alpha_fprmask
&= ~1;
1227 /* Hook to remember a recently defined label so that the auto-align
1228 code can adjust the symbol after we know what alignment will be
1232 alpha_define_label (sym
)
1235 alpha_insn_label
= sym
;
1238 /* Return true if we must always emit a reloc for a type and false if
1239 there is some hope of resolving it a assembly time. */
1242 alpha_force_relocation (f
)
1245 switch (f
->fx_r_type
)
1247 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1248 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1249 case BFD_RELOC_ALPHA_GPDISP
:
1250 case BFD_RELOC_ALPHA_LITERAL
:
1251 case BFD_RELOC_ALPHA_LITUSE
:
1252 case BFD_RELOC_GPREL32
:
1254 case BFD_RELOC_ALPHA_LINKAGE
:
1258 case BFD_RELOC_23_PCREL_S2
:
1261 case BFD_RELOC_ALPHA_HINT
:
1265 assert(f
->fx_r_type
> BFD_RELOC_UNUSED
&&
1266 f
->fx_r_type
< BFD_RELOC_UNUSED
+ alpha_num_operands
);
1271 /* Return true if we can partially resolve a relocation now. */
1274 alpha_fix_adjustable (f
)
1278 /* Prevent all adjustments to global symbols */
1279 if (S_IS_EXTERN (f
->fx_addsy
))
1283 /* Are there any relocation types for which we must generate a reloc
1284 but we can adjust the values contained within it? */
1285 switch (f
->fx_r_type
)
1287 case BFD_RELOC_GPREL32
:
1290 return !alpha_force_relocation (f
);
1295 /* Generate the BFD reloc to be stuck in the object file from the
1296 fixup used internally in the assembler. */
1299 tc_gen_reloc (sec
, fixp
)
1305 reloc
= (arelent
*) bfd_alloc_by_size_t (stdoutput
, sizeof (arelent
));
1306 reloc
->sym_ptr_ptr
= &fixp
->fx_addsy
->bsym
;
1307 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
1309 /* Make sure none of our internal relocations make it this far.
1310 They'd better have been fully resolved by this point. */
1311 assert (fixp
->fx_r_type
< BFD_RELOC_UNUSED
);
1313 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
1314 if (reloc
->howto
== NULL
)
1316 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1317 "cannot represent `%s' relocation in object file",
1318 bfd_get_reloc_code_name (fixp
->fx_r_type
));
1322 if (!fixp
->fx_pcrel
!= !reloc
->howto
->pc_relative
)
1324 as_fatal ("internal error? cannot generate `%s' relocation",
1325 bfd_get_reloc_code_name (fixp
->fx_r_type
));
1327 assert (!fixp
->fx_pcrel
== !reloc
->howto
->pc_relative
);
1330 if (fixp
->fx_r_type
== BFD_RELOC_ALPHA_LITERAL
)
1332 /* fake out bfd_perform_relocation. sigh */
1333 reloc
->addend
= -alpha_gp_value
;
1338 reloc
->addend
= fixp
->fx_offset
;
1341 * Ohhh, this is ugly. The problem is that if this is a local global
1342 * symbol, the relocation will entirely be performed at link time, not
1343 * at assembly time. bfd_perform_reloc doesn't know about this sort
1344 * of thing, and as a result we need to fake it out here.
1346 if (S_IS_EXTERN (fixp
->fx_addsy
) && !S_IS_COMMON(fixp
->fx_addsy
))
1347 reloc
->addend
-= fixp
->fx_addsy
->bsym
->value
;
1354 /* Parse a register name off of the input_line and return a register
1355 number. Gets md_undefined_symbol above to do the register name
1358 Only called as a part of processing the ECOFF .frame directive. */
1361 tc_get_register (frame
)
1364 int framereg
= AXP_REG_SP
;
1367 if (*input_line_pointer
== '$')
1369 char *s
= input_line_pointer
;
1370 char c
= get_symbol_end ();
1371 symbolS
*sym
= md_undefined_symbol (s
);
1373 *strchr(s
, '\0') = c
;
1374 if (sym
&& (framereg
= S_GET_VALUE (sym
)) <= 31)
1377 as_warn ("frame reg expected, using $%d.", framereg
);
1380 note_gpreg (framereg
);
1385 /* Parse the arguments to an opcode. */
1388 tokenize_arguments (str
, tok
, ntok
)
1393 expressionS
*end_tok
= tok
+ ntok
;
1394 char *old_input_line_pointer
;
1395 int saw_comma
= 0, saw_arg
= 0;
1397 memset (tok
, 0, sizeof(*tok
)*ntok
);
1399 /* Save and restore input_line_pointer around this function */
1400 old_input_line_pointer
= input_line_pointer
;
1401 input_line_pointer
= str
;
1403 while (tok
< end_tok
&& *input_line_pointer
)
1406 switch (*input_line_pointer
)
1412 ++input_line_pointer
;
1413 if (saw_comma
|| !saw_arg
)
1420 char *hold
= input_line_pointer
++;
1422 /* First try for parenthesized register ... */
1424 if (*input_line_pointer
== ')' && tok
->X_op
== O_register
)
1426 tok
->X_op
= (saw_comma
? O_cpregister
: O_pregister
);
1429 ++input_line_pointer
;
1434 /* ... then fall through to plain expression */
1435 input_line_pointer
= hold
;
1439 if (saw_arg
&& !saw_comma
)
1442 if (tok
->X_op
== O_illegal
|| tok
->X_op
== O_absent
)
1455 input_line_pointer
= old_input_line_pointer
;
1456 return ntok
- (end_tok
- tok
);
1459 input_line_pointer
= old_input_line_pointer
;
1463 /* Search forward through all variants of an opcode looking for a
1466 static const struct alpha_opcode
*
1467 find_opcode_match(first_opcode
, tok
, pntok
, pcpumatch
)
1468 const struct alpha_opcode
*first_opcode
;
1469 const expressionS
*tok
;
1473 const struct alpha_opcode
*opcode
= first_opcode
;
1475 int got_cpu_match
= 0;
1479 const unsigned char *opidx
;
1482 /* Don't match opcodes that don't exist on this architecture */
1483 if (!(opcode
->flags
& alpha_target
))
1488 for (opidx
= opcode
->operands
; *opidx
; ++opidx
)
1490 const struct alpha_operand
*operand
= &alpha_operands
[*opidx
];
1492 /* only take input from real operands */
1493 if (operand
->flags
& AXP_OPERAND_FAKE
)
1496 /* when we expect input, make sure we have it */
1499 if ((operand
->flags
& AXP_OPERAND_OPTIONAL_MASK
) == 0)
1504 /* match operand type with expression type */
1505 switch (operand
->flags
& AXP_OPERAND_TYPECHECK_MASK
)
1507 case AXP_OPERAND_IR
:
1508 if (tok
[tokidx
].X_op
!= O_register
1509 || !is_ir_num(tok
[tokidx
].X_add_number
))
1512 case AXP_OPERAND_FPR
:
1513 if (tok
[tokidx
].X_op
!= O_register
1514 || !is_fpr_num(tok
[tokidx
].X_add_number
))
1517 case AXP_OPERAND_IR
|AXP_OPERAND_PARENS
:
1518 if (tok
[tokidx
].X_op
!= O_pregister
1519 || !is_ir_num(tok
[tokidx
].X_add_number
))
1522 case AXP_OPERAND_IR
|AXP_OPERAND_PARENS
|AXP_OPERAND_COMMA
:
1523 if (tok
[tokidx
].X_op
!= O_cpregister
1524 || !is_ir_num(tok
[tokidx
].X_add_number
))
1528 case AXP_OPERAND_RELATIVE
:
1529 case AXP_OPERAND_SIGNED
:
1530 case AXP_OPERAND_UNSIGNED
:
1531 switch (tok
[tokidx
].X_op
)
1543 /* everything else should have been fake */
1549 /* possible match -- did we use all of our input? */
1558 while (++opcode
-alpha_opcodes
< alpha_num_opcodes
1559 && !strcmp(opcode
->name
, first_opcode
->name
));
1562 *pcpumatch
= got_cpu_match
;
1567 /* Search forward through all variants of a macro looking for a syntax
1570 static const struct alpha_macro
*
1571 find_macro_match(first_macro
, tok
, pntok
)
1572 const struct alpha_macro
*first_macro
;
1573 const expressionS
*tok
;
1576 const struct alpha_macro
*macro
= first_macro
;
1581 const enum alpha_macro_arg
*arg
= macro
->argsets
;
1596 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_register
1597 || !is_ir_num(tok
[tokidx
].X_add_number
))
1602 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_pregister
1603 || !is_ir_num(tok
[tokidx
].X_add_number
))
1608 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_cpregister
1609 || !is_ir_num(tok
[tokidx
].X_add_number
))
1614 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_register
1615 || !is_fpr_num(tok
[tokidx
].X_add_number
))
1623 switch (tok
[tokidx
].X_op
)
1636 while (*arg
!= MACRO_EOA
)
1644 while (++macro
-alpha_macros
< alpha_num_macros
1645 && !strcmp(macro
->name
, first_macro
->name
));
1650 /* Insert an operand value into an instruction. */
1653 insert_operand(insn
, operand
, val
, file
, line
)
1655 const struct alpha_operand
*operand
;
1660 if (operand
->bits
!= 32 && !(operand
->flags
& AXP_OPERAND_NOOVERFLOW
))
1664 if (operand
->flags
& AXP_OPERAND_SIGNED
)
1666 max
= (1 << (operand
->bits
- 1)) - 1;
1667 min
= -(1 << (operand
->bits
- 1));
1671 max
= (1 << operand
->bits
) - 1;
1675 if (val
< min
|| val
> max
)
1678 "operand out of range (%s not between %d and %d)";
1679 char buf
[sizeof(val
)*3+2];
1681 sprint_value(buf
, val
);
1683 as_warn_where(file
, line
, err
, buf
, min
, max
);
1685 as_warn(err
, buf
, min
, max
);
1689 if (operand
->insert
)
1691 const char *errmsg
= NULL
;
1693 insn
= (*operand
->insert
)(insn
, val
, &errmsg
);
1698 insn
|= ((val
& ((1 << operand
->bits
) - 1)) << operand
->shift
);
1704 * Turn an opcode description and a set of arguments into
1705 * an instruction and a fixup.
1709 assemble_insn(opcode
, tok
, ntok
, insn
)
1710 const struct alpha_opcode
*opcode
;
1711 const expressionS
*tok
;
1713 struct alpha_insn
*insn
;
1715 const unsigned char *argidx
;
1719 memset(insn
, 0, sizeof(*insn
));
1720 image
= opcode
->opcode
;
1722 for (argidx
= opcode
->operands
; *argidx
; ++argidx
)
1724 const struct alpha_operand
*operand
= &alpha_operands
[*argidx
];
1725 const expressionS
*t
;
1727 if (operand
->flags
& AXP_OPERAND_FAKE
)
1729 /* fake operands take no value and generate no fixup */
1730 image
= insert_operand(image
, operand
, 0, NULL
, 0);
1736 switch (operand
->flags
& AXP_OPERAND_OPTIONAL_MASK
)
1738 case AXP_OPERAND_DEFAULT_FIRST
:
1741 case AXP_OPERAND_DEFAULT_SECOND
:
1744 case AXP_OPERAND_DEFAULT_ZERO
:
1746 static const expressionS zero_exp
= { 0, 0, 0, O_constant
, 1 };
1762 image
= insert_operand(image
, operand
, regno(t
->X_add_number
),
1767 image
= insert_operand(image
, operand
, t
->X_add_number
, NULL
, 0);
1772 struct alpha_fixup
*fixup
;
1774 if (insn
->nfixups
>= MAX_INSN_FIXUPS
)
1775 as_fatal("too many fixups");
1777 fixup
= &insn
->fixups
[insn
->nfixups
++];
1780 fixup
->reloc
= operand
->default_reloc
;
1790 * Actually output an instruction with its fixup.
1795 struct alpha_insn
*insn
;
1800 /* Take care of alignment duties */
1801 if (alpha_auto_align_on
&& alpha_current_align
< 2)
1802 alpha_align (2, (char *) NULL
, alpha_insn_label
);
1803 if (alpha_current_align
> 2)
1804 alpha_current_align
= 2;
1805 alpha_insn_label
= NULL
;
1807 /* Write out the instruction. */
1809 md_number_to_chars (f
, insn
->insn
, 4);
1811 /* Apply the fixups in order */
1812 for (i
= 0; i
< insn
->nfixups
; ++i
)
1814 struct alpha_fixup
*fixup
= &insn
->fixups
[i
];
1818 /* Some fixups are only used internally and so have no howto */
1819 if (fixup
->reloc
> BFD_RELOC_UNUSED
)
1820 size
= 4, pcrel
= 0;
1822 /* These relocation types are only used internally. */
1823 else if (fixup
->reloc
== BFD_RELOC_ALPHA_GPDISP_HI16
1824 || fixup
->reloc
== BFD_RELOC_ALPHA_GPDISP_LO16
)
1826 size
= 2, pcrel
= 0;
1831 reloc_howto_type
*reloc_howto
1832 = bfd_reloc_type_lookup (stdoutput
, fixup
->reloc
);
1833 assert (reloc_howto
);
1835 size
= bfd_get_reloc_size (reloc_howto
);
1836 pcrel
= reloc_howto
->pc_relative
;
1838 assert (size
>= 1 && size
<= 4);
1840 fixP
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, size
,
1841 &fixup
->exp
, pcrel
, fixup
->reloc
);
1843 /* Turn off complaints that the addend is too large for some fixups */
1844 switch (fixup
->reloc
)
1846 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1847 case BFD_RELOC_ALPHA_LITERAL
:
1848 case BFD_RELOC_GPREL32
:
1849 fixP
->fx_no_overflow
= 1;
1857 /* Given an opcode name and a pre-tokenized set of arguments, assemble
1858 the insn, but do not emit it.
1860 Note that this implies no macros allowed, since we can't store more
1861 than one insn in an insn structure. */
1864 assemble_tokens_to_insn(opname
, tok
, ntok
, insn
)
1866 const expressionS
*tok
;
1868 struct alpha_insn
*insn
;
1870 const struct alpha_opcode
*opcode
;
1872 /* search opcodes */
1873 opcode
= (const struct alpha_opcode
*) hash_find (alpha_opcode_hash
, opname
);
1877 opcode
= find_opcode_match (opcode
, tok
, &ntok
, &cpumatch
);
1880 assemble_insn (opcode
, tok
, ntok
, insn
);
1884 as_bad ("inappropriate arguments for opcode `%s'", opname
);
1886 as_bad ("opcode `%s' not supported for target %s", opname
,
1890 as_bad ("unknown opcode `%s'", opname
);
1893 /* Given an opcode name and a pre-tokenized set of arguments, take the
1894 opcode all the way through emission. */
1897 assemble_tokens (opname
, tok
, ntok
, local_macros_on
)
1899 const expressionS
*tok
;
1901 int local_macros_on
;
1903 int found_something
= 0;
1904 const struct alpha_opcode
*opcode
;
1905 const struct alpha_macro
*macro
;
1909 if (local_macros_on
)
1911 macro
= ((const struct alpha_macro
*)
1912 hash_find (alpha_macro_hash
, opname
));
1915 found_something
= 1;
1916 macro
= find_macro_match (macro
, tok
, &ntok
);
1919 (*macro
->emit
) (tok
, ntok
, macro
->arg
);
1925 /* search opcodes */
1926 opcode
= (const struct alpha_opcode
*) hash_find (alpha_opcode_hash
, opname
);
1929 found_something
= 1;
1930 opcode
= find_opcode_match (opcode
, tok
, &ntok
, &cpumatch
);
1933 struct alpha_insn insn
;
1934 assemble_insn (opcode
, tok
, ntok
, &insn
);
1940 if (found_something
)
1942 as_bad ("inappropriate arguments for opcode `%s'", opname
);
1944 as_bad ("opcode `%s' not supported for target %s", opname
,
1947 as_bad ("unknown opcode `%s'", opname
);
1951 /* Some instruction sets indexed by lg(size) */
1952 static const char * const sextX_op
[] = { "sextb", "sextw", "sextl", NULL
};
1953 static const char * const insXl_op
[] = { "insbl", "inswl", "insll", "insql" };
1954 static const char * const insXh_op
[] = { NULL
, "inswh", "inslh", "insqh" };
1955 static const char * const extXl_op
[] = { "extbl", "extwl", "extll", "extql" };
1956 static const char * const extXh_op
[] = { NULL
, "extwh", "extlh", "extqh" };
1957 static const char * const mskXl_op
[] = { "mskbl", "mskwl", "mskll", "mskql" };
1958 static const char * const mskXh_op
[] = { NULL
, "mskwh", "msklh", "mskqh" };
1960 /* Implement the ldgp macro. */
1963 emit_ldgp (tok
, ntok
, unused
)
1964 const expressionS
*tok
;
1971 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
1972 /* from "ldgp r1,n(r2)", generate "ldah r1,X(R2); lda r1,Y(r1)"
1973 with appropriate constants and relocations. */
1974 struct alpha_insn insn
;
1975 expressionS newtok
[3];
1978 /* We're going to need this symbol in md_apply_fix(). */
1979 (void) section_symbol (absolute_section
);
1982 if (regno (tok
[2].X_add_number
) == AXP_REG_PV
)
1983 ecoff_set_gp_prolog_size (0);
1987 set_tok_const (newtok
[1], 0);
1990 assemble_tokens_to_insn ("ldah", newtok
, 3, &insn
);
1995 assert (addend
.X_op
== O_constant
);
1996 addend
.X_op
= O_symbol
;
1997 addend
.X_add_symbol
= alpha_gp_symbol
;
2001 insn
.fixups
[0].exp
= addend
;
2002 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_GPDISP_HI16
;
2006 set_tok_preg (newtok
[2], tok
[0].X_add_number
);
2008 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
2011 addend
.X_add_number
+= 4;
2015 insn
.fixups
[0].exp
= addend
;
2016 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_GPDISP_LO16
;
2019 #endif /* OBJ_ECOFF || OBJ_ELF */
2024 /* Add symbol+addend to link pool.
2025 Return offset from basesym to entry in link pool.
2027 Add new fixup only if offset isn't 16bit. */
2030 add_to_link_pool (basesym
, sym
, addend
)
2035 segT current_section
= now_seg
;
2036 int current_subsec
= now_subseg
;
2038 bfd_reloc_code_real_type reloc_type
;
2040 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
2043 offset
= -basesym
->sy_obj
;
2045 /* @@ This assumes all entries in a given section will be of the same
2046 size... Probably correct, but unwise to rely on. */
2047 /* This must always be called with the same subsegment. */
2049 if (seginfo
->frchainP
)
2050 for (fixp
= seginfo
->frchainP
->fix_root
;
2051 fixp
!= (fixS
*) NULL
;
2052 fixp
= fixp
->fx_next
, offset
+= 8)
2054 if (fixp
->fx_addsy
== sym
&& fixp
->fx_offset
== addend
)
2056 if (range_signed_16 (offset
))
2063 /* Not found in 16bit signed range. */
2065 subseg_set (alpha_link_section
, 0);
2069 fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, sym
, addend
, 0,
2072 subseg_set (current_section
, current_subsec
);
2073 seginfo
->literal_pool_size
+= 8;
2077 #endif /* OBJ_EVAX */
2079 /* Load a (partial) expression into a target register.
2081 If poffset is not null, after the call it will either contain
2082 O_constant 0, or a 16-bit offset appropriate for any MEM format
2083 instruction. In addition, pbasereg will be modified to point to
2084 the base register to use in that MEM format instruction.
2086 In any case, *pbasereg should contain a base register to add to the
2087 expression. This will normally be either AXP_REG_ZERO or
2088 alpha_gp_register. Symbol addresses will always be loaded via $gp,
2089 so "foo($0)" is interpreted as adding the address of foo to $0;
2090 i.e. "ldq $targ, LIT($gp); addq $targ, $0, $targ". Odd, perhaps,
2091 but this is what OSF/1 does.
2093 Finally, the return value is true if the calling macro may emit a
2094 LITUSE reloc if otherwise appropriate. */
2097 load_expression (targreg
, exp
, pbasereg
, poffset
)
2099 const expressionS
*exp
;
2101 expressionS
*poffset
;
2103 int emit_lituse
= 0;
2104 offsetT addend
= exp
->X_add_number
;
2105 int basereg
= *pbasereg
;
2106 struct alpha_insn insn
;
2107 expressionS newtok
[3];
2116 /* attempt to reduce .lit load by splitting the offset from
2117 its symbol when possible, but don't create a situation in
2119 if (!range_signed_32 (addend
) &&
2120 (alpha_noat_on
|| targreg
== AXP_REG_AT
))
2122 lit
= add_to_literal_pool (exp
->X_add_symbol
, addend
,
2123 alpha_lita_section
, 8);
2128 lit
= add_to_literal_pool (exp
->X_add_symbol
, 0,
2129 alpha_lita_section
, 8);
2133 as_fatal ("overflow in literal (.lita) table");
2135 /* emit "ldq r, lit(gp)" */
2137 if (basereg
!= alpha_gp_register
&& targreg
== basereg
)
2140 as_bad ("macro requires $at register while noat in effect");
2141 if (targreg
== AXP_REG_AT
)
2142 as_bad ("macro requires $at while $at in use");
2144 set_tok_reg (newtok
[0], AXP_REG_AT
);
2147 set_tok_reg (newtok
[0], targreg
);
2148 set_tok_sym (newtok
[1], alpha_lita_symbol
, lit
);
2149 set_tok_preg (newtok
[2], alpha_gp_register
);
2151 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
2153 assert (insn
.nfixups
== 1);
2154 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITERAL
;
2155 #endif /* OBJ_ECOFF */
2157 /* emit "ldq r, gotoff(gp)" */
2159 if (basereg
!= alpha_gp_register
&& targreg
== basereg
)
2162 as_bad ("macro requires $at register while noat in effect");
2163 if (targreg
== AXP_REG_AT
)
2164 as_bad ("macro requires $at while $at in use");
2166 set_tok_reg (newtok
[0], AXP_REG_AT
);
2169 set_tok_reg (newtok
[0], targreg
);
2171 if (!range_signed_32 (addend
)
2172 && (alpha_noat_on
|| targreg
== AXP_REG_AT
))
2179 set_tok_sym (newtok
[1], exp
->X_add_symbol
, 0);
2182 set_tok_preg (newtok
[2], alpha_gp_register
);
2184 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
2186 assert (insn
.nfixups
== 1);
2187 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITERAL
;
2188 #endif /* OBJ_ELF */
2192 if (alpha_basereg_clobbered
)
2194 /* no basereg, reload basreg from 0(FP). */
2195 set_tok_reg (newtok
[0], targreg
);
2196 set_tok_const (newtok
[1], 0);
2197 set_tok_preg (newtok
[2], AXP_REG_FP
);
2199 assemble_tokens ("ldq", newtok
, 3, 0);
2202 /* Find symbol or symbol pointer in link section. */
2204 if (exp
->X_add_symbol
== alpha_evax_proc
.symbol
)
2206 if (range_signed_16 (addend
))
2208 set_tok_reg (newtok
[0], targreg
);
2209 set_tok_const (newtok
[1], addend
);
2210 set_tok_preg (newtok
[2], basereg
);
2211 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
2216 set_tok_reg (newtok
[0], targreg
);
2217 set_tok_const (newtok
[1], 0);
2218 set_tok_preg (newtok
[2], basereg
);
2219 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
2224 if (!range_signed_32 (addend
))
2226 link
= add_to_link_pool (alpha_evax_proc
.symbol
,
2227 exp
->X_add_symbol
, addend
);
2232 link
= add_to_link_pool (alpha_evax_proc
.symbol
,
2233 exp
->X_add_symbol
, 0);
2235 set_tok_reg (newtok
[0], targreg
);
2236 set_tok_const (newtok
[1], link
);
2237 set_tok_preg (newtok
[2], basereg
);
2238 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
2240 #endif /* OBJ_EVAX */
2246 if (basereg
!= alpha_gp_register
&& basereg
!= AXP_REG_ZERO
)
2248 /* emit "addq r, base, r" */
2250 set_tok_reg (newtok
[1], basereg
);
2251 set_tok_reg (newtok
[2], targreg
);
2252 assemble_tokens ("addq", newtok
, 3, 0);
2263 /* Assume that this difference expression will be resolved to an
2264 absolute value and that that value will fit in 16 bits. */
2266 set_tok_reg (newtok
[0], targreg
);
2268 set_tok_preg (newtok
[2], basereg
);
2269 assemble_tokens ("lda", newtok
, 3, 0);
2272 set_tok_const (*poffset
, 0);
2279 if (!range_signed_32 (addend
))
2283 /* for 64-bit addends, just put it in the literal pool */
2287 /* emit "ldq targreg, lit(basereg)" */
2288 lit
= add_to_link_pool (alpha_evax_proc
.symbol
,
2289 section_symbol (absolute_section
), addend
);
2290 set_tok_reg (newtok
[0], targreg
);
2291 set_tok_const (newtok
[1], lit
);
2292 set_tok_preg (newtok
[2], alpha_gp_register
);
2293 assemble_tokens ("ldq", newtok
, 3, 0);
2297 if (alpha_lit8_section
== NULL
)
2299 create_literal_section (".lit8",
2300 &alpha_lit8_section
,
2301 &alpha_lit8_symbol
);
2302 S_SET_VALUE (alpha_lit8_symbol
, 0x8000);
2305 lit
= add_to_literal_pool (NULL
, addend
, alpha_lit8_section
, 8) - 0x8000;
2307 as_fatal ("overflow in literal (.lit8) table");
2309 /* emit "ldq litreg, .lit8+lit" */
2311 if (targreg
== basereg
)
2314 as_bad ("macro requires $at register while noat in effect");
2315 if (targreg
== AXP_REG_AT
)
2316 as_bad ("macro requires $at while $at in use");
2318 set_tok_reg (newtok
[0], AXP_REG_AT
);
2321 set_tok_reg (newtok
[0], targreg
);
2322 set_tok_sym (newtok
[1], alpha_lit8_symbol
, lit
);
2324 assemble_tokens ("ldq", newtok
, 2, 1); /* note this does recurse */
2326 /* emit "addq litreg, base, target" */
2328 if (basereg
!= AXP_REG_ZERO
)
2330 set_tok_reg (newtok
[1], basereg
);
2331 set_tok_reg (newtok
[2], targreg
);
2332 assemble_tokens ("addq", newtok
, 3, 0);
2334 #endif /* !OBJ_EVAX */
2337 set_tok_const (*poffset
, 0);
2338 *pbasereg
= targreg
;
2342 offsetT low
, high
, extra
, tmp
;
2344 /* for 32-bit operands, break up the addend */
2346 low
= sign_extend_16 (addend
);
2348 high
= sign_extend_16 (tmp
>> 16);
2350 if (tmp
- (high
<< 16))
2354 high
= sign_extend_16 (tmp
>> 16);
2359 set_tok_reg (newtok
[0], targreg
);
2360 set_tok_preg (newtok
[2], basereg
);
2364 /* emit "ldah r, extra(r) */
2365 set_tok_const (newtok
[1], extra
);
2366 assemble_tokens ("ldah", newtok
, 3, 0);
2367 set_tok_preg (newtok
[2], basereg
= targreg
);
2372 /* emit "ldah r, high(r) */
2373 set_tok_const (newtok
[1], high
);
2374 assemble_tokens ("ldah", newtok
, 3, 0);
2376 set_tok_preg (newtok
[2], basereg
);
2379 if ((low
&& !poffset
) || (!poffset
&& basereg
!= targreg
))
2381 /* emit "lda r, low(base)" */
2382 set_tok_const (newtok
[1], low
);
2383 assemble_tokens ("lda", newtok
, 3, 0);
2389 set_tok_const (*poffset
, low
);
2390 *pbasereg
= basereg
;
2396 /* The lda macro differs from the lda instruction in that it handles
2397 most simple expressions, particualrly symbol address loads and
2401 emit_lda (tok
, ntok
, unused
)
2402 const expressionS
*tok
;
2409 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
2411 basereg
= tok
[2].X_add_number
;
2413 (void) load_expression (tok
[0].X_add_number
, &tok
[1], &basereg
, NULL
);
2416 /* The ldah macro differs from the ldah instruction in that it has $31
2417 as an implied base register. */
2420 emit_ldah (tok
, ntok
, unused
)
2421 const expressionS
*tok
;
2425 expressionS newtok
[3];
2429 set_tok_preg (newtok
[2], AXP_REG_ZERO
);
2431 assemble_tokens ("ldah", newtok
, 3, 0);
2434 /* Handle all "simple" integer register loads -- ldq, ldq_l, ldq_u,
2435 etc. They differ from the real instructions in that they do simple
2436 expressions like the lda macro. */
2439 emit_ir_load (tok
, ntok
, opname
)
2440 const expressionS
*tok
;
2444 int basereg
, lituse
;
2445 expressionS newtok
[3];
2446 struct alpha_insn insn
;
2449 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
2451 basereg
= tok
[2].X_add_number
;
2453 lituse
= load_expression (tok
[0].X_add_number
, &tok
[1], &basereg
,
2457 set_tok_preg (newtok
[2], basereg
);
2459 assemble_tokens_to_insn ((const char *)opname
, newtok
, 3, &insn
);
2463 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
2464 if (insn
.nfixups
> 0)
2466 memmove (&insn
.fixups
[1], &insn
.fixups
[0],
2467 sizeof(struct alpha_fixup
) * insn
.nfixups
);
2470 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITUSE
;
2471 insn
.fixups
[0].exp
.X_op
= O_constant
;
2472 insn
.fixups
[0].exp
.X_add_number
= 1;
2477 /* special hack. If the basereg is clobbered for a call
2478 all lda's before the call don't have a basereg. */
2479 if ((tok
[0].X_op
== O_register
)
2480 && (tok
[0].X_add_number
== alpha_gp_register
))
2482 alpha_basereg_clobbered
= 1;
2487 /* Handle fp register loads, and both integer and fp register stores.
2488 Again, we handle simple expressions. */
2491 emit_loadstore (tok
, ntok
, opname
)
2492 const expressionS
*tok
;
2496 int basereg
, lituse
;
2497 expressionS newtok
[3];
2498 struct alpha_insn insn
;
2501 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
2503 basereg
= tok
[2].X_add_number
;
2505 if (tok
[1].X_op
!= O_constant
|| !range_signed_16(tok
[1].X_add_number
))
2508 as_bad ("macro requires $at register while noat in effect");
2510 lituse
= load_expression (AXP_REG_AT
, &tok
[1], &basereg
, &newtok
[1]);
2519 set_tok_preg (newtok
[2], basereg
);
2521 assemble_tokens_to_insn ((const char *)opname
, newtok
, 3, &insn
);
2525 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
2526 if (insn
.nfixups
> 0)
2528 memmove (&insn
.fixups
[1], &insn
.fixups
[0],
2529 sizeof(struct alpha_fixup
) * insn
.nfixups
);
2532 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITUSE
;
2533 insn
.fixups
[0].exp
.X_op
= O_constant
;
2534 insn
.fixups
[0].exp
.X_add_number
= 1;
2540 /* Load a half-word or byte as an unsigned value. */
2543 emit_ldXu (tok
, ntok
, vlgsize
)
2544 const expressionS
*tok
;
2548 expressionS newtok
[3];
2551 as_bad ("macro requires $at register while noat in effect");
2553 /* emit "lda $at, exp" */
2555 memcpy (newtok
, tok
, sizeof(expressionS
)*ntok
);
2556 newtok
[0].X_add_number
= AXP_REG_AT
;
2557 assemble_tokens ("lda", newtok
, ntok
, 1);
2559 /* emit "ldq_u targ, 0($at)" */
2562 set_tok_const (newtok
[1], 0);
2563 set_tok_preg (newtok
[2], AXP_REG_AT
);
2564 assemble_tokens ("ldq_u", newtok
, 3, 1);
2566 /* emit "extXl targ, $at, targ" */
2568 set_tok_reg (newtok
[1], AXP_REG_AT
);
2569 newtok
[2] = newtok
[0];
2570 assemble_tokens (extXl_op
[(long)vlgsize
], newtok
, 3, 1);
2573 /* Load a half-word or byte as a signed value. */
2576 emit_ldX (tok
, ntok
, vlgsize
)
2577 const expressionS
*tok
;
2581 emit_ldXu (tok
, ntok
, vlgsize
);
2582 assemble_tokens (sextX_op
[(long)vlgsize
], tok
, 1, 1);
2585 /* Load an integral value from an unaligned address as an unsigned
2589 emit_uldXu (tok
, ntok
, vlgsize
)
2590 const expressionS
*tok
;
2594 long lgsize
= (long)vlgsize
;
2595 expressionS newtok
[3];
2598 as_bad ("macro requires $at register while noat in effect");
2600 /* emit "lda $at, exp" */
2602 memcpy (newtok
, tok
, sizeof(expressionS
)*ntok
);
2603 newtok
[0].X_add_number
= AXP_REG_AT
;
2604 assemble_tokens ("lda", newtok
, ntok
, 1);
2606 /* emit "ldq_u $t9, 0($at)" */
2608 set_tok_reg (newtok
[0], AXP_REG_T9
);
2609 set_tok_const (newtok
[1], 0);
2610 set_tok_preg (newtok
[2], AXP_REG_AT
);
2611 assemble_tokens ("ldq_u", newtok
, 3, 1);
2613 /* emit "ldq_u $t10, size-1($at)" */
2615 set_tok_reg (newtok
[0], AXP_REG_T10
);
2616 set_tok_const (newtok
[1], (1<<lgsize
)-1);
2617 assemble_tokens ("ldq_u", newtok
, 3, 1);
2619 /* emit "extXl $t9, $at, $t9" */
2621 set_tok_reg (newtok
[0], AXP_REG_T9
);
2622 set_tok_reg (newtok
[1], AXP_REG_AT
);
2623 set_tok_reg (newtok
[2], AXP_REG_T9
);
2624 assemble_tokens (extXl_op
[lgsize
], newtok
, 3, 1);
2626 /* emit "extXh $t10, $at, $t10" */
2628 set_tok_reg (newtok
[0], AXP_REG_T10
);
2629 set_tok_reg (newtok
[2], AXP_REG_T10
);
2630 assemble_tokens (extXh_op
[lgsize
], newtok
, 3, 1);
2632 /* emit "or $t9, $t10, targ" */
2634 set_tok_reg (newtok
[0], AXP_REG_T9
);
2635 set_tok_reg (newtok
[1], AXP_REG_T10
);
2637 assemble_tokens ("or", newtok
, 3, 1);
2640 /* Load an integral value from an unaligned address as a signed value.
2641 Note that quads should get funneled to the unsigned load since we
2642 don't have to do the sign extension. */
2645 emit_uldX (tok
, ntok
, vlgsize
)
2646 const expressionS
*tok
;
2650 emit_uldXu (tok
, ntok
, vlgsize
);
2651 assemble_tokens (sextX_op
[(long)vlgsize
], tok
, 1, 1);
2654 /* Implement the ldil macro. */
2657 emit_ldil (tok
, ntok
, unused
)
2658 const expressionS
*tok
;
2662 expressionS newtok
[2];
2664 memcpy (newtok
, tok
, sizeof(newtok
));
2665 newtok
[1].X_add_number
= sign_extend_32 (tok
[1].X_add_number
);
2667 assemble_tokens ("lda", newtok
, ntok
, 1);
2670 /* Store a half-word or byte. */
2673 emit_stX (tok
, ntok
, vlgsize
)
2674 const expressionS
*tok
;
2677 int lgsize
= (int)(long)vlgsize
;
2678 expressionS newtok
[3];
2681 as_bad("macro requires $at register while noat in effect");
2683 /* emit "lda $at, exp" */
2685 memcpy (newtok
, tok
, sizeof(expressionS
)*ntok
);
2686 newtok
[0].X_add_number
= AXP_REG_AT
;
2687 assemble_tokens ("lda", newtok
, ntok
, 1);
2689 /* emit "ldq_u $t9, 0($at)" */
2691 set_tok_reg (newtok
[0], AXP_REG_T9
);
2692 set_tok_const (newtok
[1], 0);
2693 set_tok_preg (newtok
[2], AXP_REG_AT
);
2694 assemble_tokens ("ldq_u", newtok
, 3, 1);
2696 /* emit "insXl src, $at, $t10" */
2699 set_tok_reg (newtok
[1], AXP_REG_AT
);
2700 set_tok_reg (newtok
[2], AXP_REG_T10
);
2701 assemble_tokens (insXl_op
[lgsize
], newtok
, 3, 1);
2703 /* emit "mskXl $t9, $at, $t9" */
2705 set_tok_reg (newtok
[0], AXP_REG_T9
);
2706 newtok
[2] = newtok
[0];
2707 assemble_tokens (mskXl_op
[lgsize
], newtok
, 3, 1);
2709 /* emit "or $t9, $t10, $t9" */
2711 set_tok_reg (newtok
[1], AXP_REG_T10
);
2712 assemble_tokens ("or", newtok
, 3, 1);
2714 /* emit "stq_u $t9, 0($at) */
2716 set_tok_const (newtok
[1], 0);
2717 set_tok_preg (newtok
[2], AXP_REG_AT
);
2718 assemble_tokens ("stq_u", newtok
, 3, 1);
2721 /* Store an integer to an unaligned address. */
2724 emit_ustX (tok
, ntok
, vlgsize
)
2725 const expressionS
*tok
;
2729 int lgsize
= (int)(long)vlgsize
;
2730 expressionS newtok
[3];
2732 /* emit "lda $at, exp" */
2734 memcpy (newtok
, tok
, sizeof(expressionS
)*ntok
);
2735 newtok
[0].X_add_number
= AXP_REG_AT
;
2736 assemble_tokens ("lda", newtok
, ntok
, 1);
2738 /* emit "ldq_u $9, 0($at)" */
2740 set_tok_reg (newtok
[0], AXP_REG_T9
);
2741 set_tok_const (newtok
[1], 0);
2742 set_tok_preg (newtok
[2], AXP_REG_AT
);
2743 assemble_tokens ("ldq_u", newtok
, 3, 1);
2745 /* emit "ldq_u $10, size-1($at)" */
2747 set_tok_reg (newtok
[0], AXP_REG_T10
);
2748 set_tok_const (newtok
[1], (1 << lgsize
)-1);
2749 assemble_tokens ("ldq_u", newtok
, 3, 1);
2751 /* emit "insXl src, $at, $t11" */
2754 set_tok_reg (newtok
[1], AXP_REG_AT
);
2755 set_tok_reg (newtok
[2], AXP_REG_T11
);
2756 assemble_tokens (insXl_op
[lgsize
], newtok
, 3, 1);
2758 /* emit "insXh src, $at, $t12" */
2760 set_tok_reg (newtok
[2], AXP_REG_T12
);
2761 assemble_tokens (insXh_op
[lgsize
], newtok
, 3, 1);
2763 /* emit "mskXl $t9, $at, $t9" */
2765 set_tok_reg (newtok
[0], AXP_REG_T9
);
2766 newtok
[2] = newtok
[0];
2767 assemble_tokens (mskXl_op
[lgsize
], newtok
, 3, 1);
2769 /* emit "mskXh $t10, $at, $t10" */
2771 set_tok_reg (newtok
[0], AXP_REG_T10
);
2772 newtok
[2] = newtok
[0];
2773 assemble_tokens (mskXh_op
[lgsize
], newtok
, 3, 1);
2775 /* emit "or $t9, $t11, $t9" */
2777 set_tok_reg (newtok
[0], AXP_REG_T9
);
2778 set_tok_reg (newtok
[1], AXP_REG_T11
);
2779 newtok
[2] = newtok
[0];
2780 assemble_tokens ("or", newtok
, 3, 1);
2782 /* emit "or $t10, $t12, $t10" */
2784 set_tok_reg (newtok
[0], AXP_REG_T10
);
2785 set_tok_reg (newtok
[1], AXP_REG_T12
);
2786 newtok
[2] = newtok
[0];
2787 assemble_tokens ("or", newtok
, 3, 1);
2789 /* emit "stq_u $t9, 0($at)" */
2791 set_tok_reg (newtok
[0], AXP_REG_T9
);
2792 set_tok_const (newtok
[1], 0);
2793 set_tok_preg (newtok
[2], AXP_REG_AT
);
2794 assemble_tokens ("stq_u", newtok
, 3, 1);
2796 /* emit "stq_u $t10, size-1($at)" */
2798 set_tok_reg (newtok
[0], AXP_REG_T10
);
2799 set_tok_const (newtok
[1], (1 << lgsize
)-1);
2800 assemble_tokens ("stq_u", newtok
, 3, 1);
2803 /* Sign extend a half-word or byte. The 32-bit sign extend is
2804 implemented as "addl $31, $r, $t" in the opcode table. */
2807 emit_sextX (tok
, ntok
, vlgsize
)
2808 const expressionS
*tok
;
2812 int bitshift
= 64 - 8*(1 << (long)vlgsize
);
2813 expressionS newtok
[3];
2815 /* emit "sll src,bits,dst" */
2818 set_tok_const (newtok
[1], bitshift
);
2819 newtok
[2] = tok
[ntok
- 1];
2820 assemble_tokens ("sll", newtok
, 3, 1);
2822 /* emit "sra dst,bits,dst" */
2824 newtok
[0] = newtok
[2];
2825 assemble_tokens ("sra", newtok
, 3, 1);
2828 /* Implement the division and modulus macros. */
2832 /* Make register usage like in normal procedure call.
2833 Don't clobber PV and RA. */
2836 emit_division (tok
, ntok
, symname
)
2837 const expressionS
*tok
;
2841 /* DIVISION and MODULUS. Yech.
2846 * mov x,R16 # if x != R16
2847 * mov y,R17 # if y != R17
2852 * with appropriate optimizations if R0,R16,R17 are the registers
2853 * specified by the compiler.
2858 expressionS newtok
[3];
2860 xr
= regno (tok
[0].X_add_number
);
2861 yr
= regno (tok
[1].X_add_number
);
2866 rr
= regno (tok
[2].X_add_number
);
2868 /* Move the operands into the right place */
2869 if (yr
== AXP_REG_R16
&& xr
== AXP_REG_R17
)
2871 /* They are in exactly the wrong order -- swap through AT */
2874 as_bad ("macro requires $at register while noat in effect");
2876 set_tok_reg (newtok
[0], AXP_REG_R16
);
2877 set_tok_reg (newtok
[1], AXP_REG_AT
);
2878 assemble_tokens ("mov", newtok
, 2, 1);
2880 set_tok_reg (newtok
[0], AXP_REG_R17
);
2881 set_tok_reg (newtok
[1], AXP_REG_R16
);
2882 assemble_tokens ("mov", newtok
, 2, 1);
2884 set_tok_reg (newtok
[0], AXP_REG_AT
);
2885 set_tok_reg (newtok
[1], AXP_REG_R17
);
2886 assemble_tokens ("mov", newtok
, 2, 1);
2890 if (yr
== AXP_REG_R16
)
2892 set_tok_reg (newtok
[0], AXP_REG_R16
);
2893 set_tok_reg (newtok
[1], AXP_REG_R17
);
2894 assemble_tokens ("mov", newtok
, 2, 1);
2897 if (xr
!= AXP_REG_R16
)
2899 set_tok_reg (newtok
[0], xr
);
2900 set_tok_reg (newtok
[1], AXP_REG_R16
);
2901 assemble_tokens ("mov", newtok
, 2, 1);
2904 if (yr
!= AXP_REG_R16
&& yr
!= AXP_REG_R17
)
2906 set_tok_reg (newtok
[0], yr
);
2907 set_tok_reg (newtok
[1], AXP_REG_R17
);
2908 assemble_tokens ("mov", newtok
, 2, 1);
2912 sym
= symbol_find_or_make ((const char *)symname
);
2914 set_tok_reg (newtok
[0], AXP_REG_AT
);
2915 set_tok_sym (newtok
[1], sym
, 0);
2916 assemble_tokens ("lda", newtok
, 2, 1);
2918 /* Call the division routine */
2919 set_tok_reg (newtok
[0], AXP_REG_AT
);
2920 set_tok_cpreg (newtok
[1], AXP_REG_AT
);
2921 set_tok_const (newtok
[2], 0);
2922 assemble_tokens ("jsr", newtok
, 3, 1);
2924 /* Move the result to the right place */
2925 if (rr
!= AXP_REG_R0
)
2927 set_tok_reg (newtok
[0], AXP_REG_R0
);
2928 set_tok_reg (newtok
[1], rr
);
2929 assemble_tokens ("mov", newtok
, 2, 1);
2933 #else /* !OBJ_EVAX */
2936 emit_division (tok
, ntok
, symname
)
2937 const expressionS
*tok
;
2941 /* DIVISION and MODULUS. Yech.
2951 * with appropriate optimizations if t10,t11,t12 are the registers
2952 * specified by the compiler.
2957 expressionS newtok
[3];
2959 xr
= regno (tok
[0].X_add_number
);
2960 yr
= regno (tok
[1].X_add_number
);
2965 rr
= regno (tok
[2].X_add_number
);
2967 sym
= symbol_find_or_make ((const char *)symname
);
2969 /* Move the operands into the right place */
2970 if (yr
== AXP_REG_T10
&& xr
== AXP_REG_T11
)
2972 /* They are in exactly the wrong order -- swap through AT */
2975 as_bad ("macro requires $at register while noat in effect");
2977 set_tok_reg (newtok
[0], AXP_REG_T10
);
2978 set_tok_reg (newtok
[1], AXP_REG_AT
);
2979 assemble_tokens ("mov", newtok
, 2, 1);
2981 set_tok_reg (newtok
[0], AXP_REG_T11
);
2982 set_tok_reg (newtok
[1], AXP_REG_T10
);
2983 assemble_tokens ("mov", newtok
, 2, 1);
2985 set_tok_reg (newtok
[0], AXP_REG_AT
);
2986 set_tok_reg (newtok
[1], AXP_REG_T11
);
2987 assemble_tokens ("mov", newtok
, 2, 1);
2991 if (yr
== AXP_REG_T10
)
2993 set_tok_reg (newtok
[0], AXP_REG_T10
);
2994 set_tok_reg (newtok
[1], AXP_REG_T11
);
2995 assemble_tokens ("mov", newtok
, 2, 1);
2998 if (xr
!= AXP_REG_T10
)
3000 set_tok_reg (newtok
[0], xr
);
3001 set_tok_reg (newtok
[1], AXP_REG_T10
);
3002 assemble_tokens ("mov", newtok
, 2, 1);
3005 if (yr
!= AXP_REG_T10
&& yr
!= AXP_REG_T11
)
3007 set_tok_reg (newtok
[0], yr
);
3008 set_tok_reg (newtok
[1], AXP_REG_T11
);
3009 assemble_tokens ("mov", newtok
, 2, 1);
3013 /* Call the division routine */
3014 set_tok_reg (newtok
[0], AXP_REG_T9
);
3015 set_tok_sym (newtok
[1], sym
, 0);
3016 assemble_tokens ("jsr", newtok
, 2, 1);
3018 /* Reload the GP register */
3022 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
3023 set_tok_reg (newtok
[0], alpha_gp_register
);
3024 set_tok_const (newtok
[1], 0);
3025 set_tok_preg (newtok
[2], AXP_REG_T9
);
3026 assemble_tokens ("ldgp", newtok
, 3, 1);
3029 /* Move the result to the right place */
3030 if (rr
!= AXP_REG_T12
)
3032 set_tok_reg (newtok
[0], AXP_REG_T12
);
3033 set_tok_reg (newtok
[1], rr
);
3034 assemble_tokens ("mov", newtok
, 2, 1);
3038 #endif /* !OBJ_EVAX */
3040 /* The jsr and jmp macros differ from their instruction counterparts
3041 in that they can load the target address and default most
3045 emit_jsrjmp (tok
, ntok
, vopname
)
3046 const expressionS
*tok
;
3050 const char *opname
= (const char *) vopname
;
3051 struct alpha_insn insn
;
3052 expressionS newtok
[3];
3053 int r
, tokidx
= 0, lituse
= 0;
3055 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_register
)
3056 r
= regno (tok
[tokidx
++].X_add_number
);
3058 r
= strcmp (opname
, "jmp") == 0 ? AXP_REG_ZERO
: AXP_REG_RA
;
3060 set_tok_reg (newtok
[0], r
);
3062 if (tokidx
< ntok
&&
3063 (tok
[tokidx
].X_op
== O_pregister
|| tok
[tokidx
].X_op
== O_cpregister
))
3064 r
= regno (tok
[tokidx
++].X_add_number
);
3066 /* keep register if jsr $n.<sym> */
3070 int basereg
= alpha_gp_register
;
3071 lituse
= load_expression (r
= AXP_REG_PV
, &tok
[tokidx
], &basereg
, NULL
);
3075 set_tok_cpreg (newtok
[1], r
);
3078 /* FIXME: Add hint relocs to BFD for evax. */
3081 newtok
[2] = tok
[tokidx
];
3084 set_tok_const (newtok
[2], 0);
3086 assemble_tokens_to_insn (opname
, newtok
, 3, &insn
);
3088 /* add the LITUSE fixup */
3091 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3092 if (insn
.nfixups
> 0)
3094 memmove (&insn
.fixups
[1], &insn
.fixups
[0],
3095 sizeof(struct alpha_fixup
) * insn
.nfixups
);
3098 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITUSE
;
3099 insn
.fixups
[0].exp
.X_op
= O_constant
;
3100 insn
.fixups
[0].exp
.X_add_number
= 3;
3106 alpha_basereg_clobbered
= 0;
3108 /* reload PV from 0(FP) if it is our current base register. */
3109 if (alpha_gp_register
== AXP_REG_PV
)
3111 set_tok_reg (newtok
[0], AXP_REG_PV
);
3112 set_tok_const (newtok
[1], 0);
3113 set_tok_preg (newtok
[2], AXP_REG_FP
);
3114 assemble_tokens ("ldq", newtok
, 3, 0);
3119 /* The ret and jcr instructions differ from their instruction
3120 counterparts in that everything can be defaulted. */
3123 emit_retjcr (tok
, ntok
, vopname
)
3124 const expressionS
*tok
;
3128 const char *opname
= (const char *)vopname
;
3129 expressionS newtok
[3];
3132 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_register
)
3133 r
= regno (tok
[tokidx
++].X_add_number
);
3137 set_tok_reg (newtok
[0], r
);
3139 if (tokidx
< ntok
&&
3140 (tok
[tokidx
].X_op
== O_pregister
|| tok
[tokidx
].X_op
== O_cpregister
))
3141 r
= regno (tok
[tokidx
++].X_add_number
);
3145 set_tok_cpreg (newtok
[1], r
);
3148 newtok
[2] = tok
[tokidx
];
3150 set_tok_const (newtok
[2], strcmp(opname
, "ret") == 0);
3152 assemble_tokens (opname
, newtok
, 3, 0);
3155 /* Assembler directives */
3157 /* Handle the .text pseudo-op. This is like the usual one, but it
3158 clears alpha_insn_label and restores auto alignment. */
3166 alpha_insn_label
= NULL
;
3167 alpha_auto_align_on
= 1;
3168 alpha_current_align
= 0;
3171 /* Handle the .data pseudo-op. This is like the usual one, but it
3172 clears alpha_insn_label and restores auto alignment. */
3179 alpha_insn_label
= NULL
;
3180 alpha_auto_align_on
= 1;
3181 alpha_current_align
= 0;
3186 /* Handle the OSF/1 .comm pseudo quirks. */
3189 s_alpha_comm (ignore
)
3192 register char *name
;
3196 register symbolS
*symbolP
;
3198 name
= input_line_pointer
;
3199 c
= get_symbol_end ();
3201 /* just after name is now '\0' */
3202 p
= input_line_pointer
;
3207 /* Alpha OSF/1 compiler doesn't provide the comma, gcc does. */
3208 if (*input_line_pointer
== ',')
3210 input_line_pointer
++;
3213 if ((temp
= get_absolute_expression ()) < 0)
3215 as_warn (".COMMon length (%ld.) <0! Ignored.", (long) temp
);
3216 ignore_rest_of_line ();
3221 symbolP
= symbol_find_or_make (name
);
3224 if (S_IS_DEFINED (symbolP
))
3226 as_bad ("Ignoring attempt to re-define symbol");
3227 ignore_rest_of_line ();
3233 /* Fill common area with zeros. */
3235 segT current_seg
= now_seg
;
3236 subsegT current_subseg
= now_subseg
;
3238 subseg_set (bss_section
, 1);
3241 symbolP
->sy_frag
= frag_now
;
3242 pfrag
= frag_var (rs_org
, 1, 1, (relax_substateT
)0, symbolP
,
3246 S_SET_SEGMENT (symbolP
, bss_section
);
3248 subseg_set (current_seg
, current_subseg
);
3252 if (S_GET_VALUE (symbolP
))
3254 if (S_GET_VALUE (symbolP
) != (valueT
) temp
)
3255 as_bad ("Length of .comm \"%s\" is already %ld. Not changed to %ld.",
3256 S_GET_NAME (symbolP
),
3257 (long) S_GET_VALUE (symbolP
),
3262 S_SET_VALUE (symbolP
, (valueT
) temp
);
3263 S_SET_EXTERNAL (symbolP
);
3267 know (symbolP
->sy_frag
== &zero_address_frag
);
3270 demand_empty_rest_of_line ();
3273 #endif /* ! OBJ_ELF */
3275 #if defined (OBJ_ECOFF) || defined (OBJ_EVAX)
3277 /* Handle the .rdata pseudo-op. This is like the usual one, but it
3278 clears alpha_insn_label and restores auto alignment. */
3281 s_alpha_rdata (ignore
)
3286 temp
= get_absolute_expression ();
3287 subseg_new (".rdata", 0);
3288 demand_empty_rest_of_line ();
3289 alpha_insn_label
= NULL
;
3290 alpha_auto_align_on
= 1;
3291 alpha_current_align
= 0;
3298 /* Handle the .sdata pseudo-op. This is like the usual one, but it
3299 clears alpha_insn_label and restores auto alignment. */
3302 s_alpha_sdata (ignore
)
3307 temp
= get_absolute_expression ();
3308 subseg_new (".sdata", 0);
3309 demand_empty_rest_of_line ();
3310 alpha_insn_label
= NULL
;
3311 alpha_auto_align_on
= 1;
3312 alpha_current_align
= 0;
3318 /* Handle the .section pseudo-op. This is like the usual one, but it
3319 clears alpha_insn_label and restores auto alignment. */
3322 s_alpha_section (ignore
)
3325 obj_elf_section (ignore
);
3327 alpha_insn_label
= NULL
;
3328 alpha_auto_align_on
= 1;
3329 alpha_current_align
= 0;
3336 s_alpha_link (ignore
)
3341 temp
= get_absolute_expression ();
3342 subseg_new (".link", 0);
3343 demand_empty_rest_of_line ();
3344 alpha_insn_label
= NULL
;
3345 alpha_auto_align_on
= 1;
3346 alpha_current_align
= 0;
3353 s_alpha_prologue (ignore
)
3356 alpha_basereg_clobbered
= 0;
3357 demand_empty_rest_of_line ();
3363 /* Parse .ent directives. */
3366 s_alpha_ent (ignore
)
3370 expressionS symexpr
;
3372 alpha_evax_proc
.pdsckind
= 0;
3373 alpha_evax_proc
.framereg
= -1;
3374 alpha_evax_proc
.framesize
= 0;
3375 alpha_evax_proc
.rsa_offset
= 0;
3376 alpha_evax_proc
.ra_save
= AXP_REG_RA
;
3377 alpha_evax_proc
.fp_save
= -1;
3378 alpha_evax_proc
.imask
= 0;
3379 alpha_evax_proc
.fmask
= 0;
3380 alpha_evax_proc
.prologue
= 0;
3381 alpha_evax_proc
.type
= 0;
3383 expression (&symexpr
);
3385 if (symexpr
.X_op
!= O_symbol
)
3387 as_fatal (".ent directive has no symbol");
3388 demand_empty_rest_of_line ();
3392 symbol
= make_expr_symbol (&symexpr
);
3393 symbol
->bsym
->flags
|= BSF_FUNCTION
;
3394 alpha_evax_proc
.symbol
= symbol
;
3396 demand_empty_rest_of_line ();
3401 /* Parse .frame <framreg>,<framesize>,RA,<rsa_offset> directives. */
3404 s_alpha_frame (ignore
)
3409 alpha_evax_proc
.framereg
= tc_get_register (1);
3412 if (*input_line_pointer
++ != ','
3413 || get_absolute_expression_and_terminator (&val
) != ',')
3415 as_warn ("Bad .frame directive 1./2. param");
3416 --input_line_pointer
;
3417 demand_empty_rest_of_line ();
3421 alpha_evax_proc
.framesize
= val
;
3423 (void) tc_get_register (1);
3425 if (*input_line_pointer
++ != ',')
3427 as_warn ("Bad .frame directive 3./4. param");
3428 --input_line_pointer
;
3429 demand_empty_rest_of_line ();
3432 alpha_evax_proc
.rsa_offset
= get_absolute_expression ();
3438 s_alpha_pdesc (ignore
)
3448 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
3450 if (now_seg
!= alpha_link_section
)
3452 as_bad (".pdesc directive not in link (.link) section");
3453 demand_empty_rest_of_line ();
3457 if ((alpha_evax_proc
.symbol
== 0)
3458 || (!S_IS_DEFINED (alpha_evax_proc
.symbol
)))
3460 as_fatal (".pdesc has no matching .ent");
3461 demand_empty_rest_of_line ();
3465 alpha_evax_proc
.symbol
->sy_obj
= (valueT
)seginfo
->literal_pool_size
;
3468 if (exp
.X_op
!= O_symbol
)
3470 as_warn (".pdesc directive has no entry symbol");
3471 demand_empty_rest_of_line ();
3475 entry_sym
= make_expr_symbol (&exp
);
3476 /* Save bfd symbol of proc desc in function symbol. */
3477 alpha_evax_proc
.symbol
->bsym
->udata
.p
= (PTR
)entry_sym
->bsym
;
3480 if (*input_line_pointer
++ != ',')
3482 as_warn ("No comma after .pdesc <entryname>");
3483 demand_empty_rest_of_line ();
3488 name
= input_line_pointer
;
3489 name_end
= get_symbol_end ();
3491 if (strncmp(name
, "stack", 5) == 0)
3493 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_FP_STACK
;
3495 else if (strncmp(name
, "reg", 3) == 0)
3497 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_FP_REGISTER
;
3499 else if (strncmp(name
, "null", 4) == 0)
3501 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_NULL
;
3505 as_fatal ("unknown procedure kind");
3506 demand_empty_rest_of_line ();
3510 *input_line_pointer
= name_end
;
3511 demand_empty_rest_of_line ();
3513 #ifdef md_flush_pending_output
3514 md_flush_pending_output ();
3519 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
3521 seginfo
->literal_pool_size
+= 16;
3523 *p
= alpha_evax_proc
.pdsckind
3524 | ((alpha_evax_proc
.framereg
== 29) ? PDSC_S_M_BASE_REG_IS_FP
: 0);
3525 *(p
+1) = PDSC_S_M_NATIVE
3526 | PDSC_S_M_NO_JACKET
;
3528 switch (alpha_evax_proc
.pdsckind
)
3530 case PDSC_S_K_KIND_NULL
:
3534 case PDSC_S_K_KIND_FP_REGISTER
:
3535 *(p
+2) = alpha_evax_proc
.fp_save
;
3536 *(p
+3) = alpha_evax_proc
.ra_save
;
3538 case PDSC_S_K_KIND_FP_STACK
:
3539 md_number_to_chars (p
+2, (valueT
)alpha_evax_proc
.rsa_offset
, 2);
3541 default: /* impossible */
3546 *(p
+5) = alpha_evax_proc
.type
& 0x0f;
3548 /* Signature offset. */
3549 md_number_to_chars (p
+6, (valueT
)0, 2);
3551 fix_new_exp (frag_now
, p
-frag_now
->fr_literal
+8, 8, &exp
, 0, BFD_RELOC_64
);
3553 if (alpha_evax_proc
.pdsckind
== PDSC_S_K_KIND_NULL
)
3556 /* Add dummy fix to make add_to_link_pool work. */
3558 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
3560 seginfo
->literal_pool_size
+= 8;
3562 /* pdesc+16: Size. */
3563 md_number_to_chars (p
, (valueT
)alpha_evax_proc
.framesize
, 4);
3565 md_number_to_chars (p
+4, (valueT
)0, 2);
3568 md_number_to_chars (p
+6, alpha_evax_proc
.prologue
, 2);
3570 if (alpha_evax_proc
.pdsckind
== PDSC_S_K_KIND_FP_REGISTER
)
3573 /* Add dummy fix to make add_to_link_pool work. */
3575 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
3577 seginfo
->literal_pool_size
+= 8;
3579 /* pdesc+24: register masks. */
3581 md_number_to_chars (p
, alpha_evax_proc
.imask
, 4);
3582 md_number_to_chars (p
+4, alpha_evax_proc
.fmask
, 4);
3589 s_alpha_linkage (ignore
)
3595 #ifdef md_flush_pending_output
3596 md_flush_pending_output ();
3600 if (exp
.X_op
!= O_symbol
)
3602 as_fatal ("No symbol after .linkage");
3606 p
= frag_more (LKP_S_K_SIZE
);
3607 memset (p
, 0, LKP_S_K_SIZE
);
3608 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, LKP_S_K_SIZE
, &exp
, 0,\
3609 BFD_RELOC_ALPHA_LINKAGE
);
3611 demand_empty_rest_of_line ();
3618 s_alpha_fp_save (ignore
)
3622 alpha_evax_proc
.fp_save
= tc_get_register (1);
3624 demand_empty_rest_of_line ();
3630 s_alpha_mask (ignore
)
3635 if (get_absolute_expression_and_terminator (&val
) != ',')
3637 as_warn ("Bad .mask directive");
3638 --input_line_pointer
;
3642 alpha_evax_proc
.imask
= val
;
3643 (void)get_absolute_expression ();
3645 demand_empty_rest_of_line ();
3652 s_alpha_fmask (ignore
)
3657 if (get_absolute_expression_and_terminator (&val
) != ',')
3659 as_warn ("Bad .fmask directive");
3660 --input_line_pointer
;
3664 alpha_evax_proc
.fmask
= val
;
3665 (void) get_absolute_expression ();
3667 demand_empty_rest_of_line ();
3673 s_alpha_end (ignore
)
3678 c
= get_symbol_end ();
3679 *input_line_pointer
= c
;
3680 demand_empty_rest_of_line ();
3681 alpha_evax_proc
.symbol
= 0;
3682 alpha_basereg_clobbered
= 0;
3689 s_alpha_file (ignore
)
3694 static char case_hack
[32];
3696 extern char *demand_copy_string
PARAMS ((int *lenP
));
3698 sprintf (case_hack
, "<CASE:%01d%01d%01d%01d>",
3699 alpha_flag_hash_long_names
,
3700 alpha_flag_show_after_trunc
,
3701 alpha_flag_no_hash_mixed_case
,
3702 alpha_vms_name_mapping
);
3704 s
= symbol_find_or_make (case_hack
);
3705 s
->bsym
->flags
|= BSF_FILE
;
3707 get_absolute_expression ();
3708 s
= symbol_find_or_make (demand_copy_string (&length
));
3709 s
->bsym
->flags
|= BSF_FILE
;
3710 demand_empty_rest_of_line ();
3714 #endif /* OBJ_EVAX */
3716 /* Handle the .gprel32 pseudo op. */
3719 s_alpha_gprel32 (ignore
)
3732 e
.X_add_symbol
= section_symbol(absolute_section
);
3745 e
.X_add_symbol
= section_symbol (absolute_section
);
3748 e
.X_op
= O_subtract
;
3749 e
.X_op_symbol
= alpha_gp_symbol
;
3757 if (alpha_auto_align_on
&& alpha_current_align
< 2)
3758 alpha_align (2, (char *) NULL
, alpha_insn_label
);
3759 if (alpha_current_align
> 2)
3760 alpha_current_align
= 2;
3761 alpha_insn_label
= NULL
;
3765 fix_new_exp (frag_now
, p
-frag_now
->fr_literal
, 4,
3766 &e
, 0, BFD_RELOC_GPREL32
);
3769 /* Handle floating point allocation pseudo-ops. This is like the
3770 generic vresion, but it makes sure the current label, if any, is
3771 correctly aligned. */
3774 s_alpha_float_cons (type
)
3801 if (alpha_auto_align_on
&& alpha_current_align
< log_size
)
3802 alpha_align (log_size
, (char *) NULL
, alpha_insn_label
);
3803 if (alpha_current_align
> log_size
)
3804 alpha_current_align
= log_size
;
3805 alpha_insn_label
= NULL
;
3810 /* Handle the .proc pseudo op. We don't really do much with it except
3814 s_alpha_proc (is_static
)
3823 /* Takes ".proc name,nargs" */
3824 name
= input_line_pointer
;
3825 c
= get_symbol_end ();
3826 p
= input_line_pointer
;
3827 symbolP
= symbol_find_or_make (name
);
3830 if (*input_line_pointer
!= ',')
3833 as_warn ("Expected comma after name \"%s\"", name
);
3836 ignore_rest_of_line ();
3840 input_line_pointer
++;
3841 temp
= get_absolute_expression ();
3843 /* symbolP->sy_other = (signed char) temp; */
3844 as_warn ("unhandled: .proc %s,%d", name
, temp
);
3845 demand_empty_rest_of_line ();
3848 /* Handle the .set pseudo op. This is used to turn on and off most of
3849 the assembler features. */
3855 char *name
= input_line_pointer
, ch
, *s
;
3858 while (!is_end_of_line
[(unsigned char) *input_line_pointer
])
3859 input_line_pointer
++;
3860 ch
= *input_line_pointer
;
3861 *input_line_pointer
= '\0';
3864 if (s
[0] == 'n' && s
[1] == 'o')
3869 if (!strcmp ("reorder", s
))
3871 else if (!strcmp ("at", s
))
3872 alpha_noat_on
= !yesno
;
3873 else if (!strcmp ("macro", s
))
3874 alpha_macros_on
= yesno
;
3875 else if (!strcmp ("move", s
))
3877 else if (!strcmp ("volatile", s
))
3880 as_warn ("Tried to .set unrecognized mode `%s'", name
);
3882 *input_line_pointer
= ch
;
3883 demand_empty_rest_of_line ();
3886 /* Handle the .base pseudo op. This changes the assembler's notion of
3887 the $gp register. */
3890 s_alpha_base (ignore
)
3894 if (first_32bit_quadrant
)
3896 /* not fatal, but it might not work in the end */
3897 as_warn ("File overrides no-base-register option.");
3898 first_32bit_quadrant
= 0;
3903 if (*input_line_pointer
== '$')
3905 input_line_pointer
++;
3906 if (*input_line_pointer
== 'r')
3907 input_line_pointer
++;
3910 alpha_gp_register
= get_absolute_expression ();
3911 if (alpha_gp_register
< 0 || alpha_gp_register
> 31)
3913 alpha_gp_register
= AXP_REG_GP
;
3914 as_warn ("Bad base register, using $%d.", alpha_gp_register
);
3917 demand_empty_rest_of_line ();
3920 /* Handle the .align pseudo-op. This aligns to a power of two. It
3921 also adjusts any current instruction label. We treat this the same
3922 way the MIPS port does: .align 0 turns off auto alignment. */
3925 s_alpha_align (ignore
)
3930 long max_alignment
= 15;
3932 align
= get_absolute_expression ();
3933 if (align
> max_alignment
)
3935 align
= max_alignment
;
3936 as_bad ("Alignment too large: %d. assumed", align
);
3940 as_warn ("Alignment negative: 0 assumed");
3944 if (*input_line_pointer
== ',')
3946 input_line_pointer
++;
3947 fill
= get_absolute_expression ();
3955 alpha_auto_align_on
= 1;
3956 alpha_align (align
, pfill
, alpha_insn_label
);
3960 alpha_auto_align_on
= 0;
3963 demand_empty_rest_of_line ();
3966 /* Hook the normal string processor to reset known alignment. */
3969 s_alpha_stringer (terminate
)
3972 alpha_current_align
= 0;
3973 alpha_insn_label
= NULL
;
3974 stringer (terminate
);
3977 /* Hook the normal space processing to reset known alignment. */
3980 s_alpha_space (ignore
)
3983 alpha_current_align
= 0;
3984 alpha_insn_label
= NULL
;
3988 /* Hook into cons for auto-alignment. */
3991 alpha_cons_align (size
)
3997 while ((size
>>= 1) != 0)
4000 if (alpha_auto_align_on
&& alpha_current_align
< log_size
)
4001 alpha_align (log_size
, (char *) NULL
, alpha_insn_label
);
4002 if (alpha_current_align
> log_size
)
4003 alpha_current_align
= log_size
;
4004 alpha_insn_label
= NULL
;
4007 /* The target specific pseudo-ops which we support. */
4009 const pseudo_typeS md_pseudo_table
[] =
4011 {"common", s_comm
, 0}, /* is this used? */
4013 {"comm", s_alpha_comm
, 0}, /* osf1 compiler does this */
4015 {"text", s_alpha_text
, 0},
4016 {"data", s_alpha_data
, 0},
4017 #if defined (OBJ_ECOFF) || defined (OBJ_EVAX)
4018 {"rdata", s_alpha_rdata
, 0},
4021 {"sdata", s_alpha_sdata
, 0},
4024 {"section", s_alpha_section
, 0},
4025 {"section.s", s_alpha_section
, 0},
4026 {"sect", s_alpha_section
, 0},
4027 {"sect.s", s_alpha_section
, 0},
4030 { "pdesc", s_alpha_pdesc
, 0},
4031 { "linkage", s_alpha_linkage
, 0},
4032 { "ent", s_alpha_ent
, 0},
4033 { "frame", s_alpha_frame
, 0},
4034 { "fp_save", s_alpha_fp_save
, 0},
4035 { "mask", s_alpha_mask
, 0},
4036 { "fmask", s_alpha_fmask
, 0},
4037 { "link", s_alpha_link
, 0},
4038 { "end", s_alpha_end
, 0},
4039 { "file", s_alpha_file
, 0},
4041 {"gprel32", s_alpha_gprel32
, 0},
4042 {"t_floating", s_alpha_float_cons
, 'd'},
4043 {"s_floating", s_alpha_float_cons
, 'f'},
4044 {"f_floating", s_alpha_float_cons
, 'F'},
4045 {"g_floating", s_alpha_float_cons
, 'G'},
4046 {"d_floating", s_alpha_float_cons
, 'D'},
4048 {"proc", s_alpha_proc
, 0},
4049 {"aproc", s_alpha_proc
, 1},
4050 {"set", s_alpha_set
, 0},
4051 {"reguse", s_ignore
, 0},
4052 {"livereg", s_ignore
, 0},
4053 {"base", s_alpha_base
, 0}, /*??*/
4054 {"option", s_ignore
, 0},
4055 {"prologue", s_ignore
, 0},
4056 {"aent", s_ignore
, 0},
4057 {"ugen", s_ignore
, 0},
4058 {"eflag", s_ignore
, 0},
4060 {"align", s_alpha_align
, 0},
4061 {"double", s_alpha_float_cons
, 'd'},
4062 {"float", s_alpha_float_cons
, 'f'},
4063 {"single", s_alpha_float_cons
, 'f'},
4064 {"ascii", s_alpha_stringer
, 0},
4065 {"asciz", s_alpha_stringer
, 1},
4066 {"string", s_alpha_stringer
, 1},
4067 {"space", s_alpha_space
, 0},
4068 {"skip", s_alpha_space
, 0},
4069 {"zero", s_alpha_space
, 0},
4071 /* We don't do any optimizing, so we can safely ignore these. */
4072 {"noalias", s_ignore
, 0},
4073 {"alias", s_ignore
, 0},
4079 /* Build a BFD section with its flags set appropriately for the .lita,
4080 .lit8, or .lit4 sections. */
4083 create_literal_section (name
, secp
, symp
)
4088 segT current_section
= now_seg
;
4089 int current_subsec
= now_subseg
;
4092 *secp
= new_sec
= subseg_new (name
, 0);
4093 subseg_set (current_section
, current_subsec
);
4094 bfd_set_section_alignment (stdoutput
, new_sec
, 4);
4095 bfd_set_section_flags (stdoutput
, new_sec
,
4096 SEC_RELOC
| SEC_ALLOC
| SEC_LOAD
| SEC_READONLY
4099 S_CLEAR_EXTERNAL (*symp
= section_symbol (new_sec
));
4104 /* @@@ GP selection voodoo. All of this seems overly complicated and
4105 unnecessary; which is the primary reason it's for ECOFF only. */
4114 vma
= bfd_get_section_vma (foo
, sec
);
4115 if (vma
&& vma
< alpha_gp_value
)
4116 alpha_gp_value
= vma
;
4122 assert (alpha_gp_value
== 0);
4124 /* Get minus-one in whatever width... */
4125 alpha_gp_value
= 0; alpha_gp_value
--;
4127 /* Select the smallest VMA of these existing sections. */
4128 maybe_set_gp (alpha_lita_section
);
4130 /* These were disabled before -- should we use them? */
4131 maybe_set_gp (sdata
);
4132 maybe_set_gp (lit8_sec
);
4133 maybe_set_gp (lit4_sec
);
4136 /* @@ Will a simple 0x8000 work here? If not, why not? */
4137 #define GP_ADJUSTMENT (0x8000 - 0x10)
4139 alpha_gp_value
+= GP_ADJUSTMENT
;
4141 S_SET_VALUE (alpha_gp_symbol
, alpha_gp_value
);
4144 printf ("Chose GP value of %lx\n", alpha_gp_value
);
4147 #endif /* OBJ_ECOFF */
4149 /* Called internally to handle all alignment needs. This takes care
4150 of eliding calls to frag_align if'n the cached current alignment
4151 says we've already got it, as well as taking care of the auto-align
4152 feature wrt labels. */
4155 alpha_align (n
, pfill
, label
)
4160 if (alpha_current_align
>= n
)
4166 && (bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
) != 0)
4168 static char const nop
[4] = { 0x1f, 0x04, 0xff, 0x47 };
4170 /* First, make sure we're on a four-byte boundary, in case
4171 someone has been putting .byte values into the text
4172 section. The DEC assembler silently fills with unaligned
4173 no-op instructions. This will zero-fill, then nop-fill
4174 with proper alignment. */
4175 if (alpha_current_align
< 2)
4177 frag_align_pattern (n
, nop
, sizeof nop
);
4183 frag_align (n
, *pfill
);
4185 alpha_current_align
= n
;
4189 assert (S_GET_SEGMENT (label
) == now_seg
);
4190 label
->sy_frag
= frag_now
;
4191 S_SET_VALUE (label
, (valueT
) frag_now_fix ());
4194 record_alignment(now_seg
, n
);
4197 /* The Alpha has support for some VAX floating point types, as well as for
4198 IEEE floating point. We consider IEEE to be the primary floating point
4199 format, and sneak in the VAX floating point support here. */
4200 #define md_atof vax_md_atof
4201 #include "config/atof-vax.c"