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