* Many files: Added gettext invocations around user-visible
[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, 94, 95, 96, 1997, 1998 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
55 #include "opcode/alpha.h"
56
57 #ifdef OBJ_ELF
58 #include "elf/alpha.h"
59 #endif
60
61 #include <ctype.h>
62
63 \f
64 /* Local types */
65
66 #define MAX_INSN_FIXUPS 2
67 #define MAX_INSN_ARGS 5
68
69 struct alpha_fixup
70 {
71 expressionS exp;
72 bfd_reloc_code_real_type reloc;
73 };
74
75 struct alpha_insn
76 {
77 unsigned insn;
78 int nfixups;
79 struct alpha_fixup fixups[MAX_INSN_FIXUPS];
80 };
81
82 enum alpha_macro_arg
83 {
84 MACRO_EOA = 1, MACRO_IR, MACRO_PIR, MACRO_CPIR, MACRO_FPR, MACRO_EXP
85 };
86
87 struct alpha_macro
88 {
89 const char *name;
90 void (*emit) PARAMS ((const expressionS *, int, const PTR));
91 const PTR arg;
92 enum alpha_macro_arg argsets[16];
93 };
94
95 /* Two extra symbols we want to see in our input. This is a blatent
96 misuse of the expressionS.X_op field. */
97
98 #define O_pregister (O_max+1) /* O_register, but in parentheses */
99 #define O_cpregister (O_pregister+1) /* + 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 #endif
207 #if defined (OBJ_ECOFF) || defined (OBJ_EVAX)
208 static void s_alpha_rdata PARAMS ((int));
209 #endif
210 #ifdef OBJ_ECOFF
211 static void s_alpha_sdata PARAMS ((int));
212 #endif
213 #ifdef OBJ_ELF
214 static void s_alpha_section PARAMS ((int));
215 #endif
216 #ifdef OBJ_EVAX
217 static void s_alpha_section PARAMS ((int));
218 #endif
219 static void s_alpha_gprel32 PARAMS ((int));
220 static void s_alpha_float_cons PARAMS ((int));
221 static void s_alpha_proc PARAMS ((int));
222 static void s_alpha_set PARAMS ((int));
223 static void s_alpha_base PARAMS ((int));
224 static void s_alpha_align PARAMS ((int));
225 static void s_alpha_stringer PARAMS ((int));
226 static void s_alpha_space PARAMS ((int));
227
228 static void create_literal_section PARAMS ((const char *, segT *, symbolS **));
229 #ifndef OBJ_ELF
230 static void select_gp_value PARAMS ((void));
231 #endif
232 static void alpha_align PARAMS ((int, char *, symbolS *, int));
233
234 \f
235 /* Generic assembler global variables which must be defined by all
236 targets. */
237
238 /* These are exported to relaxing code, even though we don't do any
239 relaxing on this processor currently. */
240 int md_short_jump_size = 4;
241 int md_long_jump_size = 4;
242
243 /* Characters which always start a comment. */
244 const char comment_chars[] = "#";
245
246 /* Characters which start a comment at the beginning of a line. */
247 const char line_comment_chars[] = "#";
248
249 /* Characters which may be used to separate multiple commands on a
250 single line. */
251 const char line_separator_chars[] = ";";
252
253 /* Characters which are used to indicate an exponent in a floating
254 point number. */
255 const char EXP_CHARS[] = "eE";
256
257 /* Characters which mean that a number is a floating point constant,
258 as in 0d1.0. */
259 #if 0
260 const char FLT_CHARS[] = "dD";
261 #else
262 /* XXX: Do all of these really get used on the alpha?? */
263 char FLT_CHARS[] = "rRsSfFdDxXpP";
264 #endif
265
266 #ifdef OBJ_EVAX
267 const char *md_shortopts = "Fm:g+1h:HG:";
268 #else
269 const char *md_shortopts = "Fm:gG:";
270 #endif
271
272 struct option md_longopts[] = {
273 #define OPTION_32ADDR (OPTION_MD_BASE)
274 { "32addr", no_argument, NULL, OPTION_32ADDR },
275 #define OPTION_RELAX (OPTION_32ADDR+1)
276 { "relax", no_argument, NULL, OPTION_RELAX },
277 { NULL, no_argument, NULL, 0 }
278 };
279
280 size_t md_longopts_size = sizeof(md_longopts);
281
282 \f
283 #ifdef OBJ_EVAX
284 #define AXP_REG_R0 0
285 #define AXP_REG_R16 16
286 #define AXP_REG_R17 17
287 #undef AXP_REG_T9
288 #define AXP_REG_T9 22
289 #undef AXP_REG_T10
290 #define AXP_REG_T10 23
291 #undef AXP_REG_T11
292 #define AXP_REG_T11 24
293 #undef AXP_REG_T12
294 #define AXP_REG_T12 25
295 #define AXP_REG_AI 25
296 #undef AXP_REG_FP
297 #define AXP_REG_FP 29
298
299 #undef AXP_REG_GP
300 #define AXP_REG_GP AXP_REG_PV
301 #endif /* OBJ_EVAX */
302
303 /* The cpu for which we are generating code */
304 static unsigned alpha_target = AXP_OPCODE_BASE;
305 static const char *alpha_target_name = "<all>";
306
307 /* The hash table of instruction opcodes */
308 static struct hash_control *alpha_opcode_hash;
309
310 /* The hash table of macro opcodes */
311 static struct hash_control *alpha_macro_hash;
312
313 #ifdef OBJ_ECOFF
314 /* The $gp relocation symbol */
315 static symbolS *alpha_gp_symbol;
316
317 /* XXX: what is this, and why is it exported? */
318 valueT alpha_gp_value;
319 #endif
320
321 /* The current $gp register */
322 static int alpha_gp_register = AXP_REG_GP;
323
324 /* A table of the register symbols */
325 static symbolS *alpha_register_table[64];
326
327 /* Constant sections, or sections of constants */
328 #ifdef OBJ_ECOFF
329 static segT alpha_lita_section;
330 static segT alpha_lit4_section;
331 #endif
332 #ifdef OBJ_EVAX
333 static segT alpha_link_section;
334 static segT alpha_ctors_section;
335 static segT alpha_dtors_section;
336 #endif
337 static segT alpha_lit8_section;
338
339 /* Symbols referring to said sections. */
340 #ifdef OBJ_ECOFF
341 static symbolS *alpha_lita_symbol;
342 static symbolS *alpha_lit4_symbol;
343 #endif
344 #ifdef OBJ_EVAX
345 static symbolS *alpha_link_symbol;
346 static symbolS *alpha_ctors_symbol;
347 static symbolS *alpha_dtors_symbol;
348 #endif
349 static symbolS *alpha_lit8_symbol;
350
351 /* Literal for .litX+0x8000 within .lita */
352 #ifdef OBJ_ECOFF
353 static offsetT alpha_lit4_literal;
354 static offsetT alpha_lit8_literal;
355 #endif
356
357 /* Is the assembler not allowed to use $at? */
358 static int alpha_noat_on = 0;
359
360 /* Are macros enabled? */
361 static int alpha_macros_on = 1;
362
363 /* Are floats disabled? */
364 static int alpha_nofloats_on = 0;
365
366 /* Are addresses 32 bit? */
367 static int alpha_addr32_on = 0;
368
369 /* Symbol labelling the current insn. When the Alpha gas sees
370 foo:
371 .quad 0
372 and the section happens to not be on an eight byte boundary, it
373 will align both the symbol and the .quad to an eight byte boundary. */
374 static symbolS *alpha_insn_label;
375
376 /* Whether we should automatically align data generation pseudo-ops.
377 .align 0 will turn this off. */
378 static int alpha_auto_align_on = 1;
379
380 /* The known current alignment of the current section. */
381 static int alpha_current_align;
382
383 /* These are exported to ECOFF code. */
384 unsigned long alpha_gprmask, alpha_fprmask;
385
386 /* Whether the debugging option was seen. */
387 static int alpha_debug;
388
389 /* Don't fully resolve relocations, allowing code movement in the linker. */
390 static int alpha_flag_relax;
391
392 /* What value to give to bfd_set_gp_size. */
393 static int g_switch_value = 8;
394
395 #ifdef OBJ_EVAX
396 /* Collect information about current procedure here. */
397 static struct {
398 symbolS *symbol; /* proc pdesc symbol */
399 int pdsckind;
400 int framereg; /* register for frame pointer */
401 int framesize; /* size of frame */
402 int rsa_offset;
403 int ra_save;
404 int fp_save;
405 long imask;
406 long fmask;
407 int type;
408 int prologue;
409 } alpha_evax_proc;
410
411 static int alpha_flag_hash_long_names = 0; /* -+ */
412 static int alpha_flag_show_after_trunc = 0; /* -H */
413
414 /* If the -+ switch is given, then a hash is appended to any name that is
415 * longer than 64 characters, else longer symbol names are truncated.
416 */
417
418 #endif
419 \f
420 /* A table of CPU names and opcode sets. */
421
422 static const struct cpu_type
423 {
424 const char *name;
425 unsigned flags;
426 } cpu_types[] =
427 {
428 /* Ad hoc convention: cpu number gets palcode, process code doesn't.
429 This supports usage under DU 4.0b that does ".arch ev4", and
430 usage in MILO that does -m21064. Probably something more
431 specific like -m21064-pal should be used, but oh well. */
432
433 { "21064", AXP_OPCODE_BASE|AXP_OPCODE_EV4 },
434 { "21064a", AXP_OPCODE_BASE|AXP_OPCODE_EV4 },
435 { "21066", AXP_OPCODE_BASE|AXP_OPCODE_EV4 },
436 { "21068", AXP_OPCODE_BASE|AXP_OPCODE_EV4 },
437 { "21164", AXP_OPCODE_BASE|AXP_OPCODE_EV5 },
438 /* Do we have CIX extension here? */
439 { "21164a", AXP_OPCODE_BASE|AXP_OPCODE_EV5|AXP_OPCODE_BWX },
440 /* Still same PALcodes? */
441 { "21164pc", (AXP_OPCODE_BASE|AXP_OPCODE_EV5|AXP_OPCODE_BWX
442 |AXP_OPCODE_MAX) },
443 /* All new PALcodes? Extras? */
444 { "21264", (AXP_OPCODE_BASE|AXP_OPCODE_BWX
445 |AXP_OPCODE_CIX|AXP_OPCODE_MAX) },
446
447 { "ev4", AXP_OPCODE_BASE },
448 { "ev45", AXP_OPCODE_BASE },
449 { "lca45", AXP_OPCODE_BASE },
450 { "ev5", AXP_OPCODE_BASE },
451 { "ev56", AXP_OPCODE_BASE|AXP_OPCODE_BWX },
452 { "pca56", AXP_OPCODE_BASE|AXP_OPCODE_BWX|AXP_OPCODE_MAX },
453 { "ev6", AXP_OPCODE_BASE|AXP_OPCODE_BWX|AXP_OPCODE_CIX|AXP_OPCODE_MAX },
454
455 { "all", AXP_OPCODE_BASE },
456 { 0 }
457 };
458
459 /* The macro table */
460
461 static const struct alpha_macro alpha_macros[] = {
462 /* Load/Store macros */
463 { "lda", emit_lda, NULL,
464 { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
465 MACRO_IR, MACRO_EXP, MACRO_EOA } },
466 { "ldah", emit_ldah, NULL,
467 { MACRO_IR, MACRO_EXP, MACRO_EOA } },
468
469 { "ldl", emit_ir_load, "ldl",
470 { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
471 MACRO_IR, MACRO_EXP, MACRO_EOA } },
472 { "ldl_l", emit_ir_load, "ldl_l",
473 { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
474 MACRO_IR, MACRO_EXP, MACRO_EOA } },
475 { "ldq", emit_ir_load, "ldq",
476 { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
477 MACRO_IR, MACRO_EXP, MACRO_EOA } },
478 { "ldq_l", emit_ir_load, "ldq_l",
479 { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
480 MACRO_IR, MACRO_EXP, MACRO_EOA } },
481 { "ldq_u", emit_ir_load, "ldq_u",
482 { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
483 MACRO_IR, MACRO_EXP, MACRO_EOA } },
484 { "ldf", emit_loadstore, "ldf",
485 { MACRO_FPR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
486 MACRO_FPR, MACRO_EXP, MACRO_EOA } },
487 { "ldg", emit_loadstore, "ldg",
488 { MACRO_FPR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
489 MACRO_FPR, MACRO_EXP, MACRO_EOA } },
490 { "lds", emit_loadstore, "lds",
491 { MACRO_FPR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
492 MACRO_FPR, MACRO_EXP, MACRO_EOA } },
493 { "ldt", emit_loadstore, "ldt",
494 { MACRO_FPR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
495 MACRO_FPR, MACRO_EXP, MACRO_EOA } },
496
497 { "ldb", emit_ldX, (PTR)0,
498 { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
499 MACRO_IR, MACRO_EXP, MACRO_EOA } },
500 { "ldbu", emit_ldXu, (PTR)0,
501 { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
502 MACRO_IR, MACRO_EXP, MACRO_EOA } },
503 { "ldw", emit_ldX, (PTR)1,
504 { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
505 MACRO_IR, MACRO_EXP, MACRO_EOA } },
506 { "ldwu", emit_ldXu, (PTR)1,
507 { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
508 MACRO_IR, MACRO_EXP, MACRO_EOA } },
509
510 { "uldw", emit_uldX, (PTR)1,
511 { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
512 MACRO_IR, MACRO_EXP, MACRO_EOA } },
513 { "uldwu", emit_uldXu, (PTR)1,
514 { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
515 MACRO_IR, MACRO_EXP, MACRO_EOA } },
516 { "uldl", emit_uldX, (PTR)2,
517 { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
518 MACRO_IR, MACRO_EXP, MACRO_EOA } },
519 { "uldlu", emit_uldXu, (PTR)2,
520 { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
521 MACRO_IR, MACRO_EXP, MACRO_EOA } },
522 { "uldq", emit_uldXu, (PTR)3,
523 { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
524 MACRO_IR, MACRO_EXP, MACRO_EOA } },
525
526 { "ldgp", emit_ldgp, NULL,
527 { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA } },
528
529 { "ldi", emit_lda, NULL,
530 { MACRO_IR, MACRO_EXP, MACRO_EOA } },
531 { "ldil", emit_ldil, NULL,
532 { MACRO_IR, MACRO_EXP, MACRO_EOA } },
533 { "ldiq", emit_lda, NULL,
534 { MACRO_IR, MACRO_EXP, MACRO_EOA } },
535 #if 0
536 { "ldif" emit_ldiq, NULL,
537 { MACRO_FPR, MACRO_EXP, MACRO_EOA } },
538 { "ldid" emit_ldiq, NULL,
539 { MACRO_FPR, MACRO_EXP, MACRO_EOA } },
540 { "ldig" emit_ldiq, NULL,
541 { MACRO_FPR, MACRO_EXP, MACRO_EOA } },
542 { "ldis" emit_ldiq, NULL,
543 { MACRO_FPR, MACRO_EXP, MACRO_EOA } },
544 { "ldit" emit_ldiq, NULL,
545 { MACRO_FPR, MACRO_EXP, MACRO_EOA } },
546 #endif
547
548 { "stl", emit_loadstore, "stl",
549 { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
550 MACRO_IR, MACRO_EXP, MACRO_EOA } },
551 { "stl_c", emit_loadstore, "stl_c",
552 { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
553 MACRO_IR, MACRO_EXP, MACRO_EOA } },
554 { "stq", emit_loadstore, "stq",
555 { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
556 MACRO_IR, MACRO_EXP, MACRO_EOA } },
557 { "stq_c", emit_loadstore, "stq_c",
558 { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
559 MACRO_IR, MACRO_EXP, MACRO_EOA } },
560 { "stq_u", emit_loadstore, "stq_u",
561 { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
562 MACRO_IR, MACRO_EXP, MACRO_EOA } },
563 { "stf", emit_loadstore, "stf",
564 { MACRO_FPR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
565 MACRO_FPR, MACRO_EXP, MACRO_EOA } },
566 { "stg", emit_loadstore, "stg",
567 { MACRO_FPR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
568 MACRO_FPR, MACRO_EXP, MACRO_EOA } },
569 { "sts", emit_loadstore, "sts",
570 { MACRO_FPR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
571 MACRO_FPR, MACRO_EXP, MACRO_EOA } },
572 { "stt", emit_loadstore, "stt",
573 { MACRO_FPR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
574 MACRO_FPR, MACRO_EXP, MACRO_EOA } },
575
576 { "stb", emit_stX, (PTR)0,
577 { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
578 MACRO_IR, MACRO_EXP, MACRO_EOA } },
579 { "stw", emit_stX, (PTR)1,
580 { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
581 MACRO_IR, MACRO_EXP, MACRO_EOA } },
582 { "ustw", emit_ustX, (PTR)1,
583 { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
584 MACRO_IR, MACRO_EXP, MACRO_EOA } },
585 { "ustl", emit_ustX, (PTR)2,
586 { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
587 MACRO_IR, MACRO_EXP, MACRO_EOA } },
588 { "ustq", emit_ustX, (PTR)3,
589 { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA,
590 MACRO_IR, MACRO_EXP, MACRO_EOA } },
591
592 /* Arithmetic macros */
593 #if 0
594 { "absl" emit_absl, 1, { IR } },
595 { "absl" emit_absl, 2, { IR, IR } },
596 { "absl" emit_absl, 2, { EXP, IR } },
597 { "absq" emit_absq, 1, { IR } },
598 { "absq" emit_absq, 2, { IR, IR } },
599 { "absq" emit_absq, 2, { EXP, IR } },
600 #endif
601
602 { "sextb", emit_sextX, (PTR)0,
603 { MACRO_IR, MACRO_IR, MACRO_EOA,
604 MACRO_IR, MACRO_EOA,
605 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
606 { "sextw", emit_sextX, (PTR)1,
607 { MACRO_IR, MACRO_IR, MACRO_EOA,
608 MACRO_IR, MACRO_EOA,
609 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
610
611 { "divl", emit_division, "__divl",
612 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
613 MACRO_IR, MACRO_IR, MACRO_EOA,
614 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
615 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
616 { "divlu", emit_division, "__divlu",
617 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
618 MACRO_IR, MACRO_IR, MACRO_EOA,
619 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
620 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
621 { "divq", emit_division, "__divq",
622 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
623 MACRO_IR, MACRO_IR, MACRO_EOA,
624 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
625 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
626 { "divqu", emit_division, "__divqu",
627 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
628 MACRO_IR, MACRO_IR, MACRO_EOA,
629 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
630 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
631 { "reml", emit_division, "__reml",
632 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
633 MACRO_IR, MACRO_IR, MACRO_EOA,
634 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
635 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
636 { "remlu", emit_division, "__remlu",
637 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
638 MACRO_IR, MACRO_IR, MACRO_EOA,
639 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
640 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
641 { "remq", emit_division, "__remq",
642 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
643 MACRO_IR, MACRO_IR, MACRO_EOA,
644 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
645 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
646 { "remqu", emit_division, "__remqu",
647 { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
648 MACRO_IR, MACRO_IR, MACRO_EOA,
649 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
650 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
651
652 { "jsr", emit_jsrjmp, "jsr",
653 { MACRO_PIR, MACRO_EXP, MACRO_EOA,
654 MACRO_PIR, MACRO_EOA,
655 MACRO_IR, MACRO_EXP, MACRO_EOA,
656 MACRO_EXP, MACRO_EOA } },
657 { "jmp", emit_jsrjmp, "jmp",
658 { MACRO_PIR, MACRO_EXP, MACRO_EOA,
659 MACRO_PIR, MACRO_EOA,
660 MACRO_IR, MACRO_EXP, MACRO_EOA,
661 MACRO_EXP, MACRO_EOA } },
662 { "ret", emit_retjcr, "ret",
663 { MACRO_IR, MACRO_EXP, MACRO_EOA,
664 MACRO_IR, MACRO_EOA,
665 MACRO_PIR, MACRO_EXP, MACRO_EOA,
666 MACRO_PIR, MACRO_EOA,
667 MACRO_EXP, MACRO_EOA,
668 MACRO_EOA } },
669 { "jcr", emit_retjcr, "jcr",
670 { MACRO_IR, MACRO_EXP, MACRO_EOA,
671 MACRO_IR, MACRO_EOA,
672 MACRO_PIR, MACRO_EXP, MACRO_EOA,
673 MACRO_PIR, MACRO_EOA,
674 MACRO_EXP, MACRO_EOA,
675 MACRO_EOA } },
676 { "jsr_coroutine", emit_retjcr, "jcr",
677 { MACRO_IR, MACRO_EXP, MACRO_EOA,
678 MACRO_IR, MACRO_EOA,
679 MACRO_PIR, MACRO_EXP, MACRO_EOA,
680 MACRO_PIR, MACRO_EOA,
681 MACRO_EXP, MACRO_EOA,
682 MACRO_EOA } },
683 };
684
685 static const int alpha_num_macros
686 = sizeof(alpha_macros) / sizeof(*alpha_macros);
687 \f
688 /* Public interface functions */
689
690 /* This function is called once, at assembler startup time. It sets
691 up all the tables, etc. that the MD part of the assembler will
692 need, that can be determined before arguments are parsed. */
693
694 void
695 md_begin ()
696 {
697 unsigned int i;
698
699 /* Create the opcode hash table */
700
701 alpha_opcode_hash = hash_new ();
702 for (i = 0; i < alpha_num_opcodes; )
703 {
704 const char *name, *retval, *slash;
705
706 name = alpha_opcodes[i].name;
707 retval = hash_insert (alpha_opcode_hash, name, (PTR)&alpha_opcodes[i]);
708 if (retval)
709 as_fatal (_("internal error: can't hash opcode `%s': %s"), name, retval);
710
711 /* Some opcodes include modifiers of various sorts with a "/mod"
712 syntax, like the architecture manual suggests. However, for
713 use with gcc at least, we also need access to those same opcodes
714 without the "/". */
715
716 if ((slash = strchr (name, '/')) != NULL)
717 {
718 char *p = xmalloc (strlen (name));
719 memcpy (p, name, slash - name);
720 strcpy (p + (slash - name), slash + 1);
721
722 (void)hash_insert(alpha_opcode_hash, p, (PTR)&alpha_opcodes[i]);
723 /* Ignore failures -- the opcode table does duplicate some
724 variants in different forms, like "hw_stq" and "hw_st/q". */
725 }
726
727 while (++i < alpha_num_opcodes
728 && (alpha_opcodes[i].name == name
729 || !strcmp (alpha_opcodes[i].name, name)))
730 continue;
731 }
732
733 /* Create the macro hash table */
734
735 alpha_macro_hash = hash_new ();
736 for (i = 0; i < alpha_num_macros; )
737 {
738 const char *name, *retval;
739
740 name = alpha_macros[i].name;
741 retval = hash_insert (alpha_macro_hash, name, (PTR)&alpha_macros[i]);
742 if (retval)
743 as_fatal (_("internal error: can't hash macro `%s': %s"), name, retval);
744
745 while (++i < alpha_num_macros
746 && (alpha_macros[i].name == name
747 || !strcmp (alpha_macros[i].name, name)))
748 continue;
749 }
750
751 /* Construct symbols for each of the registers */
752
753 for (i = 0; i < 32; ++i)
754 {
755 char name[4];
756 sprintf(name, "$%d", i);
757 alpha_register_table[i] = symbol_create(name, reg_section, i,
758 &zero_address_frag);
759 }
760 for (; i < 64; ++i)
761 {
762 char name[5];
763 sprintf(name, "$f%d", i-32);
764 alpha_register_table[i] = symbol_create(name, reg_section, i,
765 &zero_address_frag);
766 }
767
768 /* Create the special symbols and sections we'll be using */
769
770 /* So .sbss will get used for tiny objects. */
771 bfd_set_gp_size (stdoutput, g_switch_value);
772
773 #ifdef OBJ_ECOFF
774 create_literal_section (".lita", &alpha_lita_section, &alpha_lita_symbol);
775
776 /* For handling the GP, create a symbol that won't be output in the
777 symbol table. We'll edit it out of relocs later. */
778 alpha_gp_symbol = symbol_create ("<GP value>", alpha_lita_section, 0x8000,
779 &zero_address_frag);
780 #endif
781
782 #ifdef OBJ_EVAX
783 create_literal_section (".link", &alpha_link_section, &alpha_link_symbol);
784 #endif
785
786 #ifdef OBJ_ELF
787 if (ECOFF_DEBUGGING)
788 {
789 segT sec;
790
791 sec = subseg_new(".mdebug", (subsegT)0);
792 bfd_set_section_flags(stdoutput, sec, SEC_HAS_CONTENTS|SEC_READONLY);
793 bfd_set_section_alignment(stdoutput, sec, 3);
794
795 #ifdef ERIC_neverdef
796 sec = subseg_new(".reginfo", (subsegT)0);
797 /* The ABI says this section should be loaded so that the running
798 program can access it. */
799 bfd_set_section_flags(stdoutput, sec,
800 SEC_ALLOC|SEC_LOAD|SEC_READONLY|SEC_DATA);
801 bfd_set_section_alignement(stdoutput, sec, 3);
802 #endif
803 }
804 #endif /* OBJ_ELF */
805
806 subseg_set(text_section, 0);
807 }
808
809 /* The public interface to the instruction assembler. */
810
811 void
812 md_assemble (str)
813 char *str;
814 {
815 char opname[32]; /* current maximum is 13 */
816 expressionS tok[MAX_INSN_ARGS];
817 int ntok, opnamelen, trunclen;
818
819 /* split off the opcode */
820 opnamelen = strspn (str, "abcdefghijklmnopqrstuvwxyz_/48");
821 trunclen = (opnamelen < sizeof (opname) - 1
822 ? opnamelen
823 : sizeof (opname) - 1);
824 memcpy (opname, str, trunclen);
825 opname[trunclen] = '\0';
826
827 /* tokenize the rest of the line */
828 if ((ntok = tokenize_arguments (str + opnamelen, tok, MAX_INSN_ARGS)) < 0)
829 {
830 as_bad (_("syntax error"));
831 return;
832 }
833
834 /* finish it off */
835 assemble_tokens (opname, tok, ntok, alpha_macros_on);
836 }
837
838 /* Round up a section's size to the appropriate boundary. */
839
840 valueT
841 md_section_align (seg, size)
842 segT seg;
843 valueT size;
844 {
845 int align = bfd_get_section_alignment(stdoutput, seg);
846 valueT mask = ((valueT)1 << align) - 1;
847
848 return (size + mask) & ~mask;
849 }
850
851 /* Turn a string in input_line_pointer into a floating point constant
852 of type type, and store the appropriate bytes in *litP. The number
853 of LITTLENUMS emitted is stored in *sizeP. An error message is
854 returned, or NULL on OK. */
855
856 /* Equal to MAX_PRECISION in atof-ieee.c */
857 #define MAX_LITTLENUMS 6
858
859 extern char *vax_md_atof PARAMS ((int, char *, int *));
860
861 char *
862 md_atof (type, litP, sizeP)
863 char type;
864 char *litP;
865 int *sizeP;
866 {
867 int prec;
868 LITTLENUM_TYPE words[MAX_LITTLENUMS];
869 LITTLENUM_TYPE *wordP;
870 char *t;
871
872 switch (type)
873 {
874 /* VAX floats */
875 case 'G':
876 /* VAX md_atof doesn't like "G" for some reason. */
877 type = 'g';
878 case 'F':
879 case 'D':
880 return vax_md_atof (type, litP, sizeP);
881
882 /* IEEE floats */
883 case 'f':
884 prec = 2;
885 break;
886
887 case 'd':
888 prec = 4;
889 break;
890
891 case 'x':
892 case 'X':
893 prec = 6;
894 break;
895
896 case 'p':
897 case 'P':
898 prec = 6;
899 break;
900
901 default:
902 *sizeP = 0;
903 return _("Bad call to MD_ATOF()");
904 }
905 t = atof_ieee (input_line_pointer, type, words);
906 if (t)
907 input_line_pointer = t;
908 *sizeP = prec * sizeof (LITTLENUM_TYPE);
909
910 for (wordP = words + prec - 1; prec--;)
911 {
912 md_number_to_chars (litP, (long) (*wordP--), sizeof (LITTLENUM_TYPE));
913 litP += sizeof (LITTLENUM_TYPE);
914 }
915
916 return 0;
917 }
918
919 /* Take care of the target-specific command-line options. */
920
921 int
922 md_parse_option (c, arg)
923 int c;
924 char *arg;
925 {
926 switch (c)
927 {
928 case 'F':
929 alpha_nofloats_on = 1;
930 break;
931
932 case OPTION_32ADDR:
933 alpha_addr32_on = 1;
934 break;
935
936 case 'g':
937 alpha_debug = 1;
938 break;
939
940 case 'G':
941 g_switch_value = atoi(arg);
942 break;
943
944 case 'm':
945 {
946 const struct cpu_type *p;
947 for (p = cpu_types; p->name; ++p)
948 if (strcmp(arg, p->name) == 0)
949 {
950 alpha_target_name = p->name, alpha_target = p->flags;
951 goto found;
952 }
953 as_warn(_("Unknown CPU identifier `%s'"), arg);
954 found:;
955 }
956 break;
957
958 #ifdef OBJ_EVAX
959 case '+': /* For g++. Hash any name > 63 chars long. */
960 alpha_flag_hash_long_names = 1;
961 break;
962
963 case 'H': /* Show new symbol after hash truncation */
964 alpha_flag_show_after_trunc = 1;
965 break;
966
967 case 'h': /* for gnu-c/vax compatibility. */
968 break;
969 #endif
970
971 case OPTION_RELAX:
972 alpha_flag_relax = 1;
973 break;
974
975 default:
976 return 0;
977 }
978
979 return 1;
980 }
981
982 /* Print a description of the command-line options that we accept. */
983
984 void
985 md_show_usage (stream)
986 FILE *stream;
987 {
988 fputs(_("\
989 Alpha options:\n\
990 -32addr treat addresses as 32-bit values\n\
991 -F lack floating point instructions support\n\
992 -m21064 | -m21066 | -m21164 | -m21164a\n\
993 -mev4 | -mev45 | -mev5 | -mev56 | -mall\n\
994 specify variant of Alpha architecture\n"),
995 stream);
996 #ifdef OBJ_EVAX
997 fputs (_("\
998 VMS options:\n\
999 -+ hash encode (don't truncate) names longer than 64 characters\n\
1000 -H show new symbol after hash truncation\n"),
1001 stream);
1002 #endif
1003 }
1004
1005 /* Decide from what point a pc-relative relocation is relative to,
1006 relative to the pc-relative fixup. Er, relatively speaking. */
1007
1008 long
1009 md_pcrel_from (fixP)
1010 fixS *fixP;
1011 {
1012 valueT addr = fixP->fx_where + fixP->fx_frag->fr_address;
1013 switch (fixP->fx_r_type)
1014 {
1015 case BFD_RELOC_ALPHA_GPDISP:
1016 case BFD_RELOC_ALPHA_GPDISP_HI16:
1017 case BFD_RELOC_ALPHA_GPDISP_LO16:
1018 return addr;
1019 default:
1020 return fixP->fx_size + addr;
1021 }
1022 }
1023
1024 /* Attempt to simplify or even eliminate a fixup. The return value is
1025 ignored; perhaps it was once meaningful, but now it is historical.
1026 To indicate that a fixup has been eliminated, set fixP->fx_done.
1027
1028 For ELF, here it is that we transform the GPDISP_HI16 reloc we used
1029 internally into the GPDISP reloc used externally. We had to do
1030 this so that we'd have the GPDISP_LO16 reloc as a tag to compute
1031 the distance to the "lda" instruction for setting the addend to
1032 GPDISP. */
1033
1034 int
1035 md_apply_fix (fixP, valueP)
1036 fixS *fixP;
1037 valueT *valueP;
1038 {
1039 char * const fixpos = fixP->fx_frag->fr_literal + fixP->fx_where;
1040 valueT value = *valueP;
1041 unsigned image, size;
1042
1043 switch (fixP->fx_r_type)
1044 {
1045 /* The GPDISP relocations are processed internally with a symbol
1046 referring to the current function; we need to drop in a value
1047 which, when added to the address of the start of the function,
1048 gives the desired GP. */
1049 case BFD_RELOC_ALPHA_GPDISP_HI16:
1050 {
1051 fixS *next = fixP->fx_next;
1052 assert (next->fx_r_type == BFD_RELOC_ALPHA_GPDISP_LO16);
1053
1054 fixP->fx_offset = (next->fx_frag->fr_address + next->fx_where
1055 - fixP->fx_frag->fr_address - fixP->fx_where);
1056
1057 value = (value - sign_extend_16 (value)) >> 16;
1058 }
1059 #ifdef OBJ_ELF
1060 fixP->fx_r_type = BFD_RELOC_ALPHA_GPDISP;
1061 #endif
1062 goto do_reloc_gp;
1063
1064 case BFD_RELOC_ALPHA_GPDISP_LO16:
1065 value = sign_extend_16 (value);
1066 fixP->fx_offset = 0;
1067 #ifdef OBJ_ELF
1068 fixP->fx_done = 1;
1069 #endif
1070
1071 do_reloc_gp:
1072 fixP->fx_addsy = section_symbol (absolute_section);
1073 md_number_to_chars (fixpos, value, 2);
1074 break;
1075
1076 case BFD_RELOC_16:
1077 if (fixP->fx_pcrel)
1078 fixP->fx_r_type = BFD_RELOC_16_PCREL;
1079 size = 2;
1080 goto do_reloc_xx;
1081 case BFD_RELOC_32:
1082 if (fixP->fx_pcrel)
1083 fixP->fx_r_type = BFD_RELOC_32_PCREL;
1084 size = 4;
1085 goto do_reloc_xx;
1086 case BFD_RELOC_64:
1087 if (fixP->fx_pcrel)
1088 fixP->fx_r_type = BFD_RELOC_64_PCREL;
1089 size = 8;
1090 do_reloc_xx:
1091 if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0)
1092 {
1093 md_number_to_chars (fixpos, value, size);
1094 goto done;
1095 }
1096 return 1;
1097
1098 #ifdef OBJ_ECOFF
1099 case BFD_RELOC_GPREL32:
1100 assert (fixP->fx_subsy == alpha_gp_symbol);
1101 fixP->fx_subsy = 0;
1102 /* FIXME: inherited this obliviousness of `value' -- why? */
1103 md_number_to_chars (fixpos, -alpha_gp_value, 4);
1104 break;
1105 #endif
1106 #ifdef OBJ_ELF
1107 case BFD_RELOC_GPREL32:
1108 return 1;
1109 #endif
1110
1111 case BFD_RELOC_23_PCREL_S2:
1112 if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0)
1113 {
1114 image = bfd_getl32(fixpos);
1115 image = (image & ~0x1FFFFF) | ((value >> 2) & 0x1FFFFF);
1116 goto write_done;
1117 }
1118 return 1;
1119
1120 case BFD_RELOC_ALPHA_HINT:
1121 if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0)
1122 {
1123 image = bfd_getl32(fixpos);
1124 image = (image & ~0x3FFF) | ((value >> 2) & 0x3FFF);
1125 goto write_done;
1126 }
1127 return 1;
1128
1129 #ifdef OBJ_ECOFF
1130 case BFD_RELOC_ALPHA_LITERAL:
1131 md_number_to_chars (fixpos, value, 2);
1132 return 1;
1133
1134 case BFD_RELOC_ALPHA_LITUSE:
1135 return 1;
1136 #endif
1137 #ifdef OBJ_ELF
1138 case BFD_RELOC_ALPHA_ELF_LITERAL:
1139 case BFD_RELOC_ALPHA_LITUSE:
1140 return 1;
1141 #endif
1142 #ifdef OBJ_EVAX
1143 case BFD_RELOC_ALPHA_LINKAGE:
1144 case BFD_RELOC_ALPHA_CODEADDR:
1145 return 1;
1146 #endif
1147
1148 default:
1149 {
1150 const struct alpha_operand *operand;
1151
1152 if ((int)fixP->fx_r_type >= 0)
1153 as_fatal (_("unhandled relocation type %s"),
1154 bfd_get_reloc_code_name (fixP->fx_r_type));
1155
1156 assert (-(int)fixP->fx_r_type < alpha_num_operands);
1157 operand = &alpha_operands[-(int)fixP->fx_r_type];
1158
1159 /* The rest of these fixups only exist internally during symbol
1160 resolution and have no representation in the object file.
1161 Therefore they must be completely resolved as constants. */
1162
1163 if (fixP->fx_addsy != 0
1164 && fixP->fx_addsy->bsym->section != absolute_section)
1165 as_bad_where (fixP->fx_file, fixP->fx_line,
1166 _("non-absolute expression in constant field"));
1167
1168 image = bfd_getl32(fixpos);
1169 image = insert_operand(image, operand, (offsetT)value,
1170 fixP->fx_file, fixP->fx_line);
1171 }
1172 goto write_done;
1173 }
1174
1175 if (fixP->fx_addsy != 0 || fixP->fx_pcrel != 0)
1176 return 1;
1177 else
1178 {
1179 as_warn_where(fixP->fx_file, fixP->fx_line,
1180 _("type %d reloc done?\n"), (int)fixP->fx_r_type);
1181 goto done;
1182 }
1183
1184 write_done:
1185 md_number_to_chars(fixpos, image, 4);
1186
1187 done:
1188 fixP->fx_done = 1;
1189 return 0;
1190 }
1191
1192 /*
1193 * Look for a register name in the given symbol.
1194 */
1195
1196 symbolS *
1197 md_undefined_symbol(name)
1198 char *name;
1199 {
1200 if (*name == '$')
1201 {
1202 int is_float = 0, num;
1203
1204 switch (*++name)
1205 {
1206 case 'f':
1207 if (name[1] == 'p' && name[2] == '\0')
1208 return alpha_register_table[AXP_REG_FP];
1209 is_float = 32;
1210 /* FALLTHRU */
1211
1212 case 'r':
1213 if (!isdigit(*++name))
1214 break;
1215 /* FALLTHRU */
1216
1217 case '0': case '1': case '2': case '3': case '4':
1218 case '5': case '6': case '7': case '8': case '9':
1219 if (name[1] == '\0')
1220 num = name[0] - '0';
1221 else if (name[0] != '0' && isdigit(name[1]) && name[2] == '\0')
1222 {
1223 num = (name[0] - '0') * 10 + name[1] - '0';
1224 if (num >= 32)
1225 break;
1226 }
1227 else
1228 break;
1229
1230 if (!alpha_noat_on && num == AXP_REG_AT)
1231 as_warn(_("Used $at without \".set noat\""));
1232 return alpha_register_table[num + is_float];
1233
1234 case 'a':
1235 if (name[1] == 't' && name[2] == '\0')
1236 {
1237 if (!alpha_noat_on)
1238 as_warn(_("Used $at without \".set noat\""));
1239 return alpha_register_table[AXP_REG_AT];
1240 }
1241 break;
1242
1243 case 'g':
1244 if (name[1] == 'p' && name[2] == '\0')
1245 return alpha_register_table[alpha_gp_register];
1246 break;
1247
1248 case 's':
1249 if (name[1] == 'p' && name[2] == '\0')
1250 return alpha_register_table[AXP_REG_SP];
1251 break;
1252 }
1253 }
1254 return NULL;
1255 }
1256
1257 #ifdef OBJ_ECOFF
1258 /* @@@ Magic ECOFF bits. */
1259
1260 void
1261 alpha_frob_ecoff_data ()
1262 {
1263 select_gp_value ();
1264 /* $zero and $f31 are read-only */
1265 alpha_gprmask &= ~1;
1266 alpha_fprmask &= ~1;
1267 }
1268 #endif
1269
1270 /* Hook to remember a recently defined label so that the auto-align
1271 code can adjust the symbol after we know what alignment will be
1272 required. */
1273
1274 void
1275 alpha_define_label (sym)
1276 symbolS *sym;
1277 {
1278 alpha_insn_label = sym;
1279 }
1280
1281 /* Return true if we must always emit a reloc for a type and false if
1282 there is some hope of resolving it a assembly time. */
1283
1284 int
1285 alpha_force_relocation (f)
1286 fixS *f;
1287 {
1288 if (alpha_flag_relax)
1289 return 1;
1290
1291 switch (f->fx_r_type)
1292 {
1293 case BFD_RELOC_ALPHA_GPDISP_HI16:
1294 case BFD_RELOC_ALPHA_GPDISP_LO16:
1295 case BFD_RELOC_ALPHA_GPDISP:
1296 #ifdef OBJ_ECOFF
1297 case BFD_RELOC_ALPHA_LITERAL:
1298 #endif
1299 #ifdef OBJ_ELF
1300 case BFD_RELOC_ALPHA_ELF_LITERAL:
1301 #endif
1302 case BFD_RELOC_ALPHA_LITUSE:
1303 case BFD_RELOC_GPREL32:
1304 #ifdef OBJ_EVAX
1305 case BFD_RELOC_ALPHA_LINKAGE:
1306 case BFD_RELOC_ALPHA_CODEADDR:
1307 #endif
1308 return 1;
1309
1310 case BFD_RELOC_23_PCREL_S2:
1311 case BFD_RELOC_32:
1312 case BFD_RELOC_64:
1313 case BFD_RELOC_ALPHA_HINT:
1314 return 0;
1315
1316 default:
1317 assert((int)f->fx_r_type < 0 && -(int)f->fx_r_type < alpha_num_operands);
1318 return 0;
1319 }
1320 }
1321
1322 /* Return true if we can partially resolve a relocation now. */
1323
1324 int
1325 alpha_fix_adjustable (f)
1326 fixS *f;
1327 {
1328 #ifdef OBJ_ELF
1329 /* Prevent all adjustments to global symbols */
1330 if (S_IS_EXTERN (f->fx_addsy))
1331 return 0;
1332 #endif
1333
1334 /* Are there any relocation types for which we must generate a reloc
1335 but we can adjust the values contained within it? */
1336 switch (f->fx_r_type)
1337 {
1338 case BFD_RELOC_ALPHA_GPDISP_HI16:
1339 case BFD_RELOC_ALPHA_GPDISP_LO16:
1340 case BFD_RELOC_ALPHA_GPDISP:
1341 return 0;
1342
1343 #ifdef OBJ_ECOFF
1344 case BFD_RELOC_ALPHA_LITERAL:
1345 #endif
1346 #ifdef OBJ_ELF
1347 case BFD_RELOC_ALPHA_ELF_LITERAL:
1348 #endif
1349 #ifdef OBJ_EVAX
1350 case BFD_RELOC_ALPHA_LINKAGE:
1351 case BFD_RELOC_ALPHA_CODEADDR:
1352 #endif
1353 return 1;
1354
1355 case BFD_RELOC_ALPHA_LITUSE:
1356 return 0;
1357
1358 case BFD_RELOC_GPREL32:
1359 case BFD_RELOC_23_PCREL_S2:
1360 case BFD_RELOC_32:
1361 case BFD_RELOC_64:
1362 case BFD_RELOC_ALPHA_HINT:
1363 return 1;
1364
1365 default:
1366 assert ((int)f->fx_r_type < 0
1367 && - (int)f->fx_r_type < alpha_num_operands);
1368 return 1;
1369 }
1370 /*NOTREACHED*/
1371 }
1372
1373 /* Generate the BFD reloc to be stuck in the object file from the
1374 fixup used internally in the assembler. */
1375
1376 arelent *
1377 tc_gen_reloc (sec, fixp)
1378 asection *sec;
1379 fixS *fixp;
1380 {
1381 arelent *reloc;
1382
1383 reloc = (arelent *) xmalloc (sizeof (arelent));
1384 reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym;
1385 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
1386
1387 /* Make sure none of our internal relocations make it this far.
1388 They'd better have been fully resolved by this point. */
1389 assert ((int)fixp->fx_r_type > 0);
1390
1391 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
1392 if (reloc->howto == NULL)
1393 {
1394 as_bad_where (fixp->fx_file, fixp->fx_line,
1395 _("cannot represent `%s' relocation in object file"),
1396 bfd_get_reloc_code_name (fixp->fx_r_type));
1397 return NULL;
1398 }
1399
1400 if (!fixp->fx_pcrel != !reloc->howto->pc_relative)
1401 {
1402 as_fatal (_("internal error? cannot generate `%s' relocation"),
1403 bfd_get_reloc_code_name (fixp->fx_r_type));
1404 }
1405 assert (!fixp->fx_pcrel == !reloc->howto->pc_relative);
1406
1407 #ifdef OBJ_ECOFF
1408 if (fixp->fx_r_type == BFD_RELOC_ALPHA_LITERAL)
1409 {
1410 /* fake out bfd_perform_relocation. sigh */
1411 reloc->addend = -alpha_gp_value;
1412 }
1413 else
1414 #endif
1415 {
1416 reloc->addend = fixp->fx_offset;
1417 #ifdef OBJ_ELF
1418 /*
1419 * Ohhh, this is ugly. The problem is that if this is a local global
1420 * symbol, the relocation will entirely be performed at link time, not
1421 * at assembly time. bfd_perform_reloc doesn't know about this sort
1422 * of thing, and as a result we need to fake it out here.
1423 */
1424 if (S_IS_EXTERN (fixp->fx_addsy) && !S_IS_COMMON(fixp->fx_addsy))
1425 reloc->addend -= fixp->fx_addsy->bsym->value;
1426 #endif
1427 }
1428
1429 return reloc;
1430 }
1431
1432 /* Parse a register name off of the input_line and return a register
1433 number. Gets md_undefined_symbol above to do the register name
1434 matching for us.
1435
1436 Only called as a part of processing the ECOFF .frame directive. */
1437
1438 int
1439 tc_get_register (frame)
1440 int frame;
1441 {
1442 int framereg = AXP_REG_SP;
1443
1444 SKIP_WHITESPACE ();
1445 if (*input_line_pointer == '$')
1446 {
1447 char *s = input_line_pointer;
1448 char c = get_symbol_end ();
1449 symbolS *sym = md_undefined_symbol (s);
1450
1451 *strchr(s, '\0') = c;
1452 if (sym && (framereg = S_GET_VALUE (sym)) <= 31)
1453 goto found;
1454 }
1455 as_warn (_("frame reg expected, using $%d."), framereg);
1456
1457 found:
1458 note_gpreg (framereg);
1459 return framereg;
1460 }
1461
1462 /* This is called before the symbol table is processed. In order to
1463 work with gcc when using mips-tfile, we must keep all local labels.
1464 However, in other cases, we want to discard them. If we were
1465 called with -g, but we didn't see any debugging information, it may
1466 mean that gcc is smuggling debugging information through to
1467 mips-tfile, in which case we must generate all local labels. */
1468
1469 #ifdef OBJ_ECOFF
1470
1471 void
1472 alpha_frob_file_before_adjust ()
1473 {
1474 if (alpha_debug != 0
1475 && ! ecoff_debugging_seen)
1476 flag_keep_locals = 1;
1477 }
1478
1479 #endif /* OBJ_ECOFF */
1480 \f
1481 /* Parse the arguments to an opcode. */
1482
1483 static int
1484 tokenize_arguments (str, tok, ntok)
1485 char *str;
1486 expressionS tok[];
1487 int ntok;
1488 {
1489 expressionS *end_tok = tok + ntok;
1490 char *old_input_line_pointer;
1491 int saw_comma = 0, saw_arg = 0;
1492
1493 memset (tok, 0, sizeof (*tok) * ntok);
1494
1495 /* Save and restore input_line_pointer around this function */
1496 old_input_line_pointer = input_line_pointer;
1497 input_line_pointer = str;
1498
1499 while (tok < end_tok && *input_line_pointer)
1500 {
1501 SKIP_WHITESPACE ();
1502 switch (*input_line_pointer)
1503 {
1504 case '\0':
1505 goto fini;
1506
1507 case ',':
1508 ++input_line_pointer;
1509 if (saw_comma || !saw_arg)
1510 goto err;
1511 saw_comma = 1;
1512 break;
1513
1514 case '(':
1515 {
1516 char *hold = input_line_pointer++;
1517
1518 /* First try for parenthesized register ... */
1519 expression (tok);
1520 if (*input_line_pointer == ')' && tok->X_op == O_register)
1521 {
1522 tok->X_op = (saw_comma ? O_cpregister : O_pregister);
1523 saw_comma = 0;
1524 saw_arg = 1;
1525 ++input_line_pointer;
1526 ++tok;
1527 break;
1528 }
1529
1530 /* ... then fall through to plain expression */
1531 input_line_pointer = hold;
1532 }
1533
1534 default:
1535 if (saw_arg && !saw_comma)
1536 goto err;
1537 expression (tok);
1538 if (tok->X_op == O_illegal || tok->X_op == O_absent)
1539 goto err;
1540
1541 saw_comma = 0;
1542 saw_arg = 1;
1543 ++tok;
1544 break;
1545 }
1546 }
1547
1548 fini:
1549 if (saw_comma)
1550 goto err;
1551 input_line_pointer = old_input_line_pointer;
1552 return ntok - (end_tok - tok);
1553
1554 err:
1555 input_line_pointer = old_input_line_pointer;
1556 return -1;
1557 }
1558
1559 /* Search forward through all variants of an opcode looking for a
1560 syntax match. */
1561
1562 static const struct alpha_opcode *
1563 find_opcode_match(first_opcode, tok, pntok, pcpumatch)
1564 const struct alpha_opcode *first_opcode;
1565 const expressionS *tok;
1566 int *pntok;
1567 int *pcpumatch;
1568 {
1569 const struct alpha_opcode *opcode = first_opcode;
1570 int ntok = *pntok;
1571 int got_cpu_match = 0;
1572
1573 do
1574 {
1575 const unsigned char *opidx;
1576 int tokidx = 0;
1577
1578 /* Don't match opcodes that don't exist on this architecture */
1579 if (!(opcode->flags & alpha_target))
1580 goto match_failed;
1581
1582 got_cpu_match = 1;
1583
1584 for (opidx = opcode->operands; *opidx; ++opidx)
1585 {
1586 const struct alpha_operand *operand = &alpha_operands[*opidx];
1587
1588 /* only take input from real operands */
1589 if (operand->flags & AXP_OPERAND_FAKE)
1590 continue;
1591
1592 /* when we expect input, make sure we have it */
1593 if (tokidx >= ntok)
1594 {
1595 if ((operand->flags & AXP_OPERAND_OPTIONAL_MASK) == 0)
1596 goto match_failed;
1597 continue;
1598 }
1599
1600 /* match operand type with expression type */
1601 switch (operand->flags & AXP_OPERAND_TYPECHECK_MASK)
1602 {
1603 case AXP_OPERAND_IR:
1604 if (tok[tokidx].X_op != O_register
1605 || !is_ir_num(tok[tokidx].X_add_number))
1606 goto match_failed;
1607 break;
1608 case AXP_OPERAND_FPR:
1609 if (tok[tokidx].X_op != O_register
1610 || !is_fpr_num(tok[tokidx].X_add_number))
1611 goto match_failed;
1612 break;
1613 case AXP_OPERAND_IR|AXP_OPERAND_PARENS:
1614 if (tok[tokidx].X_op != O_pregister
1615 || !is_ir_num(tok[tokidx].X_add_number))
1616 goto match_failed;
1617 break;
1618 case AXP_OPERAND_IR|AXP_OPERAND_PARENS|AXP_OPERAND_COMMA:
1619 if (tok[tokidx].X_op != O_cpregister
1620 || !is_ir_num(tok[tokidx].X_add_number))
1621 goto match_failed;
1622 break;
1623
1624 case AXP_OPERAND_RELATIVE:
1625 case AXP_OPERAND_SIGNED:
1626 case AXP_OPERAND_UNSIGNED:
1627 switch (tok[tokidx].X_op)
1628 {
1629 case O_illegal:
1630 case O_absent:
1631 case O_register:
1632 case O_pregister:
1633 case O_cpregister:
1634 goto match_failed;
1635 }
1636 break;
1637
1638 default:
1639 /* everything else should have been fake */
1640 abort();
1641 }
1642 ++tokidx;
1643 }
1644
1645 /* possible match -- did we use all of our input? */
1646 if (tokidx == ntok)
1647 {
1648 *pntok = ntok;
1649 return opcode;
1650 }
1651
1652 match_failed:;
1653 }
1654 while (++opcode-alpha_opcodes < alpha_num_opcodes
1655 && !strcmp(opcode->name, first_opcode->name));
1656
1657 if (*pcpumatch)
1658 *pcpumatch = got_cpu_match;
1659
1660 return NULL;
1661 }
1662
1663 /* Search forward through all variants of a macro looking for a syntax
1664 match. */
1665
1666 static const struct alpha_macro *
1667 find_macro_match(first_macro, tok, pntok)
1668 const struct alpha_macro *first_macro;
1669 const expressionS *tok;
1670 int *pntok;
1671 {
1672 const struct alpha_macro *macro = first_macro;
1673 int ntok = *pntok;
1674
1675 do
1676 {
1677 const enum alpha_macro_arg *arg = macro->argsets;
1678 int tokidx = 0;
1679
1680 while (*arg)
1681 {
1682 switch (*arg)
1683 {
1684 case MACRO_EOA:
1685 if (tokidx == ntok)
1686 return macro;
1687 else
1688 tokidx = 0;
1689 break;
1690
1691 case MACRO_IR:
1692 if (tokidx >= ntok || tok[tokidx].X_op != O_register
1693 || !is_ir_num(tok[tokidx].X_add_number))
1694 goto match_failed;
1695 ++tokidx;
1696 break;
1697 case MACRO_PIR:
1698 if (tokidx >= ntok || tok[tokidx].X_op != O_pregister
1699 || !is_ir_num(tok[tokidx].X_add_number))
1700 goto match_failed;
1701 ++tokidx;
1702 break;
1703 case MACRO_CPIR:
1704 if (tokidx >= ntok || tok[tokidx].X_op != O_cpregister
1705 || !is_ir_num(tok[tokidx].X_add_number))
1706 goto match_failed;
1707 ++tokidx;
1708 break;
1709 case MACRO_FPR:
1710 if (tokidx >= ntok || tok[tokidx].X_op != O_register
1711 || !is_fpr_num(tok[tokidx].X_add_number))
1712 goto match_failed;
1713 ++tokidx;
1714 break;
1715
1716 case MACRO_EXP:
1717 if (tokidx >= ntok)
1718 goto match_failed;
1719 switch (tok[tokidx].X_op)
1720 {
1721 case O_illegal:
1722 case O_absent:
1723 case O_register:
1724 case O_pregister:
1725 case O_cpregister:
1726 goto match_failed;
1727 }
1728 ++tokidx;
1729 break;
1730
1731 match_failed:
1732 while (*arg != MACRO_EOA)
1733 ++arg;
1734 tokidx = 0;
1735 break;
1736 }
1737 ++arg;
1738 }
1739 }
1740 while (++macro-alpha_macros < alpha_num_macros
1741 && !strcmp(macro->name, first_macro->name));
1742
1743 return NULL;
1744 }
1745
1746 /* Insert an operand value into an instruction. */
1747
1748 static unsigned
1749 insert_operand(insn, operand, val, file, line)
1750 unsigned insn;
1751 const struct alpha_operand *operand;
1752 offsetT val;
1753 char *file;
1754 unsigned line;
1755 {
1756 if (operand->bits != 32 && !(operand->flags & AXP_OPERAND_NOOVERFLOW))
1757 {
1758 offsetT min, max;
1759
1760 if (operand->flags & AXP_OPERAND_SIGNED)
1761 {
1762 max = (1 << (operand->bits - 1)) - 1;
1763 min = -(1 << (operand->bits - 1));
1764 }
1765 else
1766 {
1767 max = (1 << operand->bits) - 1;
1768 min = 0;
1769 }
1770
1771 if (val < min || val > max)
1772 {
1773 const char *err =
1774 _("operand out of range (%s not between %d and %d)");
1775 char buf[sizeof (val) * 3 + 2];
1776
1777 sprint_value(buf, val);
1778 if (file)
1779 as_warn_where(file, line, err, buf, min, max);
1780 else
1781 as_warn(err, buf, min, max);
1782 }
1783 }
1784
1785 if (operand->insert)
1786 {
1787 const char *errmsg = NULL;
1788
1789 insn = (*operand->insert) (insn, val, &errmsg);
1790 if (errmsg)
1791 as_warn (errmsg);
1792 }
1793 else
1794 insn |= ((val & ((1 << operand->bits) - 1)) << operand->shift);
1795
1796 return insn;
1797 }
1798
1799 /*
1800 * Turn an opcode description and a set of arguments into
1801 * an instruction and a fixup.
1802 */
1803
1804 static void
1805 assemble_insn(opcode, tok, ntok, insn)
1806 const struct alpha_opcode *opcode;
1807 const expressionS *tok;
1808 int ntok;
1809 struct alpha_insn *insn;
1810 {
1811 const unsigned char *argidx;
1812 unsigned image;
1813 int tokidx = 0;
1814
1815 memset (insn, 0, sizeof (*insn));
1816 image = opcode->opcode;
1817
1818 for (argidx = opcode->operands; *argidx; ++argidx)
1819 {
1820 const struct alpha_operand *operand = &alpha_operands[*argidx];
1821 const expressionS *t;
1822
1823 if (operand->flags & AXP_OPERAND_FAKE)
1824 {
1825 /* fake operands take no value and generate no fixup */
1826 image = insert_operand(image, operand, 0, NULL, 0);
1827 continue;
1828 }
1829
1830 if (tokidx >= ntok)
1831 {
1832 switch (operand->flags & AXP_OPERAND_OPTIONAL_MASK)
1833 {
1834 case AXP_OPERAND_DEFAULT_FIRST:
1835 t = &tok[0];
1836 break;
1837 case AXP_OPERAND_DEFAULT_SECOND:
1838 t = &tok[1];
1839 break;
1840 case AXP_OPERAND_DEFAULT_ZERO:
1841 {
1842 static const expressionS zero_exp = { 0, 0, 0, O_constant, 1 };
1843 t = &zero_exp;
1844 }
1845 break;
1846 default:
1847 abort();
1848 }
1849 }
1850 else
1851 t = &tok[tokidx++];
1852
1853 switch (t->X_op)
1854 {
1855 case O_register:
1856 case O_pregister:
1857 case O_cpregister:
1858 image = insert_operand(image, operand, regno(t->X_add_number),
1859 NULL, 0);
1860 break;
1861
1862 case O_constant:
1863 image = insert_operand(image, operand, t->X_add_number, NULL, 0);
1864 break;
1865
1866 default:
1867 {
1868 struct alpha_fixup *fixup;
1869
1870 if (insn->nfixups >= MAX_INSN_FIXUPS)
1871 as_fatal(_("too many fixups"));
1872
1873 fixup = &insn->fixups[insn->nfixups++];
1874
1875 fixup->exp = *t;
1876 fixup->reloc = operand->default_reloc;
1877 }
1878 break;
1879 }
1880 }
1881
1882 insn->insn = image;
1883 }
1884
1885 /*
1886 * Actually output an instruction with its fixup.
1887 */
1888
1889 static void
1890 emit_insn (insn)
1891 struct alpha_insn *insn;
1892 {
1893 char *f;
1894 int i;
1895
1896 /* Take care of alignment duties */
1897 if (alpha_auto_align_on && alpha_current_align < 2)
1898 alpha_align (2, (char *) NULL, alpha_insn_label, 0);
1899 if (alpha_current_align > 2)
1900 alpha_current_align = 2;
1901 alpha_insn_label = NULL;
1902
1903 /* Write out the instruction. */
1904 f = frag_more (4);
1905 md_number_to_chars (f, insn->insn, 4);
1906
1907 /* Apply the fixups in order */
1908 for (i = 0; i < insn->nfixups; ++i)
1909 {
1910 struct alpha_fixup *fixup = &insn->fixups[i];
1911 int size, pcrel;
1912 fixS *fixP;
1913
1914 /* Some fixups are only used internally and so have no howto */
1915 if ((int)fixup->reloc < 0)
1916 size = 4, pcrel = 0;
1917 #ifdef OBJ_ELF
1918 /* These relocation types are only used internally. */
1919 else if (fixup->reloc == BFD_RELOC_ALPHA_GPDISP_HI16
1920 || fixup->reloc == BFD_RELOC_ALPHA_GPDISP_LO16)
1921 {
1922 size = 2, pcrel = 0;
1923 }
1924 #endif
1925 else
1926 {
1927 reloc_howto_type *reloc_howto
1928 = bfd_reloc_type_lookup (stdoutput, fixup->reloc);
1929 assert (reloc_howto);
1930
1931 size = bfd_get_reloc_size (reloc_howto);
1932 pcrel = reloc_howto->pc_relative;
1933 }
1934 assert (size >= 1 && size <= 4);
1935
1936 fixP = fix_new_exp (frag_now, f - frag_now->fr_literal, size,
1937 &fixup->exp, pcrel, fixup->reloc);
1938
1939 /* Turn off complaints that the addend is too large for some fixups */
1940 switch (fixup->reloc)
1941 {
1942 case BFD_RELOC_ALPHA_GPDISP_LO16:
1943 #ifdef OBJ_ECOFF
1944 case BFD_RELOC_ALPHA_LITERAL:
1945 #endif
1946 #ifdef OBJ_ELF
1947 case BFD_RELOC_ALPHA_ELF_LITERAL:
1948 #endif
1949 case BFD_RELOC_GPREL32:
1950 fixP->fx_no_overflow = 1;
1951 break;
1952 default:
1953 break;
1954 }
1955 }
1956 }
1957
1958 /* Given an opcode name and a pre-tokenized set of arguments, assemble
1959 the insn, but do not emit it.
1960
1961 Note that this implies no macros allowed, since we can't store more
1962 than one insn in an insn structure. */
1963
1964 static void
1965 assemble_tokens_to_insn(opname, tok, ntok, insn)
1966 const char *opname;
1967 const expressionS *tok;
1968 int ntok;
1969 struct alpha_insn *insn;
1970 {
1971 const struct alpha_opcode *opcode;
1972
1973 /* search opcodes */
1974 opcode = (const struct alpha_opcode *) hash_find (alpha_opcode_hash, opname);
1975 if (opcode)
1976 {
1977 int cpumatch;
1978 opcode = find_opcode_match (opcode, tok, &ntok, &cpumatch);
1979 if (opcode)
1980 {
1981 assemble_insn (opcode, tok, ntok, insn);
1982 return;
1983 }
1984 else if (cpumatch)
1985 as_bad (_("inappropriate arguments for opcode `%s'"), opname);
1986 else
1987 as_bad (_("opcode `%s' not supported for target %s"), opname,
1988 alpha_target_name);
1989 }
1990 else
1991 as_bad (_("unknown opcode `%s'"), opname);
1992 }
1993
1994 /* Given an opcode name and a pre-tokenized set of arguments, take the
1995 opcode all the way through emission. */
1996
1997 static void
1998 assemble_tokens (opname, tok, ntok, local_macros_on)
1999 const char *opname;
2000 const expressionS *tok;
2001 int ntok;
2002 int local_macros_on;
2003 {
2004 int found_something = 0;
2005 const struct alpha_opcode *opcode;
2006 const struct alpha_macro *macro;
2007 int cpumatch = 1;
2008
2009 /* search macros */
2010 if (local_macros_on)
2011 {
2012 macro = ((const struct alpha_macro *)
2013 hash_find (alpha_macro_hash, opname));
2014 if (macro)
2015 {
2016 found_something = 1;
2017 macro = find_macro_match (macro, tok, &ntok);
2018 if (macro)
2019 {
2020 (*macro->emit) (tok, ntok, macro->arg);
2021 return;
2022 }
2023 }
2024 }
2025
2026 /* search opcodes */
2027 opcode = (const struct alpha_opcode *) hash_find (alpha_opcode_hash, opname);
2028 if (opcode)
2029 {
2030 found_something = 1;
2031 opcode = find_opcode_match (opcode, tok, &ntok, &cpumatch);
2032 if (opcode)
2033 {
2034 struct alpha_insn insn;
2035 assemble_insn (opcode, tok, ntok, &insn);
2036 emit_insn (&insn);
2037 return;
2038 }
2039 }
2040
2041 if (found_something)
2042 if (cpumatch)
2043 as_bad (_("inappropriate arguments for opcode `%s'"), opname);
2044 else
2045 as_bad (_("opcode `%s' not supported for target %s"), opname,
2046 alpha_target_name);
2047 else
2048 as_bad (_("unknown opcode `%s'"), opname);
2049 }
2050
2051 \f
2052 /* Some instruction sets indexed by lg(size) */
2053 static const char * const sextX_op[] = { "sextb", "sextw", "sextl", NULL };
2054 static const char * const insXl_op[] = { "insbl", "inswl", "insll", "insql" };
2055 static const char * const insXh_op[] = { NULL, "inswh", "inslh", "insqh" };
2056 static const char * const extXl_op[] = { "extbl", "extwl", "extll", "extql" };
2057 static const char * const extXh_op[] = { NULL, "extwh", "extlh", "extqh" };
2058 static const char * const mskXl_op[] = { "mskbl", "mskwl", "mskll", "mskql" };
2059 static const char * const mskXh_op[] = { NULL, "mskwh", "msklh", "mskqh" };
2060 static const char * const stX_op[] = { "stb", "stw", "stl", "stq" };
2061 static const char * const ldX_op[] = { "ldb", "ldw", "ldll", "ldq" };
2062 static const char * const ldXu_op[] = { "ldbu", "ldwu", NULL, NULL };
2063
2064 /* Implement the ldgp macro. */
2065
2066 static void
2067 emit_ldgp (tok, ntok, unused)
2068 const expressionS *tok;
2069 int ntok;
2070 const PTR unused;
2071 {
2072 #ifdef OBJ_AOUT
2073 FIXME
2074 #endif
2075 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
2076 /* from "ldgp r1,n(r2)", generate "ldah r1,X(R2); lda r1,Y(r1)"
2077 with appropriate constants and relocations. */
2078 struct alpha_insn insn;
2079 expressionS newtok[3];
2080 expressionS addend;
2081
2082 /* We're going to need this symbol in md_apply_fix(). */
2083 (void) section_symbol (absolute_section);
2084
2085 #ifdef OBJ_ECOFF
2086 if (regno (tok[2].X_add_number) == AXP_REG_PV)
2087 ecoff_set_gp_prolog_size (0);
2088 #endif
2089
2090 newtok[0] = tok[0];
2091 set_tok_const (newtok[1], 0);
2092 newtok[2] = tok[2];
2093
2094 assemble_tokens_to_insn ("ldah", newtok, 3, &insn);
2095
2096 addend = tok[1];
2097
2098 #ifdef OBJ_ECOFF
2099 assert (addend.X_op == O_constant);
2100 addend.X_op = O_symbol;
2101 addend.X_add_symbol = alpha_gp_symbol;
2102 #endif
2103
2104 insn.nfixups = 1;
2105 insn.fixups[0].exp = addend;
2106 insn.fixups[0].reloc = BFD_RELOC_ALPHA_GPDISP_HI16;
2107
2108 emit_insn (&insn);
2109
2110 set_tok_preg (newtok[2], tok[0].X_add_number);
2111
2112 assemble_tokens_to_insn ("lda", newtok, 3, &insn);
2113
2114 #ifdef OBJ_ECOFF
2115 addend.X_add_number += 4;
2116 #endif
2117
2118 insn.nfixups = 1;
2119 insn.fixups[0].exp = addend;
2120 insn.fixups[0].reloc = BFD_RELOC_ALPHA_GPDISP_LO16;
2121
2122 emit_insn (&insn);
2123 #endif /* OBJ_ECOFF || OBJ_ELF */
2124 }
2125
2126 #ifdef OBJ_EVAX
2127
2128 /* Add symbol+addend to link pool.
2129 Return offset from basesym to entry in link pool.
2130
2131 Add new fixup only if offset isn't 16bit. */
2132
2133 valueT
2134 add_to_link_pool (basesym, sym, addend)
2135 symbolS *basesym;
2136 symbolS *sym;
2137 offsetT addend;
2138 {
2139 segT current_section = now_seg;
2140 int current_subsec = now_subseg;
2141 valueT offset;
2142 bfd_reloc_code_real_type reloc_type;
2143 char *p;
2144 segment_info_type *seginfo = seg_info (alpha_link_section);
2145 fixS *fixp;
2146
2147 offset = -basesym->sy_obj;
2148
2149 /* @@ This assumes all entries in a given section will be of the same
2150 size... Probably correct, but unwise to rely on. */
2151 /* This must always be called with the same subsegment. */
2152
2153 if (seginfo->frchainP)
2154 for (fixp = seginfo->frchainP->fix_root;
2155 fixp != (fixS *) NULL;
2156 fixp = fixp->fx_next, offset += 8)
2157 {
2158 if (fixp->fx_addsy == sym && fixp->fx_offset == addend)
2159 {
2160 if (range_signed_16 (offset))
2161 {
2162 return offset;
2163 }
2164 }
2165 }
2166
2167 /* Not found in 16bit signed range. */
2168
2169 subseg_set (alpha_link_section, 0);
2170 p = frag_more (8);
2171 memset (p, 0, 8);
2172
2173 fix_new (frag_now, p - frag_now->fr_literal, 8, sym, addend, 0,
2174 BFD_RELOC_64);
2175
2176 subseg_set (current_section, current_subsec);
2177 seginfo->literal_pool_size += 8;
2178 return offset;
2179 }
2180
2181 #endif /* OBJ_EVAX */
2182
2183 /* Load a (partial) expression into a target register.
2184
2185 If poffset is not null, after the call it will either contain
2186 O_constant 0, or a 16-bit offset appropriate for any MEM format
2187 instruction. In addition, pbasereg will be modified to point to
2188 the base register to use in that MEM format instruction.
2189
2190 In any case, *pbasereg should contain a base register to add to the
2191 expression. This will normally be either AXP_REG_ZERO or
2192 alpha_gp_register. Symbol addresses will always be loaded via $gp,
2193 so "foo($0)" is interpreted as adding the address of foo to $0;
2194 i.e. "ldq $targ, LIT($gp); addq $targ, $0, $targ". Odd, perhaps,
2195 but this is what OSF/1 does.
2196
2197 Finally, the return value is true if the calling macro may emit a
2198 LITUSE reloc if otherwise appropriate. */
2199
2200 static int
2201 load_expression (targreg, exp, pbasereg, poffset)
2202 int targreg;
2203 const expressionS *exp;
2204 int *pbasereg;
2205 expressionS *poffset;
2206 {
2207 int emit_lituse = 0;
2208 offsetT addend = exp->X_add_number;
2209 int basereg = *pbasereg;
2210 struct alpha_insn insn;
2211 expressionS newtok[3];
2212
2213 switch (exp->X_op)
2214 {
2215 case O_symbol:
2216 {
2217 #ifdef OBJ_ECOFF
2218 offsetT lit;
2219
2220 /* attempt to reduce .lit load by splitting the offset from
2221 its symbol when possible, but don't create a situation in
2222 which we'd fail. */
2223 if (!range_signed_32 (addend) &&
2224 (alpha_noat_on || targreg == AXP_REG_AT))
2225 {
2226 lit = add_to_literal_pool (exp->X_add_symbol, addend,
2227 alpha_lita_section, 8);
2228 addend = 0;
2229 }
2230 else
2231 {
2232 lit = add_to_literal_pool (exp->X_add_symbol, 0,
2233 alpha_lita_section, 8);
2234 }
2235
2236 if (lit >= 0x8000)
2237 as_fatal (_("overflow in literal (.lita) table"));
2238
2239 /* emit "ldq r, lit(gp)" */
2240
2241 if (basereg != alpha_gp_register && targreg == basereg)
2242 {
2243 if (alpha_noat_on)
2244 as_bad (_("macro requires $at register while noat in effect"));
2245 if (targreg == AXP_REG_AT)
2246 as_bad (_("macro requires $at while $at in use"));
2247
2248 set_tok_reg (newtok[0], AXP_REG_AT);
2249 }
2250 else
2251 set_tok_reg (newtok[0], targreg);
2252 set_tok_sym (newtok[1], alpha_lita_symbol, lit);
2253 set_tok_preg (newtok[2], alpha_gp_register);
2254
2255 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
2256
2257 assert (insn.nfixups == 1);
2258 insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITERAL;
2259 #endif /* OBJ_ECOFF */
2260 #ifdef OBJ_ELF
2261 /* emit "ldq r, gotoff(gp)" */
2262
2263 if (basereg != alpha_gp_register && targreg == basereg)
2264 {
2265 if (alpha_noat_on)
2266 as_bad (_("macro requires $at register while noat in effect"));
2267 if (targreg == AXP_REG_AT)
2268 as_bad (_("macro requires $at while $at in use"));
2269
2270 set_tok_reg (newtok[0], AXP_REG_AT);
2271 }
2272 else
2273 set_tok_reg (newtok[0], targreg);
2274
2275 /* XXX: Disable this .got minimizing optimization so that we can get
2276 better instruction offset knowledge in the compiler. This happens
2277 very infrequently anyway. */
2278 if (1 || !range_signed_32 (addend)
2279 && (alpha_noat_on || targreg == AXP_REG_AT))
2280 {
2281 newtok[1] = *exp;
2282 addend = 0;
2283 }
2284 else
2285 {
2286 set_tok_sym (newtok[1], exp->X_add_symbol, 0);
2287 }
2288
2289 set_tok_preg (newtok[2], alpha_gp_register);
2290
2291 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
2292
2293 assert (insn.nfixups == 1);
2294 insn.fixups[0].reloc = BFD_RELOC_ALPHA_ELF_LITERAL;
2295 #endif /* OBJ_ELF */
2296 #ifdef OBJ_EVAX
2297 offsetT link;
2298
2299 /* Find symbol or symbol pointer in link section. */
2300
2301 if (exp->X_add_symbol == alpha_evax_proc.symbol)
2302 {
2303 if (range_signed_16 (addend))
2304 {
2305 set_tok_reg (newtok[0], targreg);
2306 set_tok_const (newtok[1], addend);
2307 set_tok_preg (newtok[2], basereg);
2308 assemble_tokens_to_insn ("lda", newtok, 3, &insn);
2309 addend = 0;
2310 }
2311 else
2312 {
2313 set_tok_reg (newtok[0], targreg);
2314 set_tok_const (newtok[1], 0);
2315 set_tok_preg (newtok[2], basereg);
2316 assemble_tokens_to_insn ("lda", newtok, 3, &insn);
2317 }
2318 }
2319 else
2320 {
2321 if (!range_signed_32 (addend))
2322 {
2323 link = add_to_link_pool (alpha_evax_proc.symbol,
2324 exp->X_add_symbol, addend);
2325 addend = 0;
2326 }
2327 else
2328 {
2329 link = add_to_link_pool (alpha_evax_proc.symbol,
2330 exp->X_add_symbol, 0);
2331 }
2332 set_tok_reg (newtok[0], targreg);
2333 set_tok_const (newtok[1], link);
2334 set_tok_preg (newtok[2], basereg);
2335 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
2336 }
2337 #endif /* OBJ_EVAX */
2338
2339 emit_insn(&insn);
2340
2341 #ifndef OBJ_EVAX
2342 emit_lituse = 1;
2343
2344 if (basereg != alpha_gp_register && basereg != AXP_REG_ZERO)
2345 {
2346 /* emit "addq r, base, r" */
2347
2348 set_tok_reg (newtok[1], basereg);
2349 set_tok_reg (newtok[2], targreg);
2350 assemble_tokens ("addq", newtok, 3, 0);
2351 }
2352 #endif
2353
2354 basereg = targreg;
2355 }
2356 break;
2357
2358 case O_constant:
2359 break;
2360
2361 case O_subtract:
2362 /* Assume that this difference expression will be resolved to an
2363 absolute value and that that value will fit in 16 bits. */
2364
2365 set_tok_reg (newtok[0], targreg);
2366 newtok[1] = *exp;
2367 set_tok_preg (newtok[2], basereg);
2368 assemble_tokens ("lda", newtok, 3, 0);
2369
2370 if (poffset)
2371 set_tok_const (*poffset, 0);
2372 return 0;
2373
2374 case O_big:
2375 if (exp->X_add_number > 0)
2376 as_bad (_("bignum invalid; zero assumed"));
2377 else
2378 as_bad (_("floating point number invalid; zero assumed"));
2379 addend = 0;
2380 break;
2381
2382 default:
2383 abort();
2384 }
2385
2386 if (!range_signed_32 (addend))
2387 {
2388 offsetT lit;
2389
2390 /* for 64-bit addends, just put it in the literal pool */
2391
2392 #ifdef OBJ_EVAX
2393 /* emit "ldq targreg, lit(basereg)" */
2394 lit = add_to_link_pool (alpha_evax_proc.symbol,
2395 section_symbol (absolute_section), addend);
2396 set_tok_reg (newtok[0], targreg);
2397 set_tok_const (newtok[1], lit);
2398 set_tok_preg (newtok[2], alpha_gp_register);
2399 assemble_tokens ("ldq", newtok, 3, 0);
2400 #else
2401
2402 if (alpha_lit8_section == NULL)
2403 {
2404 create_literal_section (".lit8",
2405 &alpha_lit8_section,
2406 &alpha_lit8_symbol);
2407
2408 #ifdef OBJ_ECOFF
2409 alpha_lit8_literal = add_to_literal_pool (alpha_lit8_symbol, 0x8000,
2410 alpha_lita_section, 8);
2411 if (alpha_lit8_literal >= 0x8000)
2412 as_fatal (_("overflow in literal (.lita) table"));
2413 #endif
2414 }
2415
2416 lit = add_to_literal_pool (NULL, addend, alpha_lit8_section, 8) - 0x8000;
2417 if (lit >= 0x8000)
2418 as_fatal (_("overflow in literal (.lit8) table"));
2419
2420 /* emit "lda litreg, .lit8+0x8000" */
2421
2422 if (targreg == basereg)
2423 {
2424 if (alpha_noat_on)
2425 as_bad (_("macro requires $at register while noat in effect"));
2426 if (targreg == AXP_REG_AT)
2427 as_bad (_("macro requires $at while $at in use"));
2428
2429 set_tok_reg (newtok[0], AXP_REG_AT);
2430 }
2431 else
2432 set_tok_reg (newtok[0], targreg);
2433 #ifdef OBJ_ECOFF
2434 set_tok_sym (newtok[1], alpha_lita_symbol, alpha_lit8_literal);
2435 #endif
2436 #ifdef OBJ_ELF
2437 set_tok_sym (newtok[1], alpha_lit8_symbol, 0x8000);
2438 #endif
2439 set_tok_preg (newtok[2], alpha_gp_register);
2440
2441 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
2442
2443 assert (insn.nfixups == 1);
2444 #ifdef OBJ_ECOFF
2445 insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITERAL;
2446 #endif
2447 #ifdef OBJ_ELF
2448 insn.fixups[0].reloc = BFD_RELOC_ALPHA_ELF_LITERAL;
2449 #endif
2450
2451 emit_insn (&insn);
2452
2453 /* emit "ldq litreg, lit(litreg)" */
2454
2455 set_tok_const (newtok[1], lit);
2456 set_tok_preg (newtok[2], newtok[0].X_add_number);
2457
2458 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
2459
2460 assert (insn.nfixups < MAX_INSN_FIXUPS);
2461 if (insn.nfixups > 0)
2462 {
2463 memmove (&insn.fixups[1], &insn.fixups[0],
2464 sizeof(struct alpha_fixup) * insn.nfixups);
2465 }
2466 insn.nfixups++;
2467 insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITUSE;
2468 insn.fixups[0].exp.X_op = O_constant;
2469 insn.fixups[0].exp.X_add_number = 1;
2470 emit_lituse = 0;
2471
2472 emit_insn (&insn);
2473
2474 /* emit "addq litreg, base, target" */
2475
2476 if (basereg != AXP_REG_ZERO)
2477 {
2478 set_tok_reg (newtok[1], basereg);
2479 set_tok_reg (newtok[2], targreg);
2480 assemble_tokens ("addq", newtok, 3, 0);
2481 }
2482 #endif /* !OBJ_EVAX */
2483
2484 if (poffset)
2485 set_tok_const (*poffset, 0);
2486 *pbasereg = targreg;
2487 }
2488 else
2489 {
2490 offsetT low, high, extra, tmp;
2491
2492 /* for 32-bit operands, break up the addend */
2493
2494 low = sign_extend_16 (addend);
2495 tmp = addend - low;
2496 high = sign_extend_16 (tmp >> 16);
2497
2498 if (tmp - (high << 16))
2499 {
2500 extra = 0x4000;
2501 tmp -= 0x40000000;
2502 high = sign_extend_16 (tmp >> 16);
2503 }
2504 else
2505 extra = 0;
2506
2507 set_tok_reg (newtok[0], targreg);
2508 set_tok_preg (newtok[2], basereg);
2509
2510 if (extra)
2511 {
2512 /* emit "ldah r, extra(r) */
2513 set_tok_const (newtok[1], extra);
2514 assemble_tokens ("ldah", newtok, 3, 0);
2515 set_tok_preg (newtok[2], basereg = targreg);
2516 }
2517
2518 if (high)
2519 {
2520 /* emit "ldah r, high(r) */
2521 set_tok_const (newtok[1], high);
2522 assemble_tokens ("ldah", newtok, 3, 0);
2523 basereg = targreg;
2524 set_tok_preg (newtok[2], basereg);
2525 }
2526
2527 if ((low && !poffset) || (!poffset && basereg != targreg))
2528 {
2529 /* emit "lda r, low(base)" */
2530 set_tok_const (newtok[1], low);
2531 assemble_tokens ("lda", newtok, 3, 0);
2532 basereg = targreg;
2533 low = 0;
2534 }
2535
2536 if (poffset)
2537 set_tok_const (*poffset, low);
2538 *pbasereg = basereg;
2539 }
2540
2541 return emit_lituse;
2542 }
2543
2544 /* The lda macro differs from the lda instruction in that it handles
2545 most simple expressions, particualrly symbol address loads and
2546 large constants. */
2547
2548 static void
2549 emit_lda (tok, ntok, unused)
2550 const expressionS *tok;
2551 int ntok;
2552 const PTR unused;
2553 {
2554 int basereg;
2555
2556 if (ntok == 2)
2557 basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
2558 else
2559 basereg = tok[2].X_add_number;
2560
2561 (void) load_expression (tok[0].X_add_number, &tok[1], &basereg, NULL);
2562 }
2563
2564 /* The ldah macro differs from the ldah instruction in that it has $31
2565 as an implied base register. */
2566
2567 static void
2568 emit_ldah (tok, ntok, unused)
2569 const expressionS *tok;
2570 int ntok;
2571 const PTR unused;
2572 {
2573 expressionS newtok[3];
2574
2575 newtok[0] = tok[0];
2576 newtok[1] = tok[1];
2577 set_tok_preg (newtok[2], AXP_REG_ZERO);
2578
2579 assemble_tokens ("ldah", newtok, 3, 0);
2580 }
2581
2582 /* Handle all "simple" integer register loads -- ldq, ldq_l, ldq_u,
2583 etc. They differ from the real instructions in that they do simple
2584 expressions like the lda macro. */
2585
2586 static void
2587 emit_ir_load (tok, ntok, opname)
2588 const expressionS *tok;
2589 int ntok;
2590 const PTR opname;
2591 {
2592 int basereg, lituse;
2593 expressionS newtok[3];
2594 struct alpha_insn insn;
2595
2596 if (ntok == 2)
2597 basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
2598 else
2599 basereg = tok[2].X_add_number;
2600
2601 lituse = load_expression (tok[0].X_add_number, &tok[1], &basereg,
2602 &newtok[1]);
2603
2604 newtok[0] = tok[0];
2605 set_tok_preg (newtok[2], basereg);
2606
2607 assemble_tokens_to_insn ((const char *)opname, newtok, 3, &insn);
2608
2609 if (lituse)
2610 {
2611 assert (insn.nfixups < MAX_INSN_FIXUPS);
2612 if (insn.nfixups > 0)
2613 {
2614 memmove (&insn.fixups[1], &insn.fixups[0],
2615 sizeof(struct alpha_fixup) * insn.nfixups);
2616 }
2617 insn.nfixups++;
2618 insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITUSE;
2619 insn.fixups[0].exp.X_op = O_constant;
2620 insn.fixups[0].exp.X_add_number = 1;
2621 }
2622
2623 emit_insn (&insn);
2624 }
2625
2626 /* Handle fp register loads, and both integer and fp register stores.
2627 Again, we handle simple expressions. */
2628
2629 static void
2630 emit_loadstore (tok, ntok, opname)
2631 const expressionS *tok;
2632 int ntok;
2633 const PTR opname;
2634 {
2635 int basereg, lituse;
2636 expressionS newtok[3];
2637 struct alpha_insn insn;
2638
2639 if (ntok == 2)
2640 basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
2641 else
2642 basereg = tok[2].X_add_number;
2643
2644 if (tok[1].X_op != O_constant || !range_signed_16(tok[1].X_add_number))
2645 {
2646 if (alpha_noat_on)
2647 as_bad (_("macro requires $at register while noat in effect"));
2648
2649 lituse = load_expression (AXP_REG_AT, &tok[1], &basereg, &newtok[1]);
2650 }
2651 else
2652 {
2653 newtok[1] = tok[1];
2654 lituse = 0;
2655 }
2656
2657 newtok[0] = tok[0];
2658 set_tok_preg (newtok[2], basereg);
2659
2660 assemble_tokens_to_insn ((const char *)opname, newtok, 3, &insn);
2661
2662 if (lituse)
2663 {
2664 assert (insn.nfixups < MAX_INSN_FIXUPS);
2665 if (insn.nfixups > 0)
2666 {
2667 memmove (&insn.fixups[1], &insn.fixups[0],
2668 sizeof(struct alpha_fixup) * insn.nfixups);
2669 }
2670 insn.nfixups++;
2671 insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITUSE;
2672 insn.fixups[0].exp.X_op = O_constant;
2673 insn.fixups[0].exp.X_add_number = 1;
2674 }
2675
2676 emit_insn (&insn);
2677 }
2678
2679 /* Load a half-word or byte as an unsigned value. */
2680
2681 static void
2682 emit_ldXu (tok, ntok, vlgsize)
2683 const expressionS *tok;
2684 int ntok;
2685 const PTR vlgsize;
2686 {
2687 if (alpha_target & AXP_OPCODE_BWX)
2688 emit_ir_load (tok, ntok, ldXu_op[(long)vlgsize]);
2689 else
2690 {
2691 expressionS newtok[3];
2692
2693 if (alpha_noat_on)
2694 as_bad (_("macro requires $at register while noat in effect"));
2695
2696 /* emit "lda $at, exp" */
2697
2698 memcpy (newtok, tok, sizeof (expressionS) * ntok);
2699 newtok[0].X_add_number = AXP_REG_AT;
2700 assemble_tokens ("lda", newtok, ntok, 1);
2701
2702 /* emit "ldq_u targ, 0($at)" */
2703
2704 newtok[0] = tok[0];
2705 set_tok_const (newtok[1], 0);
2706 set_tok_preg (newtok[2], AXP_REG_AT);
2707 assemble_tokens ("ldq_u", newtok, 3, 1);
2708
2709 /* emit "extXl targ, $at, targ" */
2710
2711 set_tok_reg (newtok[1], AXP_REG_AT);
2712 newtok[2] = newtok[0];
2713 assemble_tokens (extXl_op[(long)vlgsize], newtok, 3, 1);
2714 }
2715 }
2716
2717 /* Load a half-word or byte as a signed value. */
2718
2719 static void
2720 emit_ldX (tok, ntok, vlgsize)
2721 const expressionS *tok;
2722 int ntok;
2723 const PTR vlgsize;
2724 {
2725 emit_ldXu (tok, ntok, vlgsize);
2726 assemble_tokens (sextX_op[(long)vlgsize], tok, 1, 1);
2727 }
2728
2729 /* Load an integral value from an unaligned address as an unsigned
2730 value. */
2731
2732 static void
2733 emit_uldXu (tok, ntok, vlgsize)
2734 const expressionS *tok;
2735 int ntok;
2736 const PTR vlgsize;
2737 {
2738 long lgsize = (long)vlgsize;
2739 expressionS newtok[3];
2740
2741 if (alpha_noat_on)
2742 as_bad (_("macro requires $at register while noat in effect"));
2743
2744 /* emit "lda $at, exp" */
2745
2746 memcpy (newtok, tok, sizeof (expressionS) * ntok);
2747 newtok[0].X_add_number = AXP_REG_AT;
2748 assemble_tokens ("lda", newtok, ntok, 1);
2749
2750 /* emit "ldq_u $t9, 0($at)" */
2751
2752 set_tok_reg (newtok[0], AXP_REG_T9);
2753 set_tok_const (newtok[1], 0);
2754 set_tok_preg (newtok[2], AXP_REG_AT);
2755 assemble_tokens ("ldq_u", newtok, 3, 1);
2756
2757 /* emit "ldq_u $t10, size-1($at)" */
2758
2759 set_tok_reg (newtok[0], AXP_REG_T10);
2760 set_tok_const (newtok[1], (1<<lgsize)-1);
2761 assemble_tokens ("ldq_u", newtok, 3, 1);
2762
2763 /* emit "extXl $t9, $at, $t9" */
2764
2765 set_tok_reg (newtok[0], AXP_REG_T9);
2766 set_tok_reg (newtok[1], AXP_REG_AT);
2767 set_tok_reg (newtok[2], AXP_REG_T9);
2768 assemble_tokens (extXl_op[lgsize], newtok, 3, 1);
2769
2770 /* emit "extXh $t10, $at, $t10" */
2771
2772 set_tok_reg (newtok[0], AXP_REG_T10);
2773 set_tok_reg (newtok[2], AXP_REG_T10);
2774 assemble_tokens (extXh_op[lgsize], newtok, 3, 1);
2775
2776 /* emit "or $t9, $t10, targ" */
2777
2778 set_tok_reg (newtok[0], AXP_REG_T9);
2779 set_tok_reg (newtok[1], AXP_REG_T10);
2780 newtok[2] = tok[0];
2781 assemble_tokens ("or", newtok, 3, 1);
2782 }
2783
2784 /* Load an integral value from an unaligned address as a signed value.
2785 Note that quads should get funneled to the unsigned load since we
2786 don't have to do the sign extension. */
2787
2788 static void
2789 emit_uldX (tok, ntok, vlgsize)
2790 const expressionS *tok;
2791 int ntok;
2792 const PTR vlgsize;
2793 {
2794 emit_uldXu (tok, ntok, vlgsize);
2795 assemble_tokens (sextX_op[(long)vlgsize], tok, 1, 1);
2796 }
2797
2798 /* Implement the ldil macro. */
2799
2800 static void
2801 emit_ldil (tok, ntok, unused)
2802 const expressionS *tok;
2803 int ntok;
2804 const PTR unused;
2805 {
2806 expressionS newtok[2];
2807
2808 memcpy (newtok, tok, sizeof(newtok));
2809 newtok[1].X_add_number = sign_extend_32 (tok[1].X_add_number);
2810
2811 assemble_tokens ("lda", newtok, ntok, 1);
2812 }
2813
2814 /* Store a half-word or byte. */
2815
2816 static void
2817 emit_stX (tok, ntok, vlgsize)
2818 const expressionS *tok;
2819 int ntok;
2820 const PTR vlgsize;
2821 {
2822 int lgsize = (int)(long)vlgsize;
2823
2824 if (alpha_target & AXP_OPCODE_BWX)
2825 emit_loadstore (tok, ntok, stX_op[lgsize]);
2826 else
2827 {
2828 expressionS newtok[3];
2829
2830 if (alpha_noat_on)
2831 as_bad(_("macro requires $at register while noat in effect"));
2832
2833 /* emit "lda $at, exp" */
2834
2835 memcpy (newtok, tok, sizeof (expressionS) * ntok);
2836 newtok[0].X_add_number = AXP_REG_AT;
2837 assemble_tokens ("lda", newtok, ntok, 1);
2838
2839 /* emit "ldq_u $t9, 0($at)" */
2840
2841 set_tok_reg (newtok[0], AXP_REG_T9);
2842 set_tok_const (newtok[1], 0);
2843 set_tok_preg (newtok[2], AXP_REG_AT);
2844 assemble_tokens ("ldq_u", newtok, 3, 1);
2845
2846 /* emit "insXl src, $at, $t10" */
2847
2848 newtok[0] = tok[0];
2849 set_tok_reg (newtok[1], AXP_REG_AT);
2850 set_tok_reg (newtok[2], AXP_REG_T10);
2851 assemble_tokens (insXl_op[lgsize], newtok, 3, 1);
2852
2853 /* emit "mskXl $t9, $at, $t9" */
2854
2855 set_tok_reg (newtok[0], AXP_REG_T9);
2856 newtok[2] = newtok[0];
2857 assemble_tokens (mskXl_op[lgsize], newtok, 3, 1);
2858
2859 /* emit "or $t9, $t10, $t9" */
2860
2861 set_tok_reg (newtok[1], AXP_REG_T10);
2862 assemble_tokens ("or", newtok, 3, 1);
2863
2864 /* emit "stq_u $t9, 0($at) */
2865
2866 set_tok_const (newtok[1], 0);
2867 set_tok_preg (newtok[2], AXP_REG_AT);
2868 assemble_tokens ("stq_u", newtok, 3, 1);
2869 }
2870 }
2871
2872 /* Store an integer to an unaligned address. */
2873
2874 static void
2875 emit_ustX (tok, ntok, vlgsize)
2876 const expressionS *tok;
2877 int ntok;
2878 const PTR vlgsize;
2879 {
2880 int lgsize = (int)(long)vlgsize;
2881 expressionS newtok[3];
2882
2883 /* emit "lda $at, exp" */
2884
2885 memcpy (newtok, tok, sizeof (expressionS) * ntok);
2886 newtok[0].X_add_number = AXP_REG_AT;
2887 assemble_tokens ("lda", newtok, ntok, 1);
2888
2889 /* emit "ldq_u $9, 0($at)" */
2890
2891 set_tok_reg (newtok[0], AXP_REG_T9);
2892 set_tok_const (newtok[1], 0);
2893 set_tok_preg (newtok[2], AXP_REG_AT);
2894 assemble_tokens ("ldq_u", newtok, 3, 1);
2895
2896 /* emit "ldq_u $10, size-1($at)" */
2897
2898 set_tok_reg (newtok[0], AXP_REG_T10);
2899 set_tok_const (newtok[1], (1 << lgsize)-1);
2900 assemble_tokens ("ldq_u", newtok, 3, 1);
2901
2902 /* emit "insXl src, $at, $t11" */
2903
2904 newtok[0] = tok[0];
2905 set_tok_reg (newtok[1], AXP_REG_AT);
2906 set_tok_reg (newtok[2], AXP_REG_T11);
2907 assemble_tokens (insXl_op[lgsize], newtok, 3, 1);
2908
2909 /* emit "insXh src, $at, $t12" */
2910
2911 set_tok_reg (newtok[2], AXP_REG_T12);
2912 assemble_tokens (insXh_op[lgsize], newtok, 3, 1);
2913
2914 /* emit "mskXl $t9, $at, $t9" */
2915
2916 set_tok_reg (newtok[0], AXP_REG_T9);
2917 newtok[2] = newtok[0];
2918 assemble_tokens (mskXl_op[lgsize], newtok, 3, 1);
2919
2920 /* emit "mskXh $t10, $at, $t10" */
2921
2922 set_tok_reg (newtok[0], AXP_REG_T10);
2923 newtok[2] = newtok[0];
2924 assemble_tokens (mskXh_op[lgsize], newtok, 3, 1);
2925
2926 /* emit "or $t9, $t11, $t9" */
2927
2928 set_tok_reg (newtok[0], AXP_REG_T9);
2929 set_tok_reg (newtok[1], AXP_REG_T11);
2930 newtok[2] = newtok[0];
2931 assemble_tokens ("or", newtok, 3, 1);
2932
2933 /* emit "or $t10, $t12, $t10" */
2934
2935 set_tok_reg (newtok[0], AXP_REG_T10);
2936 set_tok_reg (newtok[1], AXP_REG_T12);
2937 newtok[2] = newtok[0];
2938 assemble_tokens ("or", newtok, 3, 1);
2939
2940 /* emit "stq_u $t9, 0($at)" */
2941
2942 set_tok_reg (newtok[0], AXP_REG_T9);
2943 set_tok_const (newtok[1], 0);
2944 set_tok_preg (newtok[2], AXP_REG_AT);
2945 assemble_tokens ("stq_u", newtok, 3, 1);
2946
2947 /* emit "stq_u $t10, size-1($at)" */
2948
2949 set_tok_reg (newtok[0], AXP_REG_T10);
2950 set_tok_const (newtok[1], (1 << lgsize)-1);
2951 assemble_tokens ("stq_u", newtok, 3, 1);
2952 }
2953
2954 /* Sign extend a half-word or byte. The 32-bit sign extend is
2955 implemented as "addl $31, $r, $t" in the opcode table. */
2956
2957 static void
2958 emit_sextX (tok, ntok, vlgsize)
2959 const expressionS *tok;
2960 int ntok;
2961 const PTR vlgsize;
2962 {
2963 long lgsize = (long)vlgsize;
2964
2965 if (alpha_target & AXP_OPCODE_BWX)
2966 assemble_tokens (sextX_op[lgsize], tok, ntok, 0);
2967 else
2968 {
2969 int bitshift = 64 - 8 * (1 << lgsize);
2970 expressionS newtok[3];
2971
2972 /* emit "sll src,bits,dst" */
2973
2974 newtok[0] = tok[0];
2975 set_tok_const (newtok[1], bitshift);
2976 newtok[2] = tok[ntok - 1];
2977 assemble_tokens ("sll", newtok, 3, 1);
2978
2979 /* emit "sra dst,bits,dst" */
2980
2981 newtok[0] = newtok[2];
2982 assemble_tokens ("sra", newtok, 3, 1);
2983 }
2984 }
2985
2986 /* Implement the division and modulus macros. */
2987
2988 #ifdef OBJ_EVAX
2989
2990 /* Make register usage like in normal procedure call.
2991 Don't clobber PV and RA. */
2992
2993 static void
2994 emit_division (tok, ntok, symname)
2995 const expressionS *tok;
2996 int ntok;
2997 const PTR symname;
2998 {
2999 /* DIVISION and MODULUS. Yech.
3000 *
3001 * Convert
3002 * OP x,y,result
3003 * to
3004 * mov x,R16 # if x != R16
3005 * mov y,R17 # if y != R17
3006 * lda AT,__OP
3007 * jsr AT,(AT),0
3008 * mov R0,result
3009 *
3010 * with appropriate optimizations if R0,R16,R17 are the registers
3011 * specified by the compiler.
3012 */
3013
3014 int xr, yr, rr;
3015 symbolS *sym;
3016 expressionS newtok[3];
3017
3018 xr = regno (tok[0].X_add_number);
3019 yr = regno (tok[1].X_add_number);
3020
3021 if (ntok < 3)
3022 rr = xr;
3023 else
3024 rr = regno (tok[2].X_add_number);
3025
3026 /* Move the operands into the right place */
3027 if (yr == AXP_REG_R16 && xr == AXP_REG_R17)
3028 {
3029 /* They are in exactly the wrong order -- swap through AT */
3030
3031 if (alpha_noat_on)
3032 as_bad (_("macro requires $at register while noat in effect"));
3033
3034 set_tok_reg (newtok[0], AXP_REG_R16);
3035 set_tok_reg (newtok[1], AXP_REG_AT);
3036 assemble_tokens ("mov", newtok, 2, 1);
3037
3038 set_tok_reg (newtok[0], AXP_REG_R17);
3039 set_tok_reg (newtok[1], AXP_REG_R16);
3040 assemble_tokens ("mov", newtok, 2, 1);
3041
3042 set_tok_reg (newtok[0], AXP_REG_AT);
3043 set_tok_reg (newtok[1], AXP_REG_R17);
3044 assemble_tokens ("mov", newtok, 2, 1);
3045 }
3046 else
3047 {
3048 if (yr == AXP_REG_R16)
3049 {
3050 set_tok_reg (newtok[0], AXP_REG_R16);
3051 set_tok_reg (newtok[1], AXP_REG_R17);
3052 assemble_tokens ("mov", newtok, 2, 1);
3053 }
3054
3055 if (xr != AXP_REG_R16)
3056 {
3057 set_tok_reg (newtok[0], xr);
3058 set_tok_reg (newtok[1], AXP_REG_R16);
3059 assemble_tokens ("mov", newtok, 2, 1);
3060 }
3061
3062 if (yr != AXP_REG_R16 && yr != AXP_REG_R17)
3063 {
3064 set_tok_reg (newtok[0], yr);
3065 set_tok_reg (newtok[1], AXP_REG_R17);
3066 assemble_tokens ("mov", newtok, 2, 1);
3067 }
3068 }
3069
3070 sym = symbol_find_or_make ((const char *)symname);
3071
3072 set_tok_reg (newtok[0], AXP_REG_AT);
3073 set_tok_sym (newtok[1], sym, 0);
3074 assemble_tokens ("lda", newtok, 2, 1);
3075
3076 /* Call the division routine */
3077 set_tok_reg (newtok[0], AXP_REG_AT);
3078 set_tok_cpreg (newtok[1], AXP_REG_AT);
3079 set_tok_const (newtok[2], 0);
3080 assemble_tokens ("jsr", newtok, 3, 1);
3081
3082 /* Move the result to the right place */
3083 if (rr != AXP_REG_R0)
3084 {
3085 set_tok_reg (newtok[0], AXP_REG_R0);
3086 set_tok_reg (newtok[1], rr);
3087 assemble_tokens ("mov", newtok, 2, 1);
3088 }
3089 }
3090
3091 #else /* !OBJ_EVAX */
3092
3093 static void
3094 emit_division (tok, ntok, symname)
3095 const expressionS *tok;
3096 int ntok;
3097 const PTR symname;
3098 {
3099 /* DIVISION and MODULUS. Yech.
3100 * Convert
3101 * OP x,y,result
3102 * to
3103 * lda pv,__OP
3104 * mov x,t10
3105 * mov y,t11
3106 * jsr t9,(pv),__OP
3107 * mov t12,result
3108 *
3109 * with appropriate optimizations if t10,t11,t12 are the registers
3110 * specified by the compiler.
3111 */
3112
3113 int xr, yr, rr;
3114 symbolS *sym;
3115 expressionS newtok[3];
3116
3117 xr = regno (tok[0].X_add_number);
3118 yr = regno (tok[1].X_add_number);
3119
3120 if (ntok < 3)
3121 rr = xr;
3122 else
3123 rr = regno (tok[2].X_add_number);
3124
3125 sym = symbol_find_or_make ((const char *)symname);
3126
3127 /* Move the operands into the right place */
3128 if (yr == AXP_REG_T10 && xr == AXP_REG_T11)
3129 {
3130 /* They are in exactly the wrong order -- swap through AT */
3131
3132 if (alpha_noat_on)
3133 as_bad (_("macro requires $at register while noat in effect"));
3134
3135 set_tok_reg (newtok[0], AXP_REG_T10);
3136 set_tok_reg (newtok[1], AXP_REG_AT);
3137 assemble_tokens ("mov", newtok, 2, 1);
3138
3139 set_tok_reg (newtok[0], AXP_REG_T11);
3140 set_tok_reg (newtok[1], AXP_REG_T10);
3141 assemble_tokens ("mov", newtok, 2, 1);
3142
3143 set_tok_reg (newtok[0], AXP_REG_AT);
3144 set_tok_reg (newtok[1], AXP_REG_T11);
3145 assemble_tokens ("mov", newtok, 2, 1);
3146 }
3147 else
3148 {
3149 if (yr == AXP_REG_T10)
3150 {
3151 set_tok_reg (newtok[0], AXP_REG_T10);
3152 set_tok_reg (newtok[1], AXP_REG_T11);
3153 assemble_tokens ("mov", newtok, 2, 1);
3154 }
3155
3156 if (xr != AXP_REG_T10)
3157 {
3158 set_tok_reg (newtok[0], xr);
3159 set_tok_reg (newtok[1], AXP_REG_T10);
3160 assemble_tokens ("mov", newtok, 2, 1);
3161 }
3162
3163 if (yr != AXP_REG_T10 && yr != AXP_REG_T11)
3164 {
3165 set_tok_reg (newtok[0], yr);
3166 set_tok_reg (newtok[1], AXP_REG_T11);
3167 assemble_tokens ("mov", newtok, 2, 1);
3168 }
3169 }
3170
3171 /* Call the division routine */
3172 set_tok_reg (newtok[0], AXP_REG_T9);
3173 set_tok_sym (newtok[1], sym, 0);
3174 assemble_tokens ("jsr", newtok, 2, 1);
3175
3176 /* Reload the GP register */
3177 #ifdef OBJ_AOUT
3178 FIXME
3179 #endif
3180 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
3181 set_tok_reg (newtok[0], alpha_gp_register);
3182 set_tok_const (newtok[1], 0);
3183 set_tok_preg (newtok[2], AXP_REG_T9);
3184 assemble_tokens ("ldgp", newtok, 3, 1);
3185 #endif
3186
3187 /* Move the result to the right place */
3188 if (rr != AXP_REG_T12)
3189 {
3190 set_tok_reg (newtok[0], AXP_REG_T12);
3191 set_tok_reg (newtok[1], rr);
3192 assemble_tokens ("mov", newtok, 2, 1);
3193 }
3194 }
3195
3196 #endif /* !OBJ_EVAX */
3197
3198 /* The jsr and jmp macros differ from their instruction counterparts
3199 in that they can load the target address and default most
3200 everything. */
3201
3202 static void
3203 emit_jsrjmp (tok, ntok, vopname)
3204 const expressionS *tok;
3205 int ntok;
3206 const PTR vopname;
3207 {
3208 const char *opname = (const char *) vopname;
3209 struct alpha_insn insn;
3210 expressionS newtok[3];
3211 int r, tokidx = 0, lituse = 0;
3212
3213 if (tokidx < ntok && tok[tokidx].X_op == O_register)
3214 r = regno (tok[tokidx++].X_add_number);
3215 else
3216 r = strcmp (opname, "jmp") == 0 ? AXP_REG_ZERO : AXP_REG_RA;
3217
3218 set_tok_reg (newtok[0], r);
3219
3220 if (tokidx < ntok &&
3221 (tok[tokidx].X_op == O_pregister || tok[tokidx].X_op == O_cpregister))
3222 r = regno (tok[tokidx++].X_add_number);
3223 #ifdef OBJ_EVAX
3224 /* keep register if jsr $n.<sym> */
3225 #else
3226 else
3227 {
3228 int basereg = alpha_gp_register;
3229 lituse = load_expression (r = AXP_REG_PV, &tok[tokidx], &basereg, NULL);
3230 }
3231 #endif
3232
3233 set_tok_cpreg (newtok[1], r);
3234
3235 #ifdef OBJ_EVAX
3236 /* FIXME: Add hint relocs to BFD for evax. */
3237 #else
3238 if (tokidx < ntok)
3239 newtok[2] = tok[tokidx];
3240 else
3241 #endif
3242 set_tok_const (newtok[2], 0);
3243
3244 assemble_tokens_to_insn (opname, newtok, 3, &insn);
3245
3246 /* add the LITUSE fixup */
3247 if (lituse)
3248 {
3249 assert (insn.nfixups < MAX_INSN_FIXUPS);
3250 if (insn.nfixups > 0)
3251 {
3252 memmove (&insn.fixups[1], &insn.fixups[0],
3253 sizeof(struct alpha_fixup) * insn.nfixups);
3254 }
3255 insn.nfixups++;
3256 insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITUSE;
3257 insn.fixups[0].exp.X_op = O_constant;
3258 insn.fixups[0].exp.X_add_number = 3;
3259 }
3260
3261 emit_insn (&insn);
3262 }
3263
3264 /* The ret and jcr instructions differ from their instruction
3265 counterparts in that everything can be defaulted. */
3266
3267 static void
3268 emit_retjcr (tok, ntok, vopname)
3269 const expressionS *tok;
3270 int ntok;
3271 const PTR vopname;
3272 {
3273 const char *opname = (const char *)vopname;
3274 expressionS newtok[3];
3275 int r, tokidx = 0;
3276
3277 if (tokidx < ntok && tok[tokidx].X_op == O_register)
3278 r = regno (tok[tokidx++].X_add_number);
3279 else
3280 r = AXP_REG_ZERO;
3281
3282 set_tok_reg (newtok[0], r);
3283
3284 if (tokidx < ntok &&
3285 (tok[tokidx].X_op == O_pregister || tok[tokidx].X_op == O_cpregister))
3286 r = regno (tok[tokidx++].X_add_number);
3287 else
3288 r = AXP_REG_RA;
3289
3290 set_tok_cpreg (newtok[1], r);
3291
3292 if (tokidx < ntok)
3293 newtok[2] = tok[tokidx];
3294 else
3295 set_tok_const (newtok[2], strcmp(opname, "ret") == 0);
3296
3297 assemble_tokens (opname, newtok, 3, 0);
3298 }
3299 \f
3300 /* Assembler directives */
3301
3302 /* Handle the .text pseudo-op. This is like the usual one, but it
3303 clears alpha_insn_label and restores auto alignment. */
3304
3305 static void
3306 s_alpha_text (i)
3307 int i;
3308
3309 {
3310 s_text (i);
3311 alpha_insn_label = NULL;
3312 alpha_auto_align_on = 1;
3313 alpha_current_align = 0;
3314 }
3315
3316 /* Handle the .data pseudo-op. This is like the usual one, but it
3317 clears alpha_insn_label and restores auto alignment. */
3318
3319 static void
3320 s_alpha_data (i)
3321 int i;
3322 {
3323 s_data (i);
3324 alpha_insn_label = NULL;
3325 alpha_auto_align_on = 1;
3326 alpha_current_align = 0;
3327 }
3328
3329 #if defined (OBJ_ECOFF) || defined (OBJ_EVAX)
3330
3331 /* Handle the OSF/1 and openVMS .comm pseudo quirks.
3332 openVMS constructs a section for every common symbol. */
3333
3334 static void
3335 s_alpha_comm (ignore)
3336 int ignore;
3337 {
3338 register char *name;
3339 register char c;
3340 register char *p;
3341 offsetT temp;
3342 register symbolS *symbolP;
3343
3344 #ifdef OBJ_EVAX
3345 segT current_section = now_seg;
3346 int current_subsec = now_subseg;
3347 segT new_seg;
3348 #endif
3349
3350 name = input_line_pointer;
3351 c = get_symbol_end ();
3352
3353 /* just after name is now '\0' */
3354 p = input_line_pointer;
3355 *p = c;
3356
3357 SKIP_WHITESPACE ();
3358
3359 /* Alpha OSF/1 compiler doesn't provide the comma, gcc does. */
3360 if (*input_line_pointer == ',')
3361 {
3362 input_line_pointer++;
3363 SKIP_WHITESPACE ();
3364 }
3365 if ((temp = get_absolute_expression ()) < 0)
3366 {
3367 as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) temp);
3368 ignore_rest_of_line ();
3369 return;
3370 }
3371
3372 *p = 0;
3373 symbolP = symbol_find_or_make (name);
3374 *p = c;
3375
3376 #ifdef OBJ_EVAX
3377 /* Make a section for the common symbol. */
3378 new_seg = subseg_new (xstrdup (name), 0);
3379 #endif
3380
3381 if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
3382 {
3383 as_bad (_("Ignoring attempt to re-define symbol"));
3384 ignore_rest_of_line ();
3385 return;
3386 }
3387
3388 #ifdef OBJ_EVAX
3389 if (bfd_section_size (stdoutput, new_seg) > 0)
3390 {
3391 if (bfd_section_size (stdoutput, new_seg) != temp)
3392 as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
3393 S_GET_NAME (symbolP),
3394 (long) bfd_section_size (stdoutput, new_seg),
3395 (long) temp);
3396 }
3397 #else
3398 if (S_GET_VALUE (symbolP))
3399 {
3400 if (S_GET_VALUE (symbolP) != (valueT) temp)
3401 as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
3402 S_GET_NAME (symbolP),
3403 (long) S_GET_VALUE (symbolP),
3404 (long) temp);
3405 }
3406 #endif
3407 else
3408 {
3409 #ifdef OBJ_EVAX
3410 subseg_set (new_seg, 0);
3411 p = frag_more (temp);
3412 new_seg->flags |= SEC_IS_COMMON;
3413 if (! S_IS_DEFINED (symbolP))
3414 symbolP->bsym->section = new_seg;
3415 #else
3416 S_SET_VALUE (symbolP, (valueT) temp);
3417 #endif
3418 S_SET_EXTERNAL (symbolP);
3419 }
3420
3421 #ifdef OBJ_EVAX
3422 subseg_set (current_section, current_subsec);
3423 #endif
3424
3425 know (symbolP->sy_frag == &zero_address_frag);
3426
3427 demand_empty_rest_of_line ();
3428 }
3429
3430 #endif /* ! OBJ_ELF */
3431
3432 #ifdef OBJ_ECOFF
3433
3434 /* Handle the .rdata pseudo-op. This is like the usual one, but it
3435 clears alpha_insn_label and restores auto alignment. */
3436
3437 static void
3438 s_alpha_rdata (ignore)
3439 int ignore;
3440 {
3441 int temp;
3442
3443 temp = get_absolute_expression ();
3444 subseg_new (".rdata", 0);
3445 demand_empty_rest_of_line ();
3446 alpha_insn_label = NULL;
3447 alpha_auto_align_on = 1;
3448 alpha_current_align = 0;
3449 }
3450
3451 #endif
3452
3453 #ifdef OBJ_ECOFF
3454
3455 /* Handle the .sdata pseudo-op. This is like the usual one, but it
3456 clears alpha_insn_label and restores auto alignment. */
3457
3458 static void
3459 s_alpha_sdata (ignore)
3460 int ignore;
3461 {
3462 int temp;
3463
3464 temp = get_absolute_expression ();
3465 subseg_new (".sdata", 0);
3466 demand_empty_rest_of_line ();
3467 alpha_insn_label = NULL;
3468 alpha_auto_align_on = 1;
3469 alpha_current_align = 0;
3470 }
3471 #endif
3472
3473 #ifdef OBJ_ELF
3474
3475 /* Handle the .section pseudo-op. This is like the usual one, but it
3476 clears alpha_insn_label and restores auto alignment. */
3477
3478 static void
3479 s_alpha_section (ignore)
3480 int ignore;
3481 {
3482 obj_elf_section (ignore);
3483
3484 alpha_insn_label = NULL;
3485 alpha_auto_align_on = 1;
3486 alpha_current_align = 0;
3487 }
3488
3489 #endif
3490
3491 #ifdef OBJ_EVAX
3492
3493 /* Handle the section specific pseudo-op. */
3494
3495 static void
3496 s_alpha_section (secid)
3497 int secid;
3498 {
3499 int temp;
3500 #define EVAX_SECTION_COUNT 5
3501 static char *section_name[EVAX_SECTION_COUNT+1] =
3502 { "NULL", ".rdata", ".comm", ".link", ".ctors", ".dtors" };
3503
3504 if ((secid <= 0) || (secid > EVAX_SECTION_COUNT))
3505 {
3506 as_fatal (_("Unknown section directive"));
3507 demand_empty_rest_of_line ();
3508 return;
3509 }
3510 temp = get_absolute_expression ();
3511 subseg_new (section_name[secid], 0);
3512 demand_empty_rest_of_line ();
3513 alpha_insn_label = NULL;
3514 alpha_auto_align_on = 1;
3515 alpha_current_align = 0;
3516 }
3517
3518
3519 /* .prologue */
3520
3521 static void
3522 s_alpha_prologue (ignore)
3523 int ignore;
3524 {
3525 demand_empty_rest_of_line ();
3526
3527 return;
3528 }
3529
3530
3531 /* Parse .ent directives. */
3532
3533 static void
3534 s_alpha_ent (ignore)
3535 int ignore;
3536 {
3537 symbolS *symbol;
3538 expressionS symexpr;
3539
3540 alpha_evax_proc.pdsckind = 0;
3541 alpha_evax_proc.framereg = -1;
3542 alpha_evax_proc.framesize = 0;
3543 alpha_evax_proc.rsa_offset = 0;
3544 alpha_evax_proc.ra_save = AXP_REG_RA;
3545 alpha_evax_proc.fp_save = -1;
3546 alpha_evax_proc.imask = 0;
3547 alpha_evax_proc.fmask = 0;
3548 alpha_evax_proc.prologue = 0;
3549 alpha_evax_proc.type = 0;
3550
3551 expression (&symexpr);
3552
3553 if (symexpr.X_op != O_symbol)
3554 {
3555 as_fatal (_(".ent directive has no symbol"));
3556 demand_empty_rest_of_line ();
3557 return;
3558 }
3559
3560 symbol = make_expr_symbol (&symexpr);
3561 symbol->bsym->flags |= BSF_FUNCTION;
3562 alpha_evax_proc.symbol = symbol;
3563
3564 demand_empty_rest_of_line ();
3565 return;
3566 }
3567
3568
3569 /* Parse .frame <framreg>,<framesize>,RA,<rsa_offset> directives. */
3570
3571 static void
3572 s_alpha_frame (ignore)
3573 int ignore;
3574 {
3575 long val;
3576
3577 alpha_evax_proc.framereg = tc_get_register (1);
3578
3579 SKIP_WHITESPACE ();
3580 if (*input_line_pointer++ != ','
3581 || get_absolute_expression_and_terminator (&val) != ',')
3582 {
3583 as_warn (_("Bad .frame directive 1./2. param"));
3584 --input_line_pointer;
3585 demand_empty_rest_of_line ();
3586 return;
3587 }
3588
3589 alpha_evax_proc.framesize = val;
3590
3591 (void) tc_get_register (1);
3592 SKIP_WHITESPACE ();
3593 if (*input_line_pointer++ != ',')
3594 {
3595 as_warn (_("Bad .frame directive 3./4. param"));
3596 --input_line_pointer;
3597 demand_empty_rest_of_line ();
3598 return;
3599 }
3600 alpha_evax_proc.rsa_offset = get_absolute_expression ();
3601
3602 return;
3603 }
3604
3605 static void
3606 s_alpha_pdesc (ignore)
3607 int ignore;
3608 {
3609 char *name;
3610 char name_end;
3611 long val;
3612 register char *p;
3613 expressionS exp;
3614 symbolS *entry_sym;
3615 fixS *fixp;
3616 segment_info_type *seginfo = seg_info (alpha_link_section);
3617
3618 if (now_seg != alpha_link_section)
3619 {
3620 as_bad (_(".pdesc directive not in link (.link) section"));
3621 demand_empty_rest_of_line ();
3622 return;
3623 }
3624
3625 if ((alpha_evax_proc.symbol == 0)
3626 || (!S_IS_DEFINED (alpha_evax_proc.symbol)))
3627 {
3628 as_fatal (_(".pdesc has no matching .ent"));
3629 demand_empty_rest_of_line ();
3630 return;
3631 }
3632
3633 alpha_evax_proc.symbol->sy_obj = (valueT)seginfo->literal_pool_size;
3634
3635 expression (&exp);
3636 if (exp.X_op != O_symbol)
3637 {
3638 as_warn (_(".pdesc directive has no entry symbol"));
3639 demand_empty_rest_of_line ();
3640 return;
3641 }
3642
3643 entry_sym = make_expr_symbol (&exp);
3644 /* Save bfd symbol of proc desc in function symbol. */
3645 alpha_evax_proc.symbol->bsym->udata.p = (PTR)entry_sym->bsym;
3646
3647 SKIP_WHITESPACE ();
3648 if (*input_line_pointer++ != ',')
3649 {
3650 as_warn (_("No comma after .pdesc <entryname>"));
3651 demand_empty_rest_of_line ();
3652 return;
3653 }
3654
3655 SKIP_WHITESPACE ();
3656 name = input_line_pointer;
3657 name_end = get_symbol_end ();
3658
3659 if (strncmp(name, "stack", 5) == 0)
3660 {
3661 alpha_evax_proc.pdsckind = PDSC_S_K_KIND_FP_STACK;
3662 }
3663 else if (strncmp(name, "reg", 3) == 0)
3664 {
3665 alpha_evax_proc.pdsckind = PDSC_S_K_KIND_FP_REGISTER;
3666 }
3667 else if (strncmp(name, "null", 4) == 0)
3668 {
3669 alpha_evax_proc.pdsckind = PDSC_S_K_KIND_NULL;
3670 }
3671 else
3672 {
3673 as_fatal (_("unknown procedure kind"));
3674 demand_empty_rest_of_line ();
3675 return;
3676 }
3677
3678 *input_line_pointer = name_end;
3679 demand_empty_rest_of_line ();
3680
3681 #ifdef md_flush_pending_output
3682 md_flush_pending_output ();
3683 #endif
3684
3685 frag_align (3, 0, 0);
3686 p = frag_more (16);
3687 fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
3688 fixp->fx_done = 1;
3689 seginfo->literal_pool_size += 16;
3690
3691 *p = alpha_evax_proc.pdsckind
3692 | ((alpha_evax_proc.framereg == 29) ? PDSC_S_M_BASE_REG_IS_FP : 0);
3693 *(p+1) = PDSC_S_M_NATIVE
3694 | PDSC_S_M_NO_JACKET;
3695
3696 switch (alpha_evax_proc.pdsckind)
3697 {
3698 case PDSC_S_K_KIND_NULL:
3699 *(p+2) = 0;
3700 *(p+3) = 0;
3701 break;
3702 case PDSC_S_K_KIND_FP_REGISTER:
3703 *(p+2) = alpha_evax_proc.fp_save;
3704 *(p+3) = alpha_evax_proc.ra_save;
3705 break;
3706 case PDSC_S_K_KIND_FP_STACK:
3707 md_number_to_chars (p+2, (valueT)alpha_evax_proc.rsa_offset, 2);
3708 break;
3709 default: /* impossible */
3710 break;
3711 }
3712
3713 *(p+4) = 0;
3714 *(p+5) = alpha_evax_proc.type & 0x0f;
3715
3716 /* Signature offset. */
3717 md_number_to_chars (p+6, (valueT)0, 2);
3718
3719 fix_new_exp (frag_now, p-frag_now->fr_literal+8, 8, &exp, 0, BFD_RELOC_64);
3720
3721 if (alpha_evax_proc.pdsckind == PDSC_S_K_KIND_NULL)
3722 return;
3723
3724 /* Add dummy fix to make add_to_link_pool work. */
3725 p = frag_more (8);
3726 fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
3727 fixp->fx_done = 1;
3728 seginfo->literal_pool_size += 8;
3729
3730 /* pdesc+16: Size. */
3731 md_number_to_chars (p, (valueT)alpha_evax_proc.framesize, 4);
3732
3733 md_number_to_chars (p+4, (valueT)0, 2);
3734
3735 /* Entry length. */
3736 md_number_to_chars (p+6, alpha_evax_proc.prologue, 2);
3737
3738 if (alpha_evax_proc.pdsckind == PDSC_S_K_KIND_FP_REGISTER)
3739 return;
3740
3741 /* Add dummy fix to make add_to_link_pool work. */
3742 p = frag_more (8);
3743 fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
3744 fixp->fx_done = 1;
3745 seginfo->literal_pool_size += 8;
3746
3747 /* pdesc+24: register masks. */
3748
3749 md_number_to_chars (p, alpha_evax_proc.imask, 4);
3750 md_number_to_chars (p+4, alpha_evax_proc.fmask, 4);
3751
3752 return;
3753 }
3754
3755
3756 /* Support for crash debug on vms. */
3757
3758 static void
3759 s_alpha_name (ignore)
3760 int ignore;
3761 {
3762 register char *p;
3763 expressionS exp;
3764 segment_info_type *seginfo = seg_info (alpha_link_section);
3765
3766 if (now_seg != alpha_link_section)
3767 {
3768 as_bad (_(".name directive not in link (.link) section"));
3769 demand_empty_rest_of_line ();
3770 return;
3771 }
3772
3773 expression (&exp);
3774 if (exp.X_op != O_symbol)
3775 {
3776 as_warn (_(".name directive has no symbol"));
3777 demand_empty_rest_of_line ();
3778 return;
3779 }
3780
3781 demand_empty_rest_of_line ();
3782
3783 #ifdef md_flush_pending_output
3784 md_flush_pending_output ();
3785 #endif
3786
3787 frag_align (3, 0, 0);
3788 p = frag_more (8);
3789 seginfo->literal_pool_size += 8;
3790
3791 fix_new_exp (frag_now, p-frag_now->fr_literal, 8, &exp, 0, BFD_RELOC_64);
3792
3793 return;
3794 }
3795
3796
3797 static void
3798 s_alpha_linkage (ignore)
3799 int ignore;
3800 {
3801 expressionS exp;
3802 char *p;
3803
3804 #ifdef md_flush_pending_output
3805 md_flush_pending_output ();
3806 #endif
3807
3808 expression (&exp);
3809 if (exp.X_op != O_symbol)
3810 {
3811 as_fatal (_("No symbol after .linkage"));
3812 }
3813 else
3814 {
3815 p = frag_more (LKP_S_K_SIZE);
3816 memset (p, 0, LKP_S_K_SIZE);
3817 fix_new_exp (frag_now, p - frag_now->fr_literal, LKP_S_K_SIZE, &exp, 0,\
3818 BFD_RELOC_ALPHA_LINKAGE);
3819 }
3820 demand_empty_rest_of_line ();
3821
3822 return;
3823 }
3824
3825
3826 static void
3827 s_alpha_code_address (ignore)
3828 int ignore;
3829 {
3830 expressionS exp;
3831 char *p;
3832
3833 #ifdef md_flush_pending_output
3834 md_flush_pending_output ();
3835 #endif
3836
3837 expression (&exp);
3838 if (exp.X_op != O_symbol)
3839 {
3840 as_fatal (_("No symbol after .code_address"));
3841 }
3842 else
3843 {
3844 p = frag_more (8);
3845 memset (p, 0, 8);
3846 fix_new_exp (frag_now, p - frag_now->fr_literal, 8, &exp, 0,\
3847 BFD_RELOC_ALPHA_CODEADDR);
3848 }
3849 demand_empty_rest_of_line ();
3850
3851 return;
3852 }
3853
3854
3855 static void
3856 s_alpha_fp_save (ignore)
3857 int ignore;
3858 {
3859
3860 alpha_evax_proc.fp_save = tc_get_register (1);
3861
3862 demand_empty_rest_of_line ();
3863 return;
3864 }
3865
3866
3867 static void
3868 s_alpha_mask (ignore)
3869 int ignore;
3870 {
3871 long val;
3872
3873 if (get_absolute_expression_and_terminator (&val) != ',')
3874 {
3875 as_warn (_("Bad .mask directive"));
3876 --input_line_pointer;
3877 }
3878 else
3879 {
3880 alpha_evax_proc.imask = val;
3881 (void)get_absolute_expression ();
3882 }
3883 demand_empty_rest_of_line ();
3884
3885 return;
3886 }
3887
3888
3889 static void
3890 s_alpha_fmask (ignore)
3891 int ignore;
3892 {
3893 long val;
3894
3895 if (get_absolute_expression_and_terminator (&val) != ',')
3896 {
3897 as_warn (_("Bad .fmask directive"));
3898 --input_line_pointer;
3899 }
3900 else
3901 {
3902 alpha_evax_proc.fmask = val;
3903 (void) get_absolute_expression ();
3904 }
3905 demand_empty_rest_of_line ();
3906
3907 return;
3908 }
3909
3910 static void
3911 s_alpha_end (ignore)
3912 int ignore;
3913 {
3914 char c;
3915
3916 c = get_symbol_end ();
3917 *input_line_pointer = c;
3918 demand_empty_rest_of_line ();
3919 alpha_evax_proc.symbol = 0;
3920
3921 return;
3922 }
3923
3924
3925 static void
3926 s_alpha_file (ignore)
3927 int ignore;
3928 {
3929 symbolS *s;
3930 int length;
3931 static char case_hack[32];
3932
3933 extern char *demand_copy_string PARAMS ((int *lenP));
3934
3935 sprintf (case_hack, "<CASE:%01d%01d>",
3936 alpha_flag_hash_long_names, alpha_flag_show_after_trunc);
3937
3938 s = symbol_find_or_make (case_hack);
3939 s->bsym->flags |= BSF_FILE;
3940
3941 get_absolute_expression ();
3942 s = symbol_find_or_make (demand_copy_string (&length));
3943 s->bsym->flags |= BSF_FILE;
3944 demand_empty_rest_of_line ();
3945
3946 return;
3947 }
3948 #endif /* OBJ_EVAX */
3949
3950 /* Handle the .gprel32 pseudo op. */
3951
3952 static void
3953 s_alpha_gprel32 (ignore)
3954 int ignore;
3955 {
3956 expressionS e;
3957 char *p;
3958
3959 SKIP_WHITESPACE ();
3960 expression (&e);
3961
3962 #ifdef OBJ_ELF
3963 switch (e.X_op)
3964 {
3965 case O_constant:
3966 e.X_add_symbol = section_symbol(absolute_section);
3967 e.X_op = O_symbol;
3968 /* FALLTHRU */
3969 case O_symbol:
3970 break;
3971 default:
3972 abort();
3973 }
3974 #else
3975 #ifdef OBJ_ECOFF
3976 switch (e.X_op)
3977 {
3978 case O_constant:
3979 e.X_add_symbol = section_symbol (absolute_section);
3980 /* fall through */
3981 case O_symbol:
3982 e.X_op = O_subtract;
3983 e.X_op_symbol = alpha_gp_symbol;
3984 break;
3985 default:
3986 abort ();
3987 }
3988 #endif
3989 #endif
3990
3991 if (alpha_auto_align_on && alpha_current_align < 2)
3992 alpha_align (2, (char *) NULL, alpha_insn_label, 0);
3993 if (alpha_current_align > 2)
3994 alpha_current_align = 2;
3995 alpha_insn_label = NULL;
3996
3997 p = frag_more (4);
3998 memset (p, 0, 4);
3999 fix_new_exp (frag_now, p-frag_now->fr_literal, 4,
4000 &e, 0, BFD_RELOC_GPREL32);
4001 }
4002
4003 /* Handle floating point allocation pseudo-ops. This is like the
4004 generic vresion, but it makes sure the current label, if any, is
4005 correctly aligned. */
4006
4007 static void
4008 s_alpha_float_cons (type)
4009 int type;
4010 {
4011 int log_size;
4012
4013 switch (type)
4014 {
4015 default:
4016 case 'f':
4017 case 'F':
4018 log_size = 2;
4019 break;
4020
4021 case 'd':
4022 case 'D':
4023 case 'G':
4024 log_size = 3;
4025 break;
4026
4027 case 'x':
4028 case 'X':
4029 case 'p':
4030 case 'P':
4031 log_size = 4;
4032 break;
4033 }
4034
4035 if (alpha_auto_align_on && alpha_current_align < log_size)
4036 alpha_align (log_size, (char *) NULL, alpha_insn_label, 0);
4037 if (alpha_current_align > log_size)
4038 alpha_current_align = log_size;
4039 alpha_insn_label = NULL;
4040
4041 float_cons (type);
4042 }
4043
4044 /* Handle the .proc pseudo op. We don't really do much with it except
4045 parse it. */
4046
4047 static void
4048 s_alpha_proc (is_static)
4049 int is_static;
4050 {
4051 char *name;
4052 char c;
4053 char *p;
4054 symbolS *symbolP;
4055 int temp;
4056
4057 /* Takes ".proc name,nargs" */
4058 SKIP_WHITESPACE ();
4059 name = input_line_pointer;
4060 c = get_symbol_end ();
4061 p = input_line_pointer;
4062 symbolP = symbol_find_or_make (name);
4063 *p = c;
4064 SKIP_WHITESPACE ();
4065 if (*input_line_pointer != ',')
4066 {
4067 *p = 0;
4068 as_warn (_("Expected comma after name \"%s\""), name);
4069 *p = c;
4070 temp = 0;
4071 ignore_rest_of_line ();
4072 }
4073 else
4074 {
4075 input_line_pointer++;
4076 temp = get_absolute_expression ();
4077 }
4078 /* symbolP->sy_other = (signed char) temp; */
4079 as_warn (_("unhandled: .proc %s,%d"), name, temp);
4080 demand_empty_rest_of_line ();
4081 }
4082
4083 /* Handle the .set pseudo op. This is used to turn on and off most of
4084 the assembler features. */
4085
4086 static void
4087 s_alpha_set (x)
4088 int x;
4089 {
4090 char *name, ch, *s;
4091 int yesno = 1;
4092
4093 SKIP_WHITESPACE ();
4094 name = input_line_pointer;
4095 ch = get_symbol_end ();
4096
4097 s = name;
4098 if (s[0] == 'n' && s[1] == 'o')
4099 {
4100 yesno = 0;
4101 s += 2;
4102 }
4103 if (!strcmp ("reorder", s))
4104 /* ignore */ ;
4105 else if (!strcmp ("at", s))
4106 alpha_noat_on = !yesno;
4107 else if (!strcmp ("macro", s))
4108 alpha_macros_on = yesno;
4109 else if (!strcmp ("move", s))
4110 /* ignore */ ;
4111 else if (!strcmp ("volatile", s))
4112 /* ignore */ ;
4113 else
4114 as_warn (_("Tried to .set unrecognized mode `%s'"), name);
4115
4116 *input_line_pointer = ch;
4117 demand_empty_rest_of_line ();
4118 }
4119
4120 /* Handle the .base pseudo op. This changes the assembler's notion of
4121 the $gp register. */
4122
4123 static void
4124 s_alpha_base (ignore)
4125 int ignore;
4126 {
4127 #if 0
4128 if (first_32bit_quadrant)
4129 {
4130 /* not fatal, but it might not work in the end */
4131 as_warn (_("File overrides no-base-register option."));
4132 first_32bit_quadrant = 0;
4133 }
4134 #endif
4135
4136 SKIP_WHITESPACE ();
4137 if (*input_line_pointer == '$')
4138 { /* $rNN form */
4139 input_line_pointer++;
4140 if (*input_line_pointer == 'r')
4141 input_line_pointer++;
4142 }
4143
4144 alpha_gp_register = get_absolute_expression ();
4145 if (alpha_gp_register < 0 || alpha_gp_register > 31)
4146 {
4147 alpha_gp_register = AXP_REG_GP;
4148 as_warn (_("Bad base register, using $%d."), alpha_gp_register);
4149 }
4150
4151 demand_empty_rest_of_line ();
4152 }
4153
4154 /* Handle the .align pseudo-op. This aligns to a power of two. It
4155 also adjusts any current instruction label. We treat this the same
4156 way the MIPS port does: .align 0 turns off auto alignment. */
4157
4158 static void
4159 s_alpha_align (ignore)
4160 int ignore;
4161 {
4162 int align;
4163 char fill, *pfill;
4164 long max_alignment = 15;
4165
4166 align = get_absolute_expression ();
4167 if (align > max_alignment)
4168 {
4169 align = max_alignment;
4170 as_bad (_("Alignment too large: %d. assumed"), align);
4171 }
4172 else if (align < 0)
4173 {
4174 as_warn (_("Alignment negative: 0 assumed"));
4175 align = 0;
4176 }
4177
4178 if (*input_line_pointer == ',')
4179 {
4180 input_line_pointer++;
4181 fill = get_absolute_expression ();
4182 pfill = &fill;
4183 }
4184 else
4185 pfill = NULL;
4186
4187 if (align != 0)
4188 {
4189 alpha_auto_align_on = 1;
4190 alpha_align (align, pfill, alpha_insn_label, 1);
4191 }
4192 else
4193 {
4194 alpha_auto_align_on = 0;
4195 }
4196
4197 demand_empty_rest_of_line ();
4198 }
4199
4200 /* Hook the normal string processor to reset known alignment. */
4201
4202 static void
4203 s_alpha_stringer (terminate)
4204 int terminate;
4205 {
4206 alpha_current_align = 0;
4207 alpha_insn_label = NULL;
4208 stringer (terminate);
4209 }
4210
4211 /* Hook the normal space processing to reset known alignment. */
4212
4213 static void
4214 s_alpha_space (ignore)
4215 int ignore;
4216 {
4217 alpha_current_align = 0;
4218 alpha_insn_label = NULL;
4219 s_space (ignore);
4220 }
4221
4222 /* Hook into cons for auto-alignment. */
4223
4224 void
4225 alpha_cons_align (size)
4226 int size;
4227 {
4228 int log_size;
4229
4230 log_size = 0;
4231 while ((size >>= 1) != 0)
4232 ++log_size;
4233
4234 if (alpha_auto_align_on && alpha_current_align < log_size)
4235 alpha_align (log_size, (char *) NULL, alpha_insn_label, 0);
4236 if (alpha_current_align > log_size)
4237 alpha_current_align = log_size;
4238 alpha_insn_label = NULL;
4239 }
4240
4241 /* Here come the .uword, .ulong, and .uquad explicitly unaligned
4242 pseudos. We just turn off auto-alignment and call down to cons. */
4243
4244 static void
4245 s_alpha_ucons (bytes)
4246 int bytes;
4247 {
4248 int hold = alpha_auto_align_on;
4249 alpha_auto_align_on = 0;
4250 cons (bytes);
4251 alpha_auto_align_on = hold;
4252 }
4253
4254 /* Switch the working cpu type. */
4255
4256 static void
4257 s_alpha_arch (ignored)
4258 int ignored;
4259 {
4260 char *name, ch;
4261 const struct cpu_type *p;
4262
4263 SKIP_WHITESPACE ();
4264 name = input_line_pointer;
4265 ch = get_symbol_end ();
4266
4267 for (p = cpu_types; p->name; ++p)
4268 if (strcmp(name, p->name) == 0)
4269 {
4270 alpha_target_name = p->name, alpha_target = p->flags;
4271 goto found;
4272 }
4273 as_warn("Unknown CPU identifier `%s'", name);
4274
4275 found:
4276 *input_line_pointer = ch;
4277 demand_empty_rest_of_line ();
4278 }
4279
4280 \f
4281
4282 #ifdef DEBUG1
4283 /* print token expression with alpha specific extension. */
4284
4285 static void
4286 alpha_print_token(f, exp)
4287 FILE *f;
4288 const expressionS *exp;
4289 {
4290 switch (exp->X_op)
4291 {
4292 case O_cpregister:
4293 putc (',', f);
4294 /* FALLTHRU */
4295 case O_pregister:
4296 putc ('(', f);
4297 {
4298 expressionS nexp = *exp;
4299 nexp.X_op = O_register;
4300 print_expr (f, &nexp);
4301 }
4302 putc (')', f);
4303 break;
4304 default:
4305 print_expr (f, exp);
4306 break;
4307 }
4308 return;
4309 }
4310 #endif
4311 \f
4312 /* The target specific pseudo-ops which we support. */
4313
4314 const pseudo_typeS md_pseudo_table[] =
4315 {
4316 #ifdef OBJ_ECOFF
4317 {"comm", s_alpha_comm, 0}, /* osf1 compiler does this */
4318 {"rdata", s_alpha_rdata, 0},
4319 #endif
4320 {"text", s_alpha_text, 0},
4321 {"data", s_alpha_data, 0},
4322 #ifdef OBJ_ECOFF
4323 {"sdata", s_alpha_sdata, 0},
4324 #endif
4325 #ifdef OBJ_ELF
4326 {"section", s_alpha_section, 0},
4327 {"section.s", s_alpha_section, 0},
4328 {"sect", s_alpha_section, 0},
4329 {"sect.s", s_alpha_section, 0},
4330 #endif
4331 #ifdef OBJ_EVAX
4332 { "pdesc", s_alpha_pdesc, 0},
4333 { "name", s_alpha_name, 0},
4334 { "linkage", s_alpha_linkage, 0},
4335 { "code_address", s_alpha_code_address, 0},
4336 { "ent", s_alpha_ent, 0},
4337 { "frame", s_alpha_frame, 0},
4338 { "fp_save", s_alpha_fp_save, 0},
4339 { "mask", s_alpha_mask, 0},
4340 { "fmask", s_alpha_fmask, 0},
4341 { "end", s_alpha_end, 0},
4342 { "file", s_alpha_file, 0},
4343 { "rdata", s_alpha_section, 1},
4344 { "comm", s_alpha_comm, 0},
4345 { "link", s_alpha_section, 3},
4346 { "ctors", s_alpha_section, 4},
4347 { "dtors", s_alpha_section, 5},
4348 #endif
4349 {"gprel32", s_alpha_gprel32, 0},
4350 {"t_floating", s_alpha_float_cons, 'd'},
4351 {"s_floating", s_alpha_float_cons, 'f'},
4352 {"f_floating", s_alpha_float_cons, 'F'},
4353 {"g_floating", s_alpha_float_cons, 'G'},
4354 {"d_floating", s_alpha_float_cons, 'D'},
4355
4356 {"proc", s_alpha_proc, 0},
4357 {"aproc", s_alpha_proc, 1},
4358 {"set", s_alpha_set, 0},
4359 {"reguse", s_ignore, 0},
4360 {"livereg", s_ignore, 0},
4361 {"base", s_alpha_base, 0}, /*??*/
4362 {"option", s_ignore, 0},
4363 {"prologue", s_ignore, 0},
4364 {"aent", s_ignore, 0},
4365 {"ugen", s_ignore, 0},
4366 {"eflag", s_ignore, 0},
4367
4368 {"align", s_alpha_align, 0},
4369 {"double", s_alpha_float_cons, 'd'},
4370 {"float", s_alpha_float_cons, 'f'},
4371 {"single", s_alpha_float_cons, 'f'},
4372 {"ascii", s_alpha_stringer, 0},
4373 {"asciz", s_alpha_stringer, 1},
4374 {"string", s_alpha_stringer, 1},
4375 {"space", s_alpha_space, 0},
4376 {"skip", s_alpha_space, 0},
4377 {"zero", s_alpha_space, 0},
4378
4379 /* Unaligned data pseudos. */
4380 {"uword", s_alpha_ucons, 2},
4381 {"ulong", s_alpha_ucons, 4},
4382 {"uquad", s_alpha_ucons, 8},
4383
4384 #ifdef OBJ_ELF
4385 /* Dwarf wants these versions of unaligned. */
4386 {"2byte", s_alpha_ucons, 2},
4387 {"4byte", s_alpha_ucons, 4},
4388 {"8byte", s_alpha_ucons, 8},
4389 #endif
4390
4391 /* We don't do any optimizing, so we can safely ignore these. */
4392 {"noalias", s_ignore, 0},
4393 {"alias", s_ignore, 0},
4394
4395 {"arch", s_alpha_arch, 0},
4396
4397 {NULL, 0, 0},
4398 };
4399
4400 \f
4401 /* Build a BFD section with its flags set appropriately for the .lita,
4402 .lit8, or .lit4 sections. */
4403
4404 static void
4405 create_literal_section (name, secp, symp)
4406 const char *name;
4407 segT *secp;
4408 symbolS **symp;
4409 {
4410 segT current_section = now_seg;
4411 int current_subsec = now_subseg;
4412 segT new_sec;
4413
4414 *secp = new_sec = subseg_new (name, 0);
4415 subseg_set (current_section, current_subsec);
4416 bfd_set_section_alignment (stdoutput, new_sec, 4);
4417 bfd_set_section_flags (stdoutput, new_sec,
4418 SEC_RELOC | SEC_ALLOC | SEC_LOAD | SEC_READONLY
4419 | SEC_DATA);
4420
4421 S_CLEAR_EXTERNAL (*symp = section_symbol (new_sec));
4422 }
4423
4424 #ifdef OBJ_ECOFF
4425
4426 /* @@@ GP selection voodoo. All of this seems overly complicated and
4427 unnecessary; which is the primary reason it's for ECOFF only. */
4428
4429 static inline void
4430 maybe_set_gp (sec)
4431 asection *sec;
4432 {
4433 bfd_vma vma;
4434 if (!sec)
4435 return;
4436 vma = bfd_get_section_vma (foo, sec);
4437 if (vma && vma < alpha_gp_value)
4438 alpha_gp_value = vma;
4439 }
4440
4441 static void
4442 select_gp_value ()
4443 {
4444 assert (alpha_gp_value == 0);
4445
4446 /* Get minus-one in whatever width... */
4447 alpha_gp_value = 0; alpha_gp_value--;
4448
4449 /* Select the smallest VMA of these existing sections. */
4450 maybe_set_gp (alpha_lita_section);
4451 #if 0
4452 /* These were disabled before -- should we use them? */
4453 maybe_set_gp (sdata);
4454 maybe_set_gp (lit8_sec);
4455 maybe_set_gp (lit4_sec);
4456 #endif
4457
4458 /* @@ Will a simple 0x8000 work here? If not, why not? */
4459 #define GP_ADJUSTMENT (0x8000 - 0x10)
4460
4461 alpha_gp_value += GP_ADJUSTMENT;
4462
4463 S_SET_VALUE (alpha_gp_symbol, alpha_gp_value);
4464
4465 #ifdef DEBUG1
4466 printf (_("Chose GP value of %lx\n"), alpha_gp_value);
4467 #endif
4468 }
4469 #endif /* OBJ_ECOFF */
4470
4471 /* Called internally to handle all alignment needs. This takes care
4472 of eliding calls to frag_align if'n the cached current alignment
4473 says we've already got it, as well as taking care of the auto-align
4474 feature wrt labels. */
4475
4476 static void
4477 alpha_align (n, pfill, label, force)
4478 int n;
4479 char *pfill;
4480 symbolS *label;
4481 int force;
4482 {
4483 if (alpha_current_align >= n)
4484 return;
4485
4486 if (pfill == NULL)
4487 {
4488 if (n > 2
4489 && (bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0)
4490 {
4491 static char const unop[4] = { 0x00, 0x00, 0xe0, 0x2f };
4492 static char const nopunop[8] = {
4493 0x1f, 0x04, 0xff, 0x47,
4494 0x00, 0x00, 0xe0, 0x2f
4495 };
4496
4497 /* First, make sure we're on a four-byte boundary, in case
4498 someone has been putting .byte values into the text
4499 section. The DEC assembler silently fills with unaligned
4500 no-op instructions. This will zero-fill, then nop-fill
4501 with proper alignment. */
4502 if (alpha_current_align < 2)
4503 frag_align (2, 0, 0);
4504 if (alpha_current_align < 3)
4505 frag_align_pattern (3, unop, sizeof unop, 0);
4506 if (n > 3)
4507 frag_align_pattern (n, nopunop, sizeof nopunop, 0);
4508 }
4509 else
4510 frag_align (n, 0, 0);
4511 }
4512 else
4513 frag_align (n, *pfill, 0);
4514
4515 alpha_current_align = n;
4516
4517 if (label != NULL)
4518 {
4519 assert (S_GET_SEGMENT (label) == now_seg);
4520 label->sy_frag = frag_now;
4521 S_SET_VALUE (label, (valueT) frag_now_fix ());
4522 }
4523
4524 record_alignment(now_seg, n);
4525
4526 /* ??? if alpha_flag_relax && force && elf, record the requested alignment
4527 in a reloc for the linker to see. */
4528 }
4529
4530 /* The Alpha has support for some VAX floating point types, as well as for
4531 IEEE floating point. We consider IEEE to be the primary floating point
4532 format, and sneak in the VAX floating point support here. */
4533 #define md_atof vax_md_atof
4534 #include "config/atof-vax.c"