1 /* tc-alpha.c - Processor-specific code for the DEC Alpha AXP CPU.
2 Copyright (C) 1989, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
3 Contributed by Carnegie Mellon University, 1993.
4 Written by Alessandro Forin, based on earlier gas-1.38 target CPU files.
5 Modified by Ken Raeburn for gas-2.x and ECOFF support.
6 Modified by Richard Henderson for ELF support.
7 Modified by Klaus K"ampf for EVAX (openVMS/Alpha) support.
9 This file is part of GAS, the GNU Assembler.
11 GAS is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2, or (at your option)
16 GAS is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with GAS; see the file COPYING. If not, write to the Free
23 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
27 * Mach Operating System
28 * Copyright (c) 1993 Carnegie Mellon University
29 * All Rights Reserved.
31 * Permission to use, copy, modify and distribute this software and its
32 * documentation is hereby granted, provided that both the copyright
33 * notice and this permission notice appear in all copies of the
34 * software, derivative works or modified versions, and any portions
35 * thereof, and that both notices appear in supporting documentation.
37 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
38 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
39 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
41 * Carnegie Mellon requests users of this software to return to
43 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
44 * School of Computer Science
45 * Carnegie Mellon University
46 * Pittsburgh PA 15213-3890
48 * any improvements or extensions that they make and grant Carnegie the
49 * rights to redistribute these changes.
55 #include "opcode/alpha.h"
58 #include "elf/alpha.h"
66 #define MAX_INSN_FIXUPS 2
67 #define MAX_INSN_ARGS 5
72 bfd_reloc_code_real_type reloc
;
79 struct alpha_fixup fixups
[MAX_INSN_FIXUPS
];
84 MACRO_EOA
= 1, MACRO_IR
, MACRO_PIR
, MACRO_CPIR
, MACRO_FPR
, MACRO_EXP
90 void (*emit
) PARAMS ((const expressionS
*, int, const PTR
));
92 enum alpha_macro_arg argsets
[16];
95 /* Two extra symbols we want to see in our input. This is a blatent
96 misuse of the expressionS.X_op field. */
98 #define O_pregister (O_max+1) /* O_register, but in parentheses */
99 #define O_cpregister (O_pregister+1) /* + a leading comma */
101 /* Macros for extracting the type and number of encoded register tokens */
103 #define is_ir_num(x) (((x) & 32) == 0)
104 #define is_fpr_num(x) (((x) & 32) != 0)
105 #define regno(x) ((x) & 31)
107 /* Something odd inherited from the old assembler */
109 #define note_gpreg(R) (alpha_gprmask |= (1 << (R)))
110 #define note_fpreg(R) (alpha_fprmask |= (1 << (R)))
112 /* Predicates for 16- and 32-bit ranges */
114 #define range_signed_16(x) ((offsetT)(x) >= -(offsetT)0x8000 && \
115 (offsetT)(x) <= (offsetT)0x7FFF)
116 #define range_signed_32(x) ((offsetT)(x) >= -(offsetT)0x80000000 && \
117 (offsetT)(x) <= (offsetT)0x7FFFFFFF)
119 /* Macros for sign extending from 16- and 32-bits. */
120 /* XXX: The cast macros will work on all the systems that I care about,
121 but really a predicate should be found to use the non-cast forms. */
124 #define sign_extend_16(x) ((short)(x))
125 #define sign_extend_32(x) ((int)(x))
127 #define sign_extend_16(x) ((offsetT)(((x) & 0xFFFF) ^ 0x8000) - 0x8000)
128 #define sign_extend_32(x) ((offsetT)(((x) & 0xFFFFFFFF) \
129 ^ 0x80000000) - 0x80000000)
132 /* Macros to build tokens */
134 #define set_tok_reg(t, r) (memset(&(t), 0, sizeof(t)), \
135 (t).X_op = O_register, \
136 (t).X_add_number = (r))
137 #define set_tok_preg(t, r) (memset(&(t), 0, sizeof(t)), \
138 (t).X_op = O_pregister, \
139 (t).X_add_number = (r))
140 #define set_tok_cpreg(t, r) (memset(&(t), 0, sizeof(t)), \
141 (t).X_op = O_cpregister, \
142 (t).X_add_number = (r))
143 #define set_tok_freg(t, r) (memset(&(t), 0, sizeof(t)), \
144 (t).X_op = O_register, \
145 (t).X_add_number = (r)+32)
146 #define set_tok_sym(t, s, a) (memset(&(t), 0, sizeof(t)), \
147 (t).X_op = O_symbol, \
148 (t).X_add_symbol = (s), \
149 (t).X_add_number = (a))
150 #define set_tok_const(t, n) (memset(&(t), 0, sizeof(t)), \
151 (t).X_op = O_constant, \
152 (t).X_add_number = (n))
155 /* Prototypes for all local functions */
157 static int tokenize_arguments
PARAMS ((char *, expressionS
*, int));
158 static const struct alpha_opcode
*find_opcode_match
159 PARAMS ((const struct alpha_opcode
*, const expressionS
*, int *, int *));
160 static const struct alpha_macro
*find_macro_match
161 PARAMS ((const struct alpha_macro
*, const expressionS
*, int *));
162 static unsigned insert_operand
163 PARAMS ((unsigned, const struct alpha_operand
*, offsetT
, char *, unsigned));
164 static void assemble_insn
165 PARAMS ((const struct alpha_opcode
*, const expressionS
*, int,
166 struct alpha_insn
*));
167 static void emit_insn
PARAMS ((struct alpha_insn
*));
168 static void assemble_tokens_to_insn
169 PARAMS ((const char *, const expressionS
*, int, struct alpha_insn
*));
170 static void assemble_tokens
171 PARAMS ((const char *, const expressionS
*, int, int));
173 static int load_expression
174 PARAMS ((int, const expressionS
*, int *, expressionS
*));
176 static void emit_ldgp
PARAMS ((const expressionS
*, int, const PTR
));
177 static void emit_division
PARAMS ((const expressionS
*, int, const PTR
));
178 static void emit_lda
PARAMS ((const expressionS
*, int, const PTR
));
179 static void emit_ldah
PARAMS ((const expressionS
*, int, const PTR
));
180 static void emit_ir_load
PARAMS ((const expressionS
*, int, const PTR
));
181 static void emit_loadstore
PARAMS ((const expressionS
*, int, const PTR
));
182 static void emit_jsrjmp
PARAMS ((const expressionS
*, int, const PTR
));
183 static void emit_ldX
PARAMS ((const expressionS
*, int, const PTR
));
184 static void emit_ldXu
PARAMS ((const expressionS
*, int, const PTR
));
185 static void emit_uldX
PARAMS ((const expressionS
*, int, const PTR
));
186 static void emit_uldXu
PARAMS ((const expressionS
*, int, const PTR
));
187 static void emit_ldil
PARAMS ((const expressionS
*, int, const PTR
));
188 static void emit_stX
PARAMS ((const expressionS
*, int, const PTR
));
189 static void emit_ustX
PARAMS ((const expressionS
*, int, const PTR
));
190 static void emit_sextX
PARAMS ((const expressionS
*, int, const PTR
));
191 static void emit_retjcr
PARAMS ((const expressionS
*, int, const PTR
));
193 static void s_alpha_text
PARAMS ((int));
194 static void s_alpha_data
PARAMS ((int));
196 static void s_alpha_comm
PARAMS ((int));
198 #if defined (OBJ_ECOFF) || defined (OBJ_EVAX)
199 static void s_alpha_rdata
PARAMS ((int));
202 static void s_alpha_sdata
PARAMS ((int));
205 static void s_alpha_section
PARAMS ((int));
208 static void s_alpha_section
PARAMS ((int));
210 static void s_alpha_gprel32
PARAMS ((int));
211 static void s_alpha_float_cons
PARAMS ((int));
212 static void s_alpha_proc
PARAMS ((int));
213 static void s_alpha_set
PARAMS ((int));
214 static void s_alpha_base
PARAMS ((int));
215 static void s_alpha_align
PARAMS ((int));
216 static void s_alpha_stringer
PARAMS ((int));
217 static void s_alpha_space
PARAMS ((int));
219 static void create_literal_section
PARAMS ((const char *, segT
*, symbolS
**));
221 static void select_gp_value
PARAMS ((void));
223 static void alpha_align
PARAMS ((int, char *, symbolS
*));
226 /* Generic assembler global variables which must be defined by all
229 /* These are exported to relaxing code, even though we don't do any
230 relaxing on this processor currently. */
231 int md_short_jump_size
= 4;
232 int md_long_jump_size
= 4;
234 /* Characters which always start a comment. */
235 const char comment_chars
[] = "#";
237 /* Characters which start a comment at the beginning of a line. */
238 const char line_comment_chars
[] = "#";
240 /* Characters which may be used to separate multiple commands on a
242 const char line_separator_chars
[] = ";";
244 /* Characters which are used to indicate an exponent in a floating
246 const char EXP_CHARS
[] = "eE";
248 /* Characters which mean that a number is a floating point constant,
251 const char FLT_CHARS
[] = "dD";
253 /* XXX: Do all of these really get used on the alpha?? */
254 char FLT_CHARS
[] = "rRsSfFdDxXpP";
258 const char *md_shortopts
= "Fm:g+1h:H";
260 const char *md_shortopts
= "Fm:g";
263 struct option md_longopts
[] = {
264 #define OPTION_32ADDR (OPTION_MD_BASE)
265 { "32addr", no_argument
, NULL
, OPTION_32ADDR
},
266 { NULL
, no_argument
, NULL
, 0 }
269 size_t md_longopts_size
= sizeof(md_longopts
);
274 #define AXP_REG_R16 16
275 #define AXP_REG_R17 17
277 #define AXP_REG_T9 22
279 #define AXP_REG_T10 23
281 #define AXP_REG_T11 24
283 #define AXP_REG_T12 25
284 #define AXP_REG_AI 25
286 #define AXP_REG_FP 29
289 #define AXP_REG_GP AXP_REG_PV
290 #endif /* OBJ_EVAX */
292 /* The cpu for which we are generating code */
293 static unsigned alpha_target
= AXP_OPCODE_BASE
;
294 static const char *alpha_target_name
= "<all>";
296 /* The hash table of instruction opcodes */
297 static struct hash_control
*alpha_opcode_hash
;
299 /* The hash table of macro opcodes */
300 static struct hash_control
*alpha_macro_hash
;
303 /* The $gp relocation symbol */
304 static symbolS
*alpha_gp_symbol
;
306 /* XXX: what is this, and why is it exported? */
307 valueT alpha_gp_value
;
310 /* The current $gp register */
311 static int alpha_gp_register
= AXP_REG_GP
;
313 /* A table of the register symbols */
314 static symbolS
*alpha_register_table
[64];
316 /* Constant sections, or sections of constants */
318 static segT alpha_lita_section
;
319 static segT alpha_lit4_section
;
322 static segT alpha_link_section
;
323 static segT alpha_ctors_section
;
324 static segT alpha_dtors_section
;
326 static segT alpha_lit8_section
;
328 /* Symbols referring to said sections. */
330 static symbolS
*alpha_lita_symbol
;
331 static symbolS
*alpha_lit4_symbol
;
334 static symbolS
*alpha_link_symbol
;
335 static symbolS
*alpha_ctors_symbol
;
336 static symbolS
*alpha_dtors_symbol
;
338 static symbolS
*alpha_lit8_symbol
;
340 /* Literal for .litX+0x8000 within .lita */
342 static offsetT alpha_lit4_literal
;
343 static offsetT alpha_lit8_literal
;
346 /* Is the assembler not allowed to use $at? */
347 static int alpha_noat_on
= 0;
349 /* Are macros enabled? */
350 static int alpha_macros_on
= 1;
352 /* Are floats disabled? */
353 static int alpha_nofloats_on
= 0;
355 /* Are addresses 32 bit? */
356 static int alpha_addr32_on
= 0;
358 /* Symbol labelling the current insn. When the Alpha gas sees
361 and the section happens to not be on an eight byte boundary, it
362 will align both the symbol and the .quad to an eight byte boundary. */
363 static symbolS
*alpha_insn_label
;
365 /* Whether we should automatically align data generation pseudo-ops.
366 .align 0 will turn this off. */
367 static int alpha_auto_align_on
= 1;
369 /* The known current alignment of the current section. */
370 static int alpha_current_align
;
372 /* These are exported to ECOFF code. */
373 unsigned long alpha_gprmask
, alpha_fprmask
;
375 /* Whether the debugging option was seen. */
376 static int alpha_debug
;
379 /* Collect information about current procedure here. */
381 symbolS
*symbol
; /* proc pdesc symbol */
383 int framereg
; /* register for frame pointer */
384 int framesize
; /* size of frame */
394 static int alpha_flag_hash_long_names
= 0; /* -+ */
395 static int alpha_flag_show_after_trunc
= 0; /* -H */
397 /* If the -+ switch is given, then a hash is appended to any name that is
398 * longer than 64 characters, else longer symbol names are truncated.
401 static int alpha_basereg_clobbered
;
404 /* The macro table */
406 static const struct alpha_macro alpha_macros
[] = {
407 /* Load/Store macros */
408 { "lda", emit_lda
, NULL
,
409 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
410 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
411 { "ldah", emit_ldah
, NULL
,
412 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
414 { "ldl", emit_ir_load
, "ldl",
415 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
416 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
417 { "ldl_l", emit_ir_load
, "ldl_l",
418 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
419 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
420 { "ldq", emit_ir_load
, "ldq",
421 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
422 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
423 { "ldq_l", emit_ir_load
, "ldq_l",
424 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
425 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
426 { "ldq_u", emit_ir_load
, "ldq_u",
427 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
428 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
429 { "ldf", emit_loadstore
, "ldf",
430 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
431 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
432 { "ldg", emit_loadstore
, "ldg",
433 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
434 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
435 { "lds", emit_loadstore
, "lds",
436 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
437 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
438 { "ldt", emit_loadstore
, "ldt",
439 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
440 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
442 { "ldb", emit_ldX
, (PTR
)0,
443 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
444 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
445 { "ldbu", emit_ldXu
, (PTR
)0,
446 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
447 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
448 { "ldw", emit_ldX
, (PTR
)1,
449 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
450 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
451 { "ldwu", emit_ldXu
, (PTR
)1,
452 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
453 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
455 { "uldw", emit_uldX
, (PTR
)1,
456 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
457 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
458 { "uldwu", emit_uldXu
, (PTR
)1,
459 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
460 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
461 { "uldl", emit_uldX
, (PTR
)2,
462 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
463 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
464 { "uldlu", emit_uldXu
, (PTR
)2,
465 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
466 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
467 { "uldq", emit_uldXu
, (PTR
)3,
468 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
469 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
471 { "ldgp", emit_ldgp
, NULL
,
472 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
} },
474 { "ldi", emit_lda
, NULL
,
475 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
476 { "ldil", emit_ldil
, NULL
,
477 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
478 { "ldiq", emit_lda
, NULL
,
479 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
481 { "ldif" emit_ldiq
, NULL
,
482 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
483 { "ldid" emit_ldiq
, NULL
,
484 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
485 { "ldig" emit_ldiq
, NULL
,
486 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
487 { "ldis" emit_ldiq
, NULL
,
488 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
489 { "ldit" emit_ldiq
, NULL
,
490 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
493 { "stl", emit_loadstore
, "stl",
494 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
495 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
496 { "stl_c", emit_loadstore
, "stl_c",
497 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
498 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
499 { "stq", emit_loadstore
, "stq",
500 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
501 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
502 { "stq_c", emit_loadstore
, "stq_c",
503 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
504 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
505 { "stq_u", emit_loadstore
, "stq_u",
506 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
507 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
508 { "stf", emit_loadstore
, "stf",
509 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
510 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
511 { "stg", emit_loadstore
, "stg",
512 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
513 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
514 { "sts", emit_loadstore
, "sts",
515 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
516 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
517 { "stt", emit_loadstore
, "stt",
518 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
519 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
521 { "stb", emit_stX
, (PTR
)0,
522 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
523 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
524 { "stw", emit_stX
, (PTR
)1,
525 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
526 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
527 { "ustw", emit_ustX
, (PTR
)1,
528 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
529 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
530 { "ustl", emit_ustX
, (PTR
)2,
531 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
532 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
533 { "ustq", emit_ustX
, (PTR
)3,
534 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
535 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
537 /* Arithmetic macros */
539 { "absl" emit_absl
, 1, { IR
} },
540 { "absl" emit_absl
, 2, { IR
, IR
} },
541 { "absl" emit_absl
, 2, { EXP
, IR
} },
542 { "absq" emit_absq
, 1, { IR
} },
543 { "absq" emit_absq
, 2, { IR
, IR
} },
544 { "absq" emit_absq
, 2, { EXP
, IR
} },
547 { "sextb", emit_sextX
, (PTR
)0,
548 { MACRO_IR
, MACRO_IR
, MACRO_EOA
,
550 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
551 { "sextw", emit_sextX
, (PTR
)1,
552 { MACRO_IR
, MACRO_IR
, MACRO_EOA
,
554 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
556 { "divl", emit_division
, "__divl",
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 { "divlu", emit_division
, "__divlu",
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 { "divq", emit_division
, "__divq",
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 { "divqu", emit_division
, "__divqu",
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 { "reml", emit_division
, "__reml",
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 { "remlu", emit_division
, "__remlu",
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 { "remq", emit_division
, "__remq",
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 */ } },
591 { "remqu", emit_division
, "__remqu",
592 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
593 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
594 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
595 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
597 { "jsr", emit_jsrjmp
, "jsr",
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 { "jmp", emit_jsrjmp
, "jmp",
603 { MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
604 MACRO_PIR
, MACRO_EOA
,
605 MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
606 MACRO_EXP
, MACRO_EOA
} },
607 { "ret", emit_retjcr
, "ret",
608 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
610 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
611 MACRO_PIR
, MACRO_EOA
,
612 MACRO_EXP
, MACRO_EOA
,
614 { "jcr", emit_retjcr
, "jcr",
615 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
617 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
618 MACRO_PIR
, MACRO_EOA
,
619 MACRO_EXP
, MACRO_EOA
,
621 { "jsr_coroutine", emit_retjcr
, "jcr",
622 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
624 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
625 MACRO_PIR
, MACRO_EOA
,
626 MACRO_EXP
, MACRO_EOA
,
630 static const int alpha_num_macros
631 = sizeof(alpha_macros
) / sizeof(*alpha_macros
);
633 /* Public interface functions */
635 /* This function is called once, at assembler startup time. It sets
636 up all the tables, etc. that the MD part of the assembler will
637 need, that can be determined before arguments are parsed. */
644 /* Create the opcode hash table */
646 alpha_opcode_hash
= hash_new ();
647 for (i
= 0; i
< alpha_num_opcodes
; )
649 const char *name
, *retval
;
651 name
= alpha_opcodes
[i
].name
;
652 retval
= hash_insert (alpha_opcode_hash
, name
, (PTR
)&alpha_opcodes
[i
]);
654 as_fatal ("internal error: can't hash opcode `%s': %s", name
, retval
);
656 while (++i
< alpha_num_opcodes
657 && (alpha_opcodes
[i
].name
== name
658 || !strcmp (alpha_opcodes
[i
].name
, name
)))
662 /* Some opcodes include modifiers of various sorts with a "/mod" syntax,
663 like the architecture manual suggests. However, for use with gcc at
664 least, we also need access to those same opcodes without the "/". */
665 for (i
= 0; i
< alpha_num_opcodes
; )
667 const char *name
, *slash
;
668 name
= alpha_opcodes
[i
].name
;
669 if ((slash
= strchr(name
, '/')) != NULL
)
671 char *p
= xmalloc (strlen (name
));
672 memcpy(p
, name
, slash
-name
);
673 strcpy(p
+(slash
-name
), slash
+1);
675 (void)hash_insert(alpha_opcode_hash
, p
, (PTR
)&alpha_opcodes
[i
]);
676 /* Ignore failures -- the opcode table does duplicate some
677 variants in different forms, like "hw_stq" and "hw_st/q". */
680 while (++i
< alpha_num_opcodes
681 && (alpha_opcodes
[i
].name
== name
682 || !strcmp (alpha_opcodes
[i
].name
, name
)))
686 /* Create the macro hash table */
688 alpha_macro_hash
= hash_new ();
689 for (i
= 0; i
< alpha_num_macros
; )
691 const char *name
, *retval
;
693 name
= alpha_macros
[i
].name
;
694 retval
= hash_insert (alpha_macro_hash
, name
, (PTR
)&alpha_macros
[i
]);
696 as_fatal ("internal error: can't hash macro `%s': %s", name
, retval
);
698 while (++i
< alpha_num_macros
699 && (alpha_macros
[i
].name
== name
700 || !strcmp (alpha_macros
[i
].name
, name
)))
704 /* Construct symbols for each of the registers */
706 for (i
= 0; i
< 32; ++i
)
709 sprintf(name
, "$%d", i
);
710 alpha_register_table
[i
] = symbol_create(name
, reg_section
, i
,
716 sprintf(name
, "$f%d", i
-32);
717 alpha_register_table
[i
] = symbol_create(name
, reg_section
, i
,
721 /* Create the special symbols and sections we'll be using */
723 /* So .sbss will get used for tiny objects. */
724 bfd_set_gp_size (stdoutput
, 8);
727 create_literal_section (".lita", &alpha_lita_section
, &alpha_lita_symbol
);
729 /* For handling the GP, create a symbol that won't be output in the
730 symbol table. We'll edit it out of relocs later. */
731 alpha_gp_symbol
= symbol_create ("<GP value>", alpha_lita_section
, 0x8000,
736 create_literal_section (".link", &alpha_link_section
, &alpha_link_symbol
);
744 sec
= subseg_new(".mdebug", (subsegT
)0);
745 bfd_set_section_flags(stdoutput
, sec
, SEC_HAS_CONTENTS
|SEC_READONLY
);
746 bfd_set_section_alignment(stdoutput
, sec
, 3);
749 sec
= subseg_new(".reginfo", (subsegT
)0);
750 /* The ABI says this section should be loaded so that the running
751 program can access it. */
752 bfd_set_section_flags(stdoutput
, sec
,
753 SEC_ALLOC
|SEC_LOAD
|SEC_READONLY
|SEC_DATA
);
754 bfd_set_section_alignement(stdoutput
, sec
, 3);
759 subseg_set(text_section
, 0);
762 /* The public interface to the instruction assembler. */
768 char opname
[32]; /* current maximum is 13 */
769 expressionS tok
[MAX_INSN_ARGS
];
770 int ntok
, opnamelen
, trunclen
;
772 /* split off the opcode */
773 opnamelen
= strspn (str
, "abcdefghijklmnopqrstuvwxyz_/48");
774 trunclen
= (opnamelen
< sizeof (opname
) - 1
776 : sizeof (opname
) - 1);
777 memcpy (opname
, str
, trunclen
);
778 opname
[trunclen
] = '\0';
780 /* tokenize the rest of the line */
781 if ((ntok
= tokenize_arguments (str
+ opnamelen
, tok
, MAX_INSN_ARGS
)) < 0)
783 as_bad ("syntax error");
788 assemble_tokens (opname
, tok
, ntok
, alpha_macros_on
);
791 /* Round up a section's size to the appropriate boundary. */
794 md_section_align (seg
, size
)
798 int align
= bfd_get_section_alignment(stdoutput
, seg
);
799 valueT mask
= ((valueT
)1 << align
) - 1;
801 return (size
+ mask
) & ~mask
;
804 /* Turn a string in input_line_pointer into a floating point constant
805 of type type, and store the appropriate bytes in *litP. The number
806 of LITTLENUMS emitted is stored in *sizeP. An error message is
807 returned, or NULL on OK. */
809 /* Equal to MAX_PRECISION in atof-ieee.c */
810 #define MAX_LITTLENUMS 6
812 extern char *vax_md_atof
PARAMS ((int, char *, int *));
815 md_atof (type
, litP
, sizeP
)
821 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
822 LITTLENUM_TYPE
*wordP
;
829 /* VAX md_atof doesn't like "G" for some reason. */
833 return vax_md_atof (type
, litP
, sizeP
);
856 return "Bad call to MD_ATOF()";
858 t
= atof_ieee (input_line_pointer
, type
, words
);
860 input_line_pointer
= t
;
861 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
863 for (wordP
= words
+ prec
- 1; prec
--;)
865 md_number_to_chars (litP
, (long) (*wordP
--), sizeof (LITTLENUM_TYPE
));
866 litP
+= sizeof (LITTLENUM_TYPE
);
872 /* Take care of the target-specific command-line options. */
875 md_parse_option (c
, arg
)
882 alpha_nofloats_on
= 1;
895 static const struct machine
901 { "21064", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
902 { "21064a", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
903 { "21066", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
904 { "21068", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
905 { "21164", AXP_OPCODE_BASE
|AXP_OPCODE_EV5
},
906 /* Do we have CIX extension here? */
907 { "21164a", AXP_OPCODE_BASE
|AXP_OPCODE_EV5
|AXP_OPCODE_BWX
},
908 /* Still same PALcodes? */
909 { "21164pc", (AXP_OPCODE_BASE
|AXP_OPCODE_EV5
|AXP_OPCODE_BWX
910 |AXP_OPCODE_CIX
|AXP_OPCODE_MAX
) },
911 /* All new PALcodes? Extras? */
912 { "21264", (AXP_OPCODE_BASE
|AXP_OPCODE_BWX
913 |AXP_OPCODE_CIX
|AXP_OPCODE_MAX
) },
915 { "ev4", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
916 { "ev45", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
917 { "lca45", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
918 { "ev5", AXP_OPCODE_BASE
|AXP_OPCODE_EV5
},
919 { "ev56", AXP_OPCODE_BASE
|AXP_OPCODE_EV5
|AXP_OPCODE_BWX
},
920 { "pca56", (AXP_OPCODE_BASE
|AXP_OPCODE_EV5
|AXP_OPCODE_BWX
921 |AXP_OPCODE_CIX
|AXP_OPCODE_MAX
) },
922 { "ev6", (AXP_OPCODE_BASE
|AXP_OPCODE_BWX
923 |AXP_OPCODE_CIX
|AXP_OPCODE_MAX
) },
925 { "all", AXP_OPCODE_BASE
},
929 for (p
= m
; p
->name
; ++p
)
930 if (strcmp(arg
, p
->name
) == 0)
932 alpha_target_name
= p
->name
, alpha_target
= p
->flags
;
935 as_warn("Unknown CPU identifier `%s'", arg
);
941 case '+': /* For g++. Hash any name > 63 chars long. */
942 alpha_flag_hash_long_names
= 1;
945 case 'H': /* Show new symbol after hash truncation */
946 alpha_flag_show_after_trunc
= 1;
949 case 'h': /* for gnu-c/vax compatibility. */
960 /* Print a description of the command-line options that we accept. */
963 md_show_usage (stream
)
968 -32addr treat addresses as 32-bit values\n\
969 -F lack floating point instructions support\n\
970 -m21064 | -m21066 | -m21164 | -m21164a\n\
971 -mev4 | -mev45 | -mev5 | -mev56 | -mall\n\
972 specify variant of Alpha architecture\n",
977 -+ hash encode (don't truncate) names longer than 64 characters\n\
978 -H show new symbol after hash truncation\n",
983 /* Decide from what point a pc-relative relocation is relative to,
984 relative to the pc-relative fixup. Er, relatively speaking. */
990 valueT addr
= fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
991 switch (fixP
->fx_r_type
)
993 case BFD_RELOC_ALPHA_GPDISP
:
994 case BFD_RELOC_ALPHA_GPDISP_HI16
:
995 case BFD_RELOC_ALPHA_GPDISP_LO16
:
998 return fixP
->fx_size
+ addr
;
1002 /* Attempt to simplify or even eliminate a fixup. The return value is
1003 ignored; perhaps it was once meaningful, but now it is historical.
1004 To indicate that a fixup has been eliminated, set fixP->fx_done.
1006 For ELF, here it is that we transform the GPDISP_HI16 reloc we used
1007 internally into the GPDISP reloc used externally. We had to do
1008 this so that we'd have the GPDISP_LO16 reloc as a tag to compute
1009 the distance to the "lda" instruction for setting the addend to
1013 md_apply_fix (fixP
, valueP
)
1017 char * const fixpos
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
1018 valueT value
= *valueP
;
1019 unsigned image
, size
;
1021 switch (fixP
->fx_r_type
)
1023 /* The GPDISP relocations are processed internally with a symbol
1024 referring to the current function; we need to drop in a value
1025 which, when added to the address of the start of the function,
1026 gives the desired GP. */
1027 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1029 fixS
*next
= fixP
->fx_next
;
1030 assert (next
->fx_r_type
== BFD_RELOC_ALPHA_GPDISP_LO16
);
1032 fixP
->fx_offset
= (next
->fx_frag
->fr_address
+ next
->fx_where
1033 - fixP
->fx_frag
->fr_address
- fixP
->fx_where
);
1035 value
= (value
- sign_extend_16 (value
)) >> 16;
1038 fixP
->fx_r_type
= BFD_RELOC_ALPHA_GPDISP
;
1042 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1043 value
= sign_extend_16 (value
);
1044 fixP
->fx_offset
= 0;
1050 fixP
->fx_addsy
= section_symbol (absolute_section
);
1051 md_number_to_chars (fixpos
, value
, 2);
1063 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
1065 md_number_to_chars (fixpos
, value
, size
);
1071 case BFD_RELOC_GPREL32
:
1072 assert (fixP
->fx_subsy
== alpha_gp_symbol
);
1074 /* FIXME: inherited this obliviousness of `value' -- why? */
1075 md_number_to_chars (fixpos
, -alpha_gp_value
, 4);
1079 case BFD_RELOC_GPREL32
:
1083 case BFD_RELOC_23_PCREL_S2
:
1084 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
1086 image
= bfd_getl32(fixpos
);
1087 image
= (image
& ~0x1FFFFF) | ((value
>> 2) & 0x1FFFFF);
1092 case BFD_RELOC_ALPHA_HINT
:
1093 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
1095 image
= bfd_getl32(fixpos
);
1096 image
= (image
& ~0x3FFF) | ((value
>> 2) & 0x3FFF);
1102 case BFD_RELOC_ALPHA_LITERAL
:
1103 md_number_to_chars (fixpos
, value
, 2);
1106 case BFD_RELOC_ALPHA_LITUSE
:
1110 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1111 case BFD_RELOC_ALPHA_LITUSE
:
1115 case BFD_RELOC_ALPHA_LINKAGE
:
1116 case BFD_RELOC_ALPHA_CODEADDR
:
1122 const struct alpha_operand
*operand
;
1124 if ((int)fixP
->fx_r_type
>= 0)
1125 as_fatal ("unhandled relocation type %s",
1126 bfd_get_reloc_code_name (fixP
->fx_r_type
));
1128 assert (-(int)fixP
->fx_r_type
< alpha_num_operands
);
1129 operand
= &alpha_operands
[-(int)fixP
->fx_r_type
];
1131 /* The rest of these fixups only exist internally during symbol
1132 resolution and have no representation in the object file.
1133 Therefore they must be completely resolved as constants. */
1135 if (fixP
->fx_addsy
!= 0
1136 && fixP
->fx_addsy
->bsym
->section
!= absolute_section
)
1137 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
1138 "non-absolute expression in constant field");
1140 image
= bfd_getl32(fixpos
);
1141 image
= insert_operand(image
, operand
, (offsetT
)value
,
1142 fixP
->fx_file
, fixP
->fx_line
);
1147 if (fixP
->fx_addsy
!= 0 || fixP
->fx_pcrel
!= 0)
1151 as_warn_where(fixP
->fx_file
, fixP
->fx_line
,
1152 "type %d reloc done?\n", (int)fixP
->fx_r_type
);
1157 md_number_to_chars(fixpos
, image
, 4);
1165 * Look for a register name in the given symbol.
1169 md_undefined_symbol(name
)
1174 int is_float
= 0, num
;
1179 if (name
[1] == 'p' && name
[2] == '\0')
1180 return alpha_register_table
[AXP_REG_FP
];
1185 if (!isdigit(*++name
))
1189 case '0': case '1': case '2': case '3': case '4':
1190 case '5': case '6': case '7': case '8': case '9':
1191 if (name
[1] == '\0')
1192 num
= name
[0] - '0';
1193 else if (name
[0] != '0' && isdigit(name
[1]) && name
[2] == '\0')
1195 num
= (name
[0] - '0') * 10 + name
[1] - '0';
1202 if (!alpha_noat_on
&& num
== AXP_REG_AT
)
1203 as_warn("Used $at without \".set noat\"");
1204 return alpha_register_table
[num
+ is_float
];
1207 if (name
[1] == 't' && name
[2] == '\0')
1210 as_warn("Used $at without \".set noat\"");
1211 return alpha_register_table
[AXP_REG_AT
];
1216 if (name
[1] == 'p' && name
[2] == '\0')
1217 return alpha_register_table
[alpha_gp_register
];
1221 if (name
[1] == 'p' && name
[2] == '\0')
1222 return alpha_register_table
[AXP_REG_SP
];
1230 /* @@@ Magic ECOFF bits. */
1233 alpha_frob_ecoff_data ()
1236 /* $zero and $f31 are read-only */
1237 alpha_gprmask
&= ~1;
1238 alpha_fprmask
&= ~1;
1242 /* Hook to remember a recently defined label so that the auto-align
1243 code can adjust the symbol after we know what alignment will be
1247 alpha_define_label (sym
)
1250 alpha_insn_label
= sym
;
1253 /* Return true if we must always emit a reloc for a type and false if
1254 there is some hope of resolving it a assembly time. */
1257 alpha_force_relocation (f
)
1260 switch (f
->fx_r_type
)
1262 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1263 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1264 case BFD_RELOC_ALPHA_GPDISP
:
1266 case BFD_RELOC_ALPHA_LITERAL
:
1269 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1271 case BFD_RELOC_ALPHA_LITUSE
:
1272 case BFD_RELOC_GPREL32
:
1274 case BFD_RELOC_ALPHA_LINKAGE
:
1275 case BFD_RELOC_ALPHA_CODEADDR
:
1279 case BFD_RELOC_23_PCREL_S2
:
1282 case BFD_RELOC_ALPHA_HINT
:
1286 assert((int)f
->fx_r_type
< 0 && -(int)f
->fx_r_type
< alpha_num_operands
);
1291 /* Return true if we can partially resolve a relocation now. */
1294 alpha_fix_adjustable (f
)
1298 /* Prevent all adjustments to global symbols */
1299 if (S_IS_EXTERN (f
->fx_addsy
))
1303 /* Are there any relocation types for which we must generate a reloc
1304 but we can adjust the values contained within it? */
1305 switch (f
->fx_r_type
)
1307 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1308 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1309 case BFD_RELOC_ALPHA_GPDISP
:
1313 case BFD_RELOC_ALPHA_LITERAL
:
1316 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1319 case BFD_RELOC_ALPHA_LINKAGE
:
1320 case BFD_RELOC_ALPHA_CODEADDR
:
1324 case BFD_RELOC_ALPHA_LITUSE
:
1327 case BFD_RELOC_GPREL32
:
1328 case BFD_RELOC_23_PCREL_S2
:
1331 case BFD_RELOC_ALPHA_HINT
:
1335 assert ((int)f
->fx_r_type
< 0
1336 && - (int)f
->fx_r_type
< alpha_num_operands
);
1342 /* Generate the BFD reloc to be stuck in the object file from the
1343 fixup used internally in the assembler. */
1346 tc_gen_reloc (sec
, fixp
)
1352 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
1353 reloc
->sym_ptr_ptr
= &fixp
->fx_addsy
->bsym
;
1354 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
1356 /* Make sure none of our internal relocations make it this far.
1357 They'd better have been fully resolved by this point. */
1358 assert ((int)fixp
->fx_r_type
> 0);
1360 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
1361 if (reloc
->howto
== NULL
)
1363 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1364 "cannot represent `%s' relocation in object file",
1365 bfd_get_reloc_code_name (fixp
->fx_r_type
));
1369 if (!fixp
->fx_pcrel
!= !reloc
->howto
->pc_relative
)
1371 as_fatal ("internal error? cannot generate `%s' relocation",
1372 bfd_get_reloc_code_name (fixp
->fx_r_type
));
1374 assert (!fixp
->fx_pcrel
== !reloc
->howto
->pc_relative
);
1377 if (fixp
->fx_r_type
== BFD_RELOC_ALPHA_LITERAL
)
1379 /* fake out bfd_perform_relocation. sigh */
1380 reloc
->addend
= -alpha_gp_value
;
1385 reloc
->addend
= fixp
->fx_offset
;
1388 * Ohhh, this is ugly. The problem is that if this is a local global
1389 * symbol, the relocation will entirely be performed at link time, not
1390 * at assembly time. bfd_perform_reloc doesn't know about this sort
1391 * of thing, and as a result we need to fake it out here.
1393 if (S_IS_EXTERN (fixp
->fx_addsy
) && !S_IS_COMMON(fixp
->fx_addsy
))
1394 reloc
->addend
-= fixp
->fx_addsy
->bsym
->value
;
1401 /* Parse a register name off of the input_line and return a register
1402 number. Gets md_undefined_symbol above to do the register name
1405 Only called as a part of processing the ECOFF .frame directive. */
1408 tc_get_register (frame
)
1411 int framereg
= AXP_REG_SP
;
1414 if (*input_line_pointer
== '$')
1416 char *s
= input_line_pointer
;
1417 char c
= get_symbol_end ();
1418 symbolS
*sym
= md_undefined_symbol (s
);
1420 *strchr(s
, '\0') = c
;
1421 if (sym
&& (framereg
= S_GET_VALUE (sym
)) <= 31)
1424 as_warn ("frame reg expected, using $%d.", framereg
);
1427 note_gpreg (framereg
);
1431 /* This is called before the symbol table is processed. In order to
1432 work with gcc when using mips-tfile, we must keep all local labels.
1433 However, in other cases, we want to discard them. If we were
1434 called with -g, but we didn't see any debugging information, it may
1435 mean that gcc is smuggling debugging information through to
1436 mips-tfile, in which case we must generate all local labels. */
1441 alpha_frob_file_before_adjust ()
1443 if (alpha_debug
!= 0
1444 && ! ecoff_debugging_seen
)
1445 flag_keep_locals
= 1;
1448 #endif /* OBJ_ECOFF */
1450 /* Parse the arguments to an opcode. */
1453 tokenize_arguments (str
, tok
, ntok
)
1458 expressionS
*end_tok
= tok
+ ntok
;
1459 char *old_input_line_pointer
;
1460 int saw_comma
= 0, saw_arg
= 0;
1462 memset (tok
, 0, sizeof (*tok
) * ntok
);
1464 /* Save and restore input_line_pointer around this function */
1465 old_input_line_pointer
= input_line_pointer
;
1466 input_line_pointer
= str
;
1468 while (tok
< end_tok
&& *input_line_pointer
)
1471 switch (*input_line_pointer
)
1477 ++input_line_pointer
;
1478 if (saw_comma
|| !saw_arg
)
1485 char *hold
= input_line_pointer
++;
1487 /* First try for parenthesized register ... */
1489 if (*input_line_pointer
== ')' && tok
->X_op
== O_register
)
1491 tok
->X_op
= (saw_comma
? O_cpregister
: O_pregister
);
1494 ++input_line_pointer
;
1499 /* ... then fall through to plain expression */
1500 input_line_pointer
= hold
;
1504 if (saw_arg
&& !saw_comma
)
1507 if (tok
->X_op
== O_illegal
|| tok
->X_op
== O_absent
)
1520 input_line_pointer
= old_input_line_pointer
;
1521 return ntok
- (end_tok
- tok
);
1524 input_line_pointer
= old_input_line_pointer
;
1528 /* Search forward through all variants of an opcode looking for a
1531 static const struct alpha_opcode
*
1532 find_opcode_match(first_opcode
, tok
, pntok
, pcpumatch
)
1533 const struct alpha_opcode
*first_opcode
;
1534 const expressionS
*tok
;
1538 const struct alpha_opcode
*opcode
= first_opcode
;
1540 int got_cpu_match
= 0;
1544 const unsigned char *opidx
;
1547 /* Don't match opcodes that don't exist on this architecture */
1548 if (!(opcode
->flags
& alpha_target
))
1553 for (opidx
= opcode
->operands
; *opidx
; ++opidx
)
1555 const struct alpha_operand
*operand
= &alpha_operands
[*opidx
];
1557 /* only take input from real operands */
1558 if (operand
->flags
& AXP_OPERAND_FAKE
)
1561 /* when we expect input, make sure we have it */
1564 if ((operand
->flags
& AXP_OPERAND_OPTIONAL_MASK
) == 0)
1569 /* match operand type with expression type */
1570 switch (operand
->flags
& AXP_OPERAND_TYPECHECK_MASK
)
1572 case AXP_OPERAND_IR
:
1573 if (tok
[tokidx
].X_op
!= O_register
1574 || !is_ir_num(tok
[tokidx
].X_add_number
))
1577 case AXP_OPERAND_FPR
:
1578 if (tok
[tokidx
].X_op
!= O_register
1579 || !is_fpr_num(tok
[tokidx
].X_add_number
))
1582 case AXP_OPERAND_IR
|AXP_OPERAND_PARENS
:
1583 if (tok
[tokidx
].X_op
!= O_pregister
1584 || !is_ir_num(tok
[tokidx
].X_add_number
))
1587 case AXP_OPERAND_IR
|AXP_OPERAND_PARENS
|AXP_OPERAND_COMMA
:
1588 if (tok
[tokidx
].X_op
!= O_cpregister
1589 || !is_ir_num(tok
[tokidx
].X_add_number
))
1593 case AXP_OPERAND_RELATIVE
:
1594 case AXP_OPERAND_SIGNED
:
1595 case AXP_OPERAND_UNSIGNED
:
1596 switch (tok
[tokidx
].X_op
)
1608 /* everything else should have been fake */
1614 /* possible match -- did we use all of our input? */
1623 while (++opcode
-alpha_opcodes
< alpha_num_opcodes
1624 && !strcmp(opcode
->name
, first_opcode
->name
));
1627 *pcpumatch
= got_cpu_match
;
1632 /* Search forward through all variants of a macro looking for a syntax
1635 static const struct alpha_macro
*
1636 find_macro_match(first_macro
, tok
, pntok
)
1637 const struct alpha_macro
*first_macro
;
1638 const expressionS
*tok
;
1641 const struct alpha_macro
*macro
= first_macro
;
1646 const enum alpha_macro_arg
*arg
= macro
->argsets
;
1661 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_register
1662 || !is_ir_num(tok
[tokidx
].X_add_number
))
1667 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_pregister
1668 || !is_ir_num(tok
[tokidx
].X_add_number
))
1673 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_cpregister
1674 || !is_ir_num(tok
[tokidx
].X_add_number
))
1679 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_register
1680 || !is_fpr_num(tok
[tokidx
].X_add_number
))
1688 switch (tok
[tokidx
].X_op
)
1701 while (*arg
!= MACRO_EOA
)
1709 while (++macro
-alpha_macros
< alpha_num_macros
1710 && !strcmp(macro
->name
, first_macro
->name
));
1715 /* Insert an operand value into an instruction. */
1718 insert_operand(insn
, operand
, val
, file
, line
)
1720 const struct alpha_operand
*operand
;
1725 if (operand
->bits
!= 32 && !(operand
->flags
& AXP_OPERAND_NOOVERFLOW
))
1729 if (operand
->flags
& AXP_OPERAND_SIGNED
)
1731 max
= (1 << (operand
->bits
- 1)) - 1;
1732 min
= -(1 << (operand
->bits
- 1));
1736 max
= (1 << operand
->bits
) - 1;
1740 if (val
< min
|| val
> max
)
1743 "operand out of range (%s not between %d and %d)";
1744 char buf
[sizeof (val
) * 3 + 2];
1746 sprint_value(buf
, val
);
1748 as_warn_where(file
, line
, err
, buf
, min
, max
);
1750 as_warn(err
, buf
, min
, max
);
1754 if (operand
->insert
)
1756 const char *errmsg
= NULL
;
1758 insn
= (*operand
->insert
) (insn
, val
, &errmsg
);
1763 insn
|= ((val
& ((1 << operand
->bits
) - 1)) << operand
->shift
);
1769 * Turn an opcode description and a set of arguments into
1770 * an instruction and a fixup.
1774 assemble_insn(opcode
, tok
, ntok
, insn
)
1775 const struct alpha_opcode
*opcode
;
1776 const expressionS
*tok
;
1778 struct alpha_insn
*insn
;
1780 const unsigned char *argidx
;
1784 memset (insn
, 0, sizeof (*insn
));
1785 image
= opcode
->opcode
;
1787 for (argidx
= opcode
->operands
; *argidx
; ++argidx
)
1789 const struct alpha_operand
*operand
= &alpha_operands
[*argidx
];
1790 const expressionS
*t
;
1792 if (operand
->flags
& AXP_OPERAND_FAKE
)
1794 /* fake operands take no value and generate no fixup */
1795 image
= insert_operand(image
, operand
, 0, NULL
, 0);
1801 switch (operand
->flags
& AXP_OPERAND_OPTIONAL_MASK
)
1803 case AXP_OPERAND_DEFAULT_FIRST
:
1806 case AXP_OPERAND_DEFAULT_SECOND
:
1809 case AXP_OPERAND_DEFAULT_ZERO
:
1811 static const expressionS zero_exp
= { 0, 0, 0, O_constant
, 1 };
1827 image
= insert_operand(image
, operand
, regno(t
->X_add_number
),
1832 image
= insert_operand(image
, operand
, t
->X_add_number
, NULL
, 0);
1837 struct alpha_fixup
*fixup
;
1839 if (insn
->nfixups
>= MAX_INSN_FIXUPS
)
1840 as_fatal("too many fixups");
1842 fixup
= &insn
->fixups
[insn
->nfixups
++];
1845 fixup
->reloc
= operand
->default_reloc
;
1855 * Actually output an instruction with its fixup.
1860 struct alpha_insn
*insn
;
1865 /* Take care of alignment duties */
1866 if (alpha_auto_align_on
&& alpha_current_align
< 2)
1867 alpha_align (2, (char *) NULL
, alpha_insn_label
);
1868 if (alpha_current_align
> 2)
1869 alpha_current_align
= 2;
1870 alpha_insn_label
= NULL
;
1872 /* Write out the instruction. */
1874 md_number_to_chars (f
, insn
->insn
, 4);
1876 /* Apply the fixups in order */
1877 for (i
= 0; i
< insn
->nfixups
; ++i
)
1879 struct alpha_fixup
*fixup
= &insn
->fixups
[i
];
1883 /* Some fixups are only used internally and so have no howto */
1884 if ((int)fixup
->reloc
< 0)
1885 size
= 4, pcrel
= 0;
1887 /* These relocation types are only used internally. */
1888 else if (fixup
->reloc
== BFD_RELOC_ALPHA_GPDISP_HI16
1889 || fixup
->reloc
== BFD_RELOC_ALPHA_GPDISP_LO16
)
1891 size
= 2, pcrel
= 0;
1896 reloc_howto_type
*reloc_howto
1897 = bfd_reloc_type_lookup (stdoutput
, fixup
->reloc
);
1898 assert (reloc_howto
);
1900 size
= bfd_get_reloc_size (reloc_howto
);
1901 pcrel
= reloc_howto
->pc_relative
;
1903 assert (size
>= 1 && size
<= 4);
1905 fixP
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, size
,
1906 &fixup
->exp
, pcrel
, fixup
->reloc
);
1908 /* Turn off complaints that the addend is too large for some fixups */
1909 switch (fixup
->reloc
)
1911 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1913 case BFD_RELOC_ALPHA_LITERAL
:
1916 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1918 case BFD_RELOC_GPREL32
:
1919 fixP
->fx_no_overflow
= 1;
1927 /* Given an opcode name and a pre-tokenized set of arguments, assemble
1928 the insn, but do not emit it.
1930 Note that this implies no macros allowed, since we can't store more
1931 than one insn in an insn structure. */
1934 assemble_tokens_to_insn(opname
, tok
, ntok
, insn
)
1936 const expressionS
*tok
;
1938 struct alpha_insn
*insn
;
1940 const struct alpha_opcode
*opcode
;
1942 /* search opcodes */
1943 opcode
= (const struct alpha_opcode
*) hash_find (alpha_opcode_hash
, opname
);
1947 opcode
= find_opcode_match (opcode
, tok
, &ntok
, &cpumatch
);
1950 assemble_insn (opcode
, tok
, ntok
, insn
);
1954 as_bad ("inappropriate arguments for opcode `%s'", opname
);
1956 as_bad ("opcode `%s' not supported for target %s", opname
,
1960 as_bad ("unknown opcode `%s'", opname
);
1963 /* Given an opcode name and a pre-tokenized set of arguments, take the
1964 opcode all the way through emission. */
1967 assemble_tokens (opname
, tok
, ntok
, local_macros_on
)
1969 const expressionS
*tok
;
1971 int local_macros_on
;
1973 int found_something
= 0;
1974 const struct alpha_opcode
*opcode
;
1975 const struct alpha_macro
*macro
;
1979 if (local_macros_on
)
1981 macro
= ((const struct alpha_macro
*)
1982 hash_find (alpha_macro_hash
, opname
));
1985 found_something
= 1;
1986 macro
= find_macro_match (macro
, tok
, &ntok
);
1989 (*macro
->emit
) (tok
, ntok
, macro
->arg
);
1995 /* search opcodes */
1996 opcode
= (const struct alpha_opcode
*) hash_find (alpha_opcode_hash
, opname
);
1999 found_something
= 1;
2000 opcode
= find_opcode_match (opcode
, tok
, &ntok
, &cpumatch
);
2003 struct alpha_insn insn
;
2004 assemble_insn (opcode
, tok
, ntok
, &insn
);
2010 if (found_something
)
2012 as_bad ("inappropriate arguments for opcode `%s'", opname
);
2014 as_bad ("opcode `%s' not supported for target %s", opname
,
2017 as_bad ("unknown opcode `%s'", opname
);
2021 /* Some instruction sets indexed by lg(size) */
2022 static const char * const sextX_op
[] = { "sextb", "sextw", "sextl", NULL
};
2023 static const char * const insXl_op
[] = { "insbl", "inswl", "insll", "insql" };
2024 static const char * const insXh_op
[] = { NULL
, "inswh", "inslh", "insqh" };
2025 static const char * const extXl_op
[] = { "extbl", "extwl", "extll", "extql" };
2026 static const char * const extXh_op
[] = { NULL
, "extwh", "extlh", "extqh" };
2027 static const char * const mskXl_op
[] = { "mskbl", "mskwl", "mskll", "mskql" };
2028 static const char * const mskXh_op
[] = { NULL
, "mskwh", "msklh", "mskqh" };
2029 static const char * const stX_op
[] = { "stb", "stw", "stl", "stq" };
2030 static const char * const ldX_op
[] = { "ldb", "ldw", "ldll", "ldq" };
2031 static const char * const ldXu_op
[] = { "ldbu", "ldwu", NULL
, NULL
};
2033 /* Implement the ldgp macro. */
2036 emit_ldgp (tok
, ntok
, unused
)
2037 const expressionS
*tok
;
2044 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
2045 /* from "ldgp r1,n(r2)", generate "ldah r1,X(R2); lda r1,Y(r1)"
2046 with appropriate constants and relocations. */
2047 struct alpha_insn insn
;
2048 expressionS newtok
[3];
2051 /* We're going to need this symbol in md_apply_fix(). */
2052 (void) section_symbol (absolute_section
);
2055 if (regno (tok
[2].X_add_number
) == AXP_REG_PV
)
2056 ecoff_set_gp_prolog_size (0);
2060 set_tok_const (newtok
[1], 0);
2063 assemble_tokens_to_insn ("ldah", newtok
, 3, &insn
);
2068 assert (addend
.X_op
== O_constant
);
2069 addend
.X_op
= O_symbol
;
2070 addend
.X_add_symbol
= alpha_gp_symbol
;
2074 insn
.fixups
[0].exp
= addend
;
2075 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_GPDISP_HI16
;
2079 set_tok_preg (newtok
[2], tok
[0].X_add_number
);
2081 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
2084 addend
.X_add_number
+= 4;
2088 insn
.fixups
[0].exp
= addend
;
2089 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_GPDISP_LO16
;
2092 #endif /* OBJ_ECOFF || OBJ_ELF */
2097 /* Add symbol+addend to link pool.
2098 Return offset from basesym to entry in link pool.
2100 Add new fixup only if offset isn't 16bit. */
2103 add_to_link_pool (basesym
, sym
, addend
)
2108 segT current_section
= now_seg
;
2109 int current_subsec
= now_subseg
;
2111 bfd_reloc_code_real_type reloc_type
;
2113 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
2116 offset
= -basesym
->sy_obj
;
2118 /* @@ This assumes all entries in a given section will be of the same
2119 size... Probably correct, but unwise to rely on. */
2120 /* This must always be called with the same subsegment. */
2122 if (seginfo
->frchainP
)
2123 for (fixp
= seginfo
->frchainP
->fix_root
;
2124 fixp
!= (fixS
*) NULL
;
2125 fixp
= fixp
->fx_next
, offset
+= 8)
2127 if (fixp
->fx_addsy
== sym
&& fixp
->fx_offset
== addend
)
2129 if (range_signed_16 (offset
))
2136 /* Not found in 16bit signed range. */
2138 subseg_set (alpha_link_section
, 0);
2142 fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, sym
, addend
, 0,
2145 subseg_set (current_section
, current_subsec
);
2146 seginfo
->literal_pool_size
+= 8;
2150 #endif /* OBJ_EVAX */
2152 /* Load a (partial) expression into a target register.
2154 If poffset is not null, after the call it will either contain
2155 O_constant 0, or a 16-bit offset appropriate for any MEM format
2156 instruction. In addition, pbasereg will be modified to point to
2157 the base register to use in that MEM format instruction.
2159 In any case, *pbasereg should contain a base register to add to the
2160 expression. This will normally be either AXP_REG_ZERO or
2161 alpha_gp_register. Symbol addresses will always be loaded via $gp,
2162 so "foo($0)" is interpreted as adding the address of foo to $0;
2163 i.e. "ldq $targ, LIT($gp); addq $targ, $0, $targ". Odd, perhaps,
2164 but this is what OSF/1 does.
2166 Finally, the return value is true if the calling macro may emit a
2167 LITUSE reloc if otherwise appropriate. */
2170 load_expression (targreg
, exp
, pbasereg
, poffset
)
2172 const expressionS
*exp
;
2174 expressionS
*poffset
;
2176 int emit_lituse
= 0;
2177 offsetT addend
= exp
->X_add_number
;
2178 int basereg
= *pbasereg
;
2179 struct alpha_insn insn
;
2180 expressionS newtok
[3];
2189 /* attempt to reduce .lit load by splitting the offset from
2190 its symbol when possible, but don't create a situation in
2192 if (!range_signed_32 (addend
) &&
2193 (alpha_noat_on
|| targreg
== AXP_REG_AT
))
2195 lit
= add_to_literal_pool (exp
->X_add_symbol
, addend
,
2196 alpha_lita_section
, 8);
2201 lit
= add_to_literal_pool (exp
->X_add_symbol
, 0,
2202 alpha_lita_section
, 8);
2206 as_fatal ("overflow in literal (.lita) table");
2208 /* emit "ldq r, lit(gp)" */
2210 if (basereg
!= alpha_gp_register
&& targreg
== basereg
)
2213 as_bad ("macro requires $at register while noat in effect");
2214 if (targreg
== AXP_REG_AT
)
2215 as_bad ("macro requires $at while $at in use");
2217 set_tok_reg (newtok
[0], AXP_REG_AT
);
2220 set_tok_reg (newtok
[0], targreg
);
2221 set_tok_sym (newtok
[1], alpha_lita_symbol
, lit
);
2222 set_tok_preg (newtok
[2], alpha_gp_register
);
2224 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
2226 assert (insn
.nfixups
== 1);
2227 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITERAL
;
2228 #endif /* OBJ_ECOFF */
2230 /* emit "ldq r, gotoff(gp)" */
2232 if (basereg
!= alpha_gp_register
&& targreg
== basereg
)
2235 as_bad ("macro requires $at register while noat in effect");
2236 if (targreg
== AXP_REG_AT
)
2237 as_bad ("macro requires $at while $at in use");
2239 set_tok_reg (newtok
[0], AXP_REG_AT
);
2242 set_tok_reg (newtok
[0], targreg
);
2244 if (!range_signed_32 (addend
)
2245 && (alpha_noat_on
|| targreg
== AXP_REG_AT
))
2252 set_tok_sym (newtok
[1], exp
->X_add_symbol
, 0);
2255 set_tok_preg (newtok
[2], alpha_gp_register
);
2257 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
2259 assert (insn
.nfixups
== 1);
2260 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_ELF_LITERAL
;
2261 #endif /* OBJ_ELF */
2265 if (alpha_basereg_clobbered
)
2267 /* no basereg, reload basreg from 0(FP). */
2268 set_tok_reg (newtok
[0], targreg
);
2269 set_tok_const (newtok
[1], 0);
2270 set_tok_preg (newtok
[2], AXP_REG_FP
);
2272 assemble_tokens ("ldq", newtok
, 3, 0);
2275 /* Find symbol or symbol pointer in link section. */
2277 if (exp
->X_add_symbol
== alpha_evax_proc
.symbol
)
2279 if (range_signed_16 (addend
))
2281 set_tok_reg (newtok
[0], targreg
);
2282 set_tok_const (newtok
[1], addend
);
2283 set_tok_preg (newtok
[2], basereg
);
2284 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
2289 set_tok_reg (newtok
[0], targreg
);
2290 set_tok_const (newtok
[1], 0);
2291 set_tok_preg (newtok
[2], basereg
);
2292 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
2297 if (!range_signed_32 (addend
))
2299 link
= add_to_link_pool (alpha_evax_proc
.symbol
,
2300 exp
->X_add_symbol
, addend
);
2305 link
= add_to_link_pool (alpha_evax_proc
.symbol
,
2306 exp
->X_add_symbol
, 0);
2308 set_tok_reg (newtok
[0], targreg
);
2309 set_tok_const (newtok
[1], link
);
2310 set_tok_preg (newtok
[2], basereg
);
2311 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
2313 #endif /* OBJ_EVAX */
2320 if (basereg
!= alpha_gp_register
&& basereg
!= AXP_REG_ZERO
)
2322 /* emit "addq r, base, r" */
2324 set_tok_reg (newtok
[1], basereg
);
2325 set_tok_reg (newtok
[2], targreg
);
2326 assemble_tokens ("addq", newtok
, 3, 0);
2338 /* Assume that this difference expression will be resolved to an
2339 absolute value and that that value will fit in 16 bits. */
2341 set_tok_reg (newtok
[0], targreg
);
2343 set_tok_preg (newtok
[2], basereg
);
2344 assemble_tokens ("lda", newtok
, 3, 0);
2347 set_tok_const (*poffset
, 0);
2351 as_bad ("%s number invalid; zero assumed",
2352 exp
->X_add_number
> 0 ? "bignum" : "floating point");
2360 if (!range_signed_32 (addend
))
2364 /* for 64-bit addends, just put it in the literal pool */
2367 /* emit "ldq targreg, lit(basereg)" */
2368 lit
= add_to_link_pool (alpha_evax_proc
.symbol
,
2369 section_symbol (absolute_section
), addend
);
2370 set_tok_reg (newtok
[0], targreg
);
2371 set_tok_const (newtok
[1], lit
);
2372 set_tok_preg (newtok
[2], alpha_gp_register
);
2373 assemble_tokens ("ldq", newtok
, 3, 0);
2376 if (alpha_lit8_section
== NULL
)
2378 create_literal_section (".lit8",
2379 &alpha_lit8_section
,
2380 &alpha_lit8_symbol
);
2383 alpha_lit8_literal
= add_to_literal_pool (alpha_lit8_symbol
, 0x8000,
2384 alpha_lita_section
, 8);
2385 if (alpha_lit8_literal
>= 0x8000)
2386 as_fatal ("overflow in literal (.lita) table");
2390 lit
= add_to_literal_pool (NULL
, addend
, alpha_lit8_section
, 8) - 0x8000;
2392 as_fatal ("overflow in literal (.lit8) table");
2394 /* emit "lda litreg, .lit8+0x8000" */
2396 if (targreg
== basereg
)
2399 as_bad ("macro requires $at register while noat in effect");
2400 if (targreg
== AXP_REG_AT
)
2401 as_bad ("macro requires $at while $at in use");
2403 set_tok_reg (newtok
[0], AXP_REG_AT
);
2406 set_tok_reg (newtok
[0], targreg
);
2408 set_tok_sym (newtok
[1], alpha_lita_symbol
, alpha_lit8_literal
);
2411 set_tok_sym (newtok
[1], alpha_lit8_symbol
, 0x8000);
2413 set_tok_preg (newtok
[2], alpha_gp_register
);
2415 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
2417 assert (insn
.nfixups
== 1);
2419 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITERAL
;
2422 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_ELF_LITERAL
;
2427 /* emit "ldq litreg, lit(litreg)" */
2429 set_tok_const (newtok
[1], lit
);
2430 set_tok_preg (newtok
[2], newtok
[0].X_add_number
);
2432 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
2434 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
2435 if (insn
.nfixups
> 0)
2437 memmove (&insn
.fixups
[1], &insn
.fixups
[0],
2438 sizeof(struct alpha_fixup
) * insn
.nfixups
);
2441 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITUSE
;
2442 insn
.fixups
[0].exp
.X_op
= O_constant
;
2443 insn
.fixups
[0].exp
.X_add_number
= 1;
2448 /* emit "addq litreg, base, target" */
2450 if (basereg
!= AXP_REG_ZERO
)
2452 set_tok_reg (newtok
[1], basereg
);
2453 set_tok_reg (newtok
[2], targreg
);
2454 assemble_tokens ("addq", newtok
, 3, 0);
2456 #endif /* !OBJ_EVAX */
2459 set_tok_const (*poffset
, 0);
2460 *pbasereg
= targreg
;
2464 offsetT low
, high
, extra
, tmp
;
2466 /* for 32-bit operands, break up the addend */
2468 low
= sign_extend_16 (addend
);
2470 high
= sign_extend_16 (tmp
>> 16);
2472 if (tmp
- (high
<< 16))
2476 high
= sign_extend_16 (tmp
>> 16);
2481 set_tok_reg (newtok
[0], targreg
);
2482 set_tok_preg (newtok
[2], basereg
);
2486 /* emit "ldah r, extra(r) */
2487 set_tok_const (newtok
[1], extra
);
2488 assemble_tokens ("ldah", newtok
, 3, 0);
2489 set_tok_preg (newtok
[2], basereg
= targreg
);
2494 /* emit "ldah r, high(r) */
2495 set_tok_const (newtok
[1], high
);
2496 assemble_tokens ("ldah", newtok
, 3, 0);
2498 set_tok_preg (newtok
[2], basereg
);
2501 if ((low
&& !poffset
) || (!poffset
&& basereg
!= targreg
))
2503 /* emit "lda r, low(base)" */
2504 set_tok_const (newtok
[1], low
);
2505 assemble_tokens ("lda", newtok
, 3, 0);
2511 set_tok_const (*poffset
, low
);
2512 *pbasereg
= basereg
;
2518 /* The lda macro differs from the lda instruction in that it handles
2519 most simple expressions, particualrly symbol address loads and
2523 emit_lda (tok
, ntok
, unused
)
2524 const expressionS
*tok
;
2531 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
2533 basereg
= tok
[2].X_add_number
;
2535 (void) load_expression (tok
[0].X_add_number
, &tok
[1], &basereg
, NULL
);
2538 /* The ldah macro differs from the ldah instruction in that it has $31
2539 as an implied base register. */
2542 emit_ldah (tok
, ntok
, unused
)
2543 const expressionS
*tok
;
2547 expressionS newtok
[3];
2551 set_tok_preg (newtok
[2], AXP_REG_ZERO
);
2553 assemble_tokens ("ldah", newtok
, 3, 0);
2556 /* Handle all "simple" integer register loads -- ldq, ldq_l, ldq_u,
2557 etc. They differ from the real instructions in that they do simple
2558 expressions like the lda macro. */
2561 emit_ir_load (tok
, ntok
, opname
)
2562 const expressionS
*tok
;
2566 int basereg
, lituse
;
2567 expressionS newtok
[3];
2568 struct alpha_insn insn
;
2571 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
2573 basereg
= tok
[2].X_add_number
;
2575 lituse
= load_expression (tok
[0].X_add_number
, &tok
[1], &basereg
,
2579 set_tok_preg (newtok
[2], basereg
);
2581 assemble_tokens_to_insn ((const char *)opname
, newtok
, 3, &insn
);
2585 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
2586 if (insn
.nfixups
> 0)
2588 memmove (&insn
.fixups
[1], &insn
.fixups
[0],
2589 sizeof(struct alpha_fixup
) * insn
.nfixups
);
2592 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITUSE
;
2593 insn
.fixups
[0].exp
.X_op
= O_constant
;
2594 insn
.fixups
[0].exp
.X_add_number
= 1;
2599 /* special hack. If the basereg is clobbered for a call
2600 all lda's before the call don't have a basereg. */
2601 if ((tok
[0].X_op
== O_register
)
2602 && (tok
[0].X_add_number
== alpha_gp_register
))
2604 alpha_basereg_clobbered
= 1;
2609 /* Handle fp register loads, and both integer and fp register stores.
2610 Again, we handle simple expressions. */
2613 emit_loadstore (tok
, ntok
, opname
)
2614 const expressionS
*tok
;
2618 int basereg
, lituse
;
2619 expressionS newtok
[3];
2620 struct alpha_insn insn
;
2623 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
2625 basereg
= tok
[2].X_add_number
;
2627 if (tok
[1].X_op
!= O_constant
|| !range_signed_16(tok
[1].X_add_number
))
2630 as_bad ("macro requires $at register while noat in effect");
2632 lituse
= load_expression (AXP_REG_AT
, &tok
[1], &basereg
, &newtok
[1]);
2641 set_tok_preg (newtok
[2], basereg
);
2643 assemble_tokens_to_insn ((const char *)opname
, newtok
, 3, &insn
);
2647 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
2648 if (insn
.nfixups
> 0)
2650 memmove (&insn
.fixups
[1], &insn
.fixups
[0],
2651 sizeof(struct alpha_fixup
) * insn
.nfixups
);
2654 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITUSE
;
2655 insn
.fixups
[0].exp
.X_op
= O_constant
;
2656 insn
.fixups
[0].exp
.X_add_number
= 1;
2662 /* Load a half-word or byte as an unsigned value. */
2665 emit_ldXu (tok
, ntok
, vlgsize
)
2666 const expressionS
*tok
;
2670 if (alpha_target
& AXP_OPCODE_BWX
)
2671 emit_ir_load (tok
, ntok
, ldXu_op
[(long)vlgsize
]);
2674 expressionS newtok
[3];
2677 as_bad ("macro requires $at register while noat in effect");
2679 /* emit "lda $at, exp" */
2681 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
2682 newtok
[0].X_add_number
= AXP_REG_AT
;
2683 assemble_tokens ("lda", newtok
, ntok
, 1);
2685 /* emit "ldq_u targ, 0($at)" */
2688 set_tok_const (newtok
[1], 0);
2689 set_tok_preg (newtok
[2], AXP_REG_AT
);
2690 assemble_tokens ("ldq_u", newtok
, 3, 1);
2692 /* emit "extXl targ, $at, targ" */
2694 set_tok_reg (newtok
[1], AXP_REG_AT
);
2695 newtok
[2] = newtok
[0];
2696 assemble_tokens (extXl_op
[(long)vlgsize
], newtok
, 3, 1);
2700 /* Load a half-word or byte as a signed value. */
2703 emit_ldX (tok
, ntok
, vlgsize
)
2704 const expressionS
*tok
;
2708 emit_ldXu (tok
, ntok
, vlgsize
);
2709 assemble_tokens (sextX_op
[(long)vlgsize
], tok
, 1, 1);
2712 /* Load an integral value from an unaligned address as an unsigned
2716 emit_uldXu (tok
, ntok
, vlgsize
)
2717 const expressionS
*tok
;
2721 long lgsize
= (long)vlgsize
;
2722 expressionS newtok
[3];
2725 as_bad ("macro requires $at register while noat in effect");
2727 /* emit "lda $at, exp" */
2729 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
2730 newtok
[0].X_add_number
= AXP_REG_AT
;
2731 assemble_tokens ("lda", newtok
, ntok
, 1);
2733 /* emit "ldq_u $t9, 0($at)" */
2735 set_tok_reg (newtok
[0], AXP_REG_T9
);
2736 set_tok_const (newtok
[1], 0);
2737 set_tok_preg (newtok
[2], AXP_REG_AT
);
2738 assemble_tokens ("ldq_u", newtok
, 3, 1);
2740 /* emit "ldq_u $t10, size-1($at)" */
2742 set_tok_reg (newtok
[0], AXP_REG_T10
);
2743 set_tok_const (newtok
[1], (1<<lgsize
)-1);
2744 assemble_tokens ("ldq_u", newtok
, 3, 1);
2746 /* emit "extXl $t9, $at, $t9" */
2748 set_tok_reg (newtok
[0], AXP_REG_T9
);
2749 set_tok_reg (newtok
[1], AXP_REG_AT
);
2750 set_tok_reg (newtok
[2], AXP_REG_T9
);
2751 assemble_tokens (extXl_op
[lgsize
], newtok
, 3, 1);
2753 /* emit "extXh $t10, $at, $t10" */
2755 set_tok_reg (newtok
[0], AXP_REG_T10
);
2756 set_tok_reg (newtok
[2], AXP_REG_T10
);
2757 assemble_tokens (extXh_op
[lgsize
], newtok
, 3, 1);
2759 /* emit "or $t9, $t10, targ" */
2761 set_tok_reg (newtok
[0], AXP_REG_T9
);
2762 set_tok_reg (newtok
[1], AXP_REG_T10
);
2764 assemble_tokens ("or", newtok
, 3, 1);
2767 /* Load an integral value from an unaligned address as a signed value.
2768 Note that quads should get funneled to the unsigned load since we
2769 don't have to do the sign extension. */
2772 emit_uldX (tok
, ntok
, vlgsize
)
2773 const expressionS
*tok
;
2777 emit_uldXu (tok
, ntok
, vlgsize
);
2778 assemble_tokens (sextX_op
[(long)vlgsize
], tok
, 1, 1);
2781 /* Implement the ldil macro. */
2784 emit_ldil (tok
, ntok
, unused
)
2785 const expressionS
*tok
;
2789 expressionS newtok
[2];
2791 memcpy (newtok
, tok
, sizeof(newtok
));
2792 newtok
[1].X_add_number
= sign_extend_32 (tok
[1].X_add_number
);
2794 assemble_tokens ("lda", newtok
, ntok
, 1);
2797 /* Store a half-word or byte. */
2800 emit_stX (tok
, ntok
, vlgsize
)
2801 const expressionS
*tok
;
2805 int lgsize
= (int)(long)vlgsize
;
2807 if (alpha_target
& AXP_OPCODE_BWX
)
2808 emit_loadstore (tok
, ntok
, stX_op
[lgsize
]);
2811 expressionS newtok
[3];
2814 as_bad("macro requires $at register while noat in effect");
2816 /* emit "lda $at, exp" */
2818 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
2819 newtok
[0].X_add_number
= AXP_REG_AT
;
2820 assemble_tokens ("lda", newtok
, ntok
, 1);
2822 /* emit "ldq_u $t9, 0($at)" */
2824 set_tok_reg (newtok
[0], AXP_REG_T9
);
2825 set_tok_const (newtok
[1], 0);
2826 set_tok_preg (newtok
[2], AXP_REG_AT
);
2827 assemble_tokens ("ldq_u", newtok
, 3, 1);
2829 /* emit "insXl src, $at, $t10" */
2832 set_tok_reg (newtok
[1], AXP_REG_AT
);
2833 set_tok_reg (newtok
[2], AXP_REG_T10
);
2834 assemble_tokens (insXl_op
[lgsize
], newtok
, 3, 1);
2836 /* emit "mskXl $t9, $at, $t9" */
2838 set_tok_reg (newtok
[0], AXP_REG_T9
);
2839 newtok
[2] = newtok
[0];
2840 assemble_tokens (mskXl_op
[lgsize
], newtok
, 3, 1);
2842 /* emit "or $t9, $t10, $t9" */
2844 set_tok_reg (newtok
[1], AXP_REG_T10
);
2845 assemble_tokens ("or", newtok
, 3, 1);
2847 /* emit "stq_u $t9, 0($at) */
2849 set_tok_const (newtok
[1], 0);
2850 set_tok_preg (newtok
[2], AXP_REG_AT
);
2851 assemble_tokens ("stq_u", newtok
, 3, 1);
2855 /* Store an integer to an unaligned address. */
2858 emit_ustX (tok
, ntok
, vlgsize
)
2859 const expressionS
*tok
;
2863 int lgsize
= (int)(long)vlgsize
;
2864 expressionS newtok
[3];
2866 /* emit "lda $at, exp" */
2868 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
2869 newtok
[0].X_add_number
= AXP_REG_AT
;
2870 assemble_tokens ("lda", newtok
, ntok
, 1);
2872 /* emit "ldq_u $9, 0($at)" */
2874 set_tok_reg (newtok
[0], AXP_REG_T9
);
2875 set_tok_const (newtok
[1], 0);
2876 set_tok_preg (newtok
[2], AXP_REG_AT
);
2877 assemble_tokens ("ldq_u", newtok
, 3, 1);
2879 /* emit "ldq_u $10, size-1($at)" */
2881 set_tok_reg (newtok
[0], AXP_REG_T10
);
2882 set_tok_const (newtok
[1], (1 << lgsize
)-1);
2883 assemble_tokens ("ldq_u", newtok
, 3, 1);
2885 /* emit "insXl src, $at, $t11" */
2888 set_tok_reg (newtok
[1], AXP_REG_AT
);
2889 set_tok_reg (newtok
[2], AXP_REG_T11
);
2890 assemble_tokens (insXl_op
[lgsize
], newtok
, 3, 1);
2892 /* emit "insXh src, $at, $t12" */
2894 set_tok_reg (newtok
[2], AXP_REG_T12
);
2895 assemble_tokens (insXh_op
[lgsize
], newtok
, 3, 1);
2897 /* emit "mskXl $t9, $at, $t9" */
2899 set_tok_reg (newtok
[0], AXP_REG_T9
);
2900 newtok
[2] = newtok
[0];
2901 assemble_tokens (mskXl_op
[lgsize
], newtok
, 3, 1);
2903 /* emit "mskXh $t10, $at, $t10" */
2905 set_tok_reg (newtok
[0], AXP_REG_T10
);
2906 newtok
[2] = newtok
[0];
2907 assemble_tokens (mskXh_op
[lgsize
], newtok
, 3, 1);
2909 /* emit "or $t9, $t11, $t9" */
2911 set_tok_reg (newtok
[0], AXP_REG_T9
);
2912 set_tok_reg (newtok
[1], AXP_REG_T11
);
2913 newtok
[2] = newtok
[0];
2914 assemble_tokens ("or", newtok
, 3, 1);
2916 /* emit "or $t10, $t12, $t10" */
2918 set_tok_reg (newtok
[0], AXP_REG_T10
);
2919 set_tok_reg (newtok
[1], AXP_REG_T12
);
2920 newtok
[2] = newtok
[0];
2921 assemble_tokens ("or", newtok
, 3, 1);
2923 /* emit "stq_u $t9, 0($at)" */
2925 set_tok_reg (newtok
[0], AXP_REG_T9
);
2926 set_tok_const (newtok
[1], 0);
2927 set_tok_preg (newtok
[2], AXP_REG_AT
);
2928 assemble_tokens ("stq_u", newtok
, 3, 1);
2930 /* emit "stq_u $t10, size-1($at)" */
2932 set_tok_reg (newtok
[0], AXP_REG_T10
);
2933 set_tok_const (newtok
[1], (1 << lgsize
)-1);
2934 assemble_tokens ("stq_u", newtok
, 3, 1);
2937 /* Sign extend a half-word or byte. The 32-bit sign extend is
2938 implemented as "addl $31, $r, $t" in the opcode table. */
2941 emit_sextX (tok
, ntok
, vlgsize
)
2942 const expressionS
*tok
;
2946 long lgsize
= (long)vlgsize
;
2948 if (alpha_target
& AXP_OPCODE_BWX
)
2949 assemble_tokens (sextX_op
[lgsize
], tok
, ntok
, 0);
2952 int bitshift
= 64 - 8 * (1 << lgsize
);
2953 expressionS newtok
[3];
2955 /* emit "sll src,bits,dst" */
2958 set_tok_const (newtok
[1], bitshift
);
2959 newtok
[2] = tok
[ntok
- 1];
2960 assemble_tokens ("sll", newtok
, 3, 1);
2962 /* emit "sra dst,bits,dst" */
2964 newtok
[0] = newtok
[2];
2965 assemble_tokens ("sra", newtok
, 3, 1);
2969 /* Implement the division and modulus macros. */
2973 /* Make register usage like in normal procedure call.
2974 Don't clobber PV and RA. */
2977 emit_division (tok
, ntok
, symname
)
2978 const expressionS
*tok
;
2982 /* DIVISION and MODULUS. Yech.
2987 * mov x,R16 # if x != R16
2988 * mov y,R17 # if y != R17
2993 * with appropriate optimizations if R0,R16,R17 are the registers
2994 * specified by the compiler.
2999 expressionS newtok
[3];
3001 xr
= regno (tok
[0].X_add_number
);
3002 yr
= regno (tok
[1].X_add_number
);
3007 rr
= regno (tok
[2].X_add_number
);
3009 /* Move the operands into the right place */
3010 if (yr
== AXP_REG_R16
&& xr
== AXP_REG_R17
)
3012 /* They are in exactly the wrong order -- swap through AT */
3015 as_bad ("macro requires $at register while noat in effect");
3017 set_tok_reg (newtok
[0], AXP_REG_R16
);
3018 set_tok_reg (newtok
[1], AXP_REG_AT
);
3019 assemble_tokens ("mov", newtok
, 2, 1);
3021 set_tok_reg (newtok
[0], AXP_REG_R17
);
3022 set_tok_reg (newtok
[1], AXP_REG_R16
);
3023 assemble_tokens ("mov", newtok
, 2, 1);
3025 set_tok_reg (newtok
[0], AXP_REG_AT
);
3026 set_tok_reg (newtok
[1], AXP_REG_R17
);
3027 assemble_tokens ("mov", newtok
, 2, 1);
3031 if (yr
== AXP_REG_R16
)
3033 set_tok_reg (newtok
[0], AXP_REG_R16
);
3034 set_tok_reg (newtok
[1], AXP_REG_R17
);
3035 assemble_tokens ("mov", newtok
, 2, 1);
3038 if (xr
!= AXP_REG_R16
)
3040 set_tok_reg (newtok
[0], xr
);
3041 set_tok_reg (newtok
[1], AXP_REG_R16
);
3042 assemble_tokens ("mov", newtok
, 2, 1);
3045 if (yr
!= AXP_REG_R16
&& yr
!= AXP_REG_R17
)
3047 set_tok_reg (newtok
[0], yr
);
3048 set_tok_reg (newtok
[1], AXP_REG_R17
);
3049 assemble_tokens ("mov", newtok
, 2, 1);
3053 sym
= symbol_find_or_make ((const char *)symname
);
3055 set_tok_reg (newtok
[0], AXP_REG_AT
);
3056 set_tok_sym (newtok
[1], sym
, 0);
3057 assemble_tokens ("lda", newtok
, 2, 1);
3059 /* Call the division routine */
3060 set_tok_reg (newtok
[0], AXP_REG_AT
);
3061 set_tok_cpreg (newtok
[1], AXP_REG_AT
);
3062 set_tok_const (newtok
[2], 0);
3063 assemble_tokens ("jsr", newtok
, 3, 1);
3065 /* Move the result to the right place */
3066 if (rr
!= AXP_REG_R0
)
3068 set_tok_reg (newtok
[0], AXP_REG_R0
);
3069 set_tok_reg (newtok
[1], rr
);
3070 assemble_tokens ("mov", newtok
, 2, 1);
3074 #else /* !OBJ_EVAX */
3077 emit_division (tok
, ntok
, symname
)
3078 const expressionS
*tok
;
3082 /* DIVISION and MODULUS. Yech.
3092 * with appropriate optimizations if t10,t11,t12 are the registers
3093 * specified by the compiler.
3098 expressionS newtok
[3];
3100 xr
= regno (tok
[0].X_add_number
);
3101 yr
= regno (tok
[1].X_add_number
);
3106 rr
= regno (tok
[2].X_add_number
);
3108 sym
= symbol_find_or_make ((const char *)symname
);
3110 /* Move the operands into the right place */
3111 if (yr
== AXP_REG_T10
&& xr
== AXP_REG_T11
)
3113 /* They are in exactly the wrong order -- swap through AT */
3116 as_bad ("macro requires $at register while noat in effect");
3118 set_tok_reg (newtok
[0], AXP_REG_T10
);
3119 set_tok_reg (newtok
[1], AXP_REG_AT
);
3120 assemble_tokens ("mov", newtok
, 2, 1);
3122 set_tok_reg (newtok
[0], AXP_REG_T11
);
3123 set_tok_reg (newtok
[1], AXP_REG_T10
);
3124 assemble_tokens ("mov", newtok
, 2, 1);
3126 set_tok_reg (newtok
[0], AXP_REG_AT
);
3127 set_tok_reg (newtok
[1], AXP_REG_T11
);
3128 assemble_tokens ("mov", newtok
, 2, 1);
3132 if (yr
== AXP_REG_T10
)
3134 set_tok_reg (newtok
[0], AXP_REG_T10
);
3135 set_tok_reg (newtok
[1], AXP_REG_T11
);
3136 assemble_tokens ("mov", newtok
, 2, 1);
3139 if (xr
!= AXP_REG_T10
)
3141 set_tok_reg (newtok
[0], xr
);
3142 set_tok_reg (newtok
[1], AXP_REG_T10
);
3143 assemble_tokens ("mov", newtok
, 2, 1);
3146 if (yr
!= AXP_REG_T10
&& yr
!= AXP_REG_T11
)
3148 set_tok_reg (newtok
[0], yr
);
3149 set_tok_reg (newtok
[1], AXP_REG_T11
);
3150 assemble_tokens ("mov", newtok
, 2, 1);
3154 /* Call the division routine */
3155 set_tok_reg (newtok
[0], AXP_REG_T9
);
3156 set_tok_sym (newtok
[1], sym
, 0);
3157 assemble_tokens ("jsr", newtok
, 2, 1);
3159 /* Reload the GP register */
3163 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
3164 set_tok_reg (newtok
[0], alpha_gp_register
);
3165 set_tok_const (newtok
[1], 0);
3166 set_tok_preg (newtok
[2], AXP_REG_T9
);
3167 assemble_tokens ("ldgp", newtok
, 3, 1);
3170 /* Move the result to the right place */
3171 if (rr
!= AXP_REG_T12
)
3173 set_tok_reg (newtok
[0], AXP_REG_T12
);
3174 set_tok_reg (newtok
[1], rr
);
3175 assemble_tokens ("mov", newtok
, 2, 1);
3179 #endif /* !OBJ_EVAX */
3181 /* The jsr and jmp macros differ from their instruction counterparts
3182 in that they can load the target address and default most
3186 emit_jsrjmp (tok
, ntok
, vopname
)
3187 const expressionS
*tok
;
3191 const char *opname
= (const char *) vopname
;
3192 struct alpha_insn insn
;
3193 expressionS newtok
[3];
3194 int r
, tokidx
= 0, lituse
= 0;
3196 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_register
)
3197 r
= regno (tok
[tokidx
++].X_add_number
);
3199 r
= strcmp (opname
, "jmp") == 0 ? AXP_REG_ZERO
: AXP_REG_RA
;
3201 set_tok_reg (newtok
[0], r
);
3203 if (tokidx
< ntok
&&
3204 (tok
[tokidx
].X_op
== O_pregister
|| tok
[tokidx
].X_op
== O_cpregister
))
3205 r
= regno (tok
[tokidx
++].X_add_number
);
3207 /* keep register if jsr $n.<sym> */
3211 int basereg
= alpha_gp_register
;
3212 lituse
= load_expression (r
= AXP_REG_PV
, &tok
[tokidx
], &basereg
, NULL
);
3216 set_tok_cpreg (newtok
[1], r
);
3219 /* FIXME: Add hint relocs to BFD for evax. */
3222 newtok
[2] = tok
[tokidx
];
3225 set_tok_const (newtok
[2], 0);
3227 assemble_tokens_to_insn (opname
, newtok
, 3, &insn
);
3229 /* add the LITUSE fixup */
3232 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3233 if (insn
.nfixups
> 0)
3235 memmove (&insn
.fixups
[1], &insn
.fixups
[0],
3236 sizeof(struct alpha_fixup
) * insn
.nfixups
);
3239 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITUSE
;
3240 insn
.fixups
[0].exp
.X_op
= O_constant
;
3241 insn
.fixups
[0].exp
.X_add_number
= 3;
3247 alpha_basereg_clobbered
= 0;
3249 /* reload PV from 0(FP) if it is our current base register. */
3250 if (alpha_gp_register
== AXP_REG_PV
)
3252 set_tok_reg (newtok
[0], AXP_REG_PV
);
3253 set_tok_const (newtok
[1], 0);
3254 set_tok_preg (newtok
[2], AXP_REG_FP
);
3255 assemble_tokens ("ldq", newtok
, 3, 0);
3260 /* The ret and jcr instructions differ from their instruction
3261 counterparts in that everything can be defaulted. */
3264 emit_retjcr (tok
, ntok
, vopname
)
3265 const expressionS
*tok
;
3269 const char *opname
= (const char *)vopname
;
3270 expressionS newtok
[3];
3273 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_register
)
3274 r
= regno (tok
[tokidx
++].X_add_number
);
3278 set_tok_reg (newtok
[0], r
);
3280 if (tokidx
< ntok
&&
3281 (tok
[tokidx
].X_op
== O_pregister
|| tok
[tokidx
].X_op
== O_cpregister
))
3282 r
= regno (tok
[tokidx
++].X_add_number
);
3286 set_tok_cpreg (newtok
[1], r
);
3289 newtok
[2] = tok
[tokidx
];
3291 set_tok_const (newtok
[2], strcmp(opname
, "ret") == 0);
3293 assemble_tokens (opname
, newtok
, 3, 0);
3296 /* Assembler directives */
3298 /* Handle the .text pseudo-op. This is like the usual one, but it
3299 clears alpha_insn_label and restores auto alignment. */
3307 alpha_insn_label
= NULL
;
3308 alpha_auto_align_on
= 1;
3309 alpha_current_align
= 0;
3312 /* Handle the .data pseudo-op. This is like the usual one, but it
3313 clears alpha_insn_label and restores auto alignment. */
3320 alpha_insn_label
= NULL
;
3321 alpha_auto_align_on
= 1;
3322 alpha_current_align
= 0;
3327 /* Handle the OSF/1 .comm pseudo quirks. */
3330 s_alpha_comm (ignore
)
3333 register char *name
;
3337 register symbolS
*symbolP
;
3339 name
= input_line_pointer
;
3340 c
= get_symbol_end ();
3342 /* just after name is now '\0' */
3343 p
= input_line_pointer
;
3348 /* Alpha OSF/1 compiler doesn't provide the comma, gcc does. */
3349 if (*input_line_pointer
== ',')
3351 input_line_pointer
++;
3354 if ((temp
= get_absolute_expression ()) < 0)
3356 as_warn (".COMMon length (%ld.) <0! Ignored.", (long) temp
);
3357 ignore_rest_of_line ();
3362 symbolP
= symbol_find_or_make (name
);
3365 if (S_IS_DEFINED (symbolP
) && ! S_IS_COMMON (symbolP
))
3367 as_bad ("Ignoring attempt to re-define symbol");
3368 ignore_rest_of_line ();
3372 if (S_GET_VALUE (symbolP
))
3374 if (S_GET_VALUE (symbolP
) != (valueT
) temp
)
3375 as_bad ("Length of .comm \"%s\" is already %ld. Not changed to %ld.",
3376 S_GET_NAME (symbolP
),
3377 (long) S_GET_VALUE (symbolP
),
3382 S_SET_VALUE (symbolP
, (valueT
) temp
);
3383 S_SET_EXTERNAL (symbolP
);
3386 know (symbolP
->sy_frag
== &zero_address_frag
);
3388 demand_empty_rest_of_line ();
3391 #endif /* ! OBJ_ELF */
3395 /* Handle the .rdata pseudo-op. This is like the usual one, but it
3396 clears alpha_insn_label and restores auto alignment. */
3399 s_alpha_rdata (ignore
)
3404 temp
= get_absolute_expression ();
3405 subseg_new (".rdata", 0);
3406 demand_empty_rest_of_line ();
3407 alpha_insn_label
= NULL
;
3408 alpha_auto_align_on
= 1;
3409 alpha_current_align
= 0;
3416 /* Handle the .sdata pseudo-op. This is like the usual one, but it
3417 clears alpha_insn_label and restores auto alignment. */
3420 s_alpha_sdata (ignore
)
3425 temp
= get_absolute_expression ();
3426 subseg_new (".sdata", 0);
3427 demand_empty_rest_of_line ();
3428 alpha_insn_label
= NULL
;
3429 alpha_auto_align_on
= 1;
3430 alpha_current_align
= 0;
3436 /* Handle the .section pseudo-op. This is like the usual one, but it
3437 clears alpha_insn_label and restores auto alignment. */
3440 s_alpha_section (ignore
)
3443 obj_elf_section (ignore
);
3445 alpha_insn_label
= NULL
;
3446 alpha_auto_align_on
= 1;
3447 alpha_current_align
= 0;
3454 /* Handle the section specific pseudo-op. */
3457 s_alpha_section (secid
)
3461 #define EVAX_SECTION_COUNT 6
3462 static char *section_name
[EVAX_SECTION_COUNT
+1] =
3463 { "NULL", ".rdata", ".comm", ".link", ".ctors", ".dtors", ".lcomm" };
3465 if ((secid
<= 0) || (secid
> EVAX_SECTION_COUNT
))
3467 as_fatal ("Unknown section directive");
3468 demand_empty_rest_of_line ();
3471 temp
= get_absolute_expression ();
3472 subseg_new (section_name
[secid
], 0);
3473 demand_empty_rest_of_line ();
3474 alpha_insn_label
= NULL
;
3475 alpha_auto_align_on
= 1;
3476 alpha_current_align
= 0;
3483 s_alpha_prologue (ignore
)
3486 alpha_basereg_clobbered
= 0;
3487 demand_empty_rest_of_line ();
3493 /* Parse .ent directives. */
3496 s_alpha_ent (ignore
)
3500 expressionS symexpr
;
3502 alpha_evax_proc
.pdsckind
= 0;
3503 alpha_evax_proc
.framereg
= -1;
3504 alpha_evax_proc
.framesize
= 0;
3505 alpha_evax_proc
.rsa_offset
= 0;
3506 alpha_evax_proc
.ra_save
= AXP_REG_RA
;
3507 alpha_evax_proc
.fp_save
= -1;
3508 alpha_evax_proc
.imask
= 0;
3509 alpha_evax_proc
.fmask
= 0;
3510 alpha_evax_proc
.prologue
= 0;
3511 alpha_evax_proc
.type
= 0;
3513 expression (&symexpr
);
3515 if (symexpr
.X_op
!= O_symbol
)
3517 as_fatal (".ent directive has no symbol");
3518 demand_empty_rest_of_line ();
3522 symbol
= make_expr_symbol (&symexpr
);
3523 symbol
->bsym
->flags
|= BSF_FUNCTION
;
3524 alpha_evax_proc
.symbol
= symbol
;
3526 demand_empty_rest_of_line ();
3531 /* Parse .frame <framreg>,<framesize>,RA,<rsa_offset> directives. */
3534 s_alpha_frame (ignore
)
3539 alpha_evax_proc
.framereg
= tc_get_register (1);
3542 if (*input_line_pointer
++ != ','
3543 || get_absolute_expression_and_terminator (&val
) != ',')
3545 as_warn ("Bad .frame directive 1./2. param");
3546 --input_line_pointer
;
3547 demand_empty_rest_of_line ();
3551 alpha_evax_proc
.framesize
= val
;
3553 (void) tc_get_register (1);
3555 if (*input_line_pointer
++ != ',')
3557 as_warn ("Bad .frame directive 3./4. param");
3558 --input_line_pointer
;
3559 demand_empty_rest_of_line ();
3562 alpha_evax_proc
.rsa_offset
= get_absolute_expression ();
3568 s_alpha_pdesc (ignore
)
3578 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
3580 if (now_seg
!= alpha_link_section
)
3582 as_bad (".pdesc directive not in link (.link) section");
3583 demand_empty_rest_of_line ();
3587 if ((alpha_evax_proc
.symbol
== 0)
3588 || (!S_IS_DEFINED (alpha_evax_proc
.symbol
)))
3590 as_fatal (".pdesc has no matching .ent");
3591 demand_empty_rest_of_line ();
3595 alpha_evax_proc
.symbol
->sy_obj
= (valueT
)seginfo
->literal_pool_size
;
3598 if (exp
.X_op
!= O_symbol
)
3600 as_warn (".pdesc directive has no entry symbol");
3601 demand_empty_rest_of_line ();
3605 entry_sym
= make_expr_symbol (&exp
);
3606 /* Save bfd symbol of proc desc in function symbol. */
3607 alpha_evax_proc
.symbol
->bsym
->udata
.p
= (PTR
)entry_sym
->bsym
;
3610 if (*input_line_pointer
++ != ',')
3612 as_warn ("No comma after .pdesc <entryname>");
3613 demand_empty_rest_of_line ();
3618 name
= input_line_pointer
;
3619 name_end
= get_symbol_end ();
3621 if (strncmp(name
, "stack", 5) == 0)
3623 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_FP_STACK
;
3625 else if (strncmp(name
, "reg", 3) == 0)
3627 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_FP_REGISTER
;
3629 else if (strncmp(name
, "null", 4) == 0)
3631 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_NULL
;
3635 as_fatal ("unknown procedure kind");
3636 demand_empty_rest_of_line ();
3640 *input_line_pointer
= name_end
;
3641 demand_empty_rest_of_line ();
3643 #ifdef md_flush_pending_output
3644 md_flush_pending_output ();
3647 frag_align (3, 0, 0);
3649 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
3651 seginfo
->literal_pool_size
+= 16;
3653 *p
= alpha_evax_proc
.pdsckind
3654 | ((alpha_evax_proc
.framereg
== 29) ? PDSC_S_M_BASE_REG_IS_FP
: 0);
3655 *(p
+1) = PDSC_S_M_NATIVE
3656 | PDSC_S_M_NO_JACKET
;
3658 switch (alpha_evax_proc
.pdsckind
)
3660 case PDSC_S_K_KIND_NULL
:
3664 case PDSC_S_K_KIND_FP_REGISTER
:
3665 *(p
+2) = alpha_evax_proc
.fp_save
;
3666 *(p
+3) = alpha_evax_proc
.ra_save
;
3668 case PDSC_S_K_KIND_FP_STACK
:
3669 md_number_to_chars (p
+2, (valueT
)alpha_evax_proc
.rsa_offset
, 2);
3671 default: /* impossible */
3676 *(p
+5) = alpha_evax_proc
.type
& 0x0f;
3678 /* Signature offset. */
3679 md_number_to_chars (p
+6, (valueT
)0, 2);
3681 fix_new_exp (frag_now
, p
-frag_now
->fr_literal
+8, 8, &exp
, 0, BFD_RELOC_64
);
3683 if (alpha_evax_proc
.pdsckind
== PDSC_S_K_KIND_NULL
)
3686 /* Add dummy fix to make add_to_link_pool work. */
3688 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
3690 seginfo
->literal_pool_size
+= 8;
3692 /* pdesc+16: Size. */
3693 md_number_to_chars (p
, (valueT
)alpha_evax_proc
.framesize
, 4);
3695 md_number_to_chars (p
+4, (valueT
)0, 2);
3698 md_number_to_chars (p
+6, alpha_evax_proc
.prologue
, 2);
3700 if (alpha_evax_proc
.pdsckind
== PDSC_S_K_KIND_FP_REGISTER
)
3703 /* Add dummy fix to make add_to_link_pool work. */
3705 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
3707 seginfo
->literal_pool_size
+= 8;
3709 /* pdesc+24: register masks. */
3711 md_number_to_chars (p
, alpha_evax_proc
.imask
, 4);
3712 md_number_to_chars (p
+4, alpha_evax_proc
.fmask
, 4);
3718 /* Support for crash debug on vms. */
3721 s_alpha_name (ignore
)
3726 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
3728 if (now_seg
!= alpha_link_section
)
3730 as_bad (".name directive not in link (.link) section");
3731 demand_empty_rest_of_line ();
3736 if (exp
.X_op
!= O_symbol
)
3738 as_warn (".name directive has no symbol");
3739 demand_empty_rest_of_line ();
3743 demand_empty_rest_of_line ();
3745 #ifdef md_flush_pending_output
3746 md_flush_pending_output ();
3749 frag_align (3, 0, 0);
3751 seginfo
->literal_pool_size
+= 8;
3753 fix_new_exp (frag_now
, p
-frag_now
->fr_literal
, 8, &exp
, 0, BFD_RELOC_64
);
3760 s_alpha_linkage (ignore
)
3766 #ifdef md_flush_pending_output
3767 md_flush_pending_output ();
3771 if (exp
.X_op
!= O_symbol
)
3773 as_fatal ("No symbol after .linkage");
3777 p
= frag_more (LKP_S_K_SIZE
);
3778 memset (p
, 0, LKP_S_K_SIZE
);
3779 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, LKP_S_K_SIZE
, &exp
, 0,\
3780 BFD_RELOC_ALPHA_LINKAGE
);
3782 demand_empty_rest_of_line ();
3789 s_alpha_code_address (ignore
)
3795 #ifdef md_flush_pending_output
3796 md_flush_pending_output ();
3800 if (exp
.X_op
!= O_symbol
)
3802 as_fatal ("No symbol after .code_address");
3808 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 8, &exp
, 0,\
3809 BFD_RELOC_ALPHA_CODEADDR
);
3811 demand_empty_rest_of_line ();
3818 s_alpha_fp_save (ignore
)
3822 alpha_evax_proc
.fp_save
= tc_get_register (1);
3824 demand_empty_rest_of_line ();
3830 s_alpha_mask (ignore
)
3835 if (get_absolute_expression_and_terminator (&val
) != ',')
3837 as_warn ("Bad .mask directive");
3838 --input_line_pointer
;
3842 alpha_evax_proc
.imask
= val
;
3843 (void)get_absolute_expression ();
3845 demand_empty_rest_of_line ();
3852 s_alpha_fmask (ignore
)
3857 if (get_absolute_expression_and_terminator (&val
) != ',')
3859 as_warn ("Bad .fmask directive");
3860 --input_line_pointer
;
3864 alpha_evax_proc
.fmask
= val
;
3865 (void) get_absolute_expression ();
3867 demand_empty_rest_of_line ();
3873 s_alpha_end (ignore
)
3878 c
= get_symbol_end ();
3879 *input_line_pointer
= c
;
3880 demand_empty_rest_of_line ();
3881 alpha_evax_proc
.symbol
= 0;
3882 alpha_basereg_clobbered
= 0;
3889 s_alpha_file (ignore
)
3894 static char case_hack
[32];
3896 extern char *demand_copy_string
PARAMS ((int *lenP
));
3898 sprintf (case_hack
, "<CASE:%01d%01d>",
3899 alpha_flag_hash_long_names
, alpha_flag_show_after_trunc
);
3901 s
= symbol_find_or_make (case_hack
);
3902 s
->bsym
->flags
|= BSF_FILE
;
3904 get_absolute_expression ();
3905 s
= symbol_find_or_make (demand_copy_string (&length
));
3906 s
->bsym
->flags
|= BSF_FILE
;
3907 demand_empty_rest_of_line ();
3911 #endif /* OBJ_EVAX */
3913 /* Handle the .gprel32 pseudo op. */
3916 s_alpha_gprel32 (ignore
)
3929 e
.X_add_symbol
= section_symbol(absolute_section
);
3942 e
.X_add_symbol
= section_symbol (absolute_section
);
3945 e
.X_op
= O_subtract
;
3946 e
.X_op_symbol
= alpha_gp_symbol
;
3954 if (alpha_auto_align_on
&& alpha_current_align
< 2)
3955 alpha_align (2, (char *) NULL
, alpha_insn_label
);
3956 if (alpha_current_align
> 2)
3957 alpha_current_align
= 2;
3958 alpha_insn_label
= NULL
;
3962 fix_new_exp (frag_now
, p
-frag_now
->fr_literal
, 4,
3963 &e
, 0, BFD_RELOC_GPREL32
);
3966 /* Handle floating point allocation pseudo-ops. This is like the
3967 generic vresion, but it makes sure the current label, if any, is
3968 correctly aligned. */
3971 s_alpha_float_cons (type
)
3998 if (alpha_auto_align_on
&& alpha_current_align
< log_size
)
3999 alpha_align (log_size
, (char *) NULL
, alpha_insn_label
);
4000 if (alpha_current_align
> log_size
)
4001 alpha_current_align
= log_size
;
4002 alpha_insn_label
= NULL
;
4007 /* Handle the .proc pseudo op. We don't really do much with it except
4011 s_alpha_proc (is_static
)
4020 /* Takes ".proc name,nargs" */
4021 name
= input_line_pointer
;
4022 c
= get_symbol_end ();
4023 p
= input_line_pointer
;
4024 symbolP
= symbol_find_or_make (name
);
4027 if (*input_line_pointer
!= ',')
4030 as_warn ("Expected comma after name \"%s\"", name
);
4033 ignore_rest_of_line ();
4037 input_line_pointer
++;
4038 temp
= get_absolute_expression ();
4040 /* symbolP->sy_other = (signed char) temp; */
4041 as_warn ("unhandled: .proc %s,%d", name
, temp
);
4042 demand_empty_rest_of_line ();
4045 /* Handle the .set pseudo op. This is used to turn on and off most of
4046 the assembler features. */
4052 char *name
= input_line_pointer
, ch
, *s
;
4055 while (!is_end_of_line
[(unsigned char) *input_line_pointer
])
4056 input_line_pointer
++;
4057 ch
= *input_line_pointer
;
4058 *input_line_pointer
= '\0';
4061 if (s
[0] == 'n' && s
[1] == 'o')
4066 if (!strcmp ("reorder", s
))
4068 else if (!strcmp ("at", s
))
4069 alpha_noat_on
= !yesno
;
4070 else if (!strcmp ("macro", s
))
4071 alpha_macros_on
= yesno
;
4072 else if (!strcmp ("move", s
))
4074 else if (!strcmp ("volatile", s
))
4077 as_warn ("Tried to .set unrecognized mode `%s'", name
);
4079 *input_line_pointer
= ch
;
4080 demand_empty_rest_of_line ();
4083 /* Handle the .base pseudo op. This changes the assembler's notion of
4084 the $gp register. */
4087 s_alpha_base (ignore
)
4091 if (first_32bit_quadrant
)
4093 /* not fatal, but it might not work in the end */
4094 as_warn ("File overrides no-base-register option.");
4095 first_32bit_quadrant
= 0;
4100 if (*input_line_pointer
== '$')
4102 input_line_pointer
++;
4103 if (*input_line_pointer
== 'r')
4104 input_line_pointer
++;
4107 alpha_gp_register
= get_absolute_expression ();
4108 if (alpha_gp_register
< 0 || alpha_gp_register
> 31)
4110 alpha_gp_register
= AXP_REG_GP
;
4111 as_warn ("Bad base register, using $%d.", alpha_gp_register
);
4114 demand_empty_rest_of_line ();
4117 /* Handle the .align pseudo-op. This aligns to a power of two. It
4118 also adjusts any current instruction label. We treat this the same
4119 way the MIPS port does: .align 0 turns off auto alignment. */
4122 s_alpha_align (ignore
)
4127 long max_alignment
= 15;
4129 align
= get_absolute_expression ();
4130 if (align
> max_alignment
)
4132 align
= max_alignment
;
4133 as_bad ("Alignment too large: %d. assumed", align
);
4137 as_warn ("Alignment negative: 0 assumed");
4141 if (*input_line_pointer
== ',')
4143 input_line_pointer
++;
4144 fill
= get_absolute_expression ();
4152 alpha_auto_align_on
= 1;
4153 alpha_align (align
, pfill
, alpha_insn_label
);
4157 alpha_auto_align_on
= 0;
4160 demand_empty_rest_of_line ();
4163 /* Hook the normal string processor to reset known alignment. */
4166 s_alpha_stringer (terminate
)
4169 alpha_current_align
= 0;
4170 alpha_insn_label
= NULL
;
4171 stringer (terminate
);
4174 /* Hook the normal space processing to reset known alignment. */
4177 s_alpha_space (ignore
)
4180 alpha_current_align
= 0;
4181 alpha_insn_label
= NULL
;
4185 /* Hook into cons for auto-alignment. */
4188 alpha_cons_align (size
)
4194 while ((size
>>= 1) != 0)
4197 if (alpha_auto_align_on
&& alpha_current_align
< log_size
)
4198 alpha_align (log_size
, (char *) NULL
, alpha_insn_label
);
4199 if (alpha_current_align
> log_size
)
4200 alpha_current_align
= log_size
;
4201 alpha_insn_label
= NULL
;
4204 /* Here come the .uword, .ulong, and .uquad explicitly unaligned
4205 pseudos. We just turn off auto-alignment and call down to cons. */
4208 s_alpha_ucons (bytes
)
4211 int hold
= alpha_auto_align_on
;
4212 alpha_auto_align_on
= 0;
4214 alpha_auto_align_on
= hold
;
4220 /* print token expression with alpha specific extension. */
4223 alpha_print_token(f
, exp
)
4225 const expressionS
*exp
;
4235 expressionS nexp
= *exp
;
4236 nexp
.X_op
= O_register
;
4237 print_expr (f
, &nexp
);
4242 print_expr (f
, exp
);
4249 /* The target specific pseudo-ops which we support. */
4251 const pseudo_typeS md_pseudo_table
[] =
4253 {"common", s_comm
, 0}, /* is this used? */
4255 {"comm", s_alpha_comm
, 0}, /* osf1 compiler does this */
4256 {"rdata", s_alpha_rdata
, 0},
4258 {"text", s_alpha_text
, 0},
4259 {"data", s_alpha_data
, 0},
4261 {"sdata", s_alpha_sdata
, 0},
4264 {"section", s_alpha_section
, 0},
4265 {"section.s", s_alpha_section
, 0},
4266 {"sect", s_alpha_section
, 0},
4267 {"sect.s", s_alpha_section
, 0},
4270 { "pdesc", s_alpha_pdesc
, 0},
4271 { "name", s_alpha_name
, 0},
4272 { "linkage", s_alpha_linkage
, 0},
4273 { "code_address", s_alpha_code_address
, 0},
4274 { "ent", s_alpha_ent
, 0},
4275 { "frame", s_alpha_frame
, 0},
4276 { "fp_save", s_alpha_fp_save
, 0},
4277 { "mask", s_alpha_mask
, 0},
4278 { "fmask", s_alpha_fmask
, 0},
4279 { "end", s_alpha_end
, 0},
4280 { "file", s_alpha_file
, 0},
4281 { "rdata", s_alpha_section
, 1},
4282 { "comm", s_alpha_section
, 2},
4283 { "link", s_alpha_section
, 3},
4284 { "ctors", s_alpha_section
, 4},
4285 { "dtors", s_alpha_section
, 5},
4286 { "lcomm", s_alpha_section
, 6},
4288 {"gprel32", s_alpha_gprel32
, 0},
4289 {"t_floating", s_alpha_float_cons
, 'd'},
4290 {"s_floating", s_alpha_float_cons
, 'f'},
4291 {"f_floating", s_alpha_float_cons
, 'F'},
4292 {"g_floating", s_alpha_float_cons
, 'G'},
4293 {"d_floating", s_alpha_float_cons
, 'D'},
4295 {"proc", s_alpha_proc
, 0},
4296 {"aproc", s_alpha_proc
, 1},
4297 {"set", s_alpha_set
, 0},
4298 {"reguse", s_ignore
, 0},
4299 {"livereg", s_ignore
, 0},
4300 {"base", s_alpha_base
, 0}, /*??*/
4301 {"option", s_ignore
, 0},
4302 {"prologue", s_ignore
, 0},
4303 {"aent", s_ignore
, 0},
4304 {"ugen", s_ignore
, 0},
4305 {"eflag", s_ignore
, 0},
4307 {"align", s_alpha_align
, 0},
4308 {"double", s_alpha_float_cons
, 'd'},
4309 {"float", s_alpha_float_cons
, 'f'},
4310 {"single", s_alpha_float_cons
, 'f'},
4311 {"ascii", s_alpha_stringer
, 0},
4312 {"asciz", s_alpha_stringer
, 1},
4313 {"string", s_alpha_stringer
, 1},
4314 {"space", s_alpha_space
, 0},
4315 {"skip", s_alpha_space
, 0},
4316 {"zero", s_alpha_space
, 0},
4318 /* Unaligned data pseudos. */
4319 {"uword", s_alpha_ucons
, 2},
4320 {"ulong", s_alpha_ucons
, 4},
4321 {"uquad", s_alpha_ucons
, 8},
4324 /* Dwarf wants these versions of unaligned. */
4325 {"2byte", s_alpha_ucons
, 2},
4326 {"4byte", s_alpha_ucons
, 4},
4327 {"8byte", s_alpha_ucons
, 8},
4330 /* We don't do any optimizing, so we can safely ignore these. */
4331 {"noalias", s_ignore
, 0},
4332 {"alias", s_ignore
, 0},
4338 /* Build a BFD section with its flags set appropriately for the .lita,
4339 .lit8, or .lit4 sections. */
4342 create_literal_section (name
, secp
, symp
)
4347 segT current_section
= now_seg
;
4348 int current_subsec
= now_subseg
;
4351 *secp
= new_sec
= subseg_new (name
, 0);
4352 subseg_set (current_section
, current_subsec
);
4353 bfd_set_section_alignment (stdoutput
, new_sec
, 4);
4354 bfd_set_section_flags (stdoutput
, new_sec
,
4355 SEC_RELOC
| SEC_ALLOC
| SEC_LOAD
| SEC_READONLY
4358 S_CLEAR_EXTERNAL (*symp
= section_symbol (new_sec
));
4363 /* @@@ GP selection voodoo. All of this seems overly complicated and
4364 unnecessary; which is the primary reason it's for ECOFF only. */
4373 vma
= bfd_get_section_vma (foo
, sec
);
4374 if (vma
&& vma
< alpha_gp_value
)
4375 alpha_gp_value
= vma
;
4381 assert (alpha_gp_value
== 0);
4383 /* Get minus-one in whatever width... */
4384 alpha_gp_value
= 0; alpha_gp_value
--;
4386 /* Select the smallest VMA of these existing sections. */
4387 maybe_set_gp (alpha_lita_section
);
4389 /* These were disabled before -- should we use them? */
4390 maybe_set_gp (sdata
);
4391 maybe_set_gp (lit8_sec
);
4392 maybe_set_gp (lit4_sec
);
4395 /* @@ Will a simple 0x8000 work here? If not, why not? */
4396 #define GP_ADJUSTMENT (0x8000 - 0x10)
4398 alpha_gp_value
+= GP_ADJUSTMENT
;
4400 S_SET_VALUE (alpha_gp_symbol
, alpha_gp_value
);
4403 printf ("Chose GP value of %lx\n", alpha_gp_value
);
4406 #endif /* OBJ_ECOFF */
4408 /* Called internally to handle all alignment needs. This takes care
4409 of eliding calls to frag_align if'n the cached current alignment
4410 says we've already got it, as well as taking care of the auto-align
4411 feature wrt labels. */
4414 alpha_align (n
, pfill
, label
)
4419 if (alpha_current_align
>= n
)
4425 && (bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
) != 0)
4427 static char const nop
[4] = { 0x1f, 0x04, 0xff, 0x47 };
4429 /* First, make sure we're on a four-byte boundary, in case
4430 someone has been putting .byte values into the text
4431 section. The DEC assembler silently fills with unaligned
4432 no-op instructions. This will zero-fill, then nop-fill
4433 with proper alignment. */
4434 if (alpha_current_align
< 2)
4435 frag_align (2, 0, 0);
4436 frag_align_pattern (n
, nop
, sizeof nop
, 0);
4439 frag_align (n
, 0, 0);
4442 frag_align (n
, *pfill
, 0);
4444 alpha_current_align
= n
;
4448 assert (S_GET_SEGMENT (label
) == now_seg
);
4449 label
->sy_frag
= frag_now
;
4450 S_SET_VALUE (label
, (valueT
) frag_now_fix ());
4453 record_alignment(now_seg
, n
);
4456 /* The Alpha has support for some VAX floating point types, as well as for
4457 IEEE floating point. We consider IEEE to be the primary floating point
4458 format, and sneak in the VAX floating point support here. */
4459 #define md_atof vax_md_atof
4460 #include "config/atof-vax.c"