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