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