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