b84fa582a4205848e381f8628a81f5982b999a2c
[deliverable/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_symtab_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_ALPHA_GPDISP:
1143 case BFD_RELOC_ALPHA_GPDISP_HI16:
1144 case BFD_RELOC_ALPHA_GPDISP_LO16:
1145 return addr;
1146 default:
1147 return fixP->fx_size + 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; we need to drop in a value
1175 which, when added to the address of the start of the function,
1176 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 case BFD_RELOC_ALPHA_TLSGD:
1265 case BFD_RELOC_ALPHA_TLSLDM:
1266 case BFD_RELOC_ALPHA_GOTDTPREL16:
1267 case BFD_RELOC_ALPHA_DTPREL_HI16:
1268 case BFD_RELOC_ALPHA_DTPREL_LO16:
1269 case BFD_RELOC_ALPHA_DTPREL16:
1270 case BFD_RELOC_ALPHA_GOTTPREL16:
1271 case BFD_RELOC_ALPHA_TPREL_HI16:
1272 case BFD_RELOC_ALPHA_TPREL_LO16:
1273 case BFD_RELOC_ALPHA_TPREL16:
1274 return;
1275 #endif
1276
1277 #ifdef OBJ_ECOFF
1278 case BFD_RELOC_ALPHA_LITERAL:
1279 md_number_to_chars (fixpos, value, 2);
1280 return;
1281 #endif
1282 case BFD_RELOC_ALPHA_ELF_LITERAL:
1283 case BFD_RELOC_ALPHA_LITUSE:
1284 case BFD_RELOC_ALPHA_LINKAGE:
1285 case BFD_RELOC_ALPHA_CODEADDR:
1286 return;
1287
1288 case BFD_RELOC_VTABLE_INHERIT:
1289 case BFD_RELOC_VTABLE_ENTRY:
1290 return;
1291
1292 default:
1293 {
1294 const struct alpha_operand *operand;
1295
1296 if ((int) fixP->fx_r_type >= 0)
1297 as_fatal (_("unhandled relocation type %s"),
1298 bfd_get_reloc_code_name (fixP->fx_r_type));
1299
1300 assert (-(int) fixP->fx_r_type < (int) alpha_num_operands);
1301 operand = &alpha_operands[-(int) fixP->fx_r_type];
1302
1303 /* The rest of these fixups only exist internally during symbol
1304 resolution and have no representation in the object file.
1305 Therefore they must be completely resolved as constants. */
1306
1307 if (fixP->fx_addsy != 0
1308 && S_GET_SEGMENT (fixP->fx_addsy) != absolute_section)
1309 as_bad_where (fixP->fx_file, fixP->fx_line,
1310 _("non-absolute expression in constant field"));
1311
1312 image = bfd_getl32 (fixpos);
1313 image = insert_operand (image, operand, (offsetT) value,
1314 fixP->fx_file, fixP->fx_line);
1315 }
1316 goto write_done;
1317 }
1318
1319 if (fixP->fx_addsy != 0 || fixP->fx_pcrel != 0)
1320 return;
1321 else
1322 {
1323 as_warn_where (fixP->fx_file, fixP->fx_line,
1324 _("type %d reloc done?\n"), (int) fixP->fx_r_type);
1325 goto done;
1326 }
1327
1328 write_done:
1329 md_number_to_chars (fixpos, image, 4);
1330
1331 done:
1332 fixP->fx_done = 1;
1333 }
1334
1335 /* Look for a register name in the given symbol. */
1336
1337 symbolS *
1338 md_undefined_symbol (name)
1339 char *name;
1340 {
1341 if (*name == '$')
1342 {
1343 int is_float = 0, num;
1344
1345 switch (*++name)
1346 {
1347 case 'f':
1348 if (name[1] == 'p' && name[2] == '\0')
1349 return alpha_register_table[AXP_REG_FP];
1350 is_float = 32;
1351 /* FALLTHRU */
1352
1353 case 'r':
1354 if (!ISDIGIT (*++name))
1355 break;
1356 /* FALLTHRU */
1357
1358 case '0': case '1': case '2': case '3': case '4':
1359 case '5': case '6': case '7': case '8': case '9':
1360 if (name[1] == '\0')
1361 num = name[0] - '0';
1362 else if (name[0] != '0' && ISDIGIT (name[1]) && name[2] == '\0')
1363 {
1364 num = (name[0] - '0') * 10 + name[1] - '0';
1365 if (num >= 32)
1366 break;
1367 }
1368 else
1369 break;
1370
1371 if (!alpha_noat_on && (num + is_float) == AXP_REG_AT)
1372 as_warn (_("Used $at without \".set noat\""));
1373 return alpha_register_table[num + is_float];
1374
1375 case 'a':
1376 if (name[1] == 't' && name[2] == '\0')
1377 {
1378 if (!alpha_noat_on)
1379 as_warn (_("Used $at without \".set noat\""));
1380 return alpha_register_table[AXP_REG_AT];
1381 }
1382 break;
1383
1384 case 'g':
1385 if (name[1] == 'p' && name[2] == '\0')
1386 return alpha_register_table[alpha_gp_register];
1387 break;
1388
1389 case 's':
1390 if (name[1] == 'p' && name[2] == '\0')
1391 return alpha_register_table[AXP_REG_SP];
1392 break;
1393 }
1394 }
1395 return NULL;
1396 }
1397
1398 #ifdef OBJ_ECOFF
1399 /* @@@ Magic ECOFF bits. */
1400
1401 void
1402 alpha_frob_ecoff_data ()
1403 {
1404 select_gp_value ();
1405 /* $zero and $f31 are read-only */
1406 alpha_gprmask &= ~1;
1407 alpha_fprmask &= ~1;
1408 }
1409 #endif
1410
1411 /* Hook to remember a recently defined label so that the auto-align
1412 code can adjust the symbol after we know what alignment will be
1413 required. */
1414
1415 void
1416 alpha_define_label (sym)
1417 symbolS *sym;
1418 {
1419 alpha_insn_label = sym;
1420 }
1421
1422 /* If we have a BRSGP reloc to a local symbol, adjust it to BRADDR and
1423 let it get resolved at assembly time. */
1424
1425 #ifdef OBJ_ELF
1426 void
1427 alpha_validate_fix (f)
1428 fixS *f;
1429 {
1430 int offset = 0;
1431 const char *name;
1432
1433 if (f->fx_r_type != BFD_RELOC_ALPHA_BRSGP)
1434 return;
1435
1436 if (! S_IS_DEFINED (f->fx_addsy))
1437 return;
1438
1439 switch (S_GET_OTHER (f->fx_addsy) & STO_ALPHA_STD_GPLOAD)
1440 {
1441 case STO_ALPHA_NOPV:
1442 break;
1443 case STO_ALPHA_STD_GPLOAD:
1444 offset = 8;
1445 break;
1446 default:
1447 if (S_IS_LOCAL (f->fx_addsy))
1448 name = "<local>";
1449 else
1450 name = S_GET_NAME (f->fx_addsy);
1451 as_bad_where (f->fx_file, f->fx_line,
1452 _("!samegp reloc against symbol without .prologue: %s"),
1453 name);
1454 break;
1455 }
1456
1457 if (! (S_IS_EXTERN (f->fx_addsy) || S_IS_WEAK (f->fx_addsy)))
1458 {
1459 f->fx_r_type = BFD_RELOC_23_PCREL_S2;
1460 f->fx_offset += offset;
1461 }
1462 }
1463 #endif
1464
1465 /* Return true if we must always emit a reloc for a type and false if
1466 there is some hope of resolving it at assembly time. */
1467
1468 int
1469 alpha_force_relocation (f)
1470 fixS *f;
1471 {
1472 if (alpha_flag_relax)
1473 return 1;
1474
1475 switch (f->fx_r_type)
1476 {
1477 case BFD_RELOC_ALPHA_GPDISP_HI16:
1478 case BFD_RELOC_ALPHA_GPDISP_LO16:
1479 case BFD_RELOC_ALPHA_GPDISP:
1480 case BFD_RELOC_ALPHA_LITERAL:
1481 case BFD_RELOC_ALPHA_ELF_LITERAL:
1482 case BFD_RELOC_ALPHA_LITUSE:
1483 case BFD_RELOC_GPREL16:
1484 case BFD_RELOC_GPREL32:
1485 case BFD_RELOC_ALPHA_GPREL_HI16:
1486 case BFD_RELOC_ALPHA_GPREL_LO16:
1487 case BFD_RELOC_ALPHA_LINKAGE:
1488 case BFD_RELOC_ALPHA_CODEADDR:
1489 case BFD_RELOC_ALPHA_BRSGP:
1490 case BFD_RELOC_VTABLE_INHERIT:
1491 case BFD_RELOC_VTABLE_ENTRY:
1492 case BFD_RELOC_ALPHA_TLSGD:
1493 case BFD_RELOC_ALPHA_TLSLDM:
1494 case BFD_RELOC_ALPHA_GOTDTPREL16:
1495 case BFD_RELOC_ALPHA_DTPREL_HI16:
1496 case BFD_RELOC_ALPHA_DTPREL_LO16:
1497 case BFD_RELOC_ALPHA_DTPREL16:
1498 case BFD_RELOC_ALPHA_GOTTPREL16:
1499 case BFD_RELOC_ALPHA_TPREL_HI16:
1500 case BFD_RELOC_ALPHA_TPREL_LO16:
1501 case BFD_RELOC_ALPHA_TPREL16:
1502 return 1;
1503
1504 case BFD_RELOC_23_PCREL_S2:
1505 case BFD_RELOC_32:
1506 case BFD_RELOC_64:
1507 case BFD_RELOC_ALPHA_HINT:
1508 return 0;
1509
1510 default:
1511 return 0;
1512 }
1513 }
1514
1515 /* Return true if we can partially resolve a relocation now. */
1516
1517 int
1518 alpha_fix_adjustable (f)
1519 fixS *f;
1520 {
1521 #ifdef OBJ_ELF
1522 /* Prevent all adjustments to global symbols */
1523 if (S_IS_EXTERN (f->fx_addsy) || S_IS_WEAK (f->fx_addsy))
1524 return 0;
1525 #endif
1526
1527 /* Are there any relocation types for which we must generate a reloc
1528 but we can adjust the values contained within it? */
1529 switch (f->fx_r_type)
1530 {
1531 case BFD_RELOC_ALPHA_GPDISP_HI16:
1532 case BFD_RELOC_ALPHA_GPDISP_LO16:
1533 case BFD_RELOC_ALPHA_GPDISP:
1534 case BFD_RELOC_ALPHA_BRSGP:
1535 return 0;
1536
1537 case BFD_RELOC_ALPHA_LITERAL:
1538 case BFD_RELOC_ALPHA_ELF_LITERAL:
1539 case BFD_RELOC_ALPHA_LITUSE:
1540 case BFD_RELOC_ALPHA_LINKAGE:
1541 case BFD_RELOC_ALPHA_CODEADDR:
1542 return 1;
1543
1544 case BFD_RELOC_VTABLE_ENTRY:
1545 case BFD_RELOC_VTABLE_INHERIT:
1546 return 0;
1547
1548 case BFD_RELOC_GPREL16:
1549 case BFD_RELOC_GPREL32:
1550 case BFD_RELOC_ALPHA_GPREL_HI16:
1551 case BFD_RELOC_ALPHA_GPREL_LO16:
1552 case BFD_RELOC_23_PCREL_S2:
1553 case BFD_RELOC_32:
1554 case BFD_RELOC_64:
1555 case BFD_RELOC_ALPHA_HINT:
1556 return 1;
1557
1558 case BFD_RELOC_ALPHA_TLSGD:
1559 case BFD_RELOC_ALPHA_TLSLDM:
1560 case BFD_RELOC_ALPHA_GOTDTPREL16:
1561 case BFD_RELOC_ALPHA_DTPREL_HI16:
1562 case BFD_RELOC_ALPHA_DTPREL_LO16:
1563 case BFD_RELOC_ALPHA_DTPREL16:
1564 case BFD_RELOC_ALPHA_GOTTPREL16:
1565 case BFD_RELOC_ALPHA_TPREL_HI16:
1566 case BFD_RELOC_ALPHA_TPREL_LO16:
1567 case BFD_RELOC_ALPHA_TPREL16:
1568 /* ??? No idea why we can't return a reference to .tbss+10, but
1569 we're preventing this in the other assemblers. Follow for now. */
1570 return 0;
1571
1572 default:
1573 return 1;
1574 }
1575 /*NOTREACHED*/
1576 }
1577
1578 /* Generate the BFD reloc to be stuck in the object file from the
1579 fixup used internally in the assembler. */
1580
1581 arelent *
1582 tc_gen_reloc (sec, fixp)
1583 asection *sec ATTRIBUTE_UNUSED;
1584 fixS *fixp;
1585 {
1586 arelent *reloc;
1587
1588 reloc = (arelent *) xmalloc (sizeof (arelent));
1589 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
1590 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
1591 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
1592
1593 /* Make sure none of our internal relocations make it this far.
1594 They'd better have been fully resolved by this point. */
1595 assert ((int) fixp->fx_r_type > 0);
1596
1597 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
1598 if (reloc->howto == NULL)
1599 {
1600 as_bad_where (fixp->fx_file, fixp->fx_line,
1601 _("cannot represent `%s' relocation in object file"),
1602 bfd_get_reloc_code_name (fixp->fx_r_type));
1603 return NULL;
1604 }
1605
1606 if (!fixp->fx_pcrel != !reloc->howto->pc_relative)
1607 {
1608 as_fatal (_("internal error? cannot generate `%s' relocation"),
1609 bfd_get_reloc_code_name (fixp->fx_r_type));
1610 }
1611 assert (!fixp->fx_pcrel == !reloc->howto->pc_relative);
1612
1613 #ifdef OBJ_ECOFF
1614 if (fixp->fx_r_type == BFD_RELOC_ALPHA_LITERAL)
1615 {
1616 /* Fake out bfd_perform_relocation. sigh. */
1617 reloc->addend = -alpha_gp_value;
1618 }
1619 else
1620 #endif
1621 {
1622 reloc->addend = fixp->fx_offset;
1623 #ifdef OBJ_ELF
1624 /* Ohhh, this is ugly. The problem is that if this is a local global
1625 symbol, the relocation will entirely be performed at link time, not
1626 at assembly time. bfd_perform_reloc doesn't know about this sort
1627 of thing, and as a result we need to fake it out here. */
1628 if ((S_IS_EXTERN (fixp->fx_addsy) || S_IS_WEAK (fixp->fx_addsy)
1629 || (S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_MERGE)
1630 || (S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_THREAD_LOCAL))
1631 && !S_IS_COMMON (fixp->fx_addsy))
1632 reloc->addend -= symbol_get_bfdsym (fixp->fx_addsy)->value;
1633 #endif
1634 }
1635
1636 return reloc;
1637 }
1638
1639 /* Parse a register name off of the input_line and return a register
1640 number. Gets md_undefined_symbol above to do the register name
1641 matching for us.
1642
1643 Only called as a part of processing the ECOFF .frame directive. */
1644
1645 int
1646 tc_get_register (frame)
1647 int frame ATTRIBUTE_UNUSED;
1648 {
1649 int framereg = AXP_REG_SP;
1650
1651 SKIP_WHITESPACE ();
1652 if (*input_line_pointer == '$')
1653 {
1654 char *s = input_line_pointer;
1655 char c = get_symbol_end ();
1656 symbolS *sym = md_undefined_symbol (s);
1657
1658 *strchr (s, '\0') = c;
1659 if (sym && (framereg = S_GET_VALUE (sym)) <= 31)
1660 goto found;
1661 }
1662 as_warn (_("frame reg expected, using $%d."), framereg);
1663
1664 found:
1665 note_gpreg (framereg);
1666 return framereg;
1667 }
1668
1669 /* This is called before the symbol table is processed. In order to
1670 work with gcc when using mips-tfile, we must keep all local labels.
1671 However, in other cases, we want to discard them. If we were
1672 called with -g, but we didn't see any debugging information, it may
1673 mean that gcc is smuggling debugging information through to
1674 mips-tfile, in which case we must generate all local labels. */
1675
1676 #ifdef OBJ_ECOFF
1677
1678 void
1679 alpha_frob_file_before_adjust ()
1680 {
1681 if (alpha_debug != 0
1682 && ! ecoff_debugging_seen)
1683 flag_keep_locals = 1;
1684 }
1685
1686 #endif /* OBJ_ECOFF */
1687 \f
1688 static struct alpha_reloc_tag *
1689 get_alpha_reloc_tag (sequence)
1690 long sequence;
1691 {
1692 char buffer[ALPHA_RELOC_DIGITS];
1693 struct alpha_reloc_tag *info;
1694
1695 sprintf (buffer, "!%ld", sequence);
1696
1697 info = (struct alpha_reloc_tag *) hash_find (alpha_literal_hash, buffer);
1698 if (! info)
1699 {
1700 size_t len = strlen (buffer);
1701 const char *errmsg;
1702
1703 info = (struct alpha_reloc_tag *)
1704 xcalloc (sizeof (struct alpha_reloc_tag) + len, 1);
1705
1706 info->segment = now_seg;
1707 info->sequence = sequence;
1708 strcpy (info->string, buffer);
1709 errmsg = hash_insert (alpha_literal_hash, info->string, (PTR) info);
1710 if (errmsg)
1711 as_fatal (errmsg);
1712 }
1713
1714 return info;
1715 }
1716
1717 /* Before the relocations are written, reorder them, so that user
1718 supplied !lituse relocations follow the appropriate !literal
1719 relocations, and similarly for !gpdisp relocations. */
1720
1721 void
1722 alpha_adjust_symtab ()
1723 {
1724 if (alpha_literal_hash)
1725 bfd_map_over_sections (stdoutput, alpha_adjust_symtab_relocs, NULL);
1726 }
1727
1728 static void
1729 alpha_adjust_symtab_relocs (abfd, sec, ptr)
1730 bfd *abfd ATTRIBUTE_UNUSED;
1731 asection *sec;
1732 PTR ptr ATTRIBUTE_UNUSED;
1733 {
1734 segment_info_type *seginfo = seg_info (sec);
1735 fixS **prevP;
1736 fixS *fixp;
1737 fixS *next;
1738 fixS *slave;
1739
1740 /* If seginfo is NULL, we did not create this section; don't do
1741 anything with it. By using a pointer to a pointer, we can update
1742 the links in place. */
1743 if (seginfo == NULL)
1744 return;
1745
1746 /* If there are no relocations, skip the section. */
1747 if (! seginfo->fix_root)
1748 return;
1749
1750 /* First rebuild the fixup chain without the expicit lituse and
1751 gpdisp_lo16 relocs. */
1752 prevP = &seginfo->fix_root;
1753 for (fixp = seginfo->fix_root; fixp; fixp = next)
1754 {
1755 next = fixp->fx_next;
1756 fixp->fx_next = (fixS *) 0;
1757
1758 switch (fixp->fx_r_type)
1759 {
1760 case BFD_RELOC_ALPHA_LITUSE:
1761 if (fixp->tc_fix_data.info->n_master == 0)
1762 as_bad_where (fixp->fx_file, fixp->fx_line,
1763 _("No !literal!%ld was found"),
1764 fixp->tc_fix_data.info->sequence);
1765 #ifdef RELOC_OP_P
1766 if (fixp->fx_offset == LITUSE_ALPHA_TLSGD)
1767 {
1768 if (! fixp->tc_fix_data.info->saw_tlsgd)
1769 as_bad_where (fixp->fx_file, fixp->fx_line,
1770 _("No !tlsgd!%ld was found"),
1771 fixp->tc_fix_data.info->sequence);
1772 }
1773 else if (fixp->fx_offset == LITUSE_ALPHA_TLSLDM)
1774 {
1775 if (! fixp->tc_fix_data.info->saw_tlsldm)
1776 as_bad_where (fixp->fx_file, fixp->fx_line,
1777 _("No !tlsldm!%ld was found"),
1778 fixp->tc_fix_data.info->sequence);
1779 }
1780 #endif
1781 break;
1782
1783 case BFD_RELOC_ALPHA_GPDISP_LO16:
1784 if (fixp->tc_fix_data.info->n_master == 0)
1785 as_bad_where (fixp->fx_file, fixp->fx_line,
1786 _("No ldah !gpdisp!%ld was found"),
1787 fixp->tc_fix_data.info->sequence);
1788 break;
1789
1790 case BFD_RELOC_ALPHA_ELF_LITERAL:
1791 if (fixp->tc_fix_data.info
1792 && (fixp->tc_fix_data.info->saw_tlsgd
1793 || fixp->tc_fix_data.info->saw_tlsldm))
1794 break;
1795 /* FALLTHRU */
1796
1797 default:
1798 *prevP = fixp;
1799 prevP = &fixp->fx_next;
1800 break;
1801 }
1802 }
1803
1804 /* Go back and re-chain dependent relocations. They are currently
1805 linked through the next_reloc field in reverse order, so as we
1806 go through the next_reloc chain, we effectively reverse the chain
1807 once again.
1808
1809 Except if there is more than one !literal for a given sequence
1810 number. In that case, the programmer and/or compiler is not sure
1811 how control flows from literal to lituse, and we can't be sure to
1812 get the relaxation correct.
1813
1814 ??? Well, actually we could, if there are enough lituses such that
1815 we can make each literal have at least one of each lituse type
1816 present. Not implemented.
1817
1818 Also suppress the optimization if the !literals/!lituses are spread
1819 in different segments. This can happen with "intersting" uses of
1820 inline assembly; examples are present in the Linux kernel semaphores. */
1821
1822 for (fixp = seginfo->fix_root; fixp; fixp = next)
1823 {
1824 next = fixp->fx_next;
1825 switch (fixp->fx_r_type)
1826 {
1827 case BFD_RELOC_ALPHA_TLSGD:
1828 case BFD_RELOC_ALPHA_TLSLDM:
1829 if (!fixp->tc_fix_data.info)
1830 break;
1831 if (fixp->tc_fix_data.info->n_master == 0)
1832 break;
1833 else if (fixp->tc_fix_data.info->n_master > 1)
1834 {
1835 as_bad_where (fixp->fx_file, fixp->fx_line,
1836 _("too many !literal!%ld for %s"),
1837 fixp->tc_fix_data.info->sequence,
1838 (fixp->fx_r_type == BFD_RELOC_ALPHA_TLSGD
1839 ? "!tlsgd" : "!tlsldm"));
1840 break;
1841 }
1842
1843 fixp->tc_fix_data.info->master->fx_next = fixp->fx_next;
1844 fixp->fx_next = fixp->tc_fix_data.info->master;
1845 fixp = fixp->fx_next;
1846 /* FALLTHRU */
1847
1848 case BFD_RELOC_ALPHA_ELF_LITERAL:
1849 if (fixp->tc_fix_data.info
1850 && fixp->tc_fix_data.info->n_master == 1
1851 && ! fixp->tc_fix_data.info->multi_section_p)
1852 {
1853 for (slave = fixp->tc_fix_data.info->slaves;
1854 slave != (fixS *) 0;
1855 slave = slave->tc_fix_data.next_reloc)
1856 {
1857 slave->fx_next = fixp->fx_next;
1858 fixp->fx_next = slave;
1859 }
1860 }
1861 break;
1862
1863 case BFD_RELOC_ALPHA_GPDISP_HI16:
1864 if (fixp->tc_fix_data.info->n_slaves == 0)
1865 as_bad_where (fixp->fx_file, fixp->fx_line,
1866 _("No lda !gpdisp!%ld was found"),
1867 fixp->tc_fix_data.info->sequence);
1868 else
1869 {
1870 slave = fixp->tc_fix_data.info->slaves;
1871 slave->fx_next = next;
1872 fixp->fx_next = slave;
1873 }
1874 break;
1875
1876 default:
1877 break;
1878 }
1879 }
1880 }
1881 \f
1882 #ifdef DEBUG_ALPHA
1883 static void
1884 debug_exp (tok, ntok)
1885 expressionS tok[];
1886 int ntok;
1887 {
1888 int i;
1889
1890 fprintf (stderr, "debug_exp: %d tokens", ntok);
1891 for (i = 0; i < ntok; i++)
1892 {
1893 expressionS *t = &tok[i];
1894 const char *name;
1895
1896 switch (t->X_op)
1897 {
1898 default: name = "unknown"; break;
1899 case O_illegal: name = "O_illegal"; break;
1900 case O_absent: name = "O_absent"; break;
1901 case O_constant: name = "O_constant"; break;
1902 case O_symbol: name = "O_symbol"; break;
1903 case O_symbol_rva: name = "O_symbol_rva"; break;
1904 case O_register: name = "O_register"; break;
1905 case O_big: name = "O_big"; break;
1906 case O_uminus: name = "O_uminus"; break;
1907 case O_bit_not: name = "O_bit_not"; break;
1908 case O_logical_not: name = "O_logical_not"; break;
1909 case O_multiply: name = "O_multiply"; break;
1910 case O_divide: name = "O_divide"; break;
1911 case O_modulus: name = "O_modulus"; break;
1912 case O_left_shift: name = "O_left_shift"; break;
1913 case O_right_shift: name = "O_right_shift"; break;
1914 case O_bit_inclusive_or: name = "O_bit_inclusive_or"; break;
1915 case O_bit_or_not: name = "O_bit_or_not"; break;
1916 case O_bit_exclusive_or: name = "O_bit_exclusive_or"; break;
1917 case O_bit_and: name = "O_bit_and"; break;
1918 case O_add: name = "O_add"; break;
1919 case O_subtract: name = "O_subtract"; break;
1920 case O_eq: name = "O_eq"; break;
1921 case O_ne: name = "O_ne"; break;
1922 case O_lt: name = "O_lt"; break;
1923 case O_le: name = "O_le"; break;
1924 case O_ge: name = "O_ge"; break;
1925 case O_gt: name = "O_gt"; break;
1926 case O_logical_and: name = "O_logical_and"; break;
1927 case O_logical_or: name = "O_logical_or"; break;
1928 case O_index: name = "O_index"; break;
1929 case O_pregister: name = "O_pregister"; break;
1930 case O_cpregister: name = "O_cpregister"; break;
1931 case O_literal: name = "O_literal"; break;
1932 case O_lituse_addr: name = "O_lituse_addr"; break;
1933 case O_lituse_base: name = "O_lituse_base"; break;
1934 case O_lituse_bytoff: name = "O_lituse_bytoff"; break;
1935 case O_lituse_jsr: name = "O_lituse_jsr"; break;
1936 case O_lituse_tlsgd: name = "O_lituse_tlsgd"; break;
1937 case O_lituse_tlsldm: name = "O_lituse_tlsldm"; break;
1938 case O_gpdisp: name = "O_gpdisp"; break;
1939 case O_gprelhigh: name = "O_gprelhigh"; break;
1940 case O_gprellow: name = "O_gprellow"; break;
1941 case O_gprel: name = "O_gprel"; break;
1942 case O_samegp: name = "O_samegp"; break;
1943 case O_tlsgd: name = "O_tlsgd"; break;
1944 case O_tlsldm: name = "O_tlsldm"; break;
1945 case O_gotdtprel: name = "O_gotdtprel"; break;
1946 case O_dtprelhi: name = "O_dtprelhi"; break;
1947 case O_dtprello: name = "O_dtprello"; break;
1948 case O_dtprel: name = "O_dtprel"; break;
1949 case O_gottprel: name = "O_gottprel"; break;
1950 case O_tprelhi: name = "O_tprelhi"; break;
1951 case O_tprello: name = "O_tprello"; break;
1952 case O_tprel: name = "O_tprel"; break;
1953 }
1954
1955 fprintf (stderr, ", %s(%s, %s, %d)", name,
1956 (t->X_add_symbol) ? S_GET_NAME (t->X_add_symbol) : "--",
1957 (t->X_op_symbol) ? S_GET_NAME (t->X_op_symbol) : "--",
1958 (int) t->X_add_number);
1959 }
1960 fprintf (stderr, "\n");
1961 fflush (stderr);
1962 }
1963 #endif
1964
1965 /* Parse the arguments to an opcode. */
1966
1967 static int
1968 tokenize_arguments (str, tok, ntok)
1969 char *str;
1970 expressionS tok[];
1971 int ntok;
1972 {
1973 expressionS *end_tok = tok + ntok;
1974 char *old_input_line_pointer;
1975 int saw_comma = 0, saw_arg = 0;
1976 #ifdef DEBUG_ALPHA
1977 expressionS *orig_tok = tok;
1978 #endif
1979 #ifdef RELOC_OP_P
1980 char *p;
1981 const struct alpha_reloc_op_tag *r;
1982 int c, i;
1983 size_t len;
1984 int reloc_found_p = 0;
1985 #endif
1986
1987 memset (tok, 0, sizeof (*tok) * ntok);
1988
1989 /* Save and restore input_line_pointer around this function. */
1990 old_input_line_pointer = input_line_pointer;
1991 input_line_pointer = str;
1992
1993 #ifdef RELOC_OP_P
1994 /* ??? Wrest control of ! away from the regular expression parser. */
1995 is_end_of_line[(unsigned char) '!'] = 1;
1996 #endif
1997
1998 while (tok < end_tok && *input_line_pointer)
1999 {
2000 SKIP_WHITESPACE ();
2001 switch (*input_line_pointer)
2002 {
2003 case '\0':
2004 goto fini;
2005
2006 #ifdef RELOC_OP_P
2007 case '!':
2008 /* A relocation operand can be placed after the normal operand on an
2009 assembly language statement, and has the following form:
2010 !relocation_type!sequence_number. */
2011 if (reloc_found_p)
2012 {
2013 /* Only support one relocation op per insn. */
2014 as_bad (_("More than one relocation op per insn"));
2015 goto err_report;
2016 }
2017
2018 if (!saw_arg)
2019 goto err;
2020
2021 ++input_line_pointer;
2022 SKIP_WHITESPACE ();
2023 p = input_line_pointer;
2024 c = get_symbol_end ();
2025
2026 /* Parse !relocation_type. */
2027 len = input_line_pointer - p;
2028 if (len == 0)
2029 {
2030 as_bad (_("No relocation operand"));
2031 goto err_report;
2032 }
2033
2034 r = &alpha_reloc_op[0];
2035 for (i = alpha_num_reloc_op - 1; i >= 0; i--, r++)
2036 if (len == r->length && memcmp (p, r->name, len) == 0)
2037 break;
2038 if (i < 0)
2039 {
2040 as_bad (_("Unknown relocation operand: !%s"), p);
2041 goto err_report;
2042 }
2043
2044 *input_line_pointer = c;
2045 SKIP_WHITESPACE ();
2046 if (*input_line_pointer != '!')
2047 {
2048 if (r->require_seq)
2049 {
2050 as_bad (_("no sequence number after !%s"), p);
2051 goto err_report;
2052 }
2053
2054 tok->X_add_number = 0;
2055 }
2056 else
2057 {
2058 if (! r->allow_seq)
2059 {
2060 as_bad (_("!%s does not use a sequence number"), p);
2061 goto err_report;
2062 }
2063
2064 input_line_pointer++;
2065
2066 /* Parse !sequence_number. */
2067 expression (tok);
2068 if (tok->X_op != O_constant || tok->X_add_number <= 0)
2069 {
2070 as_bad (_("Bad sequence number: !%s!%s"),
2071 r->name, input_line_pointer);
2072 goto err_report;
2073 }
2074 }
2075
2076 tok->X_op = r->op;
2077 reloc_found_p = 1;
2078 ++tok;
2079 break;
2080 #endif /* RELOC_OP_P */
2081
2082 case ',':
2083 ++input_line_pointer;
2084 if (saw_comma || !saw_arg)
2085 goto err;
2086 saw_comma = 1;
2087 break;
2088
2089 case '(':
2090 {
2091 char *hold = input_line_pointer++;
2092
2093 /* First try for parenthesized register ... */
2094 expression (tok);
2095 if (*input_line_pointer == ')' && tok->X_op == O_register)
2096 {
2097 tok->X_op = (saw_comma ? O_cpregister : O_pregister);
2098 saw_comma = 0;
2099 saw_arg = 1;
2100 ++input_line_pointer;
2101 ++tok;
2102 break;
2103 }
2104
2105 /* ... then fall through to plain expression. */
2106 input_line_pointer = hold;
2107 }
2108
2109 default:
2110 if (saw_arg && !saw_comma)
2111 goto err;
2112
2113 expression (tok);
2114 if (tok->X_op == O_illegal || tok->X_op == O_absent)
2115 goto err;
2116
2117 saw_comma = 0;
2118 saw_arg = 1;
2119 ++tok;
2120 break;
2121 }
2122 }
2123
2124 fini:
2125 if (saw_comma)
2126 goto err;
2127 input_line_pointer = old_input_line_pointer;
2128
2129 #ifdef DEBUG_ALPHA
2130 debug_exp (orig_tok, ntok - (end_tok - tok));
2131 #endif
2132 #ifdef RELOC_OP_P
2133 is_end_of_line[(unsigned char) '!'] = 0;
2134 #endif
2135
2136 return ntok - (end_tok - tok);
2137
2138 err:
2139 #ifdef RELOC_OP_P
2140 is_end_of_line[(unsigned char) '!'] = 0;
2141 #endif
2142 input_line_pointer = old_input_line_pointer;
2143 return TOKENIZE_ERROR;
2144
2145 #ifdef RELOC_OP_P
2146 err_report:
2147 is_end_of_line[(unsigned char) '!'] = 0;
2148 #endif
2149 input_line_pointer = old_input_line_pointer;
2150 return TOKENIZE_ERROR_REPORT;
2151 }
2152
2153 /* Search forward through all variants of an opcode looking for a
2154 syntax match. */
2155
2156 static const struct alpha_opcode *
2157 find_opcode_match (first_opcode, tok, pntok, pcpumatch)
2158 const struct alpha_opcode *first_opcode;
2159 const expressionS *tok;
2160 int *pntok;
2161 int *pcpumatch;
2162 {
2163 const struct alpha_opcode *opcode = first_opcode;
2164 int ntok = *pntok;
2165 int got_cpu_match = 0;
2166
2167 do
2168 {
2169 const unsigned char *opidx;
2170 int tokidx = 0;
2171
2172 /* Don't match opcodes that don't exist on this architecture. */
2173 if (!(opcode->flags & alpha_target))
2174 goto match_failed;
2175
2176 got_cpu_match = 1;
2177
2178 for (opidx = opcode->operands; *opidx; ++opidx)
2179 {
2180 const struct alpha_operand *operand = &alpha_operands[*opidx];
2181
2182 /* Only take input from real operands. */
2183 if (operand->flags & AXP_OPERAND_FAKE)
2184 continue;
2185
2186 /* When we expect input, make sure we have it. */
2187 if (tokidx >= ntok)
2188 {
2189 if ((operand->flags & AXP_OPERAND_OPTIONAL_MASK) == 0)
2190 goto match_failed;
2191 continue;
2192 }
2193
2194 /* Match operand type with expression type. */
2195 switch (operand->flags & AXP_OPERAND_TYPECHECK_MASK)
2196 {
2197 case AXP_OPERAND_IR:
2198 if (tok[tokidx].X_op != O_register
2199 || !is_ir_num (tok[tokidx].X_add_number))
2200 goto match_failed;
2201 break;
2202 case AXP_OPERAND_FPR:
2203 if (tok[tokidx].X_op != O_register
2204 || !is_fpr_num (tok[tokidx].X_add_number))
2205 goto match_failed;
2206 break;
2207 case AXP_OPERAND_IR | AXP_OPERAND_PARENS:
2208 if (tok[tokidx].X_op != O_pregister
2209 || !is_ir_num (tok[tokidx].X_add_number))
2210 goto match_failed;
2211 break;
2212 case AXP_OPERAND_IR | AXP_OPERAND_PARENS | AXP_OPERAND_COMMA:
2213 if (tok[tokidx].X_op != O_cpregister
2214 || !is_ir_num (tok[tokidx].X_add_number))
2215 goto match_failed;
2216 break;
2217
2218 case AXP_OPERAND_RELATIVE:
2219 case AXP_OPERAND_SIGNED:
2220 case AXP_OPERAND_UNSIGNED:
2221 switch (tok[tokidx].X_op)
2222 {
2223 case O_illegal:
2224 case O_absent:
2225 case O_register:
2226 case O_pregister:
2227 case O_cpregister:
2228 goto match_failed;
2229
2230 default:
2231 break;
2232 }
2233 break;
2234
2235 default:
2236 /* Everything else should have been fake. */
2237 abort ();
2238 }
2239 ++tokidx;
2240 }
2241
2242 /* Possible match -- did we use all of our input? */
2243 if (tokidx == ntok)
2244 {
2245 *pntok = ntok;
2246 return opcode;
2247 }
2248
2249 match_failed:;
2250 }
2251 while (++opcode - alpha_opcodes < (int) alpha_num_opcodes
2252 && !strcmp (opcode->name, first_opcode->name));
2253
2254 if (*pcpumatch)
2255 *pcpumatch = got_cpu_match;
2256
2257 return NULL;
2258 }
2259
2260 /* Search forward through all variants of a macro looking for a syntax
2261 match. */
2262
2263 static const struct alpha_macro *
2264 find_macro_match (first_macro, tok, pntok)
2265 const struct alpha_macro *first_macro;
2266 const expressionS *tok;
2267 int *pntok;
2268 {
2269 const struct alpha_macro *macro = first_macro;
2270 int ntok = *pntok;
2271
2272 do
2273 {
2274 const enum alpha_macro_arg *arg = macro->argsets;
2275 int tokidx = 0;
2276
2277 while (*arg)
2278 {
2279 switch (*arg)
2280 {
2281 case MACRO_EOA:
2282 if (tokidx == ntok)
2283 return macro;
2284 else
2285 tokidx = 0;
2286 break;
2287
2288 /* Index register. */
2289 case MACRO_IR:
2290 if (tokidx >= ntok || tok[tokidx].X_op != O_register
2291 || !is_ir_num (tok[tokidx].X_add_number))
2292 goto match_failed;
2293 ++tokidx;
2294 break;
2295
2296 /* Parenthesized index register. */
2297 case MACRO_PIR:
2298 if (tokidx >= ntok || tok[tokidx].X_op != O_pregister
2299 || !is_ir_num (tok[tokidx].X_add_number))
2300 goto match_failed;
2301 ++tokidx;
2302 break;
2303
2304 /* Optional parenthesized index register. */
2305 case MACRO_OPIR:
2306 if (tokidx < ntok && tok[tokidx].X_op == O_pregister
2307 && is_ir_num (tok[tokidx].X_add_number))
2308 ++tokidx;
2309 break;
2310
2311 /* Leading comma with a parenthesized index register. */
2312 case MACRO_CPIR:
2313 if (tokidx >= ntok || tok[tokidx].X_op != O_cpregister
2314 || !is_ir_num (tok[tokidx].X_add_number))
2315 goto match_failed;
2316 ++tokidx;
2317 break;
2318
2319 /* Floating point register. */
2320 case MACRO_FPR:
2321 if (tokidx >= ntok || tok[tokidx].X_op != O_register
2322 || !is_fpr_num (tok[tokidx].X_add_number))
2323 goto match_failed;
2324 ++tokidx;
2325 break;
2326
2327 /* Normal expression. */
2328 case MACRO_EXP:
2329 if (tokidx >= ntok)
2330 goto match_failed;
2331 switch (tok[tokidx].X_op)
2332 {
2333 case O_illegal:
2334 case O_absent:
2335 case O_register:
2336 case O_pregister:
2337 case O_cpregister:
2338 case O_literal:
2339 case O_lituse_base:
2340 case O_lituse_bytoff:
2341 case O_lituse_jsr:
2342 case O_gpdisp:
2343 case O_gprelhigh:
2344 case O_gprellow:
2345 case O_gprel:
2346 case O_samegp:
2347 goto match_failed;
2348
2349 default:
2350 break;
2351 }
2352 ++tokidx;
2353 break;
2354
2355 match_failed:
2356 while (*arg != MACRO_EOA)
2357 ++arg;
2358 tokidx = 0;
2359 break;
2360 }
2361 ++arg;
2362 }
2363 }
2364 while (++macro - alpha_macros < (int) alpha_num_macros
2365 && !strcmp (macro->name, first_macro->name));
2366
2367 return NULL;
2368 }
2369
2370 /* Insert an operand value into an instruction. */
2371
2372 static unsigned
2373 insert_operand (insn, operand, val, file, line)
2374 unsigned insn;
2375 const struct alpha_operand *operand;
2376 offsetT val;
2377 char *file;
2378 unsigned line;
2379 {
2380 if (operand->bits != 32 && !(operand->flags & AXP_OPERAND_NOOVERFLOW))
2381 {
2382 offsetT min, max;
2383
2384 if (operand->flags & AXP_OPERAND_SIGNED)
2385 {
2386 max = (1 << (operand->bits - 1)) - 1;
2387 min = -(1 << (operand->bits - 1));
2388 }
2389 else
2390 {
2391 max = (1 << operand->bits) - 1;
2392 min = 0;
2393 }
2394
2395 if (val < min || val > max)
2396 {
2397 const char *err =
2398 _("operand out of range (%s not between %d and %d)");
2399 char buf[sizeof (val) * 3 + 2];
2400
2401 sprint_value (buf, val);
2402 if (file)
2403 as_warn_where (file, line, err, buf, min, max);
2404 else
2405 as_warn (err, buf, min, max);
2406 }
2407 }
2408
2409 if (operand->insert)
2410 {
2411 const char *errmsg = NULL;
2412
2413 insn = (*operand->insert) (insn, val, &errmsg);
2414 if (errmsg)
2415 as_warn (errmsg);
2416 }
2417 else
2418 insn |= ((val & ((1 << operand->bits) - 1)) << operand->shift);
2419
2420 return insn;
2421 }
2422
2423 /* Turn an opcode description and a set of arguments into
2424 an instruction and a fixup. */
2425
2426 static void
2427 assemble_insn (opcode, tok, ntok, insn, reloc)
2428 const struct alpha_opcode *opcode;
2429 const expressionS *tok;
2430 int ntok;
2431 struct alpha_insn *insn;
2432 bfd_reloc_code_real_type reloc;
2433 {
2434 const struct alpha_operand *reloc_operand = NULL;
2435 const expressionS *reloc_exp = NULL;
2436 const unsigned char *argidx;
2437 unsigned image;
2438 int tokidx = 0;
2439
2440 memset (insn, 0, sizeof (*insn));
2441 image = opcode->opcode;
2442
2443 for (argidx = opcode->operands; *argidx; ++argidx)
2444 {
2445 const struct alpha_operand *operand = &alpha_operands[*argidx];
2446 const expressionS *t = (const expressionS *) 0;
2447
2448 if (operand->flags & AXP_OPERAND_FAKE)
2449 {
2450 /* fake operands take no value and generate no fixup */
2451 image = insert_operand (image, operand, 0, NULL, 0);
2452 continue;
2453 }
2454
2455 if (tokidx >= ntok)
2456 {
2457 switch (operand->flags & AXP_OPERAND_OPTIONAL_MASK)
2458 {
2459 case AXP_OPERAND_DEFAULT_FIRST:
2460 t = &tok[0];
2461 break;
2462 case AXP_OPERAND_DEFAULT_SECOND:
2463 t = &tok[1];
2464 break;
2465 case AXP_OPERAND_DEFAULT_ZERO:
2466 {
2467 static expressionS zero_exp;
2468 t = &zero_exp;
2469 zero_exp.X_op = O_constant;
2470 zero_exp.X_unsigned = 1;
2471 }
2472 break;
2473 default:
2474 abort ();
2475 }
2476 }
2477 else
2478 t = &tok[tokidx++];
2479
2480 switch (t->X_op)
2481 {
2482 case O_register:
2483 case O_pregister:
2484 case O_cpregister:
2485 image = insert_operand (image, operand, regno (t->X_add_number),
2486 NULL, 0);
2487 break;
2488
2489 case O_constant:
2490 image = insert_operand (image, operand, t->X_add_number, NULL, 0);
2491 assert (reloc_operand == NULL);
2492 reloc_operand = operand;
2493 reloc_exp = t;
2494 break;
2495
2496 default:
2497 /* This is only 0 for fields that should contain registers,
2498 which means this pattern shouldn't have matched. */
2499 if (operand->default_reloc == 0)
2500 abort ();
2501
2502 /* There is one special case for which an insn receives two
2503 relocations, and thus the user-supplied reloc does not
2504 override the operand reloc. */
2505 if (operand->default_reloc == BFD_RELOC_ALPHA_HINT)
2506 {
2507 struct alpha_fixup *fixup;
2508
2509 if (insn->nfixups >= MAX_INSN_FIXUPS)
2510 as_fatal (_("too many fixups"));
2511
2512 fixup = &insn->fixups[insn->nfixups++];
2513 fixup->exp = *t;
2514 fixup->reloc = BFD_RELOC_ALPHA_HINT;
2515 }
2516 else
2517 {
2518 if (reloc == BFD_RELOC_UNUSED)
2519 reloc = operand->default_reloc;
2520
2521 assert (reloc_operand == NULL);
2522 reloc_operand = operand;
2523 reloc_exp = t;
2524 }
2525 break;
2526 }
2527 }
2528
2529 if (reloc != BFD_RELOC_UNUSED)
2530 {
2531 struct alpha_fixup *fixup;
2532
2533 if (insn->nfixups >= MAX_INSN_FIXUPS)
2534 as_fatal (_("too many fixups"));
2535
2536 /* ??? My but this is hacky. But the OSF/1 assembler uses the same
2537 relocation tag for both ldah and lda with gpdisp. Choose the
2538 correct internal relocation based on the opcode. */
2539 if (reloc == BFD_RELOC_ALPHA_GPDISP)
2540 {
2541 if (strcmp (opcode->name, "ldah") == 0)
2542 reloc = BFD_RELOC_ALPHA_GPDISP_HI16;
2543 else if (strcmp (opcode->name, "lda") == 0)
2544 reloc = BFD_RELOC_ALPHA_GPDISP_LO16;
2545 else
2546 as_bad (_("invalid relocation for instruction"));
2547 }
2548
2549 /* If this is a real relocation (as opposed to a lituse hint), then
2550 the relocation width should match the operand width. */
2551 else if (reloc < BFD_RELOC_UNUSED)
2552 {
2553 reloc_howto_type *reloc_howto
2554 = bfd_reloc_type_lookup (stdoutput, reloc);
2555 if (reloc_howto->bitsize != reloc_operand->bits)
2556 {
2557 as_bad (_("invalid relocation for field"));
2558 return;
2559 }
2560 }
2561
2562 fixup = &insn->fixups[insn->nfixups++];
2563 if (reloc_exp)
2564 fixup->exp = *reloc_exp;
2565 else
2566 fixup->exp.X_op = O_absent;
2567 fixup->reloc = reloc;
2568 }
2569
2570 insn->insn = image;
2571 }
2572
2573 /* Actually output an instruction with its fixup. */
2574
2575 static void
2576 emit_insn (insn)
2577 struct alpha_insn *insn;
2578 {
2579 char *f;
2580 int i;
2581
2582 /* Take care of alignment duties. */
2583 if (alpha_auto_align_on && alpha_current_align < 2)
2584 alpha_align (2, (char *) NULL, alpha_insn_label, 0);
2585 if (alpha_current_align > 2)
2586 alpha_current_align = 2;
2587 alpha_insn_label = NULL;
2588
2589 /* Write out the instruction. */
2590 f = frag_more (4);
2591 md_number_to_chars (f, insn->insn, 4);
2592
2593 #ifdef OBJ_ELF
2594 dwarf2_emit_insn (4);
2595 #endif
2596
2597 /* Apply the fixups in order. */
2598 for (i = 0; i < insn->nfixups; ++i)
2599 {
2600 const struct alpha_operand *operand = (const struct alpha_operand *) 0;
2601 struct alpha_fixup *fixup = &insn->fixups[i];
2602 struct alpha_reloc_tag *info = NULL;
2603 int size, pcrel;
2604 fixS *fixP;
2605
2606 /* Some fixups are only used internally and so have no howto. */
2607 if ((int) fixup->reloc < 0)
2608 {
2609 operand = &alpha_operands[-(int) fixup->reloc];
2610 size = 4;
2611 pcrel = ((operand->flags & AXP_OPERAND_RELATIVE) != 0);
2612 }
2613 else if (fixup->reloc > BFD_RELOC_UNUSED
2614 || fixup->reloc == BFD_RELOC_ALPHA_GPDISP_HI16
2615 || fixup->reloc == BFD_RELOC_ALPHA_GPDISP_LO16)
2616 {
2617 size = 2;
2618 pcrel = 0;
2619 }
2620 else
2621 {
2622 reloc_howto_type *reloc_howto
2623 = bfd_reloc_type_lookup (stdoutput, fixup->reloc);
2624 assert (reloc_howto);
2625
2626 size = bfd_get_reloc_size (reloc_howto);
2627 assert (size >= 1 && size <= 4);
2628
2629 pcrel = reloc_howto->pc_relative;
2630 }
2631
2632 fixP = fix_new_exp (frag_now, f - frag_now->fr_literal, size,
2633 &fixup->exp, pcrel, fixup->reloc);
2634
2635 /* Turn off complaints that the addend is too large for some fixups,
2636 and copy in the sequence number for the explicit relocations. */
2637 switch (fixup->reloc)
2638 {
2639 case BFD_RELOC_ALPHA_HINT:
2640 case BFD_RELOC_GPREL32:
2641 case BFD_RELOC_GPREL16:
2642 case BFD_RELOC_ALPHA_GPREL_HI16:
2643 case BFD_RELOC_ALPHA_GPREL_LO16:
2644 case BFD_RELOC_ALPHA_GOTDTPREL16:
2645 case BFD_RELOC_ALPHA_DTPREL_HI16:
2646 case BFD_RELOC_ALPHA_DTPREL_LO16:
2647 case BFD_RELOC_ALPHA_DTPREL16:
2648 case BFD_RELOC_ALPHA_GOTTPREL16:
2649 case BFD_RELOC_ALPHA_TPREL_HI16:
2650 case BFD_RELOC_ALPHA_TPREL_LO16:
2651 case BFD_RELOC_ALPHA_TPREL16:
2652 fixP->fx_no_overflow = 1;
2653 break;
2654
2655 case BFD_RELOC_ALPHA_GPDISP_HI16:
2656 fixP->fx_no_overflow = 1;
2657 fixP->fx_addsy = section_symbol (now_seg);
2658 fixP->fx_offset = 0;
2659
2660 info = get_alpha_reloc_tag (insn->sequence);
2661 if (++info->n_master > 1)
2662 as_bad (_("too many ldah insns for !gpdisp!%ld"), insn->sequence);
2663 if (info->segment != now_seg)
2664 as_bad (_("both insns for !gpdisp!%ld must be in the same section"),
2665 insn->sequence);
2666 fixP->tc_fix_data.info = info;
2667 break;
2668
2669 case BFD_RELOC_ALPHA_GPDISP_LO16:
2670 fixP->fx_no_overflow = 1;
2671
2672 info = get_alpha_reloc_tag (insn->sequence);
2673 if (++info->n_slaves > 1)
2674 as_bad (_("too many lda insns for !gpdisp!%ld"), insn->sequence);
2675 if (info->segment != now_seg)
2676 as_bad (_("both insns for !gpdisp!%ld must be in the same section"),
2677 insn->sequence);
2678 fixP->tc_fix_data.info = info;
2679 info->slaves = fixP;
2680 break;
2681
2682 case BFD_RELOC_ALPHA_LITERAL:
2683 case BFD_RELOC_ALPHA_ELF_LITERAL:
2684 fixP->fx_no_overflow = 1;
2685
2686 if (insn->sequence == 0)
2687 break;
2688 info = get_alpha_reloc_tag (insn->sequence);
2689 info->master = fixP;
2690 info->n_master++;
2691 if (info->segment != now_seg)
2692 info->multi_section_p = 1;
2693 fixP->tc_fix_data.info = info;
2694 break;
2695
2696 #ifdef RELOC_OP_P
2697 case DUMMY_RELOC_LITUSE_ADDR:
2698 fixP->fx_offset = LITUSE_ALPHA_ADDR;
2699 goto do_lituse;
2700 case DUMMY_RELOC_LITUSE_BASE:
2701 fixP->fx_offset = LITUSE_ALPHA_BASE;
2702 goto do_lituse;
2703 case DUMMY_RELOC_LITUSE_BYTOFF:
2704 fixP->fx_offset = LITUSE_ALPHA_BYTOFF;
2705 goto do_lituse;
2706 case DUMMY_RELOC_LITUSE_JSR:
2707 fixP->fx_offset = LITUSE_ALPHA_JSR;
2708 goto do_lituse;
2709 case DUMMY_RELOC_LITUSE_TLSGD:
2710 fixP->fx_offset = LITUSE_ALPHA_TLSGD;
2711 goto do_lituse;
2712 case DUMMY_RELOC_LITUSE_TLSLDM:
2713 fixP->fx_offset = LITUSE_ALPHA_TLSLDM;
2714 goto do_lituse;
2715 do_lituse:
2716 fixP->fx_addsy = section_symbol (now_seg);
2717 fixP->fx_r_type = BFD_RELOC_ALPHA_LITUSE;
2718
2719 info = get_alpha_reloc_tag (insn->sequence);
2720 if (fixup->reloc == DUMMY_RELOC_LITUSE_TLSGD)
2721 info->saw_lu_tlsgd = 1;
2722 else if (fixup->reloc == DUMMY_RELOC_LITUSE_TLSLDM)
2723 info->saw_lu_tlsldm = 1;
2724 if (++info->n_slaves > 1)
2725 {
2726 if (info->saw_lu_tlsgd)
2727 as_bad (_("too many lituse insns for !lituse_tlsgd!%ld"),
2728 insn->sequence);
2729 else if (info->saw_lu_tlsldm)
2730 as_bad (_("too many lituse insns for !lituse_tlsldm!%ld"),
2731 insn->sequence);
2732 }
2733 fixP->tc_fix_data.info = info;
2734 fixP->tc_fix_data.next_reloc = info->slaves;
2735 info->slaves = fixP;
2736 if (info->segment != now_seg)
2737 info->multi_section_p = 1;
2738 break;
2739
2740 case BFD_RELOC_ALPHA_TLSGD:
2741 fixP->fx_no_overflow = 1;
2742
2743 if (insn->sequence == 0)
2744 break;
2745 info = get_alpha_reloc_tag (insn->sequence);
2746 if (info->saw_tlsgd)
2747 as_bad (_("duplicate !tlsgd!%ld"), insn->sequence);
2748 else if (info->saw_tlsldm)
2749 as_bad (_("sequence number in use for !tlsldm!%ld"),
2750 insn->sequence);
2751 else
2752 info->saw_tlsgd = 1;
2753 fixP->tc_fix_data.info = info;
2754 break;
2755
2756 case BFD_RELOC_ALPHA_TLSLDM:
2757 fixP->fx_no_overflow = 1;
2758
2759 if (insn->sequence == 0)
2760 break;
2761 info = get_alpha_reloc_tag (insn->sequence);
2762 if (info->saw_tlsldm)
2763 as_bad (_("duplicate !tlsldm!%ld"), insn->sequence);
2764 else if (info->saw_tlsgd)
2765 as_bad (_("sequence number in use for !tlsgd!%ld"),
2766 insn->sequence);
2767 else
2768 info->saw_tlsldm = 1;
2769 fixP->tc_fix_data.info = info;
2770 break;
2771 #endif
2772 default:
2773 if ((int) fixup->reloc < 0)
2774 {
2775 if (operand->flags & AXP_OPERAND_NOOVERFLOW)
2776 fixP->fx_no_overflow = 1;
2777 }
2778 break;
2779 }
2780 }
2781 }
2782
2783 /* Given an opcode name and a pre-tokenized set of arguments, assemble
2784 the insn, but do not emit it.
2785
2786 Note that this implies no macros allowed, since we can't store more
2787 than one insn in an insn structure. */
2788
2789 static void
2790 assemble_tokens_to_insn (opname, tok, ntok, insn)
2791 const char *opname;
2792 const expressionS *tok;
2793 int ntok;
2794 struct alpha_insn *insn;
2795 {
2796 const struct alpha_opcode *opcode;
2797
2798 /* search opcodes */
2799 opcode = (const struct alpha_opcode *) hash_find (alpha_opcode_hash, opname);
2800 if (opcode)
2801 {
2802 int cpumatch;
2803 opcode = find_opcode_match (opcode, tok, &ntok, &cpumatch);
2804 if (opcode)
2805 {
2806 assemble_insn (opcode, tok, ntok, insn, BFD_RELOC_UNUSED);
2807 return;
2808 }
2809 else if (cpumatch)
2810 as_bad (_("inappropriate arguments for opcode `%s'"), opname);
2811 else
2812 as_bad (_("opcode `%s' not supported for target %s"), opname,
2813 alpha_target_name);
2814 }
2815 else
2816 as_bad (_("unknown opcode `%s'"), opname);
2817 }
2818
2819 /* Given an opcode name and a pre-tokenized set of arguments, take the
2820 opcode all the way through emission. */
2821
2822 static void
2823 assemble_tokens (opname, tok, ntok, local_macros_on)
2824 const char *opname;
2825 const expressionS *tok;
2826 int ntok;
2827 int local_macros_on;
2828 {
2829 int found_something = 0;
2830 const struct alpha_opcode *opcode;
2831 const struct alpha_macro *macro;
2832 int cpumatch = 1;
2833 bfd_reloc_code_real_type reloc = BFD_RELOC_UNUSED;
2834
2835 #ifdef RELOC_OP_P
2836 /* If a user-specified relocation is present, this is not a macro. */
2837 if (ntok && USER_RELOC_P (tok[ntok - 1].X_op))
2838 {
2839 reloc = ALPHA_RELOC_TABLE (tok[ntok - 1].X_op)->reloc;
2840 ntok--;
2841 }
2842 else
2843 #endif
2844 if (local_macros_on)
2845 {
2846 macro = ((const struct alpha_macro *)
2847 hash_find (alpha_macro_hash, opname));
2848 if (macro)
2849 {
2850 found_something = 1;
2851 macro = find_macro_match (macro, tok, &ntok);
2852 if (macro)
2853 {
2854 (*macro->emit) (tok, ntok, macro->arg);
2855 return;
2856 }
2857 }
2858 }
2859
2860 /* Search opcodes. */
2861 opcode = (const struct alpha_opcode *) hash_find (alpha_opcode_hash, opname);
2862 if (opcode)
2863 {
2864 found_something = 1;
2865 opcode = find_opcode_match (opcode, tok, &ntok, &cpumatch);
2866 if (opcode)
2867 {
2868 struct alpha_insn insn;
2869 assemble_insn (opcode, tok, ntok, &insn, reloc);
2870
2871 /* Copy the sequence number for the reloc from the reloc token. */
2872 if (reloc != BFD_RELOC_UNUSED)
2873 insn.sequence = tok[ntok].X_add_number;
2874
2875 emit_insn (&insn);
2876 return;
2877 }
2878 }
2879
2880 if (found_something)
2881 {
2882 if (cpumatch)
2883 as_bad (_("inappropriate arguments for opcode `%s'"), opname);
2884 else
2885 as_bad (_("opcode `%s' not supported for target %s"), opname,
2886 alpha_target_name);
2887 }
2888 else
2889 as_bad (_("unknown opcode `%s'"), opname);
2890 }
2891 \f
2892 /* Some instruction sets indexed by lg(size). */
2893 static const char * const sextX_op[] = { "sextb", "sextw", "sextl", NULL };
2894 static const char * const insXl_op[] = { "insbl", "inswl", "insll", "insql" };
2895 static const char * const insXh_op[] = { NULL, "inswh", "inslh", "insqh" };
2896 static const char * const extXl_op[] = { "extbl", "extwl", "extll", "extql" };
2897 static const char * const extXh_op[] = { NULL, "extwh", "extlh", "extqh" };
2898 static const char * const mskXl_op[] = { "mskbl", "mskwl", "mskll", "mskql" };
2899 static const char * const mskXh_op[] = { NULL, "mskwh", "msklh", "mskqh" };
2900 static const char * const stX_op[] = { "stb", "stw", "stl", "stq" };
2901 static const char * const ldXu_op[] = { "ldbu", "ldwu", NULL, NULL };
2902
2903 /* Implement the ldgp macro. */
2904
2905 static void
2906 emit_ldgp (tok, ntok, unused)
2907 const expressionS *tok;
2908 int ntok ATTRIBUTE_UNUSED;
2909 const PTR unused ATTRIBUTE_UNUSED;
2910 {
2911 #ifdef OBJ_AOUT
2912 FIXME
2913 #endif
2914 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
2915 /* from "ldgp r1,n(r2)", generate "ldah r1,X(R2); lda r1,Y(r1)"
2916 with appropriate constants and relocations. */
2917 struct alpha_insn insn;
2918 expressionS newtok[3];
2919 expressionS addend;
2920
2921 #ifdef OBJ_ECOFF
2922 if (regno (tok[2].X_add_number) == AXP_REG_PV)
2923 ecoff_set_gp_prolog_size (0);
2924 #endif
2925
2926 newtok[0] = tok[0];
2927 set_tok_const (newtok[1], 0);
2928 newtok[2] = tok[2];
2929
2930 assemble_tokens_to_insn ("ldah", newtok, 3, &insn);
2931
2932 addend = tok[1];
2933
2934 #ifdef OBJ_ECOFF
2935 if (addend.X_op != O_constant)
2936 as_bad (_("can not resolve expression"));
2937 addend.X_op = O_symbol;
2938 addend.X_add_symbol = alpha_gp_symbol;
2939 #endif
2940
2941 insn.nfixups = 1;
2942 insn.fixups[0].exp = addend;
2943 insn.fixups[0].reloc = BFD_RELOC_ALPHA_GPDISP_HI16;
2944 insn.sequence = next_sequence_num;
2945
2946 emit_insn (&insn);
2947
2948 set_tok_preg (newtok[2], tok[0].X_add_number);
2949
2950 assemble_tokens_to_insn ("lda", newtok, 3, &insn);
2951
2952 #ifdef OBJ_ECOFF
2953 addend.X_add_number += 4;
2954 #endif
2955
2956 insn.nfixups = 1;
2957 insn.fixups[0].exp = addend;
2958 insn.fixups[0].reloc = BFD_RELOC_ALPHA_GPDISP_LO16;
2959 insn.sequence = next_sequence_num--;
2960
2961 emit_insn (&insn);
2962 #endif /* OBJ_ECOFF || OBJ_ELF */
2963 }
2964
2965 #ifdef OBJ_EVAX
2966
2967 /* Add symbol+addend to link pool.
2968 Return offset from basesym to entry in link pool.
2969
2970 Add new fixup only if offset isn't 16bit. */
2971
2972 valueT
2973 add_to_link_pool (basesym, sym, addend)
2974 symbolS *basesym;
2975 symbolS *sym;
2976 offsetT addend;
2977 {
2978 segT current_section = now_seg;
2979 int current_subsec = now_subseg;
2980 valueT offset;
2981 bfd_reloc_code_real_type reloc_type;
2982 char *p;
2983 segment_info_type *seginfo = seg_info (alpha_link_section);
2984 fixS *fixp;
2985
2986 offset = - *symbol_get_obj (basesym);
2987
2988 /* @@ This assumes all entries in a given section will be of the same
2989 size... Probably correct, but unwise to rely on. */
2990 /* This must always be called with the same subsegment. */
2991
2992 if (seginfo->frchainP)
2993 for (fixp = seginfo->frchainP->fix_root;
2994 fixp != (fixS *) NULL;
2995 fixp = fixp->fx_next, offset += 8)
2996 {
2997 if (fixp->fx_addsy == sym && fixp->fx_offset == addend)
2998 {
2999 if (range_signed_16 (offset))
3000 {
3001 return offset;
3002 }
3003 }
3004 }
3005
3006 /* Not found in 16bit signed range. */
3007
3008 subseg_set (alpha_link_section, 0);
3009 p = frag_more (8);
3010 memset (p, 0, 8);
3011
3012 fix_new (frag_now, p - frag_now->fr_literal, 8, sym, addend, 0,
3013 BFD_RELOC_64);
3014
3015 subseg_set (current_section, current_subsec);
3016 seginfo->literal_pool_size += 8;
3017 return offset;
3018 }
3019
3020 #endif /* OBJ_EVAX */
3021
3022 /* Load a (partial) expression into a target register.
3023
3024 If poffset is not null, after the call it will either contain
3025 O_constant 0, or a 16-bit offset appropriate for any MEM format
3026 instruction. In addition, pbasereg will be modified to point to
3027 the base register to use in that MEM format instruction.
3028
3029 In any case, *pbasereg should contain a base register to add to the
3030 expression. This will normally be either AXP_REG_ZERO or
3031 alpha_gp_register. Symbol addresses will always be loaded via $gp,
3032 so "foo($0)" is interpreted as adding the address of foo to $0;
3033 i.e. "ldq $targ, LIT($gp); addq $targ, $0, $targ". Odd, perhaps,
3034 but this is what OSF/1 does.
3035
3036 If explicit relocations of the form !literal!<number> are allowed,
3037 and used, then explict_reloc with be an expression pointer.
3038
3039 Finally, the return value is nonzero if the calling macro may emit
3040 a LITUSE reloc if otherwise appropriate; the return value is the
3041 sequence number to use. */
3042
3043 static long
3044 load_expression (targreg, exp, pbasereg, poffset)
3045 int targreg;
3046 const expressionS *exp;
3047 int *pbasereg;
3048 expressionS *poffset;
3049 {
3050 long emit_lituse = 0;
3051 offsetT addend = exp->X_add_number;
3052 int basereg = *pbasereg;
3053 struct alpha_insn insn;
3054 expressionS newtok[3];
3055
3056 switch (exp->X_op)
3057 {
3058 case O_symbol:
3059 {
3060 #ifdef OBJ_ECOFF
3061 offsetT lit;
3062
3063 /* Attempt to reduce .lit load by splitting the offset from
3064 its symbol when possible, but don't create a situation in
3065 which we'd fail. */
3066 if (!range_signed_32 (addend) &&
3067 (alpha_noat_on || targreg == AXP_REG_AT))
3068 {
3069 lit = add_to_literal_pool (exp->X_add_symbol, addend,
3070 alpha_lita_section, 8);
3071 addend = 0;
3072 }
3073 else
3074 {
3075 lit = add_to_literal_pool (exp->X_add_symbol, 0,
3076 alpha_lita_section, 8);
3077 }
3078
3079 if (lit >= 0x8000)
3080 as_fatal (_("overflow in literal (.lita) table"));
3081
3082 /* emit "ldq r, lit(gp)" */
3083
3084 if (basereg != alpha_gp_register && targreg == basereg)
3085 {
3086 if (alpha_noat_on)
3087 as_bad (_("macro requires $at register while noat in effect"));
3088 if (targreg == AXP_REG_AT)
3089 as_bad (_("macro requires $at while $at in use"));
3090
3091 set_tok_reg (newtok[0], AXP_REG_AT);
3092 }
3093 else
3094 set_tok_reg (newtok[0], targreg);
3095 set_tok_sym (newtok[1], alpha_lita_symbol, lit);
3096 set_tok_preg (newtok[2], alpha_gp_register);
3097
3098 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
3099
3100 assert (insn.nfixups == 1);
3101 insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITERAL;
3102 insn.sequence = emit_lituse = next_sequence_num--;
3103 #endif /* OBJ_ECOFF */
3104 #ifdef OBJ_ELF
3105 /* emit "ldq r, gotoff(gp)" */
3106
3107 if (basereg != alpha_gp_register && targreg == basereg)
3108 {
3109 if (alpha_noat_on)
3110 as_bad (_("macro requires $at register while noat in effect"));
3111 if (targreg == AXP_REG_AT)
3112 as_bad (_("macro requires $at while $at in use"));
3113
3114 set_tok_reg (newtok[0], AXP_REG_AT);
3115 }
3116 else
3117 set_tok_reg (newtok[0], targreg);
3118
3119 /* XXX: Disable this .got minimizing optimization so that we can get
3120 better instruction offset knowledge in the compiler. This happens
3121 very infrequently anyway. */
3122 if (1
3123 || (!range_signed_32 (addend)
3124 && (alpha_noat_on || targreg == AXP_REG_AT)))
3125 {
3126 newtok[1] = *exp;
3127 addend = 0;
3128 }
3129 else
3130 {
3131 set_tok_sym (newtok[1], exp->X_add_symbol, 0);
3132 }
3133
3134 set_tok_preg (newtok[2], alpha_gp_register);
3135
3136 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
3137
3138 assert (insn.nfixups == 1);
3139 insn.fixups[0].reloc = BFD_RELOC_ALPHA_ELF_LITERAL;
3140 insn.sequence = emit_lituse = next_sequence_num--;
3141 #endif /* OBJ_ELF */
3142 #ifdef OBJ_EVAX
3143 offsetT link;
3144
3145 /* Find symbol or symbol pointer in link section. */
3146
3147 if (exp->X_add_symbol == alpha_evax_proc.symbol)
3148 {
3149 if (range_signed_16 (addend))
3150 {
3151 set_tok_reg (newtok[0], targreg);
3152 set_tok_const (newtok[1], addend);
3153 set_tok_preg (newtok[2], basereg);
3154 assemble_tokens_to_insn ("lda", newtok, 3, &insn);
3155 addend = 0;
3156 }
3157 else
3158 {
3159 set_tok_reg (newtok[0], targreg);
3160 set_tok_const (newtok[1], 0);
3161 set_tok_preg (newtok[2], basereg);
3162 assemble_tokens_to_insn ("lda", newtok, 3, &insn);
3163 }
3164 }
3165 else
3166 {
3167 if (!range_signed_32 (addend))
3168 {
3169 link = add_to_link_pool (alpha_evax_proc.symbol,
3170 exp->X_add_symbol, addend);
3171 addend = 0;
3172 }
3173 else
3174 {
3175 link = add_to_link_pool (alpha_evax_proc.symbol,
3176 exp->X_add_symbol, 0);
3177 }
3178 set_tok_reg (newtok[0], targreg);
3179 set_tok_const (newtok[1], link);
3180 set_tok_preg (newtok[2], basereg);
3181 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
3182 }
3183 #endif /* OBJ_EVAX */
3184
3185 emit_insn (&insn);
3186
3187 #ifndef OBJ_EVAX
3188 if (basereg != alpha_gp_register && basereg != AXP_REG_ZERO)
3189 {
3190 /* emit "addq r, base, r" */
3191
3192 set_tok_reg (newtok[1], basereg);
3193 set_tok_reg (newtok[2], targreg);
3194 assemble_tokens ("addq", newtok, 3, 0);
3195 }
3196 #endif
3197
3198 basereg = targreg;
3199 }
3200 break;
3201
3202 case O_constant:
3203 break;
3204
3205 case O_subtract:
3206 /* Assume that this difference expression will be resolved to an
3207 absolute value and that that value will fit in 16 bits. */
3208
3209 set_tok_reg (newtok[0], targreg);
3210 newtok[1] = *exp;
3211 set_tok_preg (newtok[2], basereg);
3212 assemble_tokens ("lda", newtok, 3, 0);
3213
3214 if (poffset)
3215 set_tok_const (*poffset, 0);
3216 return 0;
3217
3218 case O_big:
3219 if (exp->X_add_number > 0)
3220 as_bad (_("bignum invalid; zero assumed"));
3221 else
3222 as_bad (_("floating point number invalid; zero assumed"));
3223 addend = 0;
3224 break;
3225
3226 default:
3227 as_bad (_("can't handle expression"));
3228 addend = 0;
3229 break;
3230 }
3231
3232 if (!range_signed_32 (addend))
3233 {
3234 offsetT lit;
3235 long seq_num = next_sequence_num--;
3236
3237 /* For 64-bit addends, just put it in the literal pool. */
3238
3239 #ifdef OBJ_EVAX
3240 /* emit "ldq targreg, lit(basereg)" */
3241 lit = add_to_link_pool (alpha_evax_proc.symbol,
3242 section_symbol (absolute_section), addend);
3243 set_tok_reg (newtok[0], targreg);
3244 set_tok_const (newtok[1], lit);
3245 set_tok_preg (newtok[2], alpha_gp_register);
3246 assemble_tokens ("ldq", newtok, 3, 0);
3247 #else
3248
3249 if (alpha_lit8_section == NULL)
3250 {
3251 create_literal_section (".lit8",
3252 &alpha_lit8_section,
3253 &alpha_lit8_symbol);
3254
3255 #ifdef OBJ_ECOFF
3256 alpha_lit8_literal = add_to_literal_pool (alpha_lit8_symbol, 0x8000,
3257 alpha_lita_section, 8);
3258 if (alpha_lit8_literal >= 0x8000)
3259 as_fatal (_("overflow in literal (.lita) table"));
3260 #endif
3261 }
3262
3263 lit = add_to_literal_pool (NULL, addend, alpha_lit8_section, 8) - 0x8000;
3264 if (lit >= 0x8000)
3265 as_fatal (_("overflow in literal (.lit8) table"));
3266
3267 /* emit "lda litreg, .lit8+0x8000" */
3268
3269 if (targreg == basereg)
3270 {
3271 if (alpha_noat_on)
3272 as_bad (_("macro requires $at register while noat in effect"));
3273 if (targreg == AXP_REG_AT)
3274 as_bad (_("macro requires $at while $at in use"));
3275
3276 set_tok_reg (newtok[0], AXP_REG_AT);
3277 }
3278 else
3279 set_tok_reg (newtok[0], targreg);
3280 #ifdef OBJ_ECOFF
3281 set_tok_sym (newtok[1], alpha_lita_symbol, alpha_lit8_literal);
3282 #endif
3283 #ifdef OBJ_ELF
3284 set_tok_sym (newtok[1], alpha_lit8_symbol, 0x8000);
3285 #endif
3286 set_tok_preg (newtok[2], alpha_gp_register);
3287
3288 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
3289
3290 assert (insn.nfixups == 1);
3291 #ifdef OBJ_ECOFF
3292 insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITERAL;
3293 #endif
3294 #ifdef OBJ_ELF
3295 insn.fixups[0].reloc = BFD_RELOC_ALPHA_ELF_LITERAL;
3296 #endif
3297 insn.sequence = seq_num;
3298
3299 emit_insn (&insn);
3300
3301 /* emit "ldq litreg, lit(litreg)" */
3302
3303 set_tok_const (newtok[1], lit);
3304 set_tok_preg (newtok[2], newtok[0].X_add_number);
3305
3306 assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
3307
3308 assert (insn.nfixups < MAX_INSN_FIXUPS);
3309 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
3310 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3311 insn.nfixups++;
3312 insn.sequence = seq_num;
3313 emit_lituse = 0;
3314
3315 emit_insn (&insn);
3316
3317 /* emit "addq litreg, base, target" */
3318
3319 if (basereg != AXP_REG_ZERO)
3320 {
3321 set_tok_reg (newtok[1], basereg);
3322 set_tok_reg (newtok[2], targreg);
3323 assemble_tokens ("addq", newtok, 3, 0);
3324 }
3325 #endif /* !OBJ_EVAX */
3326
3327 if (poffset)
3328 set_tok_const (*poffset, 0);
3329 *pbasereg = targreg;
3330 }
3331 else
3332 {
3333 offsetT low, high, extra, tmp;
3334
3335 /* for 32-bit operands, break up the addend */
3336
3337 low = sign_extend_16 (addend);
3338 tmp = addend - low;
3339 high = sign_extend_16 (tmp >> 16);
3340
3341 if (tmp - (high << 16))
3342 {
3343 extra = 0x4000;
3344 tmp -= 0x40000000;
3345 high = sign_extend_16 (tmp >> 16);
3346 }
3347 else
3348 extra = 0;
3349
3350 set_tok_reg (newtok[0], targreg);
3351 set_tok_preg (newtok[2], basereg);
3352
3353 if (extra)
3354 {
3355 /* emit "ldah r, extra(r) */
3356 set_tok_const (newtok[1], extra);
3357 assemble_tokens ("ldah", newtok, 3, 0);
3358 set_tok_preg (newtok[2], basereg = targreg);
3359 }
3360
3361 if (high)
3362 {
3363 /* emit "ldah r, high(r) */
3364 set_tok_const (newtok[1], high);
3365 assemble_tokens ("ldah", newtok, 3, 0);
3366 basereg = targreg;
3367 set_tok_preg (newtok[2], basereg);
3368 }
3369
3370 if ((low && !poffset) || (!poffset && basereg != targreg))
3371 {
3372 /* emit "lda r, low(base)" */
3373 set_tok_const (newtok[1], low);
3374 assemble_tokens ("lda", newtok, 3, 0);
3375 basereg = targreg;
3376 low = 0;
3377 }
3378
3379 if (poffset)
3380 set_tok_const (*poffset, low);
3381 *pbasereg = basereg;
3382 }
3383
3384 return emit_lituse;
3385 }
3386
3387 /* The lda macro differs from the lda instruction in that it handles
3388 most simple expressions, particualrly symbol address loads and
3389 large constants. */
3390
3391 static void
3392 emit_lda (tok, ntok, unused)
3393 const expressionS *tok;
3394 int ntok;
3395 const PTR unused ATTRIBUTE_UNUSED;
3396 {
3397 int basereg;
3398
3399 if (ntok == 2)
3400 basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
3401 else
3402 basereg = tok[2].X_add_number;
3403
3404 (void) load_expression (tok[0].X_add_number, &tok[1], &basereg, NULL);
3405 }
3406
3407 /* The ldah macro differs from the ldah instruction in that it has $31
3408 as an implied base register. */
3409
3410 static void
3411 emit_ldah (tok, ntok, unused)
3412 const expressionS *tok;
3413 int ntok ATTRIBUTE_UNUSED;
3414 const PTR unused ATTRIBUTE_UNUSED;
3415 {
3416 expressionS newtok[3];
3417
3418 newtok[0] = tok[0];
3419 newtok[1] = tok[1];
3420 set_tok_preg (newtok[2], AXP_REG_ZERO);
3421
3422 assemble_tokens ("ldah", newtok, 3, 0);
3423 }
3424
3425 /* Handle all "simple" integer register loads -- ldq, ldq_l, ldq_u,
3426 etc. They differ from the real instructions in that they do simple
3427 expressions like the lda macro. */
3428
3429 static void
3430 emit_ir_load (tok, ntok, opname)
3431 const expressionS *tok;
3432 int ntok;
3433 const PTR opname;
3434 {
3435 int basereg;
3436 long lituse;
3437 expressionS newtok[3];
3438 struct alpha_insn insn;
3439
3440 if (ntok == 2)
3441 basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
3442 else
3443 basereg = tok[2].X_add_number;
3444
3445 lituse = load_expression (tok[0].X_add_number, &tok[1], &basereg,
3446 &newtok[1]);
3447
3448 newtok[0] = tok[0];
3449 set_tok_preg (newtok[2], basereg);
3450
3451 assemble_tokens_to_insn ((const char *) opname, newtok, 3, &insn);
3452
3453 if (lituse)
3454 {
3455 assert (insn.nfixups < MAX_INSN_FIXUPS);
3456 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
3457 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3458 insn.nfixups++;
3459 insn.sequence = lituse;
3460 }
3461
3462 emit_insn (&insn);
3463 }
3464
3465 /* Handle fp register loads, and both integer and fp register stores.
3466 Again, we handle simple expressions. */
3467
3468 static void
3469 emit_loadstore (tok, ntok, opname)
3470 const expressionS *tok;
3471 int ntok;
3472 const PTR opname;
3473 {
3474 int basereg;
3475 long lituse;
3476 expressionS newtok[3];
3477 struct alpha_insn insn;
3478
3479 if (ntok == 2)
3480 basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
3481 else
3482 basereg = tok[2].X_add_number;
3483
3484 if (tok[1].X_op != O_constant || !range_signed_16 (tok[1].X_add_number))
3485 {
3486 if (alpha_noat_on)
3487 as_bad (_("macro requires $at register while noat in effect"));
3488
3489 lituse = load_expression (AXP_REG_AT, &tok[1], &basereg, &newtok[1]);
3490 }
3491 else
3492 {
3493 newtok[1] = tok[1];
3494 lituse = 0;
3495 }
3496
3497 newtok[0] = tok[0];
3498 set_tok_preg (newtok[2], basereg);
3499
3500 assemble_tokens_to_insn ((const char *) opname, newtok, 3, &insn);
3501
3502 if (lituse)
3503 {
3504 assert (insn.nfixups < MAX_INSN_FIXUPS);
3505 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
3506 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3507 insn.nfixups++;
3508 insn.sequence = lituse;
3509 }
3510
3511 emit_insn (&insn);
3512 }
3513
3514 /* Load a half-word or byte as an unsigned value. */
3515
3516 static void
3517 emit_ldXu (tok, ntok, vlgsize)
3518 const expressionS *tok;
3519 int ntok;
3520 const PTR vlgsize;
3521 {
3522 if (alpha_target & AXP_OPCODE_BWX)
3523 emit_ir_load (tok, ntok, ldXu_op[(long) vlgsize]);
3524 else
3525 {
3526 expressionS newtok[3];
3527 struct alpha_insn insn;
3528 int basereg;
3529 long lituse;
3530
3531 if (alpha_noat_on)
3532 as_bad (_("macro requires $at register while noat in effect"));
3533
3534 if (ntok == 2)
3535 basereg = (tok[1].X_op == O_constant
3536 ? AXP_REG_ZERO : alpha_gp_register);
3537 else
3538 basereg = tok[2].X_add_number;
3539
3540 /* emit "lda $at, exp" */
3541
3542 lituse = load_expression (AXP_REG_AT, &tok[1], &basereg, NULL);
3543
3544 /* emit "ldq_u targ, 0($at)" */
3545
3546 newtok[0] = tok[0];
3547 set_tok_const (newtok[1], 0);
3548 set_tok_preg (newtok[2], basereg);
3549 assemble_tokens_to_insn ("ldq_u", newtok, 3, &insn);
3550
3551 if (lituse)
3552 {
3553 assert (insn.nfixups < MAX_INSN_FIXUPS);
3554 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
3555 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3556 insn.nfixups++;
3557 insn.sequence = lituse;
3558 }
3559
3560 emit_insn (&insn);
3561
3562 /* emit "extXl targ, $at, targ" */
3563
3564 set_tok_reg (newtok[1], basereg);
3565 newtok[2] = newtok[0];
3566 assemble_tokens_to_insn (extXl_op[(long) vlgsize], newtok, 3, &insn);
3567
3568 if (lituse)
3569 {
3570 assert (insn.nfixups < MAX_INSN_FIXUPS);
3571 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF;
3572 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3573 insn.nfixups++;
3574 insn.sequence = lituse;
3575 }
3576
3577 emit_insn (&insn);
3578 }
3579 }
3580
3581 /* Load a half-word or byte as a signed value. */
3582
3583 static void
3584 emit_ldX (tok, ntok, vlgsize)
3585 const expressionS *tok;
3586 int ntok;
3587 const PTR vlgsize;
3588 {
3589 emit_ldXu (tok, ntok, vlgsize);
3590 assemble_tokens (sextX_op[(long) vlgsize], tok, 1, 1);
3591 }
3592
3593 /* Load an integral value from an unaligned address as an unsigned
3594 value. */
3595
3596 static void
3597 emit_uldXu (tok, ntok, vlgsize)
3598 const expressionS *tok;
3599 int ntok;
3600 const PTR vlgsize;
3601 {
3602 long lgsize = (long) vlgsize;
3603 expressionS newtok[3];
3604
3605 if (alpha_noat_on)
3606 as_bad (_("macro requires $at register while noat in effect"));
3607
3608 /* emit "lda $at, exp" */
3609
3610 memcpy (newtok, tok, sizeof (expressionS) * ntok);
3611 newtok[0].X_add_number = AXP_REG_AT;
3612 assemble_tokens ("lda", newtok, ntok, 1);
3613
3614 /* emit "ldq_u $t9, 0($at)" */
3615
3616 set_tok_reg (newtok[0], AXP_REG_T9);
3617 set_tok_const (newtok[1], 0);
3618 set_tok_preg (newtok[2], AXP_REG_AT);
3619 assemble_tokens ("ldq_u", newtok, 3, 1);
3620
3621 /* emit "ldq_u $t10, size-1($at)" */
3622
3623 set_tok_reg (newtok[0], AXP_REG_T10);
3624 set_tok_const (newtok[1], (1 << lgsize) - 1);
3625 assemble_tokens ("ldq_u", newtok, 3, 1);
3626
3627 /* emit "extXl $t9, $at, $t9" */
3628
3629 set_tok_reg (newtok[0], AXP_REG_T9);
3630 set_tok_reg (newtok[1], AXP_REG_AT);
3631 set_tok_reg (newtok[2], AXP_REG_T9);
3632 assemble_tokens (extXl_op[lgsize], newtok, 3, 1);
3633
3634 /* emit "extXh $t10, $at, $t10" */
3635
3636 set_tok_reg (newtok[0], AXP_REG_T10);
3637 set_tok_reg (newtok[2], AXP_REG_T10);
3638 assemble_tokens (extXh_op[lgsize], newtok, 3, 1);
3639
3640 /* emit "or $t9, $t10, targ" */
3641
3642 set_tok_reg (newtok[0], AXP_REG_T9);
3643 set_tok_reg (newtok[1], AXP_REG_T10);
3644 newtok[2] = tok[0];
3645 assemble_tokens ("or", newtok, 3, 1);
3646 }
3647
3648 /* Load an integral value from an unaligned address as a signed value.
3649 Note that quads should get funneled to the unsigned load since we
3650 don't have to do the sign extension. */
3651
3652 static void
3653 emit_uldX (tok, ntok, vlgsize)
3654 const expressionS *tok;
3655 int ntok;
3656 const PTR vlgsize;
3657 {
3658 emit_uldXu (tok, ntok, vlgsize);
3659 assemble_tokens (sextX_op[(long) vlgsize], tok, 1, 1);
3660 }
3661
3662 /* Implement the ldil macro. */
3663
3664 static void
3665 emit_ldil (tok, ntok, unused)
3666 const expressionS *tok;
3667 int ntok;
3668 const PTR unused ATTRIBUTE_UNUSED;
3669 {
3670 expressionS newtok[2];
3671
3672 memcpy (newtok, tok, sizeof (newtok));
3673 newtok[1].X_add_number = sign_extend_32 (tok[1].X_add_number);
3674
3675 assemble_tokens ("lda", newtok, ntok, 1);
3676 }
3677
3678 /* Store a half-word or byte. */
3679
3680 static void
3681 emit_stX (tok, ntok, vlgsize)
3682 const expressionS *tok;
3683 int ntok;
3684 const PTR vlgsize;
3685 {
3686 int lgsize = (int) (long) vlgsize;
3687
3688 if (alpha_target & AXP_OPCODE_BWX)
3689 emit_loadstore (tok, ntok, stX_op[lgsize]);
3690 else
3691 {
3692 expressionS newtok[3];
3693 struct alpha_insn insn;
3694 int basereg;
3695 long lituse;
3696
3697 if (alpha_noat_on)
3698 as_bad (_("macro requires $at register while noat in effect"));
3699
3700 if (ntok == 2)
3701 basereg = (tok[1].X_op == O_constant
3702 ? AXP_REG_ZERO : alpha_gp_register);
3703 else
3704 basereg = tok[2].X_add_number;
3705
3706 /* emit "lda $at, exp" */
3707
3708 lituse = load_expression (AXP_REG_AT, &tok[1], &basereg, NULL);
3709
3710 /* emit "ldq_u $t9, 0($at)" */
3711
3712 set_tok_reg (newtok[0], AXP_REG_T9);
3713 set_tok_const (newtok[1], 0);
3714 set_tok_preg (newtok[2], basereg);
3715 assemble_tokens_to_insn ("ldq_u", newtok, 3, &insn);
3716
3717 if (lituse)
3718 {
3719 assert (insn.nfixups < MAX_INSN_FIXUPS);
3720 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
3721 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3722 insn.nfixups++;
3723 insn.sequence = lituse;
3724 }
3725
3726 emit_insn (&insn);
3727
3728 /* emit "insXl src, $at, $t10" */
3729
3730 newtok[0] = tok[0];
3731 set_tok_reg (newtok[1], basereg);
3732 set_tok_reg (newtok[2], AXP_REG_T10);
3733 assemble_tokens_to_insn (insXl_op[lgsize], newtok, 3, &insn);
3734
3735 if (lituse)
3736 {
3737 assert (insn.nfixups < MAX_INSN_FIXUPS);
3738 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF;
3739 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3740 insn.nfixups++;
3741 insn.sequence = lituse;
3742 }
3743
3744 emit_insn (&insn);
3745
3746 /* emit "mskXl $t9, $at, $t9" */
3747
3748 set_tok_reg (newtok[0], AXP_REG_T9);
3749 newtok[2] = newtok[0];
3750 assemble_tokens_to_insn (mskXl_op[lgsize], newtok, 3, &insn);
3751
3752 if (lituse)
3753 {
3754 assert (insn.nfixups < MAX_INSN_FIXUPS);
3755 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF;
3756 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3757 insn.nfixups++;
3758 insn.sequence = lituse;
3759 }
3760
3761 emit_insn (&insn);
3762
3763 /* emit "or $t9, $t10, $t9" */
3764
3765 set_tok_reg (newtok[1], AXP_REG_T10);
3766 assemble_tokens ("or", newtok, 3, 1);
3767
3768 /* emit "stq_u $t9, 0($at) */
3769
3770 set_tok_const(newtok[1], 0);
3771 set_tok_preg (newtok[2], AXP_REG_AT);
3772 assemble_tokens_to_insn ("stq_u", newtok, 3, &insn);
3773
3774 if (lituse)
3775 {
3776 assert (insn.nfixups < MAX_INSN_FIXUPS);
3777 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
3778 insn.fixups[insn.nfixups].exp.X_op = O_absent;
3779 insn.nfixups++;
3780 insn.sequence = lituse;
3781 }
3782
3783 emit_insn (&insn);
3784 }
3785 }
3786
3787 /* Store an integer to an unaligned address. */
3788
3789 static void
3790 emit_ustX (tok, ntok, vlgsize)
3791 const expressionS *tok;
3792 int ntok;
3793 const PTR vlgsize;
3794 {
3795 int lgsize = (int) (long) vlgsize;
3796 expressionS newtok[3];
3797
3798 /* emit "lda $at, exp" */
3799
3800 memcpy (newtok, tok, sizeof (expressionS) * ntok);
3801 newtok[0].X_add_number = AXP_REG_AT;
3802 assemble_tokens ("lda", newtok, ntok, 1);
3803
3804 /* emit "ldq_u $9, 0($at)" */
3805
3806 set_tok_reg (newtok[0], AXP_REG_T9);
3807 set_tok_const (newtok[1], 0);
3808 set_tok_preg (newtok[2], AXP_REG_AT);
3809 assemble_tokens ("ldq_u", newtok, 3, 1);
3810
3811 /* emit "ldq_u $10, size-1($at)" */
3812
3813 set_tok_reg (newtok[0], AXP_REG_T10);
3814 set_tok_const (newtok[1], (1 << lgsize) - 1);
3815 assemble_tokens ("ldq_u", newtok, 3, 1);
3816
3817 /* emit "insXl src, $at, $t11" */
3818
3819 newtok[0] = tok[0];
3820 set_tok_reg (newtok[1], AXP_REG_AT);
3821 set_tok_reg (newtok[2], AXP_REG_T11);
3822 assemble_tokens (insXl_op[lgsize], newtok, 3, 1);
3823
3824 /* emit "insXh src, $at, $t12" */
3825
3826 set_tok_reg (newtok[2], AXP_REG_T12);
3827 assemble_tokens (insXh_op[lgsize], newtok, 3, 1);
3828
3829 /* emit "mskXl $t9, $at, $t9" */
3830
3831 set_tok_reg (newtok[0], AXP_REG_T9);
3832 newtok[2] = newtok[0];
3833 assemble_tokens (mskXl_op[lgsize], newtok, 3, 1);
3834
3835 /* emit "mskXh $t10, $at, $t10" */
3836
3837 set_tok_reg (newtok[0], AXP_REG_T10);
3838 newtok[2] = newtok[0];
3839 assemble_tokens (mskXh_op[lgsize], newtok, 3, 1);
3840
3841 /* emit "or $t9, $t11, $t9" */
3842
3843 set_tok_reg (newtok[0], AXP_REG_T9);
3844 set_tok_reg (newtok[1], AXP_REG_T11);
3845 newtok[2] = newtok[0];
3846 assemble_tokens ("or", newtok, 3, 1);
3847
3848 /* emit "or $t10, $t12, $t10" */
3849
3850 set_tok_reg (newtok[0], AXP_REG_T10);
3851 set_tok_reg (newtok[1], AXP_REG_T12);
3852 newtok[2] = newtok[0];
3853 assemble_tokens ("or", newtok, 3, 1);
3854
3855 /* emit "stq_u $t9, 0($at)" */
3856
3857 set_tok_reg (newtok[0], AXP_REG_T9);
3858 set_tok_const (newtok[1], 0);
3859 set_tok_preg (newtok[2], AXP_REG_AT);
3860 assemble_tokens ("stq_u", newtok, 3, 1);
3861
3862 /* emit "stq_u $t10, size-1($at)" */
3863
3864 set_tok_reg (newtok[0], AXP_REG_T10);
3865 set_tok_const (newtok[1], (1 << lgsize) - 1);
3866 assemble_tokens ("stq_u", newtok, 3, 1);
3867 }
3868
3869 /* Sign extend a half-word or byte. The 32-bit sign extend is
3870 implemented as "addl $31, $r, $t" in the opcode table. */
3871
3872 static void
3873 emit_sextX (tok, ntok, vlgsize)
3874 const expressionS *tok;
3875 int ntok;
3876 const PTR vlgsize;
3877 {
3878 long lgsize = (long) vlgsize;
3879
3880 if (alpha_target & AXP_OPCODE_BWX)
3881 assemble_tokens (sextX_op[lgsize], tok, ntok, 0);
3882 else
3883 {
3884 int bitshift = 64 - 8 * (1 << lgsize);
3885 expressionS newtok[3];
3886
3887 /* emit "sll src,bits,dst" */
3888
3889 newtok[0] = tok[0];
3890 set_tok_const (newtok[1], bitshift);
3891 newtok[2] = tok[ntok - 1];
3892 assemble_tokens ("sll", newtok, 3, 1);
3893
3894 /* emit "sra dst,bits,dst" */
3895
3896 newtok[0] = newtok[2];
3897 assemble_tokens ("sra", newtok, 3, 1);
3898 }
3899 }
3900
3901 /* Implement the division and modulus macros. */
3902
3903 #ifdef OBJ_EVAX
3904
3905 /* Make register usage like in normal procedure call.
3906 Don't clobber PV and RA. */
3907
3908 static void
3909 emit_division (tok, ntok, symname)
3910 const expressionS *tok;
3911 int ntok;
3912 const PTR symname;
3913 {
3914 /* DIVISION and MODULUS. Yech.
3915
3916 Convert
3917 OP x,y,result
3918 to
3919 mov x,R16 # if x != R16
3920 mov y,R17 # if y != R17
3921 lda AT,__OP
3922 jsr AT,(AT),0
3923 mov R0,result
3924
3925 with appropriate optimizations if R0,R16,R17 are the registers
3926 specified by the compiler. */
3927
3928 int xr, yr, rr;
3929 symbolS *sym;
3930 expressionS newtok[3];
3931
3932 xr = regno (tok[0].X_add_number);
3933 yr = regno (tok[1].X_add_number);
3934
3935 if (ntok < 3)
3936 rr = xr;
3937 else
3938 rr = regno (tok[2].X_add_number);
3939
3940 /* Move the operands into the right place. */
3941 if (yr == AXP_REG_R16 && xr == AXP_REG_R17)
3942 {
3943 /* They are in exactly the wrong order -- swap through AT. */
3944
3945 if (alpha_noat_on)
3946 as_bad (_("macro requires $at register while noat in effect"));
3947
3948 set_tok_reg (newtok[0], AXP_REG_R16);
3949 set_tok_reg (newtok[1], AXP_REG_AT);
3950 assemble_tokens ("mov", newtok, 2, 1);
3951
3952 set_tok_reg (newtok[0], AXP_REG_R17);
3953 set_tok_reg (newtok[1], AXP_REG_R16);
3954 assemble_tokens ("mov", newtok, 2, 1);
3955
3956 set_tok_reg (newtok[0], AXP_REG_AT);
3957 set_tok_reg (newtok[1], AXP_REG_R17);
3958 assemble_tokens ("mov", newtok, 2, 1);
3959 }
3960 else
3961 {
3962 if (yr == AXP_REG_R16)
3963 {
3964 set_tok_reg (newtok[0], AXP_REG_R16);
3965 set_tok_reg (newtok[1], AXP_REG_R17);
3966 assemble_tokens ("mov", newtok, 2, 1);
3967 }
3968
3969 if (xr != AXP_REG_R16)
3970 {
3971 set_tok_reg (newtok[0], xr);
3972 set_tok_reg (newtok[1], AXP_REG_R16);
3973 assemble_tokens ("mov", newtok, 2, 1);
3974 }
3975
3976 if (yr != AXP_REG_R16 && yr != AXP_REG_R17)
3977 {
3978 set_tok_reg (newtok[0], yr);
3979 set_tok_reg (newtok[1], AXP_REG_R17);
3980 assemble_tokens ("mov", newtok, 2, 1);
3981 }
3982 }
3983
3984 sym = symbol_find_or_make ((const char *) symname);
3985
3986 set_tok_reg (newtok[0], AXP_REG_AT);
3987 set_tok_sym (newtok[1], sym, 0);
3988 assemble_tokens ("lda", newtok, 2, 1);
3989
3990 /* Call the division routine. */
3991 set_tok_reg (newtok[0], AXP_REG_AT);
3992 set_tok_cpreg (newtok[1], AXP_REG_AT);
3993 set_tok_const (newtok[2], 0);
3994 assemble_tokens ("jsr", newtok, 3, 1);
3995
3996 /* Move the result to the right place. */
3997 if (rr != AXP_REG_R0)
3998 {
3999 set_tok_reg (newtok[0], AXP_REG_R0);
4000 set_tok_reg (newtok[1], rr);
4001 assemble_tokens ("mov", newtok, 2, 1);
4002 }
4003 }
4004
4005 #else /* !OBJ_EVAX */
4006
4007 static void
4008 emit_division (tok, ntok, symname)
4009 const expressionS *tok;
4010 int ntok;
4011 const PTR symname;
4012 {
4013 /* DIVISION and MODULUS. Yech.
4014 Convert
4015 OP x,y,result
4016 to
4017 lda pv,__OP
4018 mov x,t10
4019 mov y,t11
4020 jsr t9,(pv),__OP
4021 mov t12,result
4022
4023 with appropriate optimizations if t10,t11,t12 are the registers
4024 specified by the compiler. */
4025
4026 int xr, yr, rr;
4027 symbolS *sym;
4028 expressionS newtok[3];
4029
4030 xr = regno (tok[0].X_add_number);
4031 yr = regno (tok[1].X_add_number);
4032
4033 if (ntok < 3)
4034 rr = xr;
4035 else
4036 rr = regno (tok[2].X_add_number);
4037
4038 sym = symbol_find_or_make ((const char *) symname);
4039
4040 /* Move the operands into the right place. */
4041 if (yr == AXP_REG_T10 && xr == AXP_REG_T11)
4042 {
4043 /* They are in exactly the wrong order -- swap through AT. */
4044 if (alpha_noat_on)
4045 as_bad (_("macro requires $at register while noat in effect"));
4046
4047 set_tok_reg (newtok[0], AXP_REG_T10);
4048 set_tok_reg (newtok[1], AXP_REG_AT);
4049 assemble_tokens ("mov", newtok, 2, 1);
4050
4051 set_tok_reg (newtok[0], AXP_REG_T11);
4052 set_tok_reg (newtok[1], AXP_REG_T10);
4053 assemble_tokens ("mov", newtok, 2, 1);
4054
4055 set_tok_reg (newtok[0], AXP_REG_AT);
4056 set_tok_reg (newtok[1], AXP_REG_T11);
4057 assemble_tokens ("mov", newtok, 2, 1);
4058 }
4059 else
4060 {
4061 if (yr == AXP_REG_T10)
4062 {
4063 set_tok_reg (newtok[0], AXP_REG_T10);
4064 set_tok_reg (newtok[1], AXP_REG_T11);
4065 assemble_tokens ("mov", newtok, 2, 1);
4066 }
4067
4068 if (xr != AXP_REG_T10)
4069 {
4070 set_tok_reg (newtok[0], xr);
4071 set_tok_reg (newtok[1], AXP_REG_T10);
4072 assemble_tokens ("mov", newtok, 2, 1);
4073 }
4074
4075 if (yr != AXP_REG_T10 && yr != AXP_REG_T11)
4076 {
4077 set_tok_reg (newtok[0], yr);
4078 set_tok_reg (newtok[1], AXP_REG_T11);
4079 assemble_tokens ("mov", newtok, 2, 1);
4080 }
4081 }
4082
4083 /* Call the division routine. */
4084 set_tok_reg (newtok[0], AXP_REG_T9);
4085 set_tok_sym (newtok[1], sym, 0);
4086 assemble_tokens ("jsr", newtok, 2, 1);
4087
4088 /* Reload the GP register. */
4089 #ifdef OBJ_AOUT
4090 FIXME
4091 #endif
4092 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
4093 set_tok_reg (newtok[0], alpha_gp_register);
4094 set_tok_const (newtok[1], 0);
4095 set_tok_preg (newtok[2], AXP_REG_T9);
4096 assemble_tokens ("ldgp", newtok, 3, 1);
4097 #endif
4098
4099 /* Move the result to the right place. */
4100 if (rr != AXP_REG_T12)
4101 {
4102 set_tok_reg (newtok[0], AXP_REG_T12);
4103 set_tok_reg (newtok[1], rr);
4104 assemble_tokens ("mov", newtok, 2, 1);
4105 }
4106 }
4107
4108 #endif /* !OBJ_EVAX */
4109
4110 /* The jsr and jmp macros differ from their instruction counterparts
4111 in that they can load the target address and default most
4112 everything. */
4113
4114 static void
4115 emit_jsrjmp (tok, ntok, vopname)
4116 const expressionS *tok;
4117 int ntok;
4118 const PTR vopname;
4119 {
4120 const char *opname = (const char *) vopname;
4121 struct alpha_insn insn;
4122 expressionS newtok[3];
4123 int r, tokidx = 0;
4124 long lituse = 0;
4125
4126 if (tokidx < ntok && tok[tokidx].X_op == O_register)
4127 r = regno (tok[tokidx++].X_add_number);
4128 else
4129 r = strcmp (opname, "jmp") == 0 ? AXP_REG_ZERO : AXP_REG_RA;
4130
4131 set_tok_reg (newtok[0], r);
4132
4133 if (tokidx < ntok &&
4134 (tok[tokidx].X_op == O_pregister || tok[tokidx].X_op == O_cpregister))
4135 r = regno (tok[tokidx++].X_add_number);
4136 #ifdef OBJ_EVAX
4137 /* keep register if jsr $n.<sym> */
4138 #else
4139 else
4140 {
4141 int basereg = alpha_gp_register;
4142 lituse = load_expression (r = AXP_REG_PV, &tok[tokidx], &basereg, NULL);
4143 }
4144 #endif
4145
4146 set_tok_cpreg (newtok[1], r);
4147
4148 #ifdef OBJ_EVAX
4149 /* FIXME: Add hint relocs to BFD for evax. */
4150 #else
4151 if (tokidx < ntok)
4152 newtok[2] = tok[tokidx];
4153 else
4154 #endif
4155 set_tok_const (newtok[2], 0);
4156
4157 assemble_tokens_to_insn (opname, newtok, 3, &insn);
4158
4159 if (lituse)
4160 {
4161 assert (insn.nfixups < MAX_INSN_FIXUPS);
4162 insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_JSR;
4163 insn.fixups[insn.nfixups].exp.X_op = O_absent;
4164 insn.nfixups++;
4165 insn.sequence = lituse;
4166 }
4167
4168 emit_insn (&insn);
4169 }
4170
4171 /* The ret and jcr instructions differ from their instruction
4172 counterparts in that everything can be defaulted. */
4173
4174 static void
4175 emit_retjcr (tok, ntok, vopname)
4176 const expressionS *tok;
4177 int ntok;
4178 const PTR vopname;
4179 {
4180 const char *opname = (const char *) vopname;
4181 expressionS newtok[3];
4182 int r, tokidx = 0;
4183
4184 if (tokidx < ntok && tok[tokidx].X_op == O_register)
4185 r = regno (tok[tokidx++].X_add_number);
4186 else
4187 r = AXP_REG_ZERO;
4188
4189 set_tok_reg (newtok[0], r);
4190
4191 if (tokidx < ntok &&
4192 (tok[tokidx].X_op == O_pregister || tok[tokidx].X_op == O_cpregister))
4193 r = regno (tok[tokidx++].X_add_number);
4194 else
4195 r = AXP_REG_RA;
4196
4197 set_tok_cpreg (newtok[1], r);
4198
4199 if (tokidx < ntok)
4200 newtok[2] = tok[tokidx];
4201 else
4202 set_tok_const (newtok[2], strcmp (opname, "ret") == 0);
4203
4204 assemble_tokens (opname, newtok, 3, 0);
4205 }
4206 \f
4207 /* Assembler directives. */
4208
4209 /* Handle the .text pseudo-op. This is like the usual one, but it
4210 clears alpha_insn_label and restores auto alignment. */
4211
4212 static void
4213 s_alpha_text (i)
4214 int i;
4215
4216 {
4217 #ifdef OBJ_ELF
4218 obj_elf_text (i);
4219 #else
4220 s_text (i);
4221 #endif
4222 alpha_insn_label = NULL;
4223 alpha_auto_align_on = 1;
4224 alpha_current_align = 0;
4225 }
4226
4227 /* Handle the .data pseudo-op. This is like the usual one, but it
4228 clears alpha_insn_label and restores auto alignment. */
4229
4230 static void
4231 s_alpha_data (i)
4232 int i;
4233 {
4234 #ifdef OBJ_ELF
4235 obj_elf_data (i);
4236 #else
4237 s_data (i);
4238 #endif
4239 alpha_insn_label = NULL;
4240 alpha_auto_align_on = 1;
4241 alpha_current_align = 0;
4242 }
4243
4244 #if defined (OBJ_ECOFF) || defined (OBJ_EVAX)
4245
4246 /* Handle the OSF/1 and openVMS .comm pseudo quirks.
4247 openVMS constructs a section for every common symbol. */
4248
4249 static void
4250 s_alpha_comm (ignore)
4251 int ignore ATTRIBUTE_UNUSED;
4252 {
4253 register char *name;
4254 register char c;
4255 register char *p;
4256 offsetT temp;
4257 register symbolS *symbolP;
4258
4259 #ifdef OBJ_EVAX
4260 segT current_section = now_seg;
4261 int current_subsec = now_subseg;
4262 segT new_seg;
4263 #endif
4264
4265 name = input_line_pointer;
4266 c = get_symbol_end ();
4267
4268 /* just after name is now '\0' */
4269 p = input_line_pointer;
4270 *p = c;
4271
4272 SKIP_WHITESPACE ();
4273
4274 /* Alpha OSF/1 compiler doesn't provide the comma, gcc does. */
4275 if (*input_line_pointer == ',')
4276 {
4277 input_line_pointer++;
4278 SKIP_WHITESPACE ();
4279 }
4280 if ((temp = get_absolute_expression ()) < 0)
4281 {
4282 as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) temp);
4283 ignore_rest_of_line ();
4284 return;
4285 }
4286
4287 *p = 0;
4288 symbolP = symbol_find_or_make (name);
4289
4290 #ifdef OBJ_EVAX
4291 /* Make a section for the common symbol. */
4292 new_seg = subseg_new (xstrdup (name), 0);
4293 #endif
4294
4295 *p = c;
4296
4297 #ifdef OBJ_EVAX
4298 /* alignment might follow */
4299 if (*input_line_pointer == ',')
4300 {
4301 offsetT align;
4302
4303 input_line_pointer++;
4304 align = get_absolute_expression ();
4305 bfd_set_section_alignment (stdoutput, new_seg, align);
4306 }
4307 #endif
4308
4309 if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
4310 {
4311 as_bad (_("Ignoring attempt to re-define symbol"));
4312 ignore_rest_of_line ();
4313 return;
4314 }
4315
4316 #ifdef OBJ_EVAX
4317 if (bfd_section_size (stdoutput, new_seg) > 0)
4318 {
4319 if (bfd_section_size (stdoutput, new_seg) != temp)
4320 as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
4321 S_GET_NAME (symbolP),
4322 (long) bfd_section_size (stdoutput, new_seg),
4323 (long) temp);
4324 }
4325 #else
4326 if (S_GET_VALUE (symbolP))
4327 {
4328 if (S_GET_VALUE (symbolP) != (valueT) temp)
4329 as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
4330 S_GET_NAME (symbolP),
4331 (long) S_GET_VALUE (symbolP),
4332 (long) temp);
4333 }
4334 #endif
4335 else
4336 {
4337 #ifdef OBJ_EVAX
4338 subseg_set (new_seg, 0);
4339 p = frag_more (temp);
4340 new_seg->flags |= SEC_IS_COMMON;
4341 if (! S_IS_DEFINED (symbolP))
4342 S_SET_SEGMENT (symbolP, new_seg);
4343 #else
4344 S_SET_VALUE (symbolP, (valueT) temp);
4345 #endif
4346 S_SET_EXTERNAL (symbolP);
4347 }
4348
4349 #ifdef OBJ_EVAX
4350 subseg_set (current_section, current_subsec);
4351 #endif
4352
4353 know (symbol_get_frag (symbolP) == &zero_address_frag);
4354
4355 demand_empty_rest_of_line ();
4356 }
4357
4358 #endif /* ! OBJ_ELF */
4359
4360 #ifdef OBJ_ECOFF
4361
4362 /* Handle the .rdata pseudo-op. This is like the usual one, but it
4363 clears alpha_insn_label and restores auto alignment. */
4364
4365 static void
4366 s_alpha_rdata (ignore)
4367 int ignore ATTRIBUTE_UNUSED;
4368 {
4369 int temp;
4370
4371 temp = get_absolute_expression ();
4372 subseg_new (".rdata", 0);
4373 demand_empty_rest_of_line ();
4374 alpha_insn_label = NULL;
4375 alpha_auto_align_on = 1;
4376 alpha_current_align = 0;
4377 }
4378
4379 #endif
4380
4381 #ifdef OBJ_ECOFF
4382
4383 /* Handle the .sdata pseudo-op. This is like the usual one, but it
4384 clears alpha_insn_label and restores auto alignment. */
4385
4386 static void
4387 s_alpha_sdata (ignore)
4388 int ignore ATTRIBUTE_UNUSED;
4389 {
4390 int temp;
4391
4392 temp = get_absolute_expression ();
4393 subseg_new (".sdata", 0);
4394 demand_empty_rest_of_line ();
4395 alpha_insn_label = NULL;
4396 alpha_auto_align_on = 1;
4397 alpha_current_align = 0;
4398 }
4399 #endif
4400
4401 #ifdef OBJ_ELF
4402
4403 /* Handle the .section pseudo-op. This is like the usual one, but it
4404 clears alpha_insn_label and restores auto alignment. */
4405
4406 static void
4407 s_alpha_section (ignore)
4408 int ignore ATTRIBUTE_UNUSED;
4409 {
4410 obj_elf_section (ignore);
4411
4412 alpha_insn_label = NULL;
4413 alpha_auto_align_on = 1;
4414 alpha_current_align = 0;
4415 }
4416
4417 static void
4418 s_alpha_ent (dummy)
4419 int dummy ATTRIBUTE_UNUSED;
4420 {
4421 if (ECOFF_DEBUGGING)
4422 ecoff_directive_ent (0);
4423 else
4424 {
4425 char *name, name_end;
4426 name = input_line_pointer;
4427 name_end = get_symbol_end ();
4428
4429 if (! is_name_beginner (*name))
4430 {
4431 as_warn (_(".ent directive has no name"));
4432 *input_line_pointer = name_end;
4433 }
4434 else
4435 {
4436 symbolS *sym;
4437
4438 if (alpha_cur_ent_sym)
4439 as_warn (_("nested .ent directives"));
4440
4441 sym = symbol_find_or_make (name);
4442 symbol_get_bfdsym (sym)->flags |= BSF_FUNCTION;
4443 alpha_cur_ent_sym = sym;
4444
4445 /* The .ent directive is sometimes followed by a number. Not sure
4446 what it really means, but ignore it. */
4447 *input_line_pointer = name_end;
4448 SKIP_WHITESPACE ();
4449 if (*input_line_pointer == ',')
4450 {
4451 input_line_pointer++;
4452 SKIP_WHITESPACE ();
4453 }
4454 if (ISDIGIT (*input_line_pointer) || *input_line_pointer == '-')
4455 (void) get_absolute_expression ();
4456 }
4457 demand_empty_rest_of_line ();
4458 }
4459 }
4460
4461 static void
4462 s_alpha_end (dummy)
4463 int dummy ATTRIBUTE_UNUSED;
4464 {
4465 if (ECOFF_DEBUGGING)
4466 ecoff_directive_end (0);
4467 else
4468 {
4469 char *name, name_end;
4470 name = input_line_pointer;
4471 name_end = get_symbol_end ();
4472
4473 if (! is_name_beginner (*name))
4474 {
4475 as_warn (_(".end directive has no name"));
4476 *input_line_pointer = name_end;
4477 }
4478 else
4479 {
4480 symbolS *sym;
4481
4482 sym = symbol_find (name);
4483 if (sym != alpha_cur_ent_sym)
4484 as_warn (_(".end directive names different symbol than .ent"));
4485
4486 /* Create an expression to calculate the size of the function. */
4487 if (sym)
4488 {
4489 symbol_get_obj (sym)->size =
4490 (expressionS *) xmalloc (sizeof (expressionS));
4491 symbol_get_obj (sym)->size->X_op = O_subtract;
4492 symbol_get_obj (sym)->size->X_add_symbol
4493 = symbol_new ("L0\001", now_seg, frag_now_fix (), frag_now);
4494 symbol_get_obj (sym)->size->X_op_symbol = sym;
4495 symbol_get_obj (sym)->size->X_add_number = 0;
4496 }
4497
4498 alpha_cur_ent_sym = NULL;
4499
4500 *input_line_pointer = name_end;
4501 }
4502 demand_empty_rest_of_line ();
4503 }
4504 }
4505
4506 static void
4507 s_alpha_mask (fp)
4508 int fp;
4509 {
4510 if (ECOFF_DEBUGGING)
4511 {
4512 if (fp)
4513 ecoff_directive_fmask (0);
4514 else
4515 ecoff_directive_mask (0);
4516 }
4517 else
4518 discard_rest_of_line ();
4519 }
4520
4521 static void
4522 s_alpha_frame (dummy)
4523 int dummy ATTRIBUTE_UNUSED;
4524 {
4525 if (ECOFF_DEBUGGING)
4526 ecoff_directive_frame (0);
4527 else
4528 discard_rest_of_line ();
4529 }
4530
4531 static void
4532 s_alpha_prologue (ignore)
4533 int ignore ATTRIBUTE_UNUSED;
4534 {
4535 symbolS *sym;
4536 int arg;
4537
4538 arg = get_absolute_expression ();
4539 demand_empty_rest_of_line ();
4540
4541 if (ECOFF_DEBUGGING)
4542 sym = ecoff_get_cur_proc_sym ();
4543 else
4544 sym = alpha_cur_ent_sym;
4545 know (sym != NULL);
4546
4547 switch (arg)
4548 {
4549 case 0: /* No PV required. */
4550 S_SET_OTHER (sym, STO_ALPHA_NOPV
4551 | (S_GET_OTHER (sym) & ~STO_ALPHA_STD_GPLOAD));
4552 break;
4553 case 1: /* Std GP load. */
4554 S_SET_OTHER (sym, STO_ALPHA_STD_GPLOAD
4555 | (S_GET_OTHER (sym) & ~STO_ALPHA_STD_GPLOAD));
4556 break;
4557 case 2: /* Non-std use of PV. */
4558 break;
4559
4560 default:
4561 as_bad (_("Invalid argument %d to .prologue."), arg);
4562 break;
4563 }
4564 }
4565
4566 static char *first_file_directive;
4567
4568 static void
4569 s_alpha_file (ignore)
4570 int ignore ATTRIBUTE_UNUSED;
4571 {
4572 /* Save the first .file directive we see, so that we can change our
4573 minds about whether ecoff debugging should or shouldn't be enabled. */
4574 if (alpha_flag_mdebug < 0 && ! first_file_directive)
4575 {
4576 char *start = input_line_pointer;
4577 size_t len;
4578
4579 discard_rest_of_line ();
4580
4581 len = input_line_pointer - start;
4582 first_file_directive = xmalloc (len + 1);
4583 memcpy (first_file_directive, start, len);
4584 first_file_directive[len] = '\0';
4585
4586 input_line_pointer = start;
4587 }
4588
4589 if (ECOFF_DEBUGGING)
4590 ecoff_directive_file (0);
4591 else
4592 dwarf2_directive_file (0);
4593 }
4594
4595 static void
4596 s_alpha_loc (ignore)
4597 int ignore ATTRIBUTE_UNUSED;
4598 {
4599 if (ECOFF_DEBUGGING)
4600 ecoff_directive_loc (0);
4601 else
4602 dwarf2_directive_loc (0);
4603 }
4604
4605 static void
4606 s_alpha_stab (n)
4607 int n;
4608 {
4609 /* If we've been undecided about mdebug, make up our minds in favour. */
4610 if (alpha_flag_mdebug < 0)
4611 {
4612 segT sec = subseg_new (".mdebug", 0);
4613 bfd_set_section_flags (stdoutput, sec, SEC_HAS_CONTENTS | SEC_READONLY);
4614 bfd_set_section_alignment (stdoutput, sec, 3);
4615
4616 ecoff_read_begin_hook ();
4617
4618 if (first_file_directive)
4619 {
4620 char *save_ilp = input_line_pointer;
4621 input_line_pointer = first_file_directive;
4622 ecoff_directive_file (0);
4623 input_line_pointer = save_ilp;
4624 free (first_file_directive);
4625 }
4626
4627 alpha_flag_mdebug = 1;
4628 }
4629 s_stab (n);
4630 }
4631
4632 static void
4633 s_alpha_coff_wrapper (which)
4634 int which;
4635 {
4636 static void (* const fns[]) PARAMS ((int)) = {
4637 ecoff_directive_begin,
4638 ecoff_directive_bend,
4639 ecoff_directive_def,
4640 ecoff_directive_dim,
4641 ecoff_directive_endef,
4642 ecoff_directive_scl,
4643 ecoff_directive_tag,
4644 ecoff_directive_val,
4645 };
4646
4647 assert (which >= 0 && which < (int) (sizeof (fns)/sizeof (*fns)));
4648
4649 if (ECOFF_DEBUGGING)
4650 (*fns[which]) (0);
4651 else
4652 {
4653 as_bad (_("ECOFF debugging is disabled."));
4654 ignore_rest_of_line ();
4655 }
4656 }
4657 #endif /* OBJ_ELF */
4658
4659 #ifdef OBJ_EVAX
4660
4661 /* Handle the section specific pseudo-op. */
4662
4663 static void
4664 s_alpha_section (secid)
4665 int secid;
4666 {
4667 int temp;
4668 #define EVAX_SECTION_COUNT 5
4669 static char *section_name[EVAX_SECTION_COUNT + 1] =
4670 { "NULL", ".rdata", ".comm", ".link", ".ctors", ".dtors" };
4671
4672 if ((secid <= 0) || (secid > EVAX_SECTION_COUNT))
4673 {
4674 as_fatal (_("Unknown section directive"));
4675 demand_empty_rest_of_line ();
4676 return;
4677 }
4678 temp = get_absolute_expression ();
4679 subseg_new (section_name[secid], 0);
4680 demand_empty_rest_of_line ();
4681 alpha_insn_label = NULL;
4682 alpha_auto_align_on = 1;
4683 alpha_current_align = 0;
4684 }
4685
4686 /* Parse .ent directives. */
4687
4688 static void
4689 s_alpha_ent (ignore)
4690 int ignore ATTRIBUTE_UNUSED;
4691 {
4692 symbolS *symbol;
4693 expressionS symexpr;
4694
4695 alpha_evax_proc.pdsckind = 0;
4696 alpha_evax_proc.framereg = -1;
4697 alpha_evax_proc.framesize = 0;
4698 alpha_evax_proc.rsa_offset = 0;
4699 alpha_evax_proc.ra_save = AXP_REG_RA;
4700 alpha_evax_proc.fp_save = -1;
4701 alpha_evax_proc.imask = 0;
4702 alpha_evax_proc.fmask = 0;
4703 alpha_evax_proc.prologue = 0;
4704 alpha_evax_proc.type = 0;
4705
4706 expression (&symexpr);
4707
4708 if (symexpr.X_op != O_symbol)
4709 {
4710 as_fatal (_(".ent directive has no symbol"));
4711 demand_empty_rest_of_line ();
4712 return;
4713 }
4714
4715 symbol = make_expr_symbol (&symexpr);
4716 symbol_get_bfdsym (symbol)->flags |= BSF_FUNCTION;
4717 alpha_evax_proc.symbol = symbol;
4718
4719 demand_empty_rest_of_line ();
4720 return;
4721 }
4722
4723 /* Parse .frame <framreg>,<framesize>,RA,<rsa_offset> directives. */
4724
4725 static void
4726 s_alpha_frame (ignore)
4727 int ignore ATTRIBUTE_UNUSED;
4728 {
4729 long val;
4730
4731 alpha_evax_proc.framereg = tc_get_register (1);
4732
4733 SKIP_WHITESPACE ();
4734 if (*input_line_pointer++ != ','
4735 || get_absolute_expression_and_terminator (&val) != ',')
4736 {
4737 as_warn (_("Bad .frame directive 1./2. param"));
4738 --input_line_pointer;
4739 demand_empty_rest_of_line ();
4740 return;
4741 }
4742
4743 alpha_evax_proc.framesize = val;
4744
4745 (void) tc_get_register (1);
4746 SKIP_WHITESPACE ();
4747 if (*input_line_pointer++ != ',')
4748 {
4749 as_warn (_("Bad .frame directive 3./4. param"));
4750 --input_line_pointer;
4751 demand_empty_rest_of_line ();
4752 return;
4753 }
4754 alpha_evax_proc.rsa_offset = get_absolute_expression ();
4755
4756 return;
4757 }
4758
4759 static void
4760 s_alpha_pdesc (ignore)
4761 int ignore ATTRIBUTE_UNUSED;
4762 {
4763 char *name;
4764 char name_end;
4765 long val;
4766 register char *p;
4767 expressionS exp;
4768 symbolS *entry_sym;
4769 fixS *fixp;
4770 segment_info_type *seginfo = seg_info (alpha_link_section);
4771
4772 if (now_seg != alpha_link_section)
4773 {
4774 as_bad (_(".pdesc directive not in link (.link) section"));
4775 demand_empty_rest_of_line ();
4776 return;
4777 }
4778
4779 if ((alpha_evax_proc.symbol == 0)
4780 || (!S_IS_DEFINED (alpha_evax_proc.symbol)))
4781 {
4782 as_fatal (_(".pdesc has no matching .ent"));
4783 demand_empty_rest_of_line ();
4784 return;
4785 }
4786
4787 *symbol_get_obj (alpha_evax_proc.symbol) =
4788 (valueT) seginfo->literal_pool_size;
4789
4790 expression (&exp);
4791 if (exp.X_op != O_symbol)
4792 {
4793 as_warn (_(".pdesc directive has no entry symbol"));
4794 demand_empty_rest_of_line ();
4795 return;
4796 }
4797
4798 entry_sym = make_expr_symbol (&exp);
4799 /* Save bfd symbol of proc desc in function symbol. */
4800 symbol_get_bfdsym (alpha_evax_proc.symbol)->udata.p
4801 = symbol_get_bfdsym (entry_sym);
4802
4803 SKIP_WHITESPACE ();
4804 if (*input_line_pointer++ != ',')
4805 {
4806 as_warn (_("No comma after .pdesc <entryname>"));
4807 demand_empty_rest_of_line ();
4808 return;
4809 }
4810
4811 SKIP_WHITESPACE ();
4812 name = input_line_pointer;
4813 name_end = get_symbol_end ();
4814
4815 if (strncmp (name, "stack", 5) == 0)
4816 {
4817 alpha_evax_proc.pdsckind = PDSC_S_K_KIND_FP_STACK;
4818 }
4819 else if (strncmp (name, "reg", 3) == 0)
4820 {
4821 alpha_evax_proc.pdsckind = PDSC_S_K_KIND_FP_REGISTER;
4822 }
4823 else if (strncmp (name, "null", 4) == 0)
4824 {
4825 alpha_evax_proc.pdsckind = PDSC_S_K_KIND_NULL;
4826 }
4827 else
4828 {
4829 as_fatal (_("unknown procedure kind"));
4830 demand_empty_rest_of_line ();
4831 return;
4832 }
4833
4834 *input_line_pointer = name_end;
4835 demand_empty_rest_of_line ();
4836
4837 #ifdef md_flush_pending_output
4838 md_flush_pending_output ();
4839 #endif
4840
4841 frag_align (3, 0, 0);
4842 p = frag_more (16);
4843 fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
4844 fixp->fx_done = 1;
4845 seginfo->literal_pool_size += 16;
4846
4847 *p = alpha_evax_proc.pdsckind
4848 | ((alpha_evax_proc.framereg == 29) ? PDSC_S_M_BASE_REG_IS_FP : 0);
4849 *(p + 1) = PDSC_S_M_NATIVE | PDSC_S_M_NO_JACKET;
4850
4851 switch (alpha_evax_proc.pdsckind)
4852 {
4853 case PDSC_S_K_KIND_NULL:
4854 *(p + 2) = 0;
4855 *(p + 3) = 0;
4856 break;
4857 case PDSC_S_K_KIND_FP_REGISTER:
4858 *(p + 2) = alpha_evax_proc.fp_save;
4859 *(p + 3) = alpha_evax_proc.ra_save;
4860 break;
4861 case PDSC_S_K_KIND_FP_STACK:
4862 md_number_to_chars (p + 2, (valueT) alpha_evax_proc.rsa_offset, 2);
4863 break;
4864 default: /* impossible */
4865 break;
4866 }
4867
4868 *(p + 4) = 0;
4869 *(p + 5) = alpha_evax_proc.type & 0x0f;
4870
4871 /* Signature offset. */
4872 md_number_to_chars (p + 6, (valueT) 0, 2);
4873
4874 fix_new_exp (frag_now, p - frag_now->fr_literal+8, 8, &exp, 0, BFD_RELOC_64);
4875
4876 if (alpha_evax_proc.pdsckind == PDSC_S_K_KIND_NULL)
4877 return;
4878
4879 /* Add dummy fix to make add_to_link_pool work. */
4880 p = frag_more (8);
4881 fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
4882 fixp->fx_done = 1;
4883 seginfo->literal_pool_size += 8;
4884
4885 /* pdesc+16: Size. */
4886 md_number_to_chars (p, (valueT) alpha_evax_proc.framesize, 4);
4887
4888 md_number_to_chars (p + 4, (valueT) 0, 2);
4889
4890 /* Entry length. */
4891 md_number_to_chars (p + 6, alpha_evax_proc.prologue, 2);
4892
4893 if (alpha_evax_proc.pdsckind == PDSC_S_K_KIND_FP_REGISTER)
4894 return;
4895
4896 /* Add dummy fix to make add_to_link_pool work. */
4897 p = frag_more (8);
4898 fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
4899 fixp->fx_done = 1;
4900 seginfo->literal_pool_size += 8;
4901
4902 /* pdesc+24: register masks. */
4903
4904 md_number_to_chars (p, alpha_evax_proc.imask, 4);
4905 md_number_to_chars (p + 4, alpha_evax_proc.fmask, 4);
4906
4907 return;
4908 }
4909
4910 /* Support for crash debug on vms. */
4911
4912 static void
4913 s_alpha_name (ignore)
4914 int ignore ATTRIBUTE_UNUSED;
4915 {
4916 register char *p;
4917 expressionS exp;
4918 segment_info_type *seginfo = seg_info (alpha_link_section);
4919
4920 if (now_seg != alpha_link_section)
4921 {
4922 as_bad (_(".name directive not in link (.link) section"));
4923 demand_empty_rest_of_line ();
4924 return;
4925 }
4926
4927 expression (&exp);
4928 if (exp.X_op != O_symbol)
4929 {
4930 as_warn (_(".name directive has no symbol"));
4931 demand_empty_rest_of_line ();
4932 return;
4933 }
4934
4935 demand_empty_rest_of_line ();
4936
4937 #ifdef md_flush_pending_output
4938 md_flush_pending_output ();
4939 #endif
4940
4941 frag_align (3, 0, 0);
4942 p = frag_more (8);
4943 seginfo->literal_pool_size += 8;
4944
4945 fix_new_exp (frag_now, p - frag_now->fr_literal, 8, &exp, 0, BFD_RELOC_64);
4946
4947 return;
4948 }
4949
4950 static void
4951 s_alpha_linkage (ignore)
4952 int ignore ATTRIBUTE_UNUSED;
4953 {
4954 expressionS exp;
4955 char *p;
4956
4957 #ifdef md_flush_pending_output
4958 md_flush_pending_output ();
4959 #endif
4960
4961 expression (&exp);
4962 if (exp.X_op != O_symbol)
4963 {
4964 as_fatal (_("No symbol after .linkage"));
4965 }
4966 else
4967 {
4968 p = frag_more (LKP_S_K_SIZE);
4969 memset (p, 0, LKP_S_K_SIZE);
4970 fix_new_exp (frag_now, p - frag_now->fr_literal, LKP_S_K_SIZE, &exp, 0,\
4971 BFD_RELOC_ALPHA_LINKAGE);
4972 }
4973 demand_empty_rest_of_line ();
4974
4975 return;
4976 }
4977
4978 static void
4979 s_alpha_code_address (ignore)
4980 int ignore ATTRIBUTE_UNUSED;
4981 {
4982 expressionS exp;
4983 char *p;
4984
4985 #ifdef md_flush_pending_output
4986 md_flush_pending_output ();
4987 #endif
4988
4989 expression (&exp);
4990 if (exp.X_op != O_symbol)
4991 {
4992 as_fatal (_("No symbol after .code_address"));
4993 }
4994 else
4995 {
4996 p = frag_more (8);
4997 memset (p, 0, 8);
4998 fix_new_exp (frag_now, p - frag_now->fr_literal, 8, &exp, 0,\
4999 BFD_RELOC_ALPHA_CODEADDR);
5000 }
5001 demand_empty_rest_of_line ();
5002
5003 return;
5004 }
5005
5006 static void
5007 s_alpha_fp_save (ignore)
5008 int ignore ATTRIBUTE_UNUSED;
5009 {
5010
5011 alpha_evax_proc.fp_save = tc_get_register (1);
5012
5013 demand_empty_rest_of_line ();
5014 return;
5015 }
5016
5017 static void
5018 s_alpha_mask (ignore)
5019 int ignore ATTRIBUTE_UNUSED;
5020 {
5021 long val;
5022
5023 if (get_absolute_expression_and_terminator (&val) != ',')
5024 {
5025 as_warn (_("Bad .mask directive"));
5026 --input_line_pointer;
5027 }
5028 else
5029 {
5030 alpha_evax_proc.imask = val;
5031 (void) get_absolute_expression ();
5032 }
5033 demand_empty_rest_of_line ();
5034
5035 return;
5036 }
5037
5038 static void
5039 s_alpha_fmask (ignore)
5040 int ignore ATTRIBUTE_UNUSED;
5041 {
5042 long val;
5043
5044 if (get_absolute_expression_and_terminator (&val) != ',')
5045 {
5046 as_warn (_("Bad .fmask directive"));
5047 --input_line_pointer;
5048 }
5049 else
5050 {
5051 alpha_evax_proc.fmask = val;
5052 (void) get_absolute_expression ();
5053 }
5054 demand_empty_rest_of_line ();
5055
5056 return;
5057 }
5058
5059 static void
5060 s_alpha_end (ignore)
5061 int ignore ATTRIBUTE_UNUSED;
5062 {
5063 char c;
5064
5065 c = get_symbol_end ();
5066 *input_line_pointer = c;
5067 demand_empty_rest_of_line ();
5068 alpha_evax_proc.symbol = 0;
5069
5070 return;
5071 }
5072
5073 static void
5074 s_alpha_file (ignore)
5075 int ignore ATTRIBUTE_UNUSED;
5076 {
5077 symbolS *s;
5078 int length;
5079 static char case_hack[32];
5080
5081 extern char *demand_copy_string PARAMS ((int *lenP));
5082
5083 sprintf (case_hack, "<CASE:%01d%01d>",
5084 alpha_flag_hash_long_names, alpha_flag_show_after_trunc);
5085
5086 s = symbol_find_or_make (case_hack);
5087 symbol_get_bfdsym (s)->flags |= BSF_FILE;
5088
5089 get_absolute_expression ();
5090 s = symbol_find_or_make (demand_copy_string (&length));
5091 symbol_get_bfdsym (s)->flags |= BSF_FILE;
5092 demand_empty_rest_of_line ();
5093
5094 return;
5095 }
5096 #endif /* OBJ_EVAX */
5097
5098 /* Handle the .gprel32 pseudo op. */
5099
5100 static void
5101 s_alpha_gprel32 (ignore)
5102 int ignore ATTRIBUTE_UNUSED;
5103 {
5104 expressionS e;
5105 char *p;
5106
5107 SKIP_WHITESPACE ();
5108 expression (&e);
5109
5110 #ifdef OBJ_ELF
5111 switch (e.X_op)
5112 {
5113 case O_constant:
5114 e.X_add_symbol = section_symbol (absolute_section);
5115 e.X_op = O_symbol;
5116 /* FALLTHRU */
5117 case O_symbol:
5118 break;
5119 default:
5120 abort ();
5121 }
5122 #else
5123 #ifdef OBJ_ECOFF
5124 switch (e.X_op)
5125 {
5126 case O_constant:
5127 e.X_add_symbol = section_symbol (absolute_section);
5128 /* fall through */
5129 case O_symbol:
5130 e.X_op = O_subtract;
5131 e.X_op_symbol = alpha_gp_symbol;
5132 break;
5133 default:
5134 abort ();
5135 }
5136 #endif
5137 #endif
5138
5139 if (alpha_auto_align_on && alpha_current_align < 2)
5140 alpha_align (2, (char *) NULL, alpha_insn_label, 0);
5141 if (alpha_current_align > 2)
5142 alpha_current_align = 2;
5143 alpha_insn_label = NULL;
5144
5145 p = frag_more (4);
5146 memset (p, 0, 4);
5147 fix_new_exp (frag_now, p - frag_now->fr_literal, 4,
5148 &e, 0, BFD_RELOC_GPREL32);
5149 }
5150
5151 /* Handle floating point allocation pseudo-ops. This is like the
5152 generic vresion, but it makes sure the current label, if any, is
5153 correctly aligned. */
5154
5155 static void
5156 s_alpha_float_cons (type)
5157 int type;
5158 {
5159 int log_size;
5160
5161 switch (type)
5162 {
5163 default:
5164 case 'f':
5165 case 'F':
5166 log_size = 2;
5167 break;
5168
5169 case 'd':
5170 case 'D':
5171 case 'G':
5172 log_size = 3;
5173 break;
5174
5175 case 'x':
5176 case 'X':
5177 case 'p':
5178 case 'P':
5179 log_size = 4;
5180 break;
5181 }
5182
5183 if (alpha_auto_align_on && alpha_current_align < log_size)
5184 alpha_align (log_size, (char *) NULL, alpha_insn_label, 0);
5185 if (alpha_current_align > log_size)
5186 alpha_current_align = log_size;
5187 alpha_insn_label = NULL;
5188
5189 float_cons (type);
5190 }
5191
5192 /* Handle the .proc pseudo op. We don't really do much with it except
5193 parse it. */
5194
5195 static void
5196 s_alpha_proc (is_static)
5197 int is_static ATTRIBUTE_UNUSED;
5198 {
5199 char *name;
5200 char c;
5201 char *p;
5202 symbolS *symbolP;
5203 int temp;
5204
5205 /* Takes ".proc name,nargs" */
5206 SKIP_WHITESPACE ();
5207 name = input_line_pointer;
5208 c = get_symbol_end ();
5209 p = input_line_pointer;
5210 symbolP = symbol_find_or_make (name);
5211 *p = c;
5212 SKIP_WHITESPACE ();
5213 if (*input_line_pointer != ',')
5214 {
5215 *p = 0;
5216 as_warn (_("Expected comma after name \"%s\""), name);
5217 *p = c;
5218 temp = 0;
5219 ignore_rest_of_line ();
5220 }
5221 else
5222 {
5223 input_line_pointer++;
5224 temp = get_absolute_expression ();
5225 }
5226 /* *symbol_get_obj (symbolP) = (signed char) temp; */
5227 as_warn (_("unhandled: .proc %s,%d"), name, temp);
5228 demand_empty_rest_of_line ();
5229 }
5230
5231 /* Handle the .set pseudo op. This is used to turn on and off most of
5232 the assembler features. */
5233
5234 static void
5235 s_alpha_set (x)
5236 int x ATTRIBUTE_UNUSED;
5237 {
5238 char *name, ch, *s;
5239 int yesno = 1;
5240
5241 SKIP_WHITESPACE ();
5242 name = input_line_pointer;
5243 ch = get_symbol_end ();
5244
5245 s = name;
5246 if (s[0] == 'n' && s[1] == 'o')
5247 {
5248 yesno = 0;
5249 s += 2;
5250 }
5251 if (!strcmp ("reorder", s))
5252 /* ignore */ ;
5253 else if (!strcmp ("at", s))
5254 alpha_noat_on = !yesno;
5255 else if (!strcmp ("macro", s))
5256 alpha_macros_on = yesno;
5257 else if (!strcmp ("move", s))
5258 /* ignore */ ;
5259 else if (!strcmp ("volatile", s))
5260 /* ignore */ ;
5261 else
5262 as_warn (_("Tried to .set unrecognized mode `%s'"), name);
5263
5264 *input_line_pointer = ch;
5265 demand_empty_rest_of_line ();
5266 }
5267
5268 /* Handle the .base pseudo op. This changes the assembler's notion of
5269 the $gp register. */
5270
5271 static void
5272 s_alpha_base (ignore)
5273 int ignore ATTRIBUTE_UNUSED;
5274 {
5275 #if 0
5276 if (first_32bit_quadrant)
5277 {
5278 /* not fatal, but it might not work in the end */
5279 as_warn (_("File overrides no-base-register option."));
5280 first_32bit_quadrant = 0;
5281 }
5282 #endif
5283
5284 SKIP_WHITESPACE ();
5285 if (*input_line_pointer == '$')
5286 { /* $rNN form */
5287 input_line_pointer++;
5288 if (*input_line_pointer == 'r')
5289 input_line_pointer++;
5290 }
5291
5292 alpha_gp_register = get_absolute_expression ();
5293 if (alpha_gp_register < 0 || alpha_gp_register > 31)
5294 {
5295 alpha_gp_register = AXP_REG_GP;
5296 as_warn (_("Bad base register, using $%d."), alpha_gp_register);
5297 }
5298
5299 demand_empty_rest_of_line ();
5300 }
5301
5302 /* Handle the .align pseudo-op. This aligns to a power of two. It
5303 also adjusts any current instruction label. We treat this the same
5304 way the MIPS port does: .align 0 turns off auto alignment. */
5305
5306 static void
5307 s_alpha_align (ignore)
5308 int ignore ATTRIBUTE_UNUSED;
5309 {
5310 int align;
5311 char fill, *pfill;
5312 long max_alignment = 15;
5313
5314 align = get_absolute_expression ();
5315 if (align > max_alignment)
5316 {
5317 align = max_alignment;
5318 as_bad (_("Alignment too large: %d. assumed"), align);
5319 }
5320 else if (align < 0)
5321 {
5322 as_warn (_("Alignment negative: 0 assumed"));
5323 align = 0;
5324 }
5325
5326 if (*input_line_pointer == ',')
5327 {
5328 input_line_pointer++;
5329 fill = get_absolute_expression ();
5330 pfill = &fill;
5331 }
5332 else
5333 pfill = NULL;
5334
5335 if (align != 0)
5336 {
5337 alpha_auto_align_on = 1;
5338 alpha_align (align, pfill, alpha_insn_label, 1);
5339 }
5340 else
5341 {
5342 alpha_auto_align_on = 0;
5343 }
5344
5345 demand_empty_rest_of_line ();
5346 }
5347
5348 /* Hook the normal string processor to reset known alignment. */
5349
5350 static void
5351 s_alpha_stringer (terminate)
5352 int terminate;
5353 {
5354 alpha_current_align = 0;
5355 alpha_insn_label = NULL;
5356 stringer (terminate);
5357 }
5358
5359 /* Hook the normal space processing to reset known alignment. */
5360
5361 static void
5362 s_alpha_space (ignore)
5363 int ignore;
5364 {
5365 alpha_current_align = 0;
5366 alpha_insn_label = NULL;
5367 s_space (ignore);
5368 }
5369
5370 /* Hook into cons for auto-alignment. */
5371
5372 void
5373 alpha_cons_align (size)
5374 int size;
5375 {
5376 int log_size;
5377
5378 log_size = 0;
5379 while ((size >>= 1) != 0)
5380 ++log_size;
5381
5382 if (alpha_auto_align_on && alpha_current_align < log_size)
5383 alpha_align (log_size, (char *) NULL, alpha_insn_label, 0);
5384 if (alpha_current_align > log_size)
5385 alpha_current_align = log_size;
5386 alpha_insn_label = NULL;
5387 }
5388
5389 /* Here come the .uword, .ulong, and .uquad explicitly unaligned
5390 pseudos. We just turn off auto-alignment and call down to cons. */
5391
5392 static void
5393 s_alpha_ucons (bytes)
5394 int bytes;
5395 {
5396 int hold = alpha_auto_align_on;
5397 alpha_auto_align_on = 0;
5398 cons (bytes);
5399 alpha_auto_align_on = hold;
5400 }
5401
5402 /* Switch the working cpu type. */
5403
5404 static void
5405 s_alpha_arch (ignored)
5406 int ignored ATTRIBUTE_UNUSED;
5407 {
5408 char *name, ch;
5409 const struct cpu_type *p;
5410
5411 SKIP_WHITESPACE ();
5412 name = input_line_pointer;
5413 ch = get_symbol_end ();
5414
5415 for (p = cpu_types; p->name; ++p)
5416 if (strcmp (name, p->name) == 0)
5417 {
5418 alpha_target_name = p->name, alpha_target = p->flags;
5419 goto found;
5420 }
5421 as_warn ("Unknown CPU identifier `%s'", name);
5422
5423 found:
5424 *input_line_pointer = ch;
5425 demand_empty_rest_of_line ();
5426 }
5427 \f
5428 #ifdef DEBUG1
5429 /* print token expression with alpha specific extension. */
5430
5431 static void
5432 alpha_print_token (f, exp)
5433 FILE *f;
5434 const expressionS *exp;
5435 {
5436 switch (exp->X_op)
5437 {
5438 case O_cpregister:
5439 putc (',', f);
5440 /* FALLTHRU */
5441 case O_pregister:
5442 putc ('(', f);
5443 {
5444 expressionS nexp = *exp;
5445 nexp.X_op = O_register;
5446 print_expr (f, &nexp);
5447 }
5448 putc (')', f);
5449 break;
5450 default:
5451 print_expr (f, exp);
5452 break;
5453 }
5454 return;
5455 }
5456 #endif
5457 \f
5458 /* The target specific pseudo-ops which we support. */
5459
5460 const pseudo_typeS md_pseudo_table[] = {
5461 #ifdef OBJ_ECOFF
5462 {"comm", s_alpha_comm, 0}, /* osf1 compiler does this */
5463 {"rdata", s_alpha_rdata, 0},
5464 #endif
5465 {"text", s_alpha_text, 0},
5466 {"data", s_alpha_data, 0},
5467 #ifdef OBJ_ECOFF
5468 {"sdata", s_alpha_sdata, 0},
5469 #endif
5470 #ifdef OBJ_ELF
5471 {"section", s_alpha_section, 0},
5472 {"section.s", s_alpha_section, 0},
5473 {"sect", s_alpha_section, 0},
5474 {"sect.s", s_alpha_section, 0},
5475 #endif
5476 #ifdef OBJ_EVAX
5477 { "pdesc", s_alpha_pdesc, 0},
5478 { "name", s_alpha_name, 0},
5479 { "linkage", s_alpha_linkage, 0},
5480 { "code_address", s_alpha_code_address, 0},
5481 { "ent", s_alpha_ent, 0},
5482 { "frame", s_alpha_frame, 0},
5483 { "fp_save", s_alpha_fp_save, 0},
5484 { "mask", s_alpha_mask, 0},
5485 { "fmask", s_alpha_fmask, 0},
5486 { "end", s_alpha_end, 0},
5487 { "file", s_alpha_file, 0},
5488 { "rdata", s_alpha_section, 1},
5489 { "comm", s_alpha_comm, 0},
5490 { "link", s_alpha_section, 3},
5491 { "ctors", s_alpha_section, 4},
5492 { "dtors", s_alpha_section, 5},
5493 #endif
5494 #ifdef OBJ_ELF
5495 /* Frame related pseudos. */
5496 {"ent", s_alpha_ent, 0},
5497 {"end", s_alpha_end, 0},
5498 {"mask", s_alpha_mask, 0},
5499 {"fmask", s_alpha_mask, 1},
5500 {"frame", s_alpha_frame, 0},
5501 {"prologue", s_alpha_prologue, 0},
5502 {"file", s_alpha_file, 5},
5503 {"loc", s_alpha_loc, 9},
5504 {"stabs", s_alpha_stab, 's'},
5505 {"stabn", s_alpha_stab, 'n'},
5506 /* COFF debugging related pseudos. */
5507 {"begin", s_alpha_coff_wrapper, 0},
5508 {"bend", s_alpha_coff_wrapper, 1},
5509 {"def", s_alpha_coff_wrapper, 2},
5510 {"dim", s_alpha_coff_wrapper, 3},
5511 {"endef", s_alpha_coff_wrapper, 4},
5512 {"scl", s_alpha_coff_wrapper, 5},
5513 {"tag", s_alpha_coff_wrapper, 6},
5514 {"val", s_alpha_coff_wrapper, 7},
5515 #else
5516 {"prologue", s_ignore, 0},
5517 #endif
5518 {"gprel32", s_alpha_gprel32, 0},
5519 {"t_floating", s_alpha_float_cons, 'd'},
5520 {"s_floating", s_alpha_float_cons, 'f'},
5521 {"f_floating", s_alpha_float_cons, 'F'},
5522 {"g_floating", s_alpha_float_cons, 'G'},
5523 {"d_floating", s_alpha_float_cons, 'D'},
5524
5525 {"proc", s_alpha_proc, 0},
5526 {"aproc", s_alpha_proc, 1},
5527 {"set", s_alpha_set, 0},
5528 {"reguse", s_ignore, 0},
5529 {"livereg", s_ignore, 0},
5530 {"base", s_alpha_base, 0}, /*??*/
5531 {"option", s_ignore, 0},
5532 {"aent", s_ignore, 0},
5533 {"ugen", s_ignore, 0},
5534 {"eflag", s_ignore, 0},
5535
5536 {"align", s_alpha_align, 0},
5537 {"double", s_alpha_float_cons, 'd'},
5538 {"float", s_alpha_float_cons, 'f'},
5539 {"single", s_alpha_float_cons, 'f'},
5540 {"ascii", s_alpha_stringer, 0},
5541 {"asciz", s_alpha_stringer, 1},
5542 {"string", s_alpha_stringer, 1},
5543 {"space", s_alpha_space, 0},
5544 {"skip", s_alpha_space, 0},
5545 {"zero", s_alpha_space, 0},
5546
5547 /* Unaligned data pseudos. */
5548 {"uword", s_alpha_ucons, 2},
5549 {"ulong", s_alpha_ucons, 4},
5550 {"uquad", s_alpha_ucons, 8},
5551
5552 #ifdef OBJ_ELF
5553 /* Dwarf wants these versions of unaligned. */
5554 {"2byte", s_alpha_ucons, 2},
5555 {"4byte", s_alpha_ucons, 4},
5556 {"8byte", s_alpha_ucons, 8},
5557 #endif
5558
5559 /* We don't do any optimizing, so we can safely ignore these. */
5560 {"noalias", s_ignore, 0},
5561 {"alias", s_ignore, 0},
5562
5563 {"arch", s_alpha_arch, 0},
5564
5565 {NULL, 0, 0},
5566 };
5567 \f
5568 /* Build a BFD section with its flags set appropriately for the .lita,
5569 .lit8, or .lit4 sections. */
5570
5571 static void
5572 create_literal_section (name, secp, symp)
5573 const char *name;
5574 segT *secp;
5575 symbolS **symp;
5576 {
5577 segT current_section = now_seg;
5578 int current_subsec = now_subseg;
5579 segT new_sec;
5580
5581 *secp = new_sec = subseg_new (name, 0);
5582 subseg_set (current_section, current_subsec);
5583 bfd_set_section_alignment (stdoutput, new_sec, 4);
5584 bfd_set_section_flags (stdoutput, new_sec,
5585 SEC_RELOC | SEC_ALLOC | SEC_LOAD | SEC_READONLY
5586 | SEC_DATA);
5587
5588 S_CLEAR_EXTERNAL (*symp = section_symbol (new_sec));
5589 }
5590
5591 #ifdef OBJ_ECOFF
5592
5593 /* @@@ GP selection voodoo. All of this seems overly complicated and
5594 unnecessary; which is the primary reason it's for ECOFF only. */
5595 static inline void maybe_set_gp PARAMS ((asection *));
5596
5597 static inline void
5598 maybe_set_gp (sec)
5599 asection *sec;
5600 {
5601 bfd_vma vma;
5602 if (!sec)
5603 return;
5604 vma = bfd_get_section_vma (foo, sec);
5605 if (vma && vma < alpha_gp_value)
5606 alpha_gp_value = vma;
5607 }
5608
5609 static void
5610 select_gp_value ()
5611 {
5612 assert (alpha_gp_value == 0);
5613
5614 /* Get minus-one in whatever width... */
5615 alpha_gp_value = 0;
5616 alpha_gp_value--;
5617
5618 /* Select the smallest VMA of these existing sections. */
5619 maybe_set_gp (alpha_lita_section);
5620 #if 0
5621 /* These were disabled before -- should we use them? */
5622 maybe_set_gp (sdata);
5623 maybe_set_gp (lit8_sec);
5624 maybe_set_gp (lit4_sec);
5625 #endif
5626
5627 /* @@ Will a simple 0x8000 work here? If not, why not? */
5628 #define GP_ADJUSTMENT (0x8000 - 0x10)
5629
5630 alpha_gp_value += GP_ADJUSTMENT;
5631
5632 S_SET_VALUE (alpha_gp_symbol, alpha_gp_value);
5633
5634 #ifdef DEBUG1
5635 printf (_("Chose GP value of %lx\n"), alpha_gp_value);
5636 #endif
5637 }
5638 #endif /* OBJ_ECOFF */
5639
5640 #ifdef OBJ_ELF
5641 /* Map 's' to SHF_ALPHA_GPREL. */
5642
5643 int
5644 alpha_elf_section_letter (letter, ptr_msg)
5645 int letter;
5646 char **ptr_msg;
5647 {
5648 if (letter == 's')
5649 return SHF_ALPHA_GPREL;
5650
5651 *ptr_msg = _("Bad .section directive: want a,s,w,x,M,S,G,T in string");
5652 return 0;
5653 }
5654
5655 /* Map SHF_ALPHA_GPREL to SEC_SMALL_DATA. */
5656
5657 flagword
5658 alpha_elf_section_flags (flags, attr, type)
5659 flagword flags;
5660 int attr, type ATTRIBUTE_UNUSED;
5661 {
5662 if (attr & SHF_ALPHA_GPREL)
5663 flags |= SEC_SMALL_DATA;
5664 return flags;
5665 }
5666 #endif /* OBJ_ELF */
5667
5668 /* Called internally to handle all alignment needs. This takes care
5669 of eliding calls to frag_align if'n the cached current alignment
5670 says we've already got it, as well as taking care of the auto-align
5671 feature wrt labels. */
5672
5673 static void
5674 alpha_align (n, pfill, label, force)
5675 int n;
5676 char *pfill;
5677 symbolS *label;
5678 int force ATTRIBUTE_UNUSED;
5679 {
5680 if (alpha_current_align >= n)
5681 return;
5682
5683 if (pfill == NULL)
5684 {
5685 if (subseg_text_p (now_seg))
5686 frag_align_code (n, 0);
5687 else
5688 frag_align (n, 0, 0);
5689 }
5690 else
5691 frag_align (n, *pfill, 0);
5692
5693 alpha_current_align = n;
5694
5695 if (label != NULL && S_GET_SEGMENT (label) == now_seg)
5696 {
5697 symbol_set_frag (label, frag_now);
5698 S_SET_VALUE (label, (valueT) frag_now_fix ());
5699 }
5700
5701 record_alignment (now_seg, n);
5702
5703 /* ??? If alpha_flag_relax && force && elf, record the requested alignment
5704 in a reloc for the linker to see. */
5705 }
5706
5707 /* This is called from HANDLE_ALIGN in write.c. Fill in the contents
5708 of an rs_align_code fragment. */
5709
5710 void
5711 alpha_handle_align (fragp)
5712 fragS *fragp;
5713 {
5714 static char const unop[4] = { 0x00, 0x00, 0xfe, 0x2f };
5715 static char const nopunop[8] = {
5716 0x1f, 0x04, 0xff, 0x47,
5717 0x00, 0x00, 0xfe, 0x2f
5718 };
5719
5720 int bytes, fix;
5721 char *p;
5722
5723 if (fragp->fr_type != rs_align_code)
5724 return;
5725
5726 bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix;
5727 p = fragp->fr_literal + fragp->fr_fix;
5728 fix = 0;
5729
5730 if (bytes & 3)
5731 {
5732 fix = bytes & 3;
5733 memset (p, 0, fix);
5734 p += fix;
5735 bytes -= fix;
5736 }
5737
5738 if (bytes & 4)
5739 {
5740 memcpy (p, unop, 4);
5741 p += 4;
5742 bytes -= 4;
5743 fix += 4;
5744 }
5745
5746 memcpy (p, nopunop, 8);
5747
5748 fragp->fr_fix += fix;
5749 fragp->fr_var = 8;
5750 }
5751
5752 /* The Alpha has support for some VAX floating point types, as well as for
5753 IEEE floating point. We consider IEEE to be the primary floating point
5754 format, and sneak in the VAX floating point support here. */
5755 #define md_atof vax_md_atof
5756 #include "config/atof-vax.c"
This page took 0.148277 seconds and 4 git commands to generate.