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