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