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