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 const relax_typeS md_relax_table
[1];
69 int md_short_jump_size
= 4;
70 int md_long_jump_size
= 4;
72 /* handle of the OPCODE hash table */
73 static struct hash_control
*op_hash
;
75 /* Sections and symbols we'll want to keep track of. */
76 static segT lita_sec
, rdata
, sdata
, lit8_sec
, lit4_sec
;
77 static symbolS
*lit8_sym
, *lit4_sym
;
79 /* Setting for ".set [no]{at,macro}". */
80 static int at_ok
= 1, macro_ok
= 1;
82 /* Keep track of global pointer. */
83 valueT alpha_gp_value
;
86 /* We'll probably be using this relocation frequently, and we
87 will want to compare for it. */
88 static const reloc_howto_type
*gpdisp_hi16_howto
;
90 /* These are exported to ECOFF code. */
91 unsigned long alpha_gprmask
, alpha_fprmask
;
93 /* Used for LITUSE relocations. */
94 static expressionS lituse_basereg
, lituse_byteoff
, lituse_jsr
;
96 /* Address size: In OSF/1 1.3, an undocumented "-32addr" option will
97 cause all addresses to be treated as 32-bit values in memory. (The
98 in-register versions are all sign-extended to 64 bits, of course.)
99 Some other systems may want this option too. */
102 /* Imported functions -- they should be defined in header files somewhere. */
103 extern segT
subseg_get ();
104 extern PTR
bfd_alloc_by_size_t ();
105 extern void s_globl (), s_long (), s_short (), s_space (), cons (), s_text (),
106 s_data (), float_cons ();
108 /* Static functions, needing forward declarations. */
109 static void s_base (), s_proc (), s_alpha_set ();
110 static void s_gprel32 (), s_rdata (), s_sdata (), s_alpha_comm ();
111 static int alpha_ip ();
113 static void emit_unaligned_io
PARAMS ((char *, int, valueT
, int));
114 static void emit_load_unal
PARAMS ((int, valueT
, int));
115 static void emit_store_unal
PARAMS ((int, valueT
, int));
116 static void emit_byte_manip_r
PARAMS ((char *, int, int, int, int, int));
117 static void emit_extract_r
PARAMS ((int, int, int, int, int));
118 static void emit_insert_r
PARAMS ((int, int, int, int, int));
119 static void emit_mask_r
PARAMS ((int, int, int, int, int));
120 static void emit_sign_extend
PARAMS ((int, int));
121 static void emit_bis_r
PARAMS ((int, int, int));
122 static int build_mem
PARAMS ((int, int, int, bfd_signed_vma
));
123 static int build_operate_n
PARAMS ((int, int, int, int, int));
124 static void emit_sll_n
PARAMS ((int, int, int));
125 static void emit_ldah_num
PARAMS ((int, bfd_vma
, int));
126 static void emit_addq_r
PARAMS ((int, int, int));
127 static void emit_lda_n
PARAMS ((int, bfd_vma
, int));
128 static void emit_add64
PARAMS ((int, int, bfd_vma
));
129 static int in_range_signed
PARAMS ((bfd_vma
, int));
131 const pseudo_typeS md_pseudo_table
[] =
133 {"common", s_comm
, 0}, /* is this used? */
134 {"comm", s_alpha_comm
, 0}, /* osf1 compiler does this */
135 {"rdata", s_rdata
, 0},
136 {"sdata", s_sdata
, 0},
137 {"gprel32", s_gprel32
, 0},
138 {"t_floating", float_cons
, 'd'},
139 {"s_floating", float_cons
, 'f'},
140 {"f_floating", float_cons
, 'F'},
141 {"g_floating", float_cons
, 'G'},
142 {"d_floating", float_cons
, 'D'},
145 {"aproc", s_proc
, 1},
146 {"set", s_alpha_set
, 0},
147 {"reguse", s_ignore
, 0},
148 {"livereg", s_ignore
, 0},
149 {"extern", s_ignore
, 0}, /*??*/
150 {"base", s_base
, 0}, /*??*/
151 {"option", s_ignore
, 0},
152 {"prologue", s_ignore
, 0},
153 {"aent", s_ignore
, 0},
154 {"ugen", s_ignore
, 0},
156 /* We don't do any optimizing, so we can safely ignore these. */
157 {"noalias", s_ignore
, 0},
158 {"alias", s_ignore
, 0},
163 #define SA 21 /* shift for register Ra */
164 #define SB 16 /* shift for register Rb */
165 #define SC 0 /* shift for register Rc */
166 #define SN 13 /* shift for 8 bit immediate # */
172 #define RA 26 /* note: same as T12 */
179 #define OPCODE(X) (((X) >> 26) & 0x3f)
180 #define OP_FCN(X) (((X) >> 5) & 0x7f)
182 #ifndef FIRST_32BIT_QUADRANT
183 #define FIRST_32BIT_QUADRANT 0
186 int first_32bit_quadrant
= FIRST_32BIT_QUADRANT
;
187 int base_register
= FIRST_32BIT_QUADRANT
? ZERO
: GP
;
189 int no_mixed_code
= 0;
192 /* This array holds the chars that always start a comment. If the
193 pre-processor is disabled, these aren't very useful */
194 const char comment_chars
[] = "#";
196 /* This array holds the chars that only start a comment at the beginning of
197 a line. If the line seems to have the form '# 123 filename'
198 .line and .file directives will appear in the pre-processed output */
199 /* Note that input_file.c hand checks for '#' at the beginning of the
200 first line of the input file. This is because the compiler outputs
201 #NO_APP at the beginning of its output. */
202 /* Also note that C style comments are always recognized. */
203 const char line_comment_chars
[] = "#!";
205 /* Chars that can be used to separate mant from exp in floating point nums */
206 const char EXP_CHARS
[] = "eE";
208 const char line_separator_chars
[1];
210 /* Chars that mean this number is a floating point constant, as in
211 "0f12.456" or "0d1.2345e12". */
212 /* @@ Do all of these really get used on the alpha?? */
213 char FLT_CHARS
[] = "rRsSfFdDxXpP";
215 /* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
216 changed in read.c. Ideally it shouldn't have to know about it at all,
217 but nothing is ideal around here. */
222 bfd_reloc_code_real_type code
;
225 /* Occasionally, two relocations will be desired for one address.
226 Mainly only in cases like "jsr $r,foo" where we want both a LITUSE
231 unsigned long opcode
; /* need at least 32 bits */
232 struct reloc_data reloc
[MAX_RELOCS
];
235 static void getExpression (char *str
, struct alpha_it
*insn
);
236 static char *expr_end
;
238 #define note_gpreg(R) (alpha_gprmask |= (1 << (R)))
239 #define note_fpreg(R) (alpha_fprmask |= (1 << (R)))
242 tc_get_register (frame
)
248 if (*input_line_pointer
== '$')
250 input_line_pointer
++;
251 if (input_line_pointer
[0] == 's'
252 && input_line_pointer
[1] == 'p')
254 input_line_pointer
+= 2;
258 framereg
= get_absolute_expression ();
259 framereg
&= 31; /* ? */
262 as_warn ("frame reg expected, using $%d.", framereg
);
264 note_gpreg (framereg
);
274 temp
= get_absolute_expression ();
277 rdata
= subseg_get (".rdata", 0);
278 subseg_set (rdata
, (subsegT
) temp
);
280 rdata
= subseg_new (".rdata", 0);
282 demand_empty_rest_of_line ();
291 temp
= get_absolute_expression ();
294 sdata
= subseg_get (".sdata", 0);
295 subseg_set (sdata
, (subsegT
) temp
);
297 sdata
= subseg_new (".sdata", 0);
299 demand_empty_rest_of_line ();
303 s_alpha_comm (ignore
)
310 register symbolS
*symbolP
;
312 name
= input_line_pointer
;
313 c
= get_symbol_end ();
314 /* just after name is now '\0' */
315 p
= input_line_pointer
;
318 /* Alpha OSF/1 compiler doesn't provide the comma, gcc does. */
319 if (*input_line_pointer
== ',')
321 input_line_pointer
++;
324 if ((temp
= get_absolute_expression ()) < 0)
326 as_warn (".COMMon length (%ld.) <0! Ignored.", (long) temp
);
327 ignore_rest_of_line ();
331 symbolP
= symbol_find_or_make (name
);
333 if (S_IS_DEFINED (symbolP
))
335 as_bad ("Ignoring attempt to re-define symbol");
336 ignore_rest_of_line ();
339 if (S_GET_VALUE (symbolP
))
341 if (S_GET_VALUE (symbolP
) != (valueT
) temp
)
342 as_bad ("Length of .comm \"%s\" is already %ld. Not changed to %ld.",
343 S_GET_NAME (symbolP
),
344 (long) S_GET_VALUE (symbolP
),
349 S_SET_VALUE (symbolP
, (valueT
) temp
);
350 S_SET_EXTERNAL (symbolP
);
353 know (symbolP
->sy_frag
== &zero_address_frag
);
354 demand_empty_rest_of_line ();
358 tc_gen_reloc (sec
, fixp
)
364 reloc
= (arelent
*) bfd_alloc_by_size_t (stdoutput
, sizeof (arelent
));
365 reloc
->sym_ptr_ptr
= &fixp
->fx_addsy
->bsym
;
366 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
368 if (fixp
->fx_r_type
> BFD_RELOC_UNUSED
)
371 if (fixp
->fx_r_type
== BFD_RELOC_ALPHA_GPDISP_HI16
)
373 if (!gpdisp_hi16_howto
)
374 gpdisp_hi16_howto
= bfd_reloc_type_lookup (stdoutput
,
376 reloc
->howto
= gpdisp_hi16_howto
;
379 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
380 assert (reloc
->howto
!= 0);
381 if (!fixp
->fx_pcrel
!= !reloc
->howto
->pc_relative
)
383 as_fatal ("internal error? cannot generate `%s' relocation",
384 bfd_get_reloc_code_name (fixp
->fx_r_type
));
386 assert (!fixp
->fx_pcrel
== !reloc
->howto
->pc_relative
);
388 if (fixp
->fx_r_type
== BFD_RELOC_ALPHA_LITERAL
)
390 /* fake out bfd_perform_relocation. sigh */
391 reloc
->addend
= -alpha_gp_value
;
393 else if (reloc
->howto
->pc_relative
&& reloc
->howto
->pcrel_offset
)
395 reloc
->addend
= fixp
->fx_offset
- reloc
->address
;
398 reloc
->addend
= fixp
->fx_offset
;
405 if (first_32bit_quadrant
)
407 /* not fatal, but it might not work in the end */
408 as_warn ("File overrides no-base-register option.");
409 first_32bit_quadrant
= 0;
413 if (*input_line_pointer
== '$')
415 input_line_pointer
++;
416 if (*input_line_pointer
== 'r')
417 input_line_pointer
++;
420 base_register
= get_absolute_expression ();
421 if (base_register
< 0 || base_register
> 31)
424 as_warn ("Bad base register, using $%d.", base_register
);
426 demand_empty_rest_of_line ();
429 static int in_range_signed (val
, nbits
)
433 /* Look at top bit of value that would be stored, figure out how it
434 would be extended by the hardware, and see if that matches the
435 original supplied value. */
438 bfd_vma top_bit
, stored_value
, missing_bits
;
440 mask
= (one
<< nbits
) - 1;
441 stored_value
= val
& mask
;
442 top_bit
= stored_value
& (one
<< nbits
- 1);
443 missing_bits
= val
& ~mask
;
444 /* will sign-extend */
447 /* all remaining bits beyond mask should be one */
448 missing_bits
|= mask
;
449 return missing_bits
+ 1 == 0;
453 /* all other bits should be zero */
454 return missing_bits
== 0;
459 static int in_range_unsigned (val
, nbits
)
463 /* Look at top bit of value that would be stored, figure out how it
464 would be extended by the hardware, and see if that matches the
465 original supplied value. */
468 bfd_vma top_bit
, stored_value
, missing_bits
;
470 mask
= (one
<< nbits
) - 1;
471 stored_value
= val
& mask
;
472 top_bit
= stored_value
& (one
<< nbits
- 1);
473 missing_bits
= val
& ~mask
;
474 return missing_bits
== 0;
489 e
.X_add_symbol
= section_symbol (absolute_section
);
500 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 4, &e
, 0,
505 create_literal_section (secp
, name
)
509 segT current_section
= now_seg
;
510 int current_subsec
= now_subseg
;
513 *secp
= new_sec
= subseg_new (name
, 0);
514 subseg_set (current_section
, current_subsec
);
515 bfd_set_section_alignment (stdoutput
, new_sec
, 3);
516 bfd_set_section_flags (stdoutput
, new_sec
,
517 SEC_RELOC
| SEC_ALLOC
| SEC_LOAD
| SEC_READONLY
522 get_lit8_offset (val
)
528 create_literal_section (&lit8_sec
, ".lit8");
529 lit8_sym
= section_symbol (lit8_sec
);
531 retval
= add_to_literal_pool ((symbolS
*) 0, val
, lit8_sec
, 8);
532 if (retval
>= 0xfff0)
533 as_fatal ("overflow in fp literal (.lit8) table");
538 get_lit4_offset (val
)
544 create_literal_section (&lit4_sec
, ".lit4");
545 lit4_sym
= section_symbol (lit4_sec
);
547 retval
= add_to_literal_pool ((symbolS
*) 0, val
, lit4_sec
, 4);
548 if (retval
>= 0xfff0)
549 as_fatal ("overflow in fp literal (.lit4) table");
553 static struct alpha_it clear_insn
;
555 /* This function is called once, at assembler startup time. It should
556 set up all the tables, etc. that the MD part of the assembler will
557 need, that can be determined before arguments are parsed. */
561 const char *retval
, *name
;
564 op_hash
= hash_new ();
566 for (i
= 0; i
< NUMOPCODES
; )
568 const char *name
= alpha_opcodes
[i
].name
;
569 retval
= hash_insert (op_hash
, name
, (PTR
) &alpha_opcodes
[i
]);
571 as_fatal ("internal error: can't hash opcode `%s': %s",
576 while (i
< NUMOPCODES
577 && (alpha_opcodes
[i
].name
== name
578 || !strcmp (alpha_opcodes
[i
].name
, name
)));
580 /* Some opcodes include modifiers of various sorts with a "/mod"
581 syntax, like the architecture documentation suggests. However,
582 for use with gcc at least, we also need to access those same
583 opcodes without the "/". */
584 for (i
= 0; i
< NUMOPCODES
; )
586 name
= alpha_opcodes
[i
].name
;
588 if (strchr (name
, '/'))
590 char *p
= xmalloc (strlen (name
));
591 const char *q
= name
;
599 retval
= hash_insert (op_hash
, p
, (PTR
) &alpha_opcodes
[i
]);
600 /* Ignore failures -- the opcode table does duplicate some
601 variants in different forms, like "hw_stq" and "hw_st/q".
602 Maybe the variants can be eliminated, and this error
603 checking restored. */
608 while (i
< NUMOPCODES
609 && (alpha_opcodes
[i
].name
== name
610 || !strcmp (alpha_opcodes
[i
].name
, name
)));
613 lituse_basereg
.X_op
= O_constant
;
614 lituse_basereg
.X_add_number
= 1;
615 lituse_byteoff
.X_op
= O_constant
;
616 lituse_byteoff
.X_add_number
= 2;
617 lituse_jsr
.X_op
= O_constant
;
618 lituse_jsr
.X_add_number
= 3;
620 /* So .sbss will get used for tiny objects. */
621 bfd_set_gp_size (stdoutput
, 8);
622 create_literal_section (&lita_sec
, ".lita");
623 /* For handling the GP, create a symbol that won't be output in the
624 symbol table. We'll edit it out of relocs later. */
625 gp
= symbol_create ("<GP value>", lita_sec
, 0x8000, &zero_address_frag
);
627 memset (&clear_insn
, 0, sizeof (clear_insn
));
628 for (i
= 0; i
< MAX_RELOCS
; i
++)
629 clear_insn
.reloc
[i
].code
= BFD_RELOC_NONE
;
636 struct alpha_it
*insn
;
643 /* put out the opcode */
644 md_number_to_chars (toP
, insn
->opcode
, 4);
646 /* put out the symbol-dependent stuff */
647 for (j
= 0; j
< MAX_RELOCS
; j
++)
649 struct reloc_data
*r
= &insn
->reloc
[j
];
652 if (r
->code
!= BFD_RELOC_NONE
)
654 if (r
->exp
.X_op
== O_constant
)
656 r
->exp
.X_add_symbol
= section_symbol (absolute_section
);
657 r
->exp
.X_op
= O_symbol
;
659 f
= fix_new_exp (frag_now
, (toP
- frag_now
->fr_literal
), 4,
660 &r
->exp
, r
->pcrel
, r
->code
);
662 if (r
->code
== BFD_RELOC_ALPHA_GPDISP_LO16
)
664 static bit_fixS cookie
;
665 /* @@ This'll make the range checking in write.c shut up. */
666 f
->fx_bit_fixP
= &cookie
;
677 struct alpha_it insns
[MAX_INSNS
];
679 count
= alpha_ip (str
, insns
);
683 for (i
= 0; i
< count
; i
++)
684 emit_insn (&insns
[i
]);
694 vma
= bfd_get_section_vma (foo
, sec
);
695 if (vma
&& vma
< alpha_gp_value
)
696 alpha_gp_value
= vma
;
702 if (alpha_gp_value
!= 0)
705 /* Get minus-one in whatever width... */
706 alpha_gp_value
= 0; alpha_gp_value
--;
708 /* Select the smallest VMA of these existing sections. */
709 maybe_set_gp (lita_sec
);
710 /* maybe_set_gp (sdata); Was disabled before -- should we use it? */
712 maybe_set_gp (lit8_sec
);
713 maybe_set_gp (lit4_sec
);
716 alpha_gp_value
+= GP_ADJUSTMENT
;
718 S_SET_VALUE (gp
, alpha_gp_value
);
721 printf ("Chose GP value of %lx\n", alpha_gp_value
);
726 alpha_force_relocation (f
)
729 switch (f
->fx_r_type
)
731 case BFD_RELOC_ALPHA_GPDISP_HI16
:
732 case BFD_RELOC_ALPHA_GPDISP_LO16
:
733 case BFD_RELOC_ALPHA_LITERAL
:
734 case BFD_RELOC_ALPHA_LITUSE
:
735 case BFD_RELOC_GPREL32
:
737 case BFD_RELOC_ALPHA_HINT
:
742 case BFD_RELOC_23_PCREL_S2
:
753 alpha_fix_adjustable (f
)
756 /* Are there any relocation types for which we must generate a reloc
757 but we can adjust the values contained within it? */
758 switch (f
->fx_r_type
)
760 case BFD_RELOC_ALPHA_GPDISP_HI16
:
761 case BFD_RELOC_ALPHA_GPDISP_LO16
:
763 case BFD_RELOC_GPREL32
:
766 return !alpha_force_relocation (f
);
772 md_section_align (seg
, size
)
777 /* This should probably be handled within BFD, or by pulling the
778 number from BFD at least. */
786 /* Add this thing to the .lita section and produce a LITERAL reloc referring
789 /* Are we currently eligible to emit a LITUSE reloc for the literal
790 references just generated? */
791 static int lituse_pending
;
794 load_symbol_address (reg
, insn
)
796 struct alpha_it
*insn
;
798 static symbolS
*lita_sym
;
805 lita_sym
= section_symbol (lita_sec
);
806 S_CLEAR_EXTERNAL (lita_sym
);
809 retval
= add_to_literal_pool (insn
->reloc
[0].exp
.X_add_symbol
,
810 insn
->reloc
[0].exp
.X_add_number
,
813 /* Now emit a LITERAL relocation for the original section. */
814 insn
->reloc
[0].exp
.X_op
= O_symbol
;
815 insn
->reloc
[0].exp
.X_add_symbol
= lita_sym
;
816 insn
->reloc
[0].exp
.X_add_number
= retval
;
817 insn
->reloc
[0].code
= BFD_RELOC_ALPHA_LITERAL
;
820 if (retval
== 0x8000)
822 as_fatal ("overflow in literal (.lita) table");
825 insn
->opcode
= (0xa0000000 /* ldl */
827 | (base_register
<< SB
)
830 insn
->opcode
= (0xa4000000 /* ldq */
832 | (base_register
<< SB
)
834 note_gpreg (base_register
);
837 /* To load an address with a single instruction,
838 emit a LITERAL reloc in this section, and a REFQUAD
839 for the .lita section, so that we'll be able to access
841 lda REG, xx -> ldq REG, -32752(gp)
842 lda REG, xx+4 -> ldq REG, -32752(gp)
845 The offsets need to start near -0x8000, and the generated LITERAL
846 relocations should negate the offset. I don't completely grok the
850 load_expression (reg
, insn
)
852 struct alpha_it
*insn
;
854 valueT addend
, addendhi
, addendlo
;
857 if (insn
->reloc
[0].exp
.X_add_symbol
->bsym
->flags
& BSF_SECTION_SYM
)
863 addend
= insn
->reloc
[0].exp
.X_add_number
;
864 insn
->reloc
[0].exp
.X_add_number
= 0;
866 load_symbol_address (reg
, insn
);
869 if ((addend
& ~0x7fffffff) != 0
870 && (addend
& ~0x7fffffff) + 0x80000000 != 0)
872 as_bad ("assembler not prepared to handle constants >32 bits yet");
875 addendlo
= addend
& 0xffff;
877 addendhi
= addend
>> 16;
878 if (addendlo
& 0x8000)
880 /* It appears that the BASEREG LITUSE reloc should not be used on
881 an LDAH instruction. */
884 insn
[1].opcode
= (0x20000000 /* lda */
887 | (addendlo
& 0xffff));
888 insn
[1].reloc
[0].code
= BFD_RELOC_ALPHA_LITUSE
;
889 insn
[1].reloc
[0].exp
= lituse_basereg
;
894 insn
[num_insns
].opcode
= (0x24000000
897 | (addendhi
& 0xffff));
908 getExpression (str
, this_insn
)
910 struct alpha_it
*this_insn
;
915 #if 0 /* Not converted to bfd yet, and I don't think we need them
916 for ECOFF. Re-adding a.out support will probably require
918 static const struct am
{
920 bfd_reloc_code_real_type reloc
;
922 { "hi", RELOC_48_63
},
923 { "lo", RELOC_0_15
},
924 { "ml", RELOC_16_31
},
925 { "mh", RELOC_32_47
},
926 { "uhi", RELOC_U_48_63
},
927 { "uml", RELOC_U_16_31
},
928 { "umh", RELOC_U_32_47
},
932 /* Handle macros: "%macroname(expr)" */
943 while (*q
&& *p
== *q
)
951 str
= p
; /* keep the '(' */
952 this_insn
->reloc
= m
->reloc
;
957 save_in
= input_line_pointer
;
958 input_line_pointer
= str
;
960 seg
= expression (&this_insn
->reloc
[0].exp
);
961 /* XXX validate seg and exp, make sure they're reasonable */
962 expr_end
= input_line_pointer
;
963 input_line_pointer
= save_in
;
967 emit_unaligned_io (dir
, addr_reg
, addr_offset
, reg
)
973 sprintf (buf
, "%sq_u $%d,%ld($%d)", dir
, reg
, (long) addr_offset
, addr_reg
);
978 emit_load_unal (addr_reg
, addr_offset
, reg
)
982 emit_unaligned_io ("ld", addr_reg
, addr_offset
, reg
);
986 emit_store_unal (addr_reg
, addr_offset
, reg
)
990 emit_unaligned_io ("st", addr_reg
, addr_offset
, reg
);
994 emit_byte_manip_r (op
, in
, mask
, out
, mode
, which
)
996 int in
, mask
, out
, mode
, which
;
999 sprintf (buf
, "%s%c%c $%d,$%d,$%d", op
, mode
, which
, in
, mask
, out
);
1004 emit_extract_r (in
, mask
, out
, mode
, which
)
1005 int in
, mask
, out
, mode
, which
;
1007 emit_byte_manip_r ("ext", in
, mask
, out
, mode
, which
);
1011 emit_insert_r (in
, mask
, out
, mode
, which
)
1012 int in
, mask
, out
, mode
, which
;
1014 emit_byte_manip_r ("ins", in
, mask
, out
, mode
, which
);
1018 emit_mask_r (in
, mask
, out
, mode
, which
)
1019 int in
, mask
, out
, mode
, which
;
1021 emit_byte_manip_r ("msk", in
, mask
, out
, mode
, which
);
1025 emit_sign_extend (reg
, size
)
1029 sprintf (buf
, "sll $%d,0x%x,$%d", reg
, 64 - size
, reg
);
1031 sprintf (buf
, "sra $%d,0x%x,$%d", reg
, 64 - size
, reg
);
1036 emit_bis_r (in1
, in2
, out
)
1040 sprintf (buf
, "bis $%d,$%d,$%d", in1
, in2
, out
);
1045 build_mem (opc
, ra
, rb
, disp
)
1047 bfd_signed_vma disp
;
1049 if ((disp
>> 15) != 0
1050 && (disp
>> 15) + 1 != 0)
1052 return ((opc
<< 26) | (ra
<< SA
) | (rb
<< SB
) | (disp
& 0xffff));
1056 build_operate_n (opc
, fn
, ra
, lit
, rc
)
1057 int opc
, fn
, ra
, rc
;
1062 return ((opc
<< 26) | (fn
<< 5) | (ra
<< SA
) | (lit
<< SN
) | (1 << 12) | (rc
<< SC
));
1066 emit_sll_n (dest
, disp
, src
)
1067 int dest
, disp
, src
;
1069 struct alpha_it insn
= clear_insn
;
1070 insn
.opcode
= build_operate_n (0x12, 0x39, src
, disp
, dest
);
1075 emit_ldah_num (dest
, addend
, src
)
1079 struct alpha_it insn
= clear_insn
;
1080 insn
.opcode
= build_mem (0x09, dest
, src
, addend
);
1085 emit_addq_r (in1
, in2
, out
)
1088 struct alpha_it insn
= clear_insn
;
1089 insn
.opcode
= 0x40000400 | (in1
<< SA
) | (in2
<< SB
) | (out
<< SC
);
1094 emit_lda_n (dest
, addend
, src
)
1098 struct alpha_it insn
= clear_insn
;
1099 insn
.opcode
= build_mem (0x08, dest
, src
, addend
);
1104 emit_add64 (in
, out
, num
)
1108 bfd_signed_vma snum
= num
;
1110 if (in_range_signed (num
, 16))
1112 emit_lda_n (out
, num
, in
);
1115 if ((num
& 0xffff) == 0
1117 && in_range_signed (snum
>> 16, 16))
1119 emit_ldah_num (out
, snum
>> 16, in
);
1122 /* I'm not sure this one is getting invoked when it could. */
1123 if ((num
& 1) == 0 && in
== ZERO
)
1125 if (in_range_signed (snum
>> 1, 16))
1127 emit_lda_n (out
, snum
>> 1, in
);
1128 emit_addq_r (out
, out
, out
);
1131 else if (num
& 0x1fffe == 0
1132 && in_range_signed (snum
>> 17, 16))
1134 emit_ldah_num (out
, snum
>> 17, in
);
1135 emit_addq_r (out
, out
, out
);
1139 if (in_range_signed (num
, 32))
1141 bfd_vma lo
= num
& 0xffff;
1145 emit_ldah_num (out
, snum
>> 16, in
);
1147 emit_lda_n (out
, lo
, out
);
1151 if (in
!= ZERO
&& in
!= AT
&& out
!= AT
&& at_ok
)
1153 emit_add64 (ZERO
, AT
, num
);
1154 emit_addq_r (AT
, in
, out
);
1159 as_bad ("load expression too complex to expand");
1161 /* Could check also for loading 16- or 32-bit value and shifting by
1162 arbitrary displacement. */
1165 bfd_vma lo
= snum
& 0xffffffff;
1166 if (lo
& 0x80000000)
1167 lo
-= ((bfd_vma
)0x10000000 << 4);
1169 emit_add64 (ZERO
, out
, snum
>> 32);
1170 emit_sll_n (out
, 32, out
);
1172 emit_add64 (out
, out
, lo
);
1177 alpha_ip (str
, insns
)
1179 struct alpha_it insns
[];
1185 struct alpha_opcode
*pattern
;
1187 unsigned int opcode
;
1189 int match
= 0, num_gen
= 1;
1191 int do_add64
, add64_in
, add64_out
;
1192 bfd_vma add64_addend
;
1195 islower (*s
) || *s
== '_' || *s
== '/' || *s
== '4' || *s
== '8';
1214 as_fatal ("Unknown opcode: `%s'", str
);
1216 if ((pattern
= (struct alpha_opcode
*) hash_find (op_hash
, str
)) == NULL
)
1218 as_bad ("Unknown opcode: `%s'", str
);
1228 opcode
= pattern
->match
;
1230 for (i
= 0; i
< MAX_INSNS
; i
++)
1231 insns
[i
] = clear_insn
;
1233 /* Build the opcode, checking as we go to make sure that the
1235 for (args
= pattern
->args
;; ++args
)
1240 case '\0': /* end of args */
1259 case '(': /* these must match exactly */
1268 case '1': /* next operand must be a register */
1278 case 'a': /* $at: as temporary */
1284 case 'g': /* $gp: base register */
1287 mask
= base_register
;
1290 case 's': /* $sp: stack pointer */
1297 case 'r': /* any register */
1298 if (!isdigit (c
= *s
++))
1315 if ((c
= 10 * (c
- '0') + (*s
++ - '0')) >= 32)
1324 if ((c
== GP
) && first_32bit_quadrant
)
1334 /* Got the register, now figure out where it goes in
1342 opcode
|= mask
<< SA
;
1347 opcode
|= mask
<< SB
;
1356 opcode
|= (mask
<< SA
) | mask
;
1359 case 'R': /* ra and rb are the same */
1360 opcode
|= (mask
<< SA
) | (mask
<< SB
);
1364 opcode
|= (mask
<< SA
) | (mask
<< SB
) | (mask
);
1370 case 'e': /* next operand is a floating point register */
1374 if (*s
++ == '$' && *s
++ == 'f' && isdigit (*s
))
1379 mask
= 10 * (mask
- '0') + (*s
++ - '0');
1390 /* same encoding as gp registers */
1396 case 'h': /* bits 16..31 */
1397 insns
[0].reloc
= RELOC_16_31
;
1401 case 'l': /* bits 0..15 */
1402 insns
[0].reloc
[0].code
= BFD_RELOC_16
;
1405 case 'L': /* 21 bit PC relative immediate */
1406 insns
[0].reloc
[0].code
= BFD_RELOC_23_PCREL_S2
;
1407 insns
[0].reloc
[0].pcrel
= 1;
1410 case 'i': /* 14 bit immediate */
1411 if (OPCODE (opcode
) != 0x1a)
1412 /* Not a jmp variant?? */
1414 else if (opcode
& 0x8000)
1415 /* ret or jsr_coroutine */
1417 insns
[0].reloc
[0].code
= BFD_RELOC_14
;
1418 insns
[0].reloc
[0].pcrel
= 0;
1423 insns
[0].reloc
[0].code
= BFD_RELOC_ALPHA_HINT
;
1424 insns
[0].reloc
[0].pcrel
= 1;
1428 case 'b': /* 8 bit immediate */
1429 insns
[0].reloc
[0].code
= BFD_RELOC_8
;
1432 case 'I': /* 26 bit immediate, for PALcode */
1433 insns
[0].reloc
[0].code
= BFD_RELOC_26
;
1436 case 't': /* 12 bit displacement, for PALcode */
1437 insns
[0].reloc
[0].code
= BFD_RELOC_12_PCREL
;
1440 case '8': /* 8 bit 0...7 */
1441 insns
[0].reloc
[0].code
= BFD_RELOC_8
;
1447 getExpression (s
, &insns
[0]);
1449 /* Handle overflow in certain instructions by converting
1450 to other instructions. */
1451 if (insns
[0].reloc
[0].code
== BFD_RELOC_8
1452 && insns
[0].reloc
[0].exp
.X_op
== O_constant
1453 && (insns
[0].reloc
[0].exp
.X_add_number
< 0
1454 || insns
[0].reloc
[0].exp
.X_add_number
> 0xff))
1456 if (OPCODE (opcode
) == 0x10
1457 && (OP_FCN (opcode
) == 0x00 /* addl */
1458 || OP_FCN (opcode
) == 0x40 /* addl/v */
1459 || OP_FCN (opcode
) == 0x20 /* addq */
1460 || OP_FCN (opcode
) == 0x60 /* addq/v */
1461 || OP_FCN (opcode
) == 0x09 /* subl */
1462 || OP_FCN (opcode
) == 0x49 /* subl/v */
1463 || OP_FCN (opcode
) == 0x29 /* subq */
1464 || OP_FCN (opcode
) == 0x69 /* subq/v */
1465 || OP_FCN (opcode
) == 0x02 /* s4addl */
1466 || OP_FCN (opcode
) == 0x22 /* s4addq */
1467 || OP_FCN (opcode
) == 0x0b /* s4subl */
1468 || OP_FCN (opcode
) == 0x2b /* s4subq */
1469 || OP_FCN (opcode
) == 0x12 /* s8addl */
1470 || OP_FCN (opcode
) == 0x32 /* s8addq */
1471 || OP_FCN (opcode
) == 0x1b /* s8subl */
1472 || OP_FCN (opcode
) == 0x3b /* s8subq */
1474 /* Can we make it fit by negating? */
1475 && -insns
[0].reloc
[0].exp
.X_add_number
< 0xff
1476 && -insns
[0].reloc
[0].exp
.X_add_number
> 0)
1478 opcode
^= 0x120; /* convert add<=>sub */
1479 insns
[0].reloc
[0].exp
.X_add_number
*= -1;
1481 else if (at_ok
&& macro_ok
)
1483 /* Constant value supplied, but it's too large. */
1487 add64_addend
= insns
[0].reloc
[0].exp
.X_add_number
;
1489 opcode
|= (AT
<< SB
);
1490 insns
[0].reloc
[0].code
= BFD_RELOC_NONE
;
1493 as_bad ("overflow in 8-bit literal field in `operate' format insn");
1495 else if (insns
[0].reloc
[0].code
== BFD_RELOC_16
1496 && insns
[0].reloc
[0].exp
.X_op
== O_constant
1497 && !in_range_signed (insns
[0].reloc
[0].exp
.X_add_number
,
1500 bfd_vma val
= insns
[0].reloc
[0].exp
.X_add_number
;
1501 if (OPCODE (opcode
) == 0x08)
1508 opcode
|= (AT
<< SB
);
1509 insns
[0].reloc
[0].code
= BFD_RELOC_NONE
;
1511 else if (OPCODE (opcode
) == 0x09
1512 && in_range_signed (val
>> 16, 16))
1514 /* ldah with high operand - convert to low */
1515 insns
[0].reloc
[0].exp
.X_add_number
>>= 16;
1518 as_bad ("I don't know how to handle 32+ bit constants here yet, sorry.");
1520 else if (insns
[0].reloc
[0].code
== BFD_RELOC_32
1521 && insns
[0].reloc
[0].exp
.X_op
== O_constant
)
1523 bfd_vma val
= insns
[0].reloc
[0].exp
.X_add_number
;
1524 bfd_signed_vma sval
= val
;
1527 && sval
>> 32 != -1)
1528 as_bad ("I don't know how to handle 64 bit constants here yet, sorry.");
1534 int format
, length
, mode
, i
;
1535 char temp
[20 /*MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT*/];
1537 static const char formats
[4] = "FGfd";
1538 bfd_vma bits
, offset
;
1539 char *old_input_line_pointer
= input_line_pointer
;
1541 input_line_pointer
= s
;
1543 memset (temp
, 0, sizeof (temp
));
1544 mode
= (opcode
>> 26) & 3;
1545 format
= formats
[mode
];
1546 err
= md_atof (format
, temp
, &length
);
1549 as_bad ("Bad floating literal: %s", err
);
1554 /* Generate little-endian number from byte sequence. */
1556 for (i
= length
- 1; i
>= 0; i
--)
1557 bits
+= ((bfd_vma
)(temp
[i
] & 0xff)) << (i
* 8);
1562 offset
= get_lit8_offset (bits
) - 0x8000;
1563 insns
[0].reloc
[0].exp
.X_add_symbol
= lit8_sym
;
1564 insns
[0].reloc
[0].exp
.X_add_number
= 0x8000;
1567 offset
= get_lit4_offset (bits
) - 0x8000;
1568 insns
[0].reloc
[0].exp
.X_add_symbol
= lit4_sym
;
1569 insns
[0].reloc
[0].exp
.X_add_number
= 0x8000;
1574 insns
[0].reloc
[0].exp
.X_op
= O_symbol
;
1576 num_gen
= load_expression (AT
, &insns
[0]);
1579 insns
[num_gen
].reloc
[0].code
= BFD_RELOC_ALPHA_LITUSE
;
1580 insns
[num_gen
].reloc
[0].exp
= lituse_basereg
;
1583 insns
[num_gen
++].opcode
= opcode
| (AT
<< SB
) | offset
;
1584 opcode
= insns
[0].opcode
;
1585 s
= input_line_pointer
;
1586 input_line_pointer
= old_input_line_pointer
;
1590 /* The following two.. take advantage of the fact that
1591 opcode already contains most of what we need to know.
1592 We just prepend to the instr an "ldah
1593 $r,%ml(expr)($base)" and turn this one (done later
1594 after we return) into something like "stq
1595 $r,%lo(expr)(at)" or "ldq $r,%lo(expr)($r)".
1597 NOTE: This can fail later on at link time if the
1598 offset from $base actually turns out to be more than
1599 2**31 or 2**47 if use_large_offsets is set. */
1600 case 'P': /* Addressing macros: PUT */
1601 mask
= AT
; /* register 'at' */
1604 case 'G': /* Addressing macros: GET */
1605 /* All it is missing is the expression, which is what we
1610 getExpression (s
, &insns
[0]);
1613 /* Must check for "lda ..,number" too */
1614 if (insns
[0].reloc
[0].exp
.X_op
== O_big
)
1616 as_warn ("Sorry, not yet. Put bignums in .data section yourself.");
1619 if (insns
[0].reloc
[0].exp
.X_op
== O_constant
)
1621 bfd_vma val
= insns
[0].reloc
[0].exp
.X_add_number
;
1624 insns
[0].reloc
[0].code
= BFD_RELOC_NONE
;
1625 insns
[1].reloc
[0].code
= BFD_RELOC_NONE
;
1640 opcode
|= ZERO
<< SB
;
1642 opcode
|= low
& 0xffff;
1644 else if (insns
[0].reloc
[0].exp
.X_op
== O_symbol
)
1646 unsigned long old_opcode
= opcode
;
1650 as_bad ("insn requires expansion but `nomacro' specified");
1651 else if (*args
== 'G')
1654 as_bad ("insn expansion requires AT use, but `noat' specified");
1657 num_gen
= load_expression (tmp_reg
, insns
);
1658 opcode
= insns
[0].opcode
;
1659 /* lda is opcode 8, 0x20000000, and the macros that use
1660 this code have an opcode field of 0. The latter
1661 require further processing, and we don't have the
1662 true opcode here. */
1663 if (OPCODE (old_opcode
) != 0
1664 && OPCODE (old_opcode
) != 0x08)
1667 i
= &insns
[num_gen
++];
1668 i
->opcode
= old_opcode
| (tmp_reg
<< SB
);
1672 i
->reloc
[0].code
= BFD_RELOC_ALPHA_LITUSE
;
1673 i
->reloc
[0].exp
= lituse_basereg
;
1682 insns
[1].reloc
[0].exp
= insns
[0].reloc
[0].exp
;
1684 /* Generate: ldah REG,x1(GP); OP ?,x0(REG) */
1686 abort (); /* relocs need fixing */
1688 insns
[1].reloc
= RELOC_0_15
;
1689 insns
[1].opcode
= opcode
| mask
<< SB
;
1691 insns
[0].reloc
= RELOC_16_31
;
1692 opcode
= 0x24000000 /*ldah*/ | mask
<< SA
| (base_register
<< SB
);
1698 /* Same failure modes as above, actually most of the
1699 same code shared. */
1700 case 'B': /* Builtins */
1705 case 'a': /* ldgp */
1707 if (first_32bit_quadrant
|| no_mixed_code
)
1709 switch (OUTPUT_FLAVOR
)
1711 case bfd_target_aout_flavour
:
1712 /* this is cmu's a.out version */
1713 insns
[0].reloc
[0].code
= BFD_RELOC_NONE
;
1714 /* generate "zap %r,0xf,%r" to take high 32 bits */
1715 opcode
|= 0x48001600 /* zap ?,#,?*/ | (0xf << SN
);
1717 case bfd_target_ecoff_flavour
:
1718 /* Given "ldgp R1,N(R2)", turn it into something
1719 like "ldah R1,###(R2) ; lda R1,###(R1)" with
1720 appropriate constants and relocations. */
1722 unsigned long r1
, r2
;
1723 unsigned long addend
= 0;
1728 insns
[0].reloc
[0].code
= BFD_RELOC_ALPHA_GPDISP_HI16
;
1729 insns
[0].reloc
[0].pcrel
= 1;
1730 insns
[0].reloc
[0].exp
.X_op
= O_symbol
;
1731 insns
[0].reloc
[0].exp
.X_add_symbol
= gp
;
1732 insns
[0].reloc
[0].exp
.X_add_number
= 0;
1733 insns
[0].opcode
= (0x24000000 /* ldah */
1736 insns
[1].reloc
[0].code
= BFD_RELOC_ALPHA_GPDISP_LO16
;
1737 insns
[1].reloc
[0].exp
.X_op
= O_symbol
;
1738 insns
[1].reloc
[0].exp
.X_add_symbol
= gp
;
1739 insns
[1].reloc
[0].exp
.X_add_number
= 4;
1740 insns
[1].reloc
[0].pcrel
= 1;
1741 insns
[1].opcode
= 0x20000000 | (r1
<< SA
) | (r1
<< SB
);
1742 opcode
= insns
[0].opcode
;
1743 /* merge in addend */
1744 insns
[1].opcode
|= addend
& 0xffff;
1745 insns
[0].opcode
|= ((addend
>> 16)
1746 + (addend
& 0x8000 ? 1 : 0));
1748 ecoff_set_gp_prolog_size (0);
1757 case 'b': /* setgp */
1758 switch (OUTPUT_FLAVOR
)
1760 case bfd_target_aout_flavour
:
1761 /* generate "zap %r,0xf,$gp" to take high 32 bits */
1762 opcode
|= 0x48001600 /* zap ?,#,?*/
1763 | (0xf << SN
) | (base_register
);
1770 case 'c': /* jsr $r,foo becomes
1773 Register 27, t12, is used by convention
1776 struct alpha_it
*jsr
;
1778 struct reloc_data
*r
;
1780 /* We still have to parse the function name */
1783 getExpression (s
, &insns
[0]);
1784 etmp
= insns
[0].reloc
[0].exp
;
1786 num_gen
= load_expression (PV
, &insns
[0]);
1789 jsr
= &insns
[num_gen
++];
1790 jsr
->opcode
= (pattern
->match
1796 /* LITUSE wasn't emitted yet */
1797 jsr
->reloc
[0].code
= BFD_RELOC_ALPHA_LITUSE
;
1798 jsr
->reloc
[0].exp
= lituse_jsr
;
1805 r
->code
= BFD_RELOC_ALPHA_HINT
;
1807 opcode
= insns
[0].opcode
;
1812 /* Sub-word loads and stores. We load the address into
1813 $at, which might involve using the `P' parameter
1814 processing too, then emit a sequence to get the job
1815 done, using unaligned memory accesses and byte
1816 manipulation, with t9 and t10 as temporaries. */
1818 /* Characteristics of access. */
1819 int is_load
, is_unsigned
= 0, is_unaligned
= 0;
1820 int mode_size
, mode
;
1821 /* Register operand. */
1823 /* Addend for loads and stores. */
1825 /* Which register do we use for the address? */
1829 /* Pick apart name and set flags. */
1830 const char *s
= pattern
->name
;
1838 if (s
[0] == 'l' && s
[1] == 'd')
1840 else if (s
[0] == 's' && s
[1] == 't')
1843 as_fatal ("unrecognized sub-word access insn `%s'",
1848 if (mode
== 'b') mode_size
= 1;
1849 else if (mode
== 'w') mode_size
= 2;
1850 else if (mode
== 'l') mode_size
= 4;
1851 else if (mode
== 'q') mode_size
= 8;
1862 /* Longwords are always kept sign-extended. */
1863 if (mode
== 'l' && is_unsigned
)
1865 /* There's no special unaligned byte handling. */
1866 if (mode
== 'b' && is_unaligned
)
1868 /* Stores don't care about signedness. */
1869 if (!is_load
&& is_unsigned
)
1873 if (args
[-2] == 'P')
1882 r1 -> (opcode >> SA) & 31
1883 num -> insns->reloc[0].*
1885 We want to emit "lda at,num(r2)", since these
1886 operations require the use of a single register
1887 with the starting address of the memory operand
1890 We could probably get away without doing this
1891 (and use r2 below, with the addend for the
1892 actual reads and writes) in cases where the
1893 addend is known to be a multiple of 8. */
1895 int r1
= (opcode
>> SA
) & 31;
1897 if (insns
[0].reloc
[0].code
== BFD_RELOC_NONE
)
1899 else if (insns
[0].reloc
[0].code
== BFD_RELOC_16
)
1901 if (insns
[0].reloc
[0].exp
.X_op
!= O_constant
)
1903 addend
= insns
[0].reloc
[0].exp
.X_add_number
;
1908 if (addend
+ mode_size
- 1 < 0x7fff
1909 && (addend
% 8) == 0
1910 && (r2
< T9
|| r2
> T12
))
1917 /* Let later relocation processing deal
1918 with the addend field. */
1919 insns
[num_gen
-1].opcode
= (0x20000000 /* lda */
1928 /* Because the emit_* routines append directly to
1929 the current frag, we now need to flush any
1933 for (i
= 0; i
< num_gen
; i
++)
1934 emit_insn (&insns
[i
]);
1943 reg2
= T9
, reg3
= T10
;
1947 emit_load_unal (addr
, addend
, T9
);
1949 emit_load_unal (addr
, addend
+ mode_size
- 1, T10
);
1950 emit_extract_r (T9
, addr
, reg2
, mode
, 'l');
1953 emit_extract_r (T10
, addr
, reg3
, mode
, 'h');
1954 emit_bis_r (T9
, T10
, reg
);
1957 emit_sign_extend (reg
, mode_size
* 8);
1961 /* The second word gets processed first
1962 because if the address does turn out to be
1963 aligned, the processing for the second word
1964 will be pushing around all-zeros, and the
1965 entire value will be handled as the `first'
1966 word. So we want to store the `first' word
1968 /* Pair these up so that the memory loads get
1969 separated from each other, as well as being
1970 well in advance of the uses of the values
1974 emit_load_unal (addr
, addend
+ mode_size
- 1, T11
);
1975 emit_insert_r (reg
, addr
, T12
, mode
, 'h');
1977 emit_load_unal (addr
, addend
, T9
);
1978 emit_insert_r (reg
, addr
, T10
, mode
, 'l');
1980 emit_mask_r (T12
, addr
, T12
, mode
, 'h');
1981 emit_mask_r (T10
, addr
, T10
, mode
, 'l');
1983 emit_bis_r (T11
, T12
, T11
);
1984 emit_bis_r (T9
, T10
, T9
);
1986 emit_store_unal (addr
, addend
+ mode_size
- 1, T11
);
1987 emit_store_unal (addr
, addend
, T9
);
1992 /* DIVISION and MODULUS. Yech.
1993 Convert OP x,y,result
1999 with appropriate optimizations if t10,t11,t12
2000 are the registers specified by the compiler.
2001 We are missing an obvious optimization
2002 opportunity here; if the ldq generated by the
2003 jsr assembly requires a cycle or two to make
2004 the value available, initiating it before one
2005 or two of the mov instructions would result in
2006 faster execution. */
2007 case '0': /* reml */
2008 case '1': /* divl */
2009 case '2': /* remq */
2010 case '3': /* divq */
2011 case '4': /* remlu */
2012 case '5': /* divlu */
2013 case '6': /* remqu */
2014 case '7': /* divqu */
2016 static char func
[8][6] = {
2017 "reml", "divl", "remq", "divq",
2018 "remlu", "divlu", "remqu", "divqu"
2023 /* All regs parsed, in opcode */
2025 /* Do the expansions, one instr at a time */
2027 reg
= (opcode
>> SA
) & 31;
2031 sprintf (expansion
, "mov $%d,$%d", reg
, T10
);
2032 md_assemble (expansion
);
2034 reg
= (opcode
>> SB
) & 31;
2036 /* we already overwrote it! */
2038 else if (reg
!= T11
)
2041 sprintf (expansion
, "mov $%d,$%d", reg
, T11
);
2042 md_assemble (expansion
);
2044 sprintf (expansion
, "lda $%d,__%s", PV
, func
[*args
- '0']);
2045 md_assemble (expansion
);
2046 sprintf (expansion
, "jsr $%d,($%d),__%s", T9
, PV
,
2048 md_assemble (expansion
);
2050 if (!first_32bit_quadrant
)
2055 md_assemble (expansion
);
2058 sprintf (expansion
, "ldgp $%d,0($%d)",
2060 md_assemble (expansion
);
2062 /* Use insns[0] to get at the result */
2063 if ((reg
= (opcode
& 31)) != PV
)
2064 opcode
= (0x47e00400 /* or zero,zero,zero */
2066 | reg
/* Rc */ ); /* pv->z */
2082 /* Args don't match. */
2083 if (&pattern
[1] - alpha_opcodes
< NUMOPCODES
2084 && !strcmp (pattern
->name
, pattern
[1].name
))
2092 as_warn ("Illegal operands");
2098 /* Args match, see if a float instructions and -nofloats */
2099 if (nofloats
&& pattern
->isa_float
)
2107 emit_add64 (add64_in
, add64_out
, add64_addend
);
2110 insns
[0].opcode
= opcode
;
2114 /* Turn a string in input_line_pointer into a floating point constant
2115 of type type, and store the appropriate bytes in *litP. The number
2116 of LITTLENUMS emitted is stored in *sizeP. An error message is
2117 returned, or NULL on OK. */
2119 /* Equal to MAX_PRECISION in atof-ieee.c */
2120 #define MAX_LITTLENUMS 6
2123 md_atof (type
, litP
, sizeP
)
2129 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
2130 LITTLENUM_TYPE
*wordP
;
2132 char *atof_ieee (), *vax_md_atof ();
2138 /* VAX md_atof doesn't like "G" for some reason. */
2142 return vax_md_atof (type
, litP
, sizeP
);
2165 return "Bad call to MD_ATOF()";
2167 t
= atof_ieee (input_line_pointer
, type
, words
);
2169 input_line_pointer
= t
;
2170 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
2172 for (wordP
= words
+ prec
- 1; prec
--;)
2174 md_number_to_chars (litP
, (long) (*wordP
--), sizeof (LITTLENUM_TYPE
));
2175 litP
+= sizeof (LITTLENUM_TYPE
);
2182 md_bignum_to_chars (buf
, bignum
, nchars
)
2184 LITTLENUM_TYPE
*bignum
;
2189 LITTLENUM_TYPE work
= *bignum
++;
2190 int nb
= CHARS_PER_LITTLENUM
;
2194 *buf
++ = work
& ((1 << BITS_PER_CHAR
) - 1);
2197 work
>>= BITS_PER_CHAR
;
2203 CONST
char *md_shortopts
= "Fm:";
2204 struct option md_longopts
[] = {
2205 #define OPTION_32ADDR (OPTION_MD_BASE)
2206 {"32addr", no_argument
, NULL
, OPTION_32ADDR
},
2207 {NULL
, no_argument
, NULL
, 0}
2209 size_t md_longopts_size
= sizeof(md_longopts
);
2212 md_parse_option (c
, arg
)
2234 md_show_usage (stream
)
2239 -32addr treat addresses as 32-bit values\n\
2240 -F lack floating point instructions support\n\
2241 -m21064 | -m21066 | -m21164\n\
2242 specify variant of Alpha architecture\n");
2249 /* XXXX Align to cache linesize XXXXX */
2256 /* Takes ".proc name,nargs" */
2257 name
= input_line_pointer
;
2258 c
= get_symbol_end ();
2259 p
= input_line_pointer
;
2260 symbolP
= symbol_find_or_make (name
);
2263 if (*input_line_pointer
!= ',')
2266 as_warn ("Expected comma after name \"%s\"", name
);
2269 ignore_rest_of_line ();
2273 input_line_pointer
++;
2274 temp
= get_absolute_expression ();
2276 /* symbolP->sy_other = (signed char) temp; */
2277 as_warn ("unhandled: .proc %s,%d", name
, temp
);
2278 demand_empty_rest_of_line ();
2285 char *name
= input_line_pointer
, ch
, *s
;
2288 while (!is_end_of_line
[(unsigned char) *input_line_pointer
])
2289 input_line_pointer
++;
2290 ch
= *input_line_pointer
;
2291 *input_line_pointer
= '\0';
2294 if (s
[0] == 'n' && s
[1] == 'o')
2299 if (!strcmp ("reorder", s
))
2301 else if (!strcmp ("at", s
))
2303 else if (!strcmp ("macro", s
))
2305 else if (!strcmp ("move", s
))
2307 else if (!strcmp ("volatile", s
))
2310 as_warn ("Tried to .set unrecognized mode `%s'", name
);
2311 *input_line_pointer
= ch
;
2312 demand_empty_rest_of_line ();
2315 /* @@ Is this right?? */
2317 md_pcrel_from (fixP
)
2320 valueT addr
= fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
2321 switch (fixP
->fx_r_type
)
2323 case BFD_RELOC_ALPHA_GPDISP_HI16
:
2324 case BFD_RELOC_ALPHA_GPDISP_LO16
:
2327 return fixP
->fx_size
+ addr
;
2332 alpha_do_align (n
, fill
)
2337 && (now_seg
== text_section
2338 || !strcmp (now_seg
->name
, ".init")
2339 || !strcmp (now_seg
->name
, ".fini")))
2341 static const unsigned char nop_pattern
[] = { 0x1f, 0x04, 0xff, 0x47 };
2342 frag_align_pattern (n
, nop_pattern
, sizeof (nop_pattern
));
2349 md_apply_fix (fixP
, valueP
)
2356 char *p
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
2360 switch (fixP
->fx_r_type
)
2362 /* The GPDISP relocations are processed internally with a symbol
2363 referring to the current function; we need to drop in a value
2364 which, when added to the address of the start of the function,
2365 gives the desired GP. */
2366 case BFD_RELOC_ALPHA_GPDISP_HI16
:
2367 case BFD_RELOC_ALPHA_GPDISP_LO16
:
2369 if (fixP
->fx_r_type
== BFD_RELOC_ALPHA_GPDISP_HI16
)
2371 assert (fixP
->fx_next
->fx_r_type
== BFD_RELOC_ALPHA_GPDISP_LO16
);
2374 fprintf_vma (stdout
, addend
);
2377 if (addend
& 0x8000)
2380 fixP
->fx_offset
= 4; /* @@ Compute this using fx_next. */
2386 fprintf_vma (stdout
, addend
);
2390 fixP
->fx_offset
= 0;
2392 md_number_to_chars (fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
,
2394 fixP
->fx_addsy
= section_symbol (absolute_section
);
2395 fixP
->fx_offset
+= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
2399 /* Write 8 bits, shifted left 13 bit positions. */
2403 *p
|= (value
<< 5) & 0xe0;
2411 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2412 "overflow in type-%d reloc", (int) fixP
->fx_r_type
);
2422 /* Don't want overflow checking. */
2425 if (fixP
->fx_pcrel
== 0
2426 && fixP
->fx_addsy
== 0)
2428 md_number_to_chars (p
, value
, size
);
2429 /* @@ Overflow checks?? */
2435 if (fixP
->fx_addsy
!= 0
2436 && fixP
->fx_addsy
->bsym
->section
!= absolute_section
)
2437 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2438 "PALcode instructions require immediate constant function code");
2439 else if (value
>> 26 != 0)
2440 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2441 "overflow in 26-bit PALcode function field");
2442 *p
++ = value
& 0xff;
2444 *p
++ = value
& 0xff;
2446 *p
++ = value
& 0xff;
2457 if (fixP
->fx_addsy
!= 0
2458 && fixP
->fx_addsy
->bsym
->section
!= absolute_section
)
2459 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2460 "ret/jsr_coroutine requires constant in displacement field");
2461 else if (value
>> 14 != 0)
2462 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2463 "overflow in 14-bit operand field of ret or jsr_coroutine");
2464 *p
++ = value
& 0xff;
2466 *p
= (*p
& 0xc0) | (value
& 0x3f);
2469 case BFD_RELOC_23_PCREL_S2
:
2470 /* Write 21 bits only. */
2472 *p
++ = value
& 0xff;
2474 *p
++ = value
& 0xff;
2477 *p
|= (value
& 0x1f);
2480 case BFD_RELOC_12_PCREL
:
2481 *p
++ = value
& 0xff;
2484 *p
|= (value
& 0x0f);
2487 case BFD_RELOC_ALPHA_LITERAL
:
2488 case BFD_RELOC_ALPHA_LITUSE
:
2491 case BFD_RELOC_GPREL32
:
2492 assert (fixP
->fx_subsy
== gp
);
2493 value
= - alpha_gp_value
; /* huh? this works... */
2495 md_number_to_chars (p
, value
, 4);
2498 case BFD_RELOC_ALPHA_HINT
:
2499 if (fixP
->fx_addsy
== 0 && fixP
->fx_pcrel
== 0)
2507 as_fatal ("unhandled relocation type %s",
2508 bfd_get_reloc_code_name (fixP
->fx_r_type
));
2512 if (fixP
->fx_addsy
== 0 && fixP
->fx_pcrel
== 0)
2514 printf ("type %d reloc done?\n", fixP
->fx_r_type
);
2524 alpha_frob_ecoff_data ()
2527 /* $zero and $f31 are read-only */
2528 alpha_gprmask
&= ~1;
2529 alpha_fprmask
&= ~1;
2532 /* The Alpha has support for some VAX floating point types, as well as for
2533 IEEE floating point. We consider IEEE to be the primary floating point
2534 format, and sneak in the VAX floating point support here. */
2535 #define md_atof vax_md_atof
2536 #include "config/atof-vax.c"