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