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