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