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