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