1 /* tc-alpha.c - Processor-specific code for the DEC Alpha AXP CPU.
2 Copyright 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
4 Contributed by Carnegie Mellon University, 1993.
5 Written by Alessandro Forin, based on earlier gas-1.38 target CPU files.
6 Modified by Ken Raeburn for gas-2.x and ECOFF support.
7 Modified by Richard Henderson for ELF support.
8 Modified by Klaus K"ampf for EVAX (OpenVMS/Alpha) support.
10 This file is part of GAS, the GNU Assembler.
12 GAS is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2, or (at your option)
17 GAS is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
22 You should have received a copy of the GNU General Public License
23 along with GAS; see the file COPYING. If not, write to the Free
24 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
27 /* Mach Operating System
28 Copyright (c) 1993 Carnegie Mellon University
31 Permission to use, copy, modify and distribute this software and its
32 documentation is hereby granted, provided that both the copyright
33 notice and this permission notice appear in all copies of the
34 software, derivative works or modified versions, and any portions
35 thereof, and that both notices appear in supporting documentation.
37 CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
38 CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
39 ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
41 Carnegie Mellon requests users of this software to return to
43 Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
44 School of Computer Science
45 Carnegie Mellon University
46 Pittsburgh PA 15213-3890
48 any improvements or extensions that they make and grant Carnegie the
49 rights to redistribute these changes. */
53 #include "struc-symbol.h"
56 #include "opcode/alpha.h"
59 #include "elf/alpha.h"
60 #include "dwarf2dbg.h"
63 #include "dw2gencfi.h"
64 #include "safe-ctype.h"
68 #define TOKENIZE_ERROR -1
69 #define TOKENIZE_ERROR_REPORT -2
70 #define MAX_INSN_FIXUPS 2
71 #define MAX_INSN_ARGS 5
76 bfd_reloc_code_real_type reloc
;
83 struct alpha_fixup fixups
[MAX_INSN_FIXUPS
];
101 void (*emit
) (const expressionS
*, int, const void *);
103 enum alpha_macro_arg argsets
[16];
106 /* Extra expression types. */
108 #define O_pregister O_md1 /* O_register, in parentheses. */
109 #define O_cpregister O_md2 /* + a leading comma. */
111 /* The alpha_reloc_op table below depends on the ordering of these. */
112 #define O_literal O_md3 /* !literal relocation. */
113 #define O_lituse_addr O_md4 /* !lituse_addr relocation. */
114 #define O_lituse_base O_md5 /* !lituse_base relocation. */
115 #define O_lituse_bytoff O_md6 /* !lituse_bytoff relocation. */
116 #define O_lituse_jsr O_md7 /* !lituse_jsr relocation. */
117 #define O_lituse_tlsgd O_md8 /* !lituse_tlsgd relocation. */
118 #define O_lituse_tlsldm O_md9 /* !lituse_tlsldm relocation. */
119 #define O_gpdisp O_md10 /* !gpdisp relocation. */
120 #define O_gprelhigh O_md11 /* !gprelhigh relocation. */
121 #define O_gprellow O_md12 /* !gprellow relocation. */
122 #define O_gprel O_md13 /* !gprel relocation. */
123 #define O_samegp O_md14 /* !samegp relocation. */
124 #define O_tlsgd O_md15 /* !tlsgd relocation. */
125 #define O_tlsldm O_md16 /* !tlsldm relocation. */
126 #define O_gotdtprel O_md17 /* !gotdtprel relocation. */
127 #define O_dtprelhi O_md18 /* !dtprelhi relocation. */
128 #define O_dtprello O_md19 /* !dtprello relocation. */
129 #define O_dtprel O_md20 /* !dtprel relocation. */
130 #define O_gottprel O_md21 /* !gottprel relocation. */
131 #define O_tprelhi O_md22 /* !tprelhi relocation. */
132 #define O_tprello O_md23 /* !tprello relocation. */
133 #define O_tprel O_md24 /* !tprel relocation. */
135 #define DUMMY_RELOC_LITUSE_ADDR (BFD_RELOC_UNUSED + 1)
136 #define DUMMY_RELOC_LITUSE_BASE (BFD_RELOC_UNUSED + 2)
137 #define DUMMY_RELOC_LITUSE_BYTOFF (BFD_RELOC_UNUSED + 3)
138 #define DUMMY_RELOC_LITUSE_JSR (BFD_RELOC_UNUSED + 4)
139 #define DUMMY_RELOC_LITUSE_TLSGD (BFD_RELOC_UNUSED + 5)
140 #define DUMMY_RELOC_LITUSE_TLSLDM (BFD_RELOC_UNUSED + 6)
142 #define USER_RELOC_P(R) ((R) >= O_literal && (R) <= O_tprel)
144 /* Macros for extracting the type and number of encoded register tokens. */
146 #define is_ir_num(x) (((x) & 32) == 0)
147 #define is_fpr_num(x) (((x) & 32) != 0)
148 #define regno(x) ((x) & 31)
150 /* Something odd inherited from the old assembler. */
152 #define note_gpreg(R) (alpha_gprmask |= (1 << (R)))
153 #define note_fpreg(R) (alpha_fprmask |= (1 << (R)))
155 /* Predicates for 16- and 32-bit ranges */
156 /* XXX: The non-shift version appears to trigger a compiler bug when
157 cross-assembling from x86 w/ gcc 2.7.2. */
160 #define range_signed_16(x) \
161 (((offsetT) (x) >> 15) == 0 || ((offsetT) (x) >> 15) == -1)
162 #define range_signed_32(x) \
163 (((offsetT) (x) >> 31) == 0 || ((offsetT) (x) >> 31) == -1)
165 #define range_signed_16(x) ((offsetT) (x) >= -(offsetT) 0x8000 && \
166 (offsetT) (x) <= (offsetT) 0x7FFF)
167 #define range_signed_32(x) ((offsetT) (x) >= -(offsetT) 0x80000000 && \
168 (offsetT) (x) <= (offsetT) 0x7FFFFFFF)
171 /* Macros for sign extending from 16- and 32-bits. */
172 /* XXX: The cast macros will work on all the systems that I care about,
173 but really a predicate should be found to use the non-cast forms. */
176 #define sign_extend_16(x) ((short) (x))
177 #define sign_extend_32(x) ((int) (x))
179 #define sign_extend_16(x) ((offsetT) (((x) & 0xFFFF) ^ 0x8000) - 0x8000)
180 #define sign_extend_32(x) ((offsetT) (((x) & 0xFFFFFFFF) \
181 ^ 0x80000000) - 0x80000000)
184 /* Macros to build tokens. */
186 #define set_tok_reg(t, r) (memset (&(t), 0, sizeof (t)), \
187 (t).X_op = O_register, \
188 (t).X_add_number = (r))
189 #define set_tok_preg(t, r) (memset (&(t), 0, sizeof (t)), \
190 (t).X_op = O_pregister, \
191 (t).X_add_number = (r))
192 #define set_tok_cpreg(t, r) (memset (&(t), 0, sizeof (t)), \
193 (t).X_op = O_cpregister, \
194 (t).X_add_number = (r))
195 #define set_tok_freg(t, r) (memset (&(t), 0, sizeof (t)), \
196 (t).X_op = O_register, \
197 (t).X_add_number = (r) + 32)
198 #define set_tok_sym(t, s, a) (memset (&(t), 0, sizeof (t)), \
199 (t).X_op = O_symbol, \
200 (t).X_add_symbol = (s), \
201 (t).X_add_number = (a))
202 #define set_tok_const(t, n) (memset (&(t), 0, sizeof (t)), \
203 (t).X_op = O_constant, \
204 (t).X_add_number = (n))
206 /* Generic assembler global variables which must be defined by all
209 /* Characters which always start a comment. */
210 const char comment_chars
[] = "#";
212 /* Characters which start a comment at the beginning of a line. */
213 const char line_comment_chars
[] = "#";
215 /* Characters which may be used to separate multiple commands on a
217 const char line_separator_chars
[] = ";";
219 /* Characters which are used to indicate an exponent in a floating
221 const char EXP_CHARS
[] = "eE";
223 /* Characters which mean that a number is a floating point constant,
225 /* XXX: Do all of these really get used on the alpha?? */
226 char FLT_CHARS
[] = "rRsSfFdDxXpP";
229 const char *md_shortopts
= "Fm:g+1h:HG:";
231 const char *md_shortopts
= "Fm:gG:";
234 struct option md_longopts
[] =
236 #define OPTION_32ADDR (OPTION_MD_BASE)
237 { "32addr", no_argument
, NULL
, OPTION_32ADDR
},
238 #define OPTION_RELAX (OPTION_32ADDR + 1)
239 { "relax", no_argument
, NULL
, OPTION_RELAX
},
241 #define OPTION_MDEBUG (OPTION_RELAX + 1)
242 #define OPTION_NO_MDEBUG (OPTION_MDEBUG + 1)
243 { "mdebug", no_argument
, NULL
, OPTION_MDEBUG
},
244 { "no-mdebug", no_argument
, NULL
, OPTION_NO_MDEBUG
},
246 { NULL
, no_argument
, NULL
, 0 }
249 size_t md_longopts_size
= sizeof (md_longopts
);
253 #define AXP_REG_R16 16
254 #define AXP_REG_R17 17
256 #define AXP_REG_T9 22
258 #define AXP_REG_T10 23
260 #define AXP_REG_T11 24
262 #define AXP_REG_T12 25
263 #define AXP_REG_AI 25
265 #define AXP_REG_FP 29
268 #define AXP_REG_GP AXP_REG_PV
269 #endif /* OBJ_EVAX */
271 /* The cpu for which we are generating code. */
272 static unsigned alpha_target
= AXP_OPCODE_BASE
;
273 static const char *alpha_target_name
= "<all>";
275 /* The hash table of instruction opcodes. */
276 static struct hash_control
*alpha_opcode_hash
;
278 /* The hash table of macro opcodes. */
279 static struct hash_control
*alpha_macro_hash
;
282 /* The $gp relocation symbol. */
283 static symbolS
*alpha_gp_symbol
;
285 /* XXX: what is this, and why is it exported? */
286 valueT alpha_gp_value
;
289 /* The current $gp register. */
290 static int alpha_gp_register
= AXP_REG_GP
;
292 /* A table of the register symbols. */
293 static symbolS
*alpha_register_table
[64];
295 /* Constant sections, or sections of constants. */
297 static segT alpha_lita_section
;
300 static segT alpha_link_section
;
301 static segT alpha_ctors_section
;
302 static segT alpha_dtors_section
;
304 static segT alpha_lit8_section
;
306 /* Symbols referring to said sections. */
308 static symbolS
*alpha_lita_symbol
;
311 static symbolS
*alpha_link_symbol
;
312 static symbolS
*alpha_ctors_symbol
;
313 static symbolS
*alpha_dtors_symbol
;
315 static symbolS
*alpha_lit8_symbol
;
317 /* Literal for .litX+0x8000 within .lita. */
319 static offsetT alpha_lit8_literal
;
322 /* Is the assembler not allowed to use $at? */
323 static int alpha_noat_on
= 0;
325 /* Are macros enabled? */
326 static int alpha_macros_on
= 1;
328 /* Are floats disabled? */
329 static int alpha_nofloats_on
= 0;
331 /* Are addresses 32 bit? */
332 static int alpha_addr32_on
= 0;
334 /* Symbol labelling the current insn. When the Alpha gas sees
337 and the section happens to not be on an eight byte boundary, it
338 will align both the symbol and the .quad to an eight byte boundary. */
339 static symbolS
*alpha_insn_label
;
341 /* Whether we should automatically align data generation pseudo-ops.
342 .align 0 will turn this off. */
343 static int alpha_auto_align_on
= 1;
345 /* The known current alignment of the current section. */
346 static int alpha_current_align
;
348 /* These are exported to ECOFF code. */
349 unsigned long alpha_gprmask
, alpha_fprmask
;
351 /* Whether the debugging option was seen. */
352 static int alpha_debug
;
355 /* Whether we are emitting an mdebug section. */
356 int alpha_flag_mdebug
= -1;
359 /* Don't fully resolve relocations, allowing code movement in the linker. */
360 static int alpha_flag_relax
;
362 /* What value to give to bfd_set_gp_size. */
363 static int g_switch_value
= 8;
366 /* Collect information about current procedure here. */
369 symbolS
*symbol
; /* Proc pdesc symbol. */
371 int framereg
; /* Register for frame pointer. */
372 int framesize
; /* Size of frame. */
382 static int alpha_flag_hash_long_names
= 0; /* -+ */
383 static int alpha_flag_show_after_trunc
= 0; /* -H */
385 /* If the -+ switch is given, then a hash is appended to any name that is
386 longer than 64 characters, else longer symbol names are truncated. */
391 /* A table to map the spelling of a relocation operand into an appropriate
392 bfd_reloc_code_real_type type. The table is assumed to be ordered such
393 that op-O_literal indexes into it. */
395 #define ALPHA_RELOC_TABLE(op) \
396 (&alpha_reloc_op[ ((!USER_RELOC_P (op)) \
398 : (int) (op) - (int) O_literal) ])
400 #define DEF(NAME, RELOC, REQ, ALLOW) \
401 { #NAME, sizeof(#NAME)-1, O_##NAME, RELOC, REQ, ALLOW}
403 static const struct alpha_reloc_op_tag
405 const char *name
; /* String to lookup. */
406 size_t length
; /* Size of the string. */
407 operatorT op
; /* Which operator to use. */
408 bfd_reloc_code_real_type reloc
; /* Relocation before frob. */
409 unsigned int require_seq
: 1; /* Require a sequence number. */
410 unsigned int allow_seq
: 1; /* Allow a sequence number. */
414 DEF (literal
, BFD_RELOC_ALPHA_ELF_LITERAL
, 0, 1),
415 DEF (lituse_addr
, DUMMY_RELOC_LITUSE_ADDR
, 1, 1),
416 DEF (lituse_base
, DUMMY_RELOC_LITUSE_BASE
, 1, 1),
417 DEF (lituse_bytoff
, DUMMY_RELOC_LITUSE_BYTOFF
, 1, 1),
418 DEF (lituse_jsr
, DUMMY_RELOC_LITUSE_JSR
, 1, 1),
419 DEF (lituse_tlsgd
, DUMMY_RELOC_LITUSE_TLSGD
, 1, 1),
420 DEF (lituse_tlsldm
, DUMMY_RELOC_LITUSE_TLSLDM
, 1, 1),
421 DEF (gpdisp
, BFD_RELOC_ALPHA_GPDISP
, 1, 1),
422 DEF (gprelhigh
, BFD_RELOC_ALPHA_GPREL_HI16
, 0, 0),
423 DEF (gprellow
, BFD_RELOC_ALPHA_GPREL_LO16
, 0, 0),
424 DEF (gprel
, BFD_RELOC_GPREL16
, 0, 0),
425 DEF (samegp
, BFD_RELOC_ALPHA_BRSGP
, 0, 0),
426 DEF (tlsgd
, BFD_RELOC_ALPHA_TLSGD
, 0, 1),
427 DEF (tlsldm
, BFD_RELOC_ALPHA_TLSLDM
, 0, 1),
428 DEF (gotdtprel
, BFD_RELOC_ALPHA_GOTDTPREL16
, 0, 0),
429 DEF (dtprelhi
, BFD_RELOC_ALPHA_DTPREL_HI16
, 0, 0),
430 DEF (dtprello
, BFD_RELOC_ALPHA_DTPREL_LO16
, 0, 0),
431 DEF (dtprel
, BFD_RELOC_ALPHA_DTPREL16
, 0, 0),
432 DEF (gottprel
, BFD_RELOC_ALPHA_GOTTPREL16
, 0, 0),
433 DEF (tprelhi
, BFD_RELOC_ALPHA_TPREL_HI16
, 0, 0),
434 DEF (tprello
, BFD_RELOC_ALPHA_TPREL_LO16
, 0, 0),
435 DEF (tprel
, BFD_RELOC_ALPHA_TPREL16
, 0, 0),
440 static const int alpha_num_reloc_op
441 = sizeof (alpha_reloc_op
) / sizeof (*alpha_reloc_op
);
442 #endif /* RELOC_OP_P */
444 /* Maximum # digits needed to hold the largest sequence #. */
445 #define ALPHA_RELOC_DIGITS 25
447 /* Structure to hold explicit sequence information. */
448 struct alpha_reloc_tag
450 fixS
*master
; /* The literal reloc. */
451 fixS
*slaves
; /* Head of linked list of lituses. */
452 segT segment
; /* Segment relocs are in or undefined_section. */
453 long sequence
; /* Sequence #. */
454 unsigned n_master
; /* # of literals. */
455 unsigned n_slaves
; /* # of lituses. */
456 unsigned saw_tlsgd
: 1; /* True if ... */
457 unsigned saw_tlsldm
: 1;
458 unsigned saw_lu_tlsgd
: 1;
459 unsigned saw_lu_tlsldm
: 1;
460 unsigned multi_section_p
: 1; /* True if more than one section was used. */
461 char string
[1]; /* Printable form of sequence to hash with. */
464 /* Hash table to link up literals with the appropriate lituse. */
465 static struct hash_control
*alpha_literal_hash
;
467 /* Sequence numbers for internal use by macros. */
468 static long next_sequence_num
= -1;
470 /* A table of CPU names and opcode sets. */
472 static const struct cpu_type
479 /* Ad hoc convention: cpu number gets palcode, process code doesn't.
480 This supports usage under DU 4.0b that does ".arch ev4", and
481 usage in MILO that does -m21064. Probably something more
482 specific like -m21064-pal should be used, but oh well. */
484 { "21064", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
485 { "21064a", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
486 { "21066", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
487 { "21068", AXP_OPCODE_BASE
|AXP_OPCODE_EV4
},
488 { "21164", AXP_OPCODE_BASE
|AXP_OPCODE_EV5
},
489 { "21164a", AXP_OPCODE_BASE
|AXP_OPCODE_EV5
|AXP_OPCODE_BWX
},
490 { "21164pc", (AXP_OPCODE_BASE
|AXP_OPCODE_EV5
|AXP_OPCODE_BWX
492 { "21264", (AXP_OPCODE_BASE
|AXP_OPCODE_EV6
|AXP_OPCODE_BWX
493 |AXP_OPCODE_MAX
|AXP_OPCODE_CIX
) },
494 { "21264a", (AXP_OPCODE_BASE
|AXP_OPCODE_EV6
|AXP_OPCODE_BWX
495 |AXP_OPCODE_MAX
|AXP_OPCODE_CIX
) },
496 { "21264b", (AXP_OPCODE_BASE
|AXP_OPCODE_EV6
|AXP_OPCODE_BWX
497 |AXP_OPCODE_MAX
|AXP_OPCODE_CIX
) },
499 { "ev4", AXP_OPCODE_BASE
},
500 { "ev45", AXP_OPCODE_BASE
},
501 { "lca45", AXP_OPCODE_BASE
},
502 { "ev5", AXP_OPCODE_BASE
},
503 { "ev56", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
},
504 { "pca56", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
|AXP_OPCODE_MAX
},
505 { "ev6", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
|AXP_OPCODE_MAX
|AXP_OPCODE_CIX
},
506 { "ev67", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
|AXP_OPCODE_MAX
|AXP_OPCODE_CIX
},
507 { "ev68", AXP_OPCODE_BASE
|AXP_OPCODE_BWX
|AXP_OPCODE_MAX
|AXP_OPCODE_CIX
},
509 { "all", AXP_OPCODE_BASE
},
513 /* Some instruction sets indexed by lg(size). */
514 static const char * const sextX_op
[] = { "sextb", "sextw", "sextl", NULL
};
515 static const char * const insXl_op
[] = { "insbl", "inswl", "insll", "insql" };
516 static const char * const insXh_op
[] = { NULL
, "inswh", "inslh", "insqh" };
517 static const char * const extXl_op
[] = { "extbl", "extwl", "extll", "extql" };
518 static const char * const extXh_op
[] = { NULL
, "extwh", "extlh", "extqh" };
519 static const char * const mskXl_op
[] = { "mskbl", "mskwl", "mskll", "mskql" };
520 static const char * const mskXh_op
[] = { NULL
, "mskwh", "msklh", "mskqh" };
521 static const char * const stX_op
[] = { "stb", "stw", "stl", "stq" };
522 static const char * const ldXu_op
[] = { "ldbu", "ldwu", NULL
, NULL
};
524 static void assemble_insn (const struct alpha_opcode
*, const expressionS
*, int, struct alpha_insn
*, bfd_reloc_code_real_type
);
525 static void emit_insn (struct alpha_insn
*);
526 static void assemble_tokens (const char *, const expressionS
*, int, int);
528 static struct alpha_reloc_tag
*
529 get_alpha_reloc_tag (long sequence
)
531 char buffer
[ALPHA_RELOC_DIGITS
];
532 struct alpha_reloc_tag
*info
;
534 sprintf (buffer
, "!%ld", sequence
);
536 info
= (struct alpha_reloc_tag
*) hash_find (alpha_literal_hash
, buffer
);
539 size_t len
= strlen (buffer
);
542 info
= xcalloc (sizeof (struct alpha_reloc_tag
) + len
, 1);
544 info
->segment
= now_seg
;
545 info
->sequence
= sequence
;
546 strcpy (info
->string
, buffer
);
547 errmsg
= hash_insert (alpha_literal_hash
, info
->string
, (void *) info
);
556 alpha_adjust_relocs (bfd
*abfd ATTRIBUTE_UNUSED
,
558 void * ptr ATTRIBUTE_UNUSED
)
560 segment_info_type
*seginfo
= seg_info (sec
);
566 /* If seginfo is NULL, we did not create this section; don't do
567 anything with it. By using a pointer to a pointer, we can update
568 the links in place. */
572 /* If there are no relocations, skip the section. */
573 if (! seginfo
->fix_root
)
576 /* First rebuild the fixup chain without the explicit lituse and
577 gpdisp_lo16 relocs. */
578 prevP
= &seginfo
->fix_root
;
579 for (fixp
= seginfo
->fix_root
; fixp
; fixp
= next
)
581 next
= fixp
->fx_next
;
582 fixp
->fx_next
= (fixS
*) 0;
584 switch (fixp
->fx_r_type
)
586 case BFD_RELOC_ALPHA_LITUSE
:
587 if (fixp
->tc_fix_data
.info
->n_master
== 0)
588 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
589 _("No !literal!%ld was found"),
590 fixp
->tc_fix_data
.info
->sequence
);
592 if (fixp
->fx_offset
== LITUSE_ALPHA_TLSGD
)
594 if (! fixp
->tc_fix_data
.info
->saw_tlsgd
)
595 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
596 _("No !tlsgd!%ld was found"),
597 fixp
->tc_fix_data
.info
->sequence
);
599 else if (fixp
->fx_offset
== LITUSE_ALPHA_TLSLDM
)
601 if (! fixp
->tc_fix_data
.info
->saw_tlsldm
)
602 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
603 _("No !tlsldm!%ld was found"),
604 fixp
->tc_fix_data
.info
->sequence
);
609 case BFD_RELOC_ALPHA_GPDISP_LO16
:
610 if (fixp
->tc_fix_data
.info
->n_master
== 0)
611 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
612 _("No ldah !gpdisp!%ld was found"),
613 fixp
->tc_fix_data
.info
->sequence
);
616 case BFD_RELOC_ALPHA_ELF_LITERAL
:
617 if (fixp
->tc_fix_data
.info
618 && (fixp
->tc_fix_data
.info
->saw_tlsgd
619 || fixp
->tc_fix_data
.info
->saw_tlsldm
))
625 prevP
= &fixp
->fx_next
;
630 /* Go back and re-chain dependent relocations. They are currently
631 linked through the next_reloc field in reverse order, so as we
632 go through the next_reloc chain, we effectively reverse the chain
635 Except if there is more than one !literal for a given sequence
636 number. In that case, the programmer and/or compiler is not sure
637 how control flows from literal to lituse, and we can't be sure to
638 get the relaxation correct.
640 ??? Well, actually we could, if there are enough lituses such that
641 we can make each literal have at least one of each lituse type
642 present. Not implemented.
644 Also suppress the optimization if the !literals/!lituses are spread
645 in different segments. This can happen with "intersting" uses of
646 inline assembly; examples are present in the Linux kernel semaphores. */
648 for (fixp
= seginfo
->fix_root
; fixp
; fixp
= next
)
650 next
= fixp
->fx_next
;
651 switch (fixp
->fx_r_type
)
653 case BFD_RELOC_ALPHA_TLSGD
:
654 case BFD_RELOC_ALPHA_TLSLDM
:
655 if (!fixp
->tc_fix_data
.info
)
657 if (fixp
->tc_fix_data
.info
->n_master
== 0)
659 else if (fixp
->tc_fix_data
.info
->n_master
> 1)
661 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
662 _("too many !literal!%ld for %s"),
663 fixp
->tc_fix_data
.info
->sequence
,
664 (fixp
->fx_r_type
== BFD_RELOC_ALPHA_TLSGD
665 ? "!tlsgd" : "!tlsldm"));
669 fixp
->tc_fix_data
.info
->master
->fx_next
= fixp
->fx_next
;
670 fixp
->fx_next
= fixp
->tc_fix_data
.info
->master
;
671 fixp
= fixp
->fx_next
;
674 case BFD_RELOC_ALPHA_ELF_LITERAL
:
675 if (fixp
->tc_fix_data
.info
676 && fixp
->tc_fix_data
.info
->n_master
== 1
677 && ! fixp
->tc_fix_data
.info
->multi_section_p
)
679 for (slave
= fixp
->tc_fix_data
.info
->slaves
;
681 slave
= slave
->tc_fix_data
.next_reloc
)
683 slave
->fx_next
= fixp
->fx_next
;
684 fixp
->fx_next
= slave
;
689 case BFD_RELOC_ALPHA_GPDISP_HI16
:
690 if (fixp
->tc_fix_data
.info
->n_slaves
== 0)
691 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
692 _("No lda !gpdisp!%ld was found"),
693 fixp
->tc_fix_data
.info
->sequence
);
696 slave
= fixp
->tc_fix_data
.info
->slaves
;
697 slave
->fx_next
= next
;
698 fixp
->fx_next
= slave
;
708 /* Before the relocations are written, reorder them, so that user
709 supplied !lituse relocations follow the appropriate !literal
710 relocations, and similarly for !gpdisp relocations. */
713 alpha_before_fix (void)
715 if (alpha_literal_hash
)
716 bfd_map_over_sections (stdoutput
, alpha_adjust_relocs
, NULL
);
721 debug_exp (expressionS tok
[], int ntok
)
725 fprintf (stderr
, "debug_exp: %d tokens", ntok
);
726 for (i
= 0; i
< ntok
; i
++)
728 expressionS
*t
= &tok
[i
];
733 default: name
= "unknown"; break;
734 case O_illegal
: name
= "O_illegal"; break;
735 case O_absent
: name
= "O_absent"; break;
736 case O_constant
: name
= "O_constant"; break;
737 case O_symbol
: name
= "O_symbol"; break;
738 case O_symbol_rva
: name
= "O_symbol_rva"; break;
739 case O_register
: name
= "O_register"; break;
740 case O_big
: name
= "O_big"; break;
741 case O_uminus
: name
= "O_uminus"; break;
742 case O_bit_not
: name
= "O_bit_not"; break;
743 case O_logical_not
: name
= "O_logical_not"; break;
744 case O_multiply
: name
= "O_multiply"; break;
745 case O_divide
: name
= "O_divide"; break;
746 case O_modulus
: name
= "O_modulus"; break;
747 case O_left_shift
: name
= "O_left_shift"; break;
748 case O_right_shift
: name
= "O_right_shift"; break;
749 case O_bit_inclusive_or
: name
= "O_bit_inclusive_or"; break;
750 case O_bit_or_not
: name
= "O_bit_or_not"; break;
751 case O_bit_exclusive_or
: name
= "O_bit_exclusive_or"; break;
752 case O_bit_and
: name
= "O_bit_and"; break;
753 case O_add
: name
= "O_add"; break;
754 case O_subtract
: name
= "O_subtract"; break;
755 case O_eq
: name
= "O_eq"; break;
756 case O_ne
: name
= "O_ne"; break;
757 case O_lt
: name
= "O_lt"; break;
758 case O_le
: name
= "O_le"; break;
759 case O_ge
: name
= "O_ge"; break;
760 case O_gt
: name
= "O_gt"; break;
761 case O_logical_and
: name
= "O_logical_and"; break;
762 case O_logical_or
: name
= "O_logical_or"; break;
763 case O_index
: name
= "O_index"; break;
764 case O_pregister
: name
= "O_pregister"; break;
765 case O_cpregister
: name
= "O_cpregister"; break;
766 case O_literal
: name
= "O_literal"; break;
767 case O_lituse_addr
: name
= "O_lituse_addr"; break;
768 case O_lituse_base
: name
= "O_lituse_base"; break;
769 case O_lituse_bytoff
: name
= "O_lituse_bytoff"; break;
770 case O_lituse_jsr
: name
= "O_lituse_jsr"; break;
771 case O_lituse_tlsgd
: name
= "O_lituse_tlsgd"; break;
772 case O_lituse_tlsldm
: name
= "O_lituse_tlsldm"; break;
773 case O_gpdisp
: name
= "O_gpdisp"; break;
774 case O_gprelhigh
: name
= "O_gprelhigh"; break;
775 case O_gprellow
: name
= "O_gprellow"; break;
776 case O_gprel
: name
= "O_gprel"; break;
777 case O_samegp
: name
= "O_samegp"; break;
778 case O_tlsgd
: name
= "O_tlsgd"; break;
779 case O_tlsldm
: name
= "O_tlsldm"; break;
780 case O_gotdtprel
: name
= "O_gotdtprel"; break;
781 case O_dtprelhi
: name
= "O_dtprelhi"; break;
782 case O_dtprello
: name
= "O_dtprello"; break;
783 case O_dtprel
: name
= "O_dtprel"; break;
784 case O_gottprel
: name
= "O_gottprel"; break;
785 case O_tprelhi
: name
= "O_tprelhi"; break;
786 case O_tprello
: name
= "O_tprello"; break;
787 case O_tprel
: name
= "O_tprel"; break;
790 fprintf (stderr
, ", %s(%s, %s, %d)", name
,
791 (t
->X_add_symbol
) ? S_GET_NAME (t
->X_add_symbol
) : "--",
792 (t
->X_op_symbol
) ? S_GET_NAME (t
->X_op_symbol
) : "--",
793 (int) t
->X_add_number
);
795 fprintf (stderr
, "\n");
800 /* Parse the arguments to an opcode. */
803 tokenize_arguments (char *str
,
807 expressionS
*end_tok
= tok
+ ntok
;
808 char *old_input_line_pointer
;
809 int saw_comma
= 0, saw_arg
= 0;
811 expressionS
*orig_tok
= tok
;
815 const struct alpha_reloc_op_tag
*r
;
818 int reloc_found_p
= 0;
821 memset (tok
, 0, sizeof (*tok
) * ntok
);
823 /* Save and restore input_line_pointer around this function. */
824 old_input_line_pointer
= input_line_pointer
;
825 input_line_pointer
= str
;
828 /* ??? Wrest control of ! away from the regular expression parser. */
829 is_end_of_line
[(unsigned char) '!'] = 1;
832 while (tok
< end_tok
&& *input_line_pointer
)
835 switch (*input_line_pointer
)
842 /* A relocation operand can be placed after the normal operand on an
843 assembly language statement, and has the following form:
844 !relocation_type!sequence_number. */
847 /* Only support one relocation op per insn. */
848 as_bad (_("More than one relocation op per insn"));
855 ++input_line_pointer
;
857 p
= input_line_pointer
;
858 c
= get_symbol_end ();
860 /* Parse !relocation_type. */
861 len
= input_line_pointer
- p
;
864 as_bad (_("No relocation operand"));
868 r
= &alpha_reloc_op
[0];
869 for (i
= alpha_num_reloc_op
- 1; i
>= 0; i
--, r
++)
870 if (len
== r
->length
&& memcmp (p
, r
->name
, len
) == 0)
874 as_bad (_("Unknown relocation operand: !%s"), p
);
878 *input_line_pointer
= c
;
880 if (*input_line_pointer
!= '!')
884 as_bad (_("no sequence number after !%s"), p
);
888 tok
->X_add_number
= 0;
894 as_bad (_("!%s does not use a sequence number"), p
);
898 input_line_pointer
++;
900 /* Parse !sequence_number. */
902 if (tok
->X_op
!= O_constant
|| tok
->X_add_number
<= 0)
904 as_bad (_("Bad sequence number: !%s!%s"),
905 r
->name
, input_line_pointer
);
914 #endif /* RELOC_OP_P */
917 ++input_line_pointer
;
918 if (saw_comma
|| !saw_arg
)
925 char *hold
= input_line_pointer
++;
927 /* First try for parenthesized register ... */
929 if (*input_line_pointer
== ')' && tok
->X_op
== O_register
)
931 tok
->X_op
= (saw_comma
? O_cpregister
: O_pregister
);
934 ++input_line_pointer
;
939 /* ... then fall through to plain expression. */
940 input_line_pointer
= hold
;
944 if (saw_arg
&& !saw_comma
)
948 if (tok
->X_op
== O_illegal
|| tok
->X_op
== O_absent
)
961 input_line_pointer
= old_input_line_pointer
;
964 debug_exp (orig_tok
, ntok
- (end_tok
- tok
));
967 is_end_of_line
[(unsigned char) '!'] = 0;
970 return ntok
- (end_tok
- tok
);
974 is_end_of_line
[(unsigned char) '!'] = 0;
976 input_line_pointer
= old_input_line_pointer
;
977 return TOKENIZE_ERROR
;
981 is_end_of_line
[(unsigned char) '!'] = 0;
983 input_line_pointer
= old_input_line_pointer
;
984 return TOKENIZE_ERROR_REPORT
;
987 /* Search forward through all variants of an opcode looking for a
990 static const struct alpha_opcode
*
991 find_opcode_match (const struct alpha_opcode
*first_opcode
,
992 const expressionS
*tok
,
996 const struct alpha_opcode
*opcode
= first_opcode
;
998 int got_cpu_match
= 0;
1002 const unsigned char *opidx
;
1005 /* Don't match opcodes that don't exist on this architecture. */
1006 if (!(opcode
->flags
& alpha_target
))
1011 for (opidx
= opcode
->operands
; *opidx
; ++opidx
)
1013 const struct alpha_operand
*operand
= &alpha_operands
[*opidx
];
1015 /* Only take input from real operands. */
1016 if (operand
->flags
& AXP_OPERAND_FAKE
)
1019 /* When we expect input, make sure we have it. */
1022 if ((operand
->flags
& AXP_OPERAND_OPTIONAL_MASK
) == 0)
1027 /* Match operand type with expression type. */
1028 switch (operand
->flags
& AXP_OPERAND_TYPECHECK_MASK
)
1030 case AXP_OPERAND_IR
:
1031 if (tok
[tokidx
].X_op
!= O_register
1032 || !is_ir_num (tok
[tokidx
].X_add_number
))
1035 case AXP_OPERAND_FPR
:
1036 if (tok
[tokidx
].X_op
!= O_register
1037 || !is_fpr_num (tok
[tokidx
].X_add_number
))
1040 case AXP_OPERAND_IR
| AXP_OPERAND_PARENS
:
1041 if (tok
[tokidx
].X_op
!= O_pregister
1042 || !is_ir_num (tok
[tokidx
].X_add_number
))
1045 case AXP_OPERAND_IR
| AXP_OPERAND_PARENS
| AXP_OPERAND_COMMA
:
1046 if (tok
[tokidx
].X_op
!= O_cpregister
1047 || !is_ir_num (tok
[tokidx
].X_add_number
))
1051 case AXP_OPERAND_RELATIVE
:
1052 case AXP_OPERAND_SIGNED
:
1053 case AXP_OPERAND_UNSIGNED
:
1054 switch (tok
[tokidx
].X_op
)
1069 /* Everything else should have been fake. */
1075 /* Possible match -- did we use all of our input? */
1084 while (++opcode
- alpha_opcodes
< (int) alpha_num_opcodes
1085 && !strcmp (opcode
->name
, first_opcode
->name
));
1088 *pcpumatch
= got_cpu_match
;
1093 /* Given an opcode name and a pre-tokenized set of arguments, assemble
1094 the insn, but do not emit it.
1096 Note that this implies no macros allowed, since we can't store more
1097 than one insn in an insn structure. */
1100 assemble_tokens_to_insn (const char *opname
,
1101 const expressionS
*tok
,
1103 struct alpha_insn
*insn
)
1105 const struct alpha_opcode
*opcode
;
1107 /* Search opcodes. */
1108 opcode
= (const struct alpha_opcode
*) hash_find (alpha_opcode_hash
, opname
);
1112 opcode
= find_opcode_match (opcode
, tok
, &ntok
, &cpumatch
);
1115 assemble_insn (opcode
, tok
, ntok
, insn
, BFD_RELOC_UNUSED
);
1119 as_bad (_("inappropriate arguments for opcode `%s'"), opname
);
1121 as_bad (_("opcode `%s' not supported for target %s"), opname
,
1125 as_bad (_("unknown opcode `%s'"), opname
);
1128 /* Build a BFD section with its flags set appropriately for the .lita,
1129 .lit8, or .lit4 sections. */
1132 create_literal_section (const char *name
,
1136 segT current_section
= now_seg
;
1137 int current_subsec
= now_subseg
;
1140 *secp
= new_sec
= subseg_new (name
, 0);
1141 subseg_set (current_section
, current_subsec
);
1142 bfd_set_section_alignment (stdoutput
, new_sec
, 4);
1143 bfd_set_section_flags (stdoutput
, new_sec
,
1144 SEC_RELOC
| SEC_ALLOC
| SEC_LOAD
| SEC_READONLY
1147 S_CLEAR_EXTERNAL (*symp
= section_symbol (new_sec
));
1150 /* Load a (partial) expression into a target register.
1152 If poffset is not null, after the call it will either contain
1153 O_constant 0, or a 16-bit offset appropriate for any MEM format
1154 instruction. In addition, pbasereg will be modified to point to
1155 the base register to use in that MEM format instruction.
1157 In any case, *pbasereg should contain a base register to add to the
1158 expression. This will normally be either AXP_REG_ZERO or
1159 alpha_gp_register. Symbol addresses will always be loaded via $gp,
1160 so "foo($0)" is interpreted as adding the address of foo to $0;
1161 i.e. "ldq $targ, LIT($gp); addq $targ, $0, $targ". Odd, perhaps,
1162 but this is what OSF/1 does.
1164 If explicit relocations of the form !literal!<number> are allowed,
1165 and used, then explicit_reloc with be an expression pointer.
1167 Finally, the return value is nonzero if the calling macro may emit
1168 a LITUSE reloc if otherwise appropriate; the return value is the
1169 sequence number to use. */
1172 load_expression (int targreg
,
1173 const expressionS
*exp
,
1175 expressionS
*poffset
)
1177 long emit_lituse
= 0;
1178 offsetT addend
= exp
->X_add_number
;
1179 int basereg
= *pbasereg
;
1180 struct alpha_insn insn
;
1181 expressionS newtok
[3];
1190 /* Attempt to reduce .lit load by splitting the offset from
1191 its symbol when possible, but don't create a situation in
1193 if (!range_signed_32 (addend
) &&
1194 (alpha_noat_on
|| targreg
== AXP_REG_AT
))
1196 lit
= add_to_literal_pool (exp
->X_add_symbol
, addend
,
1197 alpha_lita_section
, 8);
1201 lit
= add_to_literal_pool (exp
->X_add_symbol
, 0,
1202 alpha_lita_section
, 8);
1205 as_fatal (_("overflow in literal (.lita) table"));
1207 /* Emit "ldq r, lit(gp)". */
1209 if (basereg
!= alpha_gp_register
&& targreg
== basereg
)
1212 as_bad (_("macro requires $at register while noat in effect"));
1213 if (targreg
== AXP_REG_AT
)
1214 as_bad (_("macro requires $at while $at in use"));
1216 set_tok_reg (newtok
[0], AXP_REG_AT
);
1219 set_tok_reg (newtok
[0], targreg
);
1221 set_tok_sym (newtok
[1], alpha_lita_symbol
, lit
);
1222 set_tok_preg (newtok
[2], alpha_gp_register
);
1224 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
1226 assert (insn
.nfixups
== 1);
1227 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITERAL
;
1228 insn
.sequence
= emit_lituse
= next_sequence_num
--;
1229 #endif /* OBJ_ECOFF */
1231 /* Emit "ldq r, gotoff(gp)". */
1233 if (basereg
!= alpha_gp_register
&& targreg
== basereg
)
1236 as_bad (_("macro requires $at register while noat in effect"));
1237 if (targreg
== AXP_REG_AT
)
1238 as_bad (_("macro requires $at while $at in use"));
1240 set_tok_reg (newtok
[0], AXP_REG_AT
);
1243 set_tok_reg (newtok
[0], targreg
);
1245 /* XXX: Disable this .got minimizing optimization so that we can get
1246 better instruction offset knowledge in the compiler. This happens
1247 very infrequently anyway. */
1249 || (!range_signed_32 (addend
)
1250 && (alpha_noat_on
|| targreg
== AXP_REG_AT
)))
1256 set_tok_sym (newtok
[1], exp
->X_add_symbol
, 0);
1258 set_tok_preg (newtok
[2], alpha_gp_register
);
1260 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
1262 assert (insn
.nfixups
== 1);
1263 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_ELF_LITERAL
;
1264 insn
.sequence
= emit_lituse
= next_sequence_num
--;
1265 #endif /* OBJ_ELF */
1269 /* Find symbol or symbol pointer in link section. */
1271 if (exp
->X_add_symbol
== alpha_evax_proc
.symbol
)
1273 if (range_signed_16 (addend
))
1275 set_tok_reg (newtok
[0], targreg
);
1276 set_tok_const (newtok
[1], addend
);
1277 set_tok_preg (newtok
[2], basereg
);
1278 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
1283 set_tok_reg (newtok
[0], targreg
);
1284 set_tok_const (newtok
[1], 0);
1285 set_tok_preg (newtok
[2], basereg
);
1286 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
1291 if (!range_signed_32 (addend
))
1293 link
= add_to_link_pool (alpha_evax_proc
.symbol
,
1294 exp
->X_add_symbol
, addend
);
1298 link
= add_to_link_pool (alpha_evax_proc
.symbol
,
1299 exp
->X_add_symbol
, 0);
1301 set_tok_reg (newtok
[0], targreg
);
1302 set_tok_const (newtok
[1], link
);
1303 set_tok_preg (newtok
[2], basereg
);
1304 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
1306 #endif /* OBJ_EVAX */
1311 if (basereg
!= alpha_gp_register
&& basereg
!= AXP_REG_ZERO
)
1313 /* Emit "addq r, base, r". */
1315 set_tok_reg (newtok
[1], basereg
);
1316 set_tok_reg (newtok
[2], targreg
);
1317 assemble_tokens ("addq", newtok
, 3, 0);
1328 /* Assume that this difference expression will be resolved to an
1329 absolute value and that that value will fit in 16 bits. */
1331 set_tok_reg (newtok
[0], targreg
);
1333 set_tok_preg (newtok
[2], basereg
);
1334 assemble_tokens ("lda", newtok
, 3, 0);
1337 set_tok_const (*poffset
, 0);
1341 if (exp
->X_add_number
> 0)
1342 as_bad (_("bignum invalid; zero assumed"));
1344 as_bad (_("floating point number invalid; zero assumed"));
1349 as_bad (_("can't handle expression"));
1354 if (!range_signed_32 (addend
))
1357 long seq_num
= next_sequence_num
--;
1359 /* For 64-bit addends, just put it in the literal pool. */
1361 /* Emit "ldq targreg, lit(basereg)". */
1362 lit
= add_to_link_pool (alpha_evax_proc
.symbol
,
1363 section_symbol (absolute_section
), addend
);
1364 set_tok_reg (newtok
[0], targreg
);
1365 set_tok_const (newtok
[1], lit
);
1366 set_tok_preg (newtok
[2], alpha_gp_register
);
1367 assemble_tokens ("ldq", newtok
, 3, 0);
1370 if (alpha_lit8_section
== NULL
)
1372 create_literal_section (".lit8",
1373 &alpha_lit8_section
,
1374 &alpha_lit8_symbol
);
1377 alpha_lit8_literal
= add_to_literal_pool (alpha_lit8_symbol
, 0x8000,
1378 alpha_lita_section
, 8);
1379 if (alpha_lit8_literal
>= 0x8000)
1380 as_fatal (_("overflow in literal (.lita) table"));
1384 lit
= add_to_literal_pool (NULL
, addend
, alpha_lit8_section
, 8) - 0x8000;
1386 as_fatal (_("overflow in literal (.lit8) table"));
1388 /* Emit "lda litreg, .lit8+0x8000". */
1390 if (targreg
== basereg
)
1393 as_bad (_("macro requires $at register while noat in effect"));
1394 if (targreg
== AXP_REG_AT
)
1395 as_bad (_("macro requires $at while $at in use"));
1397 set_tok_reg (newtok
[0], AXP_REG_AT
);
1400 set_tok_reg (newtok
[0], targreg
);
1402 set_tok_sym (newtok
[1], alpha_lita_symbol
, alpha_lit8_literal
);
1405 set_tok_sym (newtok
[1], alpha_lit8_symbol
, 0x8000);
1407 set_tok_preg (newtok
[2], alpha_gp_register
);
1409 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
1411 assert (insn
.nfixups
== 1);
1413 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITERAL
;
1416 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_ELF_LITERAL
;
1418 insn
.sequence
= seq_num
;
1422 /* Emit "ldq litreg, lit(litreg)". */
1424 set_tok_const (newtok
[1], lit
);
1425 set_tok_preg (newtok
[2], newtok
[0].X_add_number
);
1427 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
1429 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
1430 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BASE
;
1431 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
1433 insn
.sequence
= seq_num
;
1438 /* Emit "addq litreg, base, target". */
1440 if (basereg
!= AXP_REG_ZERO
)
1442 set_tok_reg (newtok
[1], basereg
);
1443 set_tok_reg (newtok
[2], targreg
);
1444 assemble_tokens ("addq", newtok
, 3, 0);
1446 #endif /* !OBJ_EVAX */
1449 set_tok_const (*poffset
, 0);
1450 *pbasereg
= targreg
;
1454 offsetT low
, high
, extra
, tmp
;
1456 /* For 32-bit operands, break up the addend. */
1458 low
= sign_extend_16 (addend
);
1460 high
= sign_extend_16 (tmp
>> 16);
1462 if (tmp
- (high
<< 16))
1466 high
= sign_extend_16 (tmp
>> 16);
1471 set_tok_reg (newtok
[0], targreg
);
1472 set_tok_preg (newtok
[2], basereg
);
1476 /* Emit "ldah r, extra(r). */
1477 set_tok_const (newtok
[1], extra
);
1478 assemble_tokens ("ldah", newtok
, 3, 0);
1479 set_tok_preg (newtok
[2], basereg
= targreg
);
1484 /* Emit "ldah r, high(r). */
1485 set_tok_const (newtok
[1], high
);
1486 assemble_tokens ("ldah", newtok
, 3, 0);
1488 set_tok_preg (newtok
[2], basereg
);
1491 if ((low
&& !poffset
) || (!poffset
&& basereg
!= targreg
))
1493 /* Emit "lda r, low(base)". */
1494 set_tok_const (newtok
[1], low
);
1495 assemble_tokens ("lda", newtok
, 3, 0);
1501 set_tok_const (*poffset
, low
);
1502 *pbasereg
= basereg
;
1508 /* The lda macro differs from the lda instruction in that it handles
1509 most simple expressions, particularly symbol address loads and
1513 emit_lda (const expressionS
*tok
,
1515 const void * unused ATTRIBUTE_UNUSED
)
1520 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
1522 basereg
= tok
[2].X_add_number
;
1524 (void) load_expression (tok
[0].X_add_number
, &tok
[1], &basereg
, NULL
);
1527 /* The ldah macro differs from the ldah instruction in that it has $31
1528 as an implied base register. */
1531 emit_ldah (const expressionS
*tok
,
1532 int ntok ATTRIBUTE_UNUSED
,
1533 const void * unused ATTRIBUTE_UNUSED
)
1535 expressionS newtok
[3];
1539 set_tok_preg (newtok
[2], AXP_REG_ZERO
);
1541 assemble_tokens ("ldah", newtok
, 3, 0);
1544 /* Called internally to handle all alignment needs. This takes care
1545 of eliding calls to frag_align if'n the cached current alignment
1546 says we've already got it, as well as taking care of the auto-align
1547 feature wrt labels. */
1553 int force ATTRIBUTE_UNUSED
)
1555 if (alpha_current_align
>= n
)
1560 if (subseg_text_p (now_seg
))
1561 frag_align_code (n
, 0);
1563 frag_align (n
, 0, 0);
1566 frag_align (n
, *pfill
, 0);
1568 alpha_current_align
= n
;
1570 if (label
!= NULL
&& S_GET_SEGMENT (label
) == now_seg
)
1572 symbol_set_frag (label
, frag_now
);
1573 S_SET_VALUE (label
, (valueT
) frag_now_fix ());
1576 record_alignment (now_seg
, n
);
1578 /* ??? If alpha_flag_relax && force && elf, record the requested alignment
1579 in a reloc for the linker to see. */
1582 /* Actually output an instruction with its fixup. */
1585 emit_insn (struct alpha_insn
*insn
)
1590 /* Take care of alignment duties. */
1591 if (alpha_auto_align_on
&& alpha_current_align
< 2)
1592 alpha_align (2, (char *) NULL
, alpha_insn_label
, 0);
1593 if (alpha_current_align
> 2)
1594 alpha_current_align
= 2;
1595 alpha_insn_label
= NULL
;
1597 /* Write out the instruction. */
1599 md_number_to_chars (f
, insn
->insn
, 4);
1602 dwarf2_emit_insn (4);
1605 /* Apply the fixups in order. */
1606 for (i
= 0; i
< insn
->nfixups
; ++i
)
1608 const struct alpha_operand
*operand
= (const struct alpha_operand
*) 0;
1609 struct alpha_fixup
*fixup
= &insn
->fixups
[i
];
1610 struct alpha_reloc_tag
*info
= NULL
;
1614 /* Some fixups are only used internally and so have no howto. */
1615 if ((int) fixup
->reloc
< 0)
1617 operand
= &alpha_operands
[-(int) fixup
->reloc
];
1619 pcrel
= ((operand
->flags
& AXP_OPERAND_RELATIVE
) != 0);
1621 else if (fixup
->reloc
> BFD_RELOC_UNUSED
1622 || fixup
->reloc
== BFD_RELOC_ALPHA_GPDISP_HI16
1623 || fixup
->reloc
== BFD_RELOC_ALPHA_GPDISP_LO16
)
1630 reloc_howto_type
*reloc_howto
1631 = bfd_reloc_type_lookup (stdoutput
, fixup
->reloc
);
1632 assert (reloc_howto
);
1634 size
= bfd_get_reloc_size (reloc_howto
);
1635 assert (size
>= 1 && size
<= 4);
1637 pcrel
= reloc_howto
->pc_relative
;
1640 fixP
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, size
,
1641 &fixup
->exp
, pcrel
, fixup
->reloc
);
1643 /* Turn off complaints that the addend is too large for some fixups,
1644 and copy in the sequence number for the explicit relocations. */
1645 switch (fixup
->reloc
)
1647 case BFD_RELOC_ALPHA_HINT
:
1648 case BFD_RELOC_GPREL32
:
1649 case BFD_RELOC_GPREL16
:
1650 case BFD_RELOC_ALPHA_GPREL_HI16
:
1651 case BFD_RELOC_ALPHA_GPREL_LO16
:
1652 case BFD_RELOC_ALPHA_GOTDTPREL16
:
1653 case BFD_RELOC_ALPHA_DTPREL_HI16
:
1654 case BFD_RELOC_ALPHA_DTPREL_LO16
:
1655 case BFD_RELOC_ALPHA_DTPREL16
:
1656 case BFD_RELOC_ALPHA_GOTTPREL16
:
1657 case BFD_RELOC_ALPHA_TPREL_HI16
:
1658 case BFD_RELOC_ALPHA_TPREL_LO16
:
1659 case BFD_RELOC_ALPHA_TPREL16
:
1660 fixP
->fx_no_overflow
= 1;
1663 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1664 fixP
->fx_no_overflow
= 1;
1665 fixP
->fx_addsy
= section_symbol (now_seg
);
1666 fixP
->fx_offset
= 0;
1668 info
= get_alpha_reloc_tag (insn
->sequence
);
1669 if (++info
->n_master
> 1)
1670 as_bad (_("too many ldah insns for !gpdisp!%ld"), insn
->sequence
);
1671 if (info
->segment
!= now_seg
)
1672 as_bad (_("both insns for !gpdisp!%ld must be in the same section"),
1674 fixP
->tc_fix_data
.info
= info
;
1677 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1678 fixP
->fx_no_overflow
= 1;
1680 info
= get_alpha_reloc_tag (insn
->sequence
);
1681 if (++info
->n_slaves
> 1)
1682 as_bad (_("too many lda insns for !gpdisp!%ld"), insn
->sequence
);
1683 if (info
->segment
!= now_seg
)
1684 as_bad (_("both insns for !gpdisp!%ld must be in the same section"),
1686 fixP
->tc_fix_data
.info
= info
;
1687 info
->slaves
= fixP
;
1690 case BFD_RELOC_ALPHA_LITERAL
:
1691 case BFD_RELOC_ALPHA_ELF_LITERAL
:
1692 fixP
->fx_no_overflow
= 1;
1694 if (insn
->sequence
== 0)
1696 info
= get_alpha_reloc_tag (insn
->sequence
);
1697 info
->master
= fixP
;
1699 if (info
->segment
!= now_seg
)
1700 info
->multi_section_p
= 1;
1701 fixP
->tc_fix_data
.info
= info
;
1705 case DUMMY_RELOC_LITUSE_ADDR
:
1706 fixP
->fx_offset
= LITUSE_ALPHA_ADDR
;
1708 case DUMMY_RELOC_LITUSE_BASE
:
1709 fixP
->fx_offset
= LITUSE_ALPHA_BASE
;
1711 case DUMMY_RELOC_LITUSE_BYTOFF
:
1712 fixP
->fx_offset
= LITUSE_ALPHA_BYTOFF
;
1714 case DUMMY_RELOC_LITUSE_JSR
:
1715 fixP
->fx_offset
= LITUSE_ALPHA_JSR
;
1717 case DUMMY_RELOC_LITUSE_TLSGD
:
1718 fixP
->fx_offset
= LITUSE_ALPHA_TLSGD
;
1720 case DUMMY_RELOC_LITUSE_TLSLDM
:
1721 fixP
->fx_offset
= LITUSE_ALPHA_TLSLDM
;
1724 fixP
->fx_addsy
= section_symbol (now_seg
);
1725 fixP
->fx_r_type
= BFD_RELOC_ALPHA_LITUSE
;
1727 info
= get_alpha_reloc_tag (insn
->sequence
);
1728 if (fixup
->reloc
== DUMMY_RELOC_LITUSE_TLSGD
)
1729 info
->saw_lu_tlsgd
= 1;
1730 else if (fixup
->reloc
== DUMMY_RELOC_LITUSE_TLSLDM
)
1731 info
->saw_lu_tlsldm
= 1;
1732 if (++info
->n_slaves
> 1)
1734 if (info
->saw_lu_tlsgd
)
1735 as_bad (_("too many lituse insns for !lituse_tlsgd!%ld"),
1737 else if (info
->saw_lu_tlsldm
)
1738 as_bad (_("too many lituse insns for !lituse_tlsldm!%ld"),
1741 fixP
->tc_fix_data
.info
= info
;
1742 fixP
->tc_fix_data
.next_reloc
= info
->slaves
;
1743 info
->slaves
= fixP
;
1744 if (info
->segment
!= now_seg
)
1745 info
->multi_section_p
= 1;
1748 case BFD_RELOC_ALPHA_TLSGD
:
1749 fixP
->fx_no_overflow
= 1;
1751 if (insn
->sequence
== 0)
1753 info
= get_alpha_reloc_tag (insn
->sequence
);
1754 if (info
->saw_tlsgd
)
1755 as_bad (_("duplicate !tlsgd!%ld"), insn
->sequence
);
1756 else if (info
->saw_tlsldm
)
1757 as_bad (_("sequence number in use for !tlsldm!%ld"),
1760 info
->saw_tlsgd
= 1;
1761 fixP
->tc_fix_data
.info
= info
;
1764 case BFD_RELOC_ALPHA_TLSLDM
:
1765 fixP
->fx_no_overflow
= 1;
1767 if (insn
->sequence
== 0)
1769 info
= get_alpha_reloc_tag (insn
->sequence
);
1770 if (info
->saw_tlsldm
)
1771 as_bad (_("duplicate !tlsldm!%ld"), insn
->sequence
);
1772 else if (info
->saw_tlsgd
)
1773 as_bad (_("sequence number in use for !tlsgd!%ld"),
1776 info
->saw_tlsldm
= 1;
1777 fixP
->tc_fix_data
.info
= info
;
1781 if ((int) fixup
->reloc
< 0)
1783 if (operand
->flags
& AXP_OPERAND_NOOVERFLOW
)
1784 fixP
->fx_no_overflow
= 1;
1791 /* Insert an operand value into an instruction. */
1794 insert_operand (unsigned insn
,
1795 const struct alpha_operand
*operand
,
1800 if (operand
->bits
!= 32 && !(operand
->flags
& AXP_OPERAND_NOOVERFLOW
))
1804 if (operand
->flags
& AXP_OPERAND_SIGNED
)
1806 max
= (1 << (operand
->bits
- 1)) - 1;
1807 min
= -(1 << (operand
->bits
- 1));
1811 max
= (1 << operand
->bits
) - 1;
1815 if (val
< min
|| val
> max
)
1816 as_warn_value_out_of_range (_("operand"), val
, min
, max
, file
, line
);
1819 if (operand
->insert
)
1821 const char *errmsg
= NULL
;
1823 insn
= (*operand
->insert
) (insn
, val
, &errmsg
);
1828 insn
|= ((val
& ((1 << operand
->bits
) - 1)) << operand
->shift
);
1833 /* Turn an opcode description and a set of arguments into
1834 an instruction and a fixup. */
1837 assemble_insn (const struct alpha_opcode
*opcode
,
1838 const expressionS
*tok
,
1840 struct alpha_insn
*insn
,
1841 bfd_reloc_code_real_type reloc
)
1843 const struct alpha_operand
*reloc_operand
= NULL
;
1844 const expressionS
*reloc_exp
= NULL
;
1845 const unsigned char *argidx
;
1849 memset (insn
, 0, sizeof (*insn
));
1850 image
= opcode
->opcode
;
1852 for (argidx
= opcode
->operands
; *argidx
; ++argidx
)
1854 const struct alpha_operand
*operand
= &alpha_operands
[*argidx
];
1855 const expressionS
*t
= (const expressionS
*) 0;
1857 if (operand
->flags
& AXP_OPERAND_FAKE
)
1859 /* Fake operands take no value and generate no fixup. */
1860 image
= insert_operand (image
, operand
, 0, NULL
, 0);
1866 switch (operand
->flags
& AXP_OPERAND_OPTIONAL_MASK
)
1868 case AXP_OPERAND_DEFAULT_FIRST
:
1871 case AXP_OPERAND_DEFAULT_SECOND
:
1874 case AXP_OPERAND_DEFAULT_ZERO
:
1876 static expressionS zero_exp
;
1878 zero_exp
.X_op
= O_constant
;
1879 zero_exp
.X_unsigned
= 1;
1894 image
= insert_operand (image
, operand
, regno (t
->X_add_number
),
1899 image
= insert_operand (image
, operand
, t
->X_add_number
, NULL
, 0);
1900 assert (reloc_operand
== NULL
);
1901 reloc_operand
= operand
;
1906 /* This is only 0 for fields that should contain registers,
1907 which means this pattern shouldn't have matched. */
1908 if (operand
->default_reloc
== 0)
1911 /* There is one special case for which an insn receives two
1912 relocations, and thus the user-supplied reloc does not
1913 override the operand reloc. */
1914 if (operand
->default_reloc
== BFD_RELOC_ALPHA_HINT
)
1916 struct alpha_fixup
*fixup
;
1918 if (insn
->nfixups
>= MAX_INSN_FIXUPS
)
1919 as_fatal (_("too many fixups"));
1921 fixup
= &insn
->fixups
[insn
->nfixups
++];
1923 fixup
->reloc
= BFD_RELOC_ALPHA_HINT
;
1927 if (reloc
== BFD_RELOC_UNUSED
)
1928 reloc
= operand
->default_reloc
;
1930 assert (reloc_operand
== NULL
);
1931 reloc_operand
= operand
;
1938 if (reloc
!= BFD_RELOC_UNUSED
)
1940 struct alpha_fixup
*fixup
;
1942 if (insn
->nfixups
>= MAX_INSN_FIXUPS
)
1943 as_fatal (_("too many fixups"));
1945 /* ??? My but this is hacky. But the OSF/1 assembler uses the same
1946 relocation tag for both ldah and lda with gpdisp. Choose the
1947 correct internal relocation based on the opcode. */
1948 if (reloc
== BFD_RELOC_ALPHA_GPDISP
)
1950 if (strcmp (opcode
->name
, "ldah") == 0)
1951 reloc
= BFD_RELOC_ALPHA_GPDISP_HI16
;
1952 else if (strcmp (opcode
->name
, "lda") == 0)
1953 reloc
= BFD_RELOC_ALPHA_GPDISP_LO16
;
1955 as_bad (_("invalid relocation for instruction"));
1958 /* If this is a real relocation (as opposed to a lituse hint), then
1959 the relocation width should match the operand width. */
1960 else if (reloc
< BFD_RELOC_UNUSED
)
1962 reloc_howto_type
*reloc_howto
1963 = bfd_reloc_type_lookup (stdoutput
, reloc
);
1964 if (reloc_howto
->bitsize
!= reloc_operand
->bits
)
1966 as_bad (_("invalid relocation for field"));
1971 fixup
= &insn
->fixups
[insn
->nfixups
++];
1973 fixup
->exp
= *reloc_exp
;
1975 fixup
->exp
.X_op
= O_absent
;
1976 fixup
->reloc
= reloc
;
1982 /* Handle all "simple" integer register loads -- ldq, ldq_l, ldq_u,
1983 etc. They differ from the real instructions in that they do simple
1984 expressions like the lda macro. */
1987 emit_ir_load (const expressionS
*tok
,
1989 const void * opname
)
1993 expressionS newtok
[3];
1994 struct alpha_insn insn
;
1997 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
1999 basereg
= tok
[2].X_add_number
;
2001 lituse
= load_expression (tok
[0].X_add_number
, &tok
[1], &basereg
,
2005 set_tok_preg (newtok
[2], basereg
);
2007 assemble_tokens_to_insn ((const char *) opname
, newtok
, 3, &insn
);
2011 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
2012 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BASE
;
2013 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
2015 insn
.sequence
= lituse
;
2021 /* Handle fp register loads, and both integer and fp register stores.
2022 Again, we handle simple expressions. */
2025 emit_loadstore (const expressionS
*tok
,
2027 const void * opname
)
2031 expressionS newtok
[3];
2032 struct alpha_insn insn
;
2035 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
2037 basereg
= tok
[2].X_add_number
;
2039 if (tok
[1].X_op
!= O_constant
|| !range_signed_16 (tok
[1].X_add_number
))
2042 as_bad (_("macro requires $at register while noat in effect"));
2044 lituse
= load_expression (AXP_REG_AT
, &tok
[1], &basereg
, &newtok
[1]);
2053 set_tok_preg (newtok
[2], basereg
);
2055 assemble_tokens_to_insn ((const char *) opname
, newtok
, 3, &insn
);
2059 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
2060 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BASE
;
2061 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
2063 insn
.sequence
= lituse
;
2069 /* Load a half-word or byte as an unsigned value. */
2072 emit_ldXu (const expressionS
*tok
,
2074 const void * vlgsize
)
2076 if (alpha_target
& AXP_OPCODE_BWX
)
2077 emit_ir_load (tok
, ntok
, ldXu_op
[(long) vlgsize
]);
2080 expressionS newtok
[3];
2081 struct alpha_insn insn
;
2086 as_bad (_("macro requires $at register while noat in effect"));
2089 basereg
= (tok
[1].X_op
== O_constant
2090 ? AXP_REG_ZERO
: alpha_gp_register
);
2092 basereg
= tok
[2].X_add_number
;
2094 /* Emit "lda $at, exp". */
2095 lituse
= load_expression (AXP_REG_AT
, &tok
[1], &basereg
, NULL
);
2097 /* Emit "ldq_u targ, 0($at)". */
2099 set_tok_const (newtok
[1], 0);
2100 set_tok_preg (newtok
[2], basereg
);
2101 assemble_tokens_to_insn ("ldq_u", newtok
, 3, &insn
);
2105 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
2106 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BASE
;
2107 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
2109 insn
.sequence
= lituse
;
2114 /* Emit "extXl targ, $at, targ". */
2115 set_tok_reg (newtok
[1], basereg
);
2116 newtok
[2] = newtok
[0];
2117 assemble_tokens_to_insn (extXl_op
[(long) vlgsize
], newtok
, 3, &insn
);
2121 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
2122 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BYTOFF
;
2123 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
2125 insn
.sequence
= lituse
;
2132 /* Load a half-word or byte as a signed value. */
2135 emit_ldX (const expressionS
*tok
,
2137 const void * vlgsize
)
2139 emit_ldXu (tok
, ntok
, vlgsize
);
2140 assemble_tokens (sextX_op
[(long) vlgsize
], tok
, 1, 1);
2143 /* Load an integral value from an unaligned address as an unsigned
2147 emit_uldXu (const expressionS
*tok
,
2149 const void * vlgsize
)
2151 long lgsize
= (long) vlgsize
;
2152 expressionS newtok
[3];
2155 as_bad (_("macro requires $at register while noat in effect"));
2157 /* Emit "lda $at, exp". */
2158 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
2159 newtok
[0].X_add_number
= AXP_REG_AT
;
2160 assemble_tokens ("lda", newtok
, ntok
, 1);
2162 /* Emit "ldq_u $t9, 0($at)". */
2163 set_tok_reg (newtok
[0], AXP_REG_T9
);
2164 set_tok_const (newtok
[1], 0);
2165 set_tok_preg (newtok
[2], AXP_REG_AT
);
2166 assemble_tokens ("ldq_u", newtok
, 3, 1);
2168 /* Emit "ldq_u $t10, size-1($at)". */
2169 set_tok_reg (newtok
[0], AXP_REG_T10
);
2170 set_tok_const (newtok
[1], (1 << lgsize
) - 1);
2171 assemble_tokens ("ldq_u", newtok
, 3, 1);
2173 /* Emit "extXl $t9, $at, $t9". */
2174 set_tok_reg (newtok
[0], AXP_REG_T9
);
2175 set_tok_reg (newtok
[1], AXP_REG_AT
);
2176 set_tok_reg (newtok
[2], AXP_REG_T9
);
2177 assemble_tokens (extXl_op
[lgsize
], newtok
, 3, 1);
2179 /* Emit "extXh $t10, $at, $t10". */
2180 set_tok_reg (newtok
[0], AXP_REG_T10
);
2181 set_tok_reg (newtok
[2], AXP_REG_T10
);
2182 assemble_tokens (extXh_op
[lgsize
], newtok
, 3, 1);
2184 /* Emit "or $t9, $t10, targ". */
2185 set_tok_reg (newtok
[0], AXP_REG_T9
);
2186 set_tok_reg (newtok
[1], AXP_REG_T10
);
2188 assemble_tokens ("or", newtok
, 3, 1);
2191 /* Load an integral value from an unaligned address as a signed value.
2192 Note that quads should get funneled to the unsigned load since we
2193 don't have to do the sign extension. */
2196 emit_uldX (const expressionS
*tok
,
2198 const void * vlgsize
)
2200 emit_uldXu (tok
, ntok
, vlgsize
);
2201 assemble_tokens (sextX_op
[(long) vlgsize
], tok
, 1, 1);
2204 /* Implement the ldil macro. */
2207 emit_ldil (const expressionS
*tok
,
2209 const void * unused ATTRIBUTE_UNUSED
)
2211 expressionS newtok
[2];
2213 memcpy (newtok
, tok
, sizeof (newtok
));
2214 newtok
[1].X_add_number
= sign_extend_32 (tok
[1].X_add_number
);
2216 assemble_tokens ("lda", newtok
, ntok
, 1);
2219 /* Store a half-word or byte. */
2222 emit_stX (const expressionS
*tok
,
2224 const void * vlgsize
)
2226 int lgsize
= (int) (long) vlgsize
;
2228 if (alpha_target
& AXP_OPCODE_BWX
)
2229 emit_loadstore (tok
, ntok
, stX_op
[lgsize
]);
2232 expressionS newtok
[3];
2233 struct alpha_insn insn
;
2238 as_bad (_("macro requires $at register while noat in effect"));
2241 basereg
= (tok
[1].X_op
== O_constant
2242 ? AXP_REG_ZERO
: alpha_gp_register
);
2244 basereg
= tok
[2].X_add_number
;
2246 /* Emit "lda $at, exp". */
2247 lituse
= load_expression (AXP_REG_AT
, &tok
[1], &basereg
, NULL
);
2249 /* Emit "ldq_u $t9, 0($at)". */
2250 set_tok_reg (newtok
[0], AXP_REG_T9
);
2251 set_tok_const (newtok
[1], 0);
2252 set_tok_preg (newtok
[2], basereg
);
2253 assemble_tokens_to_insn ("ldq_u", newtok
, 3, &insn
);
2257 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
2258 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BASE
;
2259 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
2261 insn
.sequence
= lituse
;
2266 /* Emit "insXl src, $at, $t10". */
2268 set_tok_reg (newtok
[1], basereg
);
2269 set_tok_reg (newtok
[2], AXP_REG_T10
);
2270 assemble_tokens_to_insn (insXl_op
[lgsize
], newtok
, 3, &insn
);
2274 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
2275 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BYTOFF
;
2276 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
2278 insn
.sequence
= lituse
;
2283 /* Emit "mskXl $t9, $at, $t9". */
2284 set_tok_reg (newtok
[0], AXP_REG_T9
);
2285 newtok
[2] = newtok
[0];
2286 assemble_tokens_to_insn (mskXl_op
[lgsize
], newtok
, 3, &insn
);
2290 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
2291 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BYTOFF
;
2292 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
2294 insn
.sequence
= lituse
;
2299 /* Emit "or $t9, $t10, $t9". */
2300 set_tok_reg (newtok
[1], AXP_REG_T10
);
2301 assemble_tokens ("or", newtok
, 3, 1);
2303 /* Emit "stq_u $t9, 0($at). */
2304 set_tok_const(newtok
[1], 0);
2305 set_tok_preg (newtok
[2], AXP_REG_AT
);
2306 assemble_tokens_to_insn ("stq_u", newtok
, 3, &insn
);
2310 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
2311 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_BASE
;
2312 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
2314 insn
.sequence
= lituse
;
2321 /* Store an integer to an unaligned address. */
2324 emit_ustX (const expressionS
*tok
,
2326 const void * vlgsize
)
2328 int lgsize
= (int) (long) vlgsize
;
2329 expressionS newtok
[3];
2331 /* Emit "lda $at, exp". */
2332 memcpy (newtok
, tok
, sizeof (expressionS
) * ntok
);
2333 newtok
[0].X_add_number
= AXP_REG_AT
;
2334 assemble_tokens ("lda", newtok
, ntok
, 1);
2336 /* Emit "ldq_u $9, 0($at)". */
2337 set_tok_reg (newtok
[0], AXP_REG_T9
);
2338 set_tok_const (newtok
[1], 0);
2339 set_tok_preg (newtok
[2], AXP_REG_AT
);
2340 assemble_tokens ("ldq_u", newtok
, 3, 1);
2342 /* Emit "ldq_u $10, size-1($at)". */
2343 set_tok_reg (newtok
[0], AXP_REG_T10
);
2344 set_tok_const (newtok
[1], (1 << lgsize
) - 1);
2345 assemble_tokens ("ldq_u", newtok
, 3, 1);
2347 /* Emit "insXl src, $at, $t11". */
2349 set_tok_reg (newtok
[1], AXP_REG_AT
);
2350 set_tok_reg (newtok
[2], AXP_REG_T11
);
2351 assemble_tokens (insXl_op
[lgsize
], newtok
, 3, 1);
2353 /* Emit "insXh src, $at, $t12". */
2354 set_tok_reg (newtok
[2], AXP_REG_T12
);
2355 assemble_tokens (insXh_op
[lgsize
], newtok
, 3, 1);
2357 /* Emit "mskXl $t9, $at, $t9". */
2358 set_tok_reg (newtok
[0], AXP_REG_T9
);
2359 newtok
[2] = newtok
[0];
2360 assemble_tokens (mskXl_op
[lgsize
], newtok
, 3, 1);
2362 /* Emit "mskXh $t10, $at, $t10". */
2363 set_tok_reg (newtok
[0], AXP_REG_T10
);
2364 newtok
[2] = newtok
[0];
2365 assemble_tokens (mskXh_op
[lgsize
], newtok
, 3, 1);
2367 /* Emit "or $t9, $t11, $t9". */
2368 set_tok_reg (newtok
[0], AXP_REG_T9
);
2369 set_tok_reg (newtok
[1], AXP_REG_T11
);
2370 newtok
[2] = newtok
[0];
2371 assemble_tokens ("or", newtok
, 3, 1);
2373 /* Emit "or $t10, $t12, $t10". */
2374 set_tok_reg (newtok
[0], AXP_REG_T10
);
2375 set_tok_reg (newtok
[1], AXP_REG_T12
);
2376 newtok
[2] = newtok
[0];
2377 assemble_tokens ("or", newtok
, 3, 1);
2379 /* Emit "stq_u $t9, 0($at)". */
2380 set_tok_reg (newtok
[0], AXP_REG_T9
);
2381 set_tok_const (newtok
[1], 0);
2382 set_tok_preg (newtok
[2], AXP_REG_AT
);
2383 assemble_tokens ("stq_u", newtok
, 3, 1);
2385 /* Emit "stq_u $t10, size-1($at)". */
2386 set_tok_reg (newtok
[0], AXP_REG_T10
);
2387 set_tok_const (newtok
[1], (1 << lgsize
) - 1);
2388 assemble_tokens ("stq_u", newtok
, 3, 1);
2391 /* Sign extend a half-word or byte. The 32-bit sign extend is
2392 implemented as "addl $31, $r, $t" in the opcode table. */
2395 emit_sextX (const expressionS
*tok
,
2397 const void * vlgsize
)
2399 long lgsize
= (long) vlgsize
;
2401 if (alpha_target
& AXP_OPCODE_BWX
)
2402 assemble_tokens (sextX_op
[lgsize
], tok
, ntok
, 0);
2405 int bitshift
= 64 - 8 * (1 << lgsize
);
2406 expressionS newtok
[3];
2408 /* Emit "sll src,bits,dst". */
2410 set_tok_const (newtok
[1], bitshift
);
2411 newtok
[2] = tok
[ntok
- 1];
2412 assemble_tokens ("sll", newtok
, 3, 1);
2414 /* Emit "sra dst,bits,dst". */
2415 newtok
[0] = newtok
[2];
2416 assemble_tokens ("sra", newtok
, 3, 1);
2420 /* Implement the division and modulus macros. */
2424 /* Make register usage like in normal procedure call.
2425 Don't clobber PV and RA. */
2428 emit_division (const expressionS
*tok
,
2430 const void * symname
)
2432 /* DIVISION and MODULUS. Yech.
2437 mov x,R16 # if x != R16
2438 mov y,R17 # if y != R17
2443 with appropriate optimizations if R0,R16,R17 are the registers
2444 specified by the compiler. */
2448 expressionS newtok
[3];
2450 xr
= regno (tok
[0].X_add_number
);
2451 yr
= regno (tok
[1].X_add_number
);
2456 rr
= regno (tok
[2].X_add_number
);
2458 /* Move the operands into the right place. */
2459 if (yr
== AXP_REG_R16
&& xr
== AXP_REG_R17
)
2461 /* They are in exactly the wrong order -- swap through AT. */
2463 as_bad (_("macro requires $at register while noat in effect"));
2465 set_tok_reg (newtok
[0], AXP_REG_R16
);
2466 set_tok_reg (newtok
[1], AXP_REG_AT
);
2467 assemble_tokens ("mov", newtok
, 2, 1);
2469 set_tok_reg (newtok
[0], AXP_REG_R17
);
2470 set_tok_reg (newtok
[1], AXP_REG_R16
);
2471 assemble_tokens ("mov", newtok
, 2, 1);
2473 set_tok_reg (newtok
[0], AXP_REG_AT
);
2474 set_tok_reg (newtok
[1], AXP_REG_R17
);
2475 assemble_tokens ("mov", newtok
, 2, 1);
2479 if (yr
== AXP_REG_R16
)
2481 set_tok_reg (newtok
[0], AXP_REG_R16
);
2482 set_tok_reg (newtok
[1], AXP_REG_R17
);
2483 assemble_tokens ("mov", newtok
, 2, 1);
2486 if (xr
!= AXP_REG_R16
)
2488 set_tok_reg (newtok
[0], xr
);
2489 set_tok_reg (newtok
[1], AXP_REG_R16
);
2490 assemble_tokens ("mov", newtok
, 2, 1);
2493 if (yr
!= AXP_REG_R16
&& yr
!= AXP_REG_R17
)
2495 set_tok_reg (newtok
[0], yr
);
2496 set_tok_reg (newtok
[1], AXP_REG_R17
);
2497 assemble_tokens ("mov", newtok
, 2, 1);
2501 sym
= symbol_find_or_make ((const char *) symname
);
2503 set_tok_reg (newtok
[0], AXP_REG_AT
);
2504 set_tok_sym (newtok
[1], sym
, 0);
2505 assemble_tokens ("lda", newtok
, 2, 1);
2507 /* Call the division routine. */
2508 set_tok_reg (newtok
[0], AXP_REG_AT
);
2509 set_tok_cpreg (newtok
[1], AXP_REG_AT
);
2510 set_tok_const (newtok
[2], 0);
2511 assemble_tokens ("jsr", newtok
, 3, 1);
2513 /* Move the result to the right place. */
2514 if (rr
!= AXP_REG_R0
)
2516 set_tok_reg (newtok
[0], AXP_REG_R0
);
2517 set_tok_reg (newtok
[1], rr
);
2518 assemble_tokens ("mov", newtok
, 2, 1);
2522 #else /* !OBJ_EVAX */
2525 emit_division (const expressionS
*tok
,
2527 const void * symname
)
2529 /* DIVISION and MODULUS. Yech.
2539 with appropriate optimizations if t10,t11,t12 are the registers
2540 specified by the compiler. */
2544 expressionS newtok
[3];
2546 xr
= regno (tok
[0].X_add_number
);
2547 yr
= regno (tok
[1].X_add_number
);
2552 rr
= regno (tok
[2].X_add_number
);
2554 sym
= symbol_find_or_make ((const char *) symname
);
2556 /* Move the operands into the right place. */
2557 if (yr
== AXP_REG_T10
&& xr
== AXP_REG_T11
)
2559 /* They are in exactly the wrong order -- swap through AT. */
2561 as_bad (_("macro requires $at register while noat in effect"));
2563 set_tok_reg (newtok
[0], AXP_REG_T10
);
2564 set_tok_reg (newtok
[1], AXP_REG_AT
);
2565 assemble_tokens ("mov", newtok
, 2, 1);
2567 set_tok_reg (newtok
[0], AXP_REG_T11
);
2568 set_tok_reg (newtok
[1], AXP_REG_T10
);
2569 assemble_tokens ("mov", newtok
, 2, 1);
2571 set_tok_reg (newtok
[0], AXP_REG_AT
);
2572 set_tok_reg (newtok
[1], AXP_REG_T11
);
2573 assemble_tokens ("mov", newtok
, 2, 1);
2577 if (yr
== AXP_REG_T10
)
2579 set_tok_reg (newtok
[0], AXP_REG_T10
);
2580 set_tok_reg (newtok
[1], AXP_REG_T11
);
2581 assemble_tokens ("mov", newtok
, 2, 1);
2584 if (xr
!= AXP_REG_T10
)
2586 set_tok_reg (newtok
[0], xr
);
2587 set_tok_reg (newtok
[1], AXP_REG_T10
);
2588 assemble_tokens ("mov", newtok
, 2, 1);
2591 if (yr
!= AXP_REG_T10
&& yr
!= AXP_REG_T11
)
2593 set_tok_reg (newtok
[0], yr
);
2594 set_tok_reg (newtok
[1], AXP_REG_T11
);
2595 assemble_tokens ("mov", newtok
, 2, 1);
2599 /* Call the division routine. */
2600 set_tok_reg (newtok
[0], AXP_REG_T9
);
2601 set_tok_sym (newtok
[1], sym
, 0);
2602 assemble_tokens ("jsr", newtok
, 2, 1);
2604 /* Reload the GP register. */
2608 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
2609 set_tok_reg (newtok
[0], alpha_gp_register
);
2610 set_tok_const (newtok
[1], 0);
2611 set_tok_preg (newtok
[2], AXP_REG_T9
);
2612 assemble_tokens ("ldgp", newtok
, 3, 1);
2615 /* Move the result to the right place. */
2616 if (rr
!= AXP_REG_T12
)
2618 set_tok_reg (newtok
[0], AXP_REG_T12
);
2619 set_tok_reg (newtok
[1], rr
);
2620 assemble_tokens ("mov", newtok
, 2, 1);
2624 #endif /* !OBJ_EVAX */
2626 /* The jsr and jmp macros differ from their instruction counterparts
2627 in that they can load the target address and default most
2631 emit_jsrjmp (const expressionS
*tok
,
2633 const void * vopname
)
2635 const char *opname
= (const char *) vopname
;
2636 struct alpha_insn insn
;
2637 expressionS newtok
[3];
2641 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_register
)
2642 r
= regno (tok
[tokidx
++].X_add_number
);
2644 r
= strcmp (opname
, "jmp") == 0 ? AXP_REG_ZERO
: AXP_REG_RA
;
2646 set_tok_reg (newtok
[0], r
);
2648 if (tokidx
< ntok
&&
2649 (tok
[tokidx
].X_op
== O_pregister
|| tok
[tokidx
].X_op
== O_cpregister
))
2650 r
= regno (tok
[tokidx
++].X_add_number
);
2652 /* Keep register if jsr $n.<sym>. */
2656 int basereg
= alpha_gp_register
;
2657 lituse
= load_expression (r
= AXP_REG_PV
, &tok
[tokidx
], &basereg
, NULL
);
2661 set_tok_cpreg (newtok
[1], r
);
2664 /* FIXME: Add hint relocs to BFD for evax. */
2667 newtok
[2] = tok
[tokidx
];
2670 set_tok_const (newtok
[2], 0);
2672 assemble_tokens_to_insn (opname
, newtok
, 3, &insn
);
2676 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
2677 insn
.fixups
[insn
.nfixups
].reloc
= DUMMY_RELOC_LITUSE_JSR
;
2678 insn
.fixups
[insn
.nfixups
].exp
.X_op
= O_absent
;
2680 insn
.sequence
= lituse
;
2686 /* The ret and jcr instructions differ from their instruction
2687 counterparts in that everything can be defaulted. */
2690 emit_retjcr (const expressionS
*tok
,
2692 const void * vopname
)
2694 const char *opname
= (const char *) vopname
;
2695 expressionS newtok
[3];
2698 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_register
)
2699 r
= regno (tok
[tokidx
++].X_add_number
);
2703 set_tok_reg (newtok
[0], r
);
2705 if (tokidx
< ntok
&&
2706 (tok
[tokidx
].X_op
== O_pregister
|| tok
[tokidx
].X_op
== O_cpregister
))
2707 r
= regno (tok
[tokidx
++].X_add_number
);
2711 set_tok_cpreg (newtok
[1], r
);
2714 newtok
[2] = tok
[tokidx
];
2716 set_tok_const (newtok
[2], strcmp (opname
, "ret") == 0);
2718 assemble_tokens (opname
, newtok
, 3, 0);
2721 /* Implement the ldgp macro. */
2724 emit_ldgp (const expressionS
*tok
,
2725 int ntok ATTRIBUTE_UNUSED
,
2726 const void * unused ATTRIBUTE_UNUSED
)
2731 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
2732 /* from "ldgp r1,n(r2)", generate "ldah r1,X(R2); lda r1,Y(r1)"
2733 with appropriate constants and relocations. */
2734 struct alpha_insn insn
;
2735 expressionS newtok
[3];
2739 if (regno (tok
[2].X_add_number
) == AXP_REG_PV
)
2740 ecoff_set_gp_prolog_size (0);
2744 set_tok_const (newtok
[1], 0);
2747 assemble_tokens_to_insn ("ldah", newtok
, 3, &insn
);
2752 if (addend
.X_op
!= O_constant
)
2753 as_bad (_("can not resolve expression"));
2754 addend
.X_op
= O_symbol
;
2755 addend
.X_add_symbol
= alpha_gp_symbol
;
2759 insn
.fixups
[0].exp
= addend
;
2760 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_GPDISP_HI16
;
2761 insn
.sequence
= next_sequence_num
;
2765 set_tok_preg (newtok
[2], tok
[0].X_add_number
);
2767 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
2770 addend
.X_add_number
+= 4;
2774 insn
.fixups
[0].exp
= addend
;
2775 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_GPDISP_LO16
;
2776 insn
.sequence
= next_sequence_num
--;
2779 #endif /* OBJ_ECOFF || OBJ_ELF */
2782 /* The macro table. */
2784 static const struct alpha_macro alpha_macros
[] =
2786 /* Load/Store macros. */
2787 { "lda", emit_lda
, NULL
,
2788 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
2789 { "ldah", emit_ldah
, NULL
,
2790 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
2792 { "ldl", emit_ir_load
, "ldl",
2793 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
2794 { "ldl_l", emit_ir_load
, "ldl_l",
2795 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
2796 { "ldq", emit_ir_load
, "ldq",
2797 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
2798 { "ldq_l", emit_ir_load
, "ldq_l",
2799 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
2800 { "ldq_u", emit_ir_load
, "ldq_u",
2801 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
2802 { "ldf", emit_loadstore
, "ldf",
2803 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
2804 { "ldg", emit_loadstore
, "ldg",
2805 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
2806 { "lds", emit_loadstore
, "lds",
2807 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
2808 { "ldt", emit_loadstore
, "ldt",
2809 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
2811 { "ldb", emit_ldX
, (void *) 0,
2812 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
2813 { "ldbu", emit_ldXu
, (void *) 0,
2814 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
2815 { "ldw", emit_ldX
, (void *) 1,
2816 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
2817 { "ldwu", emit_ldXu
, (void *) 1,
2818 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
2820 { "uldw", emit_uldX
, (void *) 1,
2821 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
2822 { "uldwu", emit_uldXu
, (void *) 1,
2823 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
2824 { "uldl", emit_uldX
, (void *) 2,
2825 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
2826 { "uldlu", emit_uldXu
, (void *) 2,
2827 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
2828 { "uldq", emit_uldXu
, (void *) 3,
2829 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
2831 { "ldgp", emit_ldgp
, NULL
,
2832 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
} },
2834 { "ldi", emit_lda
, NULL
,
2835 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
2836 { "ldil", emit_ldil
, NULL
,
2837 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
2838 { "ldiq", emit_lda
, NULL
,
2839 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
2841 { "stl", emit_loadstore
, "stl",
2842 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
2843 { "stl_c", emit_loadstore
, "stl_c",
2844 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
2845 { "stq", emit_loadstore
, "stq",
2846 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
2847 { "stq_c", emit_loadstore
, "stq_c",
2848 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
2849 { "stq_u", emit_loadstore
, "stq_u",
2850 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
2851 { "stf", emit_loadstore
, "stf",
2852 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
2853 { "stg", emit_loadstore
, "stg",
2854 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
2855 { "sts", emit_loadstore
, "sts",
2856 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
2857 { "stt", emit_loadstore
, "stt",
2858 { MACRO_FPR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
2860 { "stb", emit_stX
, (void *) 0,
2861 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
2862 { "stw", emit_stX
, (void *) 1,
2863 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
2864 { "ustw", emit_ustX
, (void *) 1,
2865 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
2866 { "ustl", emit_ustX
, (void *) 2,
2867 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
2868 { "ustq", emit_ustX
, (void *) 3,
2869 { MACRO_IR
, MACRO_EXP
, MACRO_OPIR
, MACRO_EOA
} },
2871 /* Arithmetic macros. */
2873 { "sextb", emit_sextX
, (void *) 0,
2874 { MACRO_IR
, MACRO_IR
, MACRO_EOA
,
2875 MACRO_IR
, MACRO_EOA
,
2876 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
2877 { "sextw", emit_sextX
, (void *) 1,
2878 { MACRO_IR
, MACRO_IR
, MACRO_EOA
,
2879 MACRO_IR
, MACRO_EOA
,
2880 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
2882 { "divl", emit_division
, "__divl",
2883 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
2884 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
2885 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
2886 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
2887 { "divlu", emit_division
, "__divlu",
2888 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
2889 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
2890 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
2891 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
2892 { "divq", emit_division
, "__divq",
2893 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
2894 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
2895 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
2896 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
2897 { "divqu", emit_division
, "__divqu",
2898 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
2899 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
2900 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
2901 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
2902 { "reml", emit_division
, "__reml",
2903 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
2904 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
2905 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
2906 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
2907 { "remlu", emit_division
, "__remlu",
2908 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
2909 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
2910 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
2911 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
2912 { "remq", emit_division
, "__remq",
2913 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
2914 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
2915 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
2916 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
2917 { "remqu", emit_division
, "__remqu",
2918 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
2919 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
2920 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
2921 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
2923 { "jsr", emit_jsrjmp
, "jsr",
2924 { MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
2925 MACRO_PIR
, MACRO_EOA
,
2926 MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
2927 MACRO_EXP
, MACRO_EOA
} },
2928 { "jmp", emit_jsrjmp
, "jmp",
2929 { MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
2930 MACRO_PIR
, MACRO_EOA
,
2931 MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
2932 MACRO_EXP
, MACRO_EOA
} },
2933 { "ret", emit_retjcr
, "ret",
2934 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
2935 MACRO_IR
, MACRO_EOA
,
2936 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
2937 MACRO_PIR
, MACRO_EOA
,
2938 MACRO_EXP
, MACRO_EOA
,
2940 { "jcr", emit_retjcr
, "jcr",
2941 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
2942 MACRO_IR
, MACRO_EOA
,
2943 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
2944 MACRO_PIR
, MACRO_EOA
,
2945 MACRO_EXP
, MACRO_EOA
,
2947 { "jsr_coroutine", emit_retjcr
, "jcr",
2948 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
2949 MACRO_IR
, MACRO_EOA
,
2950 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
2951 MACRO_PIR
, MACRO_EOA
,
2952 MACRO_EXP
, MACRO_EOA
,
2956 static const unsigned int alpha_num_macros
2957 = sizeof (alpha_macros
) / sizeof (*alpha_macros
);
2959 /* Search forward through all variants of a macro looking for a syntax
2962 static const struct alpha_macro
*
2963 find_macro_match (const struct alpha_macro
*first_macro
,
2964 const expressionS
*tok
,
2968 const struct alpha_macro
*macro
= first_macro
;
2973 const enum alpha_macro_arg
*arg
= macro
->argsets
;
2987 /* Index register. */
2989 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_register
2990 || !is_ir_num (tok
[tokidx
].X_add_number
))
2995 /* Parenthesized index register. */
2997 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_pregister
2998 || !is_ir_num (tok
[tokidx
].X_add_number
))
3003 /* Optional parenthesized index register. */
3005 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_pregister
3006 && is_ir_num (tok
[tokidx
].X_add_number
))
3010 /* Leading comma with a parenthesized index register. */
3012 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_cpregister
3013 || !is_ir_num (tok
[tokidx
].X_add_number
))
3018 /* Floating point register. */
3020 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_register
3021 || !is_fpr_num (tok
[tokidx
].X_add_number
))
3026 /* Normal expression. */
3030 switch (tok
[tokidx
].X_op
)
3039 case O_lituse_bytoff
:
3055 while (*arg
!= MACRO_EOA
)
3063 while (++macro
- alpha_macros
< (int) alpha_num_macros
3064 && !strcmp (macro
->name
, first_macro
->name
));
3069 /* Given an opcode name and a pre-tokenized set of arguments, take the
3070 opcode all the way through emission. */
3073 assemble_tokens (const char *opname
,
3074 const expressionS
*tok
,
3076 int local_macros_on
)
3078 int found_something
= 0;
3079 const struct alpha_opcode
*opcode
;
3080 const struct alpha_macro
*macro
;
3082 bfd_reloc_code_real_type reloc
= BFD_RELOC_UNUSED
;
3085 /* If a user-specified relocation is present, this is not a macro. */
3086 if (ntok
&& USER_RELOC_P (tok
[ntok
- 1].X_op
))
3088 reloc
= ALPHA_RELOC_TABLE (tok
[ntok
- 1].X_op
)->reloc
;
3093 if (local_macros_on
)
3095 macro
= ((const struct alpha_macro
*)
3096 hash_find (alpha_macro_hash
, opname
));
3099 found_something
= 1;
3100 macro
= find_macro_match (macro
, tok
, &ntok
);
3103 (*macro
->emit
) (tok
, ntok
, macro
->arg
);
3109 /* Search opcodes. */
3110 opcode
= (const struct alpha_opcode
*) hash_find (alpha_opcode_hash
, opname
);
3113 found_something
= 1;
3114 opcode
= find_opcode_match (opcode
, tok
, &ntok
, &cpumatch
);
3117 struct alpha_insn insn
;
3118 assemble_insn (opcode
, tok
, ntok
, &insn
, reloc
);
3120 /* Copy the sequence number for the reloc from the reloc token. */
3121 if (reloc
!= BFD_RELOC_UNUSED
)
3122 insn
.sequence
= tok
[ntok
].X_add_number
;
3129 if (found_something
)
3132 as_bad (_("inappropriate arguments for opcode `%s'"), opname
);
3134 as_bad (_("opcode `%s' not supported for target %s"), opname
,
3138 as_bad (_("unknown opcode `%s'"), opname
);
3143 /* Add symbol+addend to link pool.
3144 Return offset from basesym to entry in link pool.
3146 Add new fixup only if offset isn't 16bit. */
3149 add_to_link_pool (symbolS
*basesym
,
3153 segT current_section
= now_seg
;
3154 int current_subsec
= now_subseg
;
3156 bfd_reloc_code_real_type reloc_type
;
3158 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
3161 offset
= - *symbol_get_obj (basesym
);
3163 /* @@ This assumes all entries in a given section will be of the same
3164 size... Probably correct, but unwise to rely on. */
3165 /* This must always be called with the same subsegment. */
3167 if (seginfo
->frchainP
)
3168 for (fixp
= seginfo
->frchainP
->fix_root
;
3169 fixp
!= (fixS
*) NULL
;
3170 fixp
= fixp
->fx_next
, offset
+= 8)
3172 if (fixp
->fx_addsy
== sym
&& fixp
->fx_offset
== addend
)
3174 if (range_signed_16 (offset
))
3181 /* Not found in 16bit signed range. */
3183 subseg_set (alpha_link_section
, 0);
3187 fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, sym
, addend
, 0,
3190 subseg_set (current_section
, current_subsec
);
3191 seginfo
->literal_pool_size
+= 8;
3195 #endif /* OBJ_EVAX */
3197 /* Assembler directives. */
3199 /* Handle the .text pseudo-op. This is like the usual one, but it
3200 clears alpha_insn_label and restores auto alignment. */
3203 s_alpha_text (int i
)
3211 alpha_insn_label
= NULL
;
3212 alpha_auto_align_on
= 1;
3213 alpha_current_align
= 0;
3216 /* Handle the .data pseudo-op. This is like the usual one, but it
3217 clears alpha_insn_label and restores auto alignment. */
3220 s_alpha_data (int i
)
3227 alpha_insn_label
= NULL
;
3228 alpha_auto_align_on
= 1;
3229 alpha_current_align
= 0;
3232 #if defined (OBJ_ECOFF) || defined (OBJ_EVAX)
3234 /* Handle the OSF/1 and openVMS .comm pseudo quirks.
3235 openVMS constructs a section for every common symbol. */
3238 s_alpha_comm (int ignore ATTRIBUTE_UNUSED
)
3246 segT current_section
= now_seg
;
3247 int current_subsec
= now_subseg
;
3251 name
= input_line_pointer
;
3252 c
= get_symbol_end ();
3254 /* Just after name is now '\0'. */
3255 p
= input_line_pointer
;
3260 /* Alpha OSF/1 compiler doesn't provide the comma, gcc does. */
3261 if (*input_line_pointer
== ',')
3263 input_line_pointer
++;
3266 if ((temp
= get_absolute_expression ()) < 0)
3268 as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) temp
);
3269 ignore_rest_of_line ();
3274 symbolP
= symbol_find_or_make (name
);
3277 /* Make a section for the common symbol. */
3278 new_seg
= subseg_new (xstrdup (name
), 0);
3284 /* Alignment might follow. */
3285 if (*input_line_pointer
== ',')
3289 input_line_pointer
++;
3290 align
= get_absolute_expression ();
3291 bfd_set_section_alignment (stdoutput
, new_seg
, align
);
3295 if (S_IS_DEFINED (symbolP
) && ! S_IS_COMMON (symbolP
))
3297 as_bad (_("Ignoring attempt to re-define symbol"));
3298 ignore_rest_of_line ();
3303 if (bfd_section_size (stdoutput
, new_seg
) > 0)
3305 if (bfd_section_size (stdoutput
, new_seg
) != temp
)
3306 as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
3307 S_GET_NAME (symbolP
),
3308 (long) bfd_section_size (stdoutput
, new_seg
),
3312 if (S_GET_VALUE (symbolP
))
3314 if (S_GET_VALUE (symbolP
) != (valueT
) temp
)
3315 as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
3316 S_GET_NAME (symbolP
),
3317 (long) S_GET_VALUE (symbolP
),
3324 subseg_set (new_seg
, 0);
3325 p
= frag_more (temp
);
3326 new_seg
->flags
|= SEC_IS_COMMON
;
3327 if (! S_IS_DEFINED (symbolP
))
3328 S_SET_SEGMENT (symbolP
, new_seg
);
3330 S_SET_VALUE (symbolP
, (valueT
) temp
);
3332 S_SET_EXTERNAL (symbolP
);
3336 subseg_set (current_section
, current_subsec
);
3339 know (symbol_get_frag (symbolP
) == &zero_address_frag
);
3341 demand_empty_rest_of_line ();
3344 #endif /* ! OBJ_ELF */
3348 /* Handle the .rdata pseudo-op. This is like the usual one, but it
3349 clears alpha_insn_label and restores auto alignment. */
3352 s_alpha_rdata (int ignore ATTRIBUTE_UNUSED
)
3356 temp
= get_absolute_expression ();
3357 subseg_new (".rdata", 0);
3358 demand_empty_rest_of_line ();
3359 alpha_insn_label
= NULL
;
3360 alpha_auto_align_on
= 1;
3361 alpha_current_align
= 0;
3368 /* Handle the .sdata pseudo-op. This is like the usual one, but it
3369 clears alpha_insn_label and restores auto alignment. */
3372 s_alpha_sdata (int ignore ATTRIBUTE_UNUSED
)
3376 temp
= get_absolute_expression ();
3377 subseg_new (".sdata", 0);
3378 demand_empty_rest_of_line ();
3379 alpha_insn_label
= NULL
;
3380 alpha_auto_align_on
= 1;
3381 alpha_current_align
= 0;
3386 struct alpha_elf_frame_data
3389 symbolS
*func_end_sym
;
3390 symbolS
*prologue_sym
;
3396 offsetT mask_offset
;
3397 offsetT fmask_offset
;
3399 struct alpha_elf_frame_data
*next
;
3402 static struct alpha_elf_frame_data
*all_frame_data
;
3403 static struct alpha_elf_frame_data
**plast_frame_data
= &all_frame_data
;
3404 static struct alpha_elf_frame_data
*cur_frame_data
;
3406 /* Handle the .section pseudo-op. This is like the usual one, but it
3407 clears alpha_insn_label and restores auto alignment. */
3410 s_alpha_section (int ignore ATTRIBUTE_UNUSED
)
3412 obj_elf_section (ignore
);
3414 alpha_insn_label
= NULL
;
3415 alpha_auto_align_on
= 1;
3416 alpha_current_align
= 0;
3420 s_alpha_ent (int dummy ATTRIBUTE_UNUSED
)
3422 if (ECOFF_DEBUGGING
)
3423 ecoff_directive_ent (0);
3426 char *name
, name_end
;
3427 name
= input_line_pointer
;
3428 name_end
= get_symbol_end ();
3430 if (! is_name_beginner (*name
))
3432 as_warn (_(".ent directive has no name"));
3433 *input_line_pointer
= name_end
;
3440 as_warn (_("nested .ent directives"));
3442 sym
= symbol_find_or_make (name
);
3443 symbol_get_bfdsym (sym
)->flags
|= BSF_FUNCTION
;
3445 cur_frame_data
= calloc (1, sizeof (*cur_frame_data
));
3446 cur_frame_data
->func_sym
= sym
;
3448 /* Provide sensible defaults. */
3449 cur_frame_data
->fp_regno
= 30; /* sp */
3450 cur_frame_data
->ra_regno
= 26; /* ra */
3452 *plast_frame_data
= cur_frame_data
;
3453 plast_frame_data
= &cur_frame_data
->next
;
3455 /* The .ent directive is sometimes followed by a number. Not sure
3456 what it really means, but ignore it. */
3457 *input_line_pointer
= name_end
;
3459 if (*input_line_pointer
== ',')
3461 input_line_pointer
++;
3464 if (ISDIGIT (*input_line_pointer
) || *input_line_pointer
== '-')
3465 (void) get_absolute_expression ();
3467 demand_empty_rest_of_line ();
3472 s_alpha_end (int dummy ATTRIBUTE_UNUSED
)
3474 if (ECOFF_DEBUGGING
)
3475 ecoff_directive_end (0);
3478 char *name
, name_end
;
3479 name
= input_line_pointer
;
3480 name_end
= get_symbol_end ();
3482 if (! is_name_beginner (*name
))
3484 as_warn (_(".end directive has no name"));
3485 *input_line_pointer
= name_end
;
3491 sym
= symbol_find (name
);
3492 if (!cur_frame_data
)
3493 as_warn (_(".end directive without matching .ent"));
3494 else if (sym
!= cur_frame_data
->func_sym
)
3495 as_warn (_(".end directive names different symbol than .ent"));
3497 /* Create an expression to calculate the size of the function. */
3498 if (sym
&& cur_frame_data
)
3500 OBJ_SYMFIELD_TYPE
*obj
= symbol_get_obj (sym
);
3501 expressionS
*exp
= xmalloc (sizeof (expressionS
));
3504 exp
->X_op
= O_subtract
;
3505 exp
->X_add_symbol
= symbol_temp_new_now ();
3506 exp
->X_op_symbol
= sym
;
3507 exp
->X_add_number
= 0;
3509 cur_frame_data
->func_end_sym
= exp
->X_add_symbol
;
3512 cur_frame_data
= NULL
;
3514 *input_line_pointer
= name_end
;
3516 demand_empty_rest_of_line ();
3521 s_alpha_mask (int fp
)
3523 if (ECOFF_DEBUGGING
)
3526 ecoff_directive_fmask (0);
3528 ecoff_directive_mask (0);
3535 if (!cur_frame_data
)
3538 as_warn (_(".fmask outside of .ent"));
3540 as_warn (_(".mask outside of .ent"));
3541 discard_rest_of_line ();
3545 if (get_absolute_expression_and_terminator (&val
) != ',')
3548 as_warn (_("bad .fmask directive"));
3550 as_warn (_("bad .mask directive"));
3551 --input_line_pointer
;
3552 discard_rest_of_line ();
3556 offset
= get_absolute_expression ();
3557 demand_empty_rest_of_line ();
3561 cur_frame_data
->fmask
= val
;
3562 cur_frame_data
->fmask_offset
= offset
;
3566 cur_frame_data
->mask
= val
;
3567 cur_frame_data
->mask_offset
= offset
;
3573 s_alpha_frame (int dummy ATTRIBUTE_UNUSED
)
3575 if (ECOFF_DEBUGGING
)
3576 ecoff_directive_frame (0);
3581 if (!cur_frame_data
)
3583 as_warn (_(".frame outside of .ent"));
3584 discard_rest_of_line ();
3588 cur_frame_data
->fp_regno
= tc_get_register (1);
3591 if (*input_line_pointer
++ != ','
3592 || get_absolute_expression_and_terminator (&val
) != ',')
3594 as_warn (_("bad .frame directive"));
3595 --input_line_pointer
;
3596 discard_rest_of_line ();
3599 cur_frame_data
->frame_size
= val
;
3601 cur_frame_data
->ra_regno
= tc_get_register (0);
3603 /* Next comes the "offset of saved $a0 from $sp". In gcc terms
3604 this is current_function_pretend_args_size. There's no place
3605 to put this value, so ignore it. */
3611 s_alpha_prologue (int ignore ATTRIBUTE_UNUSED
)
3616 arg
= get_absolute_expression ();
3617 demand_empty_rest_of_line ();
3619 if (ECOFF_DEBUGGING
)
3620 sym
= ecoff_get_cur_proc_sym ();
3622 sym
= cur_frame_data
? cur_frame_data
->func_sym
: NULL
;
3626 as_bad (_(".prologue directive without a preceding .ent directive"));
3632 case 0: /* No PV required. */
3633 S_SET_OTHER (sym
, STO_ALPHA_NOPV
3634 | (S_GET_OTHER (sym
) & ~STO_ALPHA_STD_GPLOAD
));
3636 case 1: /* Std GP load. */
3637 S_SET_OTHER (sym
, STO_ALPHA_STD_GPLOAD
3638 | (S_GET_OTHER (sym
) & ~STO_ALPHA_STD_GPLOAD
));
3640 case 2: /* Non-std use of PV. */
3644 as_bad (_("Invalid argument %d to .prologue."), arg
);
3649 cur_frame_data
->prologue_sym
= symbol_temp_new_now ();
3652 static char *first_file_directive
;
3655 s_alpha_file (int ignore ATTRIBUTE_UNUSED
)
3657 /* Save the first .file directive we see, so that we can change our
3658 minds about whether ecoff debugging should or shouldn't be enabled. */
3659 if (alpha_flag_mdebug
< 0 && ! first_file_directive
)
3661 char *start
= input_line_pointer
;
3664 discard_rest_of_line ();
3666 len
= input_line_pointer
- start
;
3667 first_file_directive
= xmalloc (len
+ 1);
3668 memcpy (first_file_directive
, start
, len
);
3669 first_file_directive
[len
] = '\0';
3671 input_line_pointer
= start
;
3674 if (ECOFF_DEBUGGING
)
3675 ecoff_directive_file (0);
3677 dwarf2_directive_file (0);
3681 s_alpha_loc (int ignore ATTRIBUTE_UNUSED
)
3683 if (ECOFF_DEBUGGING
)
3684 ecoff_directive_loc (0);
3686 dwarf2_directive_loc (0);
3690 s_alpha_stab (int n
)
3692 /* If we've been undecided about mdebug, make up our minds in favour. */
3693 if (alpha_flag_mdebug
< 0)
3695 segT sec
= subseg_new (".mdebug", 0);
3696 bfd_set_section_flags (stdoutput
, sec
, SEC_HAS_CONTENTS
| SEC_READONLY
);
3697 bfd_set_section_alignment (stdoutput
, sec
, 3);
3699 ecoff_read_begin_hook ();
3701 if (first_file_directive
)
3703 char *save_ilp
= input_line_pointer
;
3704 input_line_pointer
= first_file_directive
;
3705 ecoff_directive_file (0);
3706 input_line_pointer
= save_ilp
;
3707 free (first_file_directive
);
3710 alpha_flag_mdebug
= 1;
3716 s_alpha_coff_wrapper (int which
)
3718 static void (* const fns
[]) PARAMS ((int)) = {
3719 ecoff_directive_begin
,
3720 ecoff_directive_bend
,
3721 ecoff_directive_def
,
3722 ecoff_directive_dim
,
3723 ecoff_directive_endef
,
3724 ecoff_directive_scl
,
3725 ecoff_directive_tag
,
3726 ecoff_directive_val
,
3729 assert (which
>= 0 && which
< (int) (sizeof (fns
)/sizeof (*fns
)));
3731 if (ECOFF_DEBUGGING
)
3735 as_bad (_("ECOFF debugging is disabled."));
3736 ignore_rest_of_line ();
3740 /* Called at the end of assembly. Here we emit unwind info for frames
3741 unless the compiler has done it for us. */
3744 alpha_elf_md_end (void)
3746 struct alpha_elf_frame_data
*p
;
3749 as_warn (_(".ent directive without matching .end"));
3751 /* If someone has generated the unwind info themselves, great. */
3752 if (bfd_get_section_by_name (stdoutput
, ".eh_frame") != NULL
)
3755 /* Generate .eh_frame data for the unwind directives specified. */
3756 for (p
= all_frame_data
; p
; p
= p
->next
)
3757 if (p
->prologue_sym
)
3759 /* Create a temporary symbol at the same location as our
3760 function symbol. This prevents problems with globals. */
3761 cfi_new_fde (symbol_temp_new (S_GET_SEGMENT (p
->func_sym
),
3762 S_GET_VALUE (p
->func_sym
),
3763 symbol_get_frag (p
->func_sym
)));
3765 cfi_set_return_column (p
->ra_regno
);
3766 cfi_add_CFA_def_cfa_register (30);
3767 if (p
->fp_regno
!= 30 || p
->mask
|| p
->fmask
|| p
->frame_size
)
3772 cfi_add_advance_loc (p
->prologue_sym
);
3774 if (p
->fp_regno
!= 30)
3775 if (p
->frame_size
!= 0)
3776 cfi_add_CFA_def_cfa (p
->fp_regno
, p
->frame_size
);
3778 cfi_add_CFA_def_cfa_register (p
->fp_regno
);
3779 else if (p
->frame_size
!= 0)
3780 cfi_add_CFA_def_cfa_offset (p
->frame_size
);
3783 offset
= p
->mask_offset
;
3785 /* Recall that $26 is special-cased and stored first. */
3786 if ((mask
>> 26) & 1)
3788 cfi_add_CFA_offset (26, offset
);
3799 cfi_add_CFA_offset (i
, offset
);
3804 offset
= p
->fmask_offset
;
3812 cfi_add_CFA_offset (i
+ 32, offset
);
3817 cfi_end_fde (p
->func_end_sym
);
3822 s_alpha_usepv (int unused ATTRIBUTE_UNUSED
)
3824 char *name
, name_end
;
3825 char *which
, which_end
;
3829 name
= input_line_pointer
;
3830 name_end
= get_symbol_end ();
3832 if (! is_name_beginner (*name
))
3834 as_bad (_(".usepv directive has no name"));
3835 *input_line_pointer
= name_end
;
3836 ignore_rest_of_line ();
3840 sym
= symbol_find_or_make (name
);
3841 *input_line_pointer
++ = name_end
;
3843 if (name_end
!= ',')
3845 as_bad (_(".usepv directive has no type"));
3846 ignore_rest_of_line ();
3851 which
= input_line_pointer
;
3852 which_end
= get_symbol_end ();
3854 if (strcmp (which
, "no") == 0)
3855 other
= STO_ALPHA_NOPV
;
3856 else if (strcmp (which
, "std") == 0)
3857 other
= STO_ALPHA_STD_GPLOAD
;
3860 as_bad (_("unknown argument for .usepv"));
3864 *input_line_pointer
= which_end
;
3865 demand_empty_rest_of_line ();
3867 S_SET_OTHER (sym
, other
| (S_GET_OTHER (sym
) & ~STO_ALPHA_STD_GPLOAD
));
3869 #endif /* OBJ_ELF */
3871 /* Standard calling conventions leaves the CFA at $30 on entry. */
3874 alpha_cfi_frame_initial_instructions (void)
3876 cfi_add_CFA_def_cfa_register (30);
3881 /* Handle the section specific pseudo-op. */
3884 s_alpha_section (int secid
)
3887 #define EVAX_SECTION_COUNT 5
3888 static char *section_name
[EVAX_SECTION_COUNT
+ 1] =
3889 { "NULL", ".rdata", ".comm", ".link", ".ctors", ".dtors" };
3891 if ((secid
<= 0) || (secid
> EVAX_SECTION_COUNT
))
3893 as_fatal (_("Unknown section directive"));
3894 demand_empty_rest_of_line ();
3897 temp
= get_absolute_expression ();
3898 subseg_new (section_name
[secid
], 0);
3899 demand_empty_rest_of_line ();
3900 alpha_insn_label
= NULL
;
3901 alpha_auto_align_on
= 1;
3902 alpha_current_align
= 0;
3905 /* Parse .ent directives. */
3908 s_alpha_ent (int ignore ATTRIBUTE_UNUSED
)
3911 expressionS symexpr
;
3913 alpha_evax_proc
.pdsckind
= 0;
3914 alpha_evax_proc
.framereg
= -1;
3915 alpha_evax_proc
.framesize
= 0;
3916 alpha_evax_proc
.rsa_offset
= 0;
3917 alpha_evax_proc
.ra_save
= AXP_REG_RA
;
3918 alpha_evax_proc
.fp_save
= -1;
3919 alpha_evax_proc
.imask
= 0;
3920 alpha_evax_proc
.fmask
= 0;
3921 alpha_evax_proc
.prologue
= 0;
3922 alpha_evax_proc
.type
= 0;
3924 expression (&symexpr
);
3926 if (symexpr
.X_op
!= O_symbol
)
3928 as_fatal (_(".ent directive has no symbol"));
3929 demand_empty_rest_of_line ();
3933 symbol
= make_expr_symbol (&symexpr
);
3934 symbol_get_bfdsym (symbol
)->flags
|= BSF_FUNCTION
;
3935 alpha_evax_proc
.symbol
= symbol
;
3937 demand_empty_rest_of_line ();
3940 /* Parse .frame <framreg>,<framesize>,RA,<rsa_offset> directives. */
3943 s_alpha_frame (int ignore ATTRIBUTE_UNUSED
)
3947 alpha_evax_proc
.framereg
= tc_get_register (1);
3950 if (*input_line_pointer
++ != ','
3951 || get_absolute_expression_and_terminator (&val
) != ',')
3953 as_warn (_("Bad .frame directive 1./2. param"));
3954 --input_line_pointer
;
3955 demand_empty_rest_of_line ();
3959 alpha_evax_proc
.framesize
= val
;
3961 (void) tc_get_register (1);
3963 if (*input_line_pointer
++ != ',')
3965 as_warn (_("Bad .frame directive 3./4. param"));
3966 --input_line_pointer
;
3967 demand_empty_rest_of_line ();
3970 alpha_evax_proc
.rsa_offset
= get_absolute_expression ();
3974 s_alpha_pdesc (int ignore ATTRIBUTE_UNUSED
)
3983 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
3985 if (now_seg
!= alpha_link_section
)
3987 as_bad (_(".pdesc directive not in link (.link) section"));
3988 demand_empty_rest_of_line ();
3992 if ((alpha_evax_proc
.symbol
== 0)
3993 || (!S_IS_DEFINED (alpha_evax_proc
.symbol
)))
3995 as_fatal (_(".pdesc has no matching .ent"));
3996 demand_empty_rest_of_line ();
4000 *symbol_get_obj (alpha_evax_proc
.symbol
) =
4001 (valueT
) seginfo
->literal_pool_size
;
4004 if (exp
.X_op
!= O_symbol
)
4006 as_warn (_(".pdesc directive has no entry symbol"));
4007 demand_empty_rest_of_line ();
4011 entry_sym
= make_expr_symbol (&exp
);
4012 /* Save bfd symbol of proc desc in function symbol. */
4013 symbol_get_bfdsym (alpha_evax_proc
.symbol
)->udata
.p
4014 = symbol_get_bfdsym (entry_sym
);
4017 if (*input_line_pointer
++ != ',')
4019 as_warn (_("No comma after .pdesc <entryname>"));
4020 demand_empty_rest_of_line ();
4025 name
= input_line_pointer
;
4026 name_end
= get_symbol_end ();
4028 if (strncmp (name
, "stack", 5) == 0)
4029 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_FP_STACK
;
4031 else if (strncmp (name
, "reg", 3) == 0)
4032 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_FP_REGISTER
;
4034 else if (strncmp (name
, "null", 4) == 0)
4035 alpha_evax_proc
.pdsckind
= PDSC_S_K_KIND_NULL
;
4039 as_fatal (_("unknown procedure kind"));
4040 demand_empty_rest_of_line ();
4044 *input_line_pointer
= name_end
;
4045 demand_empty_rest_of_line ();
4047 #ifdef md_flush_pending_output
4048 md_flush_pending_output ();
4051 frag_align (3, 0, 0);
4053 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
4055 seginfo
->literal_pool_size
+= 16;
4057 *p
= alpha_evax_proc
.pdsckind
4058 | ((alpha_evax_proc
.framereg
== 29) ? PDSC_S_M_BASE_REG_IS_FP
: 0);
4059 *(p
+ 1) = PDSC_S_M_NATIVE
| PDSC_S_M_NO_JACKET
;
4061 switch (alpha_evax_proc
.pdsckind
)
4063 case PDSC_S_K_KIND_NULL
:
4067 case PDSC_S_K_KIND_FP_REGISTER
:
4068 *(p
+ 2) = alpha_evax_proc
.fp_save
;
4069 *(p
+ 3) = alpha_evax_proc
.ra_save
;
4071 case PDSC_S_K_KIND_FP_STACK
:
4072 md_number_to_chars (p
+ 2, (valueT
) alpha_evax_proc
.rsa_offset
, 2);
4074 default: /* impossible */
4079 *(p
+ 5) = alpha_evax_proc
.type
& 0x0f;
4081 /* Signature offset. */
4082 md_number_to_chars (p
+ 6, (valueT
) 0, 2);
4084 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
+8, 8, &exp
, 0, BFD_RELOC_64
);
4086 if (alpha_evax_proc
.pdsckind
== PDSC_S_K_KIND_NULL
)
4089 /* Add dummy fix to make add_to_link_pool work. */
4091 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
4093 seginfo
->literal_pool_size
+= 8;
4095 /* pdesc+16: Size. */
4096 md_number_to_chars (p
, (valueT
) alpha_evax_proc
.framesize
, 4);
4098 md_number_to_chars (p
+ 4, (valueT
) 0, 2);
4101 md_number_to_chars (p
+ 6, alpha_evax_proc
.prologue
, 2);
4103 if (alpha_evax_proc
.pdsckind
== PDSC_S_K_KIND_FP_REGISTER
)
4106 /* Add dummy fix to make add_to_link_pool work. */
4108 fixp
= fix_new (frag_now
, p
- frag_now
->fr_literal
, 8, 0, 0, 0, 0);
4110 seginfo
->literal_pool_size
+= 8;
4112 /* pdesc+24: register masks. */
4114 md_number_to_chars (p
, alpha_evax_proc
.imask
, 4);
4115 md_number_to_chars (p
+ 4, alpha_evax_proc
.fmask
, 4);
4118 /* Support for crash debug on vms. */
4121 s_alpha_name (int ignore ATTRIBUTE_UNUSED
)
4125 segment_info_type
*seginfo
= seg_info (alpha_link_section
);
4127 if (now_seg
!= alpha_link_section
)
4129 as_bad (_(".name directive not in link (.link) section"));
4130 demand_empty_rest_of_line ();
4135 if (exp
.X_op
!= O_symbol
)
4137 as_warn (_(".name directive has no symbol"));
4138 demand_empty_rest_of_line ();
4142 demand_empty_rest_of_line ();
4144 #ifdef md_flush_pending_output
4145 md_flush_pending_output ();
4148 frag_align (3, 0, 0);
4150 seginfo
->literal_pool_size
+= 8;
4152 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 8, &exp
, 0, BFD_RELOC_64
);
4156 s_alpha_linkage (int ignore ATTRIBUTE_UNUSED
)
4161 #ifdef md_flush_pending_output
4162 md_flush_pending_output ();
4166 if (exp
.X_op
!= O_symbol
)
4168 as_fatal (_("No symbol after .linkage"));
4172 p
= frag_more (LKP_S_K_SIZE
);
4173 memset (p
, 0, LKP_S_K_SIZE
);
4174 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, LKP_S_K_SIZE
, &exp
, 0,\
4175 BFD_RELOC_ALPHA_LINKAGE
);
4177 demand_empty_rest_of_line ();
4181 s_alpha_code_address (int ignore ATTRIBUTE_UNUSED
)
4186 #ifdef md_flush_pending_output
4187 md_flush_pending_output ();
4191 if (exp
.X_op
!= O_symbol
)
4192 as_fatal (_("No symbol after .code_address"));
4197 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 8, &exp
, 0,\
4198 BFD_RELOC_ALPHA_CODEADDR
);
4200 demand_empty_rest_of_line ();
4204 s_alpha_fp_save (int ignore ATTRIBUTE_UNUSED
)
4207 alpha_evax_proc
.fp_save
= tc_get_register (1);
4209 demand_empty_rest_of_line ();
4213 s_alpha_mask (int ignore ATTRIBUTE_UNUSED
)
4217 if (get_absolute_expression_and_terminator (&val
) != ',')
4219 as_warn (_("Bad .mask directive"));
4220 --input_line_pointer
;
4224 alpha_evax_proc
.imask
= val
;
4225 (void) get_absolute_expression ();
4227 demand_empty_rest_of_line ();
4231 s_alpha_fmask (int ignore ATTRIBUTE_UNUSED
)
4235 if (get_absolute_expression_and_terminator (&val
) != ',')
4237 as_warn (_("Bad .fmask directive"));
4238 --input_line_pointer
;
4242 alpha_evax_proc
.fmask
= val
;
4243 (void) get_absolute_expression ();
4245 demand_empty_rest_of_line ();
4249 s_alpha_end (int ignore ATTRIBUTE_UNUSED
)
4253 c
= get_symbol_end ();
4254 *input_line_pointer
= c
;
4255 demand_empty_rest_of_line ();
4256 alpha_evax_proc
.symbol
= 0;
4260 s_alpha_file (int ignore ATTRIBUTE_UNUSED
)
4264 static char case_hack
[32];
4266 sprintf (case_hack
, "<CASE:%01d%01d>",
4267 alpha_flag_hash_long_names
, alpha_flag_show_after_trunc
);
4269 s
= symbol_find_or_make (case_hack
);
4270 symbol_get_bfdsym (s
)->flags
|= BSF_FILE
;
4272 get_absolute_expression ();
4273 s
= symbol_find_or_make (demand_copy_string (&length
));
4274 symbol_get_bfdsym (s
)->flags
|= BSF_FILE
;
4275 demand_empty_rest_of_line ();
4277 #endif /* OBJ_EVAX */
4279 /* Handle the .gprel32 pseudo op. */
4282 s_alpha_gprel32 (int ignore ATTRIBUTE_UNUSED
)
4294 e
.X_add_symbol
= section_symbol (absolute_section
);
4307 e
.X_add_symbol
= section_symbol (absolute_section
);
4310 e
.X_op
= O_subtract
;
4311 e
.X_op_symbol
= alpha_gp_symbol
;
4319 if (alpha_auto_align_on
&& alpha_current_align
< 2)
4320 alpha_align (2, (char *) NULL
, alpha_insn_label
, 0);
4321 if (alpha_current_align
> 2)
4322 alpha_current_align
= 2;
4323 alpha_insn_label
= NULL
;
4327 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 4,
4328 &e
, 0, BFD_RELOC_GPREL32
);
4331 /* Handle floating point allocation pseudo-ops. This is like the
4332 generic vresion, but it makes sure the current label, if any, is
4333 correctly aligned. */
4336 s_alpha_float_cons (int type
)
4362 if (alpha_auto_align_on
&& alpha_current_align
< log_size
)
4363 alpha_align (log_size
, (char *) NULL
, alpha_insn_label
, 0);
4364 if (alpha_current_align
> log_size
)
4365 alpha_current_align
= log_size
;
4366 alpha_insn_label
= NULL
;
4371 /* Handle the .proc pseudo op. We don't really do much with it except
4375 s_alpha_proc (int is_static ATTRIBUTE_UNUSED
)
4383 /* Takes ".proc name,nargs". */
4385 name
= input_line_pointer
;
4386 c
= get_symbol_end ();
4387 p
= input_line_pointer
;
4388 symbolP
= symbol_find_or_make (name
);
4391 if (*input_line_pointer
!= ',')
4394 as_warn (_("Expected comma after name \"%s\""), name
);
4397 ignore_rest_of_line ();
4401 input_line_pointer
++;
4402 temp
= get_absolute_expression ();
4404 /* *symbol_get_obj (symbolP) = (signed char) temp; */
4405 as_warn (_("unhandled: .proc %s,%d"), name
, temp
);
4406 demand_empty_rest_of_line ();
4409 /* Handle the .set pseudo op. This is used to turn on and off most of
4410 the assembler features. */
4413 s_alpha_set (int x ATTRIBUTE_UNUSED
)
4419 name
= input_line_pointer
;
4420 ch
= get_symbol_end ();
4423 if (s
[0] == 'n' && s
[1] == 'o')
4428 if (!strcmp ("reorder", s
))
4430 else if (!strcmp ("at", s
))
4431 alpha_noat_on
= !yesno
;
4432 else if (!strcmp ("macro", s
))
4433 alpha_macros_on
= yesno
;
4434 else if (!strcmp ("move", s
))
4436 else if (!strcmp ("volatile", s
))
4439 as_warn (_("Tried to .set unrecognized mode `%s'"), name
);
4441 *input_line_pointer
= ch
;
4442 demand_empty_rest_of_line ();
4445 /* Handle the .base pseudo op. This changes the assembler's notion of
4446 the $gp register. */
4449 s_alpha_base (int ignore ATTRIBUTE_UNUSED
)
4453 if (*input_line_pointer
== '$')
4456 input_line_pointer
++;
4457 if (*input_line_pointer
== 'r')
4458 input_line_pointer
++;
4461 alpha_gp_register
= get_absolute_expression ();
4462 if (alpha_gp_register
< 0 || alpha_gp_register
> 31)
4464 alpha_gp_register
= AXP_REG_GP
;
4465 as_warn (_("Bad base register, using $%d."), alpha_gp_register
);
4468 demand_empty_rest_of_line ();
4471 /* Handle the .align pseudo-op. This aligns to a power of two. It
4472 also adjusts any current instruction label. We treat this the same
4473 way the MIPS port does: .align 0 turns off auto alignment. */
4476 s_alpha_align (int ignore ATTRIBUTE_UNUSED
)
4480 long max_alignment
= 15;
4482 align
= get_absolute_expression ();
4483 if (align
> max_alignment
)
4485 align
= max_alignment
;
4486 as_bad (_("Alignment too large: %d. assumed"), align
);
4490 as_warn (_("Alignment negative: 0 assumed"));
4494 if (*input_line_pointer
== ',')
4496 input_line_pointer
++;
4497 fill
= get_absolute_expression ();
4505 alpha_auto_align_on
= 1;
4506 alpha_align (align
, pfill
, alpha_insn_label
, 1);
4510 alpha_auto_align_on
= 0;
4513 demand_empty_rest_of_line ();
4516 /* Hook the normal string processor to reset known alignment. */
4519 s_alpha_stringer (int terminate
)
4521 alpha_current_align
= 0;
4522 alpha_insn_label
= NULL
;
4523 stringer (terminate
);
4526 /* Hook the normal space processing to reset known alignment. */
4529 s_alpha_space (int ignore
)
4531 alpha_current_align
= 0;
4532 alpha_insn_label
= NULL
;
4536 /* Hook into cons for auto-alignment. */
4539 alpha_cons_align (int size
)
4544 while ((size
>>= 1) != 0)
4547 if (alpha_auto_align_on
&& alpha_current_align
< log_size
)
4548 alpha_align (log_size
, (char *) NULL
, alpha_insn_label
, 0);
4549 if (alpha_current_align
> log_size
)
4550 alpha_current_align
= log_size
;
4551 alpha_insn_label
= NULL
;
4554 /* Here come the .uword, .ulong, and .uquad explicitly unaligned
4555 pseudos. We just turn off auto-alignment and call down to cons. */
4558 s_alpha_ucons (int bytes
)
4560 int hold
= alpha_auto_align_on
;
4561 alpha_auto_align_on
= 0;
4563 alpha_auto_align_on
= hold
;
4566 /* Switch the working cpu type. */
4569 s_alpha_arch (int ignored ATTRIBUTE_UNUSED
)
4572 const struct cpu_type
*p
;
4575 name
= input_line_pointer
;
4576 ch
= get_symbol_end ();
4578 for (p
= cpu_types
; p
->name
; ++p
)
4579 if (strcmp (name
, p
->name
) == 0)
4581 alpha_target_name
= p
->name
, alpha_target
= p
->flags
;
4584 as_warn ("Unknown CPU identifier `%s'", name
);
4587 *input_line_pointer
= ch
;
4588 demand_empty_rest_of_line ();
4592 /* print token expression with alpha specific extension. */
4595 alpha_print_token (FILE *f
, const expressionS
*exp
)
4605 expressionS nexp
= *exp
;
4606 nexp
.X_op
= O_register
;
4607 print_expr (f
, &nexp
);
4612 print_expr (f
, exp
);
4618 /* The target specific pseudo-ops which we support. */
4620 const pseudo_typeS md_pseudo_table
[] =
4623 {"comm", s_alpha_comm
, 0}, /* OSF1 compiler does this. */
4624 {"rdata", s_alpha_rdata
, 0},
4626 {"text", s_alpha_text
, 0},
4627 {"data", s_alpha_data
, 0},
4629 {"sdata", s_alpha_sdata
, 0},
4632 {"section", s_alpha_section
, 0},
4633 {"section.s", s_alpha_section
, 0},
4634 {"sect", s_alpha_section
, 0},
4635 {"sect.s", s_alpha_section
, 0},
4638 { "pdesc", s_alpha_pdesc
, 0},
4639 { "name", s_alpha_name
, 0},
4640 { "linkage", s_alpha_linkage
, 0},
4641 { "code_address", s_alpha_code_address
, 0},
4642 { "ent", s_alpha_ent
, 0},
4643 { "frame", s_alpha_frame
, 0},
4644 { "fp_save", s_alpha_fp_save
, 0},
4645 { "mask", s_alpha_mask
, 0},
4646 { "fmask", s_alpha_fmask
, 0},
4647 { "end", s_alpha_end
, 0},
4648 { "file", s_alpha_file
, 0},
4649 { "rdata", s_alpha_section
, 1},
4650 { "comm", s_alpha_comm
, 0},
4651 { "link", s_alpha_section
, 3},
4652 { "ctors", s_alpha_section
, 4},
4653 { "dtors", s_alpha_section
, 5},
4656 /* Frame related pseudos. */
4657 {"ent", s_alpha_ent
, 0},
4658 {"end", s_alpha_end
, 0},
4659 {"mask", s_alpha_mask
, 0},
4660 {"fmask", s_alpha_mask
, 1},
4661 {"frame", s_alpha_frame
, 0},
4662 {"prologue", s_alpha_prologue
, 0},
4663 {"file", s_alpha_file
, 5},
4664 {"loc", s_alpha_loc
, 9},
4665 {"stabs", s_alpha_stab
, 's'},
4666 {"stabn", s_alpha_stab
, 'n'},
4667 {"usepv", s_alpha_usepv
, 0},
4668 /* COFF debugging related pseudos. */
4669 {"begin", s_alpha_coff_wrapper
, 0},
4670 {"bend", s_alpha_coff_wrapper
, 1},
4671 {"def", s_alpha_coff_wrapper
, 2},
4672 {"dim", s_alpha_coff_wrapper
, 3},
4673 {"endef", s_alpha_coff_wrapper
, 4},
4674 {"scl", s_alpha_coff_wrapper
, 5},
4675 {"tag", s_alpha_coff_wrapper
, 6},
4676 {"val", s_alpha_coff_wrapper
, 7},
4678 {"prologue", s_ignore
, 0},
4680 {"gprel32", s_alpha_gprel32
, 0},
4681 {"t_floating", s_alpha_float_cons
, 'd'},
4682 {"s_floating", s_alpha_float_cons
, 'f'},
4683 {"f_floating", s_alpha_float_cons
, 'F'},
4684 {"g_floating", s_alpha_float_cons
, 'G'},
4685 {"d_floating", s_alpha_float_cons
, 'D'},
4687 {"proc", s_alpha_proc
, 0},
4688 {"aproc", s_alpha_proc
, 1},
4689 {"set", s_alpha_set
, 0},
4690 {"reguse", s_ignore
, 0},
4691 {"livereg", s_ignore
, 0},
4692 {"base", s_alpha_base
, 0}, /*??*/
4693 {"option", s_ignore
, 0},
4694 {"aent", s_ignore
, 0},
4695 {"ugen", s_ignore
, 0},
4696 {"eflag", s_ignore
, 0},
4698 {"align", s_alpha_align
, 0},
4699 {"double", s_alpha_float_cons
, 'd'},
4700 {"float", s_alpha_float_cons
, 'f'},
4701 {"single", s_alpha_float_cons
, 'f'},
4702 {"ascii", s_alpha_stringer
, 0},
4703 {"asciz", s_alpha_stringer
, 1},
4704 {"string", s_alpha_stringer
, 1},
4705 {"space", s_alpha_space
, 0},
4706 {"skip", s_alpha_space
, 0},
4707 {"zero", s_alpha_space
, 0},
4709 /* Unaligned data pseudos. */
4710 {"uword", s_alpha_ucons
, 2},
4711 {"ulong", s_alpha_ucons
, 4},
4712 {"uquad", s_alpha_ucons
, 8},
4715 /* Dwarf wants these versions of unaligned. */
4716 {"2byte", s_alpha_ucons
, 2},
4717 {"4byte", s_alpha_ucons
, 4},
4718 {"8byte", s_alpha_ucons
, 8},
4721 /* We don't do any optimizing, so we can safely ignore these. */
4722 {"noalias", s_ignore
, 0},
4723 {"alias", s_ignore
, 0},
4725 {"arch", s_alpha_arch
, 0},
4732 /* @@@ GP selection voodoo. All of this seems overly complicated and
4733 unnecessary; which is the primary reason it's for ECOFF only. */
4734 static inline void maybe_set_gp
PARAMS ((asection
*));
4737 maybe_set_gp (asection
*sec
)
4743 vma
= bfd_get_section_vma (foo
, sec
);
4744 if (vma
&& vma
< alpha_gp_value
)
4745 alpha_gp_value
= vma
;
4749 select_gp_value (void)
4751 assert (alpha_gp_value
== 0);
4753 /* Get minus-one in whatever width... */
4757 /* Select the smallest VMA of these existing sections. */
4758 maybe_set_gp (alpha_lita_section
);
4760 /* @@ Will a simple 0x8000 work here? If not, why not? */
4761 #define GP_ADJUSTMENT (0x8000 - 0x10)
4763 alpha_gp_value
+= GP_ADJUSTMENT
;
4765 S_SET_VALUE (alpha_gp_symbol
, alpha_gp_value
);
4768 printf (_("Chose GP value of %lx\n"), alpha_gp_value
);
4771 #endif /* OBJ_ECOFF */
4774 /* Map 's' to SHF_ALPHA_GPREL. */
4777 alpha_elf_section_letter (int letter
, char **ptr_msg
)
4780 return SHF_ALPHA_GPREL
;
4782 *ptr_msg
= _("Bad .section directive: want a,s,w,x,M,S,G,T in string");
4786 /* Map SHF_ALPHA_GPREL to SEC_SMALL_DATA. */
4789 alpha_elf_section_flags (flagword flags
, int attr
, int type ATTRIBUTE_UNUSED
)
4791 if (attr
& SHF_ALPHA_GPREL
)
4792 flags
|= SEC_SMALL_DATA
;
4795 #endif /* OBJ_ELF */
4797 /* This is called from HANDLE_ALIGN in write.c. Fill in the contents
4798 of an rs_align_code fragment. */
4801 alpha_handle_align (fragS
*fragp
)
4803 static char const unop
[4] = { 0x00, 0x00, 0xfe, 0x2f };
4804 static char const nopunop
[8] =
4806 0x1f, 0x04, 0xff, 0x47,
4807 0x00, 0x00, 0xfe, 0x2f
4813 if (fragp
->fr_type
!= rs_align_code
)
4816 bytes
= fragp
->fr_next
->fr_address
- fragp
->fr_address
- fragp
->fr_fix
;
4817 p
= fragp
->fr_literal
+ fragp
->fr_fix
;
4830 memcpy (p
, unop
, 4);
4836 memcpy (p
, nopunop
, 8);
4838 fragp
->fr_fix
+= fix
;
4842 /* Public interface functions. */
4844 /* This function is called once, at assembler startup time. It sets
4845 up all the tables, etc. that the MD part of the assembler will
4846 need, that can be determined before arguments are parsed. */
4853 /* Verify that X_op field is wide enough. */
4858 assert (e
.X_op
== O_max
);
4861 /* Create the opcode hash table. */
4862 alpha_opcode_hash
= hash_new ();
4864 for (i
= 0; i
< alpha_num_opcodes
;)
4866 const char *name
, *retval
, *slash
;
4868 name
= alpha_opcodes
[i
].name
;
4869 retval
= hash_insert (alpha_opcode_hash
, name
, (void *) &alpha_opcodes
[i
]);
4871 as_fatal (_("internal error: can't hash opcode `%s': %s"),
4874 /* Some opcodes include modifiers of various sorts with a "/mod"
4875 syntax, like the architecture manual suggests. However, for
4876 use with gcc at least, we also need access to those same opcodes
4879 if ((slash
= strchr (name
, '/')) != NULL
)
4881 char *p
= xmalloc (strlen (name
));
4883 memcpy (p
, name
, slash
- name
);
4884 strcpy (p
+ (slash
- name
), slash
+ 1);
4886 (void) hash_insert (alpha_opcode_hash
, p
, (void *) &alpha_opcodes
[i
]);
4887 /* Ignore failures -- the opcode table does duplicate some
4888 variants in different forms, like "hw_stq" and "hw_st/q". */
4891 while (++i
< alpha_num_opcodes
4892 && (alpha_opcodes
[i
].name
== name
4893 || !strcmp (alpha_opcodes
[i
].name
, name
)))
4897 /* Create the macro hash table. */
4898 alpha_macro_hash
= hash_new ();
4900 for (i
= 0; i
< alpha_num_macros
;)
4902 const char *name
, *retval
;
4904 name
= alpha_macros
[i
].name
;
4905 retval
= hash_insert (alpha_macro_hash
, name
, (void *) &alpha_macros
[i
]);
4907 as_fatal (_("internal error: can't hash macro `%s': %s"),
4910 while (++i
< alpha_num_macros
4911 && (alpha_macros
[i
].name
== name
4912 || !strcmp (alpha_macros
[i
].name
, name
)))
4916 /* Construct symbols for each of the registers. */
4917 for (i
= 0; i
< 32; ++i
)
4921 sprintf (name
, "$%d", i
);
4922 alpha_register_table
[i
] = symbol_create (name
, reg_section
, i
,
4923 &zero_address_frag
);
4930 sprintf (name
, "$f%d", i
- 32);
4931 alpha_register_table
[i
] = symbol_create (name
, reg_section
, i
,
4932 &zero_address_frag
);
4935 /* Create the special symbols and sections we'll be using. */
4937 /* So .sbss will get used for tiny objects. */
4938 bfd_set_gp_size (stdoutput
, g_switch_value
);
4941 create_literal_section (".lita", &alpha_lita_section
, &alpha_lita_symbol
);
4943 /* For handling the GP, create a symbol that won't be output in the
4944 symbol table. We'll edit it out of relocs later. */
4945 alpha_gp_symbol
= symbol_create ("<GP value>", alpha_lita_section
, 0x8000,
4946 &zero_address_frag
);
4950 create_literal_section (".link", &alpha_link_section
, &alpha_link_symbol
);
4954 if (ECOFF_DEBUGGING
)
4956 segT sec
= subseg_new (".mdebug", (subsegT
) 0);
4957 bfd_set_section_flags (stdoutput
, sec
, SEC_HAS_CONTENTS
| SEC_READONLY
);
4958 bfd_set_section_alignment (stdoutput
, sec
, 3);
4962 /* Create literal lookup hash table. */
4963 alpha_literal_hash
= hash_new ();
4965 subseg_set (text_section
, 0);
4968 /* The public interface to the instruction assembler. */
4971 md_assemble (char *str
)
4973 /* Current maximum is 13. */
4975 expressionS tok
[MAX_INSN_ARGS
];
4979 /* Split off the opcode. */
4980 opnamelen
= strspn (str
, "abcdefghijklmnopqrstuvwxyz_/46819");
4981 trunclen
= (opnamelen
< sizeof (opname
) - 1
4983 : sizeof (opname
) - 1);
4984 memcpy (opname
, str
, trunclen
);
4985 opname
[trunclen
] = '\0';
4987 /* Tokenize the rest of the line. */
4988 if ((ntok
= tokenize_arguments (str
+ opnamelen
, tok
, MAX_INSN_ARGS
)) < 0)
4990 if (ntok
!= TOKENIZE_ERROR_REPORT
)
4991 as_bad (_("syntax error"));
4996 /* Finish it off. */
4997 assemble_tokens (opname
, tok
, ntok
, alpha_macros_on
);
5000 /* Round up a section's size to the appropriate boundary. */
5003 md_section_align (segT seg
, valueT size
)
5005 int align
= bfd_get_section_alignment (stdoutput
, seg
);
5006 valueT mask
= ((valueT
) 1 << align
) - 1;
5008 return (size
+ mask
) & ~mask
;
5011 /* Turn a string in input_line_pointer into a floating point constant
5012 of type TYPE, and store the appropriate bytes in *LITP. The number
5013 of LITTLENUMS emitted is stored in *SIZEP. An error message is
5014 returned, or NULL on OK. */
5016 /* Equal to MAX_PRECISION in atof-ieee.c. */
5017 #define MAX_LITTLENUMS 6
5019 extern char *vax_md_atof (int, char *, int *);
5022 md_atof (int type
, char *litP
, int *sizeP
)
5025 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
5026 LITTLENUM_TYPE
*wordP
;
5033 /* VAX md_atof doesn't like "G" for some reason. */
5037 return vax_md_atof (type
, litP
, sizeP
);
5060 return _("Bad call to MD_ATOF()");
5062 t
= atof_ieee (input_line_pointer
, type
, words
);
5064 input_line_pointer
= t
;
5065 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
5067 for (wordP
= words
+ prec
- 1; prec
--;)
5069 md_number_to_chars (litP
, (long) (*wordP
--), sizeof (LITTLENUM_TYPE
));
5070 litP
+= sizeof (LITTLENUM_TYPE
);
5076 /* Take care of the target-specific command-line options. */
5079 md_parse_option (int c
, char *arg
)
5084 alpha_nofloats_on
= 1;
5088 alpha_addr32_on
= 1;
5096 g_switch_value
= atoi (arg
);
5101 const struct cpu_type
*p
;
5103 for (p
= cpu_types
; p
->name
; ++p
)
5104 if (strcmp (arg
, p
->name
) == 0)
5106 alpha_target_name
= p
->name
, alpha_target
= p
->flags
;
5109 as_warn (_("Unknown CPU identifier `%s'"), arg
);
5115 case '+': /* For g++. Hash any name > 63 chars long. */
5116 alpha_flag_hash_long_names
= 1;
5119 case 'H': /* Show new symbol after hash truncation. */
5120 alpha_flag_show_after_trunc
= 1;
5123 case 'h': /* For gnu-c/vax compatibility. */
5128 alpha_flag_relax
= 1;
5133 alpha_flag_mdebug
= 1;
5135 case OPTION_NO_MDEBUG
:
5136 alpha_flag_mdebug
= 0;
5147 /* Print a description of the command-line options that we accept. */
5150 md_show_usage (FILE *stream
)
5154 -32addr treat addresses as 32-bit values\n\
5155 -F lack floating point instructions support\n\
5156 -mev4 | -mev45 | -mev5 | -mev56 | -mpca56 | -mev6 | -mev67 | -mev68 | -mall\n\
5157 specify variant of Alpha architecture\n\
5158 -m21064 | -m21066 | -m21164 | -m21164a | -m21164pc | -m21264 | -m21264a | -m21264b\n\
5159 these variants include PALcode opcodes\n"),
5164 -+ hash encode (don't truncate) names longer than 64 characters\n\
5165 -H show new symbol after hash truncation\n"),
5170 /* Decide from what point a pc-relative relocation is relative to,
5171 relative to the pc-relative fixup. Er, relatively speaking. */
5174 md_pcrel_from (fixS
*fixP
)
5176 valueT addr
= fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
5178 switch (fixP
->fx_r_type
)
5180 case BFD_RELOC_23_PCREL_S2
:
5181 case BFD_RELOC_ALPHA_HINT
:
5182 case BFD_RELOC_ALPHA_BRSGP
:
5189 /* Attempt to simplify or even eliminate a fixup. The return value is
5190 ignored; perhaps it was once meaningful, but now it is historical.
5191 To indicate that a fixup has been eliminated, set fixP->fx_done.
5193 For ELF, here it is that we transform the GPDISP_HI16 reloc we used
5194 internally into the GPDISP reloc used externally. We had to do
5195 this so that we'd have the GPDISP_LO16 reloc as a tag to compute
5196 the distance to the "lda" instruction for setting the addend to
5200 md_apply_fix3 (fixS
*fixP
, valueT
* valP
, segT seg
)
5202 char * const fixpos
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
5203 valueT value
= * valP
;
5204 unsigned image
, size
;
5206 switch (fixP
->fx_r_type
)
5208 /* The GPDISP relocations are processed internally with a symbol
5209 referring to the current function's section; we need to drop
5210 in a value which, when added to the address of the start of
5211 the function, gives the desired GP. */
5212 case BFD_RELOC_ALPHA_GPDISP_HI16
:
5214 fixS
*next
= fixP
->fx_next
;
5216 /* With user-specified !gpdisp relocations, we can be missing
5217 the matching LO16 reloc. We will have already issued an
5220 fixP
->fx_offset
= (next
->fx_frag
->fr_address
+ next
->fx_where
5221 - fixP
->fx_frag
->fr_address
- fixP
->fx_where
);
5223 value
= (value
- sign_extend_16 (value
)) >> 16;
5226 fixP
->fx_r_type
= BFD_RELOC_ALPHA_GPDISP
;
5230 case BFD_RELOC_ALPHA_GPDISP_LO16
:
5231 value
= sign_extend_16 (value
);
5232 fixP
->fx_offset
= 0;
5238 fixP
->fx_addsy
= section_symbol (seg
);
5239 md_number_to_chars (fixpos
, value
, 2);
5244 fixP
->fx_r_type
= BFD_RELOC_16_PCREL
;
5250 fixP
->fx_r_type
= BFD_RELOC_32_PCREL
;
5256 fixP
->fx_r_type
= BFD_RELOC_64_PCREL
;
5260 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
5262 md_number_to_chars (fixpos
, value
, size
);
5268 case BFD_RELOC_GPREL32
:
5269 assert (fixP
->fx_subsy
== alpha_gp_symbol
);
5271 /* FIXME: inherited this obliviousness of `value' -- why? */
5272 md_number_to_chars (fixpos
, -alpha_gp_value
, 4);
5275 case BFD_RELOC_GPREL32
:
5277 case BFD_RELOC_GPREL16
:
5278 case BFD_RELOC_ALPHA_GPREL_HI16
:
5279 case BFD_RELOC_ALPHA_GPREL_LO16
:
5282 case BFD_RELOC_23_PCREL_S2
:
5283 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
5285 image
= bfd_getl32 (fixpos
);
5286 image
= (image
& ~0x1FFFFF) | ((value
>> 2) & 0x1FFFFF);
5291 case BFD_RELOC_ALPHA_HINT
:
5292 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
5294 image
= bfd_getl32 (fixpos
);
5295 image
= (image
& ~0x3FFF) | ((value
>> 2) & 0x3FFF);
5301 case BFD_RELOC_ALPHA_BRSGP
:
5304 case BFD_RELOC_ALPHA_TLSGD
:
5305 case BFD_RELOC_ALPHA_TLSLDM
:
5306 case BFD_RELOC_ALPHA_GOTDTPREL16
:
5307 case BFD_RELOC_ALPHA_DTPREL_HI16
:
5308 case BFD_RELOC_ALPHA_DTPREL_LO16
:
5309 case BFD_RELOC_ALPHA_DTPREL16
:
5310 case BFD_RELOC_ALPHA_GOTTPREL16
:
5311 case BFD_RELOC_ALPHA_TPREL_HI16
:
5312 case BFD_RELOC_ALPHA_TPREL_LO16
:
5313 case BFD_RELOC_ALPHA_TPREL16
:
5315 S_SET_THREAD_LOCAL (fixP
->fx_addsy
);
5320 case BFD_RELOC_ALPHA_LITERAL
:
5321 md_number_to_chars (fixpos
, value
, 2);
5324 case BFD_RELOC_ALPHA_ELF_LITERAL
:
5325 case BFD_RELOC_ALPHA_LITUSE
:
5326 case BFD_RELOC_ALPHA_LINKAGE
:
5327 case BFD_RELOC_ALPHA_CODEADDR
:
5330 case BFD_RELOC_VTABLE_INHERIT
:
5331 case BFD_RELOC_VTABLE_ENTRY
:
5336 const struct alpha_operand
*operand
;
5338 if ((int) fixP
->fx_r_type
>= 0)
5339 as_fatal (_("unhandled relocation type %s"),
5340 bfd_get_reloc_code_name (fixP
->fx_r_type
));
5342 assert (-(int) fixP
->fx_r_type
< (int) alpha_num_operands
);
5343 operand
= &alpha_operands
[-(int) fixP
->fx_r_type
];
5345 /* The rest of these fixups only exist internally during symbol
5346 resolution and have no representation in the object file.
5347 Therefore they must be completely resolved as constants. */
5349 if (fixP
->fx_addsy
!= 0
5350 && S_GET_SEGMENT (fixP
->fx_addsy
) != absolute_section
)
5351 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5352 _("non-absolute expression in constant field"));
5354 image
= bfd_getl32 (fixpos
);
5355 image
= insert_operand (image
, operand
, (offsetT
) value
,
5356 fixP
->fx_file
, fixP
->fx_line
);
5361 if (fixP
->fx_addsy
!= 0 || fixP
->fx_pcrel
!= 0)
5365 as_warn_where (fixP
->fx_file
, fixP
->fx_line
,
5366 _("type %d reloc done?\n"), (int) fixP
->fx_r_type
);
5371 md_number_to_chars (fixpos
, image
, 4);
5377 /* Look for a register name in the given symbol. */
5380 md_undefined_symbol (char *name
)
5384 int is_float
= 0, num
;
5389 if (name
[1] == 'p' && name
[2] == '\0')
5390 return alpha_register_table
[AXP_REG_FP
];
5395 if (!ISDIGIT (*++name
))
5399 case '0': case '1': case '2': case '3': case '4':
5400 case '5': case '6': case '7': case '8': case '9':
5401 if (name
[1] == '\0')
5402 num
= name
[0] - '0';
5403 else if (name
[0] != '0' && ISDIGIT (name
[1]) && name
[2] == '\0')
5405 num
= (name
[0] - '0') * 10 + name
[1] - '0';
5412 if (!alpha_noat_on
&& (num
+ is_float
) == AXP_REG_AT
)
5413 as_warn (_("Used $at without \".set noat\""));
5414 return alpha_register_table
[num
+ is_float
];
5417 if (name
[1] == 't' && name
[2] == '\0')
5420 as_warn (_("Used $at without \".set noat\""));
5421 return alpha_register_table
[AXP_REG_AT
];
5426 if (name
[1] == 'p' && name
[2] == '\0')
5427 return alpha_register_table
[alpha_gp_register
];
5431 if (name
[1] == 'p' && name
[2] == '\0')
5432 return alpha_register_table
[AXP_REG_SP
];
5440 /* @@@ Magic ECOFF bits. */
5443 alpha_frob_ecoff_data (void)
5446 /* $zero and $f31 are read-only. */
5447 alpha_gprmask
&= ~1;
5448 alpha_fprmask
&= ~1;
5452 /* Hook to remember a recently defined label so that the auto-align
5453 code can adjust the symbol after we know what alignment will be
5457 alpha_define_label (symbolS
*sym
)
5459 alpha_insn_label
= sym
;
5462 /* Return true if we must always emit a reloc for a type and false if
5463 there is some hope of resolving it at assembly time. */
5466 alpha_force_relocation (fixS
*f
)
5468 if (alpha_flag_relax
)
5471 switch (f
->fx_r_type
)
5473 case BFD_RELOC_ALPHA_GPDISP_HI16
:
5474 case BFD_RELOC_ALPHA_GPDISP_LO16
:
5475 case BFD_RELOC_ALPHA_GPDISP
:
5476 case BFD_RELOC_ALPHA_LITERAL
:
5477 case BFD_RELOC_ALPHA_ELF_LITERAL
:
5478 case BFD_RELOC_ALPHA_LITUSE
:
5479 case BFD_RELOC_GPREL16
:
5480 case BFD_RELOC_GPREL32
:
5481 case BFD_RELOC_ALPHA_GPREL_HI16
:
5482 case BFD_RELOC_ALPHA_GPREL_LO16
:
5483 case BFD_RELOC_ALPHA_LINKAGE
:
5484 case BFD_RELOC_ALPHA_CODEADDR
:
5485 case BFD_RELOC_ALPHA_BRSGP
:
5486 case BFD_RELOC_ALPHA_TLSGD
:
5487 case BFD_RELOC_ALPHA_TLSLDM
:
5488 case BFD_RELOC_ALPHA_GOTDTPREL16
:
5489 case BFD_RELOC_ALPHA_DTPREL_HI16
:
5490 case BFD_RELOC_ALPHA_DTPREL_LO16
:
5491 case BFD_RELOC_ALPHA_DTPREL16
:
5492 case BFD_RELOC_ALPHA_GOTTPREL16
:
5493 case BFD_RELOC_ALPHA_TPREL_HI16
:
5494 case BFD_RELOC_ALPHA_TPREL_LO16
:
5495 case BFD_RELOC_ALPHA_TPREL16
:
5502 return generic_force_reloc (f
);
5505 /* Return true if we can partially resolve a relocation now. */
5508 alpha_fix_adjustable (fixS
*f
)
5510 /* Are there any relocation types for which we must generate a
5511 reloc but we can adjust the values contained within it? */
5512 switch (f
->fx_r_type
)
5514 case BFD_RELOC_ALPHA_GPDISP_HI16
:
5515 case BFD_RELOC_ALPHA_GPDISP_LO16
:
5516 case BFD_RELOC_ALPHA_GPDISP
:
5519 case BFD_RELOC_ALPHA_LITERAL
:
5520 case BFD_RELOC_ALPHA_ELF_LITERAL
:
5521 case BFD_RELOC_ALPHA_LITUSE
:
5522 case BFD_RELOC_ALPHA_LINKAGE
:
5523 case BFD_RELOC_ALPHA_CODEADDR
:
5526 case BFD_RELOC_VTABLE_ENTRY
:
5527 case BFD_RELOC_VTABLE_INHERIT
:
5530 case BFD_RELOC_GPREL16
:
5531 case BFD_RELOC_GPREL32
:
5532 case BFD_RELOC_ALPHA_GPREL_HI16
:
5533 case BFD_RELOC_ALPHA_GPREL_LO16
:
5534 case BFD_RELOC_23_PCREL_S2
:
5537 case BFD_RELOC_ALPHA_HINT
:
5540 case BFD_RELOC_ALPHA_TLSGD
:
5541 case BFD_RELOC_ALPHA_TLSLDM
:
5542 case BFD_RELOC_ALPHA_GOTDTPREL16
:
5543 case BFD_RELOC_ALPHA_DTPREL_HI16
:
5544 case BFD_RELOC_ALPHA_DTPREL_LO16
:
5545 case BFD_RELOC_ALPHA_DTPREL16
:
5546 case BFD_RELOC_ALPHA_GOTTPREL16
:
5547 case BFD_RELOC_ALPHA_TPREL_HI16
:
5548 case BFD_RELOC_ALPHA_TPREL_LO16
:
5549 case BFD_RELOC_ALPHA_TPREL16
:
5550 /* ??? No idea why we can't return a reference to .tbss+10, but
5551 we're preventing this in the other assemblers. Follow for now. */
5555 case BFD_RELOC_ALPHA_BRSGP
:
5556 /* If we have a BRSGP reloc to a local symbol, adjust it to BRADDR and
5557 let it get resolved at assembly time. */
5559 symbolS
*sym
= f
->fx_addsy
;
5563 if (generic_force_reloc (f
))
5566 switch (S_GET_OTHER (sym
) & STO_ALPHA_STD_GPLOAD
)
5568 case STO_ALPHA_NOPV
:
5570 case STO_ALPHA_STD_GPLOAD
:
5574 if (S_IS_LOCAL (sym
))
5577 name
= S_GET_NAME (sym
);
5578 as_bad_where (f
->fx_file
, f
->fx_line
,
5579 _("!samegp reloc against symbol without .prologue: %s"),
5583 f
->fx_r_type
= BFD_RELOC_23_PCREL_S2
;
5584 f
->fx_offset
+= offset
;
5594 /* Generate the BFD reloc to be stuck in the object file from the
5595 fixup used internally in the assembler. */
5598 tc_gen_reloc (asection
*sec ATTRIBUTE_UNUSED
,
5603 reloc
= xmalloc (sizeof (* reloc
));
5604 reloc
->sym_ptr_ptr
= xmalloc (sizeof (asymbol
*));
5605 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
5606 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
5608 /* Make sure none of our internal relocations make it this far.
5609 They'd better have been fully resolved by this point. */
5610 assert ((int) fixp
->fx_r_type
> 0);
5612 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
5613 if (reloc
->howto
== NULL
)
5615 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5616 _("cannot represent `%s' relocation in object file"),
5617 bfd_get_reloc_code_name (fixp
->fx_r_type
));
5621 if (!fixp
->fx_pcrel
!= !reloc
->howto
->pc_relative
)
5622 as_fatal (_("internal error? cannot generate `%s' relocation"),
5623 bfd_get_reloc_code_name (fixp
->fx_r_type
));
5625 assert (!fixp
->fx_pcrel
== !reloc
->howto
->pc_relative
);
5628 if (fixp
->fx_r_type
== BFD_RELOC_ALPHA_LITERAL
)
5629 /* Fake out bfd_perform_relocation. sigh. */
5630 reloc
->addend
= -alpha_gp_value
;
5634 reloc
->addend
= fixp
->fx_offset
;
5636 /* Ohhh, this is ugly. The problem is that if this is a local global
5637 symbol, the relocation will entirely be performed at link time, not
5638 at assembly time. bfd_perform_reloc doesn't know about this sort
5639 of thing, and as a result we need to fake it out here. */
5640 if ((S_IS_EXTERNAL (fixp
->fx_addsy
) || S_IS_WEAK (fixp
->fx_addsy
)
5641 || (S_GET_SEGMENT (fixp
->fx_addsy
)->flags
& SEC_MERGE
)
5642 || (S_GET_SEGMENT (fixp
->fx_addsy
)->flags
& SEC_THREAD_LOCAL
))
5643 && !S_IS_COMMON (fixp
->fx_addsy
))
5644 reloc
->addend
-= symbol_get_bfdsym (fixp
->fx_addsy
)->value
;
5651 /* Parse a register name off of the input_line and return a register
5652 number. Gets md_undefined_symbol above to do the register name
5655 Only called as a part of processing the ECOFF .frame directive. */
5658 tc_get_register (int frame ATTRIBUTE_UNUSED
)
5660 int framereg
= AXP_REG_SP
;
5663 if (*input_line_pointer
== '$')
5665 char *s
= input_line_pointer
;
5666 char c
= get_symbol_end ();
5667 symbolS
*sym
= md_undefined_symbol (s
);
5669 *strchr (s
, '\0') = c
;
5670 if (sym
&& (framereg
= S_GET_VALUE (sym
)) <= 31)
5673 as_warn (_("frame reg expected, using $%d."), framereg
);
5676 note_gpreg (framereg
);
5680 /* This is called before the symbol table is processed. In order to
5681 work with gcc when using mips-tfile, we must keep all local labels.
5682 However, in other cases, we want to discard them. If we were
5683 called with -g, but we didn't see any debugging information, it may
5684 mean that gcc is smuggling debugging information through to
5685 mips-tfile, in which case we must generate all local labels. */
5690 alpha_frob_file_before_adjust (void)
5692 if (alpha_debug
!= 0
5693 && ! ecoff_debugging_seen
)
5694 flag_keep_locals
= 1;
5697 #endif /* OBJ_ECOFF */
5699 /* The Alpha has support for some VAX floating point types, as well as for
5700 IEEE floating point. We consider IEEE to be the primary floating point
5701 format, and sneak in the VAX floating point support here. */
5702 #define md_atof vax_md_atof
5703 #include "config/atof-vax.c"