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