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