1 /* tc-alpha.c - Processor-specific code for the DEC Alpha AXP CPU.
2 Copyright (C) 1989, 93, 94, 95, 1996 Free Software Foundation, Inc.
3 Contributed by Carnegie Mellon University, 1993.
4 Written by Alessandro Forin, based on earlier gas-1.38 target CPU files.
5 Modified by Ken Raeburn for gas-2.x and ECOFF support.
6 Modified by Richard Henderson for ELF support.
8 This file is part of GAS, the GNU Assembler.
10 GAS is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2, or (at your option)
15 GAS is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with GAS; see the file COPYING. If not, write to the Free
22 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
26 * Mach Operating System
27 * Copyright (c) 1993 Carnegie Mellon University
28 * All Rights Reserved.
30 * Permission to use, copy, modify and distribute this software and its
31 * documentation is hereby granted, provided that both the copyright
32 * notice and this permission notice appear in all copies of the
33 * software, derivative works or modified versions, and any portions
34 * thereof, and that both notices appear in supporting documentation.
36 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
37 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
38 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
40 * Carnegie Mellon requests users of this software to return to
42 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
43 * School of Computer Science
44 * Carnegie Mellon University
45 * Pittsburgh PA 15213-3890
47 * any improvements or extensions that they make and grant Carnegie the
48 * rights to redistribute these changes.
54 #include "opcode/alpha.h"
57 #include "elf/alpha.h"
65 #define MAX_INSN_FIXUPS 2
66 #define MAX_INSN_ARGS 5
71 bfd_reloc_code_real_type reloc
;
78 struct alpha_fixup fixups
[MAX_INSN_FIXUPS
];
83 MACRO_EOA
= 1, MACRO_IR
, MACRO_PIR
, MACRO_CPIR
, MACRO_FPR
, MACRO_EXP
89 void (*emit
) PARAMS((const expressionS
*, int, void *));
91 enum alpha_macro_arg argsets
[16];
94 /* Two extra symbols we want to see in our input. This is a blatent
95 misuse of the expressionS.X_op field. */
97 #define O_pregister (O_max+1) /* O_register, but in parentheses */
98 #define O_cpregister (O_pregister+1) /* + a leading comma */
100 /* Macros for extracting the type and number of encoded register tokens */
102 #define is_ir_num(x) (((x) & 32) == 0)
103 #define is_fpr_num(x) (((x) & 32) != 0)
104 #define regno(x) ((x) & 31)
106 /* Something odd inherited from the old assembler */
108 #define note_gpreg(R) (alpha_gprmask |= (1 << (R)))
109 #define note_fpreg(R) (alpha_fprmask |= (1 << (R)))
111 /* Predicates for 16- and 32-bit ranges */
113 #define range_signed_16(x) ((offsetT)(x) >= -(offsetT)0x8000 && \
114 (offsetT)(x) <= (offsetT)0x7FFF)
115 #define range_signed_32(x) ((offsetT)(x) >= -(offsetT)0x80000000 && \
116 (offsetT)(x) <= (offsetT)0x7FFFFFFF)
118 /* Macros for sign extending from 16- and 32-bits. */
119 /* XXX: The cast macros will work on all the systems that I care about,
120 but really a predicate should be found to use the non-cast forms. */
123 #define sign_extend_16(x) ((short)(x))
124 #define sign_extend_32(x) ((int)(x))
126 #define sign_extend_16(x) ((offsetT)(((x) & 0xFFFF) ^ 0x8000) - 0x8000)
127 #define sign_extend_32(x) ((offsetT)(((x) & 0xFFFFFFFF) \
128 ^ 0x80000000) - 0x80000000)
131 /* Macros to build tokens */
133 #define set_tok_reg(t, r) (memset(&(t), 0, sizeof(t)), \
134 (t).X_op = O_register, \
135 (t).X_add_number = (r))
136 #define set_tok_preg(t, r) (memset(&(t), 0, sizeof(t)), \
137 (t).X_op = O_pregister, \
138 (t).X_add_number = (r))
139 #define set_tok_cpreg(t, r) (memset(&(t), 0, sizeof(t)), \
140 (t).X_op = O_cpregister, \
141 (t).X_add_number = (r))
142 #define set_tok_freg(t, r) (memset(&(t), 0, sizeof(t)), \
143 (t).X_op = O_register, \
144 (t).X_add_number = (r)+32)
145 #define set_tok_sym(t, s, a) (memset(&(t), 0, sizeof(t)), \
146 (t).X_op = O_symbol, \
147 (t).X_add_symbol = (s), \
148 (t).X_add_number = (a))
149 #define set_tok_const(t, n) (memset(&(t), 0, sizeof(t)), \
150 (t).X_op = O_constant, \
151 (t).X_add_number = (n))
154 /* Prototypes for all local functions */
156 static int tokenize_arguments
PARAMS((char *, expressionS
*, int));
157 static const struct alpha_opcode
*find_opcode_match
158 PARAMS((const struct alpha_opcode
*, const expressionS
*, int*, int*));
159 static const struct alpha_macro
*find_macro_match
160 PARAMS((const struct alpha_macro
*, const expressionS
*, int*));
161 static unsigned insert_operand
PARAMS((unsigned, const struct alpha_operand
*,
162 offsetT
, char *, unsigned));
163 static void assemble_insn
PARAMS((const struct alpha_opcode
*,
164 const expressionS
*, int,
165 struct alpha_insn
*));
166 static void emit_insn
PARAMS((struct alpha_insn
*));
167 static void assemble_tokens_to_insn
PARAMS((const char *, const expressionS
*,
168 int, struct alpha_insn
*));
169 static void assemble_tokens
PARAMS((const char *, const expressionS
*,
172 static int load_expression
PARAMS((int, const expressionS
*, int *,
175 static void emit_ldgp
PARAMS((const expressionS
*, int, void*));
176 static void emit_division
PARAMS((const expressionS
*, int, void*));
177 static void emit_lda
PARAMS((const expressionS
*, int, void*));
178 static void emit_ir_load
PARAMS((const expressionS
*, int, void*));
179 static void emit_loadstore
PARAMS((const expressionS
*, int, void*));
180 static void emit_jsrjmp
PARAMS((const expressionS
*, int, void*));
182 static void s_alpha_text
PARAMS((int));
183 static void s_alpha_data
PARAMS((int));
185 static void s_alpha_comm
PARAMS((int));
187 static void s_alpha_rdata
PARAMS((int));
188 static void s_alpha_sdata
PARAMS((int));
189 static void s_alpha_gprel32
PARAMS((int));
190 static void s_alpha_float_cons
PARAMS((int));
191 static void s_alpha_proc
PARAMS((int));
192 static void s_alpha_set
PARAMS((int));
193 static void s_alpha_base
PARAMS((int));
194 static void s_alpha_align
PARAMS((int));
195 static void s_alpha_cons
PARAMS((int));
197 static void create_literal_section
PARAMS((const char *, segT
*, symbolS
**));
199 static void select_gp_value
PARAMS((void));
201 static void alpha_align
PARAMS((int, char *, symbolS
*));
204 /* Generic assembler global variables which must be defined by all
207 /* These are exported to relaxing code, even though we don't do any
208 relaxing on this processor currently. */
209 int md_short_jump_size
= 4;
210 int md_long_jump_size
= 4;
212 /* Characters which always start a comment. */
213 const char comment_chars
[] = "#";
215 /* Characters which start a comment at the beginning of a line. */
216 const char line_comment_chars
[] = "#";
218 /* Characters which may be used to separate multiple commands on a
220 const char line_separator_chars
[] = ";";
222 /* Characters which are used to indicate an exponent in a floating
224 const char EXP_CHARS
[] = "eE";
226 /* Characters which mean that a number is a floating point constant,
229 const char FLT_CHARS
[] = "dD";
231 /* XXX: Do all of these really get used on the alpha?? */
232 char FLT_CHARS
[] = "rRsSfFdDxXpP";
235 const char *md_shortopts
= "Fm:g";
237 struct option md_longopts
[] = {
238 #define OPTION_32ADDR (OPTION_MD_BASE)
239 { "32addr", no_argument
, NULL
, OPTION_32ADDR
},
240 { NULL
, no_argument
, NULL
, 0 }
243 size_t md_longopts_size
= sizeof(md_longopts
);
246 /* The cpu for which we are generating code */
247 static unsigned alpha_target
= AXP_OPCODE_ALL
;
248 static const char *alpha_target_name
= "<all>";
250 /* Forward declaration of the table of macros */
251 static const struct alpha_macro alpha_macros
[];
252 static const int alpha_num_macros
;
254 /* The hash table of instruction opcodes */
255 static struct hash_control
*alpha_opcode_hash
;
257 /* The hash table of macro opcodes */
258 static struct hash_control
*alpha_macro_hash
;
261 /* The $gp relocation symbol */
262 static symbolS
*alpha_gp_symbol
;
264 /* XXX: what is this, and why is it exported? */
265 valueT alpha_gp_value
;
268 /* The current $gp register */
269 static int alpha_gp_register
= AXP_REG_GP
;
271 /* A table of the register symbols */
272 static symbolS
*alpha_register_table
[64];
274 /* Constant sections, or sections of constants */
276 static segT alpha_lita_section
;
277 static segT alpha_lit4_section
;
279 static segT alpha_lit8_section
;
281 /* Symbols referring to said sections. */
283 static symbolS
*alpha_lita_symbol
;
284 static symbolS
*alpha_lit4_symbol
;
286 static symbolS
*alpha_lit8_symbol
;
288 /* Is the assembler not allowed to use $at? */
289 static int alpha_noat_on
= 0;
291 /* Are macros enabled? */
292 static int alpha_macros_on
= 1;
294 /* Are floats disabled? */
295 static int alpha_nofloats_on
= 0;
297 /* Are addresses 32 bit? */
298 static int alpha_addr32_on
= 0;
300 /* Symbol labelling the current insn. When the Alpha gas sees
303 and the section happens to not be on an eight byte boundary, it
304 will align both the symbol and the .quad to an eight byte boundary. */
305 static symbolS
*alpha_insn_label
;
307 /* Whether we should automatically align data generation pseudo-ops.
308 .align 0 will turn this off. */
309 static int alpha_auto_align_on
= 1;
311 /* These are exported to ECOFF code. */
312 unsigned long alpha_gprmask
, alpha_fprmask
;
315 /* Public interface functions */
318 * This function is called once, at assembler startup time. It sets up
319 * all the tables, etc. that the MD part of the assembler will need,
320 * that can be determined before arguments are parsed.
328 /* Create the opcode hash table */
330 alpha_opcode_hash
= hash_new ();
331 for (i
= 0; i
< alpha_num_opcodes
; )
333 const char *name
, *retval
;
335 name
= alpha_opcodes
[i
].name
;
336 retval
= hash_insert (alpha_opcode_hash
, name
, (PTR
)&alpha_opcodes
[i
]);
338 as_fatal ("internal error: can't hash opcode `%s': %s", name
, retval
);
340 while (++i
< alpha_num_opcodes
341 && (alpha_opcodes
[i
].name
== name
342 || !strcmp (alpha_opcodes
[i
].name
, name
)))
346 /* Some opcodes include modifiers of various sorts with a "/mod" syntax,
347 like the architecture manual suggests. However, for use with gcc at
348 least, we also need access to those same opcodes without the "/". */
349 for (i
= 0; i
< alpha_num_opcodes
; )
351 const char *name
, *slash
;
352 name
= alpha_opcodes
[i
].name
;
353 if ((slash
= strchr(name
, '/')) != NULL
)
355 char *p
= xmalloc (strlen (name
));
356 memcpy(p
, name
, slash
-name
);
357 strcpy(p
+(slash
-name
), slash
+1);
359 (void)hash_insert(alpha_opcode_hash
, p
, (PTR
)&alpha_opcodes
[i
]);
360 /* Ignore failures -- the opcode table does duplicate some
361 variants in different forms, like "hw_stq" and "hw_st/q". */
364 while (++i
< alpha_num_opcodes
365 && (alpha_opcodes
[i
].name
== name
366 || !strcmp (alpha_opcodes
[i
].name
, name
)))
370 /* Create the macro hash table */
372 alpha_macro_hash
= hash_new ();
373 for (i
= 0; i
< alpha_num_macros
; )
375 const char *name
, *retval
;
377 name
= alpha_macros
[i
].name
;
378 retval
= hash_insert (alpha_macro_hash
, name
, (PTR
)&alpha_macros
[i
]);
380 as_fatal ("internal error: can't hash macro `%s': %s", name
, retval
);
382 while (++i
< alpha_num_macros
383 && (alpha_macros
[i
].name
== name
384 || !strcmp (alpha_macros
[i
].name
, name
)))
388 /* Construct symbols for each of the registers */
390 for (i
= 0; i
< 32; ++i
)
393 sprintf(name
, "$%d", i
);
394 alpha_register_table
[i
] = symbol_create(name
, reg_section
, i
,
400 sprintf(name
, "$f%d", i
-32);
401 alpha_register_table
[i
] = symbol_create(name
, reg_section
, i
,
405 /* Create the special symbols and sections we'll be using */
407 /* So .sbss will get used for tiny objects. */
408 bfd_set_gp_size (stdoutput
, 8);
411 create_literal_section (".lita", &alpha_lita_section
, &alpha_lita_symbol
);
413 /* For handling the GP, create a symbol that won't be output in the
414 symbol table. We'll edit it out of relocs later. */
415 alpha_gp_symbol
= symbol_create ("<GP value>", alpha_lita_section
, 0x8000,
424 sec
= subseg_new(".mdebug", (subsegT
)0);
425 bfd_set_section_flags(stdoutput
, sec
, SEC_HAS_CONTENTS
|SEC_READONLY
);
426 bfd_set_section_alignment(stdoutput
, sec
, 3);
429 sec
= subseg_new(".reginfo", (subsegT
)0);
430 /* The ABI says this section should be loaded so that the running
431 program can access it. */
432 bfd_set_section_flags(stdoutput
, sec
,
433 SEC_ALLOC
|SEC_LOAD
|SEC_READONLY
|SEC_DATA
);
434 bfd_set_section_alignement(stdoutput
, sec
, 3);
439 subseg_set(text_section
, 0);
443 * The public interface to the instruction assembler.
450 char opname
[32]; /* current maximum is 13 */
451 expressionS tok
[MAX_INSN_ARGS
];
452 int ntok
, opnamelen
, trunclen
;
454 /* split off the opcode */
455 opnamelen
= strspn (str
, "abcdefghijklmnopqrstuvwxyz_/48");
456 trunclen
= (opnamelen
< sizeof (opname
) - 1
458 : sizeof (opname
) - 1);
459 memcpy (opname
, str
, trunclen
);
460 opname
[trunclen
] = '\0';
462 /* tokenize the rest of the line */
463 if ((ntok
= tokenize_arguments (str
+ opnamelen
, tok
, MAX_INSN_ARGS
)) < 0)
465 as_bad ("syntax error");
470 assemble_tokens (opname
, tok
, ntok
, alpha_macros_on
);
474 md_section_align (seg
, size
)
478 int align
= bfd_get_section_alignment(stdoutput
, seg
);
479 valueT mask
= ((valueT
)1 << align
) - 1;
481 return (size
+ mask
) & ~mask
;
485 * Turn a string in input_line_pointer into a floating point constant
486 * of type type, and store the appropriate bytes in *litP. The number
487 * of LITTLENUMS emitted is stored in *sizeP. An error message is
488 * returned, or NULL on OK.
491 /* Equal to MAX_PRECISION in atof-ieee.c */
492 #define MAX_LITTLENUMS 6
495 md_atof (type
, litP
, sizeP
)
501 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
502 LITTLENUM_TYPE
*wordP
;
504 char *atof_ieee (), *vax_md_atof ();
510 /* VAX md_atof doesn't like "G" for some reason. */
514 return vax_md_atof (type
, litP
, sizeP
);
537 return "Bad call to MD_ATOF()";
539 t
= atof_ieee (input_line_pointer
, type
, words
);
541 input_line_pointer
= t
;
542 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
544 for (wordP
= words
+ prec
- 1; prec
--;)
546 md_number_to_chars (litP
, (long) (*wordP
--), sizeof (LITTLENUM_TYPE
));
547 litP
+= sizeof (LITTLENUM_TYPE
);
554 md_bignum_to_chars (buf
, bignum
, nchars
)
556 LITTLENUM_TYPE
*bignum
;
561 LITTLENUM_TYPE work
= *bignum
++;
562 int nb
= CHARS_PER_LITTLENUM
;
566 *buf
++ = work
& ((1 << BITS_PER_CHAR
) - 1);
569 work
>>= BITS_PER_CHAR
;
576 md_parse_option (c
, arg
)
583 alpha_nofloats_on
= 1;
591 /* Ignore `-g' so gcc can provide this option to the Digital
592 UNIX assembler, which otherwise would throw away info that
598 static const struct machine
604 { "21064", AXP_OPCODE_EV4
|AXP_OPCODE_ALL
},
605 { "21066", AXP_OPCODE_EV4
|AXP_OPCODE_ALL
},
606 { "21164", AXP_OPCODE_EV5
|AXP_OPCODE_ALL
},
607 { "21164a", AXP_OPCODE_EV56
|AXP_OPCODE_ALL
},
608 { "ev4", AXP_OPCODE_EV4
|AXP_OPCODE_ALL
},
609 { "ev45", AXP_OPCODE_EV4
|AXP_OPCODE_ALL
},
610 { "ev5", AXP_OPCODE_EV5
|AXP_OPCODE_ALL
},
611 { "ev56", AXP_OPCODE_EV56
|AXP_OPCODE_ALL
},
612 { "all", AXP_OPCODE_ALL
},
616 for (p
= m
; p
->name
; ++p
)
617 if (strcmp(arg
, p
->name
) == 0)
619 alpha_target_name
= p
->name
, alpha_target
= p
->flags
;
622 as_warn("Unknown CPU identifier `%s'", arg
);
635 md_show_usage (stream
)
640 -32addr treat addresses as 32-bit values\n\
641 -F lack floating point instructions support\n\
642 -m21064 | -m21066 | -m21164 | -m21164a | -m21264\n\
643 specify variant of Alpha architecture\n",
647 /* FIXME (inherited): @@ Is this right?? */
653 valueT addr
= fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
654 switch (fixP
->fx_r_type
)
656 case BFD_RELOC_ALPHA_GPDISP
:
657 case BFD_RELOC_ALPHA_GPDISP_HI16
:
658 case BFD_RELOC_ALPHA_GPDISP_LO16
:
661 return fixP
->fx_size
+ addr
;
666 md_apply_fix (fixP
, valueP
)
670 char * const fixpos
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
671 valueT value
= *valueP
;
672 unsigned image
, size
;
674 switch (fixP
->fx_r_type
)
676 /* The GPDISP relocations are processed internally with a symbol
677 referring to the current function; we need to drop in a value
678 which, when added to the address of the start of the function,
679 gives the desired GP. */
680 case BFD_RELOC_ALPHA_GPDISP_HI16
:
682 fixS
*next
= fixP
->fx_next
;
683 assert (next
->fx_r_type
== BFD_RELOC_ALPHA_GPDISP_LO16
);
685 fixP
->fx_offset
= (next
->fx_frag
->fr_address
+ next
->fx_where
686 - fixP
->fx_frag
->fr_address
- fixP
->fx_where
);
688 value
= (value
- sign_extend_16 (value
)) >> 16;
691 fixP
->fx_r_type
= BFD_RELOC_ALPHA_GPDISP
;
695 case BFD_RELOC_ALPHA_GPDISP_LO16
:
696 value
= sign_extend_16 (value
);
703 fixP
->fx_addsy
= section_symbol (absolute_section
);
704 md_number_to_chars (fixpos
, value
, 2);
716 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
718 md_number_to_chars (fixpos
, value
, size
);
724 case BFD_RELOC_GPREL32
:
725 assert (fixP
->fx_subsy
== alpha_gp_symbol
);
727 /* FIXME: inherited this obliviousness of `value' -- why? */
728 md_number_to_chars (fixpos
, -alpha_gp_value
, 4);
732 case BFD_RELOC_GPREL32
:
736 case BFD_RELOC_23_PCREL_S2
:
737 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
739 image
= bfd_getl32(fixpos
);
740 image
= (image
& ~0x1FFFFF) | ((value
>> 2) & 0x1FFFFF);
745 case BFD_RELOC_ALPHA_HINT
:
746 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
748 image
= bfd_getl32(fixpos
);
749 image
= (image
& ~0x3FFF) | ((value
>> 2) & 0x3FFF);
755 case BFD_RELOC_ALPHA_LITERAL
:
756 md_number_to_chars (fixpos
, value
, 2);
759 case BFD_RELOC_ALPHA_LITUSE
:
763 case BFD_RELOC_ALPHA_LITERAL
:
764 case BFD_RELOC_ALPHA_LITUSE
:
770 const struct alpha_operand
*operand
;
772 if (fixP
->fx_r_type
<= BFD_RELOC_UNUSED
)
773 as_fatal ("unhandled relocation type %s",
774 bfd_get_reloc_code_name (fixP
->fx_r_type
));
776 assert (fixP
->fx_r_type
< BFD_RELOC_UNUSED
+ alpha_num_operands
);
777 operand
= &alpha_operands
[fixP
->fx_r_type
- BFD_RELOC_UNUSED
];
779 /* The rest of these fixups only exist internally during symbol
780 resolution and have no representation in the object file.
781 Therefore they must be completely resolved as constants. */
783 if (fixP
->fx_addsy
!= 0
784 && fixP
->fx_addsy
->bsym
->section
!= absolute_section
)
785 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
786 "non-absolute expression in constant field");
788 image
= bfd_getl32(fixpos
);
789 image
= insert_operand(image
, operand
, (offsetT
)value
,
790 fixP
->fx_file
, fixP
->fx_line
);
795 if (fixP
->fx_addsy
!= 0 || fixP
->fx_pcrel
!= 0)
799 as_warn_where(fixP
->fx_file
, fixP
->fx_line
,
800 "type %d reloc done?\n", fixP
->fx_r_type
);
805 md_number_to_chars(fixpos
, image
, 4);
813 * Look for a register name in the given symbol.
817 md_undefined_symbol(name
)
822 int is_float
= 0, num
;
827 if (name
[1] == 'p' && name
[2] == '\0')
828 return alpha_register_table
[AXP_REG_FP
];
833 if (!isdigit(*++name
))
837 case '0': case '1': case '2': case '3': case '4':
838 case '5': case '6': case '7': case '8': case '9':
841 else if (name
[0] != '0' && isdigit(name
[1]) && name
[2] == '\0')
843 num
= (name
[0] - '0')*10 + name
[1] - '0';
850 if (!alpha_noat_on
&& num
== AXP_REG_AT
)
851 as_warn("Used $at without \".set noat\"");
852 return alpha_register_table
[num
+ is_float
];
855 if (name
[1] == 't' && name
[2] == '\0')
858 as_warn("Used $at without \".set noat\"");
859 return alpha_register_table
[AXP_REG_AT
];
864 if (name
[1] == 'p' && name
[2] == '\0')
865 return alpha_register_table
[alpha_gp_register
];
869 if (name
[1] == 'p' && name
[2] == '\0')
870 return alpha_register_table
[AXP_REG_SP
];
879 alpha_frob_ecoff_data ()
882 /* $zero and $f31 are read-only */
889 alpha_flush_pending_output ()
891 alpha_insn_label
= NULL
;
895 alpha_define_label (sym
)
898 alpha_insn_label
= sym
;
902 alpha_force_relocation (f
)
905 switch (f
->fx_r_type
)
907 case BFD_RELOC_ALPHA_GPDISP_HI16
:
908 case BFD_RELOC_ALPHA_GPDISP_LO16
:
909 case BFD_RELOC_ALPHA_GPDISP
:
910 case BFD_RELOC_ALPHA_LITERAL
:
911 case BFD_RELOC_ALPHA_LITUSE
:
912 case BFD_RELOC_GPREL32
:
915 case BFD_RELOC_23_PCREL_S2
:
918 case BFD_RELOC_ALPHA_HINT
:
922 assert(f
->fx_r_type
> BFD_RELOC_UNUSED
&&
923 f
->fx_r_type
< BFD_RELOC_UNUSED
+ alpha_num_operands
);
929 alpha_fix_adjustable (f
)
933 /* Prevent all adjustments to global symbols */
934 if (S_IS_EXTERN (f
->fx_addsy
))
938 /* Are there any relocation types for which we must generate a reloc
939 but we can adjust the values contained within it? */
940 switch (f
->fx_r_type
)
942 case BFD_RELOC_GPREL32
:
945 return !alpha_force_relocation (f
);
951 tc_gen_reloc (sec
, fixp
)
957 reloc
= (arelent
*) bfd_alloc_by_size_t (stdoutput
, sizeof (arelent
));
958 reloc
->sym_ptr_ptr
= &fixp
->fx_addsy
->bsym
;
959 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
961 assert (fixp
->fx_r_type
< BFD_RELOC_UNUSED
);
962 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
963 if (reloc
->howto
== NULL
)
965 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
966 "cannot represent `%s' relocation in object file",
967 bfd_get_reloc_code_name (fixp
->fx_r_type
));
971 if (!fixp
->fx_pcrel
!= !reloc
->howto
->pc_relative
)
973 as_fatal ("internal error? cannot generate `%s' relocation",
974 bfd_get_reloc_code_name (fixp
->fx_r_type
));
976 assert (!fixp
->fx_pcrel
== !reloc
->howto
->pc_relative
);
979 if (fixp
->fx_r_type
== BFD_RELOC_ALPHA_LITERAL
)
981 /* fake out bfd_perform_relocation. sigh */
982 reloc
->addend
= -alpha_gp_value
;
987 reloc
->addend
= fixp
->fx_offset
;
990 * Ohhh, this is ugly. The problem is that if this is a local global
991 * symbol, the relocation will entirely be performed at link time, not
992 * at assembly time. bfd_perform_reloc doesn't know about this sort
993 * of thing, and as a result we need to fake it out here.
995 if (S_IS_EXTERN (fixp
->fx_addsy
) && !S_IS_COMMON(fixp
->fx_addsy
))
996 reloc
->addend
-= fixp
->fx_addsy
->bsym
->value
;
1004 tc_get_register (frame
)
1007 int framereg
= AXP_REG_SP
;
1010 if (*input_line_pointer
== '$')
1012 char *s
= input_line_pointer
;
1013 char c
= get_symbol_end();
1014 symbolS
*sym
= md_undefined_symbol(s
);
1016 *strchr(s
, '\0') = c
;
1017 if (sym
&& (framereg
= S_GET_VALUE(sym
)) <= 31)
1020 as_warn ("frame reg expected, using $%d.", framereg
);
1023 note_gpreg (framereg
);
1029 * Parse the arguments to an opcode
1033 tokenize_arguments (str
, tok
, ntok
)
1038 expressionS
*end_tok
= tok
+ ntok
;
1039 char *old_input_line_pointer
;
1040 int saw_comma
= 0, saw_arg
= 0;
1042 memset (tok
, 0, sizeof(*tok
)*ntok
);
1044 /* Save and restore input_line_pointer around this function */
1045 old_input_line_pointer
= input_line_pointer
;
1046 input_line_pointer
= str
;
1048 while (tok
< end_tok
&& *input_line_pointer
)
1051 switch (*input_line_pointer
)
1057 ++input_line_pointer
;
1058 if (saw_comma
|| !saw_arg
)
1065 char *hold
= input_line_pointer
++;
1067 /* First try for parenthesized register ... */
1069 if (*input_line_pointer
== ')' && tok
->X_op
== O_register
)
1071 tok
->X_op
= (saw_comma
? O_cpregister
: O_pregister
);
1074 ++input_line_pointer
;
1079 /* ... then fall through to plain expression */
1080 input_line_pointer
= hold
;
1084 if (saw_arg
&& !saw_comma
)
1087 if (tok
->X_op
== O_illegal
|| tok
->X_op
== O_absent
)
1100 input_line_pointer
= old_input_line_pointer
;
1101 return ntok
- (end_tok
- tok
);
1104 input_line_pointer
= old_input_line_pointer
;
1109 * Search forward through all variants of an opcode
1110 * looking for a syntax match.
1113 static const struct alpha_opcode
*
1114 find_opcode_match(first_opcode
, tok
, pntok
, pcpumatch
)
1115 const struct alpha_opcode
*first_opcode
;
1116 const expressionS
*tok
;
1120 const struct alpha_opcode
*opcode
= first_opcode
;
1122 int got_cpu_match
= 0;
1126 const unsigned char *opidx
;
1129 /* Don't match opcodes that don't exist on this architecture */
1130 if (!(opcode
->flags
& alpha_target
))
1135 for (opidx
= opcode
->operands
; *opidx
; ++opidx
)
1137 const struct alpha_operand
*operand
= &alpha_operands
[*opidx
];
1139 /* only take input from real operands */
1140 if (operand
->flags
& AXP_OPERAND_FAKE
)
1143 /* when we expect input, make sure we have it */
1146 if ((operand
->flags
& AXP_OPERAND_OPTIONAL_MASK
) == 0)
1151 /* match operand type with expression type */
1152 switch (operand
->flags
& AXP_OPERAND_TYPECHECK_MASK
)
1154 case AXP_OPERAND_IR
:
1155 if (tok
[tokidx
].X_op
!= O_register
1156 || !is_ir_num(tok
[tokidx
].X_add_number
))
1159 case AXP_OPERAND_FPR
:
1160 if (tok
[tokidx
].X_op
!= O_register
1161 || !is_fpr_num(tok
[tokidx
].X_add_number
))
1164 case AXP_OPERAND_IR
|AXP_OPERAND_PARENS
:
1165 if (tok
[tokidx
].X_op
!= O_pregister
1166 || !is_ir_num(tok
[tokidx
].X_add_number
))
1169 case AXP_OPERAND_IR
|AXP_OPERAND_PARENS
|AXP_OPERAND_COMMA
:
1170 if (tok
[tokidx
].X_op
!= O_cpregister
1171 || !is_ir_num(tok
[tokidx
].X_add_number
))
1175 case AXP_OPERAND_RELATIVE
:
1176 case AXP_OPERAND_SIGNED
:
1177 case AXP_OPERAND_UNSIGNED
:
1178 switch (tok
[tokidx
].X_op
)
1190 /* everything else should have been fake */
1196 /* possible match -- did we use all of our input? */
1205 while (++opcode
-alpha_opcodes
< alpha_num_opcodes
1206 && !strcmp(opcode
->name
, first_opcode
->name
));
1209 *pcpumatch
= got_cpu_match
;
1215 * Search forward through all variants of a macro
1216 * looking for a syntax match.
1219 static const struct alpha_macro
*
1220 find_macro_match(first_macro
, tok
, pntok
)
1221 const struct alpha_macro
*first_macro
;
1222 const expressionS
*tok
;
1225 const struct alpha_macro
*macro
= first_macro
;
1230 const enum alpha_macro_arg
*arg
= macro
->argsets
;
1245 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_register
1246 || !is_ir_num(tok
[tokidx
].X_add_number
))
1251 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_pregister
1252 || !is_ir_num(tok
[tokidx
].X_add_number
))
1257 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_cpregister
1258 || !is_ir_num(tok
[tokidx
].X_add_number
))
1263 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_register
1264 || !is_fpr_num(tok
[tokidx
].X_add_number
))
1272 switch (tok
[tokidx
].X_op
)
1285 while (*arg
!= MACRO_EOA
)
1293 while (++macro
-alpha_macros
< alpha_num_macros
1294 && !strcmp(macro
->name
, first_macro
->name
));
1300 * Insert an operand value into an instruction.
1304 insert_operand(insn
, operand
, val
, file
, line
)
1306 const struct alpha_operand
*operand
;
1311 if (operand
->bits
!= 32 && !(operand
->flags
& AXP_OPERAND_NOOVERFLOW
))
1315 if (operand
->flags
& AXP_OPERAND_SIGNED
)
1317 max
= (1 << (operand
->bits
- 1)) - 1;
1318 min
= -(1 << (operand
->bits
- 1));
1322 max
= (1 << operand
->bits
) - 1;
1326 if (val
< min
|| val
> max
)
1329 "operand out of range (%s not between %d and %d)";
1330 char buf
[sizeof(val
)*3+2];
1332 sprint_value(buf
, val
);
1334 as_warn_where(file
, line
, err
, buf
, min
, max
);
1336 as_warn(err
, buf
, min
, max
);
1340 if (operand
->insert
)
1342 const char *errmsg
= NULL
;
1344 insn
= (*operand
->insert
)(insn
, val
, &errmsg
);
1349 insn
|= ((val
& ((1 << operand
->bits
) - 1)) << operand
->shift
);
1355 * Turn an opcode description and a set of arguments into
1356 * an instruction and a fixup.
1360 assemble_insn(opcode
, tok
, ntok
, insn
)
1361 const struct alpha_opcode
*opcode
;
1362 const expressionS
*tok
;
1364 struct alpha_insn
*insn
;
1366 const unsigned char *argidx
;
1370 memset(insn
, 0, sizeof(*insn
));
1371 image
= opcode
->opcode
;
1373 for (argidx
= opcode
->operands
; *argidx
; ++argidx
)
1375 const struct alpha_operand
*operand
= &alpha_operands
[*argidx
];
1376 const expressionS
*t
;
1378 if (operand
->flags
& AXP_OPERAND_FAKE
)
1380 /* fake operands take no value and generate no fixup */
1381 image
= insert_operand(image
, operand
, 0, NULL
, 0);
1387 switch (operand
->flags
& AXP_OPERAND_OPTIONAL_MASK
)
1389 case AXP_OPERAND_DEFAULT_FIRST
:
1392 case AXP_OPERAND_DEFAULT_SECOND
:
1395 case AXP_OPERAND_DEFAULT_ZERO
:
1397 static const expressionS zero_exp
= { 0, 0, 0, O_constant
, 1 };
1413 image
= insert_operand(image
, operand
, regno(t
->X_add_number
),
1418 image
= insert_operand(image
, operand
, t
->X_add_number
, NULL
, 0);
1423 struct alpha_fixup
*fixup
;
1425 if (insn
->nfixups
>= MAX_INSN_FIXUPS
)
1426 as_fatal("too many fixups");
1428 fixup
= &insn
->fixups
[insn
->nfixups
++];
1431 fixup
->reloc
= operand
->default_reloc
;
1441 * Actually output an instruction with its fixup.
1446 struct alpha_insn
*insn
;
1451 /* Take care of alignment duties */
1452 if (alpha_auto_align_on
)
1453 alpha_align (2, (char *) NULL
, alpha_insn_label
);
1454 alpha_insn_label
= NULL
;
1456 /* Write out the instruction. */
1458 md_number_to_chars (f
, insn
->insn
, 4);
1460 /* Apply the fixups in order */
1461 for (i
= 0; i
< insn
->nfixups
; ++i
)
1463 struct alpha_fixup
*fixup
= &insn
->fixups
[i
];
1467 /* Some fixups are only used internally and so have no howto */
1468 if (fixup
->reloc
> BFD_RELOC_UNUSED
)
1469 size
= 4, pcrel
= 0;
1471 /* These relocation types are only used internally. */
1472 else if (fixup
->reloc
== BFD_RELOC_ALPHA_GPDISP_HI16
1473 || fixup
->reloc
== BFD_RELOC_ALPHA_GPDISP_LO16
)
1475 size
= 2, pcrel
= 0;
1480 reloc_howto_type
*reloc_howto
1481 = bfd_reloc_type_lookup (stdoutput
, fixup
->reloc
);
1482 assert (reloc_howto
);
1484 size
= bfd_get_reloc_size (reloc_howto
);
1485 pcrel
= reloc_howto
->pc_relative
;
1487 assert (size
>= 1 && size
<= 4);
1489 fixP
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, size
,
1490 &fixup
->exp
, pcrel
, fixup
->reloc
);
1492 /* Turn off complaints that the addend is too large for some fixups */
1493 switch (fixup
->reloc
)
1495 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1496 case BFD_RELOC_ALPHA_LITERAL
:
1497 case BFD_RELOC_GPREL32
:
1498 fixP
->fx_no_overflow
= 1;
1507 * Given an opcode name and a pre-tokenized set of arguments,
1508 * assemble the insn, but do not emit it.
1512 assemble_tokens_to_insn(opname
, tok
, ntok
, insn
)
1514 const expressionS
*tok
;
1516 struct alpha_insn
*insn
;
1518 const struct alpha_opcode
*opcode
;
1520 /* search opcodes */
1521 opcode
= (const struct alpha_opcode
*) hash_find (alpha_opcode_hash
, opname
);
1525 opcode
= find_opcode_match (opcode
, tok
, &ntok
, &cpumatch
);
1528 assemble_insn (opcode
, tok
, ntok
, insn
);
1532 as_bad ("inappropriate arguments for opcode `%s'", opname
);
1534 as_bad ("opcode `%s' not supported for target %s", opname
,
1538 as_bad ("unknown opcode `%s'", opname
);
1542 * Given an opcode name and a pre-tokenized set of arguments,
1543 * take the opcode all the way through emission.
1547 assemble_tokens (opname
, tok
, ntok
, local_macros_on
)
1549 const expressionS
*tok
;
1551 int local_macros_on
;
1553 int found_something
= 0;
1554 const struct alpha_opcode
*opcode
;
1555 const struct alpha_macro
*macro
;
1559 if (local_macros_on
)
1561 macro
= ((const struct alpha_macro
*)
1562 hash_find (alpha_macro_hash
, opname
));
1565 found_something
= 1;
1566 macro
= find_macro_match (macro
, tok
, &ntok
);
1569 (*macro
->emit
) (tok
, ntok
, macro
->arg
);
1575 /* search opcodes */
1576 opcode
= (const struct alpha_opcode
*) hash_find (alpha_opcode_hash
, opname
);
1579 found_something
= 1;
1580 opcode
= find_opcode_match (opcode
, tok
, &ntok
, &cpumatch
);
1583 struct alpha_insn insn
;
1584 assemble_insn (opcode
, tok
, ntok
, &insn
);
1590 if (found_something
)
1592 as_bad ("inappropriate arguments for opcode `%s'", opname
);
1594 as_bad ("opcode `%s' not supported for target %s", opname
,
1597 as_bad ("unknown opcode `%s'", opname
);
1601 /* Some instruction sets indexed by lg(size) */
1602 static const char * const sextX_op
[] = { "sextb", "sextw", "sextl", NULL
};
1603 static const char * const insXl_op
[] = { "insbl", "inswl", "insll", "insql" };
1604 static const char * const insXh_op
[] = { NULL
, "inswh", "inslh", "insqh" };
1605 static const char * const extXl_op
[] = { "extbl", "extwl", "extll", "extql" };
1606 static const char * const extXh_op
[] = { NULL
, "extwh", "extlh", "extqh" };
1607 static const char * const mskXl_op
[] = { "mskbl", "mskwl", "mskll", "mskql" };
1608 static const char * const mskXh_op
[] = { NULL
, "mskwh", "msklh", "mskqh" };
1611 emit_ldgp (tok
, ntok
, unused
)
1612 const expressionS
*tok
;
1619 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
1620 /* from "ldgp r1,n(r2)", generate "ldah r1,X(R2); lda r1,Y(r1)"
1621 with appropriate constants and relocations. */
1622 struct alpha_insn insn
;
1623 expressionS newtok
[3];
1626 /* We're going to need this symbol in md_apply_fix(). */
1627 (void) section_symbol (absolute_section
);
1630 if (regno (tok
[2].X_add_number
) == AXP_REG_PV
)
1631 ecoff_set_gp_prolog_size (0);
1635 set_tok_const (newtok
[1], 0);
1638 assemble_tokens_to_insn ("ldah", newtok
, 3, &insn
);
1643 assert (addend
.X_op
== O_constant
);
1644 addend
.X_op
= O_symbol
;
1645 addend
.X_add_symbol
= alpha_gp_symbol
;
1649 insn
.fixups
[0].exp
= addend
;
1650 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_GPDISP_HI16
;
1654 set_tok_preg (newtok
[2], tok
[0].X_add_number
);
1656 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
1659 addend
.X_add_number
+= 4;
1663 insn
.fixups
[0].exp
= addend
;
1664 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_GPDISP_LO16
;
1667 #endif /* OBJ_ECOFF || OBJ_ELF */
1671 load_expression (targreg
, exp
, pbasereg
, poffset
)
1673 const expressionS
*exp
;
1675 expressionS
*poffset
;
1677 int emit_lituse
= 0;
1678 offsetT addend
= exp
->X_add_number
;
1679 int basereg
= *pbasereg
;
1680 struct alpha_insn insn
;
1681 expressionS newtok
[3];
1690 /* attempt to reduce .lit load by splitting the offset from
1691 its symbol when possible, but don't create a situation in
1693 if (!range_signed_32 (addend
) &&
1694 (alpha_noat_on
|| targreg
== AXP_REG_AT
))
1696 lit
= add_to_literal_pool (exp
->X_add_symbol
, addend
,
1697 alpha_lita_section
, 8);
1702 lit
= add_to_literal_pool (exp
->X_add_symbol
, 0,
1703 alpha_lita_section
, 8);
1707 as_fatal ("overflow in literal (.lita) table");
1709 /* emit "ldq r, lit(gp)" */
1711 if (basereg
!= alpha_gp_register
&& targreg
== basereg
)
1714 as_bad ("macro requires $at register while noat in effect");
1715 if (targreg
== AXP_REG_AT
)
1716 as_bad ("macro requires $at while $at in use");
1718 set_tok_reg (newtok
[0], AXP_REG_AT
);
1721 set_tok_reg (newtok
[0], targreg
);
1722 set_tok_sym (newtok
[1], alpha_lita_symbol
, lit
);
1723 set_tok_preg (newtok
[2], alpha_gp_register
);
1725 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
1727 assert (insn
.nfixups
== 1);
1728 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITERAL
;
1729 #endif /* OBJ_ECOFF */
1731 /* emit "ldq r, gotoff(gp)" */
1733 if (basereg
!= alpha_gp_register
&& targreg
== basereg
)
1736 as_bad ("macro requires $at register while noat in effect");
1737 if (targreg
== AXP_REG_AT
)
1738 as_bad ("macro requires $at while $at in use");
1740 set_tok_reg (newtok
[0], AXP_REG_AT
);
1743 set_tok_reg (newtok
[0], targreg
);
1745 if (!range_signed_32 (addend
)
1746 && (alpha_noat_on
|| targreg
== AXP_REG_AT
))
1753 set_tok_sym (newtok
[1], exp
->X_add_symbol
, 0);
1756 set_tok_preg (newtok
[2], alpha_gp_register
);
1758 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
1760 assert (insn
.nfixups
== 1);
1761 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITERAL
;
1762 #endif /* OBJ_ELF */
1767 if (basereg
!= alpha_gp_register
&& basereg
!= AXP_REG_ZERO
)
1769 /* emit "addq r, base, r" */
1771 set_tok_reg (newtok
[1], basereg
);
1772 set_tok_reg (newtok
[2], targreg
);
1773 assemble_tokens ("addq", newtok
, 3, 0);
1784 /* Assume that this difference expression will be resolved to an
1785 absolute value and that that value will fit in 16 bits. */
1787 set_tok_reg (newtok
[0], targreg
);
1789 set_tok_preg (newtok
[2], basereg
);
1790 assemble_tokens ("lda", newtok
, 3, 0);
1793 set_tok_const (*poffset
, 0);
1800 if (!range_signed_32 (addend
))
1804 /* for 64-bit addends, just put it in the literal pool */
1806 if (alpha_lit8_section
== NULL
)
1808 create_literal_section (".lit8",
1809 &alpha_lit8_section
,
1810 &alpha_lit8_symbol
);
1813 lit
= add_to_literal_pool (NULL
, addend
, alpha_lit8_section
, 8) - 0x8000;
1815 as_fatal ("overflow in literal (.lit8) table");
1817 /* emit "ldq litreg, .lit8+lit" */
1819 if (targreg
== basereg
)
1822 as_bad ("macro requires $at register while noat in effect");
1823 if (targreg
== AXP_REG_AT
)
1824 as_bad ("macro requires $at while $at in use");
1826 set_tok_reg (newtok
[0], AXP_REG_AT
);
1829 set_tok_reg (newtok
[0], targreg
);
1830 set_tok_sym (newtok
[1], alpha_lit8_symbol
, lit
);
1832 assemble_tokens ("ldq", newtok
, 2, 1); /* note this does recurse */
1834 /* emit "addq litreg, base, target" */
1836 if (basereg
!= AXP_REG_ZERO
)
1838 set_tok_reg (newtok
[1], basereg
);
1839 set_tok_reg (newtok
[2], targreg
);
1840 assemble_tokens ("addq", newtok
, 3, 0);
1844 set_tok_const (*poffset
, 0);
1845 *pbasereg
= targreg
;
1849 offsetT low
, high
, extra
, tmp
;
1851 /* for 32-bit operands, break up the addend */
1853 low
= sign_extend_16 (addend
);
1855 high
= sign_extend_16 (tmp
>> 16);
1857 if (tmp
- (high
<< 16))
1861 high
= sign_extend_16 (tmp
>> 16);
1866 set_tok_reg (newtok
[0], targreg
);
1867 set_tok_preg (newtok
[2], basereg
);
1871 /* emit "ldah r, extra(r) */
1872 set_tok_const (newtok
[1], extra
);
1873 assemble_tokens ("ldah", newtok
, 3, 0);
1874 set_tok_preg (newtok
[2], basereg
= targreg
);
1879 /* emit "ldah r, high(r) */
1880 set_tok_const (newtok
[1], high
);
1881 assemble_tokens ("ldah", newtok
, 3, 0);
1883 set_tok_preg (newtok
[2], basereg
);
1886 if ((low
&& !poffset
) || (!poffset
&& basereg
!= targreg
))
1888 /* emit "lda r, low(base)" */
1889 set_tok_const (newtok
[1], low
);
1890 assemble_tokens ("lda", newtok
, 3, 0);
1896 set_tok_const (*poffset
, low
);
1897 *pbasereg
= basereg
;
1904 emit_lda (tok
, ntok
, unused
)
1905 const expressionS
*tok
;
1912 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
1914 basereg
= tok
[2].X_add_number
;
1916 (void) load_expression (tok
[0].X_add_number
, &tok
[1], &basereg
, NULL
);
1920 emit_ldah (tok
, ntok
, unused
)
1921 const expressionS
*tok
;
1925 expressionS newtok
[3];
1929 set_tok_preg (newtok
[2], AXP_REG_ZERO
);
1931 assemble_tokens ("ldah", newtok
, 3, 0);
1935 emit_ir_load (tok
, ntok
, opname
)
1936 const expressionS
*tok
;
1940 int basereg
, lituse
;
1941 expressionS newtok
[3];
1942 struct alpha_insn insn
;
1945 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
1947 basereg
= tok
[2].X_add_number
;
1949 lituse
= load_expression (tok
[0].X_add_number
, &tok
[1], &basereg
,
1953 set_tok_preg (newtok
[2], basereg
);
1955 assemble_tokens_to_insn ((const char *)opname
, newtok
, 3, &insn
);
1959 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
1960 if (insn
.nfixups
> 0)
1962 memmove (&insn
.fixups
[1], &insn
.fixups
[0],
1963 sizeof(struct alpha_fixup
) * insn
.nfixups
);
1966 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITUSE
;
1967 insn
.fixups
[0].exp
.X_op
= O_constant
;
1968 insn
.fixups
[0].exp
.X_add_number
= 1;
1975 emit_loadstore (tok
, ntok
, opname
)
1976 const expressionS
*tok
;
1980 int basereg
, lituse
;
1981 expressionS newtok
[3];
1982 struct alpha_insn insn
;
1985 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
1987 basereg
= tok
[2].X_add_number
;
1989 if (tok
[1].X_op
!= O_constant
|| !range_signed_16(tok
[1].X_add_number
))
1992 as_bad ("macro requires $at register while noat in effect");
1994 lituse
= load_expression (AXP_REG_AT
, &tok
[1], &basereg
, &newtok
[1]);
2003 set_tok_preg (newtok
[2], basereg
);
2005 assemble_tokens_to_insn ((const char *)opname
, newtok
, 3, &insn
);
2009 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
2010 if (insn
.nfixups
> 0)
2012 memmove (&insn
.fixups
[1], &insn
.fixups
[0],
2013 sizeof(struct alpha_fixup
) * insn
.nfixups
);
2016 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITUSE
;
2017 insn
.fixups
[0].exp
.X_op
= O_constant
;
2018 insn
.fixups
[0].exp
.X_add_number
= 1;
2025 emit_ldXu (tok
, ntok
, vlgsize
)
2026 const expressionS
*tok
;
2030 expressionS newtok
[3];
2033 as_bad ("macro requires $at register while noat in effect");
2035 /* emit "lda $at, exp" */
2037 memcpy (newtok
, tok
, sizeof(expressionS
)*ntok
);
2038 newtok
[0].X_add_number
= AXP_REG_AT
;
2039 assemble_tokens ("lda", newtok
, ntok
, 1);
2041 /* emit "ldq_u targ, 0($at)" */
2044 set_tok_const (newtok
[1], 0);
2045 set_tok_preg (newtok
[2], AXP_REG_AT
);
2046 assemble_tokens ("ldq_u", newtok
, 3, 1);
2048 /* emit "extXl targ, $at, targ" */
2050 set_tok_reg (newtok
[1], AXP_REG_AT
);
2051 newtok
[2] = newtok
[0];
2052 assemble_tokens (extXl_op
[(long)vlgsize
], newtok
, 3, 1);
2056 emit_ldX (tok
, ntok
, vlgsize
)
2057 const expressionS
*tok
;
2061 emit_ldXu (tok
, ntok
, vlgsize
);
2062 assemble_tokens (sextX_op
[(long)vlgsize
], tok
, 1, 1);
2066 emit_uldXu (tok
, ntok
, vlgsize
)
2067 const expressionS
*tok
;
2071 long lgsize
= (long)vlgsize
;
2072 expressionS newtok
[3];
2075 as_bad ("macro requires $at register while noat in effect");
2077 /* emit "lda $at, exp" */
2079 memcpy (newtok
, tok
, sizeof(expressionS
)*ntok
);
2080 newtok
[0].X_add_number
= AXP_REG_AT
;
2081 assemble_tokens ("lda", newtok
, ntok
, 1);
2083 /* emit "ldq_u $t9, 0($at)" */
2085 set_tok_reg (newtok
[0], AXP_REG_T9
);
2086 set_tok_const (newtok
[1], 0);
2087 set_tok_preg (newtok
[2], AXP_REG_AT
);
2088 assemble_tokens ("ldq_u", newtok
, 3, 1);
2090 /* emit "ldq_u $t10, size-1($at)" */
2092 set_tok_reg (newtok
[0], AXP_REG_T10
);
2093 set_tok_const (newtok
[1], (1<<lgsize
)-1);
2094 assemble_tokens ("ldq_u", newtok
, 3, 1);
2096 /* emit "extXl $t9, $at, $t9" */
2098 set_tok_reg (newtok
[0], AXP_REG_T9
);
2099 set_tok_reg (newtok
[1], AXP_REG_AT
);
2100 set_tok_reg (newtok
[2], AXP_REG_T9
);
2101 assemble_tokens (extXl_op
[lgsize
], newtok
, 3, 1);
2103 /* emit "extXh $t10, $at, $t10" */
2105 set_tok_reg (newtok
[0], AXP_REG_T10
);
2106 set_tok_reg (newtok
[2], AXP_REG_T10
);
2107 assemble_tokens (extXh_op
[lgsize
], newtok
, 3, 1);
2109 /* emit "or $t9, $t10, targ" */
2111 set_tok_reg (newtok
[0], AXP_REG_T9
);
2112 set_tok_reg (newtok
[1], AXP_REG_T10
);
2114 assemble_tokens ("or", newtok
, 3, 1);
2118 emit_uldX (tok
, ntok
, vlgsize
)
2119 const expressionS
*tok
;
2123 emit_uldXu (tok
, ntok
, vlgsize
);
2124 assemble_tokens (sextX_op
[(long)vlgsize
], tok
, 1, 1);
2128 emit_ldil (tok
, ntok
, unused
)
2129 const expressionS
*tok
;
2133 expressionS newtok
[2];
2135 memcpy (newtok
, tok
, sizeof(newtok
));
2136 newtok
[1].X_add_number
= sign_extend_32 (tok
[1].X_add_number
);
2138 assemble_tokens ("lda", newtok
, ntok
, 1);
2142 emit_stX (tok
, ntok
, vlgsize
)
2143 const expressionS
*tok
;
2146 int lgsize
= (int)(long)vlgsize
;
2147 expressionS newtok
[3];
2150 as_bad("macro requires $at register while noat in effect");
2152 /* emit "lda $at, exp" */
2154 memcpy (newtok
, tok
, sizeof(expressionS
)*ntok
);
2155 newtok
[0].X_add_number
= AXP_REG_AT
;
2156 assemble_tokens ("lda", newtok
, ntok
, 1);
2158 /* emit "ldq_u $t9, 0($at)" */
2160 set_tok_reg (newtok
[0], AXP_REG_T9
);
2161 set_tok_const (newtok
[1], 0);
2162 set_tok_preg (newtok
[2], AXP_REG_AT
);
2163 assemble_tokens ("ldq_u", newtok
, 3, 1);
2165 /* emit "insXl src, $at, $t10" */
2168 set_tok_reg (newtok
[1], AXP_REG_AT
);
2169 set_tok_reg (newtok
[2], AXP_REG_T10
);
2170 assemble_tokens (insXl_op
[lgsize
], newtok
, 3, 1);
2172 /* emit "mskXl $t9, $at, $t9" */
2174 set_tok_reg (newtok
[0], AXP_REG_T9
);
2175 newtok
[2] = newtok
[0];
2176 assemble_tokens (mskXl_op
[lgsize
], newtok
, 3, 1);
2178 /* emit "or $t9, $t10, $t9" */
2180 set_tok_reg (newtok
[1], AXP_REG_T10
);
2181 assemble_tokens ("or", newtok
, 3, 1);
2183 /* emit "stq_u $t9, 0($at) */
2185 set_tok_const (newtok
[1], 0);
2186 set_tok_preg (newtok
[2], AXP_REG_AT
);
2187 assemble_tokens ("stq_u", newtok
, 3, 1);
2191 emit_ustX (tok
, ntok
, vlgsize
)
2192 const expressionS
*tok
;
2196 int lgsize
= (int)(long)vlgsize
;
2197 expressionS newtok
[3];
2199 /* emit "lda $at, exp" */
2201 memcpy (newtok
, tok
, sizeof(expressionS
)*ntok
);
2202 newtok
[0].X_add_number
= AXP_REG_AT
;
2203 assemble_tokens ("lda", newtok
, ntok
, 1);
2205 /* emit "ldq_u $9, 0($at)" */
2207 set_tok_reg (newtok
[0], AXP_REG_T9
);
2208 set_tok_const (newtok
[1], 0);
2209 set_tok_preg (newtok
[2], AXP_REG_AT
);
2210 assemble_tokens ("ldq_u", newtok
, 3, 1);
2212 /* emit "ldq_u $10, size-1($at)" */
2214 set_tok_reg (newtok
[0], AXP_REG_T10
);
2215 set_tok_const (newtok
[1], (1 << lgsize
)-1);
2216 assemble_tokens ("ldq_u", newtok
, 3, 1);
2218 /* emit "insXl src, $at, $t11" */
2221 set_tok_reg (newtok
[1], AXP_REG_AT
);
2222 set_tok_reg (newtok
[2], AXP_REG_T11
);
2223 assemble_tokens (insXl_op
[lgsize
], newtok
, 3, 1);
2225 /* emit "insXh src, $at, $t12" */
2227 set_tok_reg (newtok
[2], AXP_REG_T12
);
2228 assemble_tokens (insXh_op
[lgsize
], newtok
, 3, 1);
2230 /* emit "mskXl $t9, $at, $t9" */
2232 set_tok_reg (newtok
[0], AXP_REG_T9
);
2233 newtok
[2] = newtok
[0];
2234 assemble_tokens (mskXl_op
[lgsize
], newtok
, 3, 1);
2236 /* emit "mskXh $t10, $at, $t10" */
2238 set_tok_reg (newtok
[0], AXP_REG_T10
);
2239 newtok
[2] = newtok
[0];
2240 assemble_tokens (mskXh_op
[lgsize
], newtok
, 3, 1);
2242 /* emit "or $t9, $t11, $t9" */
2244 set_tok_reg (newtok
[0], AXP_REG_T9
);
2245 set_tok_reg (newtok
[1], AXP_REG_T11
);
2246 newtok
[2] = newtok
[0];
2247 assemble_tokens ("or", newtok
, 3, 1);
2249 /* emit "or $t10, $t12, $t10" */
2251 set_tok_reg (newtok
[0], AXP_REG_T10
);
2252 set_tok_reg (newtok
[1], AXP_REG_T12
);
2253 newtok
[2] = newtok
[0];
2254 assemble_tokens ("or", newtok
, 3, 1);
2256 /* emit "stq_u $t9, 0($at)" */
2258 set_tok_reg (newtok
[0], AXP_REG_T9
);
2259 set_tok_const (newtok
[1], 0);
2260 set_tok_preg (newtok
[2], AXP_REG_AT
);
2261 assemble_tokens ("stq_u", newtok
, 3, 1);
2263 /* emit "stq_u $t10, size-1($at)" */
2265 set_tok_reg (newtok
[0], AXP_REG_T10
);
2266 set_tok_const (newtok
[1], (1 << lgsize
)-1);
2267 assemble_tokens ("stq_u", newtok
, 3, 1);
2271 emit_sextX (tok
, ntok
, vlgsize
)
2272 const expressionS
*tok
;
2276 int bitshift
= 64 - 8*(1 << (long)vlgsize
);
2277 expressionS newtok
[3];
2279 /* emit "sll src,bits,dst" */
2282 set_tok_const (newtok
[1], bitshift
);
2283 newtok
[2] = tok
[ntok
- 1];
2284 assemble_tokens ("sll", newtok
, 3, 1);
2286 /* emit "sra dst,bits,dst" */
2288 newtok
[0] = newtok
[2];
2289 assemble_tokens ("sra", newtok
, 3, 1);
2293 emit_division (tok
, ntok
, symname
)
2294 const expressionS
*tok
;
2298 /* DIVISION and MODULUS. Yech.
2308 * with appropriate optimizations if t10,t11,t12 are the registers
2309 * specified by the compiler.
2314 expressionS newtok
[3];
2316 xr
= regno (tok
[0].X_add_number
);
2317 yr
= regno (tok
[1].X_add_number
);
2322 rr
= regno (tok
[2].X_add_number
);
2324 sym
= symbol_find_or_make ((const char *)symname
);
2326 /* Move the operands into the right place */
2327 if (yr
== AXP_REG_T10
&& xr
== AXP_REG_T11
)
2329 /* They are in exactly the wrong order -- swap through AT */
2332 as_bad ("macro requires $at register while noat in effect");
2334 set_tok_reg (newtok
[0], AXP_REG_T10
);
2335 set_tok_reg (newtok
[1], AXP_REG_AT
);
2336 assemble_tokens ("mov", newtok
, 2, 1);
2338 set_tok_reg (newtok
[0], AXP_REG_T11
);
2339 set_tok_reg (newtok
[1], AXP_REG_T10
);
2340 assemble_tokens ("mov", newtok
, 2, 1);
2342 set_tok_reg (newtok
[0], AXP_REG_AT
);
2343 set_tok_reg (newtok
[1], AXP_REG_T11
);
2344 assemble_tokens ("mov", newtok
, 2, 1);
2348 if (yr
== AXP_REG_T10
)
2350 set_tok_reg (newtok
[0], AXP_REG_T10
);
2351 set_tok_reg (newtok
[1], AXP_REG_T11
);
2352 assemble_tokens ("mov", newtok
, 2, 1);
2355 if (xr
!= AXP_REG_T10
)
2357 set_tok_reg (newtok
[0], xr
);
2358 set_tok_reg (newtok
[1], AXP_REG_T10
);
2359 assemble_tokens ("mov", newtok
, 2, 1);
2362 if (yr
!= AXP_REG_T10
&& yr
!= AXP_REG_T11
)
2364 set_tok_reg (newtok
[0], yr
);
2365 set_tok_reg (newtok
[1], AXP_REG_T11
);
2366 assemble_tokens ("mov", newtok
, 2, 1);
2370 /* Call the division routine */
2371 set_tok_reg (newtok
[0], AXP_REG_T9
);
2372 set_tok_sym (newtok
[1], sym
, 0);
2373 assemble_tokens ("jsr", newtok
, 2, 1);
2375 /* Reload the GP register */
2379 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
2380 set_tok_reg (newtok
[0], alpha_gp_register
);
2381 set_tok_const (newtok
[1], 0);
2382 set_tok_preg (newtok
[2], AXP_REG_T9
);
2383 assemble_tokens ("ldgp", newtok
, 3, 1);
2386 /* Move the result to the right place */
2387 if (rr
!= AXP_REG_T12
)
2389 set_tok_reg (newtok
[0], AXP_REG_T12
);
2390 set_tok_reg (newtok
[1], rr
);
2391 assemble_tokens ("mov", newtok
, 2, 1);
2396 emit_jsrjmp (tok
, ntok
, vopname
)
2397 const expressionS
*tok
;
2401 const char *opname
= (const char *) vopname
;
2402 struct alpha_insn insn
;
2403 expressionS newtok
[3];
2404 int r
, tokidx
= 0, lituse
= 0;
2406 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_register
)
2407 r
= regno (tok
[tokidx
++].X_add_number
);
2409 r
= strcmp (opname
, "jmp") == 0 ? AXP_REG_ZERO
: AXP_REG_RA
;
2411 set_tok_reg (newtok
[0], r
);
2413 if (tokidx
< ntok
&&
2414 (tok
[tokidx
].X_op
== O_pregister
|| tok
[tokidx
].X_op
== O_cpregister
))
2415 r
= regno (tok
[tokidx
++].X_add_number
);
2418 int basereg
= alpha_gp_register
;
2419 lituse
= load_expression (r
= AXP_REG_PV
, &tok
[tokidx
], &basereg
, NULL
);
2422 set_tok_cpreg (newtok
[1], r
);
2425 newtok
[2] = tok
[tokidx
];
2427 set_tok_const (newtok
[2], 0);
2429 assemble_tokens_to_insn (opname
, newtok
, 3, &insn
);
2431 /* add the LITUSE fixup */
2434 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
2435 if (insn
.nfixups
> 0)
2437 memmove (&insn
.fixups
[1], &insn
.fixups
[0],
2438 sizeof(struct alpha_fixup
) * insn
.nfixups
);
2441 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITUSE
;
2442 insn
.fixups
[0].exp
.X_op
= O_constant
;
2443 insn
.fixups
[0].exp
.X_add_number
= 3;
2450 emit_retjcr (tok
, ntok
, vopname
)
2451 const expressionS
*tok
;
2455 const char *opname
= (const char *)vopname
;
2456 expressionS newtok
[3];
2459 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_register
)
2460 r
= regno (tok
[tokidx
++].X_add_number
);
2464 set_tok_reg (newtok
[0], r
);
2466 if (tokidx
< ntok
&&
2467 (tok
[tokidx
].X_op
== O_pregister
|| tok
[tokidx
].X_op
== O_cpregister
))
2468 r
= regno (tok
[tokidx
++].X_add_number
);
2472 set_tok_cpreg (newtok
[1], r
);
2475 newtok
[2] = tok
[tokidx
];
2477 set_tok_const (newtok
[2], strcmp(opname
, "ret") == 0);
2479 assemble_tokens (opname
, newtok
, 3, 0);
2482 /* Assembler directives */
2485 * Handle the .text pseudo-op. This is like the usual one, but it
2486 * clears alpha_insn_label and restores auto alignment.
2495 alpha_insn_label
= NULL
;
2496 alpha_auto_align_on
= 1;
2500 * Handle the .data pseudo-op. This is like the usual one, but it
2501 * clears alpha_insn_label and restores auto alignment.
2509 alpha_insn_label
= NULL
;
2510 alpha_auto_align_on
= 1;
2516 s_alpha_comm (ignore
)
2519 register char *name
;
2523 register symbolS
*symbolP
;
2525 name
= input_line_pointer
;
2526 c
= get_symbol_end ();
2528 /* just after name is now '\0' */
2529 p
= input_line_pointer
;
2534 /* Alpha OSF/1 compiler doesn't provide the comma, gcc does. */
2535 if (*input_line_pointer
== ',')
2537 input_line_pointer
++;
2540 if ((temp
= get_absolute_expression ()) < 0)
2542 as_warn (".COMMon length (%ld.) <0! Ignored.", (long) temp
);
2543 ignore_rest_of_line ();
2548 symbolP
= symbol_find_or_make (name
);
2551 if (S_IS_DEFINED (symbolP
))
2553 as_bad ("Ignoring attempt to re-define symbol");
2554 ignore_rest_of_line ();
2557 if (S_GET_VALUE (symbolP
))
2559 if (S_GET_VALUE (symbolP
) != (valueT
) temp
)
2560 as_bad ("Length of .comm \"%s\" is already %ld. Not changed to %ld.",
2561 S_GET_NAME (symbolP
),
2562 (long) S_GET_VALUE (symbolP
),
2567 S_SET_VALUE (symbolP
, (valueT
) temp
);
2568 S_SET_EXTERNAL (symbolP
);
2571 know (symbolP
->sy_frag
== &zero_address_frag
);
2572 demand_empty_rest_of_line ();
2578 s_alpha_rdata (ignore
)
2583 temp
= get_absolute_expression ();
2584 subseg_new (".rdata", 0);
2585 demand_empty_rest_of_line ();
2586 alpha_insn_label
= NULL
;
2587 alpha_auto_align_on
= 1;
2591 s_alpha_sdata (ignore
)
2596 temp
= get_absolute_expression ();
2597 subseg_new (".sdata", 0);
2598 demand_empty_rest_of_line ();
2599 alpha_insn_label
= NULL
;
2600 alpha_auto_align_on
= 1;
2604 s_alpha_gprel32 (ignore
)
2617 e
.X_add_symbol
= section_symbol(absolute_section
);
2629 e
.X_add_symbol
= section_symbol (absolute_section
);
2632 e
.X_op
= O_subtract
;
2633 e
.X_op_symbol
= alpha_gp_symbol
;
2640 if (alpha_auto_align_on
)
2641 alpha_align (2, (char *) NULL
, alpha_insn_label
);
2642 alpha_insn_label
= NULL
;
2646 fix_new_exp (frag_now
, p
-frag_now
->fr_literal
, 4,
2647 &e
, 0, BFD_RELOC_GPREL32
);
2651 * Handle floating point allocation pseudo-ops. This is like the
2652 * generic vresion, but it makes sure the current label, if any, is
2653 * correctly aligned.
2657 s_alpha_float_cons (type
)
2660 if (alpha_auto_align_on
)
2686 alpha_align (log_size
, (char *) NULL
, alpha_insn_label
);
2689 alpha_insn_label
= NULL
;
2694 s_alpha_proc (is_static
)
2697 /* XXXX Align to cache linesize XXXXX */
2704 /* Takes ".proc name,nargs" */
2705 name
= input_line_pointer
;
2706 c
= get_symbol_end ();
2707 p
= input_line_pointer
;
2708 symbolP
= symbol_find_or_make (name
);
2711 if (*input_line_pointer
!= ',')
2714 as_warn ("Expected comma after name \"%s\"", name
);
2717 ignore_rest_of_line ();
2721 input_line_pointer
++;
2722 temp
= get_absolute_expression ();
2724 /* symbolP->sy_other = (signed char) temp; */
2725 as_warn ("unhandled: .proc %s,%d", name
, temp
);
2726 demand_empty_rest_of_line ();
2733 char *name
= input_line_pointer
, ch
, *s
;
2736 while (!is_end_of_line
[(unsigned char) *input_line_pointer
])
2737 input_line_pointer
++;
2738 ch
= *input_line_pointer
;
2739 *input_line_pointer
= '\0';
2742 if (s
[0] == 'n' && s
[1] == 'o')
2747 if (!strcmp ("reorder", s
))
2749 else if (!strcmp ("at", s
))
2750 alpha_noat_on
= !yesno
;
2751 else if (!strcmp ("macro", s
))
2752 alpha_macros_on
= yesno
;
2753 else if (!strcmp ("move", s
))
2755 else if (!strcmp ("volatile", s
))
2758 as_warn ("Tried to .set unrecognized mode `%s'", name
);
2760 *input_line_pointer
= ch
;
2761 demand_empty_rest_of_line ();
2765 s_alpha_base (ignore
)
2769 if (first_32bit_quadrant
)
2771 /* not fatal, but it might not work in the end */
2772 as_warn ("File overrides no-base-register option.");
2773 first_32bit_quadrant
= 0;
2778 if (*input_line_pointer
== '$')
2780 input_line_pointer
++;
2781 if (*input_line_pointer
== 'r')
2782 input_line_pointer
++;
2785 alpha_gp_register
= get_absolute_expression ();
2786 if (alpha_gp_register
< 0 || alpha_gp_register
> 31)
2788 alpha_gp_register
= AXP_REG_GP
;
2789 as_warn ("Bad base register, using $%d.", alpha_gp_register
);
2792 demand_empty_rest_of_line ();
2796 * Handle the .align pseudo-op. This aligns to a power of two. It
2797 * also adjusts any current instruction label. We treat this the same
2798 * way the MIPS port does: .align 0 turns off auto alignment.
2802 s_alpha_align (ignore
)
2807 long max_alignment
= 15;
2809 align
= get_absolute_expression ();
2810 if (align
> max_alignment
)
2812 align
= max_alignment
;
2813 as_bad ("Alignment too large: %d. assumed", align
);
2817 as_warn ("Alignment negative: 0 assumed");
2821 if (*input_line_pointer
== ',')
2823 input_line_pointer
++;
2824 fill
= get_absolute_expression ();
2832 alpha_auto_align_on
= 1;
2833 alpha_align (align
, pfill
, alpha_insn_label
);
2837 alpha_auto_align_on
= 0;
2840 demand_empty_rest_of_line ();
2844 * Handle data allocation pseudo-ops. This is like the generic
2845 * version, but it makes sure the current label, if any, is correctly
2850 s_alpha_cons (log_size
)
2853 if (alpha_auto_align_on
&& log_size
> 0)
2854 alpha_align (log_size
, (char *) NULL
, alpha_insn_label
);
2855 alpha_insn_label
= NULL
;
2856 cons (1 << log_size
);
2860 /* The macro table */
2862 const struct alpha_macro alpha_macros
[] = {
2863 /* Load/Store macros */
2864 { "lda", emit_lda
, NULL
,
2865 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
2866 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
2867 { "ldah", emit_ldah
, NULL
,
2868 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
2870 { "ldl", emit_ir_load
, "ldl",
2871 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
2872 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
2873 { "ldl_l", emit_ir_load
, "ldl_l",
2874 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
2875 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
2876 { "ldq", emit_ir_load
, "ldq",
2877 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
2878 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
2879 { "ldq_l", emit_ir_load
, "ldq_l",
2880 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
2881 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
2882 { "ldq_u", emit_ir_load
, "ldq_u",
2883 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
2884 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
2885 { "ldf", emit_loadstore
, "ldf",
2886 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
2887 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
2888 { "ldg", emit_loadstore
, "ldg",
2889 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
2890 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
2891 { "lds", emit_loadstore
, "lds",
2892 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
2893 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
2894 { "ldt", emit_loadstore
, "ldt",
2895 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
2896 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
2898 { "ldb", emit_ldX
, (void *)0,
2899 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
2900 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
2901 { "ldbu", emit_ldXu
, (void *)0,
2902 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
2903 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
2904 { "ldw", emit_ldX
, (void *)1,
2905 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
2906 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
2907 { "ldwu", emit_ldXu
, (void *)1,
2908 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
2909 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
2911 { "uldw", emit_uldX
, (void*)1,
2912 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
2913 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
2914 { "uldwu", emit_uldXu
, (void*)1,
2915 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
2916 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
2917 { "uldl", emit_uldX
, (void*)2,
2918 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
2919 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
2920 { "uldlu", emit_uldXu
, (void*)2,
2921 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
2922 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
2923 { "uldq", emit_uldXu
, (void*)3,
2924 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
2925 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
2927 { "ldgp", emit_ldgp
, NULL
,
2928 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
} },
2930 { "ldi", emit_lda
, NULL
,
2931 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
2932 { "ldil", emit_ldil
, NULL
,
2933 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
2934 { "ldiq", emit_lda
, NULL
,
2935 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
2937 { "ldif" emit_ldiq
, NULL
,
2938 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
2939 { "ldid" emit_ldiq
, NULL
,
2940 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
2941 { "ldig" emit_ldiq
, NULL
,
2942 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
2943 { "ldis" emit_ldiq
, NULL
,
2944 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
2945 { "ldit" emit_ldiq
, NULL
,
2946 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
2949 { "stl", emit_loadstore
, "stl",
2950 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
2951 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
2952 { "stl_c", emit_loadstore
, "stl_c",
2953 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
2954 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
2955 { "stq", emit_loadstore
, "stq",
2956 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
2957 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
2958 { "stq_c", emit_loadstore
, "stq_c",
2959 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
2960 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
2961 { "stq_u", emit_loadstore
, "stq_u",
2962 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
2963 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
2964 { "stf", emit_loadstore
, "stf",
2965 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
2966 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
2967 { "stg", emit_loadstore
, "stg",
2968 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
2969 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
2970 { "sts", emit_loadstore
, "sts",
2971 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
2972 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
2973 { "stt", emit_loadstore
, "stt",
2974 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
2975 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
2977 { "stb", emit_stX
, (void*)0,
2978 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
2979 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
2980 { "stw", emit_stX
, (void*)1,
2981 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
2982 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
2983 { "ustw", emit_ustX
, (void*)1,
2984 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
2985 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
2986 { "ustl", emit_ustX
, (void*)2,
2987 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
2988 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
2989 { "ustq", emit_ustX
, (void*)3,
2990 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
2991 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
2993 /* Arithmetic macros */
2995 { "absl" emit_absl
, 1, { IR
} },
2996 { "absl" emit_absl
, 2, { IR
, IR
} },
2997 { "absl" emit_absl
, 2, { EXP
, IR
} },
2998 { "absq" emit_absq
, 1, { IR
} },
2999 { "absq" emit_absq
, 2, { IR
, IR
} },
3000 { "absq" emit_absq
, 2, { EXP
, IR
} },
3003 { "sextb", emit_sextX
, (void *)0,
3004 { MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3005 MACRO_IR
, MACRO_EOA
,
3006 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
3007 { "sextw", emit_sextX
, (void *)1,
3008 { MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3009 MACRO_IR
, MACRO_EOA
,
3010 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
3012 { "divl", emit_division
, "__divl",
3013 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3014 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3015 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
3016 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
3017 { "divlu", emit_division
, "__divlu",
3018 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3019 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3020 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
3021 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
3022 { "divq", emit_division
, "__divq",
3023 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3024 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3025 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
3026 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
3027 { "divqu", emit_division
, "__divqu",
3028 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3029 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3030 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
3031 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
3032 { "reml", emit_division
, "__reml",
3033 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3034 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3035 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
3036 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
3037 { "remlu", emit_division
, "__remlu",
3038 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3039 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3040 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
3041 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
3042 { "remq", emit_division
, "__remq",
3043 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3044 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3045 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
3046 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
3047 { "remqu", emit_division
, "__remqu",
3048 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3049 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3050 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
3051 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
3053 { "jsr", emit_jsrjmp
, "jsr",
3054 { MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
3055 MACRO_PIR
, MACRO_EOA
,
3056 MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
3057 MACRO_EXP
, MACRO_EOA
} },
3058 { "jmp", emit_jsrjmp
, "jmp",
3059 { MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
3060 MACRO_PIR
, MACRO_EOA
,
3061 MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
3062 MACRO_EXP
, MACRO_EOA
} },
3063 { "ret", emit_retjcr
, "ret",
3064 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
3065 MACRO_IR
, MACRO_EOA
,
3066 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
3067 MACRO_PIR
, MACRO_EOA
,
3068 MACRO_EXP
, MACRO_EOA
,
3070 { "jcr", emit_retjcr
, "jcr",
3071 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
3072 MACRO_IR
, MACRO_EOA
,
3073 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
3074 MACRO_PIR
, MACRO_EOA
,
3075 MACRO_EXP
, MACRO_EOA
,
3077 { "jsr_coroutine", emit_retjcr
, "jcr",
3078 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
3079 MACRO_IR
, MACRO_EOA
,
3080 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
3081 MACRO_PIR
, MACRO_EOA
,
3082 MACRO_EXP
, MACRO_EOA
,
3086 static const int alpha_num_macros
3087 = sizeof(alpha_macros
) / sizeof(*alpha_macros
);
3089 /* The target specific pseudo-ops which we support. */
3091 const pseudo_typeS md_pseudo_table
[] =
3093 {"common", s_comm
, 0}, /* is this used? */
3095 {"comm", s_alpha_comm
, 0}, /* osf1 compiler does this */
3097 {"text", s_alpha_text
, 0},
3098 {"data", s_alpha_data
, 0},
3099 {"rdata", s_alpha_rdata
, 0},
3100 {"sdata", s_alpha_sdata
, 0},
3101 {"gprel32", s_alpha_gprel32
, 0},
3102 {"t_floating", s_alpha_float_cons
, 'd'},
3103 {"s_floating", s_alpha_float_cons
, 'f'},
3104 {"f_floating", s_alpha_float_cons
, 'F'},
3105 {"g_floating", s_alpha_float_cons
, 'G'},
3106 {"d_floating", s_alpha_float_cons
, 'D'},
3108 {"proc", s_alpha_proc
, 0},
3109 {"aproc", s_alpha_proc
, 1},
3110 {"set", s_alpha_set
, 0},
3111 {"reguse", s_ignore
, 0},
3112 {"livereg", s_ignore
, 0},
3113 {"base", s_alpha_base
, 0}, /*??*/
3114 {"option", s_ignore
, 0},
3115 {"prologue", s_ignore
, 0},
3116 {"aent", s_ignore
, 0},
3117 {"ugen", s_ignore
, 0},
3118 {"eflag", s_ignore
, 0},
3120 {"align", s_alpha_align
, 0},
3121 {"byte", s_alpha_cons
, 0},
3122 {"hword", s_alpha_cons
, 1},
3123 {"int", s_alpha_cons
, 2},
3124 {"long", s_alpha_cons
, 2},
3125 {"octa", s_alpha_cons
, 4},
3126 {"quad", s_alpha_cons
, 3},
3127 {"short", s_alpha_cons
, 1},
3128 {"word", s_alpha_cons
, 1},
3129 {"double", s_alpha_float_cons
, 'd'},
3130 {"float", s_alpha_float_cons
, 'f'},
3131 {"single", s_alpha_float_cons
, 'f'},
3133 /* We don't do any optimizing, so we can safely ignore these. */
3134 {"noalias", s_ignore
, 0},
3135 {"alias", s_ignore
, 0},
3143 create_literal_section (name
, secp
, symp
)
3148 segT current_section
= now_seg
;
3149 int current_subsec
= now_subseg
;
3152 *secp
= new_sec
= subseg_new (name
, 0);
3153 subseg_set (current_section
, current_subsec
);
3154 bfd_set_section_alignment (stdoutput
, new_sec
, 4);
3155 bfd_set_section_flags (stdoutput
, new_sec
,
3156 SEC_RELOC
| SEC_ALLOC
| SEC_LOAD
| SEC_READONLY
3159 S_CLEAR_EXTERNAL (*symp
= section_symbol (new_sec
));
3171 vma
= bfd_get_section_vma (foo
, sec
);
3172 if (vma
&& vma
< alpha_gp_value
)
3173 alpha_gp_value
= vma
;
3179 assert (alpha_gp_value
== 0);
3181 /* Get minus-one in whatever width... */
3182 alpha_gp_value
= 0; alpha_gp_value
--;
3184 /* Select the smallest VMA of these existing sections. */
3185 maybe_set_gp (alpha_lita_section
);
3186 /* maybe_set_gp (sdata); Was disabled before -- should we use it? */
3188 maybe_set_gp (lit8_sec
);
3189 maybe_set_gp (lit4_sec
);
3192 /* @@ Will a simple 0x8000 work here? If not, why not? */
3193 #define GP_ADJUSTMENT (0x8000 - 0x10)
3195 alpha_gp_value
+= GP_ADJUSTMENT
;
3197 S_SET_VALUE (alpha_gp_symbol
, alpha_gp_value
);
3200 printf ("Chose GP value of %lx\n", alpha_gp_value
);
3203 #endif /* !OBJ_ELF */
3206 alpha_align (n
, pfill
, label
)
3214 && (bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
) != 0)
3216 static char const nop
[4] = { 0x1f, 0x04, 0xff, 0x47 };
3218 /* First, make sure we're on a four-byte boundary, in case
3219 someone has been putting .byte values into the text
3220 section. The DEC assembler silently fills with unaligned
3221 no-op instructions. This will zero-fill, then nop-fill
3222 with proper alignment. */
3224 frag_align_pattern (n
, nop
, sizeof nop
);
3230 frag_align (n
, *pfill
);
3234 assert (S_GET_SEGMENT (label
) == now_seg
);
3235 label
->sy_frag
= frag_now
;
3236 S_SET_VALUE (label
, (valueT
) frag_now_fix ());
3239 record_alignment(now_seg
, n
);
3242 /* The Alpha has support for some VAX floating point types, as well as for
3243 IEEE floating point. We consider IEEE to be the primary floating point
3244 format, and sneak in the VAX floating point support here. */
3245 #define md_atof vax_md_atof
3246 #include "config/atof-vax.c"