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