1 /* tc-alpha.c - Processor-specific code for the DEC Alpha AXP CPU.
2    Copyright (C) 1989-2016 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 const 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 const 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 	  c = get_symbol_name (&p);
925 
926 	  /* Parse !relocation_type.  */
927 	  len = input_line_pointer - p;
928 	  if (len == 0)
929 	    {
930 	      as_bad (_("No relocation operand"));
931 	      goto err_report;
932 	    }
933 
934 	  r = &alpha_reloc_op[0];
935 	  for (i = alpha_num_reloc_op - 1; i >= 0; i--, r++)
936 	    if (len == r->length && memcmp (p, r->name, len) == 0)
937 	      break;
938 	  if (i < 0)
939 	    {
940 	      as_bad (_("Unknown relocation operand: !%s"), p);
941 	      goto err_report;
942 	    }
943 
944 	  *input_line_pointer = c;
945 	  SKIP_WHITESPACE_AFTER_NAME ();
946 	  if (*input_line_pointer != '!')
947 	    {
948 	      if (r->require_seq)
949 		{
950 		  as_bad (_("no sequence number after !%s"), p);
951 		  goto err_report;
952 		}
953 
954 	      tok->X_add_number = 0;
955 	    }
956 	  else
957 	    {
958 	      if (! r->allow_seq)
959 		{
960 		  as_bad (_("!%s does not use a sequence number"), p);
961 		  goto err_report;
962 		}
963 
964 	      input_line_pointer++;
965 
966 	      /* Parse !sequence_number.  */
967 	      expression (tok);
968 	      if (tok->X_op != O_constant || tok->X_add_number <= 0)
969 		{
970 		  as_bad (_("Bad sequence number: !%s!%s"),
971 			  r->name, input_line_pointer);
972 		  goto err_report;
973 		}
974 	    }
975 
976 	  tok->X_op = r->op;
977 	  reloc_found_p = 1;
978 	  ++tok;
979 	  break;
980 #endif /* RELOC_OP_P */
981 
982 	case ',':
983 	  ++input_line_pointer;
984 	  if (saw_comma || !saw_arg)
985 	    goto err;
986 	  saw_comma = 1;
987 	  break;
988 
989 	case '(':
990 	  {
991 	    char *hold = input_line_pointer++;
992 
993 	    /* First try for parenthesized register ...  */
994 	    expression (tok);
995 	    if (*input_line_pointer == ')' && tok->X_op == O_register)
996 	      {
997 		tok->X_op = (saw_comma ? O_cpregister : O_pregister);
998 		saw_comma = 0;
999 		saw_arg = 1;
1000 		++input_line_pointer;
1001 		++tok;
1002 		break;
1003 	      }
1004 
1005 	    /* ... then fall through to plain expression.  */
1006 	    input_line_pointer = hold;
1007 	  }
1008 
1009 	default:
1010 	  if (saw_arg && !saw_comma)
1011 	    goto err;
1012 
1013 	  expression (tok);
1014 	  if (tok->X_op == O_illegal || tok->X_op == O_absent)
1015 	    goto err;
1016 
1017 	  saw_comma = 0;
1018 	  saw_arg = 1;
1019 	  ++tok;
1020 	  break;
1021 	}
1022     }
1023 
1024 fini:
1025   if (saw_comma)
1026     goto err;
1027   input_line_pointer = old_input_line_pointer;
1028 
1029 #ifdef DEBUG_ALPHA
1030   debug_exp (orig_tok, ntok - (end_tok - tok));
1031 #endif
1032 #ifdef RELOC_OP_P
1033   is_end_of_line[(unsigned char) '!'] = 0;
1034 #endif
1035 
1036   return ntok - (end_tok - tok);
1037 
1038 err:
1039 #ifdef RELOC_OP_P
1040   is_end_of_line[(unsigned char) '!'] = 0;
1041 #endif
1042   input_line_pointer = old_input_line_pointer;
1043   return TOKENIZE_ERROR;
1044 
1045 #ifdef RELOC_OP_P
1046 err_report:
1047   is_end_of_line[(unsigned char) '!'] = 0;
1048 #endif
1049   input_line_pointer = old_input_line_pointer;
1050   return TOKENIZE_ERROR_REPORT;
1051 }
1052 
1053 /* Search forward through all variants of an opcode looking for a
1054    syntax match.  */
1055 
1056 static const struct alpha_opcode *
find_opcode_match(const struct alpha_opcode * first_opcode,const expressionS * tok,int * pntok,int * pcpumatch)1057 find_opcode_match (const struct alpha_opcode *first_opcode,
1058 		   const expressionS *tok,
1059 		   int *pntok,
1060 		   int *pcpumatch)
1061 {
1062   const struct alpha_opcode *opcode = first_opcode;
1063   int ntok = *pntok;
1064   int got_cpu_match = 0;
1065 
1066   do
1067     {
1068       const unsigned char *opidx;
1069       int tokidx = 0;
1070 
1071       /* Don't match opcodes that don't exist on this architecture.  */
1072       if (!(opcode->flags & alpha_target))
1073 	goto match_failed;
1074 
1075       got_cpu_match = 1;
1076 
1077       for (opidx = opcode->operands; *opidx; ++opidx)
1078 	{
1079 	  const struct alpha_operand *operand = &alpha_operands[*opidx];
1080 
1081 	  /* Only take input from real operands.  */
1082 	  if (operand->flags & AXP_OPERAND_FAKE)
1083 	    continue;
1084 
1085 	  /* When we expect input, make sure we have it.  */
1086 	  if (tokidx >= ntok)
1087 	    {
1088 	      if ((operand->flags & AXP_OPERAND_OPTIONAL_MASK) == 0)
1089 		goto match_failed;
1090 	      continue;
1091 	    }
1092 
1093 	  /* Match operand type with expression type.  */
1094 	  switch (operand->flags & AXP_OPERAND_TYPECHECK_MASK)
1095 	    {
1096 	    case AXP_OPERAND_IR:
1097 	      if (tok[tokidx].X_op != O_register
1098 		  || !is_ir_num (tok[tokidx].X_add_number))
1099 		goto match_failed;
1100 	      break;
1101 	    case AXP_OPERAND_FPR:
1102 	      if (tok[tokidx].X_op != O_register
1103 		  || !is_fpr_num (tok[tokidx].X_add_number))
1104 		goto match_failed;
1105 	      break;
1106 	    case AXP_OPERAND_IR | AXP_OPERAND_PARENS:
1107 	      if (tok[tokidx].X_op != O_pregister
1108 		  || !is_ir_num (tok[tokidx].X_add_number))
1109 		goto match_failed;
1110 	      break;
1111 	    case AXP_OPERAND_IR | AXP_OPERAND_PARENS | AXP_OPERAND_COMMA:
1112 	      if (tok[tokidx].X_op != O_cpregister
1113 		  || !is_ir_num (tok[tokidx].X_add_number))
1114 		goto match_failed;
1115 	      break;
1116 
1117 	    case AXP_OPERAND_RELATIVE:
1118 	    case AXP_OPERAND_SIGNED:
1119 	    case AXP_OPERAND_UNSIGNED:
1120 	      switch (tok[tokidx].X_op)
1121 		{
1122 		case O_illegal:
1123 		case O_absent:
1124 		case O_register:
1125 		case O_pregister:
1126 		case O_cpregister:
1127 		  goto match_failed;
1128 
1129 		default:
1130 		  break;
1131 		}
1132 	      break;
1133 
1134 	    default:
1135 	      /* Everything else should have been fake.  */
1136 	      abort ();
1137 	    }
1138 	  ++tokidx;
1139 	}
1140 
1141       /* Possible match -- did we use all of our input?  */
1142       if (tokidx == ntok)
1143 	{
1144 	  *pntok = ntok;
1145 	  return opcode;
1146 	}
1147 
1148     match_failed:;
1149     }
1150   while (++opcode - alpha_opcodes < (int) alpha_num_opcodes
1151 	 && !strcmp (opcode->name, first_opcode->name));
1152 
1153   if (*pcpumatch)
1154     *pcpumatch = got_cpu_match;
1155 
1156   return NULL;
1157 }
1158 
1159 /* Given an opcode name and a pre-tokenized set of arguments, assemble
1160    the insn, but do not emit it.
1161 
1162    Note that this implies no macros allowed, since we can't store more
1163    than one insn in an insn structure.  */
1164 
1165 static void
assemble_tokens_to_insn(const char * opname,const expressionS * tok,int ntok,struct alpha_insn * insn)1166 assemble_tokens_to_insn (const char *opname,
1167 			 const expressionS *tok,
1168 			 int ntok,
1169 			 struct alpha_insn *insn)
1170 {
1171   const struct alpha_opcode *opcode;
1172 
1173   /* Search opcodes.  */
1174   opcode = (const struct alpha_opcode *) hash_find (alpha_opcode_hash, opname);
1175   if (opcode)
1176     {
1177       int cpumatch;
1178       opcode = find_opcode_match (opcode, tok, &ntok, &cpumatch);
1179       if (opcode)
1180 	{
1181 	  assemble_insn (opcode, tok, ntok, insn, BFD_RELOC_UNUSED);
1182 	  return;
1183 	}
1184       else if (cpumatch)
1185 	as_bad (_("inappropriate arguments for opcode `%s'"), opname);
1186       else
1187 	as_bad (_("opcode `%s' not supported for target %s"), opname,
1188 		alpha_target_name);
1189     }
1190   else
1191     as_bad (_("unknown opcode `%s'"), opname);
1192 }
1193 
1194 /* Build a BFD section with its flags set appropriately for the .lita,
1195    .lit8, or .lit4 sections.  */
1196 
1197 static void
create_literal_section(const char * name,segT * secp,symbolS ** symp)1198 create_literal_section (const char *name,
1199 			segT *secp,
1200 			symbolS **symp)
1201 {
1202   segT current_section = now_seg;
1203   int current_subsec = now_subseg;
1204   segT new_sec;
1205 
1206   *secp = new_sec = subseg_new (name, 0);
1207   subseg_set (current_section, current_subsec);
1208   bfd_set_section_alignment (stdoutput, new_sec, 4);
1209   bfd_set_section_flags (stdoutput, new_sec,
1210 			 SEC_RELOC | SEC_ALLOC | SEC_LOAD | SEC_READONLY
1211 			 | SEC_DATA);
1212 
1213   S_CLEAR_EXTERNAL (*symp = section_symbol (new_sec));
1214 }
1215 
1216 /* Load a (partial) expression into a target register.
1217 
1218    If poffset is not null, after the call it will either contain
1219    O_constant 0, or a 16-bit offset appropriate for any MEM format
1220    instruction.  In addition, pbasereg will be modified to point to
1221    the base register to use in that MEM format instruction.
1222 
1223    In any case, *pbasereg should contain a base register to add to the
1224    expression.  This will normally be either AXP_REG_ZERO or
1225    alpha_gp_register.  Symbol addresses will always be loaded via $gp,
1226    so "foo($0)" is interpreted as adding the address of foo to $0;
1227    i.e. "ldq $targ, LIT($gp); addq $targ, $0, $targ".  Odd, perhaps,
1228    but this is what OSF/1 does.
1229 
1230    If explicit relocations of the form !literal!<number> are allowed,
1231    and used, then explicit_reloc with be an expression pointer.
1232 
1233    Finally, the return value is nonzero if the calling macro may emit
1234    a LITUSE reloc if otherwise appropriate; the return value is the
1235    sequence number to use.  */
1236 
1237 static long
load_expression(int targreg,const expressionS * exp,int * pbasereg,expressionS * poffset,const char * opname)1238 load_expression (int targreg,
1239 		 const expressionS *exp,
1240 		 int *pbasereg,
1241 		 expressionS *poffset,
1242 		 const char *opname)
1243 {
1244   long emit_lituse = 0;
1245   offsetT addend = exp->X_add_number;
1246   int basereg = *pbasereg;
1247   struct alpha_insn insn;
1248   expressionS newtok[3];
1249 
1250   switch (exp->X_op)
1251     {
1252     case O_symbol:
1253       {
1254 #ifdef OBJ_ECOFF
1255 	offsetT lit;
1256 
1257 	/* Attempt to reduce .lit load by splitting the offset from
1258 	   its symbol when possible, but don't create a situation in
1259 	   which we'd fail.  */
1260 	if (!range_signed_32 (addend) &&
1261 	    (alpha_noat_on || targreg == AXP_REG_AT))
1262 	  {
1263 	    lit = add_to_literal_pool (exp->X_add_symbol, addend,
1264 				       alpha_lita_section, 8);
1265 	    addend = 0;
1266 	  }
1267 	else
1268 	  lit = add_to_literal_pool (exp->X_add_symbol, 0,
1269 				     alpha_lita_section, 8);
1270 
1271 	if (lit >= 0x8000)
1272 	  as_fatal (_("overflow in literal (.lita) table"));
1273 
1274 	/* Emit "ldq r, lit(gp)".  */
1275 
1276 	if (basereg != alpha_gp_register && targreg == basereg)
1277 	  {
1278 	    if (alpha_noat_on)
1279 	      as_bad (_("macro requires $at register while noat in effect"));
1280 	    if (targreg == AXP_REG_AT)
1281 	      as_bad (_("macro requires $at while $at in use"));
1282 
1283 	    set_tok_reg (newtok[0], AXP_REG_AT);
1284 	  }
1285 	else
1286 	  set_tok_reg (newtok[0], targreg);
1287 
1288 	set_tok_sym (newtok[1], alpha_lita_symbol, lit);
1289 	set_tok_preg (newtok[2], alpha_gp_register);
1290 
1291 	assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
1292 
1293 	gas_assert (insn.nfixups == 1);
1294 	insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITERAL;
1295 	insn.sequence = emit_lituse = next_sequence_num--;
1296 #endif /* OBJ_ECOFF */
1297 #ifdef OBJ_ELF
1298 	/* Emit "ldq r, gotoff(gp)".  */
1299 
1300 	if (basereg != alpha_gp_register && targreg == basereg)
1301 	  {
1302 	    if (alpha_noat_on)
1303 	      as_bad (_("macro requires $at register while noat in effect"));
1304 	    if (targreg == AXP_REG_AT)
1305 	      as_bad (_("macro requires $at while $at in use"));
1306 
1307 	    set_tok_reg (newtok[0], AXP_REG_AT);
1308 	  }
1309 	else
1310 	  set_tok_reg (newtok[0], targreg);
1311 
1312 	/* XXX: Disable this .got minimizing optimization so that we can get
1313 	   better instruction offset knowledge in the compiler.  This happens
1314 	   very infrequently anyway.  */
1315 	if (1
1316 	    || (!range_signed_32 (addend)
1317 		&& (alpha_noat_on || targreg == AXP_REG_AT)))
1318 	  {
1319 	    newtok[1] = *exp;
1320 	    addend = 0;
1321 	  }
1322 	else
1323 	  set_tok_sym (newtok[1], exp->X_add_symbol, 0);
1324 
1325 	set_tok_preg (newtok[2], alpha_gp_register);
1326 
1327 	assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
1328 
1329 	gas_assert (insn.nfixups == 1);
1330 	insn.fixups[0].reloc = BFD_RELOC_ALPHA_ELF_LITERAL;
1331 	insn.sequence = emit_lituse = next_sequence_num--;
1332 #endif /* OBJ_ELF */
1333 #ifdef OBJ_EVAX
1334 	/* Find symbol or symbol pointer in link section.  */
1335 
1336 	if (exp->X_add_symbol == alpha_evax_proc->symbol)
1337 	  {
1338             /* Linkage-relative expression.  */
1339             set_tok_reg (newtok[0], targreg);
1340 
1341 	    if (range_signed_16 (addend))
1342 	      {
1343 		set_tok_const (newtok[1], addend);
1344 		addend = 0;
1345 	      }
1346 	    else
1347 	      {
1348 		set_tok_const (newtok[1], 0);
1349 	      }
1350             set_tok_preg (newtok[2], basereg);
1351             assemble_tokens_to_insn ("lda", newtok, 3, &insn);
1352 	  }
1353 	else
1354 	  {
1355 	    const char *symname = S_GET_NAME (exp->X_add_symbol);
1356 	    const char *ptr1, *ptr2;
1357 	    int symlen = strlen (symname);
1358 
1359 	    if ((symlen > 4 &&
1360 		 strcmp (ptr2 = &symname [symlen - 4], "..lk") == 0))
1361 	      {
1362                 /* Access to an item whose address is stored in the linkage
1363                    section.  Just read the address.  */
1364 		set_tok_reg (newtok[0], targreg);
1365 
1366 		newtok[1] = *exp;
1367 		newtok[1].X_op = O_subtract;
1368 		newtok[1].X_op_symbol = alpha_evax_proc->symbol;
1369 
1370 		set_tok_preg (newtok[2], basereg);
1371 		assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
1372 		alpha_linkage_symbol = exp->X_add_symbol;
1373 
1374 		if (poffset)
1375 		  set_tok_const (*poffset, 0);
1376 
1377 		if (alpha_flag_replace && targreg == 26)
1378 		  {
1379                     /* Add a NOP fixup for 'ldX $26,YYY..NAME..lk'.  */
1380 		    char *ensymname;
1381 		    symbolS *ensym;
1382 
1383                     /* Build the entry name as 'NAME..en'.  */
1384 		    ptr1 = strstr (symname, "..") + 2;
1385 		    if (ptr1 > ptr2)
1386 		      ptr1 = symname;
1387 		    ensymname = XNEWVEC (char, ptr2 - ptr1 + 5);
1388 		    memcpy (ensymname, ptr1, ptr2 - ptr1);
1389 		    memcpy (ensymname + (ptr2 - ptr1), "..en", 5);
1390 
1391 		    gas_assert (insn.nfixups + 1 <= MAX_INSN_FIXUPS);
1392 		    insn.fixups[insn.nfixups].reloc = BFD_RELOC_ALPHA_NOP;
1393 		    ensym = symbol_find_or_make (ensymname);
1394 		    free (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 = xmemdup0 (ptr1, ptr2 - ptr1);
1421 
1422 		    gas_assert (insn.nfixups + 1 <= MAX_INSN_FIXUPS);
1423 		    insn.fixups[insn.nfixups].reloc = BFD_RELOC_ALPHA_LDA;
1424 		    psym = symbol_find_or_make (psymname);
1425 		    free (psymname);
1426 		    symbol_mark_used (psym);
1427 		    insn.fixups[insn.nfixups].exp.X_op = O_subtract;
1428 		    insn.fixups[insn.nfixups].exp.X_add_symbol = psym;
1429 		    insn.fixups[insn.nfixups].exp.X_op_symbol = alpha_evax_proc->symbol;
1430 		    insn.fixups[insn.nfixups].exp.X_add_number = 0;
1431 		    insn.fixups[insn.nfixups].xtrasym = alpha_linkage_symbol;
1432 		    insn.fixups[insn.nfixups].procsym = alpha_evax_proc->symbol;
1433 		    insn.nfixups++;
1434 		  }
1435 
1436 		emit_insn (&insn);
1437 		return 0;
1438 	      }
1439 	    else
1440 	      {
1441                 /* Not in the linkage section.  Put the value into the linkage
1442                    section.  */
1443 		symbolS *linkexp;
1444 
1445 		if (!range_signed_32 (addend))
1446 		  addend = sign_extend_32 (addend);
1447 		linkexp = add_to_link_pool (exp->X_add_symbol, 0);
1448 		set_tok_reg (newtok[0], targreg);
1449 		set_tok_sym (newtok[1], linkexp, 0);
1450 		set_tok_preg (newtok[2], basereg);
1451 		assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
1452 	      }
1453 	  }
1454 #endif /* OBJ_EVAX */
1455 
1456 	emit_insn (&insn);
1457 
1458 #ifndef OBJ_EVAX
1459 	if (basereg != alpha_gp_register && basereg != AXP_REG_ZERO)
1460 	  {
1461 	    /* Emit "addq r, base, r".  */
1462 
1463 	    set_tok_reg (newtok[1], basereg);
1464 	    set_tok_reg (newtok[2], targreg);
1465 	    assemble_tokens ("addq", newtok, 3, 0);
1466 	  }
1467 #endif
1468 	basereg = targreg;
1469       }
1470       break;
1471 
1472     case O_constant:
1473       break;
1474 
1475     case O_subtract:
1476       /* Assume that this difference expression will be resolved to an
1477 	 absolute value and that that value will fit in 16 bits.  */
1478 
1479       set_tok_reg (newtok[0], targreg);
1480       newtok[1] = *exp;
1481       set_tok_preg (newtok[2], basereg);
1482       assemble_tokens (opname, newtok, 3, 0);
1483 
1484       if (poffset)
1485 	set_tok_const (*poffset, 0);
1486       return 0;
1487 
1488     case O_big:
1489       if (exp->X_add_number > 0)
1490 	as_bad (_("bignum invalid; zero assumed"));
1491       else
1492 	as_bad (_("floating point number invalid; zero assumed"));
1493       addend = 0;
1494       break;
1495 
1496     default:
1497       as_bad (_("can't handle expression"));
1498       addend = 0;
1499       break;
1500     }
1501 
1502   if (!range_signed_32 (addend))
1503     {
1504 #ifdef OBJ_EVAX
1505       symbolS *litexp;
1506 #else
1507       offsetT lit;
1508       long seq_num = next_sequence_num--;
1509 #endif
1510 
1511       /* For 64-bit addends, just put it in the literal pool.  */
1512 #ifdef OBJ_EVAX
1513       /* Emit "ldq targreg, lit(basereg)".  */
1514       litexp = add_to_link_pool (section_symbol (absolute_section), addend);
1515       set_tok_reg (newtok[0], targreg);
1516       set_tok_sym (newtok[1], litexp, 0);
1517       set_tok_preg (newtok[2], alpha_gp_register);
1518       assemble_tokens ("ldq", newtok, 3, 0);
1519 #else
1520 
1521       if (alpha_lit8_section == NULL)
1522 	{
1523 	  create_literal_section (".lit8",
1524 				  &alpha_lit8_section,
1525 				  &alpha_lit8_symbol);
1526 
1527 #ifdef OBJ_ECOFF
1528 	  alpha_lit8_literal = add_to_literal_pool (alpha_lit8_symbol, 0x8000,
1529 						    alpha_lita_section, 8);
1530 	  if (alpha_lit8_literal >= 0x8000)
1531 	    as_fatal (_("overflow in literal (.lita) table"));
1532 #endif
1533 	}
1534 
1535       lit = add_to_literal_pool (NULL, addend, alpha_lit8_section, 8) - 0x8000;
1536       if (lit >= 0x8000)
1537 	as_fatal (_("overflow in literal (.lit8) table"));
1538 
1539       /* Emit "lda litreg, .lit8+0x8000".  */
1540 
1541       if (targreg == basereg)
1542 	{
1543 	  if (alpha_noat_on)
1544 	    as_bad (_("macro requires $at register while noat in effect"));
1545 	  if (targreg == AXP_REG_AT)
1546 	    as_bad (_("macro requires $at while $at in use"));
1547 
1548 	  set_tok_reg (newtok[0], AXP_REG_AT);
1549 	}
1550       else
1551 	set_tok_reg (newtok[0], targreg);
1552 #ifdef OBJ_ECOFF
1553       set_tok_sym (newtok[1], alpha_lita_symbol, alpha_lit8_literal);
1554 #endif
1555 #ifdef OBJ_ELF
1556       set_tok_sym (newtok[1], alpha_lit8_symbol, 0x8000);
1557 #endif
1558       set_tok_preg (newtok[2], alpha_gp_register);
1559 
1560       assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
1561 
1562       gas_assert (insn.nfixups == 1);
1563 #ifdef OBJ_ECOFF
1564       insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITERAL;
1565 #endif
1566 #ifdef OBJ_ELF
1567       insn.fixups[0].reloc = BFD_RELOC_ALPHA_ELF_LITERAL;
1568 #endif
1569       insn.sequence = seq_num;
1570 
1571       emit_insn (&insn);
1572 
1573       /* Emit "ldq litreg, lit(litreg)".  */
1574 
1575       set_tok_const (newtok[1], lit);
1576       set_tok_preg (newtok[2], newtok[0].X_add_number);
1577 
1578       assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
1579 
1580       gas_assert (insn.nfixups < MAX_INSN_FIXUPS);
1581       insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
1582       insn.fixups[insn.nfixups].exp.X_op = O_absent;
1583       insn.nfixups++;
1584       insn.sequence = seq_num;
1585       emit_lituse = 0;
1586 
1587       emit_insn (&insn);
1588 
1589       /* Emit "addq litreg, base, target".  */
1590 
1591       if (basereg != AXP_REG_ZERO)
1592 	{
1593 	  set_tok_reg (newtok[1], basereg);
1594 	  set_tok_reg (newtok[2], targreg);
1595 	  assemble_tokens ("addq", newtok, 3, 0);
1596 	}
1597 #endif /* !OBJ_EVAX */
1598 
1599       if (poffset)
1600 	set_tok_const (*poffset, 0);
1601       *pbasereg = targreg;
1602     }
1603   else
1604     {
1605       offsetT low, high, extra, tmp;
1606 
1607       /* For 32-bit operands, break up the addend.  */
1608 
1609       low = sign_extend_16 (addend);
1610       tmp = addend - low;
1611       high = sign_extend_16 (tmp >> 16);
1612 
1613       if (tmp - (high << 16))
1614 	{
1615 	  extra = 0x4000;
1616 	  tmp -= 0x40000000;
1617 	  high = sign_extend_16 (tmp >> 16);
1618 	}
1619       else
1620 	extra = 0;
1621 
1622       set_tok_reg (newtok[0], targreg);
1623       set_tok_preg (newtok[2], basereg);
1624 
1625       if (extra)
1626 	{
1627 	  /* Emit "ldah r, extra(r).  */
1628 	  set_tok_const (newtok[1], extra);
1629 	  assemble_tokens ("ldah", newtok, 3, 0);
1630 	  set_tok_preg (newtok[2], basereg = targreg);
1631 	}
1632 
1633       if (high)
1634 	{
1635 	  /* Emit "ldah r, high(r).  */
1636 	  set_tok_const (newtok[1], high);
1637 	  assemble_tokens ("ldah", newtok, 3, 0);
1638 	  basereg = targreg;
1639 	  set_tok_preg (newtok[2], basereg);
1640 	}
1641 
1642       if ((low && !poffset) || (!poffset && basereg != targreg))
1643 	{
1644 	  /* Emit "lda r, low(base)".  */
1645 	  set_tok_const (newtok[1], low);
1646 	  assemble_tokens ("lda", newtok, 3, 0);
1647 	  basereg = targreg;
1648 	  low = 0;
1649 	}
1650 
1651       if (poffset)
1652 	set_tok_const (*poffset, low);
1653       *pbasereg = basereg;
1654     }
1655 
1656   return emit_lituse;
1657 }
1658 
1659 /* The lda macro differs from the lda instruction in that it handles
1660    most simple expressions, particularly symbol address loads and
1661    large constants.  */
1662 
1663 static void
emit_lda(const expressionS * tok,int ntok,const void * unused ATTRIBUTE_UNUSED)1664 emit_lda (const expressionS *tok,
1665 	  int ntok,
1666 	  const void * unused ATTRIBUTE_UNUSED)
1667 {
1668   int basereg;
1669 
1670   if (ntok == 2)
1671     basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
1672   else
1673     basereg = tok[2].X_add_number;
1674 
1675   (void) load_expression (tok[0].X_add_number, &tok[1], &basereg, NULL, "lda");
1676 }
1677 
1678 /* The ldah macro differs from the ldah instruction in that it has $31
1679    as an implied base register.  */
1680 
1681 static void
emit_ldah(const expressionS * tok,int ntok ATTRIBUTE_UNUSED,const void * unused ATTRIBUTE_UNUSED)1682 emit_ldah (const expressionS *tok,
1683 	   int ntok ATTRIBUTE_UNUSED,
1684 	   const void * unused ATTRIBUTE_UNUSED)
1685 {
1686   expressionS newtok[3];
1687 
1688   newtok[0] = tok[0];
1689   newtok[1] = tok[1];
1690   set_tok_preg (newtok[2], AXP_REG_ZERO);
1691 
1692   assemble_tokens ("ldah", newtok, 3, 0);
1693 }
1694 
1695 /* Called internally to handle all alignment needs.  This takes care
1696    of eliding calls to frag_align if'n the cached current alignment
1697    says we've already got it, as well as taking care of the auto-align
1698    feature wrt labels.  */
1699 
1700 static void
alpha_align(int n,char * pfill,symbolS * label,int force ATTRIBUTE_UNUSED)1701 alpha_align (int n,
1702 	     char *pfill,
1703 	     symbolS *label,
1704 	     int force ATTRIBUTE_UNUSED)
1705 {
1706   if (alpha_current_align >= n)
1707     return;
1708 
1709   if (pfill == NULL)
1710     {
1711       if (subseg_text_p (now_seg))
1712 	frag_align_code (n, 0);
1713       else
1714 	frag_align (n, 0, 0);
1715     }
1716   else
1717     frag_align (n, *pfill, 0);
1718 
1719   alpha_current_align = n;
1720 
1721   if (label != NULL && S_GET_SEGMENT (label) == now_seg)
1722     {
1723       symbol_set_frag (label, frag_now);
1724       S_SET_VALUE (label, (valueT) frag_now_fix ());
1725     }
1726 
1727   record_alignment (now_seg, n);
1728 
1729   /* ??? If alpha_flag_relax && force && elf, record the requested alignment
1730      in a reloc for the linker to see.  */
1731 }
1732 
1733 /* Actually output an instruction with its fixup.  */
1734 
1735 static void
emit_insn(struct alpha_insn * insn)1736 emit_insn (struct alpha_insn *insn)
1737 {
1738   char *f;
1739   int i;
1740 
1741   /* Take care of alignment duties.  */
1742   if (alpha_auto_align_on && alpha_current_align < 2)
1743     alpha_align (2, (char *) NULL, alpha_insn_label, 0);
1744   if (alpha_current_align > 2)
1745     alpha_current_align = 2;
1746   alpha_insn_label = NULL;
1747 
1748   /* Write out the instruction.  */
1749   f = frag_more (4);
1750   md_number_to_chars (f, insn->insn, 4);
1751 
1752 #ifdef OBJ_ELF
1753   dwarf2_emit_insn (4);
1754 #endif
1755 
1756   /* Apply the fixups in order.  */
1757   for (i = 0; i < insn->nfixups; ++i)
1758     {
1759       const struct alpha_operand *operand = (const struct alpha_operand *) 0;
1760       struct alpha_fixup *fixup = &insn->fixups[i];
1761       struct alpha_reloc_tag *info = NULL;
1762       int size, pcrel;
1763       fixS *fixP;
1764 
1765       /* Some fixups are only used internally and so have no howto.  */
1766       if ((int) fixup->reloc < 0)
1767 	{
1768 	  operand = &alpha_operands[-(int) fixup->reloc];
1769 	  size = 4;
1770 	  pcrel = ((operand->flags & AXP_OPERAND_RELATIVE) != 0);
1771 	}
1772       else if (fixup->reloc > BFD_RELOC_UNUSED
1773 	       || fixup->reloc == BFD_RELOC_ALPHA_GPDISP_HI16
1774 	       || fixup->reloc == BFD_RELOC_ALPHA_GPDISP_LO16)
1775 	{
1776 	  size = 2;
1777 	  pcrel = 0;
1778 	}
1779       else
1780 	{
1781 	  reloc_howto_type *reloc_howto =
1782               bfd_reloc_type_lookup (stdoutput,
1783                                      (bfd_reloc_code_real_type) fixup->reloc);
1784 	  gas_assert (reloc_howto);
1785 
1786 	  size = bfd_get_reloc_size (reloc_howto);
1787 
1788 	  switch (fixup->reloc)
1789 	    {
1790 #ifdef OBJ_EVAX
1791 	    case BFD_RELOC_ALPHA_NOP:
1792 	    case BFD_RELOC_ALPHA_BSR:
1793 	    case BFD_RELOC_ALPHA_LDA:
1794 	    case BFD_RELOC_ALPHA_BOH:
1795 	      break;
1796 #endif
1797 	    default:
1798 	      gas_assert (size >= 1 && size <= 4);
1799 	    }
1800 
1801 	  pcrel = reloc_howto->pc_relative;
1802 	}
1803 
1804       fixP = fix_new_exp (frag_now, f - frag_now->fr_literal, size,
1805 			  &fixup->exp, pcrel, (bfd_reloc_code_real_type) fixup->reloc);
1806 
1807       /* Turn off complaints that the addend is too large for some fixups,
1808          and copy in the sequence number for the explicit relocations.  */
1809       switch (fixup->reloc)
1810 	{
1811 	case BFD_RELOC_ALPHA_HINT:
1812 	case BFD_RELOC_GPREL32:
1813 	case BFD_RELOC_GPREL16:
1814 	case BFD_RELOC_ALPHA_GPREL_HI16:
1815 	case BFD_RELOC_ALPHA_GPREL_LO16:
1816 	case BFD_RELOC_ALPHA_GOTDTPREL16:
1817 	case BFD_RELOC_ALPHA_DTPREL_HI16:
1818 	case BFD_RELOC_ALPHA_DTPREL_LO16:
1819 	case BFD_RELOC_ALPHA_DTPREL16:
1820 	case BFD_RELOC_ALPHA_GOTTPREL16:
1821 	case BFD_RELOC_ALPHA_TPREL_HI16:
1822 	case BFD_RELOC_ALPHA_TPREL_LO16:
1823 	case BFD_RELOC_ALPHA_TPREL16:
1824 	  fixP->fx_no_overflow = 1;
1825 	  break;
1826 
1827 	case BFD_RELOC_ALPHA_GPDISP_HI16:
1828 	  fixP->fx_no_overflow = 1;
1829 	  fixP->fx_addsy = section_symbol (now_seg);
1830 	  fixP->fx_offset = 0;
1831 
1832 	  info = get_alpha_reloc_tag (insn->sequence);
1833 	  if (++info->n_master > 1)
1834 	    as_bad (_("too many ldah insns for !gpdisp!%ld"), insn->sequence);
1835 	  if (info->segment != now_seg)
1836 	    as_bad (_("both insns for !gpdisp!%ld must be in the same section"),
1837 		    insn->sequence);
1838 	  fixP->tc_fix_data.info = info;
1839 	  break;
1840 
1841 	case BFD_RELOC_ALPHA_GPDISP_LO16:
1842 	  fixP->fx_no_overflow = 1;
1843 
1844 	  info = get_alpha_reloc_tag (insn->sequence);
1845 	  if (++info->n_slaves > 1)
1846 	    as_bad (_("too many lda insns for !gpdisp!%ld"), insn->sequence);
1847 	  if (info->segment != now_seg)
1848 	    as_bad (_("both insns for !gpdisp!%ld must be in the same section"),
1849 		    insn->sequence);
1850 	  fixP->tc_fix_data.info = info;
1851 	  info->slaves = fixP;
1852 	  break;
1853 
1854 	case BFD_RELOC_ALPHA_LITERAL:
1855 	case BFD_RELOC_ALPHA_ELF_LITERAL:
1856 	  fixP->fx_no_overflow = 1;
1857 
1858 	  if (insn->sequence == 0)
1859 	    break;
1860 	  info = get_alpha_reloc_tag (insn->sequence);
1861 	  info->master = fixP;
1862 	  info->n_master++;
1863 	  if (info->segment != now_seg)
1864 	    info->multi_section_p = 1;
1865 	  fixP->tc_fix_data.info = info;
1866 	  break;
1867 
1868 #ifdef RELOC_OP_P
1869 	case DUMMY_RELOC_LITUSE_ADDR:
1870 	  fixP->fx_offset = LITUSE_ALPHA_ADDR;
1871 	  goto do_lituse;
1872 	case DUMMY_RELOC_LITUSE_BASE:
1873 	  fixP->fx_offset = LITUSE_ALPHA_BASE;
1874 	  goto do_lituse;
1875 	case DUMMY_RELOC_LITUSE_BYTOFF:
1876 	  fixP->fx_offset = LITUSE_ALPHA_BYTOFF;
1877 	  goto do_lituse;
1878 	case DUMMY_RELOC_LITUSE_JSR:
1879 	  fixP->fx_offset = LITUSE_ALPHA_JSR;
1880 	  goto do_lituse;
1881 	case DUMMY_RELOC_LITUSE_TLSGD:
1882 	  fixP->fx_offset = LITUSE_ALPHA_TLSGD;
1883 	  goto do_lituse;
1884 	case DUMMY_RELOC_LITUSE_TLSLDM:
1885 	  fixP->fx_offset = LITUSE_ALPHA_TLSLDM;
1886 	  goto do_lituse;
1887 	case DUMMY_RELOC_LITUSE_JSRDIRECT:
1888 	  fixP->fx_offset = LITUSE_ALPHA_JSRDIRECT;
1889 	  goto do_lituse;
1890 	do_lituse:
1891 	  fixP->fx_addsy = section_symbol (now_seg);
1892 	  fixP->fx_r_type = BFD_RELOC_ALPHA_LITUSE;
1893 
1894 	  info = get_alpha_reloc_tag (insn->sequence);
1895 	  if (fixup->reloc == DUMMY_RELOC_LITUSE_TLSGD)
1896 	    info->saw_lu_tlsgd = 1;
1897 	  else if (fixup->reloc == DUMMY_RELOC_LITUSE_TLSLDM)
1898 	    info->saw_lu_tlsldm = 1;
1899 	  if (++info->n_slaves > 1)
1900 	    {
1901 	      if (info->saw_lu_tlsgd)
1902 		as_bad (_("too many lituse insns for !lituse_tlsgd!%ld"),
1903 		        insn->sequence);
1904 	      else if (info->saw_lu_tlsldm)
1905 		as_bad (_("too many lituse insns for !lituse_tlsldm!%ld"),
1906 		        insn->sequence);
1907 	    }
1908 	  fixP->tc_fix_data.info = info;
1909 	  fixP->tc_fix_data.next_reloc = info->slaves;
1910 	  info->slaves = fixP;
1911 	  if (info->segment != now_seg)
1912 	    info->multi_section_p = 1;
1913 	  break;
1914 
1915 	case BFD_RELOC_ALPHA_TLSGD:
1916 	  fixP->fx_no_overflow = 1;
1917 
1918 	  if (insn->sequence == 0)
1919 	    break;
1920 	  info = get_alpha_reloc_tag (insn->sequence);
1921 	  if (info->saw_tlsgd)
1922 	    as_bad (_("duplicate !tlsgd!%ld"), insn->sequence);
1923 	  else if (info->saw_tlsldm)
1924 	    as_bad (_("sequence number in use for !tlsldm!%ld"),
1925 		    insn->sequence);
1926 	  else
1927 	    info->saw_tlsgd = 1;
1928 	  fixP->tc_fix_data.info = info;
1929 	  break;
1930 
1931 	case BFD_RELOC_ALPHA_TLSLDM:
1932 	  fixP->fx_no_overflow = 1;
1933 
1934 	  if (insn->sequence == 0)
1935 	    break;
1936 	  info = get_alpha_reloc_tag (insn->sequence);
1937 	  if (info->saw_tlsldm)
1938 	    as_bad (_("duplicate !tlsldm!%ld"), insn->sequence);
1939 	  else if (info->saw_tlsgd)
1940 	    as_bad (_("sequence number in use for !tlsgd!%ld"),
1941 		    insn->sequence);
1942 	  else
1943 	    info->saw_tlsldm = 1;
1944 	  fixP->tc_fix_data.info = info;
1945 	  break;
1946 #endif
1947 #ifdef OBJ_EVAX
1948 	case BFD_RELOC_ALPHA_NOP:
1949 	case BFD_RELOC_ALPHA_LDA:
1950 	case BFD_RELOC_ALPHA_BSR:
1951 	case BFD_RELOC_ALPHA_BOH:
1952 	  info = get_alpha_reloc_tag (next_sequence_num--);
1953 	  fixP->tc_fix_data.info = info;
1954 	  fixP->tc_fix_data.info->sym = fixup->xtrasym;
1955 	  fixP->tc_fix_data.info->psym = fixup->procsym;
1956 	  break;
1957 #endif
1958 
1959 	default:
1960 	  if ((int) fixup->reloc < 0)
1961 	    {
1962 	      if (operand->flags & AXP_OPERAND_NOOVERFLOW)
1963 		fixP->fx_no_overflow = 1;
1964 	    }
1965 	  break;
1966 	}
1967     }
1968 }
1969 
1970 /* Insert an operand value into an instruction.  */
1971 
1972 static unsigned
insert_operand(unsigned insn,const struct alpha_operand * operand,offsetT val,const char * file,unsigned line)1973 insert_operand (unsigned insn,
1974 		const struct alpha_operand *operand,
1975 		offsetT val,
1976 		const char *file,
1977 		unsigned line)
1978 {
1979   if (operand->bits != 32 && !(operand->flags & AXP_OPERAND_NOOVERFLOW))
1980     {
1981       offsetT min, max;
1982 
1983       if (operand->flags & AXP_OPERAND_SIGNED)
1984 	{
1985 	  max = (1 << (operand->bits - 1)) - 1;
1986 	  min = -(1 << (operand->bits - 1));
1987 	}
1988       else
1989 	{
1990 	  max = (1 << operand->bits) - 1;
1991 	  min = 0;
1992 	}
1993 
1994       if (val < min || val > max)
1995 	as_bad_value_out_of_range (_("operand"), val, min, max, file, line);
1996     }
1997 
1998   if (operand->insert)
1999     {
2000       const char *errmsg = NULL;
2001 
2002       insn = (*operand->insert) (insn, val, &errmsg);
2003       if (errmsg)
2004 	as_warn ("%s", errmsg);
2005     }
2006   else
2007     insn |= ((val & ((1 << operand->bits) - 1)) << operand->shift);
2008 
2009   return insn;
2010 }
2011 
2012 /* Turn an opcode description and a set of arguments into
2013    an instruction and a fixup.  */
2014 
2015 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)2016 assemble_insn (const struct alpha_opcode *opcode,
2017 	       const expressionS *tok,
2018 	       int ntok,
2019 	       struct alpha_insn *insn,
2020 	       extended_bfd_reloc_code_real_type reloc)
2021 {
2022   const struct alpha_operand *reloc_operand = NULL;
2023   const expressionS *reloc_exp = NULL;
2024   const unsigned char *argidx;
2025   unsigned image;
2026   int tokidx = 0;
2027 
2028   memset (insn, 0, sizeof (*insn));
2029   image = opcode->opcode;
2030 
2031   for (argidx = opcode->operands; *argidx; ++argidx)
2032     {
2033       const struct alpha_operand *operand = &alpha_operands[*argidx];
2034       const expressionS *t = (const expressionS *) 0;
2035 
2036       if (operand->flags & AXP_OPERAND_FAKE)
2037 	{
2038 	  /* Fake operands take no value and generate no fixup.  */
2039 	  image = insert_operand (image, operand, 0, NULL, 0);
2040 	  continue;
2041 	}
2042 
2043       if (tokidx >= ntok)
2044 	{
2045 	  switch (operand->flags & AXP_OPERAND_OPTIONAL_MASK)
2046 	    {
2047 	    case AXP_OPERAND_DEFAULT_FIRST:
2048 	      t = &tok[0];
2049 	      break;
2050 	    case AXP_OPERAND_DEFAULT_SECOND:
2051 	      t = &tok[1];
2052 	      break;
2053 	    case AXP_OPERAND_DEFAULT_ZERO:
2054 	      {
2055 		static expressionS zero_exp;
2056 		t = &zero_exp;
2057 		zero_exp.X_op = O_constant;
2058 		zero_exp.X_unsigned = 1;
2059 	      }
2060 	      break;
2061 	    default:
2062 	      abort ();
2063 	    }
2064 	}
2065       else
2066 	t = &tok[tokidx++];
2067 
2068       switch (t->X_op)
2069 	{
2070 	case O_register:
2071 	case O_pregister:
2072 	case O_cpregister:
2073 	  image = insert_operand (image, operand, regno (t->X_add_number),
2074 				  NULL, 0);
2075 	  break;
2076 
2077 	case O_constant:
2078 	  image = insert_operand (image, operand, t->X_add_number, NULL, 0);
2079 	  gas_assert (reloc_operand == NULL);
2080 	  reloc_operand = operand;
2081 	  reloc_exp = t;
2082 	  break;
2083 
2084 	default:
2085 	  /* This is only 0 for fields that should contain registers,
2086 	     which means this pattern shouldn't have matched.  */
2087 	  if (operand->default_reloc == 0)
2088 	    abort ();
2089 
2090 	  /* There is one special case for which an insn receives two
2091 	     relocations, and thus the user-supplied reloc does not
2092 	     override the operand reloc.  */
2093 	  if (operand->default_reloc == BFD_RELOC_ALPHA_HINT)
2094 	    {
2095 	      struct alpha_fixup *fixup;
2096 
2097 	      if (insn->nfixups >= MAX_INSN_FIXUPS)
2098 		as_fatal (_("too many fixups"));
2099 
2100 	      fixup = &insn->fixups[insn->nfixups++];
2101 	      fixup->exp = *t;
2102 	      fixup->reloc = BFD_RELOC_ALPHA_HINT;
2103 	    }
2104 	  else
2105 	    {
2106 	      if (reloc == BFD_RELOC_UNUSED)
2107 		reloc = operand->default_reloc;
2108 
2109 	      gas_assert (reloc_operand == NULL);
2110 	      reloc_operand = operand;
2111 	      reloc_exp = t;
2112 	    }
2113 	  break;
2114 	}
2115     }
2116 
2117   if (reloc != BFD_RELOC_UNUSED)
2118     {
2119       struct alpha_fixup *fixup;
2120 
2121       if (insn->nfixups >= MAX_INSN_FIXUPS)
2122 	as_fatal (_("too many fixups"));
2123 
2124       /* ??? My but this is hacky.  But the OSF/1 assembler uses the same
2125 	 relocation tag for both ldah and lda with gpdisp.  Choose the
2126 	 correct internal relocation based on the opcode.  */
2127       if (reloc == BFD_RELOC_ALPHA_GPDISP)
2128 	{
2129 	  if (strcmp (opcode->name, "ldah") == 0)
2130 	    reloc = BFD_RELOC_ALPHA_GPDISP_HI16;
2131 	  else if (strcmp (opcode->name, "lda") == 0)
2132 	    reloc = BFD_RELOC_ALPHA_GPDISP_LO16;
2133 	  else
2134 	    as_bad (_("invalid relocation for instruction"));
2135 	}
2136 
2137       /* If this is a real relocation (as opposed to a lituse hint), then
2138 	 the relocation width should match the operand width.
2139 	 Take care of -MDISP in operand table.  */
2140       else if (reloc < BFD_RELOC_UNUSED && reloc > 0)
2141 	{
2142 	  reloc_howto_type *reloc_howto
2143               = bfd_reloc_type_lookup (stdoutput,
2144                                        (bfd_reloc_code_real_type) reloc);
2145 	  if (reloc_operand == NULL
2146 	      || reloc_howto->bitsize != reloc_operand->bits)
2147 	    {
2148 	      as_bad (_("invalid relocation for field"));
2149 	      return;
2150 	    }
2151 	}
2152 
2153       fixup = &insn->fixups[insn->nfixups++];
2154       if (reloc_exp)
2155 	fixup->exp = *reloc_exp;
2156       else
2157 	fixup->exp.X_op = O_absent;
2158       fixup->reloc = reloc;
2159     }
2160 
2161   insn->insn = image;
2162 }
2163 
2164 /* Handle all "simple" integer register loads -- ldq, ldq_l, ldq_u,
2165    etc.  They differ from the real instructions in that they do simple
2166    expressions like the lda macro.  */
2167 
2168 static void
emit_ir_load(const expressionS * tok,int ntok,const void * opname)2169 emit_ir_load (const expressionS *tok,
2170 	      int ntok,
2171 	      const void * opname)
2172 {
2173   int basereg;
2174   long lituse;
2175   expressionS newtok[3];
2176   struct alpha_insn insn;
2177   const char *symname
2178     = tok[1].X_add_symbol ? S_GET_NAME (tok[1].X_add_symbol): "";
2179   int symlen = strlen (symname);
2180 
2181   if (ntok == 2)
2182     basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
2183   else
2184     basereg = tok[2].X_add_number;
2185 
2186   lituse = load_expression (tok[0].X_add_number, &tok[1],
2187 			    &basereg, &newtok[1], (const char *) opname);
2188 
2189   if (basereg == alpha_gp_register &&
2190       (symlen > 4 && strcmp (&symname [symlen - 4], "..lk") == 0))
2191     return;
2192 
2193   newtok[0] = tok[0];
2194   set_tok_preg (newtok[2], basereg);
2195 
2196   assemble_tokens_to_insn ((const char *) opname, newtok, 3, &insn);
2197 
2198   if (lituse)
2199     {
2200       gas_assert (insn.nfixups < MAX_INSN_FIXUPS);
2201       insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
2202       insn.fixups[insn.nfixups].exp.X_op = O_absent;
2203       insn.nfixups++;
2204       insn.sequence = lituse;
2205     }
2206 
2207   emit_insn (&insn);
2208 }
2209 
2210 /* Handle fp register loads, and both integer and fp register stores.
2211    Again, we handle simple expressions.  */
2212 
2213 static void
emit_loadstore(const expressionS * tok,int ntok,const void * opname)2214 emit_loadstore (const expressionS *tok,
2215 		int ntok,
2216 		const void * opname)
2217 {
2218   int basereg;
2219   long lituse;
2220   expressionS newtok[3];
2221   struct alpha_insn insn;
2222 
2223   if (ntok == 2)
2224     basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
2225   else
2226     basereg = tok[2].X_add_number;
2227 
2228   if (tok[1].X_op != O_constant || !range_signed_16 (tok[1].X_add_number))
2229     {
2230       if (alpha_noat_on)
2231 	as_bad (_("macro requires $at register while noat in effect"));
2232 
2233       lituse = load_expression (AXP_REG_AT, &tok[1],
2234 				&basereg, &newtok[1], (const char *) opname);
2235     }
2236   else
2237     {
2238       newtok[1] = tok[1];
2239       lituse = 0;
2240     }
2241 
2242   newtok[0] = tok[0];
2243   set_tok_preg (newtok[2], basereg);
2244 
2245   assemble_tokens_to_insn ((const char *) opname, newtok, 3, &insn);
2246 
2247   if (lituse)
2248     {
2249       gas_assert (insn.nfixups < MAX_INSN_FIXUPS);
2250       insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
2251       insn.fixups[insn.nfixups].exp.X_op = O_absent;
2252       insn.nfixups++;
2253       insn.sequence = lituse;
2254     }
2255 
2256   emit_insn (&insn);
2257 }
2258 
2259 /* Load a half-word or byte as an unsigned value.  */
2260 
2261 static void
emit_ldXu(const expressionS * tok,int ntok,const void * vlgsize)2262 emit_ldXu (const expressionS *tok,
2263 	   int ntok,
2264 	   const void * vlgsize)
2265 {
2266   if (alpha_target & AXP_OPCODE_BWX)
2267     emit_ir_load (tok, ntok, ldXu_op[(long) vlgsize]);
2268   else
2269     {
2270       expressionS newtok[3];
2271       struct alpha_insn insn;
2272       int basereg;
2273       long lituse;
2274 
2275       if (alpha_noat_on)
2276 	as_bad (_("macro requires $at register while noat in effect"));
2277 
2278       if (ntok == 2)
2279 	basereg = (tok[1].X_op == O_constant
2280 		   ? AXP_REG_ZERO : alpha_gp_register);
2281       else
2282 	basereg = tok[2].X_add_number;
2283 
2284       /* Emit "lda $at, exp".  */
2285       lituse = load_expression (AXP_REG_AT, &tok[1], &basereg, NULL, "lda");
2286 
2287       /* Emit "ldq_u targ, 0($at)".  */
2288       newtok[0] = tok[0];
2289       set_tok_const (newtok[1], 0);
2290       set_tok_preg (newtok[2], basereg);
2291       assemble_tokens_to_insn ("ldq_u", newtok, 3, &insn);
2292 
2293       if (lituse)
2294 	{
2295 	  gas_assert (insn.nfixups < MAX_INSN_FIXUPS);
2296 	  insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
2297 	  insn.fixups[insn.nfixups].exp.X_op = O_absent;
2298 	  insn.nfixups++;
2299 	  insn.sequence = lituse;
2300 	}
2301 
2302       emit_insn (&insn);
2303 
2304       /* Emit "extXl targ, $at, targ".  */
2305       set_tok_reg (newtok[1], basereg);
2306       newtok[2] = newtok[0];
2307       assemble_tokens_to_insn (extXl_op[(long) vlgsize], newtok, 3, &insn);
2308 
2309       if (lituse)
2310 	{
2311 	  gas_assert (insn.nfixups < MAX_INSN_FIXUPS);
2312 	  insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF;
2313 	  insn.fixups[insn.nfixups].exp.X_op = O_absent;
2314 	  insn.nfixups++;
2315 	  insn.sequence = lituse;
2316 	}
2317 
2318       emit_insn (&insn);
2319     }
2320 }
2321 
2322 /* Load a half-word or byte as a signed value.  */
2323 
2324 static void
emit_ldX(const expressionS * tok,int ntok,const void * vlgsize)2325 emit_ldX (const expressionS *tok,
2326 	  int ntok,
2327 	  const void * vlgsize)
2328 {
2329   emit_ldXu (tok, ntok, vlgsize);
2330   assemble_tokens (sextX_op[(long) vlgsize], tok, 1, 1);
2331 }
2332 
2333 /* Load an integral value from an unaligned address as an unsigned
2334    value.  */
2335 
2336 static void
emit_uldXu(const expressionS * tok,int ntok,const void * vlgsize)2337 emit_uldXu (const expressionS *tok,
2338 	    int ntok,
2339 	    const void * vlgsize)
2340 {
2341   long lgsize = (long) vlgsize;
2342   expressionS newtok[3];
2343 
2344   if (alpha_noat_on)
2345     as_bad (_("macro requires $at register while noat in effect"));
2346 
2347   /* Emit "lda $at, exp".  */
2348   memcpy (newtok, tok, sizeof (expressionS) * ntok);
2349   newtok[0].X_add_number = AXP_REG_AT;
2350   assemble_tokens ("lda", newtok, ntok, 1);
2351 
2352   /* Emit "ldq_u $t9, 0($at)".  */
2353   set_tok_reg (newtok[0], AXP_REG_T9);
2354   set_tok_const (newtok[1], 0);
2355   set_tok_preg (newtok[2], AXP_REG_AT);
2356   assemble_tokens ("ldq_u", newtok, 3, 1);
2357 
2358   /* Emit "ldq_u $t10, size-1($at)".  */
2359   set_tok_reg (newtok[0], AXP_REG_T10);
2360   set_tok_const (newtok[1], (1 << lgsize) - 1);
2361   assemble_tokens ("ldq_u", newtok, 3, 1);
2362 
2363   /* Emit "extXl $t9, $at, $t9".  */
2364   set_tok_reg (newtok[0], AXP_REG_T9);
2365   set_tok_reg (newtok[1], AXP_REG_AT);
2366   set_tok_reg (newtok[2], AXP_REG_T9);
2367   assemble_tokens (extXl_op[lgsize], newtok, 3, 1);
2368 
2369   /* Emit "extXh $t10, $at, $t10".  */
2370   set_tok_reg (newtok[0], AXP_REG_T10);
2371   set_tok_reg (newtok[2], AXP_REG_T10);
2372   assemble_tokens (extXh_op[lgsize], newtok, 3, 1);
2373 
2374   /* Emit "or $t9, $t10, targ".  */
2375   set_tok_reg (newtok[0], AXP_REG_T9);
2376   set_tok_reg (newtok[1], AXP_REG_T10);
2377   newtok[2] = tok[0];
2378   assemble_tokens ("or", newtok, 3, 1);
2379 }
2380 
2381 /* Load an integral value from an unaligned address as a signed value.
2382    Note that quads should get funneled to the unsigned load since we
2383    don't have to do the sign extension.  */
2384 
2385 static void
emit_uldX(const expressionS * tok,int ntok,const void * vlgsize)2386 emit_uldX (const expressionS *tok,
2387 	   int ntok,
2388 	   const void * vlgsize)
2389 {
2390   emit_uldXu (tok, ntok, vlgsize);
2391   assemble_tokens (sextX_op[(long) vlgsize], tok, 1, 1);
2392 }
2393 
2394 /* Implement the ldil macro.  */
2395 
2396 static void
emit_ldil(const expressionS * tok,int ntok,const void * unused ATTRIBUTE_UNUSED)2397 emit_ldil (const expressionS *tok,
2398 	   int ntok,
2399 	   const void * unused ATTRIBUTE_UNUSED)
2400 {
2401   expressionS newtok[2];
2402 
2403   memcpy (newtok, tok, sizeof (newtok));
2404   newtok[1].X_add_number = sign_extend_32 (tok[1].X_add_number);
2405 
2406   assemble_tokens ("lda", newtok, ntok, 1);
2407 }
2408 
2409 /* Store a half-word or byte.  */
2410 
2411 static void
emit_stX(const expressionS * tok,int ntok,const void * vlgsize)2412 emit_stX (const expressionS *tok,
2413 	  int ntok,
2414 	  const void * vlgsize)
2415 {
2416   int lgsize = (int) (long) vlgsize;
2417 
2418   if (alpha_target & AXP_OPCODE_BWX)
2419     emit_loadstore (tok, ntok, stX_op[lgsize]);
2420   else
2421     {
2422       expressionS newtok[3];
2423       struct alpha_insn insn;
2424       int basereg;
2425       long lituse;
2426 
2427       if (alpha_noat_on)
2428 	as_bad (_("macro requires $at register while noat in effect"));
2429 
2430       if (ntok == 2)
2431 	basereg = (tok[1].X_op == O_constant
2432 		   ? AXP_REG_ZERO : alpha_gp_register);
2433       else
2434 	basereg = tok[2].X_add_number;
2435 
2436       /* Emit "lda $at, exp".  */
2437       lituse = load_expression (AXP_REG_AT, &tok[1], &basereg, NULL, "lda");
2438 
2439       /* Emit "ldq_u $t9, 0($at)".  */
2440       set_tok_reg (newtok[0], AXP_REG_T9);
2441       set_tok_const (newtok[1], 0);
2442       set_tok_preg (newtok[2], basereg);
2443       assemble_tokens_to_insn ("ldq_u", newtok, 3, &insn);
2444 
2445       if (lituse)
2446 	{
2447 	  gas_assert (insn.nfixups < MAX_INSN_FIXUPS);
2448 	  insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
2449 	  insn.fixups[insn.nfixups].exp.X_op = O_absent;
2450 	  insn.nfixups++;
2451 	  insn.sequence = lituse;
2452 	}
2453 
2454       emit_insn (&insn);
2455 
2456       /* Emit "insXl src, $at, $t10".  */
2457       newtok[0] = tok[0];
2458       set_tok_reg (newtok[1], basereg);
2459       set_tok_reg (newtok[2], AXP_REG_T10);
2460       assemble_tokens_to_insn (insXl_op[lgsize], newtok, 3, &insn);
2461 
2462       if (lituse)
2463 	{
2464 	  gas_assert (insn.nfixups < MAX_INSN_FIXUPS);
2465 	  insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF;
2466 	  insn.fixups[insn.nfixups].exp.X_op = O_absent;
2467 	  insn.nfixups++;
2468 	  insn.sequence = lituse;
2469 	}
2470 
2471       emit_insn (&insn);
2472 
2473       /* Emit "mskXl $t9, $at, $t9".  */
2474       set_tok_reg (newtok[0], AXP_REG_T9);
2475       newtok[2] = newtok[0];
2476       assemble_tokens_to_insn (mskXl_op[lgsize], newtok, 3, &insn);
2477 
2478       if (lituse)
2479 	{
2480 	  gas_assert (insn.nfixups < MAX_INSN_FIXUPS);
2481 	  insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF;
2482 	  insn.fixups[insn.nfixups].exp.X_op = O_absent;
2483 	  insn.nfixups++;
2484 	  insn.sequence = lituse;
2485 	}
2486 
2487       emit_insn (&insn);
2488 
2489       /* Emit "or $t9, $t10, $t9".  */
2490       set_tok_reg (newtok[1], AXP_REG_T10);
2491       assemble_tokens ("or", newtok, 3, 1);
2492 
2493       /* Emit "stq_u $t9, 0($at).  */
2494       set_tok_const(newtok[1], 0);
2495       set_tok_preg (newtok[2], AXP_REG_AT);
2496       assemble_tokens_to_insn ("stq_u", newtok, 3, &insn);
2497 
2498       if (lituse)
2499 	{
2500 	  gas_assert (insn.nfixups < MAX_INSN_FIXUPS);
2501 	  insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
2502 	  insn.fixups[insn.nfixups].exp.X_op = O_absent;
2503 	  insn.nfixups++;
2504 	  insn.sequence = lituse;
2505 	}
2506 
2507       emit_insn (&insn);
2508     }
2509 }
2510 
2511 /* Store an integer to an unaligned address.  */
2512 
2513 static void
emit_ustX(const expressionS * tok,int ntok,const void * vlgsize)2514 emit_ustX (const expressionS *tok,
2515 	   int ntok,
2516 	   const void * vlgsize)
2517 {
2518   int lgsize = (int) (long) vlgsize;
2519   expressionS newtok[3];
2520 
2521   /* Emit "lda $at, exp".  */
2522   memcpy (newtok, tok, sizeof (expressionS) * ntok);
2523   newtok[0].X_add_number = AXP_REG_AT;
2524   assemble_tokens ("lda", newtok, ntok, 1);
2525 
2526   /* Emit "ldq_u $9, 0($at)".  */
2527   set_tok_reg (newtok[0], AXP_REG_T9);
2528   set_tok_const (newtok[1], 0);
2529   set_tok_preg (newtok[2], AXP_REG_AT);
2530   assemble_tokens ("ldq_u", newtok, 3, 1);
2531 
2532   /* Emit "ldq_u $10, size-1($at)".  */
2533   set_tok_reg (newtok[0], AXP_REG_T10);
2534   set_tok_const (newtok[1], (1 << lgsize) - 1);
2535   assemble_tokens ("ldq_u", newtok, 3, 1);
2536 
2537   /* Emit "insXl src, $at, $t11".  */
2538   newtok[0] = tok[0];
2539   set_tok_reg (newtok[1], AXP_REG_AT);
2540   set_tok_reg (newtok[2], AXP_REG_T11);
2541   assemble_tokens (insXl_op[lgsize], newtok, 3, 1);
2542 
2543   /* Emit "insXh src, $at, $t12".  */
2544   set_tok_reg (newtok[2], AXP_REG_T12);
2545   assemble_tokens (insXh_op[lgsize], newtok, 3, 1);
2546 
2547   /* Emit "mskXl $t9, $at, $t9".  */
2548   set_tok_reg (newtok[0], AXP_REG_T9);
2549   newtok[2] = newtok[0];
2550   assemble_tokens (mskXl_op[lgsize], newtok, 3, 1);
2551 
2552   /* Emit "mskXh $t10, $at, $t10".  */
2553   set_tok_reg (newtok[0], AXP_REG_T10);
2554   newtok[2] = newtok[0];
2555   assemble_tokens (mskXh_op[lgsize], newtok, 3, 1);
2556 
2557   /* Emit "or $t9, $t11, $t9".  */
2558   set_tok_reg (newtok[0], AXP_REG_T9);
2559   set_tok_reg (newtok[1], AXP_REG_T11);
2560   newtok[2] = newtok[0];
2561   assemble_tokens ("or", newtok, 3, 1);
2562 
2563   /* Emit "or $t10, $t12, $t10".  */
2564   set_tok_reg (newtok[0], AXP_REG_T10);
2565   set_tok_reg (newtok[1], AXP_REG_T12);
2566   newtok[2] = newtok[0];
2567   assemble_tokens ("or", newtok, 3, 1);
2568 
2569   /* Emit "stq_u $t10, size-1($at)".  */
2570   set_tok_reg (newtok[0], AXP_REG_T10);
2571   set_tok_const (newtok[1], (1 << lgsize) - 1);
2572   set_tok_preg (newtok[2], AXP_REG_AT);
2573   assemble_tokens ("stq_u", newtok, 3, 1);
2574 
2575   /* Emit "stq_u $t9, 0($at)".  */
2576   set_tok_reg (newtok[0], AXP_REG_T9);
2577   set_tok_const (newtok[1], 0);
2578   assemble_tokens ("stq_u", newtok, 3, 1);
2579 }
2580 
2581 /* Sign extend a half-word or byte.  The 32-bit sign extend is
2582    implemented as "addl $31, $r, $t" in the opcode table.  */
2583 
2584 static void
emit_sextX(const expressionS * tok,int ntok,const void * vlgsize)2585 emit_sextX (const expressionS *tok,
2586 	    int ntok,
2587 	    const void * vlgsize)
2588 {
2589   long lgsize = (long) vlgsize;
2590 
2591   if (alpha_target & AXP_OPCODE_BWX)
2592     assemble_tokens (sextX_op[lgsize], tok, ntok, 0);
2593   else
2594     {
2595       int bitshift = 64 - 8 * (1 << lgsize);
2596       expressionS newtok[3];
2597 
2598       /* Emit "sll src,bits,dst".  */
2599       newtok[0] = tok[0];
2600       set_tok_const (newtok[1], bitshift);
2601       newtok[2] = tok[ntok - 1];
2602       assemble_tokens ("sll", newtok, 3, 1);
2603 
2604       /* Emit "sra dst,bits,dst".  */
2605       newtok[0] = newtok[2];
2606       assemble_tokens ("sra", newtok, 3, 1);
2607     }
2608 }
2609 
2610 /* Implement the division and modulus macros.  */
2611 
2612 #ifdef OBJ_EVAX
2613 
2614 /* Make register usage like in normal procedure call.
2615    Don't clobber PV and RA.  */
2616 
2617 static void
emit_division(const expressionS * tok,int ntok,const void * symname)2618 emit_division (const expressionS *tok,
2619 	       int ntok,
2620 	       const void * symname)
2621 {
2622   /* DIVISION and MODULUS. Yech.
2623 
2624      Convert
2625         OP x,y,result
2626      to
2627         mov x,R16	# if x != R16
2628         mov y,R17	# if y != R17
2629         lda AT,__OP
2630         jsr AT,(AT),0
2631         mov R0,result
2632 
2633      with appropriate optimizations if R0,R16,R17 are the registers
2634      specified by the compiler.  */
2635 
2636   int xr, yr, rr;
2637   symbolS *sym;
2638   expressionS newtok[3];
2639 
2640   xr = regno (tok[0].X_add_number);
2641   yr = regno (tok[1].X_add_number);
2642 
2643   if (ntok < 3)
2644     rr = xr;
2645   else
2646     rr = regno (tok[2].X_add_number);
2647 
2648   /* Move the operands into the right place.  */
2649   if (yr == AXP_REG_R16 && xr == AXP_REG_R17)
2650     {
2651       /* They are in exactly the wrong order -- swap through AT.  */
2652       if (alpha_noat_on)
2653 	as_bad (_("macro requires $at register while noat in effect"));
2654 
2655       set_tok_reg (newtok[0], AXP_REG_R16);
2656       set_tok_reg (newtok[1], AXP_REG_AT);
2657       assemble_tokens ("mov", newtok, 2, 1);
2658 
2659       set_tok_reg (newtok[0], AXP_REG_R17);
2660       set_tok_reg (newtok[1], AXP_REG_R16);
2661       assemble_tokens ("mov", newtok, 2, 1);
2662 
2663       set_tok_reg (newtok[0], AXP_REG_AT);
2664       set_tok_reg (newtok[1], AXP_REG_R17);
2665       assemble_tokens ("mov", newtok, 2, 1);
2666     }
2667   else
2668     {
2669       if (yr == AXP_REG_R16)
2670 	{
2671 	  set_tok_reg (newtok[0], AXP_REG_R16);
2672 	  set_tok_reg (newtok[1], AXP_REG_R17);
2673 	  assemble_tokens ("mov", newtok, 2, 1);
2674 	}
2675 
2676       if (xr != AXP_REG_R16)
2677 	{
2678 	  set_tok_reg (newtok[0], xr);
2679 	  set_tok_reg (newtok[1], AXP_REG_R16);
2680 	  assemble_tokens ("mov", newtok, 2, 1);
2681 	}
2682 
2683       if (yr != AXP_REG_R16 && yr != AXP_REG_R17)
2684 	{
2685 	  set_tok_reg (newtok[0], yr);
2686 	  set_tok_reg (newtok[1], AXP_REG_R17);
2687 	  assemble_tokens ("mov", newtok, 2, 1);
2688 	}
2689     }
2690 
2691   sym = symbol_find_or_make ((const char *) symname);
2692 
2693   set_tok_reg (newtok[0], AXP_REG_AT);
2694   set_tok_sym (newtok[1], sym, 0);
2695   assemble_tokens ("lda", newtok, 2, 1);
2696 
2697   /* Call the division routine.  */
2698   set_tok_reg (newtok[0], AXP_REG_AT);
2699   set_tok_cpreg (newtok[1], AXP_REG_AT);
2700   set_tok_const (newtok[2], 0);
2701   assemble_tokens ("jsr", newtok, 3, 1);
2702 
2703   /* Move the result to the right place.  */
2704   if (rr != AXP_REG_R0)
2705     {
2706       set_tok_reg (newtok[0], AXP_REG_R0);
2707       set_tok_reg (newtok[1], rr);
2708       assemble_tokens ("mov", newtok, 2, 1);
2709     }
2710 }
2711 
2712 #else /* !OBJ_EVAX */
2713 
2714 static void
emit_division(const expressionS * tok,int ntok,const void * symname)2715 emit_division (const expressionS *tok,
2716 	       int ntok,
2717 	       const void * symname)
2718 {
2719   /* DIVISION and MODULUS. Yech.
2720      Convert
2721         OP x,y,result
2722      to
2723         lda pv,__OP
2724         mov x,t10
2725         mov y,t11
2726         jsr t9,(pv),__OP
2727         mov t12,result
2728 
2729      with appropriate optimizations if t10,t11,t12 are the registers
2730      specified by the compiler.  */
2731 
2732   int xr, yr, rr;
2733   symbolS *sym;
2734   expressionS newtok[3];
2735 
2736   xr = regno (tok[0].X_add_number);
2737   yr = regno (tok[1].X_add_number);
2738 
2739   if (ntok < 3)
2740     rr = xr;
2741   else
2742     rr = regno (tok[2].X_add_number);
2743 
2744   sym = symbol_find_or_make ((const char *) symname);
2745 
2746   /* Move the operands into the right place.  */
2747   if (yr == AXP_REG_T10 && xr == AXP_REG_T11)
2748     {
2749       /* They are in exactly the wrong order -- swap through AT.  */
2750       if (alpha_noat_on)
2751 	as_bad (_("macro requires $at register while noat in effect"));
2752 
2753       set_tok_reg (newtok[0], AXP_REG_T10);
2754       set_tok_reg (newtok[1], AXP_REG_AT);
2755       assemble_tokens ("mov", newtok, 2, 1);
2756 
2757       set_tok_reg (newtok[0], AXP_REG_T11);
2758       set_tok_reg (newtok[1], AXP_REG_T10);
2759       assemble_tokens ("mov", newtok, 2, 1);
2760 
2761       set_tok_reg (newtok[0], AXP_REG_AT);
2762       set_tok_reg (newtok[1], AXP_REG_T11);
2763       assemble_tokens ("mov", newtok, 2, 1);
2764     }
2765   else
2766     {
2767       if (yr == AXP_REG_T10)
2768 	{
2769 	  set_tok_reg (newtok[0], AXP_REG_T10);
2770 	  set_tok_reg (newtok[1], AXP_REG_T11);
2771 	  assemble_tokens ("mov", newtok, 2, 1);
2772 	}
2773 
2774       if (xr != AXP_REG_T10)
2775 	{
2776 	  set_tok_reg (newtok[0], xr);
2777 	  set_tok_reg (newtok[1], AXP_REG_T10);
2778 	  assemble_tokens ("mov", newtok, 2, 1);
2779 	}
2780 
2781       if (yr != AXP_REG_T10 && yr != AXP_REG_T11)
2782 	{
2783 	  set_tok_reg (newtok[0], yr);
2784 	  set_tok_reg (newtok[1], AXP_REG_T11);
2785 	  assemble_tokens ("mov", newtok, 2, 1);
2786 	}
2787     }
2788 
2789   /* Call the division routine.  */
2790   set_tok_reg (newtok[0], AXP_REG_T9);
2791   set_tok_sym (newtok[1], sym, 0);
2792   assemble_tokens ("jsr", newtok, 2, 1);
2793 
2794   /* Reload the GP register.  */
2795 #ifdef OBJ_AOUT
2796 FIXME
2797 #endif
2798 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
2799   set_tok_reg (newtok[0], alpha_gp_register);
2800   set_tok_const (newtok[1], 0);
2801   set_tok_preg (newtok[2], AXP_REG_T9);
2802   assemble_tokens ("ldgp", newtok, 3, 1);
2803 #endif
2804 
2805   /* Move the result to the right place.  */
2806   if (rr != AXP_REG_T12)
2807     {
2808       set_tok_reg (newtok[0], AXP_REG_T12);
2809       set_tok_reg (newtok[1], rr);
2810       assemble_tokens ("mov", newtok, 2, 1);
2811     }
2812 }
2813 
2814 #endif /* !OBJ_EVAX */
2815 
2816 /* The jsr and jmp macros differ from their instruction counterparts
2817    in that they can load the target address and default most
2818    everything.  */
2819 
2820 static void
emit_jsrjmp(const expressionS * tok,int ntok,const void * vopname)2821 emit_jsrjmp (const expressionS *tok,
2822 	     int ntok,
2823 	     const void * vopname)
2824 {
2825   const char *opname = (const char *) vopname;
2826   struct alpha_insn insn;
2827   expressionS newtok[3];
2828   int r, tokidx = 0;
2829   long lituse = 0;
2830 
2831   if (tokidx < ntok && tok[tokidx].X_op == O_register)
2832     r = regno (tok[tokidx++].X_add_number);
2833   else
2834     r = strcmp (opname, "jmp") == 0 ? AXP_REG_ZERO : AXP_REG_RA;
2835 
2836   set_tok_reg (newtok[0], r);
2837 
2838   if (tokidx < ntok &&
2839       (tok[tokidx].X_op == O_pregister || tok[tokidx].X_op == O_cpregister))
2840     r = regno (tok[tokidx++].X_add_number);
2841 #ifdef OBJ_EVAX
2842   /* Keep register if jsr $n.<sym>.  */
2843 #else
2844   else
2845     {
2846       int basereg = alpha_gp_register;
2847       lituse = load_expression (r = AXP_REG_PV, &tok[tokidx],
2848 				&basereg, NULL, opname);
2849     }
2850 #endif
2851 
2852   set_tok_cpreg (newtok[1], r);
2853 
2854 #ifndef OBJ_EVAX
2855   if (tokidx < ntok)
2856     newtok[2] = tok[tokidx];
2857   else
2858 #endif
2859     set_tok_const (newtok[2], 0);
2860 
2861   assemble_tokens_to_insn (opname, newtok, 3, &insn);
2862 
2863   if (lituse)
2864     {
2865       gas_assert (insn.nfixups < MAX_INSN_FIXUPS);
2866       insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_JSR;
2867       insn.fixups[insn.nfixups].exp.X_op = O_absent;
2868       insn.nfixups++;
2869       insn.sequence = lituse;
2870     }
2871 
2872 #ifdef OBJ_EVAX
2873   if (alpha_flag_replace
2874       && r == AXP_REG_RA
2875       && tok[tokidx].X_add_symbol
2876       && alpha_linkage_symbol)
2877     {
2878       /* Create a BOH reloc for 'jsr $27,NAME'.  */
2879       const char *symname = S_GET_NAME (tok[tokidx].X_add_symbol);
2880       int symlen = strlen (symname);
2881       char *ensymname;
2882 
2883       /* Build the entry name as 'NAME..en'.  */
2884       ensymname = XNEWVEC (char, symlen + 5);
2885       memcpy (ensymname, symname, symlen);
2886       memcpy (ensymname + symlen, "..en", 5);
2887 
2888       gas_assert (insn.nfixups < MAX_INSN_FIXUPS);
2889       if (insn.nfixups > 0)
2890 	{
2891 	  memmove (&insn.fixups[1], &insn.fixups[0],
2892 		   sizeof(struct alpha_fixup) * insn.nfixups);
2893 	}
2894 
2895       /* The fixup must be the same as the BFD_RELOC_ALPHA_NOP
2896 	 case in load_expression.  See B.4.5.2 of the OpenVMS
2897 	 Linker Utility Manual.  */
2898       insn.fixups[0].reloc = BFD_RELOC_ALPHA_BOH;
2899       insn.fixups[0].exp.X_op = O_symbol;
2900       insn.fixups[0].exp.X_add_symbol = symbol_find_or_make (ensymname);
2901       insn.fixups[0].exp.X_add_number = 0;
2902       insn.fixups[0].xtrasym = alpha_linkage_symbol;
2903       insn.fixups[0].procsym = alpha_evax_proc->symbol;
2904       insn.nfixups++;
2905       alpha_linkage_symbol = 0;
2906       free (ensymname);
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   c = get_symbol_name (&name);
3498 
3499   /* Just after name is now '\0'.  */
3500   p = input_line_pointer;
3501   *p = c;
3502 
3503   SKIP_WHITESPACE_AFTER_NAME ();
3504 
3505   /* Alpha OSF/1 compiler doesn't provide the comma, gcc does.  */
3506   if (*input_line_pointer == ',')
3507     {
3508       input_line_pointer++;
3509       SKIP_WHITESPACE ();
3510     }
3511   if ((size = get_absolute_expression ()) < 0)
3512     {
3513       as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) size);
3514       ignore_rest_of_line ();
3515       return;
3516     }
3517 
3518   *p = 0;
3519   symbolP = symbol_find_or_make (name);
3520   *p = c;
3521 
3522   if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
3523     {
3524       as_bad (_("Ignoring attempt to re-define symbol"));
3525       ignore_rest_of_line ();
3526       return;
3527     }
3528 
3529 #ifdef OBJ_EVAX
3530   if (*input_line_pointer != ',')
3531     temp = 8; /* Default alignment.  */
3532   else
3533     {
3534       input_line_pointer++;
3535       SKIP_WHITESPACE ();
3536       temp = get_absolute_expression ();
3537     }
3538 
3539   /* ??? Unlike on OSF/1, the alignment factor is not in log units.  */
3540   while ((temp >>= 1) != 0)
3541     ++log_align;
3542 
3543   if (*input_line_pointer == ',')
3544     {
3545       /* Extended form of the directive
3546 
3547 	   .comm symbol, size, alignment, section
3548 
3549          where the "common" semantics is transferred to the section.
3550          The symbol is effectively an alias for the section name.  */
3551 
3552       segT sec;
3553       const char *sec_name;
3554       symbolS *sec_symbol;
3555       segT current_seg = now_seg;
3556       subsegT current_subseg = now_subseg;
3557       int cur_size;
3558 
3559       input_line_pointer++;
3560       SKIP_WHITESPACE ();
3561       sec_name = s_alpha_section_name ();
3562       sec_symbol = symbol_find_or_make (sec_name);
3563       sec = subseg_new (sec_name, 0);
3564       S_SET_SEGMENT (sec_symbol, sec);
3565       symbol_get_bfdsym (sec_symbol)->flags |= BSF_SECTION_SYM;
3566       bfd_vms_set_section_flags (stdoutput, sec, 0,
3567 				 EGPS__V_OVR | EGPS__V_GBL | EGPS__V_NOMOD);
3568       record_alignment (sec, log_align);
3569 
3570       /* Reuse stab_string_size to store the size of the section.  */
3571       cur_size = seg_info (sec)->stabu.stab_string_size;
3572       if ((int) size > cur_size)
3573 	{
3574 	  char *pfrag
3575 	    = frag_var (rs_fill, 1, 1, (relax_substateT)0, NULL,
3576 			(valueT)size - (valueT)cur_size, NULL);
3577 	  *pfrag = 0;
3578 	  seg_info (sec)->stabu.stab_string_size = (int)size;
3579 	}
3580 
3581       S_SET_SEGMENT (symbolP, sec);
3582 
3583       subseg_set (current_seg, current_subseg);
3584     }
3585   else
3586     {
3587       /* Regular form of the directive
3588 
3589 	   .comm symbol, size, alignment
3590 
3591 	 where the "common" semantics in on the symbol.
3592 	 These symbols are assembled in the .bss section.  */
3593 
3594       char *pfrag;
3595       segT current_seg = now_seg;
3596       subsegT current_subseg = now_subseg;
3597 
3598       subseg_set (bss_section, 1);
3599       frag_align (log_align, 0, 0);
3600       record_alignment (bss_section, log_align);
3601 
3602       symbol_set_frag (symbolP, frag_now);
3603       pfrag = frag_var (rs_org, 1, 1, (relax_substateT)0, symbolP,
3604                         size, NULL);
3605       *pfrag = 0;
3606 
3607       S_SET_SEGMENT (symbolP, bss_section);
3608 
3609       subseg_set (current_seg, current_subseg);
3610     }
3611 #endif
3612 
3613   if (S_GET_VALUE (symbolP))
3614     {
3615       if (S_GET_VALUE (symbolP) != (valueT) size)
3616         as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
3617                 S_GET_NAME (symbolP),
3618                 (long) S_GET_VALUE (symbolP),
3619                 (long) size);
3620     }
3621   else
3622     {
3623 #ifndef OBJ_EVAX
3624       S_SET_VALUE (symbolP, (valueT) size);
3625 #endif
3626       S_SET_EXTERNAL (symbolP);
3627     }
3628 
3629 #ifndef OBJ_EVAX
3630   know (symbolP->sy_frag == &zero_address_frag);
3631 #endif
3632   demand_empty_rest_of_line ();
3633 }
3634 
3635 #endif /* ! OBJ_ELF */
3636 
3637 #ifdef OBJ_ECOFF
3638 
3639 /* Handle the .rdata pseudo-op.  This is like the usual one, but it
3640    clears alpha_insn_label and restores auto alignment.  */
3641 
3642 static void
s_alpha_rdata(int ignore ATTRIBUTE_UNUSED)3643 s_alpha_rdata (int ignore ATTRIBUTE_UNUSED)
3644 {
3645   get_absolute_expression ();
3646   subseg_new (".rdata", 0);
3647   demand_empty_rest_of_line ();
3648   alpha_insn_label = NULL;
3649   alpha_auto_align_on = 1;
3650   alpha_current_align = 0;
3651 }
3652 
3653 #endif
3654 
3655 #ifdef OBJ_ECOFF
3656 
3657 /* Handle the .sdata pseudo-op.  This is like the usual one, but it
3658    clears alpha_insn_label and restores auto alignment.  */
3659 
3660 static void
s_alpha_sdata(int ignore ATTRIBUTE_UNUSED)3661 s_alpha_sdata (int ignore ATTRIBUTE_UNUSED)
3662 {
3663   get_absolute_expression ();
3664   subseg_new (".sdata", 0);
3665   demand_empty_rest_of_line ();
3666   alpha_insn_label = NULL;
3667   alpha_auto_align_on = 1;
3668   alpha_current_align = 0;
3669 }
3670 #endif
3671 
3672 #ifdef OBJ_ELF
3673 struct alpha_elf_frame_data
3674 {
3675   symbolS *func_sym;
3676   symbolS *func_end_sym;
3677   symbolS *prologue_sym;
3678   unsigned int mask;
3679   unsigned int fmask;
3680   int fp_regno;
3681   int ra_regno;
3682   offsetT frame_size;
3683   offsetT mask_offset;
3684   offsetT fmask_offset;
3685 
3686   struct alpha_elf_frame_data *next;
3687 };
3688 
3689 static struct alpha_elf_frame_data *all_frame_data;
3690 static struct alpha_elf_frame_data **plast_frame_data = &all_frame_data;
3691 static struct alpha_elf_frame_data *cur_frame_data;
3692 
3693 extern int all_cfi_sections;
3694 
3695 /* Handle the .section pseudo-op.  This is like the usual one, but it
3696    clears alpha_insn_label and restores auto alignment.  */
3697 
3698 static void
s_alpha_section(int ignore ATTRIBUTE_UNUSED)3699 s_alpha_section (int ignore ATTRIBUTE_UNUSED)
3700 {
3701   obj_elf_section (ignore);
3702 
3703   alpha_insn_label = NULL;
3704   alpha_auto_align_on = 1;
3705   alpha_current_align = 0;
3706 }
3707 
3708 static void
s_alpha_ent(int dummy ATTRIBUTE_UNUSED)3709 s_alpha_ent (int dummy ATTRIBUTE_UNUSED)
3710 {
3711   if (ECOFF_DEBUGGING)
3712     ecoff_directive_ent (0);
3713   else
3714     {
3715       char *name, name_end;
3716 
3717       name_end = get_symbol_name (&name);
3718       /* CFI_EMIT_eh_frame is the default.  */
3719       all_cfi_sections = CFI_EMIT_eh_frame;
3720 
3721       if (! is_name_beginner (*name))
3722 	{
3723 	  as_warn (_(".ent directive has no name"));
3724 	  (void) restore_line_pointer (name_end);
3725 	}
3726       else
3727 	{
3728 	  symbolS *sym;
3729 
3730 	  if (cur_frame_data)
3731 	    as_warn (_("nested .ent directives"));
3732 
3733 	  sym = symbol_find_or_make (name);
3734 	  symbol_get_bfdsym (sym)->flags |= BSF_FUNCTION;
3735 
3736 	  cur_frame_data = XCNEW (struct alpha_elf_frame_data);
3737 	  cur_frame_data->func_sym = sym;
3738 
3739 	  /* Provide sensible defaults.  */
3740 	  cur_frame_data->fp_regno = 30;	/* sp */
3741 	  cur_frame_data->ra_regno = 26;	/* ra */
3742 
3743 	  *plast_frame_data = cur_frame_data;
3744 	  plast_frame_data = &cur_frame_data->next;
3745 
3746 	  /* The .ent directive is sometimes followed by a number.  Not sure
3747 	     what it really means, but ignore it.  */
3748 	  *input_line_pointer = name_end;
3749 	  SKIP_WHITESPACE_AFTER_NAME ();
3750 	  if (*input_line_pointer == ',')
3751 	    {
3752 	      input_line_pointer++;
3753 	      SKIP_WHITESPACE ();
3754 	    }
3755 	  if (ISDIGIT (*input_line_pointer) || *input_line_pointer == '-')
3756 	    (void) get_absolute_expression ();
3757 	}
3758       demand_empty_rest_of_line ();
3759     }
3760 }
3761 
3762 static void
s_alpha_end(int dummy ATTRIBUTE_UNUSED)3763 s_alpha_end (int dummy ATTRIBUTE_UNUSED)
3764 {
3765   if (ECOFF_DEBUGGING)
3766     ecoff_directive_end (0);
3767   else
3768     {
3769       char *name, name_end;
3770 
3771       name_end = get_symbol_name (&name);
3772 
3773       if (! is_name_beginner (*name))
3774 	{
3775 	  as_warn (_(".end directive has no name"));
3776 	}
3777       else
3778 	{
3779 	  symbolS *sym;
3780 
3781 	  sym = symbol_find (name);
3782 	  if (!cur_frame_data)
3783 	    as_warn (_(".end directive without matching .ent"));
3784 	  else if (sym != cur_frame_data->func_sym)
3785 	    as_warn (_(".end directive names different symbol than .ent"));
3786 
3787 	  /* Create an expression to calculate the size of the function.  */
3788 	  if (sym && cur_frame_data)
3789 	    {
3790 	      OBJ_SYMFIELD_TYPE *obj = symbol_get_obj (sym);
3791 	      expressionS *exp = XNEW (expressionS);
3792 
3793 	      obj->size = exp;
3794 	      exp->X_op = O_subtract;
3795 	      exp->X_add_symbol = symbol_temp_new_now ();
3796 	      exp->X_op_symbol = sym;
3797 	      exp->X_add_number = 0;
3798 
3799 	      cur_frame_data->func_end_sym = exp->X_add_symbol;
3800 	    }
3801 
3802 	  cur_frame_data = NULL;
3803 	}
3804 
3805       (void) restore_line_pointer (name_end);
3806       demand_empty_rest_of_line ();
3807     }
3808 }
3809 
3810 static void
s_alpha_mask(int fp)3811 s_alpha_mask (int fp)
3812 {
3813   if (ECOFF_DEBUGGING)
3814     {
3815       if (fp)
3816 	ecoff_directive_fmask (0);
3817       else
3818 	ecoff_directive_mask (0);
3819     }
3820   else
3821     {
3822       long val;
3823       offsetT offset;
3824 
3825       if (!cur_frame_data)
3826 	{
3827 	  if (fp)
3828 	    as_warn (_(".fmask outside of .ent"));
3829 	  else
3830 	    as_warn (_(".mask outside of .ent"));
3831 	  discard_rest_of_line ();
3832 	  return;
3833 	}
3834 
3835       if (get_absolute_expression_and_terminator (&val) != ',')
3836 	{
3837 	  if (fp)
3838 	    as_warn (_("bad .fmask directive"));
3839 	  else
3840 	    as_warn (_("bad .mask directive"));
3841 	  --input_line_pointer;
3842 	  discard_rest_of_line ();
3843 	  return;
3844 	}
3845 
3846       offset = get_absolute_expression ();
3847       demand_empty_rest_of_line ();
3848 
3849       if (fp)
3850 	{
3851 	  cur_frame_data->fmask = val;
3852           cur_frame_data->fmask_offset = offset;
3853 	}
3854       else
3855 	{
3856 	  cur_frame_data->mask = val;
3857 	  cur_frame_data->mask_offset = offset;
3858 	}
3859     }
3860 }
3861 
3862 static void
s_alpha_frame(int dummy ATTRIBUTE_UNUSED)3863 s_alpha_frame (int dummy ATTRIBUTE_UNUSED)
3864 {
3865   if (ECOFF_DEBUGGING)
3866     ecoff_directive_frame (0);
3867   else
3868     {
3869       long val;
3870 
3871       if (!cur_frame_data)
3872 	{
3873 	  as_warn (_(".frame outside of .ent"));
3874 	  discard_rest_of_line ();
3875 	  return;
3876 	}
3877 
3878       cur_frame_data->fp_regno = tc_get_register (1);
3879 
3880       SKIP_WHITESPACE ();
3881       if (*input_line_pointer++ != ','
3882 	  || get_absolute_expression_and_terminator (&val) != ',')
3883 	{
3884 	  as_warn (_("bad .frame directive"));
3885 	  --input_line_pointer;
3886 	  discard_rest_of_line ();
3887 	  return;
3888 	}
3889       cur_frame_data->frame_size = val;
3890 
3891       cur_frame_data->ra_regno = tc_get_register (0);
3892 
3893       /* Next comes the "offset of saved $a0 from $sp".  In gcc terms
3894 	 this is current_function_pretend_args_size.  There's no place
3895 	 to put this value, so ignore it.  */
3896       s_ignore (42);
3897     }
3898 }
3899 
3900 static void
s_alpha_prologue(int ignore ATTRIBUTE_UNUSED)3901 s_alpha_prologue (int ignore ATTRIBUTE_UNUSED)
3902 {
3903   symbolS *sym;
3904   int arg;
3905 
3906   arg = get_absolute_expression ();
3907   demand_empty_rest_of_line ();
3908   alpha_prologue_label = symbol_new
3909     (FAKE_LABEL_NAME, now_seg, (valueT) frag_now_fix (), frag_now);
3910 
3911   if (ECOFF_DEBUGGING)
3912     sym = ecoff_get_cur_proc_sym ();
3913   else
3914     sym = cur_frame_data ? cur_frame_data->func_sym : NULL;
3915 
3916   if (sym == NULL)
3917     {
3918       as_bad (_(".prologue directive without a preceding .ent directive"));
3919       return;
3920     }
3921 
3922   switch (arg)
3923     {
3924     case 0: /* No PV required.  */
3925       S_SET_OTHER (sym, STO_ALPHA_NOPV
3926 		   | (S_GET_OTHER (sym) & ~STO_ALPHA_STD_GPLOAD));
3927       break;
3928     case 1: /* Std GP load.  */
3929       S_SET_OTHER (sym, STO_ALPHA_STD_GPLOAD
3930 		   | (S_GET_OTHER (sym) & ~STO_ALPHA_STD_GPLOAD));
3931       break;
3932     case 2: /* Non-std use of PV.  */
3933       break;
3934 
3935     default:
3936       as_bad (_("Invalid argument %d to .prologue."), arg);
3937       break;
3938     }
3939 
3940   if (cur_frame_data)
3941     cur_frame_data->prologue_sym = symbol_temp_new_now ();
3942 }
3943 
3944 static char *first_file_directive;
3945 
3946 static void
s_alpha_file(int ignore ATTRIBUTE_UNUSED)3947 s_alpha_file (int ignore ATTRIBUTE_UNUSED)
3948 {
3949   /* Save the first .file directive we see, so that we can change our
3950      minds about whether ecoff debugging should or shouldn't be enabled.  */
3951   if (alpha_flag_mdebug < 0 && ! first_file_directive)
3952     {
3953       char *start = input_line_pointer;
3954       size_t len;
3955 
3956       discard_rest_of_line ();
3957 
3958       len = input_line_pointer - start;
3959       first_file_directive = xmemdup0 (start, len);
3960 
3961       input_line_pointer = start;
3962     }
3963 
3964   if (ECOFF_DEBUGGING)
3965     ecoff_directive_file (0);
3966   else
3967     dwarf2_directive_file (0);
3968 }
3969 
3970 static void
s_alpha_loc(int ignore ATTRIBUTE_UNUSED)3971 s_alpha_loc (int ignore ATTRIBUTE_UNUSED)
3972 {
3973   if (ECOFF_DEBUGGING)
3974     ecoff_directive_loc (0);
3975   else
3976     dwarf2_directive_loc (0);
3977 }
3978 
3979 static void
s_alpha_stab(int n)3980 s_alpha_stab (int n)
3981 {
3982   /* If we've been undecided about mdebug, make up our minds in favour.  */
3983   if (alpha_flag_mdebug < 0)
3984     {
3985       segT sec = subseg_new (".mdebug", 0);
3986       bfd_set_section_flags (stdoutput, sec, SEC_HAS_CONTENTS | SEC_READONLY);
3987       bfd_set_section_alignment (stdoutput, sec, 3);
3988 
3989       ecoff_read_begin_hook ();
3990 
3991       if (first_file_directive)
3992 	{
3993 	  char *save_ilp = input_line_pointer;
3994 	  input_line_pointer = first_file_directive;
3995 	  ecoff_directive_file (0);
3996 	  input_line_pointer = save_ilp;
3997 	  free (first_file_directive);
3998 	}
3999 
4000       alpha_flag_mdebug = 1;
4001     }
4002   s_stab (n);
4003 }
4004 
4005 static void
s_alpha_coff_wrapper(int which)4006 s_alpha_coff_wrapper (int which)
4007 {
4008   static void (* const fns[]) (int) = {
4009     ecoff_directive_begin,
4010     ecoff_directive_bend,
4011     ecoff_directive_def,
4012     ecoff_directive_dim,
4013     ecoff_directive_endef,
4014     ecoff_directive_scl,
4015     ecoff_directive_tag,
4016     ecoff_directive_val,
4017   };
4018 
4019   gas_assert (which >= 0 && which < (int) (sizeof (fns)/sizeof (*fns)));
4020 
4021   if (ECOFF_DEBUGGING)
4022     (*fns[which]) (0);
4023   else
4024     {
4025       as_bad (_("ECOFF debugging is disabled."));
4026       ignore_rest_of_line ();
4027     }
4028 }
4029 
4030 /* Called at the end of assembly.  Here we emit unwind info for frames
4031    unless the compiler has done it for us.  */
4032 
4033 void
alpha_elf_md_end(void)4034 alpha_elf_md_end (void)
4035 {
4036   struct alpha_elf_frame_data *p;
4037 
4038   if (cur_frame_data)
4039     as_warn (_(".ent directive without matching .end"));
4040 
4041   /* If someone has generated the unwind info themselves, great.  */
4042   if (bfd_get_section_by_name (stdoutput, ".eh_frame") != NULL)
4043     return;
4044 
4045   /* ??? In theory we could look for functions for which we have
4046      generated unwind info via CFI directives, and those we have not.
4047      Those we have not could still get their unwind info from here.
4048      For now, do nothing if we've seen any CFI directives.  Note that
4049      the above test will not trigger, as we've not emitted data yet.  */
4050   if (all_fde_data != NULL)
4051     return;
4052 
4053   /* Generate .eh_frame data for the unwind directives specified.  */
4054   for (p = all_frame_data; p ; p = p->next)
4055     if (p->prologue_sym)
4056       {
4057 	/* Create a temporary symbol at the same location as our
4058 	   function symbol.  This prevents problems with globals.  */
4059 	cfi_new_fde (symbol_temp_new (S_GET_SEGMENT (p->func_sym),
4060 				      S_GET_VALUE (p->func_sym),
4061 				      symbol_get_frag (p->func_sym)));
4062 
4063 	cfi_set_sections ();
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_end = get_symbol_name (&name);
4129 
4130   if (! is_name_beginner (*name))
4131     {
4132       as_bad (_(".usepv directive has no name"));
4133       (void) restore_line_pointer (name_end);
4134       ignore_rest_of_line ();
4135       return;
4136     }
4137 
4138   sym = symbol_find_or_make (name);
4139   name_end = restore_line_pointer (name_end);
4140   if (! is_end_of_line[(unsigned char) name_end])
4141     input_line_pointer++;
4142 
4143   if (name_end != ',')
4144     {
4145       as_bad (_(".usepv directive has no type"));
4146       ignore_rest_of_line ();
4147       return;
4148     }
4149 
4150   SKIP_WHITESPACE ();
4151 
4152   which_end = get_symbol_name (&which);
4153 
4154   if (strcmp (which, "no") == 0)
4155     other = STO_ALPHA_NOPV;
4156   else if (strcmp (which, "std") == 0)
4157     other = STO_ALPHA_STD_GPLOAD;
4158   else
4159     {
4160       as_bad (_("unknown argument for .usepv"));
4161       other = 0;
4162     }
4163 
4164   (void) restore_line_pointer (which_end);
4165   demand_empty_rest_of_line ();
4166 
4167   S_SET_OTHER (sym, other | (S_GET_OTHER (sym) & ~STO_ALPHA_STD_GPLOAD));
4168 }
4169 #endif /* OBJ_ELF */
4170 
4171 /* Standard calling conventions leaves the CFA at $30 on entry.  */
4172 
4173 void
alpha_cfi_frame_initial_instructions(void)4174 alpha_cfi_frame_initial_instructions (void)
4175 {
4176   cfi_add_CFA_def_cfa_register (30);
4177 }
4178 
4179 #ifdef OBJ_EVAX
4180 
4181 /* Get name of section.  */
4182 static const char *
s_alpha_section_name(void)4183 s_alpha_section_name (void)
4184 {
4185   char *name;
4186 
4187   SKIP_WHITESPACE ();
4188   if (*input_line_pointer == '"')
4189     {
4190       int dummy;
4191 
4192       name = demand_copy_C_string (&dummy);
4193       if (name == NULL)
4194 	{
4195 	  ignore_rest_of_line ();
4196 	  return NULL;
4197 	}
4198     }
4199   else
4200     {
4201       char *end = input_line_pointer;
4202 
4203       while (0 == strchr ("\n\t,; ", *end))
4204 	end++;
4205       if (end == input_line_pointer)
4206 	{
4207 	  as_warn (_("missing name"));
4208 	  ignore_rest_of_line ();
4209 	  return NULL;
4210 	}
4211 
4212       name = xmemdup0 (input_line_pointer, end - input_line_pointer);
4213       input_line_pointer = end;
4214     }
4215   SKIP_WHITESPACE ();
4216   return name;
4217 }
4218 
4219 /* Put clear/set flags in one flagword.  The LSBs are flags to be set,
4220    the MSBs are the flags to be cleared.  */
4221 
4222 #define EGPS__V_NO_SHIFT 16
4223 #define EGPS__V_MASK	 0xffff
4224 
4225 /* Parse one VMS section flag.  */
4226 
4227 static flagword
s_alpha_section_word(char * str,size_t len)4228 s_alpha_section_word (char *str, size_t len)
4229 {
4230   int no = 0;
4231   flagword flag = 0;
4232 
4233   if (len == 5 && strncmp (str, "NO", 2) == 0)
4234     {
4235       no = 1;
4236       str += 2;
4237       len -= 2;
4238     }
4239 
4240   if (len == 3)
4241     {
4242       if (strncmp (str, "PIC", 3) == 0)
4243 	flag = EGPS__V_PIC;
4244       else if (strncmp (str, "LIB", 3) == 0)
4245 	flag = EGPS__V_LIB;
4246       else if (strncmp (str, "OVR", 3) == 0)
4247 	flag = EGPS__V_OVR;
4248       else if (strncmp (str, "REL", 3) == 0)
4249 	flag = EGPS__V_REL;
4250       else if (strncmp (str, "GBL", 3) == 0)
4251 	flag = EGPS__V_GBL;
4252       else if (strncmp (str, "SHR", 3) == 0)
4253 	flag = EGPS__V_SHR;
4254       else if (strncmp (str, "EXE", 3) == 0)
4255 	flag = EGPS__V_EXE;
4256       else if (strncmp (str, "WRT", 3) == 0)
4257 	flag = EGPS__V_WRT;
4258       else if (strncmp (str, "VEC", 3) == 0)
4259 	flag = EGPS__V_VEC;
4260       else if (strncmp (str, "MOD", 3) == 0)
4261 	{
4262 	  flag = no ? EGPS__V_NOMOD : EGPS__V_NOMOD << EGPS__V_NO_SHIFT;
4263 	  no = 0;
4264 	}
4265       else if (strncmp (str, "COM", 3) == 0)
4266 	flag = EGPS__V_COM;
4267     }
4268 
4269   if (flag == 0)
4270     {
4271       char c = str[len];
4272       str[len] = 0;
4273       as_warn (_("unknown section attribute %s"), str);
4274       str[len] = c;
4275       return 0;
4276     }
4277 
4278   if (no)
4279     return flag << EGPS__V_NO_SHIFT;
4280   else
4281     return flag;
4282 }
4283 
4284 /* Handle the section specific pseudo-op.  */
4285 
4286 #define EVAX_SECTION_COUNT 5
4287 
4288 static const char *section_name[EVAX_SECTION_COUNT + 1] =
4289   { "NULL", ".rdata", ".comm", ".link", ".ctors", ".dtors" };
4290 
4291 static void
s_alpha_section(int secid)4292 s_alpha_section (int secid)
4293 {
4294   const char *name;
4295   char *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      	      c = get_symbol_name (&beg);
4318      	      *input_line_pointer = c;
4319 
4320      	      vms_flags |= s_alpha_section_word (beg, input_line_pointer - beg);
4321 
4322      	      SKIP_WHITESPACE_AFTER_NAME ();
4323      	    }
4324      	  while (*input_line_pointer++ == ',');
4325 
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 
4410       name_end = get_symbol_name (&name);
4411 
4412       if (! is_name_beginner (*name))
4413 	{
4414 	  as_warn (_(".handler directive has no name"));
4415 	}
4416       else
4417 	{
4418 	  symbolS *sym;
4419 
4420 	  sym = symbol_find_or_make (name);
4421 	  symbol_get_bfdsym (sym)->flags |= BSF_FUNCTION;
4422 	  alpha_evax_proc->handler = sym;
4423 	}
4424 
4425       (void) restore_line_pointer (name_end);
4426     }
4427 
4428   demand_empty_rest_of_line ();
4429 }
4430 
4431 /* Parse .frame <framreg>,<framesize>,RA,<rsa_offset> directives.  */
4432 
4433 static void
s_alpha_frame(int ignore ATTRIBUTE_UNUSED)4434 s_alpha_frame (int ignore ATTRIBUTE_UNUSED)
4435 {
4436   long val;
4437   int ra;
4438 
4439   alpha_evax_proc->framereg = tc_get_register (1);
4440 
4441   SKIP_WHITESPACE ();
4442   if (*input_line_pointer++ != ','
4443       || get_absolute_expression_and_terminator (&val) != ',')
4444     {
4445       as_warn (_("Bad .frame directive 1./2. param"));
4446       --input_line_pointer;
4447       demand_empty_rest_of_line ();
4448       return;
4449     }
4450 
4451   alpha_evax_proc->framesize = val;
4452 
4453   ra = tc_get_register (1);
4454   if (ra != AXP_REG_RA)
4455     as_warn (_("Bad RA (%d) register for .frame"), ra);
4456 
4457   SKIP_WHITESPACE ();
4458   if (*input_line_pointer++ != ',')
4459     {
4460       as_warn (_("Bad .frame directive 3./4. param"));
4461       --input_line_pointer;
4462       demand_empty_rest_of_line ();
4463       return;
4464     }
4465   alpha_evax_proc->rsa_offset = get_absolute_expression ();
4466 }
4467 
4468 /* Parse .prologue.  */
4469 
4470 static void
s_alpha_prologue(int ignore ATTRIBUTE_UNUSED)4471 s_alpha_prologue (int ignore ATTRIBUTE_UNUSED)
4472 {
4473   demand_empty_rest_of_line ();
4474   alpha_prologue_label = symbol_new
4475     (FAKE_LABEL_NAME, now_seg, (valueT) frag_now_fix (), frag_now);
4476 }
4477 
4478 /* Parse .pdesc <entry_name>,{null|stack|reg}
4479    Insert a procedure descriptor.  */
4480 
4481 static void
s_alpha_pdesc(int ignore ATTRIBUTE_UNUSED)4482 s_alpha_pdesc (int ignore ATTRIBUTE_UNUSED)
4483 {
4484   char *name;
4485   char name_end;
4486   char *p;
4487   expressionS exp;
4488   symbolS *entry_sym;
4489   const char *entry_sym_name;
4490   const char *pdesc_sym_name;
4491   fixS *fixp;
4492   size_t len;
4493 
4494   if (now_seg != alpha_link_section)
4495     {
4496       as_bad (_(".pdesc directive not in link (.link) section"));
4497       return;
4498     }
4499 
4500   expression (&exp);
4501   if (exp.X_op != O_symbol)
4502     {
4503       as_bad (_(".pdesc directive has no entry symbol"));
4504       return;
4505     }
4506 
4507   entry_sym = make_expr_symbol (&exp);
4508   entry_sym_name = S_GET_NAME (entry_sym);
4509 
4510   /* Strip "..en".  */
4511   len = strlen (entry_sym_name);
4512   if (len < 4 || strcmp (entry_sym_name + len - 4, "..en") != 0)
4513     {
4514       as_bad (_(".pdesc has a bad entry symbol"));
4515       return;
4516     }
4517   len -= 4;
4518   pdesc_sym_name = S_GET_NAME (alpha_evax_proc->symbol);
4519 
4520   if (!alpha_evax_proc
4521       || !S_IS_DEFINED (alpha_evax_proc->symbol)
4522       || strlen (pdesc_sym_name) != len
4523       || memcmp (entry_sym_name, pdesc_sym_name, len) != 0)
4524     {
4525       as_fatal (_(".pdesc doesn't match with last .ent"));
4526       return;
4527     }
4528 
4529   /* Define pdesc symbol.  */
4530   symbol_set_value_now (alpha_evax_proc->symbol);
4531 
4532   /* Save bfd symbol of proc entry in function symbol.  */
4533   ((struct evax_private_udata_struct *)
4534      symbol_get_bfdsym (alpha_evax_proc->symbol)->udata.p)->enbsym
4535        = symbol_get_bfdsym (entry_sym);
4536 
4537   SKIP_WHITESPACE ();
4538   if (*input_line_pointer++ != ',')
4539     {
4540       as_warn (_("No comma after .pdesc <entryname>"));
4541       demand_empty_rest_of_line ();
4542       return;
4543     }
4544 
4545   SKIP_WHITESPACE ();
4546   name_end = get_symbol_name (&name);
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       (void) restore_line_pointer (name_end);
4560       as_fatal (_("unknown procedure kind"));
4561       demand_empty_rest_of_line ();
4562       return;
4563     }
4564 
4565   (void) restore_line_pointer (name_end);
4566   demand_empty_rest_of_line ();
4567 
4568 #ifdef md_flush_pending_output
4569   md_flush_pending_output ();
4570 #endif
4571 
4572   frag_align (3, 0, 0);
4573   p = frag_more (16);
4574   fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
4575   fixp->fx_done = 1;
4576 
4577   *p = alpha_evax_proc->pdsckind
4578     | ((alpha_evax_proc->framereg == 29) ? PDSC_S_M_BASE_REG_IS_FP : 0)
4579     | ((alpha_evax_proc->handler) ? PDSC_S_M_HANDLER_VALID : 0)
4580     | ((alpha_evax_proc->handler_data) ? PDSC_S_M_HANDLER_DATA_VALID : 0);
4581   *(p + 1) = PDSC_S_M_NATIVE | PDSC_S_M_NO_JACKET;
4582 
4583   switch (alpha_evax_proc->pdsckind)
4584     {
4585     case PDSC_S_K_KIND_NULL:
4586       *(p + 2) = 0;
4587       *(p + 3) = 0;
4588       break;
4589     case PDSC_S_K_KIND_FP_REGISTER:
4590       *(p + 2) = alpha_evax_proc->fp_save;
4591       *(p + 3) = alpha_evax_proc->ra_save;
4592       break;
4593     case PDSC_S_K_KIND_FP_STACK:
4594       md_number_to_chars (p + 2, (valueT) alpha_evax_proc->rsa_offset, 2);
4595       break;
4596     default:		/* impossible */
4597       break;
4598     }
4599 
4600   *(p + 4) = 0;
4601   *(p + 5) = alpha_evax_proc->type & 0x0f;
4602 
4603   /* Signature offset.  */
4604   md_number_to_chars (p + 6, (valueT) 0, 2);
4605 
4606   fix_new_exp (frag_now, p - frag_now->fr_literal + 8,
4607                8, &exp, 0, BFD_RELOC_64);
4608 
4609   if (alpha_evax_proc->pdsckind == PDSC_S_K_KIND_NULL)
4610     return;
4611 
4612   /* pdesc+16: Size.  */
4613   p = frag_more (6);
4614   md_number_to_chars (p, (valueT) alpha_evax_proc->framesize, 4);
4615   md_number_to_chars (p + 4, (valueT) 0, 2);
4616 
4617   /* Entry length.  */
4618   exp.X_op = O_subtract;
4619   exp.X_add_symbol = alpha_prologue_label;
4620   exp.X_op_symbol = entry_sym;
4621   emit_expr (&exp, 2);
4622 
4623   if (alpha_evax_proc->pdsckind == PDSC_S_K_KIND_FP_REGISTER)
4624     return;
4625 
4626   /* pdesc+24: register masks.  */
4627   p = frag_more (8);
4628   md_number_to_chars (p, alpha_evax_proc->imask, 4);
4629   md_number_to_chars (p + 4, alpha_evax_proc->fmask, 4);
4630 
4631   if (alpha_evax_proc->handler)
4632     {
4633       p = frag_more (8);
4634       fixp = fix_new (frag_now, p - frag_now->fr_literal, 8,
4635 	              alpha_evax_proc->handler, 0, 0, BFD_RELOC_64);
4636     }
4637 
4638   if (alpha_evax_proc->handler_data)
4639     {
4640       p = frag_more (8);
4641       md_number_to_chars (p, alpha_evax_proc->handler_data, 8);
4642     }
4643 }
4644 
4645 /* Support for crash debug on vms.  */
4646 
4647 static void
s_alpha_name(int ignore ATTRIBUTE_UNUSED)4648 s_alpha_name (int ignore ATTRIBUTE_UNUSED)
4649 {
4650   char *p;
4651   expressionS exp;
4652 
4653   if (now_seg != alpha_link_section)
4654     {
4655       as_bad (_(".name directive not in link (.link) section"));
4656       demand_empty_rest_of_line ();
4657       return;
4658     }
4659 
4660   expression (&exp);
4661   if (exp.X_op != O_symbol)
4662     {
4663       as_warn (_(".name directive has no symbol"));
4664       demand_empty_rest_of_line ();
4665       return;
4666     }
4667 
4668   demand_empty_rest_of_line ();
4669 
4670 #ifdef md_flush_pending_output
4671   md_flush_pending_output ();
4672 #endif
4673 
4674   frag_align (3, 0, 0);
4675   p = frag_more (8);
4676 
4677   fix_new_exp (frag_now, p - frag_now->fr_literal, 8, &exp, 0, BFD_RELOC_64);
4678 }
4679 
4680 /* Parse .linkage <symbol>.
4681    Create a linkage pair relocation.  */
4682 
4683 static void
s_alpha_linkage(int ignore ATTRIBUTE_UNUSED)4684 s_alpha_linkage (int ignore ATTRIBUTE_UNUSED)
4685 {
4686   expressionS exp;
4687   char *p;
4688   fixS *fixp;
4689 
4690 #ifdef md_flush_pending_output
4691   md_flush_pending_output ();
4692 #endif
4693 
4694   expression (&exp);
4695   if (exp.X_op != O_symbol)
4696     {
4697       as_fatal (_("No symbol after .linkage"));
4698     }
4699   else
4700     {
4701       struct alpha_linkage_fixups *linkage_fixup;
4702 
4703       p = frag_more (LKP_S_K_SIZE);
4704       memset (p, 0, LKP_S_K_SIZE);
4705       fixp = fix_new_exp
4706 	(frag_now, p - frag_now->fr_literal, LKP_S_K_SIZE, &exp, 0,
4707 	 BFD_RELOC_ALPHA_LINKAGE);
4708 
4709       if (alpha_insn_label == NULL)
4710 	alpha_insn_label = symbol_new
4711 	  (FAKE_LABEL_NAME, now_seg, (valueT) frag_now_fix (), frag_now);
4712 
4713       /* Create a linkage element.  */
4714       linkage_fixup = XNEW (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 *name;
4803   char c;
4804 
4805   c = get_symbol_name (&name);
4806   (void) restore_line_pointer (c);
4807   demand_empty_rest_of_line ();
4808   alpha_evax_proc = NULL;
4809 }
4810 
4811 static void
s_alpha_file(int ignore ATTRIBUTE_UNUSED)4812 s_alpha_file (int ignore ATTRIBUTE_UNUSED)
4813 {
4814   symbolS *s;
4815   int length;
4816   static char case_hack[32];
4817 
4818   sprintf (case_hack, "<CASE:%01d%01d>",
4819 	   alpha_flag_hash_long_names, alpha_flag_show_after_trunc);
4820 
4821   s = symbol_find_or_make (case_hack);
4822   symbol_get_bfdsym (s)->flags |= BSF_FILE;
4823 
4824   get_absolute_expression ();
4825   s = symbol_find_or_make (demand_copy_string (&length));
4826   symbol_get_bfdsym (s)->flags |= BSF_FILE;
4827   demand_empty_rest_of_line ();
4828 }
4829 #endif /* OBJ_EVAX  */
4830 
4831 /* Handle the .gprel32 pseudo op.  */
4832 
4833 static void
s_alpha_gprel32(int ignore ATTRIBUTE_UNUSED)4834 s_alpha_gprel32 (int ignore ATTRIBUTE_UNUSED)
4835 {
4836   expressionS e;
4837   char *p;
4838 
4839   SKIP_WHITESPACE ();
4840   expression (&e);
4841 
4842 #ifdef OBJ_ELF
4843   switch (e.X_op)
4844     {
4845     case O_constant:
4846       e.X_add_symbol = section_symbol (absolute_section);
4847       e.X_op = O_symbol;
4848       /* FALLTHRU */
4849     case O_symbol:
4850       break;
4851     default:
4852       abort ();
4853     }
4854 #else
4855 #ifdef OBJ_ECOFF
4856   switch (e.X_op)
4857     {
4858     case O_constant:
4859       e.X_add_symbol = section_symbol (absolute_section);
4860       /* fall through */
4861     case O_symbol:
4862       e.X_op = O_subtract;
4863       e.X_op_symbol = alpha_gp_symbol;
4864       break;
4865     default:
4866       abort ();
4867     }
4868 #endif
4869 #endif
4870 
4871   if (alpha_auto_align_on && alpha_current_align < 2)
4872     alpha_align (2, (char *) NULL, alpha_insn_label, 0);
4873   if (alpha_current_align > 2)
4874     alpha_current_align = 2;
4875   alpha_insn_label = NULL;
4876 
4877   p = frag_more (4);
4878   memset (p, 0, 4);
4879   fix_new_exp (frag_now, p - frag_now->fr_literal, 4,
4880 	       &e, 0, BFD_RELOC_GPREL32);
4881 }
4882 
4883 /* Handle floating point allocation pseudo-ops.  This is like the
4884    generic vresion, but it makes sure the current label, if any, is
4885    correctly aligned.  */
4886 
4887 static void
s_alpha_float_cons(int type)4888 s_alpha_float_cons (int type)
4889 {
4890   int log_size;
4891 
4892   switch (type)
4893     {
4894     default:
4895     case 'f':
4896     case 'F':
4897       log_size = 2;
4898       break;
4899 
4900     case 'd':
4901     case 'D':
4902     case 'G':
4903       log_size = 3;
4904       break;
4905 
4906     case 'x':
4907     case 'X':
4908     case 'p':
4909     case 'P':
4910       log_size = 4;
4911       break;
4912     }
4913 
4914   if (alpha_auto_align_on && alpha_current_align < log_size)
4915     alpha_align (log_size, (char *) NULL, alpha_insn_label, 0);
4916   if (alpha_current_align > log_size)
4917     alpha_current_align = log_size;
4918   alpha_insn_label = NULL;
4919 
4920   float_cons (type);
4921 }
4922 
4923 /* Handle the .proc pseudo op.  We don't really do much with it except
4924    parse it.  */
4925 
4926 static void
s_alpha_proc(int is_static ATTRIBUTE_UNUSED)4927 s_alpha_proc (int is_static ATTRIBUTE_UNUSED)
4928 {
4929   char *name;
4930   char c;
4931   char *p;
4932   symbolS *symbolP;
4933   int temp;
4934 
4935   /* Takes ".proc name,nargs".  */
4936   SKIP_WHITESPACE ();
4937   c = get_symbol_name (&name);
4938   p = input_line_pointer;
4939   symbolP = symbol_find_or_make (name);
4940   *p = c;
4941   SKIP_WHITESPACE_AFTER_NAME ();
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 
4972   ch = get_symbol_name (&name);
4973   s = name;
4974   if (s[0] == 'n' && s[1] == 'o')
4975     {
4976       yesno = 0;
4977       s += 2;
4978     }
4979   if (!strcmp ("reorder", s))
4980     /* ignore */ ;
4981   else if (!strcmp ("at", s))
4982     alpha_noat_on = !yesno;
4983   else if (!strcmp ("macro", s))
4984     alpha_macros_on = yesno;
4985   else if (!strcmp ("move", s))
4986     /* ignore */ ;
4987   else if (!strcmp ("volatile", s))
4988     /* ignore */ ;
4989   else
4990     as_warn (_("Tried to .set unrecognized mode `%s'"), name);
4991 
4992   (void) restore_line_pointer (ch);
4993   demand_empty_rest_of_line ();
4994 }
4995 
4996 /* Handle the .base pseudo op.  This changes the assembler's notion of
4997    the $gp register.  */
4998 
4999 static void
s_alpha_base(int ignore ATTRIBUTE_UNUSED)5000 s_alpha_base (int ignore ATTRIBUTE_UNUSED)
5001 {
5002   SKIP_WHITESPACE ();
5003 
5004   if (*input_line_pointer == '$')
5005     {
5006       /* $rNN form.  */
5007       input_line_pointer++;
5008       if (*input_line_pointer == 'r')
5009 	input_line_pointer++;
5010     }
5011 
5012   alpha_gp_register = get_absolute_expression ();
5013   if (alpha_gp_register < 0 || alpha_gp_register > 31)
5014     {
5015       alpha_gp_register = AXP_REG_GP;
5016       as_warn (_("Bad base register, using $%d."), alpha_gp_register);
5017     }
5018 
5019   demand_empty_rest_of_line ();
5020 }
5021 
5022 /* Handle the .align pseudo-op.  This aligns to a power of two.  It
5023    also adjusts any current instruction label.  We treat this the same
5024    way the MIPS port does: .align 0 turns off auto alignment.  */
5025 
5026 static void
s_alpha_align(int ignore ATTRIBUTE_UNUSED)5027 s_alpha_align (int ignore ATTRIBUTE_UNUSED)
5028 {
5029   int align;
5030   char fill, *pfill;
5031   long max_alignment = 16;
5032 
5033   align = get_absolute_expression ();
5034   if (align > max_alignment)
5035     {
5036       align = max_alignment;
5037       as_bad (_("Alignment too large: %d. assumed"), align);
5038     }
5039   else if (align < 0)
5040     {
5041       as_warn (_("Alignment negative: 0 assumed"));
5042       align = 0;
5043     }
5044 
5045   if (*input_line_pointer == ',')
5046     {
5047       input_line_pointer++;
5048       fill = get_absolute_expression ();
5049       pfill = &fill;
5050     }
5051   else
5052     pfill = NULL;
5053 
5054   if (align != 0)
5055     {
5056       alpha_auto_align_on = 1;
5057       alpha_align (align, pfill, NULL, 1);
5058     }
5059   else
5060     {
5061       alpha_auto_align_on = 0;
5062     }
5063   alpha_insn_label = NULL;
5064 
5065   demand_empty_rest_of_line ();
5066 }
5067 
5068 /* Hook the normal string processor to reset known alignment.  */
5069 
5070 static void
s_alpha_stringer(int terminate)5071 s_alpha_stringer (int terminate)
5072 {
5073   alpha_current_align = 0;
5074   alpha_insn_label = NULL;
5075   stringer (8 + terminate);
5076 }
5077 
5078 /* Hook the normal space processing to reset known alignment.  */
5079 
5080 static void
s_alpha_space(int ignore)5081 s_alpha_space (int ignore)
5082 {
5083   alpha_current_align = 0;
5084   alpha_insn_label = NULL;
5085   s_space (ignore);
5086 }
5087 
5088 /* Hook into cons for auto-alignment.  */
5089 
5090 void
alpha_cons_align(int size)5091 alpha_cons_align (int size)
5092 {
5093   int log_size;
5094 
5095   log_size = 0;
5096   while ((size >>= 1) != 0)
5097     ++log_size;
5098 
5099   if (alpha_auto_align_on && alpha_current_align < log_size)
5100     alpha_align (log_size, (char *) NULL, alpha_insn_label, 0);
5101   if (alpha_current_align > log_size)
5102     alpha_current_align = log_size;
5103   alpha_insn_label = NULL;
5104 }
5105 
5106 /* Here come the .uword, .ulong, and .uquad explicitly unaligned
5107    pseudos.  We just turn off auto-alignment and call down to cons.  */
5108 
5109 static void
s_alpha_ucons(int bytes)5110 s_alpha_ucons (int bytes)
5111 {
5112   int hold = alpha_auto_align_on;
5113   alpha_auto_align_on = 0;
5114   cons (bytes);
5115   alpha_auto_align_on = hold;
5116 }
5117 
5118 /* Switch the working cpu type.  */
5119 
5120 static void
s_alpha_arch(int ignored ATTRIBUTE_UNUSED)5121 s_alpha_arch (int ignored ATTRIBUTE_UNUSED)
5122 {
5123   char *name, ch;
5124   const struct cpu_type *p;
5125 
5126   SKIP_WHITESPACE ();
5127 
5128   ch = get_symbol_name (&name);
5129 
5130   for (p = cpu_types; p->name; ++p)
5131     if (strcmp (name, p->name) == 0)
5132       {
5133 	alpha_target_name = p->name, alpha_target = p->flags;
5134 	goto found;
5135       }
5136   as_warn (_("Unknown CPU identifier `%s'"), name);
5137 
5138 found:
5139   (void) restore_line_pointer (ch);
5140   demand_empty_rest_of_line ();
5141 }
5142 
5143 #ifdef DEBUG1
5144 /* print token expression with alpha specific extension.  */
5145 
5146 static void
alpha_print_token(FILE * f,const expressionS * exp)5147 alpha_print_token (FILE *f, const expressionS *exp)
5148 {
5149   switch (exp->X_op)
5150     {
5151     case O_cpregister:
5152       putc (',', f);
5153       /* FALLTHRU */
5154     case O_pregister:
5155       putc ('(', f);
5156       {
5157 	expressionS nexp = *exp;
5158 	nexp.X_op = O_register;
5159 	print_expr_1 (f, &nexp);
5160       }
5161       putc (')', f);
5162       break;
5163     default:
5164       print_expr_1 (f, exp);
5165       break;
5166     }
5167 }
5168 #endif
5169 
5170 /* The target specific pseudo-ops which we support.  */
5171 
5172 const pseudo_typeS md_pseudo_table[] =
5173 {
5174 #ifdef OBJ_ECOFF
5175   {"comm", s_alpha_comm, 0},	/* OSF1 compiler does this.  */
5176   {"rdata", s_alpha_rdata, 0},
5177 #endif
5178   {"text", s_alpha_text, 0},
5179   {"data", s_alpha_data, 0},
5180 #ifdef OBJ_ECOFF
5181   {"sdata", s_alpha_sdata, 0},
5182 #endif
5183 #ifdef OBJ_ELF
5184   {"section", s_alpha_section, 0},
5185   {"section.s", s_alpha_section, 0},
5186   {"sect", s_alpha_section, 0},
5187   {"sect.s", s_alpha_section, 0},
5188 #endif
5189 #ifdef OBJ_EVAX
5190   {"section", s_alpha_section, 0},
5191   {"literals", s_alpha_literals, 0},
5192   {"pdesc", s_alpha_pdesc, 0},
5193   {"name", s_alpha_name, 0},
5194   {"linkage", s_alpha_linkage, 0},
5195   {"code_address", s_alpha_code_address, 0},
5196   {"ent", s_alpha_ent, 0},
5197   {"frame", s_alpha_frame, 0},
5198   {"fp_save", s_alpha_fp_save, 0},
5199   {"mask", s_alpha_mask, 0},
5200   {"fmask", s_alpha_fmask, 0},
5201   {"end", s_alpha_end, 0},
5202   {"file", s_alpha_file, 0},
5203   {"rdata", s_alpha_section, 1},
5204   {"comm", s_alpha_comm, 0},
5205   {"link", s_alpha_section, 3},
5206   {"ctors", s_alpha_section, 4},
5207   {"dtors", s_alpha_section, 5},
5208   {"handler", s_alpha_handler, 0},
5209   {"handler_data", s_alpha_handler, 1},
5210 #endif
5211 #ifdef OBJ_ELF
5212   /* Frame related pseudos.  */
5213   {"ent", s_alpha_ent, 0},
5214   {"end", s_alpha_end, 0},
5215   {"mask", s_alpha_mask, 0},
5216   {"fmask", s_alpha_mask, 1},
5217   {"frame", s_alpha_frame, 0},
5218   {"prologue", s_alpha_prologue, 0},
5219   {"file", s_alpha_file, 5},
5220   {"loc", s_alpha_loc, 9},
5221   {"stabs", s_alpha_stab, 's'},
5222   {"stabn", s_alpha_stab, 'n'},
5223   {"usepv", s_alpha_usepv, 0},
5224   /* COFF debugging related pseudos.  */
5225   {"begin", s_alpha_coff_wrapper, 0},
5226   {"bend", s_alpha_coff_wrapper, 1},
5227   {"def", s_alpha_coff_wrapper, 2},
5228   {"dim", s_alpha_coff_wrapper, 3},
5229   {"endef", s_alpha_coff_wrapper, 4},
5230   {"scl", s_alpha_coff_wrapper, 5},
5231   {"tag", s_alpha_coff_wrapper, 6},
5232   {"val", s_alpha_coff_wrapper, 7},
5233 #else
5234 #ifdef OBJ_EVAX
5235   {"prologue", s_alpha_prologue, 0},
5236 #else
5237   {"prologue", s_ignore, 0},
5238 #endif
5239 #endif
5240   {"gprel32", s_alpha_gprel32, 0},
5241   {"t_floating", s_alpha_float_cons, 'd'},
5242   {"s_floating", s_alpha_float_cons, 'f'},
5243   {"f_floating", s_alpha_float_cons, 'F'},
5244   {"g_floating", s_alpha_float_cons, 'G'},
5245   {"d_floating", s_alpha_float_cons, 'D'},
5246 
5247   {"proc", s_alpha_proc, 0},
5248   {"aproc", s_alpha_proc, 1},
5249   {"set", s_alpha_set, 0},
5250   {"reguse", s_ignore, 0},
5251   {"livereg", s_ignore, 0},
5252   {"base", s_alpha_base, 0},		/*??*/
5253   {"option", s_ignore, 0},
5254   {"aent", s_ignore, 0},
5255   {"ugen", s_ignore, 0},
5256   {"eflag", s_ignore, 0},
5257 
5258   {"align", s_alpha_align, 0},
5259   {"double", s_alpha_float_cons, 'd'},
5260   {"float", s_alpha_float_cons, 'f'},
5261   {"single", s_alpha_float_cons, 'f'},
5262   {"ascii", s_alpha_stringer, 0},
5263   {"asciz", s_alpha_stringer, 1},
5264   {"string", s_alpha_stringer, 1},
5265   {"space", s_alpha_space, 0},
5266   {"skip", s_alpha_space, 0},
5267   {"zero", s_alpha_space, 0},
5268 
5269 /* Unaligned data pseudos.  */
5270   {"uword", s_alpha_ucons, 2},
5271   {"ulong", s_alpha_ucons, 4},
5272   {"uquad", s_alpha_ucons, 8},
5273 
5274 #ifdef OBJ_ELF
5275 /* Dwarf wants these versions of unaligned.  */
5276   {"2byte", s_alpha_ucons, 2},
5277   {"4byte", s_alpha_ucons, 4},
5278   {"8byte", s_alpha_ucons, 8},
5279 #endif
5280 
5281 /* We don't do any optimizing, so we can safely ignore these.  */
5282   {"noalias", s_ignore, 0},
5283   {"alias", s_ignore, 0},
5284 
5285   {"arch", s_alpha_arch, 0},
5286 
5287   {NULL, 0, 0},
5288 };
5289 
5290 #ifdef OBJ_ECOFF
5291 
5292 /* @@@ GP selection voodoo.  All of this seems overly complicated and
5293    unnecessary; which is the primary reason it's for ECOFF only.  */
5294 
5295 static inline void
maybe_set_gp(asection * sec)5296 maybe_set_gp (asection *sec)
5297 {
5298   bfd_vma vma;
5299 
5300   if (!sec)
5301     return;
5302   vma = bfd_get_section_vma (sec->owner, sec);
5303   if (vma && vma < alpha_gp_value)
5304     alpha_gp_value = vma;
5305 }
5306 
5307 static void
select_gp_value(void)5308 select_gp_value (void)
5309 {
5310   gas_assert (alpha_gp_value == 0);
5311 
5312   /* Get minus-one in whatever width...  */
5313   alpha_gp_value = 0;
5314   alpha_gp_value--;
5315 
5316   /* Select the smallest VMA of these existing sections.  */
5317   maybe_set_gp (alpha_lita_section);
5318 
5319 /* @@ Will a simple 0x8000 work here?  If not, why not?  */
5320 #define GP_ADJUSTMENT	(0x8000 - 0x10)
5321 
5322   alpha_gp_value += GP_ADJUSTMENT;
5323 
5324   S_SET_VALUE (alpha_gp_symbol, alpha_gp_value);
5325 
5326 #ifdef DEBUG1
5327   printf (_("Chose GP value of %lx\n"), alpha_gp_value);
5328 #endif
5329 }
5330 #endif /* OBJ_ECOFF */
5331 
5332 #ifdef OBJ_ELF
5333 /* Map 's' to SHF_ALPHA_GPREL.  */
5334 
5335 bfd_vma
alpha_elf_section_letter(int letter,const char ** ptr_msg)5336 alpha_elf_section_letter (int letter, const char **ptr_msg)
5337 {
5338   if (letter == 's')
5339     return SHF_ALPHA_GPREL;
5340 
5341   *ptr_msg = _("bad .section directive: want a,s,w,x,M,S,G,T in string");
5342   return -1;
5343 }
5344 
5345 /* Map SHF_ALPHA_GPREL to SEC_SMALL_DATA.  */
5346 
5347 flagword
alpha_elf_section_flags(flagword flags,bfd_vma attr,int type ATTRIBUTE_UNUSED)5348 alpha_elf_section_flags (flagword flags, bfd_vma attr, int type ATTRIBUTE_UNUSED)
5349 {
5350   if (attr & SHF_ALPHA_GPREL)
5351     flags |= SEC_SMALL_DATA;
5352   return flags;
5353 }
5354 #endif /* OBJ_ELF */
5355 
5356 /* This is called from HANDLE_ALIGN in write.c.  Fill in the contents
5357    of an rs_align_code fragment.  */
5358 
5359 void
alpha_handle_align(fragS * fragp)5360 alpha_handle_align (fragS *fragp)
5361 {
5362   static unsigned char const unop[4] = { 0x00, 0x00, 0xfe, 0x2f };
5363   static unsigned char const nopunop[8] =
5364   {
5365     0x1f, 0x04, 0xff, 0x47,
5366     0x00, 0x00, 0xfe, 0x2f
5367   };
5368 
5369   int bytes, fix;
5370   char *p;
5371 
5372   if (fragp->fr_type != rs_align_code)
5373     return;
5374 
5375   bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix;
5376   p = fragp->fr_literal + fragp->fr_fix;
5377   fix = 0;
5378 
5379   if (bytes & 3)
5380     {
5381       fix = bytes & 3;
5382       memset (p, 0, fix);
5383       p += fix;
5384       bytes -= fix;
5385     }
5386 
5387   if (bytes & 4)
5388     {
5389       memcpy (p, unop, 4);
5390       p += 4;
5391       bytes -= 4;
5392       fix += 4;
5393     }
5394 
5395   memcpy (p, nopunop, 8);
5396 
5397   fragp->fr_fix += fix;
5398   fragp->fr_var = 8;
5399 }
5400 
5401 /* Public interface functions.  */
5402 
5403 /* This function is called once, at assembler startup time.  It sets
5404    up all the tables, etc. that the MD part of the assembler will
5405    need, that can be determined before arguments are parsed.  */
5406 
5407 void
md_begin(void)5408 md_begin (void)
5409 {
5410   unsigned int i;
5411 
5412   /* Verify that X_op field is wide enough.  */
5413   {
5414     expressionS e;
5415 
5416     e.X_op = O_max;
5417     gas_assert (e.X_op == O_max);
5418   }
5419 
5420   /* Create the opcode hash table.  */
5421   alpha_opcode_hash = hash_new ();
5422 
5423   for (i = 0; i < alpha_num_opcodes;)
5424     {
5425       const char *name, *retval, *slash;
5426 
5427       name = alpha_opcodes[i].name;
5428       retval = hash_insert (alpha_opcode_hash, name, (void *) &alpha_opcodes[i]);
5429       if (retval)
5430 	as_fatal (_("internal error: can't hash opcode `%s': %s"),
5431 		  name, retval);
5432 
5433       /* Some opcodes include modifiers of various sorts with a "/mod"
5434 	 syntax, like the architecture manual suggests.  However, for
5435 	 use with gcc at least, we also need access to those same opcodes
5436 	 without the "/".  */
5437 
5438       if ((slash = strchr (name, '/')) != NULL)
5439 	{
5440 	  char *p = XNEWVEC (char, strlen (name));
5441 
5442 	  memcpy (p, name, slash - name);
5443 	  strcpy (p + (slash - name), slash + 1);
5444 
5445 	  (void) hash_insert (alpha_opcode_hash, p, (void *) &alpha_opcodes[i]);
5446 	  /* Ignore failures -- the opcode table does duplicate some
5447 	     variants in different forms, like "hw_stq" and "hw_st/q".  */
5448 	}
5449 
5450       while (++i < alpha_num_opcodes
5451 	     && (alpha_opcodes[i].name == name
5452 		 || !strcmp (alpha_opcodes[i].name, name)))
5453 	continue;
5454     }
5455 
5456   /* Create the macro hash table.  */
5457   alpha_macro_hash = hash_new ();
5458 
5459   for (i = 0; i < alpha_num_macros;)
5460     {
5461       const char *name, *retval;
5462 
5463       name = alpha_macros[i].name;
5464       retval = hash_insert (alpha_macro_hash, name, (void *) &alpha_macros[i]);
5465       if (retval)
5466 	as_fatal (_("internal error: can't hash macro `%s': %s"),
5467 		  name, retval);
5468 
5469       while (++i < alpha_num_macros
5470 	     && (alpha_macros[i].name == name
5471 		 || !strcmp (alpha_macros[i].name, name)))
5472 	continue;
5473     }
5474 
5475   /* Construct symbols for each of the registers.  */
5476   for (i = 0; i < 32; ++i)
5477     {
5478       char name[4];
5479 
5480       sprintf (name, "$%d", i);
5481       alpha_register_table[i] = symbol_create (name, reg_section, i,
5482 					       &zero_address_frag);
5483     }
5484 
5485   for (; i < 64; ++i)
5486     {
5487       char name[5];
5488 
5489       sprintf (name, "$f%d", i - 32);
5490       alpha_register_table[i] = symbol_create (name, reg_section, i,
5491 					       &zero_address_frag);
5492     }
5493 
5494   /* Create the special symbols and sections we'll be using.  */
5495 
5496   /* So .sbss will get used for tiny objects.  */
5497   bfd_set_gp_size (stdoutput, g_switch_value);
5498 
5499 #ifdef OBJ_ECOFF
5500   create_literal_section (".lita", &alpha_lita_section, &alpha_lita_symbol);
5501 
5502   /* For handling the GP, create a symbol that won't be output in the
5503      symbol table.  We'll edit it out of relocs later.  */
5504   alpha_gp_symbol = symbol_create ("<GP value>", alpha_lita_section, 0x8000,
5505 				   &zero_address_frag);
5506 #endif
5507 
5508 #ifdef OBJ_EVAX
5509   create_literal_section (".link", &alpha_link_section, &alpha_link_symbol);
5510 #endif
5511 
5512 #ifdef OBJ_ELF
5513   if (ECOFF_DEBUGGING)
5514     {
5515       segT sec = subseg_new (".mdebug", (subsegT) 0);
5516       bfd_set_section_flags (stdoutput, sec, SEC_HAS_CONTENTS | SEC_READONLY);
5517       bfd_set_section_alignment (stdoutput, sec, 3);
5518     }
5519 #endif
5520 
5521   /* Create literal lookup hash table.  */
5522   alpha_literal_hash = hash_new ();
5523 
5524   subseg_set (text_section, 0);
5525 }
5526 
5527 /* The public interface to the instruction assembler.  */
5528 
5529 void
md_assemble(char * str)5530 md_assemble (char *str)
5531 {
5532   /* Current maximum is 13.  */
5533   char opname[32];
5534   expressionS tok[MAX_INSN_ARGS];
5535   int ntok, trunclen;
5536   size_t opnamelen;
5537 
5538   /* Split off the opcode.  */
5539   opnamelen = strspn (str, "abcdefghijklmnopqrstuvwxyz_/46819");
5540   trunclen = (opnamelen < sizeof (opname) - 1
5541 	      ? opnamelen
5542 	      : sizeof (opname) - 1);
5543   memcpy (opname, str, trunclen);
5544   opname[trunclen] = '\0';
5545 
5546   /* Tokenize the rest of the line.  */
5547   if ((ntok = tokenize_arguments (str + opnamelen, tok, MAX_INSN_ARGS)) < 0)
5548     {
5549       if (ntok != TOKENIZE_ERROR_REPORT)
5550 	as_bad (_("syntax error"));
5551 
5552       return;
5553     }
5554 
5555   /* Finish it off.  */
5556   assemble_tokens (opname, tok, ntok, alpha_macros_on);
5557 }
5558 
5559 /* Round up a section's size to the appropriate boundary.  */
5560 
5561 valueT
md_section_align(segT seg,valueT size)5562 md_section_align (segT seg, valueT size)
5563 {
5564   int align = bfd_get_section_alignment (stdoutput, seg);
5565   valueT mask = ((valueT) 1 << align) - 1;
5566 
5567   return (size + mask) & ~mask;
5568 }
5569 
5570 /* Turn a string in input_line_pointer into a floating point constant
5571    of type TYPE, and store the appropriate bytes in *LITP.  The number
5572    of LITTLENUMS emitted is stored in *SIZEP.  An error message is
5573    returned, or NULL on OK.  */
5574 
5575 const char *
md_atof(int type,char * litP,int * sizeP)5576 md_atof (int type, char *litP, int *sizeP)
5577 {
5578   extern const char *vax_md_atof (int, char *, int *);
5579 
5580   switch (type)
5581     {
5582       /* VAX floats.  */
5583     case 'G':
5584       /* vax_md_atof() doesn't like "G" for some reason.  */
5585       type = 'g';
5586     case 'F':
5587     case 'D':
5588       return vax_md_atof (type, litP, sizeP);
5589 
5590     default:
5591       return ieee_md_atof (type, litP, sizeP, FALSE);
5592     }
5593 }
5594 
5595 /* Take care of the target-specific command-line options.  */
5596 
5597 int
md_parse_option(int c,const char * arg)5598 md_parse_option (int c, const char *arg)
5599 {
5600   switch (c)
5601     {
5602     case 'F':
5603       alpha_nofloats_on = 1;
5604       break;
5605 
5606     case OPTION_32ADDR:
5607       alpha_addr32_on = 1;
5608       break;
5609 
5610     case 'g':
5611       alpha_debug = 1;
5612       break;
5613 
5614     case 'G':
5615       g_switch_value = atoi (arg);
5616       break;
5617 
5618     case 'm':
5619       {
5620 	const struct cpu_type *p;
5621 
5622 	for (p = cpu_types; p->name; ++p)
5623 	  if (strcmp (arg, p->name) == 0)
5624 	    {
5625 	      alpha_target_name = p->name, alpha_target = p->flags;
5626 	      goto found;
5627 	    }
5628 	as_warn (_("Unknown CPU identifier `%s'"), arg);
5629       found:;
5630       }
5631       break;
5632 
5633 #ifdef OBJ_EVAX
5634     case '+':			/* For g++.  Hash any name > 63 chars long.  */
5635       alpha_flag_hash_long_names = 1;
5636       break;
5637 
5638     case 'H':			/* Show new symbol after hash truncation.  */
5639       alpha_flag_show_after_trunc = 1;
5640       break;
5641 
5642     case 'h':			/* For gnu-c/vax compatibility.  */
5643       break;
5644 
5645     case OPTION_REPLACE:
5646       alpha_flag_replace = 1;
5647       break;
5648 
5649     case OPTION_NOREPLACE:
5650       alpha_flag_replace = 0;
5651       break;
5652 #endif
5653 
5654     case OPTION_RELAX:
5655       alpha_flag_relax = 1;
5656       break;
5657 
5658 #ifdef OBJ_ELF
5659     case OPTION_MDEBUG:
5660       alpha_flag_mdebug = 1;
5661       break;
5662     case OPTION_NO_MDEBUG:
5663       alpha_flag_mdebug = 0;
5664       break;
5665 #endif
5666 
5667     default:
5668       return 0;
5669     }
5670 
5671   return 1;
5672 }
5673 
5674 /* Print a description of the command-line options that we accept.  */
5675 
5676 void
md_show_usage(FILE * stream)5677 md_show_usage (FILE *stream)
5678 {
5679   fputs (_("\
5680 Alpha options:\n\
5681 -32addr			treat addresses as 32-bit values\n\
5682 -F			lack floating point instructions support\n\
5683 -mev4 | -mev45 | -mev5 | -mev56 | -mpca56 | -mev6 | -mev67 | -mev68 | -mall\n\
5684 			specify variant of Alpha architecture\n\
5685 -m21064 | -m21066 | -m21164 | -m21164a | -m21164pc | -m21264 | -m21264a | -m21264b\n\
5686 			these variants include PALcode opcodes\n"),
5687 	stream);
5688 #ifdef OBJ_EVAX
5689   fputs (_("\
5690 VMS options:\n\
5691 -+			encode (don't truncate) names longer than 64 characters\n\
5692 -H			show new symbol after hash truncation\n\
5693 -replace/-noreplace	enable or disable the optimization of procedure calls\n"),
5694 	stream);
5695 #endif
5696 }
5697 
5698 /* Decide from what point a pc-relative relocation is relative to,
5699    relative to the pc-relative fixup.  Er, relatively speaking.  */
5700 
5701 long
md_pcrel_from(fixS * fixP)5702 md_pcrel_from (fixS *fixP)
5703 {
5704   valueT addr = fixP->fx_where + fixP->fx_frag->fr_address;
5705 
5706   switch (fixP->fx_r_type)
5707     {
5708     case BFD_RELOC_23_PCREL_S2:
5709     case BFD_RELOC_ALPHA_HINT:
5710     case BFD_RELOC_ALPHA_BRSGP:
5711       return addr + 4;
5712     default:
5713       return addr;
5714     }
5715 }
5716 
5717 /* Attempt to simplify or even eliminate a fixup.  The return value is
5718    ignored; perhaps it was once meaningful, but now it is historical.
5719    To indicate that a fixup has been eliminated, set fixP->fx_done.
5720 
5721    For ELF, here it is that we transform the GPDISP_HI16 reloc we used
5722    internally into the GPDISP reloc used externally.  We had to do
5723    this so that we'd have the GPDISP_LO16 reloc as a tag to compute
5724    the distance to the "lda" instruction for setting the addend to
5725    GPDISP.  */
5726 
5727 void
md_apply_fix(fixS * fixP,valueT * valP,segT seg)5728 md_apply_fix (fixS *fixP, valueT * valP, segT seg)
5729 {
5730   char * const fixpos = fixP->fx_frag->fr_literal + fixP->fx_where;
5731   valueT value = * valP;
5732   unsigned image, size;
5733 
5734   switch (fixP->fx_r_type)
5735     {
5736       /* The GPDISP relocations are processed internally with a symbol
5737 	 referring to the current function's section;  we need to drop
5738 	 in a value which, when added to the address of the start of
5739 	 the function, gives the desired GP.  */
5740     case BFD_RELOC_ALPHA_GPDISP_HI16:
5741       {
5742 	fixS *next = fixP->fx_next;
5743 
5744 	/* With user-specified !gpdisp relocations, we can be missing
5745 	   the matching LO16 reloc.  We will have already issued an
5746 	   error message.  */
5747 	if (next)
5748 	  fixP->fx_offset = (next->fx_frag->fr_address + next->fx_where
5749 			     - fixP->fx_frag->fr_address - fixP->fx_where);
5750 
5751 	value = (value - sign_extend_16 (value)) >> 16;
5752       }
5753 #ifdef OBJ_ELF
5754       fixP->fx_r_type = BFD_RELOC_ALPHA_GPDISP;
5755 #endif
5756       goto do_reloc_gp;
5757 
5758     case BFD_RELOC_ALPHA_GPDISP_LO16:
5759       value = sign_extend_16 (value);
5760       fixP->fx_offset = 0;
5761 #ifdef OBJ_ELF
5762       fixP->fx_done = 1;
5763 #endif
5764 
5765     do_reloc_gp:
5766       fixP->fx_addsy = section_symbol (seg);
5767       md_number_to_chars (fixpos, value, 2);
5768       break;
5769 
5770     case BFD_RELOC_16:
5771       if (fixP->fx_pcrel)
5772 	fixP->fx_r_type = BFD_RELOC_16_PCREL;
5773       size = 2;
5774       goto do_reloc_xx;
5775 
5776     case BFD_RELOC_32:
5777       if (fixP->fx_pcrel)
5778 	fixP->fx_r_type = BFD_RELOC_32_PCREL;
5779       size = 4;
5780       goto do_reloc_xx;
5781 
5782     case BFD_RELOC_64:
5783       if (fixP->fx_pcrel)
5784 	fixP->fx_r_type = BFD_RELOC_64_PCREL;
5785       size = 8;
5786 
5787     do_reloc_xx:
5788       if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0)
5789 	{
5790 	  md_number_to_chars (fixpos, value, size);
5791 	  goto done;
5792 	}
5793       return;
5794 
5795 #ifdef OBJ_ECOFF
5796     case BFD_RELOC_GPREL32:
5797       gas_assert (fixP->fx_subsy == alpha_gp_symbol);
5798       fixP->fx_subsy = 0;
5799       /* FIXME: inherited this obliviousness of `value' -- why?  */
5800       md_number_to_chars (fixpos, -alpha_gp_value, 4);
5801       break;
5802 #else
5803     case BFD_RELOC_GPREL32:
5804 #endif
5805     case BFD_RELOC_GPREL16:
5806     case BFD_RELOC_ALPHA_GPREL_HI16:
5807     case BFD_RELOC_ALPHA_GPREL_LO16:
5808       return;
5809 
5810     case BFD_RELOC_23_PCREL_S2:
5811       if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0)
5812 	{
5813 	  image = bfd_getl32 (fixpos);
5814 	  image = (image & ~0x1FFFFF) | ((value >> 2) & 0x1FFFFF);
5815 	  goto write_done;
5816 	}
5817       return;
5818 
5819     case BFD_RELOC_ALPHA_HINT:
5820       if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0)
5821 	{
5822 	  image = bfd_getl32 (fixpos);
5823 	  image = (image & ~0x3FFF) | ((value >> 2) & 0x3FFF);
5824 	  goto write_done;
5825 	}
5826       return;
5827 
5828 #ifdef OBJ_ELF
5829     case BFD_RELOC_ALPHA_BRSGP:
5830       return;
5831 
5832     case BFD_RELOC_ALPHA_TLSGD:
5833     case BFD_RELOC_ALPHA_TLSLDM:
5834     case BFD_RELOC_ALPHA_GOTDTPREL16:
5835     case BFD_RELOC_ALPHA_DTPREL_HI16:
5836     case BFD_RELOC_ALPHA_DTPREL_LO16:
5837     case BFD_RELOC_ALPHA_DTPREL16:
5838     case BFD_RELOC_ALPHA_GOTTPREL16:
5839     case BFD_RELOC_ALPHA_TPREL_HI16:
5840     case BFD_RELOC_ALPHA_TPREL_LO16:
5841     case BFD_RELOC_ALPHA_TPREL16:
5842       if (fixP->fx_addsy)
5843 	S_SET_THREAD_LOCAL (fixP->fx_addsy);
5844       return;
5845 #endif
5846 
5847 #ifdef OBJ_ECOFF
5848     case BFD_RELOC_ALPHA_LITERAL:
5849       md_number_to_chars (fixpos, value, 2);
5850       return;
5851 #endif
5852     case BFD_RELOC_ALPHA_ELF_LITERAL:
5853     case BFD_RELOC_ALPHA_LITUSE:
5854     case BFD_RELOC_ALPHA_LINKAGE:
5855     case BFD_RELOC_ALPHA_CODEADDR:
5856       return;
5857 
5858 #ifdef OBJ_EVAX
5859     case BFD_RELOC_ALPHA_NOP:
5860       value -= (8 + 4); /* PC-relative, base is jsr+4.  */
5861 
5862       /* From B.4.5.2 of the OpenVMS Linker Utility Manual:
5863 	 "Finally, the ETIR$C_STC_BSR command passes the same address
5864 	  as ETIR$C_STC_NOP (so that they will fail or succeed together),
5865 	  and the same test is done again."  */
5866       if (S_GET_SEGMENT (fixP->fx_addsy) == undefined_section)
5867 	{
5868 	  fixP->fx_addnumber = -value;
5869 	  return;
5870 	}
5871 
5872       if ((abs (value) >> 2) & ~0xfffff)
5873 	goto done;
5874       else
5875 	{
5876 	  /* Change to a nop.  */
5877 	  image = 0x47FF041F;
5878 	  goto write_done;
5879 	}
5880 
5881     case BFD_RELOC_ALPHA_LDA:
5882       /* fixup_segment sets fixP->fx_addsy to NULL when it can pre-compute
5883 	 the value for an O_subtract.  */
5884       if (fixP->fx_addsy
5885 	  && S_GET_SEGMENT (fixP->fx_addsy) == undefined_section)
5886 	{
5887 	  fixP->fx_addnumber = symbol_get_bfdsym (fixP->fx_subsy)->value;
5888 	  return;
5889 	}
5890 
5891       if ((abs (value)) & ~0x7fff)
5892 	goto done;
5893       else
5894 	{
5895 	  /* Change to an lda.  */
5896 	  image = 0x237B0000 | (value & 0xFFFF);
5897 	  goto write_done;
5898 	}
5899 
5900     case BFD_RELOC_ALPHA_BSR:
5901     case BFD_RELOC_ALPHA_BOH:
5902       value -= 4; /* PC-relative, base is jsr+4.  */
5903 
5904       /* See comment in the BFD_RELOC_ALPHA_NOP case above.  */
5905       if (S_GET_SEGMENT (fixP->fx_addsy) == undefined_section)
5906 	{
5907 	  fixP->fx_addnumber = -value;
5908 	  return;
5909 	}
5910 
5911       if ((abs (value) >> 2) & ~0xfffff)
5912 	{
5913 	  /* Out of range.  */
5914 	  if (fixP->fx_r_type == BFD_RELOC_ALPHA_BOH)
5915 	    {
5916 	      /* Add a hint.  */
5917 	      image = bfd_getl32(fixpos);
5918 	      image = (image & ~0x3FFF) | ((value >> 2) & 0x3FFF);
5919 	      goto write_done;
5920 	    }
5921 	  goto done;
5922 	}
5923       else
5924 	{
5925 	  /* Change to a branch.  */
5926 	  image = 0xD3400000 | ((value >> 2) & 0x1FFFFF);
5927 	  goto write_done;
5928 	}
5929 #endif
5930 
5931     case BFD_RELOC_VTABLE_INHERIT:
5932     case BFD_RELOC_VTABLE_ENTRY:
5933       return;
5934 
5935     default:
5936       {
5937 	const struct alpha_operand *operand;
5938 
5939 	if ((int) fixP->fx_r_type >= 0)
5940 	  as_fatal (_("unhandled relocation type %s"),
5941 		    bfd_get_reloc_code_name (fixP->fx_r_type));
5942 
5943 	gas_assert (-(int) fixP->fx_r_type < (int) alpha_num_operands);
5944 	operand = &alpha_operands[-(int) fixP->fx_r_type];
5945 
5946 	/* The rest of these fixups only exist internally during symbol
5947 	   resolution and have no representation in the object file.
5948 	   Therefore they must be completely resolved as constants.  */
5949 
5950 	if (fixP->fx_addsy != 0
5951 	    && S_GET_SEGMENT (fixP->fx_addsy) != absolute_section)
5952 	  as_bad_where (fixP->fx_file, fixP->fx_line,
5953 			_("non-absolute expression in constant field"));
5954 
5955 	image = bfd_getl32 (fixpos);
5956 	image = insert_operand (image, operand, (offsetT) value,
5957 				fixP->fx_file, fixP->fx_line);
5958       }
5959       goto write_done;
5960     }
5961 
5962   if (fixP->fx_addsy != 0 || fixP->fx_pcrel != 0)
5963     return;
5964   else
5965     {
5966       as_warn_where (fixP->fx_file, fixP->fx_line,
5967 		     _("type %d reloc done?\n"), (int) fixP->fx_r_type);
5968       goto done;
5969     }
5970 
5971 write_done:
5972   md_number_to_chars (fixpos, image, 4);
5973 
5974 done:
5975   fixP->fx_done = 1;
5976 }
5977 
5978 /* Look for a register name in the given symbol.  */
5979 
5980 symbolS *
md_undefined_symbol(char * name)5981 md_undefined_symbol (char *name)
5982 {
5983   if (*name == '$')
5984     {
5985       int is_float = 0, num;
5986 
5987       switch (*++name)
5988 	{
5989 	case 'f':
5990 	  if (name[1] == 'p' && name[2] == '\0')
5991 	    return alpha_register_table[AXP_REG_FP];
5992 	  is_float = 32;
5993 	  /* Fall through.  */
5994 
5995 	case 'r':
5996 	  if (!ISDIGIT (*++name))
5997 	    break;
5998 	  /* Fall through.  */
5999 
6000 	case '0': case '1': case '2': case '3': case '4':
6001 	case '5': case '6': case '7': case '8': case '9':
6002 	  if (name[1] == '\0')
6003 	    num = name[0] - '0';
6004 	  else if (name[0] != '0' && ISDIGIT (name[1]) && name[2] == '\0')
6005 	    {
6006 	      num = (name[0] - '0') * 10 + name[1] - '0';
6007 	      if (num >= 32)
6008 		break;
6009 	    }
6010 	  else
6011 	    break;
6012 
6013 	  if (!alpha_noat_on && (num + is_float) == AXP_REG_AT)
6014 	    as_warn (_("Used $at without \".set noat\""));
6015 	  return alpha_register_table[num + is_float];
6016 
6017 	case 'a':
6018 	  if (name[1] == 't' && name[2] == '\0')
6019 	    {
6020 	      if (!alpha_noat_on)
6021 		as_warn (_("Used $at without \".set noat\""));
6022 	      return alpha_register_table[AXP_REG_AT];
6023 	    }
6024 	  break;
6025 
6026 	case 'g':
6027 	  if (name[1] == 'p' && name[2] == '\0')
6028 	    return alpha_register_table[alpha_gp_register];
6029 	  break;
6030 
6031 	case 's':
6032 	  if (name[1] == 'p' && name[2] == '\0')
6033 	    return alpha_register_table[AXP_REG_SP];
6034 	  break;
6035 	}
6036     }
6037   return NULL;
6038 }
6039 
6040 #ifdef OBJ_ECOFF
6041 /* @@@ Magic ECOFF bits.  */
6042 
6043 void
alpha_frob_ecoff_data(void)6044 alpha_frob_ecoff_data (void)
6045 {
6046   select_gp_value ();
6047   /* $zero and $f31 are read-only.  */
6048   alpha_gprmask &= ~1;
6049   alpha_fprmask &= ~1;
6050 }
6051 #endif
6052 
6053 /* Hook to remember a recently defined label so that the auto-align
6054    code can adjust the symbol after we know what alignment will be
6055    required.  */
6056 
6057 void
alpha_define_label(symbolS * sym)6058 alpha_define_label (symbolS *sym)
6059 {
6060   alpha_insn_label = sym;
6061 #ifdef OBJ_ELF
6062   dwarf2_emit_label (sym);
6063 #endif
6064 }
6065 
6066 /* Return true if we must always emit a reloc for a type and false if
6067    there is some hope of resolving it at assembly time.  */
6068 
6069 int
alpha_force_relocation(fixS * f)6070 alpha_force_relocation (fixS *f)
6071 {
6072   if (alpha_flag_relax)
6073     return 1;
6074 
6075   switch (f->fx_r_type)
6076     {
6077     case BFD_RELOC_ALPHA_GPDISP_HI16:
6078     case BFD_RELOC_ALPHA_GPDISP_LO16:
6079     case BFD_RELOC_ALPHA_GPDISP:
6080     case BFD_RELOC_ALPHA_LITERAL:
6081     case BFD_RELOC_ALPHA_ELF_LITERAL:
6082     case BFD_RELOC_ALPHA_LITUSE:
6083     case BFD_RELOC_GPREL16:
6084     case BFD_RELOC_GPREL32:
6085     case BFD_RELOC_ALPHA_GPREL_HI16:
6086     case BFD_RELOC_ALPHA_GPREL_LO16:
6087     case BFD_RELOC_ALPHA_LINKAGE:
6088     case BFD_RELOC_ALPHA_CODEADDR:
6089     case BFD_RELOC_ALPHA_BRSGP:
6090     case BFD_RELOC_ALPHA_TLSGD:
6091     case BFD_RELOC_ALPHA_TLSLDM:
6092     case BFD_RELOC_ALPHA_GOTDTPREL16:
6093     case BFD_RELOC_ALPHA_DTPREL_HI16:
6094     case BFD_RELOC_ALPHA_DTPREL_LO16:
6095     case BFD_RELOC_ALPHA_DTPREL16:
6096     case BFD_RELOC_ALPHA_GOTTPREL16:
6097     case BFD_RELOC_ALPHA_TPREL_HI16:
6098     case BFD_RELOC_ALPHA_TPREL_LO16:
6099     case BFD_RELOC_ALPHA_TPREL16:
6100 #ifdef OBJ_EVAX
6101     case BFD_RELOC_ALPHA_NOP:
6102     case BFD_RELOC_ALPHA_BSR:
6103     case BFD_RELOC_ALPHA_LDA:
6104     case BFD_RELOC_ALPHA_BOH:
6105 #endif
6106       return 1;
6107 
6108     default:
6109       break;
6110     }
6111 
6112   return generic_force_reloc (f);
6113 }
6114 
6115 /* Return true if we can partially resolve a relocation now.  */
6116 
6117 int
alpha_fix_adjustable(fixS * f)6118 alpha_fix_adjustable (fixS *f)
6119 {
6120   /* Are there any relocation types for which we must generate a
6121      reloc but we can adjust the values contained within it?   */
6122   switch (f->fx_r_type)
6123     {
6124     case BFD_RELOC_ALPHA_GPDISP_HI16:
6125     case BFD_RELOC_ALPHA_GPDISP_LO16:
6126     case BFD_RELOC_ALPHA_GPDISP:
6127       return 0;
6128 
6129     case BFD_RELOC_ALPHA_LITERAL:
6130     case BFD_RELOC_ALPHA_ELF_LITERAL:
6131     case BFD_RELOC_ALPHA_LITUSE:
6132     case BFD_RELOC_ALPHA_LINKAGE:
6133     case BFD_RELOC_ALPHA_CODEADDR:
6134       return 1;
6135 
6136     case BFD_RELOC_VTABLE_ENTRY:
6137     case BFD_RELOC_VTABLE_INHERIT:
6138       return 0;
6139 
6140     case BFD_RELOC_GPREL16:
6141     case BFD_RELOC_GPREL32:
6142     case BFD_RELOC_ALPHA_GPREL_HI16:
6143     case BFD_RELOC_ALPHA_GPREL_LO16:
6144     case BFD_RELOC_23_PCREL_S2:
6145     case BFD_RELOC_16:
6146     case BFD_RELOC_32:
6147     case BFD_RELOC_64:
6148     case BFD_RELOC_ALPHA_HINT:
6149       return 1;
6150 
6151     case BFD_RELOC_ALPHA_TLSGD:
6152     case BFD_RELOC_ALPHA_TLSLDM:
6153     case BFD_RELOC_ALPHA_GOTDTPREL16:
6154     case BFD_RELOC_ALPHA_DTPREL_HI16:
6155     case BFD_RELOC_ALPHA_DTPREL_LO16:
6156     case BFD_RELOC_ALPHA_DTPREL16:
6157     case BFD_RELOC_ALPHA_GOTTPREL16:
6158     case BFD_RELOC_ALPHA_TPREL_HI16:
6159     case BFD_RELOC_ALPHA_TPREL_LO16:
6160     case BFD_RELOC_ALPHA_TPREL16:
6161       /* ??? No idea why we can't return a reference to .tbss+10, but
6162 	 we're preventing this in the other assemblers.  Follow for now.  */
6163       return 0;
6164 
6165 #ifdef OBJ_ELF
6166     case BFD_RELOC_ALPHA_BRSGP:
6167       /* If we have a BRSGP reloc to a local symbol, adjust it to BRADDR and
6168          let it get resolved at assembly time.  */
6169       {
6170 	symbolS *sym = f->fx_addsy;
6171 	const char *name;
6172 	int offset = 0;
6173 
6174 	if (generic_force_reloc (f))
6175 	  return 0;
6176 
6177 	switch (S_GET_OTHER (sym) & STO_ALPHA_STD_GPLOAD)
6178 	  {
6179 	  case STO_ALPHA_NOPV:
6180 	    break;
6181 	  case STO_ALPHA_STD_GPLOAD:
6182 	    offset = 8;
6183 	    break;
6184 	  default:
6185 	    if (S_IS_LOCAL (sym))
6186 	      name = "<local>";
6187 	    else
6188 	      name = S_GET_NAME (sym);
6189 	    as_bad_where (f->fx_file, f->fx_line,
6190 		_("!samegp reloc against symbol without .prologue: %s"),
6191 		name);
6192 	    break;
6193 	  }
6194 	f->fx_r_type = BFD_RELOC_23_PCREL_S2;
6195 	f->fx_offset += offset;
6196 	return 1;
6197       }
6198 #endif
6199 #ifdef OBJ_EVAX
6200     case BFD_RELOC_ALPHA_NOP:
6201     case BFD_RELOC_ALPHA_BSR:
6202     case BFD_RELOC_ALPHA_LDA:
6203     case BFD_RELOC_ALPHA_BOH:
6204       return 1;
6205 #endif
6206 
6207     default:
6208       return 1;
6209     }
6210 }
6211 
6212 /* Generate the BFD reloc to be stuck in the object file from the
6213    fixup used internally in the assembler.  */
6214 
6215 arelent *
tc_gen_reloc(asection * sec ATTRIBUTE_UNUSED,fixS * fixp)6216 tc_gen_reloc (asection *sec ATTRIBUTE_UNUSED,
6217 	      fixS *fixp)
6218 {
6219   arelent *reloc;
6220 
6221   reloc = XNEW (arelent);
6222   reloc->sym_ptr_ptr = XNEW (asymbol *);
6223   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
6224   reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
6225 
6226   /* Make sure none of our internal relocations make it this far.
6227      They'd better have been fully resolved by this point.  */
6228   gas_assert ((int) fixp->fx_r_type > 0);
6229 
6230   reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
6231   if (reloc->howto == NULL)
6232     {
6233       as_bad_where (fixp->fx_file, fixp->fx_line,
6234 		    _("cannot represent `%s' relocation in object file"),
6235 		    bfd_get_reloc_code_name (fixp->fx_r_type));
6236       return NULL;
6237     }
6238 
6239   if (!fixp->fx_pcrel != !reloc->howto->pc_relative)
6240     as_fatal (_("internal error? cannot generate `%s' relocation"),
6241 	      bfd_get_reloc_code_name (fixp->fx_r_type));
6242 
6243   gas_assert (!fixp->fx_pcrel == !reloc->howto->pc_relative);
6244 
6245   reloc->addend = fixp->fx_offset;
6246 
6247 #ifdef OBJ_ECOFF
6248   /* Fake out bfd_perform_relocation. sigh.  */
6249   /* ??? Better would be to use the special_function hook.  */
6250   if (fixp->fx_r_type == BFD_RELOC_ALPHA_LITERAL)
6251     reloc->addend = -alpha_gp_value;
6252 #endif
6253 
6254 #ifdef OBJ_EVAX
6255   switch (fixp->fx_r_type)
6256     {
6257       struct evax_private_udata_struct *udata;
6258       const char *pname;
6259       int pname_len;
6260 
6261     case BFD_RELOC_ALPHA_LINKAGE:
6262       /* Copy the linkage index.  */
6263       reloc->addend = fixp->fx_addnumber;
6264       break;
6265 
6266     case BFD_RELOC_ALPHA_NOP:
6267     case BFD_RELOC_ALPHA_BSR:
6268     case BFD_RELOC_ALPHA_LDA:
6269     case BFD_RELOC_ALPHA_BOH:
6270       pname = symbol_get_bfdsym (fixp->fx_addsy)->name;
6271 
6272       /* We need the non-suffixed name of the procedure.  Beware that
6273       the main symbol might be equated so look it up and take its name.  */
6274       pname_len = strlen (pname);
6275       if (pname_len > 4 && strcmp (pname + pname_len - 4, "..en") == 0)
6276 	{
6277 	  symbolS *sym;
6278 	  char *my_pname = xmemdup0 (pname, pname_len - 4);
6279 	  sym = symbol_find (my_pname);
6280 	  free (my_pname);
6281 	  if (sym == NULL)
6282 	    abort ();
6283 
6284 	  while (symbol_equated_reloc_p (sym))
6285 	    {
6286 	      symbolS *n = symbol_get_value_expression (sym)->X_add_symbol;
6287 
6288 	      /* We must avoid looping, as that can occur with a badly
6289 	         written program.  */
6290 	      if (n == sym)
6291 		break;
6292 	      sym = n;
6293 	    }
6294 	  pname = symbol_get_bfdsym (sym)->name;
6295 	}
6296 
6297       udata = XNEW (struct evax_private_udata_struct);
6298       udata->enbsym = symbol_get_bfdsym (fixp->fx_addsy);
6299       udata->bsym = symbol_get_bfdsym (fixp->tc_fix_data.info->psym);
6300       udata->origname = (char *)pname;
6301       udata->lkindex = ((struct evax_private_udata_struct *)
6302         symbol_get_bfdsym (fixp->tc_fix_data.info->sym)->udata.p)->lkindex;
6303       reloc->sym_ptr_ptr = (void *)udata;
6304       reloc->addend = fixp->fx_addnumber;
6305 
6306     default:
6307       break;
6308     }
6309 #endif
6310 
6311   return reloc;
6312 }
6313 
6314 /* Parse a register name off of the input_line and return a register
6315    number.  Gets md_undefined_symbol above to do the register name
6316    matching for us.
6317 
6318    Only called as a part of processing the ECOFF .frame directive.  */
6319 
6320 int
tc_get_register(int frame ATTRIBUTE_UNUSED)6321 tc_get_register (int frame ATTRIBUTE_UNUSED)
6322 {
6323   int framereg = AXP_REG_SP;
6324 
6325   SKIP_WHITESPACE ();
6326   if (*input_line_pointer == '$')
6327     {
6328       char *s;
6329       char c = get_symbol_name (&s);
6330       symbolS *sym = md_undefined_symbol (s);
6331 
6332       *strchr (s, '\0') = c;
6333       if (sym && (framereg = S_GET_VALUE (sym)) <= 31)
6334 	goto found;
6335     }
6336   as_warn (_("frame reg expected, using $%d."), framereg);
6337 
6338 found:
6339   note_gpreg (framereg);
6340   return framereg;
6341 }
6342 
6343 /* This is called before the symbol table is processed.  In order to
6344    work with gcc when using mips-tfile, we must keep all local labels.
6345    However, in other cases, we want to discard them.  If we were
6346    called with -g, but we didn't see any debugging information, it may
6347    mean that gcc is smuggling debugging information through to
6348    mips-tfile, in which case we must generate all local labels.  */
6349 
6350 #ifdef OBJ_ECOFF
6351 
6352 void
alpha_frob_file_before_adjust(void)6353 alpha_frob_file_before_adjust (void)
6354 {
6355   if (alpha_debug != 0
6356       && ! ecoff_debugging_seen)
6357     flag_keep_locals = 1;
6358 }
6359 
6360 #endif /* OBJ_ECOFF */
6361 
6362 /* The Alpha has support for some VAX floating point types, as well as for
6363    IEEE floating point.  We consider IEEE to be the primary floating point
6364    format, and sneak in the VAX floating point support here.  */
6365 #include "config/atof-vax.c"
6366