]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gas/config/tc-alpha.c
* config/tc-alpha.c (alpha_align): Check, don't assert, that
[thirdparty/binutils-gdb.git] / gas / config / tc-alpha.c
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.
8
9 This file is part of GAS, the GNU Assembler.
10
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)
14 any later version.
15
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.
20
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
24 02111-1307, USA. */
25
26 /*
27 * Mach Operating System
28 * Copyright (c) 1993 Carnegie Mellon University
29 * All Rights Reserved.
30 *
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.
36 *
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.
40 *
41 * Carnegie Mellon requests users of this software to return to
42 *
43 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
44 * School of Computer Science
45 * Carnegie Mellon University
46 * Pittsburgh PA 15213-3890
47 *
48 * any improvements or extensions that they make and grant Carnegie the
49 * rights to redistribute these changes.
50 */
51
52 #include "as.h"
53 #include "subsegs.h"
54 #include "ecoff.h"
55
56 #include "opcode/alpha.h"
57
58 #ifdef OBJ_ELF
59 #include "elf/alpha.h"
60 #endif
61
62 #include <ctype.h>
63
64 \f
65 /* Local types */
66
67 #define MAX_INSN_FIXUPS 2
68 #define MAX_INSN_ARGS 5
69
70 struct alpha_fixup
71 {
72 expressionS exp;
73 bfd_reloc_code_real_type reloc;
74 };
75
76 struct alpha_insn
77 {
78 unsigned insn;
79 int nfixups;
80 struct alpha_fixup fixups[MAX_INSN_FIXUPS];
81 };
82
83 enum alpha_macro_arg
84 {
85 MACRO_EOA = 1, MACRO_IR, MACRO_PIR, MACRO_CPIR, MACRO_FPR, MACRO_EXP
86 };
87
88 struct alpha_macro
89 {
90 const char *name;
91 void (*emit) PARAMS ((const expressionS *, int, const PTR));
92 const PTR arg;
93 enum alpha_macro_arg argsets[16];
94 };
95
96 /* Extra expression types. */
97
98 #define O_pregister O_md1 /* O_register, in parentheses */
99 #define O_cpregister O_md2 /* + a leading comma */
100
101 /* Macros for extracting the type and number of encoded register tokens */
102
103 #define is_ir_num(x) (((x) & 32) == 0)
104 #define is_fpr_num(x) (((x) & 32) != 0)
105 #define regno(x) ((x) & 31)
106
107 /* Something odd inherited from the old assembler */
108
109 #define note_gpreg(R) (alpha_gprmask |= (1 << (R)))
110 #define note_fpreg(R) (alpha_fprmask |= (1 << (R)))
111
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. */
115
116 #if 1
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)
121 #else
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)
126 #endif
127
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. */
131
132 #if 1
133 #define sign_extend_16(x) ((short)(x))
134 #define sign_extend_32(x) ((int)(x))
135 #else
136 #define sign_extend_16(x) ((offsetT)(((x) & 0xFFFF) ^ 0x8000) - 0x8000)
137 #define sign_extend_32(x) ((offsetT)(((x) & 0xFFFFFFFF) \
138 ^ 0x80000000) - 0x80000000)
139 #endif
140
141 /* Macros to build tokens */
142
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))
162
163 \f
164 /* Prototypes for all local functions */
165
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));
181
182 static int load_expression
183 PARAMS ((int, const expressionS *, int *, expressionS *));
184
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));
201
202 static void s_alpha_text PARAMS ((int));
203 static void s_alpha_data PARAMS ((int));
204 #ifndef OBJ_ELF
205 static void s_alpha_comm PARAMS ((int));
206 static void s_alpha_rdata PARAMS ((int));
207 #endif
208 #ifdef OBJ_ECOFF
209 static void s_alpha_sdata PARAMS ((int));
210 #endif
211 #ifdef OBJ_ELF
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));
219 #endif
220 #ifdef OBJ_EVAX
221 static void s_alpha_section PARAMS ((int));
222 #endif
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));
231
232 static void create_literal_section PARAMS ((const char *, segT *, symbolS **));
233 #ifndef OBJ_ELF
234 static void select_gp_value PARAMS ((void));
235 #endif
236 static void alpha_align PARAMS ((int, char *, symbolS *, int));
237
238 \f
239 /* Generic assembler global variables which must be defined by all
240 targets. */
241
242 /* Characters which always start a comment. */
243 const char comment_chars[] = "#";
244
245 /* Characters which start a comment at the beginning of a line. */
246 const char line_comment_chars[] = "#";
247
248 /* Characters which may be used to separate multiple commands on a
249 single line. */
250 const char line_separator_chars[] = ";";
251
252 /* Characters which are used to indicate an exponent in a floating
253 point number. */
254 const char EXP_CHARS[] = "eE";
255
256 /* Characters which mean that a number is a floating point constant,
257 as in 0d1.0. */
258 #if 0
259 const char FLT_CHARS[] = "dD";
260 #else
261 /* XXX: Do all of these really get used on the alpha?? */
262 char FLT_CHARS[] = "rRsSfFdDxXpP";
263 #endif
264
265 #ifdef OBJ_EVAX
266 const char *md_shortopts = "Fm:g+1h:HG:";
267 #else
268 const char *md_shortopts = "Fm:gG:";
269 #endif
270
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 },
276 #ifdef OBJ_ELF
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 },
281 #endif
282 { NULL, no_argument, NULL, 0 }
283 };
284
285 size_t md_longopts_size = sizeof(md_longopts);
286
287 \f
288 #ifdef OBJ_EVAX
289 #define AXP_REG_R0 0
290 #define AXP_REG_R16 16
291 #define AXP_REG_R17 17
292 #undef AXP_REG_T9
293 #define AXP_REG_T9 22
294 #undef AXP_REG_T10
295 #define AXP_REG_T10 23
296 #undef AXP_REG_T11
297 #define AXP_REG_T11 24
298 #undef AXP_REG_T12
299 #define AXP_REG_T12 25
300 #define AXP_REG_AI 25
301 #undef AXP_REG_FP
302 #define AXP_REG_FP 29
303
304 #undef AXP_REG_GP
305 #define AXP_REG_GP AXP_REG_PV
306 #endif /* OBJ_EVAX */
307
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>";
311
312 /* The hash table of instruction opcodes */
313 static struct hash_control *alpha_opcode_hash;
314
315 /* The hash table of macro opcodes */
316 static struct hash_control *alpha_macro_hash;
317
318 #ifdef OBJ_ECOFF
319 /* The $gp relocation symbol */
320 static symbolS *alpha_gp_symbol;
321
322 /* XXX: what is this, and why is it exported? */
323 valueT alpha_gp_value;
324 #endif
325
326 /* The current $gp register */
327 static int alpha_gp_register = AXP_REG_GP;
328
329 /* A table of the register symbols */
330 static symbolS *alpha_register_table[64];
331
332 /* Constant sections, or sections of constants */
333 #ifdef OBJ_ECOFF
334 static segT alpha_lita_section;
335 static segT alpha_lit4_section;
336 #endif
337 #ifdef OBJ_EVAX
338 static segT alpha_link_section;
339 static segT alpha_ctors_section;
340 static segT alpha_dtors_section;
341 #endif
342 static segT alpha_lit8_section;
343
344 /* Symbols referring to said sections. */
345 #ifdef OBJ_ECOFF
346 static symbolS *alpha_lita_symbol;
347 static symbolS *alpha_lit4_symbol;
348 #endif
349 #ifdef OBJ_EVAX
350 static symbolS *alpha_link_symbol;
351 static symbolS *alpha_ctors_symbol;
352 static symbolS *alpha_dtors_symbol;
353 #endif
354 static symbolS *alpha_lit8_symbol;
355
356 /* Literal for .litX+0x8000 within .lita */
357 #ifdef OBJ_ECOFF
358 static offsetT alpha_lit4_literal;
359 static offsetT alpha_lit8_literal;
360 #endif
361
362 /* The active .ent symbol. */
363 #ifdef OBJ_ELF
364 static symbolS *alpha_cur_ent_sym;
365 #endif
366
367 /* Is the assembler not allowed to use $at? */
368 static int alpha_noat_on = 0;
369
370 /* Are macros enabled? */
371 static int alpha_macros_on = 1;
372
373 /* Are floats disabled? */
374 static int alpha_nofloats_on = 0;
375
376 /* Are addresses 32 bit? */
377 static int alpha_addr32_on = 0;
378
379 /* Symbol labelling the current insn. When the Alpha gas sees
380 foo:
381 .quad 0
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;
385
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;
389
390 /* The known current alignment of the current section. */
391 static int alpha_current_align;
392
393 /* These are exported to ECOFF code. */
394 unsigned long alpha_gprmask, alpha_fprmask;
395
396 /* Whether the debugging option was seen. */
397 static int alpha_debug;
398
399 #ifdef OBJ_ELF
400 /* Whether we are emitting an mdebug section. */
401 int alpha_flag_mdebug = 1;
402 #endif
403
404 /* Don't fully resolve relocations, allowing code movement in the linker. */
405 static int alpha_flag_relax;
406
407 /* What value to give to bfd_set_gp_size. */
408 static int g_switch_value = 8;
409
410 #ifdef OBJ_EVAX
411 /* Collect information about current procedure here. */
412 static struct {
413 symbolS *symbol; /* proc pdesc symbol */
414 int pdsckind;
415 int framereg; /* register for frame pointer */
416 int framesize; /* size of frame */
417 int rsa_offset;
418 int ra_save;
419 int fp_save;
420 long imask;
421 long fmask;
422 int type;
423 int prologue;
424 } alpha_evax_proc;
425
426 static int alpha_flag_hash_long_names = 0; /* -+ */
427 static int alpha_flag_show_after_trunc = 0; /* -H */
428
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.
431 */
432
433 #endif
434 \f
435 /* A table of CPU names and opcode sets. */
436
437 static const struct cpu_type
438 {
439 const char *name;
440 unsigned flags;
441 } cpu_types[] =
442 {
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. */
447
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
455 |AXP_OPCODE_MAX) },
456 { "21264", (AXP_OPCODE_BASE|AXP_OPCODE_EV6|AXP_OPCODE_BWX
457 |AXP_OPCODE_MAX|AXP_OPCODE_CIX) },
458
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 },
466
467 { "all", AXP_OPCODE_BASE },
468 { 0, 0 }
469 };
470
471 /* The macro table */
472
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 } },
480
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 } },
508
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 } },
521
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 } },
537
538 { "ldgp", emit_ldgp, NULL,
539 { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA } },
540
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 } },
547 #if 0
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 } },
558 #endif
559
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 } },
587
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 } },
603
604 /* Arithmetic macros */
605 #if 0
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 } },
612 #endif
613
614 { "sextb", emit_sextX, (PTR)0,
615 { MACRO_IR, MACRO_IR, MACRO_EOA,
616 MACRO_IR, MACRO_EOA,
617 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
618 { "sextw", emit_sextX, (PTR)1,
619 { MACRO_IR, MACRO_IR, MACRO_EOA,
620 MACRO_IR, MACRO_EOA,
621 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
622
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 */ } },
663
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,
676 MACRO_IR, MACRO_EOA,
677 MACRO_PIR, MACRO_EXP, MACRO_EOA,
678 MACRO_PIR, MACRO_EOA,
679 MACRO_EXP, MACRO_EOA,
680 MACRO_EOA } },
681 { "jcr", emit_retjcr, "jcr",
682 { MACRO_IR, MACRO_EXP, MACRO_EOA,
683 MACRO_IR, MACRO_EOA,
684 MACRO_PIR, MACRO_EXP, MACRO_EOA,
685 MACRO_PIR, MACRO_EOA,
686 MACRO_EXP, MACRO_EOA,
687 MACRO_EOA } },
688 { "jsr_coroutine", emit_retjcr, "jcr",
689 { MACRO_IR, MACRO_EXP, MACRO_EOA,
690 MACRO_IR, MACRO_EOA,
691 MACRO_PIR, MACRO_EXP, MACRO_EOA,
692 MACRO_PIR, MACRO_EOA,
693 MACRO_EXP, MACRO_EOA,
694 MACRO_EOA } },
695 };
696
697 static const unsigned int alpha_num_macros
698 = sizeof(alpha_macros) / sizeof(*alpha_macros);
699 \f
700 /* Public interface functions */
701
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. */
705
706 void
707 md_begin ()
708 {
709 unsigned int i;
710
711 /* Verify that X_op field is wide enough. */
712 {
713 expressionS e;
714 e.X_op = O_max;
715 assert (e.X_op == O_max);
716 }
717
718 /* Create the opcode hash table */
719
720 alpha_opcode_hash = hash_new ();
721 for (i = 0; i < alpha_num_opcodes; )
722 {
723 const char *name, *retval, *slash;
724
725 name = alpha_opcodes[i].name;
726 retval = hash_insert (alpha_opcode_hash, name, (PTR)&alpha_opcodes[i]);
727 if (retval)
728 as_fatal (_("internal error: can't hash opcode `%s': %s"), name, retval);
729
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
733 without the "/". */
734
735 if ((slash = strchr (name, '/')) != NULL)
736 {
737 char *p = xmalloc (strlen (name));
738 memcpy (p, name, slash - name);
739 strcpy (p + (slash - name), slash + 1);
740
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". */
744 }
745
746 while (++i < alpha_num_opcodes
747 && (alpha_opcodes[i].name == name
748 || !strcmp (alpha_opcodes[i].name, name)))
749 continue;
750 }
751
752 /* Create the macro hash table */
753
754 alpha_macro_hash = hash_new ();
755 for (i = 0; i < alpha_num_macros; )
756 {
757 const char *name, *retval;
758
759 name = alpha_macros[i].name;
760 retval = hash_insert (alpha_macro_hash, name, (PTR)&alpha_macros[i]);
761 if (retval)
762 as_fatal (_("internal error: can't hash macro `%s': %s"), name, retval);
763
764 while (++i < alpha_num_macros
765 && (alpha_macros[i].name == name
766 || !strcmp (alpha_macros[i].name, name)))
767 continue;
768 }
769
770 /* Construct symbols for each of the registers */
771
772 for (i = 0; i < 32; ++i)
773 {
774 char name[4];
775 sprintf(name, "$%d", i);
776 alpha_register_table[i] = symbol_create(name, reg_section, i,
777 &zero_address_frag);
778 }
779 for (; i < 64; ++i)
780 {
781 char name[5];
782 sprintf(name, "$f%d", i-32);
783 alpha_register_table[i] = symbol_create(name, reg_section, i,
784 &zero_address_frag);
785 }
786
787 /* Create the special symbols and sections we'll be using */
788
789 /* So .sbss will get used for tiny objects. */
790 bfd_set_gp_size (stdoutput, g_switch_value);
791
792 #ifdef OBJ_ECOFF
793 create_literal_section (".lita", &alpha_lita_section, &alpha_lita_symbol);
794
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,
798 &zero_address_frag);
799 #endif
800
801 #ifdef OBJ_EVAX
802 create_literal_section (".link", &alpha_link_section, &alpha_link_symbol);
803 #endif
804
805 #ifdef OBJ_ELF
806 if (ECOFF_DEBUGGING)
807 {
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);
811 }
812 #endif /* OBJ_ELF */
813
814 subseg_set(text_section, 0);
815 }
816
817 /* The public interface to the instruction assembler. */
818
819 void
820 md_assemble (str)
821 char *str;
822 {
823 char opname[32]; /* current maximum is 13 */
824 expressionS tok[MAX_INSN_ARGS];
825 int ntok, trunclen;
826 size_t opnamelen;
827
828 /* split off the opcode */
829 opnamelen = strspn (str, "abcdefghijklmnopqrstuvwxyz_/468");
830 trunclen = (opnamelen < sizeof (opname) - 1
831 ? opnamelen
832 : sizeof (opname) - 1);
833 memcpy (opname, str, trunclen);
834 opname[trunclen] = '\0';
835
836 /* tokenize the rest of the line */
837 if ((ntok = tokenize_arguments (str + opnamelen, tok, MAX_INSN_ARGS)) < 0)
838 {
839 as_bad (_("syntax error"));
840 return;
841 }
842
843 /* finish it off */
844 assemble_tokens (opname, tok, ntok, alpha_macros_on);
845 }
846
847 /* Round up a section's size to the appropriate boundary. */
848
849 valueT
850 md_section_align (seg, size)
851 segT seg;
852 valueT size;
853 {
854 int align = bfd_get_section_alignment(stdoutput, seg);
855 valueT mask = ((valueT)1 << align) - 1;
856
857 return (size + mask) & ~mask;
858 }
859
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. */
864
865 /* Equal to MAX_PRECISION in atof-ieee.c */
866 #define MAX_LITTLENUMS 6
867
868 extern char *vax_md_atof PARAMS ((int, char *, int *));
869
870 char *
871 md_atof (type, litP, sizeP)
872 char type;
873 char *litP;
874 int *sizeP;
875 {
876 int prec;
877 LITTLENUM_TYPE words[MAX_LITTLENUMS];
878 LITTLENUM_TYPE *wordP;
879 char *t;
880
881 switch (type)
882 {
883 /* VAX floats */
884 case 'G':
885 /* VAX md_atof doesn't like "G" for some reason. */
886 type = 'g';
887 case 'F':
888 case 'D':
889 return vax_md_atof (type, litP, sizeP);
890
891 /* IEEE floats */
892 case 'f':
893 prec = 2;
894 break;
895
896 case 'd':
897 prec = 4;
898 break;
899
900 case 'x':
901 case 'X':
902 prec = 6;
903 break;
904
905 case 'p':
906 case 'P':
907 prec = 6;
908 break;
909
910 default:
911 *sizeP = 0;
912 return _("Bad call to MD_ATOF()");
913 }
914 t = atof_ieee (input_line_pointer, type, words);
915 if (t)
916 input_line_pointer = t;
917 *sizeP = prec * sizeof (LITTLENUM_TYPE);
918
919 for (wordP = words + prec - 1; prec--;)
920 {
921 md_number_to_chars (litP, (long) (*wordP--), sizeof (LITTLENUM_TYPE));
922 litP += sizeof (LITTLENUM_TYPE);
923 }
924
925 return 0;
926 }
927
928 /* Take care of the target-specific command-line options. */
929
930 int
931 md_parse_option (c, arg)
932 int c;
933 char *arg;
934 {
935 switch (c)
936 {
937 case 'F':
938 alpha_nofloats_on = 1;
939 break;
940
941 case OPTION_32ADDR:
942 alpha_addr32_on = 1;
943 break;
944
945 case 'g':
946 alpha_debug = 1;
947 break;
948
949 case 'G':
950 g_switch_value = atoi(arg);
951 break;
952
953 case 'm':
954 {
955 const struct cpu_type *p;
956 for (p = cpu_types; p->name; ++p)
957 if (strcmp(arg, p->name) == 0)
958 {
959 alpha_target_name = p->name, alpha_target = p->flags;
960 goto found;
961 }
962 as_warn(_("Unknown CPU identifier `%s'"), arg);
963 found:;
964 }
965 break;
966
967 #ifdef OBJ_EVAX
968 case '+': /* For g++. Hash any name > 63 chars long. */
969 alpha_flag_hash_long_names = 1;
970 break;
971
972 case 'H': /* Show new symbol after hash truncation */
973 alpha_flag_show_after_trunc = 1;
974 break;
975
976 case 'h': /* for gnu-c/vax compatibility. */
977 break;
978 #endif
979
980 case OPTION_RELAX:
981 alpha_flag_relax = 1;
982 break;
983
984 #ifdef OBJ_ELF
985 case OPTION_MDEBUG:
986 alpha_flag_mdebug = 1;
987 break;
988 case OPTION_NO_MDEBUG:
989 alpha_flag_mdebug = 0;
990 break;
991 #endif
992
993 default:
994 return 0;
995 }
996
997 return 1;
998 }
999
1000 /* Print a description of the command-line options that we accept. */
1001
1002 void
1003 md_show_usage (stream)
1004 FILE *stream;
1005 {
1006 fputs(_("\
1007 Alpha options:\n\
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"),
1014 stream);
1015 #ifdef OBJ_EVAX
1016 fputs (_("\
1017 VMS options:\n\
1018 -+ hash encode (don't truncate) names longer than 64 characters\n\
1019 -H show new symbol after hash truncation\n"),
1020 stream);
1021 #endif
1022 }
1023
1024 /* Decide from what point a pc-relative relocation is relative to,
1025 relative to the pc-relative fixup. Er, relatively speaking. */
1026
1027 long
1028 md_pcrel_from (fixP)
1029 fixS *fixP;
1030 {
1031 valueT addr = fixP->fx_where + fixP->fx_frag->fr_address;
1032 switch (fixP->fx_r_type)
1033 {
1034 case BFD_RELOC_ALPHA_GPDISP:
1035 case BFD_RELOC_ALPHA_GPDISP_HI16:
1036 case BFD_RELOC_ALPHA_GPDISP_LO16:
1037 return addr;
1038 default:
1039 return fixP->fx_size + addr;
1040 }
1041 }
1042
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.
1046
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
1051 GPDISP. */
1052
1053 int
1054 md_apply_fix (fixP, valueP)
1055 fixS *fixP;
1056 valueT *valueP;
1057 {
1058 char * const fixpos = fixP->fx_frag->fr_literal + fixP->fx_where;
1059 valueT value = *valueP;
1060 unsigned image, size;
1061
1062 switch (fixP->fx_r_type)
1063 {
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:
1069 {
1070 fixS *next = fixP->fx_next;
1071 assert (next->fx_r_type == BFD_RELOC_ALPHA_GPDISP_LO16);
1072
1073 fixP->fx_offset = (next->fx_frag->fr_address + next->fx_where
1074 - fixP->fx_frag->fr_address - fixP->fx_where);
1075
1076 value = (value - sign_extend_16 (value)) >> 16;
1077 }
1078 #ifdef OBJ_ELF
1079 fixP->fx_r_type = BFD_RELOC_ALPHA_GPDISP;
1080 #endif
1081 goto do_reloc_gp;
1082
1083 case BFD_RELOC_ALPHA_GPDISP_LO16:
1084 value = sign_extend_16 (value);
1085 fixP->fx_offset = 0;
1086 #ifdef OBJ_ELF
1087 fixP->fx_done = 1;
1088 #endif
1089
1090 do_reloc_gp:
1091 fixP->fx_addsy = section_symbol (now_seg);
1092 md_number_to_chars (fixpos, value, 2);
1093 break;
1094
1095 case BFD_RELOC_16:
1096 if (fixP->fx_pcrel)
1097 fixP->fx_r_type = BFD_RELOC_16_PCREL;
1098 size = 2;
1099 goto do_reloc_xx;
1100 case BFD_RELOC_32:
1101 if (fixP->fx_pcrel)
1102 fixP->fx_r_type = BFD_RELOC_32_PCREL;
1103 size = 4;
1104 goto do_reloc_xx;
1105 case BFD_RELOC_64:
1106 if (fixP->fx_pcrel)
1107 fixP->fx_r_type = BFD_RELOC_64_PCREL;
1108 size = 8;
1109 do_reloc_xx:
1110 if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0)
1111 {
1112 md_number_to_chars (fixpos, value, size);
1113 goto done;
1114 }
1115 return 1;
1116
1117 #ifdef OBJ_ECOFF
1118 case BFD_RELOC_GPREL32:
1119 assert (fixP->fx_subsy == alpha_gp_symbol);
1120 fixP->fx_subsy = 0;
1121 /* FIXME: inherited this obliviousness of `value' -- why? */
1122 md_number_to_chars (fixpos, -alpha_gp_value, 4);
1123 break;
1124 #endif
1125 #ifdef OBJ_ELF
1126 case BFD_RELOC_GPREL32:
1127 return 1;
1128 #endif
1129
1130 case BFD_RELOC_23_PCREL_S2:
1131 if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0)
1132 {
1133 image = bfd_getl32(fixpos);
1134 image = (image & ~0x1FFFFF) | ((value >> 2) & 0x1FFFFF);
1135 goto write_done;
1136 }
1137 return 1;
1138
1139 case BFD_RELOC_ALPHA_HINT:
1140 if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0)
1141 {
1142 image = bfd_getl32(fixpos);
1143 image = (image & ~0x3FFF) | ((value >> 2) & 0x3FFF);
1144 goto write_done;
1145 }
1146 return 1;
1147
1148 #ifdef OBJ_ECOFF
1149 case BFD_RELOC_ALPHA_LITERAL:
1150 md_number_to_chars (fixpos, value, 2);
1151 return 1;
1152
1153 case BFD_RELOC_ALPHA_LITUSE:
1154 return 1;
1155 #endif
1156 #ifdef OBJ_ELF
1157 case BFD_RELOC_ALPHA_ELF_LITERAL:
1158 case BFD_RELOC_ALPHA_LITUSE:
1159 return 1;
1160 #endif
1161 #ifdef OBJ_EVAX
1162 case BFD_RELOC_ALPHA_LINKAGE:
1163 case BFD_RELOC_ALPHA_CODEADDR:
1164 return 1;
1165 #endif
1166
1167 default:
1168 {
1169 const struct alpha_operand *operand;
1170
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));
1174
1175 assert (-(int)fixP->fx_r_type < (int)alpha_num_operands);
1176 operand = &alpha_operands[-(int)fixP->fx_r_type];
1177
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. */
1181
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"));
1186
1187 image = bfd_getl32(fixpos);
1188 image = insert_operand(image, operand, (offsetT)value,
1189 fixP->fx_file, fixP->fx_line);
1190 }
1191 goto write_done;
1192 }
1193
1194 if (fixP->fx_addsy != 0 || fixP->fx_pcrel != 0)
1195 return 1;
1196 else
1197 {
1198 as_warn_where(fixP->fx_file, fixP->fx_line,
1199 _("type %d reloc done?\n"), (int)fixP->fx_r_type);
1200 goto done;
1201 }
1202
1203 write_done:
1204 md_number_to_chars(fixpos, image, 4);
1205
1206 done:
1207 fixP->fx_done = 1;
1208 return 0;
1209 }
1210
1211 /*
1212 * Look for a register name in the given symbol.
1213 */
1214
1215 symbolS *
1216 md_undefined_symbol(name)
1217 char *name;
1218 {
1219 if (*name == '$')
1220 {
1221 int is_float = 0, num;
1222
1223 switch (*++name)
1224 {
1225 case 'f':
1226 if (name[1] == 'p' && name[2] == '\0')
1227 return alpha_register_table[AXP_REG_FP];
1228 is_float = 32;
1229 /* FALLTHRU */
1230
1231 case 'r':
1232 if (!isdigit(*++name))
1233 break;
1234 /* FALLTHRU */
1235
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')
1241 {
1242 num = (name[0] - '0') * 10 + name[1] - '0';
1243 if (num >= 32)
1244 break;
1245 }
1246 else
1247 break;
1248
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];
1252
1253 case 'a':
1254 if (name[1] == 't' && name[2] == '\0')
1255 {
1256 if (!alpha_noat_on)
1257 as_warn(_("Used $at without \".set noat\""));
1258 return alpha_register_table[AXP_REG_AT];
1259 }
1260 break;
1261
1262 case 'g':
1263 if (name[1] == 'p' && name[2] == '\0')
1264 return alpha_register_table[alpha_gp_register];
1265 break;
1266
1267 case 's':
1268 if (name[1] == 'p' && name[2] == '\0')
1269 return alpha_register_table[AXP_REG_SP];
1270 break;
1271 }
1272 }
1273 return NULL;
1274 }
1275
1276 #ifdef OBJ_ECOFF
1277 /* @@@ Magic ECOFF bits. */
1278
1279 void
1280 alpha_frob_ecoff_data ()
1281 {
1282 select_gp_value ();
1283 /* $zero and $f31 are read-only */
1284 alpha_gprmask &= ~1;
1285 alpha_fprmask &= ~1;
1286 }
1287 #endif
1288
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
1291 required. */
1292
1293 void
1294 alpha_define_label (sym)
1295 symbolS *sym;
1296 {
1297 alpha_insn_label = sym;
1298 }
1299
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. */
1302
1303 int
1304 alpha_force_relocation (f)
1305 fixS *f;
1306 {
1307 if (alpha_flag_relax)
1308 return 1;
1309
1310 switch (f->fx_r_type)
1311 {
1312 case BFD_RELOC_ALPHA_GPDISP_HI16:
1313 case BFD_RELOC_ALPHA_GPDISP_LO16:
1314 case BFD_RELOC_ALPHA_GPDISP:
1315 #ifdef OBJ_ECOFF
1316 case BFD_RELOC_ALPHA_LITERAL:
1317 #endif
1318 #ifdef OBJ_ELF
1319 case BFD_RELOC_ALPHA_ELF_LITERAL:
1320 #endif
1321 case BFD_RELOC_ALPHA_LITUSE:
1322 case BFD_RELOC_GPREL32:
1323 #ifdef OBJ_EVAX
1324 case BFD_RELOC_ALPHA_LINKAGE:
1325 case BFD_RELOC_ALPHA_CODEADDR:
1326 #endif
1327 return 1;
1328
1329 case BFD_RELOC_23_PCREL_S2:
1330 case BFD_RELOC_32:
1331 case BFD_RELOC_64:
1332 case BFD_RELOC_ALPHA_HINT:
1333 return 0;
1334
1335 default:
1336 assert((int)f->fx_r_type < 0 && -(int)f->fx_r_type < (int)alpha_num_operands);
1337 return 0;
1338 }
1339 }
1340
1341 /* Return true if we can partially resolve a relocation now. */
1342
1343 int
1344 alpha_fix_adjustable (f)
1345 fixS *f;
1346 {
1347 #ifdef OBJ_ELF
1348 /* Prevent all adjustments to global symbols */
1349 if (S_IS_EXTERN (f->fx_addsy) || S_IS_WEAK (f->fx_addsy))
1350 return 0;
1351 #endif
1352
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)
1356 {
1357 case BFD_RELOC_ALPHA_GPDISP_HI16:
1358 case BFD_RELOC_ALPHA_GPDISP_LO16:
1359 case BFD_RELOC_ALPHA_GPDISP:
1360 return 0;
1361
1362 #ifdef OBJ_ECOFF
1363 case BFD_RELOC_ALPHA_LITERAL:
1364 #endif
1365 #ifdef OBJ_ELF
1366 case BFD_RELOC_ALPHA_ELF_LITERAL:
1367 #endif
1368 #ifdef OBJ_EVAX
1369 case BFD_RELOC_ALPHA_LINKAGE:
1370 case BFD_RELOC_ALPHA_CODEADDR:
1371 #endif
1372 return 1;
1373
1374 case BFD_RELOC_ALPHA_LITUSE:
1375 return 0;
1376
1377 case BFD_RELOC_GPREL32:
1378 case BFD_RELOC_23_PCREL_S2:
1379 case BFD_RELOC_32:
1380 case BFD_RELOC_64:
1381 case BFD_RELOC_ALPHA_HINT:
1382 return 1;
1383
1384 default:
1385 assert ((int)f->fx_r_type < 0
1386 && - (int)f->fx_r_type < (int)alpha_num_operands);
1387 return 1;
1388 }
1389 /*NOTREACHED*/
1390 }
1391
1392 /* Generate the BFD reloc to be stuck in the object file from the
1393 fixup used internally in the assembler. */
1394
1395 arelent *
1396 tc_gen_reloc (sec, fixp)
1397 asection *sec ATTRIBUTE_UNUSED;
1398 fixS *fixp;
1399 {
1400 arelent *reloc;
1401
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;
1406
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);
1410
1411 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
1412 if (reloc->howto == NULL)
1413 {
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));
1417 return NULL;
1418 }
1419
1420 if (!fixp->fx_pcrel != !reloc->howto->pc_relative)
1421 {
1422 as_fatal (_("internal error? cannot generate `%s' relocation"),
1423 bfd_get_reloc_code_name (fixp->fx_r_type));
1424 }
1425 assert (!fixp->fx_pcrel == !reloc->howto->pc_relative);
1426
1427 #ifdef OBJ_ECOFF
1428 if (fixp->fx_r_type == BFD_RELOC_ALPHA_LITERAL)
1429 {
1430 /* fake out bfd_perform_relocation. sigh */
1431 reloc->addend = -alpha_gp_value;
1432 }
1433 else
1434 #endif
1435 {
1436 reloc->addend = fixp->fx_offset;
1437 #ifdef OBJ_ELF
1438 /*
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.
1443 */
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;
1447 #endif
1448 }
1449
1450 return reloc;
1451 }
1452
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
1455 matching for us.
1456
1457 Only called as a part of processing the ECOFF .frame directive. */
1458
1459 int
1460 tc_get_register (frame)
1461 int frame ATTRIBUTE_UNUSED;
1462 {
1463 int framereg = AXP_REG_SP;
1464
1465 SKIP_WHITESPACE ();
1466 if (*input_line_pointer == '$')
1467 {
1468 char *s = input_line_pointer;
1469 char c = get_symbol_end ();
1470 symbolS *sym = md_undefined_symbol (s);
1471
1472 *strchr(s, '\0') = c;
1473 if (sym && (framereg = S_GET_VALUE (sym)) <= 31)
1474 goto found;
1475 }
1476 as_warn (_("frame reg expected, using $%d."), framereg);
1477
1478 found:
1479 note_gpreg (framereg);
1480 return framereg;
1481 }
1482
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. */
1489
1490 #ifdef OBJ_ECOFF
1491
1492 void
1493 alpha_frob_file_before_adjust ()
1494 {
1495 if (alpha_debug != 0
1496 && ! ecoff_debugging_seen)
1497 flag_keep_locals = 1;
1498 }
1499
1500 #endif /* OBJ_ECOFF */
1501 \f
1502 /* Parse the arguments to an opcode. */
1503
1504 static int
1505 tokenize_arguments (str, tok, ntok)
1506 char *str;
1507 expressionS tok[];
1508 int ntok;
1509 {
1510 expressionS *end_tok = tok + ntok;
1511 char *old_input_line_pointer;
1512 int saw_comma = 0, saw_arg = 0;
1513
1514 memset (tok, 0, sizeof (*tok) * ntok);
1515
1516 /* Save and restore input_line_pointer around this function */
1517 old_input_line_pointer = input_line_pointer;
1518 input_line_pointer = str;
1519
1520 while (tok < end_tok && *input_line_pointer)
1521 {
1522 SKIP_WHITESPACE ();
1523 switch (*input_line_pointer)
1524 {
1525 case '\0':
1526 goto fini;
1527
1528 case ',':
1529 ++input_line_pointer;
1530 if (saw_comma || !saw_arg)
1531 goto err;
1532 saw_comma = 1;
1533 break;
1534
1535 case '(':
1536 {
1537 char *hold = input_line_pointer++;
1538
1539 /* First try for parenthesized register ... */
1540 expression (tok);
1541 if (*input_line_pointer == ')' && tok->X_op == O_register)
1542 {
1543 tok->X_op = (saw_comma ? O_cpregister : O_pregister);
1544 saw_comma = 0;
1545 saw_arg = 1;
1546 ++input_line_pointer;
1547 ++tok;
1548 break;
1549 }
1550
1551 /* ... then fall through to plain expression */
1552 input_line_pointer = hold;
1553 }
1554
1555 default:
1556 if (saw_arg && !saw_comma)
1557 goto err;
1558 expression (tok);
1559 if (tok->X_op == O_illegal || tok->X_op == O_absent)
1560 goto err;
1561
1562 saw_comma = 0;
1563 saw_arg = 1;
1564 ++tok;
1565 break;
1566 }
1567 }
1568
1569 fini:
1570 if (saw_comma)
1571 goto err;
1572 input_line_pointer = old_input_line_pointer;
1573 return ntok - (end_tok - tok);
1574
1575 err:
1576 input_line_pointer = old_input_line_pointer;
1577 return -1;
1578 }
1579
1580 /* Search forward through all variants of an opcode looking for a
1581 syntax match. */
1582
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;
1587 int *pntok;
1588 int *pcpumatch;
1589 {
1590 const struct alpha_opcode *opcode = first_opcode;
1591 int ntok = *pntok;
1592 int got_cpu_match = 0;
1593
1594 do
1595 {
1596 const unsigned char *opidx;
1597 int tokidx = 0;
1598
1599 /* Don't match opcodes that don't exist on this architecture */
1600 if (!(opcode->flags & alpha_target))
1601 goto match_failed;
1602
1603 got_cpu_match = 1;
1604
1605 for (opidx = opcode->operands; *opidx; ++opidx)
1606 {
1607 const struct alpha_operand *operand = &alpha_operands[*opidx];
1608
1609 /* only take input from real operands */
1610 if (operand->flags & AXP_OPERAND_FAKE)
1611 continue;
1612
1613 /* when we expect input, make sure we have it */
1614 if (tokidx >= ntok)
1615 {
1616 if ((operand->flags & AXP_OPERAND_OPTIONAL_MASK) == 0)
1617 goto match_failed;
1618 continue;
1619 }
1620
1621 /* match operand type with expression type */
1622 switch (operand->flags & AXP_OPERAND_TYPECHECK_MASK)
1623 {
1624 case AXP_OPERAND_IR:
1625 if (tok[tokidx].X_op != O_register
1626 || !is_ir_num(tok[tokidx].X_add_number))
1627 goto match_failed;
1628 break;
1629 case AXP_OPERAND_FPR:
1630 if (tok[tokidx].X_op != O_register
1631 || !is_fpr_num(tok[tokidx].X_add_number))
1632 goto match_failed;
1633 break;
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))
1637 goto match_failed;
1638 break;
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))
1642 goto match_failed;
1643 break;
1644
1645 case AXP_OPERAND_RELATIVE:
1646 case AXP_OPERAND_SIGNED:
1647 case AXP_OPERAND_UNSIGNED:
1648 switch (tok[tokidx].X_op)
1649 {
1650 case O_illegal:
1651 case O_absent:
1652 case O_register:
1653 case O_pregister:
1654 case O_cpregister:
1655 goto match_failed;
1656
1657 default:
1658 break;
1659 }
1660 break;
1661
1662 default:
1663 /* everything else should have been fake */
1664 abort();
1665 }
1666 ++tokidx;
1667 }
1668
1669 /* possible match -- did we use all of our input? */
1670 if (tokidx == ntok)
1671 {
1672 *pntok = ntok;
1673 return opcode;
1674 }
1675
1676 match_failed:;
1677 }
1678 while (++opcode-alpha_opcodes < alpha_num_opcodes
1679 && !strcmp(opcode->name, first_opcode->name));
1680
1681 if (*pcpumatch)
1682 *pcpumatch = got_cpu_match;
1683
1684 return NULL;
1685 }
1686
1687 /* Search forward through all variants of a macro looking for a syntax
1688 match. */
1689
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;
1694 int *pntok;
1695 {
1696 const struct alpha_macro *macro = first_macro;
1697 int ntok = *pntok;
1698
1699 do
1700 {
1701 const enum alpha_macro_arg *arg = macro->argsets;
1702 int tokidx = 0;
1703
1704 while (*arg)
1705 {
1706 switch (*arg)
1707 {
1708 case MACRO_EOA:
1709 if (tokidx == ntok)
1710 return macro;
1711 else
1712 tokidx = 0;
1713 break;
1714
1715 case MACRO_IR:
1716 if (tokidx >= ntok || tok[tokidx].X_op != O_register
1717 || !is_ir_num(tok[tokidx].X_add_number))
1718 goto match_failed;
1719 ++tokidx;
1720 break;
1721 case MACRO_PIR:
1722 if (tokidx >= ntok || tok[tokidx].X_op != O_pregister
1723 || !is_ir_num(tok[tokidx].X_add_number))
1724 goto match_failed;
1725 ++tokidx;
1726 break;
1727 case MACRO_CPIR:
1728 if (tokidx >= ntok || tok[tokidx].X_op != O_cpregister
1729 || !is_ir_num(tok[tokidx].X_add_number))
1730 goto match_failed;
1731 ++tokidx;
1732 break;
1733 case MACRO_FPR:
1734 if (tokidx >= ntok || tok[tokidx].X_op != O_register
1735 || !is_fpr_num(tok[tokidx].X_add_number))
1736 goto match_failed;
1737 ++tokidx;
1738 break;
1739
1740 case MACRO_EXP:
1741 if (tokidx >= ntok)
1742 goto match_failed;
1743 switch (tok[tokidx].X_op)
1744 {
1745 case O_illegal:
1746 case O_absent:
1747 case O_register:
1748 case O_pregister:
1749 case O_cpregister:
1750 goto match_failed;
1751
1752 default:
1753 break;
1754 }
1755 ++tokidx;
1756 break;
1757
1758 match_failed:
1759 while (*arg != MACRO_EOA)
1760 ++arg;
1761 tokidx = 0;
1762 break;
1763 }
1764 ++arg;
1765 }
1766 }
1767 while (++macro-alpha_macros < alpha_num_macros
1768 && !strcmp(macro->name, first_macro->name));
1769
1770 return NULL;
1771 }
1772
1773 /* Insert an operand value into an instruction. */
1774
1775 static unsigned
1776 insert_operand(insn, operand, val, file, line)
1777 unsigned insn;
1778 const struct alpha_operand *operand;
1779 offsetT val;
1780 char *file;
1781 unsigned line;
1782 {
1783 if (operand->bits != 32 && !(operand->flags & AXP_OPERAND_NOOVERFLOW))
1784 {
1785 offsetT min, max;
1786
1787 if (operand->flags & AXP_OPERAND_SIGNED)
1788 {
1789 max = (1 << (operand->bits - 1)) - 1;
1790 min = -(1 << (operand->bits - 1));
1791 }
1792 else
1793 {
1794 max = (1 << operand->bits) - 1;
1795 min = 0;
1796 }
1797
1798 if (val < min || val > max)
1799 {
1800 const char *err =
1801 _("operand out of range (%s not between %d and %d)");
1802 char buf[sizeof (val) * 3 + 2];
1803
1804 sprint_value(buf, val);
1805 if (file)
1806 as_warn_where(file, line, err, buf, min, max);
1807 else
1808 as_warn(err, buf, min, max);
1809 }
1810 }
1811
1812 if (operand->insert)
1813 {
1814 const char *errmsg = NULL;
1815
1816 insn = (*operand->insert) (insn, val, &errmsg);
1817 if (errmsg)
1818 as_warn (errmsg);
1819 }
1820 else
1821 insn |= ((val & ((1 << operand->bits) - 1)) << operand->shift);
1822
1823 return insn;
1824 }
1825
1826 /*
1827 * Turn an opcode description and a set of arguments into
1828 * an instruction and a fixup.
1829 */
1830
1831 static void
1832 assemble_insn(opcode, tok, ntok, insn)
1833 const struct alpha_opcode *opcode;
1834 const expressionS *tok;
1835 int ntok;
1836 struct alpha_insn *insn;
1837 {
1838 const unsigned char *argidx;
1839 unsigned image;
1840 int tokidx = 0;
1841
1842 memset (insn, 0, sizeof (*insn));
1843 image = opcode->opcode;
1844
1845 for (argidx = opcode->operands; *argidx; ++argidx)
1846 {
1847 const struct alpha_operand *operand = &alpha_operands[*argidx];
1848 const expressionS *t = (const expressionS *)0;
1849
1850 if (operand->flags & AXP_OPERAND_FAKE)
1851 {
1852 /* fake operands take no value and generate no fixup */
1853 image = insert_operand(image, operand, 0, NULL, 0);
1854 continue;
1855 }
1856
1857 if (tokidx >= ntok)
1858 {
1859 switch (operand->flags & AXP_OPERAND_OPTIONAL_MASK)
1860 {
1861 case AXP_OPERAND_DEFAULT_FIRST:
1862 t = &tok[0];
1863 break;
1864 case AXP_OPERAND_DEFAULT_SECOND:
1865 t = &tok[1];
1866 break;
1867 case AXP_OPERAND_DEFAULT_ZERO:
1868 {
1869 static expressionS zero_exp;
1870 t = &zero_exp;
1871 zero_exp.X_op = O_constant;
1872 zero_exp.X_unsigned = 1;
1873 }
1874 break;
1875 default:
1876 abort();
1877 }
1878 }
1879 else
1880 t = &tok[tokidx++];
1881
1882 switch (t->X_op)
1883 {
1884 case O_register:
1885 case O_pregister:
1886 case O_cpregister:
1887 image = insert_operand(image, operand, regno(t->X_add_number),
1888 NULL, 0);
1889 break;
1890
1891 case O_constant:
1892 image = insert_operand(image, operand, t->X_add_number, NULL, 0);
1893 break;
1894
1895 default:
1896 {
1897 struct alpha_fixup *fixup;
1898
1899 if (insn->nfixups >= MAX_INSN_FIXUPS)
1900 as_fatal(_("too many fixups"));
1901
1902 fixup = &insn->fixups[insn->nfixups++];
1903
1904 fixup->exp = *t;
1905 fixup->reloc = operand->default_reloc;
1906 }
1907 break;
1908 }
1909 }
1910
1911 insn->insn = image;
1912 }
1913
1914 /*
1915 * Actually output an instruction with its fixup.
1916 */
1917
1918 static void
1919 emit_insn (insn)
1920 struct alpha_insn *insn;
1921 {
1922 char *f;
1923 int i;
1924
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;
1931
1932 /* Write out the instruction. */
1933 f = frag_more (4);
1934 md_number_to_chars (f, insn->insn, 4);
1935
1936 /* Apply the fixups in order */
1937 for (i = 0; i < insn->nfixups; ++i)
1938 {
1939 const struct alpha_operand *operand = (const struct alpha_operand *)0;
1940 struct alpha_fixup *fixup = &insn->fixups[i];
1941 int size, pcrel;
1942 fixS *fixP;
1943
1944 /* Some fixups are only used internally and so have no howto */
1945 if ((int)fixup->reloc < 0)
1946 {
1947 operand = &alpha_operands[-(int)fixup->reloc];
1948 size = 4;
1949 pcrel = ((operand->flags & AXP_OPERAND_RELATIVE) != 0);
1950 }
1951 #ifdef OBJ_ELF
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)
1955 {
1956 size = 2, pcrel = 0;
1957 }
1958 #endif
1959 else
1960 {
1961 reloc_howto_type *reloc_howto
1962 = bfd_reloc_type_lookup (stdoutput, fixup->reloc);
1963 assert (reloc_howto);
1964
1965 size = bfd_get_reloc_size (reloc_howto);
1966 pcrel = reloc_howto->pc_relative;
1967 }
1968 assert (size >= 1 && size <= 4);
1969
1970 fixP = fix_new_exp (frag_now, f - frag_now->fr_literal, size,
1971 &fixup->exp, pcrel, fixup->reloc);
1972
1973 /* Turn off complaints that the addend is too large for some fixups */
1974 switch (fixup->reloc)
1975 {
1976 case BFD_RELOC_ALPHA_GPDISP_LO16:
1977 #ifdef OBJ_ECOFF
1978 case BFD_RELOC_ALPHA_LITERAL:
1979 #endif
1980 #ifdef OBJ_ELF
1981 case BFD_RELOC_ALPHA_ELF_LITERAL:
1982 #endif
1983 case BFD_RELOC_GPREL32:
1984 fixP->fx_no_overflow = 1;
1985 break;
1986
1987 default:
1988 if ((int)fixup->reloc < 0)
1989 {
1990 if (operand->flags & AXP_OPERAND_NOOVERFLOW)
1991 fixP->fx_no_overflow = 1;
1992 }
1993 break;
1994 }
1995 }
1996 }
1997
1998 /* Given an opcode name and a pre-tokenized set of arguments, assemble
1999 the insn, but do not emit it.
2000
2001 Note that this implies no macros allowed, since we can't store more
2002 than one insn in an insn structure. */
2003
2004 static void
2005 assemble_tokens_to_insn(opname, tok, ntok, insn)
2006 const char *opname;
2007 const expressionS *tok;
2008 int ntok;
2009 struct alpha_insn *insn;
2010 {
2011 const struct alpha_opcode *opcode;
2012
2013 /* search opcodes */
2014 opcode = (const struct alpha_opcode *) hash_find (alpha_opcode_hash, opname);
2015 if (opcode)
2016 {
2017 int cpumatch;
2018 opcode = find_opcode_match (opcode, tok, &ntok, &cpumatch);
2019 if (opcode)
2020 {
2021 assemble_insn (opcode, tok, ntok, insn);
2022 return;
2023 }
2024 else if (cpumatch)
2025 as_bad (_("inappropriate arguments for opcode `%s'"), opname);
2026 else
2027 as_bad (_("opcode `%s' not supported for target %s"), opname,
2028 alpha_target_name);
2029 }
2030 else
2031 as_bad (_("unknown opcode `%s'"), opname);
2032 }
2033
2034 /* Given an opcode name and a pre-tokenized set of arguments, take the
2035 opcode all the way through emission. */
2036
2037 static void
2038 assemble_tokens (opname, tok, ntok, local_macros_on)
2039 const char *opname;
2040 const expressionS *tok;
2041 int ntok;
2042 int local_macros_on;
2043 {
2044 int found_something = 0;
2045 const struct alpha_opcode *opcode;
2046 const struct alpha_macro *macro;
2047 int cpumatch = 1;
2048
2049 /* search macros */
2050 if (local_macros_on)
2051 {
2052 macro = ((const struct alpha_macro *)
2053 hash_find (alpha_macro_hash, opname));
2054 if (macro)
2055 {
2056 found_something = 1;
2057 macro = find_macro_match (macro, tok, &ntok);
2058 if (macro)
2059 {
2060 (*macro->emit) (tok, ntok, macro->arg);
2061 return;
2062 }
2063 }
2064 }
2065
2066 /* search opcodes */
2067 opcode = (const struct alpha_opcode *) hash_find (alpha_opcode_hash, opname);
2068 if (opcode)
2069 {
2070 found_something = 1;
2071 opcode = find_opcode_match (opcode, tok, &ntok, &cpumatch);
2072 if (opcode)
2073 {
2074 struct alpha_insn insn;
2075 assemble_insn (opcode, tok, ntok, &insn);
2076 emit_insn (&insn);
2077 return;
2078 }
2079 }
2080
2081 if (found_something)
2082 if (cpumatch)
2083 as_bad (_("inappropriate arguments for opcode `%s'"), opname);
2084 else
2085 as_bad (_("opcode `%s' not supported for target %s"), opname,
2086 alpha_target_name);
2087 else
2088 as_bad (_("unknown opcode `%s'"), opname);
2089 }
2090
2091 \f
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 };
2103
2104 /* Implement the ldgp macro. */
2105
2106 static void
2107 emit_ldgp (tok, ntok, unused)
2108 const expressionS *tok;
2109 int ntok ATTRIBUTE_UNUSED;
2110 const PTR unused ATTRIBUTE_UNUSED;
2111 {
2112 #ifdef OBJ_AOUT
2113 FIXME
2114 #endif
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];
2120 expressionS addend;
2121
2122 #ifdef OBJ_ECOFF
2123 if (regno (tok[2].X_add_number) == AXP_REG_PV)
2124 ecoff_set_gp_prolog_size (0);
2125 #endif
2126
2127 newtok[0] = tok[0];
2128 set_tok_const (newtok[1], 0);
2129 newtok[2] = tok[2];
2130
2131 assemble_tokens_to_insn ("ldah", newtok, 3, &insn);
2132
2133 addend = tok[1];
2134
2135 #ifdef OBJ_ECOFF
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;
2140 #endif
2141
2142 insn.nfixups = 1;
2143 insn.fixups[0].exp = addend;
2144 insn.fixups[0].reloc = BFD_RELOC_ALPHA_GPDISP_HI16;
2145
2146 emit_insn (&insn);
2147
2148 set_tok_preg (newtok[2], tok[0].X_add_number);
2149
2150 assemble_tokens_to_insn ("lda", newtok, 3, &insn);
2151
2152 #ifdef OBJ_ECOFF
2153 addend.X_add_number += 4;
2154 #endif
2155
2156 insn.nfixups = 1;
2157 insn.fixups[0].exp = addend;
2158 insn.fixups[0].reloc = BFD_RELOC_ALPHA_GPDISP_LO16;
2159
2160 emit_insn (&insn);
2161 #endif /* OBJ_ECOFF || OBJ_ELF */
2162 }
2163
2164 #ifdef OBJ_EVAX
2165
2166 /* Add symbol+addend to link pool.
2167 Return offset from basesym to entry in link pool.
2168
2169 Add new fixup only if offset isn't 16bit. */
2170
2171 valueT
2172 add_to_link_pool (basesym, sym, addend)
2173 symbolS *basesym;
2174 symbolS *sym;
2175 offsetT addend;
2176 {
2177 segT current_section = now_seg;
2178 int current_subsec = now_subseg;
2179 valueT offset;
2180 bfd_reloc_code_real_type reloc_type;
2181 char *p;
2182 segment_info_type *seginfo = seg_info (alpha_link_section);
2183 fixS *fixp;
2184
2185 offset = - *symbol_get_obj (basesym);
2186
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. */
2190
2191 if (seginfo->frchainP)
2192 for (fixp = seginfo->frchainP->fix_root;
2193 fixp != (fixS *) NULL;
2194 fixp = fixp->fx_next, offset += 8)
2195 {
2196 if (fixp->fx_addsy == sym && fixp->fx_offset == addend)
2197 {
2198 if (range_signed_16 (offset))
2199 {
2200 return offset;
2201 }
2202 }
2203 }
2204
2205 /* Not found in 16bit signed range. */
2206
2207 subseg_set (alpha_link_section, 0);
2208 p = frag_more (8);
2209 memset (p, 0, 8);
2210
2211 fix_new (frag_now, p - frag_now->fr_literal, 8, sym, addend, 0,
2212 BFD_RELOC_64);
2213
2214 subseg_set (current_section, current_subsec);
2215 seginfo->literal_pool_size += 8;
2216 return offset;
2217 }
2218
2219 #endif /* OBJ_EVAX */
2220
2221 /* Load a (partial) expression into a target register.
2222
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.
2227
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.
2234
2235 Finally, the return value is true if the calling macro may emit a
2236 LITUSE reloc if otherwise appropriate. */
2237
2238 static int
2239 load_expression (targreg, exp, pbasereg, poffset)
2240 int targreg;
2241 const expressionS *exp;
2242 int *pbasereg;
2243 expressionS *poffset;
2244 {
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];
2250
2251 switch (exp->X_op)
2252 {
2253 case O_symbol:
2254 {
2255 #ifdef OBJ_ECOFF
2256 offsetT lit;
2257
2258 /* attempt to reduce .lit load by splitting the offset from
2259 its symbol when possible, but don't create a situation in
2260 which we'd fail. */
2261 if (!range_signed_32 (addend) &&
2262 (alpha_noat_on || targreg == AXP_REG_AT))
2263 {
2264 lit = add_to_literal_pool (exp->X_add_symbol, addend,
2265 alpha_lita_section, 8);
2266 addend = 0;
2267 }
2268 else
2269 {
2270 lit = add_to_literal_pool (exp->X_add_symbol, 0,
2271 alpha_lita_section, 8);
2272 }
2273
2274 if (lit >= 0x8000)
2275 as_fatal (_("overflow in literal (.lita) table"));
2276
2277 /* emit "ldq r, lit(gp)" */
2278
2279 if (basereg != alpha_gp_register && targreg == basereg)
2280 {
2281 if (alpha_noat_on)
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"));
2285
2286 set_tok_reg (newtok[0], AXP_REG_AT);
2287 }
2288 else
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);
2292
2293 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
2294
2295 assert (insn.nfixups == 1);
2296 insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITERAL;
2297 #endif /* OBJ_ECOFF */
2298 #ifdef OBJ_ELF
2299 /* emit "ldq r, gotoff(gp)" */
2300
2301 if (basereg != alpha_gp_register && targreg == basereg)
2302 {
2303 if (alpha_noat_on)
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"));
2307
2308 set_tok_reg (newtok[0], AXP_REG_AT);
2309 }
2310 else
2311 set_tok_reg (newtok[0], targreg);
2312
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)))
2318 {
2319 newtok[1] = *exp;
2320 addend = 0;
2321 }
2322 else
2323 {
2324 set_tok_sym (newtok[1], exp->X_add_symbol, 0);
2325 }
2326
2327 set_tok_preg (newtok[2], alpha_gp_register);
2328
2329 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
2330
2331 assert (insn.nfixups == 1);
2332 insn.fixups[0].reloc = BFD_RELOC_ALPHA_ELF_LITERAL;
2333 #endif /* OBJ_ELF */
2334 #ifdef OBJ_EVAX
2335 offsetT link;
2336
2337 /* Find symbol or symbol pointer in link section. */
2338
2339 if (exp->X_add_symbol == alpha_evax_proc.symbol)
2340 {
2341 if (range_signed_16 (addend))
2342 {
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);
2347 addend = 0;
2348 }
2349 else
2350 {
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);
2355 }
2356 }
2357 else
2358 {
2359 if (!range_signed_32 (addend))
2360 {
2361 link = add_to_link_pool (alpha_evax_proc.symbol,
2362 exp->X_add_symbol, addend);
2363 addend = 0;
2364 }
2365 else
2366 {
2367 link = add_to_link_pool (alpha_evax_proc.symbol,
2368 exp->X_add_symbol, 0);
2369 }
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);
2374 }
2375 #endif /* OBJ_EVAX */
2376
2377 emit_insn(&insn);
2378
2379 #ifndef OBJ_EVAX
2380 emit_lituse = 1;
2381
2382 if (basereg != alpha_gp_register && basereg != AXP_REG_ZERO)
2383 {
2384 /* emit "addq r, base, r" */
2385
2386 set_tok_reg (newtok[1], basereg);
2387 set_tok_reg (newtok[2], targreg);
2388 assemble_tokens ("addq", newtok, 3, 0);
2389 }
2390 #endif
2391
2392 basereg = targreg;
2393 }
2394 break;
2395
2396 case O_constant:
2397 break;
2398
2399 case O_subtract:
2400 /* Assume that this difference expression will be resolved to an
2401 absolute value and that that value will fit in 16 bits. */
2402
2403 set_tok_reg (newtok[0], targreg);
2404 newtok[1] = *exp;
2405 set_tok_preg (newtok[2], basereg);
2406 assemble_tokens ("lda", newtok, 3, 0);
2407
2408 if (poffset)
2409 set_tok_const (*poffset, 0);
2410 return 0;
2411
2412 case O_big:
2413 if (exp->X_add_number > 0)
2414 as_bad (_("bignum invalid; zero assumed"));
2415 else
2416 as_bad (_("floating point number invalid; zero assumed"));
2417 addend = 0;
2418 break;
2419
2420 default:
2421 as_bad (_("can't handle expression"));
2422 addend = 0;
2423 break;
2424 }
2425
2426 if (!range_signed_32 (addend))
2427 {
2428 offsetT lit;
2429
2430 /* for 64-bit addends, just put it in the literal pool */
2431
2432 #ifdef OBJ_EVAX
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);
2440 #else
2441
2442 if (alpha_lit8_section == NULL)
2443 {
2444 create_literal_section (".lit8",
2445 &alpha_lit8_section,
2446 &alpha_lit8_symbol);
2447
2448 #ifdef OBJ_ECOFF
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"));
2453 #endif
2454 }
2455
2456 lit = add_to_literal_pool (NULL, addend, alpha_lit8_section, 8) - 0x8000;
2457 if (lit >= 0x8000)
2458 as_fatal (_("overflow in literal (.lit8) table"));
2459
2460 /* emit "lda litreg, .lit8+0x8000" */
2461
2462 if (targreg == basereg)
2463 {
2464 if (alpha_noat_on)
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"));
2468
2469 set_tok_reg (newtok[0], AXP_REG_AT);
2470 }
2471 else
2472 set_tok_reg (newtok[0], targreg);
2473 #ifdef OBJ_ECOFF
2474 set_tok_sym (newtok[1], alpha_lita_symbol, alpha_lit8_literal);
2475 #endif
2476 #ifdef OBJ_ELF
2477 set_tok_sym (newtok[1], alpha_lit8_symbol, 0x8000);
2478 #endif
2479 set_tok_preg (newtok[2], alpha_gp_register);
2480
2481 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
2482
2483 assert (insn.nfixups == 1);
2484 #ifdef OBJ_ECOFF
2485 insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITERAL;
2486 #endif
2487 #ifdef OBJ_ELF
2488 insn.fixups[0].reloc = BFD_RELOC_ALPHA_ELF_LITERAL;
2489 #endif
2490
2491 emit_insn (&insn);
2492
2493 /* emit "ldq litreg, lit(litreg)" */
2494
2495 set_tok_const (newtok[1], lit);
2496 set_tok_preg (newtok[2], newtok[0].X_add_number);
2497
2498 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
2499
2500 assert (insn.nfixups < MAX_INSN_FIXUPS);
2501 if (insn.nfixups > 0)
2502 {
2503 memmove (&insn.fixups[1], &insn.fixups[0],
2504 sizeof(struct alpha_fixup) * insn.nfixups);
2505 }
2506 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;
2511 emit_lituse = 0;
2512
2513 emit_insn (&insn);
2514
2515 /* emit "addq litreg, base, target" */
2516
2517 if (basereg != AXP_REG_ZERO)
2518 {
2519 set_tok_reg (newtok[1], basereg);
2520 set_tok_reg (newtok[2], targreg);
2521 assemble_tokens ("addq", newtok, 3, 0);
2522 }
2523 #endif /* !OBJ_EVAX */
2524
2525 if (poffset)
2526 set_tok_const (*poffset, 0);
2527 *pbasereg = targreg;
2528 }
2529 else
2530 {
2531 offsetT low, high, extra, tmp;
2532
2533 /* for 32-bit operands, break up the addend */
2534
2535 low = sign_extend_16 (addend);
2536 tmp = addend - low;
2537 high = sign_extend_16 (tmp >> 16);
2538
2539 if (tmp - (high << 16))
2540 {
2541 extra = 0x4000;
2542 tmp -= 0x40000000;
2543 high = sign_extend_16 (tmp >> 16);
2544 }
2545 else
2546 extra = 0;
2547
2548 set_tok_reg (newtok[0], targreg);
2549 set_tok_preg (newtok[2], basereg);
2550
2551 if (extra)
2552 {
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);
2557 }
2558
2559 if (high)
2560 {
2561 /* emit "ldah r, high(r) */
2562 set_tok_const (newtok[1], high);
2563 assemble_tokens ("ldah", newtok, 3, 0);
2564 basereg = targreg;
2565 set_tok_preg (newtok[2], basereg);
2566 }
2567
2568 if ((low && !poffset) || (!poffset && basereg != targreg))
2569 {
2570 /* emit "lda r, low(base)" */
2571 set_tok_const (newtok[1], low);
2572 assemble_tokens ("lda", newtok, 3, 0);
2573 basereg = targreg;
2574 low = 0;
2575 }
2576
2577 if (poffset)
2578 set_tok_const (*poffset, low);
2579 *pbasereg = basereg;
2580 }
2581
2582 return emit_lituse;
2583 }
2584
2585 /* The lda macro differs from the lda instruction in that it handles
2586 most simple expressions, particualrly symbol address loads and
2587 large constants. */
2588
2589 static void
2590 emit_lda (tok, ntok, unused)
2591 const expressionS *tok;
2592 int ntok;
2593 const PTR unused ATTRIBUTE_UNUSED;
2594 {
2595 int basereg;
2596
2597 if (ntok == 2)
2598 basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
2599 else
2600 basereg = tok[2].X_add_number;
2601
2602 (void) load_expression (tok[0].X_add_number, &tok[1], &basereg, NULL);
2603 }
2604
2605 /* The ldah macro differs from the ldah instruction in that it has $31
2606 as an implied base register. */
2607
2608 static void
2609 emit_ldah (tok, ntok, unused)
2610 const expressionS *tok;
2611 int ntok ATTRIBUTE_UNUSED;
2612 const PTR unused ATTRIBUTE_UNUSED;
2613 {
2614 expressionS newtok[3];
2615
2616 newtok[0] = tok[0];
2617 newtok[1] = tok[1];
2618 set_tok_preg (newtok[2], AXP_REG_ZERO);
2619
2620 assemble_tokens ("ldah", newtok, 3, 0);
2621 }
2622
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. */
2626
2627 static void
2628 emit_ir_load (tok, ntok, opname)
2629 const expressionS *tok;
2630 int ntok;
2631 const PTR opname;
2632 {
2633 int basereg, lituse;
2634 expressionS newtok[3];
2635 struct alpha_insn insn;
2636
2637 if (ntok == 2)
2638 basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
2639 else
2640 basereg = tok[2].X_add_number;
2641
2642 lituse = load_expression (tok[0].X_add_number, &tok[1], &basereg,
2643 &newtok[1]);
2644
2645 newtok[0] = tok[0];
2646 set_tok_preg (newtok[2], basereg);
2647
2648 assemble_tokens_to_insn ((const char *)opname, newtok, 3, &insn);
2649
2650 if (lituse)
2651 {
2652 assert (insn.nfixups < MAX_INSN_FIXUPS);
2653 if (insn.nfixups > 0)
2654 {
2655 memmove (&insn.fixups[1], &insn.fixups[0],
2656 sizeof(struct alpha_fixup) * insn.nfixups);
2657 }
2658 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;
2663 }
2664
2665 emit_insn (&insn);
2666 }
2667
2668 /* Handle fp register loads, and both integer and fp register stores.
2669 Again, we handle simple expressions. */
2670
2671 static void
2672 emit_loadstore (tok, ntok, opname)
2673 const expressionS *tok;
2674 int ntok;
2675 const PTR opname;
2676 {
2677 int basereg, lituse;
2678 expressionS newtok[3];
2679 struct alpha_insn insn;
2680
2681 if (ntok == 2)
2682 basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
2683 else
2684 basereg = tok[2].X_add_number;
2685
2686 if (tok[1].X_op != O_constant || !range_signed_16(tok[1].X_add_number))
2687 {
2688 if (alpha_noat_on)
2689 as_bad (_("macro requires $at register while noat in effect"));
2690
2691 lituse = load_expression (AXP_REG_AT, &tok[1], &basereg, &newtok[1]);
2692 }
2693 else
2694 {
2695 newtok[1] = tok[1];
2696 lituse = 0;
2697 }
2698
2699 newtok[0] = tok[0];
2700 set_tok_preg (newtok[2], basereg);
2701
2702 assemble_tokens_to_insn ((const char *)opname, newtok, 3, &insn);
2703
2704 if (lituse)
2705 {
2706 assert (insn.nfixups < MAX_INSN_FIXUPS);
2707 if (insn.nfixups > 0)
2708 {
2709 memmove (&insn.fixups[1], &insn.fixups[0],
2710 sizeof(struct alpha_fixup) * insn.nfixups);
2711 }
2712 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;
2717 }
2718
2719 emit_insn (&insn);
2720 }
2721
2722 /* Load a half-word or byte as an unsigned value. */
2723
2724 static void
2725 emit_ldXu (tok, ntok, vlgsize)
2726 const expressionS *tok;
2727 int ntok;
2728 const PTR vlgsize;
2729 {
2730 if (alpha_target & AXP_OPCODE_BWX)
2731 emit_ir_load (tok, ntok, ldXu_op[(long)vlgsize]);
2732 else
2733 {
2734 expressionS newtok[3];
2735
2736 if (alpha_noat_on)
2737 as_bad (_("macro requires $at register while noat in effect"));
2738
2739 /* emit "lda $at, exp" */
2740
2741 memcpy (newtok, tok, sizeof (expressionS) * ntok);
2742 newtok[0].X_add_number = AXP_REG_AT;
2743 assemble_tokens ("lda", newtok, ntok, 1);
2744
2745 /* emit "ldq_u targ, 0($at)" */
2746
2747 newtok[0] = tok[0];
2748 set_tok_const (newtok[1], 0);
2749 set_tok_preg (newtok[2], AXP_REG_AT);
2750 assemble_tokens ("ldq_u", newtok, 3, 1);
2751
2752 /* emit "extXl targ, $at, targ" */
2753
2754 set_tok_reg (newtok[1], AXP_REG_AT);
2755 newtok[2] = newtok[0];
2756 assemble_tokens (extXl_op[(long)vlgsize], newtok, 3, 1);
2757 }
2758 }
2759
2760 /* Load a half-word or byte as a signed value. */
2761
2762 static void
2763 emit_ldX (tok, ntok, vlgsize)
2764 const expressionS *tok;
2765 int ntok;
2766 const PTR vlgsize;
2767 {
2768 emit_ldXu (tok, ntok, vlgsize);
2769 assemble_tokens (sextX_op[(long)vlgsize], tok, 1, 1);
2770 }
2771
2772 /* Load an integral value from an unaligned address as an unsigned
2773 value. */
2774
2775 static void
2776 emit_uldXu (tok, ntok, vlgsize)
2777 const expressionS *tok;
2778 int ntok;
2779 const PTR vlgsize;
2780 {
2781 long lgsize = (long)vlgsize;
2782 expressionS newtok[3];
2783
2784 if (alpha_noat_on)
2785 as_bad (_("macro requires $at register while noat in effect"));
2786
2787 /* emit "lda $at, exp" */
2788
2789 memcpy (newtok, tok, sizeof (expressionS) * ntok);
2790 newtok[0].X_add_number = AXP_REG_AT;
2791 assemble_tokens ("lda", newtok, ntok, 1);
2792
2793 /* emit "ldq_u $t9, 0($at)" */
2794
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);
2799
2800 /* emit "ldq_u $t10, size-1($at)" */
2801
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);
2805
2806 /* emit "extXl $t9, $at, $t9" */
2807
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);
2812
2813 /* emit "extXh $t10, $at, $t10" */
2814
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);
2818
2819 /* emit "or $t9, $t10, targ" */
2820
2821 set_tok_reg (newtok[0], AXP_REG_T9);
2822 set_tok_reg (newtok[1], AXP_REG_T10);
2823 newtok[2] = tok[0];
2824 assemble_tokens ("or", newtok, 3, 1);
2825 }
2826
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. */
2830
2831 static void
2832 emit_uldX (tok, ntok, vlgsize)
2833 const expressionS *tok;
2834 int ntok;
2835 const PTR vlgsize;
2836 {
2837 emit_uldXu (tok, ntok, vlgsize);
2838 assemble_tokens (sextX_op[(long)vlgsize], tok, 1, 1);
2839 }
2840
2841 /* Implement the ldil macro. */
2842
2843 static void
2844 emit_ldil (tok, ntok, unused)
2845 const expressionS *tok;
2846 int ntok;
2847 const PTR unused ATTRIBUTE_UNUSED;
2848 {
2849 expressionS newtok[2];
2850
2851 memcpy (newtok, tok, sizeof(newtok));
2852 newtok[1].X_add_number = sign_extend_32 (tok[1].X_add_number);
2853
2854 assemble_tokens ("lda", newtok, ntok, 1);
2855 }
2856
2857 /* Store a half-word or byte. */
2858
2859 static void
2860 emit_stX (tok, ntok, vlgsize)
2861 const expressionS *tok;
2862 int ntok;
2863 const PTR vlgsize;
2864 {
2865 int lgsize = (int)(long)vlgsize;
2866
2867 if (alpha_target & AXP_OPCODE_BWX)
2868 emit_loadstore (tok, ntok, stX_op[lgsize]);
2869 else
2870 {
2871 expressionS newtok[3];
2872
2873 if (alpha_noat_on)
2874 as_bad(_("macro requires $at register while noat in effect"));
2875
2876 /* emit "lda $at, exp" */
2877
2878 memcpy (newtok, tok, sizeof (expressionS) * ntok);
2879 newtok[0].X_add_number = AXP_REG_AT;
2880 assemble_tokens ("lda", newtok, ntok, 1);
2881
2882 /* emit "ldq_u $t9, 0($at)" */
2883
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);
2888
2889 /* emit "insXl src, $at, $t10" */
2890
2891 newtok[0] = tok[0];
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);
2895
2896 /* emit "mskXl $t9, $at, $t9" */
2897
2898 set_tok_reg (newtok[0], AXP_REG_T9);
2899 newtok[2] = newtok[0];
2900 assemble_tokens (mskXl_op[lgsize], newtok, 3, 1);
2901
2902 /* emit "or $t9, $t10, $t9" */
2903
2904 set_tok_reg (newtok[1], AXP_REG_T10);
2905 assemble_tokens ("or", newtok, 3, 1);
2906
2907 /* emit "stq_u $t9, 0($at) */
2908
2909 set_tok_const (newtok[1], 0);
2910 set_tok_preg (newtok[2], AXP_REG_AT);
2911 assemble_tokens ("stq_u", newtok, 3, 1);
2912 }
2913 }
2914
2915 /* Store an integer to an unaligned address. */
2916
2917 static void
2918 emit_ustX (tok, ntok, vlgsize)
2919 const expressionS *tok;
2920 int ntok;
2921 const PTR vlgsize;
2922 {
2923 int lgsize = (int)(long)vlgsize;
2924 expressionS newtok[3];
2925
2926 /* emit "lda $at, exp" */
2927
2928 memcpy (newtok, tok, sizeof (expressionS) * ntok);
2929 newtok[0].X_add_number = AXP_REG_AT;
2930 assemble_tokens ("lda", newtok, ntok, 1);
2931
2932 /* emit "ldq_u $9, 0($at)" */
2933
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);
2938
2939 /* emit "ldq_u $10, size-1($at)" */
2940
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);
2944
2945 /* emit "insXl src, $at, $t11" */
2946
2947 newtok[0] = tok[0];
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);
2951
2952 /* emit "insXh src, $at, $t12" */
2953
2954 set_tok_reg (newtok[2], AXP_REG_T12);
2955 assemble_tokens (insXh_op[lgsize], newtok, 3, 1);
2956
2957 /* emit "mskXl $t9, $at, $t9" */
2958
2959 set_tok_reg (newtok[0], AXP_REG_T9);
2960 newtok[2] = newtok[0];
2961 assemble_tokens (mskXl_op[lgsize], newtok, 3, 1);
2962
2963 /* emit "mskXh $t10, $at, $t10" */
2964
2965 set_tok_reg (newtok[0], AXP_REG_T10);
2966 newtok[2] = newtok[0];
2967 assemble_tokens (mskXh_op[lgsize], newtok, 3, 1);
2968
2969 /* emit "or $t9, $t11, $t9" */
2970
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);
2975
2976 /* emit "or $t10, $t12, $t10" */
2977
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);
2982
2983 /* emit "stq_u $t9, 0($at)" */
2984
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);
2989
2990 /* emit "stq_u $t10, size-1($at)" */
2991
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);
2995 }
2996
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. */
2999
3000 static void
3001 emit_sextX (tok, ntok, vlgsize)
3002 const expressionS *tok;
3003 int ntok;
3004 const PTR vlgsize;
3005 {
3006 long lgsize = (long)vlgsize;
3007
3008 if (alpha_target & AXP_OPCODE_BWX)
3009 assemble_tokens (sextX_op[lgsize], tok, ntok, 0);
3010 else
3011 {
3012 int bitshift = 64 - 8 * (1 << lgsize);
3013 expressionS newtok[3];
3014
3015 /* emit "sll src,bits,dst" */
3016
3017 newtok[0] = tok[0];
3018 set_tok_const (newtok[1], bitshift);
3019 newtok[2] = tok[ntok - 1];
3020 assemble_tokens ("sll", newtok, 3, 1);
3021
3022 /* emit "sra dst,bits,dst" */
3023
3024 newtok[0] = newtok[2];
3025 assemble_tokens ("sra", newtok, 3, 1);
3026 }
3027 }
3028
3029 /* Implement the division and modulus macros. */
3030
3031 #ifdef OBJ_EVAX
3032
3033 /* Make register usage like in normal procedure call.
3034 Don't clobber PV and RA. */
3035
3036 static void
3037 emit_division (tok, ntok, symname)
3038 const expressionS *tok;
3039 int ntok;
3040 const PTR symname;
3041 {
3042 /* DIVISION and MODULUS. Yech.
3043 *
3044 * Convert
3045 * OP x,y,result
3046 * to
3047 * mov x,R16 # if x != R16
3048 * mov y,R17 # if y != R17
3049 * lda AT,__OP
3050 * jsr AT,(AT),0
3051 * mov R0,result
3052 *
3053 * with appropriate optimizations if R0,R16,R17 are the registers
3054 * specified by the compiler.
3055 */
3056
3057 int xr, yr, rr;
3058 symbolS *sym;
3059 expressionS newtok[3];
3060
3061 xr = regno (tok[0].X_add_number);
3062 yr = regno (tok[1].X_add_number);
3063
3064 if (ntok < 3)
3065 rr = xr;
3066 else
3067 rr = regno (tok[2].X_add_number);
3068
3069 /* Move the operands into the right place */
3070 if (yr == AXP_REG_R16 && xr == AXP_REG_R17)
3071 {
3072 /* They are in exactly the wrong order -- swap through AT */
3073
3074 if (alpha_noat_on)
3075 as_bad (_("macro requires $at register while noat in effect"));
3076
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);
3080
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);
3084
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);
3088 }
3089 else
3090 {
3091 if (yr == AXP_REG_R16)
3092 {
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);
3096 }
3097
3098 if (xr != AXP_REG_R16)
3099 {
3100 set_tok_reg (newtok[0], xr);
3101 set_tok_reg (newtok[1], AXP_REG_R16);
3102 assemble_tokens ("mov", newtok, 2, 1);
3103 }
3104
3105 if (yr != AXP_REG_R16 && yr != AXP_REG_R17)
3106 {
3107 set_tok_reg (newtok[0], yr);
3108 set_tok_reg (newtok[1], AXP_REG_R17);
3109 assemble_tokens ("mov", newtok, 2, 1);
3110 }
3111 }
3112
3113 sym = symbol_find_or_make ((const char *)symname);
3114
3115 set_tok_reg (newtok[0], AXP_REG_AT);
3116 set_tok_sym (newtok[1], sym, 0);
3117 assemble_tokens ("lda", newtok, 2, 1);
3118
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);
3124
3125 /* Move the result to the right place */
3126 if (rr != AXP_REG_R0)
3127 {
3128 set_tok_reg (newtok[0], AXP_REG_R0);
3129 set_tok_reg (newtok[1], rr);
3130 assemble_tokens ("mov", newtok, 2, 1);
3131 }
3132 }
3133
3134 #else /* !OBJ_EVAX */
3135
3136 static void
3137 emit_division (tok, ntok, symname)
3138 const expressionS *tok;
3139 int ntok;
3140 const PTR symname;
3141 {
3142 /* DIVISION and MODULUS. Yech.
3143 * Convert
3144 * OP x,y,result
3145 * to
3146 * lda pv,__OP
3147 * mov x,t10
3148 * mov y,t11
3149 * jsr t9,(pv),__OP
3150 * mov t12,result
3151 *
3152 * with appropriate optimizations if t10,t11,t12 are the registers
3153 * specified by the compiler.
3154 */
3155
3156 int xr, yr, rr;
3157 symbolS *sym;
3158 expressionS newtok[3];
3159
3160 xr = regno (tok[0].X_add_number);
3161 yr = regno (tok[1].X_add_number);
3162
3163 if (ntok < 3)
3164 rr = xr;
3165 else
3166 rr = regno (tok[2].X_add_number);
3167
3168 sym = symbol_find_or_make ((const char *)symname);
3169
3170 /* Move the operands into the right place */
3171 if (yr == AXP_REG_T10 && xr == AXP_REG_T11)
3172 {
3173 /* They are in exactly the wrong order -- swap through AT */
3174
3175 if (alpha_noat_on)
3176 as_bad (_("macro requires $at register while noat in effect"));
3177
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);
3181
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);
3185
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);
3189 }
3190 else
3191 {
3192 if (yr == AXP_REG_T10)
3193 {
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);
3197 }
3198
3199 if (xr != AXP_REG_T10)
3200 {
3201 set_tok_reg (newtok[0], xr);
3202 set_tok_reg (newtok[1], AXP_REG_T10);
3203 assemble_tokens ("mov", newtok, 2, 1);
3204 }
3205
3206 if (yr != AXP_REG_T10 && yr != AXP_REG_T11)
3207 {
3208 set_tok_reg (newtok[0], yr);
3209 set_tok_reg (newtok[1], AXP_REG_T11);
3210 assemble_tokens ("mov", newtok, 2, 1);
3211 }
3212 }
3213
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);
3218
3219 /* Reload the GP register */
3220 #ifdef OBJ_AOUT
3221 FIXME
3222 #endif
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);
3228 #endif
3229
3230 /* Move the result to the right place */
3231 if (rr != AXP_REG_T12)
3232 {
3233 set_tok_reg (newtok[0], AXP_REG_T12);
3234 set_tok_reg (newtok[1], rr);
3235 assemble_tokens ("mov", newtok, 2, 1);
3236 }
3237 }
3238
3239 #endif /* !OBJ_EVAX */
3240
3241 /* The jsr and jmp macros differ from their instruction counterparts
3242 in that they can load the target address and default most
3243 everything. */
3244
3245 static void
3246 emit_jsrjmp (tok, ntok, vopname)
3247 const expressionS *tok;
3248 int ntok;
3249 const PTR vopname;
3250 {
3251 const char *opname = (const char *) vopname;
3252 struct alpha_insn insn;
3253 expressionS newtok[3];
3254 int r, tokidx = 0, lituse = 0;
3255
3256 if (tokidx < ntok && tok[tokidx].X_op == O_register)
3257 r = regno (tok[tokidx++].X_add_number);
3258 else
3259 r = strcmp (opname, "jmp") == 0 ? AXP_REG_ZERO : AXP_REG_RA;
3260
3261 set_tok_reg (newtok[0], r);
3262
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);
3266 #ifdef OBJ_EVAX
3267 /* keep register if jsr $n.<sym> */
3268 #else
3269 else
3270 {
3271 int basereg = alpha_gp_register;
3272 lituse = load_expression (r = AXP_REG_PV, &tok[tokidx], &basereg, NULL);
3273 }
3274 #endif
3275
3276 set_tok_cpreg (newtok[1], r);
3277
3278 #ifdef OBJ_EVAX
3279 /* FIXME: Add hint relocs to BFD for evax. */
3280 #else
3281 if (tokidx < ntok)
3282 newtok[2] = tok[tokidx];
3283 else
3284 #endif
3285 set_tok_const (newtok[2], 0);
3286
3287 assemble_tokens_to_insn (opname, newtok, 3, &insn);
3288
3289 /* add the LITUSE fixup */
3290 if (lituse)
3291 {
3292 assert (insn.nfixups < MAX_INSN_FIXUPS);
3293 if (insn.nfixups > 0)
3294 {
3295 memmove (&insn.fixups[1], &insn.fixups[0],
3296 sizeof(struct alpha_fixup) * insn.nfixups);
3297 }
3298 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;
3303 }
3304
3305 emit_insn (&insn);
3306 }
3307
3308 /* The ret and jcr instructions differ from their instruction
3309 counterparts in that everything can be defaulted. */
3310
3311 static void
3312 emit_retjcr (tok, ntok, vopname)
3313 const expressionS *tok;
3314 int ntok;
3315 const PTR vopname;
3316 {
3317 const char *opname = (const char *)vopname;
3318 expressionS newtok[3];
3319 int r, tokidx = 0;
3320
3321 if (tokidx < ntok && tok[tokidx].X_op == O_register)
3322 r = regno (tok[tokidx++].X_add_number);
3323 else
3324 r = AXP_REG_ZERO;
3325
3326 set_tok_reg (newtok[0], r);
3327
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);
3331 else
3332 r = AXP_REG_RA;
3333
3334 set_tok_cpreg (newtok[1], r);
3335
3336 if (tokidx < ntok)
3337 newtok[2] = tok[tokidx];
3338 else
3339 set_tok_const (newtok[2], strcmp(opname, "ret") == 0);
3340
3341 assemble_tokens (opname, newtok, 3, 0);
3342 }
3343 \f
3344 /* Assembler directives */
3345
3346 /* Handle the .text pseudo-op. This is like the usual one, but it
3347 clears alpha_insn_label and restores auto alignment. */
3348
3349 static void
3350 s_alpha_text (i)
3351 int i;
3352
3353 {
3354 s_text (i);
3355 alpha_insn_label = NULL;
3356 alpha_auto_align_on = 1;
3357 alpha_current_align = 0;
3358 }
3359
3360 /* Handle the .data pseudo-op. This is like the usual one, but it
3361 clears alpha_insn_label and restores auto alignment. */
3362
3363 static void
3364 s_alpha_data (i)
3365 int i;
3366 {
3367 s_data (i);
3368 alpha_insn_label = NULL;
3369 alpha_auto_align_on = 1;
3370 alpha_current_align = 0;
3371 }
3372
3373 #if defined (OBJ_ECOFF) || defined (OBJ_EVAX)
3374
3375 /* Handle the OSF/1 and openVMS .comm pseudo quirks.
3376 openVMS constructs a section for every common symbol. */
3377
3378 static void
3379 s_alpha_comm (ignore)
3380 int ignore;
3381 {
3382 register char *name;
3383 register char c;
3384 register char *p;
3385 offsetT temp;
3386 register symbolS *symbolP;
3387
3388 #ifdef OBJ_EVAX
3389 segT current_section = now_seg;
3390 int current_subsec = now_subseg;
3391 segT new_seg;
3392 #endif
3393
3394 name = input_line_pointer;
3395 c = get_symbol_end ();
3396
3397 /* just after name is now '\0' */
3398 p = input_line_pointer;
3399 *p = c;
3400
3401 SKIP_WHITESPACE ();
3402
3403 /* Alpha OSF/1 compiler doesn't provide the comma, gcc does. */
3404 if (*input_line_pointer == ',')
3405 {
3406 input_line_pointer++;
3407 SKIP_WHITESPACE ();
3408 }
3409 if ((temp = get_absolute_expression ()) < 0)
3410 {
3411 as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) temp);
3412 ignore_rest_of_line ();
3413 return;
3414 }
3415
3416 *p = 0;
3417 symbolP = symbol_find_or_make (name);
3418
3419 #ifdef OBJ_EVAX
3420 /* Make a section for the common symbol. */
3421 new_seg = subseg_new (xstrdup (name), 0);
3422 #endif
3423
3424 *p = c;
3425
3426 #ifdef OBJ_EVAX
3427 /* alignment might follow */
3428 if (*input_line_pointer == ',')
3429 {
3430 offsetT align;
3431
3432 input_line_pointer++;
3433 align = get_absolute_expression ();
3434 bfd_set_section_alignment (stdoutput, new_seg, align);
3435 }
3436 #endif
3437
3438 if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
3439 {
3440 as_bad (_("Ignoring attempt to re-define symbol"));
3441 ignore_rest_of_line ();
3442 return;
3443 }
3444
3445 #ifdef OBJ_EVAX
3446 if (bfd_section_size (stdoutput, new_seg) > 0)
3447 {
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),
3452 (long) temp);
3453 }
3454 #else
3455 if (S_GET_VALUE (symbolP))
3456 {
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),
3461 (long) temp);
3462 }
3463 #endif
3464 else
3465 {
3466 #ifdef OBJ_EVAX
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);
3472 #else
3473 S_SET_VALUE (symbolP, (valueT) temp);
3474 #endif
3475 S_SET_EXTERNAL (symbolP);
3476 }
3477
3478 #ifdef OBJ_EVAX
3479 subseg_set (current_section, current_subsec);
3480 #endif
3481
3482 know (symbol_get_frag (symbolP) == &zero_address_frag);
3483
3484 demand_empty_rest_of_line ();
3485 }
3486
3487 #endif /* ! OBJ_ELF */
3488
3489 #ifdef OBJ_ECOFF
3490
3491 /* Handle the .rdata pseudo-op. This is like the usual one, but it
3492 clears alpha_insn_label and restores auto alignment. */
3493
3494 static void
3495 s_alpha_rdata (ignore)
3496 int ignore;
3497 {
3498 int temp;
3499
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;
3506 }
3507
3508 #endif
3509
3510 #ifdef OBJ_ECOFF
3511
3512 /* Handle the .sdata pseudo-op. This is like the usual one, but it
3513 clears alpha_insn_label and restores auto alignment. */
3514
3515 static void
3516 s_alpha_sdata (ignore)
3517 int ignore;
3518 {
3519 int temp;
3520
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;
3527 }
3528 #endif
3529
3530 #ifdef OBJ_ELF
3531
3532 /* Handle the .section pseudo-op. This is like the usual one, but it
3533 clears alpha_insn_label and restores auto alignment. */
3534
3535 static void
3536 s_alpha_section (ignore)
3537 int ignore;
3538 {
3539 obj_elf_section (ignore);
3540
3541 alpha_insn_label = NULL;
3542 alpha_auto_align_on = 1;
3543 alpha_current_align = 0;
3544 }
3545
3546 static void
3547 s_alpha_ent (dummy)
3548 int dummy ATTRIBUTE_UNUSED;
3549 {
3550 if (ECOFF_DEBUGGING)
3551 ecoff_directive_ent (0);
3552 else
3553 {
3554 char *name, name_end;
3555 name = input_line_pointer;
3556 name_end = get_symbol_end ();
3557
3558 if (! is_name_beginner (*name))
3559 {
3560 as_warn (_(".ent directive has no name"));
3561 *input_line_pointer = name_end;
3562 }
3563 else
3564 {
3565 symbolS *sym;
3566
3567 if (alpha_cur_ent_sym)
3568 as_warn (_("nested .ent directives"));
3569
3570 sym = symbol_find_or_make (name);
3571 symbol_get_bfdsym (sym)->flags |= BSF_FUNCTION;
3572 alpha_cur_ent_sym = sym;
3573
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;
3577 SKIP_WHITESPACE ();
3578 if (*input_line_pointer == ',')
3579 {
3580 input_line_pointer++;
3581 SKIP_WHITESPACE ();
3582 }
3583 if (isdigit (*input_line_pointer) || *input_line_pointer == '-')
3584 (void) get_absolute_expression ();
3585 }
3586 demand_empty_rest_of_line ();
3587 }
3588 }
3589
3590 static void
3591 s_alpha_end (dummy)
3592 int dummy ATTRIBUTE_UNUSED;
3593 {
3594 if (ECOFF_DEBUGGING)
3595 ecoff_directive_end (0);
3596 else
3597 {
3598 char *name, name_end;
3599 name = input_line_pointer;
3600 name_end = get_symbol_end ();
3601
3602 if (! is_name_beginner (*name))
3603 {
3604 as_warn (_(".end directive has no name"));
3605 *input_line_pointer = name_end;
3606 }
3607 else
3608 {
3609 symbolS *sym;
3610
3611 sym = symbol_find (name);
3612 if (sym != alpha_cur_ent_sym)
3613 as_warn (_(".end directive names different symbol than .ent"));
3614
3615 /* Create an expression to calculate the size of the function. */
3616 if (sym)
3617 {
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;
3625 }
3626
3627 alpha_cur_ent_sym = NULL;
3628
3629 *input_line_pointer = name_end;
3630 }
3631 demand_empty_rest_of_line ();
3632 }
3633 }
3634
3635 static void
3636 s_alpha_mask (fp)
3637 int fp;
3638 {
3639 if (ECOFF_DEBUGGING)
3640 {
3641 if (fp)
3642 ecoff_directive_fmask (0);
3643 else
3644 ecoff_directive_mask (0);
3645 }
3646 else
3647 discard_rest_of_line ();
3648 }
3649
3650 static void
3651 s_alpha_frame (dummy)
3652 int dummy ATTRIBUTE_UNUSED;
3653 {
3654 if (ECOFF_DEBUGGING)
3655 ecoff_directive_frame (0);
3656 else
3657 discard_rest_of_line ();
3658 }
3659
3660 static void
3661 s_alpha_prologue (ignore)
3662 int ignore ATTRIBUTE_UNUSED;
3663 {
3664 symbolS *sym;
3665 int arg;
3666
3667 arg = get_absolute_expression ();
3668 demand_empty_rest_of_line ();
3669
3670 if (ECOFF_DEBUGGING)
3671 sym = ecoff_get_cur_proc_sym ();
3672 else
3673 sym = alpha_cur_ent_sym;
3674 know (sym != NULL);
3675
3676 switch (arg)
3677 {
3678 case 0: /* No PV required. */
3679 S_SET_OTHER (sym, STO_ALPHA_NOPV);
3680 break;
3681 case 1: /* Std GP load. */
3682 S_SET_OTHER (sym, STO_ALPHA_STD_GPLOAD);
3683 break;
3684 case 2: /* Non-std use of PV. */
3685 break;
3686
3687 default:
3688 as_bad (_("Invalid argument %d to .prologue."), arg);
3689 break;
3690 }
3691 }
3692
3693 static void
3694 s_alpha_coff_wrapper (which)
3695 int which;
3696 {
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,
3708 };
3709
3710 assert (which >= 0 && which < (int)(sizeof(fns)/sizeof(*fns)));
3711
3712 if (ECOFF_DEBUGGING)
3713 (*fns[which])(0);
3714 else
3715 {
3716 as_bad (_("ECOFF debugging is disabled."));
3717 ignore_rest_of_line ();
3718 }
3719 }
3720 #endif /* OBJ_ELF */
3721
3722 #ifdef OBJ_EVAX
3723
3724 /* Handle the section specific pseudo-op. */
3725
3726 static void
3727 s_alpha_section (secid)
3728 int secid;
3729 {
3730 int temp;
3731 #define EVAX_SECTION_COUNT 5
3732 static char *section_name[EVAX_SECTION_COUNT+1] =
3733 { "NULL", ".rdata", ".comm", ".link", ".ctors", ".dtors" };
3734
3735 if ((secid <= 0) || (secid > EVAX_SECTION_COUNT))
3736 {
3737 as_fatal (_("Unknown section directive"));
3738 demand_empty_rest_of_line ();
3739 return;
3740 }
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;
3747 }
3748
3749
3750 /* Parse .ent directives. */
3751
3752 static void
3753 s_alpha_ent (ignore)
3754 int ignore;
3755 {
3756 symbolS *symbol;
3757 expressionS symexpr;
3758
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;
3769
3770 expression (&symexpr);
3771
3772 if (symexpr.X_op != O_symbol)
3773 {
3774 as_fatal (_(".ent directive has no symbol"));
3775 demand_empty_rest_of_line ();
3776 return;
3777 }
3778
3779 symbol = make_expr_symbol (&symexpr);
3780 symbol_get_bfdsym (symbol)->flags |= BSF_FUNCTION;
3781 alpha_evax_proc.symbol = symbol;
3782
3783 demand_empty_rest_of_line ();
3784 return;
3785 }
3786
3787
3788 /* Parse .frame <framreg>,<framesize>,RA,<rsa_offset> directives. */
3789
3790 static void
3791 s_alpha_frame (ignore)
3792 int ignore;
3793 {
3794 long val;
3795
3796 alpha_evax_proc.framereg = tc_get_register (1);
3797
3798 SKIP_WHITESPACE ();
3799 if (*input_line_pointer++ != ','
3800 || get_absolute_expression_and_terminator (&val) != ',')
3801 {
3802 as_warn (_("Bad .frame directive 1./2. param"));
3803 --input_line_pointer;
3804 demand_empty_rest_of_line ();
3805 return;
3806 }
3807
3808 alpha_evax_proc.framesize = val;
3809
3810 (void) tc_get_register (1);
3811 SKIP_WHITESPACE ();
3812 if (*input_line_pointer++ != ',')
3813 {
3814 as_warn (_("Bad .frame directive 3./4. param"));
3815 --input_line_pointer;
3816 demand_empty_rest_of_line ();
3817 return;
3818 }
3819 alpha_evax_proc.rsa_offset = get_absolute_expression ();
3820
3821 return;
3822 }
3823
3824 static void
3825 s_alpha_pdesc (ignore)
3826 int ignore;
3827 {
3828 char *name;
3829 char name_end;
3830 long val;
3831 register char *p;
3832 expressionS exp;
3833 symbolS *entry_sym;
3834 fixS *fixp;
3835 segment_info_type *seginfo = seg_info (alpha_link_section);
3836
3837 if (now_seg != alpha_link_section)
3838 {
3839 as_bad (_(".pdesc directive not in link (.link) section"));
3840 demand_empty_rest_of_line ();
3841 return;
3842 }
3843
3844 if ((alpha_evax_proc.symbol == 0)
3845 || (!S_IS_DEFINED (alpha_evax_proc.symbol)))
3846 {
3847 as_fatal (_(".pdesc has no matching .ent"));
3848 demand_empty_rest_of_line ();
3849 return;
3850 }
3851
3852 *symbol_get_obj (alpha_evax_proc.symbol) =
3853 (valueT) seginfo->literal_pool_size;
3854
3855 expression (&exp);
3856 if (exp.X_op != O_symbol)
3857 {
3858 as_warn (_(".pdesc directive has no entry symbol"));
3859 demand_empty_rest_of_line ();
3860 return;
3861 }
3862
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);
3867
3868 SKIP_WHITESPACE ();
3869 if (*input_line_pointer++ != ',')
3870 {
3871 as_warn (_("No comma after .pdesc <entryname>"));
3872 demand_empty_rest_of_line ();
3873 return;
3874 }
3875
3876 SKIP_WHITESPACE ();
3877 name = input_line_pointer;
3878 name_end = get_symbol_end ();
3879
3880 if (strncmp(name, "stack", 5) == 0)
3881 {
3882 alpha_evax_proc.pdsckind = PDSC_S_K_KIND_FP_STACK;
3883 }
3884 else if (strncmp(name, "reg", 3) == 0)
3885 {
3886 alpha_evax_proc.pdsckind = PDSC_S_K_KIND_FP_REGISTER;
3887 }
3888 else if (strncmp(name, "null", 4) == 0)
3889 {
3890 alpha_evax_proc.pdsckind = PDSC_S_K_KIND_NULL;
3891 }
3892 else
3893 {
3894 as_fatal (_("unknown procedure kind"));
3895 demand_empty_rest_of_line ();
3896 return;
3897 }
3898
3899 *input_line_pointer = name_end;
3900 demand_empty_rest_of_line ();
3901
3902 #ifdef md_flush_pending_output
3903 md_flush_pending_output ();
3904 #endif
3905
3906 frag_align (3, 0, 0);
3907 p = frag_more (16);
3908 fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
3909 fixp->fx_done = 1;
3910 seginfo->literal_pool_size += 16;
3911
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;
3916
3917 switch (alpha_evax_proc.pdsckind)
3918 {
3919 case PDSC_S_K_KIND_NULL:
3920 *(p+2) = 0;
3921 *(p+3) = 0;
3922 break;
3923 case PDSC_S_K_KIND_FP_REGISTER:
3924 *(p+2) = alpha_evax_proc.fp_save;
3925 *(p+3) = alpha_evax_proc.ra_save;
3926 break;
3927 case PDSC_S_K_KIND_FP_STACK:
3928 md_number_to_chars (p+2, (valueT)alpha_evax_proc.rsa_offset, 2);
3929 break;
3930 default: /* impossible */
3931 break;
3932 }
3933
3934 *(p+4) = 0;
3935 *(p+5) = alpha_evax_proc.type & 0x0f;
3936
3937 /* Signature offset. */
3938 md_number_to_chars (p+6, (valueT)0, 2);
3939
3940 fix_new_exp (frag_now, p-frag_now->fr_literal+8, 8, &exp, 0, BFD_RELOC_64);
3941
3942 if (alpha_evax_proc.pdsckind == PDSC_S_K_KIND_NULL)
3943 return;
3944
3945 /* Add dummy fix to make add_to_link_pool work. */
3946 p = frag_more (8);
3947 fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
3948 fixp->fx_done = 1;
3949 seginfo->literal_pool_size += 8;
3950
3951 /* pdesc+16: Size. */
3952 md_number_to_chars (p, (valueT)alpha_evax_proc.framesize, 4);
3953
3954 md_number_to_chars (p+4, (valueT)0, 2);
3955
3956 /* Entry length. */
3957 md_number_to_chars (p+6, alpha_evax_proc.prologue, 2);
3958
3959 if (alpha_evax_proc.pdsckind == PDSC_S_K_KIND_FP_REGISTER)
3960 return;
3961
3962 /* Add dummy fix to make add_to_link_pool work. */
3963 p = frag_more (8);
3964 fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
3965 fixp->fx_done = 1;
3966 seginfo->literal_pool_size += 8;
3967
3968 /* pdesc+24: register masks. */
3969
3970 md_number_to_chars (p, alpha_evax_proc.imask, 4);
3971 md_number_to_chars (p+4, alpha_evax_proc.fmask, 4);
3972
3973 return;
3974 }
3975
3976
3977 /* Support for crash debug on vms. */
3978
3979 static void
3980 s_alpha_name (ignore)
3981 int ignore;
3982 {
3983 register char *p;
3984 expressionS exp;
3985 segment_info_type *seginfo = seg_info (alpha_link_section);
3986
3987 if (now_seg != alpha_link_section)
3988 {
3989 as_bad (_(".name directive not in link (.link) section"));
3990 demand_empty_rest_of_line ();
3991 return;
3992 }
3993
3994 expression (&exp);
3995 if (exp.X_op != O_symbol)
3996 {
3997 as_warn (_(".name directive has no symbol"));
3998 demand_empty_rest_of_line ();
3999 return;
4000 }
4001
4002 demand_empty_rest_of_line ();
4003
4004 #ifdef md_flush_pending_output
4005 md_flush_pending_output ();
4006 #endif
4007
4008 frag_align (3, 0, 0);
4009 p = frag_more (8);
4010 seginfo->literal_pool_size += 8;
4011
4012 fix_new_exp (frag_now, p-frag_now->fr_literal, 8, &exp, 0, BFD_RELOC_64);
4013
4014 return;
4015 }
4016
4017
4018 static void
4019 s_alpha_linkage (ignore)
4020 int ignore;
4021 {
4022 expressionS exp;
4023 char *p;
4024
4025 #ifdef md_flush_pending_output
4026 md_flush_pending_output ();
4027 #endif
4028
4029 expression (&exp);
4030 if (exp.X_op != O_symbol)
4031 {
4032 as_fatal (_("No symbol after .linkage"));
4033 }
4034 else
4035 {
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);
4040 }
4041 demand_empty_rest_of_line ();
4042
4043 return;
4044 }
4045
4046
4047 static void
4048 s_alpha_code_address (ignore)
4049 int ignore;
4050 {
4051 expressionS exp;
4052 char *p;
4053
4054 #ifdef md_flush_pending_output
4055 md_flush_pending_output ();
4056 #endif
4057
4058 expression (&exp);
4059 if (exp.X_op != O_symbol)
4060 {
4061 as_fatal (_("No symbol after .code_address"));
4062 }
4063 else
4064 {
4065 p = frag_more (8);
4066 memset (p, 0, 8);
4067 fix_new_exp (frag_now, p - frag_now->fr_literal, 8, &exp, 0,\
4068 BFD_RELOC_ALPHA_CODEADDR);
4069 }
4070 demand_empty_rest_of_line ();
4071
4072 return;
4073 }
4074
4075
4076 static void
4077 s_alpha_fp_save (ignore)
4078 int ignore;
4079 {
4080
4081 alpha_evax_proc.fp_save = tc_get_register (1);
4082
4083 demand_empty_rest_of_line ();
4084 return;
4085 }
4086
4087
4088 static void
4089 s_alpha_mask (ignore)
4090 int ignore;
4091 {
4092 long val;
4093
4094 if (get_absolute_expression_and_terminator (&val) != ',')
4095 {
4096 as_warn (_("Bad .mask directive"));
4097 --input_line_pointer;
4098 }
4099 else
4100 {
4101 alpha_evax_proc.imask = val;
4102 (void)get_absolute_expression ();
4103 }
4104 demand_empty_rest_of_line ();
4105
4106 return;
4107 }
4108
4109
4110 static void
4111 s_alpha_fmask (ignore)
4112 int ignore;
4113 {
4114 long val;
4115
4116 if (get_absolute_expression_and_terminator (&val) != ',')
4117 {
4118 as_warn (_("Bad .fmask directive"));
4119 --input_line_pointer;
4120 }
4121 else
4122 {
4123 alpha_evax_proc.fmask = val;
4124 (void) get_absolute_expression ();
4125 }
4126 demand_empty_rest_of_line ();
4127
4128 return;
4129 }
4130
4131 static void
4132 s_alpha_end (ignore)
4133 int ignore;
4134 {
4135 char c;
4136
4137 c = get_symbol_end ();
4138 *input_line_pointer = c;
4139 demand_empty_rest_of_line ();
4140 alpha_evax_proc.symbol = 0;
4141
4142 return;
4143 }
4144
4145
4146 static void
4147 s_alpha_file (ignore)
4148 int ignore;
4149 {
4150 symbolS *s;
4151 int length;
4152 static char case_hack[32];
4153
4154 extern char *demand_copy_string PARAMS ((int *lenP));
4155
4156 sprintf (case_hack, "<CASE:%01d%01d>",
4157 alpha_flag_hash_long_names, alpha_flag_show_after_trunc);
4158
4159 s = symbol_find_or_make (case_hack);
4160 symbol_get_bfdsym (s)->flags |= BSF_FILE;
4161
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 ();
4166
4167 return;
4168 }
4169 #endif /* OBJ_EVAX */
4170
4171 /* Handle the .gprel32 pseudo op. */
4172
4173 static void
4174 s_alpha_gprel32 (ignore)
4175 int ignore ATTRIBUTE_UNUSED;
4176 {
4177 expressionS e;
4178 char *p;
4179
4180 SKIP_WHITESPACE ();
4181 expression (&e);
4182
4183 #ifdef OBJ_ELF
4184 switch (e.X_op)
4185 {
4186 case O_constant:
4187 e.X_add_symbol = section_symbol(absolute_section);
4188 e.X_op = O_symbol;
4189 /* FALLTHRU */
4190 case O_symbol:
4191 break;
4192 default:
4193 abort();
4194 }
4195 #else
4196 #ifdef OBJ_ECOFF
4197 switch (e.X_op)
4198 {
4199 case O_constant:
4200 e.X_add_symbol = section_symbol (absolute_section);
4201 /* fall through */
4202 case O_symbol:
4203 e.X_op = O_subtract;
4204 e.X_op_symbol = alpha_gp_symbol;
4205 break;
4206 default:
4207 abort ();
4208 }
4209 #endif
4210 #endif
4211
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;
4217
4218 p = frag_more (4);
4219 memset (p, 0, 4);
4220 fix_new_exp (frag_now, p-frag_now->fr_literal, 4,
4221 &e, 0, BFD_RELOC_GPREL32);
4222 }
4223
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. */
4227
4228 static void
4229 s_alpha_float_cons (type)
4230 int type;
4231 {
4232 int log_size;
4233
4234 switch (type)
4235 {
4236 default:
4237 case 'f':
4238 case 'F':
4239 log_size = 2;
4240 break;
4241
4242 case 'd':
4243 case 'D':
4244 case 'G':
4245 log_size = 3;
4246 break;
4247
4248 case 'x':
4249 case 'X':
4250 case 'p':
4251 case 'P':
4252 log_size = 4;
4253 break;
4254 }
4255
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;
4261
4262 float_cons (type);
4263 }
4264
4265 /* Handle the .proc pseudo op. We don't really do much with it except
4266 parse it. */
4267
4268 static void
4269 s_alpha_proc (is_static)
4270 int is_static ATTRIBUTE_UNUSED;
4271 {
4272 char *name;
4273 char c;
4274 char *p;
4275 symbolS *symbolP;
4276 int temp;
4277
4278 /* Takes ".proc name,nargs" */
4279 SKIP_WHITESPACE ();
4280 name = input_line_pointer;
4281 c = get_symbol_end ();
4282 p = input_line_pointer;
4283 symbolP = symbol_find_or_make (name);
4284 *p = c;
4285 SKIP_WHITESPACE ();
4286 if (*input_line_pointer != ',')
4287 {
4288 *p = 0;
4289 as_warn (_("Expected comma after name \"%s\""), name);
4290 *p = c;
4291 temp = 0;
4292 ignore_rest_of_line ();
4293 }
4294 else
4295 {
4296 input_line_pointer++;
4297 temp = get_absolute_expression ();
4298 }
4299 /* *symbol_get_obj (symbolP) = (signed char) temp; */
4300 as_warn (_("unhandled: .proc %s,%d"), name, temp);
4301 demand_empty_rest_of_line ();
4302 }
4303
4304 /* Handle the .set pseudo op. This is used to turn on and off most of
4305 the assembler features. */
4306
4307 static void
4308 s_alpha_set (x)
4309 int x ATTRIBUTE_UNUSED;
4310 {
4311 char *name, ch, *s;
4312 int yesno = 1;
4313
4314 SKIP_WHITESPACE ();
4315 name = input_line_pointer;
4316 ch = get_symbol_end ();
4317
4318 s = name;
4319 if (s[0] == 'n' && s[1] == 'o')
4320 {
4321 yesno = 0;
4322 s += 2;
4323 }
4324 if (!strcmp ("reorder", s))
4325 /* ignore */ ;
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))
4331 /* ignore */ ;
4332 else if (!strcmp ("volatile", s))
4333 /* ignore */ ;
4334 else
4335 as_warn (_("Tried to .set unrecognized mode `%s'"), name);
4336
4337 *input_line_pointer = ch;
4338 demand_empty_rest_of_line ();
4339 }
4340
4341 /* Handle the .base pseudo op. This changes the assembler's notion of
4342 the $gp register. */
4343
4344 static void
4345 s_alpha_base (ignore)
4346 int ignore ATTRIBUTE_UNUSED;
4347 {
4348 #if 0
4349 if (first_32bit_quadrant)
4350 {
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;
4354 }
4355 #endif
4356
4357 SKIP_WHITESPACE ();
4358 if (*input_line_pointer == '$')
4359 { /* $rNN form */
4360 input_line_pointer++;
4361 if (*input_line_pointer == 'r')
4362 input_line_pointer++;
4363 }
4364
4365 alpha_gp_register = get_absolute_expression ();
4366 if (alpha_gp_register < 0 || alpha_gp_register > 31)
4367 {
4368 alpha_gp_register = AXP_REG_GP;
4369 as_warn (_("Bad base register, using $%d."), alpha_gp_register);
4370 }
4371
4372 demand_empty_rest_of_line ();
4373 }
4374
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. */
4378
4379 static void
4380 s_alpha_align (ignore)
4381 int ignore ATTRIBUTE_UNUSED;
4382 {
4383 int align;
4384 char fill, *pfill;
4385 long max_alignment = 15;
4386
4387 align = get_absolute_expression ();
4388 if (align > max_alignment)
4389 {
4390 align = max_alignment;
4391 as_bad (_("Alignment too large: %d. assumed"), align);
4392 }
4393 else if (align < 0)
4394 {
4395 as_warn (_("Alignment negative: 0 assumed"));
4396 align = 0;
4397 }
4398
4399 if (*input_line_pointer == ',')
4400 {
4401 input_line_pointer++;
4402 fill = get_absolute_expression ();
4403 pfill = &fill;
4404 }
4405 else
4406 pfill = NULL;
4407
4408 if (align != 0)
4409 {
4410 alpha_auto_align_on = 1;
4411 alpha_align (align, pfill, alpha_insn_label, 1);
4412 }
4413 else
4414 {
4415 alpha_auto_align_on = 0;
4416 }
4417
4418 demand_empty_rest_of_line ();
4419 }
4420
4421 /* Hook the normal string processor to reset known alignment. */
4422
4423 static void
4424 s_alpha_stringer (terminate)
4425 int terminate;
4426 {
4427 alpha_current_align = 0;
4428 alpha_insn_label = NULL;
4429 stringer (terminate);
4430 }
4431
4432 /* Hook the normal space processing to reset known alignment. */
4433
4434 static void
4435 s_alpha_space (ignore)
4436 int ignore;
4437 {
4438 alpha_current_align = 0;
4439 alpha_insn_label = NULL;
4440 s_space (ignore);
4441 }
4442
4443 /* Hook into cons for auto-alignment. */
4444
4445 void
4446 alpha_cons_align (size)
4447 int size;
4448 {
4449 int log_size;
4450
4451 log_size = 0;
4452 while ((size >>= 1) != 0)
4453 ++log_size;
4454
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;
4460 }
4461
4462 /* Here come the .uword, .ulong, and .uquad explicitly unaligned
4463 pseudos. We just turn off auto-alignment and call down to cons. */
4464
4465 static void
4466 s_alpha_ucons (bytes)
4467 int bytes;
4468 {
4469 int hold = alpha_auto_align_on;
4470 alpha_auto_align_on = 0;
4471 cons (bytes);
4472 alpha_auto_align_on = hold;
4473 }
4474
4475 /* Switch the working cpu type. */
4476
4477 static void
4478 s_alpha_arch (ignored)
4479 int ignored ATTRIBUTE_UNUSED;
4480 {
4481 char *name, ch;
4482 const struct cpu_type *p;
4483
4484 SKIP_WHITESPACE ();
4485 name = input_line_pointer;
4486 ch = get_symbol_end ();
4487
4488 for (p = cpu_types; p->name; ++p)
4489 if (strcmp(name, p->name) == 0)
4490 {
4491 alpha_target_name = p->name, alpha_target = p->flags;
4492 goto found;
4493 }
4494 as_warn("Unknown CPU identifier `%s'", name);
4495
4496 found:
4497 *input_line_pointer = ch;
4498 demand_empty_rest_of_line ();
4499 }
4500
4501 \f
4502
4503 #ifdef DEBUG1
4504 /* print token expression with alpha specific extension. */
4505
4506 static void
4507 alpha_print_token(f, exp)
4508 FILE *f;
4509 const expressionS *exp;
4510 {
4511 switch (exp->X_op)
4512 {
4513 case O_cpregister:
4514 putc (',', f);
4515 /* FALLTHRU */
4516 case O_pregister:
4517 putc ('(', f);
4518 {
4519 expressionS nexp = *exp;
4520 nexp.X_op = O_register;
4521 print_expr (f, &nexp);
4522 }
4523 putc (')', f);
4524 break;
4525 default:
4526 print_expr (f, exp);
4527 break;
4528 }
4529 return;
4530 }
4531 #endif
4532 \f
4533 /* The target specific pseudo-ops which we support. */
4534
4535 const pseudo_typeS md_pseudo_table[] =
4536 {
4537 #ifdef OBJ_ECOFF
4538 {"comm", s_alpha_comm, 0}, /* osf1 compiler does this */
4539 {"rdata", s_alpha_rdata, 0},
4540 #endif
4541 {"text", s_alpha_text, 0},
4542 {"data", s_alpha_data, 0},
4543 #ifdef OBJ_ECOFF
4544 {"sdata", s_alpha_sdata, 0},
4545 #endif
4546 #ifdef OBJ_ELF
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},
4551 #endif
4552 #ifdef OBJ_EVAX
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},
4569 #endif
4570 #ifdef OBJ_ELF
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},
4589 #else
4590 {"prologue", s_ignore, 0},
4591 #endif
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'},
4598
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},
4609
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},
4620
4621 /* Unaligned data pseudos. */
4622 {"uword", s_alpha_ucons, 2},
4623 {"ulong", s_alpha_ucons, 4},
4624 {"uquad", s_alpha_ucons, 8},
4625
4626 #ifdef OBJ_ELF
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},
4631 #endif
4632
4633 /* We don't do any optimizing, so we can safely ignore these. */
4634 {"noalias", s_ignore, 0},
4635 {"alias", s_ignore, 0},
4636
4637 {"arch", s_alpha_arch, 0},
4638
4639 {NULL, 0, 0},
4640 };
4641
4642 \f
4643 /* Build a BFD section with its flags set appropriately for the .lita,
4644 .lit8, or .lit4 sections. */
4645
4646 static void
4647 create_literal_section (name, secp, symp)
4648 const char *name;
4649 segT *secp;
4650 symbolS **symp;
4651 {
4652 segT current_section = now_seg;
4653 int current_subsec = now_subseg;
4654 segT new_sec;
4655
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
4661 | SEC_DATA);
4662
4663 S_CLEAR_EXTERNAL (*symp = section_symbol (new_sec));
4664 }
4665
4666 #ifdef OBJ_ECOFF
4667
4668 /* @@@ GP selection voodoo. All of this seems overly complicated and
4669 unnecessary; which is the primary reason it's for ECOFF only. */
4670
4671 static inline void
4672 maybe_set_gp (sec)
4673 asection *sec;
4674 {
4675 bfd_vma vma;
4676 if (!sec)
4677 return;
4678 vma = bfd_get_section_vma (foo, sec);
4679 if (vma && vma < alpha_gp_value)
4680 alpha_gp_value = vma;
4681 }
4682
4683 static void
4684 select_gp_value ()
4685 {
4686 assert (alpha_gp_value == 0);
4687
4688 /* Get minus-one in whatever width... */
4689 alpha_gp_value = 0; alpha_gp_value--;
4690
4691 /* Select the smallest VMA of these existing sections. */
4692 maybe_set_gp (alpha_lita_section);
4693 #if 0
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);
4698 #endif
4699
4700 /* @@ Will a simple 0x8000 work here? If not, why not? */
4701 #define GP_ADJUSTMENT (0x8000 - 0x10)
4702
4703 alpha_gp_value += GP_ADJUSTMENT;
4704
4705 S_SET_VALUE (alpha_gp_symbol, alpha_gp_value);
4706
4707 #ifdef DEBUG1
4708 printf (_("Chose GP value of %lx\n"), alpha_gp_value);
4709 #endif
4710 }
4711 #endif /* OBJ_ECOFF */
4712
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. */
4717
4718 static void
4719 alpha_align (n, pfill, label, force)
4720 int n;
4721 char *pfill;
4722 symbolS *label;
4723 int force ATTRIBUTE_UNUSED;
4724 {
4725 if (alpha_current_align >= n)
4726 return;
4727
4728 if (pfill == NULL)
4729 {
4730 if (n > 2
4731 && (bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0)
4732 {
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
4737 };
4738
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);
4748 if (n > 3)
4749 frag_align_pattern (n, nopunop, sizeof nopunop, 0);
4750 }
4751 else
4752 frag_align (n, 0, 0);
4753 }
4754 else
4755 frag_align (n, *pfill, 0);
4756
4757 alpha_current_align = n;
4758
4759 if (label != NULL && S_GET_SEGMENT (label) == now_seg)
4760 {
4761 symbol_set_frag (label, frag_now);
4762 S_SET_VALUE (label, (valueT) frag_now_fix ());
4763 }
4764
4765 record_alignment (now_seg, n);
4766
4767 /* ??? if alpha_flag_relax && force && elf, record the requested alignment
4768 in a reloc for the linker to see. */
4769 }
4770
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"