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