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