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