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