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