08baf6be02abf690281ca86b8930685cf72d5885
[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 if (fixP->fx_pcrel)
1054 fixP->fx_r_type = BFD_RELOC_16_PCREL;
1055 size = 2;
1056 goto do_reloc_xx;
1057 case BFD_RELOC_32:
1058 if (fixP->fx_pcrel)
1059 fixP->fx_r_type = BFD_RELOC_32_PCREL;
1060 size = 4;
1061 goto do_reloc_xx;
1062 case BFD_RELOC_64:
1063 if (fixP->fx_pcrel)
1064 fixP->fx_r_type = BFD_RELOC_64_PCREL;
1065 size = 8;
1066 do_reloc_xx:
1067 if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0)
1068 {
1069 md_number_to_chars (fixpos, value, size);
1070 goto done;
1071 }
1072 return 1;
1073
1074 #ifdef OBJ_ECOFF
1075 case BFD_RELOC_GPREL32:
1076 assert (fixP->fx_subsy == alpha_gp_symbol);
1077 fixP->fx_subsy = 0;
1078 /* FIXME: inherited this obliviousness of `value' -- why? */
1079 md_number_to_chars (fixpos, -alpha_gp_value, 4);
1080 break;
1081 #endif
1082 #ifdef OBJ_ELF
1083 case BFD_RELOC_GPREL32:
1084 return 1;
1085 #endif
1086
1087 case BFD_RELOC_23_PCREL_S2:
1088 if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0)
1089 {
1090 image = bfd_getl32(fixpos);
1091 image = (image & ~0x1FFFFF) | ((value >> 2) & 0x1FFFFF);
1092 goto write_done;
1093 }
1094 return 1;
1095
1096 case BFD_RELOC_ALPHA_HINT:
1097 if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0)
1098 {
1099 image = bfd_getl32(fixpos);
1100 image = (image & ~0x3FFF) | ((value >> 2) & 0x3FFF);
1101 goto write_done;
1102 }
1103 return 1;
1104
1105 #ifdef OBJ_ECOFF
1106 case BFD_RELOC_ALPHA_LITERAL:
1107 md_number_to_chars (fixpos, value, 2);
1108 return 1;
1109
1110 case BFD_RELOC_ALPHA_LITUSE:
1111 return 1;
1112 #endif
1113 #ifdef OBJ_ELF
1114 case BFD_RELOC_ALPHA_ELF_LITERAL:
1115 case BFD_RELOC_ALPHA_LITUSE:
1116 return 1;
1117 #endif
1118 #ifdef OBJ_EVAX
1119 case BFD_RELOC_ALPHA_LINKAGE:
1120 case BFD_RELOC_ALPHA_CODEADDR:
1121 return 1;
1122 #endif
1123
1124 default:
1125 {
1126 const struct alpha_operand *operand;
1127
1128 if ((int)fixP->fx_r_type >= 0)
1129 as_fatal ("unhandled relocation type %s",
1130 bfd_get_reloc_code_name (fixP->fx_r_type));
1131
1132 assert (-(int)fixP->fx_r_type < alpha_num_operands);
1133 operand = &alpha_operands[-(int)fixP->fx_r_type];
1134
1135 /* The rest of these fixups only exist internally during symbol
1136 resolution and have no representation in the object file.
1137 Therefore they must be completely resolved as constants. */
1138
1139 if (fixP->fx_addsy != 0
1140 && fixP->fx_addsy->bsym->section != absolute_section)
1141 as_bad_where (fixP->fx_file, fixP->fx_line,
1142 "non-absolute expression in constant field");
1143
1144 image = bfd_getl32(fixpos);
1145 image = insert_operand(image, operand, (offsetT)value,
1146 fixP->fx_file, fixP->fx_line);
1147 }
1148 goto write_done;
1149 }
1150
1151 if (fixP->fx_addsy != 0 || fixP->fx_pcrel != 0)
1152 return 1;
1153 else
1154 {
1155 as_warn_where(fixP->fx_file, fixP->fx_line,
1156 "type %d reloc done?\n", (int)fixP->fx_r_type);
1157 goto done;
1158 }
1159
1160 write_done:
1161 md_number_to_chars(fixpos, image, 4);
1162
1163 done:
1164 fixP->fx_done = 1;
1165 return 0;
1166 }
1167
1168 /*
1169 * Look for a register name in the given symbol.
1170 */
1171
1172 symbolS *
1173 md_undefined_symbol(name)
1174 char *name;
1175 {
1176 if (*name == '$')
1177 {
1178 int is_float = 0, num;
1179
1180 switch (*++name)
1181 {
1182 case 'f':
1183 if (name[1] == 'p' && name[2] == '\0')
1184 return alpha_register_table[AXP_REG_FP];
1185 is_float = 32;
1186 /* FALLTHRU */
1187
1188 case 'r':
1189 if (!isdigit(*++name))
1190 break;
1191 /* FALLTHRU */
1192
1193 case '0': case '1': case '2': case '3': case '4':
1194 case '5': case '6': case '7': case '8': case '9':
1195 if (name[1] == '\0')
1196 num = name[0] - '0';
1197 else if (name[0] != '0' && isdigit(name[1]) && name[2] == '\0')
1198 {
1199 num = (name[0] - '0') * 10 + name[1] - '0';
1200 if (num >= 32)
1201 break;
1202 }
1203 else
1204 break;
1205
1206 if (!alpha_noat_on && num == AXP_REG_AT)
1207 as_warn("Used $at without \".set noat\"");
1208 return alpha_register_table[num + is_float];
1209
1210 case 'a':
1211 if (name[1] == 't' && name[2] == '\0')
1212 {
1213 if (!alpha_noat_on)
1214 as_warn("Used $at without \".set noat\"");
1215 return alpha_register_table[AXP_REG_AT];
1216 }
1217 break;
1218
1219 case 'g':
1220 if (name[1] == 'p' && name[2] == '\0')
1221 return alpha_register_table[alpha_gp_register];
1222 break;
1223
1224 case 's':
1225 if (name[1] == 'p' && name[2] == '\0')
1226 return alpha_register_table[AXP_REG_SP];
1227 break;
1228 }
1229 }
1230 return NULL;
1231 }
1232
1233 #ifdef OBJ_ECOFF
1234 /* @@@ Magic ECOFF bits. */
1235
1236 void
1237 alpha_frob_ecoff_data ()
1238 {
1239 select_gp_value ();
1240 /* $zero and $f31 are read-only */
1241 alpha_gprmask &= ~1;
1242 alpha_fprmask &= ~1;
1243 }
1244 #endif
1245
1246 /* Hook to remember a recently defined label so that the auto-align
1247 code can adjust the symbol after we know what alignment will be
1248 required. */
1249
1250 void
1251 alpha_define_label (sym)
1252 symbolS *sym;
1253 {
1254 alpha_insn_label = sym;
1255 }
1256
1257 /* Return true if we must always emit a reloc for a type and false if
1258 there is some hope of resolving it a assembly time. */
1259
1260 int
1261 alpha_force_relocation (f)
1262 fixS *f;
1263 {
1264 switch (f->fx_r_type)
1265 {
1266 case BFD_RELOC_ALPHA_GPDISP_HI16:
1267 case BFD_RELOC_ALPHA_GPDISP_LO16:
1268 case BFD_RELOC_ALPHA_GPDISP:
1269 #ifdef OBJ_ECOFF
1270 case BFD_RELOC_ALPHA_LITERAL:
1271 #endif
1272 #ifdef OBJ_ELF
1273 case BFD_RELOC_ALPHA_ELF_LITERAL:
1274 #endif
1275 case BFD_RELOC_ALPHA_LITUSE:
1276 case BFD_RELOC_GPREL32:
1277 #ifdef OBJ_EVAX
1278 case BFD_RELOC_ALPHA_LINKAGE:
1279 case BFD_RELOC_ALPHA_CODEADDR:
1280 #endif
1281 return 1;
1282
1283 case BFD_RELOC_23_PCREL_S2:
1284 case BFD_RELOC_32:
1285 case BFD_RELOC_64:
1286 case BFD_RELOC_ALPHA_HINT:
1287 return 0;
1288
1289 default:
1290 assert((int)f->fx_r_type < 0 && -(int)f->fx_r_type < alpha_num_operands);
1291 return 0;
1292 }
1293 }
1294
1295 /* Return true if we can partially resolve a relocation now. */
1296
1297 int
1298 alpha_fix_adjustable (f)
1299 fixS *f;
1300 {
1301 #ifdef OBJ_ELF
1302 /* Prevent all adjustments to global symbols */
1303 if (S_IS_EXTERN (f->fx_addsy))
1304 return 0;
1305 #endif
1306
1307 /* Are there any relocation types for which we must generate a reloc
1308 but we can adjust the values contained within it? */
1309 switch (f->fx_r_type)
1310 {
1311 case BFD_RELOC_ALPHA_GPDISP_HI16:
1312 case BFD_RELOC_ALPHA_GPDISP_LO16:
1313 case BFD_RELOC_ALPHA_GPDISP:
1314 return 0;
1315
1316 #ifdef OBJ_ECOFF
1317 case BFD_RELOC_ALPHA_LITERAL:
1318 #endif
1319 #ifdef OBJ_ELF
1320 case BFD_RELOC_ALPHA_ELF_LITERAL:
1321 #endif
1322 #ifdef OBJ_EVAX
1323 case BFD_RELOC_ALPHA_LINKAGE:
1324 case BFD_RELOC_ALPHA_CODEADDR:
1325 #endif
1326 return 1;
1327
1328 case BFD_RELOC_ALPHA_LITUSE:
1329 return 0;
1330
1331 case BFD_RELOC_GPREL32:
1332 case BFD_RELOC_23_PCREL_S2:
1333 case BFD_RELOC_32:
1334 case BFD_RELOC_64:
1335 case BFD_RELOC_ALPHA_HINT:
1336 return 1;
1337
1338 default:
1339 assert ((int)f->fx_r_type < 0
1340 && - (int)f->fx_r_type < alpha_num_operands);
1341 return 1;
1342 }
1343 /*NOTREACHED*/
1344 }
1345
1346 /* Generate the BFD reloc to be stuck in the object file from the
1347 fixup used internally in the assembler. */
1348
1349 arelent *
1350 tc_gen_reloc (sec, fixp)
1351 asection *sec;
1352 fixS *fixp;
1353 {
1354 arelent *reloc;
1355
1356 reloc = (arelent *) xmalloc (sizeof (arelent));
1357 reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym;
1358 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
1359
1360 /* Make sure none of our internal relocations make it this far.
1361 They'd better have been fully resolved by this point. */
1362 assert ((int)fixp->fx_r_type > 0);
1363
1364 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
1365 if (reloc->howto == NULL)
1366 {
1367 as_bad_where (fixp->fx_file, fixp->fx_line,
1368 "cannot represent `%s' relocation in object file",
1369 bfd_get_reloc_code_name (fixp->fx_r_type));
1370 return NULL;
1371 }
1372
1373 if (!fixp->fx_pcrel != !reloc->howto->pc_relative)
1374 {
1375 as_fatal ("internal error? cannot generate `%s' relocation",
1376 bfd_get_reloc_code_name (fixp->fx_r_type));
1377 }
1378 assert (!fixp->fx_pcrel == !reloc->howto->pc_relative);
1379
1380 #ifdef OBJ_ECOFF
1381 if (fixp->fx_r_type == BFD_RELOC_ALPHA_LITERAL)
1382 {
1383 /* fake out bfd_perform_relocation. sigh */
1384 reloc->addend = -alpha_gp_value;
1385 }
1386 else
1387 #endif
1388 {
1389 reloc->addend = fixp->fx_offset;
1390 #ifdef OBJ_ELF
1391 /*
1392 * Ohhh, this is ugly. The problem is that if this is a local global
1393 * symbol, the relocation will entirely be performed at link time, not
1394 * at assembly time. bfd_perform_reloc doesn't know about this sort
1395 * of thing, and as a result we need to fake it out here.
1396 */
1397 if (S_IS_EXTERN (fixp->fx_addsy) && !S_IS_COMMON(fixp->fx_addsy))
1398 reloc->addend -= fixp->fx_addsy->bsym->value;
1399 #endif
1400 }
1401
1402 return reloc;
1403 }
1404
1405 /* Parse a register name off of the input_line and return a register
1406 number. Gets md_undefined_symbol above to do the register name
1407 matching for us.
1408
1409 Only called as a part of processing the ECOFF .frame directive. */
1410
1411 int
1412 tc_get_register (frame)
1413 int frame;
1414 {
1415 int framereg = AXP_REG_SP;
1416
1417 SKIP_WHITESPACE ();
1418 if (*input_line_pointer == '$')
1419 {
1420 char *s = input_line_pointer;
1421 char c = get_symbol_end ();
1422 symbolS *sym = md_undefined_symbol (s);
1423
1424 *strchr(s, '\0') = c;
1425 if (sym && (framereg = S_GET_VALUE (sym)) <= 31)
1426 goto found;
1427 }
1428 as_warn ("frame reg expected, using $%d.", framereg);
1429
1430 found:
1431 note_gpreg (framereg);
1432 return framereg;
1433 }
1434
1435 /* This is called before the symbol table is processed. In order to
1436 work with gcc when using mips-tfile, we must keep all local labels.
1437 However, in other cases, we want to discard them. If we were
1438 called with -g, but we didn't see any debugging information, it may
1439 mean that gcc is smuggling debugging information through to
1440 mips-tfile, in which case we must generate all local labels. */
1441
1442 #ifdef OBJ_ECOFF
1443
1444 void
1445 alpha_frob_file_before_adjust ()
1446 {
1447 if (alpha_debug != 0
1448 && ! ecoff_debugging_seen)
1449 flag_keep_locals = 1;
1450 }
1451
1452 #endif /* OBJ_ECOFF */
1453 \f
1454 /* Parse the arguments to an opcode. */
1455
1456 static int
1457 tokenize_arguments (str, tok, ntok)
1458 char *str;
1459 expressionS tok[];
1460 int ntok;
1461 {
1462 expressionS *end_tok = tok + ntok;
1463 char *old_input_line_pointer;
1464 int saw_comma = 0, saw_arg = 0;
1465
1466 memset (tok, 0, sizeof (*tok) * ntok);
1467
1468 /* Save and restore input_line_pointer around this function */
1469 old_input_line_pointer = input_line_pointer;
1470 input_line_pointer = str;
1471
1472 while (tok < end_tok && *input_line_pointer)
1473 {
1474 SKIP_WHITESPACE ();
1475 switch (*input_line_pointer)
1476 {
1477 case '\0':
1478 goto fini;
1479
1480 case ',':
1481 ++input_line_pointer;
1482 if (saw_comma || !saw_arg)
1483 goto err;
1484 saw_comma = 1;
1485 break;
1486
1487 case '(':
1488 {
1489 char *hold = input_line_pointer++;
1490
1491 /* First try for parenthesized register ... */
1492 expression (tok);
1493 if (*input_line_pointer == ')' && tok->X_op == O_register)
1494 {
1495 tok->X_op = (saw_comma ? O_cpregister : O_pregister);
1496 saw_comma = 0;
1497 saw_arg = 1;
1498 ++input_line_pointer;
1499 ++tok;
1500 break;
1501 }
1502
1503 /* ... then fall through to plain expression */
1504 input_line_pointer = hold;
1505 }
1506
1507 default:
1508 if (saw_arg && !saw_comma)
1509 goto err;
1510 expression (tok);
1511 if (tok->X_op == O_illegal || tok->X_op == O_absent)
1512 goto err;
1513
1514 saw_comma = 0;
1515 saw_arg = 1;
1516 ++tok;
1517 break;
1518 }
1519 }
1520
1521 fini:
1522 if (saw_comma)
1523 goto err;
1524 input_line_pointer = old_input_line_pointer;
1525 return ntok - (end_tok - tok);
1526
1527 err:
1528 input_line_pointer = old_input_line_pointer;
1529 return -1;
1530 }
1531
1532 /* Search forward through all variants of an opcode looking for a
1533 syntax match. */
1534
1535 static const struct alpha_opcode *
1536 find_opcode_match(first_opcode, tok, pntok, pcpumatch)
1537 const struct alpha_opcode *first_opcode;
1538 const expressionS *tok;
1539 int *pntok;
1540 int *pcpumatch;
1541 {
1542 const struct alpha_opcode *opcode = first_opcode;
1543 int ntok = *pntok;
1544 int got_cpu_match = 0;
1545
1546 do
1547 {
1548 const unsigned char *opidx;
1549 int tokidx = 0;
1550
1551 /* Don't match opcodes that don't exist on this architecture */
1552 if (!(opcode->flags & alpha_target))
1553 goto match_failed;
1554
1555 got_cpu_match = 1;
1556
1557 for (opidx = opcode->operands; *opidx; ++opidx)
1558 {
1559 const struct alpha_operand *operand = &alpha_operands[*opidx];
1560
1561 /* only take input from real operands */
1562 if (operand->flags & AXP_OPERAND_FAKE)
1563 continue;
1564
1565 /* when we expect input, make sure we have it */
1566 if (tokidx >= ntok)
1567 {
1568 if ((operand->flags & AXP_OPERAND_OPTIONAL_MASK) == 0)
1569 goto match_failed;
1570 continue;
1571 }
1572
1573 /* match operand type with expression type */
1574 switch (operand->flags & AXP_OPERAND_TYPECHECK_MASK)
1575 {
1576 case AXP_OPERAND_IR:
1577 if (tok[tokidx].X_op != O_register
1578 || !is_ir_num(tok[tokidx].X_add_number))
1579 goto match_failed;
1580 break;
1581 case AXP_OPERAND_FPR:
1582 if (tok[tokidx].X_op != O_register
1583 || !is_fpr_num(tok[tokidx].X_add_number))
1584 goto match_failed;
1585 break;
1586 case AXP_OPERAND_IR|AXP_OPERAND_PARENS:
1587 if (tok[tokidx].X_op != O_pregister
1588 || !is_ir_num(tok[tokidx].X_add_number))
1589 goto match_failed;
1590 break;
1591 case AXP_OPERAND_IR|AXP_OPERAND_PARENS|AXP_OPERAND_COMMA:
1592 if (tok[tokidx].X_op != O_cpregister
1593 || !is_ir_num(tok[tokidx].X_add_number))
1594 goto match_failed;
1595 break;
1596
1597 case AXP_OPERAND_RELATIVE:
1598 case AXP_OPERAND_SIGNED:
1599 case AXP_OPERAND_UNSIGNED:
1600 switch (tok[tokidx].X_op)
1601 {
1602 case O_illegal:
1603 case O_absent:
1604 case O_register:
1605 case O_pregister:
1606 case O_cpregister:
1607 goto match_failed;
1608 }
1609 break;
1610
1611 default:
1612 /* everything else should have been fake */
1613 abort();
1614 }
1615 ++tokidx;
1616 }
1617
1618 /* possible match -- did we use all of our input? */
1619 if (tokidx == ntok)
1620 {
1621 *pntok = ntok;
1622 return opcode;
1623 }
1624
1625 match_failed:;
1626 }
1627 while (++opcode-alpha_opcodes < alpha_num_opcodes
1628 && !strcmp(opcode->name, first_opcode->name));
1629
1630 if (*pcpumatch)
1631 *pcpumatch = got_cpu_match;
1632
1633 return NULL;
1634 }
1635
1636 /* Search forward through all variants of a macro looking for a syntax
1637 match. */
1638
1639 static const struct alpha_macro *
1640 find_macro_match(first_macro, tok, pntok)
1641 const struct alpha_macro *first_macro;
1642 const expressionS *tok;
1643 int *pntok;
1644 {
1645 const struct alpha_macro *macro = first_macro;
1646 int ntok = *pntok;
1647
1648 do
1649 {
1650 const enum alpha_macro_arg *arg = macro->argsets;
1651 int tokidx = 0;
1652
1653 while (*arg)
1654 {
1655 switch (*arg)
1656 {
1657 case MACRO_EOA:
1658 if (tokidx == ntok)
1659 return macro;
1660 else
1661 tokidx = 0;
1662 break;
1663
1664 case MACRO_IR:
1665 if (tokidx >= ntok || tok[tokidx].X_op != O_register
1666 || !is_ir_num(tok[tokidx].X_add_number))
1667 goto match_failed;
1668 ++tokidx;
1669 break;
1670 case MACRO_PIR:
1671 if (tokidx >= ntok || tok[tokidx].X_op != O_pregister
1672 || !is_ir_num(tok[tokidx].X_add_number))
1673 goto match_failed;
1674 ++tokidx;
1675 break;
1676 case MACRO_CPIR:
1677 if (tokidx >= ntok || tok[tokidx].X_op != O_cpregister
1678 || !is_ir_num(tok[tokidx].X_add_number))
1679 goto match_failed;
1680 ++tokidx;
1681 break;
1682 case MACRO_FPR:
1683 if (tokidx >= ntok || tok[tokidx].X_op != O_register
1684 || !is_fpr_num(tok[tokidx].X_add_number))
1685 goto match_failed;
1686 ++tokidx;
1687 break;
1688
1689 case MACRO_EXP:
1690 if (tokidx >= ntok)
1691 goto match_failed;
1692 switch (tok[tokidx].X_op)
1693 {
1694 case O_illegal:
1695 case O_absent:
1696 case O_register:
1697 case O_pregister:
1698 case O_cpregister:
1699 goto match_failed;
1700 }
1701 ++tokidx;
1702 break;
1703
1704 match_failed:
1705 while (*arg != MACRO_EOA)
1706 ++arg;
1707 tokidx = 0;
1708 break;
1709 }
1710 ++arg;
1711 }
1712 }
1713 while (++macro-alpha_macros < alpha_num_macros
1714 && !strcmp(macro->name, first_macro->name));
1715
1716 return NULL;
1717 }
1718
1719 /* Insert an operand value into an instruction. */
1720
1721 static unsigned
1722 insert_operand(insn, operand, val, file, line)
1723 unsigned insn;
1724 const struct alpha_operand *operand;
1725 offsetT val;
1726 char *file;
1727 unsigned line;
1728 {
1729 if (operand->bits != 32 && !(operand->flags & AXP_OPERAND_NOOVERFLOW))
1730 {
1731 offsetT min, max;
1732
1733 if (operand->flags & AXP_OPERAND_SIGNED)
1734 {
1735 max = (1 << (operand->bits - 1)) - 1;
1736 min = -(1 << (operand->bits - 1));
1737 }
1738 else
1739 {
1740 max = (1 << operand->bits) - 1;
1741 min = 0;
1742 }
1743
1744 if (val < min || val > max)
1745 {
1746 const char *err =
1747 "operand out of range (%s not between %d and %d)";
1748 char buf[sizeof (val) * 3 + 2];
1749
1750 sprint_value(buf, val);
1751 if (file)
1752 as_warn_where(file, line, err, buf, min, max);
1753 else
1754 as_warn(err, buf, min, max);
1755 }
1756 }
1757
1758 if (operand->insert)
1759 {
1760 const char *errmsg = NULL;
1761
1762 insn = (*operand->insert) (insn, val, &errmsg);
1763 if (errmsg)
1764 as_warn (errmsg);
1765 }
1766 else
1767 insn |= ((val & ((1 << operand->bits) - 1)) << operand->shift);
1768
1769 return insn;
1770 }
1771
1772 /*
1773 * Turn an opcode description and a set of arguments into
1774 * an instruction and a fixup.
1775 */
1776
1777 static void
1778 assemble_insn(opcode, tok, ntok, insn)
1779 const struct alpha_opcode *opcode;
1780 const expressionS *tok;
1781 int ntok;
1782 struct alpha_insn *insn;
1783 {
1784 const unsigned char *argidx;
1785 unsigned image;
1786 int tokidx = 0;
1787
1788 memset (insn, 0, sizeof (*insn));
1789 image = opcode->opcode;
1790
1791 for (argidx = opcode->operands; *argidx; ++argidx)
1792 {
1793 const struct alpha_operand *operand = &alpha_operands[*argidx];
1794 const expressionS *t;
1795
1796 if (operand->flags & AXP_OPERAND_FAKE)
1797 {
1798 /* fake operands take no value and generate no fixup */
1799 image = insert_operand(image, operand, 0, NULL, 0);
1800 continue;
1801 }
1802
1803 if (tokidx >= ntok)
1804 {
1805 switch (operand->flags & AXP_OPERAND_OPTIONAL_MASK)
1806 {
1807 case AXP_OPERAND_DEFAULT_FIRST:
1808 t = &tok[0];
1809 break;
1810 case AXP_OPERAND_DEFAULT_SECOND:
1811 t = &tok[1];
1812 break;
1813 case AXP_OPERAND_DEFAULT_ZERO:
1814 {
1815 static const expressionS zero_exp = { 0, 0, 0, O_constant, 1 };
1816 t = &zero_exp;
1817 }
1818 break;
1819 default:
1820 abort();
1821 }
1822 }
1823 else
1824 t = &tok[tokidx++];
1825
1826 switch (t->X_op)
1827 {
1828 case O_register:
1829 case O_pregister:
1830 case O_cpregister:
1831 image = insert_operand(image, operand, regno(t->X_add_number),
1832 NULL, 0);
1833 break;
1834
1835 case O_constant:
1836 image = insert_operand(image, operand, t->X_add_number, NULL, 0);
1837 break;
1838
1839 default:
1840 {
1841 struct alpha_fixup *fixup;
1842
1843 if (insn->nfixups >= MAX_INSN_FIXUPS)
1844 as_fatal("too many fixups");
1845
1846 fixup = &insn->fixups[insn->nfixups++];
1847
1848 fixup->exp = *t;
1849 fixup->reloc = operand->default_reloc;
1850 }
1851 break;
1852 }
1853 }
1854
1855 insn->insn = image;
1856 }
1857
1858 /*
1859 * Actually output an instruction with its fixup.
1860 */
1861
1862 static void
1863 emit_insn (insn)
1864 struct alpha_insn *insn;
1865 {
1866 char *f;
1867 int i;
1868
1869 /* Take care of alignment duties */
1870 if (alpha_auto_align_on && alpha_current_align < 2)
1871 alpha_align (2, (char *) NULL, alpha_insn_label);
1872 if (alpha_current_align > 2)
1873 alpha_current_align = 2;
1874 alpha_insn_label = NULL;
1875
1876 /* Write out the instruction. */
1877 f = frag_more (4);
1878 md_number_to_chars (f, insn->insn, 4);
1879
1880 /* Apply the fixups in order */
1881 for (i = 0; i < insn->nfixups; ++i)
1882 {
1883 struct alpha_fixup *fixup = &insn->fixups[i];
1884 int size, pcrel;
1885 fixS *fixP;
1886
1887 /* Some fixups are only used internally and so have no howto */
1888 if ((int)fixup->reloc < 0)
1889 size = 4, pcrel = 0;
1890 #ifdef OBJ_ELF
1891 /* These relocation types are only used internally. */
1892 else if (fixup->reloc == BFD_RELOC_ALPHA_GPDISP_HI16
1893 || fixup->reloc == BFD_RELOC_ALPHA_GPDISP_LO16)
1894 {
1895 size = 2, pcrel = 0;
1896 }
1897 #endif
1898 else
1899 {
1900 reloc_howto_type *reloc_howto
1901 = bfd_reloc_type_lookup (stdoutput, fixup->reloc);
1902 assert (reloc_howto);
1903
1904 size = bfd_get_reloc_size (reloc_howto);
1905 pcrel = reloc_howto->pc_relative;
1906 }
1907 assert (size >= 1 && size <= 4);
1908
1909 fixP = fix_new_exp (frag_now, f - frag_now->fr_literal, size,
1910 &fixup->exp, pcrel, fixup->reloc);
1911
1912 /* Turn off complaints that the addend is too large for some fixups */
1913 switch (fixup->reloc)
1914 {
1915 case BFD_RELOC_ALPHA_GPDISP_LO16:
1916 #ifdef OBJ_ECOFF
1917 case BFD_RELOC_ALPHA_LITERAL:
1918 #endif
1919 #ifdef OBJ_ELF
1920 case BFD_RELOC_ALPHA_ELF_LITERAL:
1921 #endif
1922 case BFD_RELOC_GPREL32:
1923 fixP->fx_no_overflow = 1;
1924 break;
1925 default:
1926 break;
1927 }
1928 }
1929 }
1930
1931 /* Given an opcode name and a pre-tokenized set of arguments, assemble
1932 the insn, but do not emit it.
1933
1934 Note that this implies no macros allowed, since we can't store more
1935 than one insn in an insn structure. */
1936
1937 static void
1938 assemble_tokens_to_insn(opname, tok, ntok, insn)
1939 const char *opname;
1940 const expressionS *tok;
1941 int ntok;
1942 struct alpha_insn *insn;
1943 {
1944 const struct alpha_opcode *opcode;
1945
1946 /* search opcodes */
1947 opcode = (const struct alpha_opcode *) hash_find (alpha_opcode_hash, opname);
1948 if (opcode)
1949 {
1950 int cpumatch;
1951 opcode = find_opcode_match (opcode, tok, &ntok, &cpumatch);
1952 if (opcode)
1953 {
1954 assemble_insn (opcode, tok, ntok, insn);
1955 return;
1956 }
1957 else if (cpumatch)
1958 as_bad ("inappropriate arguments for opcode `%s'", opname);
1959 else
1960 as_bad ("opcode `%s' not supported for target %s", opname,
1961 alpha_target_name);
1962 }
1963 else
1964 as_bad ("unknown opcode `%s'", opname);
1965 }
1966
1967 /* Given an opcode name and a pre-tokenized set of arguments, take the
1968 opcode all the way through emission. */
1969
1970 static void
1971 assemble_tokens (opname, tok, ntok, local_macros_on)
1972 const char *opname;
1973 const expressionS *tok;
1974 int ntok;
1975 int local_macros_on;
1976 {
1977 int found_something = 0;
1978 const struct alpha_opcode *opcode;
1979 const struct alpha_macro *macro;
1980 int cpumatch = 1;
1981
1982 /* search macros */
1983 if (local_macros_on)
1984 {
1985 macro = ((const struct alpha_macro *)
1986 hash_find (alpha_macro_hash, opname));
1987 if (macro)
1988 {
1989 found_something = 1;
1990 macro = find_macro_match (macro, tok, &ntok);
1991 if (macro)
1992 {
1993 (*macro->emit) (tok, ntok, macro->arg);
1994 return;
1995 }
1996 }
1997 }
1998
1999 /* search opcodes */
2000 opcode = (const struct alpha_opcode *) hash_find (alpha_opcode_hash, opname);
2001 if (opcode)
2002 {
2003 found_something = 1;
2004 opcode = find_opcode_match (opcode, tok, &ntok, &cpumatch);
2005 if (opcode)
2006 {
2007 struct alpha_insn insn;
2008 assemble_insn (opcode, tok, ntok, &insn);
2009 emit_insn (&insn);
2010 return;
2011 }
2012 }
2013
2014 if (found_something)
2015 if (cpumatch)
2016 as_bad ("inappropriate arguments for opcode `%s'", opname);
2017 else
2018 as_bad ("opcode `%s' not supported for target %s", opname,
2019 alpha_target_name);
2020 else
2021 as_bad ("unknown opcode `%s'", opname);
2022 }
2023
2024 \f
2025 /* Some instruction sets indexed by lg(size) */
2026 static const char * const sextX_op[] = { "sextb", "sextw", "sextl", NULL };
2027 static const char * const insXl_op[] = { "insbl", "inswl", "insll", "insql" };
2028 static const char * const insXh_op[] = { NULL, "inswh", "inslh", "insqh" };
2029 static const char * const extXl_op[] = { "extbl", "extwl", "extll", "extql" };
2030 static const char * const extXh_op[] = { NULL, "extwh", "extlh", "extqh" };
2031 static const char * const mskXl_op[] = { "mskbl", "mskwl", "mskll", "mskql" };
2032 static const char * const mskXh_op[] = { NULL, "mskwh", "msklh", "mskqh" };
2033 static const char * const stX_op[] = { "stb", "stw", "stl", "stq" };
2034 static const char * const ldX_op[] = { "ldb", "ldw", "ldll", "ldq" };
2035 static const char * const ldXu_op[] = { "ldbu", "ldwu", NULL, NULL };
2036
2037 /* Implement the ldgp macro. */
2038
2039 static void
2040 emit_ldgp (tok, ntok, unused)
2041 const expressionS *tok;
2042 int ntok;
2043 const PTR unused;
2044 {
2045 #ifdef OBJ_AOUT
2046 FIXME
2047 #endif
2048 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
2049 /* from "ldgp r1,n(r2)", generate "ldah r1,X(R2); lda r1,Y(r1)"
2050 with appropriate constants and relocations. */
2051 struct alpha_insn insn;
2052 expressionS newtok[3];
2053 expressionS addend;
2054
2055 /* We're going to need this symbol in md_apply_fix(). */
2056 (void) section_symbol (absolute_section);
2057
2058 #ifdef OBJ_ECOFF
2059 if (regno (tok[2].X_add_number) == AXP_REG_PV)
2060 ecoff_set_gp_prolog_size (0);
2061 #endif
2062
2063 newtok[0] = tok[0];
2064 set_tok_const (newtok[1], 0);
2065 newtok[2] = tok[2];
2066
2067 assemble_tokens_to_insn ("ldah", newtok, 3, &insn);
2068
2069 addend = tok[1];
2070
2071 #ifdef OBJ_ECOFF
2072 assert (addend.X_op == O_constant);
2073 addend.X_op = O_symbol;
2074 addend.X_add_symbol = alpha_gp_symbol;
2075 #endif
2076
2077 insn.nfixups = 1;
2078 insn.fixups[0].exp = addend;
2079 insn.fixups[0].reloc = BFD_RELOC_ALPHA_GPDISP_HI16;
2080
2081 emit_insn (&insn);
2082
2083 set_tok_preg (newtok[2], tok[0].X_add_number);
2084
2085 assemble_tokens_to_insn ("lda", newtok, 3, &insn);
2086
2087 #ifdef OBJ_ECOFF
2088 addend.X_add_number += 4;
2089 #endif
2090
2091 insn.nfixups = 1;
2092 insn.fixups[0].exp = addend;
2093 insn.fixups[0].reloc = BFD_RELOC_ALPHA_GPDISP_LO16;
2094
2095 emit_insn (&insn);
2096 #endif /* OBJ_ECOFF || OBJ_ELF */
2097 }
2098
2099 #ifdef OBJ_EVAX
2100
2101 /* Add symbol+addend to link pool.
2102 Return offset from basesym to entry in link pool.
2103
2104 Add new fixup only if offset isn't 16bit. */
2105
2106 valueT
2107 add_to_link_pool (basesym, sym, addend)
2108 symbolS *basesym;
2109 symbolS *sym;
2110 offsetT addend;
2111 {
2112 segT current_section = now_seg;
2113 int current_subsec = now_subseg;
2114 valueT offset;
2115 bfd_reloc_code_real_type reloc_type;
2116 char *p;
2117 segment_info_type *seginfo = seg_info (alpha_link_section);
2118 fixS *fixp;
2119
2120 offset = -basesym->sy_obj;
2121
2122 /* @@ This assumes all entries in a given section will be of the same
2123 size... Probably correct, but unwise to rely on. */
2124 /* This must always be called with the same subsegment. */
2125
2126 if (seginfo->frchainP)
2127 for (fixp = seginfo->frchainP->fix_root;
2128 fixp != (fixS *) NULL;
2129 fixp = fixp->fx_next, offset += 8)
2130 {
2131 if (fixp->fx_addsy == sym && fixp->fx_offset == addend)
2132 {
2133 if (range_signed_16 (offset))
2134 {
2135 return offset;
2136 }
2137 }
2138 }
2139
2140 /* Not found in 16bit signed range. */
2141
2142 subseg_set (alpha_link_section, 0);
2143 p = frag_more (8);
2144 memset (p, 0, 8);
2145
2146 fix_new (frag_now, p - frag_now->fr_literal, 8, sym, addend, 0,
2147 BFD_RELOC_64);
2148
2149 subseg_set (current_section, current_subsec);
2150 seginfo->literal_pool_size += 8;
2151 return offset;
2152 }
2153
2154 #endif /* OBJ_EVAX */
2155
2156 /* Load a (partial) expression into a target register.
2157
2158 If poffset is not null, after the call it will either contain
2159 O_constant 0, or a 16-bit offset appropriate for any MEM format
2160 instruction. In addition, pbasereg will be modified to point to
2161 the base register to use in that MEM format instruction.
2162
2163 In any case, *pbasereg should contain a base register to add to the
2164 expression. This will normally be either AXP_REG_ZERO or
2165 alpha_gp_register. Symbol addresses will always be loaded via $gp,
2166 so "foo($0)" is interpreted as adding the address of foo to $0;
2167 i.e. "ldq $targ, LIT($gp); addq $targ, $0, $targ". Odd, perhaps,
2168 but this is what OSF/1 does.
2169
2170 Finally, the return value is true if the calling macro may emit a
2171 LITUSE reloc if otherwise appropriate. */
2172
2173 static int
2174 load_expression (targreg, exp, pbasereg, poffset)
2175 int targreg;
2176 const expressionS *exp;
2177 int *pbasereg;
2178 expressionS *poffset;
2179 {
2180 int emit_lituse = 0;
2181 offsetT addend = exp->X_add_number;
2182 int basereg = *pbasereg;
2183 struct alpha_insn insn;
2184 expressionS newtok[3];
2185
2186 switch (exp->X_op)
2187 {
2188 case O_symbol:
2189 {
2190 #ifdef OBJ_ECOFF
2191 offsetT lit;
2192
2193 /* attempt to reduce .lit load by splitting the offset from
2194 its symbol when possible, but don't create a situation in
2195 which we'd fail. */
2196 if (!range_signed_32 (addend) &&
2197 (alpha_noat_on || targreg == AXP_REG_AT))
2198 {
2199 lit = add_to_literal_pool (exp->X_add_symbol, addend,
2200 alpha_lita_section, 8);
2201 addend = 0;
2202 }
2203 else
2204 {
2205 lit = add_to_literal_pool (exp->X_add_symbol, 0,
2206 alpha_lita_section, 8);
2207 }
2208
2209 if (lit >= 0x8000)
2210 as_fatal ("overflow in literal (.lita) table");
2211
2212 /* emit "ldq r, lit(gp)" */
2213
2214 if (basereg != alpha_gp_register && targreg == basereg)
2215 {
2216 if (alpha_noat_on)
2217 as_bad ("macro requires $at register while noat in effect");
2218 if (targreg == AXP_REG_AT)
2219 as_bad ("macro requires $at while $at in use");
2220
2221 set_tok_reg (newtok[0], AXP_REG_AT);
2222 }
2223 else
2224 set_tok_reg (newtok[0], targreg);
2225 set_tok_sym (newtok[1], alpha_lita_symbol, lit);
2226 set_tok_preg (newtok[2], alpha_gp_register);
2227
2228 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
2229
2230 assert (insn.nfixups == 1);
2231 insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITERAL;
2232 #endif /* OBJ_ECOFF */
2233 #ifdef OBJ_ELF
2234 /* emit "ldq r, gotoff(gp)" */
2235
2236 if (basereg != alpha_gp_register && targreg == basereg)
2237 {
2238 if (alpha_noat_on)
2239 as_bad ("macro requires $at register while noat in effect");
2240 if (targreg == AXP_REG_AT)
2241 as_bad ("macro requires $at while $at in use");
2242
2243 set_tok_reg (newtok[0], AXP_REG_AT);
2244 }
2245 else
2246 set_tok_reg (newtok[0], targreg);
2247
2248 /* XXX: Disable this .got minimizing optimization so that we can get
2249 better instruction offset knowledge in the compiler. This happens
2250 very infrequently anyway. */
2251 if (1 || !range_signed_32 (addend)
2252 && (alpha_noat_on || targreg == AXP_REG_AT))
2253 {
2254 newtok[1] = *exp;
2255 addend = 0;
2256 }
2257 else
2258 {
2259 set_tok_sym (newtok[1], exp->X_add_symbol, 0);
2260 }
2261
2262 set_tok_preg (newtok[2], alpha_gp_register);
2263
2264 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
2265
2266 assert (insn.nfixups == 1);
2267 insn.fixups[0].reloc = BFD_RELOC_ALPHA_ELF_LITERAL;
2268 #endif /* OBJ_ELF */
2269 #ifdef OBJ_EVAX
2270 offsetT link;
2271
2272 if (alpha_basereg_clobbered)
2273 {
2274 /* no basereg, reload basreg from 0(FP). */
2275 set_tok_reg (newtok[0], targreg);
2276 set_tok_const (newtok[1], 0);
2277 set_tok_preg (newtok[2], AXP_REG_FP);
2278 basereg = targreg;
2279 assemble_tokens ("ldq", newtok, 3, 0);
2280 }
2281
2282 /* Find symbol or symbol pointer in link section. */
2283
2284 if (exp->X_add_symbol == alpha_evax_proc.symbol)
2285 {
2286 if (range_signed_16 (addend))
2287 {
2288 set_tok_reg (newtok[0], targreg);
2289 set_tok_const (newtok[1], addend);
2290 set_tok_preg (newtok[2], basereg);
2291 assemble_tokens_to_insn ("lda", newtok, 3, &insn);
2292 addend = 0;
2293 }
2294 else
2295 {
2296 set_tok_reg (newtok[0], targreg);
2297 set_tok_const (newtok[1], 0);
2298 set_tok_preg (newtok[2], basereg);
2299 assemble_tokens_to_insn ("lda", newtok, 3, &insn);
2300 }
2301 }
2302 else
2303 {
2304 if (!range_signed_32 (addend))
2305 {
2306 link = add_to_link_pool (alpha_evax_proc.symbol,
2307 exp->X_add_symbol, addend);
2308 addend = 0;
2309 }
2310 else
2311 {
2312 link = add_to_link_pool (alpha_evax_proc.symbol,
2313 exp->X_add_symbol, 0);
2314 }
2315 set_tok_reg (newtok[0], targreg);
2316 set_tok_const (newtok[1], link);
2317 set_tok_preg (newtok[2], basereg);
2318 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
2319 }
2320 #endif /* OBJ_EVAX */
2321
2322 emit_insn(&insn);
2323
2324 #ifndef OBJ_EVAX
2325 emit_lituse = 1;
2326
2327 if (basereg != alpha_gp_register && basereg != AXP_REG_ZERO)
2328 {
2329 /* emit "addq r, base, r" */
2330
2331 set_tok_reg (newtok[1], basereg);
2332 set_tok_reg (newtok[2], targreg);
2333 assemble_tokens ("addq", newtok, 3, 0);
2334 }
2335 #endif
2336
2337 basereg = targreg;
2338 }
2339 break;
2340
2341 case O_constant:
2342 break;
2343
2344 case O_subtract:
2345 /* Assume that this difference expression will be resolved to an
2346 absolute value and that that value will fit in 16 bits. */
2347
2348 set_tok_reg (newtok[0], targreg);
2349 newtok[1] = *exp;
2350 set_tok_preg (newtok[2], basereg);
2351 assemble_tokens ("lda", newtok, 3, 0);
2352
2353 if (poffset)
2354 set_tok_const (*poffset, 0);
2355 return 0;
2356
2357 case O_big:
2358 as_bad ("%s number invalid; zero assumed",
2359 exp->X_add_number > 0 ? "bignum" : "floating point");
2360 addend = 0;
2361 break;
2362
2363 default:
2364 abort();
2365 }
2366
2367 if (!range_signed_32 (addend))
2368 {
2369 offsetT lit;
2370
2371 /* for 64-bit addends, just put it in the literal pool */
2372
2373 #ifdef OBJ_EVAX
2374 /* emit "ldq targreg, lit(basereg)" */
2375 lit = add_to_link_pool (alpha_evax_proc.symbol,
2376 section_symbol (absolute_section), addend);
2377 set_tok_reg (newtok[0], targreg);
2378 set_tok_const (newtok[1], lit);
2379 set_tok_preg (newtok[2], alpha_gp_register);
2380 assemble_tokens ("ldq", newtok, 3, 0);
2381 #else
2382
2383 if (alpha_lit8_section == NULL)
2384 {
2385 create_literal_section (".lit8",
2386 &alpha_lit8_section,
2387 &alpha_lit8_symbol);
2388
2389 #ifdef OBJ_ECOFF
2390 alpha_lit8_literal = add_to_literal_pool (alpha_lit8_symbol, 0x8000,
2391 alpha_lita_section, 8);
2392 if (alpha_lit8_literal >= 0x8000)
2393 as_fatal ("overflow in literal (.lita) table");
2394 #endif
2395 }
2396
2397 lit = add_to_literal_pool (NULL, addend, alpha_lit8_section, 8) - 0x8000;
2398 if (lit >= 0x8000)
2399 as_fatal ("overflow in literal (.lit8) table");
2400
2401 /* emit "lda litreg, .lit8+0x8000" */
2402
2403 if (targreg == basereg)
2404 {
2405 if (alpha_noat_on)
2406 as_bad ("macro requires $at register while noat in effect");
2407 if (targreg == AXP_REG_AT)
2408 as_bad ("macro requires $at while $at in use");
2409
2410 set_tok_reg (newtok[0], AXP_REG_AT);
2411 }
2412 else
2413 set_tok_reg (newtok[0], targreg);
2414 #ifdef OBJ_ECOFF
2415 set_tok_sym (newtok[1], alpha_lita_symbol, alpha_lit8_literal);
2416 #endif
2417 #ifdef OBJ_ELF
2418 set_tok_sym (newtok[1], alpha_lit8_symbol, 0x8000);
2419 #endif
2420 set_tok_preg (newtok[2], alpha_gp_register);
2421
2422 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
2423
2424 assert (insn.nfixups == 1);
2425 #ifdef OBJ_ECOFF
2426 insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITERAL;
2427 #endif
2428 #ifdef OBJ_ELF
2429 insn.fixups[0].reloc = BFD_RELOC_ALPHA_ELF_LITERAL;
2430 #endif
2431
2432 emit_insn (&insn);
2433
2434 /* emit "ldq litreg, lit(litreg)" */
2435
2436 set_tok_const (newtok[1], lit);
2437 set_tok_preg (newtok[2], newtok[0].X_add_number);
2438
2439 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
2440
2441 assert (insn.nfixups < MAX_INSN_FIXUPS);
2442 if (insn.nfixups > 0)
2443 {
2444 memmove (&insn.fixups[1], &insn.fixups[0],
2445 sizeof(struct alpha_fixup) * insn.nfixups);
2446 }
2447 insn.nfixups++;
2448 insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITUSE;
2449 insn.fixups[0].exp.X_op = O_constant;
2450 insn.fixups[0].exp.X_add_number = 1;
2451 emit_lituse = 0;
2452
2453 emit_insn (&insn);
2454
2455 /* emit "addq litreg, base, target" */
2456
2457 if (basereg != AXP_REG_ZERO)
2458 {
2459 set_tok_reg (newtok[1], basereg);
2460 set_tok_reg (newtok[2], targreg);
2461 assemble_tokens ("addq", newtok, 3, 0);
2462 }
2463 #endif /* !OBJ_EVAX */
2464
2465 if (poffset)
2466 set_tok_const (*poffset, 0);
2467 *pbasereg = targreg;
2468 }
2469 else
2470 {
2471 offsetT low, high, extra, tmp;
2472
2473 /* for 32-bit operands, break up the addend */
2474
2475 low = sign_extend_16 (addend);
2476 tmp = addend - low;
2477 high = sign_extend_16 (tmp >> 16);
2478
2479 if (tmp - (high << 16))
2480 {
2481 extra = 0x4000;
2482 tmp -= 0x40000000;
2483 high = sign_extend_16 (tmp >> 16);
2484 }
2485 else
2486 extra = 0;
2487
2488 set_tok_reg (newtok[0], targreg);
2489 set_tok_preg (newtok[2], basereg);
2490
2491 if (extra)
2492 {
2493 /* emit "ldah r, extra(r) */
2494 set_tok_const (newtok[1], extra);
2495 assemble_tokens ("ldah", newtok, 3, 0);
2496 set_tok_preg (newtok[2], basereg = targreg);
2497 }
2498
2499 if (high)
2500 {
2501 /* emit "ldah r, high(r) */
2502 set_tok_const (newtok[1], high);
2503 assemble_tokens ("ldah", newtok, 3, 0);
2504 basereg = targreg;
2505 set_tok_preg (newtok[2], basereg);
2506 }
2507
2508 if ((low && !poffset) || (!poffset && basereg != targreg))
2509 {
2510 /* emit "lda r, low(base)" */
2511 set_tok_const (newtok[1], low);
2512 assemble_tokens ("lda", newtok, 3, 0);
2513 basereg = targreg;
2514 low = 0;
2515 }
2516
2517 if (poffset)
2518 set_tok_const (*poffset, low);
2519 *pbasereg = basereg;
2520 }
2521
2522 return emit_lituse;
2523 }
2524
2525 /* The lda macro differs from the lda instruction in that it handles
2526 most simple expressions, particualrly symbol address loads and
2527 large constants. */
2528
2529 static void
2530 emit_lda (tok, ntok, unused)
2531 const expressionS *tok;
2532 int ntok;
2533 const PTR unused;
2534 {
2535 int basereg;
2536
2537 if (ntok == 2)
2538 basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
2539 else
2540 basereg = tok[2].X_add_number;
2541
2542 (void) load_expression (tok[0].X_add_number, &tok[1], &basereg, NULL);
2543 }
2544
2545 /* The ldah macro differs from the ldah instruction in that it has $31
2546 as an implied base register. */
2547
2548 static void
2549 emit_ldah (tok, ntok, unused)
2550 const expressionS *tok;
2551 int ntok;
2552 const PTR unused;
2553 {
2554 expressionS newtok[3];
2555
2556 newtok[0] = tok[0];
2557 newtok[1] = tok[1];
2558 set_tok_preg (newtok[2], AXP_REG_ZERO);
2559
2560 assemble_tokens ("ldah", newtok, 3, 0);
2561 }
2562
2563 /* Handle all "simple" integer register loads -- ldq, ldq_l, ldq_u,
2564 etc. They differ from the real instructions in that they do simple
2565 expressions like the lda macro. */
2566
2567 static void
2568 emit_ir_load (tok, ntok, opname)
2569 const expressionS *tok;
2570 int ntok;
2571 const PTR opname;
2572 {
2573 int basereg, lituse;
2574 expressionS newtok[3];
2575 struct alpha_insn insn;
2576
2577 if (ntok == 2)
2578 basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
2579 else
2580 basereg = tok[2].X_add_number;
2581
2582 lituse = load_expression (tok[0].X_add_number, &tok[1], &basereg,
2583 &newtok[1]);
2584
2585 newtok[0] = tok[0];
2586 set_tok_preg (newtok[2], basereg);
2587
2588 assemble_tokens_to_insn ((const char *)opname, newtok, 3, &insn);
2589
2590 if (lituse)
2591 {
2592 assert (insn.nfixups < MAX_INSN_FIXUPS);
2593 if (insn.nfixups > 0)
2594 {
2595 memmove (&insn.fixups[1], &insn.fixups[0],
2596 sizeof(struct alpha_fixup) * insn.nfixups);
2597 }
2598 insn.nfixups++;
2599 insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITUSE;
2600 insn.fixups[0].exp.X_op = O_constant;
2601 insn.fixups[0].exp.X_add_number = 1;
2602 }
2603
2604 emit_insn (&insn);
2605 #ifdef OBJ_EVAX
2606 /* special hack. If the basereg is clobbered for a call
2607 all lda's before the call don't have a basereg. */
2608 if ((tok[0].X_op == O_register)
2609 && (tok[0].X_add_number == alpha_gp_register))
2610 {
2611 alpha_basereg_clobbered = 1;
2612 }
2613 #endif
2614 }
2615
2616 /* Handle fp register loads, and both integer and fp register stores.
2617 Again, we handle simple expressions. */
2618
2619 static void
2620 emit_loadstore (tok, ntok, opname)
2621 const expressionS *tok;
2622 int ntok;
2623 const PTR opname;
2624 {
2625 int basereg, lituse;
2626 expressionS newtok[3];
2627 struct alpha_insn insn;
2628
2629 if (ntok == 2)
2630 basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
2631 else
2632 basereg = tok[2].X_add_number;
2633
2634 if (tok[1].X_op != O_constant || !range_signed_16(tok[1].X_add_number))
2635 {
2636 if (alpha_noat_on)
2637 as_bad ("macro requires $at register while noat in effect");
2638
2639 lituse = load_expression (AXP_REG_AT, &tok[1], &basereg, &newtok[1]);
2640 }
2641 else
2642 {
2643 newtok[1] = tok[1];
2644 lituse = 0;
2645 }
2646
2647 newtok[0] = tok[0];
2648 set_tok_preg (newtok[2], basereg);
2649
2650 assemble_tokens_to_insn ((const char *)opname, newtok, 3, &insn);
2651
2652 if (lituse)
2653 {
2654 assert (insn.nfixups < MAX_INSN_FIXUPS);
2655 if (insn.nfixups > 0)
2656 {
2657 memmove (&insn.fixups[1], &insn.fixups[0],
2658 sizeof(struct alpha_fixup) * insn.nfixups);
2659 }
2660 insn.nfixups++;
2661 insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITUSE;
2662 insn.fixups[0].exp.X_op = O_constant;
2663 insn.fixups[0].exp.X_add_number = 1;
2664 }
2665
2666 emit_insn (&insn);
2667 }
2668
2669 /* Load a half-word or byte as an unsigned value. */
2670
2671 static void
2672 emit_ldXu (tok, ntok, vlgsize)
2673 const expressionS *tok;
2674 int ntok;
2675 const PTR vlgsize;
2676 {
2677 if (alpha_target & AXP_OPCODE_BWX)
2678 emit_ir_load (tok, ntok, ldXu_op[(long)vlgsize]);
2679 else
2680 {
2681 expressionS newtok[3];
2682
2683 if (alpha_noat_on)
2684 as_bad ("macro requires $at register while noat in effect");
2685
2686 /* emit "lda $at, exp" */
2687
2688 memcpy (newtok, tok, sizeof (expressionS) * ntok);
2689 newtok[0].X_add_number = AXP_REG_AT;
2690 assemble_tokens ("lda", newtok, ntok, 1);
2691
2692 /* emit "ldq_u targ, 0($at)" */
2693
2694 newtok[0] = tok[0];
2695 set_tok_const (newtok[1], 0);
2696 set_tok_preg (newtok[2], AXP_REG_AT);
2697 assemble_tokens ("ldq_u", newtok, 3, 1);
2698
2699 /* emit "extXl targ, $at, targ" */
2700
2701 set_tok_reg (newtok[1], AXP_REG_AT);
2702 newtok[2] = newtok[0];
2703 assemble_tokens (extXl_op[(long)vlgsize], newtok, 3, 1);
2704 }
2705 }
2706
2707 /* Load a half-word or byte as a signed value. */
2708
2709 static void
2710 emit_ldX (tok, ntok, vlgsize)
2711 const expressionS *tok;
2712 int ntok;
2713 const PTR vlgsize;
2714 {
2715 emit_ldXu (tok, ntok, vlgsize);
2716 assemble_tokens (sextX_op[(long)vlgsize], tok, 1, 1);
2717 }
2718
2719 /* Load an integral value from an unaligned address as an unsigned
2720 value. */
2721
2722 static void
2723 emit_uldXu (tok, ntok, vlgsize)
2724 const expressionS *tok;
2725 int ntok;
2726 const PTR vlgsize;
2727 {
2728 long lgsize = (long)vlgsize;
2729 expressionS newtok[3];
2730
2731 if (alpha_noat_on)
2732 as_bad ("macro requires $at register while noat in effect");
2733
2734 /* emit "lda $at, exp" */
2735
2736 memcpy (newtok, tok, sizeof (expressionS) * ntok);
2737 newtok[0].X_add_number = AXP_REG_AT;
2738 assemble_tokens ("lda", newtok, ntok, 1);
2739
2740 /* emit "ldq_u $t9, 0($at)" */
2741
2742 set_tok_reg (newtok[0], AXP_REG_T9);
2743 set_tok_const (newtok[1], 0);
2744 set_tok_preg (newtok[2], AXP_REG_AT);
2745 assemble_tokens ("ldq_u", newtok, 3, 1);
2746
2747 /* emit "ldq_u $t10, size-1($at)" */
2748
2749 set_tok_reg (newtok[0], AXP_REG_T10);
2750 set_tok_const (newtok[1], (1<<lgsize)-1);
2751 assemble_tokens ("ldq_u", newtok, 3, 1);
2752
2753 /* emit "extXl $t9, $at, $t9" */
2754
2755 set_tok_reg (newtok[0], AXP_REG_T9);
2756 set_tok_reg (newtok[1], AXP_REG_AT);
2757 set_tok_reg (newtok[2], AXP_REG_T9);
2758 assemble_tokens (extXl_op[lgsize], newtok, 3, 1);
2759
2760 /* emit "extXh $t10, $at, $t10" */
2761
2762 set_tok_reg (newtok[0], AXP_REG_T10);
2763 set_tok_reg (newtok[2], AXP_REG_T10);
2764 assemble_tokens (extXh_op[lgsize], newtok, 3, 1);
2765
2766 /* emit "or $t9, $t10, targ" */
2767
2768 set_tok_reg (newtok[0], AXP_REG_T9);
2769 set_tok_reg (newtok[1], AXP_REG_T10);
2770 newtok[2] = tok[0];
2771 assemble_tokens ("or", newtok, 3, 1);
2772 }
2773
2774 /* Load an integral value from an unaligned address as a signed value.
2775 Note that quads should get funneled to the unsigned load since we
2776 don't have to do the sign extension. */
2777
2778 static void
2779 emit_uldX (tok, ntok, vlgsize)
2780 const expressionS *tok;
2781 int ntok;
2782 const PTR vlgsize;
2783 {
2784 emit_uldXu (tok, ntok, vlgsize);
2785 assemble_tokens (sextX_op[(long)vlgsize], tok, 1, 1);
2786 }
2787
2788 /* Implement the ldil macro. */
2789
2790 static void
2791 emit_ldil (tok, ntok, unused)
2792 const expressionS *tok;
2793 int ntok;
2794 const PTR unused;
2795 {
2796 expressionS newtok[2];
2797
2798 memcpy (newtok, tok, sizeof(newtok));
2799 newtok[1].X_add_number = sign_extend_32 (tok[1].X_add_number);
2800
2801 assemble_tokens ("lda", newtok, ntok, 1);
2802 }
2803
2804 /* Store a half-word or byte. */
2805
2806 static void
2807 emit_stX (tok, ntok, vlgsize)
2808 const expressionS *tok;
2809 int ntok;
2810 const PTR vlgsize;
2811 {
2812 int lgsize = (int)(long)vlgsize;
2813
2814 if (alpha_target & AXP_OPCODE_BWX)
2815 emit_loadstore (tok, ntok, stX_op[lgsize]);
2816 else
2817 {
2818 expressionS newtok[3];
2819
2820 if (alpha_noat_on)
2821 as_bad("macro requires $at register while noat in effect");
2822
2823 /* emit "lda $at, exp" */
2824
2825 memcpy (newtok, tok, sizeof (expressionS) * ntok);
2826 newtok[0].X_add_number = AXP_REG_AT;
2827 assemble_tokens ("lda", newtok, ntok, 1);
2828
2829 /* emit "ldq_u $t9, 0($at)" */
2830
2831 set_tok_reg (newtok[0], AXP_REG_T9);
2832 set_tok_const (newtok[1], 0);
2833 set_tok_preg (newtok[2], AXP_REG_AT);
2834 assemble_tokens ("ldq_u", newtok, 3, 1);
2835
2836 /* emit "insXl src, $at, $t10" */
2837
2838 newtok[0] = tok[0];
2839 set_tok_reg (newtok[1], AXP_REG_AT);
2840 set_tok_reg (newtok[2], AXP_REG_T10);
2841 assemble_tokens (insXl_op[lgsize], newtok, 3, 1);
2842
2843 /* emit "mskXl $t9, $at, $t9" */
2844
2845 set_tok_reg (newtok[0], AXP_REG_T9);
2846 newtok[2] = newtok[0];
2847 assemble_tokens (mskXl_op[lgsize], newtok, 3, 1);
2848
2849 /* emit "or $t9, $t10, $t9" */
2850
2851 set_tok_reg (newtok[1], AXP_REG_T10);
2852 assemble_tokens ("or", newtok, 3, 1);
2853
2854 /* emit "stq_u $t9, 0($at) */
2855
2856 set_tok_const (newtok[1], 0);
2857 set_tok_preg (newtok[2], AXP_REG_AT);
2858 assemble_tokens ("stq_u", newtok, 3, 1);
2859 }
2860 }
2861
2862 /* Store an integer to an unaligned address. */
2863
2864 static void
2865 emit_ustX (tok, ntok, vlgsize)
2866 const expressionS *tok;
2867 int ntok;
2868 const PTR vlgsize;
2869 {
2870 int lgsize = (int)(long)vlgsize;
2871 expressionS newtok[3];
2872
2873 /* emit "lda $at, exp" */
2874
2875 memcpy (newtok, tok, sizeof (expressionS) * ntok);
2876 newtok[0].X_add_number = AXP_REG_AT;
2877 assemble_tokens ("lda", newtok, ntok, 1);
2878
2879 /* emit "ldq_u $9, 0($at)" */
2880
2881 set_tok_reg (newtok[0], AXP_REG_T9);
2882 set_tok_const (newtok[1], 0);
2883 set_tok_preg (newtok[2], AXP_REG_AT);
2884 assemble_tokens ("ldq_u", newtok, 3, 1);
2885
2886 /* emit "ldq_u $10, size-1($at)" */
2887
2888 set_tok_reg (newtok[0], AXP_REG_T10);
2889 set_tok_const (newtok[1], (1 << lgsize)-1);
2890 assemble_tokens ("ldq_u", newtok, 3, 1);
2891
2892 /* emit "insXl src, $at, $t11" */
2893
2894 newtok[0] = tok[0];
2895 set_tok_reg (newtok[1], AXP_REG_AT);
2896 set_tok_reg (newtok[2], AXP_REG_T11);
2897 assemble_tokens (insXl_op[lgsize], newtok, 3, 1);
2898
2899 /* emit "insXh src, $at, $t12" */
2900
2901 set_tok_reg (newtok[2], AXP_REG_T12);
2902 assemble_tokens (insXh_op[lgsize], newtok, 3, 1);
2903
2904 /* emit "mskXl $t9, $at, $t9" */
2905
2906 set_tok_reg (newtok[0], AXP_REG_T9);
2907 newtok[2] = newtok[0];
2908 assemble_tokens (mskXl_op[lgsize], newtok, 3, 1);
2909
2910 /* emit "mskXh $t10, $at, $t10" */
2911
2912 set_tok_reg (newtok[0], AXP_REG_T10);
2913 newtok[2] = newtok[0];
2914 assemble_tokens (mskXh_op[lgsize], newtok, 3, 1);
2915
2916 /* emit "or $t9, $t11, $t9" */
2917
2918 set_tok_reg (newtok[0], AXP_REG_T9);
2919 set_tok_reg (newtok[1], AXP_REG_T11);
2920 newtok[2] = newtok[0];
2921 assemble_tokens ("or", newtok, 3, 1);
2922
2923 /* emit "or $t10, $t12, $t10" */
2924
2925 set_tok_reg (newtok[0], AXP_REG_T10);
2926 set_tok_reg (newtok[1], AXP_REG_T12);
2927 newtok[2] = newtok[0];
2928 assemble_tokens ("or", newtok, 3, 1);
2929
2930 /* emit "stq_u $t9, 0($at)" */
2931
2932 set_tok_reg (newtok[0], AXP_REG_T9);
2933 set_tok_const (newtok[1], 0);
2934 set_tok_preg (newtok[2], AXP_REG_AT);
2935 assemble_tokens ("stq_u", newtok, 3, 1);
2936
2937 /* emit "stq_u $t10, size-1($at)" */
2938
2939 set_tok_reg (newtok[0], AXP_REG_T10);
2940 set_tok_const (newtok[1], (1 << lgsize)-1);
2941 assemble_tokens ("stq_u", newtok, 3, 1);
2942 }
2943
2944 /* Sign extend a half-word or byte. The 32-bit sign extend is
2945 implemented as "addl $31, $r, $t" in the opcode table. */
2946
2947 static void
2948 emit_sextX (tok, ntok, vlgsize)
2949 const expressionS *tok;
2950 int ntok;
2951 const PTR vlgsize;
2952 {
2953 long lgsize = (long)vlgsize;
2954
2955 if (alpha_target & AXP_OPCODE_BWX)
2956 assemble_tokens (sextX_op[lgsize], tok, ntok, 0);
2957 else
2958 {
2959 int bitshift = 64 - 8 * (1 << lgsize);
2960 expressionS newtok[3];
2961
2962 /* emit "sll src,bits,dst" */
2963
2964 newtok[0] = tok[0];
2965 set_tok_const (newtok[1], bitshift);
2966 newtok[2] = tok[ntok - 1];
2967 assemble_tokens ("sll", newtok, 3, 1);
2968
2969 /* emit "sra dst,bits,dst" */
2970
2971 newtok[0] = newtok[2];
2972 assemble_tokens ("sra", newtok, 3, 1);
2973 }
2974 }
2975
2976 /* Implement the division and modulus macros. */
2977
2978 #ifdef OBJ_EVAX
2979
2980 /* Make register usage like in normal procedure call.
2981 Don't clobber PV and RA. */
2982
2983 static void
2984 emit_division (tok, ntok, symname)
2985 const expressionS *tok;
2986 int ntok;
2987 const PTR symname;
2988 {
2989 /* DIVISION and MODULUS. Yech.
2990 *
2991 * Convert
2992 * OP x,y,result
2993 * to
2994 * mov x,R16 # if x != R16
2995 * mov y,R17 # if y != R17
2996 * lda AT,__OP
2997 * jsr AT,(AT),0
2998 * mov R0,result
2999 *
3000 * with appropriate optimizations if R0,R16,R17 are the registers
3001 * specified by the compiler.
3002 */
3003
3004 int xr, yr, rr;
3005 symbolS *sym;
3006 expressionS newtok[3];
3007
3008 xr = regno (tok[0].X_add_number);
3009 yr = regno (tok[1].X_add_number);
3010
3011 if (ntok < 3)
3012 rr = xr;
3013 else
3014 rr = regno (tok[2].X_add_number);
3015
3016 /* Move the operands into the right place */
3017 if (yr == AXP_REG_R16 && xr == AXP_REG_R17)
3018 {
3019 /* They are in exactly the wrong order -- swap through AT */
3020
3021 if (alpha_noat_on)
3022 as_bad ("macro requires $at register while noat in effect");
3023
3024 set_tok_reg (newtok[0], AXP_REG_R16);
3025 set_tok_reg (newtok[1], AXP_REG_AT);
3026 assemble_tokens ("mov", newtok, 2, 1);
3027
3028 set_tok_reg (newtok[0], AXP_REG_R17);
3029 set_tok_reg (newtok[1], AXP_REG_R16);
3030 assemble_tokens ("mov", newtok, 2, 1);
3031
3032 set_tok_reg (newtok[0], AXP_REG_AT);
3033 set_tok_reg (newtok[1], AXP_REG_R17);
3034 assemble_tokens ("mov", newtok, 2, 1);
3035 }
3036 else
3037 {
3038 if (yr == AXP_REG_R16)
3039 {
3040 set_tok_reg (newtok[0], AXP_REG_R16);
3041 set_tok_reg (newtok[1], AXP_REG_R17);
3042 assemble_tokens ("mov", newtok, 2, 1);
3043 }
3044
3045 if (xr != AXP_REG_R16)
3046 {
3047 set_tok_reg (newtok[0], xr);
3048 set_tok_reg (newtok[1], AXP_REG_R16);
3049 assemble_tokens ("mov", newtok, 2, 1);
3050 }
3051
3052 if (yr != AXP_REG_R16 && yr != AXP_REG_R17)
3053 {
3054 set_tok_reg (newtok[0], yr);
3055 set_tok_reg (newtok[1], AXP_REG_R17);
3056 assemble_tokens ("mov", newtok, 2, 1);
3057 }
3058 }
3059
3060 sym = symbol_find_or_make ((const char *)symname);
3061
3062 set_tok_reg (newtok[0], AXP_REG_AT);
3063 set_tok_sym (newtok[1], sym, 0);
3064 assemble_tokens ("lda", newtok, 2, 1);
3065
3066 /* Call the division routine */
3067 set_tok_reg (newtok[0], AXP_REG_AT);
3068 set_tok_cpreg (newtok[1], AXP_REG_AT);
3069 set_tok_const (newtok[2], 0);
3070 assemble_tokens ("jsr", newtok, 3, 1);
3071
3072 /* Move the result to the right place */
3073 if (rr != AXP_REG_R0)
3074 {
3075 set_tok_reg (newtok[0], AXP_REG_R0);
3076 set_tok_reg (newtok[1], rr);
3077 assemble_tokens ("mov", newtok, 2, 1);
3078 }
3079 }
3080
3081 #else /* !OBJ_EVAX */
3082
3083 static void
3084 emit_division (tok, ntok, symname)
3085 const expressionS *tok;
3086 int ntok;
3087 const PTR symname;
3088 {
3089 /* DIVISION and MODULUS. Yech.
3090 * Convert
3091 * OP x,y,result
3092 * to
3093 * lda pv,__OP
3094 * mov x,t10
3095 * mov y,t11
3096 * jsr t9,(pv),__OP
3097 * mov t12,result
3098 *
3099 * with appropriate optimizations if t10,t11,t12 are the registers
3100 * specified by the compiler.
3101 */
3102
3103 int xr, yr, rr;
3104 symbolS *sym;
3105 expressionS newtok[3];
3106
3107 xr = regno (tok[0].X_add_number);
3108 yr = regno (tok[1].X_add_number);
3109
3110 if (ntok < 3)
3111 rr = xr;
3112 else
3113 rr = regno (tok[2].X_add_number);
3114
3115 sym = symbol_find_or_make ((const char *)symname);
3116
3117 /* Move the operands into the right place */
3118 if (yr == AXP_REG_T10 && xr == AXP_REG_T11)
3119 {
3120 /* They are in exactly the wrong order -- swap through AT */
3121
3122 if (alpha_noat_on)
3123 as_bad ("macro requires $at register while noat in effect");
3124
3125 set_tok_reg (newtok[0], AXP_REG_T10);
3126 set_tok_reg (newtok[1], AXP_REG_AT);
3127 assemble_tokens ("mov", newtok, 2, 1);
3128
3129 set_tok_reg (newtok[0], AXP_REG_T11);
3130 set_tok_reg (newtok[1], AXP_REG_T10);
3131 assemble_tokens ("mov", newtok, 2, 1);
3132
3133 set_tok_reg (newtok[0], AXP_REG_AT);
3134 set_tok_reg (newtok[1], AXP_REG_T11);
3135 assemble_tokens ("mov", newtok, 2, 1);
3136 }
3137 else
3138 {
3139 if (yr == AXP_REG_T10)
3140 {
3141 set_tok_reg (newtok[0], AXP_REG_T10);
3142 set_tok_reg (newtok[1], AXP_REG_T11);
3143 assemble_tokens ("mov", newtok, 2, 1);
3144 }
3145
3146 if (xr != AXP_REG_T10)
3147 {
3148 set_tok_reg (newtok[0], xr);
3149 set_tok_reg (newtok[1], AXP_REG_T10);
3150 assemble_tokens ("mov", newtok, 2, 1);
3151 }
3152
3153 if (yr != AXP_REG_T10 && yr != AXP_REG_T11)
3154 {
3155 set_tok_reg (newtok[0], yr);
3156 set_tok_reg (newtok[1], AXP_REG_T11);
3157 assemble_tokens ("mov", newtok, 2, 1);
3158 }
3159 }
3160
3161 /* Call the division routine */
3162 set_tok_reg (newtok[0], AXP_REG_T9);
3163 set_tok_sym (newtok[1], sym, 0);
3164 assemble_tokens ("jsr", newtok, 2, 1);
3165
3166 /* Reload the GP register */
3167 #ifdef OBJ_AOUT
3168 FIXME
3169 #endif
3170 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
3171 set_tok_reg (newtok[0], alpha_gp_register);
3172 set_tok_const (newtok[1], 0);
3173 set_tok_preg (newtok[2], AXP_REG_T9);
3174 assemble_tokens ("ldgp", newtok, 3, 1);
3175 #endif
3176
3177 /* Move the result to the right place */
3178 if (rr != AXP_REG_T12)
3179 {
3180 set_tok_reg (newtok[0], AXP_REG_T12);
3181 set_tok_reg (newtok[1], rr);
3182 assemble_tokens ("mov", newtok, 2, 1);
3183 }
3184 }
3185
3186 #endif /* !OBJ_EVAX */
3187
3188 /* The jsr and jmp macros differ from their instruction counterparts
3189 in that they can load the target address and default most
3190 everything. */
3191
3192 static void
3193 emit_jsrjmp (tok, ntok, vopname)
3194 const expressionS *tok;
3195 int ntok;
3196 const PTR vopname;
3197 {
3198 const char *opname = (const char *) vopname;
3199 struct alpha_insn insn;
3200 expressionS newtok[3];
3201 int r, tokidx = 0, lituse = 0;
3202
3203 if (tokidx < ntok && tok[tokidx].X_op == O_register)
3204 r = regno (tok[tokidx++].X_add_number);
3205 else
3206 r = strcmp (opname, "jmp") == 0 ? AXP_REG_ZERO : AXP_REG_RA;
3207
3208 set_tok_reg (newtok[0], r);
3209
3210 if (tokidx < ntok &&
3211 (tok[tokidx].X_op == O_pregister || tok[tokidx].X_op == O_cpregister))
3212 r = regno (tok[tokidx++].X_add_number);
3213 #ifdef OBJ_EVAX
3214 /* keep register if jsr $n.<sym> */
3215 #else
3216 else
3217 {
3218 int basereg = alpha_gp_register;
3219 lituse = load_expression (r = AXP_REG_PV, &tok[tokidx], &basereg, NULL);
3220 }
3221 #endif
3222
3223 set_tok_cpreg (newtok[1], r);
3224
3225 #ifdef OBJ_EVAX
3226 /* FIXME: Add hint relocs to BFD for evax. */
3227 #else
3228 if (tokidx < ntok)
3229 newtok[2] = tok[tokidx];
3230 else
3231 #endif
3232 set_tok_const (newtok[2], 0);
3233
3234 assemble_tokens_to_insn (opname, newtok, 3, &insn);
3235
3236 /* add the LITUSE fixup */
3237 if (lituse)
3238 {
3239 assert (insn.nfixups < MAX_INSN_FIXUPS);
3240 if (insn.nfixups > 0)
3241 {
3242 memmove (&insn.fixups[1], &insn.fixups[0],
3243 sizeof(struct alpha_fixup) * insn.nfixups);
3244 }
3245 insn.nfixups++;
3246 insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITUSE;
3247 insn.fixups[0].exp.X_op = O_constant;
3248 insn.fixups[0].exp.X_add_number = 3;
3249 }
3250
3251 emit_insn (&insn);
3252
3253 #ifdef OBJ_EVAX
3254 alpha_basereg_clobbered = 0;
3255
3256 /* reload PV from 0(FP) if it is our current base register. */
3257 if (alpha_gp_register == AXP_REG_PV)
3258 {
3259 set_tok_reg (newtok[0], AXP_REG_PV);
3260 set_tok_const (newtok[1], 0);
3261 set_tok_preg (newtok[2], AXP_REG_FP);
3262 assemble_tokens ("ldq", newtok, 3, 0);
3263 }
3264 #endif
3265 }
3266
3267 /* The ret and jcr instructions differ from their instruction
3268 counterparts in that everything can be defaulted. */
3269
3270 static void
3271 emit_retjcr (tok, ntok, vopname)
3272 const expressionS *tok;
3273 int ntok;
3274 const PTR vopname;
3275 {
3276 const char *opname = (const char *)vopname;
3277 expressionS newtok[3];
3278 int r, tokidx = 0;
3279
3280 if (tokidx < ntok && tok[tokidx].X_op == O_register)
3281 r = regno (tok[tokidx++].X_add_number);
3282 else
3283 r = AXP_REG_ZERO;
3284
3285 set_tok_reg (newtok[0], r);
3286
3287 if (tokidx < ntok &&
3288 (tok[tokidx].X_op == O_pregister || tok[tokidx].X_op == O_cpregister))
3289 r = regno (tok[tokidx++].X_add_number);
3290 else
3291 r = AXP_REG_RA;
3292
3293 set_tok_cpreg (newtok[1], r);
3294
3295 if (tokidx < ntok)
3296 newtok[2] = tok[tokidx];
3297 else
3298 set_tok_const (newtok[2], strcmp(opname, "ret") == 0);
3299
3300 assemble_tokens (opname, newtok, 3, 0);
3301 }
3302 \f
3303 /* Assembler directives */
3304
3305 /* Handle the .text pseudo-op. This is like the usual one, but it
3306 clears alpha_insn_label and restores auto alignment. */
3307
3308 static void
3309 s_alpha_text (i)
3310 int i;
3311
3312 {
3313 s_text (i);
3314 alpha_insn_label = NULL;
3315 alpha_auto_align_on = 1;
3316 alpha_current_align = 0;
3317 }
3318
3319 /* Handle the .data pseudo-op. This is like the usual one, but it
3320 clears alpha_insn_label and restores auto alignment. */
3321
3322 static void
3323 s_alpha_data (i)
3324 int i;
3325 {
3326 s_data (i);
3327 alpha_insn_label = NULL;
3328 alpha_auto_align_on = 1;
3329 alpha_current_align = 0;
3330 }
3331
3332 #ifdef OBJ_ECOFF
3333
3334 /* Handle the OSF/1 .comm pseudo quirks. */
3335
3336 static void
3337 s_alpha_comm (ignore)
3338 int ignore;
3339 {
3340 register char *name;
3341 register char c;
3342 register char *p;
3343 offsetT temp;
3344 register symbolS *symbolP;
3345
3346 name = input_line_pointer;
3347 c = get_symbol_end ();
3348
3349 /* just after name is now '\0' */
3350 p = input_line_pointer;
3351 *p = c;
3352
3353 SKIP_WHITESPACE ();
3354
3355 /* Alpha OSF/1 compiler doesn't provide the comma, gcc does. */
3356 if (*input_line_pointer == ',')
3357 {
3358 input_line_pointer++;
3359 SKIP_WHITESPACE ();
3360 }
3361 if ((temp = get_absolute_expression ()) < 0)
3362 {
3363 as_warn (".COMMon length (%ld.) <0! Ignored.", (long) temp);
3364 ignore_rest_of_line ();
3365 return;
3366 }
3367
3368 *p = 0;
3369 symbolP = symbol_find_or_make (name);
3370 *p = c;
3371
3372 if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
3373 {
3374 as_bad ("Ignoring attempt to re-define symbol");
3375 ignore_rest_of_line ();
3376 return;
3377 }
3378
3379 if (S_GET_VALUE (symbolP))
3380 {
3381 if (S_GET_VALUE (symbolP) != (valueT) temp)
3382 as_bad ("Length of .comm \"%s\" is already %ld. Not changed to %ld.",
3383 S_GET_NAME (symbolP),
3384 (long) S_GET_VALUE (symbolP),
3385 (long) temp);
3386 }
3387 else
3388 {
3389 S_SET_VALUE (symbolP, (valueT) temp);
3390 S_SET_EXTERNAL (symbolP);
3391 }
3392
3393 know (symbolP->sy_frag == &zero_address_frag);
3394
3395 demand_empty_rest_of_line ();
3396 }
3397
3398 #endif /* ! OBJ_ELF */
3399
3400 #ifdef OBJ_ECOFF
3401
3402 /* Handle the .rdata pseudo-op. This is like the usual one, but it
3403 clears alpha_insn_label and restores auto alignment. */
3404
3405 static void
3406 s_alpha_rdata (ignore)
3407 int ignore;
3408 {
3409 int temp;
3410
3411 temp = get_absolute_expression ();
3412 subseg_new (".rdata", 0);
3413 demand_empty_rest_of_line ();
3414 alpha_insn_label = NULL;
3415 alpha_auto_align_on = 1;
3416 alpha_current_align = 0;
3417 }
3418
3419 #endif
3420
3421 #ifdef OBJ_ECOFF
3422
3423 /* Handle the .sdata pseudo-op. This is like the usual one, but it
3424 clears alpha_insn_label and restores auto alignment. */
3425
3426 static void
3427 s_alpha_sdata (ignore)
3428 int ignore;
3429 {
3430 int temp;
3431
3432 temp = get_absolute_expression ();
3433 subseg_new (".sdata", 0);
3434 demand_empty_rest_of_line ();
3435 alpha_insn_label = NULL;
3436 alpha_auto_align_on = 1;
3437 alpha_current_align = 0;
3438 }
3439 #endif
3440
3441 #ifdef OBJ_ELF
3442
3443 /* Handle the .section pseudo-op. This is like the usual one, but it
3444 clears alpha_insn_label and restores auto alignment. */
3445
3446 static void
3447 s_alpha_section (ignore)
3448 int ignore;
3449 {
3450 obj_elf_section (ignore);
3451
3452 alpha_insn_label = NULL;
3453 alpha_auto_align_on = 1;
3454 alpha_current_align = 0;
3455 }
3456
3457 #endif
3458
3459 #ifdef OBJ_EVAX
3460
3461 /* Handle the section specific pseudo-op. */
3462
3463 static void
3464 s_alpha_section (secid)
3465 int secid;
3466 {
3467 int temp;
3468 #define EVAX_SECTION_COUNT 6
3469 static char *section_name[EVAX_SECTION_COUNT+1] =
3470 { "NULL", ".rdata", ".comm", ".link", ".ctors", ".dtors", ".lcomm" };
3471
3472 if ((secid <= 0) || (secid > EVAX_SECTION_COUNT))
3473 {
3474 as_fatal ("Unknown section directive");
3475 demand_empty_rest_of_line ();
3476 return;
3477 }
3478 temp = get_absolute_expression ();
3479 subseg_new (section_name[secid], 0);
3480 demand_empty_rest_of_line ();
3481 alpha_insn_label = NULL;
3482 alpha_auto_align_on = 1;
3483 alpha_current_align = 0;
3484 }
3485
3486
3487 /* .prologue */
3488
3489 static void
3490 s_alpha_prologue (ignore)
3491 int ignore;
3492 {
3493 alpha_basereg_clobbered = 0;
3494 demand_empty_rest_of_line ();
3495
3496 return;
3497 }
3498
3499
3500 /* Parse .ent directives. */
3501
3502 static void
3503 s_alpha_ent (ignore)
3504 int ignore;
3505 {
3506 symbolS *symbol;
3507 expressionS symexpr;
3508
3509 alpha_evax_proc.pdsckind = 0;
3510 alpha_evax_proc.framereg = -1;
3511 alpha_evax_proc.framesize = 0;
3512 alpha_evax_proc.rsa_offset = 0;
3513 alpha_evax_proc.ra_save = AXP_REG_RA;
3514 alpha_evax_proc.fp_save = -1;
3515 alpha_evax_proc.imask = 0;
3516 alpha_evax_proc.fmask = 0;
3517 alpha_evax_proc.prologue = 0;
3518 alpha_evax_proc.type = 0;
3519
3520 expression (&symexpr);
3521
3522 if (symexpr.X_op != O_symbol)
3523 {
3524 as_fatal (".ent directive has no symbol");
3525 demand_empty_rest_of_line ();
3526 return;
3527 }
3528
3529 symbol = make_expr_symbol (&symexpr);
3530 symbol->bsym->flags |= BSF_FUNCTION;
3531 alpha_evax_proc.symbol = symbol;
3532
3533 demand_empty_rest_of_line ();
3534 return;
3535 }
3536
3537
3538 /* Parse .frame <framreg>,<framesize>,RA,<rsa_offset> directives. */
3539
3540 static void
3541 s_alpha_frame (ignore)
3542 int ignore;
3543 {
3544 long val;
3545
3546 alpha_evax_proc.framereg = tc_get_register (1);
3547
3548 SKIP_WHITESPACE ();
3549 if (*input_line_pointer++ != ','
3550 || get_absolute_expression_and_terminator (&val) != ',')
3551 {
3552 as_warn ("Bad .frame directive 1./2. param");
3553 --input_line_pointer;
3554 demand_empty_rest_of_line ();
3555 return;
3556 }
3557
3558 alpha_evax_proc.framesize = val;
3559
3560 (void) tc_get_register (1);
3561 SKIP_WHITESPACE ();
3562 if (*input_line_pointer++ != ',')
3563 {
3564 as_warn ("Bad .frame directive 3./4. param");
3565 --input_line_pointer;
3566 demand_empty_rest_of_line ();
3567 return;
3568 }
3569 alpha_evax_proc.rsa_offset = get_absolute_expression ();
3570
3571 return;
3572 }
3573
3574 static void
3575 s_alpha_pdesc (ignore)
3576 int ignore;
3577 {
3578 char *name;
3579 char name_end;
3580 long val;
3581 register char *p;
3582 expressionS exp;
3583 symbolS *entry_sym;
3584 fixS *fixp;
3585 segment_info_type *seginfo = seg_info (alpha_link_section);
3586
3587 if (now_seg != alpha_link_section)
3588 {
3589 as_bad (".pdesc directive not in link (.link) section");
3590 demand_empty_rest_of_line ();
3591 return;
3592 }
3593
3594 if ((alpha_evax_proc.symbol == 0)
3595 || (!S_IS_DEFINED (alpha_evax_proc.symbol)))
3596 {
3597 as_fatal (".pdesc has no matching .ent");
3598 demand_empty_rest_of_line ();
3599 return;
3600 }
3601
3602 alpha_evax_proc.symbol->sy_obj = (valueT)seginfo->literal_pool_size;
3603
3604 expression (&exp);
3605 if (exp.X_op != O_symbol)
3606 {
3607 as_warn (".pdesc directive has no entry symbol");
3608 demand_empty_rest_of_line ();
3609 return;
3610 }
3611
3612 entry_sym = make_expr_symbol (&exp);
3613 /* Save bfd symbol of proc desc in function symbol. */
3614 alpha_evax_proc.symbol->bsym->udata.p = (PTR)entry_sym->bsym;
3615
3616 SKIP_WHITESPACE ();
3617 if (*input_line_pointer++ != ',')
3618 {
3619 as_warn ("No comma after .pdesc <entryname>");
3620 demand_empty_rest_of_line ();
3621 return;
3622 }
3623
3624 SKIP_WHITESPACE ();
3625 name = input_line_pointer;
3626 name_end = get_symbol_end ();
3627
3628 if (strncmp(name, "stack", 5) == 0)
3629 {
3630 alpha_evax_proc.pdsckind = PDSC_S_K_KIND_FP_STACK;
3631 }
3632 else if (strncmp(name, "reg", 3) == 0)
3633 {
3634 alpha_evax_proc.pdsckind = PDSC_S_K_KIND_FP_REGISTER;
3635 }
3636 else if (strncmp(name, "null", 4) == 0)
3637 {
3638 alpha_evax_proc.pdsckind = PDSC_S_K_KIND_NULL;
3639 }
3640 else
3641 {
3642 as_fatal ("unknown procedure kind");
3643 demand_empty_rest_of_line ();
3644 return;
3645 }
3646
3647 *input_line_pointer = name_end;
3648 demand_empty_rest_of_line ();
3649
3650 #ifdef md_flush_pending_output
3651 md_flush_pending_output ();
3652 #endif
3653
3654 frag_align (3, 0, 0);
3655 p = frag_more (16);
3656 fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
3657 fixp->fx_done = 1;
3658 seginfo->literal_pool_size += 16;
3659
3660 *p = alpha_evax_proc.pdsckind
3661 | ((alpha_evax_proc.framereg == 29) ? PDSC_S_M_BASE_REG_IS_FP : 0);
3662 *(p+1) = PDSC_S_M_NATIVE
3663 | PDSC_S_M_NO_JACKET;
3664
3665 switch (alpha_evax_proc.pdsckind)
3666 {
3667 case PDSC_S_K_KIND_NULL:
3668 *(p+2) = 0;
3669 *(p+3) = 0;
3670 break;
3671 case PDSC_S_K_KIND_FP_REGISTER:
3672 *(p+2) = alpha_evax_proc.fp_save;
3673 *(p+3) = alpha_evax_proc.ra_save;
3674 break;
3675 case PDSC_S_K_KIND_FP_STACK:
3676 md_number_to_chars (p+2, (valueT)alpha_evax_proc.rsa_offset, 2);
3677 break;
3678 default: /* impossible */
3679 break;
3680 }
3681
3682 *(p+4) = 0;
3683 *(p+5) = alpha_evax_proc.type & 0x0f;
3684
3685 /* Signature offset. */
3686 md_number_to_chars (p+6, (valueT)0, 2);
3687
3688 fix_new_exp (frag_now, p-frag_now->fr_literal+8, 8, &exp, 0, BFD_RELOC_64);
3689
3690 if (alpha_evax_proc.pdsckind == PDSC_S_K_KIND_NULL)
3691 return;
3692
3693 /* Add dummy fix to make add_to_link_pool work. */
3694 p = frag_more (8);
3695 fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
3696 fixp->fx_done = 1;
3697 seginfo->literal_pool_size += 8;
3698
3699 /* pdesc+16: Size. */
3700 md_number_to_chars (p, (valueT)alpha_evax_proc.framesize, 4);
3701
3702 md_number_to_chars (p+4, (valueT)0, 2);
3703
3704 /* Entry length. */
3705 md_number_to_chars (p+6, alpha_evax_proc.prologue, 2);
3706
3707 if (alpha_evax_proc.pdsckind == PDSC_S_K_KIND_FP_REGISTER)
3708 return;
3709
3710 /* Add dummy fix to make add_to_link_pool work. */
3711 p = frag_more (8);
3712 fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
3713 fixp->fx_done = 1;
3714 seginfo->literal_pool_size += 8;
3715
3716 /* pdesc+24: register masks. */
3717
3718 md_number_to_chars (p, alpha_evax_proc.imask, 4);
3719 md_number_to_chars (p+4, alpha_evax_proc.fmask, 4);
3720
3721 return;
3722 }
3723
3724
3725 /* Support for crash debug on vms. */
3726
3727 static void
3728 s_alpha_name (ignore)
3729 int ignore;
3730 {
3731 register char *p;
3732 expressionS exp;
3733 segment_info_type *seginfo = seg_info (alpha_link_section);
3734
3735 if (now_seg != alpha_link_section)
3736 {
3737 as_bad (".name directive not in link (.link) section");
3738 demand_empty_rest_of_line ();
3739 return;
3740 }
3741
3742 expression (&exp);
3743 if (exp.X_op != O_symbol)
3744 {
3745 as_warn (".name directive has no symbol");
3746 demand_empty_rest_of_line ();
3747 return;
3748 }
3749
3750 demand_empty_rest_of_line ();
3751
3752 #ifdef md_flush_pending_output
3753 md_flush_pending_output ();
3754 #endif
3755
3756 frag_align (3, 0, 0);
3757 p = frag_more (8);
3758 seginfo->literal_pool_size += 8;
3759
3760 fix_new_exp (frag_now, p-frag_now->fr_literal, 8, &exp, 0, BFD_RELOC_64);
3761
3762 return;
3763 }
3764
3765
3766 static void
3767 s_alpha_linkage (ignore)
3768 int ignore;
3769 {
3770 expressionS exp;
3771 char *p;
3772
3773 #ifdef md_flush_pending_output
3774 md_flush_pending_output ();
3775 #endif
3776
3777 expression (&exp);
3778 if (exp.X_op != O_symbol)
3779 {
3780 as_fatal ("No symbol after .linkage");
3781 }
3782 else
3783 {
3784 p = frag_more (LKP_S_K_SIZE);
3785 memset (p, 0, LKP_S_K_SIZE);
3786 fix_new_exp (frag_now, p - frag_now->fr_literal, LKP_S_K_SIZE, &exp, 0,\
3787 BFD_RELOC_ALPHA_LINKAGE);
3788 }
3789 demand_empty_rest_of_line ();
3790
3791 return;
3792 }
3793
3794
3795 static void
3796 s_alpha_code_address (ignore)
3797 int ignore;
3798 {
3799 expressionS exp;
3800 char *p;
3801
3802 #ifdef md_flush_pending_output
3803 md_flush_pending_output ();
3804 #endif
3805
3806 expression (&exp);
3807 if (exp.X_op != O_symbol)
3808 {
3809 as_fatal ("No symbol after .code_address");
3810 }
3811 else
3812 {
3813 p = frag_more (8);
3814 memset (p, 0, 8);
3815 fix_new_exp (frag_now, p - frag_now->fr_literal, 8, &exp, 0,\
3816 BFD_RELOC_ALPHA_CODEADDR);
3817 }
3818 demand_empty_rest_of_line ();
3819
3820 return;
3821 }
3822
3823
3824 static void
3825 s_alpha_fp_save (ignore)
3826 int ignore;
3827 {
3828
3829 alpha_evax_proc.fp_save = tc_get_register (1);
3830
3831 demand_empty_rest_of_line ();
3832 return;
3833 }
3834
3835
3836 static void
3837 s_alpha_mask (ignore)
3838 int ignore;
3839 {
3840 long val;
3841
3842 if (get_absolute_expression_and_terminator (&val) != ',')
3843 {
3844 as_warn ("Bad .mask directive");
3845 --input_line_pointer;
3846 }
3847 else
3848 {
3849 alpha_evax_proc.imask = val;
3850 (void)get_absolute_expression ();
3851 }
3852 demand_empty_rest_of_line ();
3853
3854 return;
3855 }
3856
3857
3858 static void
3859 s_alpha_fmask (ignore)
3860 int ignore;
3861 {
3862 long val;
3863
3864 if (get_absolute_expression_and_terminator (&val) != ',')
3865 {
3866 as_warn ("Bad .fmask directive");
3867 --input_line_pointer;
3868 }
3869 else
3870 {
3871 alpha_evax_proc.fmask = val;
3872 (void) get_absolute_expression ();
3873 }
3874 demand_empty_rest_of_line ();
3875
3876 return;
3877 }
3878
3879 static void
3880 s_alpha_end (ignore)
3881 int ignore;
3882 {
3883 char c;
3884
3885 c = get_symbol_end ();
3886 *input_line_pointer = c;
3887 demand_empty_rest_of_line ();
3888 alpha_evax_proc.symbol = 0;
3889 alpha_basereg_clobbered = 0;
3890
3891 return;
3892 }
3893
3894
3895 static void
3896 s_alpha_file (ignore)
3897 int ignore;
3898 {
3899 symbolS *s;
3900 int length;
3901 static char case_hack[32];
3902
3903 extern char *demand_copy_string PARAMS ((int *lenP));
3904
3905 sprintf (case_hack, "<CASE:%01d%01d>",
3906 alpha_flag_hash_long_names, alpha_flag_show_after_trunc);
3907
3908 s = symbol_find_or_make (case_hack);
3909 s->bsym->flags |= BSF_FILE;
3910
3911 get_absolute_expression ();
3912 s = symbol_find_or_make (demand_copy_string (&length));
3913 s->bsym->flags |= BSF_FILE;
3914 demand_empty_rest_of_line ();
3915
3916 return;
3917 }
3918 #endif /* OBJ_EVAX */
3919
3920 /* Handle the .gprel32 pseudo op. */
3921
3922 static void
3923 s_alpha_gprel32 (ignore)
3924 int ignore;
3925 {
3926 expressionS e;
3927 char *p;
3928
3929 SKIP_WHITESPACE ();
3930 expression (&e);
3931
3932 #ifdef OBJ_ELF
3933 switch (e.X_op)
3934 {
3935 case O_constant:
3936 e.X_add_symbol = section_symbol(absolute_section);
3937 e.X_op = O_symbol;
3938 /* FALLTHRU */
3939 case O_symbol:
3940 break;
3941 default:
3942 abort();
3943 }
3944 #else
3945 #ifdef OBJ_ECOFF
3946 switch (e.X_op)
3947 {
3948 case O_constant:
3949 e.X_add_symbol = section_symbol (absolute_section);
3950 /* fall through */
3951 case O_symbol:
3952 e.X_op = O_subtract;
3953 e.X_op_symbol = alpha_gp_symbol;
3954 break;
3955 default:
3956 abort ();
3957 }
3958 #endif
3959 #endif
3960
3961 if (alpha_auto_align_on && alpha_current_align < 2)
3962 alpha_align (2, (char *) NULL, alpha_insn_label);
3963 if (alpha_current_align > 2)
3964 alpha_current_align = 2;
3965 alpha_insn_label = NULL;
3966
3967 p = frag_more (4);
3968 memset (p, 0, 4);
3969 fix_new_exp (frag_now, p-frag_now->fr_literal, 4,
3970 &e, 0, BFD_RELOC_GPREL32);
3971 }
3972
3973 /* Handle floating point allocation pseudo-ops. This is like the
3974 generic vresion, but it makes sure the current label, if any, is
3975 correctly aligned. */
3976
3977 static void
3978 s_alpha_float_cons (type)
3979 int type;
3980 {
3981 int log_size;
3982
3983 switch (type)
3984 {
3985 default:
3986 case 'f':
3987 case 'F':
3988 log_size = 2;
3989 break;
3990
3991 case 'd':
3992 case 'D':
3993 case 'G':
3994 log_size = 3;
3995 break;
3996
3997 case 'x':
3998 case 'X':
3999 case 'p':
4000 case 'P':
4001 log_size = 4;
4002 break;
4003 }
4004
4005 if (alpha_auto_align_on && alpha_current_align < log_size)
4006 alpha_align (log_size, (char *) NULL, alpha_insn_label);
4007 if (alpha_current_align > log_size)
4008 alpha_current_align = log_size;
4009 alpha_insn_label = NULL;
4010
4011 float_cons (type);
4012 }
4013
4014 /* Handle the .proc pseudo op. We don't really do much with it except
4015 parse it. */
4016
4017 static void
4018 s_alpha_proc (is_static)
4019 int is_static;
4020 {
4021 char *name;
4022 char c;
4023 char *p;
4024 symbolS *symbolP;
4025 int temp;
4026
4027 /* Takes ".proc name,nargs" */
4028 SKIP_WHITESPACE ();
4029 name = input_line_pointer;
4030 c = get_symbol_end ();
4031 p = input_line_pointer;
4032 symbolP = symbol_find_or_make (name);
4033 *p = c;
4034 SKIP_WHITESPACE ();
4035 if (*input_line_pointer != ',')
4036 {
4037 *p = 0;
4038 as_warn ("Expected comma after name \"%s\"", name);
4039 *p = c;
4040 temp = 0;
4041 ignore_rest_of_line ();
4042 }
4043 else
4044 {
4045 input_line_pointer++;
4046 temp = get_absolute_expression ();
4047 }
4048 /* symbolP->sy_other = (signed char) temp; */
4049 as_warn ("unhandled: .proc %s,%d", name, temp);
4050 demand_empty_rest_of_line ();
4051 }
4052
4053 /* Handle the .set pseudo op. This is used to turn on and off most of
4054 the assembler features. */
4055
4056 static void
4057 s_alpha_set (x)
4058 int x;
4059 {
4060 char *name, ch, *s;
4061 int yesno = 1;
4062
4063 SKIP_WHITESPACE ();
4064 name = input_line_pointer;
4065 ch = get_symbol_end ();
4066
4067 s = name;
4068 if (s[0] == 'n' && s[1] == 'o')
4069 {
4070 yesno = 0;
4071 s += 2;
4072 }
4073 if (!strcmp ("reorder", s))
4074 /* ignore */ ;
4075 else if (!strcmp ("at", s))
4076 alpha_noat_on = !yesno;
4077 else if (!strcmp ("macro", s))
4078 alpha_macros_on = yesno;
4079 else if (!strcmp ("move", s))
4080 /* ignore */ ;
4081 else if (!strcmp ("volatile", s))
4082 /* ignore */ ;
4083 else
4084 as_warn ("Tried to .set unrecognized mode `%s'", name);
4085
4086 *input_line_pointer = ch;
4087 demand_empty_rest_of_line ();
4088 }
4089
4090 /* Handle the .base pseudo op. This changes the assembler's notion of
4091 the $gp register. */
4092
4093 static void
4094 s_alpha_base (ignore)
4095 int ignore;
4096 {
4097 #if 0
4098 if (first_32bit_quadrant)
4099 {
4100 /* not fatal, but it might not work in the end */
4101 as_warn ("File overrides no-base-register option.");
4102 first_32bit_quadrant = 0;
4103 }
4104 #endif
4105
4106 SKIP_WHITESPACE ();
4107 if (*input_line_pointer == '$')
4108 { /* $rNN form */
4109 input_line_pointer++;
4110 if (*input_line_pointer == 'r')
4111 input_line_pointer++;
4112 }
4113
4114 alpha_gp_register = get_absolute_expression ();
4115 if (alpha_gp_register < 0 || alpha_gp_register > 31)
4116 {
4117 alpha_gp_register = AXP_REG_GP;
4118 as_warn ("Bad base register, using $%d.", alpha_gp_register);
4119 }
4120
4121 demand_empty_rest_of_line ();
4122 }
4123
4124 /* Handle the .align pseudo-op. This aligns to a power of two. It
4125 also adjusts any current instruction label. We treat this the same
4126 way the MIPS port does: .align 0 turns off auto alignment. */
4127
4128 static void
4129 s_alpha_align (ignore)
4130 int ignore;
4131 {
4132 int align;
4133 char fill, *pfill;
4134 long max_alignment = 15;
4135
4136 align = get_absolute_expression ();
4137 if (align > max_alignment)
4138 {
4139 align = max_alignment;
4140 as_bad ("Alignment too large: %d. assumed", align);
4141 }
4142 else if (align < 0)
4143 {
4144 as_warn ("Alignment negative: 0 assumed");
4145 align = 0;
4146 }
4147
4148 if (*input_line_pointer == ',')
4149 {
4150 input_line_pointer++;
4151 fill = get_absolute_expression ();
4152 pfill = &fill;
4153 }
4154 else
4155 pfill = NULL;
4156
4157 if (align != 0)
4158 {
4159 alpha_auto_align_on = 1;
4160 alpha_align (align, pfill, alpha_insn_label);
4161 }
4162 else
4163 {
4164 alpha_auto_align_on = 0;
4165 }
4166
4167 demand_empty_rest_of_line ();
4168 }
4169
4170 /* Hook the normal string processor to reset known alignment. */
4171
4172 static void
4173 s_alpha_stringer (terminate)
4174 int terminate;
4175 {
4176 alpha_current_align = 0;
4177 alpha_insn_label = NULL;
4178 stringer (terminate);
4179 }
4180
4181 /* Hook the normal space processing to reset known alignment. */
4182
4183 static void
4184 s_alpha_space (ignore)
4185 int ignore;
4186 {
4187 alpha_current_align = 0;
4188 alpha_insn_label = NULL;
4189 s_space (ignore);
4190 }
4191
4192 /* Hook into cons for auto-alignment. */
4193
4194 void
4195 alpha_cons_align (size)
4196 int size;
4197 {
4198 int log_size;
4199
4200 log_size = 0;
4201 while ((size >>= 1) != 0)
4202 ++log_size;
4203
4204 if (alpha_auto_align_on && alpha_current_align < log_size)
4205 alpha_align (log_size, (char *) NULL, alpha_insn_label);
4206 if (alpha_current_align > log_size)
4207 alpha_current_align = log_size;
4208 alpha_insn_label = NULL;
4209 }
4210
4211 /* Here come the .uword, .ulong, and .uquad explicitly unaligned
4212 pseudos. We just turn off auto-alignment and call down to cons. */
4213
4214 static void
4215 s_alpha_ucons (bytes)
4216 int bytes;
4217 {
4218 int hold = alpha_auto_align_on;
4219 alpha_auto_align_on = 0;
4220 cons (bytes);
4221 alpha_auto_align_on = hold;
4222 }
4223
4224 /* Switch the working cpu type. */
4225
4226 static void
4227 s_alpha_arch (ignored)
4228 int ignored;
4229 {
4230 char *name, ch;
4231 const struct cpu_type *p;
4232
4233 SKIP_WHITESPACE ();
4234 name = input_line_pointer;
4235 ch = get_symbol_end ();
4236
4237 for (p = cpu_types; p->name; ++p)
4238 if (strcmp(name, p->name) == 0)
4239 {
4240 alpha_target_name = p->name, alpha_target = p->flags;
4241 goto found;
4242 }
4243 as_warn("Unknown CPU identifier `%s'", name);
4244
4245 found:
4246 *input_line_pointer = ch;
4247 demand_empty_rest_of_line ();
4248 }
4249
4250 \f
4251
4252 #ifdef DEBUG1
4253 /* print token expression with alpha specific extension. */
4254
4255 static void
4256 alpha_print_token(f, exp)
4257 FILE *f;
4258 const expressionS *exp;
4259 {
4260 switch (exp->X_op)
4261 {
4262 case O_cpregister:
4263 putc (',', f);
4264 /* FALLTHRU */
4265 case O_pregister:
4266 putc ('(', f);
4267 {
4268 expressionS nexp = *exp;
4269 nexp.X_op = O_register;
4270 print_expr (f, &nexp);
4271 }
4272 putc (')', f);
4273 break;
4274 default:
4275 print_expr (f, exp);
4276 break;
4277 }
4278 return;
4279 }
4280 #endif
4281 \f
4282 /* The target specific pseudo-ops which we support. */
4283
4284 const pseudo_typeS md_pseudo_table[] =
4285 {
4286 {"common", s_comm, 0}, /* is this used? */
4287 #ifdef OBJ_ECOFF
4288 {"comm", s_alpha_comm, 0}, /* osf1 compiler does this */
4289 {"rdata", s_alpha_rdata, 0},
4290 #endif
4291 {"text", s_alpha_text, 0},
4292 {"data", s_alpha_data, 0},
4293 #ifdef OBJ_ECOFF
4294 {"sdata", s_alpha_sdata, 0},
4295 #endif
4296 #ifdef OBJ_ELF
4297 {"section", s_alpha_section, 0},
4298 {"section.s", s_alpha_section, 0},
4299 {"sect", s_alpha_section, 0},
4300 {"sect.s", s_alpha_section, 0},
4301 #endif
4302 #ifdef OBJ_EVAX
4303 { "pdesc", s_alpha_pdesc, 0},
4304 { "name", s_alpha_name, 0},
4305 { "linkage", s_alpha_linkage, 0},
4306 { "code_address", s_alpha_code_address, 0},
4307 { "ent", s_alpha_ent, 0},
4308 { "frame", s_alpha_frame, 0},
4309 { "fp_save", s_alpha_fp_save, 0},
4310 { "mask", s_alpha_mask, 0},
4311 { "fmask", s_alpha_fmask, 0},
4312 { "end", s_alpha_end, 0},
4313 { "file", s_alpha_file, 0},
4314 { "rdata", s_alpha_section, 1},
4315 { "comm", s_alpha_section, 2},
4316 { "link", s_alpha_section, 3},
4317 { "ctors", s_alpha_section, 4},
4318 { "dtors", s_alpha_section, 5},
4319 { "lcomm", s_alpha_section, 6},
4320 #endif
4321 {"gprel32", s_alpha_gprel32, 0},
4322 {"t_floating", s_alpha_float_cons, 'd'},
4323 {"s_floating", s_alpha_float_cons, 'f'},
4324 {"f_floating", s_alpha_float_cons, 'F'},
4325 {"g_floating", s_alpha_float_cons, 'G'},
4326 {"d_floating", s_alpha_float_cons, 'D'},
4327
4328 {"proc", s_alpha_proc, 0},
4329 {"aproc", s_alpha_proc, 1},
4330 {"set", s_alpha_set, 0},
4331 {"reguse", s_ignore, 0},
4332 {"livereg", s_ignore, 0},
4333 {"base", s_alpha_base, 0}, /*??*/
4334 {"option", s_ignore, 0},
4335 {"prologue", s_ignore, 0},
4336 {"aent", s_ignore, 0},
4337 {"ugen", s_ignore, 0},
4338 {"eflag", s_ignore, 0},
4339
4340 {"align", s_alpha_align, 0},
4341 {"double", s_alpha_float_cons, 'd'},
4342 {"float", s_alpha_float_cons, 'f'},
4343 {"single", s_alpha_float_cons, 'f'},
4344 {"ascii", s_alpha_stringer, 0},
4345 {"asciz", s_alpha_stringer, 1},
4346 {"string", s_alpha_stringer, 1},
4347 {"space", s_alpha_space, 0},
4348 {"skip", s_alpha_space, 0},
4349 {"zero", s_alpha_space, 0},
4350
4351 /* Unaligned data pseudos. */
4352 {"uword", s_alpha_ucons, 2},
4353 {"ulong", s_alpha_ucons, 4},
4354 {"uquad", s_alpha_ucons, 8},
4355
4356 #ifdef OBJ_ELF
4357 /* Dwarf wants these versions of unaligned. */
4358 {"2byte", s_alpha_ucons, 2},
4359 {"4byte", s_alpha_ucons, 4},
4360 {"8byte", s_alpha_ucons, 8},
4361 #endif
4362
4363 /* We don't do any optimizing, so we can safely ignore these. */
4364 {"noalias", s_ignore, 0},
4365 {"alias", s_ignore, 0},
4366
4367 {"arch", s_alpha_arch, 0},
4368
4369 {NULL, 0, 0},
4370 };
4371
4372 \f
4373 /* Build a BFD section with its flags set appropriately for the .lita,
4374 .lit8, or .lit4 sections. */
4375
4376 static void
4377 create_literal_section (name, secp, symp)
4378 const char *name;
4379 segT *secp;
4380 symbolS **symp;
4381 {
4382 segT current_section = now_seg;
4383 int current_subsec = now_subseg;
4384 segT new_sec;
4385
4386 *secp = new_sec = subseg_new (name, 0);
4387 subseg_set (current_section, current_subsec);
4388 bfd_set_section_alignment (stdoutput, new_sec, 4);
4389 bfd_set_section_flags (stdoutput, new_sec,
4390 SEC_RELOC | SEC_ALLOC | SEC_LOAD | SEC_READONLY
4391 | SEC_DATA);
4392
4393 S_CLEAR_EXTERNAL (*symp = section_symbol (new_sec));
4394 }
4395
4396 #ifdef OBJ_ECOFF
4397
4398 /* @@@ GP selection voodoo. All of this seems overly complicated and
4399 unnecessary; which is the primary reason it's for ECOFF only. */
4400
4401 static inline void
4402 maybe_set_gp (sec)
4403 asection *sec;
4404 {
4405 bfd_vma vma;
4406 if (!sec)
4407 return;
4408 vma = bfd_get_section_vma (foo, sec);
4409 if (vma && vma < alpha_gp_value)
4410 alpha_gp_value = vma;
4411 }
4412
4413 static void
4414 select_gp_value ()
4415 {
4416 assert (alpha_gp_value == 0);
4417
4418 /* Get minus-one in whatever width... */
4419 alpha_gp_value = 0; alpha_gp_value--;
4420
4421 /* Select the smallest VMA of these existing sections. */
4422 maybe_set_gp (alpha_lita_section);
4423 #if 0
4424 /* These were disabled before -- should we use them? */
4425 maybe_set_gp (sdata);
4426 maybe_set_gp (lit8_sec);
4427 maybe_set_gp (lit4_sec);
4428 #endif
4429
4430 /* @@ Will a simple 0x8000 work here? If not, why not? */
4431 #define GP_ADJUSTMENT (0x8000 - 0x10)
4432
4433 alpha_gp_value += GP_ADJUSTMENT;
4434
4435 S_SET_VALUE (alpha_gp_symbol, alpha_gp_value);
4436
4437 #ifdef DEBUG1
4438 printf ("Chose GP value of %lx\n", alpha_gp_value);
4439 #endif
4440 }
4441 #endif /* OBJ_ECOFF */
4442
4443 /* Called internally to handle all alignment needs. This takes care
4444 of eliding calls to frag_align if'n the cached current alignment
4445 says we've already got it, as well as taking care of the auto-align
4446 feature wrt labels. */
4447
4448 static void
4449 alpha_align (n, pfill, label)
4450 int n;
4451 char *pfill;
4452 symbolS *label;
4453 {
4454 if (alpha_current_align >= n)
4455 return;
4456
4457 if (pfill == NULL)
4458 {
4459 if (n > 2
4460 && (bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0)
4461 {
4462 static char const nop[4] = { 0x1f, 0x04, 0xff, 0x47 };
4463
4464 /* First, make sure we're on a four-byte boundary, in case
4465 someone has been putting .byte values into the text
4466 section. The DEC assembler silently fills with unaligned
4467 no-op instructions. This will zero-fill, then nop-fill
4468 with proper alignment. */
4469 if (alpha_current_align < 2)
4470 frag_align (2, 0, 0);
4471 frag_align_pattern (n, nop, sizeof nop, 0);
4472 }
4473 else
4474 frag_align (n, 0, 0);
4475 }
4476 else
4477 frag_align (n, *pfill, 0);
4478
4479 alpha_current_align = n;
4480
4481 if (label != NULL)
4482 {
4483 assert (S_GET_SEGMENT (label) == now_seg);
4484 label->sy_frag = frag_now;
4485 S_SET_VALUE (label, (valueT) frag_now_fix ());
4486 }
4487
4488 record_alignment(now_seg, n);
4489 }
4490
4491 /* The Alpha has support for some VAX floating point types, as well as for
4492 IEEE floating point. We consider IEEE to be the primary floating point
4493 format, and sneak in the VAX floating point support here. */
4494 #define md_atof vax_md_atof
4495 #include "config/atof-vax.c"