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