70aaec8590fd79f45cc7d34b53d8ef46b46c085b
[deliverable/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 #ifdef OBJ_EVAX
3376 /* alignment might follow */
3377 if (*input_line_pointer == ',')
3378 {
3379 offsetT align;
3380
3381 input_line_pointer++;
3382 align = get_absolute_expression ();
3383 bfd_set_section_alignment (stdoutput, new_seg, align);
3384 }
3385 #endif
3386
3387 if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
3388 {
3389 as_bad (_("Ignoring attempt to re-define symbol"));
3390 ignore_rest_of_line ();
3391 return;
3392 }
3393
3394 #ifdef OBJ_EVAX
3395 if (bfd_section_size (stdoutput, new_seg) > 0)
3396 {
3397 if (bfd_section_size (stdoutput, new_seg) != temp)
3398 as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
3399 S_GET_NAME (symbolP),
3400 (long) bfd_section_size (stdoutput, new_seg),
3401 (long) temp);
3402 }
3403 #else
3404 if (S_GET_VALUE (symbolP))
3405 {
3406 if (S_GET_VALUE (symbolP) != (valueT) temp)
3407 as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
3408 S_GET_NAME (symbolP),
3409 (long) S_GET_VALUE (symbolP),
3410 (long) temp);
3411 }
3412 #endif
3413 else
3414 {
3415 #ifdef OBJ_EVAX
3416 subseg_set (new_seg, 0);
3417 p = frag_more (temp);
3418 new_seg->flags |= SEC_IS_COMMON;
3419 if (! S_IS_DEFINED (symbolP))
3420 symbolP->bsym->section = new_seg;
3421 #else
3422 S_SET_VALUE (symbolP, (valueT) temp);
3423 #endif
3424 S_SET_EXTERNAL (symbolP);
3425 }
3426
3427 #ifdef OBJ_EVAX
3428 subseg_set (current_section, current_subsec);
3429 #endif
3430
3431 know (symbolP->sy_frag == &zero_address_frag);
3432
3433 demand_empty_rest_of_line ();
3434 }
3435
3436 #endif /* ! OBJ_ELF */
3437
3438 #ifdef OBJ_ECOFF
3439
3440 /* Handle the .rdata pseudo-op. This is like the usual one, but it
3441 clears alpha_insn_label and restores auto alignment. */
3442
3443 static void
3444 s_alpha_rdata (ignore)
3445 int ignore;
3446 {
3447 int temp;
3448
3449 temp = get_absolute_expression ();
3450 subseg_new (".rdata", 0);
3451 demand_empty_rest_of_line ();
3452 alpha_insn_label = NULL;
3453 alpha_auto_align_on = 1;
3454 alpha_current_align = 0;
3455 }
3456
3457 #endif
3458
3459 #ifdef OBJ_ECOFF
3460
3461 /* Handle the .sdata pseudo-op. This is like the usual one, but it
3462 clears alpha_insn_label and restores auto alignment. */
3463
3464 static void
3465 s_alpha_sdata (ignore)
3466 int ignore;
3467 {
3468 int temp;
3469
3470 temp = get_absolute_expression ();
3471 subseg_new (".sdata", 0);
3472 demand_empty_rest_of_line ();
3473 alpha_insn_label = NULL;
3474 alpha_auto_align_on = 1;
3475 alpha_current_align = 0;
3476 }
3477 #endif
3478
3479 #ifdef OBJ_ELF
3480
3481 /* Handle the .section pseudo-op. This is like the usual one, but it
3482 clears alpha_insn_label and restores auto alignment. */
3483
3484 static void
3485 s_alpha_section (ignore)
3486 int ignore;
3487 {
3488 obj_elf_section (ignore);
3489
3490 alpha_insn_label = NULL;
3491 alpha_auto_align_on = 1;
3492 alpha_current_align = 0;
3493 }
3494
3495 static void
3496 s_alpha_prologue (ignore)
3497 int ignore;
3498 {
3499 symbolS *sym;
3500 int arg;
3501
3502 arg = get_absolute_expression ();
3503 demand_empty_rest_of_line ();
3504
3505 sym = ecoff_get_cur_proc_sym ();
3506 know (sym != NULL);
3507
3508 switch (arg)
3509 {
3510 case 0: /* No PV required. */
3511 S_SET_OTHER (sym, STO_ALPHA_NOPV);
3512 break;
3513 case 1: /* Std GP load. */
3514 S_SET_OTHER (sym, STO_ALPHA_STD_GPLOAD);
3515 break;
3516 case 2: /* Non-std use of PV. */
3517 break;
3518
3519 default:
3520 as_bad (_("Invalid argument %d to .prologue."), arg);
3521 break;
3522 }
3523 }
3524
3525 #endif
3526
3527 #ifdef OBJ_EVAX
3528
3529 /* Handle the section specific pseudo-op. */
3530
3531 static void
3532 s_alpha_section (secid)
3533 int secid;
3534 {
3535 int temp;
3536 #define EVAX_SECTION_COUNT 5
3537 static char *section_name[EVAX_SECTION_COUNT+1] =
3538 { "NULL", ".rdata", ".comm", ".link", ".ctors", ".dtors" };
3539
3540 if ((secid <= 0) || (secid > EVAX_SECTION_COUNT))
3541 {
3542 as_fatal (_("Unknown section directive"));
3543 demand_empty_rest_of_line ();
3544 return;
3545 }
3546 temp = get_absolute_expression ();
3547 subseg_new (section_name[secid], 0);
3548 demand_empty_rest_of_line ();
3549 alpha_insn_label = NULL;
3550 alpha_auto_align_on = 1;
3551 alpha_current_align = 0;
3552 }
3553
3554
3555 /* Parse .ent directives. */
3556
3557 static void
3558 s_alpha_ent (ignore)
3559 int ignore;
3560 {
3561 symbolS *symbol;
3562 expressionS symexpr;
3563
3564 alpha_evax_proc.pdsckind = 0;
3565 alpha_evax_proc.framereg = -1;
3566 alpha_evax_proc.framesize = 0;
3567 alpha_evax_proc.rsa_offset = 0;
3568 alpha_evax_proc.ra_save = AXP_REG_RA;
3569 alpha_evax_proc.fp_save = -1;
3570 alpha_evax_proc.imask = 0;
3571 alpha_evax_proc.fmask = 0;
3572 alpha_evax_proc.prologue = 0;
3573 alpha_evax_proc.type = 0;
3574
3575 expression (&symexpr);
3576
3577 if (symexpr.X_op != O_symbol)
3578 {
3579 as_fatal (_(".ent directive has no symbol"));
3580 demand_empty_rest_of_line ();
3581 return;
3582 }
3583
3584 symbol = make_expr_symbol (&symexpr);
3585 symbol->bsym->flags |= BSF_FUNCTION;
3586 alpha_evax_proc.symbol = symbol;
3587
3588 demand_empty_rest_of_line ();
3589 return;
3590 }
3591
3592
3593 /* Parse .frame <framreg>,<framesize>,RA,<rsa_offset> directives. */
3594
3595 static void
3596 s_alpha_frame (ignore)
3597 int ignore;
3598 {
3599 long val;
3600
3601 alpha_evax_proc.framereg = tc_get_register (1);
3602
3603 SKIP_WHITESPACE ();
3604 if (*input_line_pointer++ != ','
3605 || get_absolute_expression_and_terminator (&val) != ',')
3606 {
3607 as_warn (_("Bad .frame directive 1./2. param"));
3608 --input_line_pointer;
3609 demand_empty_rest_of_line ();
3610 return;
3611 }
3612
3613 alpha_evax_proc.framesize = val;
3614
3615 (void) tc_get_register (1);
3616 SKIP_WHITESPACE ();
3617 if (*input_line_pointer++ != ',')
3618 {
3619 as_warn (_("Bad .frame directive 3./4. param"));
3620 --input_line_pointer;
3621 demand_empty_rest_of_line ();
3622 return;
3623 }
3624 alpha_evax_proc.rsa_offset = get_absolute_expression ();
3625
3626 return;
3627 }
3628
3629 static void
3630 s_alpha_pdesc (ignore)
3631 int ignore;
3632 {
3633 char *name;
3634 char name_end;
3635 long val;
3636 register char *p;
3637 expressionS exp;
3638 symbolS *entry_sym;
3639 fixS *fixp;
3640 segment_info_type *seginfo = seg_info (alpha_link_section);
3641
3642 if (now_seg != alpha_link_section)
3643 {
3644 as_bad (_(".pdesc directive not in link (.link) section"));
3645 demand_empty_rest_of_line ();
3646 return;
3647 }
3648
3649 if ((alpha_evax_proc.symbol == 0)
3650 || (!S_IS_DEFINED (alpha_evax_proc.symbol)))
3651 {
3652 as_fatal (_(".pdesc has no matching .ent"));
3653 demand_empty_rest_of_line ();
3654 return;
3655 }
3656
3657 alpha_evax_proc.symbol->sy_obj = (valueT)seginfo->literal_pool_size;
3658
3659 expression (&exp);
3660 if (exp.X_op != O_symbol)
3661 {
3662 as_warn (_(".pdesc directive has no entry symbol"));
3663 demand_empty_rest_of_line ();
3664 return;
3665 }
3666
3667 entry_sym = make_expr_symbol (&exp);
3668 /* Save bfd symbol of proc desc in function symbol. */
3669 alpha_evax_proc.symbol->bsym->udata.p = (PTR)entry_sym->bsym;
3670
3671 SKIP_WHITESPACE ();
3672 if (*input_line_pointer++ != ',')
3673 {
3674 as_warn (_("No comma after .pdesc <entryname>"));
3675 demand_empty_rest_of_line ();
3676 return;
3677 }
3678
3679 SKIP_WHITESPACE ();
3680 name = input_line_pointer;
3681 name_end = get_symbol_end ();
3682
3683 if (strncmp(name, "stack", 5) == 0)
3684 {
3685 alpha_evax_proc.pdsckind = PDSC_S_K_KIND_FP_STACK;
3686 }
3687 else if (strncmp(name, "reg", 3) == 0)
3688 {
3689 alpha_evax_proc.pdsckind = PDSC_S_K_KIND_FP_REGISTER;
3690 }
3691 else if (strncmp(name, "null", 4) == 0)
3692 {
3693 alpha_evax_proc.pdsckind = PDSC_S_K_KIND_NULL;
3694 }
3695 else
3696 {
3697 as_fatal (_("unknown procedure kind"));
3698 demand_empty_rest_of_line ();
3699 return;
3700 }
3701
3702 *input_line_pointer = name_end;
3703 demand_empty_rest_of_line ();
3704
3705 #ifdef md_flush_pending_output
3706 md_flush_pending_output ();
3707 #endif
3708
3709 frag_align (3, 0, 0);
3710 p = frag_more (16);
3711 fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
3712 fixp->fx_done = 1;
3713 seginfo->literal_pool_size += 16;
3714
3715 *p = alpha_evax_proc.pdsckind
3716 | ((alpha_evax_proc.framereg == 29) ? PDSC_S_M_BASE_REG_IS_FP : 0);
3717 *(p+1) = PDSC_S_M_NATIVE
3718 | PDSC_S_M_NO_JACKET;
3719
3720 switch (alpha_evax_proc.pdsckind)
3721 {
3722 case PDSC_S_K_KIND_NULL:
3723 *(p+2) = 0;
3724 *(p+3) = 0;
3725 break;
3726 case PDSC_S_K_KIND_FP_REGISTER:
3727 *(p+2) = alpha_evax_proc.fp_save;
3728 *(p+3) = alpha_evax_proc.ra_save;
3729 break;
3730 case PDSC_S_K_KIND_FP_STACK:
3731 md_number_to_chars (p+2, (valueT)alpha_evax_proc.rsa_offset, 2);
3732 break;
3733 default: /* impossible */
3734 break;
3735 }
3736
3737 *(p+4) = 0;
3738 *(p+5) = alpha_evax_proc.type & 0x0f;
3739
3740 /* Signature offset. */
3741 md_number_to_chars (p+6, (valueT)0, 2);
3742
3743 fix_new_exp (frag_now, p-frag_now->fr_literal+8, 8, &exp, 0, BFD_RELOC_64);
3744
3745 if (alpha_evax_proc.pdsckind == PDSC_S_K_KIND_NULL)
3746 return;
3747
3748 /* Add dummy fix to make add_to_link_pool work. */
3749 p = frag_more (8);
3750 fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
3751 fixp->fx_done = 1;
3752 seginfo->literal_pool_size += 8;
3753
3754 /* pdesc+16: Size. */
3755 md_number_to_chars (p, (valueT)alpha_evax_proc.framesize, 4);
3756
3757 md_number_to_chars (p+4, (valueT)0, 2);
3758
3759 /* Entry length. */
3760 md_number_to_chars (p+6, alpha_evax_proc.prologue, 2);
3761
3762 if (alpha_evax_proc.pdsckind == PDSC_S_K_KIND_FP_REGISTER)
3763 return;
3764
3765 /* Add dummy fix to make add_to_link_pool work. */
3766 p = frag_more (8);
3767 fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
3768 fixp->fx_done = 1;
3769 seginfo->literal_pool_size += 8;
3770
3771 /* pdesc+24: register masks. */
3772
3773 md_number_to_chars (p, alpha_evax_proc.imask, 4);
3774 md_number_to_chars (p+4, alpha_evax_proc.fmask, 4);
3775
3776 return;
3777 }
3778
3779
3780 /* Support for crash debug on vms. */
3781
3782 static void
3783 s_alpha_name (ignore)
3784 int ignore;
3785 {
3786 register char *p;
3787 expressionS exp;
3788 segment_info_type *seginfo = seg_info (alpha_link_section);
3789
3790 if (now_seg != alpha_link_section)
3791 {
3792 as_bad (_(".name directive not in link (.link) section"));
3793 demand_empty_rest_of_line ();
3794 return;
3795 }
3796
3797 expression (&exp);
3798 if (exp.X_op != O_symbol)
3799 {
3800 as_warn (_(".name directive has no symbol"));
3801 demand_empty_rest_of_line ();
3802 return;
3803 }
3804
3805 demand_empty_rest_of_line ();
3806
3807 #ifdef md_flush_pending_output
3808 md_flush_pending_output ();
3809 #endif
3810
3811 frag_align (3, 0, 0);
3812 p = frag_more (8);
3813 seginfo->literal_pool_size += 8;
3814
3815 fix_new_exp (frag_now, p-frag_now->fr_literal, 8, &exp, 0, BFD_RELOC_64);
3816
3817 return;
3818 }
3819
3820
3821 static void
3822 s_alpha_linkage (ignore)
3823 int ignore;
3824 {
3825 expressionS exp;
3826 char *p;
3827
3828 #ifdef md_flush_pending_output
3829 md_flush_pending_output ();
3830 #endif
3831
3832 expression (&exp);
3833 if (exp.X_op != O_symbol)
3834 {
3835 as_fatal (_("No symbol after .linkage"));
3836 }
3837 else
3838 {
3839 p = frag_more (LKP_S_K_SIZE);
3840 memset (p, 0, LKP_S_K_SIZE);
3841 fix_new_exp (frag_now, p - frag_now->fr_literal, LKP_S_K_SIZE, &exp, 0,\
3842 BFD_RELOC_ALPHA_LINKAGE);
3843 }
3844 demand_empty_rest_of_line ();
3845
3846 return;
3847 }
3848
3849
3850 static void
3851 s_alpha_code_address (ignore)
3852 int ignore;
3853 {
3854 expressionS exp;
3855 char *p;
3856
3857 #ifdef md_flush_pending_output
3858 md_flush_pending_output ();
3859 #endif
3860
3861 expression (&exp);
3862 if (exp.X_op != O_symbol)
3863 {
3864 as_fatal (_("No symbol after .code_address"));
3865 }
3866 else
3867 {
3868 p = frag_more (8);
3869 memset (p, 0, 8);
3870 fix_new_exp (frag_now, p - frag_now->fr_literal, 8, &exp, 0,\
3871 BFD_RELOC_ALPHA_CODEADDR);
3872 }
3873 demand_empty_rest_of_line ();
3874
3875 return;
3876 }
3877
3878
3879 static void
3880 s_alpha_fp_save (ignore)
3881 int ignore;
3882 {
3883
3884 alpha_evax_proc.fp_save = tc_get_register (1);
3885
3886 demand_empty_rest_of_line ();
3887 return;
3888 }
3889
3890
3891 static void
3892 s_alpha_mask (ignore)
3893 int ignore;
3894 {
3895 long val;
3896
3897 if (get_absolute_expression_and_terminator (&val) != ',')
3898 {
3899 as_warn (_("Bad .mask directive"));
3900 --input_line_pointer;
3901 }
3902 else
3903 {
3904 alpha_evax_proc.imask = val;
3905 (void)get_absolute_expression ();
3906 }
3907 demand_empty_rest_of_line ();
3908
3909 return;
3910 }
3911
3912
3913 static void
3914 s_alpha_fmask (ignore)
3915 int ignore;
3916 {
3917 long val;
3918
3919 if (get_absolute_expression_and_terminator (&val) != ',')
3920 {
3921 as_warn (_("Bad .fmask directive"));
3922 --input_line_pointer;
3923 }
3924 else
3925 {
3926 alpha_evax_proc.fmask = val;
3927 (void) get_absolute_expression ();
3928 }
3929 demand_empty_rest_of_line ();
3930
3931 return;
3932 }
3933
3934 static void
3935 s_alpha_end (ignore)
3936 int ignore;
3937 {
3938 char c;
3939
3940 c = get_symbol_end ();
3941 *input_line_pointer = c;
3942 demand_empty_rest_of_line ();
3943 alpha_evax_proc.symbol = 0;
3944
3945 return;
3946 }
3947
3948
3949 static void
3950 s_alpha_file (ignore)
3951 int ignore;
3952 {
3953 symbolS *s;
3954 int length;
3955 static char case_hack[32];
3956
3957 extern char *demand_copy_string PARAMS ((int *lenP));
3958
3959 sprintf (case_hack, "<CASE:%01d%01d>",
3960 alpha_flag_hash_long_names, alpha_flag_show_after_trunc);
3961
3962 s = symbol_find_or_make (case_hack);
3963 s->bsym->flags |= BSF_FILE;
3964
3965 get_absolute_expression ();
3966 s = symbol_find_or_make (demand_copy_string (&length));
3967 s->bsym->flags |= BSF_FILE;
3968 demand_empty_rest_of_line ();
3969
3970 return;
3971 }
3972 #endif /* OBJ_EVAX */
3973
3974 /* Handle the .gprel32 pseudo op. */
3975
3976 static void
3977 s_alpha_gprel32 (ignore)
3978 int ignore;
3979 {
3980 expressionS e;
3981 char *p;
3982
3983 SKIP_WHITESPACE ();
3984 expression (&e);
3985
3986 #ifdef OBJ_ELF
3987 switch (e.X_op)
3988 {
3989 case O_constant:
3990 e.X_add_symbol = section_symbol(absolute_section);
3991 e.X_op = O_symbol;
3992 /* FALLTHRU */
3993 case O_symbol:
3994 break;
3995 default:
3996 abort();
3997 }
3998 #else
3999 #ifdef OBJ_ECOFF
4000 switch (e.X_op)
4001 {
4002 case O_constant:
4003 e.X_add_symbol = section_symbol (absolute_section);
4004 /* fall through */
4005 case O_symbol:
4006 e.X_op = O_subtract;
4007 e.X_op_symbol = alpha_gp_symbol;
4008 break;
4009 default:
4010 abort ();
4011 }
4012 #endif
4013 #endif
4014
4015 if (alpha_auto_align_on && alpha_current_align < 2)
4016 alpha_align (2, (char *) NULL, alpha_insn_label, 0);
4017 if (alpha_current_align > 2)
4018 alpha_current_align = 2;
4019 alpha_insn_label = NULL;
4020
4021 p = frag_more (4);
4022 memset (p, 0, 4);
4023 fix_new_exp (frag_now, p-frag_now->fr_literal, 4,
4024 &e, 0, BFD_RELOC_GPREL32);
4025 }
4026
4027 /* Handle floating point allocation pseudo-ops. This is like the
4028 generic vresion, but it makes sure the current label, if any, is
4029 correctly aligned. */
4030
4031 static void
4032 s_alpha_float_cons (type)
4033 int type;
4034 {
4035 int log_size;
4036
4037 switch (type)
4038 {
4039 default:
4040 case 'f':
4041 case 'F':
4042 log_size = 2;
4043 break;
4044
4045 case 'd':
4046 case 'D':
4047 case 'G':
4048 log_size = 3;
4049 break;
4050
4051 case 'x':
4052 case 'X':
4053 case 'p':
4054 case 'P':
4055 log_size = 4;
4056 break;
4057 }
4058
4059 if (alpha_auto_align_on && alpha_current_align < log_size)
4060 alpha_align (log_size, (char *) NULL, alpha_insn_label, 0);
4061 if (alpha_current_align > log_size)
4062 alpha_current_align = log_size;
4063 alpha_insn_label = NULL;
4064
4065 float_cons (type);
4066 }
4067
4068 /* Handle the .proc pseudo op. We don't really do much with it except
4069 parse it. */
4070
4071 static void
4072 s_alpha_proc (is_static)
4073 int is_static;
4074 {
4075 char *name;
4076 char c;
4077 char *p;
4078 symbolS *symbolP;
4079 int temp;
4080
4081 /* Takes ".proc name,nargs" */
4082 SKIP_WHITESPACE ();
4083 name = input_line_pointer;
4084 c = get_symbol_end ();
4085 p = input_line_pointer;
4086 symbolP = symbol_find_or_make (name);
4087 *p = c;
4088 SKIP_WHITESPACE ();
4089 if (*input_line_pointer != ',')
4090 {
4091 *p = 0;
4092 as_warn (_("Expected comma after name \"%s\""), name);
4093 *p = c;
4094 temp = 0;
4095 ignore_rest_of_line ();
4096 }
4097 else
4098 {
4099 input_line_pointer++;
4100 temp = get_absolute_expression ();
4101 }
4102 /* symbolP->sy_other = (signed char) temp; */
4103 as_warn (_("unhandled: .proc %s,%d"), name, temp);
4104 demand_empty_rest_of_line ();
4105 }
4106
4107 /* Handle the .set pseudo op. This is used to turn on and off most of
4108 the assembler features. */
4109
4110 static void
4111 s_alpha_set (x)
4112 int x;
4113 {
4114 char *name, ch, *s;
4115 int yesno = 1;
4116
4117 SKIP_WHITESPACE ();
4118 name = input_line_pointer;
4119 ch = get_symbol_end ();
4120
4121 s = name;
4122 if (s[0] == 'n' && s[1] == 'o')
4123 {
4124 yesno = 0;
4125 s += 2;
4126 }
4127 if (!strcmp ("reorder", s))
4128 /* ignore */ ;
4129 else if (!strcmp ("at", s))
4130 alpha_noat_on = !yesno;
4131 else if (!strcmp ("macro", s))
4132 alpha_macros_on = yesno;
4133 else if (!strcmp ("move", s))
4134 /* ignore */ ;
4135 else if (!strcmp ("volatile", s))
4136 /* ignore */ ;
4137 else
4138 as_warn (_("Tried to .set unrecognized mode `%s'"), name);
4139
4140 *input_line_pointer = ch;
4141 demand_empty_rest_of_line ();
4142 }
4143
4144 /* Handle the .base pseudo op. This changes the assembler's notion of
4145 the $gp register. */
4146
4147 static void
4148 s_alpha_base (ignore)
4149 int ignore;
4150 {
4151 #if 0
4152 if (first_32bit_quadrant)
4153 {
4154 /* not fatal, but it might not work in the end */
4155 as_warn (_("File overrides no-base-register option."));
4156 first_32bit_quadrant = 0;
4157 }
4158 #endif
4159
4160 SKIP_WHITESPACE ();
4161 if (*input_line_pointer == '$')
4162 { /* $rNN form */
4163 input_line_pointer++;
4164 if (*input_line_pointer == 'r')
4165 input_line_pointer++;
4166 }
4167
4168 alpha_gp_register = get_absolute_expression ();
4169 if (alpha_gp_register < 0 || alpha_gp_register > 31)
4170 {
4171 alpha_gp_register = AXP_REG_GP;
4172 as_warn (_("Bad base register, using $%d."), alpha_gp_register);
4173 }
4174
4175 demand_empty_rest_of_line ();
4176 }
4177
4178 /* Handle the .align pseudo-op. This aligns to a power of two. It
4179 also adjusts any current instruction label. We treat this the same
4180 way the MIPS port does: .align 0 turns off auto alignment. */
4181
4182 static void
4183 s_alpha_align (ignore)
4184 int ignore;
4185 {
4186 int align;
4187 char fill, *pfill;
4188 long max_alignment = 15;
4189
4190 align = get_absolute_expression ();
4191 if (align > max_alignment)
4192 {
4193 align = max_alignment;
4194 as_bad (_("Alignment too large: %d. assumed"), align);
4195 }
4196 else if (align < 0)
4197 {
4198 as_warn (_("Alignment negative: 0 assumed"));
4199 align = 0;
4200 }
4201
4202 if (*input_line_pointer == ',')
4203 {
4204 input_line_pointer++;
4205 fill = get_absolute_expression ();
4206 pfill = &fill;
4207 }
4208 else
4209 pfill = NULL;
4210
4211 if (align != 0)
4212 {
4213 alpha_auto_align_on = 1;
4214 alpha_align (align, pfill, alpha_insn_label, 1);
4215 }
4216 else
4217 {
4218 alpha_auto_align_on = 0;
4219 }
4220
4221 demand_empty_rest_of_line ();
4222 }
4223
4224 /* Hook the normal string processor to reset known alignment. */
4225
4226 static void
4227 s_alpha_stringer (terminate)
4228 int terminate;
4229 {
4230 alpha_current_align = 0;
4231 alpha_insn_label = NULL;
4232 stringer (terminate);
4233 }
4234
4235 /* Hook the normal space processing to reset known alignment. */
4236
4237 static void
4238 s_alpha_space (ignore)
4239 int ignore;
4240 {
4241 alpha_current_align = 0;
4242 alpha_insn_label = NULL;
4243 s_space (ignore);
4244 }
4245
4246 /* Hook into cons for auto-alignment. */
4247
4248 void
4249 alpha_cons_align (size)
4250 int size;
4251 {
4252 int log_size;
4253
4254 log_size = 0;
4255 while ((size >>= 1) != 0)
4256 ++log_size;
4257
4258 if (alpha_auto_align_on && alpha_current_align < log_size)
4259 alpha_align (log_size, (char *) NULL, alpha_insn_label, 0);
4260 if (alpha_current_align > log_size)
4261 alpha_current_align = log_size;
4262 alpha_insn_label = NULL;
4263 }
4264
4265 /* Here come the .uword, .ulong, and .uquad explicitly unaligned
4266 pseudos. We just turn off auto-alignment and call down to cons. */
4267
4268 static void
4269 s_alpha_ucons (bytes)
4270 int bytes;
4271 {
4272 int hold = alpha_auto_align_on;
4273 alpha_auto_align_on = 0;
4274 cons (bytes);
4275 alpha_auto_align_on = hold;
4276 }
4277
4278 /* Switch the working cpu type. */
4279
4280 static void
4281 s_alpha_arch (ignored)
4282 int ignored;
4283 {
4284 char *name, ch;
4285 const struct cpu_type *p;
4286
4287 SKIP_WHITESPACE ();
4288 name = input_line_pointer;
4289 ch = get_symbol_end ();
4290
4291 for (p = cpu_types; p->name; ++p)
4292 if (strcmp(name, p->name) == 0)
4293 {
4294 alpha_target_name = p->name, alpha_target = p->flags;
4295 goto found;
4296 }
4297 as_warn("Unknown CPU identifier `%s'", name);
4298
4299 found:
4300 *input_line_pointer = ch;
4301 demand_empty_rest_of_line ();
4302 }
4303
4304 \f
4305
4306 #ifdef DEBUG1
4307 /* print token expression with alpha specific extension. */
4308
4309 static void
4310 alpha_print_token(f, exp)
4311 FILE *f;
4312 const expressionS *exp;
4313 {
4314 switch (exp->X_op)
4315 {
4316 case O_cpregister:
4317 putc (',', f);
4318 /* FALLTHRU */
4319 case O_pregister:
4320 putc ('(', f);
4321 {
4322 expressionS nexp = *exp;
4323 nexp.X_op = O_register;
4324 print_expr (f, &nexp);
4325 }
4326 putc (')', f);
4327 break;
4328 default:
4329 print_expr (f, exp);
4330 break;
4331 }
4332 return;
4333 }
4334 #endif
4335 \f
4336 /* The target specific pseudo-ops which we support. */
4337
4338 const pseudo_typeS md_pseudo_table[] =
4339 {
4340 #ifdef OBJ_ECOFF
4341 {"comm", s_alpha_comm, 0}, /* osf1 compiler does this */
4342 {"rdata", s_alpha_rdata, 0},
4343 #endif
4344 {"text", s_alpha_text, 0},
4345 {"data", s_alpha_data, 0},
4346 #ifdef OBJ_ECOFF
4347 {"sdata", s_alpha_sdata, 0},
4348 #endif
4349 #ifdef OBJ_ELF
4350 {"section", s_alpha_section, 0},
4351 {"section.s", s_alpha_section, 0},
4352 {"sect", s_alpha_section, 0},
4353 {"sect.s", s_alpha_section, 0},
4354 #endif
4355 #ifdef OBJ_EVAX
4356 { "pdesc", s_alpha_pdesc, 0},
4357 { "name", s_alpha_name, 0},
4358 { "linkage", s_alpha_linkage, 0},
4359 { "code_address", s_alpha_code_address, 0},
4360 { "ent", s_alpha_ent, 0},
4361 { "frame", s_alpha_frame, 0},
4362 { "fp_save", s_alpha_fp_save, 0},
4363 { "mask", s_alpha_mask, 0},
4364 { "fmask", s_alpha_fmask, 0},
4365 { "end", s_alpha_end, 0},
4366 { "file", s_alpha_file, 0},
4367 { "rdata", s_alpha_section, 1},
4368 { "comm", s_alpha_comm, 0},
4369 { "link", s_alpha_section, 3},
4370 { "ctors", s_alpha_section, 4},
4371 { "dtors", s_alpha_section, 5},
4372 #endif
4373 #ifdef OBJ_ELF
4374 {"prologue", s_alpha_prologue, 0},
4375 #else
4376 {"prologue", s_ignore, 0},
4377 #endif
4378 {"gprel32", s_alpha_gprel32, 0},
4379 {"t_floating", s_alpha_float_cons, 'd'},
4380 {"s_floating", s_alpha_float_cons, 'f'},
4381 {"f_floating", s_alpha_float_cons, 'F'},
4382 {"g_floating", s_alpha_float_cons, 'G'},
4383 {"d_floating", s_alpha_float_cons, 'D'},
4384
4385 {"proc", s_alpha_proc, 0},
4386 {"aproc", s_alpha_proc, 1},
4387 {"set", s_alpha_set, 0},
4388 {"reguse", s_ignore, 0},
4389 {"livereg", s_ignore, 0},
4390 {"base", s_alpha_base, 0}, /*??*/
4391 {"option", s_ignore, 0},
4392 {"aent", s_ignore, 0},
4393 {"ugen", s_ignore, 0},
4394 {"eflag", s_ignore, 0},
4395
4396 {"align", s_alpha_align, 0},
4397 {"double", s_alpha_float_cons, 'd'},
4398 {"float", s_alpha_float_cons, 'f'},
4399 {"single", s_alpha_float_cons, 'f'},
4400 {"ascii", s_alpha_stringer, 0},
4401 {"asciz", s_alpha_stringer, 1},
4402 {"string", s_alpha_stringer, 1},
4403 {"space", s_alpha_space, 0},
4404 {"skip", s_alpha_space, 0},
4405 {"zero", s_alpha_space, 0},
4406
4407 /* Unaligned data pseudos. */
4408 {"uword", s_alpha_ucons, 2},
4409 {"ulong", s_alpha_ucons, 4},
4410 {"uquad", s_alpha_ucons, 8},
4411
4412 #ifdef OBJ_ELF
4413 /* Dwarf wants these versions of unaligned. */
4414 {"2byte", s_alpha_ucons, 2},
4415 {"4byte", s_alpha_ucons, 4},
4416 {"8byte", s_alpha_ucons, 8},
4417 #endif
4418
4419 /* We don't do any optimizing, so we can safely ignore these. */
4420 {"noalias", s_ignore, 0},
4421 {"alias", s_ignore, 0},
4422
4423 {"arch", s_alpha_arch, 0},
4424
4425 {NULL, 0, 0},
4426 };
4427
4428 \f
4429 /* Build a BFD section with its flags set appropriately for the .lita,
4430 .lit8, or .lit4 sections. */
4431
4432 static void
4433 create_literal_section (name, secp, symp)
4434 const char *name;
4435 segT *secp;
4436 symbolS **symp;
4437 {
4438 segT current_section = now_seg;
4439 int current_subsec = now_subseg;
4440 segT new_sec;
4441
4442 *secp = new_sec = subseg_new (name, 0);
4443 subseg_set (current_section, current_subsec);
4444 bfd_set_section_alignment (stdoutput, new_sec, 4);
4445 bfd_set_section_flags (stdoutput, new_sec,
4446 SEC_RELOC | SEC_ALLOC | SEC_LOAD | SEC_READONLY
4447 | SEC_DATA);
4448
4449 S_CLEAR_EXTERNAL (*symp = section_symbol (new_sec));
4450 }
4451
4452 #ifdef OBJ_ECOFF
4453
4454 /* @@@ GP selection voodoo. All of this seems overly complicated and
4455 unnecessary; which is the primary reason it's for ECOFF only. */
4456
4457 static inline void
4458 maybe_set_gp (sec)
4459 asection *sec;
4460 {
4461 bfd_vma vma;
4462 if (!sec)
4463 return;
4464 vma = bfd_get_section_vma (foo, sec);
4465 if (vma && vma < alpha_gp_value)
4466 alpha_gp_value = vma;
4467 }
4468
4469 static void
4470 select_gp_value ()
4471 {
4472 assert (alpha_gp_value == 0);
4473
4474 /* Get minus-one in whatever width... */
4475 alpha_gp_value = 0; alpha_gp_value--;
4476
4477 /* Select the smallest VMA of these existing sections. */
4478 maybe_set_gp (alpha_lita_section);
4479 #if 0
4480 /* These were disabled before -- should we use them? */
4481 maybe_set_gp (sdata);
4482 maybe_set_gp (lit8_sec);
4483 maybe_set_gp (lit4_sec);
4484 #endif
4485
4486 /* @@ Will a simple 0x8000 work here? If not, why not? */
4487 #define GP_ADJUSTMENT (0x8000 - 0x10)
4488
4489 alpha_gp_value += GP_ADJUSTMENT;
4490
4491 S_SET_VALUE (alpha_gp_symbol, alpha_gp_value);
4492
4493 #ifdef DEBUG1
4494 printf (_("Chose GP value of %lx\n"), alpha_gp_value);
4495 #endif
4496 }
4497 #endif /* OBJ_ECOFF */
4498
4499 /* Called internally to handle all alignment needs. This takes care
4500 of eliding calls to frag_align if'n the cached current alignment
4501 says we've already got it, as well as taking care of the auto-align
4502 feature wrt labels. */
4503
4504 static void
4505 alpha_align (n, pfill, label, force)
4506 int n;
4507 char *pfill;
4508 symbolS *label;
4509 int force;
4510 {
4511 if (alpha_current_align >= n)
4512 return;
4513
4514 if (pfill == NULL)
4515 {
4516 if (n > 2
4517 && (bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0)
4518 {
4519 static char const unop[4] = { 0x00, 0x00, 0xe0, 0x2f };
4520 static char const nopunop[8] = {
4521 0x1f, 0x04, 0xff, 0x47,
4522 0x00, 0x00, 0xe0, 0x2f
4523 };
4524
4525 /* First, make sure we're on a four-byte boundary, in case
4526 someone has been putting .byte values into the text
4527 section. The DEC assembler silently fills with unaligned
4528 no-op instructions. This will zero-fill, then nop-fill
4529 with proper alignment. */
4530 if (alpha_current_align < 2)
4531 frag_align (2, 0, 0);
4532 if (alpha_current_align < 3)
4533 frag_align_pattern (3, unop, sizeof unop, 0);
4534 if (n > 3)
4535 frag_align_pattern (n, nopunop, sizeof nopunop, 0);
4536 }
4537 else
4538 frag_align (n, 0, 0);
4539 }
4540 else
4541 frag_align (n, *pfill, 0);
4542
4543 alpha_current_align = n;
4544
4545 if (label != NULL)
4546 {
4547 assert (S_GET_SEGMENT (label) == now_seg);
4548 label->sy_frag = frag_now;
4549 S_SET_VALUE (label, (valueT) frag_now_fix ());
4550 }
4551
4552 record_alignment(now_seg, n);
4553
4554 /* ??? if alpha_flag_relax && force && elf, record the requested alignment
4555 in a reloc for the linker to see. */
4556 }
4557
4558 /* The Alpha has support for some VAX floating point types, as well as for
4559 IEEE floating point. We consider IEEE to be the primary floating point
4560 format, and sneak in the VAX floating point support here. */
4561 #define md_atof vax_md_atof
4562 #include "config/atof-vax.c"
This page took 0.130065 seconds and 4 git commands to generate.