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 /* Which machine type is this? Currently stores an integer for the
67 model, one of: 21064, 21066, 21164. */
68 static unsigned long machine
;
70 /* These are exported to relaxing code, even though we don't do any
71 relaxing on this processor currently. */
72 const relax_typeS md_relax_table
[1];
73 int md_short_jump_size
= 4;
74 int md_long_jump_size
= 4;
76 /* handle of the OPCODE hash table */
77 static struct hash_control
*op_hash
;
79 /* Sections and symbols we'll want to keep track of. */
80 static segT lita_sec
, rdata
, sdata
, lit8_sec
, lit4_sec
;
81 static symbolS
*lit8_sym
, *lit4_sym
;
83 /* Setting for ".set [no]{at,macro}". */
84 static int at_ok
= 1, macro_ok
= 1;
86 /* Keep track of global pointer. */
87 valueT alpha_gp_value
;
90 /* We'll probably be using this relocation frequently, and we
91 will want to compare for it. */
92 static const reloc_howto_type
*gpdisp_hi16_howto
;
94 /* These are exported to ECOFF code. */
95 unsigned long alpha_gprmask
, alpha_fprmask
;
97 /* Used for LITUSE relocations. */
98 static expressionS lituse_basereg
, lituse_byteoff
, lituse_jsr
;
100 /* Address size: In OSF/1 1.3, an undocumented "-32addr" option will
101 cause all addresses to be treated as 32-bit values in memory. (The
102 in-register versions are all sign-extended to 64 bits, of course.)
103 Some other systems may want this option too. */
106 /* Imported functions -- they should be defined in header files somewhere. */
107 extern segT
subseg_get ();
108 extern PTR
bfd_alloc_by_size_t ();
109 extern void s_globl (), s_long (), s_short (), s_space (), cons (), s_text (),
110 s_data (), float_cons ();
112 /* Static functions, needing forward declarations. */
113 static void s_base (), s_proc (), s_alpha_set ();
114 static void s_gprel32 (), s_rdata (), s_sdata (), s_alpha_comm ();
115 static int alpha_ip ();
117 static void emit_unaligned_io
PARAMS ((char *, int, valueT
, int));
118 static void emit_load_unal
PARAMS ((int, valueT
, int));
119 static void emit_store_unal
PARAMS ((int, valueT
, int));
120 static void emit_byte_manip_r
PARAMS ((char *, int, int, int, int, int));
121 static void emit_extract_r
PARAMS ((int, int, int, int, int));
122 static void emit_insert_r
PARAMS ((int, int, int, int, int));
123 static void emit_mask_r
PARAMS ((int, int, int, int, int));
124 static void emit_sign_extend
PARAMS ((int, int));
125 static void emit_bis_r
PARAMS ((int, int, int));
126 static int build_mem
PARAMS ((int, int, int, bfd_signed_vma
));
127 static int build_operate_n
PARAMS ((int, int, int, int, int));
128 static void emit_sll_n
PARAMS ((int, int, int));
129 static void emit_ldah_num
PARAMS ((int, bfd_vma
, int));
130 static void emit_addq_r
PARAMS ((int, int, int));
131 static void emit_lda_n
PARAMS ((int, bfd_vma
, int));
132 static void emit_add64
PARAMS ((int, int, bfd_vma
));
133 static int in_range_signed
PARAMS ((bfd_vma
, int));
135 const pseudo_typeS md_pseudo_table
[] =
137 {"common", s_comm
, 0}, /* is this used? */
138 {"comm", s_alpha_comm
, 0}, /* osf1 compiler does this */
139 {"rdata", s_rdata
, 0},
140 {"sdata", s_sdata
, 0},
141 {"gprel32", s_gprel32
, 0},
142 {"t_floating", float_cons
, 'd'},
143 {"s_floating", float_cons
, 'f'},
144 {"f_floating", float_cons
, 'F'},
145 {"g_floating", float_cons
, 'G'},
146 {"d_floating", float_cons
, 'D'},
149 {"aproc", s_proc
, 1},
150 {"set", s_alpha_set
, 0},
151 {"reguse", s_ignore
, 0},
152 {"livereg", s_ignore
, 0},
153 {"extern", s_ignore
, 0}, /*??*/
154 {"base", s_base
, 0}, /*??*/
155 {"option", s_ignore
, 0},
156 {"prologue", s_ignore
, 0},
157 {"aent", s_ignore
, 0},
158 {"ugen", s_ignore
, 0},
160 /* We don't do any optimizing, so we can safely ignore these. */
161 {"noalias", s_ignore
, 0},
162 {"alias", s_ignore
, 0},
167 #define SA 21 /* shift for register Ra */
168 #define SB 16 /* shift for register Rb */
169 #define SC 0 /* shift for register Rc */
170 #define SN 13 /* shift for 8 bit immediate # */
176 #define RA 26 /* note: same as T12 */
183 #define OPCODE(X) (((X) >> 26) & 0x3f)
184 #define OP_FCN(X) (((X) >> 5) & 0x7f)
186 #ifndef FIRST_32BIT_QUADRANT
187 #define FIRST_32BIT_QUADRANT 0
190 int first_32bit_quadrant
= FIRST_32BIT_QUADRANT
;
191 int base_register
= FIRST_32BIT_QUADRANT
? ZERO
: GP
;
193 int no_mixed_code
= 0;
196 /* This array holds the chars that always start a comment. If the
197 pre-processor is disabled, these aren't very useful */
198 const char comment_chars
[] = "#";
200 /* This array holds the chars that only start a comment at the beginning of
201 a line. If the line seems to have the form '# 123 filename'
202 .line and .file directives will appear in the pre-processed output */
203 /* Note that input_file.c hand checks for '#' at the beginning of the
204 first line of the input file. This is because the compiler outputs
205 #NO_APP at the beginning of its output. */
206 /* Also note that C style comments are always recognized. */
207 const char line_comment_chars
[] = "#!";
209 /* Chars that can be used to separate mant from exp in floating point nums */
210 const char EXP_CHARS
[] = "eE";
212 const char line_separator_chars
[1];
214 /* Chars that mean this number is a floating point constant, as in
215 "0f12.456" or "0d1.2345e12". */
216 /* @@ Do all of these really get used on the alpha?? */
217 char FLT_CHARS
[] = "rRsSfFdDxXpP";
219 /* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
220 changed in read.c. Ideally it shouldn't have to know about it at all,
221 but nothing is ideal around here. */
226 bfd_reloc_code_real_type code
;
229 /* Occasionally, two relocations will be desired for one address.
230 Mainly only in cases like "jsr $r,foo" where we want both a LITUSE
235 unsigned long opcode
; /* need at least 32 bits */
236 struct reloc_data reloc
[MAX_RELOCS
];
239 static void getExpression (char *str
, struct alpha_it
*insn
);
240 static char *expr_end
;
242 #define note_gpreg(R) (alpha_gprmask |= (1 << (R)))
243 #define note_fpreg(R) (alpha_fprmask |= (1 << (R)))
246 tc_get_register (frame
)
252 if (*input_line_pointer
== '$')
254 input_line_pointer
++;
255 if (input_line_pointer
[0] == 's'
256 && input_line_pointer
[1] == 'p')
258 input_line_pointer
+= 2;
262 framereg
= get_absolute_expression ();
263 framereg
&= 31; /* ? */
266 as_warn ("frame reg expected, using $%d.", framereg
);
268 note_gpreg (framereg
);
278 temp
= get_absolute_expression ();
281 rdata
= subseg_get (".rdata", 0);
282 subseg_set (rdata
, (subsegT
) temp
);
284 rdata
= subseg_new (".rdata", 0);
286 demand_empty_rest_of_line ();
295 temp
= get_absolute_expression ();
298 sdata
= subseg_get (".sdata", 0);
299 subseg_set (sdata
, (subsegT
) temp
);
301 sdata
= subseg_new (".sdata", 0);
303 demand_empty_rest_of_line ();
307 s_alpha_comm (ignore
)
314 register symbolS
*symbolP
;
316 name
= input_line_pointer
;
317 c
= get_symbol_end ();
318 /* just after name is now '\0' */
319 p
= input_line_pointer
;
322 /* Alpha OSF/1 compiler doesn't provide the comma, gcc does. */
323 if (*input_line_pointer
== ',')
325 input_line_pointer
++;
328 if ((temp
= get_absolute_expression ()) < 0)
330 as_warn (".COMMon length (%ld.) <0! Ignored.", (long) temp
);
331 ignore_rest_of_line ();
335 symbolP
= symbol_find_or_make (name
);
337 if (S_IS_DEFINED (symbolP
))
339 as_bad ("Ignoring attempt to re-define symbol");
340 ignore_rest_of_line ();
343 if (S_GET_VALUE (symbolP
))
345 if (S_GET_VALUE (symbolP
) != (valueT
) temp
)
346 as_bad ("Length of .comm \"%s\" is already %ld. Not changed to %ld.",
347 S_GET_NAME (symbolP
),
348 (long) S_GET_VALUE (symbolP
),
353 S_SET_VALUE (symbolP
, (valueT
) temp
);
354 S_SET_EXTERNAL (symbolP
);
357 know (symbolP
->sy_frag
== &zero_address_frag
);
358 demand_empty_rest_of_line ();
362 tc_gen_reloc (sec
, fixp
)
368 reloc
= (arelent
*) bfd_alloc_by_size_t (stdoutput
, sizeof (arelent
));
369 reloc
->sym_ptr_ptr
= &fixp
->fx_addsy
->bsym
;
370 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
372 if (fixp
->fx_r_type
> BFD_RELOC_UNUSED
)
375 if (fixp
->fx_r_type
== BFD_RELOC_ALPHA_GPDISP_HI16
)
377 if (!gpdisp_hi16_howto
)
378 gpdisp_hi16_howto
= bfd_reloc_type_lookup (stdoutput
,
380 reloc
->howto
= gpdisp_hi16_howto
;
383 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
384 assert (reloc
->howto
!= 0);
385 if (!fixp
->fx_pcrel
!= !reloc
->howto
->pc_relative
)
387 as_fatal ("internal error? cannot generate `%s' relocation",
388 bfd_get_reloc_code_name (fixp
->fx_r_type
));
390 assert (!fixp
->fx_pcrel
== !reloc
->howto
->pc_relative
);
392 if (fixp
->fx_r_type
== BFD_RELOC_ALPHA_LITERAL
)
394 /* fake out bfd_perform_relocation. sigh */
395 reloc
->addend
= -alpha_gp_value
;
397 else if (reloc
->howto
->pc_relative
&& reloc
->howto
->pcrel_offset
)
399 reloc
->addend
= fixp
->fx_offset
- reloc
->address
;
402 reloc
->addend
= fixp
->fx_offset
;
409 if (first_32bit_quadrant
)
411 /* not fatal, but it might not work in the end */
412 as_warn ("File overrides no-base-register option.");
413 first_32bit_quadrant
= 0;
417 if (*input_line_pointer
== '$')
419 input_line_pointer
++;
420 if (*input_line_pointer
== 'r')
421 input_line_pointer
++;
424 base_register
= get_absolute_expression ();
425 if (base_register
< 0 || base_register
> 31)
428 as_warn ("Bad base register, using $%d.", base_register
);
430 demand_empty_rest_of_line ();
433 static int in_range_signed (val
, nbits
)
437 /* Look at top bit of value that would be stored, figure out how it
438 would be extended by the hardware, and see if that matches the
439 original supplied value. */
442 bfd_vma top_bit
, stored_value
, missing_bits
;
444 mask
= (one
<< nbits
) - 1;
445 stored_value
= val
& mask
;
446 top_bit
= stored_value
& (one
<< nbits
- 1);
447 missing_bits
= val
& ~mask
;
448 /* will sign-extend */
451 /* all remaining bits beyond mask should be one */
452 missing_bits
|= mask
;
453 return missing_bits
+ 1 == 0;
457 /* all other bits should be zero */
458 return missing_bits
== 0;
463 static int in_range_unsigned (val
, nbits
)
467 /* Look at top bit of value that would be stored, figure out how it
468 would be extended by the hardware, and see if that matches the
469 original supplied value. */
472 bfd_vma top_bit
, stored_value
, missing_bits
;
474 mask
= (one
<< nbits
) - 1;
475 stored_value
= val
& mask
;
476 top_bit
= stored_value
& (one
<< nbits
- 1);
477 missing_bits
= val
& ~mask
;
478 return missing_bits
== 0;
493 e
.X_add_symbol
= section_symbol (absolute_section
);
504 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 4, &e
, 0,
509 create_literal_section (secp
, name
)
513 segT current_section
= now_seg
;
514 int current_subsec
= now_subseg
;
517 *secp
= new_sec
= subseg_new (name
, 0);
518 subseg_set (current_section
, current_subsec
);
519 bfd_set_section_alignment (stdoutput
, new_sec
, 3);
520 bfd_set_section_flags (stdoutput
, new_sec
,
521 SEC_RELOC
| SEC_ALLOC
| SEC_LOAD
| SEC_READONLY
526 get_lit8_offset (val
)
532 create_literal_section (&lit8_sec
, ".lit8");
533 lit8_sym
= section_symbol (lit8_sec
);
535 retval
= add_to_literal_pool ((symbolS
*) 0, val
, lit8_sec
, 8);
536 if (retval
>= 0xfff0)
537 as_fatal ("overflow in fp literal (.lit8) table");
542 get_lit4_offset (val
)
548 create_literal_section (&lit4_sec
, ".lit4");
549 lit4_sym
= section_symbol (lit4_sec
);
551 retval
= add_to_literal_pool ((symbolS
*) 0, val
, lit4_sec
, 4);
552 if (retval
>= 0xfff0)
553 as_fatal ("overflow in fp literal (.lit4) table");
557 #define load_insn(NAME, OP) (hash_insert (op_hash, (NAME), (PTR) (OP)))
560 load_insn_table (ops
, size
)
561 struct alpha_opcode
*ops
;
564 struct alpha_opcode
*end
= ops
+ size
;
565 struct alpha_opcode
*op
;
568 for (op
= ops
; op
< end
; )
574 retval
= load_insn (op
->name
, op
);
576 as_fatal ("internal error: can't hash opcode `%s': %s",
583 || !strcmp (op
->name
, name
)));
585 /* Some opcodes include modifiers of various sorts with a "/mod"
586 syntax, like the architecture documentation suggests. However,
587 for use with gcc at least, we also need to access those same
588 opcodes without the "/". */
589 for (op
= ops
; op
< end
; )
593 if (strchr (name
, '/'))
598 name2
= xmalloc (strlen (name
));
608 /* Ignore failures -- the opcode table does duplicate some
609 variants in different forms, like "hw_stq" and "hw_st/q".
610 Maybe the variants can be eliminated, and this error checking
612 load_insn (name2
, op
);
619 || !strcmp (op
->name
, name
)));
623 static struct alpha_it clear_insn
;
625 /* This function is called once, at assembler startup time. It should
626 set up all the tables, etc. that the MD part of the assembler will
627 need, that can be determined before arguments are parsed. */
633 op_hash
= hash_new ();
634 load_insn_table (alpha_opcodes
, NUMOPCODES
);
636 /* Default to 21064 PAL instructions. */
644 load_insn_table (alpha_pal21064_opcodes
, NUM21064OPCODES
);
647 load_insn_table (alpha_pal21164_opcodes
, NUM21164OPCODES
);
650 as_fatal ("palcode set unknown (internal error)");
653 lituse_basereg
.X_op
= O_constant
;
654 lituse_basereg
.X_add_number
= 1;
655 lituse_byteoff
.X_op
= O_constant
;
656 lituse_byteoff
.X_add_number
= 2;
657 lituse_jsr
.X_op
= O_constant
;
658 lituse_jsr
.X_add_number
= 3;
660 /* So .sbss will get used for tiny objects. */
661 bfd_set_gp_size (stdoutput
, 8);
662 create_literal_section (&lita_sec
, ".lita");
663 /* For handling the GP, create a symbol that won't be output in the
664 symbol table. We'll edit it out of relocs later. */
665 gp
= symbol_create ("<GP value>", lita_sec
, 0x8000, &zero_address_frag
);
667 memset (&clear_insn
, 0, sizeof (clear_insn
));
668 for (i
= 0; i
< MAX_RELOCS
; i
++)
669 clear_insn
.reloc
[i
].code
= BFD_RELOC_NONE
;
676 struct alpha_it
*insn
;
683 /* put out the opcode */
684 md_number_to_chars (toP
, insn
->opcode
, 4);
686 /* put out the symbol-dependent stuff */
687 for (j
= 0; j
< MAX_RELOCS
; j
++)
689 struct reloc_data
*r
= &insn
->reloc
[j
];
692 if (r
->code
!= BFD_RELOC_NONE
)
694 if (r
->exp
.X_op
== O_constant
)
696 r
->exp
.X_add_symbol
= section_symbol (absolute_section
);
697 r
->exp
.X_op
= O_symbol
;
699 f
= fix_new_exp (frag_now
, (toP
- frag_now
->fr_literal
), 4,
700 &r
->exp
, r
->pcrel
, r
->code
);
702 if (r
->code
== BFD_RELOC_ALPHA_GPDISP_LO16
)
704 static bit_fixS cookie
;
705 /* @@ This'll make the range checking in write.c shut up. */
706 f
->fx_bit_fixP
= &cookie
;
717 struct alpha_it insns
[MAX_INSNS
];
719 count
= alpha_ip (str
, insns
);
723 for (i
= 0; i
< count
; i
++)
724 emit_insn (&insns
[i
]);
734 vma
= bfd_get_section_vma (foo
, sec
);
735 if (vma
&& vma
< alpha_gp_value
)
736 alpha_gp_value
= vma
;
742 if (alpha_gp_value
!= 0)
745 /* Get minus-one in whatever width... */
746 alpha_gp_value
= 0; alpha_gp_value
--;
748 /* Select the smallest VMA of these existing sections. */
749 maybe_set_gp (lita_sec
);
750 /* maybe_set_gp (sdata); Was disabled before -- should we use it? */
752 maybe_set_gp (lit8_sec
);
753 maybe_set_gp (lit4_sec
);
756 alpha_gp_value
+= GP_ADJUSTMENT
;
758 S_SET_VALUE (gp
, alpha_gp_value
);
761 printf ("Chose GP value of %lx\n", alpha_gp_value
);
766 alpha_force_relocation (f
)
769 switch (f
->fx_r_type
)
771 case BFD_RELOC_ALPHA_GPDISP_HI16
:
772 case BFD_RELOC_ALPHA_GPDISP_LO16
:
773 case BFD_RELOC_ALPHA_LITERAL
:
774 case BFD_RELOC_ALPHA_LITUSE
:
775 case BFD_RELOC_GPREL32
:
777 case BFD_RELOC_ALPHA_HINT
:
782 case BFD_RELOC_23_PCREL_S2
:
793 alpha_fix_adjustable (f
)
796 /* Are there any relocation types for which we must generate a reloc
797 but we can adjust the values contained within it? */
798 switch (f
->fx_r_type
)
800 case BFD_RELOC_ALPHA_GPDISP_HI16
:
801 case BFD_RELOC_ALPHA_GPDISP_LO16
:
803 case BFD_RELOC_GPREL32
:
806 return !alpha_force_relocation (f
);
812 md_section_align (seg
, size
)
817 /* This should probably be handled within BFD, or by pulling the
818 number from BFD at least. */
826 /* Add this thing to the .lita section and produce a LITERAL reloc referring
829 /* Are we currently eligible to emit a LITUSE reloc for the literal
830 references just generated? */
831 static int lituse_pending
;
834 load_symbol_address (reg
, insn
)
836 struct alpha_it
*insn
;
838 static symbolS
*lita_sym
;
845 lita_sym
= section_symbol (lita_sec
);
846 S_CLEAR_EXTERNAL (lita_sym
);
849 retval
= add_to_literal_pool (insn
->reloc
[0].exp
.X_add_symbol
,
850 insn
->reloc
[0].exp
.X_add_number
,
853 /* Now emit a LITERAL relocation for the original section. */
854 insn
->reloc
[0].exp
.X_op
= O_symbol
;
855 insn
->reloc
[0].exp
.X_add_symbol
= lita_sym
;
856 insn
->reloc
[0].exp
.X_add_number
= retval
;
857 insn
->reloc
[0].code
= BFD_RELOC_ALPHA_LITERAL
;
860 if (retval
== 0x8000)
862 as_fatal ("overflow in literal (.lita) table");
865 insn
->opcode
= (0xa0000000 /* ldl */
867 | (base_register
<< SB
)
870 insn
->opcode
= (0xa4000000 /* ldq */
872 | (base_register
<< SB
)
874 note_gpreg (base_register
);
877 /* To load an address with a single instruction,
878 emit a LITERAL reloc in this section, and a REFQUAD
879 for the .lita section, so that we'll be able to access
881 lda REG, xx -> ldq REG, -32752(gp)
882 lda REG, xx+4 -> ldq REG, -32752(gp)
885 The offsets need to start near -0x8000, and the generated LITERAL
886 relocations should negate the offset. I don't completely grok the
890 load_expression (reg
, insn
)
892 struct alpha_it
*insn
;
894 valueT addend
, addendhi
, addendlo
;
897 if (insn
->reloc
[0].exp
.X_add_symbol
->bsym
->flags
& BSF_SECTION_SYM
)
903 addend
= insn
->reloc
[0].exp
.X_add_number
;
904 insn
->reloc
[0].exp
.X_add_number
= 0;
906 load_symbol_address (reg
, insn
);
909 if ((addend
& ~0x7fffffff) != 0
910 && (addend
& ~0x7fffffff) + 0x80000000 != 0)
912 as_bad ("assembler not prepared to handle constants >32 bits yet");
915 addendlo
= addend
& 0xffff;
917 addendhi
= addend
>> 16;
918 if (addendlo
& 0x8000)
920 /* It appears that the BASEREG LITUSE reloc should not be used on
921 an LDAH instruction. */
924 insn
[1].opcode
= (0x20000000 /* lda */
927 | (addendlo
& 0xffff));
928 insn
[1].reloc
[0].code
= BFD_RELOC_ALPHA_LITUSE
;
929 insn
[1].reloc
[0].exp
= lituse_basereg
;
934 insn
[num_insns
].opcode
= (0x24000000
937 | (addendhi
& 0xffff));
948 getExpression (str
, this_insn
)
950 struct alpha_it
*this_insn
;
955 #if 0 /* Not converted to bfd yet, and I don't think we need them
956 for ECOFF. Re-adding a.out support will probably require
958 static const struct am
{
960 bfd_reloc_code_real_type reloc
;
962 { "hi", RELOC_48_63
},
963 { "lo", RELOC_0_15
},
964 { "ml", RELOC_16_31
},
965 { "mh", RELOC_32_47
},
966 { "uhi", RELOC_U_48_63
},
967 { "uml", RELOC_U_16_31
},
968 { "umh", RELOC_U_32_47
},
972 /* Handle macros: "%macroname(expr)" */
983 while (*q
&& *p
== *q
)
991 str
= p
; /* keep the '(' */
992 this_insn
->reloc
= m
->reloc
;
997 save_in
= input_line_pointer
;
998 input_line_pointer
= str
;
1000 seg
= expression (&this_insn
->reloc
[0].exp
);
1001 /* XXX validate seg and exp, make sure they're reasonable */
1002 expr_end
= input_line_pointer
;
1003 input_line_pointer
= save_in
;
1007 emit_unaligned_io (dir
, addr_reg
, addr_offset
, reg
)
1013 sprintf (buf
, "%sq_u $%d,%ld($%d)", dir
, reg
, (long) addr_offset
, addr_reg
);
1018 emit_load_unal (addr_reg
, addr_offset
, reg
)
1022 emit_unaligned_io ("ld", addr_reg
, addr_offset
, reg
);
1026 emit_store_unal (addr_reg
, addr_offset
, reg
)
1030 emit_unaligned_io ("st", addr_reg
, addr_offset
, reg
);
1034 emit_byte_manip_r (op
, in
, mask
, out
, mode
, which
)
1036 int in
, mask
, out
, mode
, which
;
1039 sprintf (buf
, "%s%c%c $%d,$%d,$%d", op
, mode
, which
, in
, mask
, out
);
1044 emit_extract_r (in
, mask
, out
, mode
, which
)
1045 int in
, mask
, out
, mode
, which
;
1047 emit_byte_manip_r ("ext", in
, mask
, out
, mode
, which
);
1051 emit_insert_r (in
, mask
, out
, mode
, which
)
1052 int in
, mask
, out
, mode
, which
;
1054 emit_byte_manip_r ("ins", in
, mask
, out
, mode
, which
);
1058 emit_mask_r (in
, mask
, out
, mode
, which
)
1059 int in
, mask
, out
, mode
, which
;
1061 emit_byte_manip_r ("msk", in
, mask
, out
, mode
, which
);
1065 emit_sign_extend (reg
, size
)
1069 sprintf (buf
, "sll $%d,0x%x,$%d", reg
, 64 - size
, reg
);
1071 sprintf (buf
, "sra $%d,0x%x,$%d", reg
, 64 - size
, reg
);
1076 emit_bis_r (in1
, in2
, out
)
1080 sprintf (buf
, "bis $%d,$%d,$%d", in1
, in2
, out
);
1085 build_mem (opc
, ra
, rb
, disp
)
1087 bfd_signed_vma disp
;
1089 if ((disp
>> 15) != 0
1090 && (disp
>> 15) + 1 != 0)
1092 return ((opc
<< 26) | (ra
<< SA
) | (rb
<< SB
) | (disp
& 0xffff));
1096 build_operate_n (opc
, fn
, ra
, lit
, rc
)
1097 int opc
, fn
, ra
, rc
;
1102 return ((opc
<< 26) | (fn
<< 5) | (ra
<< SA
) | (lit
<< SN
) | (1 << 12) | (rc
<< SC
));
1106 emit_sll_n (dest
, disp
, src
)
1107 int dest
, disp
, src
;
1109 struct alpha_it insn
= clear_insn
;
1110 insn
.opcode
= build_operate_n (0x12, 0x39, src
, disp
, dest
);
1115 emit_ldah_num (dest
, addend
, src
)
1119 struct alpha_it insn
= clear_insn
;
1120 insn
.opcode
= build_mem (0x09, dest
, src
, addend
);
1125 emit_addq_r (in1
, in2
, out
)
1128 struct alpha_it insn
= clear_insn
;
1129 insn
.opcode
= 0x40000400 | (in1
<< SA
) | (in2
<< SB
) | (out
<< SC
);
1134 emit_lda_n (dest
, addend
, src
)
1138 struct alpha_it insn
= clear_insn
;
1139 insn
.opcode
= build_mem (0x08, dest
, src
, addend
);
1144 emit_add64 (in
, out
, num
)
1148 bfd_signed_vma snum
= num
;
1150 if (in_range_signed (num
, 16))
1152 emit_lda_n (out
, num
, in
);
1155 if ((num
& 0xffff) == 0
1157 && in_range_signed (snum
>> 16, 16))
1159 emit_ldah_num (out
, snum
>> 16, in
);
1162 /* I'm not sure this one is getting invoked when it could. */
1163 if ((num
& 1) == 0 && in
== ZERO
)
1165 if (in_range_signed (snum
>> 1, 16))
1167 emit_lda_n (out
, snum
>> 1, in
);
1168 emit_addq_r (out
, out
, out
);
1171 else if (num
& 0x1fffe == 0
1172 && in_range_signed (snum
>> 17, 16))
1174 emit_ldah_num (out
, snum
>> 17, in
);
1175 emit_addq_r (out
, out
, out
);
1179 if (in_range_signed (num
, 32))
1181 bfd_vma lo
= num
& 0xffff;
1185 emit_ldah_num (out
, snum
>> 16, in
);
1187 emit_lda_n (out
, lo
, out
);
1191 if (in
!= ZERO
&& in
!= AT
&& out
!= AT
&& at_ok
)
1193 emit_add64 (ZERO
, AT
, num
);
1194 emit_addq_r (AT
, in
, out
);
1199 as_bad ("load expression too complex to expand");
1201 /* Could check also for loading 16- or 32-bit value and shifting by
1202 arbitrary displacement. */
1205 bfd_vma lo
= snum
& 0xffffffff;
1206 if (lo
& 0x80000000)
1207 lo
-= ((bfd_vma
)0x10000000 << 4);
1209 emit_add64 (ZERO
, out
, snum
>> 32);
1210 emit_sll_n (out
, 32, out
);
1212 emit_add64 (out
, out
, lo
);
1217 alpha_ip (str
, insns
)
1219 struct alpha_it insns
[];
1225 struct alpha_opcode
*pattern
;
1227 unsigned int opcode
;
1229 int match
= 0, num_gen
= 1;
1231 int do_add64
, add64_in
, add64_out
;
1232 bfd_vma add64_addend
;
1235 islower (*s
) || *s
== '_' || *s
== '/' || *s
== '4' || *s
== '8';
1254 as_fatal ("Unknown opcode: `%s'", str
);
1256 if ((pattern
= (struct alpha_opcode
*) hash_find (op_hash
, str
)) == NULL
)
1258 as_bad ("Unknown opcode: `%s'", str
);
1268 opcode
= pattern
->match
;
1270 for (i
= 0; i
< MAX_INSNS
; i
++)
1271 insns
[i
] = clear_insn
;
1273 /* Build the opcode, checking as we go to make sure that the
1275 for (args
= pattern
->args
;; ++args
)
1280 case '\0': /* end of args */
1299 case '(': /* these must match exactly */
1308 case '1': /* next operand must be a register */
1318 case 'a': /* $at: as temporary */
1324 case 'g': /* $gp: base register */
1327 mask
= base_register
;
1330 case 's': /* $sp: stack pointer */
1337 case 'r': /* any register */
1338 if (!isdigit (c
= *s
++))
1355 if ((c
= 10 * (c
- '0') + (*s
++ - '0')) >= 32)
1364 if ((c
== GP
) && first_32bit_quadrant
)
1374 /* Got the register, now figure out where it goes in
1382 opcode
|= mask
<< SA
;
1387 opcode
|= mask
<< SB
;
1396 opcode
|= (mask
<< SA
) | mask
;
1399 case 'R': /* ra and rb are the same */
1400 opcode
|= (mask
<< SA
) | (mask
<< SB
);
1404 opcode
|= (mask
<< SA
) | (mask
<< SB
) | (mask
);
1410 case 'e': /* next operand is a floating point register */
1414 if (*s
++ == '$' && *s
++ == 'f' && isdigit (*s
))
1419 mask
= 10 * (mask
- '0') + (*s
++ - '0');
1430 /* same encoding as gp registers */
1436 case 'h': /* bits 16..31 */
1437 insns
[0].reloc
= RELOC_16_31
;
1441 case 'l': /* bits 0..15 */
1442 insns
[0].reloc
[0].code
= BFD_RELOC_16
;
1445 case 'L': /* 21 bit PC relative immediate */
1446 insns
[0].reloc
[0].code
= BFD_RELOC_23_PCREL_S2
;
1447 insns
[0].reloc
[0].pcrel
= 1;
1450 case 'i': /* 14 bit immediate */
1451 if (OPCODE (opcode
) != 0x1a)
1452 /* Not a jmp variant?? */
1454 else if (opcode
& 0x8000)
1455 /* ret or jsr_coroutine */
1457 insns
[0].reloc
[0].code
= BFD_RELOC_14
;
1458 insns
[0].reloc
[0].pcrel
= 0;
1463 insns
[0].reloc
[0].code
= BFD_RELOC_ALPHA_HINT
;
1464 insns
[0].reloc
[0].pcrel
= 1;
1468 case 'b': /* 8 bit immediate */
1469 insns
[0].reloc
[0].code
= BFD_RELOC_8
;
1472 case 'I': /* 26 bit immediate, for PALcode */
1473 insns
[0].reloc
[0].code
= BFD_RELOC_26
;
1476 case 't': /* 12 bit displacement, for PALcode */
1477 insns
[0].reloc
[0].code
= BFD_RELOC_12_PCREL
;
1480 case '8': /* 8 bit 0...7 */
1481 insns
[0].reloc
[0].code
= BFD_RELOC_8
;
1487 getExpression (s
, &insns
[0]);
1489 /* Handle overflow in certain instructions by converting
1490 to other instructions. */
1491 if (insns
[0].reloc
[0].code
== BFD_RELOC_8
1492 && insns
[0].reloc
[0].exp
.X_op
== O_constant
1493 && (insns
[0].reloc
[0].exp
.X_add_number
< 0
1494 || insns
[0].reloc
[0].exp
.X_add_number
> 0xff))
1496 if (OPCODE (opcode
) == 0x10
1497 && (OP_FCN (opcode
) == 0x00 /* addl */
1498 || OP_FCN (opcode
) == 0x40 /* addl/v */
1499 || OP_FCN (opcode
) == 0x20 /* addq */
1500 || OP_FCN (opcode
) == 0x60 /* addq/v */
1501 || OP_FCN (opcode
) == 0x09 /* subl */
1502 || OP_FCN (opcode
) == 0x49 /* subl/v */
1503 || OP_FCN (opcode
) == 0x29 /* subq */
1504 || OP_FCN (opcode
) == 0x69 /* subq/v */
1505 || OP_FCN (opcode
) == 0x02 /* s4addl */
1506 || OP_FCN (opcode
) == 0x22 /* s4addq */
1507 || OP_FCN (opcode
) == 0x0b /* s4subl */
1508 || OP_FCN (opcode
) == 0x2b /* s4subq */
1509 || OP_FCN (opcode
) == 0x12 /* s8addl */
1510 || OP_FCN (opcode
) == 0x32 /* s8addq */
1511 || OP_FCN (opcode
) == 0x1b /* s8subl */
1512 || OP_FCN (opcode
) == 0x3b /* s8subq */
1514 /* Can we make it fit by negating? */
1515 && -insns
[0].reloc
[0].exp
.X_add_number
< 0xff
1516 && -insns
[0].reloc
[0].exp
.X_add_number
> 0)
1518 opcode
^= 0x120; /* convert add<=>sub */
1519 insns
[0].reloc
[0].exp
.X_add_number
*= -1;
1521 else if (at_ok
&& macro_ok
)
1523 /* Constant value supplied, but it's too large. */
1527 add64_addend
= insns
[0].reloc
[0].exp
.X_add_number
;
1529 opcode
|= (AT
<< SB
);
1530 insns
[0].reloc
[0].code
= BFD_RELOC_NONE
;
1533 as_bad ("overflow in 8-bit literal field in `operate' format insn");
1535 else if (insns
[0].reloc
[0].code
== BFD_RELOC_16
1536 && insns
[0].reloc
[0].exp
.X_op
== O_constant
1537 && !in_range_signed (insns
[0].reloc
[0].exp
.X_add_number
,
1540 bfd_vma val
= insns
[0].reloc
[0].exp
.X_add_number
;
1541 if (OPCODE (opcode
) == 0x08)
1548 opcode
|= (AT
<< SB
);
1549 insns
[0].reloc
[0].code
= BFD_RELOC_NONE
;
1551 else if (OPCODE (opcode
) == 0x09
1552 && in_range_signed (val
>> 16, 16))
1554 /* ldah with high operand - convert to low */
1555 insns
[0].reloc
[0].exp
.X_add_number
>>= 16;
1558 as_bad ("I don't know how to handle 32+ bit constants here yet, sorry.");
1560 else if (insns
[0].reloc
[0].code
== BFD_RELOC_32
1561 && insns
[0].reloc
[0].exp
.X_op
== O_constant
)
1563 bfd_vma val
= insns
[0].reloc
[0].exp
.X_add_number
;
1564 bfd_signed_vma sval
= val
;
1567 && sval
>> 32 != -1)
1568 as_bad ("I don't know how to handle 64 bit constants here yet, sorry.");
1574 int format
, length
, mode
, i
;
1575 char temp
[20 /*MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT*/];
1577 static const char formats
[4] = "FGfd";
1578 bfd_vma bits
, offset
;
1579 char *old_input_line_pointer
= input_line_pointer
;
1581 input_line_pointer
= s
;
1583 memset (temp
, 0, sizeof (temp
));
1584 mode
= (opcode
>> 26) & 3;
1585 format
= formats
[mode
];
1586 err
= md_atof (format
, temp
, &length
);
1589 as_bad ("Bad floating literal: %s", err
);
1594 /* Generate little-endian number from byte sequence. */
1596 for (i
= length
- 1; i
>= 0; i
--)
1597 bits
+= ((bfd_vma
)(temp
[i
] & 0xff)) << (i
* 8);
1602 offset
= get_lit8_offset (bits
) - 0x8000;
1603 insns
[0].reloc
[0].exp
.X_add_symbol
= lit8_sym
;
1604 insns
[0].reloc
[0].exp
.X_add_number
= 0x8000;
1607 offset
= get_lit4_offset (bits
) - 0x8000;
1608 insns
[0].reloc
[0].exp
.X_add_symbol
= lit4_sym
;
1609 insns
[0].reloc
[0].exp
.X_add_number
= 0x8000;
1614 insns
[0].reloc
[0].exp
.X_op
= O_symbol
;
1616 num_gen
= load_expression (AT
, &insns
[0]);
1619 insns
[num_gen
].reloc
[0].code
= BFD_RELOC_ALPHA_LITUSE
;
1620 insns
[num_gen
].reloc
[0].exp
= lituse_basereg
;
1623 insns
[num_gen
++].opcode
= opcode
| (AT
<< SB
) | offset
;
1624 opcode
= insns
[0].opcode
;
1625 s
= input_line_pointer
;
1626 input_line_pointer
= old_input_line_pointer
;
1630 /* The following two.. take advantage of the fact that
1631 opcode already contains most of what we need to know.
1632 We just prepend to the instr an "ldah
1633 $r,%ml(expr)($base)" and turn this one (done later
1634 after we return) into something like "stq
1635 $r,%lo(expr)(at)" or "ldq $r,%lo(expr)($r)".
1637 NOTE: This can fail later on at link time if the
1638 offset from $base actually turns out to be more than
1639 2**31 or 2**47 if use_large_offsets is set. */
1640 case 'P': /* Addressing macros: PUT */
1641 mask
= AT
; /* register 'at' */
1644 case 'G': /* Addressing macros: GET */
1645 /* All it is missing is the expression, which is what we
1650 getExpression (s
, &insns
[0]);
1653 /* Must check for "lda ..,number" too */
1654 if (insns
[0].reloc
[0].exp
.X_op
== O_big
)
1656 as_warn ("Sorry, not yet. Put bignums in .data section yourself.");
1659 if (insns
[0].reloc
[0].exp
.X_op
== O_constant
)
1661 bfd_vma val
= insns
[0].reloc
[0].exp
.X_add_number
;
1664 insns
[0].reloc
[0].code
= BFD_RELOC_NONE
;
1665 insns
[1].reloc
[0].code
= BFD_RELOC_NONE
;
1680 opcode
|= ZERO
<< SB
;
1682 opcode
|= low
& 0xffff;
1684 else if (insns
[0].reloc
[0].exp
.X_op
== O_symbol
)
1686 unsigned long old_opcode
= opcode
;
1690 as_bad ("insn requires expansion but `nomacro' specified");
1691 else if (*args
== 'G')
1694 as_bad ("insn expansion requires AT use, but `noat' specified");
1697 num_gen
= load_expression (tmp_reg
, insns
);
1698 opcode
= insns
[0].opcode
;
1699 /* lda is opcode 8, 0x20000000, and the macros that use
1700 this code have an opcode field of 0. The latter
1701 require further processing, and we don't have the
1702 true opcode here. */
1703 if (OPCODE (old_opcode
) != 0
1704 && OPCODE (old_opcode
) != 0x08)
1707 i
= &insns
[num_gen
++];
1708 i
->opcode
= old_opcode
| (tmp_reg
<< SB
);
1712 i
->reloc
[0].code
= BFD_RELOC_ALPHA_LITUSE
;
1713 i
->reloc
[0].exp
= lituse_basereg
;
1722 insns
[1].reloc
[0].exp
= insns
[0].reloc
[0].exp
;
1724 /* Generate: ldah REG,x1(GP); OP ?,x0(REG) */
1726 abort (); /* relocs need fixing */
1728 insns
[1].reloc
= RELOC_0_15
;
1729 insns
[1].opcode
= opcode
| mask
<< SB
;
1731 insns
[0].reloc
= RELOC_16_31
;
1732 opcode
= 0x24000000 /*ldah*/ | mask
<< SA
| (base_register
<< SB
);
1738 /* Same failure modes as above, actually most of the
1739 same code shared. */
1740 case 'B': /* Builtins */
1745 case 'a': /* ldgp */
1747 if (first_32bit_quadrant
|| no_mixed_code
)
1749 switch (OUTPUT_FLAVOR
)
1751 case bfd_target_aout_flavour
:
1752 /* this is cmu's a.out version */
1753 insns
[0].reloc
[0].code
= BFD_RELOC_NONE
;
1754 /* generate "zap %r,0xf,%r" to take high 32 bits */
1755 opcode
|= 0x48001600 /* zap ?,#,?*/ | (0xf << SN
);
1757 case bfd_target_ecoff_flavour
:
1758 /* Given "ldgp R1,N(R2)", turn it into something
1759 like "ldah R1,###(R2) ; lda R1,###(R1)" with
1760 appropriate constants and relocations. */
1762 unsigned long r1
, r2
;
1763 unsigned long addend
= 0;
1768 insns
[0].reloc
[0].code
= BFD_RELOC_ALPHA_GPDISP_HI16
;
1769 insns
[0].reloc
[0].pcrel
= 1;
1770 insns
[0].reloc
[0].exp
.X_op
= O_symbol
;
1771 insns
[0].reloc
[0].exp
.X_add_symbol
= gp
;
1772 insns
[0].reloc
[0].exp
.X_add_number
= 0;
1773 insns
[0].opcode
= (0x24000000 /* ldah */
1776 insns
[1].reloc
[0].code
= BFD_RELOC_ALPHA_GPDISP_LO16
;
1777 insns
[1].reloc
[0].exp
.X_op
= O_symbol
;
1778 insns
[1].reloc
[0].exp
.X_add_symbol
= gp
;
1779 insns
[1].reloc
[0].exp
.X_add_number
= 4;
1780 insns
[1].reloc
[0].pcrel
= 1;
1781 insns
[1].opcode
= 0x20000000 | (r1
<< SA
) | (r1
<< SB
);
1782 opcode
= insns
[0].opcode
;
1783 /* merge in addend */
1784 insns
[1].opcode
|= addend
& 0xffff;
1785 insns
[0].opcode
|= ((addend
>> 16)
1786 + (addend
& 0x8000 ? 1 : 0));
1788 ecoff_set_gp_prolog_size (0);
1797 case 'b': /* setgp */
1798 switch (OUTPUT_FLAVOR
)
1800 case bfd_target_aout_flavour
:
1801 /* generate "zap %r,0xf,$gp" to take high 32 bits */
1802 opcode
|= 0x48001600 /* zap ?,#,?*/
1803 | (0xf << SN
) | (base_register
);
1810 case 'c': /* jsr $r,foo becomes
1813 Register 27, t12, is used by convention
1816 struct alpha_it
*jsr
;
1818 struct reloc_data
*r
;
1820 /* We still have to parse the function name */
1823 getExpression (s
, &insns
[0]);
1824 etmp
= insns
[0].reloc
[0].exp
;
1826 num_gen
= load_expression (PV
, &insns
[0]);
1829 jsr
= &insns
[num_gen
++];
1830 jsr
->opcode
= (pattern
->match
1836 /* LITUSE wasn't emitted yet */
1837 jsr
->reloc
[0].code
= BFD_RELOC_ALPHA_LITUSE
;
1838 jsr
->reloc
[0].exp
= lituse_jsr
;
1845 r
->code
= BFD_RELOC_ALPHA_HINT
;
1847 opcode
= insns
[0].opcode
;
1852 /* Sub-word loads and stores. We load the address into
1853 $at, which might involve using the `P' parameter
1854 processing too, then emit a sequence to get the job
1855 done, using unaligned memory accesses and byte
1856 manipulation, with t9 and t10 as temporaries. */
1858 /* Characteristics of access. */
1859 int is_load
, is_unsigned
= 0, is_unaligned
= 0;
1860 int mode_size
, mode
;
1861 /* Register operand. */
1863 /* Addend for loads and stores. */
1865 /* Which register do we use for the address? */
1869 /* Pick apart name and set flags. */
1870 const char *s
= pattern
->name
;
1878 if (s
[0] == 'l' && s
[1] == 'd')
1880 else if (s
[0] == 's' && s
[1] == 't')
1883 as_fatal ("unrecognized sub-word access insn `%s'",
1888 if (mode
== 'b') mode_size
= 1;
1889 else if (mode
== 'w') mode_size
= 2;
1890 else if (mode
== 'l') mode_size
= 4;
1891 else if (mode
== 'q') mode_size
= 8;
1902 /* Longwords are always kept sign-extended. */
1903 if (mode
== 'l' && is_unsigned
)
1905 /* There's no special unaligned byte handling. */
1906 if (mode
== 'b' && is_unaligned
)
1908 /* Stores don't care about signedness. */
1909 if (!is_load
&& is_unsigned
)
1913 if (args
[-2] == 'P')
1922 r1 -> (opcode >> SA) & 31
1923 num -> insns->reloc[0].*
1925 We want to emit "lda at,num(r2)", since these
1926 operations require the use of a single register
1927 with the starting address of the memory operand
1930 We could probably get away without doing this
1931 (and use r2 below, with the addend for the
1932 actual reads and writes) in cases where the
1933 addend is known to be a multiple of 8. */
1935 int r1
= (opcode
>> SA
) & 31;
1937 if (insns
[0].reloc
[0].code
== BFD_RELOC_NONE
)
1939 else if (insns
[0].reloc
[0].code
== BFD_RELOC_16
)
1941 if (insns
[0].reloc
[0].exp
.X_op
!= O_constant
)
1943 addend
= insns
[0].reloc
[0].exp
.X_add_number
;
1948 if (addend
+ mode_size
- 1 < 0x7fff
1949 && (addend
% 8) == 0
1950 && (r2
< T9
|| r2
> T12
))
1957 /* Let later relocation processing deal
1958 with the addend field. */
1959 insns
[num_gen
-1].opcode
= (0x20000000 /* lda */
1968 /* Because the emit_* routines append directly to
1969 the current frag, we now need to flush any
1973 for (i
= 0; i
< num_gen
; i
++)
1974 emit_insn (&insns
[i
]);
1983 reg2
= T9
, reg3
= T10
;
1987 emit_load_unal (addr
, addend
, T9
);
1989 emit_load_unal (addr
, addend
+ mode_size
- 1, T10
);
1990 emit_extract_r (T9
, addr
, reg2
, mode
, 'l');
1993 emit_extract_r (T10
, addr
, reg3
, mode
, 'h');
1994 emit_bis_r (T9
, T10
, reg
);
1997 emit_sign_extend (reg
, mode_size
* 8);
2001 /* The second word gets processed first
2002 because if the address does turn out to be
2003 aligned, the processing for the second word
2004 will be pushing around all-zeros, and the
2005 entire value will be handled as the `first'
2006 word. So we want to store the `first' word
2008 /* Pair these up so that the memory loads get
2009 separated from each other, as well as being
2010 well in advance of the uses of the values
2014 emit_load_unal (addr
, addend
+ mode_size
- 1, T11
);
2015 emit_insert_r (reg
, addr
, T12
, mode
, 'h');
2017 emit_load_unal (addr
, addend
, T9
);
2018 emit_insert_r (reg
, addr
, T10
, mode
, 'l');
2020 emit_mask_r (T12
, addr
, T12
, mode
, 'h');
2021 emit_mask_r (T10
, addr
, T10
, mode
, 'l');
2023 emit_bis_r (T11
, T12
, T11
);
2024 emit_bis_r (T9
, T10
, T9
);
2026 emit_store_unal (addr
, addend
+ mode_size
- 1, T11
);
2027 emit_store_unal (addr
, addend
, T9
);
2032 /* DIVISION and MODULUS. Yech.
2033 Convert OP x,y,result
2039 with appropriate optimizations if t10,t11,t12
2040 are the registers specified by the compiler.
2041 We are missing an obvious optimization
2042 opportunity here; if the ldq generated by the
2043 jsr assembly requires a cycle or two to make
2044 the value available, initiating it before one
2045 or two of the mov instructions would result in
2046 faster execution. */
2047 case '0': /* reml */
2048 case '1': /* divl */
2049 case '2': /* remq */
2050 case '3': /* divq */
2051 case '4': /* remlu */
2052 case '5': /* divlu */
2053 case '6': /* remqu */
2054 case '7': /* divqu */
2056 static char func
[8][6] = {
2057 "reml", "divl", "remq", "divq",
2058 "remlu", "divlu", "remqu", "divqu"
2063 /* All regs parsed, in opcode */
2065 /* Do the expansions, one instr at a time */
2067 reg
= (opcode
>> SA
) & 31;
2071 sprintf (expansion
, "mov $%d,$%d", reg
, T10
);
2072 md_assemble (expansion
);
2074 reg
= (opcode
>> SB
) & 31;
2076 /* we already overwrote it! */
2078 else if (reg
!= T11
)
2081 sprintf (expansion
, "mov $%d,$%d", reg
, T11
);
2082 md_assemble (expansion
);
2084 sprintf (expansion
, "lda $%d,__%s", PV
, func
[*args
- '0']);
2085 md_assemble (expansion
);
2086 sprintf (expansion
, "jsr $%d,($%d),__%s", T9
, PV
,
2088 md_assemble (expansion
);
2090 if (!first_32bit_quadrant
)
2095 md_assemble (expansion
);
2098 sprintf (expansion
, "ldgp $%d,0($%d)",
2100 md_assemble (expansion
);
2102 /* Use insns[0] to get at the result */
2103 if ((reg
= (opcode
& 31)) != PV
)
2104 opcode
= (0x47e00400 /* or zero,zero,zero */
2106 | reg
/* Rc */ ); /* pv->z */
2122 /* Args don't match. */
2123 if (&pattern
[1] - alpha_opcodes
< NUMOPCODES
2124 && !strcmp (pattern
->name
, pattern
[1].name
))
2132 as_warn ("Illegal operands");
2138 /* Args match, see if a float instructions and -nofloats */
2139 if (nofloats
&& pattern
->isa_float
)
2147 emit_add64 (add64_in
, add64_out
, add64_addend
);
2150 insns
[0].opcode
= opcode
;
2154 /* Turn a string in input_line_pointer into a floating point constant
2155 of type type, and store the appropriate bytes in *litP. The number
2156 of LITTLENUMS emitted is stored in *sizeP. An error message is
2157 returned, or NULL on OK. */
2159 /* Equal to MAX_PRECISION in atof-ieee.c */
2160 #define MAX_LITTLENUMS 6
2163 md_atof (type
, litP
, sizeP
)
2169 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
2170 LITTLENUM_TYPE
*wordP
;
2172 char *atof_ieee (), *vax_md_atof ();
2178 /* VAX md_atof doesn't like "G" for some reason. */
2182 return vax_md_atof (type
, litP
, sizeP
);
2205 return "Bad call to MD_ATOF()";
2207 t
= atof_ieee (input_line_pointer
, type
, words
);
2209 input_line_pointer
= t
;
2210 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
2212 for (wordP
= words
+ prec
- 1; prec
--;)
2214 md_number_to_chars (litP
, (long) (*wordP
--), sizeof (LITTLENUM_TYPE
));
2215 litP
+= sizeof (LITTLENUM_TYPE
);
2222 md_bignum_to_chars (buf
, bignum
, nchars
)
2224 LITTLENUM_TYPE
*bignum
;
2229 LITTLENUM_TYPE work
= *bignum
++;
2230 int nb
= CHARS_PER_LITTLENUM
;
2234 *buf
++ = work
& ((1 << BITS_PER_CHAR
) - 1);
2237 work
>>= BITS_PER_CHAR
;
2243 CONST
char *md_shortopts
= "Fm:";
2244 struct option md_longopts
[] = {
2245 #define OPTION_32ADDR (OPTION_MD_BASE)
2246 {"32addr", no_argument
, NULL
, OPTION_32ADDR
},
2247 {NULL
, no_argument
, NULL
, 0}
2249 size_t md_longopts_size
= sizeof(md_longopts
);
2252 md_parse_option (c
, arg
)
2270 if (!strcmp (arg
, "21064"))
2272 else if (!strcmp (arg
, "21066"))
2274 else if (!strcmp (arg
, "21164"))
2278 as_bad ("invalid architecture %s", arg
);
2282 if (machine
!= 0 && machine
!= mach
)
2284 as_warn ("machine type %lu already chosen, overriding with %lu",
2299 md_show_usage (stream
)
2304 -32addr treat addresses as 32-bit values\n\
2305 -F lack floating point instructions support\n\
2306 -m21064 | -m21066 | -m21164\n\
2307 specify variant of Alpha architecture\n");
2314 /* XXXX Align to cache linesize XXXXX */
2321 /* Takes ".proc name,nargs" */
2322 name
= input_line_pointer
;
2323 c
= get_symbol_end ();
2324 p
= input_line_pointer
;
2325 symbolP
= symbol_find_or_make (name
);
2328 if (*input_line_pointer
!= ',')
2331 as_warn ("Expected comma after name \"%s\"", name
);
2334 ignore_rest_of_line ();
2338 input_line_pointer
++;
2339 temp
= get_absolute_expression ();
2341 /* symbolP->sy_other = (signed char) temp; */
2342 as_warn ("unhandled: .proc %s,%d", name
, temp
);
2343 demand_empty_rest_of_line ();
2350 char *name
= input_line_pointer
, ch
, *s
;
2353 while (!is_end_of_line
[(unsigned char) *input_line_pointer
])
2354 input_line_pointer
++;
2355 ch
= *input_line_pointer
;
2356 *input_line_pointer
= '\0';
2359 if (s
[0] == 'n' && s
[1] == 'o')
2364 if (!strcmp ("reorder", s
))
2366 else if (!strcmp ("at", s
))
2368 else if (!strcmp ("macro", s
))
2370 else if (!strcmp ("move", s
))
2372 else if (!strcmp ("volatile", s
))
2375 as_warn ("Tried to .set unrecognized mode `%s'", name
);
2376 *input_line_pointer
= ch
;
2377 demand_empty_rest_of_line ();
2380 /* @@ Is this right?? */
2382 md_pcrel_from (fixP
)
2385 valueT addr
= fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
2386 switch (fixP
->fx_r_type
)
2388 case BFD_RELOC_ALPHA_GPDISP_HI16
:
2389 case BFD_RELOC_ALPHA_GPDISP_LO16
:
2392 return fixP
->fx_size
+ addr
;
2397 alpha_do_align (n
, fill
)
2402 && (now_seg
== text_section
2403 || !strcmp (now_seg
->name
, ".init")
2404 || !strcmp (now_seg
->name
, ".fini")))
2406 static const unsigned char nop_pattern
[] = { 0x1f, 0x04, 0xff, 0x47 };
2407 frag_align_pattern (n
, nop_pattern
, sizeof (nop_pattern
));
2414 md_apply_fix (fixP
, valueP
)
2421 char *p
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
2425 switch (fixP
->fx_r_type
)
2427 /* The GPDISP relocations are processed internally with a symbol
2428 referring to the current function; we need to drop in a value
2429 which, when added to the address of the start of the function,
2430 gives the desired GP. */
2431 case BFD_RELOC_ALPHA_GPDISP_HI16
:
2432 case BFD_RELOC_ALPHA_GPDISP_LO16
:
2434 if (fixP
->fx_r_type
== BFD_RELOC_ALPHA_GPDISP_HI16
)
2436 assert (fixP
->fx_next
->fx_r_type
== BFD_RELOC_ALPHA_GPDISP_LO16
);
2439 fprintf_vma (stdout
, addend
);
2442 if (addend
& 0x8000)
2445 fixP
->fx_offset
= 4; /* @@ Compute this using fx_next. */
2451 fprintf_vma (stdout
, addend
);
2455 fixP
->fx_offset
= 0;
2457 md_number_to_chars (fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
,
2459 fixP
->fx_addsy
= section_symbol (absolute_section
);
2460 fixP
->fx_offset
+= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
2464 /* Write 8 bits, shifted left 13 bit positions. */
2468 *p
|= (value
<< 5) & 0xe0;
2476 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2477 "overflow in type-%d reloc", (int) fixP
->fx_r_type
);
2487 /* Don't want overflow checking. */
2490 if (fixP
->fx_pcrel
== 0
2491 && fixP
->fx_addsy
== 0)
2493 md_number_to_chars (p
, value
, size
);
2494 /* @@ Overflow checks?? */
2500 if (fixP
->fx_addsy
!= 0
2501 && fixP
->fx_addsy
->bsym
->section
!= absolute_section
)
2502 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2503 "PALcode instructions require immediate constant function code");
2504 else if (value
>> 26 != 0)
2505 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2506 "overflow in 26-bit PALcode function field");
2507 *p
++ = value
& 0xff;
2509 *p
++ = value
& 0xff;
2511 *p
++ = value
& 0xff;
2522 if (fixP
->fx_addsy
!= 0
2523 && fixP
->fx_addsy
->bsym
->section
!= absolute_section
)
2524 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2525 "ret/jsr_coroutine requires constant in displacement field");
2526 else if (value
>> 14 != 0)
2527 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2528 "overflow in 14-bit operand field of ret or jsr_coroutine");
2529 *p
++ = value
& 0xff;
2531 *p
= (*p
& 0xc0) | (value
& 0x3f);
2534 case BFD_RELOC_23_PCREL_S2
:
2535 /* Write 21 bits only. */
2537 *p
++ = value
& 0xff;
2539 *p
++ = value
& 0xff;
2542 *p
|= (value
& 0x1f);
2545 case BFD_RELOC_12_PCREL
:
2546 *p
++ = value
& 0xff;
2549 *p
|= (value
& 0x0f);
2552 case BFD_RELOC_ALPHA_LITERAL
:
2553 case BFD_RELOC_ALPHA_LITUSE
:
2556 case BFD_RELOC_GPREL32
:
2557 assert (fixP
->fx_subsy
== gp
);
2558 value
= - alpha_gp_value
; /* huh? this works... */
2560 md_number_to_chars (p
, value
, 4);
2563 case BFD_RELOC_ALPHA_HINT
:
2564 if (fixP
->fx_addsy
== 0 && fixP
->fx_pcrel
== 0)
2572 as_fatal ("unhandled relocation type %s",
2573 bfd_get_reloc_code_name (fixP
->fx_r_type
));
2577 if (fixP
->fx_addsy
== 0 && fixP
->fx_pcrel
== 0)
2579 printf ("type %d reloc done?\n", fixP
->fx_r_type
);
2589 alpha_frob_ecoff_data ()
2592 /* $zero and $f31 are read-only */
2593 alpha_gprmask
&= ~1;
2594 alpha_fprmask
&= ~1;
2597 /* The Alpha has support for some VAX floating point types, as well as for
2598 IEEE floating point. We consider IEEE to be the primary floating point
2599 format, and sneak in the VAX floating point support here. */
2600 #define md_atof vax_md_atof
2601 #include "config/atof-vax.c"