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