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