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