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