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