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