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