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