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