1 /* tc-alpha.c - Processor-specific code for the DEC Alpha AXP CPU.
2 Copyright (C) 1989-2022 Free Software Foundation, Inc.
3 Contributed by Carnegie Mellon University, 1993.
4 Written by Alessandro Forin, based on earlier gas-1.38 target CPU files.
5 Modified by Ken Raeburn for gas-2.x and ECOFF support.
6 Modified by Richard Henderson for ELF support.
7 Modified by Klaus K"ampf for EVAX (OpenVMS/Alpha) support.
9 This file is part of GAS, the GNU Assembler.
11 GAS is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 3, or (at your option)
16 GAS is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with GAS; see the file COPYING. If not, write to the Free
23 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
26 /* Mach Operating System
27 Copyright (c) 1993 Carnegie Mellon University
30 Permission to use, copy, modify and distribute this software and its
31 documentation is hereby granted, provided that both the copyright
32 notice and this permission notice appear in all copies of the
33 software, derivative works or modified versions, and any portions
34 thereof, and that both notices appear in supporting documentation.
36 CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
37 CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
38 ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
40 Carnegie Mellon requests users of this software to return to
42 Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
43 School of Computer Science
44 Carnegie Mellon University
45 Pittsburgh PA 15213-3890
47 any improvements or extensions that they make and grant Carnegie the
48 rights to redistribute these changes. */
54 #include "opcode/alpha.h"
57 #include "elf/alpha.h"
65 #include "dwarf2dbg.h"
66 #include "dw2gencfi.h"
67 #include "safe-ctype.h"
71 #define TOKENIZE_ERROR -1
72 #define TOKENIZE_ERROR_REPORT -2
73 #define MAX_INSN_FIXUPS 2
74 #define MAX_INSN_ARGS 5
76 /* Used since new relocation types are introduced in this
77 file (DUMMY_RELOC_LITUSE_*) */
78 typedef int extended_bfd_reloc_code_real_type
;
83 /* bfd_reloc_code_real_type reloc; */
84 extended_bfd_reloc_code_real_type reloc
;
86 /* The symbol of the item in the linkage section. */
89 /* The symbol of the procedure descriptor. */
98 struct alpha_fixup fixups
[MAX_INSN_FIXUPS
];
116 void (*emit
) (const expressionS
*, int, const void *);
118 enum alpha_macro_arg argsets
[16];
121 /* Extra expression types. */
123 #define O_pregister O_md1 /* O_register, in parentheses. */
124 #define O_cpregister O_md2 /* + a leading comma. */
126 /* The alpha_reloc_op table below depends on the ordering of these. */
127 #define O_literal O_md3 /* !literal relocation. */
128 #define O_lituse_addr O_md4 /* !lituse_addr relocation. */
129 #define O_lituse_base O_md5 /* !lituse_base relocation. */
130 #define O_lituse_bytoff O_md6 /* !lituse_bytoff relocation. */
131 #define O_lituse_jsr O_md7 /* !lituse_jsr relocation. */
132 #define O_lituse_tlsgd O_md8 /* !lituse_tlsgd relocation. */
133 #define O_lituse_tlsldm O_md9 /* !lituse_tlsldm relocation. */
134 #define O_lituse_jsrdirect O_md10 /* !lituse_jsrdirect relocation. */
135 #define O_gpdisp O_md11 /* !gpdisp relocation. */
136 #define O_gprelhigh O_md12 /* !gprelhigh relocation. */
137 #define O_gprellow O_md13 /* !gprellow relocation. */
138 #define O_gprel O_md14 /* !gprel relocation. */
139 #define O_samegp O_md15 /* !samegp relocation. */
140 #define O_tlsgd O_md16 /* !tlsgd relocation. */
141 #define O_tlsldm O_md17 /* !tlsldm relocation. */
142 #define O_gotdtprel O_md18 /* !gotdtprel relocation. */
143 #define O_dtprelhi O_md19 /* !dtprelhi relocation. */
144 #define O_dtprello O_md20 /* !dtprello relocation. */
145 #define O_dtprel O_md21 /* !dtprel relocation. */
146 #define O_gottprel O_md22 /* !gottprel relocation. */
147 #define O_tprelhi O_md23 /* !tprelhi relocation. */
148 #define O_tprello O_md24 /* !tprello relocation. */
149 #define O_tprel O_md25 /* !tprel relocation. */
151 #define DUMMY_RELOC_LITUSE_ADDR (BFD_RELOC_UNUSED + 1)
152 #define DUMMY_RELOC_LITUSE_BASE (BFD_RELOC_UNUSED + 2)
153 #define DUMMY_RELOC_LITUSE_BYTOFF (BFD_RELOC_UNUSED + 3)
154 #define DUMMY_RELOC_LITUSE_JSR (BFD_RELOC_UNUSED + 4)
155 #define DUMMY_RELOC_LITUSE_TLSGD (BFD_RELOC_UNUSED + 5)
156 #define DUMMY_RELOC_LITUSE_TLSLDM (BFD_RELOC_UNUSED + 6)
157 #define DUMMY_RELOC_LITUSE_JSRDIRECT (BFD_RELOC_UNUSED + 7)
159 #define USER_RELOC_P(R) ((R) >= O_literal && (R) <= O_tprel)
161 /* Macros for extracting the type and number of encoded register tokens. */
163 #define is_ir_num(x) (((x) & 32) == 0)
164 #define is_fpr_num(x) (((x) & 32) != 0)
165 #define regno(x) ((x) & 31)
167 /* Something odd inherited from the old assembler. */
169 #define note_gpreg(R) (alpha_gprmask |= (1 << (R)))
170 #define note_fpreg(R) (alpha_fprmask |= (1 << (R)))
172 /* Predicates for 16- and 32-bit ranges */
173 /* XXX: The non-shift version appears to trigger a compiler bug when
174 cross-assembling from x86 w/ gcc 2.7.2. */
177 #define range_signed_16(x) \
178 (((offsetT) (x) >> 15) == 0 || ((offsetT) (x) >> 15) == -1)
179 #define range_signed_32(x) \
180 (((offsetT) (x) >> 31) == 0 || ((offsetT) (x) >> 31) == -1)
182 #define range_signed_16(x) ((offsetT) (x) >= -(offsetT) 0x8000 && \
183 (offsetT) (x) <= (offsetT) 0x7FFF)
184 #define range_signed_32(x) ((offsetT) (x) >= -(offsetT) 0x80000000 && \
185 (offsetT) (x) <= (offsetT) 0x7FFFFFFF)
188 /* Macros for sign extending from 16- and 32-bits. */
189 /* XXX: The cast macros will work on all the systems that I care about,
190 but really a predicate should be found to use the non-cast forms. */
193 #define sign_extend_16(x) ((short) (x))
194 #define sign_extend_32(x) ((int) (x))
196 #define sign_extend_16(x) ((offsetT) (((x) & 0xFFFF) ^ 0x8000) - 0x8000)
197 #define sign_extend_32(x) ((offsetT) (((x) & 0xFFFFFFFF) \
198 ^ 0x80000000) - 0x80000000)
201 /* Macros to build tokens. */
203 #define set_tok_reg(t, r) (memset (&(t), 0, sizeof (t)), \
204 (t).X_op = O_register, \
205 (t).X_add_number = (r))
206 #define set_tok_preg(t, r) (memset (&(t), 0, sizeof (t)), \
207 (t).X_op = O_pregister, \
208 (t).X_add_number = (r))
209 #define set_tok_cpreg(t, r) (memset (&(t), 0, sizeof (t)), \
210 (t).X_op = O_cpregister, \
211 (t).X_add_number = (r))
212 #define set_tok_freg(t, r) (memset (&(t), 0, sizeof (t)), \
213 (t).X_op = O_register, \
214 (t).X_add_number = (r) + 32)
215 #define set_tok_sym(t, s, a) (memset (&(t), 0, sizeof (t)), \
216 (t).X_op = O_symbol, \
217 (t).X_add_symbol = (s), \
218 (t).X_add_number = (a))
219 #define set_tok_const(t, n) (memset (&(t), 0, sizeof (t)), \
220 (t).X_op = O_constant, \
221 (t).X_add_number = (n))
223 /* Generic assembler global variables which must be defined by all
226 /* Characters which always start a comment. */
227 const char comment_chars
[] = "#";
229 /* Characters which start a comment at the beginning of a line. */
230 const char line_comment_chars
[] = "#";
232 /* Characters which may be used to separate multiple commands on a
234 const char line_separator_chars
[] = ";";
236 /* Characters which are used to indicate an exponent in a floating
238 const char EXP_CHARS
[] = "eE";
240 /* Characters which mean that a number is a floating point constant,
242 /* XXX: Do all of these really get used on the alpha?? */
243 const char FLT_CHARS
[] = "rRsSfFdDxXpP";
246 const char *md_shortopts
= "Fm:g+1h:HG:";
248 const char *md_shortopts
= "Fm:gG:";
251 struct option md_longopts
[] =
253 #define OPTION_32ADDR (OPTION_MD_BASE)
254 { "32addr", no_argument
, NULL
, OPTION_32ADDR
},
255 #define OPTION_RELAX (OPTION_32ADDR + 1)
256 { "relax", no_argument
, NULL
, OPTION_RELAX
},
258 #define OPTION_MDEBUG (OPTION_RELAX + 1)
259 #define OPTION_NO_MDEBUG (OPTION_MDEBUG + 1)
260 { "mdebug", no_argument
, NULL
, OPTION_MDEBUG
},
261 { "no-mdebug", no_argument
, NULL
, OPTION_NO_MDEBUG
},
264 #define OPTION_REPLACE (OPTION_RELAX + 1)
265 #define OPTION_NOREPLACE (OPTION_REPLACE+1)
266 { "replace", no_argument
, NULL
, OPTION_REPLACE
},
267 { "noreplace", no_argument
, NULL
, OPTION_NOREPLACE
},
269 { NULL
, no_argument
, NULL
, 0 }
272 size_t md_longopts_size
= sizeof (md_longopts
);
276 #define AXP_REG_R16 16
277 #define AXP_REG_R17 17
279 #define AXP_REG_T9 22
281 #define AXP_REG_T10 23
283 #define AXP_REG_T11 24
285 #define AXP_REG_T12 25
286 #define AXP_REG_AI 25
288 #define AXP_REG_FP 29
291 #define AXP_REG_GP AXP_REG_PV
293 #endif /* OBJ_EVAX */
295 /* The cpu for which we are generating code. */
296 static unsigned alpha_target
= AXP_OPCODE_BASE
;
297 static const char *alpha_target_name
= "<all>";
299 /* The hash table of instruction opcodes. */
300 static htab_t alpha_opcode_hash
;
302 /* The hash table of macro opcodes. */
303 static htab_t alpha_macro_hash
;
306 /* The $gp relocation symbol. */
307 static symbolS
*alpha_gp_symbol
;
309 /* XXX: what is this, and why is it exported? */
310 valueT alpha_gp_value
;
313 /* The current $gp register. */
314 static int alpha_gp_register
= AXP_REG_GP
;
316 /* A table of the register symbols. */
317 static symbolS
*alpha_register_table
[64];
319 /* Constant sections, or sections of constants. */
321 static segT alpha_lita_section
;
324 segT alpha_link_section
;
327 static segT alpha_lit8_section
;
330 /* Symbols referring to said sections. */
332 static symbolS
*alpha_lita_symbol
;
335 static symbolS
*alpha_link_symbol
;
338 static symbolS
*alpha_lit8_symbol
;
341 /* Literal for .litX+0x8000 within .lita. */
343 static offsetT alpha_lit8_literal
;
346 /* Is the assembler not allowed to use $at? */
347 static int alpha_noat_on
= 0;
349 /* Are macros enabled? */
350 static int alpha_macros_on
= 1;
352 /* Are floats disabled? */
353 static int alpha_nofloats_on
= 0;
355 /* Are addresses 32 bit? */
356 static int alpha_addr32_on
= 0;
358 /* Symbol labelling the current insn. When the Alpha gas sees
361 and the section happens to not be on an eight byte boundary, it
362 will align both the symbol and the .quad to an eight byte boundary. */
363 static symbolS
*alpha_insn_label
;
364 #if defined(OBJ_ELF) || defined (OBJ_EVAX)
365 static symbolS
*alpha_prologue_label
;
369 /* Symbol associate with the current jsr instruction. */
370 static symbolS
*alpha_linkage_symbol
;
373 /* Whether we should automatically align data generation pseudo-ops.
374 .align 0 will turn this off. */
375 static int alpha_auto_align_on
= 1;
377 /* The known current alignment of the current section. */
378 static int alpha_current_align
;
380 /* These are exported to ECOFF code. */
381 unsigned long alpha_gprmask
, alpha_fprmask
;
383 /* Whether the debugging option was seen. */
384 static int alpha_debug
;
387 /* Whether we are emitting an mdebug section. */
388 int alpha_flag_mdebug
= -1;
392 /* Whether to perform the VMS procedure call optimization. */
393 int alpha_flag_replace
= 1;
396 /* Don't fully resolve relocations, allowing code movement in the linker. */
397 static int alpha_flag_relax
;
399 /* What value to give to bfd_set_gp_size. */
400 static int g_switch_value
= 8;
403 /* Collect information about current procedure here. */
404 struct alpha_evax_procs
406 symbolS
*symbol
; /* Proc pdesc symbol. */
408 int framereg
; /* Register for frame pointer. */
409 int framesize
; /* Size of frame. */
421 /* Linked list of .linkage fixups. */
422 struct alpha_linkage_fixups
*alpha_linkage_fixup_root
;
423 static struct alpha_linkage_fixups
*alpha_linkage_fixup_tail
;
425 /* Current procedure descriptor. */
426 static struct alpha_evax_procs
*alpha_evax_proc
;
427 static struct alpha_evax_procs alpha_evax_proc_data
;
429 static int alpha_flag_hash_long_names
= 0; /* -+ */
430 static int alpha_flag_show_after_trunc
= 0; /* -H */
432 /* If the -+ switch is given, then a hash is appended to any name that is
433 longer than 64 characters, else longer symbol names are truncated. */
438 /* A table to map the spelling of a relocation operand into an appropriate
439 bfd_reloc_code_real_type type. The table is assumed to be ordered such
440 that op-O_literal indexes into it. */
442 #define ALPHA_RELOC_TABLE(op) \
443 (&alpha_reloc_op[ ((!USER_RELOC_P (op)) \
445 : (int) (op) - (int) O_literal) ])
447 #define DEF(NAME, RELOC, REQ, ALLOW) \
448 { #NAME, sizeof(#NAME)-1, O_##NAME, RELOC, REQ, ALLOW}
450 static const struct alpha_reloc_op_tag
452 const char *name
; /* String to lookup. */
453 size_t length
; /* Size of the string. */
454 operatorT op
; /* Which operator to use. */
455 extended_bfd_reloc_code_real_type reloc
;
456 unsigned int require_seq
: 1; /* Require a sequence number. */
457 unsigned int allow_seq
: 1; /* Allow a sequence number. */
461 DEF (literal
, BFD_RELOC_ALPHA_ELF_LITERAL
, 0, 1),
462 DEF (lituse_addr
, DUMMY_RELOC_LITUSE_ADDR
, 1, 1),
463 DEF (lituse_base
, DUMMY_RELOC_LITUSE_BASE
, 1, 1),
464 DEF (lituse_bytoff
, DUMMY_RELOC_LITUSE_BYTOFF
, 1, 1),
465 DEF (lituse_jsr
, DUMMY_RELOC_LITUSE_JSR
, 1, 1),
466 DEF (lituse_tlsgd
, DUMMY_RELOC_LITUSE_TLSGD
, 1, 1),
467 DEF (lituse_tlsldm
, DUMMY_RELOC_LITUSE_TLSLDM
, 1, 1),
468 DEF (lituse_jsrdirect
, DUMMY_RELOC_LITUSE_JSRDIRECT
, 1, 1),
469 DEF (gpdisp
, BFD_RELOC_ALPHA_GPDISP
, 1, 1),
470 DEF (gprelhigh
, BFD_RELOC_ALPHA_GPREL_HI16
, 0, 0),
471 DEF (gprellow
, BFD_RELOC_ALPHA_GPREL_LO16
, 0, 0),
472 DEF (gprel
, BFD_RELOC_GPREL16
, 0, 0),
473 DEF (samegp
, BFD_RELOC_ALPHA_BRSGP
, 0, 0),
474 DEF (tlsgd
, BFD_RELOC_ALPHA_TLSGD
, 0, 1),
475 DEF (tlsldm
, BFD_RELOC_ALPHA_TLSLDM
, 0, 1),
476 DEF (gotdtprel
, BFD_RELOC_ALPHA_GOTDTPREL16
, 0, 0),
477 DEF (dtprelhi
, BFD_RELOC_ALPHA_DTPREL_HI16
, 0, 0),
478 DEF (dtprello
, BFD_RELOC_ALPHA_DTPREL_LO16
, 0, 0),
479 DEF (dtprel
, BFD_RELOC_ALPHA_DTPREL16
, 0, 0),
480 DEF (gottprel
, BFD_RELOC_ALPHA_GOTTPREL16
, 0, 0),
481 DEF (tprelhi
, BFD_RELOC_ALPHA_TPREL_HI16
, 0, 0),
482 DEF (tprello
, BFD_RELOC_ALPHA_TPREL_LO16
, 0, 0),
483 DEF (tprel
, BFD_RELOC_ALPHA_TPREL16
, 0, 0),
488 static const int alpha_num_reloc_op
489 = sizeof (alpha_reloc_op
) / sizeof (*alpha_reloc_op
);
490 #endif /* RELOC_OP_P */
492 /* Maximum # digits needed to hold the largest sequence #. */
493 #define ALPHA_RELOC_DIGITS 25
495 /* Structure to hold explicit sequence information. */
496 struct alpha_reloc_tag
498 fixS
*master
; /* The literal reloc. */
500 struct symbol
*sym
; /* Linkage section item symbol. */
501 struct symbol
*psym
; /* Pdesc symbol. */
503 fixS
*slaves
; /* Head of linked list of lituses. */
504 segT segment
; /* Segment relocs are in or undefined_section. */
505 long sequence
; /* Sequence #. */
506 unsigned n_master
; /* # of literals. */
507 unsigned n_slaves
; /* # of lituses. */
508 unsigned saw_tlsgd
: 1; /* True if ... */
509 unsigned saw_tlsldm
: 1;
510 unsigned saw_lu_tlsgd
: 1;
511 unsigned saw_lu_tlsldm
: 1;
512 unsigned multi_section_p
: 1; /* True if more than one section was used. */
513 char string
[1]; /* Printable form of sequence to hash with. */
516 /* Hash table to link up literals with the appropriate lituse. */
517 static htab_t alpha_literal_hash
;
519 /* Sequence numbers for internal use by macros. */
520 static long next_sequence_num
= -1;
522 /* A table of CPU names and opcode sets. */
524 static const struct cpu_type
531 /* Ad hoc convention: cpu number gets palcode, process code doesn't.
532 This supports usage under DU 4.0b that does ".arch ev4", and
533 usage in MILO that does -m21064. Probably something more
534 specific like -m21064-pal should be used, but oh well. */
536 { "21064", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
537 { "21064a", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
538 { "21066", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
539 { "21068", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
540 { "21164", AXP_OPCODE_BASE
|AXP_OPCODE_EV5
},
541 { "21164a", AXP_OPCODE_BASE
|AXP_OPCODE_EV5
|AXP_OPCODE_BWX
},
542 { "21164pc", (AXP_OPCODE_BASE
|AXP_OPCODE_EV5
|AXP_OPCODE_BWX
544 { "21264", (AXP_OPCODE_BASE
|AXP_OPCODE_EV6
|AXP_OPCODE_BWX
545 |AXP_OPCODE_MAX
|AXP_OPCODE_CIX
) },
546 { "21264a", (AXP_OPCODE_BASE
|AXP_OPCODE_EV6
|AXP_OPCODE_BWX
547 |AXP_OPCODE_MAX
|AXP_OPCODE_CIX
) },
548 { "21264b", (AXP_OPCODE_BASE
|AXP_OPCODE_EV6
|AXP_OPCODE_BWX
549 |AXP_OPCODE_MAX
|AXP_OPCODE_CIX
) },
551 { "ev4", AXP_OPCODE_BASE
},
552 { "ev45", AXP_OPCODE_BASE
},
553 { "lca45", AXP_OPCODE_BASE
},
554 { "ev5", AXP_OPCODE_BASE
},
555 { "ev56", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
},
556 { "pca56", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
|AXP_OPCODE_MAX
},
557 { "ev6", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
|AXP_OPCODE_MAX
|AXP_OPCODE_CIX
},
558 { "ev67", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
|AXP_OPCODE_MAX
|AXP_OPCODE_CIX
},
559 { "ev68", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
|AXP_OPCODE_MAX
|AXP_OPCODE_CIX
},
561 { "all", AXP_OPCODE_BASE
},
565 /* Some instruction sets indexed by lg(size). */
566 static const char * const sextX_op
[] = { "sextb", "sextw", "sextl", NULL
};
567 static const char * const insXl_op
[] = { "insbl", "inswl", "insll", "insql" };
568 static const char * const insXh_op
[] = { NULL
, "inswh", "inslh", "insqh" };
569 static const char * const extXl_op
[] = { "extbl", "extwl", "extll", "extql" };
570 static const char * const extXh_op
[] = { NULL
, "extwh", "extlh", "extqh" };
571 static const char * const mskXl_op
[] = { "mskbl", "mskwl", "mskll", "mskql" };
572 static const char * const mskXh_op
[] = { NULL
, "mskwh", "msklh", "mskqh" };
573 static const char * const stX_op
[] = { "stb", "stw", "stl", "stq" };
574 static const char * const ldXu_op
[] = { "ldbu", "ldwu", NULL
, NULL
};
576 static void assemble_insn (const struct alpha_opcode
*, const expressionS
*, int, struct alpha_insn
*, extended_bfd_reloc_code_real_type
);
577 static void emit_insn (struct alpha_insn
*);
578 static void assemble_tokens (const char *, const expressionS
*, int, int);
580 static const char *s_alpha_section_name (void);
581 static symbolS
*add_to_link_pool (symbolS
*, offsetT
);
584 static struct alpha_reloc_tag
*
585 get_alpha_reloc_tag (long sequence
)
587 char buffer
[ALPHA_RELOC_DIGITS
];
588 struct alpha_reloc_tag
*info
;
590 sprintf (buffer
, "!%ld", sequence
);
592 info
= (struct alpha_reloc_tag
*) str_hash_find (alpha_literal_hash
, buffer
);
595 size_t len
= strlen (buffer
);
597 info
= (struct alpha_reloc_tag
*)
598 xcalloc (sizeof (struct alpha_reloc_tag
) + len
, 1);
600 info
->segment
= now_seg
;
601 info
->sequence
= sequence
;
602 strcpy (info
->string
, buffer
);
603 str_hash_insert (alpha_literal_hash
, info
->string
, info
, 0);
616 alpha_adjust_relocs (bfd
*abfd ATTRIBUTE_UNUSED
,
618 void * ptr ATTRIBUTE_UNUSED
)
620 segment_info_type
*seginfo
= seg_info (sec
);
626 /* If seginfo is NULL, we did not create this section; don't do
627 anything with it. By using a pointer to a pointer, we can update
628 the links in place. */
632 /* If there are no relocations, skip the section. */
633 if (! seginfo
->fix_root
)
636 /* First rebuild the fixup chain without the explicit lituse and
637 gpdisp_lo16 relocs. */
638 prevP
= &seginfo
->fix_root
;
639 for (fixp
= seginfo
->fix_root
; fixp
; fixp
= next
)
641 next
= fixp
->fx_next
;
642 fixp
->fx_next
= (fixS
*) 0;
644 switch (fixp
->fx_r_type
)
646 case BFD_RELOC_ALPHA_LITUSE
:
647 if (fixp
->tc_fix_data
.info
->n_master
== 0)
648 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
649 _("No !literal!%ld was found"),
650 fixp
->tc_fix_data
.info
->sequence
);
652 if (fixp
->fx_offset
== LITUSE_ALPHA_TLSGD
)
654 if (! fixp
->tc_fix_data
.info
->saw_tlsgd
)
655 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
656 _("No !tlsgd!%ld was found"),
657 fixp
->tc_fix_data
.info
->sequence
);
659 else if (fixp
->fx_offset
== LITUSE_ALPHA_TLSLDM
)
661 if (! fixp
->tc_fix_data
.info
->saw_tlsldm
)
662 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
663 _("No !tlsldm!%ld was found"),
664 fixp
->tc_fix_data
.info
->sequence
);
669 case BFD_RELOC_ALPHA_GPDISP_LO16
:
670 if (fixp
->tc_fix_data
.info
->n_master
== 0)
671 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
672 _("No ldah !gpdisp!%ld was found"),
673 fixp
->tc_fix_data
.info
->sequence
);
676 case BFD_RELOC_ALPHA_ELF_LITERAL
:
677 if (fixp
->tc_fix_data
.info
678 && (fixp
->tc_fix_data
.info
->saw_tlsgd
679 || fixp
->tc_fix_data
.info
->saw_tlsldm
))
685 prevP
= &fixp
->fx_next
;
690 /* Go back and re-chain dependent relocations. They are currently
691 linked through the next_reloc field in reverse order, so as we
692 go through the next_reloc chain, we effectively reverse the chain
695 Except if there is more than one !literal for a given sequence
696 number. In that case, the programmer and/or compiler is not sure
697 how control flows from literal to lituse, and we can't be sure to
698 get the relaxation correct.
700 ??? Well, actually we could, if there are enough lituses such that
701 we can make each literal have at least one of each lituse type
702 present. Not implemented.
704 Also suppress the optimization if the !literals/!lituses are spread
705 in different segments. This can happen with "interesting" uses of
706 inline assembly; examples are present in the Linux kernel semaphores. */
708 for (fixp
= seginfo
->fix_root
; fixp
; fixp
= next
)
710 next
= fixp
->fx_next
;
711 switch (fixp
->fx_r_type
)
713 case BFD_RELOC_ALPHA_TLSGD
:
714 case BFD_RELOC_ALPHA_TLSLDM
:
715 if (!fixp
->tc_fix_data
.info
)
717 if (fixp
->tc_fix_data
.info
->n_master
== 0)
719 else if (fixp
->tc_fix_data
.info
->n_master
> 1)
721 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
722 _("too many !literal!%ld for %s"),
723 fixp
->tc_fix_data
.info
->sequence
,
724 (fixp
->fx_r_type
== BFD_RELOC_ALPHA_TLSGD
725 ? "!tlsgd" : "!tlsldm"));
729 fixp
->tc_fix_data
.info
->master
->fx_next
= fixp
->fx_next
;
730 fixp
->fx_next
= fixp
->tc_fix_data
.info
->master
;
731 fixp
= fixp
->fx_next
;
734 case BFD_RELOC_ALPHA_ELF_LITERAL
:
735 if (fixp
->tc_fix_data
.info
736 && fixp
->tc_fix_data
.info
->n_master
== 1
737 && ! fixp
->tc_fix_data
.info
->multi_section_p
)
739 for (slave
= fixp
->tc_fix_data
.info
->slaves
;
741 slave
= slave
->tc_fix_data
.next_reloc
)
743 slave
->fx_next
= fixp
->fx_next
;
744 fixp
->fx_next
= slave
;
749 case BFD_RELOC_ALPHA_GPDISP_HI16
:
750 if (fixp
->tc_fix_data
.info
->n_slaves
== 0)
751 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
752 _("No lda !gpdisp!%ld was found"),
753 fixp
->tc_fix_data
.info
->sequence
);
756 slave
= fixp
->tc_fix_data
.info
->slaves
;
757 slave
->fx_next
= next
;
758 fixp
->fx_next
= slave
;
768 /* Before the relocations are written, reorder them, so that user
769 supplied !lituse relocations follow the appropriate !literal
770 relocations, and similarly for !gpdisp relocations. */
773 alpha_before_fix (void)
775 if (alpha_literal_hash
)
776 bfd_map_over_sections (stdoutput
, alpha_adjust_relocs
, NULL
);
783 debug_exp (expressionS tok
[], int ntok
)
787 fprintf (stderr
, "debug_exp: %d tokens", ntok
);
788 for (i
= 0; i
< ntok
; i
++)
790 expressionS
*t
= &tok
[i
];
795 default: name
= "unknown"; break;
796 case O_illegal
: name
= "O_illegal"; break;
797 case O_absent
: name
= "O_absent"; break;
798 case O_constant
: name
= "O_constant"; break;
799 case O_symbol
: name
= "O_symbol"; break;
800 case O_symbol_rva
: name
= "O_symbol_rva"; break;
801 case O_register
: name
= "O_register"; break;
802 case O_big
: name
= "O_big"; break;
803 case O_uminus
: name
= "O_uminus"; break;
804 case O_bit_not
: name
= "O_bit_not"; break;
805 case O_logical_not
: name
= "O_logical_not"; break;
806 case O_multiply
: name
= "O_multiply"; break;
807 case O_divide
: name
= "O_divide"; break;
808 case O_modulus
: name
= "O_modulus"; break;
809 case O_left_shift
: name
= "O_left_shift"; break;
810 case O_right_shift
: name
= "O_right_shift"; break;
811 case O_bit_inclusive_or
: name
= "O_bit_inclusive_or"; break;
812 case O_bit_or_not
: name
= "O_bit_or_not"; break;
813 case O_bit_exclusive_or
: name
= "O_bit_exclusive_or"; break;
814 case O_bit_and
: name
= "O_bit_and"; break;
815 case O_add
: name
= "O_add"; break;
816 case O_subtract
: name
= "O_subtract"; break;
817 case O_eq
: name
= "O_eq"; break;
818 case O_ne
: name
= "O_ne"; break;
819 case O_lt
: name
= "O_lt"; break;
820 case O_le
: name
= "O_le"; break;
821 case O_ge
: name
= "O_ge"; break;
822 case O_gt
: name
= "O_gt"; break;
823 case O_logical_and
: name
= "O_logical_and"; break;
824 case O_logical_or
: name
= "O_logical_or"; break;
825 case O_index
: name
= "O_index"; break;
826 case O_pregister
: name
= "O_pregister"; break;
827 case O_cpregister
: name
= "O_cpregister"; break;
828 case O_literal
: name
= "O_literal"; break;
829 case O_lituse_addr
: name
= "O_lituse_addr"; break;
830 case O_lituse_base
: name
= "O_lituse_base"; break;
831 case O_lituse_bytoff
: name
= "O_lituse_bytoff"; break;
832 case O_lituse_jsr
: name
= "O_lituse_jsr"; break;
833 case O_lituse_tlsgd
: name
= "O_lituse_tlsgd"; break;
834 case O_lituse_tlsldm
: name
= "O_lituse_tlsldm"; break;
835 case O_lituse_jsrdirect
: name
= "O_lituse_jsrdirect"; break;
836 case O_gpdisp
: name
= "O_gpdisp"; break;
837 case O_gprelhigh
: name
= "O_gprelhigh"; break;
838 case O_gprellow
: name
= "O_gprellow"; break;
839 case O_gprel
: name
= "O_gprel"; break;
840 case O_samegp
: name
= "O_samegp"; break;
841 case O_tlsgd
: name
= "O_tlsgd"; break;
842 case O_tlsldm
: name
= "O_tlsldm"; break;
843 case O_gotdtprel
: name
= "O_gotdtprel"; break;
844 case O_dtprelhi
: name
= "O_dtprelhi"; break;
845 case O_dtprello
: name
= "O_dtprello"; break;
846 case O_dtprel
: name
= "O_dtprel"; break;
847 case O_gottprel
: name
= "O_gottprel"; break;
848 case O_tprelhi
: name
= "O_tprelhi"; break;
849 case O_tprello
: name
= "O_tprello"; break;
850 case O_tprel
: name
= "O_tprel"; break;
853 fprintf (stderr
, ", %s(%s, %s, %d)", name
,
854 (t
->X_add_symbol
) ? S_GET_NAME (t
->X_add_symbol
) : "--",
855 (t
->X_op_symbol
) ? S_GET_NAME (t
->X_op_symbol
) : "--",
856 (int) t
->X_add_number
);
858 fprintf (stderr
, "\n");
863 /* Parse the arguments to an opcode. */
866 tokenize_arguments (char *str
,
870 expressionS
*end_tok
= tok
+ ntok
;
871 char *old_input_line_pointer
;
872 int saw_comma
= 0, saw_arg
= 0;
874 expressionS
*orig_tok
= tok
;
878 const struct alpha_reloc_op_tag
*r
;
881 int reloc_found_p
= 0;
884 memset (tok
, 0, sizeof (*tok
) * ntok
);
886 /* Save and restore input_line_pointer around this function. */
887 old_input_line_pointer
= input_line_pointer
;
888 input_line_pointer
= str
;
891 /* ??? Wrest control of ! away from the regular expression parser. */
892 is_end_of_line
[(unsigned char) '!'] = 1;
895 while (tok
< end_tok
&& *input_line_pointer
)
898 switch (*input_line_pointer
)
905 /* A relocation operand can be placed after the normal operand on an
906 assembly language statement, and has the following form:
907 !relocation_type!sequence_number. */
910 /* Only support one relocation op per insn. */
911 as_bad (_("More than one relocation op per insn"));
918 ++input_line_pointer
;
920 c
= get_symbol_name (&p
);
922 /* Parse !relocation_type. */
923 len
= input_line_pointer
- p
;
926 as_bad (_("No relocation operand"));
930 r
= &alpha_reloc_op
[0];
931 for (i
= alpha_num_reloc_op
- 1; i
>= 0; i
--, r
++)
932 if (len
== r
->length
&& memcmp (p
, r
->name
, len
) == 0)
936 as_bad (_("Unknown relocation operand: !%s"), p
);
940 *input_line_pointer
= c
;
941 SKIP_WHITESPACE_AFTER_NAME ();
942 if (*input_line_pointer
!= '!')
946 as_bad (_("no sequence number after !%s"), p
);
950 tok
->X_add_number
= 0;
956 as_bad (_("!%s does not use a sequence number"), p
);
960 input_line_pointer
++;
962 /* Parse !sequence_number. */
964 if (tok
->X_op
!= O_constant
|| tok
->X_add_number
<= 0)
966 as_bad (_("Bad sequence number: !%s!%s"),
967 r
->name
, input_line_pointer
);
976 #endif /* RELOC_OP_P */
979 ++input_line_pointer
;
980 if (saw_comma
|| !saw_arg
)
987 char *hold
= input_line_pointer
++;
989 /* First try for parenthesized register ... */
991 if (*input_line_pointer
== ')' && tok
->X_op
== O_register
)
993 tok
->X_op
= (saw_comma
? O_cpregister
: O_pregister
);
996 ++input_line_pointer
;
1001 /* ... then fall through to plain expression. */
1002 input_line_pointer
= hold
;
1007 if (saw_arg
&& !saw_comma
)
1011 if (tok
->X_op
== O_illegal
|| tok
->X_op
== O_absent
)
1024 input_line_pointer
= old_input_line_pointer
;
1027 debug_exp (orig_tok
, ntok
- (end_tok
- tok
));
1030 is_end_of_line
[(unsigned char) '!'] = 0;
1033 return ntok
- (end_tok
- tok
);
1037 is_end_of_line
[(unsigned char) '!'] = 0;
1039 input_line_pointer
= old_input_line_pointer
;
1040 return TOKENIZE_ERROR
;
1044 is_end_of_line
[(unsigned char) '!'] = 0;
1046 input_line_pointer
= old_input_line_pointer
;
1047 return TOKENIZE_ERROR_REPORT
;
1050 /* Search forward through all variants of an opcode looking for a
1053 static const struct alpha_opcode
*
1054 find_opcode_match (const struct alpha_opcode
*first_opcode
,
1055 const expressionS
*tok
,
1059 const struct alpha_opcode
*opcode
= first_opcode
;
1061 int got_cpu_match
= 0;
1065 const unsigned char *opidx
;
1068 /* Don't match opcodes that don't exist on this architecture. */
1069 if (!(opcode
->flags
& alpha_target
))
1074 for (opidx
= opcode
->operands
; *opidx
; ++opidx
)
1076 const struct alpha_operand
*operand
= &alpha_operands
[*opidx
];
1078 /* Only take input from real operands. */
1079 if (operand
->flags
& AXP_OPERAND_FAKE
)
1082 /* When we expect input, make sure we have it. */
1085 if ((operand
->flags
& AXP_OPERAND_OPTIONAL_MASK
) == 0)
1090 /* Match operand type with expression type. */
1091 switch (operand
->flags
& AXP_OPERAND_TYPECHECK_MASK
)
1093 case AXP_OPERAND_IR
:
1094 if (tok
[tokidx
].X_op
!= O_register
1095 || !is_ir_num (tok
[tokidx
].X_add_number
))
1098 case AXP_OPERAND_FPR
:
1099 if (tok
[tokidx
].X_op
!= O_register
1100 || !is_fpr_num (tok
[tokidx
].X_add_number
))
1103 case AXP_OPERAND_IR
| AXP_OPERAND_PARENS
:
1104 if (tok
[tokidx
].X_op
!= O_pregister
1105 || !is_ir_num (tok
[tokidx
].X_add_number
))
1108 case AXP_OPERAND_IR
| AXP_OPERAND_PARENS
| AXP_OPERAND_COMMA
:
1109 if (tok
[tokidx
].X_op
!= O_cpregister
1110 || !is_ir_num (tok
[tokidx
].X_add_number
))
1114 case AXP_OPERAND_RELATIVE
:
1115 case AXP_OPERAND_SIGNED
:
1116 case AXP_OPERAND_UNSIGNED
:
1117 switch (tok
[tokidx
].X_op
)
1132 /* Everything else should have been fake. */
1138 /* Possible match -- did we use all of our input? */
1147 while (++opcode
- alpha_opcodes
< (int) alpha_num_opcodes
1148 && !strcmp (opcode
->name
, first_opcode
->name
));
1151 *pcpumatch
= got_cpu_match
;
1156 /* Given an opcode name and a pre-tokenized set of arguments, assemble
1157 the insn, but do not emit it.
1159 Note that this implies no macros allowed, since we can't store more
1160 than one insn in an insn structure. */
1163 assemble_tokens_to_insn (const char *opname
,
1164 const expressionS
*tok
,
1166 struct alpha_insn
*insn
)
1168 const struct alpha_opcode
*opcode
;
1170 /* Search opcodes. */
1171 opcode
= (const struct alpha_opcode
*) str_hash_find (alpha_opcode_hash
,
1176 opcode
= find_opcode_match (opcode
, tok
, &ntok
, &cpumatch
);
1179 assemble_insn (opcode
, tok
, ntok
, insn
, BFD_RELOC_UNUSED
);
1183 as_bad (_("inappropriate arguments for opcode `%s'"), opname
);
1185 as_bad (_("opcode `%s' not supported for target %s"), opname
,
1189 as_bad (_("unknown opcode `%s'"), opname
);
1192 /* Build a BFD section with its flags set appropriately for the .lita,
1193 .lit8, or .lit4 sections. */
1196 create_literal_section (const char *name
,
1200 segT current_section
= now_seg
;
1201 int current_subsec
= now_subseg
;
1204 *secp
= new_sec
= subseg_new (name
, 0);
1205 subseg_set (current_section
, current_subsec
);
1206 bfd_set_section_alignment (new_sec
, 4);
1207 bfd_set_section_flags (new_sec
, (SEC_RELOC
| SEC_ALLOC
| SEC_LOAD
1208 | SEC_READONLY
| SEC_DATA
));
1210 S_CLEAR_EXTERNAL (*symp
= section_symbol (new_sec
));
1213 /* Load a (partial) expression into a target register.
1215 If poffset is not null, after the call it will either contain
1216 O_constant 0, or a 16-bit offset appropriate for any MEM format
1217 instruction. In addition, pbasereg will be modified to point to
1218 the base register to use in that MEM format instruction.
1220 In any case, *pbasereg should contain a base register to add to the
1221 expression. This will normally be either AXP_REG_ZERO or
1222 alpha_gp_register. Symbol addresses will always be loaded via $gp,
1223 so "foo($0)" is interpreted as adding the address of foo to $0;
1224 i.e. "ldq $targ, LIT($gp); addq $targ, $0, $targ". Odd, perhaps,
1225 but this is what OSF/1 does.
1227 If explicit relocations of the form !literal!<number> are allowed,
1228 and used, then explicit_reloc with be an expression pointer.
1230 Finally, the return value is nonzero if the calling macro may emit
1231 a LITUSE reloc if otherwise appropriate; the return value is the
1232 sequence number to use. */
1235 load_expression (int targreg
,
1236 const expressionS
*exp
,
1238 expressionS
*poffset
,
1241 long emit_lituse
= 0;
1242 offsetT addend
= exp
->X_add_number
;
1243 int basereg
= *pbasereg
;
1244 struct alpha_insn insn
;
1245 expressionS newtok
[3];
1254 /* Attempt to reduce .lit load by splitting the offset from
1255 its symbol when possible, but don't create a situation in
1257 if (!range_signed_32 (addend
) &&
1258 (alpha_noat_on
|| targreg
== AXP_REG_AT
))
1260 lit
= add_to_literal_pool (exp
->X_add_symbol
, addend
,
1261 alpha_lita_section
, 8);
1265 lit
= add_to_literal_pool (exp
->X_add_symbol
, 0,
1266 alpha_lita_section
, 8);
1269 as_fatal (_("overflow in literal (.lita) table"));
1271 /* Emit "ldq r, lit(gp)". */
1273 if (basereg
!= alpha_gp_register
&& targreg
== basereg
)
1276 as_bad (_("macro requires $at register while noat in effect"));
1277 if (targreg
== AXP_REG_AT
)
1278 as_bad (_("macro requires $at while $at in use"));
1280 set_tok_reg (newtok
[0], AXP_REG_AT
);
1283 set_tok_reg (newtok
[0], targreg
);
1285 set_tok_sym (newtok
[1], alpha_lita_symbol
, lit
);
1286 set_tok_preg (newtok
[2], alpha_gp_register
);
1288 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
1290 gas_assert (insn
.nfixups
== 1);
1291 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITERAL
;
1292 insn
.sequence
= emit_lituse
= next_sequence_num
--;
1293 #endif /* OBJ_ECOFF */
1295 /* Emit "ldq r, gotoff(gp)". */
1297 if (basereg
!= alpha_gp_register
&& targreg
== basereg
)
1300 as_bad (_("macro requires $at register while noat in effect"));
1301 if (targreg
== AXP_REG_AT
)
1302 as_bad (_("macro requires $at while $at in use"));
1304 set_tok_reg (newtok
[0], AXP_REG_AT
);
1307 set_tok_reg (newtok
[0], targreg
);
1309 /* XXX: Disable this .got minimizing optimization so that we can get
1310 better instruction offset knowledge in the compiler. This happens
1311 very infrequently anyway. */
1313 || (!range_signed_32 (addend
)
1314 && (alpha_noat_on
|| targreg
== AXP_REG_AT
)))
1320 set_tok_sym (newtok
[1], exp
->X_add_symbol
, 0);
1322 set_tok_preg (newtok
[2], alpha_gp_register
);
1324 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
1326 gas_assert (insn
.nfixups
== 1);
1327 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_ELF_LITERAL
;
1328 insn
.sequence
= emit_lituse
= next_sequence_num
--;
1329 #endif /* OBJ_ELF */
1331 /* Find symbol or symbol pointer in link section. */
1333 if (exp
->X_add_symbol
== alpha_evax_proc
->symbol
)
1335 /* Linkage-relative expression. */
1336 set_tok_reg (newtok
[0], targreg
);
1338 if (range_signed_16 (addend
))
1340 set_tok_const (newtok
[1], addend
);
1345 set_tok_const (newtok
[1], 0);
1347 set_tok_preg (newtok
[2], basereg
);
1348 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
1352 const char *symname
= S_GET_NAME (exp
->X_add_symbol
);
1353 const char *ptr1
, *ptr2
;
1354 int symlen
= strlen (symname
);
1357 strcmp (ptr2
= &symname
[symlen
- 4], "..lk") == 0))
1359 /* Access to an item whose address is stored in the linkage
1360 section. Just read the address. */
1361 set_tok_reg (newtok
[0], targreg
);
1364 newtok
[1].X_op
= O_subtract
;
1365 newtok
[1].X_op_symbol
= alpha_evax_proc
->symbol
;
1367 set_tok_preg (newtok
[2], basereg
);
1368 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
1369 alpha_linkage_symbol
= exp
->X_add_symbol
;
1372 set_tok_const (*poffset
, 0);
1374 if (alpha_flag_replace
&& targreg
== 26)
1376 /* Add a NOP fixup for 'ldX $26,YYY..NAME..lk'. */
1380 /* Build the entry name as 'NAME..en'. */
1381 ptr1
= strstr (symname
, "..") + 2;
1384 ensymname
= XNEWVEC (char, ptr2
- ptr1
+ 5);
1385 memcpy (ensymname
, ptr1
, ptr2
- ptr1
);
1386 memcpy (ensymname
+ (ptr2
- ptr1
), "..en", 5);
1388 gas_assert (insn
.nfixups
+ 1 <= MAX_INSN_FIXUPS
);
1389 insn
.fixups
[insn
.nfixups
].reloc
= BFD_RELOC_ALPHA_NOP
;
1390 ensym
= symbol_find_or_make (ensymname
);
1392 symbol_mark_used (ensym
);
1393 /* The fixup must be the same as the BFD_RELOC_ALPHA_BOH
1394 case in emit_jsrjmp. See B.4.5.2 of the OpenVMS Linker
1396 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_symbol
;
1397 insn
.fixups
[insn
.nfixups
].exp
.X_add_symbol
= ensym
;
1398 insn
.fixups
[insn
.nfixups
].exp
.X_add_number
= 0;
1399 insn
.fixups
[insn
.nfixups
].xtrasym
= alpha_linkage_symbol
;
1400 insn
.fixups
[insn
.nfixups
].procsym
= alpha_evax_proc
->symbol
;
1403 /* ??? Force bsym to be instantiated now, as it will be
1404 too late to do so in tc_gen_reloc. */
1405 symbol_get_bfdsym (exp
->X_add_symbol
);
1407 else if (alpha_flag_replace
&& targreg
== 27)
1409 /* Add a lda fixup for 'ldX $27,YYY.NAME..lk+8'. */
1414 ptr1
= strstr (symname
, "..") + 2;
1417 psymname
= xmemdup0 (ptr1
, ptr2
- ptr1
);
1419 gas_assert (insn
.nfixups
+ 1 <= MAX_INSN_FIXUPS
);
1420 insn
.fixups
[insn
.nfixups
].reloc
= BFD_RELOC_ALPHA_LDA
;
1421 psym
= symbol_find_or_make (psymname
);
1423 symbol_mark_used (psym
);
1424 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_subtract
;
1425 insn
.fixups
[insn
.nfixups
].exp
.X_add_symbol
= psym
;
1426 insn
.fixups
[insn
.nfixups
].exp
.X_op_symbol
= alpha_evax_proc
->symbol
;
1427 insn
.fixups
[insn
.nfixups
].exp
.X_add_number
= 0;
1428 insn
.fixups
[insn
.nfixups
].xtrasym
= alpha_linkage_symbol
;
1429 insn
.fixups
[insn
.nfixups
].procsym
= alpha_evax_proc
->symbol
;
1438 /* Not in the linkage section. Put the value into the linkage
1442 if (!range_signed_32 (addend
))
1443 addend
= sign_extend_32 (addend
);
1444 linkexp
= add_to_link_pool (exp
->X_add_symbol
, 0);
1445 set_tok_reg (newtok
[0], targreg
);
1446 set_tok_sym (newtok
[1], linkexp
, 0);
1447 set_tok_preg (newtok
[2], basereg
);
1448 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
1451 #endif /* OBJ_EVAX */
1456 if (basereg
!= alpha_gp_register
&& basereg
!= AXP_REG_ZERO
)
1458 /* Emit "addq r, base, r". */
1460 set_tok_reg (newtok
[1], basereg
);
1461 set_tok_reg (newtok
[2], targreg
);
1462 assemble_tokens ("addq", newtok
, 3, 0);
1473 /* Assume that this difference expression will be resolved to an
1474 absolute value and that that value will fit in 16 bits. */
1476 set_tok_reg (newtok
[0], targreg
);
1478 set_tok_preg (newtok
[2], basereg
);
1479 assemble_tokens (opname
, newtok
, 3, 0);
1482 set_tok_const (*poffset
, 0);
1486 if (exp
->X_add_number
> 0)
1487 as_bad (_("bignum invalid; zero assumed"));
1489 as_bad (_("floating point number invalid; zero assumed"));
1494 as_bad (_("can't handle expression"));
1499 if (!range_signed_32 (addend
))
1505 long seq_num
= next_sequence_num
--;
1508 /* For 64-bit addends, just put it in the literal pool. */
1510 /* Emit "ldq targreg, lit(basereg)". */
1511 litexp
= add_to_link_pool (section_symbol (absolute_section
), addend
);
1512 set_tok_reg (newtok
[0], targreg
);
1513 set_tok_sym (newtok
[1], litexp
, 0);
1514 set_tok_preg (newtok
[2], alpha_gp_register
);
1515 assemble_tokens ("ldq", newtok
, 3, 0);
1518 if (alpha_lit8_section
== NULL
)
1520 create_literal_section (".lit8",
1521 &alpha_lit8_section
,
1522 &alpha_lit8_symbol
);
1525 alpha_lit8_literal
= add_to_literal_pool (alpha_lit8_symbol
, 0x8000,
1526 alpha_lita_section
, 8);
1527 if (alpha_lit8_literal
>= 0x8000)
1528 as_fatal (_("overflow in literal (.lita) table"));
1532 lit
= add_to_literal_pool (NULL
, addend
, alpha_lit8_section
, 8) - 0x8000;
1534 as_fatal (_("overflow in literal (.lit8) table"));
1536 /* Emit "lda litreg, .lit8+0x8000". */
1538 if (targreg
== basereg
)
1541 as_bad (_("macro requires $at register while noat in effect"));
1542 if (targreg
== AXP_REG_AT
)
1543 as_bad (_("macro requires $at while $at in use"));
1545 set_tok_reg (newtok
[0], AXP_REG_AT
);
1548 set_tok_reg (newtok
[0], targreg
);
1550 set_tok_sym (newtok
[1], alpha_lita_symbol
, alpha_lit8_literal
);
1553 set_tok_sym (newtok
[1], alpha_lit8_symbol
, 0x8000);
1555 set_tok_preg (newtok
[2], alpha_gp_register
);
1557 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
1559 gas_assert (insn
.nfixups
== 1);
1561 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITERAL
;
1564 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_ELF_LITERAL
;
1566 insn
.sequence
= seq_num
;
1570 /* Emit "ldq litreg, lit(litreg)". */
1572 set_tok_const (newtok
[1], lit
);
1573 set_tok_preg (newtok
[2], newtok
[0].X_add_number
);
1575 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
1577 gas_assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
1578 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BASE
;
1579 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
1581 insn
.sequence
= seq_num
;
1586 /* Emit "addq litreg, base, target". */
1588 if (basereg
!= AXP_REG_ZERO
)
1590 set_tok_reg (newtok
[1], basereg
);
1591 set_tok_reg (newtok
[2], targreg
);
1592 assemble_tokens ("addq", newtok
, 3, 0);
1594 #endif /* !OBJ_EVAX */
1597 set_tok_const (*poffset
, 0);
1598 *pbasereg
= targreg
;
1602 offsetT low
, high
, extra
, tmp
;
1604 /* For 32-bit operands, break up the addend. */
1606 low
= sign_extend_16 (addend
);
1608 high
= sign_extend_16 (tmp
>> 16);
1610 if (tmp
- (high
<< 16))
1614 high
= sign_extend_16 (tmp
>> 16);
1619 set_tok_reg (newtok
[0], targreg
);
1620 set_tok_preg (newtok
[2], basereg
);
1624 /* Emit "ldah r, extra(r). */
1625 set_tok_const (newtok
[1], extra
);
1626 assemble_tokens ("ldah", newtok
, 3, 0);
1627 set_tok_preg (newtok
[2], basereg
= targreg
);
1632 /* Emit "ldah r, high(r). */
1633 set_tok_const (newtok
[1], high
);
1634 assemble_tokens ("ldah", newtok
, 3, 0);
1636 set_tok_preg (newtok
[2], basereg
);
1639 if ((low
&& !poffset
) || (!poffset
&& basereg
!= targreg
))
1641 /* Emit "lda r, low(base)". */
1642 set_tok_const (newtok
[1], low
);
1643 assemble_tokens ("lda", newtok
, 3, 0);
1649 set_tok_const (*poffset
, low
);
1650 *pbasereg
= basereg
;
1656 /* The lda macro differs from the lda instruction in that it handles
1657 most simple expressions, particularly symbol address loads and
1661 emit_lda (const expressionS
*tok
,
1663 const void * unused ATTRIBUTE_UNUSED
)
1668 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
1670 basereg
= tok
[2].X_add_number
;
1672 (void) load_expression (tok
[0].X_add_number
, &tok
[1], &basereg
, NULL
, "lda");
1675 /* The ldah macro differs from the ldah instruction in that it has $31
1676 as an implied base register. */
1679 emit_ldah (const expressionS
*tok
,
1680 int ntok ATTRIBUTE_UNUSED
,
1681 const void * unused ATTRIBUTE_UNUSED
)
1683 expressionS newtok
[3];
1687 set_tok_preg (newtok
[2], AXP_REG_ZERO
);
1689 assemble_tokens ("ldah", newtok
, 3, 0);
1692 /* Called internally to handle all alignment needs. This takes care
1693 of eliding calls to frag_align if'n the cached current alignment
1694 says we've already got it, as well as taking care of the auto-align
1695 feature wrt labels. */
1701 int force ATTRIBUTE_UNUSED
)
1703 if (alpha_current_align
>= n
)
1708 if (subseg_text_p (now_seg
))
1709 frag_align_code (n
, 0);
1711 frag_align (n
, 0, 0);
1714 frag_align (n
, *pfill
, 0);
1716 alpha_current_align
= n
;
1718 if (label
!= NULL
&& S_GET_SEGMENT (label
) == now_seg
)
1720 symbol_set_frag (label
, frag_now
);
1721 S_SET_VALUE (label
, (valueT
) frag_now_fix ());
1724 record_alignment (now_seg
, n
);
1726 /* ??? If alpha_flag_relax && force && elf, record the requested alignment
1727 in a reloc for the linker to see. */
1730 /* Actually output an instruction with its fixup. */
1733 emit_insn (struct alpha_insn
*insn
)
1738 /* Take care of alignment duties. */
1739 if (alpha_auto_align_on
&& alpha_current_align
< 2)
1740 alpha_align (2, (char *) NULL
, alpha_insn_label
, 0);
1741 if (alpha_current_align
> 2)
1742 alpha_current_align
= 2;
1743 alpha_insn_label
= NULL
;
1745 /* Write out the instruction. */
1747 md_number_to_chars (f
, insn
->insn
, 4);
1750 dwarf2_emit_insn (4);
1753 /* Apply the fixups in order. */
1754 for (i
= 0; i
< insn
->nfixups
; ++i
)
1756 const struct alpha_operand
*operand
= (const struct alpha_operand
*) 0;
1757 struct alpha_fixup
*fixup
= &insn
->fixups
[i
];
1758 struct alpha_reloc_tag
*info
= NULL
;
1762 /* Some fixups are only used internally and so have no howto. */
1763 if ((int) fixup
->reloc
< 0)
1765 operand
= &alpha_operands
[-(int) fixup
->reloc
];
1767 pcrel
= ((operand
->flags
& AXP_OPERAND_RELATIVE
) != 0);
1769 else if (fixup
->reloc
> BFD_RELOC_UNUSED
1770 || fixup
->reloc
== BFD_RELOC_ALPHA_GPDISP_HI16
1771 || fixup
->reloc
== BFD_RELOC_ALPHA_GPDISP_LO16
)
1778 reloc_howto_type
*reloc_howto
=
1779 bfd_reloc_type_lookup (stdoutput
,
1780 (bfd_reloc_code_real_type
) fixup
->reloc
);
1781 gas_assert (reloc_howto
);
1783 size
= bfd_get_reloc_size (reloc_howto
);
1785 switch (fixup
->reloc
)
1788 case BFD_RELOC_ALPHA_NOP
:
1789 case BFD_RELOC_ALPHA_BSR
:
1790 case BFD_RELOC_ALPHA_LDA
:
1791 case BFD_RELOC_ALPHA_BOH
:
1795 gas_assert (size
>= 1 && size
<= 4);
1798 pcrel
= reloc_howto
->pc_relative
;
1801 fixP
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, size
,
1802 &fixup
->exp
, pcrel
, (bfd_reloc_code_real_type
) fixup
->reloc
);
1804 /* Turn off complaints that the addend is too large for some fixups,
1805 and copy in the sequence number for the explicit relocations. */
1806 switch (fixup
->reloc
)
1808 case BFD_RELOC_ALPHA_HINT
:
1809 case BFD_RELOC_GPREL32
:
1810 case BFD_RELOC_GPREL16
:
1811 case BFD_RELOC_ALPHA_GPREL_HI16
:
1812 case BFD_RELOC_ALPHA_GPREL_LO16
:
1813 case BFD_RELOC_ALPHA_GOTDTPREL16
:
1814 case BFD_RELOC_ALPHA_DTPREL_HI16
:
1815 case BFD_RELOC_ALPHA_DTPREL_LO16
:
1816 case BFD_RELOC_ALPHA_DTPREL16
:
1817 case BFD_RELOC_ALPHA_GOTTPREL16
:
1818 case BFD_RELOC_ALPHA_TPREL_HI16
:
1819 case BFD_RELOC_ALPHA_TPREL_LO16
:
1820 case BFD_RELOC_ALPHA_TPREL16
:
1821 fixP
->fx_no_overflow
= 1;
1824 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1825 fixP
->fx_no_overflow
= 1;
1826 fixP
->fx_addsy
= section_symbol (now_seg
);
1827 fixP
->fx_offset
= 0;
1829 info
= get_alpha_reloc_tag (insn
->sequence
);
1830 if (++info
->n_master
> 1)
1831 as_bad (_("too many ldah insns for !gpdisp!%ld"), insn
->sequence
);
1832 if (info
->segment
!= now_seg
)
1833 as_bad (_("both insns for !gpdisp!%ld must be in the same section"),
1835 fixP
->tc_fix_data
.info
= info
;
1838 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1839 fixP
->fx_no_overflow
= 1;
1841 info
= get_alpha_reloc_tag (insn
->sequence
);
1842 if (++info
->n_slaves
> 1)
1843 as_bad (_("too many lda insns for !gpdisp!%ld"), insn
->sequence
);
1844 if (info
->segment
!= now_seg
)
1845 as_bad (_("both insns for !gpdisp!%ld must be in the same section"),
1847 fixP
->tc_fix_data
.info
= info
;
1848 info
->slaves
= fixP
;
1851 case BFD_RELOC_ALPHA_LITERAL
:
1852 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1853 fixP
->fx_no_overflow
= 1;
1855 if (insn
->sequence
== 0)
1857 info
= get_alpha_reloc_tag (insn
->sequence
);
1858 info
->master
= fixP
;
1860 if (info
->segment
!= now_seg
)
1861 info
->multi_section_p
= 1;
1862 fixP
->tc_fix_data
.info
= info
;
1866 case DUMMY_RELOC_LITUSE_ADDR
:
1867 fixP
->fx_offset
= LITUSE_ALPHA_ADDR
;
1869 case DUMMY_RELOC_LITUSE_BASE
:
1870 fixP
->fx_offset
= LITUSE_ALPHA_BASE
;
1872 case DUMMY_RELOC_LITUSE_BYTOFF
:
1873 fixP
->fx_offset
= LITUSE_ALPHA_BYTOFF
;
1875 case DUMMY_RELOC_LITUSE_JSR
:
1876 fixP
->fx_offset
= LITUSE_ALPHA_JSR
;
1878 case DUMMY_RELOC_LITUSE_TLSGD
:
1879 fixP
->fx_offset
= LITUSE_ALPHA_TLSGD
;
1881 case DUMMY_RELOC_LITUSE_TLSLDM
:
1882 fixP
->fx_offset
= LITUSE_ALPHA_TLSLDM
;
1884 case DUMMY_RELOC_LITUSE_JSRDIRECT
:
1885 fixP
->fx_offset
= LITUSE_ALPHA_JSRDIRECT
;
1888 fixP
->fx_addsy
= section_symbol (now_seg
);
1889 fixP
->fx_r_type
= BFD_RELOC_ALPHA_LITUSE
;
1891 info
= get_alpha_reloc_tag (insn
->sequence
);
1892 if (fixup
->reloc
== DUMMY_RELOC_LITUSE_TLSGD
)
1893 info
->saw_lu_tlsgd
= 1;
1894 else if (fixup
->reloc
== DUMMY_RELOC_LITUSE_TLSLDM
)
1895 info
->saw_lu_tlsldm
= 1;
1896 if (++info
->n_slaves
> 1)
1898 if (info
->saw_lu_tlsgd
)
1899 as_bad (_("too many lituse insns for !lituse_tlsgd!%ld"),
1901 else if (info
->saw_lu_tlsldm
)
1902 as_bad (_("too many lituse insns for !lituse_tlsldm!%ld"),
1905 fixP
->tc_fix_data
.info
= info
;
1906 fixP
->tc_fix_data
.next_reloc
= info
->slaves
;
1907 info
->slaves
= fixP
;
1908 if (info
->segment
!= now_seg
)
1909 info
->multi_section_p
= 1;
1912 case BFD_RELOC_ALPHA_TLSGD
:
1913 fixP
->fx_no_overflow
= 1;
1915 if (insn
->sequence
== 0)
1917 info
= get_alpha_reloc_tag (insn
->sequence
);
1918 if (info
->saw_tlsgd
)
1919 as_bad (_("duplicate !tlsgd!%ld"), insn
->sequence
);
1920 else if (info
->saw_tlsldm
)
1921 as_bad (_("sequence number in use for !tlsldm!%ld"),
1924 info
->saw_tlsgd
= 1;
1925 fixP
->tc_fix_data
.info
= info
;
1928 case BFD_RELOC_ALPHA_TLSLDM
:
1929 fixP
->fx_no_overflow
= 1;
1931 if (insn
->sequence
== 0)
1933 info
= get_alpha_reloc_tag (insn
->sequence
);
1934 if (info
->saw_tlsldm
)
1935 as_bad (_("duplicate !tlsldm!%ld"), insn
->sequence
);
1936 else if (info
->saw_tlsgd
)
1937 as_bad (_("sequence number in use for !tlsgd!%ld"),
1940 info
->saw_tlsldm
= 1;
1941 fixP
->tc_fix_data
.info
= info
;
1945 case BFD_RELOC_ALPHA_NOP
:
1946 case BFD_RELOC_ALPHA_LDA
:
1947 case BFD_RELOC_ALPHA_BSR
:
1948 case BFD_RELOC_ALPHA_BOH
:
1949 info
= get_alpha_reloc_tag (next_sequence_num
--);
1950 fixP
->tc_fix_data
.info
= info
;
1951 fixP
->tc_fix_data
.info
->sym
= fixup
->xtrasym
;
1952 fixP
->tc_fix_data
.info
->psym
= fixup
->procsym
;
1957 if ((int) fixup
->reloc
< 0)
1959 if (operand
->flags
& AXP_OPERAND_NOOVERFLOW
)
1960 fixP
->fx_no_overflow
= 1;
1967 /* Insert an operand value into an instruction. */
1970 insert_operand (unsigned insn
,
1971 const struct alpha_operand
*operand
,
1976 if (!(operand
->flags
& AXP_OPERAND_NOOVERFLOW
))
1980 if (operand
->flags
& AXP_OPERAND_SIGNED
)
1982 max
= (1 << (operand
->bits
- 1)) - 1;
1983 min
= -(1 << (operand
->bits
- 1));
1987 max
= (1 << operand
->bits
) - 1;
1991 if (val
< min
|| val
> max
)
1992 as_bad_value_out_of_range (_("operand"), val
, min
, max
, file
, line
);
1995 if (operand
->insert
)
1997 const char *errmsg
= NULL
;
1999 insn
= (*operand
->insert
) (insn
, val
, &errmsg
);
2001 as_warn ("%s", errmsg
);
2004 insn
|= ((val
& ((1 << operand
->bits
) - 1)) << operand
->shift
);
2009 /* Turn an opcode description and a set of arguments into
2010 an instruction and a fixup. */
2013 assemble_insn (const struct alpha_opcode
*opcode
,
2014 const expressionS
*tok
,
2016 struct alpha_insn
*insn
,
2017 extended_bfd_reloc_code_real_type reloc
)
2019 const struct alpha_operand
*reloc_operand
= NULL
;
2020 const expressionS
*reloc_exp
= NULL
;
2021 const unsigned char *argidx
;
2025 memset (insn
, 0, sizeof (*insn
));
2026 image
= opcode
->opcode
;
2028 for (argidx
= opcode
->operands
; *argidx
; ++argidx
)
2030 const struct alpha_operand
*operand
= &alpha_operands
[*argidx
];
2031 const expressionS
*t
= (const expressionS
*) 0;
2033 if (operand
->flags
& AXP_OPERAND_FAKE
)
2035 /* Fake operands take no value and generate no fixup. */
2036 image
= insert_operand (image
, operand
, 0, NULL
, 0);
2042 switch (operand
->flags
& AXP_OPERAND_OPTIONAL_MASK
)
2044 case AXP_OPERAND_DEFAULT_FIRST
:
2047 case AXP_OPERAND_DEFAULT_SECOND
:
2050 case AXP_OPERAND_DEFAULT_ZERO
:
2052 static expressionS zero_exp
;
2054 zero_exp
.X_op
= O_constant
;
2055 zero_exp
.X_unsigned
= 1;
2070 image
= insert_operand (image
, operand
, regno (t
->X_add_number
),
2075 image
= insert_operand (image
, operand
, t
->X_add_number
, NULL
, 0);
2076 gas_assert (reloc_operand
== NULL
);
2077 reloc_operand
= operand
;
2082 /* This is only 0 for fields that should contain registers,
2083 which means this pattern shouldn't have matched. */
2084 if (operand
->default_reloc
== 0)
2087 /* There is one special case for which an insn receives two
2088 relocations, and thus the user-supplied reloc does not
2089 override the operand reloc. */
2090 if (operand
->default_reloc
== BFD_RELOC_ALPHA_HINT
)
2092 struct alpha_fixup
*fixup
;
2094 if (insn
->nfixups
>= MAX_INSN_FIXUPS
)
2095 as_fatal (_("too many fixups"));
2097 fixup
= &insn
->fixups
[insn
->nfixups
++];
2099 fixup
->reloc
= BFD_RELOC_ALPHA_HINT
;
2103 if (reloc
== BFD_RELOC_UNUSED
)
2104 reloc
= operand
->default_reloc
;
2106 gas_assert (reloc_operand
== NULL
);
2107 reloc_operand
= operand
;
2114 if (reloc
!= BFD_RELOC_UNUSED
)
2116 struct alpha_fixup
*fixup
;
2118 if (insn
->nfixups
>= MAX_INSN_FIXUPS
)
2119 as_fatal (_("too many fixups"));
2121 /* ??? My but this is hacky. But the OSF/1 assembler uses the same
2122 relocation tag for both ldah and lda with gpdisp. Choose the
2123 correct internal relocation based on the opcode. */
2124 if (reloc
== BFD_RELOC_ALPHA_GPDISP
)
2126 if (strcmp (opcode
->name
, "ldah") == 0)
2127 reloc
= BFD_RELOC_ALPHA_GPDISP_HI16
;
2128 else if (strcmp (opcode
->name
, "lda") == 0)
2129 reloc
= BFD_RELOC_ALPHA_GPDISP_LO16
;
2131 as_bad (_("invalid relocation for instruction"));
2134 /* If this is a real relocation (as opposed to a lituse hint), then
2135 the relocation width should match the operand width.
2136 Take care of -MDISP in operand table. */
2137 else if (reloc
< BFD_RELOC_UNUSED
&& reloc
> 0)
2139 reloc_howto_type
*reloc_howto
2140 = bfd_reloc_type_lookup (stdoutput
,
2141 (bfd_reloc_code_real_type
) reloc
);
2142 if (reloc_operand
== NULL
2143 || reloc_howto
->bitsize
!= reloc_operand
->bits
)
2145 as_bad (_("invalid relocation for field"));
2150 fixup
= &insn
->fixups
[insn
->nfixups
++];
2152 fixup
->exp
= *reloc_exp
;
2154 fixup
->exp
.X_op
= O_absent
;
2155 fixup
->reloc
= reloc
;
2161 /* Handle all "simple" integer register loads -- ldq, ldq_l, ldq_u,
2162 etc. They differ from the real instructions in that they do simple
2163 expressions like the lda macro. */
2166 emit_ir_load (const expressionS
*tok
,
2168 const void * opname
)
2172 expressionS newtok
[3];
2173 struct alpha_insn insn
;
2175 = tok
[1].X_add_symbol
? S_GET_NAME (tok
[1].X_add_symbol
): "";
2176 int symlen
= strlen (symname
);
2179 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
2181 basereg
= tok
[2].X_add_number
;
2183 lituse
= load_expression (tok
[0].X_add_number
, &tok
[1],
2184 &basereg
, &newtok
[1], (const char *) opname
);
2186 if (basereg
== alpha_gp_register
&&
2187 (symlen
> 4 && strcmp (&symname
[symlen
- 4], "..lk") == 0))
2191 set_tok_preg (newtok
[2], basereg
);
2193 assemble_tokens_to_insn ((const char *) opname
, newtok
, 3, &insn
);
2197 gas_assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
2198 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BASE
;
2199 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
2201 insn
.sequence
= lituse
;
2207 /* Handle fp register loads, and both integer and fp register stores.
2208 Again, we handle simple expressions. */
2211 emit_loadstore (const expressionS
*tok
,
2213 const void * opname
)
2217 expressionS newtok
[3];
2218 struct alpha_insn insn
;
2221 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
2223 basereg
= tok
[2].X_add_number
;
2225 if (tok
[1].X_op
!= O_constant
|| !range_signed_16 (tok
[1].X_add_number
))
2228 as_bad (_("macro requires $at register while noat in effect"));
2230 lituse
= load_expression (AXP_REG_AT
, &tok
[1],
2231 &basereg
, &newtok
[1], (const char *) opname
);
2240 set_tok_preg (newtok
[2], basereg
);
2242 assemble_tokens_to_insn ((const char *) opname
, newtok
, 3, &insn
);
2246 gas_assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
2247 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BASE
;
2248 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
2250 insn
.sequence
= lituse
;
2256 /* Load a half-word or byte as an unsigned value. */
2259 emit_ldXu (const expressionS
*tok
,
2261 const void * vlgsize
)
2263 if (alpha_target
& AXP_OPCODE_BWX
)
2264 emit_ir_load (tok
, ntok
, ldXu_op
[(long) vlgsize
]);
2267 expressionS newtok
[3];
2268 struct alpha_insn insn
;
2273 as_bad (_("macro requires $at register while noat in effect"));
2276 basereg
= (tok
[1].X_op
== O_constant
2277 ? AXP_REG_ZERO
: alpha_gp_register
);
2279 basereg
= tok
[2].X_add_number
;
2281 /* Emit "lda $at, exp". */
2282 lituse
= load_expression (AXP_REG_AT
, &tok
[1], &basereg
, NULL
, "lda");
2284 /* Emit "ldq_u targ, 0($at)". */
2286 set_tok_const (newtok
[1], 0);
2287 set_tok_preg (newtok
[2], basereg
);
2288 assemble_tokens_to_insn ("ldq_u", newtok
, 3, &insn
);
2292 gas_assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
2293 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BASE
;
2294 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
2296 insn
.sequence
= lituse
;
2301 /* Emit "extXl targ, $at, targ". */
2302 set_tok_reg (newtok
[1], basereg
);
2303 newtok
[2] = newtok
[0];
2304 assemble_tokens_to_insn (extXl_op
[(long) vlgsize
], newtok
, 3, &insn
);
2308 gas_assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
2309 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BYTOFF
;
2310 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
2312 insn
.sequence
= lituse
;
2319 /* Load a half-word or byte as a signed value. */
2322 emit_ldX (const expressionS
*tok
,
2324 const void * vlgsize
)
2326 emit_ldXu (tok
, ntok
, vlgsize
);
2327 assemble_tokens (sextX_op
[(long) vlgsize
], tok
, 1, 1);
2330 /* Load an integral value from an unaligned address as an unsigned
2334 emit_uldXu (const expressionS
*tok
,
2336 const void * vlgsize
)
2338 long lgsize
= (long) vlgsize
;
2339 expressionS newtok
[3];
2342 as_bad (_("macro requires $at register while noat in effect"));
2344 /* Emit "lda $at, exp". */
2345 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
2346 newtok
[0].X_add_number
= AXP_REG_AT
;
2347 assemble_tokens ("lda", newtok
, ntok
, 1);
2349 /* Emit "ldq_u $t9, 0($at)". */
2350 set_tok_reg (newtok
[0], AXP_REG_T9
);
2351 set_tok_const (newtok
[1], 0);
2352 set_tok_preg (newtok
[2], AXP_REG_AT
);
2353 assemble_tokens ("ldq_u", newtok
, 3, 1);
2355 /* Emit "ldq_u $t10, size-1($at)". */
2356 set_tok_reg (newtok
[0], AXP_REG_T10
);
2357 set_tok_const (newtok
[1], (1 << lgsize
) - 1);
2358 assemble_tokens ("ldq_u", newtok
, 3, 1);
2360 /* Emit "extXl $t9, $at, $t9". */
2361 set_tok_reg (newtok
[0], AXP_REG_T9
);
2362 set_tok_reg (newtok
[1], AXP_REG_AT
);
2363 set_tok_reg (newtok
[2], AXP_REG_T9
);
2364 assemble_tokens (extXl_op
[lgsize
], newtok
, 3, 1);
2366 /* Emit "extXh $t10, $at, $t10". */
2367 set_tok_reg (newtok
[0], AXP_REG_T10
);
2368 set_tok_reg (newtok
[2], AXP_REG_T10
);
2369 assemble_tokens (extXh_op
[lgsize
], newtok
, 3, 1);
2371 /* Emit "or $t9, $t10, targ". */
2372 set_tok_reg (newtok
[0], AXP_REG_T9
);
2373 set_tok_reg (newtok
[1], AXP_REG_T10
);
2375 assemble_tokens ("or", newtok
, 3, 1);
2378 /* Load an integral value from an unaligned address as a signed value.
2379 Note that quads should get funneled to the unsigned load since we
2380 don't have to do the sign extension. */
2383 emit_uldX (const expressionS
*tok
,
2385 const void * vlgsize
)
2387 emit_uldXu (tok
, ntok
, vlgsize
);
2388 assemble_tokens (sextX_op
[(long) vlgsize
], tok
, 1, 1);
2391 /* Implement the ldil macro. */
2394 emit_ldil (const expressionS
*tok
,
2396 const void * unused ATTRIBUTE_UNUSED
)
2398 expressionS newtok
[2];
2400 memcpy (newtok
, tok
, sizeof (newtok
));
2401 newtok
[1].X_add_number
= sign_extend_32 (tok
[1].X_add_number
);
2403 assemble_tokens ("lda", newtok
, ntok
, 1);
2406 /* Store a half-word or byte. */
2409 emit_stX (const expressionS
*tok
,
2411 const void * vlgsize
)
2413 int lgsize
= (int) (long) vlgsize
;
2415 if (alpha_target
& AXP_OPCODE_BWX
)
2416 emit_loadstore (tok
, ntok
, stX_op
[lgsize
]);
2419 expressionS newtok
[3];
2420 struct alpha_insn insn
;
2425 as_bad (_("macro requires $at register while noat in effect"));
2428 basereg
= (tok
[1].X_op
== O_constant
2429 ? AXP_REG_ZERO
: alpha_gp_register
);
2431 basereg
= tok
[2].X_add_number
;
2433 /* Emit "lda $at, exp". */
2434 lituse
= load_expression (AXP_REG_AT
, &tok
[1], &basereg
, NULL
, "lda");
2436 /* Emit "ldq_u $t9, 0($at)". */
2437 set_tok_reg (newtok
[0], AXP_REG_T9
);
2438 set_tok_const (newtok
[1], 0);
2439 set_tok_preg (newtok
[2], basereg
);
2440 assemble_tokens_to_insn ("ldq_u", newtok
, 3, &insn
);
2444 gas_assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
2445 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BASE
;
2446 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
2448 insn
.sequence
= lituse
;
2453 /* Emit "insXl src, $at, $t10". */
2455 set_tok_reg (newtok
[1], basereg
);
2456 set_tok_reg (newtok
[2], AXP_REG_T10
);
2457 assemble_tokens_to_insn (insXl_op
[lgsize
], newtok
, 3, &insn
);
2461 gas_assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
2462 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BYTOFF
;
2463 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
2465 insn
.sequence
= lituse
;
2470 /* Emit "mskXl $t9, $at, $t9". */
2471 set_tok_reg (newtok
[0], AXP_REG_T9
);
2472 newtok
[2] = newtok
[0];
2473 assemble_tokens_to_insn (mskXl_op
[lgsize
], newtok
, 3, &insn
);
2477 gas_assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
2478 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BYTOFF
;
2479 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
2481 insn
.sequence
= lituse
;
2486 /* Emit "or $t9, $t10, $t9". */
2487 set_tok_reg (newtok
[1], AXP_REG_T10
);
2488 assemble_tokens ("or", newtok
, 3, 1);
2490 /* Emit "stq_u $t9, 0($at). */
2491 set_tok_const(newtok
[1], 0);
2492 set_tok_preg (newtok
[2], AXP_REG_AT
);
2493 assemble_tokens_to_insn ("stq_u", newtok
, 3, &insn
);
2497 gas_assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
2498 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BASE
;
2499 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
2501 insn
.sequence
= lituse
;
2508 /* Store an integer to an unaligned address. */
2511 emit_ustX (const expressionS
*tok
,
2513 const void * vlgsize
)
2515 int lgsize
= (int) (long) vlgsize
;
2516 expressionS newtok
[3];
2518 /* Emit "lda $at, exp". */
2519 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
2520 newtok
[0].X_add_number
= AXP_REG_AT
;
2521 assemble_tokens ("lda", newtok
, ntok
, 1);
2523 /* Emit "ldq_u $9, 0($at)". */
2524 set_tok_reg (newtok
[0], AXP_REG_T9
);
2525 set_tok_const (newtok
[1], 0);
2526 set_tok_preg (newtok
[2], AXP_REG_AT
);
2527 assemble_tokens ("ldq_u", newtok
, 3, 1);
2529 /* Emit "ldq_u $10, size-1($at)". */
2530 set_tok_reg (newtok
[0], AXP_REG_T10
);
2531 set_tok_const (newtok
[1], (1 << lgsize
) - 1);
2532 assemble_tokens ("ldq_u", newtok
, 3, 1);
2534 /* Emit "insXl src, $at, $t11". */
2536 set_tok_reg (newtok
[1], AXP_REG_AT
);
2537 set_tok_reg (newtok
[2], AXP_REG_T11
);
2538 assemble_tokens (insXl_op
[lgsize
], newtok
, 3, 1);
2540 /* Emit "insXh src, $at, $t12". */
2541 set_tok_reg (newtok
[2], AXP_REG_T12
);
2542 assemble_tokens (insXh_op
[lgsize
], newtok
, 3, 1);
2544 /* Emit "mskXl $t9, $at, $t9". */
2545 set_tok_reg (newtok
[0], AXP_REG_T9
);
2546 newtok
[2] = newtok
[0];
2547 assemble_tokens (mskXl_op
[lgsize
], newtok
, 3, 1);
2549 /* Emit "mskXh $t10, $at, $t10". */
2550 set_tok_reg (newtok
[0], AXP_REG_T10
);
2551 newtok
[2] = newtok
[0];
2552 assemble_tokens (mskXh_op
[lgsize
], newtok
, 3, 1);
2554 /* Emit "or $t9, $t11, $t9". */
2555 set_tok_reg (newtok
[0], AXP_REG_T9
);
2556 set_tok_reg (newtok
[1], AXP_REG_T11
);
2557 newtok
[2] = newtok
[0];
2558 assemble_tokens ("or", newtok
, 3, 1);
2560 /* Emit "or $t10, $t12, $t10". */
2561 set_tok_reg (newtok
[0], AXP_REG_T10
);
2562 set_tok_reg (newtok
[1], AXP_REG_T12
);
2563 newtok
[2] = newtok
[0];
2564 assemble_tokens ("or", newtok
, 3, 1);
2566 /* Emit "stq_u $t10, size-1($at)". */
2567 set_tok_reg (newtok
[0], AXP_REG_T10
);
2568 set_tok_const (newtok
[1], (1 << lgsize
) - 1);
2569 set_tok_preg (newtok
[2], AXP_REG_AT
);
2570 assemble_tokens ("stq_u", newtok
, 3, 1);
2572 /* Emit "stq_u $t9, 0($at)". */
2573 set_tok_reg (newtok
[0], AXP_REG_T9
);
2574 set_tok_const (newtok
[1], 0);
2575 assemble_tokens ("stq_u", newtok
, 3, 1);
2578 /* Sign extend a half-word or byte. The 32-bit sign extend is
2579 implemented as "addl $31, $r, $t" in the opcode table. */
2582 emit_sextX (const expressionS
*tok
,
2584 const void * vlgsize
)
2586 long lgsize
= (long) vlgsize
;
2588 if (alpha_target
& AXP_OPCODE_BWX
)
2589 assemble_tokens (sextX_op
[lgsize
], tok
, ntok
, 0);
2592 int bitshift
= 64 - 8 * (1 << lgsize
);
2593 expressionS newtok
[3];
2595 /* Emit "sll src,bits,dst". */
2597 set_tok_const (newtok
[1], bitshift
);
2598 newtok
[2] = tok
[ntok
- 1];
2599 assemble_tokens ("sll", newtok
, 3, 1);
2601 /* Emit "sra dst,bits,dst". */
2602 newtok
[0] = newtok
[2];
2603 assemble_tokens ("sra", newtok
, 3, 1);
2607 /* Implement the division and modulus macros. */
2611 /* Make register usage like in normal procedure call.
2612 Don't clobber PV and RA. */
2615 emit_division (const expressionS
*tok
,
2617 const void * symname
)
2619 /* DIVISION and MODULUS. Yech.
2624 mov x,R16 # if x != R16
2625 mov y,R17 # if y != R17
2630 with appropriate optimizations if R0,R16,R17 are the registers
2631 specified by the compiler. */
2635 expressionS newtok
[3];
2637 xr
= regno (tok
[0].X_add_number
);
2638 yr
= regno (tok
[1].X_add_number
);
2643 rr
= regno (tok
[2].X_add_number
);
2645 /* Move the operands into the right place. */
2646 if (yr
== AXP_REG_R16
&& xr
== AXP_REG_R17
)
2648 /* They are in exactly the wrong order -- swap through AT. */
2650 as_bad (_("macro requires $at register while noat in effect"));
2652 set_tok_reg (newtok
[0], AXP_REG_R16
);
2653 set_tok_reg (newtok
[1], AXP_REG_AT
);
2654 assemble_tokens ("mov", newtok
, 2, 1);
2656 set_tok_reg (newtok
[0], AXP_REG_R17
);
2657 set_tok_reg (newtok
[1], AXP_REG_R16
);
2658 assemble_tokens ("mov", newtok
, 2, 1);
2660 set_tok_reg (newtok
[0], AXP_REG_AT
);
2661 set_tok_reg (newtok
[1], AXP_REG_R17
);
2662 assemble_tokens ("mov", newtok
, 2, 1);
2666 if (yr
== AXP_REG_R16
)
2668 set_tok_reg (newtok
[0], AXP_REG_R16
);
2669 set_tok_reg (newtok
[1], AXP_REG_R17
);
2670 assemble_tokens ("mov", newtok
, 2, 1);
2673 if (xr
!= AXP_REG_R16
)
2675 set_tok_reg (newtok
[0], xr
);
2676 set_tok_reg (newtok
[1], AXP_REG_R16
);
2677 assemble_tokens ("mov", newtok
, 2, 1);
2680 if (yr
!= AXP_REG_R16
&& yr
!= AXP_REG_R17
)
2682 set_tok_reg (newtok
[0], yr
);
2683 set_tok_reg (newtok
[1], AXP_REG_R17
);
2684 assemble_tokens ("mov", newtok
, 2, 1);
2688 sym
= symbol_find_or_make ((const char *) symname
);
2690 set_tok_reg (newtok
[0], AXP_REG_AT
);
2691 set_tok_sym (newtok
[1], sym
, 0);
2692 assemble_tokens ("lda", newtok
, 2, 1);
2694 /* Call the division routine. */
2695 set_tok_reg (newtok
[0], AXP_REG_AT
);
2696 set_tok_cpreg (newtok
[1], AXP_REG_AT
);
2697 set_tok_const (newtok
[2], 0);
2698 assemble_tokens ("jsr", newtok
, 3, 1);
2700 /* Move the result to the right place. */
2701 if (rr
!= AXP_REG_R0
)
2703 set_tok_reg (newtok
[0], AXP_REG_R0
);
2704 set_tok_reg (newtok
[1], rr
);
2705 assemble_tokens ("mov", newtok
, 2, 1);
2709 #else /* !OBJ_EVAX */
2712 emit_division (const expressionS
*tok
,
2714 const void * symname
)
2716 /* DIVISION and MODULUS. Yech.
2726 with appropriate optimizations if t10,t11,t12 are the registers
2727 specified by the compiler. */
2731 expressionS newtok
[3];
2733 xr
= regno (tok
[0].X_add_number
);
2734 yr
= regno (tok
[1].X_add_number
);
2739 rr
= regno (tok
[2].X_add_number
);
2741 sym
= symbol_find_or_make ((const char *) symname
);
2743 /* Move the operands into the right place. */
2744 if (yr
== AXP_REG_T10
&& xr
== AXP_REG_T11
)
2746 /* They are in exactly the wrong order -- swap through AT. */
2748 as_bad (_("macro requires $at register while noat in effect"));
2750 set_tok_reg (newtok
[0], AXP_REG_T10
);
2751 set_tok_reg (newtok
[1], AXP_REG_AT
);
2752 assemble_tokens ("mov", newtok
, 2, 1);
2754 set_tok_reg (newtok
[0], AXP_REG_T11
);
2755 set_tok_reg (newtok
[1], AXP_REG_T10
);
2756 assemble_tokens ("mov", newtok
, 2, 1);
2758 set_tok_reg (newtok
[0], AXP_REG_AT
);
2759 set_tok_reg (newtok
[1], AXP_REG_T11
);
2760 assemble_tokens ("mov", newtok
, 2, 1);
2764 if (yr
== AXP_REG_T10
)
2766 set_tok_reg (newtok
[0], AXP_REG_T10
);
2767 set_tok_reg (newtok
[1], AXP_REG_T11
);
2768 assemble_tokens ("mov", newtok
, 2, 1);
2771 if (xr
!= AXP_REG_T10
)
2773 set_tok_reg (newtok
[0], xr
);
2774 set_tok_reg (newtok
[1], AXP_REG_T10
);
2775 assemble_tokens ("mov", newtok
, 2, 1);
2778 if (yr
!= AXP_REG_T10
&& yr
!= AXP_REG_T11
)
2780 set_tok_reg (newtok
[0], yr
);
2781 set_tok_reg (newtok
[1], AXP_REG_T11
);
2782 assemble_tokens ("mov", newtok
, 2, 1);
2786 /* Call the division routine. */
2787 set_tok_reg (newtok
[0], AXP_REG_T9
);
2788 set_tok_sym (newtok
[1], sym
, 0);
2789 assemble_tokens ("jsr", newtok
, 2, 1);
2791 /* Reload the GP register. */
2795 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
2796 set_tok_reg (newtok
[0], alpha_gp_register
);
2797 set_tok_const (newtok
[1], 0);
2798 set_tok_preg (newtok
[2], AXP_REG_T9
);
2799 assemble_tokens ("ldgp", newtok
, 3, 1);
2802 /* Move the result to the right place. */
2803 if (rr
!= AXP_REG_T12
)
2805 set_tok_reg (newtok
[0], AXP_REG_T12
);
2806 set_tok_reg (newtok
[1], rr
);
2807 assemble_tokens ("mov", newtok
, 2, 1);
2811 #endif /* !OBJ_EVAX */
2813 /* The jsr and jmp macros differ from their instruction counterparts
2814 in that they can load the target address and default most
2818 emit_jsrjmp (const expressionS
*tok
,
2820 const void * vopname
)
2822 const char *opname
= (const char *) vopname
;
2823 struct alpha_insn insn
;
2824 expressionS newtok
[3];
2828 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_register
)
2829 r
= regno (tok
[tokidx
++].X_add_number
);
2831 r
= strcmp (opname
, "jmp") == 0 ? AXP_REG_ZERO
: AXP_REG_RA
;
2833 set_tok_reg (newtok
[0], r
);
2835 if (tokidx
< ntok
&&
2836 (tok
[tokidx
].X_op
== O_pregister
|| tok
[tokidx
].X_op
== O_cpregister
))
2837 r
= regno (tok
[tokidx
++].X_add_number
);
2839 /* Keep register if jsr $n.<sym>. */
2843 int basereg
= alpha_gp_register
;
2844 lituse
= load_expression (r
= AXP_REG_PV
, &tok
[tokidx
],
2845 &basereg
, NULL
, opname
);
2849 set_tok_cpreg (newtok
[1], r
);
2853 newtok
[2] = tok
[tokidx
];
2856 set_tok_const (newtok
[2], 0);
2858 assemble_tokens_to_insn (opname
, newtok
, 3, &insn
);
2862 gas_assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
2863 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_JSR
;
2864 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
2866 insn
.sequence
= lituse
;
2870 if (alpha_flag_replace
2872 && tok
[tokidx
].X_add_symbol
2873 && alpha_linkage_symbol
)
2875 /* Create a BOH reloc for 'jsr $27,NAME'. */
2876 const char *symname
= S_GET_NAME (tok
[tokidx
].X_add_symbol
);
2877 int symlen
= strlen (symname
);
2880 /* Build the entry name as 'NAME..en'. */
2881 ensymname
= XNEWVEC (char, symlen
+ 5);
2882 memcpy (ensymname
, symname
, symlen
);
2883 memcpy (ensymname
+ symlen
, "..en", 5);
2885 gas_assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
2886 if (insn
.nfixups
> 0)
2888 memmove (&insn
.fixups
[1], &insn
.fixups
[0],
2889 sizeof(struct alpha_fixup
) * insn
.nfixups
);
2892 /* The fixup must be the same as the BFD_RELOC_ALPHA_NOP
2893 case in load_expression. See B.4.5.2 of the OpenVMS
2894 Linker Utility Manual. */
2895 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_BOH
;
2896 insn
.fixups
[0].exp
.X_op
= O_symbol
;
2897 insn
.fixups
[0].exp
.X_add_symbol
= symbol_find_or_make (ensymname
);
2898 insn
.fixups
[0].exp
.X_add_number
= 0;
2899 insn
.fixups
[0].xtrasym
= alpha_linkage_symbol
;
2900 insn
.fixups
[0].procsym
= alpha_evax_proc
->symbol
;
2902 alpha_linkage_symbol
= 0;
2910 /* The ret and jcr instructions differ from their instruction
2911 counterparts in that everything can be defaulted. */
2914 emit_retjcr (const expressionS
*tok
,
2916 const void * vopname
)
2918 const char *opname
= (const char *) vopname
;
2919 expressionS newtok
[3];
2922 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_register
)
2923 r
= regno (tok
[tokidx
++].X_add_number
);
2927 set_tok_reg (newtok
[0], r
);
2929 if (tokidx
< ntok
&&
2930 (tok
[tokidx
].X_op
== O_pregister
|| tok
[tokidx
].X_op
== O_cpregister
))
2931 r
= regno (tok
[tokidx
++].X_add_number
);
2935 set_tok_cpreg (newtok
[1], r
);
2938 newtok
[2] = tok
[tokidx
];
2940 set_tok_const (newtok
[2], strcmp (opname
, "ret") == 0);
2942 assemble_tokens (opname
, newtok
, 3, 0);
2945 /* Implement the ldgp macro. */
2948 emit_ldgp (const expressionS
*tok ATTRIBUTE_UNUSED
,
2949 int ntok ATTRIBUTE_UNUSED
,
2950 const void * unused ATTRIBUTE_UNUSED
)
2955 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
2956 /* from "ldgp r1,n(r2)", generate "ldah r1,X(R2); lda r1,Y(r1)"
2957 with appropriate constants and relocations. */
2958 struct alpha_insn insn
;
2959 expressionS newtok
[3];
2963 if (regno (tok
[2].X_add_number
) == AXP_REG_PV
)
2964 ecoff_set_gp_prolog_size (0);
2968 set_tok_const (newtok
[1], 0);
2971 assemble_tokens_to_insn ("ldah", newtok
, 3, &insn
);
2976 if (addend
.X_op
!= O_constant
)
2977 as_bad (_("can not resolve expression"));
2978 addend
.X_op
= O_symbol
;
2979 addend
.X_add_symbol
= alpha_gp_symbol
;
2983 insn
.fixups
[0].exp
= addend
;
2984 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_GPDISP_HI16
;
2985 insn
.sequence
= next_sequence_num
;
2989 set_tok_preg (newtok
[2], tok
[0].X_add_number
);
2991 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
2994 addend
.X_add_number
+= 4;
2998 insn
.fixups
[0].exp
= addend
;
2999 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_GPDISP_LO16
;
3000 insn
.sequence
= next_sequence_num
--;
3003 #endif /* OBJ_ECOFF || OBJ_ELF */
3006 /* The macro table. */
3008 static const struct alpha_macro alpha_macros
[] =
3010 /* Load/Store macros. */
3011 { "lda", emit_lda
, NULL
,
3012 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
3013 { "ldah", emit_ldah
, NULL
,
3014 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
3016 { "ldl", emit_ir_load
, "ldl",
3017 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
3018 { "ldl_l", emit_ir_load
, "ldl_l",
3019 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
3020 { "ldq", emit_ir_load
, "ldq",
3021 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
3022 { "ldq_l", emit_ir_load
, "ldq_l",
3023 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
3024 { "ldq_u", emit_ir_load
, "ldq_u",
3025 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
3026 { "ldf", emit_loadstore
, "ldf",
3027 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
3028 { "ldg", emit_loadstore
, "ldg",
3029 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
3030 { "lds", emit_loadstore
, "lds",
3031 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
3032 { "ldt", emit_loadstore
, "ldt",
3033 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
3035 { "ldb", emit_ldX
, (void *) 0,
3036 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
3037 { "ldbu", emit_ldXu
, (void *) 0,
3038 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
3039 { "ldw", emit_ldX
, (void *) 1,
3040 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
3041 { "ldwu", emit_ldXu
, (void *) 1,
3042 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
3044 { "uldw", emit_uldX
, (void *) 1,
3045 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
3046 { "uldwu", emit_uldXu
, (void *) 1,
3047 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
3048 { "uldl", emit_uldX
, (void *) 2,
3049 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
3050 { "uldlu", emit_uldXu
, (void *) 2,
3051 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
3052 { "uldq", emit_uldXu
, (void *) 3,
3053 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
3055 { "ldgp", emit_ldgp
, NULL
,
3056 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
} },
3058 { "ldi", emit_lda
, NULL
,
3059 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
3060 { "ldil", emit_ldil
, NULL
,
3061 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
3062 { "ldiq", emit_lda
, NULL
,
3063 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
3065 { "stl", emit_loadstore
, "stl",
3066 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
3067 { "stl_c", emit_loadstore
, "stl_c",
3068 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
3069 { "stq", emit_loadstore
, "stq",
3070 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
3071 { "stq_c", emit_loadstore
, "stq_c",
3072 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
3073 { "stq_u", emit_loadstore
, "stq_u",
3074 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
3075 { "stf", emit_loadstore
, "stf",
3076 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
3077 { "stg", emit_loadstore
, "stg",
3078 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
3079 { "sts", emit_loadstore
, "sts",
3080 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
3081 { "stt", emit_loadstore
, "stt",
3082 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
3084 { "stb", emit_stX
, (void *) 0,
3085 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
3086 { "stw", emit_stX
, (void *) 1,
3087 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
3088 { "ustw", emit_ustX
, (void *) 1,
3089 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
3090 { "ustl", emit_ustX
, (void *) 2,
3091 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
3092 { "ustq", emit_ustX
, (void *) 3,
3093 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
3095 /* Arithmetic macros. */
3097 { "sextb", emit_sextX
, (void *) 0,
3098 { MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3099 MACRO_IR
, MACRO_EOA
,
3100 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
3101 { "sextw", emit_sextX
, (void *) 1,
3102 { MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3103 MACRO_IR
, MACRO_EOA
,
3104 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
3106 { "divl", emit_division
, "__divl",
3107 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3108 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3109 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
3110 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
3111 { "divlu", emit_division
, "__divlu",
3112 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3113 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3114 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
3115 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
3116 { "divq", emit_division
, "__divq",
3117 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3118 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3119 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
3120 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
3121 { "divqu", emit_division
, "__divqu",
3122 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3123 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3124 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
3125 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
3126 { "reml", emit_division
, "__reml",
3127 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3128 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3129 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
3130 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
3131 { "remlu", emit_division
, "__remlu",
3132 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3133 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3134 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
3135 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
3136 { "remq", emit_division
, "__remq",
3137 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3138 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3139 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
3140 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
3141 { "remqu", emit_division
, "__remqu",
3142 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3143 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3144 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
3145 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
3147 { "jsr", emit_jsrjmp
, "jsr",
3148 { MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
3149 MACRO_PIR
, MACRO_EOA
,
3150 MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
3151 MACRO_EXP
, MACRO_EOA
} },
3152 { "jmp", emit_jsrjmp
, "jmp",
3153 { MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
3154 MACRO_PIR
, MACRO_EOA
,
3155 MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
3156 MACRO_EXP
, MACRO_EOA
} },
3157 { "ret", emit_retjcr
, "ret",
3158 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
3159 MACRO_IR
, MACRO_EOA
,
3160 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
3161 MACRO_PIR
, MACRO_EOA
,
3162 MACRO_EXP
, MACRO_EOA
,
3164 { "jcr", emit_retjcr
, "jcr",
3165 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
3166 MACRO_IR
, MACRO_EOA
,
3167 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
3168 MACRO_PIR
, MACRO_EOA
,
3169 MACRO_EXP
, MACRO_EOA
,
3171 { "jsr_coroutine", emit_retjcr
, "jcr",
3172 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
3173 MACRO_IR
, MACRO_EOA
,
3174 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
3175 MACRO_PIR
, MACRO_EOA
,
3176 MACRO_EXP
, MACRO_EOA
,
3180 static const unsigned int alpha_num_macros
3181 = sizeof (alpha_macros
) / sizeof (*alpha_macros
);
3183 /* Search forward through all variants of a macro looking for a syntax
3186 static const struct alpha_macro
*
3187 find_macro_match (const struct alpha_macro
*first_macro
,
3188 const expressionS
*tok
,
3192 const struct alpha_macro
*macro
= first_macro
;
3197 const enum alpha_macro_arg
*arg
= macro
->argsets
;
3211 /* Index register. */
3213 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_register
3214 || !is_ir_num (tok
[tokidx
].X_add_number
))
3219 /* Parenthesized index register. */
3221 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_pregister
3222 || !is_ir_num (tok
[tokidx
].X_add_number
))
3227 /* Optional parenthesized index register. */
3229 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_pregister
3230 && is_ir_num (tok
[tokidx
].X_add_number
))
3234 /* Leading comma with a parenthesized index register. */
3236 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_cpregister
3237 || !is_ir_num (tok
[tokidx
].X_add_number
))
3242 /* Floating point register. */
3244 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_register
3245 || !is_fpr_num (tok
[tokidx
].X_add_number
))
3250 /* Normal expression. */
3254 switch (tok
[tokidx
].X_op
)
3263 case O_lituse_bytoff
:
3279 while (*arg
!= MACRO_EOA
)
3287 while (++macro
- alpha_macros
< (int) alpha_num_macros
3288 && !strcmp (macro
->name
, first_macro
->name
));
3293 /* Given an opcode name and a pre-tokenized set of arguments, take the
3294 opcode all the way through emission. */
3297 assemble_tokens (const char *opname
,
3298 const expressionS
*tok
,
3300 int local_macros_on
)
3302 int found_something
= 0;
3303 const struct alpha_opcode
*opcode
;
3304 const struct alpha_macro
*macro
;
3306 extended_bfd_reloc_code_real_type reloc
= BFD_RELOC_UNUSED
;
3309 /* If a user-specified relocation is present, this is not a macro. */
3310 if (ntok
&& USER_RELOC_P (tok
[ntok
- 1].X_op
))
3312 reloc
= ALPHA_RELOC_TABLE (tok
[ntok
- 1].X_op
)->reloc
;
3317 if (local_macros_on
)
3319 macro
= (const struct alpha_macro
*) str_hash_find (alpha_macro_hash
,
3323 found_something
= 1;
3324 macro
= find_macro_match (macro
, tok
, &ntok
);
3327 (*macro
->emit
) (tok
, ntok
, macro
->arg
);
3333 /* Search opcodes. */
3334 opcode
= (const struct alpha_opcode
*) str_hash_find (alpha_opcode_hash
,
3338 found_something
= 1;
3339 opcode
= find_opcode_match (opcode
, tok
, &ntok
, &cpumatch
);
3342 struct alpha_insn insn
;
3343 assemble_insn (opcode
, tok
, ntok
, &insn
, reloc
);
3345 /* Copy the sequence number for the reloc from the reloc token. */
3346 if (reloc
!= BFD_RELOC_UNUSED
)
3347 insn
.sequence
= tok
[ntok
].X_add_number
;
3354 if (found_something
)
3357 as_bad (_("inappropriate arguments for opcode `%s'"), opname
);
3359 as_bad (_("opcode `%s' not supported for target %s"), opname
,
3363 as_bad (_("unknown opcode `%s'"), opname
);
3368 /* Add sym+addend to link pool.
3369 Return offset from current procedure value (pv) to entry in link pool.
3371 Add new fixup only if offset isn't 16bit. */
3374 add_to_link_pool (symbolS
*sym
, offsetT addend
)
3377 segT current_section
= now_seg
;
3378 int current_subsec
= now_subseg
;
3380 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
3382 symbolS
*linksym
, *expsym
;
3385 basesym
= alpha_evax_proc
->symbol
;
3387 /* @@ This assumes all entries in a given section will be of the same
3388 size... Probably correct, but unwise to rely on. */
3389 /* This must always be called with the same subsegment. */
3391 if (seginfo
->frchainP
)
3392 for (fixp
= seginfo
->frchainP
->fix_root
;
3393 fixp
!= (fixS
*) NULL
;
3394 fixp
= fixp
->fx_next
)
3396 if (fixp
->fx_addsy
== sym
3397 && fixp
->fx_offset
== (valueT
)addend
3398 && fixp
->tc_fix_data
.info
3399 && fixp
->tc_fix_data
.info
->sym
3400 && symbol_symbolS (fixp
->tc_fix_data
.info
->sym
)
3401 && (symbol_get_value_expression (fixp
->tc_fix_data
.info
->sym
)
3402 ->X_op_symbol
== basesym
))
3403 return fixp
->tc_fix_data
.info
->sym
;
3406 /* Not found, add a new entry. */
3407 subseg_set (alpha_link_section
, 0);
3408 linksym
= symbol_new (FAKE_LABEL_NAME
, now_seg
, frag_now
, frag_now_fix ());
3412 /* Create a symbol for 'basesym - linksym' (offset of the added entry). */
3413 e
.X_op
= O_subtract
;
3414 e
.X_add_symbol
= linksym
;
3415 e
.X_op_symbol
= basesym
;
3417 expsym
= make_expr_symbol (&e
);
3419 /* Create a fixup for the entry. */
3421 (frag_now
, p
- frag_now
->fr_literal
, 8, sym
, addend
, 0, BFD_RELOC_64
);
3422 fixp
->tc_fix_data
.info
= get_alpha_reloc_tag (next_sequence_num
--);
3423 fixp
->tc_fix_data
.info
->sym
= expsym
;
3425 subseg_set (current_section
, current_subsec
);
3427 /* Return the symbol. */
3430 #endif /* OBJ_EVAX */
3432 /* Assembler directives. */
3434 /* Handle the .text pseudo-op. This is like the usual one, but it
3435 clears alpha_insn_label and restores auto alignment. */
3438 s_alpha_text (int i
)
3449 symbolP
= symbol_find (".text");
3450 if (symbolP
== NULL
)
3452 symbolP
= symbol_make (".text");
3453 S_SET_SEGMENT (symbolP
, text_section
);
3454 symbol_table_insert (symbolP
);
3458 alpha_insn_label
= NULL
;
3459 alpha_auto_align_on
= 1;
3460 alpha_current_align
= 0;
3463 /* Handle the .data pseudo-op. This is like the usual one, but it
3464 clears alpha_insn_label and restores auto alignment. */
3467 s_alpha_data (int i
)
3474 alpha_insn_label
= NULL
;
3475 alpha_auto_align_on
= 1;
3476 alpha_current_align
= 0;
3479 #if defined (OBJ_ECOFF) || defined (OBJ_EVAX)
3481 /* Handle the OSF/1 and openVMS .comm pseudo quirks. */
3484 s_alpha_comm (int ignore ATTRIBUTE_UNUSED
)
3496 c
= get_symbol_name (&name
);
3498 /* Just after name is now '\0'. */
3499 p
= input_line_pointer
;
3502 SKIP_WHITESPACE_AFTER_NAME ();
3504 /* Alpha OSF/1 compiler doesn't provide the comma, gcc does. */
3505 if (*input_line_pointer
== ',')
3507 input_line_pointer
++;
3510 if ((size
= get_absolute_expression ()) < 0)
3512 as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) size
);
3513 ignore_rest_of_line ();
3518 symbolP
= symbol_find_or_make (name
);
3521 if (S_IS_DEFINED (symbolP
) && ! S_IS_COMMON (symbolP
))
3523 as_bad (_("Ignoring attempt to re-define symbol"));
3524 ignore_rest_of_line ();
3529 if (*input_line_pointer
!= ',')
3530 temp
= 8; /* Default alignment. */
3533 input_line_pointer
++;
3535 temp
= get_absolute_expression ();
3538 /* ??? Unlike on OSF/1, the alignment factor is not in log units. */
3539 while ((temp
>>= 1) != 0)
3542 if (*input_line_pointer
== ',')
3544 /* Extended form of the directive
3546 .comm symbol, size, alignment, section
3548 where the "common" semantics is transferred to the section.
3549 The symbol is effectively an alias for the section name. */
3552 const char *sec_name
;
3553 symbolS
*sec_symbol
;
3554 segT current_seg
= now_seg
;
3555 subsegT current_subseg
= now_subseg
;
3558 input_line_pointer
++;
3560 sec_name
= s_alpha_section_name ();
3561 sec_symbol
= symbol_find_or_make (sec_name
);
3562 sec
= subseg_new (sec_name
, 0);
3563 S_SET_SEGMENT (sec_symbol
, sec
);
3564 symbol_get_bfdsym (sec_symbol
)->flags
|= BSF_SECTION_SYM
;
3565 bfd_vms_set_section_flags (stdoutput
, sec
, 0,
3566 EGPS__V_OVR
| EGPS__V_GBL
| EGPS__V_NOMOD
);
3567 record_alignment (sec
, log_align
);
3569 /* Reuse stab_string_size to store the size of the section. */
3570 cur_size
= seg_info (sec
)->stabu
.stab_string_size
;
3571 if ((int) size
> cur_size
)
3574 = frag_var (rs_fill
, 1, 1, (relax_substateT
)0, NULL
,
3575 (valueT
)size
- (valueT
)cur_size
, NULL
);
3577 seg_info (sec
)->stabu
.stab_string_size
= (int)size
;
3580 S_SET_SEGMENT (symbolP
, sec
);
3582 subseg_set (current_seg
, current_subseg
);
3586 /* Regular form of the directive
3588 .comm symbol, size, alignment
3590 where the "common" semantics in on the symbol.
3591 These symbols are assembled in the .bss section. */
3594 segT current_seg
= now_seg
;
3595 subsegT current_subseg
= now_subseg
;
3597 subseg_set (bss_section
, 1);
3598 frag_align (log_align
, 0, 0);
3599 record_alignment (bss_section
, log_align
);
3601 symbol_set_frag (symbolP
, frag_now
);
3602 pfrag
= frag_var (rs_org
, 1, 1, (relax_substateT
)0, symbolP
,
3606 S_SET_SEGMENT (symbolP
, bss_section
);
3608 subseg_set (current_seg
, current_subseg
);
3612 if (S_GET_VALUE (symbolP
))
3614 if (S_GET_VALUE (symbolP
) != (valueT
) size
)
3615 as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
3616 S_GET_NAME (symbolP
),
3617 (long) S_GET_VALUE (symbolP
),
3623 S_SET_VALUE (symbolP
, (valueT
) size
);
3625 S_SET_EXTERNAL (symbolP
);
3629 know (symbol_get_frag (symbolP
) == &zero_address_frag
);
3631 demand_empty_rest_of_line ();
3634 #endif /* ! OBJ_ELF */
3638 /* Handle the .rdata pseudo-op. This is like the usual one, but it
3639 clears alpha_insn_label and restores auto alignment. */
3642 s_alpha_rdata (int ignore ATTRIBUTE_UNUSED
)
3644 get_absolute_expression ();
3645 subseg_new (".rdata", 0);
3646 demand_empty_rest_of_line ();
3647 alpha_insn_label
= NULL
;
3648 alpha_auto_align_on
= 1;
3649 alpha_current_align
= 0;
3656 /* Handle the .sdata pseudo-op. This is like the usual one, but it
3657 clears alpha_insn_label and restores auto alignment. */
3660 s_alpha_sdata (int ignore ATTRIBUTE_UNUSED
)
3662 get_absolute_expression ();
3663 subseg_new (".sdata", 0);
3664 demand_empty_rest_of_line ();
3665 alpha_insn_label
= NULL
;
3666 alpha_auto_align_on
= 1;
3667 alpha_current_align
= 0;
3672 struct alpha_elf_frame_data
3675 symbolS
*func_end_sym
;
3676 symbolS
*prologue_sym
;
3682 offsetT mask_offset
;
3683 offsetT fmask_offset
;
3685 struct alpha_elf_frame_data
*next
;
3688 static struct alpha_elf_frame_data
*all_frame_data
;
3689 static struct alpha_elf_frame_data
**plast_frame_data
= &all_frame_data
;
3690 static struct alpha_elf_frame_data
*cur_frame_data
;
3692 extern int all_cfi_sections
;
3694 /* Handle the .section pseudo-op. This is like the usual one, but it
3695 clears alpha_insn_label and restores auto alignment. */
3698 s_alpha_section (int ignore ATTRIBUTE_UNUSED
)
3700 obj_elf_section (ignore
);
3702 alpha_insn_label
= NULL
;
3703 alpha_auto_align_on
= 1;
3704 alpha_current_align
= 0;
3708 s_alpha_ent (int dummy ATTRIBUTE_UNUSED
)
3710 if (ECOFF_DEBUGGING
)
3711 ecoff_directive_ent (0);
3714 char *name
, name_end
;
3716 name_end
= get_symbol_name (&name
);
3717 /* CFI_EMIT_eh_frame is the default. */
3718 all_cfi_sections
= CFI_EMIT_eh_frame
;
3720 if (! is_name_beginner (*name
))
3722 as_warn (_(".ent directive has no name"));
3723 (void) restore_line_pointer (name_end
);
3730 as_warn (_("nested .ent directives"));
3732 sym
= symbol_find_or_make (name
);
3733 symbol_get_bfdsym (sym
)->flags
|= BSF_FUNCTION
;
3735 cur_frame_data
= XCNEW (struct alpha_elf_frame_data
);
3736 cur_frame_data
->func_sym
= sym
;
3738 /* Provide sensible defaults. */
3739 cur_frame_data
->fp_regno
= 30; /* sp */
3740 cur_frame_data
->ra_regno
= 26; /* ra */
3742 *plast_frame_data
= cur_frame_data
;
3743 plast_frame_data
= &cur_frame_data
->next
;
3745 /* The .ent directive is sometimes followed by a number. Not sure
3746 what it really means, but ignore it. */
3747 *input_line_pointer
= name_end
;
3748 SKIP_WHITESPACE_AFTER_NAME ();
3749 if (*input_line_pointer
== ',')
3751 input_line_pointer
++;
3754 if (ISDIGIT (*input_line_pointer
) || *input_line_pointer
== '-')
3755 (void) get_absolute_expression ();
3757 demand_empty_rest_of_line ();
3762 s_alpha_end (int dummy ATTRIBUTE_UNUSED
)
3764 if (ECOFF_DEBUGGING
)
3765 ecoff_directive_end (0);
3768 char *name
, name_end
;
3770 name_end
= get_symbol_name (&name
);
3772 if (! is_name_beginner (*name
))
3774 as_warn (_(".end directive has no name"));
3780 sym
= symbol_find (name
);
3781 if (!cur_frame_data
)
3782 as_warn (_(".end directive without matching .ent"));
3783 else if (sym
!= cur_frame_data
->func_sym
)
3784 as_warn (_(".end directive names different symbol than .ent"));
3786 /* Create an expression to calculate the size of the function. */
3787 if (sym
&& cur_frame_data
)
3789 OBJ_SYMFIELD_TYPE
*obj
= symbol_get_obj (sym
);
3790 expressionS
*exp
= XNEW (expressionS
);
3793 exp
->X_op
= O_subtract
;
3794 exp
->X_add_symbol
= symbol_temp_new_now ();
3795 exp
->X_op_symbol
= sym
;
3796 exp
->X_add_number
= 0;
3798 cur_frame_data
->func_end_sym
= exp
->X_add_symbol
;
3801 cur_frame_data
= NULL
;
3804 (void) restore_line_pointer (name_end
);
3805 demand_empty_rest_of_line ();
3810 s_alpha_mask (int fp
)
3812 if (ECOFF_DEBUGGING
)
3815 ecoff_directive_fmask (0);
3817 ecoff_directive_mask (0);
3824 if (!cur_frame_data
)
3827 as_warn (_(".fmask outside of .ent"));
3829 as_warn (_(".mask outside of .ent"));
3830 discard_rest_of_line ();
3834 if (get_absolute_expression_and_terminator (&val
) != ',')
3837 as_warn (_("bad .fmask directive"));
3839 as_warn (_("bad .mask directive"));
3840 --input_line_pointer
;
3841 discard_rest_of_line ();
3845 offset
= get_absolute_expression ();
3846 demand_empty_rest_of_line ();
3850 cur_frame_data
->fmask
= val
;
3851 cur_frame_data
->fmask_offset
= offset
;
3855 cur_frame_data
->mask
= val
;
3856 cur_frame_data
->mask_offset
= offset
;
3862 s_alpha_frame (int dummy ATTRIBUTE_UNUSED
)
3864 if (ECOFF_DEBUGGING
)
3865 ecoff_directive_frame (0);
3870 if (!cur_frame_data
)
3872 as_warn (_(".frame outside of .ent"));
3873 discard_rest_of_line ();
3877 cur_frame_data
->fp_regno
= tc_get_register (1);
3880 if (*input_line_pointer
++ != ','
3881 || get_absolute_expression_and_terminator (&val
) != ',')
3883 as_warn (_("bad .frame directive"));
3884 --input_line_pointer
;
3885 discard_rest_of_line ();
3888 cur_frame_data
->frame_size
= val
;
3890 cur_frame_data
->ra_regno
= tc_get_register (0);
3892 /* Next comes the "offset of saved $a0 from $sp". In gcc terms
3893 this is current_function_pretend_args_size. There's no place
3894 to put this value, so ignore it. */
3900 s_alpha_prologue (int ignore ATTRIBUTE_UNUSED
)
3905 arg
= get_absolute_expression ();
3906 demand_empty_rest_of_line ();
3907 alpha_prologue_label
= symbol_new (FAKE_LABEL_NAME
, now_seg
, frag_now
,
3910 if (ECOFF_DEBUGGING
)
3911 sym
= ecoff_get_cur_proc_sym ();
3913 sym
= cur_frame_data
? cur_frame_data
->func_sym
: NULL
;
3917 as_bad (_(".prologue directive without a preceding .ent directive"));
3923 case 0: /* No PV required. */
3924 S_SET_OTHER (sym
, STO_ALPHA_NOPV
3925 | (S_GET_OTHER (sym
) & ~STO_ALPHA_STD_GPLOAD
));
3927 case 1: /* Std GP load. */
3928 S_SET_OTHER (sym
, STO_ALPHA_STD_GPLOAD
3929 | (S_GET_OTHER (sym
) & ~STO_ALPHA_STD_GPLOAD
));
3931 case 2: /* Non-std use of PV. */
3935 as_bad (_("Invalid argument %d to .prologue."), arg
);
3940 cur_frame_data
->prologue_sym
= symbol_temp_new_now ();
3943 static char *first_file_directive
;
3946 s_alpha_file (int ignore ATTRIBUTE_UNUSED
)
3948 /* Save the first .file directive we see, so that we can change our
3949 minds about whether ecoff debugging should or shouldn't be enabled. */
3950 if (alpha_flag_mdebug
< 0 && ! first_file_directive
)
3952 char *start
= input_line_pointer
;
3955 discard_rest_of_line ();
3957 len
= input_line_pointer
- start
;
3958 first_file_directive
= xmemdup0 (start
, len
);
3960 input_line_pointer
= start
;
3963 if (ECOFF_DEBUGGING
)
3964 ecoff_directive_file (0);
3966 dwarf2_directive_file (0);
3970 s_alpha_loc (int ignore ATTRIBUTE_UNUSED
)
3972 if (ECOFF_DEBUGGING
)
3973 ecoff_directive_loc (0);
3975 dwarf2_directive_loc (0);
3979 s_alpha_stab (int n
)
3981 /* If we've been undecided about mdebug, make up our minds in favour. */
3982 if (alpha_flag_mdebug
< 0)
3984 segT sec
= subseg_new (".mdebug", 0);
3985 bfd_set_section_flags (sec
, SEC_HAS_CONTENTS
| SEC_READONLY
);
3986 bfd_set_section_alignment (sec
, 3);
3988 ecoff_read_begin_hook ();
3990 if (first_file_directive
)
3992 char *save_ilp
= input_line_pointer
;
3993 input_line_pointer
= first_file_directive
;
3994 ecoff_directive_file (0);
3995 input_line_pointer
= save_ilp
;
3996 free (first_file_directive
);
3999 alpha_flag_mdebug
= 1;
4005 s_alpha_coff_wrapper (int which
)
4007 static void (* const fns
[]) (int) = {
4008 ecoff_directive_begin
,
4009 ecoff_directive_bend
,
4010 ecoff_directive_def
,
4011 ecoff_directive_dim
,
4012 ecoff_directive_endef
,
4013 ecoff_directive_scl
,
4014 ecoff_directive_tag
,
4015 ecoff_directive_val
,
4018 gas_assert (which
>= 0 && which
< (int) (sizeof (fns
)/sizeof (*fns
)));
4020 if (ECOFF_DEBUGGING
)
4024 as_bad (_("ECOFF debugging is disabled."));
4025 ignore_rest_of_line ();
4029 /* Called at the end of assembly. Here we emit unwind info for frames
4030 unless the compiler has done it for us. */
4033 alpha_elf_md_end (void)
4035 struct alpha_elf_frame_data
*p
;
4038 as_warn (_(".ent directive without matching .end"));
4040 /* If someone has generated the unwind info themselves, great. */
4041 if (bfd_get_section_by_name (stdoutput
, ".eh_frame") != NULL
)
4044 /* ??? In theory we could look for functions for which we have
4045 generated unwind info via CFI directives, and those we have not.
4046 Those we have not could still get their unwind info from here.
4047 For now, do nothing if we've seen any CFI directives. Note that
4048 the above test will not trigger, as we've not emitted data yet. */
4049 if (all_fde_data
!= NULL
)
4052 /* Generate .eh_frame data for the unwind directives specified. */
4053 for (p
= all_frame_data
; p
; p
= p
->next
)
4054 if (p
->prologue_sym
)
4056 /* Create a temporary symbol at the same location as our
4057 function symbol. This prevents problems with globals. */
4058 cfi_new_fde (symbol_temp_new (S_GET_SEGMENT (p
->func_sym
),
4059 symbol_get_frag (p
->func_sym
),
4060 S_GET_VALUE (p
->func_sym
)));
4062 cfi_set_sections ();
4063 cfi_set_return_column (p
->ra_regno
);
4064 cfi_add_CFA_def_cfa_register (30);
4065 if (p
->fp_regno
!= 30 || p
->mask
|| p
->fmask
|| p
->frame_size
)
4070 cfi_add_advance_loc (p
->prologue_sym
);
4072 if (p
->fp_regno
!= 30)
4073 if (p
->frame_size
!= 0)
4074 cfi_add_CFA_def_cfa (p
->fp_regno
, p
->frame_size
);
4076 cfi_add_CFA_def_cfa_register (p
->fp_regno
);
4077 else if (p
->frame_size
!= 0)
4078 cfi_add_CFA_def_cfa_offset (p
->frame_size
);
4081 offset
= p
->mask_offset
;
4083 /* Recall that $26 is special-cased and stored first. */
4084 if ((mask
>> 26) & 1)
4086 cfi_add_CFA_offset (26, offset
);
4097 cfi_add_CFA_offset (i
, offset
);
4102 offset
= p
->fmask_offset
;
4110 cfi_add_CFA_offset (i
+ 32, offset
);
4115 cfi_end_fde (p
->func_end_sym
);
4120 s_alpha_usepv (int unused ATTRIBUTE_UNUSED
)
4122 char *name
, name_end
;
4123 char *which
, which_end
;
4127 name_end
= get_symbol_name (&name
);
4129 if (! is_name_beginner (*name
))
4131 as_bad (_(".usepv directive has no name"));
4132 (void) restore_line_pointer (name_end
);
4133 ignore_rest_of_line ();
4137 sym
= symbol_find_or_make (name
);
4138 name_end
= restore_line_pointer (name_end
);
4139 if (! is_end_of_line
[(unsigned char) name_end
])
4140 input_line_pointer
++;
4142 if (name_end
!= ',')
4144 as_bad (_(".usepv directive has no type"));
4145 ignore_rest_of_line ();
4151 which_end
= get_symbol_name (&which
);
4153 if (strcmp (which
, "no") == 0)
4154 other
= STO_ALPHA_NOPV
;
4155 else if (strcmp (which
, "std") == 0)
4156 other
= STO_ALPHA_STD_GPLOAD
;
4159 as_bad (_("unknown argument for .usepv"));
4163 (void) restore_line_pointer (which_end
);
4164 demand_empty_rest_of_line ();
4166 S_SET_OTHER (sym
, other
| (S_GET_OTHER (sym
) & ~STO_ALPHA_STD_GPLOAD
));
4168 #endif /* OBJ_ELF */
4170 /* Standard calling conventions leaves the CFA at $30 on entry. */
4173 alpha_cfi_frame_initial_instructions (void)
4175 cfi_add_CFA_def_cfa_register (30);
4180 /* Get name of section. */
4182 s_alpha_section_name (void)
4187 if (*input_line_pointer
== '"')
4191 name
= demand_copy_C_string (&dummy
);
4194 ignore_rest_of_line ();
4200 char *end
= input_line_pointer
;
4202 while (0 == strchr ("\n\t,; ", *end
))
4204 if (end
== input_line_pointer
)
4206 as_warn (_("missing name"));
4207 ignore_rest_of_line ();
4211 name
= xmemdup0 (input_line_pointer
, end
- input_line_pointer
);
4212 input_line_pointer
= end
;
4218 /* Put clear/set flags in one flagword. The LSBs are flags to be set,
4219 the MSBs are the flags to be cleared. */
4221 #define EGPS__V_NO_SHIFT 16
4222 #define EGPS__V_MASK 0xffff
4224 /* Parse one VMS section flag. */
4227 s_alpha_section_word (char *str
, size_t len
)
4232 if (len
== 5 && startswith (str
, "NO"))
4241 if (startswith (str
, "PIC"))
4243 else if (startswith (str
, "LIB"))
4245 else if (startswith (str
, "OVR"))
4247 else if (startswith (str
, "REL"))
4249 else if (startswith (str
, "GBL"))
4251 else if (startswith (str
, "SHR"))
4253 else if (startswith (str
, "EXE"))
4255 else if (startswith (str
, "WRT"))
4257 else if (startswith (str
, "VEC"))
4259 else if (startswith (str
, "MOD"))
4261 flag
= no
? EGPS__V_NOMOD
: EGPS__V_NOMOD
<< EGPS__V_NO_SHIFT
;
4264 else if (startswith (str
, "COM"))
4272 as_warn (_("unknown section attribute %s"), str
);
4278 return flag
<< EGPS__V_NO_SHIFT
;
4283 /* Handle the section specific pseudo-op. */
4285 #define EVAX_SECTION_COUNT 5
4287 static const char *section_name
[EVAX_SECTION_COUNT
+ 1] =
4288 { "NULL", ".rdata", ".comm", ".link", ".ctors", ".dtors" };
4291 s_alpha_section (int secid
)
4296 flagword vms_flags
= 0;
4301 name
= s_alpha_section_name ();
4304 sec
= subseg_new (name
, 0);
4305 if (*input_line_pointer
== ',')
4307 /* Skip the comma. */
4308 ++input_line_pointer
;
4316 c
= get_symbol_name (&beg
);
4317 *input_line_pointer
= c
;
4319 vms_flags
|= s_alpha_section_word (beg
, input_line_pointer
- beg
);
4321 SKIP_WHITESPACE_AFTER_NAME ();
4323 while (*input_line_pointer
++ == ',');
4325 --input_line_pointer
;
4328 symbol
= symbol_find_or_make (name
);
4329 S_SET_SEGMENT (symbol
, sec
);
4330 symbol_get_bfdsym (symbol
)->flags
|= BSF_SECTION_SYM
;
4331 bfd_vms_set_section_flags
4333 (vms_flags
>> EGPS__V_NO_SHIFT
) & EGPS__V_MASK
,
4334 vms_flags
& EGPS__V_MASK
);
4338 get_absolute_expression ();
4339 subseg_new (section_name
[secid
], 0);
4342 demand_empty_rest_of_line ();
4343 alpha_insn_label
= NULL
;
4344 alpha_auto_align_on
= 1;
4345 alpha_current_align
= 0;
4349 s_alpha_literals (int ignore ATTRIBUTE_UNUSED
)
4351 subseg_new (".literals", 0);
4352 demand_empty_rest_of_line ();
4353 alpha_insn_label
= NULL
;
4354 alpha_auto_align_on
= 1;
4355 alpha_current_align
= 0;
4358 /* Parse .ent directives. */
4361 s_alpha_ent (int ignore ATTRIBUTE_UNUSED
)
4364 expressionS symexpr
;
4366 if (alpha_evax_proc
!= NULL
)
4367 as_bad (_("previous .ent not closed by a .end"));
4369 alpha_evax_proc
= &alpha_evax_proc_data
;
4371 alpha_evax_proc
->pdsckind
= 0;
4372 alpha_evax_proc
->framereg
= -1;
4373 alpha_evax_proc
->framesize
= 0;
4374 alpha_evax_proc
->rsa_offset
= 0;
4375 alpha_evax_proc
->ra_save
= AXP_REG_RA
;
4376 alpha_evax_proc
->fp_save
= -1;
4377 alpha_evax_proc
->imask
= 0;
4378 alpha_evax_proc
->fmask
= 0;
4379 alpha_evax_proc
->prologue
= 0;
4380 alpha_evax_proc
->type
= 0;
4381 alpha_evax_proc
->handler
= 0;
4382 alpha_evax_proc
->handler_data
= 0;
4384 expression (&symexpr
);
4386 if (symexpr
.X_op
!= O_symbol
)
4388 as_fatal (_(".ent directive has no symbol"));
4389 demand_empty_rest_of_line ();
4393 symbol
= make_expr_symbol (&symexpr
);
4394 symbol_get_bfdsym (symbol
)->flags
|= BSF_FUNCTION
;
4395 alpha_evax_proc
->symbol
= symbol
;
4397 demand_empty_rest_of_line ();
4401 s_alpha_handler (int is_data
)
4404 alpha_evax_proc
->handler_data
= get_absolute_expression ();
4407 char *name
, name_end
;
4409 name_end
= get_symbol_name (&name
);
4411 if (! is_name_beginner (*name
))
4413 as_warn (_(".handler directive has no name"));
4419 sym
= symbol_find_or_make (name
);
4420 symbol_get_bfdsym (sym
)->flags
|= BSF_FUNCTION
;
4421 alpha_evax_proc
->handler
= sym
;
4424 (void) restore_line_pointer (name_end
);
4427 demand_empty_rest_of_line ();
4430 /* Parse .frame <framreg>,<framesize>,RA,<rsa_offset> directives. */
4433 s_alpha_frame (int ignore ATTRIBUTE_UNUSED
)
4438 alpha_evax_proc
->framereg
= tc_get_register (1);
4441 if (*input_line_pointer
++ != ','
4442 || get_absolute_expression_and_terminator (&val
) != ',')
4444 as_warn (_("Bad .frame directive 1./2. param"));
4445 --input_line_pointer
;
4446 demand_empty_rest_of_line ();
4450 alpha_evax_proc
->framesize
= val
;
4452 ra
= tc_get_register (1);
4453 if (ra
!= AXP_REG_RA
)
4454 as_warn (_("Bad RA (%d) register for .frame"), ra
);
4457 if (*input_line_pointer
++ != ',')
4459 as_warn (_("Bad .frame directive 3./4. param"));
4460 --input_line_pointer
;
4461 demand_empty_rest_of_line ();
4464 alpha_evax_proc
->rsa_offset
= get_absolute_expression ();
4467 /* Parse .prologue. */
4470 s_alpha_prologue (int ignore ATTRIBUTE_UNUSED
)
4472 demand_empty_rest_of_line ();
4473 alpha_prologue_label
= symbol_new (FAKE_LABEL_NAME
, now_seg
, frag_now
,
4477 /* Parse .pdesc <entry_name>,{null|stack|reg}
4478 Insert a procedure descriptor. */
4481 s_alpha_pdesc (int ignore ATTRIBUTE_UNUSED
)
4488 const char *entry_sym_name
;
4489 const char *pdesc_sym_name
;
4493 if (now_seg
!= alpha_link_section
)
4495 as_bad (_(".pdesc directive not in link (.link) section"));
4500 if (exp
.X_op
!= O_symbol
)
4502 as_bad (_(".pdesc directive has no entry symbol"));
4506 entry_sym
= make_expr_symbol (&exp
);
4507 entry_sym_name
= S_GET_NAME (entry_sym
);
4510 len
= strlen (entry_sym_name
);
4511 if (len
< 4 || strcmp (entry_sym_name
+ len
- 4, "..en") != 0)
4513 as_bad (_(".pdesc has a bad entry symbol"));
4517 pdesc_sym_name
= S_GET_NAME (alpha_evax_proc
->symbol
);
4519 if (!alpha_evax_proc
4520 || !S_IS_DEFINED (alpha_evax_proc
->symbol
)
4521 || strlen (pdesc_sym_name
) != len
4522 || memcmp (entry_sym_name
, pdesc_sym_name
, len
) != 0)
4524 as_fatal (_(".pdesc doesn't match with last .ent"));
4528 /* Define pdesc symbol. */
4529 symbol_set_value_now (alpha_evax_proc
->symbol
);
4531 /* Save bfd symbol of proc entry in function symbol. */
4532 ((struct evax_private_udata_struct
*)
4533 symbol_get_bfdsym (alpha_evax_proc
->symbol
)->udata
.p
)->enbsym
4534 = symbol_get_bfdsym (entry_sym
);
4537 if (*input_line_pointer
++ != ',')
4539 as_warn (_("No comma after .pdesc <entryname>"));
4540 demand_empty_rest_of_line ();
4545 name_end
= get_symbol_name (&name
);
4547 if (startswith (name
, "stack"))
4548 alpha_evax_proc
->pdsckind
= PDSC_S_K_KIND_FP_STACK
;
4550 else if (startswith (name
, "reg"))
4551 alpha_evax_proc
->pdsckind
= PDSC_S_K_KIND_FP_REGISTER
;
4553 else if (startswith (name
, "null"))
4554 alpha_evax_proc
->pdsckind
= PDSC_S_K_KIND_NULL
;
4558 (void) restore_line_pointer (name_end
);
4559 as_fatal (_("unknown procedure kind"));
4560 demand_empty_rest_of_line ();
4564 (void) restore_line_pointer (name_end
);
4565 demand_empty_rest_of_line ();
4567 #ifdef md_flush_pending_output
4568 md_flush_pending_output ();
4571 frag_align (3, 0, 0);
4573 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
4576 *p
= alpha_evax_proc
->pdsckind
4577 | ((alpha_evax_proc
->framereg
== 29) ? PDSC_S_M_BASE_REG_IS_FP
: 0)
4578 | ((alpha_evax_proc
->handler
) ? PDSC_S_M_HANDLER_VALID
: 0)
4579 | ((alpha_evax_proc
->handler_data
) ? PDSC_S_M_HANDLER_DATA_VALID
: 0);
4580 *(p
+ 1) = PDSC_S_M_NATIVE
| PDSC_S_M_NO_JACKET
;
4582 switch (alpha_evax_proc
->pdsckind
)
4584 case PDSC_S_K_KIND_NULL
:
4588 case PDSC_S_K_KIND_FP_REGISTER
:
4589 *(p
+ 2) = alpha_evax_proc
->fp_save
;
4590 *(p
+ 3) = alpha_evax_proc
->ra_save
;
4592 case PDSC_S_K_KIND_FP_STACK
:
4593 md_number_to_chars (p
+ 2, (valueT
) alpha_evax_proc
->rsa_offset
, 2);
4595 default: /* impossible */
4600 *(p
+ 5) = alpha_evax_proc
->type
& 0x0f;
4602 /* Signature offset. */
4603 md_number_to_chars (p
+ 6, (valueT
) 0, 2);
4605 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
+ 8,
4606 8, &exp
, 0, BFD_RELOC_64
);
4608 if (alpha_evax_proc
->pdsckind
== PDSC_S_K_KIND_NULL
)
4611 /* pdesc+16: Size. */
4613 md_number_to_chars (p
, (valueT
) alpha_evax_proc
->framesize
, 4);
4614 md_number_to_chars (p
+ 4, (valueT
) 0, 2);
4617 exp
.X_op
= O_subtract
;
4618 exp
.X_add_symbol
= alpha_prologue_label
;
4619 exp
.X_op_symbol
= entry_sym
;
4620 emit_expr (&exp
, 2);
4622 if (alpha_evax_proc
->pdsckind
== PDSC_S_K_KIND_FP_REGISTER
)
4625 /* pdesc+24: register masks. */
4627 md_number_to_chars (p
, alpha_evax_proc
->imask
, 4);
4628 md_number_to_chars (p
+ 4, alpha_evax_proc
->fmask
, 4);
4630 if (alpha_evax_proc
->handler
)
4633 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8,
4634 alpha_evax_proc
->handler
, 0, 0, BFD_RELOC_64
);
4637 if (alpha_evax_proc
->handler_data
)
4640 md_number_to_chars (p
, alpha_evax_proc
->handler_data
, 8);
4644 /* Support for crash debug on vms. */
4647 s_alpha_name (int ignore ATTRIBUTE_UNUSED
)
4652 if (now_seg
!= alpha_link_section
)
4654 as_bad (_(".name directive not in link (.link) section"));
4655 demand_empty_rest_of_line ();
4660 if (exp
.X_op
!= O_symbol
)
4662 as_warn (_(".name directive has no symbol"));
4663 demand_empty_rest_of_line ();
4667 demand_empty_rest_of_line ();
4669 #ifdef md_flush_pending_output
4670 md_flush_pending_output ();
4673 frag_align (3, 0, 0);
4676 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 8, &exp
, 0, BFD_RELOC_64
);
4679 /* Parse .linkage <symbol>.
4680 Create a linkage pair relocation. */
4683 s_alpha_linkage (int ignore ATTRIBUTE_UNUSED
)
4689 #ifdef md_flush_pending_output
4690 md_flush_pending_output ();
4694 if (exp
.X_op
!= O_symbol
)
4696 as_fatal (_("No symbol after .linkage"));
4700 struct alpha_linkage_fixups
*linkage_fixup
;
4702 p
= frag_more (LKP_S_K_SIZE
);
4703 memset (p
, 0, LKP_S_K_SIZE
);
4705 (frag_now
, p
- frag_now
->fr_literal
, LKP_S_K_SIZE
, &exp
, 0,
4706 BFD_RELOC_ALPHA_LINKAGE
);
4708 if (alpha_insn_label
== NULL
)
4709 alpha_insn_label
= symbol_new (FAKE_LABEL_NAME
, now_seg
, frag_now
,
4712 /* Create a linkage element. */
4713 linkage_fixup
= XNEW (struct alpha_linkage_fixups
);
4714 linkage_fixup
->fixp
= fixp
;
4715 linkage_fixup
->next
= NULL
;
4716 linkage_fixup
->label
= alpha_insn_label
;
4718 /* Append it to the list. */
4719 if (alpha_linkage_fixup_root
== NULL
)
4720 alpha_linkage_fixup_root
= linkage_fixup
;
4722 alpha_linkage_fixup_tail
->next
= linkage_fixup
;
4723 alpha_linkage_fixup_tail
= linkage_fixup
;
4725 demand_empty_rest_of_line ();
4728 /* Parse .code_address <symbol>.
4729 Create a code address relocation. */
4732 s_alpha_code_address (int ignore ATTRIBUTE_UNUSED
)
4737 #ifdef md_flush_pending_output
4738 md_flush_pending_output ();
4742 if (exp
.X_op
!= O_symbol
)
4743 as_fatal (_("No symbol after .code_address"));
4748 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 8, &exp
, 0,\
4749 BFD_RELOC_ALPHA_CODEADDR
);
4751 demand_empty_rest_of_line ();
4755 s_alpha_fp_save (int ignore ATTRIBUTE_UNUSED
)
4757 alpha_evax_proc
->fp_save
= tc_get_register (1);
4759 demand_empty_rest_of_line ();
4763 s_alpha_mask (int ignore ATTRIBUTE_UNUSED
)
4767 if (get_absolute_expression_and_terminator (&val
) != ',')
4769 as_warn (_("Bad .mask directive"));
4770 --input_line_pointer
;
4774 alpha_evax_proc
->imask
= val
;
4775 (void) get_absolute_expression ();
4777 demand_empty_rest_of_line ();
4781 s_alpha_fmask (int ignore ATTRIBUTE_UNUSED
)
4785 if (get_absolute_expression_and_terminator (&val
) != ',')
4787 as_warn (_("Bad .fmask directive"));
4788 --input_line_pointer
;
4792 alpha_evax_proc
->fmask
= val
;
4793 (void) get_absolute_expression ();
4795 demand_empty_rest_of_line ();
4799 s_alpha_end (int ignore ATTRIBUTE_UNUSED
)
4804 c
= get_symbol_name (&name
);
4805 (void) restore_line_pointer (c
);
4806 demand_empty_rest_of_line ();
4807 alpha_evax_proc
= NULL
;
4811 s_alpha_file (int ignore ATTRIBUTE_UNUSED
)
4815 static char case_hack
[32];
4817 sprintf (case_hack
, "<CASE:%01d%01d>",
4818 alpha_flag_hash_long_names
, alpha_flag_show_after_trunc
);
4820 s
= symbol_find_or_make (case_hack
);
4821 symbol_get_bfdsym (s
)->flags
|= BSF_FILE
;
4823 get_absolute_expression ();
4824 s
= symbol_find_or_make (demand_copy_string (&length
));
4825 symbol_get_bfdsym (s
)->flags
|= BSF_FILE
;
4826 demand_empty_rest_of_line ();
4828 #endif /* OBJ_EVAX */
4830 /* Handle the .gprel32 pseudo op. */
4833 s_alpha_gprel32 (int ignore ATTRIBUTE_UNUSED
)
4845 e
.X_add_symbol
= section_symbol (absolute_section
);
4858 e
.X_add_symbol
= section_symbol (absolute_section
);
4861 e
.X_op
= O_subtract
;
4862 e
.X_op_symbol
= alpha_gp_symbol
;
4870 if (alpha_auto_align_on
&& alpha_current_align
< 2)
4871 alpha_align (2, (char *) NULL
, alpha_insn_label
, 0);
4872 if (alpha_current_align
> 2)
4873 alpha_current_align
= 2;
4874 alpha_insn_label
= NULL
;
4878 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 4,
4879 &e
, 0, BFD_RELOC_GPREL32
);
4882 /* Handle floating point allocation pseudo-ops. This is like the
4883 generic version, but it makes sure the current label, if any, is
4884 correctly aligned. */
4887 s_alpha_float_cons (int type
)
4913 if (alpha_auto_align_on
&& alpha_current_align
< log_size
)
4914 alpha_align (log_size
, (char *) NULL
, alpha_insn_label
, 0);
4915 if (alpha_current_align
> log_size
)
4916 alpha_current_align
= log_size
;
4917 alpha_insn_label
= NULL
;
4922 /* Handle the .proc pseudo op. We don't really do much with it except
4926 s_alpha_proc (int is_static ATTRIBUTE_UNUSED
)
4934 /* Takes ".proc name,nargs". */
4936 c
= get_symbol_name (&name
);
4937 p
= input_line_pointer
;
4938 symbolP
= symbol_find_or_make (name
);
4940 SKIP_WHITESPACE_AFTER_NAME ();
4941 if (*input_line_pointer
!= ',')
4944 as_warn (_("Expected comma after name \"%s\""), name
);
4947 ignore_rest_of_line ();
4951 input_line_pointer
++;
4952 temp
= get_absolute_expression ();
4954 /* *symbol_get_obj (symbolP) = (signed char) temp; */
4956 as_warn (_("unhandled: .proc %s,%d"), name
, temp
);
4957 demand_empty_rest_of_line ();
4960 /* Handle the .set pseudo op. This is used to turn on and off most of
4961 the assembler features. */
4964 s_alpha_set (int x ATTRIBUTE_UNUSED
)
4971 ch
= get_symbol_name (&name
);
4973 if (s
[0] == 'n' && s
[1] == 'o')
4978 if (!strcmp ("reorder", s
))
4980 else if (!strcmp ("at", s
))
4981 alpha_noat_on
= !yesno
;
4982 else if (!strcmp ("macro", s
))
4983 alpha_macros_on
= yesno
;
4984 else if (!strcmp ("move", s
))
4986 else if (!strcmp ("volatile", s
))
4989 as_warn (_("Tried to .set unrecognized mode `%s'"), name
);
4991 (void) restore_line_pointer (ch
);
4992 demand_empty_rest_of_line ();
4995 /* Handle the .base pseudo op. This changes the assembler's notion of
4996 the $gp register. */
4999 s_alpha_base (int ignore ATTRIBUTE_UNUSED
)
5003 if (*input_line_pointer
== '$')
5006 input_line_pointer
++;
5007 if (*input_line_pointer
== 'r')
5008 input_line_pointer
++;
5011 alpha_gp_register
= get_absolute_expression ();
5012 if (alpha_gp_register
< 0 || alpha_gp_register
> 31)
5014 alpha_gp_register
= AXP_REG_GP
;
5015 as_warn (_("Bad base register, using $%d."), alpha_gp_register
);
5018 demand_empty_rest_of_line ();
5021 /* Handle the .align pseudo-op. This aligns to a power of two. It
5022 also adjusts any current instruction label. We treat this the same
5023 way the MIPS port does: .align 0 turns off auto alignment. */
5026 s_alpha_align (int ignore ATTRIBUTE_UNUSED
)
5030 long max_alignment
= 16;
5032 align
= get_absolute_expression ();
5033 if (align
> max_alignment
)
5035 align
= max_alignment
;
5036 as_bad (_("Alignment too large: %d. assumed"), align
);
5040 as_warn (_("Alignment negative: 0 assumed"));
5044 if (*input_line_pointer
== ',')
5046 input_line_pointer
++;
5047 fill
= get_absolute_expression ();
5055 alpha_auto_align_on
= 1;
5056 alpha_align (align
, pfill
, NULL
, 1);
5060 alpha_auto_align_on
= 0;
5062 alpha_insn_label
= NULL
;
5064 demand_empty_rest_of_line ();
5067 /* Hook the normal string processor to reset known alignment. */
5070 s_alpha_stringer (int terminate
)
5072 alpha_current_align
= 0;
5073 alpha_insn_label
= NULL
;
5074 stringer (8 + terminate
);
5077 /* Hook the normal space processing to reset known alignment. */
5080 s_alpha_space (int ignore
)
5082 alpha_current_align
= 0;
5083 alpha_insn_label
= NULL
;
5087 /* Hook into cons for auto-alignment. */
5090 alpha_cons_align (int size
)
5095 while ((size
>>= 1) != 0)
5098 if (alpha_auto_align_on
&& alpha_current_align
< log_size
)
5099 alpha_align (log_size
, (char *) NULL
, alpha_insn_label
, 0);
5100 if (alpha_current_align
> log_size
)
5101 alpha_current_align
= log_size
;
5102 alpha_insn_label
= NULL
;
5105 /* Here come the .uword, .ulong, and .uquad explicitly unaligned
5106 pseudos. We just turn off auto-alignment and call down to cons. */
5109 s_alpha_ucons (int bytes
)
5111 int hold
= alpha_auto_align_on
;
5112 alpha_auto_align_on
= 0;
5114 alpha_auto_align_on
= hold
;
5117 /* Switch the working cpu type. */
5120 s_alpha_arch (int ignored ATTRIBUTE_UNUSED
)
5123 const struct cpu_type
*p
;
5127 ch
= get_symbol_name (&name
);
5129 for (p
= cpu_types
; p
->name
; ++p
)
5130 if (strcmp (name
, p
->name
) == 0)
5132 alpha_target_name
= p
->name
, alpha_target
= p
->flags
;
5135 as_warn (_("Unknown CPU identifier `%s'"), name
);
5138 (void) restore_line_pointer (ch
);
5139 demand_empty_rest_of_line ();
5143 /* print token expression with alpha specific extension. */
5146 alpha_print_token (FILE *f
, const expressionS
*exp
)
5156 expressionS nexp
= *exp
;
5157 nexp
.X_op
= O_register
;
5158 print_expr_1 (f
, &nexp
);
5163 print_expr_1 (f
, exp
);
5169 /* The target specific pseudo-ops which we support. */
5171 const pseudo_typeS md_pseudo_table
[] =
5174 {"comm", s_alpha_comm
, 0}, /* OSF1 compiler does this. */
5175 {"rdata", s_alpha_rdata
, 0},
5177 {"text", s_alpha_text
, 0},
5178 {"data", s_alpha_data
, 0},
5180 {"sdata", s_alpha_sdata
, 0},
5183 {"section", s_alpha_section
, 0},
5184 {"section.s", s_alpha_section
, 0},
5185 {"sect", s_alpha_section
, 0},
5186 {"sect.s", s_alpha_section
, 0},
5189 {"section", s_alpha_section
, 0},
5190 {"literals", s_alpha_literals
, 0},
5191 {"pdesc", s_alpha_pdesc
, 0},
5192 {"name", s_alpha_name
, 0},
5193 {"linkage", s_alpha_linkage
, 0},
5194 {"code_address", s_alpha_code_address
, 0},
5195 {"ent", s_alpha_ent
, 0},
5196 {"frame", s_alpha_frame
, 0},
5197 {"fp_save", s_alpha_fp_save
, 0},
5198 {"mask", s_alpha_mask
, 0},
5199 {"fmask", s_alpha_fmask
, 0},
5200 {"end", s_alpha_end
, 0},
5201 {"file", s_alpha_file
, 0},
5202 {"rdata", s_alpha_section
, 1},
5203 {"comm", s_alpha_comm
, 0},
5204 {"link", s_alpha_section
, 3},
5205 {"ctors", s_alpha_section
, 4},
5206 {"dtors", s_alpha_section
, 5},
5207 {"handler", s_alpha_handler
, 0},
5208 {"handler_data", s_alpha_handler
, 1},
5211 /* Frame related pseudos. */
5212 {"ent", s_alpha_ent
, 0},
5213 {"end", s_alpha_end
, 0},
5214 {"mask", s_alpha_mask
, 0},
5215 {"fmask", s_alpha_mask
, 1},
5216 {"frame", s_alpha_frame
, 0},
5217 {"prologue", s_alpha_prologue
, 0},
5218 {"file", s_alpha_file
, 5},
5219 {"loc", s_alpha_loc
, 9},
5220 {"stabs", s_alpha_stab
, 's'},
5221 {"stabn", s_alpha_stab
, 'n'},
5222 {"usepv", s_alpha_usepv
, 0},
5223 /* COFF debugging related pseudos. */
5224 {"begin", s_alpha_coff_wrapper
, 0},
5225 {"bend", s_alpha_coff_wrapper
, 1},
5226 {"def", s_alpha_coff_wrapper
, 2},
5227 {"dim", s_alpha_coff_wrapper
, 3},
5228 {"endef", s_alpha_coff_wrapper
, 4},
5229 {"scl", s_alpha_coff_wrapper
, 5},
5230 {"tag", s_alpha_coff_wrapper
, 6},
5231 {"val", s_alpha_coff_wrapper
, 7},
5234 {"prologue", s_alpha_prologue
, 0},
5236 {"prologue", s_ignore
, 0},
5239 {"gprel32", s_alpha_gprel32
, 0},
5240 {"t_floating", s_alpha_float_cons
, 'd'},
5241 {"s_floating", s_alpha_float_cons
, 'f'},
5242 {"f_floating", s_alpha_float_cons
, 'F'},
5243 {"g_floating", s_alpha_float_cons
, 'G'},
5244 {"d_floating", s_alpha_float_cons
, 'D'},
5246 {"proc", s_alpha_proc
, 0},
5247 {"aproc", s_alpha_proc
, 1},
5248 {"set", s_alpha_set
, 0},
5249 {"reguse", s_ignore
, 0},
5250 {"livereg", s_ignore
, 0},
5251 {"base", s_alpha_base
, 0}, /*??*/
5252 {"option", s_ignore
, 0},
5253 {"aent", s_ignore
, 0},
5254 {"ugen", s_ignore
, 0},
5255 {"eflag", s_ignore
, 0},
5257 {"align", s_alpha_align
, 0},
5258 {"double", s_alpha_float_cons
, 'd'},
5259 {"float", s_alpha_float_cons
, 'f'},
5260 {"single", s_alpha_float_cons
, 'f'},
5261 {"ascii", s_alpha_stringer
, 0},
5262 {"asciz", s_alpha_stringer
, 1},
5263 {"string", s_alpha_stringer
, 1},
5264 {"space", s_alpha_space
, 0},
5265 {"skip", s_alpha_space
, 0},
5266 {"zero", s_alpha_space
, 0},
5268 /* Unaligned data pseudos. */
5269 {"uword", s_alpha_ucons
, 2},
5270 {"ulong", s_alpha_ucons
, 4},
5271 {"uquad", s_alpha_ucons
, 8},
5274 /* Dwarf wants these versions of unaligned. */
5275 {"2byte", s_alpha_ucons
, 2},
5276 {"4byte", s_alpha_ucons
, 4},
5277 {"8byte", s_alpha_ucons
, 8},
5280 /* We don't do any optimizing, so we can safely ignore these. */
5281 {"noalias", s_ignore
, 0},
5282 {"alias", s_ignore
, 0},
5284 {"arch", s_alpha_arch
, 0},
5291 /* @@@ GP selection voodoo. All of this seems overly complicated and
5292 unnecessary; which is the primary reason it's for ECOFF only. */
5295 maybe_set_gp (asection
*sec
)
5301 vma
= bfd_section_vma (sec
);
5302 if (vma
&& vma
< alpha_gp_value
)
5303 alpha_gp_value
= vma
;
5307 select_gp_value (void)
5309 gas_assert (alpha_gp_value
== 0);
5311 /* Get minus-one in whatever width... */
5315 /* Select the smallest VMA of these existing sections. */
5316 maybe_set_gp (alpha_lita_section
);
5318 /* @@ Will a simple 0x8000 work here? If not, why not? */
5319 #define GP_ADJUSTMENT (0x8000 - 0x10)
5321 alpha_gp_value
+= GP_ADJUSTMENT
;
5323 S_SET_VALUE (alpha_gp_symbol
, alpha_gp_value
);
5326 printf (_("Chose GP value of %lx\n"), alpha_gp_value
);
5329 #endif /* OBJ_ECOFF */
5332 /* Map 's' to SHF_ALPHA_GPREL. */
5335 alpha_elf_section_letter (int letter
, const char **ptr_msg
)
5338 return SHF_ALPHA_GPREL
;
5340 *ptr_msg
= _("bad .section directive: want a,s,w,x,M,S,G,T in string");
5344 /* Map SHF_ALPHA_GPREL to SEC_SMALL_DATA. */
5347 alpha_elf_section_flags (flagword flags
, bfd_vma attr
, int type ATTRIBUTE_UNUSED
)
5349 if (attr
& SHF_ALPHA_GPREL
)
5350 flags
|= SEC_SMALL_DATA
;
5353 #endif /* OBJ_ELF */
5355 /* This is called from HANDLE_ALIGN in write.c. Fill in the contents
5356 of an rs_align_code fragment. */
5359 alpha_handle_align (fragS
*fragp
)
5361 static unsigned char const unop
[4] = { 0x00, 0x00, 0xfe, 0x2f };
5362 static unsigned char const nopunop
[8] =
5364 0x1f, 0x04, 0xff, 0x47,
5365 0x00, 0x00, 0xfe, 0x2f
5371 if (fragp
->fr_type
!= rs_align_code
)
5374 bytes
= fragp
->fr_next
->fr_address
- fragp
->fr_address
- fragp
->fr_fix
;
5375 p
= fragp
->fr_literal
+ fragp
->fr_fix
;
5388 memcpy (p
, unop
, 4);
5394 memcpy (p
, nopunop
, 8);
5396 fragp
->fr_fix
+= fix
;
5400 /* Public interface functions. */
5402 /* This function is called once, at assembler startup time. It sets
5403 up all the tables, etc. that the MD part of the assembler will
5404 need, that can be determined before arguments are parsed. */
5411 /* Verify that X_op field is wide enough. */
5416 gas_assert (e
.X_op
== O_max
);
5419 /* Create the opcode hash table. */
5420 alpha_opcode_hash
= str_htab_create ();
5422 for (i
= 0; i
< alpha_num_opcodes
;)
5424 const char *name
, *slash
;
5426 name
= alpha_opcodes
[i
].name
;
5427 if (str_hash_insert (alpha_opcode_hash
, name
, &alpha_opcodes
[i
], 0))
5428 as_fatal (_("duplicate %s"), name
);
5430 /* Some opcodes include modifiers of various sorts with a "/mod"
5431 syntax, like the architecture manual suggests. However, for
5432 use with gcc at least, we also need access to those same opcodes
5435 if ((slash
= strchr (name
, '/')) != NULL
)
5437 char *p
= XNEWVEC (char, strlen (name
));
5439 memcpy (p
, name
, slash
- name
);
5440 strcpy (p
+ (slash
- name
), slash
+ 1);
5442 (void) str_hash_insert (alpha_opcode_hash
, p
, &alpha_opcodes
[i
], 0);
5443 /* Ignore failures -- the opcode table does duplicate some
5444 variants in different forms, like "hw_stq" and "hw_st/q". */
5447 while (++i
< alpha_num_opcodes
5448 && (alpha_opcodes
[i
].name
== name
5449 || !strcmp (alpha_opcodes
[i
].name
, name
)))
5453 /* Create the macro hash table. */
5454 alpha_macro_hash
= str_htab_create ();
5456 for (i
= 0; i
< alpha_num_macros
;)
5460 name
= alpha_macros
[i
].name
;
5461 if (str_hash_insert (alpha_macro_hash
, name
, &alpha_macros
[i
], 0))
5462 as_fatal (_("duplicate %s"), name
);
5464 while (++i
< alpha_num_macros
5465 && (alpha_macros
[i
].name
== name
5466 || !strcmp (alpha_macros
[i
].name
, name
)))
5470 /* Construct symbols for each of the registers. */
5471 for (i
= 0; i
< 32; ++i
)
5475 sprintf (name
, "$%d", i
);
5476 alpha_register_table
[i
] = symbol_create (name
, reg_section
,
5477 &zero_address_frag
, i
);
5484 sprintf (name
, "$f%d", i
- 32);
5485 alpha_register_table
[i
] = symbol_create (name
, reg_section
,
5486 &zero_address_frag
, i
);
5489 /* Create the special symbols and sections we'll be using. */
5491 /* So .sbss will get used for tiny objects. */
5492 bfd_set_gp_size (stdoutput
, g_switch_value
);
5495 create_literal_section (".lita", &alpha_lita_section
, &alpha_lita_symbol
);
5497 /* For handling the GP, create a symbol that won't be output in the
5498 symbol table. We'll edit it out of relocs later. */
5499 alpha_gp_symbol
= symbol_create ("<GP value>", alpha_lita_section
,
5500 &zero_address_frag
, 0x8000);
5504 create_literal_section (".link", &alpha_link_section
, &alpha_link_symbol
);
5508 if (ECOFF_DEBUGGING
)
5510 segT sec
= subseg_new (".mdebug", (subsegT
) 0);
5511 bfd_set_section_flags (sec
, SEC_HAS_CONTENTS
| SEC_READONLY
);
5512 bfd_set_section_alignment (sec
, 3);
5516 /* Create literal lookup hash table. */
5517 alpha_literal_hash
= str_htab_create ();
5519 subseg_set (text_section
, 0);
5522 /* The public interface to the instruction assembler. */
5525 md_assemble (char *str
)
5527 /* Current maximum is 13. */
5529 expressionS tok
[MAX_INSN_ARGS
];
5533 /* Split off the opcode. */
5534 opnamelen
= strspn (str
, "abcdefghijklmnopqrstuvwxyz_/46819");
5535 trunclen
= (opnamelen
< sizeof (opname
) - 1
5537 : sizeof (opname
) - 1);
5538 memcpy (opname
, str
, trunclen
);
5539 opname
[trunclen
] = '\0';
5541 /* Tokenize the rest of the line. */
5542 if ((ntok
= tokenize_arguments (str
+ opnamelen
, tok
, MAX_INSN_ARGS
)) < 0)
5544 if (ntok
!= TOKENIZE_ERROR_REPORT
)
5545 as_bad (_("syntax error"));
5550 /* Finish it off. */
5551 assemble_tokens (opname
, tok
, ntok
, alpha_macros_on
);
5554 /* Round up a section's size to the appropriate boundary. */
5557 md_section_align (segT seg
, valueT size
)
5559 int align
= bfd_section_alignment (seg
);
5560 valueT mask
= ((valueT
) 1 << align
) - 1;
5562 return (size
+ mask
) & ~mask
;
5565 /* Turn a string in input_line_pointer into a floating point constant
5566 of type TYPE, and store the appropriate bytes in *LITP. The number
5567 of LITTLENUMS emitted is stored in *SIZEP. An error message is
5568 returned, or NULL on OK. */
5571 md_atof (int type
, char *litP
, int *sizeP
)
5573 extern const char *vax_md_atof (int, char *, int *);
5579 /* vax_md_atof() doesn't like "G" for some reason. */
5584 return vax_md_atof (type
, litP
, sizeP
);
5587 return ieee_md_atof (type
, litP
, sizeP
, false);
5591 /* Take care of the target-specific command-line options. */
5594 md_parse_option (int c
, const char *arg
)
5599 alpha_nofloats_on
= 1;
5603 alpha_addr32_on
= 1;
5611 g_switch_value
= atoi (arg
);
5616 const struct cpu_type
*p
;
5618 for (p
= cpu_types
; p
->name
; ++p
)
5619 if (strcmp (arg
, p
->name
) == 0)
5621 alpha_target_name
= p
->name
, alpha_target
= p
->flags
;
5624 as_warn (_("Unknown CPU identifier `%s'"), arg
);
5630 case '+': /* For g++. Hash any name > 63 chars long. */
5631 alpha_flag_hash_long_names
= 1;
5634 case 'H': /* Show new symbol after hash truncation. */
5635 alpha_flag_show_after_trunc
= 1;
5638 case 'h': /* For gnu-c/vax compatibility. */
5641 case OPTION_REPLACE
:
5642 alpha_flag_replace
= 1;
5645 case OPTION_NOREPLACE
:
5646 alpha_flag_replace
= 0;
5651 alpha_flag_relax
= 1;
5656 alpha_flag_mdebug
= 1;
5658 case OPTION_NO_MDEBUG
:
5659 alpha_flag_mdebug
= 0;
5670 /* Print a description of the command-line options that we accept. */
5673 md_show_usage (FILE *stream
)
5677 -32addr treat addresses as 32-bit values\n\
5678 -F lack floating point instructions support\n\
5679 -mev4 | -mev45 | -mev5 | -mev56 | -mpca56 | -mev6 | -mev67 | -mev68 | -mall\n\
5680 specify variant of Alpha architecture\n\
5681 -m21064 | -m21066 | -m21164 | -m21164a | -m21164pc | -m21264 | -m21264a | -m21264b\n\
5682 these variants include PALcode opcodes\n"),
5687 -+ encode (don't truncate) names longer than 64 characters\n\
5688 -H show new symbol after hash truncation\n\
5689 -replace/-noreplace enable or disable the optimization of procedure calls\n"),
5694 /* Decide from what point a pc-relative relocation is relative to,
5695 relative to the pc-relative fixup. Er, relatively speaking. */
5698 md_pcrel_from (fixS
*fixP
)
5700 valueT addr
= fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
5702 switch (fixP
->fx_r_type
)
5704 case BFD_RELOC_23_PCREL_S2
:
5705 case BFD_RELOC_ALPHA_HINT
:
5706 case BFD_RELOC_ALPHA_BRSGP
:
5713 /* Attempt to simplify or even eliminate a fixup. The return value is
5714 ignored; perhaps it was once meaningful, but now it is historical.
5715 To indicate that a fixup has been eliminated, set fixP->fx_done.
5717 For ELF, here it is that we transform the GPDISP_HI16 reloc we used
5718 internally into the GPDISP reloc used externally. We had to do
5719 this so that we'd have the GPDISP_LO16 reloc as a tag to compute
5720 the distance to the "lda" instruction for setting the addend to
5724 md_apply_fix (fixS
*fixP
, valueT
* valP
, segT seg
)
5726 char * const fixpos
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
5727 valueT value
= * valP
;
5728 unsigned image
, size
;
5730 switch (fixP
->fx_r_type
)
5732 /* The GPDISP relocations are processed internally with a symbol
5733 referring to the current function's section; we need to drop
5734 in a value which, when added to the address of the start of
5735 the function, gives the desired GP. */
5736 case BFD_RELOC_ALPHA_GPDISP_HI16
:
5738 fixS
*next
= fixP
->fx_next
;
5740 /* With user-specified !gpdisp relocations, we can be missing
5741 the matching LO16 reloc. We will have already issued an
5744 fixP
->fx_offset
= (next
->fx_frag
->fr_address
+ next
->fx_where
5745 - fixP
->fx_frag
->fr_address
- fixP
->fx_where
);
5747 value
= (value
- sign_extend_16 (value
)) >> 16;
5750 fixP
->fx_r_type
= BFD_RELOC_ALPHA_GPDISP
;
5754 case BFD_RELOC_ALPHA_GPDISP_LO16
:
5755 value
= sign_extend_16 (value
);
5756 fixP
->fx_offset
= 0;
5762 fixP
->fx_addsy
= section_symbol (seg
);
5763 md_number_to_chars (fixpos
, value
, 2);
5768 fixP
->fx_r_type
= BFD_RELOC_8_PCREL
;
5774 fixP
->fx_r_type
= BFD_RELOC_16_PCREL
;
5780 fixP
->fx_r_type
= BFD_RELOC_32_PCREL
;
5786 fixP
->fx_r_type
= BFD_RELOC_64_PCREL
;
5790 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
5792 md_number_to_chars (fixpos
, value
, size
);
5798 case BFD_RELOC_GPREL32
:
5799 gas_assert (fixP
->fx_subsy
== alpha_gp_symbol
);
5801 /* FIXME: inherited this obliviousness of `value' -- why? */
5802 md_number_to_chars (fixpos
, -alpha_gp_value
, 4);
5805 case BFD_RELOC_GPREL32
:
5807 case BFD_RELOC_GPREL16
:
5808 case BFD_RELOC_ALPHA_GPREL_HI16
:
5809 case BFD_RELOC_ALPHA_GPREL_LO16
:
5812 case BFD_RELOC_23_PCREL_S2
:
5813 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
5815 image
= bfd_getl32 (fixpos
);
5816 image
= (image
& ~0x1FFFFF) | ((value
>> 2) & 0x1FFFFF);
5821 case BFD_RELOC_ALPHA_HINT
:
5822 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
5824 image
= bfd_getl32 (fixpos
);
5825 image
= (image
& ~0x3FFF) | ((value
>> 2) & 0x3FFF);
5831 case BFD_RELOC_ALPHA_BRSGP
:
5834 case BFD_RELOC_ALPHA_TLSGD
:
5835 case BFD_RELOC_ALPHA_TLSLDM
:
5836 case BFD_RELOC_ALPHA_GOTDTPREL16
:
5837 case BFD_RELOC_ALPHA_DTPREL_HI16
:
5838 case BFD_RELOC_ALPHA_DTPREL_LO16
:
5839 case BFD_RELOC_ALPHA_DTPREL16
:
5840 case BFD_RELOC_ALPHA_GOTTPREL16
:
5841 case BFD_RELOC_ALPHA_TPREL_HI16
:
5842 case BFD_RELOC_ALPHA_TPREL_LO16
:
5843 case BFD_RELOC_ALPHA_TPREL16
:
5845 S_SET_THREAD_LOCAL (fixP
->fx_addsy
);
5850 case BFD_RELOC_ALPHA_LITERAL
:
5851 md_number_to_chars (fixpos
, value
, 2);
5854 case BFD_RELOC_ALPHA_ELF_LITERAL
:
5855 case BFD_RELOC_ALPHA_LITUSE
:
5856 case BFD_RELOC_ALPHA_LINKAGE
:
5857 case BFD_RELOC_ALPHA_CODEADDR
:
5861 case BFD_RELOC_ALPHA_NOP
:
5862 value
-= (8 + 4); /* PC-relative, base is jsr+4. */
5864 /* From B.4.5.2 of the OpenVMS Linker Utility Manual:
5865 "Finally, the ETIR$C_STC_BSR command passes the same address
5866 as ETIR$C_STC_NOP (so that they will fail or succeed together),
5867 and the same test is done again." */
5868 if (S_GET_SEGMENT (fixP
->fx_addsy
) == undefined_section
)
5870 fixP
->fx_addnumber
= -value
;
5874 if (value
+ (1u << 22) >= (1u << 23))
5878 /* Change to a nop. */
5883 case BFD_RELOC_ALPHA_LDA
:
5884 /* fixup_segment sets fixP->fx_addsy to NULL when it can pre-compute
5885 the value for an O_subtract. */
5887 && S_GET_SEGMENT (fixP
->fx_addsy
) == undefined_section
)
5889 fixP
->fx_addnumber
= symbol_get_bfdsym (fixP
->fx_subsy
)->value
;
5893 if (value
+ (1u << 15) >= (1u << 16))
5897 /* Change to an lda. */
5898 image
= 0x237B0000 | (value
& 0xFFFF);
5902 case BFD_RELOC_ALPHA_BSR
:
5903 case BFD_RELOC_ALPHA_BOH
:
5904 value
-= 4; /* PC-relative, base is jsr+4. */
5906 /* See comment in the BFD_RELOC_ALPHA_NOP case above. */
5907 if (S_GET_SEGMENT (fixP
->fx_addsy
) == undefined_section
)
5909 fixP
->fx_addnumber
= -value
;
5913 if (value
+ (1u << 22) >= (1u << 23))
5916 if (fixP
->fx_r_type
== BFD_RELOC_ALPHA_BOH
)
5919 image
= bfd_getl32(fixpos
);
5920 image
= (image
& ~0x3FFF) | ((value
>> 2) & 0x3FFF);
5927 /* Change to a branch. */
5928 image
= 0xD3400000 | ((value
>> 2) & 0x1FFFFF);
5933 case BFD_RELOC_VTABLE_INHERIT
:
5934 case BFD_RELOC_VTABLE_ENTRY
:
5939 const struct alpha_operand
*operand
;
5941 if ((int) fixP
->fx_r_type
>= 0)
5942 as_fatal (_("unhandled relocation type %s"),
5943 bfd_get_reloc_code_name (fixP
->fx_r_type
));
5945 gas_assert (-(int) fixP
->fx_r_type
< (int) alpha_num_operands
);
5946 operand
= &alpha_operands
[-(int) fixP
->fx_r_type
];
5948 /* The rest of these fixups only exist internally during symbol
5949 resolution and have no representation in the object file.
5950 Therefore they must be completely resolved as constants. */
5952 if (fixP
->fx_addsy
!= 0
5953 && S_GET_SEGMENT (fixP
->fx_addsy
) != absolute_section
)
5954 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5955 _("non-absolute expression in constant field"));
5957 image
= bfd_getl32 (fixpos
);
5958 image
= insert_operand (image
, operand
, (offsetT
) value
,
5959 fixP
->fx_file
, fixP
->fx_line
);
5964 if (fixP
->fx_addsy
!= 0 || fixP
->fx_pcrel
!= 0)
5968 as_warn_where (fixP
->fx_file
, fixP
->fx_line
,
5969 _("type %d reloc done?\n"), (int) fixP
->fx_r_type
);
5974 md_number_to_chars (fixpos
, image
, 4);
5980 /* Look for a register name in the given symbol. */
5983 md_undefined_symbol (char *name
)
5987 int is_float
= 0, num
;
5992 if (name
[1] == 'p' && name
[2] == '\0')
5993 return alpha_register_table
[AXP_REG_FP
];
5998 if (!ISDIGIT (*++name
))
6002 case '0': case '1': case '2': case '3': case '4':
6003 case '5': case '6': case '7': case '8': case '9':
6004 if (name
[1] == '\0')
6005 num
= name
[0] - '0';
6006 else if (name
[0] != '0' && ISDIGIT (name
[1]) && name
[2] == '\0')
6008 num
= (name
[0] - '0') * 10 + name
[1] - '0';
6015 if (!alpha_noat_on
&& (num
+ is_float
) == AXP_REG_AT
)
6016 as_warn (_("Used $at without \".set noat\""));
6017 return alpha_register_table
[num
+ is_float
];
6020 if (name
[1] == 't' && name
[2] == '\0')
6023 as_warn (_("Used $at without \".set noat\""));
6024 return alpha_register_table
[AXP_REG_AT
];
6029 if (name
[1] == 'p' && name
[2] == '\0')
6030 return alpha_register_table
[alpha_gp_register
];
6034 if (name
[1] == 'p' && name
[2] == '\0')
6035 return alpha_register_table
[AXP_REG_SP
];
6043 /* @@@ Magic ECOFF bits. */
6046 alpha_frob_ecoff_data (void)
6049 /* $zero and $f31 are read-only. */
6050 alpha_gprmask
&= ~1;
6051 alpha_fprmask
&= ~1;
6055 /* Hook to remember a recently defined label so that the auto-align
6056 code can adjust the symbol after we know what alignment will be
6060 alpha_define_label (symbolS
*sym
)
6062 alpha_insn_label
= sym
;
6064 dwarf2_emit_label (sym
);
6068 /* Return true if we must always emit a reloc for a type and false if
6069 there is some hope of resolving it at assembly time. */
6072 alpha_force_relocation (fixS
*f
)
6074 if (alpha_flag_relax
)
6077 switch (f
->fx_r_type
)
6079 case BFD_RELOC_ALPHA_GPDISP_HI16
:
6080 case BFD_RELOC_ALPHA_GPDISP_LO16
:
6081 case BFD_RELOC_ALPHA_GPDISP
:
6082 case BFD_RELOC_ALPHA_LITERAL
:
6083 case BFD_RELOC_ALPHA_ELF_LITERAL
:
6084 case BFD_RELOC_ALPHA_LITUSE
:
6085 case BFD_RELOC_GPREL16
:
6086 case BFD_RELOC_GPREL32
:
6087 case BFD_RELOC_ALPHA_GPREL_HI16
:
6088 case BFD_RELOC_ALPHA_GPREL_LO16
:
6089 case BFD_RELOC_ALPHA_LINKAGE
:
6090 case BFD_RELOC_ALPHA_CODEADDR
:
6091 case BFD_RELOC_ALPHA_BRSGP
:
6092 case BFD_RELOC_ALPHA_TLSGD
:
6093 case BFD_RELOC_ALPHA_TLSLDM
:
6094 case BFD_RELOC_ALPHA_GOTDTPREL16
:
6095 case BFD_RELOC_ALPHA_DTPREL_HI16
:
6096 case BFD_RELOC_ALPHA_DTPREL_LO16
:
6097 case BFD_RELOC_ALPHA_DTPREL16
:
6098 case BFD_RELOC_ALPHA_GOTTPREL16
:
6099 case BFD_RELOC_ALPHA_TPREL_HI16
:
6100 case BFD_RELOC_ALPHA_TPREL_LO16
:
6101 case BFD_RELOC_ALPHA_TPREL16
:
6103 case BFD_RELOC_ALPHA_NOP
:
6104 case BFD_RELOC_ALPHA_BSR
:
6105 case BFD_RELOC_ALPHA_LDA
:
6106 case BFD_RELOC_ALPHA_BOH
:
6114 return generic_force_reloc (f
);
6117 /* Return true if we can partially resolve a relocation now. */
6120 alpha_fix_adjustable (fixS
*f
)
6122 /* Are there any relocation types for which we must generate a
6123 reloc but we can adjust the values contained within it? */
6124 switch (f
->fx_r_type
)
6126 case BFD_RELOC_ALPHA_GPDISP_HI16
:
6127 case BFD_RELOC_ALPHA_GPDISP_LO16
:
6128 case BFD_RELOC_ALPHA_GPDISP
:
6131 case BFD_RELOC_ALPHA_LITERAL
:
6132 case BFD_RELOC_ALPHA_ELF_LITERAL
:
6133 case BFD_RELOC_ALPHA_LITUSE
:
6134 case BFD_RELOC_ALPHA_LINKAGE
:
6135 case BFD_RELOC_ALPHA_CODEADDR
:
6138 case BFD_RELOC_VTABLE_ENTRY
:
6139 case BFD_RELOC_VTABLE_INHERIT
:
6142 case BFD_RELOC_GPREL16
:
6143 case BFD_RELOC_GPREL32
:
6144 case BFD_RELOC_ALPHA_GPREL_HI16
:
6145 case BFD_RELOC_ALPHA_GPREL_LO16
:
6146 case BFD_RELOC_23_PCREL_S2
:
6150 case BFD_RELOC_ALPHA_HINT
:
6153 case BFD_RELOC_ALPHA_TLSGD
:
6154 case BFD_RELOC_ALPHA_TLSLDM
:
6155 case BFD_RELOC_ALPHA_GOTDTPREL16
:
6156 case BFD_RELOC_ALPHA_DTPREL_HI16
:
6157 case BFD_RELOC_ALPHA_DTPREL_LO16
:
6158 case BFD_RELOC_ALPHA_DTPREL16
:
6159 case BFD_RELOC_ALPHA_GOTTPREL16
:
6160 case BFD_RELOC_ALPHA_TPREL_HI16
:
6161 case BFD_RELOC_ALPHA_TPREL_LO16
:
6162 case BFD_RELOC_ALPHA_TPREL16
:
6163 /* ??? No idea why we can't return a reference to .tbss+10, but
6164 we're preventing this in the other assemblers. Follow for now. */
6168 case BFD_RELOC_ALPHA_BRSGP
:
6169 /* If we have a BRSGP reloc to a local symbol, adjust it to BRADDR and
6170 let it get resolved at assembly time. */
6172 symbolS
*sym
= f
->fx_addsy
;
6176 if (generic_force_reloc (f
))
6179 switch (S_GET_OTHER (sym
) & STO_ALPHA_STD_GPLOAD
)
6181 case STO_ALPHA_NOPV
:
6183 case STO_ALPHA_STD_GPLOAD
:
6187 if (S_IS_LOCAL (sym
))
6190 name
= S_GET_NAME (sym
);
6191 as_bad_where (f
->fx_file
, f
->fx_line
,
6192 _("!samegp reloc against symbol without .prologue: %s"),
6196 f
->fx_r_type
= BFD_RELOC_23_PCREL_S2
;
6197 f
->fx_offset
+= offset
;
6202 case BFD_RELOC_ALPHA_NOP
:
6203 case BFD_RELOC_ALPHA_BSR
:
6204 case BFD_RELOC_ALPHA_LDA
:
6205 case BFD_RELOC_ALPHA_BOH
:
6214 /* Generate the BFD reloc to be stuck in the object file from the
6215 fixup used internally in the assembler. */
6218 tc_gen_reloc (asection
*sec ATTRIBUTE_UNUSED
,
6223 reloc
= XNEW (arelent
);
6224 reloc
->sym_ptr_ptr
= XNEW (asymbol
*);
6225 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
6226 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
6228 /* Make sure none of our internal relocations make it this far.
6229 They'd better have been fully resolved by this point. */
6230 gas_assert ((int) fixp
->fx_r_type
> 0);
6232 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
6233 if (reloc
->howto
== NULL
)
6235 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
6236 _("cannot represent `%s' relocation in object file"),
6237 bfd_get_reloc_code_name (fixp
->fx_r_type
));
6241 if (!fixp
->fx_pcrel
!= !reloc
->howto
->pc_relative
)
6242 as_fatal (_("internal error? cannot generate `%s' relocation"),
6243 bfd_get_reloc_code_name (fixp
->fx_r_type
));
6245 gas_assert (!fixp
->fx_pcrel
== !reloc
->howto
->pc_relative
);
6247 reloc
->addend
= fixp
->fx_offset
;
6250 /* Fake out bfd_perform_relocation. sigh. */
6251 /* ??? Better would be to use the special_function hook. */
6252 if (fixp
->fx_r_type
== BFD_RELOC_ALPHA_LITERAL
)
6253 reloc
->addend
= -alpha_gp_value
;
6257 switch (fixp
->fx_r_type
)
6259 struct evax_private_udata_struct
*udata
;
6263 case BFD_RELOC_ALPHA_LINKAGE
:
6264 /* Copy the linkage index. */
6265 reloc
->addend
= fixp
->fx_addnumber
;
6268 case BFD_RELOC_ALPHA_NOP
:
6269 case BFD_RELOC_ALPHA_BSR
:
6270 case BFD_RELOC_ALPHA_LDA
:
6271 case BFD_RELOC_ALPHA_BOH
:
6272 pname
= symbol_get_bfdsym (fixp
->fx_addsy
)->name
;
6274 /* We need the non-suffixed name of the procedure. Beware that
6275 the main symbol might be equated so look it up and take its name. */
6276 pname_len
= strlen (pname
);
6277 if (pname_len
> 4 && strcmp (pname
+ pname_len
- 4, "..en") == 0)
6280 char *my_pname
= xmemdup0 (pname
, pname_len
- 4);
6281 sym
= symbol_find (my_pname
);
6286 while (symbol_equated_reloc_p (sym
))
6288 symbolS
*n
= symbol_get_value_expression (sym
)->X_add_symbol
;
6290 /* We must avoid looping, as that can occur with a badly
6296 pname
= symbol_get_bfdsym (sym
)->name
;
6299 udata
= XNEW (struct evax_private_udata_struct
);
6300 udata
->enbsym
= symbol_get_bfdsym (fixp
->fx_addsy
);
6301 udata
->bsym
= symbol_get_bfdsym (fixp
->tc_fix_data
.info
->psym
);
6302 udata
->origname
= (char *)pname
;
6303 udata
->lkindex
= ((struct evax_private_udata_struct
*)
6304 symbol_get_bfdsym (fixp
->tc_fix_data
.info
->sym
)->udata
.p
)->lkindex
;
6305 reloc
->sym_ptr_ptr
= (void *)udata
;
6306 reloc
->addend
= fixp
->fx_addnumber
;
6316 /* Parse a register name off of the input_line and return a register
6317 number. Gets md_undefined_symbol above to do the register name
6320 Only called as a part of processing the ECOFF .frame directive. */
6323 tc_get_register (int frame ATTRIBUTE_UNUSED
)
6325 int framereg
= AXP_REG_SP
;
6328 if (*input_line_pointer
== '$')
6331 char c
= get_symbol_name (&s
);
6332 symbolS
*sym
= md_undefined_symbol (s
);
6334 *strchr (s
, '\0') = c
;
6335 if (sym
&& (framereg
= S_GET_VALUE (sym
)) <= 31)
6338 as_warn (_("frame reg expected, using $%d."), framereg
);
6341 note_gpreg (framereg
);
6345 /* This is called before the symbol table is processed. In order to
6346 work with gcc when using mips-tfile, we must keep all local labels.
6347 However, in other cases, we want to discard them. If we were
6348 called with -g, but we didn't see any debugging information, it may
6349 mean that gcc is smuggling debugging information through to
6350 mips-tfile, in which case we must generate all local labels. */
6355 alpha_frob_file_before_adjust (void)
6357 if (alpha_debug
!= 0
6358 && ! ecoff_debugging_seen
)
6359 flag_keep_locals
= 1;
6362 #endif /* OBJ_ECOFF */
6364 /* The Alpha has support for some VAX floating point types, as well as for
6365 IEEE floating point. We consider IEEE to be the primary floating point
6366 format, and sneak in the VAX floating point support here. */
6367 #include "config/atof-vax.c"