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