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