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