1 /* tc-alpha.c - Processor-specific code for the DEC Alpha CPU.
2 Copyright (C) 1989, 1993, 1994 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.
7 This file is part of GAS, the GNU Assembler.
9 GAS is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2, or (at your option)
14 GAS is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GAS; see the file COPYING. If not, write to
21 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
24 * Mach Operating System
25 * Copyright (c) 1993 Carnegie Mellon University
26 * All Rights Reserved.
28 * Permission to use, copy, modify and distribute this software and its
29 * documentation is hereby granted, provided that both the copyright
30 * notice and this permission notice appear in all copies of the
31 * software, derivative works or modified versions, and any portions
32 * thereof, and that both notices appear in supporting documentation.
34 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
35 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
36 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
38 * Carnegie Mellon requests users of this software to return to
40 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
41 * School of Computer Science
42 * Carnegie Mellon University
43 * Pittsburgh PA 15213-3890
45 * any improvements or extensions that they make and grant Carnegie the
46 * rights to redistribute these changes.
50 * 5-Oct-93 Alessandro Forin (af) at Carnegie-Mellon University
53 * Author: Alessandro Forin, Carnegie Mellon University
60 #include "alpha-opcode.h"
63 /* @@ Will a simple 0x8000 work here? If not, why not? */
64 #define GP_ADJUSTMENT (0x8000 - 0x10)
66 /* These are exported to relaxing code, even though we don't do any
67 relaxing on this processor currently. */
68 int md_short_jump_size
= 4;
69 int md_long_jump_size
= 4;
71 /* handle of the OPCODE hash table */
72 static struct hash_control
*op_hash
;
74 /* Sections and symbols we'll want to keep track of. */
75 static segT lita_sec
, rdata
, sdata
, lit8_sec
, lit4_sec
;
76 static symbolS
*lit8_sym
, *lit4_sym
;
78 /* Setting for ".set [no]{at,macro}". */
79 static int at_ok
= 1, macro_ok
= 1;
81 /* Keep track of global pointer. */
82 valueT alpha_gp_value
;
85 /* We'll probably be using this relocation frequently, and we
86 will want to compare for it. */
87 static reloc_howto_type
*gpdisp_hi16_howto
;
89 /* These are exported to ECOFF code. */
90 unsigned long alpha_gprmask
, alpha_fprmask
;
92 /* Used for LITUSE relocations. */
93 static expressionS lituse_basereg
, lituse_byteoff
, lituse_jsr
;
95 /* Address size: In OSF/1 1.3, an undocumented "-32addr" option will
96 cause all addresses to be treated as 32-bit values in memory. (The
97 in-register versions are all sign-extended to 64 bits, of course.)
98 Some other systems may want this option too. */
101 /* Symbol labelling the current insn. When the Alpha gas sees
104 and the section happens to not be on an eight byte boundary, it
105 will align both the symbol and the .quad to an eight byte boundary. */
106 static symbolS
*insn_label
;
108 /* Whether we should automatically align data generation pseudo-ops.
109 .align 0 will turn this off. */
110 static int auto_align
= 1;
112 /* Imported functions -- they should be defined in header files somewhere. */
113 extern segT
subseg_get ();
114 extern PTR
bfd_alloc_by_size_t ();
115 extern void s_globl (), s_long (), s_short (), s_space (), cons (), s_text (),
116 s_data (), float_cons ();
118 /* Static functions, needing forward declarations. */
119 static void s_base (), s_proc (), s_alpha_set ();
120 static void s_gprel32 (), s_rdata (), s_sdata (), s_alpha_comm ();
121 static void s_alpha_text
PARAMS ((int));
122 static void s_alpha_data
PARAMS ((int));
123 static void s_alpha_align
PARAMS ((int));
124 static void s_alpha_cons
PARAMS ((int));
125 static void s_alpha_float_cons
PARAMS ((int));
126 static int alpha_ip ();
128 static void emit_unaligned_io
PARAMS ((char *, int, valueT
, int));
129 static void emit_load_unal
PARAMS ((int, valueT
, int));
130 static void emit_store_unal
PARAMS ((int, valueT
, int));
131 static void emit_byte_manip_r
PARAMS ((char *, int, int, int, int, int));
132 static void emit_extract_r
PARAMS ((int, int, int, int, int));
133 static void emit_insert_r
PARAMS ((int, int, int, int, int));
134 static void emit_mask_r
PARAMS ((int, int, int, int, int));
135 static void emit_sign_extend
PARAMS ((int, int));
136 static void emit_bis_r
PARAMS ((int, int, int));
137 static int build_mem
PARAMS ((int, int, int, bfd_signed_vma
));
138 static int build_operate_n
PARAMS ((int, int, int, int, int));
139 static void emit_sll_n
PARAMS ((int, int, int));
140 static void emit_ldah_num
PARAMS ((int, bfd_vma
, int));
141 static void emit_addq_r
PARAMS ((int, int, int));
142 static void emit_lda_n
PARAMS ((int, bfd_vma
, int));
143 static void emit_add64
PARAMS ((int, int, bfd_vma
));
144 static int in_range_signed
PARAMS ((bfd_vma
, int));
145 static void alpha_align
PARAMS ((int, int, symbolS
*));
147 const pseudo_typeS md_pseudo_table
[] =
149 {"common", s_comm
, 0}, /* is this used? */
150 {"comm", s_alpha_comm
, 0}, /* osf1 compiler does this */
151 {"text", s_alpha_text
, 0},
152 {"data", s_alpha_data
, 0},
153 {"rdata", s_rdata
, 0},
154 {"sdata", s_sdata
, 0},
155 {"gprel32", s_gprel32
, 0},
156 {"t_floating", s_alpha_float_cons
, 'd'},
157 {"s_floating", s_alpha_float_cons
, 'f'},
158 {"f_floating", s_alpha_float_cons
, 'F'},
159 {"g_floating", s_alpha_float_cons
, 'G'},
160 {"d_floating", s_alpha_float_cons
, 'D'},
163 {"aproc", s_proc
, 1},
164 {"set", s_alpha_set
, 0},
165 {"reguse", s_ignore
, 0},
166 {"livereg", s_ignore
, 0},
167 {"extern", s_ignore
, 0}, /*??*/
168 {"base", s_base
, 0}, /*??*/
169 {"option", s_ignore
, 0},
170 {"prologue", s_ignore
, 0},
171 {"aent", s_ignore
, 0},
172 {"ugen", s_ignore
, 0},
174 {"align", s_alpha_align
, 0},
175 {"byte", s_alpha_cons
, 0},
176 {"hword", s_alpha_cons
, 1},
177 {"int", s_alpha_cons
, 2},
178 {"long", s_alpha_cons
, 2},
179 {"octa", s_alpha_cons
, 4},
180 {"quad", s_alpha_cons
, 3},
181 {"short", s_alpha_cons
, 1},
182 {"word", s_alpha_cons
, 1},
183 {"double", s_alpha_float_cons
, 'd'},
184 {"float", s_alpha_float_cons
, 'f'},
185 {"single", s_alpha_float_cons
, 'f'},
187 /* We don't do any optimizing, so we can safely ignore these. */
188 {"noalias", s_ignore
, 0},
189 {"alias", s_ignore
, 0},
194 #define SA 21 /* shift for register Ra */
195 #define SB 16 /* shift for register Rb */
196 #define SC 0 /* shift for register Rc */
197 #define SN 13 /* shift for 8 bit immediate # */
203 #define RA 26 /* note: same as T12 */
210 #define OPCODE(X) (((X) >> 26) & 0x3f)
211 #define OP_FCN(X) (((X) >> 5) & 0x7f)
213 #ifndef FIRST_32BIT_QUADRANT
214 #define FIRST_32BIT_QUADRANT 0
217 int first_32bit_quadrant
= FIRST_32BIT_QUADRANT
;
218 int base_register
= FIRST_32BIT_QUADRANT
? ZERO
: GP
;
220 int no_mixed_code
= 0;
223 /* This array holds the chars that always start a comment. If the
224 pre-processor is disabled, these aren't very useful */
225 const char comment_chars
[] = "#";
227 /* This array holds the chars that only start a comment at the beginning of
228 a line. If the line seems to have the form '# 123 filename'
229 .line and .file directives will appear in the pre-processed output */
230 /* Note that input_file.c hand checks for '#' at the beginning of the
231 first line of the input file. This is because the compiler outputs
232 #NO_APP at the beginning of its output. */
233 /* Also note that C style comments are always recognized. */
234 const char line_comment_chars
[] = "#!";
236 /* Chars that can be used to separate mant from exp in floating point nums */
237 const char EXP_CHARS
[] = "eE";
239 const char line_separator_chars
[1];
241 /* Chars that mean this number is a floating point constant, as in
242 "0f12.456" or "0d1.2345e12". */
243 /* @@ Do all of these really get used on the alpha?? */
244 char FLT_CHARS
[] = "rRsSfFdDxXpP";
246 /* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
247 changed in read.c. Ideally it shouldn't have to know about it at all,
248 but nothing is ideal around here. */
253 bfd_reloc_code_real_type code
;
256 /* Occasionally, two relocations will be desired for one address.
257 Mainly only in cases like "jsr $r,foo" where we want both a LITUSE
262 unsigned long opcode
; /* need at least 32 bits */
263 struct reloc_data reloc
[MAX_RELOCS
];
266 static void getExpression (char *str
, struct alpha_it
*insn
);
267 static char *expr_end
;
269 #define note_gpreg(R) (alpha_gprmask |= (1 << (R)))
270 #define note_fpreg(R) (alpha_fprmask |= (1 << (R)))
273 tc_get_register (frame
)
279 if (*input_line_pointer
== '$')
281 input_line_pointer
++;
282 if (input_line_pointer
[0] == 's'
283 && input_line_pointer
[1] == 'p')
285 input_line_pointer
+= 2;
289 framereg
= get_absolute_expression ();
290 framereg
&= 31; /* ? */
293 as_warn ("frame reg expected, using $%d.", framereg
);
295 note_gpreg (framereg
);
299 /* Handle the .text pseudo-op. This is like the usual one, but it
300 clears insn_label and restores auto alignment. */
311 /* Handle the .data pseudo-op. This is like the usual one, but it
312 clears insn_label and restores auto alignment. */
329 temp
= get_absolute_expression ();
332 rdata
= subseg_get (".rdata", 0);
333 subseg_set (rdata
, (subsegT
) temp
);
335 rdata
= subseg_new (".rdata", 0);
337 demand_empty_rest_of_line ();
348 temp
= get_absolute_expression ();
351 sdata
= subseg_get (".sdata", 0);
352 subseg_set (sdata
, (subsegT
) temp
);
354 sdata
= subseg_new (".sdata", 0);
356 demand_empty_rest_of_line ();
362 s_alpha_comm (ignore
)
369 register symbolS
*symbolP
;
371 name
= input_line_pointer
;
372 c
= get_symbol_end ();
373 /* just after name is now '\0' */
374 p
= input_line_pointer
;
377 /* Alpha OSF/1 compiler doesn't provide the comma, gcc does. */
378 if (*input_line_pointer
== ',')
380 input_line_pointer
++;
383 if ((temp
= get_absolute_expression ()) < 0)
385 as_warn (".COMMon length (%ld.) <0! Ignored.", (long) temp
);
386 ignore_rest_of_line ();
390 symbolP
= symbol_find_or_make (name
);
392 if (S_IS_DEFINED (symbolP
))
394 as_bad ("Ignoring attempt to re-define symbol");
395 ignore_rest_of_line ();
398 if (S_GET_VALUE (symbolP
))
400 if (S_GET_VALUE (symbolP
) != (valueT
) temp
)
401 as_bad ("Length of .comm \"%s\" is already %ld. Not changed to %ld.",
402 S_GET_NAME (symbolP
),
403 (long) S_GET_VALUE (symbolP
),
408 S_SET_VALUE (symbolP
, (valueT
) temp
);
409 S_SET_EXTERNAL (symbolP
);
412 know (symbolP
->sy_frag
== &zero_address_frag
);
413 demand_empty_rest_of_line ();
417 tc_gen_reloc (sec
, fixp
)
423 reloc
= (arelent
*) bfd_alloc_by_size_t (stdoutput
, sizeof (arelent
));
424 reloc
->sym_ptr_ptr
= &fixp
->fx_addsy
->bsym
;
425 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
427 if (fixp
->fx_r_type
> BFD_RELOC_UNUSED
)
430 if (fixp
->fx_r_type
== BFD_RELOC_ALPHA_GPDISP_HI16
)
432 if (!gpdisp_hi16_howto
)
433 gpdisp_hi16_howto
= bfd_reloc_type_lookup (stdoutput
,
435 reloc
->howto
= gpdisp_hi16_howto
;
438 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
439 assert (reloc
->howto
!= 0);
440 if (!fixp
->fx_pcrel
!= !reloc
->howto
->pc_relative
)
442 as_fatal ("internal error? cannot generate `%s' relocation",
443 bfd_get_reloc_code_name (fixp
->fx_r_type
));
445 assert (!fixp
->fx_pcrel
== !reloc
->howto
->pc_relative
);
447 if (fixp
->fx_r_type
== BFD_RELOC_ALPHA_LITERAL
)
449 /* fake out bfd_perform_relocation. sigh */
450 reloc
->addend
= -alpha_gp_value
;
452 else if (reloc
->howto
->pc_relative
&& reloc
->howto
->pcrel_offset
)
454 reloc
->addend
= fixp
->fx_offset
- reloc
->address
;
457 reloc
->addend
= fixp
->fx_offset
;
464 if (first_32bit_quadrant
)
466 /* not fatal, but it might not work in the end */
467 as_warn ("File overrides no-base-register option.");
468 first_32bit_quadrant
= 0;
472 if (*input_line_pointer
== '$')
474 input_line_pointer
++;
475 if (*input_line_pointer
== 'r')
476 input_line_pointer
++;
479 base_register
= get_absolute_expression ();
480 if (base_register
< 0 || base_register
> 31)
483 as_warn ("Bad base register, using $%d.", base_register
);
485 demand_empty_rest_of_line ();
488 static int in_range_signed (val
, nbits
)
492 /* Look at top bit of value that would be stored, figure out how it
493 would be extended by the hardware, and see if that matches the
494 original supplied value. */
497 bfd_vma top_bit
, stored_value
, missing_bits
;
499 mask
= (one
<< nbits
) - 1;
500 stored_value
= val
& mask
;
501 top_bit
= stored_value
& (one
<< (nbits
- 1));
502 missing_bits
= val
& ~mask
;
503 /* will sign-extend */
506 /* all remaining bits beyond mask should be one */
507 missing_bits
|= mask
;
508 return missing_bits
+ 1 == 0;
512 /* all other bits should be zero */
513 return missing_bits
== 0;
518 static int in_range_unsigned (val
, nbits
)
522 /* Look at top bit of value that would be stored, figure out how it
523 would be extended by the hardware, and see if that matches the
524 original supplied value. */
527 bfd_vma top_bit
, stored_value
, missing_bits
;
529 mask
= (one
<< nbits
) - 1;
530 stored_value
= val
& mask
;
531 top_bit
= stored_value
& (one
<< nbits
- 1);
532 missing_bits
= val
& ~mask
;
533 return missing_bits
== 0;
548 e
.X_add_symbol
= section_symbol (absolute_section
);
558 alpha_align (2, 0, insn_label
);
561 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 4, &e
, 0,
567 create_literal_section (secp
, name
)
571 segT current_section
= now_seg
;
572 int current_subsec
= now_subseg
;
575 *secp
= new_sec
= subseg_new (name
, 0);
576 subseg_set (current_section
, current_subsec
);
577 bfd_set_section_alignment (stdoutput
, new_sec
, 3);
578 bfd_set_section_flags (stdoutput
, new_sec
,
579 SEC_RELOC
| SEC_ALLOC
| SEC_LOAD
| SEC_READONLY
584 get_lit8_offset (val
)
590 create_literal_section (&lit8_sec
, ".lit8");
591 lit8_sym
= section_symbol (lit8_sec
);
593 retval
= add_to_literal_pool ((symbolS
*) 0, val
, lit8_sec
, 8);
594 if (retval
>= 0xfff0)
595 as_fatal ("overflow in fp literal (.lit8) table");
600 get_lit4_offset (val
)
606 create_literal_section (&lit4_sec
, ".lit4");
607 lit4_sym
= section_symbol (lit4_sec
);
609 retval
= add_to_literal_pool ((symbolS
*) 0, val
, lit4_sec
, 4);
610 if (retval
>= 0xfff0)
611 as_fatal ("overflow in fp literal (.lit4) table");
615 static struct alpha_it clear_insn
;
617 /* This function is called once, at assembler startup time. It should
618 set up all the tables, etc. that the MD part of the assembler will
619 need, that can be determined before arguments are parsed. */
623 const char *retval
, *name
;
626 op_hash
= hash_new ();
628 for (i
= 0; i
< NUMOPCODES
; )
630 const char *name
= alpha_opcodes
[i
].name
;
631 retval
= hash_insert (op_hash
, name
, (PTR
) &alpha_opcodes
[i
]);
633 as_fatal ("internal error: can't hash opcode `%s': %s",
638 while (i
< NUMOPCODES
639 && (alpha_opcodes
[i
].name
== name
640 || !strcmp (alpha_opcodes
[i
].name
, name
)));
642 /* Some opcodes include modifiers of various sorts with a "/mod"
643 syntax, like the architecture documentation suggests. However,
644 for use with gcc at least, we also need to access those same
645 opcodes without the "/". */
646 for (i
= 0; i
< NUMOPCODES
; )
648 name
= alpha_opcodes
[i
].name
;
650 if (strchr (name
, '/'))
652 char *p
= xmalloc (strlen (name
));
653 const char *q
= name
;
661 retval
= hash_insert (op_hash
, p
, (PTR
) &alpha_opcodes
[i
]);
662 /* Ignore failures -- the opcode table does duplicate some
663 variants in different forms, like "hw_stq" and "hw_st/q".
664 Maybe the variants can be eliminated, and this error
665 checking restored. */
670 while (i
< NUMOPCODES
671 && (alpha_opcodes
[i
].name
== name
672 || !strcmp (alpha_opcodes
[i
].name
, name
)));
675 lituse_basereg
.X_op
= O_constant
;
676 lituse_basereg
.X_add_number
= 1;
677 lituse_byteoff
.X_op
= O_constant
;
678 lituse_byteoff
.X_add_number
= 2;
679 lituse_jsr
.X_op
= O_constant
;
680 lituse_jsr
.X_add_number
= 3;
682 /* So .sbss will get used for tiny objects. */
683 bfd_set_gp_size (stdoutput
, 8);
684 create_literal_section (&lita_sec
, ".lita");
685 /* For handling the GP, create a symbol that won't be output in the
686 symbol table. We'll edit it out of relocs later. */
687 gp
= symbol_create ("<GP value>", lita_sec
, 0x8000, &zero_address_frag
);
689 memset (&clear_insn
, 0, sizeof (clear_insn
));
690 for (i
= 0; i
< MAX_RELOCS
; i
++)
691 clear_insn
.reloc
[i
].code
= BFD_RELOC_NONE
;
698 struct alpha_it
*insn
;
705 /* put out the opcode */
706 md_number_to_chars (toP
, insn
->opcode
, 4);
708 /* put out the symbol-dependent stuff */
709 for (j
= 0; j
< MAX_RELOCS
; j
++)
711 struct reloc_data
*r
= &insn
->reloc
[j
];
714 if (r
->code
!= BFD_RELOC_NONE
)
716 if (r
->exp
.X_op
== O_constant
)
718 r
->exp
.X_add_symbol
= section_symbol (absolute_section
);
719 r
->exp
.X_op
= O_symbol
;
721 f
= fix_new_exp (frag_now
, (toP
- frag_now
->fr_literal
), 4,
722 &r
->exp
, r
->pcrel
, r
->code
);
723 if (r
->code
== BFD_RELOC_ALPHA_GPDISP_LO16
)
725 static bit_fixS cookie
;
726 /* @@ This'll make the range checking in write.c shut up. */
727 f
->fx_bit_fixP
= &cookie
;
741 struct alpha_it insns
[MAX_INSNS
];
743 count
= alpha_ip (str
, insns
);
747 for (i
= 0; i
< count
; i
++)
748 emit_insn (&insns
[i
]);
758 vma
= bfd_get_section_vma (foo
, sec
);
759 if (vma
&& vma
< alpha_gp_value
)
760 alpha_gp_value
= vma
;
766 if (alpha_gp_value
!= 0)
769 /* Get minus-one in whatever width... */
770 alpha_gp_value
= 0; alpha_gp_value
--;
772 /* Select the smallest VMA of these existing sections. */
773 maybe_set_gp (lita_sec
);
774 /* maybe_set_gp (sdata); Was disabled before -- should we use it? */
776 maybe_set_gp (lit8_sec
);
777 maybe_set_gp (lit4_sec
);
780 alpha_gp_value
+= GP_ADJUSTMENT
;
782 S_SET_VALUE (gp
, alpha_gp_value
);
785 printf ("Chose GP value of %lx\n", alpha_gp_value
);
790 alpha_force_relocation (f
)
793 switch (f
->fx_r_type
)
795 case BFD_RELOC_ALPHA_GPDISP_HI16
:
796 case BFD_RELOC_ALPHA_GPDISP_LO16
:
797 case BFD_RELOC_ALPHA_LITERAL
:
798 case BFD_RELOC_ALPHA_LITUSE
:
799 case BFD_RELOC_GPREL32
:
801 case BFD_RELOC_ALPHA_HINT
:
806 case BFD_RELOC_23_PCREL_S2
:
817 alpha_fix_adjustable (f
)
820 /* Are there any relocation types for which we must generate a reloc
821 but we can adjust the values contained within it? */
822 switch (f
->fx_r_type
)
824 case BFD_RELOC_ALPHA_GPDISP_HI16
:
825 case BFD_RELOC_ALPHA_GPDISP_LO16
:
827 case BFD_RELOC_GPREL32
:
830 return !alpha_force_relocation (f
);
836 md_section_align (seg
, size
)
841 /* This should probably be handled within BFD, or by pulling the
842 number from BFD at least. */
850 /* Add this thing to the .lita section and produce a LITERAL reloc referring
853 /* Are we currently eligible to emit a LITUSE reloc for the literal
854 references just generated? */
855 static int lituse_pending
;
858 load_symbol_address (reg
, insn
)
860 struct alpha_it
*insn
;
862 static symbolS
*lita_sym
;
869 lita_sym
= section_symbol (lita_sec
);
870 S_CLEAR_EXTERNAL (lita_sym
);
873 retval
= add_to_literal_pool (insn
->reloc
[0].exp
.X_add_symbol
,
874 insn
->reloc
[0].exp
.X_add_number
,
877 /* Now emit a LITERAL relocation for the original section. */
878 insn
->reloc
[0].exp
.X_op
= O_symbol
;
879 insn
->reloc
[0].exp
.X_add_symbol
= lita_sym
;
880 insn
->reloc
[0].exp
.X_add_number
= retval
;
881 insn
->reloc
[0].code
= BFD_RELOC_ALPHA_LITERAL
;
884 if (retval
== 0x8000)
886 as_fatal ("overflow in literal (.lita) table");
889 insn
->opcode
= (0xa0000000 /* ldl */
891 | (base_register
<< SB
)
894 insn
->opcode
= (0xa4000000 /* ldq */
896 | (base_register
<< SB
)
898 note_gpreg (base_register
);
901 /* To load an address with a single instruction,
902 emit a LITERAL reloc in this section, and a REFQUAD
903 for the .lita section, so that we'll be able to access
905 lda REG, xx -> ldq REG, -32752(gp)
906 lda REG, xx+4 -> ldq REG, -32752(gp)
909 The offsets need to start near -0x8000, and the generated LITERAL
910 relocations should negate the offset. I don't completely grok the
914 load_expression (reg
, insn
)
916 struct alpha_it
*insn
;
918 valueT addend
, addendhi
, addendlo
;
921 if (insn
->reloc
[0].exp
.X_add_symbol
->bsym
->flags
& BSF_SECTION_SYM
)
927 addend
= insn
->reloc
[0].exp
.X_add_number
;
928 insn
->reloc
[0].exp
.X_add_number
= 0;
930 load_symbol_address (reg
, insn
);
933 if ((addend
& ~0x7fffffff) != 0
934 && (addend
& ~0x7fffffff) + 0x80000000 != 0)
936 as_bad ("assembler not prepared to handle constants >32 bits yet");
939 addendlo
= addend
& 0xffff;
941 addendhi
= addend
>> 16;
942 if (addendlo
& 0x8000)
944 /* It appears that the BASEREG LITUSE reloc should not be used on
945 an LDAH instruction. */
948 insn
[1].opcode
= (0x20000000 /* lda */
951 | (addendlo
& 0xffff));
952 insn
[1].reloc
[0].code
= BFD_RELOC_ALPHA_LITUSE
;
953 insn
[1].reloc
[0].exp
= lituse_basereg
;
958 insn
[num_insns
].opcode
= (0x24000000
961 | (addendhi
& 0xffff));
972 getExpression (str
, this_insn
)
974 struct alpha_it
*this_insn
;
979 #if 0 /* Not converted to bfd yet, and I don't think we need them
980 for ECOFF. Re-adding a.out support will probably require
982 static const struct am
{
984 bfd_reloc_code_real_type reloc
;
986 { "hi", RELOC_48_63
},
987 { "lo", RELOC_0_15
},
988 { "ml", RELOC_16_31
},
989 { "mh", RELOC_32_47
},
990 { "uhi", RELOC_U_48_63
},
991 { "uml", RELOC_U_16_31
},
992 { "umh", RELOC_U_32_47
},
996 /* Handle macros: "%macroname(expr)" */
1007 while (*q
&& *p
== *q
)
1015 str
= p
; /* keep the '(' */
1016 this_insn
->reloc
= m
->reloc
;
1021 save_in
= input_line_pointer
;
1022 input_line_pointer
= str
;
1024 seg
= expression (&this_insn
->reloc
[0].exp
);
1025 /* XXX validate seg and exp, make sure they're reasonable */
1026 expr_end
= input_line_pointer
;
1027 input_line_pointer
= save_in
;
1031 emit_unaligned_io (dir
, addr_reg
, addr_offset
, reg
)
1037 sprintf (buf
, "%sq_u $%d,%ld($%d)", dir
, reg
, (long) addr_offset
, addr_reg
);
1042 emit_load_unal (addr_reg
, addr_offset
, reg
)
1046 emit_unaligned_io ("ld", addr_reg
, addr_offset
, reg
);
1050 emit_store_unal (addr_reg
, addr_offset
, reg
)
1054 emit_unaligned_io ("st", addr_reg
, addr_offset
, reg
);
1058 emit_byte_manip_r (op
, in
, mask
, out
, mode
, which
)
1060 int in
, mask
, out
, mode
, which
;
1063 sprintf (buf
, "%s%c%c $%d,$%d,$%d", op
, mode
, which
, in
, mask
, out
);
1068 emit_extract_r (in
, mask
, out
, mode
, which
)
1069 int in
, mask
, out
, mode
, which
;
1071 emit_byte_manip_r ("ext", in
, mask
, out
, mode
, which
);
1075 emit_insert_r (in
, mask
, out
, mode
, which
)
1076 int in
, mask
, out
, mode
, which
;
1078 emit_byte_manip_r ("ins", in
, mask
, out
, mode
, which
);
1082 emit_mask_r (in
, mask
, out
, mode
, which
)
1083 int in
, mask
, out
, mode
, which
;
1085 emit_byte_manip_r ("msk", in
, mask
, out
, mode
, which
);
1089 emit_sign_extend (reg
, size
)
1093 sprintf (buf
, "sll $%d,0x%x,$%d", reg
, 64 - size
, reg
);
1095 sprintf (buf
, "sra $%d,0x%x,$%d", reg
, 64 - size
, reg
);
1100 emit_bis_r (in1
, in2
, out
)
1104 sprintf (buf
, "bis $%d,$%d,$%d", in1
, in2
, out
);
1109 build_mem (opc
, ra
, rb
, disp
)
1111 bfd_signed_vma disp
;
1113 if ((disp
>> 15) != 0
1114 && (disp
>> 15) + 1 != 0)
1116 return ((opc
<< 26) | (ra
<< SA
) | (rb
<< SB
) | (disp
& 0xffff));
1120 build_operate_n (opc
, fn
, ra
, lit
, rc
)
1121 int opc
, fn
, ra
, rc
;
1126 return ((opc
<< 26) | (fn
<< 5) | (ra
<< SA
) | (lit
<< SN
) | (1 << 12) | (rc
<< SC
));
1130 emit_sll_n (dest
, disp
, src
)
1131 int dest
, disp
, src
;
1133 struct alpha_it insn
= clear_insn
;
1134 insn
.opcode
= build_operate_n (0x12, 0x39, src
, disp
, dest
);
1139 emit_ldah_num (dest
, addend
, src
)
1143 struct alpha_it insn
= clear_insn
;
1144 insn
.opcode
= build_mem (0x09, dest
, src
, addend
);
1149 emit_addq_r (in1
, in2
, out
)
1152 struct alpha_it insn
= clear_insn
;
1153 insn
.opcode
= 0x40000400 | (in1
<< SA
) | (in2
<< SB
) | (out
<< SC
);
1158 emit_lda_n (dest
, addend
, src
)
1162 struct alpha_it insn
= clear_insn
;
1163 insn
.opcode
= build_mem (0x08, dest
, src
, addend
);
1168 emit_add64 (in
, out
, num
)
1172 bfd_signed_vma snum
= num
;
1174 if (in_range_signed (num
, 16))
1176 emit_lda_n (out
, num
, in
);
1179 if ((num
& 0xffff) == 0
1181 && in_range_signed (snum
>> 16, 16))
1183 emit_ldah_num (out
, snum
>> 16, in
);
1186 /* I'm not sure this one is getting invoked when it could. */
1187 if ((num
& 1) == 0 && in
== ZERO
)
1189 if (in_range_signed (snum
>> 1, 16))
1191 emit_lda_n (out
, snum
>> 1, in
);
1192 emit_addq_r (out
, out
, out
);
1195 else if (num
& 0x1fffe == 0
1196 && in_range_signed (snum
>> 17, 16))
1198 emit_ldah_num (out
, snum
>> 17, in
);
1199 emit_addq_r (out
, out
, out
);
1203 if (in_range_signed (num
, 32))
1205 bfd_vma lo
= num
& 0xffff;
1209 emit_ldah_num (out
, snum
>> 16, in
);
1211 emit_lda_n (out
, lo
, out
);
1215 if (in
!= ZERO
&& in
!= AT
&& out
!= AT
&& at_ok
)
1217 emit_add64 (ZERO
, AT
, num
);
1218 emit_addq_r (AT
, in
, out
);
1223 as_bad ("load expression too complex to expand");
1225 /* Could check also for loading 16- or 32-bit value and shifting by
1226 arbitrary displacement. */
1229 bfd_vma lo
= snum
& 0xffffffff;
1230 if (lo
& 0x80000000)
1231 lo
-= ((bfd_vma
)0x10000000 << 4);
1233 emit_add64 (ZERO
, out
, snum
>> 32);
1234 emit_sll_n (out
, 32, out
);
1236 emit_add64 (out
, out
, lo
);
1241 alpha_ip (str
, insns
)
1243 struct alpha_it insns
[];
1249 struct alpha_opcode
*pattern
;
1251 unsigned int opcode
;
1252 unsigned int mask
= 0;
1253 int match
= 0, num_gen
= 1;
1255 int do_add64
, add64_in
= 0, add64_out
= 0;
1256 bfd_vma add64_addend
= 0;
1259 islower (*s
) || *s
== '_' || *s
== '/' || *s
== '4' || *s
== '8';
1278 as_fatal ("Unknown opcode: `%s'", str
);
1280 if ((pattern
= (struct alpha_opcode
*) hash_find (op_hash
, str
)) == NULL
)
1282 as_bad ("Unknown opcode: `%s'", str
);
1292 opcode
= pattern
->match
;
1294 for (i
= 0; i
< MAX_INSNS
; i
++)
1295 insns
[i
] = clear_insn
;
1297 /* Build the opcode, checking as we go to make sure that the
1299 for (args
= pattern
->args
;; ++args
)
1304 case '\0': /* end of args */
1323 case '(': /* these must match exactly */
1332 case '1': /* next operand must be a register */
1342 case 'a': /* $at: as temporary */
1348 case 'g': /* $gp: base register */
1351 mask
= base_register
;
1354 case 's': /* $sp: stack pointer */
1361 case 'r': /* any register */
1362 if (!isdigit (c
= *s
++))
1379 if ((c
= 10 * (c
- '0') + (*s
++ - '0')) >= 32)
1388 if ((c
== GP
) && first_32bit_quadrant
)
1398 /* Got the register, now figure out where it goes in
1406 opcode
|= mask
<< SA
;
1411 opcode
|= mask
<< SB
;
1420 opcode
|= (mask
<< SA
) | mask
;
1423 case 'R': /* ra and rb are the same */
1424 opcode
|= (mask
<< SA
) | (mask
<< SB
);
1428 opcode
|= (mask
<< SA
) | (mask
<< SB
) | (mask
);
1434 case 'e': /* next operand is a floating point register */
1438 if (*s
++ == '$' && *s
++ == 'f' && isdigit (*s
))
1443 mask
= 10 * (mask
- '0') + (*s
++ - '0');
1454 /* same encoding as gp registers */
1460 case 'h': /* bits 16..31 */
1461 insns
[0].reloc
= RELOC_16_31
;
1465 case 'l': /* bits 0..15 */
1466 insns
[0].reloc
[0].code
= BFD_RELOC_16
;
1469 case 'L': /* 21 bit PC relative immediate */
1470 insns
[0].reloc
[0].code
= BFD_RELOC_23_PCREL_S2
;
1471 insns
[0].reloc
[0].pcrel
= 1;
1474 case 'i': /* 14 bit immediate */
1475 if (OPCODE (opcode
) != 0x1a)
1476 /* Not a jmp variant?? */
1478 else if (opcode
& 0x8000)
1479 /* ret or jsr_coroutine */
1481 insns
[0].reloc
[0].code
= BFD_RELOC_14
;
1482 insns
[0].reloc
[0].pcrel
= 0;
1487 insns
[0].reloc
[0].code
= BFD_RELOC_ALPHA_HINT
;
1488 insns
[0].reloc
[0].pcrel
= 1;
1492 case 'b': /* 8 bit immediate */
1493 insns
[0].reloc
[0].code
= BFD_RELOC_8
;
1496 case 'I': /* 26 bit immediate, for PALcode */
1497 insns
[0].reloc
[0].code
= BFD_RELOC_26
;
1500 case 't': /* 12 bit displacement, for PALcode */
1501 insns
[0].reloc
[0].code
= BFD_RELOC_12_PCREL
;
1504 case '8': /* 8 bit 0...7 */
1505 insns
[0].reloc
[0].code
= BFD_RELOC_8
;
1511 getExpression (s
, &insns
[0]);
1513 /* Handle overflow in certain instructions by converting
1514 to other instructions. */
1515 if (insns
[0].reloc
[0].code
== BFD_RELOC_8
1516 && insns
[0].reloc
[0].exp
.X_op
== O_constant
1517 && (insns
[0].reloc
[0].exp
.X_add_number
< 0
1518 || insns
[0].reloc
[0].exp
.X_add_number
> 0xff))
1520 if (OPCODE (opcode
) == 0x10
1521 && (OP_FCN (opcode
) == 0x00 /* addl */
1522 || OP_FCN (opcode
) == 0x40 /* addl/v */
1523 || OP_FCN (opcode
) == 0x20 /* addq */
1524 || OP_FCN (opcode
) == 0x60 /* addq/v */
1525 || OP_FCN (opcode
) == 0x09 /* subl */
1526 || OP_FCN (opcode
) == 0x49 /* subl/v */
1527 || OP_FCN (opcode
) == 0x29 /* subq */
1528 || OP_FCN (opcode
) == 0x69 /* subq/v */
1529 || OP_FCN (opcode
) == 0x02 /* s4addl */
1530 || OP_FCN (opcode
) == 0x22 /* s4addq */
1531 || OP_FCN (opcode
) == 0x0b /* s4subl */
1532 || OP_FCN (opcode
) == 0x2b /* s4subq */
1533 || OP_FCN (opcode
) == 0x12 /* s8addl */
1534 || OP_FCN (opcode
) == 0x32 /* s8addq */
1535 || OP_FCN (opcode
) == 0x1b /* s8subl */
1536 || OP_FCN (opcode
) == 0x3b /* s8subq */
1538 /* Can we make it fit by negating? */
1539 && -insns
[0].reloc
[0].exp
.X_add_number
< 0xff
1540 && -insns
[0].reloc
[0].exp
.X_add_number
> 0)
1542 opcode
^= 0x120; /* convert add<=>sub */
1543 insns
[0].reloc
[0].exp
.X_add_number
*= -1;
1545 else if (at_ok
&& macro_ok
)
1547 /* Constant value supplied, but it's too large. */
1551 add64_addend
= insns
[0].reloc
[0].exp
.X_add_number
;
1553 opcode
|= (AT
<< SB
);
1554 insns
[0].reloc
[0].code
= BFD_RELOC_NONE
;
1557 as_bad ("overflow in 8-bit literal field in `operate' format insn");
1559 else if (insns
[0].reloc
[0].code
== BFD_RELOC_16
1560 && insns
[0].reloc
[0].exp
.X_op
== O_constant
1561 && !in_range_signed (insns
[0].reloc
[0].exp
.X_add_number
,
1564 bfd_vma val
= insns
[0].reloc
[0].exp
.X_add_number
;
1565 if (OPCODE (opcode
) == 0x08)
1572 opcode
|= (AT
<< SB
);
1573 insns
[0].reloc
[0].code
= BFD_RELOC_NONE
;
1575 else if (OPCODE (opcode
) == 0x09
1576 && in_range_signed (val
>> 16, 16))
1578 /* ldah with high operand - convert to low */
1579 insns
[0].reloc
[0].exp
.X_add_number
>>= 16;
1582 as_bad ("I don't know how to handle 32+ bit constants here yet, sorry.");
1584 else if (insns
[0].reloc
[0].code
== BFD_RELOC_32
1585 && insns
[0].reloc
[0].exp
.X_op
== O_constant
)
1587 bfd_vma val
= insns
[0].reloc
[0].exp
.X_add_number
;
1588 bfd_signed_vma sval
= val
;
1591 && sval
>> 32 != -1)
1592 as_bad ("I don't know how to handle 64 bit constants here yet, sorry.");
1598 int format
, length
, mode
, i
;
1599 char temp
[20 /*MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT*/];
1601 static const char formats
[4] = "FGfd";
1602 bfd_vma bits
, offset
;
1603 char *old_input_line_pointer
= input_line_pointer
;
1605 input_line_pointer
= s
;
1607 memset (temp
, 0, sizeof (temp
));
1608 mode
= (opcode
>> 26) & 3;
1609 format
= formats
[mode
];
1610 err
= md_atof (format
, temp
, &length
);
1613 as_bad ("Bad floating literal: %s", err
);
1618 /* Generate little-endian number from byte sequence. */
1620 for (i
= length
- 1; i
>= 0; i
--)
1621 bits
+= ((bfd_vma
)(temp
[i
] & 0xff)) << (i
* 8);
1626 offset
= get_lit8_offset (bits
) - 0x8000;
1627 insns
[0].reloc
[0].exp
.X_add_symbol
= lit8_sym
;
1628 insns
[0].reloc
[0].exp
.X_add_number
= 0x8000;
1631 offset
= get_lit4_offset (bits
) - 0x8000;
1632 insns
[0].reloc
[0].exp
.X_add_symbol
= lit4_sym
;
1633 insns
[0].reloc
[0].exp
.X_add_number
= 0x8000;
1638 insns
[0].reloc
[0].exp
.X_op
= O_symbol
;
1640 num_gen
= load_expression (AT
, &insns
[0]);
1643 insns
[num_gen
].reloc
[0].code
= BFD_RELOC_ALPHA_LITUSE
;
1644 insns
[num_gen
].reloc
[0].exp
= lituse_basereg
;
1647 insns
[num_gen
++].opcode
= opcode
| (AT
<< SB
) | offset
;
1648 opcode
= insns
[0].opcode
;
1649 s
= input_line_pointer
;
1650 input_line_pointer
= old_input_line_pointer
;
1654 /* The following two.. take advantage of the fact that
1655 opcode already contains most of what we need to know.
1656 We just prepend to the instr an "ldah
1657 $r,%ml(expr)($base)" and turn this one (done later
1658 after we return) into something like "stq
1659 $r,%lo(expr)(at)" or "ldq $r,%lo(expr)($r)".
1661 NOTE: This can fail later on at link time if the
1662 offset from $base actually turns out to be more than
1663 2**31 or 2**47 if use_large_offsets is set. */
1664 case 'P': /* Addressing macros: PUT */
1665 mask
= AT
; /* register 'at' */
1668 case 'G': /* Addressing macros: GET */
1669 /* All it is missing is the expression, which is what we
1674 getExpression (s
, &insns
[0]);
1677 /* Must check for "lda ..,number" too */
1678 if (insns
[0].reloc
[0].exp
.X_op
== O_big
)
1680 as_warn ("Sorry, not yet. Put bignums in .data section yourself.");
1683 if (insns
[0].reloc
[0].exp
.X_op
== O_constant
)
1685 bfd_vma val
= insns
[0].reloc
[0].exp
.X_add_number
;
1688 insns
[0].reloc
[0].code
= BFD_RELOC_NONE
;
1689 insns
[1].reloc
[0].code
= BFD_RELOC_NONE
;
1704 opcode
|= ZERO
<< SB
;
1706 opcode
|= low
& 0xffff;
1708 else if (insns
[0].reloc
[0].exp
.X_op
== O_symbol
)
1710 unsigned long old_opcode
= opcode
;
1714 as_bad ("insn requires expansion but `nomacro' specified");
1715 else if (*args
== 'G')
1718 as_bad ("insn expansion requires AT use, but `noat' specified");
1721 num_gen
= load_expression (tmp_reg
, insns
);
1722 opcode
= insns
[0].opcode
;
1723 /* lda is opcode 8, 0x20000000, and the macros that use
1724 this code have an opcode field of 0. The latter
1725 require further processing, and we don't have the
1726 true opcode here. */
1727 if (OPCODE (old_opcode
) != 0
1728 && OPCODE (old_opcode
) != 0x08)
1731 i
= &insns
[num_gen
++];
1732 i
->opcode
= old_opcode
| (tmp_reg
<< SB
);
1736 i
->reloc
[0].code
= BFD_RELOC_ALPHA_LITUSE
;
1737 i
->reloc
[0].exp
= lituse_basereg
;
1746 insns
[1].reloc
[0].exp
= insns
[0].reloc
[0].exp
;
1748 /* Generate: ldah REG,x1(GP); OP ?,x0(REG) */
1750 abort (); /* relocs need fixing */
1752 insns
[1].reloc
= RELOC_0_15
;
1753 insns
[1].opcode
= opcode
| mask
<< SB
;
1755 insns
[0].reloc
= RELOC_16_31
;
1756 opcode
= 0x24000000 /*ldah*/ | mask
<< SA
| (base_register
<< SB
);
1762 /* Same failure modes as above, actually most of the
1763 same code shared. */
1764 case 'B': /* Builtins */
1769 case 'a': /* ldgp */
1771 if (first_32bit_quadrant
|| no_mixed_code
)
1773 switch (OUTPUT_FLAVOR
)
1775 case bfd_target_aout_flavour
:
1776 /* this is cmu's a.out version */
1777 insns
[0].reloc
[0].code
= BFD_RELOC_NONE
;
1778 /* generate "zap %r,0xf,%r" to take high 32 bits */
1779 opcode
|= 0x48001600 /* zap ?,#,?*/ | (0xf << SN
);
1781 case bfd_target_ecoff_flavour
:
1782 /* Given "ldgp R1,N(R2)", turn it into something
1783 like "ldah R1,###(R2) ; lda R1,###(R1)" with
1784 appropriate constants and relocations. */
1786 unsigned long r1
, r2
;
1787 unsigned long addend
= 0;
1792 insns
[0].reloc
[0].code
= BFD_RELOC_ALPHA_GPDISP_HI16
;
1793 insns
[0].reloc
[0].pcrel
= 1;
1794 insns
[0].reloc
[0].exp
.X_op
= O_symbol
;
1795 insns
[0].reloc
[0].exp
.X_add_symbol
= gp
;
1796 insns
[0].reloc
[0].exp
.X_add_number
= 0;
1797 insns
[0].opcode
= (0x24000000 /* ldah */
1800 insns
[1].reloc
[0].code
= BFD_RELOC_ALPHA_GPDISP_LO16
;
1801 insns
[1].reloc
[0].exp
.X_op
= O_symbol
;
1802 insns
[1].reloc
[0].exp
.X_add_symbol
= gp
;
1803 insns
[1].reloc
[0].exp
.X_add_number
= 4;
1804 insns
[1].reloc
[0].pcrel
= 1;
1805 insns
[1].opcode
= 0x20000000 | (r1
<< SA
) | (r1
<< SB
);
1806 opcode
= insns
[0].opcode
;
1807 /* merge in addend */
1808 insns
[1].opcode
|= addend
& 0xffff;
1809 insns
[0].opcode
|= ((addend
>> 16)
1810 + (addend
& 0x8000 ? 1 : 0));
1812 ecoff_set_gp_prolog_size (0);
1821 case 'b': /* setgp */
1822 switch (OUTPUT_FLAVOR
)
1824 case bfd_target_aout_flavour
:
1825 /* generate "zap %r,0xf,$gp" to take high 32 bits */
1826 opcode
|= 0x48001600 /* zap ?,#,?*/
1827 | (0xf << SN
) | (base_register
);
1834 case 'c': /* jsr $r,foo becomes
1837 Register 27, t12, is used by convention
1840 struct alpha_it
*jsr
;
1842 struct reloc_data
*r
;
1844 /* We still have to parse the function name */
1847 getExpression (s
, &insns
[0]);
1848 etmp
= insns
[0].reloc
[0].exp
;
1850 num_gen
= load_expression (PV
, &insns
[0]);
1853 jsr
= &insns
[num_gen
++];
1854 jsr
->opcode
= (pattern
->match
1860 /* LITUSE wasn't emitted yet */
1861 jsr
->reloc
[0].code
= BFD_RELOC_ALPHA_LITUSE
;
1862 jsr
->reloc
[0].exp
= lituse_jsr
;
1869 r
->code
= BFD_RELOC_ALPHA_HINT
;
1871 opcode
= insns
[0].opcode
;
1876 /* Sub-word loads and stores. We load the address into
1877 $at, which might involve using the `P' parameter
1878 processing too, then emit a sequence to get the job
1879 done, using unaligned memory accesses and byte
1880 manipulation, with t9 and t10 as temporaries. */
1882 /* Characteristics of access. */
1883 int is_load
= 99, is_unsigned
= 0, is_unaligned
= 0;
1884 int mode_size
, mode
;
1885 /* Register operand. */
1887 /* Addend for loads and stores. */
1889 /* Which register do we use for the address? */
1893 /* Pick apart name and set flags. */
1894 const char *s
= pattern
->name
;
1902 if (s
[0] == 'l' && s
[1] == 'd')
1904 else if (s
[0] == 's' && s
[1] == 't')
1907 as_fatal ("unrecognized sub-word access insn `%s'",
1912 if (mode
== 'b') mode_size
= 1;
1913 else if (mode
== 'w') mode_size
= 2;
1914 else if (mode
== 'l') mode_size
= 4;
1915 else if (mode
== 'q') mode_size
= 8;
1926 /* Longwords are always kept sign-extended. */
1927 if (mode
== 'l' && is_unsigned
)
1929 /* There's no special unaligned byte handling. */
1930 if (mode
== 'b' && is_unaligned
)
1932 /* Stores don't care about signedness. */
1933 if (!is_load
&& is_unsigned
)
1937 if (args
[-2] == 'P')
1946 r1 -> (opcode >> SA) & 31
1947 num -> insns->reloc[0].*
1949 We want to emit "lda at,num(r2)", since these
1950 operations require the use of a single register
1951 with the starting address of the memory operand
1954 We could probably get away without doing this
1955 (and use r2 below, with the addend for the
1956 actual reads and writes) in cases where the
1957 addend is known to be a multiple of 8. */
1959 int r1
= (opcode
>> SA
) & 31;
1961 if (insns
[0].reloc
[0].code
== BFD_RELOC_NONE
)
1963 else if (insns
[0].reloc
[0].code
== BFD_RELOC_16
)
1965 if (insns
[0].reloc
[0].exp
.X_op
!= O_constant
)
1967 addend
= insns
[0].reloc
[0].exp
.X_add_number
;
1972 if (addend
+ mode_size
- 1 < 0x7fff
1973 && (addend
% 8) == 0
1974 && (r2
< T9
|| r2
> T12
))
1981 /* Let later relocation processing deal
1982 with the addend field. */
1983 insns
[num_gen
-1].opcode
= (0x20000000 /* lda */
1992 /* Because the emit_* routines append directly to
1993 the current frag, we now need to flush any
1997 for (i
= 0; i
< num_gen
; i
++)
1998 emit_insn (&insns
[i
]);
2004 int reg2
, reg3
= -1;
2007 reg2
= T9
, reg3
= T10
;
2011 emit_load_unal (addr
, addend
, T9
);
2013 emit_load_unal (addr
, addend
+ mode_size
- 1, T10
);
2014 emit_extract_r (T9
, addr
, reg2
, mode
, 'l');
2017 emit_extract_r (T10
, addr
, reg3
, mode
, 'h');
2018 emit_bis_r (T9
, T10
, reg
);
2021 emit_sign_extend (reg
, mode_size
* 8);
2025 /* The second word gets processed first
2026 because if the address does turn out to be
2027 aligned, the processing for the second word
2028 will be pushing around all-zeros, and the
2029 entire value will be handled as the `first'
2030 word. So we want to store the `first' word
2032 /* Pair these up so that the memory loads get
2033 separated from each other, as well as being
2034 well in advance of the uses of the values
2038 emit_load_unal (addr
, addend
+ mode_size
- 1, T11
);
2039 emit_insert_r (reg
, addr
, T12
, mode
, 'h');
2041 emit_load_unal (addr
, addend
, T9
);
2042 emit_insert_r (reg
, addr
, T10
, mode
, 'l');
2044 emit_mask_r (T12
, addr
, T12
, mode
, 'h');
2045 emit_mask_r (T10
, addr
, T10
, mode
, 'l');
2047 emit_bis_r (T11
, T12
, T11
);
2048 emit_bis_r (T9
, T10
, T9
);
2050 emit_store_unal (addr
, addend
+ mode_size
- 1, T11
);
2051 emit_store_unal (addr
, addend
, T9
);
2056 /* DIVISION and MODULUS. Yech.
2057 Convert OP x,y,result
2063 with appropriate optimizations if t10,t11,t12
2064 are the registers specified by the compiler.
2065 We are missing an obvious optimization
2066 opportunity here; if the ldq generated by the
2067 jsr assembly requires a cycle or two to make
2068 the value available, initiating it before one
2069 or two of the mov instructions would result in
2070 faster execution. */
2071 case '0': /* reml */
2072 case '1': /* divl */
2073 case '2': /* remq */
2074 case '3': /* divq */
2075 case '4': /* remlu */
2076 case '5': /* divlu */
2077 case '6': /* remqu */
2078 case '7': /* divqu */
2080 static char func
[8][6] = {
2081 "reml", "divl", "remq", "divq",
2082 "remlu", "divlu", "remqu", "divqu"
2087 /* All regs parsed, in opcode */
2089 /* Do the expansions, one instr at a time */
2091 reg
= (opcode
>> SA
) & 31;
2095 sprintf (expansion
, "mov $%d,$%d", reg
, T10
);
2096 md_assemble (expansion
);
2098 reg
= (opcode
>> SB
) & 31;
2100 /* we already overwrote it! */
2102 else if (reg
!= T11
)
2105 sprintf (expansion
, "mov $%d,$%d", reg
, T11
);
2106 md_assemble (expansion
);
2108 sprintf (expansion
, "lda $%d,__%s", PV
, func
[*args
- '0']);
2109 md_assemble (expansion
);
2110 sprintf (expansion
, "jsr $%d,($%d),__%s", T9
, PV
,
2112 md_assemble (expansion
);
2114 if (!first_32bit_quadrant
)
2119 md_assemble (expansion
);
2122 sprintf (expansion
, "ldgp $%d,0($%d)",
2124 md_assemble (expansion
);
2126 /* Use insns[0] to get at the result */
2127 if ((reg
= (opcode
& 31)) != PV
)
2128 opcode
= (0x47e00400 /* or zero,zero,zero */
2130 | reg
/* Rc */ ); /* pv->z */
2146 /* Args don't match. */
2147 if (&pattern
[1] - alpha_opcodes
< NUMOPCODES
2148 && !strcmp (pattern
->name
, pattern
[1].name
))
2156 as_warn ("Illegal operands");
2162 /* Args match, see if a float instructions and -nofloats */
2163 if (nofloats
&& pattern
->isa_float
)
2171 emit_add64 (add64_in
, add64_out
, add64_addend
);
2174 insns
[0].opcode
= opcode
;
2178 /* Turn a string in input_line_pointer into a floating point constant
2179 of type type, and store the appropriate bytes in *litP. The number
2180 of LITTLENUMS emitted is stored in *sizeP. An error message is
2181 returned, or NULL on OK. */
2183 /* Equal to MAX_PRECISION in atof-ieee.c */
2184 #define MAX_LITTLENUMS 6
2187 md_atof (type
, litP
, sizeP
)
2193 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
2194 LITTLENUM_TYPE
*wordP
;
2196 char *atof_ieee (), *vax_md_atof ();
2202 /* VAX md_atof doesn't like "G" for some reason. */
2206 return vax_md_atof (type
, litP
, sizeP
);
2229 return "Bad call to MD_ATOF()";
2231 t
= atof_ieee (input_line_pointer
, type
, words
);
2233 input_line_pointer
= t
;
2234 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
2236 for (wordP
= words
+ prec
- 1; prec
--;)
2238 md_number_to_chars (litP
, (long) (*wordP
--), sizeof (LITTLENUM_TYPE
));
2239 litP
+= sizeof (LITTLENUM_TYPE
);
2246 md_bignum_to_chars (buf
, bignum
, nchars
)
2248 LITTLENUM_TYPE
*bignum
;
2253 LITTLENUM_TYPE work
= *bignum
++;
2254 int nb
= CHARS_PER_LITTLENUM
;
2258 *buf
++ = work
& ((1 << BITS_PER_CHAR
) - 1);
2261 work
>>= BITS_PER_CHAR
;
2267 CONST
char *md_shortopts
= "Fm:";
2268 struct option md_longopts
[] = {
2269 #define OPTION_32ADDR (OPTION_MD_BASE)
2270 {"32addr", no_argument
, NULL
, OPTION_32ADDR
},
2271 {NULL
, no_argument
, NULL
, 0}
2273 size_t md_longopts_size
= sizeof(md_longopts
);
2276 md_parse_option (c
, arg
)
2298 md_show_usage (stream
)
2303 -32addr treat addresses as 32-bit values\n\
2304 -F lack floating point instructions support\n\
2305 -m21064 | -m21066 | -m21164\n\
2306 specify variant of Alpha architecture\n");
2313 /* XXXX Align to cache linesize XXXXX */
2320 /* Takes ".proc name,nargs" */
2321 name
= input_line_pointer
;
2322 c
= get_symbol_end ();
2323 p
= input_line_pointer
;
2324 symbolP
= symbol_find_or_make (name
);
2327 if (*input_line_pointer
!= ',')
2330 as_warn ("Expected comma after name \"%s\"", name
);
2333 ignore_rest_of_line ();
2337 input_line_pointer
++;
2338 temp
= get_absolute_expression ();
2340 /* symbolP->sy_other = (signed char) temp; */
2341 as_warn ("unhandled: .proc %s,%d", name
, temp
);
2342 demand_empty_rest_of_line ();
2349 char *name
= input_line_pointer
, ch
, *s
;
2352 while (!is_end_of_line
[(unsigned char) *input_line_pointer
])
2353 input_line_pointer
++;
2354 ch
= *input_line_pointer
;
2355 *input_line_pointer
= '\0';
2358 if (s
[0] == 'n' && s
[1] == 'o')
2363 if (!strcmp ("reorder", s
))
2365 else if (!strcmp ("at", s
))
2367 else if (!strcmp ("macro", s
))
2369 else if (!strcmp ("move", s
))
2371 else if (!strcmp ("volatile", s
))
2374 as_warn ("Tried to .set unrecognized mode `%s'", name
);
2375 *input_line_pointer
= ch
;
2376 demand_empty_rest_of_line ();
2379 /* @@ Is this right?? */
2381 md_pcrel_from (fixP
)
2384 valueT addr
= fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
2385 switch (fixP
->fx_r_type
)
2387 case BFD_RELOC_ALPHA_GPDISP_HI16
:
2388 case BFD_RELOC_ALPHA_GPDISP_LO16
:
2391 return fixP
->fx_size
+ addr
;
2395 /* Handle the .align pseudo-op. This aligns to a power of two. It
2396 also adjusts any current instruction label. We treat this the same
2397 way the MIPS port does: .align 0 turns off auto alignment. */
2400 s_alpha_align (ignore
)
2404 register long temp_fill
;
2405 long max_alignment
= 15;
2407 temp
= get_absolute_expression ();
2408 if (temp
> max_alignment
)
2409 as_bad ("Alignment too large: %d. assumed.", temp
= max_alignment
);
2412 as_warn ("Alignment negative: 0 assumed.");
2415 if (*input_line_pointer
== ',')
2417 input_line_pointer
++;
2418 temp_fill
= get_absolute_expression ();
2425 alpha_align (temp
, (int) temp_fill
, insn_label
);
2432 demand_empty_rest_of_line ();
2436 alpha_align (n
, fill
, label
)
2442 && (now_seg
== text_section
2443 || !strcmp (now_seg
->name
, ".init")
2444 || !strcmp (now_seg
->name
, ".fini")))
2446 static const unsigned char nop_pattern
[] = { 0x1f, 0x04, 0xff, 0x47 };
2447 frag_align_pattern (n
, nop_pattern
, sizeof (nop_pattern
));
2450 frag_align (n
, fill
);
2454 assert (S_GET_SEGMENT (label
) == now_seg
);
2455 label
->sy_frag
= frag_now
;
2456 S_SET_VALUE (label
, (valueT
) frag_now_fix ());
2460 /* This function is called just before the generic pseudo-ops output
2461 something. It just clears insn_label. */
2464 alpha_flush_pending_output ()
2469 /* Handle data allocation pseudo-ops. This is like the generic
2470 version, but it makes sure the current label, if any, is correctly
2474 s_alpha_cons (log_size
)
2477 if (log_size
> 0 && auto_align
)
2478 alpha_align (log_size
, 0, insn_label
);
2480 cons (1 << log_size
);
2483 /* Handle floating point allocation pseudo-ops. This is like the
2484 generic vresion, but it makes sure the current label, if any, is
2485 correctly aligned. */
2488 s_alpha_float_cons (type
)
2517 alpha_align (log_size
, 0, insn_label
);
2524 /* This function is called whenever a label is defined. It is used to
2525 adjust the label when an automatic alignment occurs. */
2528 alpha_define_label (sym
)
2535 md_apply_fix (fixP
, valueP
)
2542 char *p
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
2546 switch (fixP
->fx_r_type
)
2548 /* The GPDISP relocations are processed internally with a symbol
2549 referring to the current function; we need to drop in a value
2550 which, when added to the address of the start of the function,
2551 gives the desired GP. */
2552 case BFD_RELOC_ALPHA_GPDISP_HI16
:
2553 case BFD_RELOC_ALPHA_GPDISP_LO16
:
2555 if (fixP
->fx_r_type
== BFD_RELOC_ALPHA_GPDISP_HI16
)
2557 assert (fixP
->fx_next
->fx_r_type
== BFD_RELOC_ALPHA_GPDISP_LO16
);
2560 fprintf_vma (stdout
, addend
);
2563 if (addend
& 0x8000)
2566 fixP
->fx_offset
= 4; /* @@ Compute this using fx_next. */
2572 fprintf_vma (stdout
, addend
);
2576 fixP
->fx_offset
= 0;
2578 md_number_to_chars (fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
,
2580 fixP
->fx_addsy
= section_symbol (absolute_section
);
2581 fixP
->fx_offset
+= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
2585 /* Write 8 bits, shifted left 13 bit positions. */
2589 *p
|= (value
<< 5) & 0xe0;
2597 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2598 "overflow in type-%d reloc", (int) fixP
->fx_r_type
);
2608 /* Don't want overflow checking. */
2611 if (fixP
->fx_pcrel
== 0
2612 && fixP
->fx_addsy
== 0)
2614 md_number_to_chars (p
, value
, size
);
2615 /* @@ Overflow checks?? */
2621 if (fixP
->fx_addsy
!= 0
2622 && fixP
->fx_addsy
->bsym
->section
!= absolute_section
)
2623 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2624 "PALcode instructions require immediate constant function code");
2625 else if (value
>> 26 != 0)
2626 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2627 "overflow in 26-bit PALcode function field");
2628 *p
++ = value
& 0xff;
2630 *p
++ = value
& 0xff;
2632 *p
++ = value
& 0xff;
2643 if (fixP
->fx_addsy
!= 0
2644 && fixP
->fx_addsy
->bsym
->section
!= absolute_section
)
2645 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2646 "ret/jsr_coroutine requires constant in displacement field");
2647 else if (value
>> 14 != 0)
2648 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2649 "overflow in 14-bit operand field of ret or jsr_coroutine");
2650 *p
++ = value
& 0xff;
2652 *p
= (*p
& 0xc0) | (value
& 0x3f);
2655 case BFD_RELOC_23_PCREL_S2
:
2656 /* Write 21 bits only. */
2658 *p
++ = value
& 0xff;
2660 *p
++ = value
& 0xff;
2663 *p
|= (value
& 0x1f);
2666 case BFD_RELOC_12_PCREL
:
2667 *p
++ = value
& 0xff;
2670 *p
|= (value
& 0x0f);
2673 case BFD_RELOC_ALPHA_LITERAL
:
2674 case BFD_RELOC_ALPHA_LITUSE
:
2677 case BFD_RELOC_GPREL32
:
2678 assert (fixP
->fx_subsy
== gp
);
2679 value
= - alpha_gp_value
; /* huh? this works... */
2681 md_number_to_chars (p
, value
, 4);
2684 case BFD_RELOC_ALPHA_HINT
:
2685 if (fixP
->fx_addsy
== 0 && fixP
->fx_pcrel
== 0)
2693 as_fatal ("unhandled relocation type %s",
2694 bfd_get_reloc_code_name (fixP
->fx_r_type
));
2698 if (fixP
->fx_addsy
== 0 && fixP
->fx_pcrel
== 0)
2700 printf ("type %d reloc done?\n", fixP
->fx_r_type
);
2710 alpha_frob_ecoff_data ()
2713 /* $zero and $f31 are read-only */
2714 alpha_gprmask
&= ~1;
2715 alpha_fprmask
&= ~1;
2718 /* The Alpha has support for some VAX floating point types, as well as for
2719 IEEE floating point. We consider IEEE to be the primary floating point
2720 format, and sneak in the VAX floating point support here. */
2721 #define md_atof vax_md_atof
2722 #include "config/atof-vax.c"