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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 /* The OSF/1 V2.0 Alpha compiler can't compile this file with inline
70 /* @@ Will a simple 0x8000 work here? If not, why not? */
71 #define GP_ADJUSTMENT (0x8000 - 0x10)
73 /* These are exported to relaxing code, even though we don't do any
74 relaxing on this processor currently. */
75 int md_short_jump_size
= 4;
76 int md_long_jump_size
= 4;
78 /* handle of the OPCODE hash table */
79 static struct hash_control
*op_hash
;
81 /* Sections and symbols we'll want to keep track of. */
82 static segT lita_sec
, rdata
, sdata
, lit8_sec
, lit4_sec
;
83 static symbolS
*lit8_sym
, *lit4_sym
;
85 /* Setting for ".set [no]{at,macro}". */
86 static int at_ok
= 1, macro_ok
= 1;
88 /* Keep track of global pointer. */
89 valueT alpha_gp_value
;
92 /* We'll probably be using this relocation frequently, and we
93 will want to compare for it. */
94 static reloc_howto_type
*gpdisp_hi16_howto
;
96 /* These are exported to ECOFF code. */
97 unsigned long alpha_gprmask
, alpha_fprmask
;
99 /* Used for LITUSE relocations. */
100 static expressionS lituse_basereg
, lituse_byteoff
, lituse_jsr
;
102 /* Address size: In OSF/1 1.3, an undocumented "-32addr" option will
103 cause all addresses to be treated as 32-bit values in memory. (The
104 in-register versions are all sign-extended to 64 bits, of course.)
105 Some other systems may want this option too. */
108 /* Symbol labelling the current insn. When the Alpha gas sees
111 and the section happens to not be on an eight byte boundary, it
112 will align both the symbol and the .quad to an eight byte boundary. */
113 static symbolS
*insn_label
;
115 /* Whether we should automatically align data generation pseudo-ops.
116 .align 0 will turn this off. */
117 static int auto_align
= 1;
119 /* Imported functions -- they should be defined in header files somewhere. */
120 extern segT
subseg_get ();
121 extern PTR
bfd_alloc_by_size_t ();
122 extern void s_globl (), s_long (), s_short (), s_space (), cons (), s_text (),
123 s_data (), float_cons ();
125 /* Static functions, needing forward declarations. */
126 static void s_base (), s_proc (), s_alpha_set ();
127 static void s_gprel32 (), s_rdata (), s_sdata (), s_alpha_comm ();
128 static void s_alpha_text
PARAMS ((int));
129 static void s_alpha_data
PARAMS ((int));
130 static void s_alpha_align
PARAMS ((int));
131 static void s_alpha_cons
PARAMS ((int));
132 static void s_alpha_float_cons
PARAMS ((int));
133 static int alpha_ip ();
135 static void emit_unaligned_io
PARAMS ((char *, int, valueT
, int));
136 static void emit_load_unal
PARAMS ((int, valueT
, int));
137 static void emit_store_unal
PARAMS ((int, valueT
, int));
138 static void emit_byte_manip_r
PARAMS ((char *, int, int, int, int, int));
139 static void emit_extract_r
PARAMS ((int, int, int, int, int));
140 static void emit_insert_r
PARAMS ((int, int, int, int, int));
141 static void emit_mask_r
PARAMS ((int, int, int, int, int));
142 static void emit_sign_extend
PARAMS ((int, int));
143 static void emit_bis_r
PARAMS ((int, int, int));
144 static int build_mem
PARAMS ((int, int, int, bfd_signed_vma
));
145 static int build_operate_n
PARAMS ((int, int, int, int, int));
146 static void emit_sll_n
PARAMS ((int, int, int));
147 static void emit_ldah_num
PARAMS ((int, bfd_vma
, int));
148 static void emit_addq_r
PARAMS ((int, int, int));
149 static void emit_lda_n
PARAMS ((int, bfd_vma
, int));
150 static void emit_add64
PARAMS ((int, int, bfd_vma
));
151 static int in_range_signed
PARAMS ((bfd_vma
, int));
152 static void alpha_align
PARAMS ((int, int, symbolS
*));
154 const pseudo_typeS md_pseudo_table
[] =
156 {"common", s_comm
, 0}, /* is this used? */
157 {"comm", s_alpha_comm
, 0}, /* osf1 compiler does this */
158 {"text", s_alpha_text
, 0},
159 {"data", s_alpha_data
, 0},
160 {"rdata", s_rdata
, 0},
161 {"sdata", s_sdata
, 0},
162 {"gprel32", s_gprel32
, 0},
163 {"t_floating", s_alpha_float_cons
, 'd'},
164 {"s_floating", s_alpha_float_cons
, 'f'},
165 {"f_floating", s_alpha_float_cons
, 'F'},
166 {"g_floating", s_alpha_float_cons
, 'G'},
167 {"d_floating", s_alpha_float_cons
, 'D'},
170 {"aproc", s_proc
, 1},
171 {"set", s_alpha_set
, 0},
172 {"reguse", s_ignore
, 0},
173 {"livereg", s_ignore
, 0},
174 {"base", s_base
, 0}, /*??*/
175 {"option", s_ignore
, 0},
176 {"prologue", s_ignore
, 0},
177 {"aent", s_ignore
, 0},
178 {"ugen", s_ignore
, 0},
180 {"align", s_alpha_align
, 0},
181 {"byte", s_alpha_cons
, 0},
182 {"hword", s_alpha_cons
, 1},
183 {"int", s_alpha_cons
, 2},
184 {"long", s_alpha_cons
, 2},
185 {"octa", s_alpha_cons
, 4},
186 {"quad", s_alpha_cons
, 3},
187 {"short", s_alpha_cons
, 1},
188 {"word", s_alpha_cons
, 1},
189 {"double", s_alpha_float_cons
, 'd'},
190 {"float", s_alpha_float_cons
, 'f'},
191 {"single", s_alpha_float_cons
, 'f'},
193 /* We don't do any optimizing, so we can safely ignore these. */
194 {"noalias", s_ignore
, 0},
195 {"alias", s_ignore
, 0},
200 #define SA 21 /* shift for register Ra */
201 #define SB 16 /* shift for register Rb */
202 #define SC 0 /* shift for register Rc */
203 #define SN 13 /* shift for 8 bit immediate # */
209 #define RA 26 /* note: same as T12 */
216 #define OPCODE(X) (((X) >> 26) & 0x3f)
217 #define OP_FCN(X) (((X) >> 5) & 0x7f)
219 #ifndef FIRST_32BIT_QUADRANT
220 #define FIRST_32BIT_QUADRANT 0
223 int first_32bit_quadrant
= FIRST_32BIT_QUADRANT
;
224 int base_register
= FIRST_32BIT_QUADRANT
? ZERO
: GP
;
226 int no_mixed_code
= 0;
229 /* This array holds the chars that always start a comment. If the
230 pre-processor is disabled, these aren't very useful */
231 const char comment_chars
[] = "#";
233 /* This array holds the chars that only start a comment at the beginning of
234 a line. If the line seems to have the form '# 123 filename'
235 .line and .file directives will appear in the pre-processed output */
236 /* Note that input_file.c hand checks for '#' at the beginning of the
237 first line of the input file. This is because the compiler outputs
238 #NO_APP at the beginning of its output. */
239 /* Also note that C style comments are always recognized. */
240 const char line_comment_chars
[] = "#!";
242 /* Chars that can be used to separate mant from exp in floating point nums */
243 const char EXP_CHARS
[] = "eE";
245 const char line_separator_chars
[1];
247 /* Chars that mean this number is a floating point constant, as in
248 "0f12.456" or "0d1.2345e12". */
249 /* @@ Do all of these really get used on the alpha?? */
250 char FLT_CHARS
[] = "rRsSfFdDxXpP";
252 /* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
253 changed in read.c. Ideally it shouldn't have to know about it at all,
254 but nothing is ideal around here. */
259 bfd_reloc_code_real_type code
;
262 /* Occasionally, two relocations will be desired for one address.
263 Mainly only in cases like "jsr $r,foo" where we want both a LITUSE
268 unsigned long opcode
; /* need at least 32 bits */
269 struct reloc_data reloc
[MAX_RELOCS
];
272 static void getExpression (char *str
, struct alpha_it
*insn
);
273 static char *expr_end
;
275 #define note_gpreg(R) (alpha_gprmask |= (1 << (R)))
276 #define note_fpreg(R) (alpha_fprmask |= (1 << (R)))
279 tc_get_register (frame
)
285 if (*input_line_pointer
== '$')
287 input_line_pointer
++;
288 if (input_line_pointer
[0] == 's'
289 && input_line_pointer
[1] == 'p')
291 input_line_pointer
+= 2;
295 framereg
= get_absolute_expression ();
296 framereg
&= 31; /* ? */
299 as_warn ("frame reg expected, using $%d.", framereg
);
301 note_gpreg (framereg
);
305 /* Handle the .text pseudo-op. This is like the usual one, but it
306 clears insn_label and restores auto alignment. */
317 /* Handle the .data pseudo-op. This is like the usual one, but it
318 clears insn_label and restores auto alignment. */
335 temp
= get_absolute_expression ();
338 rdata
= subseg_get (".rdata", 0);
339 subseg_set (rdata
, (subsegT
) temp
);
341 rdata
= subseg_new (".rdata", 0);
343 demand_empty_rest_of_line ();
354 temp
= get_absolute_expression ();
357 sdata
= subseg_get (".sdata", 0);
358 subseg_set (sdata
, (subsegT
) temp
);
360 sdata
= subseg_new (".sdata", 0);
362 demand_empty_rest_of_line ();
368 s_alpha_comm (ignore
)
375 register symbolS
*symbolP
;
377 name
= input_line_pointer
;
378 c
= get_symbol_end ();
379 /* just after name is now '\0' */
380 p
= input_line_pointer
;
383 /* Alpha OSF/1 compiler doesn't provide the comma, gcc does. */
384 if (*input_line_pointer
== ',')
386 input_line_pointer
++;
389 if ((temp
= get_absolute_expression ()) < 0)
391 as_warn (".COMMon length (%ld.) <0! Ignored.", (long) temp
);
392 ignore_rest_of_line ();
396 symbolP
= symbol_find_or_make (name
);
398 if (S_IS_DEFINED (symbolP
))
400 as_bad ("Ignoring attempt to re-define symbol");
401 ignore_rest_of_line ();
404 if (S_GET_VALUE (symbolP
))
406 if (S_GET_VALUE (symbolP
) != (valueT
) temp
)
407 as_bad ("Length of .comm \"%s\" is already %ld. Not changed to %ld.",
408 S_GET_NAME (symbolP
),
409 (long) S_GET_VALUE (symbolP
),
414 S_SET_VALUE (symbolP
, (valueT
) temp
);
415 S_SET_EXTERNAL (symbolP
);
418 know (symbolP
->sy_frag
== &zero_address_frag
);
419 demand_empty_rest_of_line ();
423 tc_gen_reloc (sec
, fixp
)
429 reloc
= (arelent
*) bfd_alloc_by_size_t (stdoutput
, sizeof (arelent
));
430 reloc
->sym_ptr_ptr
= &fixp
->fx_addsy
->bsym
;
431 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
433 if (fixp
->fx_r_type
> BFD_RELOC_UNUSED
)
436 if (fixp
->fx_r_type
== BFD_RELOC_ALPHA_GPDISP_HI16
)
438 if (!gpdisp_hi16_howto
)
439 gpdisp_hi16_howto
= bfd_reloc_type_lookup (stdoutput
,
441 reloc
->howto
= gpdisp_hi16_howto
;
444 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
445 if (reloc
->howto
== NULL
)
447 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
448 "cannot represent `%s' relocation in object file",
449 bfd_get_reloc_code_name (fixp
->fx_r_type
));
452 if (!fixp
->fx_pcrel
!= !reloc
->howto
->pc_relative
)
454 as_fatal ("internal error? cannot generate `%s' relocation",
455 bfd_get_reloc_code_name (fixp
->fx_r_type
));
457 assert (!fixp
->fx_pcrel
== !reloc
->howto
->pc_relative
);
459 if (fixp
->fx_r_type
== BFD_RELOC_ALPHA_LITERAL
)
461 /* fake out bfd_perform_relocation. sigh */
462 reloc
->addend
= -alpha_gp_value
;
464 else if (reloc
->howto
->pc_relative
&& reloc
->howto
->pcrel_offset
)
466 reloc
->addend
= fixp
->fx_offset
- reloc
->address
;
469 reloc
->addend
= fixp
->fx_offset
;
476 if (first_32bit_quadrant
)
478 /* not fatal, but it might not work in the end */
479 as_warn ("File overrides no-base-register option.");
480 first_32bit_quadrant
= 0;
484 if (*input_line_pointer
== '$')
486 input_line_pointer
++;
487 if (*input_line_pointer
== 'r')
488 input_line_pointer
++;
491 base_register
= get_absolute_expression ();
492 if (base_register
< 0 || base_register
> 31)
495 as_warn ("Bad base register, using $%d.", base_register
);
497 demand_empty_rest_of_line ();
500 static int in_range_signed (val
, nbits
)
504 /* Look at top bit of value that would be stored, figure out how it
505 would be extended by the hardware, and see if that matches the
506 original supplied value. */
509 bfd_vma top_bit
, stored_value
, missing_bits
;
511 mask
= (one
<< nbits
) - 1;
512 stored_value
= val
& mask
;
513 top_bit
= stored_value
& (one
<< (nbits
- 1));
514 missing_bits
= val
& ~mask
;
515 /* will sign-extend */
518 /* all remaining bits beyond mask should be one */
519 missing_bits
|= mask
;
520 return missing_bits
+ 1 == 0;
524 /* all other bits should be zero */
525 return missing_bits
== 0;
530 static int in_range_unsigned (val
, nbits
)
534 /* Look at top bit of value that would be stored, figure out how it
535 would be extended by the hardware, and see if that matches the
536 original supplied value. */
539 bfd_vma top_bit
, stored_value
, missing_bits
;
541 mask
= (one
<< nbits
) - 1;
542 stored_value
= val
& mask
;
543 top_bit
= stored_value
& (one
<< nbits
- 1);
544 missing_bits
= val
& ~mask
;
545 return missing_bits
== 0;
560 e
.X_add_symbol
= section_symbol (absolute_section
);
570 alpha_align (2, 0, insn_label
);
573 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 4, &e
, 0,
579 create_literal_section (secp
, name
)
583 segT current_section
= now_seg
;
584 int current_subsec
= now_subseg
;
587 *secp
= new_sec
= subseg_new (name
, 0);
588 subseg_set (current_section
, current_subsec
);
589 bfd_set_section_alignment (stdoutput
, new_sec
, 3);
590 bfd_set_section_flags (stdoutput
, new_sec
,
591 SEC_RELOC
| SEC_ALLOC
| SEC_LOAD
| SEC_READONLY
596 get_lit8_offset (val
)
602 create_literal_section (&lit8_sec
, ".lit8");
603 lit8_sym
= section_symbol (lit8_sec
);
605 retval
= add_to_literal_pool ((symbolS
*) 0, val
, lit8_sec
, 8);
606 if (retval
>= 0xfff0)
607 as_fatal ("overflow in fp literal (.lit8) table");
612 get_lit4_offset (val
)
618 create_literal_section (&lit4_sec
, ".lit4");
619 lit4_sym
= section_symbol (lit4_sec
);
621 retval
= add_to_literal_pool ((symbolS
*) 0, val
, lit4_sec
, 4);
622 if (retval
>= 0xfff0)
623 as_fatal ("overflow in fp literal (.lit4) table");
627 static struct alpha_it clear_insn
;
629 /* This function is called once, at assembler startup time. It should
630 set up all the tables, etc. that the MD part of the assembler will
631 need, that can be determined before arguments are parsed. */
635 const char *retval
, *name
;
638 op_hash
= hash_new ();
640 for (i
= 0; i
< NUMOPCODES
; )
642 const char *name
= alpha_opcodes
[i
].name
;
643 retval
= hash_insert (op_hash
, name
, (PTR
) &alpha_opcodes
[i
]);
645 as_fatal ("internal error: can't hash opcode `%s': %s",
650 while (i
< NUMOPCODES
651 && (alpha_opcodes
[i
].name
== name
652 || !strcmp (alpha_opcodes
[i
].name
, name
)));
654 /* Some opcodes include modifiers of various sorts with a "/mod"
655 syntax, like the architecture documentation suggests. However,
656 for use with gcc at least, we also need to access those same
657 opcodes without the "/". */
658 for (i
= 0; i
< NUMOPCODES
; )
660 name
= alpha_opcodes
[i
].name
;
662 if (strchr (name
, '/'))
664 char *p
= xmalloc (strlen (name
));
665 const char *q
= name
;
673 retval
= hash_insert (op_hash
, p
, (PTR
) &alpha_opcodes
[i
]);
674 /* Ignore failures -- the opcode table does duplicate some
675 variants in different forms, like "hw_stq" and "hw_st/q".
676 Maybe the variants can be eliminated, and this error
677 checking restored. */
682 while (i
< NUMOPCODES
683 && (alpha_opcodes
[i
].name
== name
684 || !strcmp (alpha_opcodes
[i
].name
, name
)));
687 lituse_basereg
.X_op
= O_constant
;
688 lituse_basereg
.X_add_number
= 1;
689 lituse_byteoff
.X_op
= O_constant
;
690 lituse_byteoff
.X_add_number
= 2;
691 lituse_jsr
.X_op
= O_constant
;
692 lituse_jsr
.X_add_number
= 3;
694 /* So .sbss will get used for tiny objects. */
695 bfd_set_gp_size (stdoutput
, 8);
696 create_literal_section (&lita_sec
, ".lita");
697 /* For handling the GP, create a symbol that won't be output in the
698 symbol table. We'll edit it out of relocs later. */
699 gp
= symbol_create ("<GP value>", lita_sec
, 0x8000, &zero_address_frag
);
701 memset (&clear_insn
, 0, sizeof (clear_insn
));
702 for (i
= 0; i
< MAX_RELOCS
; i
++)
703 clear_insn
.reloc
[i
].code
= BFD_RELOC_NONE
;
710 struct alpha_it
*insn
;
717 /* put out the opcode */
718 md_number_to_chars (toP
, insn
->opcode
, 4);
720 /* put out the symbol-dependent stuff */
721 for (j
= 0; j
< MAX_RELOCS
; j
++)
723 struct reloc_data
*r
= &insn
->reloc
[j
];
726 if (r
->code
!= BFD_RELOC_NONE
)
728 if (r
->exp
.X_op
== O_constant
)
730 r
->exp
.X_add_symbol
= section_symbol (absolute_section
);
731 r
->exp
.X_op
= O_symbol
;
733 f
= fix_new_exp (frag_now
, (toP
- frag_now
->fr_literal
), 4,
734 &r
->exp
, r
->pcrel
, r
->code
);
735 if (r
->code
== BFD_RELOC_ALPHA_GPDISP_LO16
)
737 static bit_fixS cookie
;
738 /* @@ This'll make the range checking in write.c shut up. */
739 f
->fx_bit_fixP
= &cookie
;
753 struct alpha_it insns
[MAX_INSNS
];
755 count
= alpha_ip (str
, insns
);
759 for (i
= 0; i
< count
; i
++)
760 emit_insn (&insns
[i
]);
770 vma
= bfd_get_section_vma (foo
, sec
);
771 if (vma
&& vma
< alpha_gp_value
)
772 alpha_gp_value
= vma
;
778 if (alpha_gp_value
!= 0)
781 /* Get minus-one in whatever width... */
782 alpha_gp_value
= 0; alpha_gp_value
--;
784 /* Select the smallest VMA of these existing sections. */
785 maybe_set_gp (lita_sec
);
786 /* maybe_set_gp (sdata); Was disabled before -- should we use it? */
788 maybe_set_gp (lit8_sec
);
789 maybe_set_gp (lit4_sec
);
792 alpha_gp_value
+= GP_ADJUSTMENT
;
794 S_SET_VALUE (gp
, alpha_gp_value
);
797 printf ("Chose GP value of %lx\n", alpha_gp_value
);
802 alpha_force_relocation (f
)
805 switch (f
->fx_r_type
)
807 case BFD_RELOC_ALPHA_GPDISP_HI16
:
808 case BFD_RELOC_ALPHA_GPDISP_LO16
:
809 case BFD_RELOC_ALPHA_LITERAL
:
810 case BFD_RELOC_ALPHA_LITUSE
:
811 case BFD_RELOC_GPREL32
:
813 case BFD_RELOC_ALPHA_HINT
:
818 case BFD_RELOC_23_PCREL_S2
:
821 case BFD_RELOC_12_PCREL
:
830 alpha_fix_adjustable (f
)
833 /* Are there any relocation types for which we must generate a reloc
834 but we can adjust the values contained within it? */
835 switch (f
->fx_r_type
)
837 case BFD_RELOC_ALPHA_GPDISP_HI16
:
838 case BFD_RELOC_ALPHA_GPDISP_LO16
:
840 case BFD_RELOC_GPREL32
:
843 return !alpha_force_relocation (f
);
849 md_section_align (seg
, size
)
854 /* This should probably be handled within BFD, or by pulling the
855 number from BFD at least. */
864 build_mem (opc
, ra
, rb
, disp
)
868 if ((disp
>> 15) != 0
869 && (disp
>> 15) + 1 != 0)
871 return ((opc
<< 26) | (ra
<< SA
) | (rb
<< SB
) | (disp
& 0xffff));
875 build_operate_n (opc
, fn
, ra
, lit
, rc
)
881 return ((opc
<< 26) | (fn
<< 5) | (ra
<< SA
) | (lit
<< SN
) | (1 << 12) | (rc
<< SC
));
885 build_operate (opc
, fn
, ra
, rb
, rc
)
886 int opc
, fn
, ra
, rb
, rc
;
888 return ((opc
<< 26) | (fn
<< 5) | (ra
<< SA
) | (rb
<< SB
) | (rc
<< SC
));
891 /* Add this thing to the .lita section and produce a LITERAL reloc referring
894 /* Are we currently eligible to emit a LITUSE reloc for the literal
895 references just generated? */
896 static int lituse_pending
;
899 load_symbol_address (reg
, insn
)
901 struct alpha_it
*insn
;
903 static symbolS
*lita_sym
;
910 lita_sym
= section_symbol (lita_sec
);
911 S_CLEAR_EXTERNAL (lita_sym
);
914 retval
= add_to_literal_pool (insn
->reloc
[0].exp
.X_add_symbol
,
915 insn
->reloc
[0].exp
.X_add_number
,
918 /* Now emit a LITERAL relocation for the original section. */
919 insn
->reloc
[0].exp
.X_op
= O_symbol
;
920 insn
->reloc
[0].exp
.X_add_symbol
= lita_sym
;
921 insn
->reloc
[0].exp
.X_add_number
= retval
;
922 insn
->reloc
[0].code
= BFD_RELOC_ALPHA_LITERAL
;
925 if (retval
== 0x8000)
927 as_fatal ("overflow in literal (.lita) table");
929 insn
->opcode
= build_mem (addr32
? 0x28 : 0x29, /* ldl or ldq */
930 reg
, base_register
, x
& 0xffff);
931 note_gpreg (base_register
);
934 /* To load an address with a single instruction,
935 emit a LITERAL reloc in this section, and a REFQUAD
936 for the .lita section, so that we'll be able to access
938 lda REG, xx -> ldq REG, -32752(gp)
939 lda REG, xx+4 -> ldq REG, -32752(gp)
942 The offsets need to start near -0x8000, and the generated LITERAL
943 relocations should negate the offset. I don't completely grok the
947 load_expression (reg
, insn
)
949 struct alpha_it
*insn
;
951 valueT addend
, addendhi
, addendlo
;
954 if (insn
->reloc
[0].exp
.X_add_symbol
->bsym
->flags
& BSF_SECTION_SYM
)
960 addend
= insn
->reloc
[0].exp
.X_add_number
;
961 insn
->reloc
[0].exp
.X_add_number
= 0;
963 load_symbol_address (reg
, insn
);
966 if ((addend
& ~0x7fffffff) != 0
967 && (addend
& ~0x7fffffff) + 0x80000000 != 0)
969 as_bad ("assembler not prepared to handle constants >32 bits yet");
972 addendlo
= addend
& 0xffff;
974 addendhi
= addend
>> 16;
975 if (addendlo
& 0x8000)
977 /* It appears that the BASEREG LITUSE reloc should not be used on
978 an LDAH instruction. */
981 insn
[1].opcode
= build_mem (0x08, reg
, reg
, addendlo
& 0xffff);
982 insn
[1].reloc
[0].code
= BFD_RELOC_ALPHA_LITUSE
;
983 insn
[1].reloc
[0].exp
= lituse_basereg
;
988 insn
[num_insns
].opcode
= build_mem (0x09, reg
, reg
,
1000 getExpression (str
, this_insn
)
1002 struct alpha_it
*this_insn
;
1007 #if 0 /* Not converted to bfd yet, and I don't think we need them
1008 for ECOFF. Re-adding a.out support will probably require
1010 static const struct am
{
1012 bfd_reloc_code_real_type reloc
;
1014 { "hi", RELOC_48_63
},
1015 { "lo", RELOC_0_15
},
1016 { "ml", RELOC_16_31
},
1017 { "mh", RELOC_32_47
},
1018 { "uhi", RELOC_U_48_63
},
1019 { "uml", RELOC_U_16_31
},
1020 { "umh", RELOC_U_32_47
},
1024 /* Handle macros: "%macroname(expr)" */
1035 while (*q
&& *p
== *q
)
1043 str
= p
; /* keep the '(' */
1044 this_insn
->reloc
= m
->reloc
;
1049 save_in
= input_line_pointer
;
1050 input_line_pointer
= str
;
1052 seg
= expression (&this_insn
->reloc
[0].exp
);
1053 /* XXX validate seg and exp, make sure they're reasonable */
1054 expr_end
= input_line_pointer
;
1055 input_line_pointer
= save_in
;
1059 emit_unaligned_io (dir
, addr_reg
, addr_offset
, reg
)
1065 sprintf (buf
, "%sq_u $%d,%ld($%d)", dir
, reg
, (long) addr_offset
, addr_reg
);
1070 emit_load_unal (addr_reg
, addr_offset
, reg
)
1074 emit_unaligned_io ("ld", addr_reg
, addr_offset
, reg
);
1078 emit_store_unal (addr_reg
, addr_offset
, reg
)
1082 emit_unaligned_io ("st", addr_reg
, addr_offset
, reg
);
1086 emit_byte_manip_r (op
, in
, mask
, out
, mode
, which
)
1088 int in
, mask
, out
, mode
, which
;
1091 sprintf (buf
, "%s%c%c $%d,$%d,$%d", op
, mode
, which
, in
, mask
, out
);
1096 emit_extract_r (in
, mask
, out
, mode
, which
)
1097 int in
, mask
, out
, mode
, which
;
1099 emit_byte_manip_r ("ext", in
, mask
, out
, mode
, which
);
1103 emit_insert_r (in
, mask
, out
, mode
, which
)
1104 int in
, mask
, out
, mode
, which
;
1106 emit_byte_manip_r ("ins", in
, mask
, out
, mode
, which
);
1110 emit_mask_r (in
, mask
, out
, mode
, which
)
1111 int in
, mask
, out
, mode
, which
;
1113 emit_byte_manip_r ("msk", in
, mask
, out
, mode
, which
);
1117 emit_sign_extend (reg
, size
)
1121 sprintf (buf
, "sll $%d,0x%x,$%d", reg
, 64 - size
, reg
);
1123 sprintf (buf
, "sra $%d,0x%x,$%d", reg
, 64 - size
, reg
);
1128 emit_bis_r (in1
, in2
, out
)
1132 sprintf (buf
, "bis $%d,$%d,$%d", in1
, in2
, out
);
1137 emit_sll_n (dest
, disp
, src
)
1138 int dest
, disp
, src
;
1140 struct alpha_it insn
= clear_insn
;
1141 insn
.opcode
= build_operate_n (0x12, 0x39, src
, disp
, dest
);
1146 emit_ldah_num (dest
, addend
, src
)
1150 struct alpha_it insn
= clear_insn
;
1151 insn
.opcode
= build_mem (0x09, dest
, src
, addend
);
1156 emit_addq_r (in1
, in2
, out
)
1159 struct alpha_it insn
= clear_insn
;
1160 insn
.opcode
= build_operate (0x10, 0x20, in1
, in2
, out
);
1165 emit_lda_n (dest
, addend
, src
)
1169 struct alpha_it insn
= clear_insn
;
1170 insn
.opcode
= build_mem (0x08, dest
, src
, addend
);
1175 emit_add64 (in
, out
, num
)
1179 bfd_signed_vma snum
= num
;
1181 if (in_range_signed (num
, 16))
1183 emit_lda_n (out
, num
, in
);
1186 if ((num
& 0xffff) == 0
1188 && in_range_signed (snum
>> 16, 16))
1190 emit_ldah_num (out
, snum
>> 16, in
);
1193 /* I'm not sure this one is getting invoked when it could. */
1194 if ((num
& 1) == 0 && in
== ZERO
)
1196 if (in_range_signed (snum
>> 1, 16))
1198 emit_lda_n (out
, snum
>> 1, in
);
1199 emit_addq_r (out
, out
, out
);
1202 else if (num
& 0x1fffe == 0
1203 && in_range_signed (snum
>> 17, 16))
1205 emit_ldah_num (out
, snum
>> 17, in
);
1206 emit_addq_r (out
, out
, out
);
1210 if (in_range_signed (num
, 32))
1212 bfd_vma lo
= num
& 0xffff;
1216 emit_ldah_num (out
, snum
>> 16, in
);
1218 emit_lda_n (out
, lo
, out
);
1222 if (in
!= ZERO
&& in
!= AT
&& out
!= AT
&& at_ok
)
1224 emit_add64 (ZERO
, AT
, num
);
1225 emit_addq_r (AT
, in
, out
);
1230 as_bad ("load expression too complex to expand");
1232 /* Could check also for loading 16- or 32-bit value and shifting by
1233 arbitrary displacement. */
1236 bfd_vma lo
= snum
& 0xffffffff;
1237 if (lo
& 0x80000000)
1238 lo
-= ((bfd_vma
)0x10000000 << 4);
1240 emit_add64 (ZERO
, out
, snum
>> 32);
1241 emit_sll_n (out
, 32, out
);
1243 emit_add64 (out
, out
, lo
);
1248 alpha_ip (str
, insns
)
1250 struct alpha_it insns
[];
1256 struct alpha_opcode
*pattern
;
1258 unsigned int opcode
;
1259 unsigned int mask
= 0;
1260 int match
= 0, num_gen
= 1;
1262 int do_add64
, add64_in
= 0, add64_out
= 0;
1263 bfd_vma add64_addend
= 0;
1266 islower (*s
) || *s
== '_' || *s
== '/' || *s
== '4' || *s
== '8';
1285 as_fatal ("Unknown opcode: `%s'", str
);
1287 if ((pattern
= (struct alpha_opcode
*) hash_find (op_hash
, str
)) == NULL
)
1289 as_bad ("Unknown opcode: `%s'", str
);
1299 opcode
= pattern
->match
;
1301 for (i
= 0; i
< MAX_INSNS
; i
++)
1302 insns
[i
] = clear_insn
;
1304 /* Build the opcode, checking as we go to make sure that the
1306 for (args
= pattern
->args
;; ++args
)
1311 case '\0': /* end of args */
1330 case '(': /* these must match exactly */
1339 case '1': /* next operand must be a register */
1349 case 'a': /* $at: as temporary */
1355 case 'g': /* $gp: base register */
1358 mask
= base_register
;
1361 case 's': /* $sp: stack pointer */
1368 case 'r': /* any register */
1369 if (!isdigit (c
= *s
++))
1386 if ((c
= 10 * (c
- '0') + (*s
++ - '0')) >= 32)
1395 if ((c
== GP
) && first_32bit_quadrant
)
1405 /* Got the register, now figure out where it goes in
1413 opcode
|= mask
<< SA
;
1418 opcode
|= mask
<< SB
;
1427 opcode
|= (mask
<< SA
) | mask
;
1430 case 'R': /* ra and rb are the same */
1431 opcode
|= (mask
<< SA
) | (mask
<< SB
);
1435 opcode
|= (mask
<< SA
) | (mask
<< SB
) | (mask
);
1441 case 'e': /* next operand is a floating point register */
1445 if (*s
++ == '$' && *s
++ == 'f' && isdigit (*s
))
1450 mask
= 10 * (mask
- '0') + (*s
++ - '0');
1461 /* same encoding as gp registers */
1467 case 'h': /* bits 16..31 */
1468 insns
[0].reloc
= RELOC_16_31
;
1472 case 'l': /* bits 0..15 */
1473 insns
[0].reloc
[0].code
= BFD_RELOC_16
;
1476 case 'L': /* 21 bit PC relative immediate */
1477 insns
[0].reloc
[0].code
= BFD_RELOC_23_PCREL_S2
;
1478 insns
[0].reloc
[0].pcrel
= 1;
1481 case 'i': /* 14 bit immediate */
1482 if (OPCODE (opcode
) != 0x1a)
1483 /* Not a jmp variant?? */
1485 else if (opcode
& 0x8000)
1486 /* ret or jsr_coroutine */
1488 insns
[0].reloc
[0].code
= BFD_RELOC_14
;
1489 insns
[0].reloc
[0].pcrel
= 0;
1494 insns
[0].reloc
[0].code
= BFD_RELOC_ALPHA_HINT
;
1495 insns
[0].reloc
[0].pcrel
= 1;
1499 case 'b': /* 8 bit immediate */
1500 insns
[0].reloc
[0].code
= BFD_RELOC_8
;
1503 case 'I': /* 26 bit immediate, for PALcode */
1504 insns
[0].reloc
[0].code
= BFD_RELOC_26
;
1507 case 't': /* 12 bit displacement, for PALcode */
1508 insns
[0].reloc
[0].code
= BFD_RELOC_12_PCREL
;
1511 case '8': /* 8 bit 0...7 */
1512 insns
[0].reloc
[0].code
= BFD_RELOC_8
;
1518 getExpression (s
, &insns
[0]);
1520 /* Handle overflow in certain instructions by converting
1521 to other instructions. */
1522 if (insns
[0].reloc
[0].code
== BFD_RELOC_8
1523 && insns
[0].reloc
[0].exp
.X_op
== O_constant
1524 && (insns
[0].reloc
[0].exp
.X_add_number
< 0
1525 || insns
[0].reloc
[0].exp
.X_add_number
> 0xff))
1527 if (OPCODE (opcode
) == 0x10
1528 && (OP_FCN (opcode
) == 0x00 /* addl */
1529 || OP_FCN (opcode
) == 0x40 /* addl/v */
1530 || OP_FCN (opcode
) == 0x20 /* addq */
1531 || OP_FCN (opcode
) == 0x60 /* addq/v */
1532 || OP_FCN (opcode
) == 0x09 /* subl */
1533 || OP_FCN (opcode
) == 0x49 /* subl/v */
1534 || OP_FCN (opcode
) == 0x29 /* subq */
1535 || OP_FCN (opcode
) == 0x69 /* subq/v */
1536 || OP_FCN (opcode
) == 0x02 /* s4addl */
1537 || OP_FCN (opcode
) == 0x22 /* s4addq */
1538 || OP_FCN (opcode
) == 0x0b /* s4subl */
1539 || OP_FCN (opcode
) == 0x2b /* s4subq */
1540 || OP_FCN (opcode
) == 0x12 /* s8addl */
1541 || OP_FCN (opcode
) == 0x32 /* s8addq */
1542 || OP_FCN (opcode
) == 0x1b /* s8subl */
1543 || OP_FCN (opcode
) == 0x3b /* s8subq */
1545 /* Can we make it fit by negating? */
1546 && -insns
[0].reloc
[0].exp
.X_add_number
< 0xff
1547 && -insns
[0].reloc
[0].exp
.X_add_number
> 0)
1549 opcode
^= 0x120; /* convert add<=>sub */
1550 insns
[0].reloc
[0].exp
.X_add_number
*= -1;
1552 else if (at_ok
&& macro_ok
)
1554 /* Constant value supplied, but it's too large. */
1558 add64_addend
= insns
[0].reloc
[0].exp
.X_add_number
;
1560 opcode
|= (AT
<< SB
);
1561 insns
[0].reloc
[0].code
= BFD_RELOC_NONE
;
1564 as_bad ("overflow in 8-bit literal field in `operate' format insn");
1566 else if (insns
[0].reloc
[0].code
== BFD_RELOC_16
1567 && insns
[0].reloc
[0].exp
.X_op
== O_constant
1568 && !in_range_signed (insns
[0].reloc
[0].exp
.X_add_number
,
1571 bfd_vma val
= insns
[0].reloc
[0].exp
.X_add_number
;
1572 if (OPCODE (opcode
) == 0x08)
1579 opcode
|= (AT
<< SB
);
1580 insns
[0].reloc
[0].code
= BFD_RELOC_NONE
;
1582 else if (OPCODE (opcode
) == 0x09
1583 && in_range_signed (val
>> 16, 16))
1585 /* ldah with high operand - convert to low */
1586 insns
[0].reloc
[0].exp
.X_add_number
>>= 16;
1589 as_bad ("I don't know how to handle 32+ bit constants here yet, sorry.");
1591 else if (insns
[0].reloc
[0].code
== BFD_RELOC_32
1592 && insns
[0].reloc
[0].exp
.X_op
== O_constant
)
1594 bfd_vma val
= insns
[0].reloc
[0].exp
.X_add_number
;
1595 bfd_signed_vma sval
= val
;
1598 && sval
>> 32 != -1)
1599 as_bad ("I don't know how to handle 64 bit constants here yet, sorry.");
1605 int format
, length
, mode
, i
;
1606 char temp
[20 /*MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT*/];
1608 static const char formats
[4] = "FGfd";
1609 bfd_vma bits
, offset
;
1610 char *old_input_line_pointer
= input_line_pointer
;
1612 input_line_pointer
= s
;
1614 memset (temp
, 0, sizeof (temp
));
1615 mode
= (opcode
>> 26) & 3;
1616 format
= formats
[mode
];
1617 err
= md_atof (format
, temp
, &length
);
1620 as_bad ("Bad floating literal: %s", err
);
1625 /* Generate little-endian number from byte sequence. */
1627 for (i
= length
- 1; i
>= 0; i
--)
1628 bits
+= ((bfd_vma
)(temp
[i
] & 0xff)) << (i
* 8);
1633 offset
= get_lit8_offset (bits
) - 0x8000;
1634 insns
[0].reloc
[0].exp
.X_add_symbol
= lit8_sym
;
1635 insns
[0].reloc
[0].exp
.X_add_number
= 0x8000;
1638 offset
= get_lit4_offset (bits
) - 0x8000;
1639 insns
[0].reloc
[0].exp
.X_add_symbol
= lit4_sym
;
1640 insns
[0].reloc
[0].exp
.X_add_number
= 0x8000;
1645 insns
[0].reloc
[0].exp
.X_op
= O_symbol
;
1647 num_gen
= load_expression (AT
, &insns
[0]);
1650 insns
[num_gen
].reloc
[0].code
= BFD_RELOC_ALPHA_LITUSE
;
1651 insns
[num_gen
].reloc
[0].exp
= lituse_basereg
;
1654 insns
[num_gen
++].opcode
= opcode
| (AT
<< SB
) | offset
;
1655 opcode
= insns
[0].opcode
;
1656 s
= input_line_pointer
;
1657 input_line_pointer
= old_input_line_pointer
;
1661 /* The following two.. take advantage of the fact that
1662 opcode already contains most of what we need to know.
1663 We just prepend to the instr an "ldah
1664 $r,%ml(expr)($base)" and turn this one (done later
1665 after we return) into something like "stq
1666 $r,%lo(expr)(at)" or "ldq $r,%lo(expr)($r)".
1668 NOTE: This can fail later on at link time if the
1669 offset from $base actually turns out to be more than
1670 2**31 or 2**47 if use_large_offsets is set. */
1671 case 'P': /* Addressing macros: PUT */
1672 mask
= AT
; /* register 'at' */
1675 case 'G': /* Addressing macros: GET */
1676 /* All it is missing is the expression, which is what we
1681 getExpression (s
, &insns
[0]);
1684 /* Must check for "lda ..,number" too */
1685 if (insns
[0].reloc
[0].exp
.X_op
== O_big
)
1687 as_warn ("Sorry, not yet. Put bignums in .data section yourself.");
1690 if (insns
[0].reloc
[0].exp
.X_op
== O_constant
)
1692 bfd_vma val
= insns
[0].reloc
[0].exp
.X_add_number
;
1695 insns
[0].reloc
[0].code
= BFD_RELOC_NONE
;
1696 insns
[1].reloc
[0].code
= BFD_RELOC_NONE
;
1711 opcode
|= ZERO
<< SB
;
1713 opcode
|= low
& 0xffff;
1715 else if (insns
[0].reloc
[0].exp
.X_op
== O_symbol
)
1717 unsigned long old_opcode
= opcode
;
1721 as_bad ("insn requires expansion but `nomacro' specified");
1722 else if (*args
== 'G')
1725 as_bad ("insn expansion requires AT use, but `noat' specified");
1728 num_gen
= load_expression (tmp_reg
, insns
);
1729 opcode
= insns
[0].opcode
;
1730 /* lda is opcode 8, 0x20000000, and the macros that use
1731 this code have an opcode field of 0. The latter
1732 require further processing, and we don't have the
1733 true opcode here. */
1734 if (OPCODE (old_opcode
) != 0
1735 && OPCODE (old_opcode
) != 0x08)
1738 i
= &insns
[num_gen
++];
1739 i
->opcode
= old_opcode
| (tmp_reg
<< SB
);
1743 i
->reloc
[0].code
= BFD_RELOC_ALPHA_LITUSE
;
1744 i
->reloc
[0].exp
= lituse_basereg
;
1753 insns
[1].reloc
[0].exp
= insns
[0].reloc
[0].exp
;
1755 /* Generate: ldah REG,x1(GP); OP ?,x0(REG) */
1757 abort (); /* relocs need fixing */
1759 insns
[1].reloc
= RELOC_0_15
;
1760 insns
[1].opcode
= opcode
| mask
<< SB
;
1762 insns
[0].reloc
= RELOC_16_31
;
1763 opcode
= 0x24000000 /*ldah*/ | mask
<< SA
| (base_register
<< SB
);
1769 /* Same failure modes as above, actually most of the
1770 same code shared. */
1771 case 'B': /* Builtins */
1776 case 'a': /* ldgp */
1778 if (first_32bit_quadrant
|| no_mixed_code
)
1780 switch (OUTPUT_FLAVOR
)
1782 case bfd_target_aout_flavour
:
1783 /* this is cmu's a.out version */
1784 insns
[0].reloc
[0].code
= BFD_RELOC_NONE
;
1785 /* generate "zap %r,0xf,%r" to take high 32 bits */
1786 opcode
|= 0x48001600 /* zap ?,#,?*/ | (0xf << SN
);
1788 case bfd_target_ecoff_flavour
:
1789 /* Given "ldgp R1,N(R2)", turn it into something
1790 like "ldah R1,###(R2) ; lda R1,###(R1)" with
1791 appropriate constants and relocations. */
1793 unsigned long r1
, r2
;
1794 unsigned long addend
= 0;
1799 insns
[0].reloc
[0].code
= BFD_RELOC_ALPHA_GPDISP_HI16
;
1800 insns
[0].reloc
[0].pcrel
= 1;
1801 insns
[0].reloc
[0].exp
.X_op
= O_symbol
;
1802 insns
[0].reloc
[0].exp
.X_add_symbol
= gp
;
1803 insns
[0].reloc
[0].exp
.X_add_number
= 0;
1804 insns
[0].opcode
= (0x24000000 /* ldah */
1807 insns
[1].reloc
[0].code
= BFD_RELOC_ALPHA_GPDISP_LO16
;
1808 insns
[1].reloc
[0].exp
.X_op
= O_symbol
;
1809 insns
[1].reloc
[0].exp
.X_add_symbol
= gp
;
1810 insns
[1].reloc
[0].exp
.X_add_number
= 4;
1811 insns
[1].reloc
[0].pcrel
= 1;
1812 insns
[1].opcode
= 0x20000000 | (r1
<< SA
) | (r1
<< SB
);
1813 opcode
= insns
[0].opcode
;
1814 /* merge in addend */
1815 insns
[1].opcode
|= addend
& 0xffff;
1816 insns
[0].opcode
|= ((addend
>> 16)
1817 + (addend
& 0x8000 ? 1 : 0));
1819 ecoff_set_gp_prolog_size (0);
1828 case 'b': /* setgp */
1829 switch (OUTPUT_FLAVOR
)
1831 case bfd_target_aout_flavour
:
1832 /* generate "zap %r,0xf,$gp" to take high 32 bits */
1833 opcode
|= 0x48001600 /* zap ?,#,?*/
1834 | (0xf << SN
) | (base_register
);
1841 case 'c': /* jsr $r,foo becomes
1844 Register 27, t12, is used by convention
1847 struct alpha_it
*jsr
;
1849 struct reloc_data
*r
;
1851 /* We still have to parse the function name */
1854 getExpression (s
, &insns
[0]);
1855 etmp
= insns
[0].reloc
[0].exp
;
1857 num_gen
= load_expression (PV
, &insns
[0]);
1860 jsr
= &insns
[num_gen
++];
1861 jsr
->opcode
= (pattern
->match
1867 /* LITUSE wasn't emitted yet */
1868 jsr
->reloc
[0].code
= BFD_RELOC_ALPHA_LITUSE
;
1869 jsr
->reloc
[0].exp
= lituse_jsr
;
1876 r
->code
= BFD_RELOC_ALPHA_HINT
;
1878 opcode
= insns
[0].opcode
;
1883 /* Sub-word loads and stores. We load the address into
1884 $at, which might involve using the `P' parameter
1885 processing too, then emit a sequence to get the job
1886 done, using unaligned memory accesses and byte
1887 manipulation, with t9 and t10 as temporaries. */
1889 /* Characteristics of access. */
1890 int is_load
= 99, is_unsigned
= 0, is_unaligned
= 0;
1891 int mode_size
, mode
;
1892 /* Register operand. */
1894 /* Addend for loads and stores. */
1896 /* Which register do we use for the address? */
1900 /* Pick apart name and set flags. */
1901 const char *s
= pattern
->name
;
1909 if (s
[0] == 'l' && s
[1] == 'd')
1911 else if (s
[0] == 's' && s
[1] == 't')
1914 as_fatal ("unrecognized sub-word access insn `%s'",
1919 if (mode
== 'b') mode_size
= 1;
1920 else if (mode
== 'w') mode_size
= 2;
1921 else if (mode
== 'l') mode_size
= 4;
1922 else if (mode
== 'q') mode_size
= 8;
1933 /* Longwords are always kept sign-extended. */
1934 if (mode
== 'l' && is_unsigned
)
1936 /* There's no special unaligned byte handling. */
1937 if (mode
== 'b' && is_unaligned
)
1939 /* Stores don't care about signedness. */
1940 if (!is_load
&& is_unsigned
)
1944 if (args
[-2] == 'P')
1953 r1 -> (opcode >> SA) & 31
1954 num -> insns->reloc[0].*
1956 We want to emit "lda at,num(r2)", since these
1957 operations require the use of a single register
1958 with the starting address of the memory operand
1961 We could probably get away without doing this
1962 (and use r2 below, with the addend for the
1963 actual reads and writes) in cases where the
1964 addend is known to be a multiple of 8. */
1966 int r1
= (opcode
>> SA
) & 31;
1968 if (insns
[0].reloc
[0].code
== BFD_RELOC_NONE
)
1970 else if (insns
[0].reloc
[0].code
== BFD_RELOC_16
)
1972 if (insns
[0].reloc
[0].exp
.X_op
!= O_constant
)
1974 addend
= insns
[0].reloc
[0].exp
.X_add_number
;
1979 if (addend
+ mode_size
- 1 < 0x7fff
1980 && (addend
% 8) == 0
1981 && (r2
< T9
|| r2
> T12
))
1988 /* Let later relocation processing deal
1989 with the addend field. */
1990 insns
[num_gen
-1].opcode
= (0x20000000 /* lda */
1999 /* Because the emit_* routines append directly to
2000 the current frag, we now need to flush any
2004 for (i
= 0; i
< num_gen
; i
++)
2005 emit_insn (&insns
[i
]);
2011 int reg2
, reg3
= -1;
2014 reg2
= T9
, reg3
= T10
;
2018 emit_load_unal (addr
, addend
, T9
);
2020 emit_load_unal (addr
, addend
+ mode_size
- 1, T10
);
2021 emit_extract_r (T9
, addr
, reg2
, mode
, 'l');
2024 emit_extract_r (T10
, addr
, reg3
, mode
, 'h');
2025 emit_bis_r (T9
, T10
, reg
);
2028 emit_sign_extend (reg
, mode_size
* 8);
2032 /* The second word gets processed first
2033 because if the address does turn out to be
2034 aligned, the processing for the second word
2035 will be pushing around all-zeros, and the
2036 entire value will be handled as the `first'
2037 word. So we want to store the `first' word
2039 /* Pair these up so that the memory loads get
2040 separated from each other, as well as being
2041 well in advance of the uses of the values
2045 emit_load_unal (addr
, addend
+ mode_size
- 1, T11
);
2046 emit_insert_r (reg
, addr
, T12
, mode
, 'h');
2048 emit_load_unal (addr
, addend
, T9
);
2049 emit_insert_r (reg
, addr
, T10
, mode
, 'l');
2051 emit_mask_r (T12
, addr
, T12
, mode
, 'h');
2052 emit_mask_r (T10
, addr
, T10
, mode
, 'l');
2054 emit_bis_r (T11
, T12
, T11
);
2055 emit_bis_r (T9
, T10
, T9
);
2057 emit_store_unal (addr
, addend
+ mode_size
- 1, T11
);
2058 emit_store_unal (addr
, addend
, T9
);
2063 /* DIVISION and MODULUS. Yech.
2064 Convert OP x,y,result
2070 with appropriate optimizations if t10,t11,t12
2071 are the registers specified by the compiler.
2072 We are missing an obvious optimization
2073 opportunity here; if the ldq generated by the
2074 jsr assembly requires a cycle or two to make
2075 the value available, initiating it before one
2076 or two of the mov instructions would result in
2077 faster execution. */
2078 case '0': /* reml */
2079 case '1': /* divl */
2080 case '2': /* remq */
2081 case '3': /* divq */
2082 case '4': /* remlu */
2083 case '5': /* divlu */
2084 case '6': /* remqu */
2085 case '7': /* divqu */
2087 static char func
[8][6] = {
2088 "reml", "divl", "remq", "divq",
2089 "remlu", "divlu", "remqu", "divqu"
2094 /* All regs parsed, in opcode */
2096 /* Do the expansions, one instr at a time */
2098 reg
= (opcode
>> SA
) & 31;
2102 sprintf (expansion
, "mov $%d,$%d", reg
, T10
);
2103 md_assemble (expansion
);
2105 reg
= (opcode
>> SB
) & 31;
2107 /* we already overwrote it! */
2109 else if (reg
!= T11
)
2112 sprintf (expansion
, "mov $%d,$%d", reg
, T11
);
2113 md_assemble (expansion
);
2115 sprintf (expansion
, "lda $%d,__%s", PV
, func
[*args
- '0']);
2116 md_assemble (expansion
);
2117 sprintf (expansion
, "jsr $%d,($%d),__%s", T9
, PV
,
2119 md_assemble (expansion
);
2121 if (!first_32bit_quadrant
)
2126 md_assemble (expansion
);
2129 sprintf (expansion
, "ldgp $%d,0($%d)",
2131 md_assemble (expansion
);
2133 /* Use insns[0] to get at the result */
2134 if ((reg
= (opcode
& 31)) != PV
)
2135 opcode
= (0x47e00400 /* or zero,zero,zero */
2137 | reg
/* Rc */ ); /* pv->z */
2153 /* Args don't match. */
2154 if (&pattern
[1] - alpha_opcodes
< NUMOPCODES
2155 && !strcmp (pattern
->name
, pattern
[1].name
))
2163 as_warn ("Illegal operands");
2169 /* Args match, see if a float instructions and -nofloats */
2170 if (nofloats
&& pattern
->isa_float
)
2178 /* If opcode represents an addq instruction, and the addend we
2179 are using fits in a 16 bit range, we can change the addq
2180 directly into an lda rather than emitting an lda followed by
2182 if (OPCODE (opcode
) == 0x10
2183 && OP_FCN (opcode
) == 0x20 /* addq */
2186 && in_range_signed (add64_addend
, 16))
2188 opcode
= (0x20000000 /* lda */
2189 | (((opcode
>> SC
) & 0x1f) << SA
)
2190 | (((opcode
>> SA
) & 0x1f) << SB
)
2191 | (add64_addend
& 0xffff));
2194 emit_add64 (add64_in
, add64_out
, add64_addend
);
2197 insns
[0].opcode
= opcode
;
2201 /* Turn a string in input_line_pointer into a floating point constant
2202 of type type, and store the appropriate bytes in *litP. The number
2203 of LITTLENUMS emitted is stored in *sizeP. An error message is
2204 returned, or NULL on OK. */
2206 /* Equal to MAX_PRECISION in atof-ieee.c */
2207 #define MAX_LITTLENUMS 6
2210 md_atof (type
, litP
, sizeP
)
2216 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
2217 LITTLENUM_TYPE
*wordP
;
2219 char *atof_ieee (), *vax_md_atof ();
2225 /* VAX md_atof doesn't like "G" for some reason. */
2229 return vax_md_atof (type
, litP
, sizeP
);
2252 return "Bad call to MD_ATOF()";
2254 t
= atof_ieee (input_line_pointer
, type
, words
);
2256 input_line_pointer
= t
;
2257 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
2259 for (wordP
= words
+ prec
- 1; prec
--;)
2261 md_number_to_chars (litP
, (long) (*wordP
--), sizeof (LITTLENUM_TYPE
));
2262 litP
+= sizeof (LITTLENUM_TYPE
);
2269 md_bignum_to_chars (buf
, bignum
, nchars
)
2271 LITTLENUM_TYPE
*bignum
;
2276 LITTLENUM_TYPE work
= *bignum
++;
2277 int nb
= CHARS_PER_LITTLENUM
;
2281 *buf
++ = work
& ((1 << BITS_PER_CHAR
) - 1);
2284 work
>>= BITS_PER_CHAR
;
2290 CONST
char *md_shortopts
= "Fm:g";
2291 struct option md_longopts
[] = {
2292 #define OPTION_32ADDR (OPTION_MD_BASE)
2293 {"32addr", no_argument
, NULL
, OPTION_32ADDR
},
2294 {NULL
, no_argument
, NULL
, 0}
2296 size_t md_longopts_size
= sizeof(md_longopts
);
2299 md_parse_option (c
, arg
)
2314 /* Ignore `-g' so gcc can provide this option to the Digital
2315 UNIX assembler, which otherwise would throw away info that
2316 mips-tfile needs. */
2327 md_show_usage (stream
)
2332 -32addr treat addresses as 32-bit values\n\
2333 -F lack floating point instructions support\n\
2334 -m21064 | -m21066 | -m21164\n\
2335 specify variant of Alpha architecture\n");
2342 /* XXXX Align to cache linesize XXXXX */
2349 /* Takes ".proc name,nargs" */
2350 name
= input_line_pointer
;
2351 c
= get_symbol_end ();
2352 p
= input_line_pointer
;
2353 symbolP
= symbol_find_or_make (name
);
2356 if (*input_line_pointer
!= ',')
2359 as_warn ("Expected comma after name \"%s\"", name
);
2362 ignore_rest_of_line ();
2366 input_line_pointer
++;
2367 temp
= get_absolute_expression ();
2369 /* symbolP->sy_other = (signed char) temp; */
2370 as_warn ("unhandled: .proc %s,%d", name
, temp
);
2371 demand_empty_rest_of_line ();
2378 char *name
= input_line_pointer
, ch
, *s
;
2381 while (!is_end_of_line
[(unsigned char) *input_line_pointer
])
2382 input_line_pointer
++;
2383 ch
= *input_line_pointer
;
2384 *input_line_pointer
= '\0';
2387 if (s
[0] == 'n' && s
[1] == 'o')
2392 if (!strcmp ("reorder", s
))
2394 else if (!strcmp ("at", s
))
2396 else if (!strcmp ("macro", s
))
2398 else if (!strcmp ("move", s
))
2400 else if (!strcmp ("volatile", s
))
2403 as_warn ("Tried to .set unrecognized mode `%s'", name
);
2404 *input_line_pointer
= ch
;
2405 demand_empty_rest_of_line ();
2408 /* @@ Is this right?? */
2410 md_pcrel_from (fixP
)
2413 valueT addr
= fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
2414 switch (fixP
->fx_r_type
)
2416 case BFD_RELOC_ALPHA_GPDISP_HI16
:
2417 case BFD_RELOC_ALPHA_GPDISP_LO16
:
2420 return fixP
->fx_size
+ addr
;
2424 /* Handle the .align pseudo-op. This aligns to a power of two. It
2425 also adjusts any current instruction label. We treat this the same
2426 way the MIPS port does: .align 0 turns off auto alignment. */
2429 s_alpha_align (ignore
)
2433 register long temp_fill
;
2434 long max_alignment
= 15;
2436 temp
= get_absolute_expression ();
2437 if (temp
> max_alignment
)
2438 as_bad ("Alignment too large: %d. assumed.", temp
= max_alignment
);
2441 as_warn ("Alignment negative: 0 assumed.");
2444 if (*input_line_pointer
== ',')
2446 input_line_pointer
++;
2447 temp_fill
= get_absolute_expression ();
2454 alpha_align (temp
, (int) temp_fill
, insn_label
);
2461 demand_empty_rest_of_line ();
2465 alpha_align (n
, fill
, label
)
2471 && (now_seg
== text_section
2472 || !strcmp (now_seg
->name
, ".init")
2473 || !strcmp (now_seg
->name
, ".fini"))
2476 static const unsigned char nop_pattern
[] = { 0x1f, 0x04, 0xff, 0x47 };
2477 /* First, make sure we're on a four-byte boundary, in case
2478 someone has been putting .byte values into the text section.
2479 The DEC assembler silently fills with unaligned no-op
2480 instructions. This will zero-fill, then nop-fill with proper
2482 frag_align (2, fill
);
2483 frag_align_pattern (n
, nop_pattern
, sizeof (nop_pattern
));
2486 frag_align (n
, fill
);
2490 assert (S_GET_SEGMENT (label
) == now_seg
);
2491 label
->sy_frag
= frag_now
;
2492 S_SET_VALUE (label
, (valueT
) frag_now_fix ());
2496 /* This function is called just before the generic pseudo-ops output
2497 something. It just clears insn_label. */
2500 alpha_flush_pending_output ()
2505 /* Handle data allocation pseudo-ops. This is like the generic
2506 version, but it makes sure the current label, if any, is correctly
2510 s_alpha_cons (log_size
)
2513 if (log_size
> 0 && auto_align
)
2514 alpha_align (log_size
, 0, insn_label
);
2516 cons (1 << log_size
);
2519 /* Handle floating point allocation pseudo-ops. This is like the
2520 generic vresion, but it makes sure the current label, if any, is
2521 correctly aligned. */
2524 s_alpha_float_cons (type
)
2553 alpha_align (log_size
, 0, insn_label
);
2560 /* This function is called whenever a label is defined. It is used to
2561 adjust the label when an automatic alignment occurs. */
2564 alpha_define_label (sym
)
2571 md_apply_fix (fixP
, valueP
)
2578 char *p
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
2582 switch (fixP
->fx_r_type
)
2584 /* The GPDISP relocations are processed internally with a symbol
2585 referring to the current function; we need to drop in a value
2586 which, when added to the address of the start of the function,
2587 gives the desired GP. */
2588 case BFD_RELOC_ALPHA_GPDISP_HI16
:
2589 case BFD_RELOC_ALPHA_GPDISP_LO16
:
2591 if (fixP
->fx_r_type
== BFD_RELOC_ALPHA_GPDISP_HI16
)
2593 assert (fixP
->fx_next
->fx_r_type
== BFD_RELOC_ALPHA_GPDISP_LO16
);
2596 fprintf_vma (stdout
, addend
);
2599 if (addend
& 0x8000)
2602 fixP
->fx_offset
= 4; /* @@ Compute this using fx_next. */
2608 fprintf_vma (stdout
, addend
);
2612 fixP
->fx_offset
= 0;
2614 md_number_to_chars (fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
,
2616 fixP
->fx_addsy
= section_symbol (absolute_section
);
2617 fixP
->fx_offset
+= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
2621 /* Write 8 bits, shifted left 13 bit positions. */
2625 *p
|= (value
<< 5) & 0xe0;
2633 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2634 "overflow in type-%d reloc", (int) fixP
->fx_r_type
);
2644 /* Don't want overflow checking. */
2647 if (fixP
->fx_pcrel
== 0
2648 && fixP
->fx_addsy
== 0)
2650 md_number_to_chars (p
, value
, size
);
2651 /* @@ Overflow checks?? */
2657 if (fixP
->fx_addsy
!= 0
2658 && fixP
->fx_addsy
->bsym
->section
!= absolute_section
)
2659 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2660 "PALcode instructions require immediate constant function code");
2661 else if (value
>> 26 != 0)
2662 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2663 "overflow in 26-bit PALcode function field");
2664 *p
++ = value
& 0xff;
2666 *p
++ = value
& 0xff;
2668 *p
++ = value
& 0xff;
2679 if (fixP
->fx_addsy
!= 0
2680 && fixP
->fx_addsy
->bsym
->section
!= absolute_section
)
2681 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2682 "ret/jsr_coroutine requires constant in displacement field");
2683 else if (value
>> 14 != 0)
2684 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2685 "overflow in 14-bit operand field of ret or jsr_coroutine");
2686 *p
++ = value
& 0xff;
2688 *p
= (*p
& 0xc0) | (value
& 0x3f);
2691 case BFD_RELOC_23_PCREL_S2
:
2692 /* Write 21 bits only. */
2694 *p
++ = value
& 0xff;
2696 *p
++ = value
& 0xff;
2699 *p
|= (value
& 0x1f);
2702 case BFD_RELOC_12_PCREL
:
2703 *p
++ = value
& 0xff;
2706 *p
|= (value
& 0x0f);
2709 case BFD_RELOC_ALPHA_LITERAL
:
2710 case BFD_RELOC_ALPHA_LITUSE
:
2713 case BFD_RELOC_GPREL32
:
2714 assert (fixP
->fx_subsy
== gp
);
2715 value
= - alpha_gp_value
; /* huh? this works... */
2717 md_number_to_chars (p
, value
, 4);
2720 case BFD_RELOC_ALPHA_HINT
:
2721 if (fixP
->fx_addsy
== 0 && fixP
->fx_pcrel
== 0)
2729 as_fatal ("unhandled relocation type %s",
2730 bfd_get_reloc_code_name (fixP
->fx_r_type
));
2734 if (fixP
->fx_addsy
== 0 && fixP
->fx_pcrel
== 0)
2736 printf ("type %d reloc done?\n", fixP
->fx_r_type
);
2746 alpha_frob_ecoff_data ()
2749 /* $zero and $f31 are read-only */
2750 alpha_gprmask
&= ~1;
2751 alpha_fprmask
&= ~1;
2754 /* The Alpha has support for some VAX floating point types, as well as for
2755 IEEE floating point. We consider IEEE to be the primary floating point
2756 format, and sneak in the VAX floating point support here. */
2757 #define md_atof vax_md_atof
2758 #include "config/atof-vax.c"