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
54 * Revision 1.1 1994/01/28 01:36:53 raeburn
55 * New Alpha support files, based on files from CMU.
57 * - fix floating-point handling
58 * - figure out if we can adapt to using ../opcodes/alpha-opc.h
59 * - gcc bootstrap testing
60 * - 32-bit mode support?
61 * - test cross-assembly
64 * Author: Alessandro Forin, Carnegie Mellon University
69 #include "alpha-opcode.h"
72 /* These are exported to relaxing code, even though we don't do any
73 relaxing on this processor currently. */
74 const relax_typeS md_relax_table
[1];
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 we'll want to keep track of */
82 static segT lita_sec
, rdata
, sdata
;
84 /* setting for ".set [no]{at,macro}" */
85 static int at_ok
= 1, macro_ok
= 1;
87 /* Keep track of global pointer. */
88 static valueT gp_value
;
91 /* We'll probably be using this relocation frequently, and we
92 will want to compare for it. */
93 static reloc_howto_type
*gpdisp_hi16_howto
;
95 /* These are exported to ECOFF code. */
96 unsigned long alpha_gprmask
, alpha_fprmask
;
98 /* Used for LITUSE relocations. */
99 static expressionS lituse_basereg
, lituse_byteoff
, lituse_jsr
;
101 /* Imported functions -- they should be defined in header files somewhere. */
102 extern segT
subseg_get ();
103 extern PTR
bfd_alloc_by_size_t ();
104 extern void s_globl (), s_long (), s_short (), s_space (), cons (), s_text (),
105 s_data (), float_cons ();
107 static void s_mask (), s_base (), s_proc (), s_alpha_set ();
108 static void s_gprel32 (), s_rdata (), s_sdata (), s_alpha_comm ();
109 static int alpha_ip ();
111 const pseudo_typeS md_pseudo_table
[] =
113 {"common", s_comm
, 0}, /* is this used? */
114 {"comm", s_alpha_comm
, 0}, /* osf1 compiler does this */
115 {"rdata", s_rdata
, 0},
116 {"sdata", s_sdata
, 0},
117 {"gprel32", s_gprel32
, 0},
118 {"t_floating", float_cons
, 'd'},
119 {"s_floating", float_cons
, 'f'},
120 {"f_floating", float_cons
, 'F'},
121 {"g_floating", float_cons
, 'G'},
122 {"d_floating", float_cons
, 'D'},
125 {"aproc", s_proc
, 1},
126 {"set", s_alpha_set
, 0},
127 {"reguse", s_ignore
, 0},
128 {"livereg", s_ignore
, 0},
129 {"extern", s_ignore
, 0}, /*??*/
130 {"base", s_base
, 0}, /*??*/
131 {"option", s_ignore
, 0},
132 {"prologue", s_ignore
, 0},
133 {"aent", s_ignore
, 0},
134 {"ugen", s_ignore
, 0},
136 /* We don't do any optimizing, so we can safely ignore these. */
137 {"noalias", s_ignore
, 0},
138 {"alias", s_ignore
, 0},
143 #define SA 21 /* shift for register Ra */
144 #define SB 16 /* shift for register Rb */
145 #define SC 0 /* shift for register Rc */
146 #define SN 13 /* shift for 8 bit immediate # */
158 #define OPCODE(X) (((X) >> 26) & 0x3f)
159 #define OP_FCN(X) (((X) >> 5) & 0x7f)
161 #ifndef FIRST_32BIT_QUADRANT
162 #define FIRST_32BIT_QUADRANT 0
165 int first_32bit_quadrant
= FIRST_32BIT_QUADRANT
;
166 int base_register
= FIRST_32BIT_QUADRANT
? ZERO
: GP
;
168 int no_mixed_code
= 0;
171 /* This array holds the chars that always start a comment. If the
172 pre-processor is disabled, these aren't very useful */
173 const char comment_chars
[] = "#";
175 /* This array holds the chars that only start a comment at the beginning of
176 a line. If the line seems to have the form '# 123 filename'
177 .line and .file directives will appear in the pre-processed output */
178 /* Note that input_file.c hand checks for '#' at the beginning of the
179 first line of the input file. This is because the compiler outputs
180 #NO_APP at the beginning of its output. */
181 /* Also note that '/*' will always start a comment */
182 const char line_comment_chars
[] = "#";
184 /* Chars that can be used to separate mant from exp in floating point nums */
185 const char EXP_CHARS
[] = "eE";
187 const char line_separator_chars
[1];
189 /* Chars that mean this number is a floating point constant, as in
190 "0f12.456" or "0d1.2345e12". */
191 char FLT_CHARS
[] = "rRsSfFdDxXpP";
193 /* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
194 changed in read.c. Ideally it shouldn't have to know about it at all,
195 but nothing is ideal around here. */
200 bfd_reloc_code_real_type code
;
203 /* Occasionally, two relocations will be desired for one address.
204 Mainly only in cases like "jsr $r,foo" where we want both a LITUSE
209 unsigned long opcode
; /* need at least 32 bits */
210 struct reloc_data reloc
[MAX_RELOCS
];
213 static int getExpression (char *str
, struct alpha_it
*insn
);
214 static char *expr_end
;
216 #define note_gpreg(R) (alpha_gprmask |= (1 << (R)))
217 #define note_fpreg(R) (alpha_fprmask |= (1 << (R)))
220 tc_get_register (frame
)
227 if (*input_line_pointer
== '$')
229 input_line_pointer
++;
230 if (input_line_pointer
[0] == 's'
231 && input_line_pointer
[1] == 'p')
233 input_line_pointer
+= 2;
237 framereg
= get_absolute_expression ();
238 framereg
&= 31; /* ? */
241 as_warn ("frame reg expected, using $%d.", framereg
);
243 note_gpreg (framereg
);
253 temp
= get_absolute_expression ();
256 rdata
= subseg_get (".rdata", 0);
257 subseg_set (rdata
, (subsegT
) temp
);
259 rdata
= subseg_new (".rdata", 0);
261 demand_empty_rest_of_line ();
270 temp
= get_absolute_expression ();
273 sdata
= subseg_get (".sdata", 0);
274 subseg_set (sdata
, (subsegT
) temp
);
276 sdata
= subseg_new (".sdata", 0);
278 demand_empty_rest_of_line ();
282 s_alpha_comm (ignore
)
289 register symbolS
*symbolP
;
291 name
= input_line_pointer
;
292 c
= get_symbol_end ();
293 /* just after name is now '\0' */
294 p
= input_line_pointer
;
297 /* Alpha OSF/1 compiler doesn't provide the comma, gcc does. */
298 if (*input_line_pointer
== ',')
300 input_line_pointer
++;
303 if ((temp
= get_absolute_expression ()) < 0)
305 as_warn (".COMMon length (%ld.) <0! Ignored.", (long) temp
);
306 ignore_rest_of_line ();
310 symbolP
= symbol_find_or_make (name
);
312 if (S_IS_DEFINED (symbolP
))
314 as_bad ("Ignoring attempt to re-define symbol");
315 ignore_rest_of_line ();
318 if (S_GET_VALUE (symbolP
))
320 if (S_GET_VALUE (symbolP
) != (valueT
) temp
)
321 as_bad ("Length of .comm \"%s\" is already %ld. Not changed to %ld.",
322 S_GET_NAME (symbolP
),
323 (long) S_GET_VALUE (symbolP
),
328 S_SET_VALUE (symbolP
, (valueT
) temp
);
329 S_SET_EXTERNAL (symbolP
);
332 know (symbolP
->sy_frag
== &zero_address_frag
);
333 demand_empty_rest_of_line ();
337 alpha_local_label (name
)
340 if (name
[0] == 'L' /* || name[0] == '$' */)
346 tc_gen_reloc (sec
, fixp
)
351 bfd_reloc_code_real_type code
;
353 reloc
= (arelent
*) bfd_alloc_by_size_t (stdoutput
, sizeof (arelent
));
354 reloc
->sym_ptr_ptr
= &fixp
->fx_addsy
->bsym
;
355 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
357 if (fixp
->fx_r_type
> BFD_RELOC_UNUSED
|| fixp
->fx_r_type
< 0)
360 if (fixp
->fx_r_type
== BFD_RELOC_ALPHA_GPDISP_HI16
)
362 if (!gpdisp_hi16_howto
)
363 gpdisp_hi16_howto
= bfd_reloc_type_lookup (stdoutput
,
365 reloc
->howto
= gpdisp_hi16_howto
;
368 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
369 assert (reloc
->howto
!= 0);
370 if (!fixp
->fx_pcrel
!= !reloc
->howto
->pc_relative
)
372 as_fatal ("bug in handling type-%d relocs", fixp
->fx_r_type
);
375 assert (!fixp
->fx_pcrel
== !reloc
->howto
->pc_relative
);
377 if (reloc
->howto
->pc_relative
378 && reloc
->howto
->pcrel_offset
380 && code
!= BFD_RELOC_ALPHA_GPDISP_HI16
381 && code
!= BFD_RELOC_ALPHA_GPDISP_LO16
385 reloc
->addend
= fixp
->fx_offset
- reloc
->address
;
388 reloc
->addend
= fixp
->fx_offset
;
395 if (first_32bit_quadrant
)
397 /* not fatal, but it might not work in the end */
398 as_warn ("File overrides no-base-register option.");
399 first_32bit_quadrant
= 0;
403 if (*input_line_pointer
== '$')
405 input_line_pointer
++;
406 if (*input_line_pointer
== 'r')
407 input_line_pointer
++;
410 base_register
= get_absolute_expression ();
411 if (base_register
< 0 || base_register
> 31)
414 as_warn ("Bad base register, using $r.", base_register
);
416 demand_empty_rest_of_line ();
430 e
.X_add_symbol
= section_symbol (absolute_section
);
441 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 4, &e
, 0,
446 create_lita_section ()
448 segT current_section
= now_seg
;
449 int current_subsec
= now_subseg
;
451 lita_sec
= subseg_new (".lita", 0);
452 subseg_set (current_section
, current_subsec
);
453 bfd_set_section_flags (stdoutput
, lita_sec
,
454 SEC_RELOC
| SEC_ALLOC
| SEC_LOAD
| SEC_READONLY
456 bfd_set_section_alignment (stdoutput
, lita_sec
, 3);
459 /* This function is called once, at assembler startup time. It should
460 set up all the tables, etc. that the MD part of the assembler will need. */
468 op_hash
= hash_new ();
470 for (i
= 0; i
< NUMOPCODES
; )
472 const char *name
= alpha_opcodes
[i
].name
;
473 retval
= hash_insert (op_hash
, name
, (PTR
) & alpha_opcodes
[i
]);
476 as_bad ("internal error: can't hash opcode `%s': %s",
477 alpha_opcodes
[i
].name
, retval
);
482 while (i
< NUMOPCODES
483 && (alpha_opcodes
[i
].name
== name
484 || !strcmp (alpha_opcodes
[i
].name
, name
)));
486 /* Some opcodes include modifiers of various sorts with a "/mod"
487 syntax, like the architecture documentation suggests. However,
488 for use with gcc at least, we also need to access those same
489 opcodes without the "/". */
490 for (i
= 0; i
< NUMOPCODES
; )
492 const char *name
= alpha_opcodes
[i
].name
;
493 if (strchr (name
, '/'))
495 char *p
= xmalloc (strlen (name
));
496 const char *q
= name
;
504 retval
= hash_insert (op_hash
, p
, (PTR
) & alpha_opcodes
[i
]);
507 /* Ignore failures -- the opcode table does duplicate
508 some variants in different forms, like "hw_st/q" and
511 as_bad ("internal error: can't hash opcode variant `%s': %s",
519 while (i
< NUMOPCODES
520 && (alpha_opcodes
[i
].name
== name
521 || !strcmp (alpha_opcodes
[i
].name
, name
)));
527 as_fatal ("Broken assembler. No assembly attempted.");
529 lituse_basereg
.X_op
= O_constant
;
530 lituse_basereg
.X_add_number
= 1;
531 lituse_byteoff
.X_op
= O_constant
;
532 lituse_byteoff
.X_add_number
= 2;
533 lituse_jsr
.X_op
= O_constant
;
534 lituse_jsr
.X_add_number
= 3;
536 /* So .sbss will get used for tiny objects. */
537 bfd_set_gp_size (stdoutput
, 8);
538 create_lita_section ();
539 /* For handling the GP, create a symbol that won't be output in the
540 symbol table. We'll edit it out of relocs later. */
541 gp
= symbol_new ("<GP value>", lita_sec
, 0x8000, &zero_address_frag
);
542 symbol_remove (gp
, &symbol_rootP
, &symbol_lastP
);
554 struct alpha_it insns
[MAX_INSNS
];
556 count
= alpha_ip (str
, insns
);
560 for (i
= 0; i
< count
; i
++)
564 /* put out the opcode */
565 md_number_to_chars (toP
, insns
[i
].opcode
, 4);
567 /* put out the symbol-dependent stuff */
568 for (j
= 0; j
< MAX_RELOCS
; j
++)
570 struct reloc_data
*r
= &insns
[i
].reloc
[j
];
573 if (r
->code
!= BFD_RELOC_NONE
)
575 if (r
->exp
.X_op
== O_constant
)
577 r
->exp
.X_add_symbol
= section_symbol (absolute_section
);
578 r
->exp
.X_op
= O_symbol
;
580 f
= fix_new_exp (frag_now
, (toP
- frag_now
->fr_literal
), 4,
581 &r
->exp
, r
->pcrel
, r
->code
);
583 if (r
->code
== BFD_RELOC_ALPHA_GPDISP_LO16
)
585 static bit_fixS cookie
;
586 /* This'll make the range checking in write.c shut up. */
587 f
->fx_bit_fixP
= &cookie
;
593 /* @@ Will a simple 0x8000 work here? If not, why not? */
594 #define GP_ADJUSTMENT (0x8000 - 0x10)
600 /* Must be first time through -- pick a GP to use for this file. */
602 bfd_vma lita_vma
, sdata_vma
;
604 lita_vma
= bfd_get_section_vma (abfd
, lita_sec
);
609 sdata_vma
= bfd_get_section_vma (abfd
, sdata
);
615 /* Who knows which order they'll get laid out in? */
616 || (sdata_vma
!= 0 && sdata_vma
< lita_vma
))
617 gp_value
= sdata_vma
;
621 gp_value
+= GP_ADJUSTMENT
;
623 S_SET_VALUE (gp
, gp_value
);
626 printf ("Chose GP value of %lx\n", gp_value
);
628 bfd_set_gp_value (stdoutput
, gp_value
);
633 alpha_force_relocation (f
)
636 switch (f
->fx_r_type
)
638 case BFD_RELOC_ALPHA_GPDISP_HI16
:
639 case BFD_RELOC_ALPHA_GPDISP_LO16
:
640 case BFD_RELOC_ALPHA_LITERAL
:
641 case BFD_RELOC_ALPHA_LITUSE
:
642 case BFD_RELOC_GPREL32
:
644 case BFD_RELOC_ALPHA_HINT
:
649 case BFD_RELOC_23_PCREL_S2
:
659 alpha_fix_adjustable (f
)
662 /* Are there any relocation types for which we must generate a reloc
663 but we can adjust the values contained within it? */
664 switch (f
->fx_r_type
)
666 case BFD_RELOC_ALPHA_GPDISP_HI16
:
667 case BFD_RELOC_ALPHA_GPDISP_LO16
:
669 case BFD_RELOC_GPREL32
:
672 return !alpha_force_relocation (f
);
676 alpha_validate_fix (fixp
, seg
)
680 /* We must make sure we've got a good GP value if any relocations might
688 alpha_frob_symbol (s
)
695 md_section_align (seg
, size
)
700 /* This should probably be handled within BFD, or by pulling the
701 number from BFD at least. */
709 /* Add this thing to the .lita section and produce a LITERAL reloc referring
714 Set GP value properly, and have values in LITERAL references set
719 load_symbol_address (reg
, insn
)
721 struct alpha_it
*insn
;
723 static symbolS
*lita_sym
;
734 lita_sym
= section_symbol (lita_sec
);
735 S_CLEAR_EXTERNAL (lita_sym
);
738 retval
= add_to_literal_pool (insn
->reloc
[0].exp
.X_add_symbol
,
739 insn
->reloc
[0].exp
.X_add_number
,
742 /* @@ Get these numbers from GP setting. */
743 retval
-= GP_ADJUSTMENT
;
745 /* Now emit a LITERAL relocation for the original section. */
746 insn
->reloc
[0].exp
.X_op
= O_symbol
;
747 insn
->reloc
[0].exp
.X_add_symbol
= lita_sym
;
748 insn
->reloc
[0].exp
.X_add_number
= retval
;
749 insn
->reloc
[0].code
= BFD_RELOC_ALPHA_LITERAL
;
751 if (retval
== 0x8000)
753 as_fatal ("overflow in literal (.lita) table");
755 insn
->opcode
= (0xa4000000 /* ldq */
757 | (base_register
<< SB
)
759 note_gpreg (base_register
);
762 /* To load an address with a single instruction,
763 emit a LITERAL reloc in this section, and a REFQUAD
764 for the .lita section, so that we'll be able to access
766 lda REG, xx -> ldq REG, -32752(gp)
767 lda REG, xx+4 -> ldq REG, -32752(gp)
770 The offsets need to start near -0x8000, and the generated LITERAL
771 relocations should negate the offset. I don't completely grok the
775 load_expression (reg
, insn
)
777 struct alpha_it
*insn
;
782 addend
= insn
->reloc
[0].exp
.X_add_number
;
783 insn
->reloc
[0].exp
.X_add_number
= 0;
784 load_symbol_address (reg
, insn
);
791 && (x
& ~0x7fff) + 0x8000 != 0)
793 as_bad ("assembler not prepared to handle constants >16 bits yet");
797 insn
[1].opcode
= (0x20000000 /* lda */
800 | (addend
& 0xffff));
801 insn
[1].reloc
[0].code
= BFD_RELOC_ALPHA_LITUSE
;
802 insn
[1].reloc
[0].exp
= lituse_basereg
;
808 getExpression (str
, this_insn
)
810 struct alpha_it
*this_insn
;
815 #if 0 /* Not converted to bfd yet, and I don't think we need them
816 for ECOFF. Re-adding a.out support will probably require
818 static const struct am
{
820 bfd_reloc_code_real_type reloc
;
822 { "hi", RELOC_48_63
},
823 { "lo", RELOC_0_15
},
824 { "ml", RELOC_16_31
},
825 { "mh", RELOC_32_47
},
826 { "uhi", RELOC_U_48_63
},
827 { "uml", RELOC_U_16_31
},
828 { "umh", RELOC_U_32_47
},
832 /* Handle macros: "%macroname(expr)" */
843 while (*q
&& *p
== *q
)
851 str
= p
; /* keep the '(' */
852 this_insn
->reloc
= m
->reloc
;
857 save_in
= input_line_pointer
;
858 input_line_pointer
= str
;
860 seg
= expression (&this_insn
->reloc
[0].exp
);
861 /* XXX validate seg and exp, make sure they're reasonable */
862 expr_end
= input_line_pointer
;
863 input_line_pointer
= save_in
;
868 /* Note that for now, this function is called recursively. Some of the
869 macros defined as part of the assembly language are currently
870 rewritten as sequences of strings to be assembled. See, for example,
871 the handling of "divq".
873 For efficiency, this should be fixed someday. */
875 alpha_ip (str
, insns
)
877 struct alpha_it insns
[];
883 struct alpha_opcode
*pattern
;
887 int match
= 0, num_gen
= 1;
891 islower (*s
) || *s
== '_' || *s
== '/' || *s
== '4' || *s
== '8';
910 as_warn ("Unknown opcode: `%s'", str
);
913 if ((pattern
= (struct alpha_opcode
*) hash_find (op_hash
, str
)) == NULL
)
915 as_warn ("Unknown opcode: `%s'", str
);
924 opcode
= pattern
->match
;
926 memset (insns
, 0, sizeof (*insns
));
927 for (i
= 0; i
< MAX_RELOCS
; i
++)
928 insns
[0].reloc
[i
].code
= BFD_RELOC_NONE
;
929 for (i
= 1; i
< MAX_INSNS
; i
++)
932 /* Build the opcode, checking as we go to make sure that the
934 for (args
= pattern
->args
;; ++args
)
939 case '\0': /* end of args */
958 case '(': /* these must match exactly */
967 case '1': /* next operand must be a register */
977 case 'a': /* $at: as temporary */
983 case 'g': /* $gp: base register */
986 mask
= base_register
;
989 case 's': /* $sp: stack pointer */
996 case 'r': /* any register */
997 if (!isdigit (c
= *s
++))
1014 if ((c
= 10 * (c
- '0') + (*s
++ - '0')) >= 32)
1023 if ((c
== GP
) && first_32bit_quadrant
)
1033 /* Got the register, now figure out where it goes in
1041 opcode
|= mask
<< SA
;
1046 opcode
|= mask
<< SB
;
1055 opcode
|= (mask
<< SA
) | mask
;
1058 case 'R': /* ra and rb are the same */
1059 opcode
|= (mask
<< SA
) | (mask
<< SB
);
1063 opcode
|= (mask
<< SA
) | (mask
<< SB
) | (mask
);
1069 case 'e': /* next operand is a floating point register */
1073 if (*s
++ == '$' && *s
++ == 'f' && isdigit (*s
))
1078 mask
= 10 * (mask
- '0') + (*s
++ - '0');
1089 /* same encoding as gp registers */
1095 case 'h': /* bits 16..31 */
1096 insns
[0].reloc
= RELOC_16_31
;
1100 case 'l': /* bits 0..15 */
1101 insns
[0].reloc
[0].code
= BFD_RELOC_16
;
1104 case 'L': /* 21 bit PC relative immediate */
1105 insns
[0].reloc
[0].code
= BFD_RELOC_23_PCREL_S2
;
1106 insns
[0].reloc
[0].pcrel
= 1;
1109 case 'i': /* 14 bit immediate */
1110 if (OPCODE (opcode
) != 0x1a)
1111 /* Not a jmp variant?? */
1113 else if (opcode
& 0x8000)
1114 /* ret or jsr_coroutine */
1116 insns
[0].reloc
[0].code
= BFD_RELOC_14
;
1117 insns
[0].reloc
[0].pcrel
= 0;
1122 insns
[0].reloc
[0].code
= BFD_RELOC_ALPHA_HINT
;
1123 insns
[0].reloc
[0].pcrel
= 1;
1127 case 'b': /* 8 bit immediate */
1128 insns
[0].reloc
[0].code
= BFD_RELOC_8
;
1132 case 't': /* 12 bit 0...11 */
1133 insns
[0].reloc
= RELOC_0_12
;
1136 case '8': /* 8 bit 0...7 */
1137 insns
[0].reloc
= RELOC_0_8
;
1140 case 'I': /* 26 bit immediate */
1141 insns
[0].reloc
= RELOC_0_25
;
1153 (void) getExpression (s
, &insns
[0]);
1155 /* Handle overflow in certain instructions by converting
1156 to other instructions. */
1157 if (insns
[0].reloc
[0].code
== BFD_RELOC_8
1158 && insns
[0].reloc
[0].exp
.X_op
== O_constant
1159 && (insns
[0].reloc
[0].exp
.X_add_number
< 0
1160 || insns
[0].reloc
[0].exp
.X_add_number
> 0xff))
1162 if (OPCODE (opcode
) == 0x10
1163 && (OP_FCN (opcode
) == 0x00 /* addl */
1164 || OP_FCN (opcode
) == 0x40 /* addl/v */
1165 || OP_FCN (opcode
) == 0x20 /* addq */
1166 || OP_FCN (opcode
) == 0x60 /* addq/v */
1167 || OP_FCN (opcode
) == 0x09 /* subl */
1168 || OP_FCN (opcode
) == 0x49 /* subl/v */
1169 || OP_FCN (opcode
) == 0x29 /* subq */
1170 || OP_FCN (opcode
) == 0x69 /* subq/v */
1171 || OP_FCN (opcode
) == 0x02 /* s4addl */
1172 || OP_FCN (opcode
) == 0x22 /* s4addq */
1173 || OP_FCN (opcode
) == 0x0b /* s4subl */
1174 || OP_FCN (opcode
) == 0x2b /* s4subq */
1175 || OP_FCN (opcode
) == 0x12 /* s8addl */
1176 || OP_FCN (opcode
) == 0x32 /* s8addq */
1177 || OP_FCN (opcode
) == 0x1b /* s8subl */
1178 || OP_FCN (opcode
) == 0x3b /* s8subq */
1180 /* Can we make it fit by negating? */
1181 && -insns
[0].reloc
[0].exp
.X_add_number
< 0xff
1182 && -insns
[0].reloc
[0].exp
.X_add_number
> 0)
1184 opcode
^= 0x120; /* convert add<=>sub */
1185 insns
[0].reloc
[0].exp
.X_add_number
*= -1;
1187 else if (at_ok
&& macro_ok
)
1189 /* Constant value supplied, but it's too large. */
1191 sprintf (expansion
, "lda $%d,%d($%d)", AT
,
1192 insns
[0].reloc
[0].exp
.X_add_number
, ZERO
);
1193 md_assemble (expansion
);
1194 opcode
|= 0x1000 /* use reg */ | (AT
<< SB
);
1195 insns
[0].reloc
[0].code
= BFD_RELOC_NONE
;
1198 as_bad ("overflow in 8-bit literal field in `operate' format insn");
1202 /* The following two.. take advantage of the fact that
1203 opcode already contains most of what we need to know.
1204 We just prepend to the instr an "ldah
1205 $r,%ml(expr)($base)" and turn this one (done later
1206 after we return) into something like "stq
1207 $r,%lo(expr)(at)" or "ldq $r,%lo(expr)($r)".
1209 NOTE: This can fail later on at link time if the
1210 offset from $base actually turns out to be more than
1211 2**31 or 2**47 if use_large_offsets is set. */
1212 case 'P': /* Addressing macros: PUT */
1213 mask
= AT
; /* register 'at' */
1216 case 'G': /* Addressing macros: GET */
1218 /* All it is missing is the expression, which is what we
1223 (void) getExpression (s
, &insns
[0]);
1226 /* Must check for "lda ..,number" too */
1227 if (insns
[0].reloc
[0].exp
.X_op
== O_big
)
1229 as_warn ("Sorry, not yet. Put bignums in .data section yourself.");
1232 if (insns
[0].reloc
[0].exp
.X_op
== O_constant
)
1234 /* This only handles 32bit numbers */
1235 register int val
= insns
[0].reloc
[0].exp
.X_add_number
;
1236 register short sval
;
1238 insns
[0].reloc
[0].code
= BFD_RELOC_NONE
;
1239 insns
[1].reloc
[0].code
= BFD_RELOC_NONE
;
1243 fprintf (stderr
, "val %lx sval %lx\n", val
, sval
);
1244 if ((sval
!= val
) && (val
& 0x8000))
1250 if (optnum
&& (sval
== val
))
1252 /* optimize away the ldah */
1254 opcode
|= (ZERO
<< SB
) | (val
& 0xffff);
1259 insns
[1].opcode
= opcode
| (mask
<< SB
) | (val
& 0xffff);
1260 opcode
= 0x24000000 /*ldah*/ |
1261 mask
<< SA
| (ZERO
<< SB
) |
1262 ((val
>> 16) & 0xffff);
1265 else if (insns
[0].reloc
[0].exp
.X_op
== O_symbol
)
1267 unsigned long old_opcode
= opcode
;
1271 as_bad ("insn requires expansion but `nomacro' specified");
1272 else if (*args
== 'G')
1275 as_bad ("insn expansion requires AT use, but `noat' specified");
1278 num_gen
= load_expression (tmp_reg
, insns
);
1279 opcode
= insns
[0].opcode
;
1280 /* lda is opcode 8, 0x20000000 */
1281 if (OPCODE (old_opcode
) != 0x08)
1284 i
= &insns
[num_gen
++];
1285 i
->reloc
[0].code
= BFD_RELOC_NONE
;
1286 i
->opcode
= old_opcode
| (tmp_reg
<< SB
);
1293 insns
[1].reloc
[0].exp
= insns
[0].reloc
[0].exp
;
1295 /* Generate: ldah REG,x1(GP); OP ?,x0(REG) */
1297 abort (); /* relocs need fixing */
1299 insns
[1].reloc
= RELOC_0_15
;
1300 insns
[1].opcode
= opcode
| mask
<< SB
;
1302 insns
[0].reloc
= RELOC_16_31
;
1303 opcode
= 0x24000000 /*ldah*/ | mask
<< SA
| (base_register
<< SB
);
1309 /* Same failure modes as above, actually most of the
1310 same code shared. */
1311 case 'B': /* Builtins */
1316 case 'a': /* ldgp */
1318 if (first_32bit_quadrant
|| no_mixed_code
)
1320 switch (OUTPUT_FLAVOR
)
1322 case bfd_target_aout_flavour
:
1323 /* this is cmu's a.out version */
1324 insns
[0].reloc
[0].code
= BFD_RELOC_NONE
;
1325 /* generate "zap %r,0xf,%r" to take high 32 bits */
1326 opcode
|= 0x48001600 /* zap ?,#,?*/ | (0xf << SN
);
1328 case bfd_target_ecoff_flavour
:
1329 /* Given "ldgp R1,N(R2)", turn it into something
1330 like "ldah R1,###(R2) ; lda R1,###(R1)" with
1331 appropriate constants and relocations. */
1333 unsigned long r1
, r2
;
1334 unsigned long addend
= 0;
1339 insns
[0].reloc
[0].code
= BFD_RELOC_ALPHA_GPDISP_HI16
;
1340 insns
[0].reloc
[0].pcrel
= 1;
1341 insns
[0].reloc
[0].exp
.X_op
= O_symbol
;
1342 insns
[0].reloc
[0].exp
.X_add_symbol
= gp
;
1343 insns
[0].reloc
[0].exp
.X_add_number
= 0;
1344 insns
[0].opcode
= (0x24000000 /* ldah */
1347 insns
[1].reloc
[0].code
= BFD_RELOC_ALPHA_GPDISP_LO16
;
1348 insns
[1].reloc
[0].exp
.X_op
= O_symbol
;
1349 insns
[1].reloc
[0].exp
.X_add_symbol
= gp
;
1350 insns
[1].reloc
[0].exp
.X_add_number
= 4;
1351 insns
[1].reloc
[0].pcrel
= 1;
1352 insns
[1].opcode
= 0x20000000 | (r1
<< SA
) | (r1
<< SB
);
1353 opcode
= insns
[0].opcode
;
1354 /* merge in addend */
1355 insns
[1].opcode
|= addend
& 0xffff;
1356 insns
[0].opcode
|= ((addend
>> 16)
1357 + (addend
& 0x8000 ? 1 : 0));
1358 ecoff_set_gp_prolog_size (0);
1367 case 'b': /* setgp */
1368 switch (OUTPUT_FLAVOR
)
1370 case bfd_target_aout_flavour
:
1371 /* generate "zap %r,0xf,$gp" to take high 32 bits */
1372 opcode
|= 0x48001600 /* zap ?,#,?*/
1373 | (0xf << SN
) | (base_register
);
1380 case 'c': /* jsr $r,foo becomes
1383 Register 27, t12, is used by convention
1386 struct alpha_it
*jsr
;
1388 struct reloc_data
*r
;
1390 /* We still have to parse the function name */
1393 (void) getExpression (s
, &insns
[0]);
1394 etmp
= insns
[0].reloc
[0].exp
;
1396 num_gen
= load_expression (PV
, &insns
[0]);
1399 jsr
= &insns
[num_gen
++];
1400 jsr
->opcode
= (0x68004000 /* jsr */
1406 /* LITUSE wasn't emitted yet */
1407 jsr
->reloc
[0].code
= BFD_RELOC_ALPHA_LITUSE
;
1408 jsr
->reloc
[0].exp
= lituse_jsr
;
1414 r
->code
= BFD_RELOC_ALPHA_HINT
;
1416 opcode
= insns
[0].opcode
;
1420 /* DIVISION and MODULUS. Yech.
1421 Convert OP x,y,result
1427 with appropriate optimizations if t10,t11,t12
1428 are the registers specified by the compiler.
1429 We are missing an obvious optimization
1430 opportunity here; if the ldq generated by the
1431 jsr assembly requires a cycle or two to make
1432 the value available, initiating it before one
1433 or two of the mov instructions would result in
1434 faster execution. */
1435 case '0': /* reml */
1436 case '1': /* divl */
1437 case '2': /* remq */
1438 case '3': /* divq */
1439 case '4': /* remlu */
1440 case '5': /* divlu */
1441 case '6': /* remqu */
1442 case '7': /* divqu */
1444 static char func
[8][6] = {
1445 "reml", "divl", "remq", "divq",
1446 "remlu", "divlu", "remqu", "divqu"
1451 /* All regs parsed, in opcode */
1453 /* Do the expansions, one instr at a time */
1455 reg
= (opcode
>> SA
) & 31;
1459 sprintf (expansion
, "mov $%d,$%d", reg
, T10
);
1460 md_assemble (expansion
);
1462 reg
= (opcode
>> SB
) & 31;
1464 /* we already overwrote it! */
1466 else if (reg
!= T11
)
1469 sprintf (expansion
, "mov $%d,$%d", reg
, T11
);
1470 md_assemble (expansion
);
1472 sprintf (expansion
, "lda $%d,__%s", PV
, func
[*args
- '0']);
1473 md_assemble (expansion
);
1474 sprintf (expansion
, "jsr $%d,($%d),__%s", T9
, PV
,
1476 md_assemble (expansion
);
1478 if (!first_32bit_quadrant
)
1483 md_assemble (expansion
);
1486 sprintf (expansion
, "ldgp $%d,0($%d)",
1488 md_assemble (expansion
);
1490 /* Use insns[0] to get at the result */
1491 if ((reg
= (opcode
& 31)) != PV
)
1492 opcode
= (0x47e00400 /* or zero,zero,zero */
1494 | reg
/* Rc */ ); /* pv->z */
1510 /* Args don't match. */
1511 if (&pattern
[1] - alpha_opcodes
< NUMOPCODES
1512 && !strcmp (pattern
->name
, pattern
[1].name
))
1520 as_warn ("Illegal operands");
1526 /* Args match, see if a float instructions and -nofloats */
1527 if (nofloats
&& pattern
->isa_float
)
1533 insns
[0].opcode
= opcode
;
1537 /* Turn a string in input_line_pointer into a floating point constant
1538 of type type, and store the appropriate bytes in *litP. The number
1539 of LITTLENUMS emitted is stored in *sizeP. An error message is
1540 returned, or NULL on OK. */
1542 /* Equal to MAX_PRECISION in atof-ieee.c */
1543 #define MAX_LITTLENUMS 6
1546 md_atof (type
, litP
, sizeP
)
1552 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
1553 LITTLENUM_TYPE
*wordP
;
1555 char *atof_ieee (), *vax_md_atof ();
1564 return vax_md_atof (type
, litP
, sizeP
);
1587 return "Bad call to MD_ATOF()";
1589 t
= atof_ieee (input_line_pointer
, type
, words
);
1591 input_line_pointer
= t
;
1592 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
1594 for (wordP
= words
+ prec
- 1; prec
--;)
1596 md_number_to_chars (litP
, (long) (*wordP
--), sizeof (LITTLENUM_TYPE
));
1597 litP
+= sizeof (LITTLENUM_TYPE
);
1604 md_bignum_to_chars (buf
, bignum
, nchars
)
1606 LITTLENUM_TYPE
*bignum
;
1611 LITTLENUM_TYPE work
= *bignum
++;
1612 int nb
= CHARS_PER_LITTLENUM
;
1616 *buf
++ = work
& ((1 << BITS_PER_CHAR
) - 1);
1619 work
>>= BITS_PER_CHAR
;
1626 md_parse_option (argP
, cntP
, vecP
)
1636 #if 0 /* I have no idea if this stuff would work any more. And it's
1637 probably not right for ECOFF anyways. */
1638 /* Use base-register addressing, e.g. PIC code */
1641 if (first_32bit_quadrant
)
1643 first_32bit_quadrant
= 0;
1648 first_32bit_quadrant
= 1;
1649 base_register
= ZERO
;
1651 if (argP
[0][1] == 'k')
1657 if (!strcmp (*argP
, "nocpp"))
1668 /* XXXX Align to cache linesize XXXXX */
1675 /* Takes ".proc name,nargs" */
1676 name
= input_line_pointer
;
1677 c
= get_symbol_end ();
1678 p
= input_line_pointer
;
1679 symbolP
= symbol_find_or_make (name
);
1682 if (*input_line_pointer
!= ',')
1685 as_warn ("Expected comma after name \"%s\"", name
);
1688 ignore_rest_of_line ();
1692 input_line_pointer
++;
1693 temp
= get_absolute_expression ();
1695 /* symbolP->sy_other = (signed char) temp; */
1696 as_warn ("unhandled: .proc %s,%d", name
, temp
);
1697 demand_empty_rest_of_line ();
1704 char *name
= input_line_pointer
, ch
, *s
;
1707 while (!is_end_of_line
[(unsigned char) *input_line_pointer
])
1708 input_line_pointer
++;
1709 ch
= *input_line_pointer
;
1710 *input_line_pointer
= '\0';
1713 if (s
[0] == 'n' && s
[1] == 'o')
1718 if (!strcmp ("reorder", s
))
1720 else if (!strcmp ("at", s
))
1722 else if (!strcmp ("macro", s
))
1725 as_warn ("Tried to set unrecognized symbol: %s", name
);
1726 *input_line_pointer
= ch
;
1727 demand_empty_rest_of_line ();
1730 /* @@ Is this right?? */
1732 md_pcrel_from (fixP
)
1735 valueT addr
= fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
1736 switch (fixP
->fx_r_type
)
1738 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1739 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1742 return fixP
->fx_size
+ addr
;
1747 alpha_do_align (n
, fill
)
1752 && (now_seg
== text_section
1753 || !strcmp (now_seg
->name
, ".init")
1754 || !strcmp (now_seg
->name
, ".fini")))
1756 static const char nop_pattern
[] = { 0x1f, 0x04, 0xff, 0x47 };
1757 frag_align_pattern (n
, nop_pattern
, sizeof (nop_pattern
));
1764 md_apply_fix (fixP
, valueP
)
1771 char *p
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
1775 switch (fixP
->fx_r_type
)
1777 /* The GPDISP relocations are processed internally with a symbol
1778 referring to the current function; we need to drop in a value
1779 which, when added to the address of the start of the function,
1780 gives the desired GP. */
1781 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1782 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1784 if (fixP
->fx_r_type
== BFD_RELOC_ALPHA_GPDISP_HI16
)
1786 assert (fixP
->fx_next
->fx_r_type
== BFD_RELOC_ALPHA_GPDISP_LO16
);
1789 fprintf_vma (stdout
, addend
);
1792 if (addend
& 0x8000)
1795 fixP
->fx_offset
= 4; /* @@ Compute this using fx_next. */
1801 fprintf_vma (stdout
, addend
);
1805 fixP
->fx_offset
= 0;
1807 md_number_to_chars (fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
,
1809 fixP
->fx_addsy
= section_symbol (absolute_section
);
1810 fixP
->fx_offset
+= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
1814 /* Write 8 bits, shifted left 13 bit positions. */
1818 *p
|= (value
<< 5) & 0xe0;
1827 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
1828 "overflow in type-%d reloc", (int) fixP
->fx_r_type
);
1835 /* Don't want overflow checking. */
1838 if (fixP
->fx_pcrel
== 0
1839 && fixP
->fx_addsy
== 0)
1841 md_number_to_chars (p
, value
, size
);
1842 /* @@ Overflow checks?? */
1848 if (fixP
->fx_addsy
!= 0
1849 && fixP
->fx_addsy
->bsym
->section
!= absolute_section
)
1850 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
1851 "ret/jsr_coroutine requires constant in displacement field");
1852 else if (value
>> 14 != 0)
1853 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
1854 "overflow in 14-bit operand field of ret or jsr_coroutine");
1855 *p
++ = value
& 0xff;
1857 *p
= (*p
& 0xc0) | (value
& 0x3f);
1860 case BFD_RELOC_23_PCREL_S2
:
1861 /* Write 21 bits only. */
1863 *p
++ = value
& 0xff;
1865 *p
++ = value
& 0xff;
1868 *p
|= (value
& 0x1f);
1871 case BFD_RELOC_ALPHA_LITERAL
:
1872 case BFD_RELOC_ALPHA_LITUSE
:
1875 case BFD_RELOC_GPREL32
:
1876 assert (fixP
->fx_subsy
== gp
);
1877 value
= - gp_value
; /* huh? this works... */
1879 md_number_to_chars (p
, value
, 4);
1882 case BFD_RELOC_ALPHA_HINT
:
1883 if (fixP
->fx_addsy
== 0 && fixP
->fx_pcrel
== 0)
1891 as_fatal ("unknown relocation type %d?", fixP
->fx_r_type
);
1895 if (fixP
->fx_addsy
== 0 && fixP
->fx_pcrel
== 0)
1897 printf ("type %d reloc done?\n", fixP
->fx_r_type
);
1909 /* $zero and $f31 are read-only */
1910 alpha_gprmask
&= ~(1L << 31);
1911 alpha_fprmask
&= ~(1L << 31);
1914 /* The Alpha has support for some VAX floating point types, as well as for
1915 IEEE floating point. We consider IEEE to be the primary floating point
1916 format, and sneak in the VAX floating point support here. */
1917 #define md_atof vax_md_atof
1918 #include "config/atof-vax.c"