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";
254 const char *md_shortopts
= "Fm:g";
256 struct option md_longopts
[] = {
257 #define OPTION_32ADDR (OPTION_MD_BASE)
258 { "32addr", no_argument
, NULL
, OPTION_32ADDR
},
259 { NULL
, no_argument
, NULL
, 0 }
262 size_t md_longopts_size
= sizeof(md_longopts
);
265 /* The cpu for which we are generating code */
266 static unsigned alpha_target
= AXP_OPCODE_ALL
;
267 static const char *alpha_target_name
= "<all>";
269 /* The hash table of instruction opcodes */
270 static struct hash_control
*alpha_opcode_hash
;
272 /* The hash table of macro opcodes */
273 static struct hash_control
*alpha_macro_hash
;
276 /* The $gp relocation symbol */
277 static symbolS
*alpha_gp_symbol
;
279 /* XXX: what is this, and why is it exported? */
280 valueT alpha_gp_value
;
283 /* The current $gp register */
284 static int alpha_gp_register
= AXP_REG_GP
;
286 /* A table of the register symbols */
287 static symbolS
*alpha_register_table
[64];
289 /* Constant sections, or sections of constants */
291 static segT alpha_lita_section
;
292 static segT alpha_lit4_section
;
295 static segT alpha_link_section
;
297 static segT alpha_lit8_section
;
299 /* Symbols referring to said sections. */
301 static symbolS
*alpha_lita_symbol
;
302 static symbolS
*alpha_lit4_symbol
;
305 static symbolS
*alpha_link_symbol
;
307 static symbolS
*alpha_lit8_symbol
;
309 /* Is the assembler not allowed to use $at? */
310 static int alpha_noat_on
= 0;
312 /* Are macros enabled? */
313 static int alpha_macros_on
= 1;
315 /* Are floats disabled? */
316 static int alpha_nofloats_on
= 0;
318 /* Are addresses 32 bit? */
319 static int alpha_addr32_on
= 0;
321 /* Symbol labelling the current insn. When the Alpha gas sees
324 and the section happens to not be on an eight byte boundary, it
325 will align both the symbol and the .quad to an eight byte boundary. */
326 static symbolS
*alpha_insn_label
;
328 /* Whether we should automatically align data generation pseudo-ops.
329 .align 0 will turn this off. */
330 static int alpha_auto_align_on
= 1;
332 /* The known current alignment of the current section. */
333 static int alpha_current_align
;
335 /* These are exported to ECOFF code. */
336 unsigned long alpha_gprmask
, alpha_fprmask
;
339 /* Collect information about current procedure here. */
340 static evaxProcT alpha_evax_proc
;
343 /* The macro table */
345 static const struct alpha_macro alpha_macros
[] = {
346 /* Load/Store macros */
347 { "lda", emit_lda
, NULL
,
348 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
349 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
350 { "ldah", emit_ldah
, NULL
,
351 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
353 { "ldl", emit_ir_load
, "ldl",
354 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
355 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
356 { "ldl_l", emit_ir_load
, "ldl_l",
357 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
358 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
359 { "ldq", emit_ir_load
, "ldq",
360 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
361 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
362 { "ldq_l", emit_ir_load
, "ldq_l",
363 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
364 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
365 { "ldq_u", emit_ir_load
, "ldq_u",
366 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
367 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
368 { "ldf", emit_loadstore
, "ldf",
369 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
370 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
371 { "ldg", emit_loadstore
, "ldg",
372 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
373 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
374 { "lds", emit_loadstore
, "lds",
375 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
376 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
377 { "ldt", emit_loadstore
, "ldt",
378 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
379 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
381 { "ldb", emit_ldX
, (void *)0,
382 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
383 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
384 { "ldbu", emit_ldXu
, (void *)0,
385 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
386 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
387 { "ldw", emit_ldX
, (void *)1,
388 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
389 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
390 { "ldwu", emit_ldXu
, (void *)1,
391 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
392 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
394 { "uldw", emit_uldX
, (void*)1,
395 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
396 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
397 { "uldwu", emit_uldXu
, (void*)1,
398 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
399 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
400 { "uldl", emit_uldX
, (void*)2,
401 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
402 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
403 { "uldlu", emit_uldXu
, (void*)2,
404 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
405 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
406 { "uldq", emit_uldXu
, (void*)3,
407 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
408 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
410 { "ldgp", emit_ldgp
, NULL
,
411 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
} },
413 { "ldi", emit_lda
, NULL
,
414 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
415 { "ldil", emit_ldil
, NULL
,
416 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
417 { "ldiq", emit_lda
, NULL
,
418 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
420 { "ldif" emit_ldiq
, NULL
,
421 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
422 { "ldid" emit_ldiq
, NULL
,
423 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
424 { "ldig" emit_ldiq
, NULL
,
425 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
426 { "ldis" emit_ldiq
, NULL
,
427 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
428 { "ldit" emit_ldiq
, NULL
,
429 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
432 { "stl", emit_loadstore
, "stl",
433 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
434 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
435 { "stl_c", emit_loadstore
, "stl_c",
436 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
437 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
438 { "stq", emit_loadstore
, "stq",
439 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
440 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
441 { "stq_c", emit_loadstore
, "stq_c",
442 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
443 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
444 { "stq_u", emit_loadstore
, "stq_u",
445 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
446 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
447 { "stf", emit_loadstore
, "stf",
448 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
449 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
450 { "stg", emit_loadstore
, "stg",
451 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
452 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
453 { "sts", emit_loadstore
, "sts",
454 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
455 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
456 { "stt", emit_loadstore
, "stt",
457 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
458 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
460 { "stb", emit_stX
, (void*)0,
461 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
462 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
463 { "stw", emit_stX
, (void*)1,
464 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
465 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
466 { "ustw", emit_ustX
, (void*)1,
467 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
468 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
469 { "ustl", emit_ustX
, (void*)2,
470 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
471 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
472 { "ustq", emit_ustX
, (void*)3,
473 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
474 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
476 /* Arithmetic macros */
478 { "absl" emit_absl
, 1, { IR
} },
479 { "absl" emit_absl
, 2, { IR
, IR
} },
480 { "absl" emit_absl
, 2, { EXP
, IR
} },
481 { "absq" emit_absq
, 1, { IR
} },
482 { "absq" emit_absq
, 2, { IR
, IR
} },
483 { "absq" emit_absq
, 2, { EXP
, IR
} },
486 { "sextb", emit_sextX
, (void *)0,
487 { MACRO_IR
, MACRO_IR
, MACRO_EOA
,
489 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
490 { "sextw", emit_sextX
, (void *)1,
491 { MACRO_IR
, MACRO_IR
, MACRO_EOA
,
493 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
495 { "divl", emit_division
, "__divl",
496 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
497 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
498 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
499 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
500 { "divlu", emit_division
, "__divlu",
501 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
502 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
503 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
504 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
505 { "divq", emit_division
, "__divq",
506 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
507 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
508 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
509 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
510 { "divqu", emit_division
, "__divqu",
511 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
512 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
513 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
514 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
515 { "reml", emit_division
, "__reml",
516 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
517 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
518 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
519 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
520 { "remlu", emit_division
, "__remlu",
521 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
522 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
523 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
524 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
525 { "remq", emit_division
, "__remq",
526 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
527 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
528 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
529 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
530 { "remqu", emit_division
, "__remqu",
531 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
532 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
533 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
534 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
536 { "jsr", emit_jsrjmp
, "jsr",
537 { MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
538 MACRO_PIR
, MACRO_EOA
,
539 MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
540 MACRO_EXP
, MACRO_EOA
} },
541 { "jmp", emit_jsrjmp
, "jmp",
542 { MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
543 MACRO_PIR
, MACRO_EOA
,
544 MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
545 MACRO_EXP
, MACRO_EOA
} },
546 { "ret", emit_retjcr
, "ret",
547 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
549 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
550 MACRO_PIR
, MACRO_EOA
,
551 MACRO_EXP
, MACRO_EOA
,
553 { "jcr", emit_retjcr
, "jcr",
554 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
556 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
557 MACRO_PIR
, MACRO_EOA
,
558 MACRO_EXP
, MACRO_EOA
,
560 { "jsr_coroutine", emit_retjcr
, "jcr",
561 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
563 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
564 MACRO_PIR
, MACRO_EOA
,
565 MACRO_EXP
, MACRO_EOA
,
569 static const int alpha_num_macros
570 = sizeof(alpha_macros
) / sizeof(*alpha_macros
);
572 /* Public interface functions */
574 /* This function is called once, at assembler startup time. It sets
575 up all the tables, etc. that the MD part of the assembler will
576 need, that can be determined before arguments are parsed. */
583 /* Create the opcode hash table */
585 alpha_opcode_hash
= hash_new ();
586 for (i
= 0; i
< alpha_num_opcodes
; )
588 const char *name
, *retval
;
590 name
= alpha_opcodes
[i
].name
;
591 retval
= hash_insert (alpha_opcode_hash
, name
, (PTR
)&alpha_opcodes
[i
]);
593 as_fatal ("internal error: can't hash opcode `%s': %s", name
, retval
);
595 while (++i
< alpha_num_opcodes
596 && (alpha_opcodes
[i
].name
== name
597 || !strcmp (alpha_opcodes
[i
].name
, name
)))
601 /* Some opcodes include modifiers of various sorts with a "/mod" syntax,
602 like the architecture manual suggests. However, for use with gcc at
603 least, we also need access to those same opcodes without the "/". */
604 for (i
= 0; i
< alpha_num_opcodes
; )
606 const char *name
, *slash
;
607 name
= alpha_opcodes
[i
].name
;
608 if ((slash
= strchr(name
, '/')) != NULL
)
610 char *p
= xmalloc (strlen (name
));
611 memcpy(p
, name
, slash
-name
);
612 strcpy(p
+(slash
-name
), slash
+1);
614 (void)hash_insert(alpha_opcode_hash
, p
, (PTR
)&alpha_opcodes
[i
]);
615 /* Ignore failures -- the opcode table does duplicate some
616 variants in different forms, like "hw_stq" and "hw_st/q". */
619 while (++i
< alpha_num_opcodes
620 && (alpha_opcodes
[i
].name
== name
621 || !strcmp (alpha_opcodes
[i
].name
, name
)))
625 /* Create the macro hash table */
627 alpha_macro_hash
= hash_new ();
628 for (i
= 0; i
< alpha_num_macros
; )
630 const char *name
, *retval
;
632 name
= alpha_macros
[i
].name
;
633 retval
= hash_insert (alpha_macro_hash
, name
, (PTR
)&alpha_macros
[i
]);
635 as_fatal ("internal error: can't hash macro `%s': %s", name
, retval
);
637 while (++i
< alpha_num_macros
638 && (alpha_macros
[i
].name
== name
639 || !strcmp (alpha_macros
[i
].name
, name
)))
643 /* Construct symbols for each of the registers */
645 for (i
= 0; i
< 32; ++i
)
648 sprintf(name
, "$%d", i
);
649 alpha_register_table
[i
] = symbol_create(name
, reg_section
, i
,
655 sprintf(name
, "$f%d", i
-32);
656 alpha_register_table
[i
] = symbol_create(name
, reg_section
, i
,
660 /* Create the special symbols and sections we'll be using */
662 /* So .sbss will get used for tiny objects. */
663 bfd_set_gp_size (stdoutput
, 8);
666 create_literal_section (".lita", &alpha_lita_section
, &alpha_lita_symbol
);
668 /* For handling the GP, create a symbol that won't be output in the
669 symbol table. We'll edit it out of relocs later. */
670 alpha_gp_symbol
= symbol_create ("<GP value>", alpha_lita_section
, 0x8000,
675 create_literal_section (".link", &alpha_link_section
, &alpha_link_symbol
);
683 sec
= subseg_new(".mdebug", (subsegT
)0);
684 bfd_set_section_flags(stdoutput
, sec
, SEC_HAS_CONTENTS
|SEC_READONLY
);
685 bfd_set_section_alignment(stdoutput
, sec
, 3);
688 sec
= subseg_new(".reginfo", (subsegT
)0);
689 /* The ABI says this section should be loaded so that the running
690 program can access it. */
691 bfd_set_section_flags(stdoutput
, sec
,
692 SEC_ALLOC
|SEC_LOAD
|SEC_READONLY
|SEC_DATA
);
693 bfd_set_section_alignement(stdoutput
, sec
, 3);
698 subseg_set(text_section
, 0);
701 /* The public interface to the instruction assembler. */
707 char opname
[32]; /* current maximum is 13 */
708 expressionS tok
[MAX_INSN_ARGS
];
709 int ntok
, opnamelen
, trunclen
;
711 /* split off the opcode */
712 opnamelen
= strspn (str
, "abcdefghijklmnopqrstuvwxyz_/48");
713 trunclen
= (opnamelen
< sizeof (opname
) - 1
715 : sizeof (opname
) - 1);
716 memcpy (opname
, str
, trunclen
);
717 opname
[trunclen
] = '\0';
719 /* tokenize the rest of the line */
720 if ((ntok
= tokenize_arguments (str
+ opnamelen
, tok
, MAX_INSN_ARGS
)) < 0)
722 as_bad ("syntax error");
727 assemble_tokens (opname
, tok
, ntok
, alpha_macros_on
);
730 /* Round up a section's size to the appropriate boundary. */
733 md_section_align (seg
, size
)
737 int align
= bfd_get_section_alignment(stdoutput
, seg
);
738 valueT mask
= ((valueT
)1 << align
) - 1;
740 return (size
+ mask
) & ~mask
;
743 /* Turn a string in input_line_pointer into a floating point constant
744 of type type, and store the appropriate bytes in *litP. The number
745 of LITTLENUMS emitted is stored in *sizeP. An error message is
746 returned, or NULL on OK. */
748 /* Equal to MAX_PRECISION in atof-ieee.c */
749 #define MAX_LITTLENUMS 6
752 md_atof (type
, litP
, sizeP
)
758 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
759 LITTLENUM_TYPE
*wordP
;
761 char *atof_ieee (), *vax_md_atof ();
767 /* VAX md_atof doesn't like "G" for some reason. */
771 return vax_md_atof (type
, litP
, sizeP
);
794 return "Bad call to MD_ATOF()";
796 t
= atof_ieee (input_line_pointer
, type
, words
);
798 input_line_pointer
= t
;
799 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
801 for (wordP
= words
+ prec
- 1; prec
--;)
803 md_number_to_chars (litP
, (long) (*wordP
--), sizeof (LITTLENUM_TYPE
));
804 litP
+= sizeof (LITTLENUM_TYPE
);
810 /* Take care of the target-specific command-line options. */
813 md_parse_option (c
, arg
)
820 alpha_nofloats_on
= 1;
828 /* Ignore `-g' so gcc can provide this option to the Digital
829 UNIX assembler, which otherwise would throw away info that
835 static const struct machine
841 { "21064", AXP_OPCODE_EV4
|AXP_OPCODE_ALL
},
842 { "21066", AXP_OPCODE_EV4
|AXP_OPCODE_ALL
},
843 { "21164", AXP_OPCODE_EV5
|AXP_OPCODE_ALL
},
844 { "21164a", AXP_OPCODE_EV56
|AXP_OPCODE_ALL
},
845 { "ev4", AXP_OPCODE_EV4
|AXP_OPCODE_ALL
},
846 { "ev45", AXP_OPCODE_EV4
|AXP_OPCODE_ALL
},
847 { "ev5", AXP_OPCODE_EV5
|AXP_OPCODE_ALL
},
848 { "ev56", AXP_OPCODE_EV56
|AXP_OPCODE_ALL
},
849 { "all", AXP_OPCODE_ALL
},
853 for (p
= m
; p
->name
; ++p
)
854 if (strcmp(arg
, p
->name
) == 0)
856 alpha_target_name
= p
->name
, alpha_target
= p
->flags
;
859 as_warn("Unknown CPU identifier `%s'", arg
);
871 /* Print a description of the command-line options that we accept. */
874 md_show_usage (stream
)
879 -32addr treat addresses as 32-bit values\n\
880 -F lack floating point instructions support\n\
881 -m21064 | -m21066 | -m21164 | -m21164a\n\
882 -mev4 | -mev45 | -mev5 | -mev56 | -mall\n\
883 specify variant of Alpha architecture\n",
887 /* Decide from what point a pc-relative relocation is relative to,
888 relative to the pc-relative fixup. Er, relatively speaking. */
894 valueT addr
= fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
895 switch (fixP
->fx_r_type
)
897 case BFD_RELOC_ALPHA_GPDISP
:
898 case BFD_RELOC_ALPHA_GPDISP_HI16
:
899 case BFD_RELOC_ALPHA_GPDISP_LO16
:
902 return fixP
->fx_size
+ addr
;
906 /* Attempt to simplify or even eliminate a fixup. The return value is
907 ignored; perhaps it was once meaningful, but now it is historical.
908 To indicate that a fixup has been eliminated, set fixP->fx_done.
910 For ELF, here it is that we transform the GPDISP_HI16 reloc we used
911 internally into the GPDISP reloc used externally. We had to do
912 this so that we'd have the GPDISP_LO16 reloc as a tag to compute
913 the distance to the "lda" instruction for setting the addend to
917 md_apply_fix (fixP
, valueP
)
921 char * const fixpos
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
922 valueT value
= *valueP
;
923 unsigned image
, size
;
925 switch (fixP
->fx_r_type
)
927 /* The GPDISP relocations are processed internally with a symbol
928 referring to the current function; we need to drop in a value
929 which, when added to the address of the start of the function,
930 gives the desired GP. */
931 case BFD_RELOC_ALPHA_GPDISP_HI16
:
933 fixS
*next
= fixP
->fx_next
;
934 assert (next
->fx_r_type
== BFD_RELOC_ALPHA_GPDISP_LO16
);
936 fixP
->fx_offset
= (next
->fx_frag
->fr_address
+ next
->fx_where
937 - fixP
->fx_frag
->fr_address
- fixP
->fx_where
);
939 value
= (value
- sign_extend_16 (value
)) >> 16;
942 fixP
->fx_r_type
= BFD_RELOC_ALPHA_GPDISP
;
946 case BFD_RELOC_ALPHA_GPDISP_LO16
:
947 value
= sign_extend_16 (value
);
954 fixP
->fx_addsy
= section_symbol (absolute_section
);
955 md_number_to_chars (fixpos
, value
, 2);
967 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
969 md_number_to_chars (fixpos
, value
, size
);
975 case BFD_RELOC_GPREL32
:
976 assert (fixP
->fx_subsy
== alpha_gp_symbol
);
978 /* FIXME: inherited this obliviousness of `value' -- why? */
979 md_number_to_chars (fixpos
, -alpha_gp_value
, 4);
983 case BFD_RELOC_GPREL32
:
987 case BFD_RELOC_23_PCREL_S2
:
988 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
990 image
= bfd_getl32(fixpos
);
991 image
= (image
& ~0x1FFFFF) | ((value
>> 2) & 0x1FFFFF);
996 case BFD_RELOC_ALPHA_HINT
:
997 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
999 image
= bfd_getl32(fixpos
);
1000 image
= (image
& ~0x3FFF) | ((value
>> 2) & 0x3FFF);
1006 case BFD_RELOC_ALPHA_LITERAL
:
1007 md_number_to_chars (fixpos
, value
, 2);
1010 case BFD_RELOC_ALPHA_LITUSE
:
1014 case BFD_RELOC_ALPHA_LITERAL
:
1015 case BFD_RELOC_ALPHA_LITUSE
:
1019 case BFD_RELOC_ALPHA_LINKAGE
:
1025 const struct alpha_operand
*operand
;
1027 if (fixP
->fx_r_type
<= BFD_RELOC_UNUSED
)
1028 as_fatal ("unhandled relocation type %s",
1029 bfd_get_reloc_code_name (fixP
->fx_r_type
));
1031 assert (fixP
->fx_r_type
< BFD_RELOC_UNUSED
+ alpha_num_operands
);
1032 operand
= &alpha_operands
[fixP
->fx_r_type
- BFD_RELOC_UNUSED
];
1034 /* The rest of these fixups only exist internally during symbol
1035 resolution and have no representation in the object file.
1036 Therefore they must be completely resolved as constants. */
1038 if (fixP
->fx_addsy
!= 0
1039 && fixP
->fx_addsy
->bsym
->section
!= absolute_section
)
1040 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
1041 "non-absolute expression in constant field");
1043 image
= bfd_getl32(fixpos
);
1044 image
= insert_operand(image
, operand
, (offsetT
)value
,
1045 fixP
->fx_file
, fixP
->fx_line
);
1050 if (fixP
->fx_addsy
!= 0 || fixP
->fx_pcrel
!= 0)
1054 as_warn_where(fixP
->fx_file
, fixP
->fx_line
,
1055 "type %d reloc done?\n", fixP
->fx_r_type
);
1060 md_number_to_chars(fixpos
, image
, 4);
1068 * Look for a register name in the given symbol.
1072 md_undefined_symbol(name
)
1077 int is_float
= 0, num
;
1082 if (name
[1] == 'p' && name
[2] == '\0')
1083 return alpha_register_table
[AXP_REG_FP
];
1088 if (!isdigit(*++name
))
1092 case '0': case '1': case '2': case '3': case '4':
1093 case '5': case '6': case '7': case '8': case '9':
1094 if (name
[1] == '\0')
1095 num
= name
[0] - '0';
1096 else if (name
[0] != '0' && isdigit(name
[1]) && name
[2] == '\0')
1098 num
= (name
[0] - '0')*10 + name
[1] - '0';
1105 if (!alpha_noat_on
&& num
== AXP_REG_AT
)
1106 as_warn("Used $at without \".set noat\"");
1107 return alpha_register_table
[num
+ is_float
];
1110 if (name
[1] == 't' && name
[2] == '\0')
1113 as_warn("Used $at without \".set noat\"");
1114 return alpha_register_table
[AXP_REG_AT
];
1119 if (name
[1] == 'p' && name
[2] == '\0')
1120 return alpha_register_table
[alpha_gp_register
];
1124 if (name
[1] == 'p' && name
[2] == '\0')
1125 return alpha_register_table
[AXP_REG_SP
];
1133 /* @@@ Magic ECOFF bits. */
1136 alpha_frob_ecoff_data ()
1139 /* $zero and $f31 are read-only */
1140 alpha_gprmask
&= ~1;
1141 alpha_fprmask
&= ~1;
1145 /* Hook to remember a recently defined label so that the auto-align
1146 code can adjust the symbol after we know what alignment will be
1150 alpha_define_label (sym
)
1153 alpha_insn_label
= sym
;
1156 /* Return true if we must always emit a reloc for a type and false if
1157 there is some hope of resolving it a assembly time. */
1160 alpha_force_relocation (f
)
1163 switch (f
->fx_r_type
)
1165 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1166 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1167 case BFD_RELOC_ALPHA_GPDISP
:
1168 case BFD_RELOC_ALPHA_LITERAL
:
1169 case BFD_RELOC_ALPHA_LITUSE
:
1170 case BFD_RELOC_GPREL32
:
1172 case BFD_RELOC_ALPHA_LINKAGE
:
1176 case BFD_RELOC_23_PCREL_S2
:
1179 case BFD_RELOC_ALPHA_HINT
:
1183 assert(f
->fx_r_type
> BFD_RELOC_UNUSED
&&
1184 f
->fx_r_type
< BFD_RELOC_UNUSED
+ alpha_num_operands
);
1189 /* Return true if we can partially resolve a relocation now. */
1192 alpha_fix_adjustable (f
)
1196 /* Prevent all adjustments to global symbols */
1197 if (S_IS_EXTERN (f
->fx_addsy
))
1201 /* Are there any relocation types for which we must generate a reloc
1202 but we can adjust the values contained within it? */
1203 switch (f
->fx_r_type
)
1205 case BFD_RELOC_GPREL32
:
1208 return !alpha_force_relocation (f
);
1213 /* Generate the BFD reloc to be stuck in the object file from the
1214 fixup used internally in the assembler. */
1217 tc_gen_reloc (sec
, fixp
)
1223 reloc
= (arelent
*) bfd_alloc_by_size_t (stdoutput
, sizeof (arelent
));
1224 reloc
->sym_ptr_ptr
= &fixp
->fx_addsy
->bsym
;
1225 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
1227 /* Make sure none of our internal relocations make it this far.
1228 They'd better have been fully resolved by this point. */
1229 assert (fixp
->fx_r_type
< BFD_RELOC_UNUSED
);
1231 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
1232 if (reloc
->howto
== NULL
)
1234 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1235 "cannot represent `%s' relocation in object file",
1236 bfd_get_reloc_code_name (fixp
->fx_r_type
));
1240 if (!fixp
->fx_pcrel
!= !reloc
->howto
->pc_relative
)
1242 as_fatal ("internal error? cannot generate `%s' relocation",
1243 bfd_get_reloc_code_name (fixp
->fx_r_type
));
1245 assert (!fixp
->fx_pcrel
== !reloc
->howto
->pc_relative
);
1248 if (fixp
->fx_r_type
== BFD_RELOC_ALPHA_LITERAL
)
1250 /* fake out bfd_perform_relocation. sigh */
1251 reloc
->addend
= -alpha_gp_value
;
1256 reloc
->addend
= fixp
->fx_offset
;
1259 * Ohhh, this is ugly. The problem is that if this is a local global
1260 * symbol, the relocation will entirely be performed at link time, not
1261 * at assembly time. bfd_perform_reloc doesn't know about this sort
1262 * of thing, and as a result we need to fake it out here.
1264 if (S_IS_EXTERN (fixp
->fx_addsy
) && !S_IS_COMMON(fixp
->fx_addsy
))
1265 reloc
->addend
-= fixp
->fx_addsy
->bsym
->value
;
1272 /* Parse a register name off of the input_line and return a register
1273 number. Gets md_undefined_symbol above to do the register name
1276 Only called as a part of processing the ECOFF .frame directive. */
1279 tc_get_register (frame
)
1282 int framereg
= AXP_REG_SP
;
1285 if (*input_line_pointer
== '$')
1287 char *s
= input_line_pointer
;
1288 char c
= get_symbol_end ();
1289 symbolS
*sym
= md_undefined_symbol (s
);
1291 *strchr(s
, '\0') = c
;
1292 if (sym
&& (framereg
= S_GET_VALUE (sym
)) <= 31)
1295 as_warn ("frame reg expected, using $%d.", framereg
);
1298 note_gpreg (framereg
);
1303 /* Parse the arguments to an opcode. */
1306 tokenize_arguments (str
, tok
, ntok
)
1311 expressionS
*end_tok
= tok
+ ntok
;
1312 char *old_input_line_pointer
;
1313 int saw_comma
= 0, saw_arg
= 0;
1315 memset (tok
, 0, sizeof(*tok
)*ntok
);
1317 /* Save and restore input_line_pointer around this function */
1318 old_input_line_pointer
= input_line_pointer
;
1319 input_line_pointer
= str
;
1321 while (tok
< end_tok
&& *input_line_pointer
)
1324 switch (*input_line_pointer
)
1330 ++input_line_pointer
;
1331 if (saw_comma
|| !saw_arg
)
1338 char *hold
= input_line_pointer
++;
1340 /* First try for parenthesized register ... */
1342 if (*input_line_pointer
== ')' && tok
->X_op
== O_register
)
1344 tok
->X_op
= (saw_comma
? O_cpregister
: O_pregister
);
1347 ++input_line_pointer
;
1352 /* ... then fall through to plain expression */
1353 input_line_pointer
= hold
;
1357 if (saw_arg
&& !saw_comma
)
1360 if (tok
->X_op
== O_illegal
|| tok
->X_op
== O_absent
)
1373 input_line_pointer
= old_input_line_pointer
;
1374 return ntok
- (end_tok
- tok
);
1377 input_line_pointer
= old_input_line_pointer
;
1381 /* Search forward through all variants of an opcode looking for a
1384 static const struct alpha_opcode
*
1385 find_opcode_match(first_opcode
, tok
, pntok
, pcpumatch
)
1386 const struct alpha_opcode
*first_opcode
;
1387 const expressionS
*tok
;
1391 const struct alpha_opcode
*opcode
= first_opcode
;
1393 int got_cpu_match
= 0;
1397 const unsigned char *opidx
;
1400 /* Don't match opcodes that don't exist on this architecture */
1401 if (!(opcode
->flags
& alpha_target
))
1406 for (opidx
= opcode
->operands
; *opidx
; ++opidx
)
1408 const struct alpha_operand
*operand
= &alpha_operands
[*opidx
];
1410 /* only take input from real operands */
1411 if (operand
->flags
& AXP_OPERAND_FAKE
)
1414 /* when we expect input, make sure we have it */
1417 if ((operand
->flags
& AXP_OPERAND_OPTIONAL_MASK
) == 0)
1422 /* match operand type with expression type */
1423 switch (operand
->flags
& AXP_OPERAND_TYPECHECK_MASK
)
1425 case AXP_OPERAND_IR
:
1426 if (tok
[tokidx
].X_op
!= O_register
1427 || !is_ir_num(tok
[tokidx
].X_add_number
))
1430 case AXP_OPERAND_FPR
:
1431 if (tok
[tokidx
].X_op
!= O_register
1432 || !is_fpr_num(tok
[tokidx
].X_add_number
))
1435 case AXP_OPERAND_IR
|AXP_OPERAND_PARENS
:
1436 if (tok
[tokidx
].X_op
!= O_pregister
1437 || !is_ir_num(tok
[tokidx
].X_add_number
))
1440 case AXP_OPERAND_IR
|AXP_OPERAND_PARENS
|AXP_OPERAND_COMMA
:
1441 if (tok
[tokidx
].X_op
!= O_cpregister
1442 || !is_ir_num(tok
[tokidx
].X_add_number
))
1446 case AXP_OPERAND_RELATIVE
:
1447 case AXP_OPERAND_SIGNED
:
1448 case AXP_OPERAND_UNSIGNED
:
1449 switch (tok
[tokidx
].X_op
)
1461 /* everything else should have been fake */
1467 /* possible match -- did we use all of our input? */
1476 while (++opcode
-alpha_opcodes
< alpha_num_opcodes
1477 && !strcmp(opcode
->name
, first_opcode
->name
));
1480 *pcpumatch
= got_cpu_match
;
1485 /* Search forward through all variants of a macro looking for a syntax
1488 static const struct alpha_macro
*
1489 find_macro_match(first_macro
, tok
, pntok
)
1490 const struct alpha_macro
*first_macro
;
1491 const expressionS
*tok
;
1494 const struct alpha_macro
*macro
= first_macro
;
1499 const enum alpha_macro_arg
*arg
= macro
->argsets
;
1514 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_register
1515 || !is_ir_num(tok
[tokidx
].X_add_number
))
1520 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_pregister
1521 || !is_ir_num(tok
[tokidx
].X_add_number
))
1526 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_cpregister
1527 || !is_ir_num(tok
[tokidx
].X_add_number
))
1532 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_register
1533 || !is_fpr_num(tok
[tokidx
].X_add_number
))
1541 switch (tok
[tokidx
].X_op
)
1554 while (*arg
!= MACRO_EOA
)
1562 while (++macro
-alpha_macros
< alpha_num_macros
1563 && !strcmp(macro
->name
, first_macro
->name
));
1568 /* Insert an operand value into an instruction. */
1571 insert_operand(insn
, operand
, val
, file
, line
)
1573 const struct alpha_operand
*operand
;
1578 if (operand
->bits
!= 32 && !(operand
->flags
& AXP_OPERAND_NOOVERFLOW
))
1582 if (operand
->flags
& AXP_OPERAND_SIGNED
)
1584 max
= (1 << (operand
->bits
- 1)) - 1;
1585 min
= -(1 << (operand
->bits
- 1));
1589 max
= (1 << operand
->bits
) - 1;
1593 if (val
< min
|| val
> max
)
1596 "operand out of range (%s not between %d and %d)";
1597 char buf
[sizeof(val
)*3+2];
1599 sprint_value(buf
, val
);
1601 as_warn_where(file
, line
, err
, buf
, min
, max
);
1603 as_warn(err
, buf
, min
, max
);
1607 if (operand
->insert
)
1609 const char *errmsg
= NULL
;
1611 insn
= (*operand
->insert
)(insn
, val
, &errmsg
);
1616 insn
|= ((val
& ((1 << operand
->bits
) - 1)) << operand
->shift
);
1622 * Turn an opcode description and a set of arguments into
1623 * an instruction and a fixup.
1627 assemble_insn(opcode
, tok
, ntok
, insn
)
1628 const struct alpha_opcode
*opcode
;
1629 const expressionS
*tok
;
1631 struct alpha_insn
*insn
;
1633 const unsigned char *argidx
;
1637 memset(insn
, 0, sizeof(*insn
));
1638 image
= opcode
->opcode
;
1640 for (argidx
= opcode
->operands
; *argidx
; ++argidx
)
1642 const struct alpha_operand
*operand
= &alpha_operands
[*argidx
];
1643 const expressionS
*t
;
1645 if (operand
->flags
& AXP_OPERAND_FAKE
)
1647 /* fake operands take no value and generate no fixup */
1648 image
= insert_operand(image
, operand
, 0, NULL
, 0);
1654 switch (operand
->flags
& AXP_OPERAND_OPTIONAL_MASK
)
1656 case AXP_OPERAND_DEFAULT_FIRST
:
1659 case AXP_OPERAND_DEFAULT_SECOND
:
1662 case AXP_OPERAND_DEFAULT_ZERO
:
1664 static const expressionS zero_exp
= { 0, 0, 0, O_constant
, 1 };
1680 image
= insert_operand(image
, operand
, regno(t
->X_add_number
),
1685 image
= insert_operand(image
, operand
, t
->X_add_number
, NULL
, 0);
1690 struct alpha_fixup
*fixup
;
1692 if (insn
->nfixups
>= MAX_INSN_FIXUPS
)
1693 as_fatal("too many fixups");
1695 fixup
= &insn
->fixups
[insn
->nfixups
++];
1698 fixup
->reloc
= operand
->default_reloc
;
1708 * Actually output an instruction with its fixup.
1713 struct alpha_insn
*insn
;
1718 /* Take care of alignment duties */
1719 if (alpha_auto_align_on
&& alpha_current_align
< 2)
1720 alpha_align (2, (char *) NULL
, alpha_insn_label
);
1721 if (alpha_current_align
> 2)
1722 alpha_current_align
= 2;
1723 alpha_insn_label
= NULL
;
1725 /* Write out the instruction. */
1727 md_number_to_chars (f
, insn
->insn
, 4);
1729 /* Apply the fixups in order */
1730 for (i
= 0; i
< insn
->nfixups
; ++i
)
1732 struct alpha_fixup
*fixup
= &insn
->fixups
[i
];
1736 /* Some fixups are only used internally and so have no howto */
1737 if (fixup
->reloc
> BFD_RELOC_UNUSED
)
1738 size
= 4, pcrel
= 0;
1740 /* These relocation types are only used internally. */
1741 else if (fixup
->reloc
== BFD_RELOC_ALPHA_GPDISP_HI16
1742 || fixup
->reloc
== BFD_RELOC_ALPHA_GPDISP_LO16
)
1744 size
= 2, pcrel
= 0;
1749 reloc_howto_type
*reloc_howto
1750 = bfd_reloc_type_lookup (stdoutput
, fixup
->reloc
);
1751 assert (reloc_howto
);
1753 size
= bfd_get_reloc_size (reloc_howto
);
1754 pcrel
= reloc_howto
->pc_relative
;
1756 assert (size
>= 1 && size
<= 4);
1758 fixP
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, size
,
1759 &fixup
->exp
, pcrel
, fixup
->reloc
);
1761 /* Turn off complaints that the addend is too large for some fixups */
1762 switch (fixup
->reloc
)
1764 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1765 case BFD_RELOC_ALPHA_LITERAL
:
1766 case BFD_RELOC_GPREL32
:
1767 fixP
->fx_no_overflow
= 1;
1775 /* Given an opcode name and a pre-tokenized set of arguments, assemble
1776 the insn, but do not emit it.
1778 Note that this implies no macros allowed, since we can't store more
1779 than one insn in an insn structure. */
1782 assemble_tokens_to_insn(opname
, tok
, ntok
, insn
)
1784 const expressionS
*tok
;
1786 struct alpha_insn
*insn
;
1788 const struct alpha_opcode
*opcode
;
1790 /* search opcodes */
1791 opcode
= (const struct alpha_opcode
*) hash_find (alpha_opcode_hash
, opname
);
1795 opcode
= find_opcode_match (opcode
, tok
, &ntok
, &cpumatch
);
1798 assemble_insn (opcode
, tok
, ntok
, insn
);
1802 as_bad ("inappropriate arguments for opcode `%s'", opname
);
1804 as_bad ("opcode `%s' not supported for target %s", opname
,
1808 as_bad ("unknown opcode `%s'", opname
);
1811 /* Given an opcode name and a pre-tokenized set of arguments, take the
1812 opcode all the way through emission. */
1815 assemble_tokens (opname
, tok
, ntok
, local_macros_on
)
1817 const expressionS
*tok
;
1819 int local_macros_on
;
1821 int found_something
= 0;
1822 const struct alpha_opcode
*opcode
;
1823 const struct alpha_macro
*macro
;
1827 if (local_macros_on
)
1829 macro
= ((const struct alpha_macro
*)
1830 hash_find (alpha_macro_hash
, opname
));
1833 found_something
= 1;
1834 macro
= find_macro_match (macro
, tok
, &ntok
);
1837 (*macro
->emit
) (tok
, ntok
, macro
->arg
);
1843 /* search opcodes */
1844 opcode
= (const struct alpha_opcode
*) hash_find (alpha_opcode_hash
, opname
);
1847 found_something
= 1;
1848 opcode
= find_opcode_match (opcode
, tok
, &ntok
, &cpumatch
);
1851 struct alpha_insn insn
;
1852 assemble_insn (opcode
, tok
, ntok
, &insn
);
1858 if (found_something
)
1860 as_bad ("inappropriate arguments for opcode `%s'", opname
);
1862 as_bad ("opcode `%s' not supported for target %s", opname
,
1865 as_bad ("unknown opcode `%s'", opname
);
1869 /* Some instruction sets indexed by lg(size) */
1870 static const char * const sextX_op
[] = { "sextb", "sextw", "sextl", NULL
};
1871 static const char * const insXl_op
[] = { "insbl", "inswl", "insll", "insql" };
1872 static const char * const insXh_op
[] = { NULL
, "inswh", "inslh", "insqh" };
1873 static const char * const extXl_op
[] = { "extbl", "extwl", "extll", "extql" };
1874 static const char * const extXh_op
[] = { NULL
, "extwh", "extlh", "extqh" };
1875 static const char * const mskXl_op
[] = { "mskbl", "mskwl", "mskll", "mskql" };
1876 static const char * const mskXh_op
[] = { NULL
, "mskwh", "msklh", "mskqh" };
1878 /* Implement the ldgp macro. */
1881 emit_ldgp (tok
, ntok
, unused
)
1882 const expressionS
*tok
;
1889 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
1890 /* from "ldgp r1,n(r2)", generate "ldah r1,X(R2); lda r1,Y(r1)"
1891 with appropriate constants and relocations. */
1892 struct alpha_insn insn
;
1893 expressionS newtok
[3];
1896 /* We're going to need this symbol in md_apply_fix(). */
1897 (void) section_symbol (absolute_section
);
1900 if (regno (tok
[2].X_add_number
) == AXP_REG_PV
)
1901 ecoff_set_gp_prolog_size (0);
1905 set_tok_const (newtok
[1], 0);
1908 assemble_tokens_to_insn ("ldah", newtok
, 3, &insn
);
1913 assert (addend
.X_op
== O_constant
);
1914 addend
.X_op
= O_symbol
;
1915 addend
.X_add_symbol
= alpha_gp_symbol
;
1919 insn
.fixups
[0].exp
= addend
;
1920 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_GPDISP_HI16
;
1924 set_tok_preg (newtok
[2], tok
[0].X_add_number
);
1926 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
1929 addend
.X_add_number
+= 4;
1933 insn
.fixups
[0].exp
= addend
;
1934 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_GPDISP_LO16
;
1937 #endif /* OBJ_ECOFF || OBJ_ELF */
1942 /* Add symbol+addend to link pool.
1943 Return offset from basesym to entry in link pool.
1945 Add new fixup only if offset isn't 16bit. */
1948 add_to_link_pool (basesym
, sym
, addend
)
1953 segT current_section
= now_seg
;
1954 int current_subsec
= now_subseg
;
1956 bfd_reloc_code_real_type reloc_type
;
1958 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
1961 offset
= -basesym
->sy_obj
;
1963 /* @@ This assumes all entries in a given section will be of the same
1964 size... Probably correct, but unwise to rely on. */
1965 /* This must always be called with the same subsegment. */
1967 if (seginfo
->frchainP
)
1968 for (fixp
= seginfo
->frchainP
->fix_root
;
1969 fixp
!= (fixS
*) NULL
;
1970 fixp
= fixp
->fx_next
, offset
+= 8)
1972 if (fixp
->fx_addsy
== sym
&& fixp
->fx_offset
== addend
)
1974 if (range_signed_16 (offset
))
1981 /* Not found in 16bit signed range. */
1983 subseg_set (alpha_link_section
, 0);
1987 fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, sym
, addend
, 0,
1990 subseg_set (current_section
, current_subsec
);
1991 seginfo
->literal_pool_size
+= 8;
1995 #endif /* OBJ_EVAX */
1997 /* Load a (partial) expression into a target register.
1999 If poffset is not null, after the call it will either contain
2000 O_constant 0, or a 16-bit offset appropriate for any MEM format
2001 instruction. In addition, pbasereg will be modified to point to
2002 the base register to use in that MEM format instruction.
2004 In any case, *pbasereg should contain a base register to add to the
2005 expression. This will normally be either AXP_REG_ZERO or
2006 alpha_gp_register. Symbol addresses will always be loaded via $gp,
2007 so "foo($0)" is interpreted as adding the address of foo to $0;
2008 i.e. "ldq $targ, LIT($gp); addq $targ, $0, $targ". Odd, perhaps,
2009 but this is what OSF/1 does.
2011 Finally, the return value is true if the calling macro may emit a
2012 LITUSE reloc if otherwise appropriate. */
2015 load_expression (targreg
, exp
, pbasereg
, poffset
)
2017 const expressionS
*exp
;
2019 expressionS
*poffset
;
2021 int emit_lituse
= 0;
2022 offsetT addend
= exp
->X_add_number
;
2023 int basereg
= *pbasereg
;
2024 struct alpha_insn insn
;
2025 expressionS newtok
[3];
2034 /* attempt to reduce .lit load by splitting the offset from
2035 its symbol when possible, but don't create a situation in
2037 if (!range_signed_32 (addend
) &&
2038 (alpha_noat_on
|| targreg
== AXP_REG_AT
))
2040 lit
= add_to_literal_pool (exp
->X_add_symbol
, addend
,
2041 alpha_lita_section
, 8);
2046 lit
= add_to_literal_pool (exp
->X_add_symbol
, 0,
2047 alpha_lita_section
, 8);
2051 as_fatal ("overflow in literal (.lita) table");
2053 /* emit "ldq r, lit(gp)" */
2055 if (basereg
!= alpha_gp_register
&& targreg
== basereg
)
2058 as_bad ("macro requires $at register while noat in effect");
2059 if (targreg
== AXP_REG_AT
)
2060 as_bad ("macro requires $at while $at in use");
2062 set_tok_reg (newtok
[0], AXP_REG_AT
);
2065 set_tok_reg (newtok
[0], targreg
);
2066 set_tok_sym (newtok
[1], alpha_lita_symbol
, lit
);
2067 set_tok_preg (newtok
[2], alpha_gp_register
);
2069 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
2071 assert (insn
.nfixups
== 1);
2072 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITERAL
;
2073 #endif /* OBJ_ECOFF */
2075 /* emit "ldq r, gotoff(gp)" */
2077 if (basereg
!= alpha_gp_register
&& targreg
== basereg
)
2080 as_bad ("macro requires $at register while noat in effect");
2081 if (targreg
== AXP_REG_AT
)
2082 as_bad ("macro requires $at while $at in use");
2084 set_tok_reg (newtok
[0], AXP_REG_AT
);
2087 set_tok_reg (newtok
[0], targreg
);
2089 if (!range_signed_32 (addend
)
2090 && (alpha_noat_on
|| targreg
== AXP_REG_AT
))
2097 set_tok_sym (newtok
[1], exp
->X_add_symbol
, 0);
2100 set_tok_preg (newtok
[2], alpha_gp_register
);
2102 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
2104 assert (insn
.nfixups
== 1);
2105 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITERAL
;
2106 #endif /* OBJ_ELF */
2110 /* Find symbol or symbol pointer in link section. */
2112 if (exp
->X_add_symbol
== alpha_evax_proc
.symbol
)
2114 if (range_signed_16 (addend
))
2116 set_tok_reg (newtok
[0], targreg
);
2117 set_tok_const (newtok
[1], addend
);
2118 set_tok_preg (newtok
[2], basereg
);
2119 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
2124 set_tok_reg (newtok
[0], targreg
);
2125 set_tok_const (newtok
[1], 0);
2126 set_tok_preg (newtok
[2], basereg
);
2127 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
2132 if (!range_signed_32 (addend
))
2134 link
= add_to_link_pool (alpha_evax_proc
.symbol
,
2135 exp
->X_add_symbol
, addend
);
2140 link
= add_to_link_pool (alpha_evax_proc
.symbol
,
2141 exp
->X_add_symbol
, 0);
2143 set_tok_reg (newtok
[0], targreg
);
2144 set_tok_const (newtok
[1], link
);
2145 set_tok_preg (newtok
[2], basereg
);
2146 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
2148 #endif /* OBJ_EVAX */
2154 if (basereg
!= alpha_gp_register
&& basereg
!= AXP_REG_ZERO
)
2156 /* emit "addq r, base, r" */
2158 set_tok_reg (newtok
[1], basereg
);
2159 set_tok_reg (newtok
[2], targreg
);
2160 assemble_tokens ("addq", newtok
, 3, 0);
2171 /* Assume that this difference expression will be resolved to an
2172 absolute value and that that value will fit in 16 bits. */
2174 set_tok_reg (newtok
[0], targreg
);
2176 set_tok_preg (newtok
[2], basereg
);
2177 assemble_tokens ("lda", newtok
, 3, 0);
2180 set_tok_const (*poffset
, 0);
2187 if (!range_signed_32 (addend
))
2191 /* for 64-bit addends, just put it in the literal pool */
2195 /* emit "ldq targreg, lit(basereg)" */
2196 lit
= add_to_link_pool (alpha_evax_proc
.symbol
,
2197 section_symbol (absolute_section
), addend
);
2198 set_tok_reg (newtok
[0], targreg
);
2199 set_tok_const (newtok
[1], lit
);
2200 set_tok_preg (newtok
[2], alpha_gp_register
);
2201 assemble_tokens ("ldq", newtok
, 3, 0);
2205 if (alpha_lit8_section
== NULL
)
2207 create_literal_section (".lit8",
2208 &alpha_lit8_section
,
2209 &alpha_lit8_symbol
);
2210 S_SET_VALUE (alpha_lit8_symbol
, 0x8000);
2213 lit
= add_to_literal_pool (NULL
, addend
, alpha_lit8_section
, 8) - 0x8000;
2215 as_fatal ("overflow in literal (.lit8) table");
2217 /* emit "ldq litreg, .lit8+lit" */
2219 if (targreg
== basereg
)
2222 as_bad ("macro requires $at register while noat in effect");
2223 if (targreg
== AXP_REG_AT
)
2224 as_bad ("macro requires $at while $at in use");
2226 set_tok_reg (newtok
[0], AXP_REG_AT
);
2229 set_tok_reg (newtok
[0], targreg
);
2230 set_tok_sym (newtok
[1], alpha_lit8_symbol
, lit
);
2232 assemble_tokens ("ldq", newtok
, 2, 1); /* note this does recurse */
2234 /* emit "addq litreg, base, target" */
2236 if (basereg
!= AXP_REG_ZERO
)
2238 set_tok_reg (newtok
[1], basereg
);
2239 set_tok_reg (newtok
[2], targreg
);
2240 assemble_tokens ("addq", newtok
, 3, 0);
2242 #endif /* !OBJ_EVAX */
2245 set_tok_const (*poffset
, 0);
2246 *pbasereg
= targreg
;
2250 offsetT low
, high
, extra
, tmp
;
2252 /* for 32-bit operands, break up the addend */
2254 low
= sign_extend_16 (addend
);
2256 high
= sign_extend_16 (tmp
>> 16);
2258 if (tmp
- (high
<< 16))
2262 high
= sign_extend_16 (tmp
>> 16);
2267 set_tok_reg (newtok
[0], targreg
);
2268 set_tok_preg (newtok
[2], basereg
);
2272 /* emit "ldah r, extra(r) */
2273 set_tok_const (newtok
[1], extra
);
2274 assemble_tokens ("ldah", newtok
, 3, 0);
2275 set_tok_preg (newtok
[2], basereg
= targreg
);
2280 /* emit "ldah r, high(r) */
2281 set_tok_const (newtok
[1], high
);
2282 assemble_tokens ("ldah", newtok
, 3, 0);
2284 set_tok_preg (newtok
[2], basereg
);
2287 if ((low
&& !poffset
) || (!poffset
&& basereg
!= targreg
))
2289 /* emit "lda r, low(base)" */
2290 set_tok_const (newtok
[1], low
);
2291 assemble_tokens ("lda", newtok
, 3, 0);
2297 set_tok_const (*poffset
, low
);
2298 *pbasereg
= basereg
;
2304 /* The lda macro differs from the lda instruction in that it handles
2305 most simple expressions, particualrly symbol address loads and
2309 emit_lda (tok
, ntok
, unused
)
2310 const expressionS
*tok
;
2317 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
2319 basereg
= tok
[2].X_add_number
;
2321 (void) load_expression (tok
[0].X_add_number
, &tok
[1], &basereg
, NULL
);
2324 /* The ldah macro differs from the ldah instruction in that it has $31
2325 as an implied base register. */
2328 emit_ldah (tok
, ntok
, unused
)
2329 const expressionS
*tok
;
2333 expressionS newtok
[3];
2337 set_tok_preg (newtok
[2], AXP_REG_ZERO
);
2339 assemble_tokens ("ldah", newtok
, 3, 0);
2342 /* Handle all "simple" integer register loads -- ldq, ldq_l, ldq_u,
2343 etc. They differ from the real instructions in that they do simple
2344 expressions like the lda macro. */
2347 emit_ir_load (tok
, ntok
, opname
)
2348 const expressionS
*tok
;
2352 int basereg
, lituse
;
2353 expressionS newtok
[3];
2354 struct alpha_insn insn
;
2357 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
2359 basereg
= tok
[2].X_add_number
;
2361 lituse
= load_expression (tok
[0].X_add_number
, &tok
[1], &basereg
,
2365 set_tok_preg (newtok
[2], basereg
);
2367 assemble_tokens_to_insn ((const char *)opname
, newtok
, 3, &insn
);
2371 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
2372 if (insn
.nfixups
> 0)
2374 memmove (&insn
.fixups
[1], &insn
.fixups
[0],
2375 sizeof(struct alpha_fixup
) * insn
.nfixups
);
2378 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITUSE
;
2379 insn
.fixups
[0].exp
.X_op
= O_constant
;
2380 insn
.fixups
[0].exp
.X_add_number
= 1;
2386 /* Handle fp register loads, and both integer and fp register stores.
2387 Again, we handle simple expressions. */
2390 emit_loadstore (tok
, ntok
, opname
)
2391 const expressionS
*tok
;
2395 int basereg
, lituse
;
2396 expressionS newtok
[3];
2397 struct alpha_insn insn
;
2400 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
2402 basereg
= tok
[2].X_add_number
;
2404 if (tok
[1].X_op
!= O_constant
|| !range_signed_16(tok
[1].X_add_number
))
2407 as_bad ("macro requires $at register while noat in effect");
2409 lituse
= load_expression (AXP_REG_AT
, &tok
[1], &basereg
, &newtok
[1]);
2418 set_tok_preg (newtok
[2], basereg
);
2420 assemble_tokens_to_insn ((const char *)opname
, newtok
, 3, &insn
);
2424 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
2425 if (insn
.nfixups
> 0)
2427 memmove (&insn
.fixups
[1], &insn
.fixups
[0],
2428 sizeof(struct alpha_fixup
) * insn
.nfixups
);
2431 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITUSE
;
2432 insn
.fixups
[0].exp
.X_op
= O_constant
;
2433 insn
.fixups
[0].exp
.X_add_number
= 1;
2439 /* Load a half-word or byte as an unsigned value. */
2442 emit_ldXu (tok
, ntok
, vlgsize
)
2443 const expressionS
*tok
;
2447 expressionS newtok
[3];
2450 as_bad ("macro requires $at register while noat in effect");
2452 /* emit "lda $at, exp" */
2454 memcpy (newtok
, tok
, sizeof(expressionS
)*ntok
);
2455 newtok
[0].X_add_number
= AXP_REG_AT
;
2456 assemble_tokens ("lda", newtok
, ntok
, 1);
2458 /* emit "ldq_u targ, 0($at)" */
2461 set_tok_const (newtok
[1], 0);
2462 set_tok_preg (newtok
[2], AXP_REG_AT
);
2463 assemble_tokens ("ldq_u", newtok
, 3, 1);
2465 /* emit "extXl targ, $at, targ" */
2467 set_tok_reg (newtok
[1], AXP_REG_AT
);
2468 newtok
[2] = newtok
[0];
2469 assemble_tokens (extXl_op
[(long)vlgsize
], newtok
, 3, 1);
2472 /* Load a half-word or byte as a signed value. */
2475 emit_ldX (tok
, ntok
, vlgsize
)
2476 const expressionS
*tok
;
2480 emit_ldXu (tok
, ntok
, vlgsize
);
2481 assemble_tokens (sextX_op
[(long)vlgsize
], tok
, 1, 1);
2484 /* Load an integral value from an unaligned address as an unsigned
2488 emit_uldXu (tok
, ntok
, vlgsize
)
2489 const expressionS
*tok
;
2493 long lgsize
= (long)vlgsize
;
2494 expressionS newtok
[3];
2497 as_bad ("macro requires $at register while noat in effect");
2499 /* emit "lda $at, exp" */
2501 memcpy (newtok
, tok
, sizeof(expressionS
)*ntok
);
2502 newtok
[0].X_add_number
= AXP_REG_AT
;
2503 assemble_tokens ("lda", newtok
, ntok
, 1);
2505 /* emit "ldq_u $t9, 0($at)" */
2507 set_tok_reg (newtok
[0], AXP_REG_T9
);
2508 set_tok_const (newtok
[1], 0);
2509 set_tok_preg (newtok
[2], AXP_REG_AT
);
2510 assemble_tokens ("ldq_u", newtok
, 3, 1);
2512 /* emit "ldq_u $t10, size-1($at)" */
2514 set_tok_reg (newtok
[0], AXP_REG_T10
);
2515 set_tok_const (newtok
[1], (1<<lgsize
)-1);
2516 assemble_tokens ("ldq_u", newtok
, 3, 1);
2518 /* emit "extXl $t9, $at, $t9" */
2520 set_tok_reg (newtok
[0], AXP_REG_T9
);
2521 set_tok_reg (newtok
[1], AXP_REG_AT
);
2522 set_tok_reg (newtok
[2], AXP_REG_T9
);
2523 assemble_tokens (extXl_op
[lgsize
], newtok
, 3, 1);
2525 /* emit "extXh $t10, $at, $t10" */
2527 set_tok_reg (newtok
[0], AXP_REG_T10
);
2528 set_tok_reg (newtok
[2], AXP_REG_T10
);
2529 assemble_tokens (extXh_op
[lgsize
], newtok
, 3, 1);
2531 /* emit "or $t9, $t10, targ" */
2533 set_tok_reg (newtok
[0], AXP_REG_T9
);
2534 set_tok_reg (newtok
[1], AXP_REG_T10
);
2536 assemble_tokens ("or", newtok
, 3, 1);
2539 /* Load an integral value from an unaligned address as a signed value.
2540 Note that quads should get funneled to the unsigned load since we
2541 don't have to do the sign extension. */
2544 emit_uldX (tok
, ntok
, vlgsize
)
2545 const expressionS
*tok
;
2549 emit_uldXu (tok
, ntok
, vlgsize
);
2550 assemble_tokens (sextX_op
[(long)vlgsize
], tok
, 1, 1);
2553 /* Implement the ldil macro. */
2556 emit_ldil (tok
, ntok
, unused
)
2557 const expressionS
*tok
;
2561 expressionS newtok
[2];
2563 memcpy (newtok
, tok
, sizeof(newtok
));
2564 newtok
[1].X_add_number
= sign_extend_32 (tok
[1].X_add_number
);
2566 assemble_tokens ("lda", newtok
, ntok
, 1);
2569 /* Store a half-word or byte. */
2572 emit_stX (tok
, ntok
, vlgsize
)
2573 const expressionS
*tok
;
2576 int lgsize
= (int)(long)vlgsize
;
2577 expressionS newtok
[3];
2580 as_bad("macro requires $at register while noat in effect");
2582 /* emit "lda $at, exp" */
2584 memcpy (newtok
, tok
, sizeof(expressionS
)*ntok
);
2585 newtok
[0].X_add_number
= AXP_REG_AT
;
2586 assemble_tokens ("lda", newtok
, ntok
, 1);
2588 /* emit "ldq_u $t9, 0($at)" */
2590 set_tok_reg (newtok
[0], AXP_REG_T9
);
2591 set_tok_const (newtok
[1], 0);
2592 set_tok_preg (newtok
[2], AXP_REG_AT
);
2593 assemble_tokens ("ldq_u", newtok
, 3, 1);
2595 /* emit "insXl src, $at, $t10" */
2598 set_tok_reg (newtok
[1], AXP_REG_AT
);
2599 set_tok_reg (newtok
[2], AXP_REG_T10
);
2600 assemble_tokens (insXl_op
[lgsize
], newtok
, 3, 1);
2602 /* emit "mskXl $t9, $at, $t9" */
2604 set_tok_reg (newtok
[0], AXP_REG_T9
);
2605 newtok
[2] = newtok
[0];
2606 assemble_tokens (mskXl_op
[lgsize
], newtok
, 3, 1);
2608 /* emit "or $t9, $t10, $t9" */
2610 set_tok_reg (newtok
[1], AXP_REG_T10
);
2611 assemble_tokens ("or", newtok
, 3, 1);
2613 /* emit "stq_u $t9, 0($at) */
2615 set_tok_const (newtok
[1], 0);
2616 set_tok_preg (newtok
[2], AXP_REG_AT
);
2617 assemble_tokens ("stq_u", newtok
, 3, 1);
2620 /* Store an integer to an unaligned address. */
2623 emit_ustX (tok
, ntok
, vlgsize
)
2624 const expressionS
*tok
;
2628 int lgsize
= (int)(long)vlgsize
;
2629 expressionS newtok
[3];
2631 /* emit "lda $at, exp" */
2633 memcpy (newtok
, tok
, sizeof(expressionS
)*ntok
);
2634 newtok
[0].X_add_number
= AXP_REG_AT
;
2635 assemble_tokens ("lda", newtok
, ntok
, 1);
2637 /* emit "ldq_u $9, 0($at)" */
2639 set_tok_reg (newtok
[0], AXP_REG_T9
);
2640 set_tok_const (newtok
[1], 0);
2641 set_tok_preg (newtok
[2], AXP_REG_AT
);
2642 assemble_tokens ("ldq_u", newtok
, 3, 1);
2644 /* emit "ldq_u $10, size-1($at)" */
2646 set_tok_reg (newtok
[0], AXP_REG_T10
);
2647 set_tok_const (newtok
[1], (1 << lgsize
)-1);
2648 assemble_tokens ("ldq_u", newtok
, 3, 1);
2650 /* emit "insXl src, $at, $t11" */
2653 set_tok_reg (newtok
[1], AXP_REG_AT
);
2654 set_tok_reg (newtok
[2], AXP_REG_T11
);
2655 assemble_tokens (insXl_op
[lgsize
], newtok
, 3, 1);
2657 /* emit "insXh src, $at, $t12" */
2659 set_tok_reg (newtok
[2], AXP_REG_T12
);
2660 assemble_tokens (insXh_op
[lgsize
], newtok
, 3, 1);
2662 /* emit "mskXl $t9, $at, $t9" */
2664 set_tok_reg (newtok
[0], AXP_REG_T9
);
2665 newtok
[2] = newtok
[0];
2666 assemble_tokens (mskXl_op
[lgsize
], newtok
, 3, 1);
2668 /* emit "mskXh $t10, $at, $t10" */
2670 set_tok_reg (newtok
[0], AXP_REG_T10
);
2671 newtok
[2] = newtok
[0];
2672 assemble_tokens (mskXh_op
[lgsize
], newtok
, 3, 1);
2674 /* emit "or $t9, $t11, $t9" */
2676 set_tok_reg (newtok
[0], AXP_REG_T9
);
2677 set_tok_reg (newtok
[1], AXP_REG_T11
);
2678 newtok
[2] = newtok
[0];
2679 assemble_tokens ("or", newtok
, 3, 1);
2681 /* emit "or $t10, $t12, $t10" */
2683 set_tok_reg (newtok
[0], AXP_REG_T10
);
2684 set_tok_reg (newtok
[1], AXP_REG_T12
);
2685 newtok
[2] = newtok
[0];
2686 assemble_tokens ("or", newtok
, 3, 1);
2688 /* emit "stq_u $t9, 0($at)" */
2690 set_tok_reg (newtok
[0], AXP_REG_T9
);
2691 set_tok_const (newtok
[1], 0);
2692 set_tok_preg (newtok
[2], AXP_REG_AT
);
2693 assemble_tokens ("stq_u", newtok
, 3, 1);
2695 /* emit "stq_u $t10, size-1($at)" */
2697 set_tok_reg (newtok
[0], AXP_REG_T10
);
2698 set_tok_const (newtok
[1], (1 << lgsize
)-1);
2699 assemble_tokens ("stq_u", newtok
, 3, 1);
2702 /* Sign extend a half-word or byte. The 32-bit sign extend is
2703 implemented as "addl $31, $r, $t" in the opcode table. */
2706 emit_sextX (tok
, ntok
, vlgsize
)
2707 const expressionS
*tok
;
2711 int bitshift
= 64 - 8*(1 << (long)vlgsize
);
2712 expressionS newtok
[3];
2714 /* emit "sll src,bits,dst" */
2717 set_tok_const (newtok
[1], bitshift
);
2718 newtok
[2] = tok
[ntok
- 1];
2719 assemble_tokens ("sll", newtok
, 3, 1);
2721 /* emit "sra dst,bits,dst" */
2723 newtok
[0] = newtok
[2];
2724 assemble_tokens ("sra", newtok
, 3, 1);
2727 /* Implement the division and modulus macros. */
2731 /* Make register usage like in normal procedure call.
2732 Don't clobber PV and RA. */
2735 emit_division (tok
, ntok
, symname
)
2736 const expressionS
*tok
;
2740 /* DIVISION and MODULUS. Yech.
2745 * mov x,R16 # if x != R16
2746 * mov y,R17 # if y != R17
2751 * with appropriate optimizations if R0,R16,R17 are the registers
2752 * specified by the compiler.
2757 expressionS newtok
[3];
2759 xr
= regno (tok
[0].X_add_number
);
2760 yr
= regno (tok
[1].X_add_number
);
2765 rr
= regno (tok
[2].X_add_number
);
2767 /* Move the operands into the right place */
2768 if (yr
== AXP_REG_R16
&& xr
== AXP_REG_R17
)
2770 /* They are in exactly the wrong order -- swap through AT */
2773 as_bad ("macro requires $at register while noat in effect");
2775 set_tok_reg (newtok
[0], AXP_REG_R16
);
2776 set_tok_reg (newtok
[1], AXP_REG_AT
);
2777 assemble_tokens ("mov", newtok
, 2, 1);
2779 set_tok_reg (newtok
[0], AXP_REG_R17
);
2780 set_tok_reg (newtok
[1], AXP_REG_R16
);
2781 assemble_tokens ("mov", newtok
, 2, 1);
2783 set_tok_reg (newtok
[0], AXP_REG_AT
);
2784 set_tok_reg (newtok
[1], AXP_REG_R17
);
2785 assemble_tokens ("mov", newtok
, 2, 1);
2789 if (yr
== AXP_REG_R16
)
2791 set_tok_reg (newtok
[0], AXP_REG_R16
);
2792 set_tok_reg (newtok
[1], AXP_REG_R17
);
2793 assemble_tokens ("mov", newtok
, 2, 1);
2796 if (xr
!= AXP_REG_R16
)
2798 set_tok_reg (newtok
[0], xr
);
2799 set_tok_reg (newtok
[1], AXP_REG_R16
);
2800 assemble_tokens ("mov", newtok
, 2, 1);
2803 if (yr
!= AXP_REG_R16
&& yr
!= AXP_REG_R17
)
2805 set_tok_reg (newtok
[0], yr
);
2806 set_tok_reg (newtok
[1], AXP_REG_R17
);
2807 assemble_tokens ("mov", newtok
, 2, 1);
2811 sym
= symbol_find_or_make ((const char *)symname
);
2813 set_tok_reg (newtok
[0], AXP_REG_AT
);
2814 set_tok_sym (newtok
[1], sym
, 0);
2815 assemble_tokens ("lda", newtok
, 2, 1);
2817 /* Call the division routine */
2818 set_tok_reg (newtok
[0], AXP_REG_AT
);
2819 set_tok_cpreg (newtok
[1], AXP_REG_AT
);
2820 set_tok_const (newtok
[2], 0);
2821 assemble_tokens ("jsr", newtok
, 3, 1);
2823 /* Move the result to the right place */
2824 if (rr
!= AXP_REG_R0
)
2826 set_tok_reg (newtok
[0], AXP_REG_R0
);
2827 set_tok_reg (newtok
[1], rr
);
2828 assemble_tokens ("mov", newtok
, 2, 1);
2832 #else /* !OBJ_EVAX */
2835 emit_division (tok
, ntok
, symname
)
2836 const expressionS
*tok
;
2840 /* DIVISION and MODULUS. Yech.
2850 * with appropriate optimizations if t10,t11,t12 are the registers
2851 * specified by the compiler.
2856 expressionS newtok
[3];
2858 xr
= regno (tok
[0].X_add_number
);
2859 yr
= regno (tok
[1].X_add_number
);
2864 rr
= regno (tok
[2].X_add_number
);
2866 sym
= symbol_find_or_make ((const char *)symname
);
2868 /* Move the operands into the right place */
2869 if (yr
== AXP_REG_T10
&& xr
== AXP_REG_T11
)
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_T10
);
2877 set_tok_reg (newtok
[1], AXP_REG_AT
);
2878 assemble_tokens ("mov", newtok
, 2, 1);
2880 set_tok_reg (newtok
[0], AXP_REG_T11
);
2881 set_tok_reg (newtok
[1], AXP_REG_T10
);
2882 assemble_tokens ("mov", newtok
, 2, 1);
2884 set_tok_reg (newtok
[0], AXP_REG_AT
);
2885 set_tok_reg (newtok
[1], AXP_REG_T11
);
2886 assemble_tokens ("mov", newtok
, 2, 1);
2890 if (yr
== AXP_REG_T10
)
2892 set_tok_reg (newtok
[0], AXP_REG_T10
);
2893 set_tok_reg (newtok
[1], AXP_REG_T11
);
2894 assemble_tokens ("mov", newtok
, 2, 1);
2897 if (xr
!= AXP_REG_T10
)
2899 set_tok_reg (newtok
[0], xr
);
2900 set_tok_reg (newtok
[1], AXP_REG_T10
);
2901 assemble_tokens ("mov", newtok
, 2, 1);
2904 if (yr
!= AXP_REG_T10
&& yr
!= AXP_REG_T11
)
2906 set_tok_reg (newtok
[0], yr
);
2907 set_tok_reg (newtok
[1], AXP_REG_T11
);
2908 assemble_tokens ("mov", newtok
, 2, 1);
2912 /* Call the division routine */
2913 set_tok_reg (newtok
[0], AXP_REG_T9
);
2914 set_tok_sym (newtok
[1], sym
, 0);
2915 assemble_tokens ("jsr", newtok
, 2, 1);
2917 /* Reload the GP register */
2921 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
2922 set_tok_reg (newtok
[0], alpha_gp_register
);
2923 set_tok_const (newtok
[1], 0);
2924 set_tok_preg (newtok
[2], AXP_REG_T9
);
2925 assemble_tokens ("ldgp", newtok
, 3, 1);
2928 /* Move the result to the right place */
2929 if (rr
!= AXP_REG_T12
)
2931 set_tok_reg (newtok
[0], AXP_REG_T12
);
2932 set_tok_reg (newtok
[1], rr
);
2933 assemble_tokens ("mov", newtok
, 2, 1);
2937 #endif /* !OBJ_EVAX */
2939 /* The jsr and jmp macros differ from their instruction counterparts
2940 in that they can load the target address and default most
2944 emit_jsrjmp (tok
, ntok
, vopname
)
2945 const expressionS
*tok
;
2949 const char *opname
= (const char *) vopname
;
2950 struct alpha_insn insn
;
2951 expressionS newtok
[3];
2952 int r
, tokidx
= 0, lituse
= 0;
2954 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_register
)
2955 r
= regno (tok
[tokidx
++].X_add_number
);
2957 r
= strcmp (opname
, "jmp") == 0 ? AXP_REG_ZERO
: AXP_REG_RA
;
2959 set_tok_reg (newtok
[0], r
);
2961 if (tokidx
< ntok
&&
2962 (tok
[tokidx
].X_op
== O_pregister
|| tok
[tokidx
].X_op
== O_cpregister
))
2963 r
= regno (tok
[tokidx
++].X_add_number
);
2965 /* keep register if jsr $n.<sym> */
2969 int basereg
= alpha_gp_register
;
2970 lituse
= load_expression (r
= AXP_REG_PV
, &tok
[tokidx
], &basereg
, NULL
);
2974 set_tok_cpreg (newtok
[1], r
);
2977 /* FIXME: Add hint relocs to BFD for evax. */
2980 newtok
[2] = tok
[tokidx
];
2983 set_tok_const (newtok
[2], 0);
2985 assemble_tokens_to_insn (opname
, newtok
, 3, &insn
);
2987 /* add the LITUSE fixup */
2990 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
2991 if (insn
.nfixups
> 0)
2993 memmove (&insn
.fixups
[1], &insn
.fixups
[0],
2994 sizeof(struct alpha_fixup
) * insn
.nfixups
);
2997 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITUSE
;
2998 insn
.fixups
[0].exp
.X_op
= O_constant
;
2999 insn
.fixups
[0].exp
.X_add_number
= 3;
3005 /* reload PV from 0(FP) if it is our current base register. */
3006 if (alpha_gp_register
== AXP_REG_PV
)
3008 set_tok_reg (newtok
[0], AXP_REG_PV
);
3009 set_tok_const (newtok
[1], 0);
3010 set_tok_preg (newtok
[2], AXP_REG_FP
);
3011 assemble_tokens ("ldq", newtok
, 3, 0);
3016 /* The ret and jcr instructions differ from their instruction
3017 counterparts in that everything can be defaulted. */
3020 emit_retjcr (tok
, ntok
, vopname
)
3021 const expressionS
*tok
;
3025 const char *opname
= (const char *)vopname
;
3026 expressionS newtok
[3];
3029 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_register
)
3030 r
= regno (tok
[tokidx
++].X_add_number
);
3034 set_tok_reg (newtok
[0], r
);
3036 if (tokidx
< ntok
&&
3037 (tok
[tokidx
].X_op
== O_pregister
|| tok
[tokidx
].X_op
== O_cpregister
))
3038 r
= regno (tok
[tokidx
++].X_add_number
);
3042 set_tok_cpreg (newtok
[1], r
);
3045 newtok
[2] = tok
[tokidx
];
3047 set_tok_const (newtok
[2], strcmp(opname
, "ret") == 0);
3049 assemble_tokens (opname
, newtok
, 3, 0);
3052 /* Assembler directives */
3054 /* Handle the .text pseudo-op. This is like the usual one, but it
3055 clears alpha_insn_label and restores auto alignment. */
3063 alpha_insn_label
= NULL
;
3064 alpha_auto_align_on
= 1;
3065 alpha_current_align
= 0;
3068 /* Handle the .data pseudo-op. This is like the usual one, but it
3069 clears alpha_insn_label and restores auto alignment. */
3076 alpha_insn_label
= NULL
;
3077 alpha_auto_align_on
= 1;
3078 alpha_current_align
= 0;
3083 /* Handle the OSF/1 .comm pseudo quirks. */
3086 s_alpha_comm (ignore
)
3089 register char *name
;
3093 register symbolS
*symbolP
;
3095 name
= input_line_pointer
;
3096 c
= get_symbol_end ();
3098 /* just after name is now '\0' */
3099 p
= input_line_pointer
;
3104 /* Alpha OSF/1 compiler doesn't provide the comma, gcc does. */
3105 if (*input_line_pointer
== ',')
3107 input_line_pointer
++;
3110 if ((temp
= get_absolute_expression ()) < 0)
3112 as_warn (".COMMon length (%ld.) <0! Ignored.", (long) temp
);
3113 ignore_rest_of_line ();
3118 symbolP
= symbol_find_or_make (name
);
3121 if (S_IS_DEFINED (symbolP
))
3123 as_bad ("Ignoring attempt to re-define symbol");
3124 ignore_rest_of_line ();
3130 /* Fill common area with zeros. */
3132 segT current_seg
= now_seg
;
3133 subsegT current_subseg
= now_subseg
;
3135 subseg_set (bss_section
, 1);
3138 symbolP
->sy_frag
= frag_now
;
3139 pfrag
= frag_var (rs_org
, 1, 1, (relax_substateT
)0, symbolP
,
3143 S_SET_SEGMENT (symbolP
, bss_section
);
3145 subseg_set (current_seg
, current_subseg
);
3149 if (S_GET_VALUE (symbolP
))
3151 if (S_GET_VALUE (symbolP
) != (valueT
) temp
)
3152 as_bad ("Length of .comm \"%s\" is already %ld. Not changed to %ld.",
3153 S_GET_NAME (symbolP
),
3154 (long) S_GET_VALUE (symbolP
),
3159 S_SET_VALUE (symbolP
, (valueT
) temp
);
3160 S_SET_EXTERNAL (symbolP
);
3164 know (symbolP
->sy_frag
== &zero_address_frag
);
3167 demand_empty_rest_of_line ();
3170 #endif /* ! OBJ_ELF */
3172 #if defined (OBJ_ECOFF) || defined (OBJ_EVAX)
3174 /* Handle the .rdata pseudo-op. This is like the usual one, but it
3175 clears alpha_insn_label and restores auto alignment. */
3178 s_alpha_rdata (ignore
)
3183 temp
= get_absolute_expression ();
3184 subseg_new (".rdata", 0);
3185 demand_empty_rest_of_line ();
3186 alpha_insn_label
= NULL
;
3187 alpha_auto_align_on
= 1;
3188 alpha_current_align
= 0;
3195 /* Handle the .sdata pseudo-op. This is like the usual one, but it
3196 clears alpha_insn_label and restores auto alignment. */
3199 s_alpha_sdata (ignore
)
3204 temp
= get_absolute_expression ();
3205 subseg_new (".sdata", 0);
3206 demand_empty_rest_of_line ();
3207 alpha_insn_label
= NULL
;
3208 alpha_auto_align_on
= 1;
3209 alpha_current_align
= 0;
3215 /* Handle the .section pseudo-op. This is like the usual one, but it
3216 clears alpha_insn_label and restores auto alignment. */
3219 s_alpha_section (ignore
)
3222 obj_elf_section (ignore
);
3224 alpha_insn_label
= NULL
;
3225 alpha_auto_align_on
= 1;
3226 alpha_current_align
= 0;
3233 s_alpha_link (ignore
)
3238 temp
= get_absolute_expression ();
3239 subseg_new (".link", 0);
3240 demand_empty_rest_of_line ();
3241 alpha_insn_label
= NULL
;
3242 alpha_auto_align_on
= 1;
3243 alpha_current_align
= 0;
3250 s_alpha_prologue (ignore
)
3253 demand_empty_rest_of_line ();
3259 /* Parse .ent directives. */
3262 s_alpha_ent (ignore
)
3266 expressionS symexpr
;
3268 alpha_evax_proc
.pdsckind
= 0;
3269 alpha_evax_proc
.framereg
= -1;
3270 alpha_evax_proc
.framesize
= 0;
3271 alpha_evax_proc
.rsa_offset
= 0;
3272 alpha_evax_proc
.ra_save
= AXP_REG_RA
;
3273 alpha_evax_proc
.fp_save
= -1;
3274 alpha_evax_proc
.imask
= 0;
3275 alpha_evax_proc
.fmask
= 0;
3276 alpha_evax_proc
.prologue
= 0;
3277 alpha_evax_proc
.type
= 0;
3279 expression (&symexpr
);
3281 if (symexpr
.X_op
!= O_symbol
)
3283 as_fatal (".ent directive has no symbol");
3284 demand_empty_rest_of_line ();
3288 symbol
= make_expr_symbol (&symexpr
);
3289 symbol
->bsym
->flags
|= BSF_FUNCTION
;
3290 alpha_evax_proc
.symbol
= symbol
;
3292 demand_empty_rest_of_line ();
3297 /* Parse .frame <framreg>,<framesize>,RA,<rsa_offset> directives. */
3300 s_alpha_frame (ignore
)
3305 alpha_evax_proc
.framereg
= tc_get_register (1);
3308 if (*input_line_pointer
++ != ','
3309 || get_absolute_expression_and_terminator (&val
) != ',')
3311 as_warn ("Bad .frame directive 1./2. param");
3312 --input_line_pointer
;
3313 demand_empty_rest_of_line ();
3317 alpha_evax_proc
.framesize
= val
;
3319 (void) tc_get_register (1);
3321 if (*input_line_pointer
++ != ',')
3323 as_warn ("Bad .frame directive 3./4. param");
3324 --input_line_pointer
;
3325 demand_empty_rest_of_line ();
3328 alpha_evax_proc
.rsa_offset
= get_absolute_expression ();
3334 s_alpha_pdesc (ignore
)
3344 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
3346 if (now_seg
!= alpha_link_section
)
3348 as_bad (".pdesc directive not in link (.link) section");
3349 demand_empty_rest_of_line ();
3353 if ((alpha_evax_proc
.symbol
== 0)
3354 || (!S_IS_DEFINED (alpha_evax_proc
.symbol
)))
3356 as_fatal (".pdesc has no matching .ent");
3357 demand_empty_rest_of_line ();
3361 alpha_evax_proc
.symbol
->sy_obj
= (valueT
)seginfo
->literal_pool_size
;
3364 if (exp
.X_op
!= O_symbol
)
3366 as_warn (".pdesc directive has no entry symbol");
3367 demand_empty_rest_of_line ();
3371 entry_sym
= make_expr_symbol (&exp
);
3372 /* Save bfd symbol of proc desc in function symbol. */
3373 alpha_evax_proc
.symbol
->bsym
->udata
.p
= (PTR
)entry_sym
->bsym
;
3376 if (*input_line_pointer
++ != ',')
3378 as_warn ("No comma after .pdesc <entryname>");
3379 demand_empty_rest_of_line ();
3384 name
= input_line_pointer
;
3385 name_end
= get_symbol_end ();
3387 if (strncmp(name
, "stack", 5) == 0)
3389 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_FP_STACK
;
3391 else if (strncmp(name
, "reg", 3) == 0)
3393 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_FP_REGISTER
;
3395 else if (strncmp(name
, "null", 4) == 0)
3397 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_NULL
;
3401 as_fatal ("unknown procedure kind");
3402 demand_empty_rest_of_line ();
3406 *input_line_pointer
= name_end
;
3407 demand_empty_rest_of_line ();
3409 #ifdef md_flush_pending_output
3410 md_flush_pending_output ();
3415 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
3417 seginfo
->literal_pool_size
+= 16;
3419 *p
= alpha_evax_proc
.pdsckind
3420 | ((alpha_evax_proc
.framereg
== 29) ? PDSC_S_M_BASE_REG_IS_FP
: 0);
3421 *(p
+1) = PDSC_S_M_NATIVE
3422 | PDSC_S_M_NO_JACKET
;
3424 switch (alpha_evax_proc
.pdsckind
)
3426 case PDSC_S_K_KIND_NULL
:
3430 case PDSC_S_K_KIND_FP_REGISTER
:
3431 *(p
+2) = alpha_evax_proc
.fp_save
;
3432 *(p
+3) = alpha_evax_proc
.ra_save
;
3434 case PDSC_S_K_KIND_FP_STACK
:
3435 md_number_to_chars (p
+2, (valueT
)alpha_evax_proc
.rsa_offset
, 2);
3437 default: /* impossible */
3442 *(p
+5) = alpha_evax_proc
.type
& 0x0f;
3444 /* Signature offset. */
3445 md_number_to_chars (p
+6, (valueT
)0, 2);
3447 fix_new_exp (frag_now
, p
-frag_now
->fr_literal
+8, 8, &exp
, 0, BFD_RELOC_64
);
3449 if (alpha_evax_proc
.pdsckind
== PDSC_S_K_KIND_NULL
)
3452 /* Add dummy fix to make add_to_link_pool work. */
3454 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
3456 seginfo
->literal_pool_size
+= 8;
3458 /* pdesc+16: Size. */
3459 md_number_to_chars (p
, (valueT
)alpha_evax_proc
.framesize
, 4);
3461 md_number_to_chars (p
+4, (valueT
)0, 2);
3464 md_number_to_chars (p
+6, alpha_evax_proc
.prologue
, 2);
3466 if (alpha_evax_proc
.pdsckind
== PDSC_S_K_KIND_FP_REGISTER
)
3469 /* Add dummy fix to make add_to_link_pool work. */
3471 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
3473 seginfo
->literal_pool_size
+= 8;
3475 /* pdesc+24: register masks. */
3477 md_number_to_chars (p
, alpha_evax_proc
.imask
, 4);
3478 md_number_to_chars (p
+4, alpha_evax_proc
.fmask
, 4);
3485 s_alpha_linkage (ignore
)
3491 #ifdef md_flush_pending_output
3492 md_flush_pending_output ();
3496 if (exp
.X_op
!= O_symbol
)
3498 as_fatal ("No symbol after .linkage");
3502 p
= frag_more (LKP_S_K_SIZE
);
3503 memset (p
, 0, LKP_S_K_SIZE
);
3504 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, LKP_S_K_SIZE
, &exp
, 0,\
3505 BFD_RELOC_ALPHA_LINKAGE
);
3507 demand_empty_rest_of_line ();
3514 s_alpha_fp_save (ignore
)
3518 alpha_evax_proc
.fp_save
= tc_get_register (1);
3520 demand_empty_rest_of_line ();
3526 s_alpha_mask (ignore
)
3531 if (get_absolute_expression_and_terminator (&val
) != ',')
3533 as_warn ("Bad .mask directive");
3534 --input_line_pointer
;
3538 alpha_evax_proc
.imask
= val
;
3539 (void)get_absolute_expression ();
3541 demand_empty_rest_of_line ();
3548 s_alpha_fmask (ignore
)
3553 if (get_absolute_expression_and_terminator (&val
) != ',')
3555 as_warn ("Bad .fmask directive");
3556 --input_line_pointer
;
3560 alpha_evax_proc
.fmask
= val
;
3561 (void) get_absolute_expression ();
3563 demand_empty_rest_of_line ();
3569 s_alpha_end (ignore
)
3574 c
= get_symbol_end ();
3575 *input_line_pointer
= c
;
3576 demand_empty_rest_of_line ();
3577 alpha_evax_proc
.symbol
= 0;
3584 s_alpha_file (ignore
)
3589 extern char *demand_copy_string
PARAMS ((int *lenP
));
3591 get_absolute_expression ();
3592 s
= demand_copy_string (&length
);
3593 demand_empty_rest_of_line ();
3597 #endif /* OBJ_EVAX */
3599 /* Handle the .gprel32 pseudo op. */
3602 s_alpha_gprel32 (ignore
)
3615 e
.X_add_symbol
= section_symbol(absolute_section
);
3628 e
.X_add_symbol
= section_symbol (absolute_section
);
3631 e
.X_op
= O_subtract
;
3632 e
.X_op_symbol
= alpha_gp_symbol
;
3640 if (alpha_auto_align_on
&& alpha_current_align
< 2)
3641 alpha_align (2, (char *) NULL
, alpha_insn_label
);
3642 if (alpha_current_align
> 2)
3643 alpha_current_align
= 2;
3644 alpha_insn_label
= NULL
;
3648 fix_new_exp (frag_now
, p
-frag_now
->fr_literal
, 4,
3649 &e
, 0, BFD_RELOC_GPREL32
);
3652 /* Handle floating point allocation pseudo-ops. This is like the
3653 generic vresion, but it makes sure the current label, if any, is
3654 correctly aligned. */
3657 s_alpha_float_cons (type
)
3684 if (alpha_auto_align_on
&& alpha_current_align
< log_size
)
3685 alpha_align (log_size
, (char *) NULL
, alpha_insn_label
);
3686 if (alpha_current_align
> log_size
)
3687 alpha_current_align
= log_size
;
3688 alpha_insn_label
= NULL
;
3693 /* Handle the .proc pseudo op. We don't really do much with it except
3697 s_alpha_proc (is_static
)
3706 /* Takes ".proc name,nargs" */
3707 name
= input_line_pointer
;
3708 c
= get_symbol_end ();
3709 p
= input_line_pointer
;
3710 symbolP
= symbol_find_or_make (name
);
3713 if (*input_line_pointer
!= ',')
3716 as_warn ("Expected comma after name \"%s\"", name
);
3719 ignore_rest_of_line ();
3723 input_line_pointer
++;
3724 temp
= get_absolute_expression ();
3726 /* symbolP->sy_other = (signed char) temp; */
3727 as_warn ("unhandled: .proc %s,%d", name
, temp
);
3728 demand_empty_rest_of_line ();
3731 /* Handle the .set pseudo op. This is used to turn on and off most of
3732 the assembler features. */
3738 char *name
= input_line_pointer
, ch
, *s
;
3741 while (!is_end_of_line
[(unsigned char) *input_line_pointer
])
3742 input_line_pointer
++;
3743 ch
= *input_line_pointer
;
3744 *input_line_pointer
= '\0';
3747 if (s
[0] == 'n' && s
[1] == 'o')
3752 if (!strcmp ("reorder", s
))
3754 else if (!strcmp ("at", s
))
3755 alpha_noat_on
= !yesno
;
3756 else if (!strcmp ("macro", s
))
3757 alpha_macros_on
= yesno
;
3758 else if (!strcmp ("move", s
))
3760 else if (!strcmp ("volatile", s
))
3763 as_warn ("Tried to .set unrecognized mode `%s'", name
);
3765 *input_line_pointer
= ch
;
3766 demand_empty_rest_of_line ();
3769 /* Handle the .base pseudo op. This changes the assembler's notion of
3770 the $gp register. */
3773 s_alpha_base (ignore
)
3777 if (first_32bit_quadrant
)
3779 /* not fatal, but it might not work in the end */
3780 as_warn ("File overrides no-base-register option.");
3781 first_32bit_quadrant
= 0;
3786 if (*input_line_pointer
== '$')
3788 input_line_pointer
++;
3789 if (*input_line_pointer
== 'r')
3790 input_line_pointer
++;
3793 alpha_gp_register
= get_absolute_expression ();
3794 if (alpha_gp_register
< 0 || alpha_gp_register
> 31)
3796 alpha_gp_register
= AXP_REG_GP
;
3797 as_warn ("Bad base register, using $%d.", alpha_gp_register
);
3800 demand_empty_rest_of_line ();
3803 /* Handle the .align pseudo-op. This aligns to a power of two. It
3804 also adjusts any current instruction label. We treat this the same
3805 way the MIPS port does: .align 0 turns off auto alignment. */
3808 s_alpha_align (ignore
)
3813 long max_alignment
= 15;
3815 align
= get_absolute_expression ();
3816 if (align
> max_alignment
)
3818 align
= max_alignment
;
3819 as_bad ("Alignment too large: %d. assumed", align
);
3823 as_warn ("Alignment negative: 0 assumed");
3827 if (*input_line_pointer
== ',')
3829 input_line_pointer
++;
3830 fill
= get_absolute_expression ();
3838 alpha_auto_align_on
= 1;
3839 alpha_align (align
, pfill
, alpha_insn_label
);
3843 alpha_auto_align_on
= 0;
3846 demand_empty_rest_of_line ();
3849 /* Hook the normal string processor to reset known alignment. */
3852 s_alpha_stringer (terminate
)
3855 alpha_current_align
= 0;
3856 alpha_insn_label
= NULL
;
3857 stringer (terminate
);
3860 /* Hook the normal space processing to reset known alignment. */
3863 s_alpha_space (ignore
)
3866 alpha_current_align
= 0;
3867 alpha_insn_label
= NULL
;
3871 /* Hook into cons for auto-alignment. */
3874 alpha_cons_align (size
)
3880 while ((size
>>= 1) != 0)
3883 if (alpha_auto_align_on
&& alpha_current_align
< log_size
)
3884 alpha_align (log_size
, (char *) NULL
, alpha_insn_label
);
3885 if (alpha_current_align
> log_size
)
3886 alpha_current_align
= log_size
;
3887 alpha_insn_label
= NULL
;
3890 /* The target specific pseudo-ops which we support. */
3892 const pseudo_typeS md_pseudo_table
[] =
3894 {"common", s_comm
, 0}, /* is this used? */
3896 {"comm", s_alpha_comm
, 0}, /* osf1 compiler does this */
3898 {"text", s_alpha_text
, 0},
3899 {"data", s_alpha_data
, 0},
3900 #if defined (OBJ_ECOFF) || defined (OBJ_EVAX)
3901 {"rdata", s_alpha_rdata
, 0},
3904 {"sdata", s_alpha_sdata
, 0},
3907 {"section", s_alpha_section
, 0},
3908 {"section.s", s_alpha_section
, 0},
3909 {"sect", s_alpha_section
, 0},
3910 {"sect.s", s_alpha_section
, 0},
3913 { "pdesc", s_alpha_pdesc
, 0},
3914 { "linkage", s_alpha_linkage
, 0},
3915 { "ent", s_alpha_ent
, 0},
3916 { "frame", s_alpha_frame
, 0},
3917 { "fp_save", s_alpha_fp_save
, 0},
3918 { "mask", s_alpha_mask
, 0},
3919 { "fmask", s_alpha_fmask
, 0},
3920 { "link", s_alpha_link
, 0},
3921 { "end", s_alpha_end
, 0},
3922 { "file", s_alpha_file
, 0},
3924 {"gprel32", s_alpha_gprel32
, 0},
3925 {"t_floating", s_alpha_float_cons
, 'd'},
3926 {"s_floating", s_alpha_float_cons
, 'f'},
3927 {"f_floating", s_alpha_float_cons
, 'F'},
3928 {"g_floating", s_alpha_float_cons
, 'G'},
3929 {"d_floating", s_alpha_float_cons
, 'D'},
3931 {"proc", s_alpha_proc
, 0},
3932 {"aproc", s_alpha_proc
, 1},
3933 {"set", s_alpha_set
, 0},
3934 {"reguse", s_ignore
, 0},
3935 {"livereg", s_ignore
, 0},
3936 {"base", s_alpha_base
, 0}, /*??*/
3937 {"option", s_ignore
, 0},
3938 {"prologue", s_ignore
, 0},
3939 {"aent", s_ignore
, 0},
3940 {"ugen", s_ignore
, 0},
3941 {"eflag", s_ignore
, 0},
3943 {"align", s_alpha_align
, 0},
3944 {"double", s_alpha_float_cons
, 'd'},
3945 {"float", s_alpha_float_cons
, 'f'},
3946 {"single", s_alpha_float_cons
, 'f'},
3947 {"ascii", s_alpha_stringer
, 0},
3948 {"asciz", s_alpha_stringer
, 1},
3949 {"string", s_alpha_stringer
, 1},
3950 {"space", s_alpha_space
, 0},
3951 {"skip", s_alpha_space
, 0},
3952 {"zero", s_alpha_space
, 0},
3954 /* We don't do any optimizing, so we can safely ignore these. */
3955 {"noalias", s_ignore
, 0},
3956 {"alias", s_ignore
, 0},
3962 /* Build a BFD section with its flags set appropriately for the .lita,
3963 .lit8, or .lit4 sections. */
3966 create_literal_section (name
, secp
, symp
)
3971 segT current_section
= now_seg
;
3972 int current_subsec
= now_subseg
;
3975 *secp
= new_sec
= subseg_new (name
, 0);
3976 subseg_set (current_section
, current_subsec
);
3977 bfd_set_section_alignment (stdoutput
, new_sec
, 4);
3978 bfd_set_section_flags (stdoutput
, new_sec
,
3979 SEC_RELOC
| SEC_ALLOC
| SEC_LOAD
| SEC_READONLY
3982 S_CLEAR_EXTERNAL (*symp
= section_symbol (new_sec
));
3987 /* @@@ GP selection voodoo. All of this seems overly complicated and
3988 unnecessary; which is the primary reason it's for ECOFF only. */
3997 vma
= bfd_get_section_vma (foo
, sec
);
3998 if (vma
&& vma
< alpha_gp_value
)
3999 alpha_gp_value
= vma
;
4005 assert (alpha_gp_value
== 0);
4007 /* Get minus-one in whatever width... */
4008 alpha_gp_value
= 0; alpha_gp_value
--;
4010 /* Select the smallest VMA of these existing sections. */
4011 maybe_set_gp (alpha_lita_section
);
4013 /* These were disabled before -- should we use them? */
4014 maybe_set_gp (sdata
);
4015 maybe_set_gp (lit8_sec
);
4016 maybe_set_gp (lit4_sec
);
4019 /* @@ Will a simple 0x8000 work here? If not, why not? */
4020 #define GP_ADJUSTMENT (0x8000 - 0x10)
4022 alpha_gp_value
+= GP_ADJUSTMENT
;
4024 S_SET_VALUE (alpha_gp_symbol
, alpha_gp_value
);
4027 printf ("Chose GP value of %lx\n", alpha_gp_value
);
4030 #endif /* OBJ_ECOFF */
4032 /* Called internally to handle all alignment needs. This takes care
4033 of eliding calls to frag_align if'n the cached current alignment
4034 says we've already got it, as well as taking care of the auto-align
4035 feature wrt labels. */
4038 alpha_align (n
, pfill
, label
)
4043 if (alpha_current_align
>= n
)
4049 && (bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
) != 0)
4051 static char const nop
[4] = { 0x1f, 0x04, 0xff, 0x47 };
4053 /* First, make sure we're on a four-byte boundary, in case
4054 someone has been putting .byte values into the text
4055 section. The DEC assembler silently fills with unaligned
4056 no-op instructions. This will zero-fill, then nop-fill
4057 with proper alignment. */
4058 if (alpha_current_align
< 2)
4060 frag_align_pattern (n
, nop
, sizeof nop
);
4066 frag_align (n
, *pfill
);
4068 alpha_current_align
= n
;
4072 assert (S_GET_SEGMENT (label
) == now_seg
);
4073 label
->sy_frag
= frag_now
;
4074 S_SET_VALUE (label
, (valueT
) frag_now_fix ());
4077 record_alignment(now_seg
, n
);
4080 /* The Alpha has support for some VAX floating point types, as well as for
4081 IEEE floating point. We consider IEEE to be the primary floating point
4082 format, and sneak in the VAX floating point support here. */
4083 #define md_atof vax_md_atof
4084 #include "config/atof-vax.c"