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