1 /* tc-alpha.c - Processor-specific code for the DEC Alpha AXP CPU.
2 Copyright 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009
4 Free Software Foundation, Inc.
5 Contributed by Carnegie Mellon University, 1993.
6 Written by Alessandro Forin, based on earlier gas-1.38 target CPU files.
7 Modified by Ken Raeburn for gas-2.x and ECOFF support.
8 Modified by Richard Henderson for ELF support.
9 Modified by Klaus K"ampf for EVAX (OpenVMS/Alpha) support.
11 This file is part of GAS, the GNU Assembler.
13 GAS is free software; you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation; either version 3, or (at your option)
18 GAS is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
23 You should have received a copy of the GNU General Public License
24 along with GAS; see the file COPYING. If not, write to the Free
25 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
28 /* Mach Operating System
29 Copyright (c) 1993 Carnegie Mellon University
32 Permission to use, copy, modify and distribute this software and its
33 documentation is hereby granted, provided that both the copyright
34 notice and this permission notice appear in all copies of the
35 software, derivative works or modified versions, and any portions
36 thereof, and that both notices appear in supporting documentation.
38 CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
39 CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
40 ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
42 Carnegie Mellon requests users of this software to return to
44 Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
45 School of Computer Science
46 Carnegie Mellon University
47 Pittsburgh PA 15213-3890
49 any improvements or extensions that they make and grant Carnegie the
50 rights to redistribute these changes. */
54 #include "struc-symbol.h"
57 #include "opcode/alpha.h"
60 #include "elf/alpha.h"
68 #include "dwarf2dbg.h"
69 #include "dw2gencfi.h"
70 #include "safe-ctype.h"
74 #define TOKENIZE_ERROR -1
75 #define TOKENIZE_ERROR_REPORT -2
76 #define MAX_INSN_FIXUPS 2
77 #define MAX_INSN_ARGS 5
79 /* Used since new relocation types are introduced in this
80 file (DUMMY_RELOC_LITUSE_*) */
81 typedef int extended_bfd_reloc_code_real_type
;
86 /* bfd_reloc_code_real_type reloc; */
87 extended_bfd_reloc_code_real_type reloc
;
89 symbolS
*xtrasym
, *procsym
;
97 struct alpha_fixup fixups
[MAX_INSN_FIXUPS
];
115 void (*emit
) (const expressionS
*, int, const void *);
117 enum alpha_macro_arg argsets
[16];
120 /* Extra expression types. */
122 #define O_pregister O_md1 /* O_register, in parentheses. */
123 #define O_cpregister O_md2 /* + a leading comma. */
125 /* The alpha_reloc_op table below depends on the ordering of these. */
126 #define O_literal O_md3 /* !literal relocation. */
127 #define O_lituse_addr O_md4 /* !lituse_addr relocation. */
128 #define O_lituse_base O_md5 /* !lituse_base relocation. */
129 #define O_lituse_bytoff O_md6 /* !lituse_bytoff relocation. */
130 #define O_lituse_jsr O_md7 /* !lituse_jsr relocation. */
131 #define O_lituse_tlsgd O_md8 /* !lituse_tlsgd relocation. */
132 #define O_lituse_tlsldm O_md9 /* !lituse_tlsldm relocation. */
133 #define O_lituse_jsrdirect O_md10 /* !lituse_jsrdirect relocation. */
134 #define O_gpdisp O_md11 /* !gpdisp relocation. */
135 #define O_gprelhigh O_md12 /* !gprelhigh relocation. */
136 #define O_gprellow O_md13 /* !gprellow relocation. */
137 #define O_gprel O_md14 /* !gprel relocation. */
138 #define O_samegp O_md15 /* !samegp relocation. */
139 #define O_tlsgd O_md16 /* !tlsgd relocation. */
140 #define O_tlsldm O_md17 /* !tlsldm relocation. */
141 #define O_gotdtprel O_md18 /* !gotdtprel relocation. */
142 #define O_dtprelhi O_md19 /* !dtprelhi relocation. */
143 #define O_dtprello O_md20 /* !dtprello relocation. */
144 #define O_dtprel O_md21 /* !dtprel relocation. */
145 #define O_gottprel O_md22 /* !gottprel relocation. */
146 #define O_tprelhi O_md23 /* !tprelhi relocation. */
147 #define O_tprello O_md24 /* !tprello relocation. */
148 #define O_tprel O_md25 /* !tprel relocation. */
150 #define DUMMY_RELOC_LITUSE_ADDR (BFD_RELOC_UNUSED + 1)
151 #define DUMMY_RELOC_LITUSE_BASE (BFD_RELOC_UNUSED + 2)
152 #define DUMMY_RELOC_LITUSE_BYTOFF (BFD_RELOC_UNUSED + 3)
153 #define DUMMY_RELOC_LITUSE_JSR (BFD_RELOC_UNUSED + 4)
154 #define DUMMY_RELOC_LITUSE_TLSGD (BFD_RELOC_UNUSED + 5)
155 #define DUMMY_RELOC_LITUSE_TLSLDM (BFD_RELOC_UNUSED + 6)
156 #define DUMMY_RELOC_LITUSE_JSRDIRECT (BFD_RELOC_UNUSED + 7)
158 #define USER_RELOC_P(R) ((R) >= O_literal && (R) <= O_tprel)
160 /* Macros for extracting the type and number of encoded register tokens. */
162 #define is_ir_num(x) (((x) & 32) == 0)
163 #define is_fpr_num(x) (((x) & 32) != 0)
164 #define regno(x) ((x) & 31)
166 /* Something odd inherited from the old assembler. */
168 #define note_gpreg(R) (alpha_gprmask |= (1 << (R)))
169 #define note_fpreg(R) (alpha_fprmask |= (1 << (R)))
171 /* Predicates for 16- and 32-bit ranges */
172 /* XXX: The non-shift version appears to trigger a compiler bug when
173 cross-assembling from x86 w/ gcc 2.7.2. */
176 #define range_signed_16(x) \
177 (((offsetT) (x) >> 15) == 0 || ((offsetT) (x) >> 15) == -1)
178 #define range_signed_32(x) \
179 (((offsetT) (x) >> 31) == 0 || ((offsetT) (x) >> 31) == -1)
181 #define range_signed_16(x) ((offsetT) (x) >= -(offsetT) 0x8000 && \
182 (offsetT) (x) <= (offsetT) 0x7FFF)
183 #define range_signed_32(x) ((offsetT) (x) >= -(offsetT) 0x80000000 && \
184 (offsetT) (x) <= (offsetT) 0x7FFFFFFF)
187 /* Macros for sign extending from 16- and 32-bits. */
188 /* XXX: The cast macros will work on all the systems that I care about,
189 but really a predicate should be found to use the non-cast forms. */
192 #define sign_extend_16(x) ((short) (x))
193 #define sign_extend_32(x) ((int) (x))
195 #define sign_extend_16(x) ((offsetT) (((x) & 0xFFFF) ^ 0x8000) - 0x8000)
196 #define sign_extend_32(x) ((offsetT) (((x) & 0xFFFFFFFF) \
197 ^ 0x80000000) - 0x80000000)
200 /* Macros to build tokens. */
202 #define set_tok_reg(t, r) (memset (&(t), 0, sizeof (t)), \
203 (t).X_op = O_register, \
204 (t).X_add_number = (r))
205 #define set_tok_preg(t, r) (memset (&(t), 0, sizeof (t)), \
206 (t).X_op = O_pregister, \
207 (t).X_add_number = (r))
208 #define set_tok_cpreg(t, r) (memset (&(t), 0, sizeof (t)), \
209 (t).X_op = O_cpregister, \
210 (t).X_add_number = (r))
211 #define set_tok_freg(t, r) (memset (&(t), 0, sizeof (t)), \
212 (t).X_op = O_register, \
213 (t).X_add_number = (r) + 32)
214 #define set_tok_sym(t, s, a) (memset (&(t), 0, sizeof (t)), \
215 (t).X_op = O_symbol, \
216 (t).X_add_symbol = (s), \
217 (t).X_add_number = (a))
218 #define set_tok_const(t, n) (memset (&(t), 0, sizeof (t)), \
219 (t).X_op = O_constant, \
220 (t).X_add_number = (n))
222 /* Generic assembler global variables which must be defined by all
225 /* Characters which always start a comment. */
226 const char comment_chars
[] = "#";
228 /* Characters which start a comment at the beginning of a line. */
229 const char line_comment_chars
[] = "#";
231 /* Characters which may be used to separate multiple commands on a
233 const char line_separator_chars
[] = ";";
235 /* Characters which are used to indicate an exponent in a floating
237 const char EXP_CHARS
[] = "eE";
239 /* Characters which mean that a number is a floating point constant,
241 /* XXX: Do all of these really get used on the alpha?? */
242 char FLT_CHARS
[] = "rRsSfFdDxXpP";
245 const char *md_shortopts
= "Fm:g+1h:HG:";
247 const char *md_shortopts
= "Fm:gG:";
250 struct option md_longopts
[] =
252 #define OPTION_32ADDR (OPTION_MD_BASE)
253 { "32addr", no_argument
, NULL
, OPTION_32ADDR
},
254 #define OPTION_RELAX (OPTION_32ADDR + 1)
255 { "relax", no_argument
, NULL
, OPTION_RELAX
},
257 #define OPTION_MDEBUG (OPTION_RELAX + 1)
258 #define OPTION_NO_MDEBUG (OPTION_MDEBUG + 1)
259 { "mdebug", no_argument
, NULL
, OPTION_MDEBUG
},
260 { "no-mdebug", no_argument
, NULL
, OPTION_NO_MDEBUG
},
263 #define OPTION_REPLACE (OPTION_RELAX + 1)
264 #define OPTION_NOREPLACE (OPTION_REPLACE+1)
265 { "replace", no_argument
, NULL
, OPTION_REPLACE
},
266 { "noreplace", no_argument
, NULL
, OPTION_NOREPLACE
},
268 { NULL
, no_argument
, NULL
, 0 }
271 size_t md_longopts_size
= sizeof (md_longopts
);
275 #define AXP_REG_R16 16
276 #define AXP_REG_R17 17
278 #define AXP_REG_T9 22
280 #define AXP_REG_T10 23
282 #define AXP_REG_T11 24
284 #define AXP_REG_T12 25
285 #define AXP_REG_AI 25
287 #define AXP_REG_FP 29
290 #define AXP_REG_GP AXP_REG_PV
292 static struct hash_control
*alpha_evax_proc_hash
;
294 #endif /* OBJ_EVAX */
296 /* The cpu for which we are generating code. */
297 static unsigned alpha_target
= AXP_OPCODE_BASE
;
298 static const char *alpha_target_name
= "<all>";
300 /* The hash table of instruction opcodes. */
301 static struct hash_control
*alpha_opcode_hash
;
303 /* The hash table of macro opcodes. */
304 static struct hash_control
*alpha_macro_hash
;
307 /* The $gp relocation symbol. */
308 static symbolS
*alpha_gp_symbol
;
310 /* XXX: what is this, and why is it exported? */
311 valueT alpha_gp_value
;
314 /* The current $gp register. */
315 static int alpha_gp_register
= AXP_REG_GP
;
317 /* A table of the register symbols. */
318 static symbolS
*alpha_register_table
[64];
320 /* Constant sections, or sections of constants. */
322 static segT alpha_lita_section
;
325 segT alpha_link_section
;
328 static segT alpha_lit8_section
;
331 /* Symbols referring to said sections. */
333 static symbolS
*alpha_lita_symbol
;
336 static symbolS
*alpha_link_symbol
;
339 static symbolS
*alpha_lit8_symbol
;
342 /* Literal for .litX+0x8000 within .lita. */
344 static offsetT alpha_lit8_literal
;
347 /* Is the assembler not allowed to use $at? */
348 static int alpha_noat_on
= 0;
350 /* Are macros enabled? */
351 static int alpha_macros_on
= 1;
353 /* Are floats disabled? */
354 static int alpha_nofloats_on
= 0;
356 /* Are addresses 32 bit? */
357 static int alpha_addr32_on
= 0;
359 /* Symbol labelling the current insn. When the Alpha gas sees
362 and the section happens to not be on an eight byte boundary, it
363 will align both the symbol and the .quad to an eight byte boundary. */
364 static symbolS
*alpha_insn_label
;
365 #if defined(OBJ_ELF) || defined (OBJ_EVAX)
366 static symbolS
*alpha_prologue_label
;
370 /* Symbol associate with the current jsr instruction. */
371 static symbolS
*alpha_linkage_symbol
;
374 /* Whether we should automatically align data generation pseudo-ops.
375 .align 0 will turn this off. */
376 static int alpha_auto_align_on
= 1;
378 /* The known current alignment of the current section. */
379 static int alpha_current_align
;
381 /* These are exported to ECOFF code. */
382 unsigned long alpha_gprmask
, alpha_fprmask
;
384 /* Whether the debugging option was seen. */
385 static int alpha_debug
;
388 /* Whether we are emitting an mdebug section. */
389 int alpha_flag_mdebug
= -1;
393 /* Whether to perform the VMS procedure call optimization. */
394 int alpha_flag_replace
= 1;
397 /* Don't fully resolve relocations, allowing code movement in the linker. */
398 static int alpha_flag_relax
;
400 /* What value to give to bfd_set_gp_size. */
401 static int g_switch_value
= 8;
404 /* Collect information about current procedure here. */
405 struct alpha_evax_procs
407 symbolS
*symbol
; /* Proc pdesc symbol. */
409 int framereg
; /* Register for frame pointer. */
410 int framesize
; /* Size of frame. */
422 struct alpha_linkage_fixups
*alpha_linkage_fixup_root
;
423 static struct alpha_linkage_fixups
*alpha_linkage_fixup_tail
;
425 static struct alpha_evax_procs
*alpha_evax_proc
;
427 static int alpha_flag_hash_long_names
= 0; /* -+ */
428 static int alpha_flag_show_after_trunc
= 0; /* -H */
430 /* If the -+ switch is given, then a hash is appended to any name that is
431 longer than 64 characters, else longer symbol names are truncated. */
436 /* A table to map the spelling of a relocation operand into an appropriate
437 bfd_reloc_code_real_type type. The table is assumed to be ordered such
438 that op-O_literal indexes into it. */
440 #define ALPHA_RELOC_TABLE(op) \
441 (&alpha_reloc_op[ ((!USER_RELOC_P (op)) \
443 : (int) (op) - (int) O_literal) ])
445 #define DEF(NAME, RELOC, REQ, ALLOW) \
446 { #NAME, sizeof(#NAME)-1, O_##NAME, RELOC, REQ, ALLOW}
448 static const struct alpha_reloc_op_tag
450 const char *name
; /* String to lookup. */
451 size_t length
; /* Size of the string. */
452 operatorT op
; /* Which operator to use. */
453 extended_bfd_reloc_code_real_type reloc
;
454 unsigned int require_seq
: 1; /* Require a sequence number. */
455 unsigned int allow_seq
: 1; /* Allow a sequence number. */
459 DEF (literal
, BFD_RELOC_ALPHA_ELF_LITERAL
, 0, 1),
460 DEF (lituse_addr
, DUMMY_RELOC_LITUSE_ADDR
, 1, 1),
461 DEF (lituse_base
, DUMMY_RELOC_LITUSE_BASE
, 1, 1),
462 DEF (lituse_bytoff
, DUMMY_RELOC_LITUSE_BYTOFF
, 1, 1),
463 DEF (lituse_jsr
, DUMMY_RELOC_LITUSE_JSR
, 1, 1),
464 DEF (lituse_tlsgd
, DUMMY_RELOC_LITUSE_TLSGD
, 1, 1),
465 DEF (lituse_tlsldm
, DUMMY_RELOC_LITUSE_TLSLDM
, 1, 1),
466 DEF (lituse_jsrdirect
, DUMMY_RELOC_LITUSE_JSRDIRECT
, 1, 1),
467 DEF (gpdisp
, BFD_RELOC_ALPHA_GPDISP
, 1, 1),
468 DEF (gprelhigh
, BFD_RELOC_ALPHA_GPREL_HI16
, 0, 0),
469 DEF (gprellow
, BFD_RELOC_ALPHA_GPREL_LO16
, 0, 0),
470 DEF (gprel
, BFD_RELOC_GPREL16
, 0, 0),
471 DEF (samegp
, BFD_RELOC_ALPHA_BRSGP
, 0, 0),
472 DEF (tlsgd
, BFD_RELOC_ALPHA_TLSGD
, 0, 1),
473 DEF (tlsldm
, BFD_RELOC_ALPHA_TLSLDM
, 0, 1),
474 DEF (gotdtprel
, BFD_RELOC_ALPHA_GOTDTPREL16
, 0, 0),
475 DEF (dtprelhi
, BFD_RELOC_ALPHA_DTPREL_HI16
, 0, 0),
476 DEF (dtprello
, BFD_RELOC_ALPHA_DTPREL_LO16
, 0, 0),
477 DEF (dtprel
, BFD_RELOC_ALPHA_DTPREL16
, 0, 0),
478 DEF (gottprel
, BFD_RELOC_ALPHA_GOTTPREL16
, 0, 0),
479 DEF (tprelhi
, BFD_RELOC_ALPHA_TPREL_HI16
, 0, 0),
480 DEF (tprello
, BFD_RELOC_ALPHA_TPREL_LO16
, 0, 0),
481 DEF (tprel
, BFD_RELOC_ALPHA_TPREL16
, 0, 0),
486 static const int alpha_num_reloc_op
487 = sizeof (alpha_reloc_op
) / sizeof (*alpha_reloc_op
);
488 #endif /* RELOC_OP_P */
490 /* Maximum # digits needed to hold the largest sequence #. */
491 #define ALPHA_RELOC_DIGITS 25
493 /* Structure to hold explicit sequence information. */
494 struct alpha_reloc_tag
496 fixS
*master
; /* The literal reloc. */
501 fixS
*slaves
; /* Head of linked list of lituses. */
502 segT segment
; /* Segment relocs are in or undefined_section. */
503 long sequence
; /* Sequence #. */
504 unsigned n_master
; /* # of literals. */
505 unsigned n_slaves
; /* # of lituses. */
506 unsigned saw_tlsgd
: 1; /* True if ... */
507 unsigned saw_tlsldm
: 1;
508 unsigned saw_lu_tlsgd
: 1;
509 unsigned saw_lu_tlsldm
: 1;
510 unsigned multi_section_p
: 1; /* True if more than one section was used. */
511 char string
[1]; /* Printable form of sequence to hash with. */
514 /* Hash table to link up literals with the appropriate lituse. */
515 static struct hash_control
*alpha_literal_hash
;
517 /* Sequence numbers for internal use by macros. */
518 static long next_sequence_num
= -1;
520 /* A table of CPU names and opcode sets. */
522 static const struct cpu_type
529 /* Ad hoc convention: cpu number gets palcode, process code doesn't.
530 This supports usage under DU 4.0b that does ".arch ev4", and
531 usage in MILO that does -m21064. Probably something more
532 specific like -m21064-pal should be used, but oh well. */
534 { "21064", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
535 { "21064a", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
536 { "21066", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
537 { "21068", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
538 { "21164", AXP_OPCODE_BASE
|AXP_OPCODE_EV5
},
539 { "21164a", AXP_OPCODE_BASE
|AXP_OPCODE_EV5
|AXP_OPCODE_BWX
},
540 { "21164pc", (AXP_OPCODE_BASE
|AXP_OPCODE_EV5
|AXP_OPCODE_BWX
542 { "21264", (AXP_OPCODE_BASE
|AXP_OPCODE_EV6
|AXP_OPCODE_BWX
543 |AXP_OPCODE_MAX
|AXP_OPCODE_CIX
) },
544 { "21264a", (AXP_OPCODE_BASE
|AXP_OPCODE_EV6
|AXP_OPCODE_BWX
545 |AXP_OPCODE_MAX
|AXP_OPCODE_CIX
) },
546 { "21264b", (AXP_OPCODE_BASE
|AXP_OPCODE_EV6
|AXP_OPCODE_BWX
547 |AXP_OPCODE_MAX
|AXP_OPCODE_CIX
) },
549 { "ev4", AXP_OPCODE_BASE
},
550 { "ev45", AXP_OPCODE_BASE
},
551 { "lca45", AXP_OPCODE_BASE
},
552 { "ev5", AXP_OPCODE_BASE
},
553 { "ev56", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
},
554 { "pca56", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
|AXP_OPCODE_MAX
},
555 { "ev6", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
|AXP_OPCODE_MAX
|AXP_OPCODE_CIX
},
556 { "ev67", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
|AXP_OPCODE_MAX
|AXP_OPCODE_CIX
},
557 { "ev68", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
|AXP_OPCODE_MAX
|AXP_OPCODE_CIX
},
559 { "all", AXP_OPCODE_BASE
},
563 /* Some instruction sets indexed by lg(size). */
564 static const char * const sextX_op
[] = { "sextb", "sextw", "sextl", NULL
};
565 static const char * const insXl_op
[] = { "insbl", "inswl", "insll", "insql" };
566 static const char * const insXh_op
[] = { NULL
, "inswh", "inslh", "insqh" };
567 static const char * const extXl_op
[] = { "extbl", "extwl", "extll", "extql" };
568 static const char * const extXh_op
[] = { NULL
, "extwh", "extlh", "extqh" };
569 static const char * const mskXl_op
[] = { "mskbl", "mskwl", "mskll", "mskql" };
570 static const char * const mskXh_op
[] = { NULL
, "mskwh", "msklh", "mskqh" };
571 static const char * const stX_op
[] = { "stb", "stw", "stl", "stq" };
572 static const char * const ldXu_op
[] = { "ldbu", "ldwu", NULL
, NULL
};
574 static void assemble_insn (const struct alpha_opcode
*, const expressionS
*, int, struct alpha_insn
*, extended_bfd_reloc_code_real_type
);
575 static void emit_insn (struct alpha_insn
*);
576 static void assemble_tokens (const char *, const expressionS
*, int, int);
578 static char *s_alpha_section_name (void);
579 static symbolS
*add_to_link_pool (symbolS
*, symbolS
*, offsetT
);
582 static struct alpha_reloc_tag
*
583 get_alpha_reloc_tag (long sequence
)
585 char buffer
[ALPHA_RELOC_DIGITS
];
586 struct alpha_reloc_tag
*info
;
588 sprintf (buffer
, "!%ld", sequence
);
590 info
= (struct alpha_reloc_tag
*) hash_find (alpha_literal_hash
, buffer
);
593 size_t len
= strlen (buffer
);
596 info
= (struct alpha_reloc_tag
*)
597 xcalloc (sizeof (struct alpha_reloc_tag
) + len
, 1);
599 info
->segment
= now_seg
;
600 info
->sequence
= sequence
;
601 strcpy (info
->string
, buffer
);
602 errmsg
= hash_insert (alpha_literal_hash
, info
->string
, (void *) info
);
604 as_fatal ("%s", errmsg
);
617 alpha_adjust_relocs (bfd
*abfd ATTRIBUTE_UNUSED
,
619 void * ptr ATTRIBUTE_UNUSED
)
621 segment_info_type
*seginfo
= seg_info (sec
);
627 /* If seginfo is NULL, we did not create this section; don't do
628 anything with it. By using a pointer to a pointer, we can update
629 the links in place. */
633 /* If there are no relocations, skip the section. */
634 if (! seginfo
->fix_root
)
637 /* First rebuild the fixup chain without the explicit lituse and
638 gpdisp_lo16 relocs. */
639 prevP
= &seginfo
->fix_root
;
640 for (fixp
= seginfo
->fix_root
; fixp
; fixp
= next
)
642 next
= fixp
->fx_next
;
643 fixp
->fx_next
= (fixS
*) 0;
645 switch (fixp
->fx_r_type
)
647 case BFD_RELOC_ALPHA_LITUSE
:
648 if (fixp
->tc_fix_data
.info
->n_master
== 0)
649 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
650 _("No !literal!%ld was found"),
651 fixp
->tc_fix_data
.info
->sequence
);
653 if (fixp
->fx_offset
== LITUSE_ALPHA_TLSGD
)
655 if (! fixp
->tc_fix_data
.info
->saw_tlsgd
)
656 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
657 _("No !tlsgd!%ld was found"),
658 fixp
->tc_fix_data
.info
->sequence
);
660 else if (fixp
->fx_offset
== LITUSE_ALPHA_TLSLDM
)
662 if (! fixp
->tc_fix_data
.info
->saw_tlsldm
)
663 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
664 _("No !tlsldm!%ld was found"),
665 fixp
->tc_fix_data
.info
->sequence
);
670 case BFD_RELOC_ALPHA_GPDISP_LO16
:
671 if (fixp
->tc_fix_data
.info
->n_master
== 0)
672 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
673 _("No ldah !gpdisp!%ld was found"),
674 fixp
->tc_fix_data
.info
->sequence
);
677 case BFD_RELOC_ALPHA_ELF_LITERAL
:
678 if (fixp
->tc_fix_data
.info
679 && (fixp
->tc_fix_data
.info
->saw_tlsgd
680 || fixp
->tc_fix_data
.info
->saw_tlsldm
))
686 prevP
= &fixp
->fx_next
;
691 /* Go back and re-chain dependent relocations. They are currently
692 linked through the next_reloc field in reverse order, so as we
693 go through the next_reloc chain, we effectively reverse the chain
696 Except if there is more than one !literal for a given sequence
697 number. In that case, the programmer and/or compiler is not sure
698 how control flows from literal to lituse, and we can't be sure to
699 get the relaxation correct.
701 ??? Well, actually we could, if there are enough lituses such that
702 we can make each literal have at least one of each lituse type
703 present. Not implemented.
705 Also suppress the optimization if the !literals/!lituses are spread
706 in different segments. This can happen with "intersting" uses of
707 inline assembly; examples are present in the Linux kernel semaphores. */
709 for (fixp
= seginfo
->fix_root
; fixp
; fixp
= next
)
711 next
= fixp
->fx_next
;
712 switch (fixp
->fx_r_type
)
714 case BFD_RELOC_ALPHA_TLSGD
:
715 case BFD_RELOC_ALPHA_TLSLDM
:
716 if (!fixp
->tc_fix_data
.info
)
718 if (fixp
->tc_fix_data
.info
->n_master
== 0)
720 else if (fixp
->tc_fix_data
.info
->n_master
> 1)
722 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
723 _("too many !literal!%ld for %s"),
724 fixp
->tc_fix_data
.info
->sequence
,
725 (fixp
->fx_r_type
== BFD_RELOC_ALPHA_TLSGD
726 ? "!tlsgd" : "!tlsldm"));
730 fixp
->tc_fix_data
.info
->master
->fx_next
= fixp
->fx_next
;
731 fixp
->fx_next
= fixp
->tc_fix_data
.info
->master
;
732 fixp
= fixp
->fx_next
;
735 case BFD_RELOC_ALPHA_ELF_LITERAL
:
736 if (fixp
->tc_fix_data
.info
737 && fixp
->tc_fix_data
.info
->n_master
== 1
738 && ! fixp
->tc_fix_data
.info
->multi_section_p
)
740 for (slave
= fixp
->tc_fix_data
.info
->slaves
;
742 slave
= slave
->tc_fix_data
.next_reloc
)
744 slave
->fx_next
= fixp
->fx_next
;
745 fixp
->fx_next
= slave
;
750 case BFD_RELOC_ALPHA_GPDISP_HI16
:
751 if (fixp
->tc_fix_data
.info
->n_slaves
== 0)
752 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
753 _("No lda !gpdisp!%ld was found"),
754 fixp
->tc_fix_data
.info
->sequence
);
757 slave
= fixp
->tc_fix_data
.info
->slaves
;
758 slave
->fx_next
= next
;
759 fixp
->fx_next
= slave
;
769 /* Before the relocations are written, reorder them, so that user
770 supplied !lituse relocations follow the appropriate !literal
771 relocations, and similarly for !gpdisp relocations. */
774 alpha_before_fix (void)
776 if (alpha_literal_hash
)
777 bfd_map_over_sections (stdoutput
, alpha_adjust_relocs
, NULL
);
784 debug_exp (expressionS tok
[], int ntok
)
788 fprintf (stderr
, "debug_exp: %d tokens", ntok
);
789 for (i
= 0; i
< ntok
; i
++)
791 expressionS
*t
= &tok
[i
];
796 default: name
= "unknown"; break;
797 case O_illegal
: name
= "O_illegal"; break;
798 case O_absent
: name
= "O_absent"; break;
799 case O_constant
: name
= "O_constant"; break;
800 case O_symbol
: name
= "O_symbol"; break;
801 case O_symbol_rva
: name
= "O_symbol_rva"; break;
802 case O_register
: name
= "O_register"; break;
803 case O_big
: name
= "O_big"; break;
804 case O_uminus
: name
= "O_uminus"; break;
805 case O_bit_not
: name
= "O_bit_not"; break;
806 case O_logical_not
: name
= "O_logical_not"; break;
807 case O_multiply
: name
= "O_multiply"; break;
808 case O_divide
: name
= "O_divide"; break;
809 case O_modulus
: name
= "O_modulus"; break;
810 case O_left_shift
: name
= "O_left_shift"; break;
811 case O_right_shift
: name
= "O_right_shift"; break;
812 case O_bit_inclusive_or
: name
= "O_bit_inclusive_or"; break;
813 case O_bit_or_not
: name
= "O_bit_or_not"; break;
814 case O_bit_exclusive_or
: name
= "O_bit_exclusive_or"; break;
815 case O_bit_and
: name
= "O_bit_and"; break;
816 case O_add
: name
= "O_add"; break;
817 case O_subtract
: name
= "O_subtract"; break;
818 case O_eq
: name
= "O_eq"; break;
819 case O_ne
: name
= "O_ne"; break;
820 case O_lt
: name
= "O_lt"; break;
821 case O_le
: name
= "O_le"; break;
822 case O_ge
: name
= "O_ge"; break;
823 case O_gt
: name
= "O_gt"; break;
824 case O_logical_and
: name
= "O_logical_and"; break;
825 case O_logical_or
: name
= "O_logical_or"; break;
826 case O_index
: name
= "O_index"; break;
827 case O_pregister
: name
= "O_pregister"; break;
828 case O_cpregister
: name
= "O_cpregister"; break;
829 case O_literal
: name
= "O_literal"; break;
830 case O_lituse_addr
: name
= "O_lituse_addr"; break;
831 case O_lituse_base
: name
= "O_lituse_base"; break;
832 case O_lituse_bytoff
: name
= "O_lituse_bytoff"; break;
833 case O_lituse_jsr
: name
= "O_lituse_jsr"; break;
834 case O_lituse_tlsgd
: name
= "O_lituse_tlsgd"; break;
835 case O_lituse_tlsldm
: name
= "O_lituse_tlsldm"; break;
836 case O_lituse_jsrdirect
: name
= "O_lituse_jsrdirect"; break;
837 case O_gpdisp
: name
= "O_gpdisp"; break;
838 case O_gprelhigh
: name
= "O_gprelhigh"; break;
839 case O_gprellow
: name
= "O_gprellow"; break;
840 case O_gprel
: name
= "O_gprel"; break;
841 case O_samegp
: name
= "O_samegp"; break;
842 case O_tlsgd
: name
= "O_tlsgd"; break;
843 case O_tlsldm
: name
= "O_tlsldm"; break;
844 case O_gotdtprel
: name
= "O_gotdtprel"; break;
845 case O_dtprelhi
: name
= "O_dtprelhi"; break;
846 case O_dtprello
: name
= "O_dtprello"; break;
847 case O_dtprel
: name
= "O_dtprel"; break;
848 case O_gottprel
: name
= "O_gottprel"; break;
849 case O_tprelhi
: name
= "O_tprelhi"; break;
850 case O_tprello
: name
= "O_tprello"; break;
851 case O_tprel
: name
= "O_tprel"; break;
854 fprintf (stderr
, ", %s(%s, %s, %d)", name
,
855 (t
->X_add_symbol
) ? S_GET_NAME (t
->X_add_symbol
) : "--",
856 (t
->X_op_symbol
) ? S_GET_NAME (t
->X_op_symbol
) : "--",
857 (int) t
->X_add_number
);
859 fprintf (stderr
, "\n");
864 /* Parse the arguments to an opcode. */
867 tokenize_arguments (char *str
,
871 expressionS
*end_tok
= tok
+ ntok
;
872 char *old_input_line_pointer
;
873 int saw_comma
= 0, saw_arg
= 0;
875 expressionS
*orig_tok
= tok
;
879 const struct alpha_reloc_op_tag
*r
;
882 int reloc_found_p
= 0;
885 memset (tok
, 0, sizeof (*tok
) * ntok
);
887 /* Save and restore input_line_pointer around this function. */
888 old_input_line_pointer
= input_line_pointer
;
889 input_line_pointer
= str
;
892 /* ??? Wrest control of ! away from the regular expression parser. */
893 is_end_of_line
[(unsigned char) '!'] = 1;
896 while (tok
< end_tok
&& *input_line_pointer
)
899 switch (*input_line_pointer
)
906 /* A relocation operand can be placed after the normal operand on an
907 assembly language statement, and has the following form:
908 !relocation_type!sequence_number. */
911 /* Only support one relocation op per insn. */
912 as_bad (_("More than one relocation op per insn"));
919 ++input_line_pointer
;
921 p
= input_line_pointer
;
922 c
= get_symbol_end ();
924 /* Parse !relocation_type. */
925 len
= input_line_pointer
- p
;
928 as_bad (_("No relocation operand"));
932 r
= &alpha_reloc_op
[0];
933 for (i
= alpha_num_reloc_op
- 1; i
>= 0; i
--, r
++)
934 if (len
== r
->length
&& memcmp (p
, r
->name
, len
) == 0)
938 as_bad (_("Unknown relocation operand: !%s"), p
);
942 *input_line_pointer
= c
;
944 if (*input_line_pointer
!= '!')
948 as_bad (_("no sequence number after !%s"), p
);
952 tok
->X_add_number
= 0;
958 as_bad (_("!%s does not use a sequence number"), p
);
962 input_line_pointer
++;
964 /* Parse !sequence_number. */
966 if (tok
->X_op
!= O_constant
|| tok
->X_add_number
<= 0)
968 as_bad (_("Bad sequence number: !%s!%s"),
969 r
->name
, input_line_pointer
);
978 #endif /* RELOC_OP_P */
981 ++input_line_pointer
;
982 if (saw_comma
|| !saw_arg
)
989 char *hold
= input_line_pointer
++;
991 /* First try for parenthesized register ... */
993 if (*input_line_pointer
== ')' && tok
->X_op
== O_register
)
995 tok
->X_op
= (saw_comma
? O_cpregister
: O_pregister
);
998 ++input_line_pointer
;
1003 /* ... then fall through to plain expression. */
1004 input_line_pointer
= hold
;
1008 if (saw_arg
&& !saw_comma
)
1012 if (tok
->X_op
== O_illegal
|| tok
->X_op
== O_absent
)
1025 input_line_pointer
= old_input_line_pointer
;
1028 debug_exp (orig_tok
, ntok
- (end_tok
- tok
));
1031 is_end_of_line
[(unsigned char) '!'] = 0;
1034 return ntok
- (end_tok
- tok
);
1038 is_end_of_line
[(unsigned char) '!'] = 0;
1040 input_line_pointer
= old_input_line_pointer
;
1041 return TOKENIZE_ERROR
;
1045 is_end_of_line
[(unsigned char) '!'] = 0;
1047 input_line_pointer
= old_input_line_pointer
;
1048 return TOKENIZE_ERROR_REPORT
;
1051 /* Search forward through all variants of an opcode looking for a
1054 static const struct alpha_opcode
*
1055 find_opcode_match (const struct alpha_opcode
*first_opcode
,
1056 const expressionS
*tok
,
1060 const struct alpha_opcode
*opcode
= first_opcode
;
1062 int got_cpu_match
= 0;
1066 const unsigned char *opidx
;
1069 /* Don't match opcodes that don't exist on this architecture. */
1070 if (!(opcode
->flags
& alpha_target
))
1075 for (opidx
= opcode
->operands
; *opidx
; ++opidx
)
1077 const struct alpha_operand
*operand
= &alpha_operands
[*opidx
];
1079 /* Only take input from real operands. */
1080 if (operand
->flags
& AXP_OPERAND_FAKE
)
1083 /* When we expect input, make sure we have it. */
1086 if ((operand
->flags
& AXP_OPERAND_OPTIONAL_MASK
) == 0)
1091 /* Match operand type with expression type. */
1092 switch (operand
->flags
& AXP_OPERAND_TYPECHECK_MASK
)
1094 case AXP_OPERAND_IR
:
1095 if (tok
[tokidx
].X_op
!= O_register
1096 || !is_ir_num (tok
[tokidx
].X_add_number
))
1099 case AXP_OPERAND_FPR
:
1100 if (tok
[tokidx
].X_op
!= O_register
1101 || !is_fpr_num (tok
[tokidx
].X_add_number
))
1104 case AXP_OPERAND_IR
| AXP_OPERAND_PARENS
:
1105 if (tok
[tokidx
].X_op
!= O_pregister
1106 || !is_ir_num (tok
[tokidx
].X_add_number
))
1109 case AXP_OPERAND_IR
| AXP_OPERAND_PARENS
| AXP_OPERAND_COMMA
:
1110 if (tok
[tokidx
].X_op
!= O_cpregister
1111 || !is_ir_num (tok
[tokidx
].X_add_number
))
1115 case AXP_OPERAND_RELATIVE
:
1116 case AXP_OPERAND_SIGNED
:
1117 case AXP_OPERAND_UNSIGNED
:
1118 switch (tok
[tokidx
].X_op
)
1133 /* Everything else should have been fake. */
1139 /* Possible match -- did we use all of our input? */
1148 while (++opcode
- alpha_opcodes
< (int) alpha_num_opcodes
1149 && !strcmp (opcode
->name
, first_opcode
->name
));
1152 *pcpumatch
= got_cpu_match
;
1157 /* Given an opcode name and a pre-tokenized set of arguments, assemble
1158 the insn, but do not emit it.
1160 Note that this implies no macros allowed, since we can't store more
1161 than one insn in an insn structure. */
1164 assemble_tokens_to_insn (const char *opname
,
1165 const expressionS
*tok
,
1167 struct alpha_insn
*insn
)
1169 const struct alpha_opcode
*opcode
;
1171 /* Search opcodes. */
1172 opcode
= (const struct alpha_opcode
*) hash_find (alpha_opcode_hash
, opname
);
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 (stdoutput
, new_sec
, 4);
1207 bfd_set_section_flags (stdoutput
, new_sec
,
1208 SEC_RELOC
| SEC_ALLOC
| SEC_LOAD
| SEC_READONLY
1211 S_CLEAR_EXTERNAL (*symp
= section_symbol (new_sec
));
1214 /* Load a (partial) expression into a target register.
1216 If poffset is not null, after the call it will either contain
1217 O_constant 0, or a 16-bit offset appropriate for any MEM format
1218 instruction. In addition, pbasereg will be modified to point to
1219 the base register to use in that MEM format instruction.
1221 In any case, *pbasereg should contain a base register to add to the
1222 expression. This will normally be either AXP_REG_ZERO or
1223 alpha_gp_register. Symbol addresses will always be loaded via $gp,
1224 so "foo($0)" is interpreted as adding the address of foo to $0;
1225 i.e. "ldq $targ, LIT($gp); addq $targ, $0, $targ". Odd, perhaps,
1226 but this is what OSF/1 does.
1228 If explicit relocations of the form !literal!<number> are allowed,
1229 and used, then explicit_reloc with be an expression pointer.
1231 Finally, the return value is nonzero if the calling macro may emit
1232 a LITUSE reloc if otherwise appropriate; the return value is the
1233 sequence number to use. */
1236 load_expression (int targreg
,
1237 const expressionS
*exp
,
1239 expressionS
*poffset
,
1242 long emit_lituse
= 0;
1243 offsetT addend
= exp
->X_add_number
;
1244 int basereg
= *pbasereg
;
1245 struct alpha_insn insn
;
1246 expressionS newtok
[3];
1255 /* Attempt to reduce .lit load by splitting the offset from
1256 its symbol when possible, but don't create a situation in
1258 if (!range_signed_32 (addend
) &&
1259 (alpha_noat_on
|| targreg
== AXP_REG_AT
))
1261 lit
= add_to_literal_pool (exp
->X_add_symbol
, addend
,
1262 alpha_lita_section
, 8);
1266 lit
= add_to_literal_pool (exp
->X_add_symbol
, 0,
1267 alpha_lita_section
, 8);
1270 as_fatal (_("overflow in literal (.lita) table"));
1272 /* Emit "ldq r, lit(gp)". */
1274 if (basereg
!= alpha_gp_register
&& targreg
== basereg
)
1277 as_bad (_("macro requires $at register while noat in effect"));
1278 if (targreg
== AXP_REG_AT
)
1279 as_bad (_("macro requires $at while $at in use"));
1281 set_tok_reg (newtok
[0], AXP_REG_AT
);
1284 set_tok_reg (newtok
[0], targreg
);
1286 set_tok_sym (newtok
[1], alpha_lita_symbol
, lit
);
1287 set_tok_preg (newtok
[2], alpha_gp_register
);
1289 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
1291 gas_assert (insn
.nfixups
== 1);
1292 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITERAL
;
1293 insn
.sequence
= emit_lituse
= next_sequence_num
--;
1294 #endif /* OBJ_ECOFF */
1296 /* Emit "ldq r, gotoff(gp)". */
1298 if (basereg
!= alpha_gp_register
&& targreg
== basereg
)
1301 as_bad (_("macro requires $at register while noat in effect"));
1302 if (targreg
== AXP_REG_AT
)
1303 as_bad (_("macro requires $at while $at in use"));
1305 set_tok_reg (newtok
[0], AXP_REG_AT
);
1308 set_tok_reg (newtok
[0], targreg
);
1310 /* XXX: Disable this .got minimizing optimization so that we can get
1311 better instruction offset knowledge in the compiler. This happens
1312 very infrequently anyway. */
1314 || (!range_signed_32 (addend
)
1315 && (alpha_noat_on
|| targreg
== AXP_REG_AT
)))
1321 set_tok_sym (newtok
[1], exp
->X_add_symbol
, 0);
1323 set_tok_preg (newtok
[2], alpha_gp_register
);
1325 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
1327 gas_assert (insn
.nfixups
== 1);
1328 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_ELF_LITERAL
;
1329 insn
.sequence
= emit_lituse
= next_sequence_num
--;
1330 #endif /* OBJ_ELF */
1332 /* Find symbol or symbol pointer in link section. */
1334 if (exp
->X_add_symbol
== alpha_evax_proc
->symbol
)
1336 if (range_signed_16 (addend
))
1338 set_tok_reg (newtok
[0], targreg
);
1339 set_tok_const (newtok
[1], addend
);
1340 set_tok_preg (newtok
[2], basereg
);
1341 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
1346 set_tok_reg (newtok
[0], targreg
);
1347 set_tok_const (newtok
[1], 0);
1348 set_tok_preg (newtok
[2], basereg
);
1349 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
1354 const char *symname
= S_GET_NAME (exp
->X_add_symbol
);
1355 const char *ptr1
, *ptr2
;
1356 int symlen
= strlen (symname
);
1359 strcmp (ptr2
= &symname
[symlen
- 4], "..lk") == 0))
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)
1378 volatile asymbol
*dummy
;
1380 ptr1
= strstr (symname
, "..") + 2;
1383 ensymname
= (char *) xmalloc (ptr2
- ptr1
+ 5);
1384 memcpy (ensymname
, ptr1
, ptr2
- ptr1
);
1385 memcpy (ensymname
+ (ptr2
- ptr1
), "..en", 5);
1387 gas_assert (insn
.nfixups
+ 1 <= MAX_INSN_FIXUPS
);
1388 insn
.fixups
[insn
.nfixups
].reloc
= BFD_RELOC_ALPHA_NOP
;
1389 ensym
= symbol_find_or_make (ensymname
);
1391 /* The fixup must be the same as the BFD_RELOC_ALPHA_BOH
1392 case in emit_jsrjmp. See B.4.5.2 of the OpenVMS Linker
1394 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_symbol
;
1395 insn
.fixups
[insn
.nfixups
].exp
.X_add_symbol
= ensym
;
1396 insn
.fixups
[insn
.nfixups
].exp
.X_add_number
= 0;
1397 insn
.fixups
[insn
.nfixups
].xtrasym
= alpha_linkage_symbol
;
1398 insn
.fixups
[insn
.nfixups
].procsym
= alpha_evax_proc
->symbol
;
1401 /* ??? Force bsym to be instantiated now, as it will be
1402 too late to do so in tc_gen_reloc. */
1403 dummy
= symbol_get_bfdsym (exp
->X_add_symbol
);
1405 else if (alpha_flag_replace
&& targreg
== 27)
1410 ptr1
= strstr (symname
, "..") + 2;
1413 psymname
= (char *) xmalloc (ptr2
- ptr1
+ 1);
1414 memcpy (psymname
, ptr1
, ptr2
- ptr1
);
1415 psymname
[ptr2
- ptr1
] = 0;
1416 gas_assert (insn
.nfixups
+ 1 <= MAX_INSN_FIXUPS
);
1417 insn
.fixups
[insn
.nfixups
].reloc
= BFD_RELOC_ALPHA_LDA
;
1418 psym
= symbol_find_or_make (psymname
);
1420 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_subtract
;
1421 insn
.fixups
[insn
.nfixups
].exp
.X_add_symbol
= psym
;
1422 insn
.fixups
[insn
.nfixups
].exp
.X_op_symbol
= alpha_evax_proc
->symbol
;
1423 insn
.fixups
[insn
.nfixups
].exp
.X_add_number
= 0;
1424 insn
.fixups
[insn
.nfixups
].xtrasym
= alpha_linkage_symbol
;
1425 insn
.fixups
[insn
.nfixups
].procsym
= alpha_evax_proc
->symbol
;
1436 if (!range_signed_32 (addend
))
1437 addend
= sign_extend_32 (addend
);
1438 linkexp
= add_to_link_pool (alpha_evax_proc
->symbol
,
1439 exp
->X_add_symbol
, 0);
1440 set_tok_reg (newtok
[0], targreg
);
1441 set_tok_sym (newtok
[1], linkexp
, 0);
1442 set_tok_preg (newtok
[2], basereg
);
1443 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
1446 #endif /* OBJ_EVAX */
1451 if (basereg
!= alpha_gp_register
&& basereg
!= AXP_REG_ZERO
)
1453 /* Emit "addq r, base, r". */
1455 set_tok_reg (newtok
[1], basereg
);
1456 set_tok_reg (newtok
[2], targreg
);
1457 assemble_tokens ("addq", newtok
, 3, 0);
1468 /* Assume that this difference expression will be resolved to an
1469 absolute value and that that value will fit in 16 bits. */
1471 set_tok_reg (newtok
[0], targreg
);
1473 set_tok_preg (newtok
[2], basereg
);
1474 assemble_tokens (opname
, newtok
, 3, 0);
1477 set_tok_const (*poffset
, 0);
1481 if (exp
->X_add_number
> 0)
1482 as_bad (_("bignum invalid; zero assumed"));
1484 as_bad (_("floating point number invalid; zero assumed"));
1489 as_bad (_("can't handle expression"));
1494 if (!range_signed_32 (addend
))
1500 long seq_num
= next_sequence_num
--;
1503 /* For 64-bit addends, just put it in the literal pool. */
1505 /* Emit "ldq targreg, lit(basereg)". */
1506 litexp
= add_to_link_pool (alpha_evax_proc
->symbol
,
1507 section_symbol (absolute_section
), addend
);
1508 set_tok_reg (newtok
[0], targreg
);
1509 set_tok_sym (newtok
[1], litexp
, 0);
1510 set_tok_preg (newtok
[2], alpha_gp_register
);
1511 assemble_tokens ("ldq", newtok
, 3, 0);
1514 if (alpha_lit8_section
== NULL
)
1516 create_literal_section (".lit8",
1517 &alpha_lit8_section
,
1518 &alpha_lit8_symbol
);
1521 alpha_lit8_literal
= add_to_literal_pool (alpha_lit8_symbol
, 0x8000,
1522 alpha_lita_section
, 8);
1523 if (alpha_lit8_literal
>= 0x8000)
1524 as_fatal (_("overflow in literal (.lita) table"));
1528 lit
= add_to_literal_pool (NULL
, addend
, alpha_lit8_section
, 8) - 0x8000;
1530 as_fatal (_("overflow in literal (.lit8) table"));
1532 /* Emit "lda litreg, .lit8+0x8000". */
1534 if (targreg
== basereg
)
1537 as_bad (_("macro requires $at register while noat in effect"));
1538 if (targreg
== AXP_REG_AT
)
1539 as_bad (_("macro requires $at while $at in use"));
1541 set_tok_reg (newtok
[0], AXP_REG_AT
);
1544 set_tok_reg (newtok
[0], targreg
);
1546 set_tok_sym (newtok
[1], alpha_lita_symbol
, alpha_lit8_literal
);
1549 set_tok_sym (newtok
[1], alpha_lit8_symbol
, 0x8000);
1551 set_tok_preg (newtok
[2], alpha_gp_register
);
1553 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
1555 gas_assert (insn
.nfixups
== 1);
1557 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITERAL
;
1560 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_ELF_LITERAL
;
1562 insn
.sequence
= seq_num
;
1566 /* Emit "ldq litreg, lit(litreg)". */
1568 set_tok_const (newtok
[1], lit
);
1569 set_tok_preg (newtok
[2], newtok
[0].X_add_number
);
1571 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
1573 gas_assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
1574 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BASE
;
1575 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
1577 insn
.sequence
= seq_num
;
1582 /* Emit "addq litreg, base, target". */
1584 if (basereg
!= AXP_REG_ZERO
)
1586 set_tok_reg (newtok
[1], basereg
);
1587 set_tok_reg (newtok
[2], targreg
);
1588 assemble_tokens ("addq", newtok
, 3, 0);
1590 #endif /* !OBJ_EVAX */
1593 set_tok_const (*poffset
, 0);
1594 *pbasereg
= targreg
;
1598 offsetT low
, high
, extra
, tmp
;
1600 /* For 32-bit operands, break up the addend. */
1602 low
= sign_extend_16 (addend
);
1604 high
= sign_extend_16 (tmp
>> 16);
1606 if (tmp
- (high
<< 16))
1610 high
= sign_extend_16 (tmp
>> 16);
1615 set_tok_reg (newtok
[0], targreg
);
1616 set_tok_preg (newtok
[2], basereg
);
1620 /* Emit "ldah r, extra(r). */
1621 set_tok_const (newtok
[1], extra
);
1622 assemble_tokens ("ldah", newtok
, 3, 0);
1623 set_tok_preg (newtok
[2], basereg
= targreg
);
1628 /* Emit "ldah r, high(r). */
1629 set_tok_const (newtok
[1], high
);
1630 assemble_tokens ("ldah", newtok
, 3, 0);
1632 set_tok_preg (newtok
[2], basereg
);
1635 if ((low
&& !poffset
) || (!poffset
&& basereg
!= targreg
))
1637 /* Emit "lda r, low(base)". */
1638 set_tok_const (newtok
[1], low
);
1639 assemble_tokens ("lda", newtok
, 3, 0);
1645 set_tok_const (*poffset
, low
);
1646 *pbasereg
= basereg
;
1652 /* The lda macro differs from the lda instruction in that it handles
1653 most simple expressions, particularly symbol address loads and
1657 emit_lda (const expressionS
*tok
,
1659 const void * unused ATTRIBUTE_UNUSED
)
1664 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
1666 basereg
= tok
[2].X_add_number
;
1668 (void) load_expression (tok
[0].X_add_number
, &tok
[1], &basereg
, NULL
, "lda");
1671 /* The ldah macro differs from the ldah instruction in that it has $31
1672 as an implied base register. */
1675 emit_ldah (const expressionS
*tok
,
1676 int ntok ATTRIBUTE_UNUSED
,
1677 const void * unused ATTRIBUTE_UNUSED
)
1679 expressionS newtok
[3];
1683 set_tok_preg (newtok
[2], AXP_REG_ZERO
);
1685 assemble_tokens ("ldah", newtok
, 3, 0);
1688 /* Called internally to handle all alignment needs. This takes care
1689 of eliding calls to frag_align if'n the cached current alignment
1690 says we've already got it, as well as taking care of the auto-align
1691 feature wrt labels. */
1697 int force ATTRIBUTE_UNUSED
)
1699 if (alpha_current_align
>= n
)
1704 if (subseg_text_p (now_seg
))
1705 frag_align_code (n
, 0);
1707 frag_align (n
, 0, 0);
1710 frag_align (n
, *pfill
, 0);
1712 alpha_current_align
= n
;
1714 if (label
!= NULL
&& S_GET_SEGMENT (label
) == now_seg
)
1716 symbol_set_frag (label
, frag_now
);
1717 S_SET_VALUE (label
, (valueT
) frag_now_fix ());
1720 record_alignment (now_seg
, n
);
1722 /* ??? If alpha_flag_relax && force && elf, record the requested alignment
1723 in a reloc for the linker to see. */
1726 /* Actually output an instruction with its fixup. */
1729 emit_insn (struct alpha_insn
*insn
)
1734 /* Take care of alignment duties. */
1735 if (alpha_auto_align_on
&& alpha_current_align
< 2)
1736 alpha_align (2, (char *) NULL
, alpha_insn_label
, 0);
1737 if (alpha_current_align
> 2)
1738 alpha_current_align
= 2;
1739 alpha_insn_label
= NULL
;
1741 /* Write out the instruction. */
1743 md_number_to_chars (f
, insn
->insn
, 4);
1746 dwarf2_emit_insn (4);
1749 /* Apply the fixups in order. */
1750 for (i
= 0; i
< insn
->nfixups
; ++i
)
1752 const struct alpha_operand
*operand
= (const struct alpha_operand
*) 0;
1753 struct alpha_fixup
*fixup
= &insn
->fixups
[i
];
1754 struct alpha_reloc_tag
*info
= NULL
;
1758 /* Some fixups are only used internally and so have no howto. */
1759 if ((int) fixup
->reloc
< 0)
1761 operand
= &alpha_operands
[-(int) fixup
->reloc
];
1763 pcrel
= ((operand
->flags
& AXP_OPERAND_RELATIVE
) != 0);
1765 else if (fixup
->reloc
> BFD_RELOC_UNUSED
1766 || fixup
->reloc
== BFD_RELOC_ALPHA_GPDISP_HI16
1767 || fixup
->reloc
== BFD_RELOC_ALPHA_GPDISP_LO16
)
1774 reloc_howto_type
*reloc_howto
=
1775 bfd_reloc_type_lookup (stdoutput
,
1776 (bfd_reloc_code_real_type
) fixup
->reloc
);
1777 gas_assert (reloc_howto
);
1779 size
= bfd_get_reloc_size (reloc_howto
);
1781 switch (fixup
->reloc
)
1784 case BFD_RELOC_ALPHA_NOP
:
1785 case BFD_RELOC_ALPHA_BSR
:
1786 case BFD_RELOC_ALPHA_LDA
:
1787 case BFD_RELOC_ALPHA_BOH
:
1791 gas_assert (size
>= 1 && size
<= 4);
1794 pcrel
= reloc_howto
->pc_relative
;
1797 fixP
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, size
,
1798 &fixup
->exp
, pcrel
, (bfd_reloc_code_real_type
) fixup
->reloc
);
1800 /* Turn off complaints that the addend is too large for some fixups,
1801 and copy in the sequence number for the explicit relocations. */
1802 switch (fixup
->reloc
)
1804 case BFD_RELOC_ALPHA_HINT
:
1805 case BFD_RELOC_GPREL32
:
1806 case BFD_RELOC_GPREL16
:
1807 case BFD_RELOC_ALPHA_GPREL_HI16
:
1808 case BFD_RELOC_ALPHA_GPREL_LO16
:
1809 case BFD_RELOC_ALPHA_GOTDTPREL16
:
1810 case BFD_RELOC_ALPHA_DTPREL_HI16
:
1811 case BFD_RELOC_ALPHA_DTPREL_LO16
:
1812 case BFD_RELOC_ALPHA_DTPREL16
:
1813 case BFD_RELOC_ALPHA_GOTTPREL16
:
1814 case BFD_RELOC_ALPHA_TPREL_HI16
:
1815 case BFD_RELOC_ALPHA_TPREL_LO16
:
1816 case BFD_RELOC_ALPHA_TPREL16
:
1817 fixP
->fx_no_overflow
= 1;
1820 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1821 fixP
->fx_no_overflow
= 1;
1822 fixP
->fx_addsy
= section_symbol (now_seg
);
1823 fixP
->fx_offset
= 0;
1825 info
= get_alpha_reloc_tag (insn
->sequence
);
1826 if (++info
->n_master
> 1)
1827 as_bad (_("too many ldah insns for !gpdisp!%ld"), insn
->sequence
);
1828 if (info
->segment
!= now_seg
)
1829 as_bad (_("both insns for !gpdisp!%ld must be in the same section"),
1831 fixP
->tc_fix_data
.info
= info
;
1834 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1835 fixP
->fx_no_overflow
= 1;
1837 info
= get_alpha_reloc_tag (insn
->sequence
);
1838 if (++info
->n_slaves
> 1)
1839 as_bad (_("too many lda insns for !gpdisp!%ld"), insn
->sequence
);
1840 if (info
->segment
!= now_seg
)
1841 as_bad (_("both insns for !gpdisp!%ld must be in the same section"),
1843 fixP
->tc_fix_data
.info
= info
;
1844 info
->slaves
= fixP
;
1847 case BFD_RELOC_ALPHA_LITERAL
:
1848 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1849 fixP
->fx_no_overflow
= 1;
1851 if (insn
->sequence
== 0)
1853 info
= get_alpha_reloc_tag (insn
->sequence
);
1854 info
->master
= fixP
;
1856 if (info
->segment
!= now_seg
)
1857 info
->multi_section_p
= 1;
1858 fixP
->tc_fix_data
.info
= info
;
1862 case DUMMY_RELOC_LITUSE_ADDR
:
1863 fixP
->fx_offset
= LITUSE_ALPHA_ADDR
;
1865 case DUMMY_RELOC_LITUSE_BASE
:
1866 fixP
->fx_offset
= LITUSE_ALPHA_BASE
;
1868 case DUMMY_RELOC_LITUSE_BYTOFF
:
1869 fixP
->fx_offset
= LITUSE_ALPHA_BYTOFF
;
1871 case DUMMY_RELOC_LITUSE_JSR
:
1872 fixP
->fx_offset
= LITUSE_ALPHA_JSR
;
1874 case DUMMY_RELOC_LITUSE_TLSGD
:
1875 fixP
->fx_offset
= LITUSE_ALPHA_TLSGD
;
1877 case DUMMY_RELOC_LITUSE_TLSLDM
:
1878 fixP
->fx_offset
= LITUSE_ALPHA_TLSLDM
;
1880 case DUMMY_RELOC_LITUSE_JSRDIRECT
:
1881 fixP
->fx_offset
= LITUSE_ALPHA_JSRDIRECT
;
1884 fixP
->fx_addsy
= section_symbol (now_seg
);
1885 fixP
->fx_r_type
= BFD_RELOC_ALPHA_LITUSE
;
1887 info
= get_alpha_reloc_tag (insn
->sequence
);
1888 if (fixup
->reloc
== DUMMY_RELOC_LITUSE_TLSGD
)
1889 info
->saw_lu_tlsgd
= 1;
1890 else if (fixup
->reloc
== DUMMY_RELOC_LITUSE_TLSLDM
)
1891 info
->saw_lu_tlsldm
= 1;
1892 if (++info
->n_slaves
> 1)
1894 if (info
->saw_lu_tlsgd
)
1895 as_bad (_("too many lituse insns for !lituse_tlsgd!%ld"),
1897 else if (info
->saw_lu_tlsldm
)
1898 as_bad (_("too many lituse insns for !lituse_tlsldm!%ld"),
1901 fixP
->tc_fix_data
.info
= info
;
1902 fixP
->tc_fix_data
.next_reloc
= info
->slaves
;
1903 info
->slaves
= fixP
;
1904 if (info
->segment
!= now_seg
)
1905 info
->multi_section_p
= 1;
1908 case BFD_RELOC_ALPHA_TLSGD
:
1909 fixP
->fx_no_overflow
= 1;
1911 if (insn
->sequence
== 0)
1913 info
= get_alpha_reloc_tag (insn
->sequence
);
1914 if (info
->saw_tlsgd
)
1915 as_bad (_("duplicate !tlsgd!%ld"), insn
->sequence
);
1916 else if (info
->saw_tlsldm
)
1917 as_bad (_("sequence number in use for !tlsldm!%ld"),
1920 info
->saw_tlsgd
= 1;
1921 fixP
->tc_fix_data
.info
= info
;
1924 case BFD_RELOC_ALPHA_TLSLDM
:
1925 fixP
->fx_no_overflow
= 1;
1927 if (insn
->sequence
== 0)
1929 info
= get_alpha_reloc_tag (insn
->sequence
);
1930 if (info
->saw_tlsldm
)
1931 as_bad (_("duplicate !tlsldm!%ld"), insn
->sequence
);
1932 else if (info
->saw_tlsgd
)
1933 as_bad (_("sequence number in use for !tlsgd!%ld"),
1936 info
->saw_tlsldm
= 1;
1937 fixP
->tc_fix_data
.info
= info
;
1941 case BFD_RELOC_ALPHA_NOP
:
1942 case BFD_RELOC_ALPHA_LDA
:
1943 case BFD_RELOC_ALPHA_BSR
:
1944 case BFD_RELOC_ALPHA_BOH
:
1945 info
= get_alpha_reloc_tag (next_sequence_num
--);
1946 fixP
->tc_fix_data
.info
= info
;
1947 fixP
->tc_fix_data
.info
->sym
= fixup
->xtrasym
;
1948 fixP
->tc_fix_data
.info
->psym
= fixup
->procsym
;
1953 if ((int) fixup
->reloc
< 0)
1955 if (operand
->flags
& AXP_OPERAND_NOOVERFLOW
)
1956 fixP
->fx_no_overflow
= 1;
1963 /* Insert an operand value into an instruction. */
1966 insert_operand (unsigned insn
,
1967 const struct alpha_operand
*operand
,
1972 if (operand
->bits
!= 32 && !(operand
->flags
& AXP_OPERAND_NOOVERFLOW
))
1976 if (operand
->flags
& AXP_OPERAND_SIGNED
)
1978 max
= (1 << (operand
->bits
- 1)) - 1;
1979 min
= -(1 << (operand
->bits
- 1));
1983 max
= (1 << operand
->bits
) - 1;
1987 if (val
< min
|| val
> max
)
1988 as_warn_value_out_of_range (_("operand"), val
, min
, max
, file
, line
);
1991 if (operand
->insert
)
1993 const char *errmsg
= NULL
;
1995 insn
= (*operand
->insert
) (insn
, val
, &errmsg
);
1997 as_warn ("%s", errmsg
);
2000 insn
|= ((val
& ((1 << operand
->bits
) - 1)) << operand
->shift
);
2005 /* Turn an opcode description and a set of arguments into
2006 an instruction and a fixup. */
2009 assemble_insn (const struct alpha_opcode
*opcode
,
2010 const expressionS
*tok
,
2012 struct alpha_insn
*insn
,
2013 extended_bfd_reloc_code_real_type reloc
)
2015 const struct alpha_operand
*reloc_operand
= NULL
;
2016 const expressionS
*reloc_exp
= NULL
;
2017 const unsigned char *argidx
;
2021 memset (insn
, 0, sizeof (*insn
));
2022 image
= opcode
->opcode
;
2024 for (argidx
= opcode
->operands
; *argidx
; ++argidx
)
2026 const struct alpha_operand
*operand
= &alpha_operands
[*argidx
];
2027 const expressionS
*t
= (const expressionS
*) 0;
2029 if (operand
->flags
& AXP_OPERAND_FAKE
)
2031 /* Fake operands take no value and generate no fixup. */
2032 image
= insert_operand (image
, operand
, 0, NULL
, 0);
2038 switch (operand
->flags
& AXP_OPERAND_OPTIONAL_MASK
)
2040 case AXP_OPERAND_DEFAULT_FIRST
:
2043 case AXP_OPERAND_DEFAULT_SECOND
:
2046 case AXP_OPERAND_DEFAULT_ZERO
:
2048 static expressionS zero_exp
;
2050 zero_exp
.X_op
= O_constant
;
2051 zero_exp
.X_unsigned
= 1;
2066 image
= insert_operand (image
, operand
, regno (t
->X_add_number
),
2071 image
= insert_operand (image
, operand
, t
->X_add_number
, NULL
, 0);
2072 gas_assert (reloc_operand
== NULL
);
2073 reloc_operand
= operand
;
2078 /* This is only 0 for fields that should contain registers,
2079 which means this pattern shouldn't have matched. */
2080 if (operand
->default_reloc
== 0)
2083 /* There is one special case for which an insn receives two
2084 relocations, and thus the user-supplied reloc does not
2085 override the operand reloc. */
2086 if (operand
->default_reloc
== BFD_RELOC_ALPHA_HINT
)
2088 struct alpha_fixup
*fixup
;
2090 if (insn
->nfixups
>= MAX_INSN_FIXUPS
)
2091 as_fatal (_("too many fixups"));
2093 fixup
= &insn
->fixups
[insn
->nfixups
++];
2095 fixup
->reloc
= BFD_RELOC_ALPHA_HINT
;
2099 if (reloc
== BFD_RELOC_UNUSED
)
2100 reloc
= operand
->default_reloc
;
2102 gas_assert (reloc_operand
== NULL
);
2103 reloc_operand
= operand
;
2110 if (reloc
!= BFD_RELOC_UNUSED
)
2112 struct alpha_fixup
*fixup
;
2114 if (insn
->nfixups
>= MAX_INSN_FIXUPS
)
2115 as_fatal (_("too many fixups"));
2117 /* ??? My but this is hacky. But the OSF/1 assembler uses the same
2118 relocation tag for both ldah and lda with gpdisp. Choose the
2119 correct internal relocation based on the opcode. */
2120 if (reloc
== BFD_RELOC_ALPHA_GPDISP
)
2122 if (strcmp (opcode
->name
, "ldah") == 0)
2123 reloc
= BFD_RELOC_ALPHA_GPDISP_HI16
;
2124 else if (strcmp (opcode
->name
, "lda") == 0)
2125 reloc
= BFD_RELOC_ALPHA_GPDISP_LO16
;
2127 as_bad (_("invalid relocation for instruction"));
2130 /* If this is a real relocation (as opposed to a lituse hint), then
2131 the relocation width should match the operand width.
2132 Take care of -MDISP in operand table. */
2133 else if (reloc
< BFD_RELOC_UNUSED
&& reloc
> 0)
2135 reloc_howto_type
*reloc_howto
2136 = bfd_reloc_type_lookup (stdoutput
,
2137 (bfd_reloc_code_real_type
) reloc
);
2138 if (reloc_operand
== NULL
2139 || reloc_howto
->bitsize
!= reloc_operand
->bits
)
2141 as_bad (_("invalid relocation for field"));
2146 fixup
= &insn
->fixups
[insn
->nfixups
++];
2148 fixup
->exp
= *reloc_exp
;
2150 fixup
->exp
.X_op
= O_absent
;
2151 fixup
->reloc
= reloc
;
2157 /* Handle all "simple" integer register loads -- ldq, ldq_l, ldq_u,
2158 etc. They differ from the real instructions in that they do simple
2159 expressions like the lda macro. */
2162 emit_ir_load (const expressionS
*tok
,
2164 const void * opname
)
2168 expressionS newtok
[3];
2169 struct alpha_insn insn
;
2171 = tok
[1].X_add_symbol
? S_GET_NAME (tok
[1].X_add_symbol
): "";
2172 int symlen
= strlen (symname
);
2175 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
2177 basereg
= tok
[2].X_add_number
;
2179 lituse
= load_expression (tok
[0].X_add_number
, &tok
[1],
2180 &basereg
, &newtok
[1], (const char *) opname
);
2182 if (basereg
== alpha_gp_register
&&
2183 (symlen
> 4 && strcmp (&symname
[symlen
- 4], "..lk") == 0))
2187 set_tok_preg (newtok
[2], basereg
);
2189 assemble_tokens_to_insn ((const char *) opname
, newtok
, 3, &insn
);
2193 gas_assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
2194 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BASE
;
2195 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
2197 insn
.sequence
= lituse
;
2203 /* Handle fp register loads, and both integer and fp register stores.
2204 Again, we handle simple expressions. */
2207 emit_loadstore (const expressionS
*tok
,
2209 const void * opname
)
2213 expressionS newtok
[3];
2214 struct alpha_insn insn
;
2217 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
2219 basereg
= tok
[2].X_add_number
;
2221 if (tok
[1].X_op
!= O_constant
|| !range_signed_16 (tok
[1].X_add_number
))
2224 as_bad (_("macro requires $at register while noat in effect"));
2226 lituse
= load_expression (AXP_REG_AT
, &tok
[1],
2227 &basereg
, &newtok
[1], (const char *) opname
);
2236 set_tok_preg (newtok
[2], basereg
);
2238 assemble_tokens_to_insn ((const char *) opname
, newtok
, 3, &insn
);
2242 gas_assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
2243 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BASE
;
2244 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
2246 insn
.sequence
= lituse
;
2252 /* Load a half-word or byte as an unsigned value. */
2255 emit_ldXu (const expressionS
*tok
,
2257 const void * vlgsize
)
2259 if (alpha_target
& AXP_OPCODE_BWX
)
2260 emit_ir_load (tok
, ntok
, ldXu_op
[(long) vlgsize
]);
2263 expressionS newtok
[3];
2264 struct alpha_insn insn
;
2269 as_bad (_("macro requires $at register while noat in effect"));
2272 basereg
= (tok
[1].X_op
== O_constant
2273 ? AXP_REG_ZERO
: alpha_gp_register
);
2275 basereg
= tok
[2].X_add_number
;
2277 /* Emit "lda $at, exp". */
2278 lituse
= load_expression (AXP_REG_AT
, &tok
[1], &basereg
, NULL
, "lda");
2280 /* Emit "ldq_u targ, 0($at)". */
2282 set_tok_const (newtok
[1], 0);
2283 set_tok_preg (newtok
[2], basereg
);
2284 assemble_tokens_to_insn ("ldq_u", newtok
, 3, &insn
);
2288 gas_assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
2289 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BASE
;
2290 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
2292 insn
.sequence
= lituse
;
2297 /* Emit "extXl targ, $at, targ". */
2298 set_tok_reg (newtok
[1], basereg
);
2299 newtok
[2] = newtok
[0];
2300 assemble_tokens_to_insn (extXl_op
[(long) vlgsize
], newtok
, 3, &insn
);
2304 gas_assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
2305 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BYTOFF
;
2306 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
2308 insn
.sequence
= lituse
;
2315 /* Load a half-word or byte as a signed value. */
2318 emit_ldX (const expressionS
*tok
,
2320 const void * vlgsize
)
2322 emit_ldXu (tok
, ntok
, vlgsize
);
2323 assemble_tokens (sextX_op
[(long) vlgsize
], tok
, 1, 1);
2326 /* Load an integral value from an unaligned address as an unsigned
2330 emit_uldXu (const expressionS
*tok
,
2332 const void * vlgsize
)
2334 long lgsize
= (long) vlgsize
;
2335 expressionS newtok
[3];
2338 as_bad (_("macro requires $at register while noat in effect"));
2340 /* Emit "lda $at, exp". */
2341 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
2342 newtok
[0].X_add_number
= AXP_REG_AT
;
2343 assemble_tokens ("lda", newtok
, ntok
, 1);
2345 /* Emit "ldq_u $t9, 0($at)". */
2346 set_tok_reg (newtok
[0], AXP_REG_T9
);
2347 set_tok_const (newtok
[1], 0);
2348 set_tok_preg (newtok
[2], AXP_REG_AT
);
2349 assemble_tokens ("ldq_u", newtok
, 3, 1);
2351 /* Emit "ldq_u $t10, size-1($at)". */
2352 set_tok_reg (newtok
[0], AXP_REG_T10
);
2353 set_tok_const (newtok
[1], (1 << lgsize
) - 1);
2354 assemble_tokens ("ldq_u", newtok
, 3, 1);
2356 /* Emit "extXl $t9, $at, $t9". */
2357 set_tok_reg (newtok
[0], AXP_REG_T9
);
2358 set_tok_reg (newtok
[1], AXP_REG_AT
);
2359 set_tok_reg (newtok
[2], AXP_REG_T9
);
2360 assemble_tokens (extXl_op
[lgsize
], newtok
, 3, 1);
2362 /* Emit "extXh $t10, $at, $t10". */
2363 set_tok_reg (newtok
[0], AXP_REG_T10
);
2364 set_tok_reg (newtok
[2], AXP_REG_T10
);
2365 assemble_tokens (extXh_op
[lgsize
], newtok
, 3, 1);
2367 /* Emit "or $t9, $t10, targ". */
2368 set_tok_reg (newtok
[0], AXP_REG_T9
);
2369 set_tok_reg (newtok
[1], AXP_REG_T10
);
2371 assemble_tokens ("or", newtok
, 3, 1);
2374 /* Load an integral value from an unaligned address as a signed value.
2375 Note that quads should get funneled to the unsigned load since we
2376 don't have to do the sign extension. */
2379 emit_uldX (const expressionS
*tok
,
2381 const void * vlgsize
)
2383 emit_uldXu (tok
, ntok
, vlgsize
);
2384 assemble_tokens (sextX_op
[(long) vlgsize
], tok
, 1, 1);
2387 /* Implement the ldil macro. */
2390 emit_ldil (const expressionS
*tok
,
2392 const void * unused ATTRIBUTE_UNUSED
)
2394 expressionS newtok
[2];
2396 memcpy (newtok
, tok
, sizeof (newtok
));
2397 newtok
[1].X_add_number
= sign_extend_32 (tok
[1].X_add_number
);
2399 assemble_tokens ("lda", newtok
, ntok
, 1);
2402 /* Store a half-word or byte. */
2405 emit_stX (const expressionS
*tok
,
2407 const void * vlgsize
)
2409 int lgsize
= (int) (long) vlgsize
;
2411 if (alpha_target
& AXP_OPCODE_BWX
)
2412 emit_loadstore (tok
, ntok
, stX_op
[lgsize
]);
2415 expressionS newtok
[3];
2416 struct alpha_insn insn
;
2421 as_bad (_("macro requires $at register while noat in effect"));
2424 basereg
= (tok
[1].X_op
== O_constant
2425 ? AXP_REG_ZERO
: alpha_gp_register
);
2427 basereg
= tok
[2].X_add_number
;
2429 /* Emit "lda $at, exp". */
2430 lituse
= load_expression (AXP_REG_AT
, &tok
[1], &basereg
, NULL
, "lda");
2432 /* Emit "ldq_u $t9, 0($at)". */
2433 set_tok_reg (newtok
[0], AXP_REG_T9
);
2434 set_tok_const (newtok
[1], 0);
2435 set_tok_preg (newtok
[2], basereg
);
2436 assemble_tokens_to_insn ("ldq_u", newtok
, 3, &insn
);
2440 gas_assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
2441 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BASE
;
2442 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
2444 insn
.sequence
= lituse
;
2449 /* Emit "insXl src, $at, $t10". */
2451 set_tok_reg (newtok
[1], basereg
);
2452 set_tok_reg (newtok
[2], AXP_REG_T10
);
2453 assemble_tokens_to_insn (insXl_op
[lgsize
], newtok
, 3, &insn
);
2457 gas_assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
2458 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BYTOFF
;
2459 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
2461 insn
.sequence
= lituse
;
2466 /* Emit "mskXl $t9, $at, $t9". */
2467 set_tok_reg (newtok
[0], AXP_REG_T9
);
2468 newtok
[2] = newtok
[0];
2469 assemble_tokens_to_insn (mskXl_op
[lgsize
], newtok
, 3, &insn
);
2473 gas_assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
2474 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BYTOFF
;
2475 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
2477 insn
.sequence
= lituse
;
2482 /* Emit "or $t9, $t10, $t9". */
2483 set_tok_reg (newtok
[1], AXP_REG_T10
);
2484 assemble_tokens ("or", newtok
, 3, 1);
2486 /* Emit "stq_u $t9, 0($at). */
2487 set_tok_const(newtok
[1], 0);
2488 set_tok_preg (newtok
[2], AXP_REG_AT
);
2489 assemble_tokens_to_insn ("stq_u", newtok
, 3, &insn
);
2493 gas_assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
2494 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BASE
;
2495 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
2497 insn
.sequence
= lituse
;
2504 /* Store an integer to an unaligned address. */
2507 emit_ustX (const expressionS
*tok
,
2509 const void * vlgsize
)
2511 int lgsize
= (int) (long) vlgsize
;
2512 expressionS newtok
[3];
2514 /* Emit "lda $at, exp". */
2515 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
2516 newtok
[0].X_add_number
= AXP_REG_AT
;
2517 assemble_tokens ("lda", newtok
, ntok
, 1);
2519 /* Emit "ldq_u $9, 0($at)". */
2520 set_tok_reg (newtok
[0], AXP_REG_T9
);
2521 set_tok_const (newtok
[1], 0);
2522 set_tok_preg (newtok
[2], AXP_REG_AT
);
2523 assemble_tokens ("ldq_u", newtok
, 3, 1);
2525 /* Emit "ldq_u $10, size-1($at)". */
2526 set_tok_reg (newtok
[0], AXP_REG_T10
);
2527 set_tok_const (newtok
[1], (1 << lgsize
) - 1);
2528 assemble_tokens ("ldq_u", newtok
, 3, 1);
2530 /* Emit "insXl src, $at, $t11". */
2532 set_tok_reg (newtok
[1], AXP_REG_AT
);
2533 set_tok_reg (newtok
[2], AXP_REG_T11
);
2534 assemble_tokens (insXl_op
[lgsize
], newtok
, 3, 1);
2536 /* Emit "insXh src, $at, $t12". */
2537 set_tok_reg (newtok
[2], AXP_REG_T12
);
2538 assemble_tokens (insXh_op
[lgsize
], newtok
, 3, 1);
2540 /* Emit "mskXl $t9, $at, $t9". */
2541 set_tok_reg (newtok
[0], AXP_REG_T9
);
2542 newtok
[2] = newtok
[0];
2543 assemble_tokens (mskXl_op
[lgsize
], newtok
, 3, 1);
2545 /* Emit "mskXh $t10, $at, $t10". */
2546 set_tok_reg (newtok
[0], AXP_REG_T10
);
2547 newtok
[2] = newtok
[0];
2548 assemble_tokens (mskXh_op
[lgsize
], newtok
, 3, 1);
2550 /* Emit "or $t9, $t11, $t9". */
2551 set_tok_reg (newtok
[0], AXP_REG_T9
);
2552 set_tok_reg (newtok
[1], AXP_REG_T11
);
2553 newtok
[2] = newtok
[0];
2554 assemble_tokens ("or", newtok
, 3, 1);
2556 /* Emit "or $t10, $t12, $t10". */
2557 set_tok_reg (newtok
[0], AXP_REG_T10
);
2558 set_tok_reg (newtok
[1], AXP_REG_T12
);
2559 newtok
[2] = newtok
[0];
2560 assemble_tokens ("or", newtok
, 3, 1);
2562 /* Emit "stq_u $t10, size-1($at)". */
2563 set_tok_reg (newtok
[0], AXP_REG_T10
);
2564 set_tok_const (newtok
[1], (1 << lgsize
) - 1);
2565 set_tok_preg (newtok
[2], AXP_REG_AT
);
2566 assemble_tokens ("stq_u", newtok
, 3, 1);
2568 /* Emit "stq_u $t9, 0($at)". */
2569 set_tok_reg (newtok
[0], AXP_REG_T9
);
2570 set_tok_const (newtok
[1], 0);
2571 assemble_tokens ("stq_u", newtok
, 3, 1);
2574 /* Sign extend a half-word or byte. The 32-bit sign extend is
2575 implemented as "addl $31, $r, $t" in the opcode table. */
2578 emit_sextX (const expressionS
*tok
,
2580 const void * vlgsize
)
2582 long lgsize
= (long) vlgsize
;
2584 if (alpha_target
& AXP_OPCODE_BWX
)
2585 assemble_tokens (sextX_op
[lgsize
], tok
, ntok
, 0);
2588 int bitshift
= 64 - 8 * (1 << lgsize
);
2589 expressionS newtok
[3];
2591 /* Emit "sll src,bits,dst". */
2593 set_tok_const (newtok
[1], bitshift
);
2594 newtok
[2] = tok
[ntok
- 1];
2595 assemble_tokens ("sll", newtok
, 3, 1);
2597 /* Emit "sra dst,bits,dst". */
2598 newtok
[0] = newtok
[2];
2599 assemble_tokens ("sra", newtok
, 3, 1);
2603 /* Implement the division and modulus macros. */
2607 /* Make register usage like in normal procedure call.
2608 Don't clobber PV and RA. */
2611 emit_division (const expressionS
*tok
,
2613 const void * symname
)
2615 /* DIVISION and MODULUS. Yech.
2620 mov x,R16 # if x != R16
2621 mov y,R17 # if y != R17
2626 with appropriate optimizations if R0,R16,R17 are the registers
2627 specified by the compiler. */
2631 expressionS newtok
[3];
2633 xr
= regno (tok
[0].X_add_number
);
2634 yr
= regno (tok
[1].X_add_number
);
2639 rr
= regno (tok
[2].X_add_number
);
2641 /* Move the operands into the right place. */
2642 if (yr
== AXP_REG_R16
&& xr
== AXP_REG_R17
)
2644 /* They are in exactly the wrong order -- swap through AT. */
2646 as_bad (_("macro requires $at register while noat in effect"));
2648 set_tok_reg (newtok
[0], AXP_REG_R16
);
2649 set_tok_reg (newtok
[1], AXP_REG_AT
);
2650 assemble_tokens ("mov", newtok
, 2, 1);
2652 set_tok_reg (newtok
[0], AXP_REG_R17
);
2653 set_tok_reg (newtok
[1], AXP_REG_R16
);
2654 assemble_tokens ("mov", newtok
, 2, 1);
2656 set_tok_reg (newtok
[0], AXP_REG_AT
);
2657 set_tok_reg (newtok
[1], AXP_REG_R17
);
2658 assemble_tokens ("mov", newtok
, 2, 1);
2662 if (yr
== AXP_REG_R16
)
2664 set_tok_reg (newtok
[0], AXP_REG_R16
);
2665 set_tok_reg (newtok
[1], AXP_REG_R17
);
2666 assemble_tokens ("mov", newtok
, 2, 1);
2669 if (xr
!= AXP_REG_R16
)
2671 set_tok_reg (newtok
[0], xr
);
2672 set_tok_reg (newtok
[1], AXP_REG_R16
);
2673 assemble_tokens ("mov", newtok
, 2, 1);
2676 if (yr
!= AXP_REG_R16
&& yr
!= AXP_REG_R17
)
2678 set_tok_reg (newtok
[0], yr
);
2679 set_tok_reg (newtok
[1], AXP_REG_R17
);
2680 assemble_tokens ("mov", newtok
, 2, 1);
2684 sym
= symbol_find_or_make ((const char *) symname
);
2686 set_tok_reg (newtok
[0], AXP_REG_AT
);
2687 set_tok_sym (newtok
[1], sym
, 0);
2688 assemble_tokens ("lda", newtok
, 2, 1);
2690 /* Call the division routine. */
2691 set_tok_reg (newtok
[0], AXP_REG_AT
);
2692 set_tok_cpreg (newtok
[1], AXP_REG_AT
);
2693 set_tok_const (newtok
[2], 0);
2694 assemble_tokens ("jsr", newtok
, 3, 1);
2696 /* Move the result to the right place. */
2697 if (rr
!= AXP_REG_R0
)
2699 set_tok_reg (newtok
[0], AXP_REG_R0
);
2700 set_tok_reg (newtok
[1], rr
);
2701 assemble_tokens ("mov", newtok
, 2, 1);
2705 #else /* !OBJ_EVAX */
2708 emit_division (const expressionS
*tok
,
2710 const void * symname
)
2712 /* DIVISION and MODULUS. Yech.
2722 with appropriate optimizations if t10,t11,t12 are the registers
2723 specified by the compiler. */
2727 expressionS newtok
[3];
2729 xr
= regno (tok
[0].X_add_number
);
2730 yr
= regno (tok
[1].X_add_number
);
2735 rr
= regno (tok
[2].X_add_number
);
2737 sym
= symbol_find_or_make ((const char *) symname
);
2739 /* Move the operands into the right place. */
2740 if (yr
== AXP_REG_T10
&& xr
== AXP_REG_T11
)
2742 /* They are in exactly the wrong order -- swap through AT. */
2744 as_bad (_("macro requires $at register while noat in effect"));
2746 set_tok_reg (newtok
[0], AXP_REG_T10
);
2747 set_tok_reg (newtok
[1], AXP_REG_AT
);
2748 assemble_tokens ("mov", newtok
, 2, 1);
2750 set_tok_reg (newtok
[0], AXP_REG_T11
);
2751 set_tok_reg (newtok
[1], AXP_REG_T10
);
2752 assemble_tokens ("mov", newtok
, 2, 1);
2754 set_tok_reg (newtok
[0], AXP_REG_AT
);
2755 set_tok_reg (newtok
[1], AXP_REG_T11
);
2756 assemble_tokens ("mov", newtok
, 2, 1);
2760 if (yr
== AXP_REG_T10
)
2762 set_tok_reg (newtok
[0], AXP_REG_T10
);
2763 set_tok_reg (newtok
[1], AXP_REG_T11
);
2764 assemble_tokens ("mov", newtok
, 2, 1);
2767 if (xr
!= AXP_REG_T10
)
2769 set_tok_reg (newtok
[0], xr
);
2770 set_tok_reg (newtok
[1], AXP_REG_T10
);
2771 assemble_tokens ("mov", newtok
, 2, 1);
2774 if (yr
!= AXP_REG_T10
&& yr
!= AXP_REG_T11
)
2776 set_tok_reg (newtok
[0], yr
);
2777 set_tok_reg (newtok
[1], AXP_REG_T11
);
2778 assemble_tokens ("mov", newtok
, 2, 1);
2782 /* Call the division routine. */
2783 set_tok_reg (newtok
[0], AXP_REG_T9
);
2784 set_tok_sym (newtok
[1], sym
, 0);
2785 assemble_tokens ("jsr", newtok
, 2, 1);
2787 /* Reload the GP register. */
2791 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
2792 set_tok_reg (newtok
[0], alpha_gp_register
);
2793 set_tok_const (newtok
[1], 0);
2794 set_tok_preg (newtok
[2], AXP_REG_T9
);
2795 assemble_tokens ("ldgp", newtok
, 3, 1);
2798 /* Move the result to the right place. */
2799 if (rr
!= AXP_REG_T12
)
2801 set_tok_reg (newtok
[0], AXP_REG_T12
);
2802 set_tok_reg (newtok
[1], rr
);
2803 assemble_tokens ("mov", newtok
, 2, 1);
2807 #endif /* !OBJ_EVAX */
2809 /* The jsr and jmp macros differ from their instruction counterparts
2810 in that they can load the target address and default most
2814 emit_jsrjmp (const expressionS
*tok
,
2816 const void * vopname
)
2818 const char *opname
= (const char *) vopname
;
2819 struct alpha_insn insn
;
2820 expressionS newtok
[3];
2824 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_register
)
2825 r
= regno (tok
[tokidx
++].X_add_number
);
2827 r
= strcmp (opname
, "jmp") == 0 ? AXP_REG_ZERO
: AXP_REG_RA
;
2829 set_tok_reg (newtok
[0], r
);
2831 if (tokidx
< ntok
&&
2832 (tok
[tokidx
].X_op
== O_pregister
|| tok
[tokidx
].X_op
== O_cpregister
))
2833 r
= regno (tok
[tokidx
++].X_add_number
);
2835 /* Keep register if jsr $n.<sym>. */
2839 int basereg
= alpha_gp_register
;
2840 lituse
= load_expression (r
= AXP_REG_PV
, &tok
[tokidx
],
2841 &basereg
, NULL
, opname
);
2845 set_tok_cpreg (newtok
[1], r
);
2849 newtok
[2] = tok
[tokidx
];
2852 set_tok_const (newtok
[2], 0);
2854 assemble_tokens_to_insn (opname
, newtok
, 3, &insn
);
2858 gas_assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
2859 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_JSR
;
2860 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
2862 insn
.sequence
= lituse
;
2866 if (alpha_flag_replace
2868 && tok
[tokidx
].X_add_symbol
2869 && alpha_linkage_symbol
)
2871 const char *symname
= S_GET_NAME (tok
[tokidx
].X_add_symbol
);
2872 int symlen
= strlen (symname
);
2875 ensymname
= (char *) xmalloc (symlen
+ 5);
2876 memcpy (ensymname
, symname
, symlen
);
2877 memcpy (ensymname
+ symlen
, "..en", 5);
2879 gas_assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
2880 if (insn
.nfixups
> 0)
2882 memmove (&insn
.fixups
[1], &insn
.fixups
[0],
2883 sizeof(struct alpha_fixup
) * insn
.nfixups
);
2886 /* The fixup must be the same as the BFD_RELOC_ALPHA_NOP
2887 case in load_expression. See B.4.5.2 of the OpenVMS
2888 Linker Utility Manual. */
2889 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_BOH
;
2890 insn
.fixups
[0].exp
.X_op
= O_symbol
;
2891 insn
.fixups
[0].exp
.X_add_symbol
= symbol_find_or_make (ensymname
);
2892 insn
.fixups
[0].exp
.X_add_number
= 0;
2893 insn
.fixups
[0].xtrasym
= alpha_linkage_symbol
;
2894 insn
.fixups
[0].procsym
= alpha_evax_proc
->symbol
;
2896 alpha_linkage_symbol
= 0;
2903 /* The ret and jcr instructions differ from their instruction
2904 counterparts in that everything can be defaulted. */
2907 emit_retjcr (const expressionS
*tok
,
2909 const void * vopname
)
2911 const char *opname
= (const char *) vopname
;
2912 expressionS newtok
[3];
2915 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_register
)
2916 r
= regno (tok
[tokidx
++].X_add_number
);
2920 set_tok_reg (newtok
[0], r
);
2922 if (tokidx
< ntok
&&
2923 (tok
[tokidx
].X_op
== O_pregister
|| tok
[tokidx
].X_op
== O_cpregister
))
2924 r
= regno (tok
[tokidx
++].X_add_number
);
2928 set_tok_cpreg (newtok
[1], r
);
2931 newtok
[2] = tok
[tokidx
];
2933 set_tok_const (newtok
[2], strcmp (opname
, "ret") == 0);
2935 assemble_tokens (opname
, newtok
, 3, 0);
2938 /* Implement the ldgp macro. */
2941 emit_ldgp (const expressionS
*tok
,
2942 int ntok ATTRIBUTE_UNUSED
,
2943 const void * unused ATTRIBUTE_UNUSED
)
2948 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
2949 /* from "ldgp r1,n(r2)", generate "ldah r1,X(R2); lda r1,Y(r1)"
2950 with appropriate constants and relocations. */
2951 struct alpha_insn insn
;
2952 expressionS newtok
[3];
2956 if (regno (tok
[2].X_add_number
) == AXP_REG_PV
)
2957 ecoff_set_gp_prolog_size (0);
2961 set_tok_const (newtok
[1], 0);
2964 assemble_tokens_to_insn ("ldah", newtok
, 3, &insn
);
2969 if (addend
.X_op
!= O_constant
)
2970 as_bad (_("can not resolve expression"));
2971 addend
.X_op
= O_symbol
;
2972 addend
.X_add_symbol
= alpha_gp_symbol
;
2976 insn
.fixups
[0].exp
= addend
;
2977 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_GPDISP_HI16
;
2978 insn
.sequence
= next_sequence_num
;
2982 set_tok_preg (newtok
[2], tok
[0].X_add_number
);
2984 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
2987 addend
.X_add_number
+= 4;
2991 insn
.fixups
[0].exp
= addend
;
2992 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_GPDISP_LO16
;
2993 insn
.sequence
= next_sequence_num
--;
2996 #else /* OBJ_ECOFF || OBJ_ELF */
2997 /* Avoid warning. */
3002 /* The macro table. */
3004 static const struct alpha_macro alpha_macros
[] =
3006 /* Load/Store macros. */
3007 { "lda", emit_lda
, NULL
,
3008 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
3009 { "ldah", emit_ldah
, NULL
,
3010 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
3012 { "ldl", emit_ir_load
, "ldl",
3013 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
3014 { "ldl_l", emit_ir_load
, "ldl_l",
3015 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
3016 { "ldq", emit_ir_load
, "ldq",
3017 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
3018 { "ldq_l", emit_ir_load
, "ldq_l",
3019 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
3020 { "ldq_u", emit_ir_load
, "ldq_u",
3021 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
3022 { "ldf", emit_loadstore
, "ldf",
3023 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
3024 { "ldg", emit_loadstore
, "ldg",
3025 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
3026 { "lds", emit_loadstore
, "lds",
3027 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
3028 { "ldt", emit_loadstore
, "ldt",
3029 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
3031 { "ldb", emit_ldX
, (void *) 0,
3032 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
3033 { "ldbu", emit_ldXu
, (void *) 0,
3034 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
3035 { "ldw", emit_ldX
, (void *) 1,
3036 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
3037 { "ldwu", emit_ldXu
, (void *) 1,
3038 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
3040 { "uldw", emit_uldX
, (void *) 1,
3041 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
3042 { "uldwu", emit_uldXu
, (void *) 1,
3043 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
3044 { "uldl", emit_uldX
, (void *) 2,
3045 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
3046 { "uldlu", emit_uldXu
, (void *) 2,
3047 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
3048 { "uldq", emit_uldXu
, (void *) 3,
3049 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
3051 { "ldgp", emit_ldgp
, NULL
,
3052 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
} },
3054 { "ldi", emit_lda
, NULL
,
3055 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
3056 { "ldil", emit_ldil
, NULL
,
3057 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
3058 { "ldiq", emit_lda
, NULL
,
3059 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
3061 { "stl", emit_loadstore
, "stl",
3062 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
3063 { "stl_c", emit_loadstore
, "stl_c",
3064 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
3065 { "stq", emit_loadstore
, "stq",
3066 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
3067 { "stq_c", emit_loadstore
, "stq_c",
3068 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
3069 { "stq_u", emit_loadstore
, "stq_u",
3070 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
3071 { "stf", emit_loadstore
, "stf",
3072 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
3073 { "stg", emit_loadstore
, "stg",
3074 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
3075 { "sts", emit_loadstore
, "sts",
3076 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
3077 { "stt", emit_loadstore
, "stt",
3078 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
3080 { "stb", emit_stX
, (void *) 0,
3081 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
3082 { "stw", emit_stX
, (void *) 1,
3083 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
3084 { "ustw", emit_ustX
, (void *) 1,
3085 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
3086 { "ustl", emit_ustX
, (void *) 2,
3087 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
3088 { "ustq", emit_ustX
, (void *) 3,
3089 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
3091 /* Arithmetic macros. */
3093 { "sextb", emit_sextX
, (void *) 0,
3094 { MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3095 MACRO_IR
, MACRO_EOA
,
3096 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
3097 { "sextw", emit_sextX
, (void *) 1,
3098 { MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3099 MACRO_IR
, MACRO_EOA
,
3100 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
3102 { "divl", emit_division
, "__divl",
3103 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3104 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3105 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
3106 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
3107 { "divlu", emit_division
, "__divlu",
3108 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3109 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3110 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
3111 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
3112 { "divq", emit_division
, "__divq",
3113 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3114 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3115 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
3116 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
3117 { "divqu", emit_division
, "__divqu",
3118 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3119 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3120 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
3121 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
3122 { "reml", emit_division
, "__reml",
3123 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3124 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3125 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
3126 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
3127 { "remlu", emit_division
, "__remlu",
3128 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3129 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3130 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
3131 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
3132 { "remq", emit_division
, "__remq",
3133 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3134 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3135 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
3136 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
3137 { "remqu", emit_division
, "__remqu",
3138 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3139 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3140 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
3141 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
3143 { "jsr", emit_jsrjmp
, "jsr",
3144 { MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
3145 MACRO_PIR
, MACRO_EOA
,
3146 MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
3147 MACRO_EXP
, MACRO_EOA
} },
3148 { "jmp", emit_jsrjmp
, "jmp",
3149 { MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
3150 MACRO_PIR
, MACRO_EOA
,
3151 MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
3152 MACRO_EXP
, MACRO_EOA
} },
3153 { "ret", emit_retjcr
, "ret",
3154 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
3155 MACRO_IR
, MACRO_EOA
,
3156 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
3157 MACRO_PIR
, MACRO_EOA
,
3158 MACRO_EXP
, MACRO_EOA
,
3160 { "jcr", emit_retjcr
, "jcr",
3161 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
3162 MACRO_IR
, MACRO_EOA
,
3163 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
3164 MACRO_PIR
, MACRO_EOA
,
3165 MACRO_EXP
, MACRO_EOA
,
3167 { "jsr_coroutine", emit_retjcr
, "jcr",
3168 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
3169 MACRO_IR
, MACRO_EOA
,
3170 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
3171 MACRO_PIR
, MACRO_EOA
,
3172 MACRO_EXP
, MACRO_EOA
,
3176 static const unsigned int alpha_num_macros
3177 = sizeof (alpha_macros
) / sizeof (*alpha_macros
);
3179 /* Search forward through all variants of a macro looking for a syntax
3182 static const struct alpha_macro
*
3183 find_macro_match (const struct alpha_macro
*first_macro
,
3184 const expressionS
*tok
,
3188 const struct alpha_macro
*macro
= first_macro
;
3193 const enum alpha_macro_arg
*arg
= macro
->argsets
;
3207 /* Index register. */
3209 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_register
3210 || !is_ir_num (tok
[tokidx
].X_add_number
))
3215 /* Parenthesized index register. */
3217 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_pregister
3218 || !is_ir_num (tok
[tokidx
].X_add_number
))
3223 /* Optional parenthesized index register. */
3225 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_pregister
3226 && is_ir_num (tok
[tokidx
].X_add_number
))
3230 /* Leading comma with a parenthesized index register. */
3232 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_cpregister
3233 || !is_ir_num (tok
[tokidx
].X_add_number
))
3238 /* Floating point register. */
3240 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_register
3241 || !is_fpr_num (tok
[tokidx
].X_add_number
))
3246 /* Normal expression. */
3250 switch (tok
[tokidx
].X_op
)
3259 case O_lituse_bytoff
:
3275 while (*arg
!= MACRO_EOA
)
3283 while (++macro
- alpha_macros
< (int) alpha_num_macros
3284 && !strcmp (macro
->name
, first_macro
->name
));
3289 /* Given an opcode name and a pre-tokenized set of arguments, take the
3290 opcode all the way through emission. */
3293 assemble_tokens (const char *opname
,
3294 const expressionS
*tok
,
3296 int local_macros_on
)
3298 int found_something
= 0;
3299 const struct alpha_opcode
*opcode
;
3300 const struct alpha_macro
*macro
;
3302 extended_bfd_reloc_code_real_type reloc
= BFD_RELOC_UNUSED
;
3305 /* If a user-specified relocation is present, this is not a macro. */
3306 if (ntok
&& USER_RELOC_P (tok
[ntok
- 1].X_op
))
3308 reloc
= ALPHA_RELOC_TABLE (tok
[ntok
- 1].X_op
)->reloc
;
3313 if (local_macros_on
)
3315 macro
= ((const struct alpha_macro
*)
3316 hash_find (alpha_macro_hash
, opname
));
3319 found_something
= 1;
3320 macro
= find_macro_match (macro
, tok
, &ntok
);
3323 (*macro
->emit
) (tok
, ntok
, macro
->arg
);
3329 /* Search opcodes. */
3330 opcode
= (const struct alpha_opcode
*) hash_find (alpha_opcode_hash
, opname
);
3333 found_something
= 1;
3334 opcode
= find_opcode_match (opcode
, tok
, &ntok
, &cpumatch
);
3337 struct alpha_insn insn
;
3338 assemble_insn (opcode
, tok
, ntok
, &insn
, reloc
);
3340 /* Copy the sequence number for the reloc from the reloc token. */
3341 if (reloc
!= BFD_RELOC_UNUSED
)
3342 insn
.sequence
= tok
[ntok
].X_add_number
;
3349 if (found_something
)
3352 as_bad (_("inappropriate arguments for opcode `%s'"), opname
);
3354 as_bad (_("opcode `%s' not supported for target %s"), opname
,
3358 as_bad (_("unknown opcode `%s'"), opname
);
3363 /* Add symbol+addend to link pool.
3364 Return offset from basesym to entry in link pool.
3366 Add new fixup only if offset isn't 16bit. */
3369 add_to_link_pool (symbolS
*basesym
,
3373 segT current_section
= now_seg
;
3374 int current_subsec
= now_subseg
;
3377 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
3379 symbolS
*linksym
, *expsym
;
3382 offset
= 0; /* ??? DBR */
3384 /* @@ This assumes all entries in a given section will be of the same
3385 size... Probably correct, but unwise to rely on. */
3386 /* This must always be called with the same subsegment. */
3388 if (seginfo
->frchainP
)
3389 for (fixp
= seginfo
->frchainP
->fix_root
;
3390 fixp
!= (fixS
*) NULL
;
3391 fixp
= fixp
->fx_next
)
3393 if (fixp
->tc_fix_data
.info
3394 && fixp
->tc_fix_data
.info
->sym
3395 && fixp
->tc_fix_data
.info
->sym
->sy_value
.X_op_symbol
== basesym
)
3398 if (fixp
->fx_addsy
== sym
3399 && fixp
->fx_offset
== (valueT
)addend
3400 && fixp
->tc_fix_data
.info
3401 && fixp
->tc_fix_data
.info
->sym
3402 && fixp
->tc_fix_data
.info
->sym
->sy_value
.X_op_symbol
== basesym
)
3403 return fixp
->tc_fix_data
.info
->sym
;
3406 /* Not found in 16bit signed range. */
3408 subseg_set (alpha_link_section
, 0);
3409 linksym
= symbol_new
3410 (FAKE_LABEL_NAME
, now_seg
, (valueT
) frag_now_fix (), frag_now
);
3414 e
.X_op
= O_subtract
;
3415 e
.X_add_symbol
= linksym
;
3416 e
.X_op_symbol
= basesym
;
3418 expsym
= make_expr_symbol (&e
);
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
);
3426 seginfo
->literal_pool_size
+= 8;
3429 #endif /* OBJ_EVAX */
3431 /* Assembler directives. */
3433 /* Handle the .text pseudo-op. This is like the usual one, but it
3434 clears alpha_insn_label and restores auto alignment. */
3437 s_alpha_text (int i
)
3448 symbolP
= symbol_find (".text");
3449 if (symbolP
== NULL
)
3451 symbolP
= symbol_make (".text");
3452 S_SET_SEGMENT (symbolP
, text_section
);
3453 symbol_table_insert (symbolP
);
3457 alpha_insn_label
= NULL
;
3458 alpha_auto_align_on
= 1;
3459 alpha_current_align
= 0;
3462 /* Handle the .data pseudo-op. This is like the usual one, but it
3463 clears alpha_insn_label and restores auto alignment. */
3466 s_alpha_data (int i
)
3473 alpha_insn_label
= NULL
;
3474 alpha_auto_align_on
= 1;
3475 alpha_current_align
= 0;
3478 #if defined (OBJ_ECOFF) || defined (OBJ_EVAX)
3480 /* Handle the OSF/1 and openVMS .comm pseudo quirks. */
3483 s_alpha_comm (int ignore ATTRIBUTE_UNUSED
)
3495 name
= input_line_pointer
;
3496 c
= get_symbol_end ();
3498 /* Just after name is now '\0'. */
3499 p
= input_line_pointer
;
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. */
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 symbolP
->sy_frag
= 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 (symbolP
->sy_frag
== &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
)
3646 temp
= get_absolute_expression ();
3647 subseg_new (".rdata", 0);
3648 demand_empty_rest_of_line ();
3649 alpha_insn_label
= NULL
;
3650 alpha_auto_align_on
= 1;
3651 alpha_current_align
= 0;
3658 /* Handle the .sdata pseudo-op. This is like the usual one, but it
3659 clears alpha_insn_label and restores auto alignment. */
3662 s_alpha_sdata (int ignore ATTRIBUTE_UNUSED
)
3666 temp
= get_absolute_expression ();
3667 subseg_new (".sdata", 0);
3668 demand_empty_rest_of_line ();
3669 alpha_insn_label
= NULL
;
3670 alpha_auto_align_on
= 1;
3671 alpha_current_align
= 0;
3676 struct alpha_elf_frame_data
3679 symbolS
*func_end_sym
;
3680 symbolS
*prologue_sym
;
3686 offsetT mask_offset
;
3687 offsetT fmask_offset
;
3689 struct alpha_elf_frame_data
*next
;
3692 static struct alpha_elf_frame_data
*all_frame_data
;
3693 static struct alpha_elf_frame_data
**plast_frame_data
= &all_frame_data
;
3694 static struct alpha_elf_frame_data
*cur_frame_data
;
3696 /* Handle the .section pseudo-op. This is like the usual one, but it
3697 clears alpha_insn_label and restores auto alignment. */
3700 s_alpha_section (int ignore ATTRIBUTE_UNUSED
)
3702 obj_elf_section (ignore
);
3704 alpha_insn_label
= NULL
;
3705 alpha_auto_align_on
= 1;
3706 alpha_current_align
= 0;
3710 s_alpha_ent (int dummy ATTRIBUTE_UNUSED
)
3712 if (ECOFF_DEBUGGING
)
3713 ecoff_directive_ent (0);
3716 char *name
, name_end
;
3717 name
= input_line_pointer
;
3718 name_end
= get_symbol_end ();
3720 if (! is_name_beginner (*name
))
3722 as_warn (_(".ent directive has no name"));
3723 *input_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
= (struct alpha_elf_frame_data
*)
3736 calloc (1, sizeof (*cur_frame_data
));
3737 cur_frame_data
->func_sym
= sym
;
3739 /* Provide sensible defaults. */
3740 cur_frame_data
->fp_regno
= 30; /* sp */
3741 cur_frame_data
->ra_regno
= 26; /* ra */
3743 *plast_frame_data
= cur_frame_data
;
3744 plast_frame_data
= &cur_frame_data
->next
;
3746 /* The .ent directive is sometimes followed by a number. Not sure
3747 what it really means, but ignore it. */
3748 *input_line_pointer
= name_end
;
3750 if (*input_line_pointer
== ',')
3752 input_line_pointer
++;
3755 if (ISDIGIT (*input_line_pointer
) || *input_line_pointer
== '-')
3756 (void) get_absolute_expression ();
3758 demand_empty_rest_of_line ();
3763 s_alpha_end (int dummy ATTRIBUTE_UNUSED
)
3765 if (ECOFF_DEBUGGING
)
3766 ecoff_directive_end (0);
3769 char *name
, name_end
;
3770 name
= input_line_pointer
;
3771 name_end
= get_symbol_end ();
3773 if (! is_name_beginner (*name
))
3775 as_warn (_(".end directive has no name"));
3776 *input_line_pointer
= name_end
;
3782 sym
= symbol_find (name
);
3783 if (!cur_frame_data
)
3784 as_warn (_(".end directive without matching .ent"));
3785 else if (sym
!= cur_frame_data
->func_sym
)
3786 as_warn (_(".end directive names different symbol than .ent"));
3788 /* Create an expression to calculate the size of the function. */
3789 if (sym
&& cur_frame_data
)
3791 OBJ_SYMFIELD_TYPE
*obj
= symbol_get_obj (sym
);
3792 expressionS
*exp
= (expressionS
*) xmalloc (sizeof (expressionS
));
3795 exp
->X_op
= O_subtract
;
3796 exp
->X_add_symbol
= symbol_temp_new_now ();
3797 exp
->X_op_symbol
= sym
;
3798 exp
->X_add_number
= 0;
3800 cur_frame_data
->func_end_sym
= exp
->X_add_symbol
;
3803 cur_frame_data
= NULL
;
3805 *input_line_pointer
= name_end
;
3807 demand_empty_rest_of_line ();
3812 s_alpha_mask (int fp
)
3814 if (ECOFF_DEBUGGING
)
3817 ecoff_directive_fmask (0);
3819 ecoff_directive_mask (0);
3826 if (!cur_frame_data
)
3829 as_warn (_(".fmask outside of .ent"));
3831 as_warn (_(".mask outside of .ent"));
3832 discard_rest_of_line ();
3836 if (get_absolute_expression_and_terminator (&val
) != ',')
3839 as_warn (_("bad .fmask directive"));
3841 as_warn (_("bad .mask directive"));
3842 --input_line_pointer
;
3843 discard_rest_of_line ();
3847 offset
= get_absolute_expression ();
3848 demand_empty_rest_of_line ();
3852 cur_frame_data
->fmask
= val
;
3853 cur_frame_data
->fmask_offset
= offset
;
3857 cur_frame_data
->mask
= val
;
3858 cur_frame_data
->mask_offset
= offset
;
3864 s_alpha_frame (int dummy ATTRIBUTE_UNUSED
)
3866 if (ECOFF_DEBUGGING
)
3867 ecoff_directive_frame (0);
3872 if (!cur_frame_data
)
3874 as_warn (_(".frame outside of .ent"));
3875 discard_rest_of_line ();
3879 cur_frame_data
->fp_regno
= tc_get_register (1);
3882 if (*input_line_pointer
++ != ','
3883 || get_absolute_expression_and_terminator (&val
) != ',')
3885 as_warn (_("bad .frame directive"));
3886 --input_line_pointer
;
3887 discard_rest_of_line ();
3890 cur_frame_data
->frame_size
= val
;
3892 cur_frame_data
->ra_regno
= tc_get_register (0);
3894 /* Next comes the "offset of saved $a0 from $sp". In gcc terms
3895 this is current_function_pretend_args_size. There's no place
3896 to put this value, so ignore it. */
3902 s_alpha_prologue (int ignore ATTRIBUTE_UNUSED
)
3907 arg
= get_absolute_expression ();
3908 demand_empty_rest_of_line ();
3909 alpha_prologue_label
= symbol_new
3910 (FAKE_LABEL_NAME
, now_seg
, (valueT
) frag_now_fix (), frag_now
);
3912 if (ECOFF_DEBUGGING
)
3913 sym
= ecoff_get_cur_proc_sym ();
3915 sym
= cur_frame_data
? cur_frame_data
->func_sym
: NULL
;
3919 as_bad (_(".prologue directive without a preceding .ent directive"));
3925 case 0: /* No PV required. */
3926 S_SET_OTHER (sym
, STO_ALPHA_NOPV
3927 | (S_GET_OTHER (sym
) & ~STO_ALPHA_STD_GPLOAD
));
3929 case 1: /* Std GP load. */
3930 S_SET_OTHER (sym
, STO_ALPHA_STD_GPLOAD
3931 | (S_GET_OTHER (sym
) & ~STO_ALPHA_STD_GPLOAD
));
3933 case 2: /* Non-std use of PV. */
3937 as_bad (_("Invalid argument %d to .prologue."), arg
);
3942 cur_frame_data
->prologue_sym
= symbol_temp_new_now ();
3945 static char *first_file_directive
;
3948 s_alpha_file (int ignore ATTRIBUTE_UNUSED
)
3950 /* Save the first .file directive we see, so that we can change our
3951 minds about whether ecoff debugging should or shouldn't be enabled. */
3952 if (alpha_flag_mdebug
< 0 && ! first_file_directive
)
3954 char *start
= input_line_pointer
;
3957 discard_rest_of_line ();
3959 len
= input_line_pointer
- start
;
3960 first_file_directive
= (char *) xmalloc (len
+ 1);
3961 memcpy (first_file_directive
, start
, len
);
3962 first_file_directive
[len
] = '\0';
3964 input_line_pointer
= start
;
3967 if (ECOFF_DEBUGGING
)
3968 ecoff_directive_file (0);
3970 dwarf2_directive_file (0);
3974 s_alpha_loc (int ignore ATTRIBUTE_UNUSED
)
3976 if (ECOFF_DEBUGGING
)
3977 ecoff_directive_loc (0);
3979 dwarf2_directive_loc (0);
3983 s_alpha_stab (int n
)
3985 /* If we've been undecided about mdebug, make up our minds in favour. */
3986 if (alpha_flag_mdebug
< 0)
3988 segT sec
= subseg_new (".mdebug", 0);
3989 bfd_set_section_flags (stdoutput
, sec
, SEC_HAS_CONTENTS
| SEC_READONLY
);
3990 bfd_set_section_alignment (stdoutput
, sec
, 3);
3992 ecoff_read_begin_hook ();
3994 if (first_file_directive
)
3996 char *save_ilp
= input_line_pointer
;
3997 input_line_pointer
= first_file_directive
;
3998 ecoff_directive_file (0);
3999 input_line_pointer
= save_ilp
;
4000 free (first_file_directive
);
4003 alpha_flag_mdebug
= 1;
4009 s_alpha_coff_wrapper (int which
)
4011 static void (* const fns
[]) (int) = {
4012 ecoff_directive_begin
,
4013 ecoff_directive_bend
,
4014 ecoff_directive_def
,
4015 ecoff_directive_dim
,
4016 ecoff_directive_endef
,
4017 ecoff_directive_scl
,
4018 ecoff_directive_tag
,
4019 ecoff_directive_val
,
4022 gas_assert (which
>= 0 && which
< (int) (sizeof (fns
)/sizeof (*fns
)));
4024 if (ECOFF_DEBUGGING
)
4028 as_bad (_("ECOFF debugging is disabled."));
4029 ignore_rest_of_line ();
4033 /* Called at the end of assembly. Here we emit unwind info for frames
4034 unless the compiler has done it for us. */
4037 alpha_elf_md_end (void)
4039 struct alpha_elf_frame_data
*p
;
4042 as_warn (_(".ent directive without matching .end"));
4044 /* If someone has generated the unwind info themselves, great. */
4045 if (bfd_get_section_by_name (stdoutput
, ".eh_frame") != NULL
)
4048 /* Generate .eh_frame data for the unwind directives specified. */
4049 for (p
= all_frame_data
; p
; p
= p
->next
)
4050 if (p
->prologue_sym
)
4052 /* Create a temporary symbol at the same location as our
4053 function symbol. This prevents problems with globals. */
4054 cfi_new_fde (symbol_temp_new (S_GET_SEGMENT (p
->func_sym
),
4055 S_GET_VALUE (p
->func_sym
),
4056 symbol_get_frag (p
->func_sym
)));
4058 cfi_set_return_column (p
->ra_regno
);
4059 cfi_add_CFA_def_cfa_register (30);
4060 if (p
->fp_regno
!= 30 || p
->mask
|| p
->fmask
|| p
->frame_size
)
4065 cfi_add_advance_loc (p
->prologue_sym
);
4067 if (p
->fp_regno
!= 30)
4068 if (p
->frame_size
!= 0)
4069 cfi_add_CFA_def_cfa (p
->fp_regno
, p
->frame_size
);
4071 cfi_add_CFA_def_cfa_register (p
->fp_regno
);
4072 else if (p
->frame_size
!= 0)
4073 cfi_add_CFA_def_cfa_offset (p
->frame_size
);
4076 offset
= p
->mask_offset
;
4078 /* Recall that $26 is special-cased and stored first. */
4079 if ((mask
>> 26) & 1)
4081 cfi_add_CFA_offset (26, offset
);
4092 cfi_add_CFA_offset (i
, offset
);
4097 offset
= p
->fmask_offset
;
4105 cfi_add_CFA_offset (i
+ 32, offset
);
4110 cfi_end_fde (p
->func_end_sym
);
4115 s_alpha_usepv (int unused ATTRIBUTE_UNUSED
)
4117 char *name
, name_end
;
4118 char *which
, which_end
;
4122 name
= input_line_pointer
;
4123 name_end
= get_symbol_end ();
4125 if (! is_name_beginner (*name
))
4127 as_bad (_(".usepv directive has no name"));
4128 *input_line_pointer
= name_end
;
4129 ignore_rest_of_line ();
4133 sym
= symbol_find_or_make (name
);
4134 *input_line_pointer
++ = name_end
;
4136 if (name_end
!= ',')
4138 as_bad (_(".usepv directive has no type"));
4139 ignore_rest_of_line ();
4144 which
= input_line_pointer
;
4145 which_end
= get_symbol_end ();
4147 if (strcmp (which
, "no") == 0)
4148 other
= STO_ALPHA_NOPV
;
4149 else if (strcmp (which
, "std") == 0)
4150 other
= STO_ALPHA_STD_GPLOAD
;
4153 as_bad (_("unknown argument for .usepv"));
4157 *input_line_pointer
= which_end
;
4158 demand_empty_rest_of_line ();
4160 S_SET_OTHER (sym
, other
| (S_GET_OTHER (sym
) & ~STO_ALPHA_STD_GPLOAD
));
4162 #endif /* OBJ_ELF */
4164 /* Standard calling conventions leaves the CFA at $30 on entry. */
4167 alpha_cfi_frame_initial_instructions (void)
4169 cfi_add_CFA_def_cfa_register (30);
4174 /* Get name of section. */
4176 s_alpha_section_name (void)
4181 if (*input_line_pointer
== '"')
4185 name
= demand_copy_C_string (&dummy
);
4188 ignore_rest_of_line ();
4194 char *end
= input_line_pointer
;
4196 while (0 == strchr ("\n\t,; ", *end
))
4198 if (end
== input_line_pointer
)
4200 as_warn (_("missing name"));
4201 ignore_rest_of_line ();
4205 name
= xmalloc (end
- input_line_pointer
+ 1);
4206 memcpy (name
, input_line_pointer
, end
- input_line_pointer
);
4207 name
[end
- input_line_pointer
] = '\0';
4208 input_line_pointer
= end
;
4214 /* Put clear/set flags in one flagword. The LSBs are flags to be set,
4215 the MSBs are the flags to be cleared. */
4217 #define EGPS__V_NO_SHIFT 16
4218 #define EGPS__V_MASK 0xffff
4220 /* Parse one VMS section flag. */
4223 s_alpha_section_word (char *str
, size_t len
)
4228 if (len
== 5 && strncmp (str
, "NO", 2) == 0)
4237 if (strncmp (str
, "PIC", 3) == 0)
4239 else if (strncmp (str
, "LIB", 3) == 0)
4241 else if (strncmp (str
, "OVR", 3) == 0)
4243 else if (strncmp (str
, "REL", 3) == 0)
4245 else if (strncmp (str
, "GBL", 3) == 0)
4247 else if (strncmp (str
, "SHR", 3) == 0)
4249 else if (strncmp (str
, "EXE", 3) == 0)
4251 else if (strncmp (str
, "WRT", 3) == 0)
4253 else if (strncmp (str
, "VEC", 3) == 0)
4255 else if (strncmp (str
, "MOD", 3) == 0)
4257 flag
= no
? EGPS__V_NOMOD
: EGPS__V_NOMOD
<< EGPS__V_NO_SHIFT
;
4260 else if (strncmp (str
, "COM", 3) == 0)
4268 as_warn (_("unknown section attribute %s"), str
);
4274 return flag
<< EGPS__V_NO_SHIFT
;
4279 /* Handle the section specific pseudo-op. */
4281 #define EVAX_SECTION_COUNT 5
4283 static char *section_name
[EVAX_SECTION_COUNT
+ 1] =
4284 { "NULL", ".rdata", ".comm", ".link", ".ctors", ".dtors" };
4287 s_alpha_section (int secid
)
4292 flagword vms_flags
= 0;
4297 name
= s_alpha_section_name ();
4300 sec
= subseg_new (name
, 0);
4301 if (*input_line_pointer
== ',')
4303 /* Skip the comma. */
4304 ++input_line_pointer
;
4312 beg
= input_line_pointer
;
4313 c
= get_symbol_end ();
4314 *input_line_pointer
= c
;
4316 vms_flags
|= s_alpha_section_word (beg
, input_line_pointer
- beg
);
4320 while (*input_line_pointer
++ == ',');
4321 --input_line_pointer
;
4324 symbol
= symbol_find_or_make (name
);
4325 S_SET_SEGMENT (symbol
, sec
);
4326 symbol_get_bfdsym (symbol
)->flags
|= BSF_SECTION_SYM
;
4327 bfd_vms_set_section_flags
4329 (vms_flags
>> EGPS__V_NO_SHIFT
) & EGPS__V_MASK
,
4330 vms_flags
& EGPS__V_MASK
);
4334 temp
= get_absolute_expression ();
4335 subseg_new (section_name
[secid
], 0);
4338 demand_empty_rest_of_line ();
4339 alpha_insn_label
= NULL
;
4340 alpha_auto_align_on
= 1;
4341 alpha_current_align
= 0;
4345 s_alpha_literals (int ignore ATTRIBUTE_UNUSED
)
4347 subseg_new (".literals", 0);
4348 demand_empty_rest_of_line ();
4349 alpha_insn_label
= NULL
;
4350 alpha_auto_align_on
= 1;
4351 alpha_current_align
= 0;
4354 /* Parse .ent directives. */
4357 s_alpha_ent (int ignore ATTRIBUTE_UNUSED
)
4360 expressionS symexpr
;
4363 = (struct alpha_evax_procs
*) xmalloc (sizeof (struct alpha_evax_procs
));
4365 alpha_evax_proc
->pdsckind
= 0;
4366 alpha_evax_proc
->framereg
= -1;
4367 alpha_evax_proc
->framesize
= 0;
4368 alpha_evax_proc
->rsa_offset
= 0;
4369 alpha_evax_proc
->ra_save
= AXP_REG_RA
;
4370 alpha_evax_proc
->fp_save
= -1;
4371 alpha_evax_proc
->imask
= 0;
4372 alpha_evax_proc
->fmask
= 0;
4373 alpha_evax_proc
->prologue
= 0;
4374 alpha_evax_proc
->type
= 0;
4375 alpha_evax_proc
->handler
= 0;
4376 alpha_evax_proc
->handler_data
= 0;
4378 expression (&symexpr
);
4380 if (symexpr
.X_op
!= O_symbol
)
4382 as_fatal (_(".ent directive has no symbol"));
4383 demand_empty_rest_of_line ();
4387 symbol
= make_expr_symbol (&symexpr
);
4388 symbol_get_bfdsym (symbol
)->flags
|= BSF_FUNCTION
;
4389 alpha_evax_proc
->symbol
= symbol
;
4392 (alpha_evax_proc_hash
,
4393 symbol_get_bfdsym (alpha_evax_proc
->symbol
)->name
, (PTR
)alpha_evax_proc
);
4395 demand_empty_rest_of_line ();
4399 s_alpha_handler (int is_data
)
4402 alpha_evax_proc
->handler_data
= get_absolute_expression ();
4405 char *name
, name_end
;
4406 name
= input_line_pointer
;
4407 name_end
= get_symbol_end ();
4409 if (! is_name_beginner (*name
))
4411 as_warn (_(".handler directive has no name"));
4412 *input_line_pointer
= name_end
;
4418 sym
= symbol_find_or_make (name
);
4419 symbol_get_bfdsym (sym
)->flags
|= BSF_FUNCTION
;
4420 alpha_evax_proc
->handler
= sym
;
4421 *input_line_pointer
= name_end
;
4424 demand_empty_rest_of_line ();
4427 /* Parse .frame <framreg>,<framesize>,RA,<rsa_offset> directives. */
4430 s_alpha_frame (int ignore ATTRIBUTE_UNUSED
)
4434 alpha_evax_proc
->framereg
= tc_get_register (1);
4437 if (*input_line_pointer
++ != ','
4438 || get_absolute_expression_and_terminator (&val
) != ',')
4440 as_warn (_("Bad .frame directive 1./2. param"));
4441 --input_line_pointer
;
4442 demand_empty_rest_of_line ();
4446 alpha_evax_proc
->framesize
= val
;
4448 (void) tc_get_register (1);
4450 if (*input_line_pointer
++ != ',')
4452 as_warn (_("Bad .frame directive 3./4. param"));
4453 --input_line_pointer
;
4454 demand_empty_rest_of_line ();
4457 alpha_evax_proc
->rsa_offset
= get_absolute_expression ();
4461 s_alpha_prologue (int ignore ATTRIBUTE_UNUSED
)
4465 arg
= get_absolute_expression ();
4466 demand_empty_rest_of_line ();
4467 alpha_prologue_label
= symbol_new
4468 (FAKE_LABEL_NAME
, now_seg
, (valueT
) frag_now_fix (), frag_now
);
4472 s_alpha_pdesc (int ignore ATTRIBUTE_UNUSED
)
4480 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
4481 const char *entry_sym_name
;
4485 if (now_seg
!= alpha_link_section
)
4487 as_bad (_(".pdesc directive not in link (.link) section"));
4488 demand_empty_rest_of_line ();
4493 if (exp
.X_op
!= O_symbol
)
4495 as_warn (_(".pdesc directive has no entry symbol"));
4496 demand_empty_rest_of_line ();
4500 entry_sym
= make_expr_symbol (&exp
);
4501 entry_sym_name
= symbol_get_bfdsym (entry_sym
)->name
;
4503 len
= strlen (entry_sym_name
);
4504 sym_name
= (char *) xmalloc (len
- 4 + 1);
4505 strncpy (sym_name
, entry_sym_name
, len
- 4);
4506 sym_name
[len
- 4] = 0;
4508 alpha_evax_proc
= (struct alpha_evax_procs
*)
4509 hash_find (alpha_evax_proc_hash
, sym_name
);
4511 if (!alpha_evax_proc
|| !S_IS_DEFINED (alpha_evax_proc
->symbol
))
4513 as_fatal (_(".pdesc has no matching .ent"));
4514 demand_empty_rest_of_line ();
4518 *symbol_get_obj (alpha_evax_proc
->symbol
) =
4519 (valueT
) seginfo
->literal_pool_size
;
4521 alpha_evax_proc
->symbol
->sy_obj
= (valueT
)seginfo
->literal_pool_size
;
4523 /* Save bfd symbol of proc entry in function symbol. */
4524 ((struct evax_private_udata_struct
*)
4525 symbol_get_bfdsym (alpha_evax_proc
->symbol
)->udata
.p
)->enbsym
4526 = symbol_get_bfdsym (entry_sym
);
4529 if (*input_line_pointer
++ != ',')
4531 as_warn (_("No comma after .pdesc <entryname>"));
4532 demand_empty_rest_of_line ();
4537 name
= input_line_pointer
;
4538 name_end
= get_symbol_end ();
4540 if (strncmp (name
, "stack", 5) == 0)
4541 alpha_evax_proc
->pdsckind
= PDSC_S_K_KIND_FP_STACK
;
4543 else if (strncmp (name
, "reg", 3) == 0)
4544 alpha_evax_proc
->pdsckind
= PDSC_S_K_KIND_FP_REGISTER
;
4546 else if (strncmp (name
, "null", 4) == 0)
4547 alpha_evax_proc
->pdsckind
= PDSC_S_K_KIND_NULL
;
4551 as_fatal (_("unknown procedure kind"));
4552 demand_empty_rest_of_line ();
4556 *input_line_pointer
= name_end
;
4557 demand_empty_rest_of_line ();
4559 #ifdef md_flush_pending_output
4560 md_flush_pending_output ();
4563 frag_align (3, 0, 0);
4565 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
4567 seginfo
->literal_pool_size
+= 16;
4569 *p
= alpha_evax_proc
->pdsckind
4570 | ((alpha_evax_proc
->framereg
== 29) ? PDSC_S_M_BASE_REG_IS_FP
: 0)
4571 | ((alpha_evax_proc
->handler
) ? PDSC_S_M_HANDLER_VALID
: 0)
4572 | ((alpha_evax_proc
->handler_data
) ? PDSC_S_M_HANDLER_DATA_VALID
: 0);
4573 *(p
+ 1) = PDSC_S_M_NATIVE
| PDSC_S_M_NO_JACKET
;
4575 switch (alpha_evax_proc
->pdsckind
)
4577 case PDSC_S_K_KIND_NULL
:
4581 case PDSC_S_K_KIND_FP_REGISTER
:
4582 *(p
+ 2) = alpha_evax_proc
->fp_save
;
4583 *(p
+ 3) = alpha_evax_proc
->ra_save
;
4585 case PDSC_S_K_KIND_FP_STACK
:
4586 md_number_to_chars (p
+ 2, (valueT
) alpha_evax_proc
->rsa_offset
, 2);
4588 default: /* impossible */
4593 *(p
+ 5) = alpha_evax_proc
->type
& 0x0f;
4595 /* Signature offset. */
4596 md_number_to_chars (p
+ 6, (valueT
) 0, 2);
4598 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
+8, 8, &exp
, 0, BFD_RELOC_64
);
4600 if (alpha_evax_proc
->pdsckind
== PDSC_S_K_KIND_NULL
)
4603 /* Add dummy fix to make add_to_link_pool work. */
4605 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 6, 0, 0, 0, 0);
4607 seginfo
->literal_pool_size
+= 6;
4609 /* pdesc+16: Size. */
4610 md_number_to_chars (p
, (valueT
) alpha_evax_proc
->framesize
, 4);
4612 md_number_to_chars (p
+ 4, (valueT
) 0, 2);
4615 exp
.X_op
= O_subtract
;
4616 exp
.X_add_symbol
= alpha_prologue_label
;
4617 exp
.X_op_symbol
= entry_sym
;
4618 emit_expr (&exp
, 2);
4620 if (alpha_evax_proc
->pdsckind
== PDSC_S_K_KIND_FP_REGISTER
)
4623 /* Add dummy fix to make add_to_link_pool work. */
4625 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
4627 seginfo
->literal_pool_size
+= 8;
4629 /* pdesc+24: register masks. */
4631 md_number_to_chars (p
, alpha_evax_proc
->imask
, 4);
4632 md_number_to_chars (p
+ 4, alpha_evax_proc
->fmask
, 4);
4634 if (alpha_evax_proc
->handler
)
4637 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8,
4638 alpha_evax_proc
->handler
, 0, 0, BFD_RELOC_64
);
4641 if (alpha_evax_proc
->handler_data
)
4643 /* Add dummy fix to make add_to_link_pool work. */
4645 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
4647 seginfo
->literal_pool_size
+= 8;
4648 md_number_to_chars (p
, alpha_evax_proc
->handler_data
, 8);
4652 /* Support for crash debug on vms. */
4655 s_alpha_name (int ignore ATTRIBUTE_UNUSED
)
4659 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
4661 if (now_seg
!= alpha_link_section
)
4663 as_bad (_(".name directive not in link (.link) section"));
4664 demand_empty_rest_of_line ();
4669 if (exp
.X_op
!= O_symbol
)
4671 as_warn (_(".name directive has no symbol"));
4672 demand_empty_rest_of_line ();
4676 demand_empty_rest_of_line ();
4678 #ifdef md_flush_pending_output
4679 md_flush_pending_output ();
4682 frag_align (3, 0, 0);
4684 seginfo
->literal_pool_size
+= 8;
4686 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 8, &exp
, 0, BFD_RELOC_64
);
4690 s_alpha_linkage (int ignore ATTRIBUTE_UNUSED
)
4696 #ifdef md_flush_pending_output
4697 md_flush_pending_output ();
4701 if (exp
.X_op
!= O_symbol
)
4703 as_fatal (_("No symbol after .linkage"));
4707 struct alpha_linkage_fixups
*linkage_fixup
;
4709 p
= frag_more (LKP_S_K_SIZE
);
4710 memset (p
, 0, LKP_S_K_SIZE
);
4712 (frag_now
, p
- frag_now
->fr_literal
, LKP_S_K_SIZE
, &exp
, 0,\
4713 BFD_RELOC_ALPHA_LINKAGE
);
4715 linkage_fixup
= (struct alpha_linkage_fixups
*)
4716 xmalloc (sizeof (struct alpha_linkage_fixups
));
4718 linkage_fixup
->fixp
= fixp
;
4719 linkage_fixup
->next
= 0;
4721 if (alpha_insn_label
== 0)
4722 alpha_insn_label
= symbol_new
4723 (FAKE_LABEL_NAME
, now_seg
, (valueT
) frag_now_fix (), frag_now
);
4724 linkage_fixup
->label
= alpha_insn_label
;
4726 if (alpha_linkage_fixup_root
== 0)
4728 alpha_linkage_fixup_root
= alpha_linkage_fixup_tail
= linkage_fixup
;
4729 alpha_linkage_fixup_tail
->next
= 0;
4733 alpha_linkage_fixup_tail
->next
= linkage_fixup
;
4734 alpha_linkage_fixup_tail
= linkage_fixup
;
4735 alpha_linkage_fixup_tail
->next
= 0;
4738 demand_empty_rest_of_line ();
4742 s_alpha_code_address (int ignore ATTRIBUTE_UNUSED
)
4747 #ifdef md_flush_pending_output
4748 md_flush_pending_output ();
4752 if (exp
.X_op
!= O_symbol
)
4753 as_fatal (_("No symbol after .code_address"));
4758 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 8, &exp
, 0,\
4759 BFD_RELOC_ALPHA_CODEADDR
);
4761 demand_empty_rest_of_line ();
4765 s_alpha_fp_save (int ignore ATTRIBUTE_UNUSED
)
4768 alpha_evax_proc
->fp_save
= tc_get_register (1);
4770 demand_empty_rest_of_line ();
4774 s_alpha_mask (int ignore ATTRIBUTE_UNUSED
)
4778 if (get_absolute_expression_and_terminator (&val
) != ',')
4780 as_warn (_("Bad .mask directive"));
4781 --input_line_pointer
;
4785 alpha_evax_proc
->imask
= val
;
4786 (void) get_absolute_expression ();
4788 demand_empty_rest_of_line ();
4792 s_alpha_fmask (int ignore ATTRIBUTE_UNUSED
)
4796 if (get_absolute_expression_and_terminator (&val
) != ',')
4798 as_warn (_("Bad .fmask directive"));
4799 --input_line_pointer
;
4803 alpha_evax_proc
->fmask
= val
;
4804 (void) get_absolute_expression ();
4806 demand_empty_rest_of_line ();
4810 s_alpha_end (int ignore ATTRIBUTE_UNUSED
)
4814 c
= get_symbol_end ();
4815 *input_line_pointer
= c
;
4816 demand_empty_rest_of_line ();
4817 alpha_evax_proc
= 0;
4821 s_alpha_file (int ignore ATTRIBUTE_UNUSED
)
4825 static char case_hack
[32];
4827 sprintf (case_hack
, "<CASE:%01d%01d>",
4828 alpha_flag_hash_long_names
, alpha_flag_show_after_trunc
);
4830 s
= symbol_find_or_make (case_hack
);
4831 symbol_get_bfdsym (s
)->flags
|= BSF_FILE
;
4833 get_absolute_expression ();
4834 s
= symbol_find_or_make (demand_copy_string (&length
));
4835 symbol_get_bfdsym (s
)->flags
|= BSF_FILE
;
4836 demand_empty_rest_of_line ();
4838 #endif /* OBJ_EVAX */
4840 /* Handle the .gprel32 pseudo op. */
4843 s_alpha_gprel32 (int ignore ATTRIBUTE_UNUSED
)
4855 e
.X_add_symbol
= section_symbol (absolute_section
);
4868 e
.X_add_symbol
= section_symbol (absolute_section
);
4871 e
.X_op
= O_subtract
;
4872 e
.X_op_symbol
= alpha_gp_symbol
;
4880 if (alpha_auto_align_on
&& alpha_current_align
< 2)
4881 alpha_align (2, (char *) NULL
, alpha_insn_label
, 0);
4882 if (alpha_current_align
> 2)
4883 alpha_current_align
= 2;
4884 alpha_insn_label
= NULL
;
4888 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 4,
4889 &e
, 0, BFD_RELOC_GPREL32
);
4892 /* Handle floating point allocation pseudo-ops. This is like the
4893 generic vresion, but it makes sure the current label, if any, is
4894 correctly aligned. */
4897 s_alpha_float_cons (int type
)
4923 if (alpha_auto_align_on
&& alpha_current_align
< log_size
)
4924 alpha_align (log_size
, (char *) NULL
, alpha_insn_label
, 0);
4925 if (alpha_current_align
> log_size
)
4926 alpha_current_align
= log_size
;
4927 alpha_insn_label
= NULL
;
4932 /* Handle the .proc pseudo op. We don't really do much with it except
4936 s_alpha_proc (int is_static ATTRIBUTE_UNUSED
)
4944 /* Takes ".proc name,nargs". */
4946 name
= input_line_pointer
;
4947 c
= get_symbol_end ();
4948 p
= input_line_pointer
;
4949 symbolP
= symbol_find_or_make (name
);
4952 if (*input_line_pointer
!= ',')
4955 as_warn (_("Expected comma after name \"%s\""), name
);
4958 ignore_rest_of_line ();
4962 input_line_pointer
++;
4963 temp
= get_absolute_expression ();
4965 /* *symbol_get_obj (symbolP) = (signed char) temp; */
4966 as_warn (_("unhandled: .proc %s,%d"), name
, temp
);
4967 demand_empty_rest_of_line ();
4970 /* Handle the .set pseudo op. This is used to turn on and off most of
4971 the assembler features. */
4974 s_alpha_set (int x ATTRIBUTE_UNUSED
)
4980 name
= input_line_pointer
;
4981 ch
= get_symbol_end ();
4984 if (s
[0] == 'n' && s
[1] == 'o')
4989 if (!strcmp ("reorder", s
))
4991 else if (!strcmp ("at", s
))
4992 alpha_noat_on
= !yesno
;
4993 else if (!strcmp ("macro", s
))
4994 alpha_macros_on
= yesno
;
4995 else if (!strcmp ("move", s
))
4997 else if (!strcmp ("volatile", s
))
5000 as_warn (_("Tried to .set unrecognized mode `%s'"), name
);
5002 *input_line_pointer
= ch
;
5003 demand_empty_rest_of_line ();
5006 /* Handle the .base pseudo op. This changes the assembler's notion of
5007 the $gp register. */
5010 s_alpha_base (int ignore ATTRIBUTE_UNUSED
)
5014 if (*input_line_pointer
== '$')
5017 input_line_pointer
++;
5018 if (*input_line_pointer
== 'r')
5019 input_line_pointer
++;
5022 alpha_gp_register
= get_absolute_expression ();
5023 if (alpha_gp_register
< 0 || alpha_gp_register
> 31)
5025 alpha_gp_register
= AXP_REG_GP
;
5026 as_warn (_("Bad base register, using $%d."), alpha_gp_register
);
5029 demand_empty_rest_of_line ();
5032 /* Handle the .align pseudo-op. This aligns to a power of two. It
5033 also adjusts any current instruction label. We treat this the same
5034 way the MIPS port does: .align 0 turns off auto alignment. */
5037 s_alpha_align (int ignore ATTRIBUTE_UNUSED
)
5041 long max_alignment
= 16;
5043 align
= get_absolute_expression ();
5044 if (align
> max_alignment
)
5046 align
= max_alignment
;
5047 as_bad (_("Alignment too large: %d. assumed"), align
);
5051 as_warn (_("Alignment negative: 0 assumed"));
5055 if (*input_line_pointer
== ',')
5057 input_line_pointer
++;
5058 fill
= get_absolute_expression ();
5066 alpha_auto_align_on
= 1;
5067 alpha_align (align
, pfill
, alpha_insn_label
, 1);
5071 alpha_auto_align_on
= 0;
5074 demand_empty_rest_of_line ();
5077 /* Hook the normal string processor to reset known alignment. */
5080 s_alpha_stringer (int terminate
)
5082 alpha_current_align
= 0;
5083 alpha_insn_label
= NULL
;
5084 stringer (8 + terminate
);
5087 /* Hook the normal space processing to reset known alignment. */
5090 s_alpha_space (int ignore
)
5092 alpha_current_align
= 0;
5093 alpha_insn_label
= NULL
;
5097 /* Hook into cons for auto-alignment. */
5100 alpha_cons_align (int size
)
5105 while ((size
>>= 1) != 0)
5108 if (alpha_auto_align_on
&& alpha_current_align
< log_size
)
5109 alpha_align (log_size
, (char *) NULL
, alpha_insn_label
, 0);
5110 if (alpha_current_align
> log_size
)
5111 alpha_current_align
= log_size
;
5112 alpha_insn_label
= NULL
;
5115 /* Here come the .uword, .ulong, and .uquad explicitly unaligned
5116 pseudos. We just turn off auto-alignment and call down to cons. */
5119 s_alpha_ucons (int bytes
)
5121 int hold
= alpha_auto_align_on
;
5122 alpha_auto_align_on
= 0;
5124 alpha_auto_align_on
= hold
;
5127 /* Switch the working cpu type. */
5130 s_alpha_arch (int ignored ATTRIBUTE_UNUSED
)
5133 const struct cpu_type
*p
;
5136 name
= input_line_pointer
;
5137 ch
= get_symbol_end ();
5139 for (p
= cpu_types
; p
->name
; ++p
)
5140 if (strcmp (name
, p
->name
) == 0)
5142 alpha_target_name
= p
->name
, alpha_target
= p
->flags
;
5145 as_warn (_("Unknown CPU identifier `%s'"), name
);
5148 *input_line_pointer
= ch
;
5149 demand_empty_rest_of_line ();
5153 /* print token expression with alpha specific extension. */
5156 alpha_print_token (FILE *f
, const expressionS
*exp
)
5166 expressionS nexp
= *exp
;
5167 nexp
.X_op
= O_register
;
5168 print_expr_1 (f
, &nexp
);
5173 print_expr_1 (f
, exp
);
5179 /* The target specific pseudo-ops which we support. */
5181 const pseudo_typeS md_pseudo_table
[] =
5184 {"comm", s_alpha_comm
, 0}, /* OSF1 compiler does this. */
5185 {"rdata", s_alpha_rdata
, 0},
5187 {"text", s_alpha_text
, 0},
5188 {"data", s_alpha_data
, 0},
5190 {"sdata", s_alpha_sdata
, 0},
5193 {"section", s_alpha_section
, 0},
5194 {"section.s", s_alpha_section
, 0},
5195 {"sect", s_alpha_section
, 0},
5196 {"sect.s", s_alpha_section
, 0},
5199 {"section", s_alpha_section
, 0},
5200 {"literals", s_alpha_literals
, 0},
5201 {"pdesc", s_alpha_pdesc
, 0},
5202 {"name", s_alpha_name
, 0},
5203 {"linkage", s_alpha_linkage
, 0},
5204 {"code_address", s_alpha_code_address
, 0},
5205 {"ent", s_alpha_ent
, 0},
5206 {"frame", s_alpha_frame
, 0},
5207 {"fp_save", s_alpha_fp_save
, 0},
5208 {"mask", s_alpha_mask
, 0},
5209 {"fmask", s_alpha_fmask
, 0},
5210 {"end", s_alpha_end
, 0},
5211 {"file", s_alpha_file
, 0},
5212 {"rdata", s_alpha_section
, 1},
5213 {"comm", s_alpha_comm
, 0},
5214 {"link", s_alpha_section
, 3},
5215 {"ctors", s_alpha_section
, 4},
5216 {"dtors", s_alpha_section
, 5},
5217 {"handler", s_alpha_handler
, 0},
5218 {"handler_data", s_alpha_handler
, 1},
5221 /* Frame related pseudos. */
5222 {"ent", s_alpha_ent
, 0},
5223 {"end", s_alpha_end
, 0},
5224 {"mask", s_alpha_mask
, 0},
5225 {"fmask", s_alpha_mask
, 1},
5226 {"frame", s_alpha_frame
, 0},
5227 {"prologue", s_alpha_prologue
, 0},
5228 {"file", s_alpha_file
, 5},
5229 {"loc", s_alpha_loc
, 9},
5230 {"stabs", s_alpha_stab
, 's'},
5231 {"stabn", s_alpha_stab
, 'n'},
5232 {"usepv", s_alpha_usepv
, 0},
5233 /* COFF debugging related pseudos. */
5234 {"begin", s_alpha_coff_wrapper
, 0},
5235 {"bend", s_alpha_coff_wrapper
, 1},
5236 {"def", s_alpha_coff_wrapper
, 2},
5237 {"dim", s_alpha_coff_wrapper
, 3},
5238 {"endef", s_alpha_coff_wrapper
, 4},
5239 {"scl", s_alpha_coff_wrapper
, 5},
5240 {"tag", s_alpha_coff_wrapper
, 6},
5241 {"val", s_alpha_coff_wrapper
, 7},
5244 {"prologue", s_alpha_prologue
, 0},
5246 {"prologue", s_ignore
, 0},
5249 {"gprel32", s_alpha_gprel32
, 0},
5250 {"t_floating", s_alpha_float_cons
, 'd'},
5251 {"s_floating", s_alpha_float_cons
, 'f'},
5252 {"f_floating", s_alpha_float_cons
, 'F'},
5253 {"g_floating", s_alpha_float_cons
, 'G'},
5254 {"d_floating", s_alpha_float_cons
, 'D'},
5256 {"proc", s_alpha_proc
, 0},
5257 {"aproc", s_alpha_proc
, 1},
5258 {"set", s_alpha_set
, 0},
5259 {"reguse", s_ignore
, 0},
5260 {"livereg", s_ignore
, 0},
5261 {"base", s_alpha_base
, 0}, /*??*/
5262 {"option", s_ignore
, 0},
5263 {"aent", s_ignore
, 0},
5264 {"ugen", s_ignore
, 0},
5265 {"eflag", s_ignore
, 0},
5267 {"align", s_alpha_align
, 0},
5268 {"double", s_alpha_float_cons
, 'd'},
5269 {"float", s_alpha_float_cons
, 'f'},
5270 {"single", s_alpha_float_cons
, 'f'},
5271 {"ascii", s_alpha_stringer
, 0},
5272 {"asciz", s_alpha_stringer
, 1},
5273 {"string", s_alpha_stringer
, 1},
5274 {"space", s_alpha_space
, 0},
5275 {"skip", s_alpha_space
, 0},
5276 {"zero", s_alpha_space
, 0},
5278 /* Unaligned data pseudos. */
5279 {"uword", s_alpha_ucons
, 2},
5280 {"ulong", s_alpha_ucons
, 4},
5281 {"uquad", s_alpha_ucons
, 8},
5284 /* Dwarf wants these versions of unaligned. */
5285 {"2byte", s_alpha_ucons
, 2},
5286 {"4byte", s_alpha_ucons
, 4},
5287 {"8byte", s_alpha_ucons
, 8},
5290 /* We don't do any optimizing, so we can safely ignore these. */
5291 {"noalias", s_ignore
, 0},
5292 {"alias", s_ignore
, 0},
5294 {"arch", s_alpha_arch
, 0},
5301 /* @@@ GP selection voodoo. All of this seems overly complicated and
5302 unnecessary; which is the primary reason it's for ECOFF only. */
5305 maybe_set_gp (asection
*sec
)
5311 vma
= bfd_get_section_vma (foo
, sec
);
5312 if (vma
&& vma
< alpha_gp_value
)
5313 alpha_gp_value
= vma
;
5317 select_gp_value (void)
5319 gas_assert (alpha_gp_value
== 0);
5321 /* Get minus-one in whatever width... */
5325 /* Select the smallest VMA of these existing sections. */
5326 maybe_set_gp (alpha_lita_section
);
5328 /* @@ Will a simple 0x8000 work here? If not, why not? */
5329 #define GP_ADJUSTMENT (0x8000 - 0x10)
5331 alpha_gp_value
+= GP_ADJUSTMENT
;
5333 S_SET_VALUE (alpha_gp_symbol
, alpha_gp_value
);
5336 printf (_("Chose GP value of %lx\n"), alpha_gp_value
);
5339 #endif /* OBJ_ECOFF */
5342 /* Map 's' to SHF_ALPHA_GPREL. */
5345 alpha_elf_section_letter (int letter
, char **ptr_msg
)
5348 return SHF_ALPHA_GPREL
;
5350 *ptr_msg
= _("Bad .section directive: want a,s,w,x,M,S,G,T in string");
5354 /* Map SHF_ALPHA_GPREL to SEC_SMALL_DATA. */
5357 alpha_elf_section_flags (flagword flags
, bfd_vma attr
, int type ATTRIBUTE_UNUSED
)
5359 if (attr
& SHF_ALPHA_GPREL
)
5360 flags
|= SEC_SMALL_DATA
;
5363 #endif /* OBJ_ELF */
5365 /* This is called from HANDLE_ALIGN in write.c. Fill in the contents
5366 of an rs_align_code fragment. */
5369 alpha_handle_align (fragS
*fragp
)
5371 static char const unop
[4] = { 0x00, 0x00, 0xfe, 0x2f };
5372 static char const nopunop
[8] =
5374 0x1f, 0x04, 0xff, 0x47,
5375 0x00, 0x00, 0xfe, 0x2f
5381 if (fragp
->fr_type
!= rs_align_code
)
5384 bytes
= fragp
->fr_next
->fr_address
- fragp
->fr_address
- fragp
->fr_fix
;
5385 p
= fragp
->fr_literal
+ fragp
->fr_fix
;
5398 memcpy (p
, unop
, 4);
5404 memcpy (p
, nopunop
, 8);
5406 fragp
->fr_fix
+= fix
;
5410 /* Public interface functions. */
5412 /* This function is called once, at assembler startup time. It sets
5413 up all the tables, etc. that the MD part of the assembler will
5414 need, that can be determined before arguments are parsed. */
5421 /* Verify that X_op field is wide enough. */
5426 gas_assert (e
.X_op
== O_max
);
5429 /* Create the opcode hash table. */
5430 alpha_opcode_hash
= hash_new ();
5432 for (i
= 0; i
< alpha_num_opcodes
;)
5434 const char *name
, *retval
, *slash
;
5436 name
= alpha_opcodes
[i
].name
;
5437 retval
= hash_insert (alpha_opcode_hash
, name
, (void *) &alpha_opcodes
[i
]);
5439 as_fatal (_("internal error: can't hash opcode `%s': %s"),
5442 /* Some opcodes include modifiers of various sorts with a "/mod"
5443 syntax, like the architecture manual suggests. However, for
5444 use with gcc at least, we also need access to those same opcodes
5447 if ((slash
= strchr (name
, '/')) != NULL
)
5449 char *p
= (char *) xmalloc (strlen (name
));
5451 memcpy (p
, name
, slash
- name
);
5452 strcpy (p
+ (slash
- name
), slash
+ 1);
5454 (void) hash_insert (alpha_opcode_hash
, p
, (void *) &alpha_opcodes
[i
]);
5455 /* Ignore failures -- the opcode table does duplicate some
5456 variants in different forms, like "hw_stq" and "hw_st/q". */
5459 while (++i
< alpha_num_opcodes
5460 && (alpha_opcodes
[i
].name
== name
5461 || !strcmp (alpha_opcodes
[i
].name
, name
)))
5465 /* Create the macro hash table. */
5466 alpha_macro_hash
= hash_new ();
5468 for (i
= 0; i
< alpha_num_macros
;)
5470 const char *name
, *retval
;
5472 name
= alpha_macros
[i
].name
;
5473 retval
= hash_insert (alpha_macro_hash
, name
, (void *) &alpha_macros
[i
]);
5475 as_fatal (_("internal error: can't hash macro `%s': %s"),
5478 while (++i
< alpha_num_macros
5479 && (alpha_macros
[i
].name
== name
5480 || !strcmp (alpha_macros
[i
].name
, name
)))
5484 /* Construct symbols for each of the registers. */
5485 for (i
= 0; i
< 32; ++i
)
5489 sprintf (name
, "$%d", i
);
5490 alpha_register_table
[i
] = symbol_create (name
, reg_section
, i
,
5491 &zero_address_frag
);
5498 sprintf (name
, "$f%d", i
- 32);
5499 alpha_register_table
[i
] = symbol_create (name
, reg_section
, i
,
5500 &zero_address_frag
);
5503 /* Create the special symbols and sections we'll be using. */
5505 /* So .sbss will get used for tiny objects. */
5506 bfd_set_gp_size (stdoutput
, g_switch_value
);
5509 create_literal_section (".lita", &alpha_lita_section
, &alpha_lita_symbol
);
5511 /* For handling the GP, create a symbol that won't be output in the
5512 symbol table. We'll edit it out of relocs later. */
5513 alpha_gp_symbol
= symbol_create ("<GP value>", alpha_lita_section
, 0x8000,
5514 &zero_address_frag
);
5518 create_literal_section (".link", &alpha_link_section
, &alpha_link_symbol
);
5519 alpha_evax_proc_hash
= hash_new ();
5523 if (ECOFF_DEBUGGING
)
5525 segT sec
= subseg_new (".mdebug", (subsegT
) 0);
5526 bfd_set_section_flags (stdoutput
, sec
, SEC_HAS_CONTENTS
| SEC_READONLY
);
5527 bfd_set_section_alignment (stdoutput
, sec
, 3);
5531 /* Create literal lookup hash table. */
5532 alpha_literal_hash
= hash_new ();
5534 subseg_set (text_section
, 0);
5537 /* The public interface to the instruction assembler. */
5540 md_assemble (char *str
)
5542 /* Current maximum is 13. */
5544 expressionS tok
[MAX_INSN_ARGS
];
5548 /* Split off the opcode. */
5549 opnamelen
= strspn (str
, "abcdefghijklmnopqrstuvwxyz_/46819");
5550 trunclen
= (opnamelen
< sizeof (opname
) - 1
5552 : sizeof (opname
) - 1);
5553 memcpy (opname
, str
, trunclen
);
5554 opname
[trunclen
] = '\0';
5556 /* Tokenize the rest of the line. */
5557 if ((ntok
= tokenize_arguments (str
+ opnamelen
, tok
, MAX_INSN_ARGS
)) < 0)
5559 if (ntok
!= TOKENIZE_ERROR_REPORT
)
5560 as_bad (_("syntax error"));
5565 /* Finish it off. */
5566 assemble_tokens (opname
, tok
, ntok
, alpha_macros_on
);
5569 /* Round up a section's size to the appropriate boundary. */
5572 md_section_align (segT seg
, valueT size
)
5574 int align
= bfd_get_section_alignment (stdoutput
, seg
);
5575 valueT mask
= ((valueT
) 1 << align
) - 1;
5577 return (size
+ mask
) & ~mask
;
5580 /* Turn a string in input_line_pointer into a floating point constant
5581 of type TYPE, and store the appropriate bytes in *LITP. The number
5582 of LITTLENUMS emitted is stored in *SIZEP. An error message is
5583 returned, or NULL on OK. */
5586 md_atof (int type
, char *litP
, int *sizeP
)
5588 extern char *vax_md_atof (int, char *, int *);
5594 /* vax_md_atof() doesn't like "G" for some reason. */
5598 return vax_md_atof (type
, litP
, sizeP
);
5601 return ieee_md_atof (type
, litP
, sizeP
, FALSE
);
5605 /* Take care of the target-specific command-line options. */
5608 md_parse_option (int c
, char *arg
)
5613 alpha_nofloats_on
= 1;
5617 alpha_addr32_on
= 1;
5625 g_switch_value
= atoi (arg
);
5630 const struct cpu_type
*p
;
5632 for (p
= cpu_types
; p
->name
; ++p
)
5633 if (strcmp (arg
, p
->name
) == 0)
5635 alpha_target_name
= p
->name
, alpha_target
= p
->flags
;
5638 as_warn (_("Unknown CPU identifier `%s'"), arg
);
5644 case '+': /* For g++. Hash any name > 63 chars long. */
5645 alpha_flag_hash_long_names
= 1;
5648 case 'H': /* Show new symbol after hash truncation. */
5649 alpha_flag_show_after_trunc
= 1;
5652 case 'h': /* For gnu-c/vax compatibility. */
5655 case OPTION_REPLACE
:
5656 alpha_flag_replace
= 1;
5659 case OPTION_NOREPLACE
:
5660 alpha_flag_replace
= 0;
5665 alpha_flag_relax
= 1;
5670 alpha_flag_mdebug
= 1;
5672 case OPTION_NO_MDEBUG
:
5673 alpha_flag_mdebug
= 0;
5684 /* Print a description of the command-line options that we accept. */
5687 md_show_usage (FILE *stream
)
5691 -32addr treat addresses as 32-bit values\n\
5692 -F lack floating point instructions support\n\
5693 -mev4 | -mev45 | -mev5 | -mev56 | -mpca56 | -mev6 | -mev67 | -mev68 | -mall\n\
5694 specify variant of Alpha architecture\n\
5695 -m21064 | -m21066 | -m21164 | -m21164a | -m21164pc | -m21264 | -m21264a | -m21264b\n\
5696 these variants include PALcode opcodes\n"),
5701 -+ encode (don't truncate) names longer than 64 characters\n\
5702 -H show new symbol after hash truncation\n\
5703 -replace/-noreplace enable or disable the optimization of procedure calls\n"),
5708 /* Decide from what point a pc-relative relocation is relative to,
5709 relative to the pc-relative fixup. Er, relatively speaking. */
5712 md_pcrel_from (fixS
*fixP
)
5714 valueT addr
= fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
5716 switch (fixP
->fx_r_type
)
5718 case BFD_RELOC_23_PCREL_S2
:
5719 case BFD_RELOC_ALPHA_HINT
:
5720 case BFD_RELOC_ALPHA_BRSGP
:
5727 /* Attempt to simplify or even eliminate a fixup. The return value is
5728 ignored; perhaps it was once meaningful, but now it is historical.
5729 To indicate that a fixup has been eliminated, set fixP->fx_done.
5731 For ELF, here it is that we transform the GPDISP_HI16 reloc we used
5732 internally into the GPDISP reloc used externally. We had to do
5733 this so that we'd have the GPDISP_LO16 reloc as a tag to compute
5734 the distance to the "lda" instruction for setting the addend to
5738 md_apply_fix (fixS
*fixP
, valueT
* valP
, segT seg
)
5740 char * const fixpos
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
5741 valueT value
= * valP
;
5742 unsigned image
, size
;
5744 switch (fixP
->fx_r_type
)
5746 /* The GPDISP relocations are processed internally with a symbol
5747 referring to the current function's section; we need to drop
5748 in a value which, when added to the address of the start of
5749 the function, gives the desired GP. */
5750 case BFD_RELOC_ALPHA_GPDISP_HI16
:
5752 fixS
*next
= fixP
->fx_next
;
5754 /* With user-specified !gpdisp relocations, we can be missing
5755 the matching LO16 reloc. We will have already issued an
5758 fixP
->fx_offset
= (next
->fx_frag
->fr_address
+ next
->fx_where
5759 - fixP
->fx_frag
->fr_address
- fixP
->fx_where
);
5761 value
= (value
- sign_extend_16 (value
)) >> 16;
5764 fixP
->fx_r_type
= BFD_RELOC_ALPHA_GPDISP
;
5768 case BFD_RELOC_ALPHA_GPDISP_LO16
:
5769 value
= sign_extend_16 (value
);
5770 fixP
->fx_offset
= 0;
5776 fixP
->fx_addsy
= section_symbol (seg
);
5777 md_number_to_chars (fixpos
, value
, 2);
5782 fixP
->fx_r_type
= BFD_RELOC_16_PCREL
;
5788 fixP
->fx_r_type
= BFD_RELOC_32_PCREL
;
5794 fixP
->fx_r_type
= BFD_RELOC_64_PCREL
;
5798 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
5800 md_number_to_chars (fixpos
, value
, size
);
5806 case BFD_RELOC_GPREL32
:
5807 gas_assert (fixP
->fx_subsy
== alpha_gp_symbol
);
5809 /* FIXME: inherited this obliviousness of `value' -- why? */
5810 md_number_to_chars (fixpos
, -alpha_gp_value
, 4);
5813 case BFD_RELOC_GPREL32
:
5815 case BFD_RELOC_GPREL16
:
5816 case BFD_RELOC_ALPHA_GPREL_HI16
:
5817 case BFD_RELOC_ALPHA_GPREL_LO16
:
5820 case BFD_RELOC_23_PCREL_S2
:
5821 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
5823 image
= bfd_getl32 (fixpos
);
5824 image
= (image
& ~0x1FFFFF) | ((value
>> 2) & 0x1FFFFF);
5829 case BFD_RELOC_ALPHA_HINT
:
5830 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
5832 image
= bfd_getl32 (fixpos
);
5833 image
= (image
& ~0x3FFF) | ((value
>> 2) & 0x3FFF);
5839 case BFD_RELOC_ALPHA_BRSGP
:
5842 case BFD_RELOC_ALPHA_TLSGD
:
5843 case BFD_RELOC_ALPHA_TLSLDM
:
5844 case BFD_RELOC_ALPHA_GOTDTPREL16
:
5845 case BFD_RELOC_ALPHA_DTPREL_HI16
:
5846 case BFD_RELOC_ALPHA_DTPREL_LO16
:
5847 case BFD_RELOC_ALPHA_DTPREL16
:
5848 case BFD_RELOC_ALPHA_GOTTPREL16
:
5849 case BFD_RELOC_ALPHA_TPREL_HI16
:
5850 case BFD_RELOC_ALPHA_TPREL_LO16
:
5851 case BFD_RELOC_ALPHA_TPREL16
:
5853 S_SET_THREAD_LOCAL (fixP
->fx_addsy
);
5858 case BFD_RELOC_ALPHA_LITERAL
:
5859 md_number_to_chars (fixpos
, value
, 2);
5862 case BFD_RELOC_ALPHA_ELF_LITERAL
:
5863 case BFD_RELOC_ALPHA_LITUSE
:
5864 case BFD_RELOC_ALPHA_LINKAGE
:
5865 case BFD_RELOC_ALPHA_CODEADDR
:
5869 case BFD_RELOC_ALPHA_NOP
:
5870 value
-= (8 + 4); /* PC-relative, base is jsr+4. */
5872 /* From B.4.5.2 of the OpenVMS Linker Utility Manual:
5873 "Finally, the ETIR$C_STC_BSR command passes the same address
5874 as ETIR$C_STC_NOP (so that they will fail or succeed together),
5875 and the same test is done again." */
5876 if (S_GET_SEGMENT (fixP
->fx_addsy
) == undefined_section
)
5878 fixP
->fx_addnumber
= -value
;
5882 if ((abs (value
) >> 2) & ~0xfffff)
5886 /* Change to a nop. */
5891 case BFD_RELOC_ALPHA_LDA
:
5892 /* fixup_segment sets fixP->fx_addsy to NULL when it can pre-compute
5893 the value for an O_subtract. */
5895 && S_GET_SEGMENT (fixP
->fx_addsy
) == undefined_section
)
5897 fixP
->fx_addnumber
= symbol_get_bfdsym (fixP
->fx_subsy
)->value
;
5901 if ((abs (value
)) & ~0x7fff)
5905 /* Change to an lda. */
5906 image
= 0x237B0000 | (value
& 0xFFFF);
5910 case BFD_RELOC_ALPHA_BSR
:
5911 case BFD_RELOC_ALPHA_BOH
:
5912 value
-= 4; /* PC-relative, base is jsr+4. */
5914 /* See comment in the BFD_RELOC_ALPHA_NOP case above. */
5915 if (S_GET_SEGMENT (fixP
->fx_addsy
) == undefined_section
)
5917 fixP
->fx_addnumber
= -value
;
5921 if ((abs (value
) >> 2) & ~0xfffff)
5924 if (fixP
->fx_r_type
== BFD_RELOC_ALPHA_BOH
)
5927 image
= bfd_getl32(fixpos
);
5928 image
= (image
& ~0x3FFF) | ((value
>> 2) & 0x3FFF);
5935 /* Change to a branch. */
5936 image
= 0xD3400000 | ((value
>> 2) & 0x1FFFFF);
5941 case BFD_RELOC_VTABLE_INHERIT
:
5942 case BFD_RELOC_VTABLE_ENTRY
:
5947 const struct alpha_operand
*operand
;
5949 if ((int) fixP
->fx_r_type
>= 0)
5950 as_fatal (_("unhandled relocation type %s"),
5951 bfd_get_reloc_code_name (fixP
->fx_r_type
));
5953 gas_assert (-(int) fixP
->fx_r_type
< (int) alpha_num_operands
);
5954 operand
= &alpha_operands
[-(int) fixP
->fx_r_type
];
5956 /* The rest of these fixups only exist internally during symbol
5957 resolution and have no representation in the object file.
5958 Therefore they must be completely resolved as constants. */
5960 if (fixP
->fx_addsy
!= 0
5961 && S_GET_SEGMENT (fixP
->fx_addsy
) != absolute_section
)
5962 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5963 _("non-absolute expression in constant field"));
5965 image
= bfd_getl32 (fixpos
);
5966 image
= insert_operand (image
, operand
, (offsetT
) value
,
5967 fixP
->fx_file
, fixP
->fx_line
);
5972 if (fixP
->fx_addsy
!= 0 || fixP
->fx_pcrel
!= 0)
5976 as_warn_where (fixP
->fx_file
, fixP
->fx_line
,
5977 _("type %d reloc done?\n"), (int) fixP
->fx_r_type
);
5982 md_number_to_chars (fixpos
, image
, 4);
5988 /* Look for a register name in the given symbol. */
5991 md_undefined_symbol (char *name
)
5995 int is_float
= 0, num
;
6000 if (name
[1] == 'p' && name
[2] == '\0')
6001 return alpha_register_table
[AXP_REG_FP
];
6006 if (!ISDIGIT (*++name
))
6010 case '0': case '1': case '2': case '3': case '4':
6011 case '5': case '6': case '7': case '8': case '9':
6012 if (name
[1] == '\0')
6013 num
= name
[0] - '0';
6014 else if (name
[0] != '0' && ISDIGIT (name
[1]) && name
[2] == '\0')
6016 num
= (name
[0] - '0') * 10 + name
[1] - '0';
6023 if (!alpha_noat_on
&& (num
+ is_float
) == AXP_REG_AT
)
6024 as_warn (_("Used $at without \".set noat\""));
6025 return alpha_register_table
[num
+ is_float
];
6028 if (name
[1] == 't' && name
[2] == '\0')
6031 as_warn (_("Used $at without \".set noat\""));
6032 return alpha_register_table
[AXP_REG_AT
];
6037 if (name
[1] == 'p' && name
[2] == '\0')
6038 return alpha_register_table
[alpha_gp_register
];
6042 if (name
[1] == 'p' && name
[2] == '\0')
6043 return alpha_register_table
[AXP_REG_SP
];
6051 /* @@@ Magic ECOFF bits. */
6054 alpha_frob_ecoff_data (void)
6057 /* $zero and $f31 are read-only. */
6058 alpha_gprmask
&= ~1;
6059 alpha_fprmask
&= ~1;
6063 /* Hook to remember a recently defined label so that the auto-align
6064 code can adjust the symbol after we know what alignment will be
6068 alpha_define_label (symbolS
*sym
)
6070 alpha_insn_label
= sym
;
6072 dwarf2_emit_label (sym
);
6076 /* Return true if we must always emit a reloc for a type and false if
6077 there is some hope of resolving it at assembly time. */
6080 alpha_force_relocation (fixS
*f
)
6082 if (alpha_flag_relax
)
6085 switch (f
->fx_r_type
)
6087 case BFD_RELOC_ALPHA_GPDISP_HI16
:
6088 case BFD_RELOC_ALPHA_GPDISP_LO16
:
6089 case BFD_RELOC_ALPHA_GPDISP
:
6090 case BFD_RELOC_ALPHA_LITERAL
:
6091 case BFD_RELOC_ALPHA_ELF_LITERAL
:
6092 case BFD_RELOC_ALPHA_LITUSE
:
6093 case BFD_RELOC_GPREL16
:
6094 case BFD_RELOC_GPREL32
:
6095 case BFD_RELOC_ALPHA_GPREL_HI16
:
6096 case BFD_RELOC_ALPHA_GPREL_LO16
:
6097 case BFD_RELOC_ALPHA_LINKAGE
:
6098 case BFD_RELOC_ALPHA_CODEADDR
:
6099 case BFD_RELOC_ALPHA_BRSGP
:
6100 case BFD_RELOC_ALPHA_TLSGD
:
6101 case BFD_RELOC_ALPHA_TLSLDM
:
6102 case BFD_RELOC_ALPHA_GOTDTPREL16
:
6103 case BFD_RELOC_ALPHA_DTPREL_HI16
:
6104 case BFD_RELOC_ALPHA_DTPREL_LO16
:
6105 case BFD_RELOC_ALPHA_DTPREL16
:
6106 case BFD_RELOC_ALPHA_GOTTPREL16
:
6107 case BFD_RELOC_ALPHA_TPREL_HI16
:
6108 case BFD_RELOC_ALPHA_TPREL_LO16
:
6109 case BFD_RELOC_ALPHA_TPREL16
:
6111 case BFD_RELOC_ALPHA_NOP
:
6112 case BFD_RELOC_ALPHA_BSR
:
6113 case BFD_RELOC_ALPHA_LDA
:
6114 case BFD_RELOC_ALPHA_BOH
:
6122 return generic_force_reloc (f
);
6125 /* Return true if we can partially resolve a relocation now. */
6128 alpha_fix_adjustable (fixS
*f
)
6130 /* Are there any relocation types for which we must generate a
6131 reloc but we can adjust the values contained within it? */
6132 switch (f
->fx_r_type
)
6134 case BFD_RELOC_ALPHA_GPDISP_HI16
:
6135 case BFD_RELOC_ALPHA_GPDISP_LO16
:
6136 case BFD_RELOC_ALPHA_GPDISP
:
6139 case BFD_RELOC_ALPHA_LITERAL
:
6140 case BFD_RELOC_ALPHA_ELF_LITERAL
:
6141 case BFD_RELOC_ALPHA_LITUSE
:
6142 case BFD_RELOC_ALPHA_LINKAGE
:
6143 case BFD_RELOC_ALPHA_CODEADDR
:
6146 case BFD_RELOC_VTABLE_ENTRY
:
6147 case BFD_RELOC_VTABLE_INHERIT
:
6150 case BFD_RELOC_GPREL16
:
6151 case BFD_RELOC_GPREL32
:
6152 case BFD_RELOC_ALPHA_GPREL_HI16
:
6153 case BFD_RELOC_ALPHA_GPREL_LO16
:
6154 case BFD_RELOC_23_PCREL_S2
:
6158 case BFD_RELOC_ALPHA_HINT
:
6161 case BFD_RELOC_ALPHA_TLSGD
:
6162 case BFD_RELOC_ALPHA_TLSLDM
:
6163 case BFD_RELOC_ALPHA_GOTDTPREL16
:
6164 case BFD_RELOC_ALPHA_DTPREL_HI16
:
6165 case BFD_RELOC_ALPHA_DTPREL_LO16
:
6166 case BFD_RELOC_ALPHA_DTPREL16
:
6167 case BFD_RELOC_ALPHA_GOTTPREL16
:
6168 case BFD_RELOC_ALPHA_TPREL_HI16
:
6169 case BFD_RELOC_ALPHA_TPREL_LO16
:
6170 case BFD_RELOC_ALPHA_TPREL16
:
6171 /* ??? No idea why we can't return a reference to .tbss+10, but
6172 we're preventing this in the other assemblers. Follow for now. */
6176 case BFD_RELOC_ALPHA_BRSGP
:
6177 /* If we have a BRSGP reloc to a local symbol, adjust it to BRADDR and
6178 let it get resolved at assembly time. */
6180 symbolS
*sym
= f
->fx_addsy
;
6184 if (generic_force_reloc (f
))
6187 switch (S_GET_OTHER (sym
) & STO_ALPHA_STD_GPLOAD
)
6189 case STO_ALPHA_NOPV
:
6191 case STO_ALPHA_STD_GPLOAD
:
6195 if (S_IS_LOCAL (sym
))
6198 name
= S_GET_NAME (sym
);
6199 as_bad_where (f
->fx_file
, f
->fx_line
,
6200 _("!samegp reloc against symbol without .prologue: %s"),
6204 f
->fx_r_type
= BFD_RELOC_23_PCREL_S2
;
6205 f
->fx_offset
+= offset
;
6210 case BFD_RELOC_ALPHA_NOP
:
6211 case BFD_RELOC_ALPHA_BSR
:
6212 case BFD_RELOC_ALPHA_LDA
:
6213 case BFD_RELOC_ALPHA_BOH
:
6222 /* Generate the BFD reloc to be stuck in the object file from the
6223 fixup used internally in the assembler. */
6226 tc_gen_reloc (asection
*sec ATTRIBUTE_UNUSED
,
6231 reloc
= (arelent
*) xmalloc (sizeof (* reloc
));
6232 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
6233 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
6234 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
6236 /* Make sure none of our internal relocations make it this far.
6237 They'd better have been fully resolved by this point. */
6238 gas_assert ((int) fixp
->fx_r_type
> 0);
6240 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
6241 if (reloc
->howto
== NULL
)
6243 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
6244 _("cannot represent `%s' relocation in object file"),
6245 bfd_get_reloc_code_name (fixp
->fx_r_type
));
6249 if (!fixp
->fx_pcrel
!= !reloc
->howto
->pc_relative
)
6250 as_fatal (_("internal error? cannot generate `%s' relocation"),
6251 bfd_get_reloc_code_name (fixp
->fx_r_type
));
6253 gas_assert (!fixp
->fx_pcrel
== !reloc
->howto
->pc_relative
);
6256 if (fixp
->fx_r_type
== BFD_RELOC_ALPHA_LITERAL
)
6257 /* Fake out bfd_perform_relocation. sigh. */
6258 reloc
->addend
= -alpha_gp_value
;
6262 reloc
->addend
= fixp
->fx_offset
;
6264 /* Ohhh, this is ugly. The problem is that if this is a local global
6265 symbol, the relocation will entirely be performed at link time, not
6266 at assembly time. bfd_perform_reloc doesn't know about this sort
6267 of thing, and as a result we need to fake it out here. */
6268 if ((S_IS_EXTERNAL (fixp
->fx_addsy
) || S_IS_WEAK (fixp
->fx_addsy
)
6269 || (S_GET_SEGMENT (fixp
->fx_addsy
)->flags
& SEC_MERGE
)
6270 || (S_GET_SEGMENT (fixp
->fx_addsy
)->flags
& SEC_THREAD_LOCAL
))
6271 && !S_IS_COMMON (fixp
->fx_addsy
))
6272 reloc
->addend
-= symbol_get_bfdsym (fixp
->fx_addsy
)->value
;
6277 switch (fixp
->fx_r_type
)
6279 struct evax_private_udata_struct
*udata
;
6283 case BFD_RELOC_ALPHA_LINKAGE
:
6284 reloc
->addend
= fixp
->fx_addnumber
;
6287 case BFD_RELOC_ALPHA_NOP
:
6288 case BFD_RELOC_ALPHA_BSR
:
6289 case BFD_RELOC_ALPHA_LDA
:
6290 case BFD_RELOC_ALPHA_BOH
:
6291 pname
= symbol_get_bfdsym (fixp
->fx_addsy
)->name
;
6293 /* We need the non-suffixed name of the procedure. Beware that
6294 the main symbol might be equated so look it up and take its name. */
6295 pname_len
= strlen (pname
);
6296 if (pname_len
> 4 && strcmp (pname
+ pname_len
- 4, "..en") == 0)
6299 char *my_pname
= xstrdup (pname
);
6300 my_pname
[pname_len
- 4] = 0;
6301 sym
= symbol_find (my_pname
);
6304 while (symbol_equated_reloc_p (sym
))
6306 symbolS
*n
= symbol_get_value_expression (sym
)->X_add_symbol
;
6308 /* We must avoid looping, as that can occur with a badly
6314 pname
= symbol_get_bfdsym (sym
)->name
;
6317 udata
= (struct evax_private_udata_struct
*)
6318 xmalloc (sizeof (struct evax_private_udata_struct
));
6319 udata
->enbsym
= symbol_get_bfdsym (fixp
->fx_addsy
);
6320 udata
->bsym
= symbol_get_bfdsym (fixp
->tc_fix_data
.info
->psym
);
6321 udata
->origname
= (char *)pname
;
6322 udata
->lkindex
= ((struct evax_private_udata_struct
*)
6323 symbol_get_bfdsym (fixp
->tc_fix_data
.info
->sym
)->udata
.p
)->lkindex
;
6324 reloc
->sym_ptr_ptr
= (void *)udata
;
6325 reloc
->addend
= fixp
->fx_addnumber
;
6335 /* Parse a register name off of the input_line and return a register
6336 number. Gets md_undefined_symbol above to do the register name
6339 Only called as a part of processing the ECOFF .frame directive. */
6342 tc_get_register (int frame ATTRIBUTE_UNUSED
)
6344 int framereg
= AXP_REG_SP
;
6347 if (*input_line_pointer
== '$')
6349 char *s
= input_line_pointer
;
6350 char c
= get_symbol_end ();
6351 symbolS
*sym
= md_undefined_symbol (s
);
6353 *strchr (s
, '\0') = c
;
6354 if (sym
&& (framereg
= S_GET_VALUE (sym
)) <= 31)
6357 as_warn (_("frame reg expected, using $%d."), framereg
);
6360 note_gpreg (framereg
);
6364 /* This is called before the symbol table is processed. In order to
6365 work with gcc when using mips-tfile, we must keep all local labels.
6366 However, in other cases, we want to discard them. If we were
6367 called with -g, but we didn't see any debugging information, it may
6368 mean that gcc is smuggling debugging information through to
6369 mips-tfile, in which case we must generate all local labels. */
6374 alpha_frob_file_before_adjust (void)
6376 if (alpha_debug
!= 0
6377 && ! ecoff_debugging_seen
)
6378 flag_keep_locals
= 1;
6381 #endif /* OBJ_ECOFF */
6383 /* The Alpha has support for some VAX floating point types, as well as for
6384 IEEE floating point. We consider IEEE to be the primary floating point
6385 format, and sneak in the VAX floating point support here. */
6386 #include "config/atof-vax.c"