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