1 /* tc-alpha.c - Processor-specific code for the DEC Alpha AXP CPU.
2 Copyright (C) 1989, 93-98, 1999 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.
56 #include "opcode/alpha.h"
59 #include "elf/alpha.h"
67 #define MAX_INSN_FIXUPS 2
68 #define MAX_INSN_ARGS 5
73 bfd_reloc_code_real_type reloc
;
80 struct alpha_fixup fixups
[MAX_INSN_FIXUPS
];
85 MACRO_EOA
= 1, MACRO_IR
, MACRO_PIR
, MACRO_CPIR
, MACRO_FPR
, MACRO_EXP
91 void (*emit
) PARAMS ((const expressionS
*, int, const PTR
));
93 enum alpha_macro_arg argsets
[16];
96 /* Extra expression types. */
98 #define O_pregister O_md1 /* O_register, in parentheses */
99 #define O_cpregister O_md2 /* + a leading comma */
101 /* Macros for extracting the type and number of encoded register tokens */
103 #define is_ir_num(x) (((x) & 32) == 0)
104 #define is_fpr_num(x) (((x) & 32) != 0)
105 #define regno(x) ((x) & 31)
107 /* Something odd inherited from the old assembler */
109 #define note_gpreg(R) (alpha_gprmask |= (1 << (R)))
110 #define note_fpreg(R) (alpha_fprmask |= (1 << (R)))
112 /* Predicates for 16- and 32-bit ranges */
113 /* XXX: The non-shift version appears to trigger a compiler bug when
114 cross-assembling from x86 w/ gcc 2.7.2. */
117 #define range_signed_16(x) \
118 (((offsetT)(x) >> 15) == 0 || ((offsetT)(x) >> 15) == -1)
119 #define range_signed_32(x) \
120 (((offsetT)(x) >> 31) == 0 || ((offsetT)(x) >> 31) == -1)
122 #define range_signed_16(x) ((offsetT)(x) >= -(offsetT)0x8000 && \
123 (offsetT)(x) <= (offsetT)0x7FFF)
124 #define range_signed_32(x) ((offsetT)(x) >= -(offsetT)0x80000000 && \
125 (offsetT)(x) <= (offsetT)0x7FFFFFFF)
128 /* Macros for sign extending from 16- and 32-bits. */
129 /* XXX: The cast macros will work on all the systems that I care about,
130 but really a predicate should be found to use the non-cast forms. */
133 #define sign_extend_16(x) ((short)(x))
134 #define sign_extend_32(x) ((int)(x))
136 #define sign_extend_16(x) ((offsetT)(((x) & 0xFFFF) ^ 0x8000) - 0x8000)
137 #define sign_extend_32(x) ((offsetT)(((x) & 0xFFFFFFFF) \
138 ^ 0x80000000) - 0x80000000)
141 /* Macros to build tokens */
143 #define set_tok_reg(t, r) (memset(&(t), 0, sizeof(t)), \
144 (t).X_op = O_register, \
145 (t).X_add_number = (r))
146 #define set_tok_preg(t, r) (memset(&(t), 0, sizeof(t)), \
147 (t).X_op = O_pregister, \
148 (t).X_add_number = (r))
149 #define set_tok_cpreg(t, r) (memset(&(t), 0, sizeof(t)), \
150 (t).X_op = O_cpregister, \
151 (t).X_add_number = (r))
152 #define set_tok_freg(t, r) (memset(&(t), 0, sizeof(t)), \
153 (t).X_op = O_register, \
154 (t).X_add_number = (r)+32)
155 #define set_tok_sym(t, s, a) (memset(&(t), 0, sizeof(t)), \
156 (t).X_op = O_symbol, \
157 (t).X_add_symbol = (s), \
158 (t).X_add_number = (a))
159 #define set_tok_const(t, n) (memset(&(t), 0, sizeof(t)), \
160 (t).X_op = O_constant, \
161 (t).X_add_number = (n))
164 /* Prototypes for all local functions */
166 static int tokenize_arguments
PARAMS ((char *, expressionS
*, int));
167 static const struct alpha_opcode
*find_opcode_match
168 PARAMS ((const struct alpha_opcode
*, const expressionS
*, int *, int *));
169 static const struct alpha_macro
*find_macro_match
170 PARAMS ((const struct alpha_macro
*, const expressionS
*, int *));
171 static unsigned insert_operand
172 PARAMS ((unsigned, const struct alpha_operand
*, offsetT
, char *, unsigned));
173 static void assemble_insn
174 PARAMS ((const struct alpha_opcode
*, const expressionS
*, int,
175 struct alpha_insn
*));
176 static void emit_insn
PARAMS ((struct alpha_insn
*));
177 static void assemble_tokens_to_insn
178 PARAMS ((const char *, const expressionS
*, int, struct alpha_insn
*));
179 static void assemble_tokens
180 PARAMS ((const char *, const expressionS
*, int, int));
182 static int load_expression
183 PARAMS ((int, const expressionS
*, int *, expressionS
*));
185 static void emit_ldgp
PARAMS ((const expressionS
*, int, const PTR
));
186 static void emit_division
PARAMS ((const expressionS
*, int, const PTR
));
187 static void emit_lda
PARAMS ((const expressionS
*, int, const PTR
));
188 static void emit_ldah
PARAMS ((const expressionS
*, int, const PTR
));
189 static void emit_ir_load
PARAMS ((const expressionS
*, int, const PTR
));
190 static void emit_loadstore
PARAMS ((const expressionS
*, int, const PTR
));
191 static void emit_jsrjmp
PARAMS ((const expressionS
*, int, const PTR
));
192 static void emit_ldX
PARAMS ((const expressionS
*, int, const PTR
));
193 static void emit_ldXu
PARAMS ((const expressionS
*, int, const PTR
));
194 static void emit_uldX
PARAMS ((const expressionS
*, int, const PTR
));
195 static void emit_uldXu
PARAMS ((const expressionS
*, int, const PTR
));
196 static void emit_ldil
PARAMS ((const expressionS
*, int, const PTR
));
197 static void emit_stX
PARAMS ((const expressionS
*, int, const PTR
));
198 static void emit_ustX
PARAMS ((const expressionS
*, int, const PTR
));
199 static void emit_sextX
PARAMS ((const expressionS
*, int, const PTR
));
200 static void emit_retjcr
PARAMS ((const expressionS
*, int, const PTR
));
202 static void s_alpha_text
PARAMS ((int));
203 static void s_alpha_data
PARAMS ((int));
205 static void s_alpha_comm
PARAMS ((int));
206 static void s_alpha_rdata
PARAMS ((int));
209 static void s_alpha_sdata
PARAMS ((int));
212 static void s_alpha_section
PARAMS ((int));
213 static void s_alpha_ent
PARAMS ((int));
214 static void s_alpha_end
PARAMS ((int));
215 static void s_alpha_mask
PARAMS ((int));
216 static void s_alpha_frame
PARAMS ((int));
217 static void s_alpha_prologue
PARAMS ((int));
218 static void s_alpha_coff_wrapper
PARAMS ((int));
221 static void s_alpha_section
PARAMS ((int));
223 static void s_alpha_gprel32
PARAMS ((int));
224 static void s_alpha_float_cons
PARAMS ((int));
225 static void s_alpha_proc
PARAMS ((int));
226 static void s_alpha_set
PARAMS ((int));
227 static void s_alpha_base
PARAMS ((int));
228 static void s_alpha_align
PARAMS ((int));
229 static void s_alpha_stringer
PARAMS ((int));
230 static void s_alpha_space
PARAMS ((int));
232 static void create_literal_section
PARAMS ((const char *, segT
*, symbolS
**));
234 static void select_gp_value
PARAMS ((void));
236 static void alpha_align
PARAMS ((int, char *, symbolS
*, int));
239 /* Generic assembler global variables which must be defined by all
242 /* Characters which always start a comment. */
243 const char comment_chars
[] = "#";
245 /* Characters which start a comment at the beginning of a line. */
246 const char line_comment_chars
[] = "#";
248 /* Characters which may be used to separate multiple commands on a
250 const char line_separator_chars
[] = ";";
252 /* Characters which are used to indicate an exponent in a floating
254 const char EXP_CHARS
[] = "eE";
256 /* Characters which mean that a number is a floating point constant,
259 const char FLT_CHARS
[] = "dD";
261 /* XXX: Do all of these really get used on the alpha?? */
262 char FLT_CHARS
[] = "rRsSfFdDxXpP";
266 const char *md_shortopts
= "Fm:g+1h:HG:";
268 const char *md_shortopts
= "Fm:gG:";
271 struct option md_longopts
[] = {
272 #define OPTION_32ADDR (OPTION_MD_BASE)
273 { "32addr", no_argument
, NULL
, OPTION_32ADDR
},
274 #define OPTION_RELAX (OPTION_32ADDR+1)
275 { "relax", no_argument
, NULL
, OPTION_RELAX
},
277 #define OPTION_MDEBUG (OPTION_RELAX+1)
278 #define OPTION_NO_MDEBUG (OPTION_MDEBUG+1)
279 { "mdebug", no_argument
, NULL
, OPTION_MDEBUG
},
280 { "no-mdebug", no_argument
, NULL
, OPTION_NO_MDEBUG
},
282 { NULL
, no_argument
, NULL
, 0 }
285 size_t md_longopts_size
= sizeof(md_longopts
);
290 #define AXP_REG_R16 16
291 #define AXP_REG_R17 17
293 #define AXP_REG_T9 22
295 #define AXP_REG_T10 23
297 #define AXP_REG_T11 24
299 #define AXP_REG_T12 25
300 #define AXP_REG_AI 25
302 #define AXP_REG_FP 29
305 #define AXP_REG_GP AXP_REG_PV
306 #endif /* OBJ_EVAX */
308 /* The cpu for which we are generating code */
309 static unsigned alpha_target
= AXP_OPCODE_BASE
;
310 static const char *alpha_target_name
= "<all>";
312 /* The hash table of instruction opcodes */
313 static struct hash_control
*alpha_opcode_hash
;
315 /* The hash table of macro opcodes */
316 static struct hash_control
*alpha_macro_hash
;
319 /* The $gp relocation symbol */
320 static symbolS
*alpha_gp_symbol
;
322 /* XXX: what is this, and why is it exported? */
323 valueT alpha_gp_value
;
326 /* The current $gp register */
327 static int alpha_gp_register
= AXP_REG_GP
;
329 /* A table of the register symbols */
330 static symbolS
*alpha_register_table
[64];
332 /* Constant sections, or sections of constants */
334 static segT alpha_lita_section
;
335 static segT alpha_lit4_section
;
338 static segT alpha_link_section
;
339 static segT alpha_ctors_section
;
340 static segT alpha_dtors_section
;
342 static segT alpha_lit8_section
;
344 /* Symbols referring to said sections. */
346 static symbolS
*alpha_lita_symbol
;
347 static symbolS
*alpha_lit4_symbol
;
350 static symbolS
*alpha_link_symbol
;
351 static symbolS
*alpha_ctors_symbol
;
352 static symbolS
*alpha_dtors_symbol
;
354 static symbolS
*alpha_lit8_symbol
;
356 /* Literal for .litX+0x8000 within .lita */
358 static offsetT alpha_lit4_literal
;
359 static offsetT alpha_lit8_literal
;
362 /* The active .ent symbol. */
364 static symbolS
*alpha_cur_ent_sym
;
367 /* Is the assembler not allowed to use $at? */
368 static int alpha_noat_on
= 0;
370 /* Are macros enabled? */
371 static int alpha_macros_on
= 1;
373 /* Are floats disabled? */
374 static int alpha_nofloats_on
= 0;
376 /* Are addresses 32 bit? */
377 static int alpha_addr32_on
= 0;
379 /* Symbol labelling the current insn. When the Alpha gas sees
382 and the section happens to not be on an eight byte boundary, it
383 will align both the symbol and the .quad to an eight byte boundary. */
384 static symbolS
*alpha_insn_label
;
386 /* Whether we should automatically align data generation pseudo-ops.
387 .align 0 will turn this off. */
388 static int alpha_auto_align_on
= 1;
390 /* The known current alignment of the current section. */
391 static int alpha_current_align
;
393 /* These are exported to ECOFF code. */
394 unsigned long alpha_gprmask
, alpha_fprmask
;
396 /* Whether the debugging option was seen. */
397 static int alpha_debug
;
400 /* Whether we are emitting an mdebug section. */
401 int alpha_flag_mdebug
= 1;
404 /* Don't fully resolve relocations, allowing code movement in the linker. */
405 static int alpha_flag_relax
;
407 /* What value to give to bfd_set_gp_size. */
408 static int g_switch_value
= 8;
411 /* Collect information about current procedure here. */
413 symbolS
*symbol
; /* proc pdesc symbol */
415 int framereg
; /* register for frame pointer */
416 int framesize
; /* size of frame */
426 static int alpha_flag_hash_long_names
= 0; /* -+ */
427 static int alpha_flag_show_after_trunc
= 0; /* -H */
429 /* If the -+ switch is given, then a hash is appended to any name that is
430 * longer than 64 characters, else longer symbol names are truncated.
435 /* A table of CPU names and opcode sets. */
437 static const struct cpu_type
443 /* Ad hoc convention: cpu number gets palcode, process code doesn't.
444 This supports usage under DU 4.0b that does ".arch ev4", and
445 usage in MILO that does -m21064. Probably something more
446 specific like -m21064-pal should be used, but oh well. */
448 { "21064", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
449 { "21064a", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
450 { "21066", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
451 { "21068", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
452 { "21164", AXP_OPCODE_BASE
|AXP_OPCODE_EV5
},
453 { "21164a", AXP_OPCODE_BASE
|AXP_OPCODE_EV5
|AXP_OPCODE_BWX
},
454 { "21164pc", (AXP_OPCODE_BASE
|AXP_OPCODE_EV5
|AXP_OPCODE_BWX
456 { "21264", (AXP_OPCODE_BASE
|AXP_OPCODE_EV6
|AXP_OPCODE_BWX
457 |AXP_OPCODE_MAX
|AXP_OPCODE_CIX
) },
459 { "ev4", AXP_OPCODE_BASE
},
460 { "ev45", AXP_OPCODE_BASE
},
461 { "lca45", AXP_OPCODE_BASE
},
462 { "ev5", AXP_OPCODE_BASE
},
463 { "ev56", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
},
464 { "pca56", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
|AXP_OPCODE_MAX
},
465 { "ev6", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
|AXP_OPCODE_MAX
|AXP_OPCODE_CIX
},
467 { "all", AXP_OPCODE_BASE
},
471 /* The macro table */
473 static const struct alpha_macro alpha_macros
[] = {
474 /* Load/Store macros */
475 { "lda", emit_lda
, NULL
,
476 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
477 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
478 { "ldah", emit_ldah
, NULL
,
479 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
481 { "ldl", emit_ir_load
, "ldl",
482 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
483 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
484 { "ldl_l", emit_ir_load
, "ldl_l",
485 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
486 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
487 { "ldq", emit_ir_load
, "ldq",
488 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
489 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
490 { "ldq_l", emit_ir_load
, "ldq_l",
491 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
492 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
493 { "ldq_u", emit_ir_load
, "ldq_u",
494 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
495 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
496 { "ldf", emit_loadstore
, "ldf",
497 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
498 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
499 { "ldg", emit_loadstore
, "ldg",
500 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
501 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
502 { "lds", emit_loadstore
, "lds",
503 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
504 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
505 { "ldt", emit_loadstore
, "ldt",
506 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
507 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
509 { "ldb", emit_ldX
, (PTR
)0,
510 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
511 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
512 { "ldbu", emit_ldXu
, (PTR
)0,
513 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
514 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
515 { "ldw", emit_ldX
, (PTR
)1,
516 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
517 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
518 { "ldwu", emit_ldXu
, (PTR
)1,
519 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
520 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
522 { "uldw", emit_uldX
, (PTR
)1,
523 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
524 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
525 { "uldwu", emit_uldXu
, (PTR
)1,
526 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
527 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
528 { "uldl", emit_uldX
, (PTR
)2,
529 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
530 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
531 { "uldlu", emit_uldXu
, (PTR
)2,
532 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
533 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
534 { "uldq", emit_uldXu
, (PTR
)3,
535 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
536 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
538 { "ldgp", emit_ldgp
, NULL
,
539 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
} },
541 { "ldi", emit_lda
, NULL
,
542 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
543 { "ldil", emit_ldil
, NULL
,
544 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
545 { "ldiq", emit_lda
, NULL
,
546 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
548 { "ldif" emit_ldiq
, NULL
,
549 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
550 { "ldid" emit_ldiq
, NULL
,
551 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
552 { "ldig" emit_ldiq
, NULL
,
553 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
554 { "ldis" emit_ldiq
, NULL
,
555 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
556 { "ldit" emit_ldiq
, NULL
,
557 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
560 { "stl", emit_loadstore
, "stl",
561 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
562 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
563 { "stl_c", emit_loadstore
, "stl_c",
564 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
565 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
566 { "stq", emit_loadstore
, "stq",
567 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
568 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
569 { "stq_c", emit_loadstore
, "stq_c",
570 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
571 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
572 { "stq_u", emit_loadstore
, "stq_u",
573 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
574 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
575 { "stf", emit_loadstore
, "stf",
576 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
577 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
578 { "stg", emit_loadstore
, "stg",
579 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
580 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
581 { "sts", emit_loadstore
, "sts",
582 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
583 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
584 { "stt", emit_loadstore
, "stt",
585 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
586 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
588 { "stb", emit_stX
, (PTR
)0,
589 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
590 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
591 { "stw", emit_stX
, (PTR
)1,
592 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
593 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
594 { "ustw", emit_ustX
, (PTR
)1,
595 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
596 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
597 { "ustl", emit_ustX
, (PTR
)2,
598 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
599 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
600 { "ustq", emit_ustX
, (PTR
)3,
601 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
602 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
604 /* Arithmetic macros */
606 { "absl" emit_absl
, 1, { IR
} },
607 { "absl" emit_absl
, 2, { IR
, IR
} },
608 { "absl" emit_absl
, 2, { EXP
, IR
} },
609 { "absq" emit_absq
, 1, { IR
} },
610 { "absq" emit_absq
, 2, { IR
, IR
} },
611 { "absq" emit_absq
, 2, { EXP
, IR
} },
614 { "sextb", emit_sextX
, (PTR
)0,
615 { MACRO_IR
, MACRO_IR
, MACRO_EOA
,
617 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
618 { "sextw", emit_sextX
, (PTR
)1,
619 { MACRO_IR
, MACRO_IR
, MACRO_EOA
,
621 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
623 { "divl", emit_division
, "__divl",
624 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
625 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
626 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
627 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
628 { "divlu", emit_division
, "__divlu",
629 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
630 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
631 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
632 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
633 { "divq", emit_division
, "__divq",
634 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
635 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
636 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
637 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
638 { "divqu", emit_division
, "__divqu",
639 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
640 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
641 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
642 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
643 { "reml", emit_division
, "__reml",
644 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
645 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
646 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
647 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
648 { "remlu", emit_division
, "__remlu",
649 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
650 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
651 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
652 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
653 { "remq", emit_division
, "__remq",
654 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
655 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
656 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
657 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
658 { "remqu", emit_division
, "__remqu",
659 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
660 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
661 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
662 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
664 { "jsr", emit_jsrjmp
, "jsr",
665 { MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
666 MACRO_PIR
, MACRO_EOA
,
667 MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
668 MACRO_EXP
, MACRO_EOA
} },
669 { "jmp", emit_jsrjmp
, "jmp",
670 { MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
671 MACRO_PIR
, MACRO_EOA
,
672 MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
673 MACRO_EXP
, MACRO_EOA
} },
674 { "ret", emit_retjcr
, "ret",
675 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
677 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
678 MACRO_PIR
, MACRO_EOA
,
679 MACRO_EXP
, MACRO_EOA
,
681 { "jcr", emit_retjcr
, "jcr",
682 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
684 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
685 MACRO_PIR
, MACRO_EOA
,
686 MACRO_EXP
, MACRO_EOA
,
688 { "jsr_coroutine", emit_retjcr
, "jcr",
689 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
691 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
692 MACRO_PIR
, MACRO_EOA
,
693 MACRO_EXP
, MACRO_EOA
,
697 static const unsigned int alpha_num_macros
698 = sizeof(alpha_macros
) / sizeof(*alpha_macros
);
700 /* Public interface functions */
702 /* This function is called once, at assembler startup time. It sets
703 up all the tables, etc. that the MD part of the assembler will
704 need, that can be determined before arguments are parsed. */
711 /* Verify that X_op field is wide enough. */
715 assert (e
.X_op
== O_max
);
718 /* Create the opcode hash table */
720 alpha_opcode_hash
= hash_new ();
721 for (i
= 0; i
< alpha_num_opcodes
; )
723 const char *name
, *retval
, *slash
;
725 name
= alpha_opcodes
[i
].name
;
726 retval
= hash_insert (alpha_opcode_hash
, name
, (PTR
)&alpha_opcodes
[i
]);
728 as_fatal (_("internal error: can't hash opcode `%s': %s"), name
, retval
);
730 /* Some opcodes include modifiers of various sorts with a "/mod"
731 syntax, like the architecture manual suggests. However, for
732 use with gcc at least, we also need access to those same opcodes
735 if ((slash
= strchr (name
, '/')) != NULL
)
737 char *p
= xmalloc (strlen (name
));
738 memcpy (p
, name
, slash
- name
);
739 strcpy (p
+ (slash
- name
), slash
+ 1);
741 (void)hash_insert(alpha_opcode_hash
, p
, (PTR
)&alpha_opcodes
[i
]);
742 /* Ignore failures -- the opcode table does duplicate some
743 variants in different forms, like "hw_stq" and "hw_st/q". */
746 while (++i
< alpha_num_opcodes
747 && (alpha_opcodes
[i
].name
== name
748 || !strcmp (alpha_opcodes
[i
].name
, name
)))
752 /* Create the macro hash table */
754 alpha_macro_hash
= hash_new ();
755 for (i
= 0; i
< alpha_num_macros
; )
757 const char *name
, *retval
;
759 name
= alpha_macros
[i
].name
;
760 retval
= hash_insert (alpha_macro_hash
, name
, (PTR
)&alpha_macros
[i
]);
762 as_fatal (_("internal error: can't hash macro `%s': %s"), name
, retval
);
764 while (++i
< alpha_num_macros
765 && (alpha_macros
[i
].name
== name
766 || !strcmp (alpha_macros
[i
].name
, name
)))
770 /* Construct symbols for each of the registers */
772 for (i
= 0; i
< 32; ++i
)
775 sprintf(name
, "$%d", i
);
776 alpha_register_table
[i
] = symbol_create(name
, reg_section
, i
,
782 sprintf(name
, "$f%d", i
-32);
783 alpha_register_table
[i
] = symbol_create(name
, reg_section
, i
,
787 /* Create the special symbols and sections we'll be using */
789 /* So .sbss will get used for tiny objects. */
790 bfd_set_gp_size (stdoutput
, g_switch_value
);
793 create_literal_section (".lita", &alpha_lita_section
, &alpha_lita_symbol
);
795 /* For handling the GP, create a symbol that won't be output in the
796 symbol table. We'll edit it out of relocs later. */
797 alpha_gp_symbol
= symbol_create ("<GP value>", alpha_lita_section
, 0x8000,
802 create_literal_section (".link", &alpha_link_section
, &alpha_link_symbol
);
808 segT sec
= subseg_new(".mdebug", (subsegT
)0);
809 bfd_set_section_flags(stdoutput
, sec
, SEC_HAS_CONTENTS
|SEC_READONLY
);
810 bfd_set_section_alignment(stdoutput
, sec
, 3);
814 subseg_set(text_section
, 0);
817 /* The public interface to the instruction assembler. */
823 char opname
[32]; /* current maximum is 13 */
824 expressionS tok
[MAX_INSN_ARGS
];
828 /* split off the opcode */
829 opnamelen
= strspn (str
, "abcdefghijklmnopqrstuvwxyz_/468");
830 trunclen
= (opnamelen
< sizeof (opname
) - 1
832 : sizeof (opname
) - 1);
833 memcpy (opname
, str
, trunclen
);
834 opname
[trunclen
] = '\0';
836 /* tokenize the rest of the line */
837 if ((ntok
= tokenize_arguments (str
+ opnamelen
, tok
, MAX_INSN_ARGS
)) < 0)
839 as_bad (_("syntax error"));
844 assemble_tokens (opname
, tok
, ntok
, alpha_macros_on
);
847 /* Round up a section's size to the appropriate boundary. */
850 md_section_align (seg
, size
)
854 int align
= bfd_get_section_alignment(stdoutput
, seg
);
855 valueT mask
= ((valueT
)1 << align
) - 1;
857 return (size
+ mask
) & ~mask
;
860 /* Turn a string in input_line_pointer into a floating point constant
861 of type type, and store the appropriate bytes in *litP. The number
862 of LITTLENUMS emitted is stored in *sizeP. An error message is
863 returned, or NULL on OK. */
865 /* Equal to MAX_PRECISION in atof-ieee.c */
866 #define MAX_LITTLENUMS 6
868 extern char *vax_md_atof
PARAMS ((int, char *, int *));
871 md_atof (type
, litP
, sizeP
)
877 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
878 LITTLENUM_TYPE
*wordP
;
885 /* VAX md_atof doesn't like "G" for some reason. */
889 return vax_md_atof (type
, litP
, sizeP
);
912 return _("Bad call to MD_ATOF()");
914 t
= atof_ieee (input_line_pointer
, type
, words
);
916 input_line_pointer
= t
;
917 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
919 for (wordP
= words
+ prec
- 1; prec
--;)
921 md_number_to_chars (litP
, (long) (*wordP
--), sizeof (LITTLENUM_TYPE
));
922 litP
+= sizeof (LITTLENUM_TYPE
);
928 /* Take care of the target-specific command-line options. */
931 md_parse_option (c
, arg
)
938 alpha_nofloats_on
= 1;
950 g_switch_value
= atoi(arg
);
955 const struct cpu_type
*p
;
956 for (p
= cpu_types
; p
->name
; ++p
)
957 if (strcmp(arg
, p
->name
) == 0)
959 alpha_target_name
= p
->name
, alpha_target
= p
->flags
;
962 as_warn(_("Unknown CPU identifier `%s'"), arg
);
968 case '+': /* For g++. Hash any name > 63 chars long. */
969 alpha_flag_hash_long_names
= 1;
972 case 'H': /* Show new symbol after hash truncation */
973 alpha_flag_show_after_trunc
= 1;
976 case 'h': /* for gnu-c/vax compatibility. */
981 alpha_flag_relax
= 1;
986 alpha_flag_mdebug
= 1;
988 case OPTION_NO_MDEBUG
:
989 alpha_flag_mdebug
= 0;
1000 /* Print a description of the command-line options that we accept. */
1003 md_show_usage (stream
)
1008 -32addr treat addresses as 32-bit values\n\
1009 -F lack floating point instructions support\n\
1010 -mev4 | -mev45 | -mev5 | -mev56 | -mpca56 | -mev6 | -mall\n\
1011 specify variant of Alpha architecture\n\
1012 -m21064 | -m21066 | -m21164 | -m21164a | -m21164pc | -m21264\n\
1013 these variants include PALcode opcodes\n"),
1018 -+ hash encode (don't truncate) names longer than 64 characters\n\
1019 -H show new symbol after hash truncation\n"),
1024 /* Decide from what point a pc-relative relocation is relative to,
1025 relative to the pc-relative fixup. Er, relatively speaking. */
1028 md_pcrel_from (fixP
)
1031 valueT addr
= fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
1032 switch (fixP
->fx_r_type
)
1034 case BFD_RELOC_ALPHA_GPDISP
:
1035 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1036 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1039 return fixP
->fx_size
+ addr
;
1043 /* Attempt to simplify or even eliminate a fixup. The return value is
1044 ignored; perhaps it was once meaningful, but now it is historical.
1045 To indicate that a fixup has been eliminated, set fixP->fx_done.
1047 For ELF, here it is that we transform the GPDISP_HI16 reloc we used
1048 internally into the GPDISP reloc used externally. We had to do
1049 this so that we'd have the GPDISP_LO16 reloc as a tag to compute
1050 the distance to the "lda" instruction for setting the addend to
1054 md_apply_fix (fixP
, valueP
)
1058 char * const fixpos
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
1059 valueT value
= *valueP
;
1060 unsigned image
, size
;
1062 switch (fixP
->fx_r_type
)
1064 /* The GPDISP relocations are processed internally with a symbol
1065 referring to the current function; we need to drop in a value
1066 which, when added to the address of the start of the function,
1067 gives the desired GP. */
1068 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1070 fixS
*next
= fixP
->fx_next
;
1071 assert (next
->fx_r_type
== BFD_RELOC_ALPHA_GPDISP_LO16
);
1073 fixP
->fx_offset
= (next
->fx_frag
->fr_address
+ next
->fx_where
1074 - fixP
->fx_frag
->fr_address
- fixP
->fx_where
);
1076 value
= (value
- sign_extend_16 (value
)) >> 16;
1079 fixP
->fx_r_type
= BFD_RELOC_ALPHA_GPDISP
;
1083 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1084 value
= sign_extend_16 (value
);
1085 fixP
->fx_offset
= 0;
1091 fixP
->fx_addsy
= section_symbol (now_seg
);
1092 md_number_to_chars (fixpos
, value
, 2);
1097 fixP
->fx_r_type
= BFD_RELOC_16_PCREL
;
1102 fixP
->fx_r_type
= BFD_RELOC_32_PCREL
;
1107 fixP
->fx_r_type
= BFD_RELOC_64_PCREL
;
1110 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
1112 md_number_to_chars (fixpos
, value
, size
);
1118 case BFD_RELOC_GPREL32
:
1119 assert (fixP
->fx_subsy
== alpha_gp_symbol
);
1121 /* FIXME: inherited this obliviousness of `value' -- why? */
1122 md_number_to_chars (fixpos
, -alpha_gp_value
, 4);
1126 case BFD_RELOC_GPREL32
:
1130 case BFD_RELOC_23_PCREL_S2
:
1131 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
1133 image
= bfd_getl32(fixpos
);
1134 image
= (image
& ~0x1FFFFF) | ((value
>> 2) & 0x1FFFFF);
1139 case BFD_RELOC_ALPHA_HINT
:
1140 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
1142 image
= bfd_getl32(fixpos
);
1143 image
= (image
& ~0x3FFF) | ((value
>> 2) & 0x3FFF);
1149 case BFD_RELOC_ALPHA_LITERAL
:
1150 md_number_to_chars (fixpos
, value
, 2);
1153 case BFD_RELOC_ALPHA_LITUSE
:
1157 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1158 case BFD_RELOC_ALPHA_LITUSE
:
1162 case BFD_RELOC_ALPHA_LINKAGE
:
1163 case BFD_RELOC_ALPHA_CODEADDR
:
1169 const struct alpha_operand
*operand
;
1171 if ((int)fixP
->fx_r_type
>= 0)
1172 as_fatal (_("unhandled relocation type %s"),
1173 bfd_get_reloc_code_name (fixP
->fx_r_type
));
1175 assert (-(int)fixP
->fx_r_type
< (int)alpha_num_operands
);
1176 operand
= &alpha_operands
[-(int)fixP
->fx_r_type
];
1178 /* The rest of these fixups only exist internally during symbol
1179 resolution and have no representation in the object file.
1180 Therefore they must be completely resolved as constants. */
1182 if (fixP
->fx_addsy
!= 0
1183 && S_GET_SEGMENT (fixP
->fx_addsy
) != absolute_section
)
1184 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
1185 _("non-absolute expression in constant field"));
1187 image
= bfd_getl32(fixpos
);
1188 image
= insert_operand(image
, operand
, (offsetT
)value
,
1189 fixP
->fx_file
, fixP
->fx_line
);
1194 if (fixP
->fx_addsy
!= 0 || fixP
->fx_pcrel
!= 0)
1198 as_warn_where(fixP
->fx_file
, fixP
->fx_line
,
1199 _("type %d reloc done?\n"), (int)fixP
->fx_r_type
);
1204 md_number_to_chars(fixpos
, image
, 4);
1212 * Look for a register name in the given symbol.
1216 md_undefined_symbol(name
)
1221 int is_float
= 0, num
;
1226 if (name
[1] == 'p' && name
[2] == '\0')
1227 return alpha_register_table
[AXP_REG_FP
];
1232 if (!isdigit(*++name
))
1236 case '0': case '1': case '2': case '3': case '4':
1237 case '5': case '6': case '7': case '8': case '9':
1238 if (name
[1] == '\0')
1239 num
= name
[0] - '0';
1240 else if (name
[0] != '0' && isdigit(name
[1]) && name
[2] == '\0')
1242 num
= (name
[0] - '0') * 10 + name
[1] - '0';
1249 if (!alpha_noat_on
&& num
== AXP_REG_AT
)
1250 as_warn(_("Used $at without \".set noat\""));
1251 return alpha_register_table
[num
+ is_float
];
1254 if (name
[1] == 't' && name
[2] == '\0')
1257 as_warn(_("Used $at without \".set noat\""));
1258 return alpha_register_table
[AXP_REG_AT
];
1263 if (name
[1] == 'p' && name
[2] == '\0')
1264 return alpha_register_table
[alpha_gp_register
];
1268 if (name
[1] == 'p' && name
[2] == '\0')
1269 return alpha_register_table
[AXP_REG_SP
];
1277 /* @@@ Magic ECOFF bits. */
1280 alpha_frob_ecoff_data ()
1283 /* $zero and $f31 are read-only */
1284 alpha_gprmask
&= ~1;
1285 alpha_fprmask
&= ~1;
1289 /* Hook to remember a recently defined label so that the auto-align
1290 code can adjust the symbol after we know what alignment will be
1294 alpha_define_label (sym
)
1297 alpha_insn_label
= sym
;
1300 /* Return true if we must always emit a reloc for a type and false if
1301 there is some hope of resolving it a assembly time. */
1304 alpha_force_relocation (f
)
1307 if (alpha_flag_relax
)
1310 switch (f
->fx_r_type
)
1312 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1313 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1314 case BFD_RELOC_ALPHA_GPDISP
:
1316 case BFD_RELOC_ALPHA_LITERAL
:
1319 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1321 case BFD_RELOC_ALPHA_LITUSE
:
1322 case BFD_RELOC_GPREL32
:
1324 case BFD_RELOC_ALPHA_LINKAGE
:
1325 case BFD_RELOC_ALPHA_CODEADDR
:
1329 case BFD_RELOC_23_PCREL_S2
:
1332 case BFD_RELOC_ALPHA_HINT
:
1336 assert((int)f
->fx_r_type
< 0 && -(int)f
->fx_r_type
< (int)alpha_num_operands
);
1341 /* Return true if we can partially resolve a relocation now. */
1344 alpha_fix_adjustable (f
)
1348 /* Prevent all adjustments to global symbols */
1349 if (S_IS_EXTERN (f
->fx_addsy
) || S_IS_WEAK (f
->fx_addsy
))
1353 /* Are there any relocation types for which we must generate a reloc
1354 but we can adjust the values contained within it? */
1355 switch (f
->fx_r_type
)
1357 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1358 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1359 case BFD_RELOC_ALPHA_GPDISP
:
1363 case BFD_RELOC_ALPHA_LITERAL
:
1366 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1369 case BFD_RELOC_ALPHA_LINKAGE
:
1370 case BFD_RELOC_ALPHA_CODEADDR
:
1374 case BFD_RELOC_ALPHA_LITUSE
:
1377 case BFD_RELOC_GPREL32
:
1378 case BFD_RELOC_23_PCREL_S2
:
1381 case BFD_RELOC_ALPHA_HINT
:
1385 assert ((int)f
->fx_r_type
< 0
1386 && - (int)f
->fx_r_type
< (int)alpha_num_operands
);
1392 /* Generate the BFD reloc to be stuck in the object file from the
1393 fixup used internally in the assembler. */
1396 tc_gen_reloc (sec
, fixp
)
1397 asection
*sec ATTRIBUTE_UNUSED
;
1402 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
1403 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
1404 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
1405 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
1407 /* Make sure none of our internal relocations make it this far.
1408 They'd better have been fully resolved by this point. */
1409 assert ((int)fixp
->fx_r_type
> 0);
1411 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
1412 if (reloc
->howto
== NULL
)
1414 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1415 _("cannot represent `%s' relocation in object file"),
1416 bfd_get_reloc_code_name (fixp
->fx_r_type
));
1420 if (!fixp
->fx_pcrel
!= !reloc
->howto
->pc_relative
)
1422 as_fatal (_("internal error? cannot generate `%s' relocation"),
1423 bfd_get_reloc_code_name (fixp
->fx_r_type
));
1425 assert (!fixp
->fx_pcrel
== !reloc
->howto
->pc_relative
);
1428 if (fixp
->fx_r_type
== BFD_RELOC_ALPHA_LITERAL
)
1430 /* fake out bfd_perform_relocation. sigh */
1431 reloc
->addend
= -alpha_gp_value
;
1436 reloc
->addend
= fixp
->fx_offset
;
1439 * Ohhh, this is ugly. The problem is that if this is a local global
1440 * symbol, the relocation will entirely be performed at link time, not
1441 * at assembly time. bfd_perform_reloc doesn't know about this sort
1442 * of thing, and as a result we need to fake it out here.
1444 if ((S_IS_EXTERN (fixp
->fx_addsy
) || S_IS_WEAK (fixp
->fx_addsy
))
1445 && !S_IS_COMMON(fixp
->fx_addsy
))
1446 reloc
->addend
-= symbol_get_bfdsym (fixp
->fx_addsy
)->value
;
1453 /* Parse a register name off of the input_line and return a register
1454 number. Gets md_undefined_symbol above to do the register name
1457 Only called as a part of processing the ECOFF .frame directive. */
1460 tc_get_register (frame
)
1461 int frame ATTRIBUTE_UNUSED
;
1463 int framereg
= AXP_REG_SP
;
1466 if (*input_line_pointer
== '$')
1468 char *s
= input_line_pointer
;
1469 char c
= get_symbol_end ();
1470 symbolS
*sym
= md_undefined_symbol (s
);
1472 *strchr(s
, '\0') = c
;
1473 if (sym
&& (framereg
= S_GET_VALUE (sym
)) <= 31)
1476 as_warn (_("frame reg expected, using $%d."), framereg
);
1479 note_gpreg (framereg
);
1483 /* This is called before the symbol table is processed. In order to
1484 work with gcc when using mips-tfile, we must keep all local labels.
1485 However, in other cases, we want to discard them. If we were
1486 called with -g, but we didn't see any debugging information, it may
1487 mean that gcc is smuggling debugging information through to
1488 mips-tfile, in which case we must generate all local labels. */
1493 alpha_frob_file_before_adjust ()
1495 if (alpha_debug
!= 0
1496 && ! ecoff_debugging_seen
)
1497 flag_keep_locals
= 1;
1500 #endif /* OBJ_ECOFF */
1502 /* Parse the arguments to an opcode. */
1505 tokenize_arguments (str
, tok
, ntok
)
1510 expressionS
*end_tok
= tok
+ ntok
;
1511 char *old_input_line_pointer
;
1512 int saw_comma
= 0, saw_arg
= 0;
1514 memset (tok
, 0, sizeof (*tok
) * ntok
);
1516 /* Save and restore input_line_pointer around this function */
1517 old_input_line_pointer
= input_line_pointer
;
1518 input_line_pointer
= str
;
1520 while (tok
< end_tok
&& *input_line_pointer
)
1523 switch (*input_line_pointer
)
1529 ++input_line_pointer
;
1530 if (saw_comma
|| !saw_arg
)
1537 char *hold
= input_line_pointer
++;
1539 /* First try for parenthesized register ... */
1541 if (*input_line_pointer
== ')' && tok
->X_op
== O_register
)
1543 tok
->X_op
= (saw_comma
? O_cpregister
: O_pregister
);
1546 ++input_line_pointer
;
1551 /* ... then fall through to plain expression */
1552 input_line_pointer
= hold
;
1556 if (saw_arg
&& !saw_comma
)
1559 if (tok
->X_op
== O_illegal
|| tok
->X_op
== O_absent
)
1572 input_line_pointer
= old_input_line_pointer
;
1573 return ntok
- (end_tok
- tok
);
1576 input_line_pointer
= old_input_line_pointer
;
1580 /* Search forward through all variants of an opcode looking for a
1583 static const struct alpha_opcode
*
1584 find_opcode_match(first_opcode
, tok
, pntok
, pcpumatch
)
1585 const struct alpha_opcode
*first_opcode
;
1586 const expressionS
*tok
;
1590 const struct alpha_opcode
*opcode
= first_opcode
;
1592 int got_cpu_match
= 0;
1596 const unsigned char *opidx
;
1599 /* Don't match opcodes that don't exist on this architecture */
1600 if (!(opcode
->flags
& alpha_target
))
1605 for (opidx
= opcode
->operands
; *opidx
; ++opidx
)
1607 const struct alpha_operand
*operand
= &alpha_operands
[*opidx
];
1609 /* only take input from real operands */
1610 if (operand
->flags
& AXP_OPERAND_FAKE
)
1613 /* when we expect input, make sure we have it */
1616 if ((operand
->flags
& AXP_OPERAND_OPTIONAL_MASK
) == 0)
1621 /* match operand type with expression type */
1622 switch (operand
->flags
& AXP_OPERAND_TYPECHECK_MASK
)
1624 case AXP_OPERAND_IR
:
1625 if (tok
[tokidx
].X_op
!= O_register
1626 || !is_ir_num(tok
[tokidx
].X_add_number
))
1629 case AXP_OPERAND_FPR
:
1630 if (tok
[tokidx
].X_op
!= O_register
1631 || !is_fpr_num(tok
[tokidx
].X_add_number
))
1634 case AXP_OPERAND_IR
|AXP_OPERAND_PARENS
:
1635 if (tok
[tokidx
].X_op
!= O_pregister
1636 || !is_ir_num(tok
[tokidx
].X_add_number
))
1639 case AXP_OPERAND_IR
|AXP_OPERAND_PARENS
|AXP_OPERAND_COMMA
:
1640 if (tok
[tokidx
].X_op
!= O_cpregister
1641 || !is_ir_num(tok
[tokidx
].X_add_number
))
1645 case AXP_OPERAND_RELATIVE
:
1646 case AXP_OPERAND_SIGNED
:
1647 case AXP_OPERAND_UNSIGNED
:
1648 switch (tok
[tokidx
].X_op
)
1663 /* everything else should have been fake */
1669 /* possible match -- did we use all of our input? */
1678 while (++opcode
-alpha_opcodes
< alpha_num_opcodes
1679 && !strcmp(opcode
->name
, first_opcode
->name
));
1682 *pcpumatch
= got_cpu_match
;
1687 /* Search forward through all variants of a macro looking for a syntax
1690 static const struct alpha_macro
*
1691 find_macro_match(first_macro
, tok
, pntok
)
1692 const struct alpha_macro
*first_macro
;
1693 const expressionS
*tok
;
1696 const struct alpha_macro
*macro
= first_macro
;
1701 const enum alpha_macro_arg
*arg
= macro
->argsets
;
1716 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_register
1717 || !is_ir_num(tok
[tokidx
].X_add_number
))
1722 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_pregister
1723 || !is_ir_num(tok
[tokidx
].X_add_number
))
1728 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_cpregister
1729 || !is_ir_num(tok
[tokidx
].X_add_number
))
1734 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_register
1735 || !is_fpr_num(tok
[tokidx
].X_add_number
))
1743 switch (tok
[tokidx
].X_op
)
1759 while (*arg
!= MACRO_EOA
)
1767 while (++macro
-alpha_macros
< alpha_num_macros
1768 && !strcmp(macro
->name
, first_macro
->name
));
1773 /* Insert an operand value into an instruction. */
1776 insert_operand(insn
, operand
, val
, file
, line
)
1778 const struct alpha_operand
*operand
;
1783 if (operand
->bits
!= 32 && !(operand
->flags
& AXP_OPERAND_NOOVERFLOW
))
1787 if (operand
->flags
& AXP_OPERAND_SIGNED
)
1789 max
= (1 << (operand
->bits
- 1)) - 1;
1790 min
= -(1 << (operand
->bits
- 1));
1794 max
= (1 << operand
->bits
) - 1;
1798 if (val
< min
|| val
> max
)
1801 _("operand out of range (%s not between %d and %d)");
1802 char buf
[sizeof (val
) * 3 + 2];
1804 sprint_value(buf
, val
);
1806 as_warn_where(file
, line
, err
, buf
, min
, max
);
1808 as_warn(err
, buf
, min
, max
);
1812 if (operand
->insert
)
1814 const char *errmsg
= NULL
;
1816 insn
= (*operand
->insert
) (insn
, val
, &errmsg
);
1821 insn
|= ((val
& ((1 << operand
->bits
) - 1)) << operand
->shift
);
1827 * Turn an opcode description and a set of arguments into
1828 * an instruction and a fixup.
1832 assemble_insn(opcode
, tok
, ntok
, insn
)
1833 const struct alpha_opcode
*opcode
;
1834 const expressionS
*tok
;
1836 struct alpha_insn
*insn
;
1838 const unsigned char *argidx
;
1842 memset (insn
, 0, sizeof (*insn
));
1843 image
= opcode
->opcode
;
1845 for (argidx
= opcode
->operands
; *argidx
; ++argidx
)
1847 const struct alpha_operand
*operand
= &alpha_operands
[*argidx
];
1848 const expressionS
*t
= (const expressionS
*)0;
1850 if (operand
->flags
& AXP_OPERAND_FAKE
)
1852 /* fake operands take no value and generate no fixup */
1853 image
= insert_operand(image
, operand
, 0, NULL
, 0);
1859 switch (operand
->flags
& AXP_OPERAND_OPTIONAL_MASK
)
1861 case AXP_OPERAND_DEFAULT_FIRST
:
1864 case AXP_OPERAND_DEFAULT_SECOND
:
1867 case AXP_OPERAND_DEFAULT_ZERO
:
1869 static expressionS zero_exp
;
1871 zero_exp
.X_op
= O_constant
;
1872 zero_exp
.X_unsigned
= 1;
1887 image
= insert_operand(image
, operand
, regno(t
->X_add_number
),
1892 image
= insert_operand(image
, operand
, t
->X_add_number
, NULL
, 0);
1897 struct alpha_fixup
*fixup
;
1899 if (insn
->nfixups
>= MAX_INSN_FIXUPS
)
1900 as_fatal(_("too many fixups"));
1902 fixup
= &insn
->fixups
[insn
->nfixups
++];
1905 fixup
->reloc
= operand
->default_reloc
;
1915 * Actually output an instruction with its fixup.
1920 struct alpha_insn
*insn
;
1925 /* Take care of alignment duties */
1926 if (alpha_auto_align_on
&& alpha_current_align
< 2)
1927 alpha_align (2, (char *) NULL
, alpha_insn_label
, 0);
1928 if (alpha_current_align
> 2)
1929 alpha_current_align
= 2;
1930 alpha_insn_label
= NULL
;
1932 /* Write out the instruction. */
1934 md_number_to_chars (f
, insn
->insn
, 4);
1936 /* Apply the fixups in order */
1937 for (i
= 0; i
< insn
->nfixups
; ++i
)
1939 const struct alpha_operand
*operand
= (const struct alpha_operand
*)0;
1940 struct alpha_fixup
*fixup
= &insn
->fixups
[i
];
1944 /* Some fixups are only used internally and so have no howto */
1945 if ((int)fixup
->reloc
< 0)
1947 operand
= &alpha_operands
[-(int)fixup
->reloc
];
1949 pcrel
= ((operand
->flags
& AXP_OPERAND_RELATIVE
) != 0);
1952 /* These relocation types are only used internally. */
1953 else if (fixup
->reloc
== BFD_RELOC_ALPHA_GPDISP_HI16
1954 || fixup
->reloc
== BFD_RELOC_ALPHA_GPDISP_LO16
)
1956 size
= 2, pcrel
= 0;
1961 reloc_howto_type
*reloc_howto
1962 = bfd_reloc_type_lookup (stdoutput
, fixup
->reloc
);
1963 assert (reloc_howto
);
1965 size
= bfd_get_reloc_size (reloc_howto
);
1966 pcrel
= reloc_howto
->pc_relative
;
1968 assert (size
>= 1 && size
<= 4);
1970 fixP
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, size
,
1971 &fixup
->exp
, pcrel
, fixup
->reloc
);
1973 /* Turn off complaints that the addend is too large for some fixups */
1974 switch (fixup
->reloc
)
1976 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1978 case BFD_RELOC_ALPHA_LITERAL
:
1981 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1983 case BFD_RELOC_GPREL32
:
1984 fixP
->fx_no_overflow
= 1;
1988 if ((int)fixup
->reloc
< 0)
1990 if (operand
->flags
& AXP_OPERAND_NOOVERFLOW
)
1991 fixP
->fx_no_overflow
= 1;
1998 /* Given an opcode name and a pre-tokenized set of arguments, assemble
1999 the insn, but do not emit it.
2001 Note that this implies no macros allowed, since we can't store more
2002 than one insn in an insn structure. */
2005 assemble_tokens_to_insn(opname
, tok
, ntok
, insn
)
2007 const expressionS
*tok
;
2009 struct alpha_insn
*insn
;
2011 const struct alpha_opcode
*opcode
;
2013 /* search opcodes */
2014 opcode
= (const struct alpha_opcode
*) hash_find (alpha_opcode_hash
, opname
);
2018 opcode
= find_opcode_match (opcode
, tok
, &ntok
, &cpumatch
);
2021 assemble_insn (opcode
, tok
, ntok
, insn
);
2025 as_bad (_("inappropriate arguments for opcode `%s'"), opname
);
2027 as_bad (_("opcode `%s' not supported for target %s"), opname
,
2031 as_bad (_("unknown opcode `%s'"), opname
);
2034 /* Given an opcode name and a pre-tokenized set of arguments, take the
2035 opcode all the way through emission. */
2038 assemble_tokens (opname
, tok
, ntok
, local_macros_on
)
2040 const expressionS
*tok
;
2042 int local_macros_on
;
2044 int found_something
= 0;
2045 const struct alpha_opcode
*opcode
;
2046 const struct alpha_macro
*macro
;
2050 if (local_macros_on
)
2052 macro
= ((const struct alpha_macro
*)
2053 hash_find (alpha_macro_hash
, opname
));
2056 found_something
= 1;
2057 macro
= find_macro_match (macro
, tok
, &ntok
);
2060 (*macro
->emit
) (tok
, ntok
, macro
->arg
);
2066 /* search opcodes */
2067 opcode
= (const struct alpha_opcode
*) hash_find (alpha_opcode_hash
, opname
);
2070 found_something
= 1;
2071 opcode
= find_opcode_match (opcode
, tok
, &ntok
, &cpumatch
);
2074 struct alpha_insn insn
;
2075 assemble_insn (opcode
, tok
, ntok
, &insn
);
2081 if (found_something
)
2083 as_bad (_("inappropriate arguments for opcode `%s'"), opname
);
2085 as_bad (_("opcode `%s' not supported for target %s"), opname
,
2088 as_bad (_("unknown opcode `%s'"), opname
);
2092 /* Some instruction sets indexed by lg(size) */
2093 static const char * const sextX_op
[] = { "sextb", "sextw", "sextl", NULL
};
2094 static const char * const insXl_op
[] = { "insbl", "inswl", "insll", "insql" };
2095 static const char * const insXh_op
[] = { NULL
, "inswh", "inslh", "insqh" };
2096 static const char * const extXl_op
[] = { "extbl", "extwl", "extll", "extql" };
2097 static const char * const extXh_op
[] = { NULL
, "extwh", "extlh", "extqh" };
2098 static const char * const mskXl_op
[] = { "mskbl", "mskwl", "mskll", "mskql" };
2099 static const char * const mskXh_op
[] = { NULL
, "mskwh", "msklh", "mskqh" };
2100 static const char * const stX_op
[] = { "stb", "stw", "stl", "stq" };
2101 static const char * const ldX_op
[] = { "ldb", "ldw", "ldll", "ldq" };
2102 static const char * const ldXu_op
[] = { "ldbu", "ldwu", NULL
, NULL
};
2104 /* Implement the ldgp macro. */
2107 emit_ldgp (tok
, ntok
, unused
)
2108 const expressionS
*tok
;
2109 int ntok ATTRIBUTE_UNUSED
;
2110 const PTR unused ATTRIBUTE_UNUSED
;
2115 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
2116 /* from "ldgp r1,n(r2)", generate "ldah r1,X(R2); lda r1,Y(r1)"
2117 with appropriate constants and relocations. */
2118 struct alpha_insn insn
;
2119 expressionS newtok
[3];
2123 if (regno (tok
[2].X_add_number
) == AXP_REG_PV
)
2124 ecoff_set_gp_prolog_size (0);
2128 set_tok_const (newtok
[1], 0);
2131 assemble_tokens_to_insn ("ldah", newtok
, 3, &insn
);
2136 if (addend
.X_op
!= O_constant
)
2137 as_bad (_("can not resolve expression"));
2138 addend
.X_op
= O_symbol
;
2139 addend
.X_add_symbol
= alpha_gp_symbol
;
2143 insn
.fixups
[0].exp
= addend
;
2144 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_GPDISP_HI16
;
2148 set_tok_preg (newtok
[2], tok
[0].X_add_number
);
2150 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
2153 addend
.X_add_number
+= 4;
2157 insn
.fixups
[0].exp
= addend
;
2158 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_GPDISP_LO16
;
2161 #endif /* OBJ_ECOFF || OBJ_ELF */
2166 /* Add symbol+addend to link pool.
2167 Return offset from basesym to entry in link pool.
2169 Add new fixup only if offset isn't 16bit. */
2172 add_to_link_pool (basesym
, sym
, addend
)
2177 segT current_section
= now_seg
;
2178 int current_subsec
= now_subseg
;
2180 bfd_reloc_code_real_type reloc_type
;
2182 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
2185 offset
= - *symbol_get_obj (basesym
);
2187 /* @@ This assumes all entries in a given section will be of the same
2188 size... Probably correct, but unwise to rely on. */
2189 /* This must always be called with the same subsegment. */
2191 if (seginfo
->frchainP
)
2192 for (fixp
= seginfo
->frchainP
->fix_root
;
2193 fixp
!= (fixS
*) NULL
;
2194 fixp
= fixp
->fx_next
, offset
+= 8)
2196 if (fixp
->fx_addsy
== sym
&& fixp
->fx_offset
== addend
)
2198 if (range_signed_16 (offset
))
2205 /* Not found in 16bit signed range. */
2207 subseg_set (alpha_link_section
, 0);
2211 fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, sym
, addend
, 0,
2214 subseg_set (current_section
, current_subsec
);
2215 seginfo
->literal_pool_size
+= 8;
2219 #endif /* OBJ_EVAX */
2221 /* Load a (partial) expression into a target register.
2223 If poffset is not null, after the call it will either contain
2224 O_constant 0, or a 16-bit offset appropriate for any MEM format
2225 instruction. In addition, pbasereg will be modified to point to
2226 the base register to use in that MEM format instruction.
2228 In any case, *pbasereg should contain a base register to add to the
2229 expression. This will normally be either AXP_REG_ZERO or
2230 alpha_gp_register. Symbol addresses will always be loaded via $gp,
2231 so "foo($0)" is interpreted as adding the address of foo to $0;
2232 i.e. "ldq $targ, LIT($gp); addq $targ, $0, $targ". Odd, perhaps,
2233 but this is what OSF/1 does.
2235 Finally, the return value is true if the calling macro may emit a
2236 LITUSE reloc if otherwise appropriate. */
2239 load_expression (targreg
, exp
, pbasereg
, poffset
)
2241 const expressionS
*exp
;
2243 expressionS
*poffset
;
2245 int emit_lituse
= 0;
2246 offsetT addend
= exp
->X_add_number
;
2247 int basereg
= *pbasereg
;
2248 struct alpha_insn insn
;
2249 expressionS newtok
[3];
2258 /* attempt to reduce .lit load by splitting the offset from
2259 its symbol when possible, but don't create a situation in
2261 if (!range_signed_32 (addend
) &&
2262 (alpha_noat_on
|| targreg
== AXP_REG_AT
))
2264 lit
= add_to_literal_pool (exp
->X_add_symbol
, addend
,
2265 alpha_lita_section
, 8);
2270 lit
= add_to_literal_pool (exp
->X_add_symbol
, 0,
2271 alpha_lita_section
, 8);
2275 as_fatal (_("overflow in literal (.lita) table"));
2277 /* emit "ldq r, lit(gp)" */
2279 if (basereg
!= alpha_gp_register
&& targreg
== basereg
)
2282 as_bad (_("macro requires $at register while noat in effect"));
2283 if (targreg
== AXP_REG_AT
)
2284 as_bad (_("macro requires $at while $at in use"));
2286 set_tok_reg (newtok
[0], AXP_REG_AT
);
2289 set_tok_reg (newtok
[0], targreg
);
2290 set_tok_sym (newtok
[1], alpha_lita_symbol
, lit
);
2291 set_tok_preg (newtok
[2], alpha_gp_register
);
2293 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
2295 assert (insn
.nfixups
== 1);
2296 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITERAL
;
2297 #endif /* OBJ_ECOFF */
2299 /* emit "ldq r, gotoff(gp)" */
2301 if (basereg
!= alpha_gp_register
&& targreg
== basereg
)
2304 as_bad (_("macro requires $at register while noat in effect"));
2305 if (targreg
== AXP_REG_AT
)
2306 as_bad (_("macro requires $at while $at in use"));
2308 set_tok_reg (newtok
[0], AXP_REG_AT
);
2311 set_tok_reg (newtok
[0], targreg
);
2313 /* XXX: Disable this .got minimizing optimization so that we can get
2314 better instruction offset knowledge in the compiler. This happens
2315 very infrequently anyway. */
2316 if (1 || (!range_signed_32 (addend
)
2317 && (alpha_noat_on
|| targreg
== AXP_REG_AT
)))
2324 set_tok_sym (newtok
[1], exp
->X_add_symbol
, 0);
2327 set_tok_preg (newtok
[2], alpha_gp_register
);
2329 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
2331 assert (insn
.nfixups
== 1);
2332 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_ELF_LITERAL
;
2333 #endif /* OBJ_ELF */
2337 /* Find symbol or symbol pointer in link section. */
2339 if (exp
->X_add_symbol
== alpha_evax_proc
.symbol
)
2341 if (range_signed_16 (addend
))
2343 set_tok_reg (newtok
[0], targreg
);
2344 set_tok_const (newtok
[1], addend
);
2345 set_tok_preg (newtok
[2], basereg
);
2346 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
2351 set_tok_reg (newtok
[0], targreg
);
2352 set_tok_const (newtok
[1], 0);
2353 set_tok_preg (newtok
[2], basereg
);
2354 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
2359 if (!range_signed_32 (addend
))
2361 link
= add_to_link_pool (alpha_evax_proc
.symbol
,
2362 exp
->X_add_symbol
, addend
);
2367 link
= add_to_link_pool (alpha_evax_proc
.symbol
,
2368 exp
->X_add_symbol
, 0);
2370 set_tok_reg (newtok
[0], targreg
);
2371 set_tok_const (newtok
[1], link
);
2372 set_tok_preg (newtok
[2], basereg
);
2373 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
2375 #endif /* OBJ_EVAX */
2382 if (basereg
!= alpha_gp_register
&& basereg
!= AXP_REG_ZERO
)
2384 /* emit "addq r, base, r" */
2386 set_tok_reg (newtok
[1], basereg
);
2387 set_tok_reg (newtok
[2], targreg
);
2388 assemble_tokens ("addq", newtok
, 3, 0);
2400 /* Assume that this difference expression will be resolved to an
2401 absolute value and that that value will fit in 16 bits. */
2403 set_tok_reg (newtok
[0], targreg
);
2405 set_tok_preg (newtok
[2], basereg
);
2406 assemble_tokens ("lda", newtok
, 3, 0);
2409 set_tok_const (*poffset
, 0);
2413 if (exp
->X_add_number
> 0)
2414 as_bad (_("bignum invalid; zero assumed"));
2416 as_bad (_("floating point number invalid; zero assumed"));
2421 as_bad (_("can't handle expression"));
2426 if (!range_signed_32 (addend
))
2430 /* for 64-bit addends, just put it in the literal pool */
2433 /* emit "ldq targreg, lit(basereg)" */
2434 lit
= add_to_link_pool (alpha_evax_proc
.symbol
,
2435 section_symbol (absolute_section
), addend
);
2436 set_tok_reg (newtok
[0], targreg
);
2437 set_tok_const (newtok
[1], lit
);
2438 set_tok_preg (newtok
[2], alpha_gp_register
);
2439 assemble_tokens ("ldq", newtok
, 3, 0);
2442 if (alpha_lit8_section
== NULL
)
2444 create_literal_section (".lit8",
2445 &alpha_lit8_section
,
2446 &alpha_lit8_symbol
);
2449 alpha_lit8_literal
= add_to_literal_pool (alpha_lit8_symbol
, 0x8000,
2450 alpha_lita_section
, 8);
2451 if (alpha_lit8_literal
>= 0x8000)
2452 as_fatal (_("overflow in literal (.lita) table"));
2456 lit
= add_to_literal_pool (NULL
, addend
, alpha_lit8_section
, 8) - 0x8000;
2458 as_fatal (_("overflow in literal (.lit8) table"));
2460 /* emit "lda litreg, .lit8+0x8000" */
2462 if (targreg
== basereg
)
2465 as_bad (_("macro requires $at register while noat in effect"));
2466 if (targreg
== AXP_REG_AT
)
2467 as_bad (_("macro requires $at while $at in use"));
2469 set_tok_reg (newtok
[0], AXP_REG_AT
);
2472 set_tok_reg (newtok
[0], targreg
);
2474 set_tok_sym (newtok
[1], alpha_lita_symbol
, alpha_lit8_literal
);
2477 set_tok_sym (newtok
[1], alpha_lit8_symbol
, 0x8000);
2479 set_tok_preg (newtok
[2], alpha_gp_register
);
2481 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
2483 assert (insn
.nfixups
== 1);
2485 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITERAL
;
2488 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_ELF_LITERAL
;
2493 /* emit "ldq litreg, lit(litreg)" */
2495 set_tok_const (newtok
[1], lit
);
2496 set_tok_preg (newtok
[2], newtok
[0].X_add_number
);
2498 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
2500 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
2501 if (insn
.nfixups
> 0)
2503 memmove (&insn
.fixups
[1], &insn
.fixups
[0],
2504 sizeof(struct alpha_fixup
) * insn
.nfixups
);
2507 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITUSE
;
2508 insn
.fixups
[0].exp
.X_op
= O_symbol
;
2509 insn
.fixups
[0].exp
.X_add_symbol
= section_symbol (now_seg
);
2510 insn
.fixups
[0].exp
.X_add_number
= 1;
2515 /* emit "addq litreg, base, target" */
2517 if (basereg
!= AXP_REG_ZERO
)
2519 set_tok_reg (newtok
[1], basereg
);
2520 set_tok_reg (newtok
[2], targreg
);
2521 assemble_tokens ("addq", newtok
, 3, 0);
2523 #endif /* !OBJ_EVAX */
2526 set_tok_const (*poffset
, 0);
2527 *pbasereg
= targreg
;
2531 offsetT low
, high
, extra
, tmp
;
2533 /* for 32-bit operands, break up the addend */
2535 low
= sign_extend_16 (addend
);
2537 high
= sign_extend_16 (tmp
>> 16);
2539 if (tmp
- (high
<< 16))
2543 high
= sign_extend_16 (tmp
>> 16);
2548 set_tok_reg (newtok
[0], targreg
);
2549 set_tok_preg (newtok
[2], basereg
);
2553 /* emit "ldah r, extra(r) */
2554 set_tok_const (newtok
[1], extra
);
2555 assemble_tokens ("ldah", newtok
, 3, 0);
2556 set_tok_preg (newtok
[2], basereg
= targreg
);
2561 /* emit "ldah r, high(r) */
2562 set_tok_const (newtok
[1], high
);
2563 assemble_tokens ("ldah", newtok
, 3, 0);
2565 set_tok_preg (newtok
[2], basereg
);
2568 if ((low
&& !poffset
) || (!poffset
&& basereg
!= targreg
))
2570 /* emit "lda r, low(base)" */
2571 set_tok_const (newtok
[1], low
);
2572 assemble_tokens ("lda", newtok
, 3, 0);
2578 set_tok_const (*poffset
, low
);
2579 *pbasereg
= basereg
;
2585 /* The lda macro differs from the lda instruction in that it handles
2586 most simple expressions, particualrly symbol address loads and
2590 emit_lda (tok
, ntok
, unused
)
2591 const expressionS
*tok
;
2593 const PTR unused ATTRIBUTE_UNUSED
;
2598 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
2600 basereg
= tok
[2].X_add_number
;
2602 (void) load_expression (tok
[0].X_add_number
, &tok
[1], &basereg
, NULL
);
2605 /* The ldah macro differs from the ldah instruction in that it has $31
2606 as an implied base register. */
2609 emit_ldah (tok
, ntok
, unused
)
2610 const expressionS
*tok
;
2611 int ntok ATTRIBUTE_UNUSED
;
2612 const PTR unused ATTRIBUTE_UNUSED
;
2614 expressionS newtok
[3];
2618 set_tok_preg (newtok
[2], AXP_REG_ZERO
);
2620 assemble_tokens ("ldah", newtok
, 3, 0);
2623 /* Handle all "simple" integer register loads -- ldq, ldq_l, ldq_u,
2624 etc. They differ from the real instructions in that they do simple
2625 expressions like the lda macro. */
2628 emit_ir_load (tok
, ntok
, opname
)
2629 const expressionS
*tok
;
2633 int basereg
, lituse
;
2634 expressionS newtok
[3];
2635 struct alpha_insn insn
;
2638 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
2640 basereg
= tok
[2].X_add_number
;
2642 lituse
= load_expression (tok
[0].X_add_number
, &tok
[1], &basereg
,
2646 set_tok_preg (newtok
[2], basereg
);
2648 assemble_tokens_to_insn ((const char *)opname
, newtok
, 3, &insn
);
2652 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
2653 if (insn
.nfixups
> 0)
2655 memmove (&insn
.fixups
[1], &insn
.fixups
[0],
2656 sizeof(struct alpha_fixup
) * insn
.nfixups
);
2659 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITUSE
;
2660 insn
.fixups
[0].exp
.X_op
= O_symbol
;
2661 insn
.fixups
[0].exp
.X_add_symbol
= section_symbol (now_seg
);
2662 insn
.fixups
[0].exp
.X_add_number
= 1;
2668 /* Handle fp register loads, and both integer and fp register stores.
2669 Again, we handle simple expressions. */
2672 emit_loadstore (tok
, ntok
, opname
)
2673 const expressionS
*tok
;
2677 int basereg
, lituse
;
2678 expressionS newtok
[3];
2679 struct alpha_insn insn
;
2682 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
2684 basereg
= tok
[2].X_add_number
;
2686 if (tok
[1].X_op
!= O_constant
|| !range_signed_16(tok
[1].X_add_number
))
2689 as_bad (_("macro requires $at register while noat in effect"));
2691 lituse
= load_expression (AXP_REG_AT
, &tok
[1], &basereg
, &newtok
[1]);
2700 set_tok_preg (newtok
[2], basereg
);
2702 assemble_tokens_to_insn ((const char *)opname
, newtok
, 3, &insn
);
2706 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
2707 if (insn
.nfixups
> 0)
2709 memmove (&insn
.fixups
[1], &insn
.fixups
[0],
2710 sizeof(struct alpha_fixup
) * insn
.nfixups
);
2713 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITUSE
;
2714 insn
.fixups
[0].exp
.X_op
= O_symbol
;
2715 insn
.fixups
[0].exp
.X_add_symbol
= section_symbol (now_seg
);
2716 insn
.fixups
[0].exp
.X_add_number
= 1;
2722 /* Load a half-word or byte as an unsigned value. */
2725 emit_ldXu (tok
, ntok
, vlgsize
)
2726 const expressionS
*tok
;
2730 if (alpha_target
& AXP_OPCODE_BWX
)
2731 emit_ir_load (tok
, ntok
, ldXu_op
[(long)vlgsize
]);
2734 expressionS newtok
[3];
2737 as_bad (_("macro requires $at register while noat in effect"));
2739 /* emit "lda $at, exp" */
2741 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
2742 newtok
[0].X_add_number
= AXP_REG_AT
;
2743 assemble_tokens ("lda", newtok
, ntok
, 1);
2745 /* emit "ldq_u targ, 0($at)" */
2748 set_tok_const (newtok
[1], 0);
2749 set_tok_preg (newtok
[2], AXP_REG_AT
);
2750 assemble_tokens ("ldq_u", newtok
, 3, 1);
2752 /* emit "extXl targ, $at, targ" */
2754 set_tok_reg (newtok
[1], AXP_REG_AT
);
2755 newtok
[2] = newtok
[0];
2756 assemble_tokens (extXl_op
[(long)vlgsize
], newtok
, 3, 1);
2760 /* Load a half-word or byte as a signed value. */
2763 emit_ldX (tok
, ntok
, vlgsize
)
2764 const expressionS
*tok
;
2768 emit_ldXu (tok
, ntok
, vlgsize
);
2769 assemble_tokens (sextX_op
[(long)vlgsize
], tok
, 1, 1);
2772 /* Load an integral value from an unaligned address as an unsigned
2776 emit_uldXu (tok
, ntok
, vlgsize
)
2777 const expressionS
*tok
;
2781 long lgsize
= (long)vlgsize
;
2782 expressionS newtok
[3];
2785 as_bad (_("macro requires $at register while noat in effect"));
2787 /* emit "lda $at, exp" */
2789 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
2790 newtok
[0].X_add_number
= AXP_REG_AT
;
2791 assemble_tokens ("lda", newtok
, ntok
, 1);
2793 /* emit "ldq_u $t9, 0($at)" */
2795 set_tok_reg (newtok
[0], AXP_REG_T9
);
2796 set_tok_const (newtok
[1], 0);
2797 set_tok_preg (newtok
[2], AXP_REG_AT
);
2798 assemble_tokens ("ldq_u", newtok
, 3, 1);
2800 /* emit "ldq_u $t10, size-1($at)" */
2802 set_tok_reg (newtok
[0], AXP_REG_T10
);
2803 set_tok_const (newtok
[1], (1<<lgsize
)-1);
2804 assemble_tokens ("ldq_u", newtok
, 3, 1);
2806 /* emit "extXl $t9, $at, $t9" */
2808 set_tok_reg (newtok
[0], AXP_REG_T9
);
2809 set_tok_reg (newtok
[1], AXP_REG_AT
);
2810 set_tok_reg (newtok
[2], AXP_REG_T9
);
2811 assemble_tokens (extXl_op
[lgsize
], newtok
, 3, 1);
2813 /* emit "extXh $t10, $at, $t10" */
2815 set_tok_reg (newtok
[0], AXP_REG_T10
);
2816 set_tok_reg (newtok
[2], AXP_REG_T10
);
2817 assemble_tokens (extXh_op
[lgsize
], newtok
, 3, 1);
2819 /* emit "or $t9, $t10, targ" */
2821 set_tok_reg (newtok
[0], AXP_REG_T9
);
2822 set_tok_reg (newtok
[1], AXP_REG_T10
);
2824 assemble_tokens ("or", newtok
, 3, 1);
2827 /* Load an integral value from an unaligned address as a signed value.
2828 Note that quads should get funneled to the unsigned load since we
2829 don't have to do the sign extension. */
2832 emit_uldX (tok
, ntok
, vlgsize
)
2833 const expressionS
*tok
;
2837 emit_uldXu (tok
, ntok
, vlgsize
);
2838 assemble_tokens (sextX_op
[(long)vlgsize
], tok
, 1, 1);
2841 /* Implement the ldil macro. */
2844 emit_ldil (tok
, ntok
, unused
)
2845 const expressionS
*tok
;
2847 const PTR unused ATTRIBUTE_UNUSED
;
2849 expressionS newtok
[2];
2851 memcpy (newtok
, tok
, sizeof(newtok
));
2852 newtok
[1].X_add_number
= sign_extend_32 (tok
[1].X_add_number
);
2854 assemble_tokens ("lda", newtok
, ntok
, 1);
2857 /* Store a half-word or byte. */
2860 emit_stX (tok
, ntok
, vlgsize
)
2861 const expressionS
*tok
;
2865 int lgsize
= (int)(long)vlgsize
;
2867 if (alpha_target
& AXP_OPCODE_BWX
)
2868 emit_loadstore (tok
, ntok
, stX_op
[lgsize
]);
2871 expressionS newtok
[3];
2874 as_bad(_("macro requires $at register while noat in effect"));
2876 /* emit "lda $at, exp" */
2878 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
2879 newtok
[0].X_add_number
= AXP_REG_AT
;
2880 assemble_tokens ("lda", newtok
, ntok
, 1);
2882 /* emit "ldq_u $t9, 0($at)" */
2884 set_tok_reg (newtok
[0], AXP_REG_T9
);
2885 set_tok_const (newtok
[1], 0);
2886 set_tok_preg (newtok
[2], AXP_REG_AT
);
2887 assemble_tokens ("ldq_u", newtok
, 3, 1);
2889 /* emit "insXl src, $at, $t10" */
2892 set_tok_reg (newtok
[1], AXP_REG_AT
);
2893 set_tok_reg (newtok
[2], AXP_REG_T10
);
2894 assemble_tokens (insXl_op
[lgsize
], newtok
, 3, 1);
2896 /* emit "mskXl $t9, $at, $t9" */
2898 set_tok_reg (newtok
[0], AXP_REG_T9
);
2899 newtok
[2] = newtok
[0];
2900 assemble_tokens (mskXl_op
[lgsize
], newtok
, 3, 1);
2902 /* emit "or $t9, $t10, $t9" */
2904 set_tok_reg (newtok
[1], AXP_REG_T10
);
2905 assemble_tokens ("or", newtok
, 3, 1);
2907 /* emit "stq_u $t9, 0($at) */
2909 set_tok_const (newtok
[1], 0);
2910 set_tok_preg (newtok
[2], AXP_REG_AT
);
2911 assemble_tokens ("stq_u", newtok
, 3, 1);
2915 /* Store an integer to an unaligned address. */
2918 emit_ustX (tok
, ntok
, vlgsize
)
2919 const expressionS
*tok
;
2923 int lgsize
= (int)(long)vlgsize
;
2924 expressionS newtok
[3];
2926 /* emit "lda $at, exp" */
2928 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
2929 newtok
[0].X_add_number
= AXP_REG_AT
;
2930 assemble_tokens ("lda", newtok
, ntok
, 1);
2932 /* emit "ldq_u $9, 0($at)" */
2934 set_tok_reg (newtok
[0], AXP_REG_T9
);
2935 set_tok_const (newtok
[1], 0);
2936 set_tok_preg (newtok
[2], AXP_REG_AT
);
2937 assemble_tokens ("ldq_u", newtok
, 3, 1);
2939 /* emit "ldq_u $10, size-1($at)" */
2941 set_tok_reg (newtok
[0], AXP_REG_T10
);
2942 set_tok_const (newtok
[1], (1 << lgsize
)-1);
2943 assemble_tokens ("ldq_u", newtok
, 3, 1);
2945 /* emit "insXl src, $at, $t11" */
2948 set_tok_reg (newtok
[1], AXP_REG_AT
);
2949 set_tok_reg (newtok
[2], AXP_REG_T11
);
2950 assemble_tokens (insXl_op
[lgsize
], newtok
, 3, 1);
2952 /* emit "insXh src, $at, $t12" */
2954 set_tok_reg (newtok
[2], AXP_REG_T12
);
2955 assemble_tokens (insXh_op
[lgsize
], newtok
, 3, 1);
2957 /* emit "mskXl $t9, $at, $t9" */
2959 set_tok_reg (newtok
[0], AXP_REG_T9
);
2960 newtok
[2] = newtok
[0];
2961 assemble_tokens (mskXl_op
[lgsize
], newtok
, 3, 1);
2963 /* emit "mskXh $t10, $at, $t10" */
2965 set_tok_reg (newtok
[0], AXP_REG_T10
);
2966 newtok
[2] = newtok
[0];
2967 assemble_tokens (mskXh_op
[lgsize
], newtok
, 3, 1);
2969 /* emit "or $t9, $t11, $t9" */
2971 set_tok_reg (newtok
[0], AXP_REG_T9
);
2972 set_tok_reg (newtok
[1], AXP_REG_T11
);
2973 newtok
[2] = newtok
[0];
2974 assemble_tokens ("or", newtok
, 3, 1);
2976 /* emit "or $t10, $t12, $t10" */
2978 set_tok_reg (newtok
[0], AXP_REG_T10
);
2979 set_tok_reg (newtok
[1], AXP_REG_T12
);
2980 newtok
[2] = newtok
[0];
2981 assemble_tokens ("or", newtok
, 3, 1);
2983 /* emit "stq_u $t9, 0($at)" */
2985 set_tok_reg (newtok
[0], AXP_REG_T9
);
2986 set_tok_const (newtok
[1], 0);
2987 set_tok_preg (newtok
[2], AXP_REG_AT
);
2988 assemble_tokens ("stq_u", newtok
, 3, 1);
2990 /* emit "stq_u $t10, size-1($at)" */
2992 set_tok_reg (newtok
[0], AXP_REG_T10
);
2993 set_tok_const (newtok
[1], (1 << lgsize
)-1);
2994 assemble_tokens ("stq_u", newtok
, 3, 1);
2997 /* Sign extend a half-word or byte. The 32-bit sign extend is
2998 implemented as "addl $31, $r, $t" in the opcode table. */
3001 emit_sextX (tok
, ntok
, vlgsize
)
3002 const expressionS
*tok
;
3006 long lgsize
= (long)vlgsize
;
3008 if (alpha_target
& AXP_OPCODE_BWX
)
3009 assemble_tokens (sextX_op
[lgsize
], tok
, ntok
, 0);
3012 int bitshift
= 64 - 8 * (1 << lgsize
);
3013 expressionS newtok
[3];
3015 /* emit "sll src,bits,dst" */
3018 set_tok_const (newtok
[1], bitshift
);
3019 newtok
[2] = tok
[ntok
- 1];
3020 assemble_tokens ("sll", newtok
, 3, 1);
3022 /* emit "sra dst,bits,dst" */
3024 newtok
[0] = newtok
[2];
3025 assemble_tokens ("sra", newtok
, 3, 1);
3029 /* Implement the division and modulus macros. */
3033 /* Make register usage like in normal procedure call.
3034 Don't clobber PV and RA. */
3037 emit_division (tok
, ntok
, symname
)
3038 const expressionS
*tok
;
3042 /* DIVISION and MODULUS. Yech.
3047 * mov x,R16 # if x != R16
3048 * mov y,R17 # if y != R17
3053 * with appropriate optimizations if R0,R16,R17 are the registers
3054 * specified by the compiler.
3059 expressionS newtok
[3];
3061 xr
= regno (tok
[0].X_add_number
);
3062 yr
= regno (tok
[1].X_add_number
);
3067 rr
= regno (tok
[2].X_add_number
);
3069 /* Move the operands into the right place */
3070 if (yr
== AXP_REG_R16
&& xr
== AXP_REG_R17
)
3072 /* They are in exactly the wrong order -- swap through AT */
3075 as_bad (_("macro requires $at register while noat in effect"));
3077 set_tok_reg (newtok
[0], AXP_REG_R16
);
3078 set_tok_reg (newtok
[1], AXP_REG_AT
);
3079 assemble_tokens ("mov", newtok
, 2, 1);
3081 set_tok_reg (newtok
[0], AXP_REG_R17
);
3082 set_tok_reg (newtok
[1], AXP_REG_R16
);
3083 assemble_tokens ("mov", newtok
, 2, 1);
3085 set_tok_reg (newtok
[0], AXP_REG_AT
);
3086 set_tok_reg (newtok
[1], AXP_REG_R17
);
3087 assemble_tokens ("mov", newtok
, 2, 1);
3091 if (yr
== AXP_REG_R16
)
3093 set_tok_reg (newtok
[0], AXP_REG_R16
);
3094 set_tok_reg (newtok
[1], AXP_REG_R17
);
3095 assemble_tokens ("mov", newtok
, 2, 1);
3098 if (xr
!= AXP_REG_R16
)
3100 set_tok_reg (newtok
[0], xr
);
3101 set_tok_reg (newtok
[1], AXP_REG_R16
);
3102 assemble_tokens ("mov", newtok
, 2, 1);
3105 if (yr
!= AXP_REG_R16
&& yr
!= AXP_REG_R17
)
3107 set_tok_reg (newtok
[0], yr
);
3108 set_tok_reg (newtok
[1], AXP_REG_R17
);
3109 assemble_tokens ("mov", newtok
, 2, 1);
3113 sym
= symbol_find_or_make ((const char *)symname
);
3115 set_tok_reg (newtok
[0], AXP_REG_AT
);
3116 set_tok_sym (newtok
[1], sym
, 0);
3117 assemble_tokens ("lda", newtok
, 2, 1);
3119 /* Call the division routine */
3120 set_tok_reg (newtok
[0], AXP_REG_AT
);
3121 set_tok_cpreg (newtok
[1], AXP_REG_AT
);
3122 set_tok_const (newtok
[2], 0);
3123 assemble_tokens ("jsr", newtok
, 3, 1);
3125 /* Move the result to the right place */
3126 if (rr
!= AXP_REG_R0
)
3128 set_tok_reg (newtok
[0], AXP_REG_R0
);
3129 set_tok_reg (newtok
[1], rr
);
3130 assemble_tokens ("mov", newtok
, 2, 1);
3134 #else /* !OBJ_EVAX */
3137 emit_division (tok
, ntok
, symname
)
3138 const expressionS
*tok
;
3142 /* DIVISION and MODULUS. Yech.
3152 * with appropriate optimizations if t10,t11,t12 are the registers
3153 * specified by the compiler.
3158 expressionS newtok
[3];
3160 xr
= regno (tok
[0].X_add_number
);
3161 yr
= regno (tok
[1].X_add_number
);
3166 rr
= regno (tok
[2].X_add_number
);
3168 sym
= symbol_find_or_make ((const char *)symname
);
3170 /* Move the operands into the right place */
3171 if (yr
== AXP_REG_T10
&& xr
== AXP_REG_T11
)
3173 /* They are in exactly the wrong order -- swap through AT */
3176 as_bad (_("macro requires $at register while noat in effect"));
3178 set_tok_reg (newtok
[0], AXP_REG_T10
);
3179 set_tok_reg (newtok
[1], AXP_REG_AT
);
3180 assemble_tokens ("mov", newtok
, 2, 1);
3182 set_tok_reg (newtok
[0], AXP_REG_T11
);
3183 set_tok_reg (newtok
[1], AXP_REG_T10
);
3184 assemble_tokens ("mov", newtok
, 2, 1);
3186 set_tok_reg (newtok
[0], AXP_REG_AT
);
3187 set_tok_reg (newtok
[1], AXP_REG_T11
);
3188 assemble_tokens ("mov", newtok
, 2, 1);
3192 if (yr
== AXP_REG_T10
)
3194 set_tok_reg (newtok
[0], AXP_REG_T10
);
3195 set_tok_reg (newtok
[1], AXP_REG_T11
);
3196 assemble_tokens ("mov", newtok
, 2, 1);
3199 if (xr
!= AXP_REG_T10
)
3201 set_tok_reg (newtok
[0], xr
);
3202 set_tok_reg (newtok
[1], AXP_REG_T10
);
3203 assemble_tokens ("mov", newtok
, 2, 1);
3206 if (yr
!= AXP_REG_T10
&& yr
!= AXP_REG_T11
)
3208 set_tok_reg (newtok
[0], yr
);
3209 set_tok_reg (newtok
[1], AXP_REG_T11
);
3210 assemble_tokens ("mov", newtok
, 2, 1);
3214 /* Call the division routine */
3215 set_tok_reg (newtok
[0], AXP_REG_T9
);
3216 set_tok_sym (newtok
[1], sym
, 0);
3217 assemble_tokens ("jsr", newtok
, 2, 1);
3219 /* Reload the GP register */
3223 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
3224 set_tok_reg (newtok
[0], alpha_gp_register
);
3225 set_tok_const (newtok
[1], 0);
3226 set_tok_preg (newtok
[2], AXP_REG_T9
);
3227 assemble_tokens ("ldgp", newtok
, 3, 1);
3230 /* Move the result to the right place */
3231 if (rr
!= AXP_REG_T12
)
3233 set_tok_reg (newtok
[0], AXP_REG_T12
);
3234 set_tok_reg (newtok
[1], rr
);
3235 assemble_tokens ("mov", newtok
, 2, 1);
3239 #endif /* !OBJ_EVAX */
3241 /* The jsr and jmp macros differ from their instruction counterparts
3242 in that they can load the target address and default most
3246 emit_jsrjmp (tok
, ntok
, vopname
)
3247 const expressionS
*tok
;
3251 const char *opname
= (const char *) vopname
;
3252 struct alpha_insn insn
;
3253 expressionS newtok
[3];
3254 int r
, tokidx
= 0, lituse
= 0;
3256 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_register
)
3257 r
= regno (tok
[tokidx
++].X_add_number
);
3259 r
= strcmp (opname
, "jmp") == 0 ? AXP_REG_ZERO
: AXP_REG_RA
;
3261 set_tok_reg (newtok
[0], r
);
3263 if (tokidx
< ntok
&&
3264 (tok
[tokidx
].X_op
== O_pregister
|| tok
[tokidx
].X_op
== O_cpregister
))
3265 r
= regno (tok
[tokidx
++].X_add_number
);
3267 /* keep register if jsr $n.<sym> */
3271 int basereg
= alpha_gp_register
;
3272 lituse
= load_expression (r
= AXP_REG_PV
, &tok
[tokidx
], &basereg
, NULL
);
3276 set_tok_cpreg (newtok
[1], r
);
3279 /* FIXME: Add hint relocs to BFD for evax. */
3282 newtok
[2] = tok
[tokidx
];
3285 set_tok_const (newtok
[2], 0);
3287 assemble_tokens_to_insn (opname
, newtok
, 3, &insn
);
3289 /* add the LITUSE fixup */
3292 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
3293 if (insn
.nfixups
> 0)
3295 memmove (&insn
.fixups
[1], &insn
.fixups
[0],
3296 sizeof(struct alpha_fixup
) * insn
.nfixups
);
3299 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITUSE
;
3300 insn
.fixups
[0].exp
.X_op
= O_symbol
;
3301 insn
.fixups
[0].exp
.X_add_symbol
= section_symbol (now_seg
);
3302 insn
.fixups
[0].exp
.X_add_number
= 3;
3308 /* The ret and jcr instructions differ from their instruction
3309 counterparts in that everything can be defaulted. */
3312 emit_retjcr (tok
, ntok
, vopname
)
3313 const expressionS
*tok
;
3317 const char *opname
= (const char *)vopname
;
3318 expressionS newtok
[3];
3321 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_register
)
3322 r
= regno (tok
[tokidx
++].X_add_number
);
3326 set_tok_reg (newtok
[0], r
);
3328 if (tokidx
< ntok
&&
3329 (tok
[tokidx
].X_op
== O_pregister
|| tok
[tokidx
].X_op
== O_cpregister
))
3330 r
= regno (tok
[tokidx
++].X_add_number
);
3334 set_tok_cpreg (newtok
[1], r
);
3337 newtok
[2] = tok
[tokidx
];
3339 set_tok_const (newtok
[2], strcmp(opname
, "ret") == 0);
3341 assemble_tokens (opname
, newtok
, 3, 0);
3344 /* Assembler directives */
3346 /* Handle the .text pseudo-op. This is like the usual one, but it
3347 clears alpha_insn_label and restores auto alignment. */
3355 alpha_insn_label
= NULL
;
3356 alpha_auto_align_on
= 1;
3357 alpha_current_align
= 0;
3360 /* Handle the .data pseudo-op. This is like the usual one, but it
3361 clears alpha_insn_label and restores auto alignment. */
3368 alpha_insn_label
= NULL
;
3369 alpha_auto_align_on
= 1;
3370 alpha_current_align
= 0;
3373 #if defined (OBJ_ECOFF) || defined (OBJ_EVAX)
3375 /* Handle the OSF/1 and openVMS .comm pseudo quirks.
3376 openVMS constructs a section for every common symbol. */
3379 s_alpha_comm (ignore
)
3382 register char *name
;
3386 register symbolS
*symbolP
;
3389 segT current_section
= now_seg
;
3390 int current_subsec
= now_subseg
;
3394 name
= input_line_pointer
;
3395 c
= get_symbol_end ();
3397 /* just after name is now '\0' */
3398 p
= input_line_pointer
;
3403 /* Alpha OSF/1 compiler doesn't provide the comma, gcc does. */
3404 if (*input_line_pointer
== ',')
3406 input_line_pointer
++;
3409 if ((temp
= get_absolute_expression ()) < 0)
3411 as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) temp
);
3412 ignore_rest_of_line ();
3417 symbolP
= symbol_find_or_make (name
);
3420 /* Make a section for the common symbol. */
3421 new_seg
= subseg_new (xstrdup (name
), 0);
3427 /* alignment might follow */
3428 if (*input_line_pointer
== ',')
3432 input_line_pointer
++;
3433 align
= get_absolute_expression ();
3434 bfd_set_section_alignment (stdoutput
, new_seg
, align
);
3438 if (S_IS_DEFINED (symbolP
) && ! S_IS_COMMON (symbolP
))
3440 as_bad (_("Ignoring attempt to re-define symbol"));
3441 ignore_rest_of_line ();
3446 if (bfd_section_size (stdoutput
, new_seg
) > 0)
3448 if (bfd_section_size (stdoutput
, new_seg
) != temp
)
3449 as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
3450 S_GET_NAME (symbolP
),
3451 (long) bfd_section_size (stdoutput
, new_seg
),
3455 if (S_GET_VALUE (symbolP
))
3457 if (S_GET_VALUE (symbolP
) != (valueT
) temp
)
3458 as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
3459 S_GET_NAME (symbolP
),
3460 (long) S_GET_VALUE (symbolP
),
3467 subseg_set (new_seg
, 0);
3468 p
= frag_more (temp
);
3469 new_seg
->flags
|= SEC_IS_COMMON
;
3470 if (! S_IS_DEFINED (symbolP
))
3471 S_SET_SEGMENT (symbolP
, new_seg
);
3473 S_SET_VALUE (symbolP
, (valueT
) temp
);
3475 S_SET_EXTERNAL (symbolP
);
3479 subseg_set (current_section
, current_subsec
);
3482 know (symbol_get_frag (symbolP
) == &zero_address_frag
);
3484 demand_empty_rest_of_line ();
3487 #endif /* ! OBJ_ELF */
3491 /* Handle the .rdata pseudo-op. This is like the usual one, but it
3492 clears alpha_insn_label and restores auto alignment. */
3495 s_alpha_rdata (ignore
)
3500 temp
= get_absolute_expression ();
3501 subseg_new (".rdata", 0);
3502 demand_empty_rest_of_line ();
3503 alpha_insn_label
= NULL
;
3504 alpha_auto_align_on
= 1;
3505 alpha_current_align
= 0;
3512 /* Handle the .sdata pseudo-op. This is like the usual one, but it
3513 clears alpha_insn_label and restores auto alignment. */
3516 s_alpha_sdata (ignore
)
3521 temp
= get_absolute_expression ();
3522 subseg_new (".sdata", 0);
3523 demand_empty_rest_of_line ();
3524 alpha_insn_label
= NULL
;
3525 alpha_auto_align_on
= 1;
3526 alpha_current_align
= 0;
3532 /* Handle the .section pseudo-op. This is like the usual one, but it
3533 clears alpha_insn_label and restores auto alignment. */
3536 s_alpha_section (ignore
)
3539 obj_elf_section (ignore
);
3541 alpha_insn_label
= NULL
;
3542 alpha_auto_align_on
= 1;
3543 alpha_current_align
= 0;
3548 int dummy ATTRIBUTE_UNUSED
;
3550 if (ECOFF_DEBUGGING
)
3551 ecoff_directive_ent (0);
3554 char *name
, name_end
;
3555 name
= input_line_pointer
;
3556 name_end
= get_symbol_end ();
3558 if (! is_name_beginner (*name
))
3560 as_warn (_(".ent directive has no name"));
3561 *input_line_pointer
= name_end
;
3567 if (alpha_cur_ent_sym
)
3568 as_warn (_("nested .ent directives"));
3570 sym
= symbol_find_or_make (name
);
3571 symbol_get_bfdsym (sym
)->flags
|= BSF_FUNCTION
;
3572 alpha_cur_ent_sym
= sym
;
3574 /* The .ent directive is sometimes followed by a number. Not sure
3575 what it really means, but ignore it. */
3576 *input_line_pointer
= name_end
;
3578 if (*input_line_pointer
== ',')
3580 input_line_pointer
++;
3583 if (isdigit (*input_line_pointer
) || *input_line_pointer
== '-')
3584 (void) get_absolute_expression ();
3586 demand_empty_rest_of_line ();
3592 int dummy ATTRIBUTE_UNUSED
;
3594 if (ECOFF_DEBUGGING
)
3595 ecoff_directive_end (0);
3598 char *name
, name_end
;
3599 name
= input_line_pointer
;
3600 name_end
= get_symbol_end ();
3602 if (! is_name_beginner (*name
))
3604 as_warn (_(".end directive has no name"));
3605 *input_line_pointer
= name_end
;
3611 sym
= symbol_find (name
);
3612 if (sym
!= alpha_cur_ent_sym
)
3613 as_warn (_(".end directive names different symbol than .ent"));
3615 /* Create an expression to calculate the size of the function. */
3618 symbol_get_obj (sym
)->size
=
3619 (expressionS
*) xmalloc (sizeof (expressionS
));
3620 symbol_get_obj (sym
)->size
->X_op
= O_subtract
;
3621 symbol_get_obj (sym
)->size
->X_add_symbol
3622 = symbol_new ("L0\001", now_seg
, frag_now_fix (), frag_now
);
3623 symbol_get_obj (sym
)->size
->X_op_symbol
= sym
;
3624 symbol_get_obj (sym
)->size
->X_add_number
= 0;
3627 alpha_cur_ent_sym
= NULL
;
3629 *input_line_pointer
= name_end
;
3631 demand_empty_rest_of_line ();
3639 if (ECOFF_DEBUGGING
)
3642 ecoff_directive_fmask (0);
3644 ecoff_directive_mask (0);
3647 discard_rest_of_line ();
3651 s_alpha_frame (dummy
)
3652 int dummy ATTRIBUTE_UNUSED
;
3654 if (ECOFF_DEBUGGING
)
3655 ecoff_directive_frame (0);
3657 discard_rest_of_line ();
3661 s_alpha_prologue (ignore
)
3662 int ignore ATTRIBUTE_UNUSED
;
3667 arg
= get_absolute_expression ();
3668 demand_empty_rest_of_line ();
3670 if (ECOFF_DEBUGGING
)
3671 sym
= ecoff_get_cur_proc_sym ();
3673 sym
= alpha_cur_ent_sym
;
3678 case 0: /* No PV required. */
3679 S_SET_OTHER (sym
, STO_ALPHA_NOPV
);
3681 case 1: /* Std GP load. */
3682 S_SET_OTHER (sym
, STO_ALPHA_STD_GPLOAD
);
3684 case 2: /* Non-std use of PV. */
3688 as_bad (_("Invalid argument %d to .prologue."), arg
);
3694 s_alpha_coff_wrapper (which
)
3697 static void (* const fns
[]) PARAMS ((int)) = {
3698 ecoff_directive_begin
,
3699 ecoff_directive_bend
,
3700 ecoff_directive_def
,
3701 ecoff_directive_dim
,
3702 ecoff_directive_endef
,
3703 ecoff_directive_file
,
3704 ecoff_directive_scl
,
3705 ecoff_directive_tag
,
3706 ecoff_directive_val
,
3707 ecoff_directive_loc
,
3710 assert (which
>= 0 && which
< (int)(sizeof(fns
)/sizeof(*fns
)));
3712 if (ECOFF_DEBUGGING
)
3716 as_bad (_("ECOFF debugging is disabled."));
3717 ignore_rest_of_line ();
3720 #endif /* OBJ_ELF */
3724 /* Handle the section specific pseudo-op. */
3727 s_alpha_section (secid
)
3731 #define EVAX_SECTION_COUNT 5
3732 static char *section_name
[EVAX_SECTION_COUNT
+1] =
3733 { "NULL", ".rdata", ".comm", ".link", ".ctors", ".dtors" };
3735 if ((secid
<= 0) || (secid
> EVAX_SECTION_COUNT
))
3737 as_fatal (_("Unknown section directive"));
3738 demand_empty_rest_of_line ();
3741 temp
= get_absolute_expression ();
3742 subseg_new (section_name
[secid
], 0);
3743 demand_empty_rest_of_line ();
3744 alpha_insn_label
= NULL
;
3745 alpha_auto_align_on
= 1;
3746 alpha_current_align
= 0;
3750 /* Parse .ent directives. */
3753 s_alpha_ent (ignore
)
3757 expressionS symexpr
;
3759 alpha_evax_proc
.pdsckind
= 0;
3760 alpha_evax_proc
.framereg
= -1;
3761 alpha_evax_proc
.framesize
= 0;
3762 alpha_evax_proc
.rsa_offset
= 0;
3763 alpha_evax_proc
.ra_save
= AXP_REG_RA
;
3764 alpha_evax_proc
.fp_save
= -1;
3765 alpha_evax_proc
.imask
= 0;
3766 alpha_evax_proc
.fmask
= 0;
3767 alpha_evax_proc
.prologue
= 0;
3768 alpha_evax_proc
.type
= 0;
3770 expression (&symexpr
);
3772 if (symexpr
.X_op
!= O_symbol
)
3774 as_fatal (_(".ent directive has no symbol"));
3775 demand_empty_rest_of_line ();
3779 symbol
= make_expr_symbol (&symexpr
);
3780 symbol_get_bfdsym (symbol
)->flags
|= BSF_FUNCTION
;
3781 alpha_evax_proc
.symbol
= symbol
;
3783 demand_empty_rest_of_line ();
3788 /* Parse .frame <framreg>,<framesize>,RA,<rsa_offset> directives. */
3791 s_alpha_frame (ignore
)
3796 alpha_evax_proc
.framereg
= tc_get_register (1);
3799 if (*input_line_pointer
++ != ','
3800 || get_absolute_expression_and_terminator (&val
) != ',')
3802 as_warn (_("Bad .frame directive 1./2. param"));
3803 --input_line_pointer
;
3804 demand_empty_rest_of_line ();
3808 alpha_evax_proc
.framesize
= val
;
3810 (void) tc_get_register (1);
3812 if (*input_line_pointer
++ != ',')
3814 as_warn (_("Bad .frame directive 3./4. param"));
3815 --input_line_pointer
;
3816 demand_empty_rest_of_line ();
3819 alpha_evax_proc
.rsa_offset
= get_absolute_expression ();
3825 s_alpha_pdesc (ignore
)
3835 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
3837 if (now_seg
!= alpha_link_section
)
3839 as_bad (_(".pdesc directive not in link (.link) section"));
3840 demand_empty_rest_of_line ();
3844 if ((alpha_evax_proc
.symbol
== 0)
3845 || (!S_IS_DEFINED (alpha_evax_proc
.symbol
)))
3847 as_fatal (_(".pdesc has no matching .ent"));
3848 demand_empty_rest_of_line ();
3852 *symbol_get_obj (alpha_evax_proc
.symbol
) =
3853 (valueT
) seginfo
->literal_pool_size
;
3856 if (exp
.X_op
!= O_symbol
)
3858 as_warn (_(".pdesc directive has no entry symbol"));
3859 demand_empty_rest_of_line ();
3863 entry_sym
= make_expr_symbol (&exp
);
3864 /* Save bfd symbol of proc desc in function symbol. */
3865 symbol_get_bfdsym (alpha_evax_proc
.symbol
)->udata
.p
3866 = symbol_get_bfdsym (entry_sym
);
3869 if (*input_line_pointer
++ != ',')
3871 as_warn (_("No comma after .pdesc <entryname>"));
3872 demand_empty_rest_of_line ();
3877 name
= input_line_pointer
;
3878 name_end
= get_symbol_end ();
3880 if (strncmp(name
, "stack", 5) == 0)
3882 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_FP_STACK
;
3884 else if (strncmp(name
, "reg", 3) == 0)
3886 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_FP_REGISTER
;
3888 else if (strncmp(name
, "null", 4) == 0)
3890 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_NULL
;
3894 as_fatal (_("unknown procedure kind"));
3895 demand_empty_rest_of_line ();
3899 *input_line_pointer
= name_end
;
3900 demand_empty_rest_of_line ();
3902 #ifdef md_flush_pending_output
3903 md_flush_pending_output ();
3906 frag_align (3, 0, 0);
3908 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
3910 seginfo
->literal_pool_size
+= 16;
3912 *p
= alpha_evax_proc
.pdsckind
3913 | ((alpha_evax_proc
.framereg
== 29) ? PDSC_S_M_BASE_REG_IS_FP
: 0);
3914 *(p
+1) = PDSC_S_M_NATIVE
3915 | PDSC_S_M_NO_JACKET
;
3917 switch (alpha_evax_proc
.pdsckind
)
3919 case PDSC_S_K_KIND_NULL
:
3923 case PDSC_S_K_KIND_FP_REGISTER
:
3924 *(p
+2) = alpha_evax_proc
.fp_save
;
3925 *(p
+3) = alpha_evax_proc
.ra_save
;
3927 case PDSC_S_K_KIND_FP_STACK
:
3928 md_number_to_chars (p
+2, (valueT
)alpha_evax_proc
.rsa_offset
, 2);
3930 default: /* impossible */
3935 *(p
+5) = alpha_evax_proc
.type
& 0x0f;
3937 /* Signature offset. */
3938 md_number_to_chars (p
+6, (valueT
)0, 2);
3940 fix_new_exp (frag_now
, p
-frag_now
->fr_literal
+8, 8, &exp
, 0, BFD_RELOC_64
);
3942 if (alpha_evax_proc
.pdsckind
== PDSC_S_K_KIND_NULL
)
3945 /* Add dummy fix to make add_to_link_pool work. */
3947 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
3949 seginfo
->literal_pool_size
+= 8;
3951 /* pdesc+16: Size. */
3952 md_number_to_chars (p
, (valueT
)alpha_evax_proc
.framesize
, 4);
3954 md_number_to_chars (p
+4, (valueT
)0, 2);
3957 md_number_to_chars (p
+6, alpha_evax_proc
.prologue
, 2);
3959 if (alpha_evax_proc
.pdsckind
== PDSC_S_K_KIND_FP_REGISTER
)
3962 /* Add dummy fix to make add_to_link_pool work. */
3964 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
3966 seginfo
->literal_pool_size
+= 8;
3968 /* pdesc+24: register masks. */
3970 md_number_to_chars (p
, alpha_evax_proc
.imask
, 4);
3971 md_number_to_chars (p
+4, alpha_evax_proc
.fmask
, 4);
3977 /* Support for crash debug on vms. */
3980 s_alpha_name (ignore
)
3985 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
3987 if (now_seg
!= alpha_link_section
)
3989 as_bad (_(".name directive not in link (.link) section"));
3990 demand_empty_rest_of_line ();
3995 if (exp
.X_op
!= O_symbol
)
3997 as_warn (_(".name directive has no symbol"));
3998 demand_empty_rest_of_line ();
4002 demand_empty_rest_of_line ();
4004 #ifdef md_flush_pending_output
4005 md_flush_pending_output ();
4008 frag_align (3, 0, 0);
4010 seginfo
->literal_pool_size
+= 8;
4012 fix_new_exp (frag_now
, p
-frag_now
->fr_literal
, 8, &exp
, 0, BFD_RELOC_64
);
4019 s_alpha_linkage (ignore
)
4025 #ifdef md_flush_pending_output
4026 md_flush_pending_output ();
4030 if (exp
.X_op
!= O_symbol
)
4032 as_fatal (_("No symbol after .linkage"));
4036 p
= frag_more (LKP_S_K_SIZE
);
4037 memset (p
, 0, LKP_S_K_SIZE
);
4038 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, LKP_S_K_SIZE
, &exp
, 0,\
4039 BFD_RELOC_ALPHA_LINKAGE
);
4041 demand_empty_rest_of_line ();
4048 s_alpha_code_address (ignore
)
4054 #ifdef md_flush_pending_output
4055 md_flush_pending_output ();
4059 if (exp
.X_op
!= O_symbol
)
4061 as_fatal (_("No symbol after .code_address"));
4067 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 8, &exp
, 0,\
4068 BFD_RELOC_ALPHA_CODEADDR
);
4070 demand_empty_rest_of_line ();
4077 s_alpha_fp_save (ignore
)
4081 alpha_evax_proc
.fp_save
= tc_get_register (1);
4083 demand_empty_rest_of_line ();
4089 s_alpha_mask (ignore
)
4094 if (get_absolute_expression_and_terminator (&val
) != ',')
4096 as_warn (_("Bad .mask directive"));
4097 --input_line_pointer
;
4101 alpha_evax_proc
.imask
= val
;
4102 (void)get_absolute_expression ();
4104 demand_empty_rest_of_line ();
4111 s_alpha_fmask (ignore
)
4116 if (get_absolute_expression_and_terminator (&val
) != ',')
4118 as_warn (_("Bad .fmask directive"));
4119 --input_line_pointer
;
4123 alpha_evax_proc
.fmask
= val
;
4124 (void) get_absolute_expression ();
4126 demand_empty_rest_of_line ();
4132 s_alpha_end (ignore
)
4137 c
= get_symbol_end ();
4138 *input_line_pointer
= c
;
4139 demand_empty_rest_of_line ();
4140 alpha_evax_proc
.symbol
= 0;
4147 s_alpha_file (ignore
)
4152 static char case_hack
[32];
4154 extern char *demand_copy_string
PARAMS ((int *lenP
));
4156 sprintf (case_hack
, "<CASE:%01d%01d>",
4157 alpha_flag_hash_long_names
, alpha_flag_show_after_trunc
);
4159 s
= symbol_find_or_make (case_hack
);
4160 symbol_get_bfdsym (s
)->flags
|= BSF_FILE
;
4162 get_absolute_expression ();
4163 s
= symbol_find_or_make (demand_copy_string (&length
));
4164 symbol_get_bfdsym (s
)->flags
|= BSF_FILE
;
4165 demand_empty_rest_of_line ();
4169 #endif /* OBJ_EVAX */
4171 /* Handle the .gprel32 pseudo op. */
4174 s_alpha_gprel32 (ignore
)
4175 int ignore ATTRIBUTE_UNUSED
;
4187 e
.X_add_symbol
= section_symbol(absolute_section
);
4200 e
.X_add_symbol
= section_symbol (absolute_section
);
4203 e
.X_op
= O_subtract
;
4204 e
.X_op_symbol
= alpha_gp_symbol
;
4212 if (alpha_auto_align_on
&& alpha_current_align
< 2)
4213 alpha_align (2, (char *) NULL
, alpha_insn_label
, 0);
4214 if (alpha_current_align
> 2)
4215 alpha_current_align
= 2;
4216 alpha_insn_label
= NULL
;
4220 fix_new_exp (frag_now
, p
-frag_now
->fr_literal
, 4,
4221 &e
, 0, BFD_RELOC_GPREL32
);
4224 /* Handle floating point allocation pseudo-ops. This is like the
4225 generic vresion, but it makes sure the current label, if any, is
4226 correctly aligned. */
4229 s_alpha_float_cons (type
)
4256 if (alpha_auto_align_on
&& alpha_current_align
< log_size
)
4257 alpha_align (log_size
, (char *) NULL
, alpha_insn_label
, 0);
4258 if (alpha_current_align
> log_size
)
4259 alpha_current_align
= log_size
;
4260 alpha_insn_label
= NULL
;
4265 /* Handle the .proc pseudo op. We don't really do much with it except
4269 s_alpha_proc (is_static
)
4270 int is_static ATTRIBUTE_UNUSED
;
4278 /* Takes ".proc name,nargs" */
4280 name
= input_line_pointer
;
4281 c
= get_symbol_end ();
4282 p
= input_line_pointer
;
4283 symbolP
= symbol_find_or_make (name
);
4286 if (*input_line_pointer
!= ',')
4289 as_warn (_("Expected comma after name \"%s\""), name
);
4292 ignore_rest_of_line ();
4296 input_line_pointer
++;
4297 temp
= get_absolute_expression ();
4299 /* *symbol_get_obj (symbolP) = (signed char) temp; */
4300 as_warn (_("unhandled: .proc %s,%d"), name
, temp
);
4301 demand_empty_rest_of_line ();
4304 /* Handle the .set pseudo op. This is used to turn on and off most of
4305 the assembler features. */
4309 int x ATTRIBUTE_UNUSED
;
4315 name
= input_line_pointer
;
4316 ch
= get_symbol_end ();
4319 if (s
[0] == 'n' && s
[1] == 'o')
4324 if (!strcmp ("reorder", s
))
4326 else if (!strcmp ("at", s
))
4327 alpha_noat_on
= !yesno
;
4328 else if (!strcmp ("macro", s
))
4329 alpha_macros_on
= yesno
;
4330 else if (!strcmp ("move", s
))
4332 else if (!strcmp ("volatile", s
))
4335 as_warn (_("Tried to .set unrecognized mode `%s'"), name
);
4337 *input_line_pointer
= ch
;
4338 demand_empty_rest_of_line ();
4341 /* Handle the .base pseudo op. This changes the assembler's notion of
4342 the $gp register. */
4345 s_alpha_base (ignore
)
4346 int ignore ATTRIBUTE_UNUSED
;
4349 if (first_32bit_quadrant
)
4351 /* not fatal, but it might not work in the end */
4352 as_warn (_("File overrides no-base-register option."));
4353 first_32bit_quadrant
= 0;
4358 if (*input_line_pointer
== '$')
4360 input_line_pointer
++;
4361 if (*input_line_pointer
== 'r')
4362 input_line_pointer
++;
4365 alpha_gp_register
= get_absolute_expression ();
4366 if (alpha_gp_register
< 0 || alpha_gp_register
> 31)
4368 alpha_gp_register
= AXP_REG_GP
;
4369 as_warn (_("Bad base register, using $%d."), alpha_gp_register
);
4372 demand_empty_rest_of_line ();
4375 /* Handle the .align pseudo-op. This aligns to a power of two. It
4376 also adjusts any current instruction label. We treat this the same
4377 way the MIPS port does: .align 0 turns off auto alignment. */
4380 s_alpha_align (ignore
)
4381 int ignore ATTRIBUTE_UNUSED
;
4385 long max_alignment
= 15;
4387 align
= get_absolute_expression ();
4388 if (align
> max_alignment
)
4390 align
= max_alignment
;
4391 as_bad (_("Alignment too large: %d. assumed"), align
);
4395 as_warn (_("Alignment negative: 0 assumed"));
4399 if (*input_line_pointer
== ',')
4401 input_line_pointer
++;
4402 fill
= get_absolute_expression ();
4410 alpha_auto_align_on
= 1;
4411 alpha_align (align
, pfill
, alpha_insn_label
, 1);
4415 alpha_auto_align_on
= 0;
4418 demand_empty_rest_of_line ();
4421 /* Hook the normal string processor to reset known alignment. */
4424 s_alpha_stringer (terminate
)
4427 alpha_current_align
= 0;
4428 alpha_insn_label
= NULL
;
4429 stringer (terminate
);
4432 /* Hook the normal space processing to reset known alignment. */
4435 s_alpha_space (ignore
)
4438 alpha_current_align
= 0;
4439 alpha_insn_label
= NULL
;
4443 /* Hook into cons for auto-alignment. */
4446 alpha_cons_align (size
)
4452 while ((size
>>= 1) != 0)
4455 if (alpha_auto_align_on
&& alpha_current_align
< log_size
)
4456 alpha_align (log_size
, (char *) NULL
, alpha_insn_label
, 0);
4457 if (alpha_current_align
> log_size
)
4458 alpha_current_align
= log_size
;
4459 alpha_insn_label
= NULL
;
4462 /* Here come the .uword, .ulong, and .uquad explicitly unaligned
4463 pseudos. We just turn off auto-alignment and call down to cons. */
4466 s_alpha_ucons (bytes
)
4469 int hold
= alpha_auto_align_on
;
4470 alpha_auto_align_on
= 0;
4472 alpha_auto_align_on
= hold
;
4475 /* Switch the working cpu type. */
4478 s_alpha_arch (ignored
)
4479 int ignored ATTRIBUTE_UNUSED
;
4482 const struct cpu_type
*p
;
4485 name
= input_line_pointer
;
4486 ch
= get_symbol_end ();
4488 for (p
= cpu_types
; p
->name
; ++p
)
4489 if (strcmp(name
, p
->name
) == 0)
4491 alpha_target_name
= p
->name
, alpha_target
= p
->flags
;
4494 as_warn("Unknown CPU identifier `%s'", name
);
4497 *input_line_pointer
= ch
;
4498 demand_empty_rest_of_line ();
4504 /* print token expression with alpha specific extension. */
4507 alpha_print_token(f
, exp
)
4509 const expressionS
*exp
;
4519 expressionS nexp
= *exp
;
4520 nexp
.X_op
= O_register
;
4521 print_expr (f
, &nexp
);
4526 print_expr (f
, exp
);
4533 /* The target specific pseudo-ops which we support. */
4535 const pseudo_typeS md_pseudo_table
[] =
4538 {"comm", s_alpha_comm
, 0}, /* osf1 compiler does this */
4539 {"rdata", s_alpha_rdata
, 0},
4541 {"text", s_alpha_text
, 0},
4542 {"data", s_alpha_data
, 0},
4544 {"sdata", s_alpha_sdata
, 0},
4547 {"section", s_alpha_section
, 0},
4548 {"section.s", s_alpha_section
, 0},
4549 {"sect", s_alpha_section
, 0},
4550 {"sect.s", s_alpha_section
, 0},
4553 { "pdesc", s_alpha_pdesc
, 0},
4554 { "name", s_alpha_name
, 0},
4555 { "linkage", s_alpha_linkage
, 0},
4556 { "code_address", s_alpha_code_address
, 0},
4557 { "ent", s_alpha_ent
, 0},
4558 { "frame", s_alpha_frame
, 0},
4559 { "fp_save", s_alpha_fp_save
, 0},
4560 { "mask", s_alpha_mask
, 0},
4561 { "fmask", s_alpha_fmask
, 0},
4562 { "end", s_alpha_end
, 0},
4563 { "file", s_alpha_file
, 0},
4564 { "rdata", s_alpha_section
, 1},
4565 { "comm", s_alpha_comm
, 0},
4566 { "link", s_alpha_section
, 3},
4567 { "ctors", s_alpha_section
, 4},
4568 { "dtors", s_alpha_section
, 5},
4571 /* Frame related pseudos. */
4572 {"ent", s_alpha_ent
, 0},
4573 {"end", s_alpha_end
, 0},
4574 {"mask", s_alpha_mask
, 0},
4575 {"fmask", s_alpha_mask
, 1},
4576 {"frame", s_alpha_frame
, 0},
4577 {"prologue", s_alpha_prologue
, 0},
4578 /* COFF debugging related pseudos. */
4579 {"begin", s_alpha_coff_wrapper
, 0},
4580 {"bend", s_alpha_coff_wrapper
, 1},
4581 {"def", s_alpha_coff_wrapper
, 2},
4582 {"dim", s_alpha_coff_wrapper
, 3},
4583 {"endef", s_alpha_coff_wrapper
, 4},
4584 {"file", s_alpha_coff_wrapper
, 5},
4585 {"scl", s_alpha_coff_wrapper
, 6},
4586 {"tag", s_alpha_coff_wrapper
, 7},
4587 {"val", s_alpha_coff_wrapper
, 8},
4588 {"loc", s_alpha_coff_wrapper
, 9},
4590 {"prologue", s_ignore
, 0},
4592 {"gprel32", s_alpha_gprel32
, 0},
4593 {"t_floating", s_alpha_float_cons
, 'd'},
4594 {"s_floating", s_alpha_float_cons
, 'f'},
4595 {"f_floating", s_alpha_float_cons
, 'F'},
4596 {"g_floating", s_alpha_float_cons
, 'G'},
4597 {"d_floating", s_alpha_float_cons
, 'D'},
4599 {"proc", s_alpha_proc
, 0},
4600 {"aproc", s_alpha_proc
, 1},
4601 {"set", s_alpha_set
, 0},
4602 {"reguse", s_ignore
, 0},
4603 {"livereg", s_ignore
, 0},
4604 {"base", s_alpha_base
, 0}, /*??*/
4605 {"option", s_ignore
, 0},
4606 {"aent", s_ignore
, 0},
4607 {"ugen", s_ignore
, 0},
4608 {"eflag", s_ignore
, 0},
4610 {"align", s_alpha_align
, 0},
4611 {"double", s_alpha_float_cons
, 'd'},
4612 {"float", s_alpha_float_cons
, 'f'},
4613 {"single", s_alpha_float_cons
, 'f'},
4614 {"ascii", s_alpha_stringer
, 0},
4615 {"asciz", s_alpha_stringer
, 1},
4616 {"string", s_alpha_stringer
, 1},
4617 {"space", s_alpha_space
, 0},
4618 {"skip", s_alpha_space
, 0},
4619 {"zero", s_alpha_space
, 0},
4621 /* Unaligned data pseudos. */
4622 {"uword", s_alpha_ucons
, 2},
4623 {"ulong", s_alpha_ucons
, 4},
4624 {"uquad", s_alpha_ucons
, 8},
4627 /* Dwarf wants these versions of unaligned. */
4628 {"2byte", s_alpha_ucons
, 2},
4629 {"4byte", s_alpha_ucons
, 4},
4630 {"8byte", s_alpha_ucons
, 8},
4633 /* We don't do any optimizing, so we can safely ignore these. */
4634 {"noalias", s_ignore
, 0},
4635 {"alias", s_ignore
, 0},
4637 {"arch", s_alpha_arch
, 0},
4643 /* Build a BFD section with its flags set appropriately for the .lita,
4644 .lit8, or .lit4 sections. */
4647 create_literal_section (name
, secp
, symp
)
4652 segT current_section
= now_seg
;
4653 int current_subsec
= now_subseg
;
4656 *secp
= new_sec
= subseg_new (name
, 0);
4657 subseg_set (current_section
, current_subsec
);
4658 bfd_set_section_alignment (stdoutput
, new_sec
, 4);
4659 bfd_set_section_flags (stdoutput
, new_sec
,
4660 SEC_RELOC
| SEC_ALLOC
| SEC_LOAD
| SEC_READONLY
4663 S_CLEAR_EXTERNAL (*symp
= section_symbol (new_sec
));
4668 /* @@@ GP selection voodoo. All of this seems overly complicated and
4669 unnecessary; which is the primary reason it's for ECOFF only. */
4678 vma
= bfd_get_section_vma (foo
, sec
);
4679 if (vma
&& vma
< alpha_gp_value
)
4680 alpha_gp_value
= vma
;
4686 assert (alpha_gp_value
== 0);
4688 /* Get minus-one in whatever width... */
4689 alpha_gp_value
= 0; alpha_gp_value
--;
4691 /* Select the smallest VMA of these existing sections. */
4692 maybe_set_gp (alpha_lita_section
);
4694 /* These were disabled before -- should we use them? */
4695 maybe_set_gp (sdata
);
4696 maybe_set_gp (lit8_sec
);
4697 maybe_set_gp (lit4_sec
);
4700 /* @@ Will a simple 0x8000 work here? If not, why not? */
4701 #define GP_ADJUSTMENT (0x8000 - 0x10)
4703 alpha_gp_value
+= GP_ADJUSTMENT
;
4705 S_SET_VALUE (alpha_gp_symbol
, alpha_gp_value
);
4708 printf (_("Chose GP value of %lx\n"), alpha_gp_value
);
4711 #endif /* OBJ_ECOFF */
4713 /* Called internally to handle all alignment needs. This takes care
4714 of eliding calls to frag_align if'n the cached current alignment
4715 says we've already got it, as well as taking care of the auto-align
4716 feature wrt labels. */
4719 alpha_align (n
, pfill
, label
, force
)
4723 int force ATTRIBUTE_UNUSED
;
4725 if (alpha_current_align
>= n
)
4731 && (bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
) != 0)
4733 static char const unop
[4] = { 0x00, 0x00, 0xe0, 0x2f };
4734 static char const nopunop
[8] = {
4735 0x1f, 0x04, 0xff, 0x47,
4736 0x00, 0x00, 0xe0, 0x2f
4739 /* First, make sure we're on a four-byte boundary, in case
4740 someone has been putting .byte values into the text
4741 section. The DEC assembler silently fills with unaligned
4742 no-op instructions. This will zero-fill, then nop-fill
4743 with proper alignment. */
4744 if (alpha_current_align
< 2)
4745 frag_align (2, 0, 0);
4746 if (alpha_current_align
< 3)
4747 frag_align_pattern (3, unop
, sizeof unop
, 0);
4749 frag_align_pattern (n
, nopunop
, sizeof nopunop
, 0);
4752 frag_align (n
, 0, 0);
4755 frag_align (n
, *pfill
, 0);
4757 alpha_current_align
= n
;
4759 if (label
!= NULL
&& S_GET_SEGMENT (label
) == now_seg
)
4761 symbol_set_frag (label
, frag_now
);
4762 S_SET_VALUE (label
, (valueT
) frag_now_fix ());
4765 record_alignment (now_seg
, n
);
4767 /* ??? if alpha_flag_relax && force && elf, record the requested alignment
4768 in a reloc for the linker to see. */
4771 /* The Alpha has support for some VAX floating point types, as well as for
4772 IEEE floating point. We consider IEEE to be the primary floating point
4773 format, and sneak in the VAX floating point support here. */
4774 #define md_atof vax_md_atof
4775 #include "config/atof-vax.c"