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