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
58 #include "alpha-opcode.h"
61 /* @@ Will a simple 0x8000 work here? If not, why not? */
62 #define GP_ADJUSTMENT (0x8000 - 0x10)
64 /* These are exported to relaxing code, even though we don't do any
65 relaxing on this processor currently. */
66 const relax_typeS md_relax_table
[1];
67 int md_short_jump_size
= 4;
68 int md_long_jump_size
= 4;
70 /* handle of the OPCODE hash table */
71 static struct hash_control
*op_hash
;
73 /* Sections and symbols we'll want to keep track of. */
74 static segT lita_sec
, rdata
, sdata
, lit8_sec
, lit4_sec
;
75 static symbolS
*lit8_sym
, *lit4_sym
;
77 /* Setting for ".set [no]{at,macro}". */
78 static int at_ok
= 1, macro_ok
= 1;
80 /* Keep track of global pointer. */
81 valueT alpha_gp_value
;
84 /* We'll probably be using this relocation frequently, and we
85 will want to compare for it. */
86 static reloc_howto_type
*gpdisp_hi16_howto
;
88 /* These are exported to ECOFF code. */
89 unsigned long alpha_gprmask
, alpha_fprmask
;
91 /* Used for LITUSE relocations. */
92 static expressionS lituse_basereg
, lituse_byteoff
, lituse_jsr
;
94 /* Address size: In OSF/1 1.3, an undocumented "-32addr" option will
95 cause all addresses to be treated as 32-bit values in memory. (The
96 in-register versions are all sign-extended to 64 bits, of course.)
97 Some other systems may want this option too. */
100 /* Imported functions -- they should be defined in header files somewhere. */
101 extern segT
subseg_get ();
102 extern PTR
bfd_alloc_by_size_t ();
103 extern void s_globl (), s_long (), s_short (), s_space (), cons (), s_text (),
104 s_data (), float_cons ();
106 /* Static functions, needing forward declarations. */
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 void 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 tc_gen_reloc (sec
, fixp
)
343 reloc
= (arelent
*) bfd_alloc_by_size_t (stdoutput
, sizeof (arelent
));
344 reloc
->sym_ptr_ptr
= &fixp
->fx_addsy
->bsym
;
345 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
347 if (fixp
->fx_r_type
> BFD_RELOC_UNUSED
|| fixp
->fx_r_type
< 0)
350 if (fixp
->fx_r_type
== BFD_RELOC_ALPHA_GPDISP_HI16
)
352 if (!gpdisp_hi16_howto
)
353 gpdisp_hi16_howto
= bfd_reloc_type_lookup (stdoutput
,
355 reloc
->howto
= gpdisp_hi16_howto
;
358 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
359 assert (reloc
->howto
!= 0);
360 if (!fixp
->fx_pcrel
!= !reloc
->howto
->pc_relative
)
362 as_fatal ("bug in handling type-%d relocs", fixp
->fx_r_type
);
365 assert (!fixp
->fx_pcrel
== !reloc
->howto
->pc_relative
);
367 if (fixp
->fx_r_type
== BFD_RELOC_ALPHA_LITERAL
)
369 /* fake out bfd_perform_relocation. sigh */
370 reloc
->addend
= -alpha_gp_value
;
372 else if (reloc
->howto
->pc_relative
&& reloc
->howto
->pcrel_offset
)
374 reloc
->addend
= fixp
->fx_offset
- reloc
->address
;
377 reloc
->addend
= fixp
->fx_offset
;
384 if (first_32bit_quadrant
)
386 /* not fatal, but it might not work in the end */
387 as_warn ("File overrides no-base-register option.");
388 first_32bit_quadrant
= 0;
392 if (*input_line_pointer
== '$')
394 input_line_pointer
++;
395 if (*input_line_pointer
== 'r')
396 input_line_pointer
++;
399 base_register
= get_absolute_expression ();
400 if (base_register
< 0 || base_register
> 31)
403 as_warn ("Bad base register, using $r.", base_register
);
405 demand_empty_rest_of_line ();
419 e
.X_add_symbol
= section_symbol (absolute_section
);
430 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 4, &e
, 0,
435 create_literal_section (secp
, name
)
439 segT current_section
= now_seg
;
440 int current_subsec
= now_subseg
;
443 *secp
= new_sec
= subseg_new (name
, 0);
444 subseg_set (current_section
, current_subsec
);
445 bfd_set_section_alignment (stdoutput
, new_sec
, 3);
446 bfd_set_section_flags (stdoutput
, new_sec
,
447 SEC_RELOC
| SEC_ALLOC
| SEC_LOAD
| SEC_READONLY
451 #define create_lita_section() create_literal_section (&lita_sec, ".lita")
454 get_lit8_offset (val
)
460 create_literal_section (&lit8_sec
, ".lit8");
461 lit8_sym
= section_symbol (lit8_sec
);
463 retval
= add_to_literal_pool ((symbolS
*) 0, val
, lit8_sec
, 8);
464 if (retval
>= 0xfff0)
465 as_fatal ("overflow in fp literal (.lit8) table");
470 get_lit4_offset (val
)
476 create_literal_section (&lit4_sec
, ".lit4");
477 lit4_sym
= section_symbol (lit4_sec
);
479 retval
= add_to_literal_pool ((symbolS
*) 0, val
, lit4_sec
, 4);
480 if (retval
>= 0xfff0)
481 as_fatal ("overflow in fp literal (.lit4) table");
485 /* This function is called once, at assembler startup time. It should
486 set up all the tables, etc. that the MD part of the assembler will need. */
494 op_hash
= hash_new ();
496 for (i
= 0; i
< NUMOPCODES
; )
498 const char *name
= alpha_opcodes
[i
].name
;
499 retval
= hash_insert (op_hash
, name
, (PTR
) & alpha_opcodes
[i
]);
502 as_bad ("internal error: can't hash opcode `%s': %s",
503 alpha_opcodes
[i
].name
, retval
);
508 while (i
< NUMOPCODES
509 && (alpha_opcodes
[i
].name
== name
510 || !strcmp (alpha_opcodes
[i
].name
, name
)));
512 /* Some opcodes include modifiers of various sorts with a "/mod"
513 syntax, like the architecture documentation suggests. However,
514 for use with gcc at least, we also need to access those same
515 opcodes without the "/". */
516 for (i
= 0; i
< NUMOPCODES
; )
518 const char *name
= alpha_opcodes
[i
].name
;
519 if (strchr (name
, '/'))
521 char *p
= xmalloc (strlen (name
));
522 const char *q
= name
;
530 retval
= hash_insert (op_hash
, p
, (PTR
) & alpha_opcodes
[i
]);
533 /* Ignore failures -- the opcode table does duplicate
534 some variants in different forms, like "hw_st/q" and
537 as_bad ("internal error: can't hash opcode variant `%s': %s",
545 while (i
< NUMOPCODES
546 && (alpha_opcodes
[i
].name
== name
547 || !strcmp (alpha_opcodes
[i
].name
, name
)));
552 as_fatal ("Broken assembler. No assembly attempted.");
554 lituse_basereg
.X_op
= O_constant
;
555 lituse_basereg
.X_add_number
= 1;
556 lituse_byteoff
.X_op
= O_constant
;
557 lituse_byteoff
.X_add_number
= 2;
558 lituse_jsr
.X_op
= O_constant
;
559 lituse_jsr
.X_add_number
= 3;
561 /* So .sbss will get used for tiny objects. */
562 bfd_set_gp_size (stdoutput
, 8);
563 create_lita_section ();
564 /* For handling the GP, create a symbol that won't be output in the
565 symbol table. We'll edit it out of relocs later. */
566 gp
= symbol_new ("<GP value>", lita_sec
, 0x8000, &zero_address_frag
);
567 symbol_remove (gp
, &symbol_rootP
, &symbol_lastP
);
579 struct alpha_it insns
[MAX_INSNS
];
581 count
= alpha_ip (str
, insns
);
585 for (i
= 0; i
< count
; i
++)
589 /* put out the opcode */
590 md_number_to_chars (toP
, insns
[i
].opcode
, 4);
592 /* put out the symbol-dependent stuff */
593 for (j
= 0; j
< MAX_RELOCS
; j
++)
595 struct reloc_data
*r
= &insns
[i
].reloc
[j
];
598 if (r
->code
!= BFD_RELOC_NONE
)
600 if (r
->exp
.X_op
== O_constant
)
602 r
->exp
.X_add_symbol
= section_symbol (absolute_section
);
603 r
->exp
.X_op
= O_symbol
;
605 f
= fix_new_exp (frag_now
, (toP
- frag_now
->fr_literal
), 4,
606 &r
->exp
, r
->pcrel
, r
->code
);
608 if (r
->code
== BFD_RELOC_ALPHA_GPDISP_LO16
)
610 static bit_fixS cookie
;
611 /* This'll make the range checking in write.c shut up. */
612 f
->fx_bit_fixP
= &cookie
;
625 vma
= bfd_get_section_vma (foo
, sec
);
626 if (vma
&& vma
< alpha_gp_value
)
627 alpha_gp_value
= vma
;
633 if (alpha_gp_value
!= 0)
636 /* Get minus-one in whatever width... */
637 alpha_gp_value
= 0; alpha_gp_value
--;
639 /* Select the smallest VMA of these existing sections. */
640 maybe_set_gp (lita_sec
);
641 /* maybe_set_gp (sdata); Was disabled before -- should we use it? */
643 maybe_set_gp (lit8_sec
);
644 maybe_set_gp (lit4_sec
);
647 alpha_gp_value
+= GP_ADJUSTMENT
;
649 S_SET_VALUE (gp
, alpha_gp_value
);
652 printf ("Chose GP value of %lx\n", alpha_gp_value
);
657 alpha_force_relocation (f
)
660 switch (f
->fx_r_type
)
662 case BFD_RELOC_ALPHA_GPDISP_HI16
:
663 case BFD_RELOC_ALPHA_GPDISP_LO16
:
664 case BFD_RELOC_ALPHA_LITERAL
:
665 case BFD_RELOC_ALPHA_LITUSE
:
666 case BFD_RELOC_GPREL32
:
668 case BFD_RELOC_ALPHA_HINT
:
673 case BFD_RELOC_23_PCREL_S2
:
683 alpha_fix_adjustable (f
)
686 /* Are there any relocation types for which we must generate a reloc
687 but we can adjust the values contained within it? */
688 switch (f
->fx_r_type
)
690 case BFD_RELOC_ALPHA_GPDISP_HI16
:
691 case BFD_RELOC_ALPHA_GPDISP_LO16
:
693 case BFD_RELOC_GPREL32
:
696 return !alpha_force_relocation (f
);
700 md_section_align (seg
, size
)
705 /* This should probably be handled within BFD, or by pulling the
706 number from BFD at least. */
714 /* Add this thing to the .lita section and produce a LITERAL reloc referring
719 Set GP value properly, and have values in LITERAL references set
724 load_symbol_address (reg
, insn
)
726 struct alpha_it
*insn
;
728 static symbolS
*lita_sym
;
739 lita_sym
= section_symbol (lita_sec
);
740 S_CLEAR_EXTERNAL (lita_sym
);
743 retval
= add_to_literal_pool (insn
->reloc
[0].exp
.X_add_symbol
,
744 insn
->reloc
[0].exp
.X_add_number
,
747 /* Now emit a LITERAL relocation for the original section. */
748 insn
->reloc
[0].exp
.X_op
= O_symbol
;
749 insn
->reloc
[0].exp
.X_add_symbol
= lita_sym
;
750 insn
->reloc
[0].exp
.X_add_number
= retval
;
751 insn
->reloc
[0].code
= BFD_RELOC_ALPHA_LITERAL
;
753 if (retval
== 0x8000)
755 as_fatal ("overflow in literal (.lita) table");
758 insn
->opcode
= (0xa0000000 /* ldl */
760 | (base_register
<< SB
)
763 insn
->opcode
= (0xa4000000 /* ldq */
765 | (base_register
<< SB
)
767 note_gpreg (base_register
);
770 /* To load an address with a single instruction,
771 emit a LITERAL reloc in this section, and a REFQUAD
772 for the .lita section, so that we'll be able to access
774 lda REG, xx -> ldq REG, -32752(gp)
775 lda REG, xx+4 -> ldq REG, -32752(gp)
778 The offsets need to start near -0x8000, and the generated LITERAL
779 relocations should negate the offset. I don't completely grok the
783 load_expression (reg
, insn
)
785 struct alpha_it
*insn
;
790 if (insn
->reloc
[0].exp
.X_add_symbol
->bsym
->flags
& BSF_SECTION_SYM
)
796 addend
= insn
->reloc
[0].exp
.X_add_number
;
797 insn
->reloc
[0].exp
.X_add_number
= 0;
799 load_symbol_address (reg
, insn
);
805 if ((x
& ~0x7fff) != 0
806 && (x
& ~0x7fff) + 0x8000 != 0)
808 as_bad ("assembler not prepared to handle constants >16 bits yet");
812 insn
[1].opcode
= (0x20000000 /* lda */
815 | (addend
& 0xffff));
816 insn
[1].reloc
[0].code
= BFD_RELOC_ALPHA_LITUSE
;
817 insn
[1].reloc
[0].exp
= lituse_basereg
;
823 getExpression (str
, this_insn
)
825 struct alpha_it
*this_insn
;
830 #if 0 /* Not converted to bfd yet, and I don't think we need them
831 for ECOFF. Re-adding a.out support will probably require
833 static const struct am
{
835 bfd_reloc_code_real_type reloc
;
837 { "hi", RELOC_48_63
},
838 { "lo", RELOC_0_15
},
839 { "ml", RELOC_16_31
},
840 { "mh", RELOC_32_47
},
841 { "uhi", RELOC_U_48_63
},
842 { "uml", RELOC_U_16_31
},
843 { "umh", RELOC_U_32_47
},
847 /* Handle macros: "%macroname(expr)" */
858 while (*q
&& *p
== *q
)
866 str
= p
; /* keep the '(' */
867 this_insn
->reloc
= m
->reloc
;
872 save_in
= input_line_pointer
;
873 input_line_pointer
= str
;
875 seg
= expression (&this_insn
->reloc
[0].exp
);
876 /* XXX validate seg and exp, make sure they're reasonable */
877 expr_end
= input_line_pointer
;
878 input_line_pointer
= save_in
;
881 /* Note that for now, this function is called recursively (by way of
882 calling md_assemble again). Some of the macros defined as part of
883 the assembly language are currently rewritten as sequences of
884 strings to be assembled. See, for example, the handling of "divq".
886 For efficiency, this should be fixed someday. */
888 alpha_ip (str
, insns
)
890 struct alpha_it insns
[];
896 struct alpha_opcode
*pattern
;
900 int match
= 0, num_gen
= 1;
904 islower (*s
) || *s
== '_' || *s
== '/' || *s
== '4' || *s
== '8';
923 as_warn ("Unknown opcode: `%s'", str
);
926 if ((pattern
= (struct alpha_opcode
*) hash_find (op_hash
, str
)) == NULL
)
928 as_warn ("Unknown opcode: `%s'", str
);
937 opcode
= pattern
->match
;
939 memset (insns
, 0, sizeof (*insns
));
940 for (i
= 0; i
< MAX_RELOCS
; i
++)
941 insns
[0].reloc
[i
].code
= BFD_RELOC_NONE
;
942 for (i
= 1; i
< MAX_INSNS
; i
++)
945 /* Build the opcode, checking as we go to make sure that the
947 for (args
= pattern
->args
;; ++args
)
952 case '\0': /* end of args */
971 case '(': /* these must match exactly */
980 case '1': /* next operand must be a register */
990 case 'a': /* $at: as temporary */
996 case 'g': /* $gp: base register */
999 mask
= base_register
;
1002 case 's': /* $sp: stack pointer */
1009 case 'r': /* any register */
1010 if (!isdigit (c
= *s
++))
1027 if ((c
= 10 * (c
- '0') + (*s
++ - '0')) >= 32)
1036 if ((c
== GP
) && first_32bit_quadrant
)
1046 /* Got the register, now figure out where it goes in
1054 opcode
|= mask
<< SA
;
1059 opcode
|= mask
<< SB
;
1068 opcode
|= (mask
<< SA
) | mask
;
1071 case 'R': /* ra and rb are the same */
1072 opcode
|= (mask
<< SA
) | (mask
<< SB
);
1076 opcode
|= (mask
<< SA
) | (mask
<< SB
) | (mask
);
1082 case 'e': /* next operand is a floating point register */
1086 if (*s
++ == '$' && *s
++ == 'f' && isdigit (*s
))
1091 mask
= 10 * (mask
- '0') + (*s
++ - '0');
1102 /* same encoding as gp registers */
1108 case 'h': /* bits 16..31 */
1109 insns
[0].reloc
= RELOC_16_31
;
1113 case 'l': /* bits 0..15 */
1114 insns
[0].reloc
[0].code
= BFD_RELOC_16
;
1117 case 'L': /* 21 bit PC relative immediate */
1118 insns
[0].reloc
[0].code
= BFD_RELOC_23_PCREL_S2
;
1119 insns
[0].reloc
[0].pcrel
= 1;
1122 case 'i': /* 14 bit immediate */
1123 if (OPCODE (opcode
) != 0x1a)
1124 /* Not a jmp variant?? */
1126 else if (opcode
& 0x8000)
1127 /* ret or jsr_coroutine */
1129 insns
[0].reloc
[0].code
= BFD_RELOC_14
;
1130 insns
[0].reloc
[0].pcrel
= 0;
1135 insns
[0].reloc
[0].code
= BFD_RELOC_ALPHA_HINT
;
1136 insns
[0].reloc
[0].pcrel
= 1;
1140 case 'b': /* 8 bit immediate */
1141 insns
[0].reloc
[0].code
= BFD_RELOC_8
;
1145 case 't': /* 12 bit 0...11 */
1146 insns
[0].reloc
= RELOC_0_12
;
1149 case '8': /* 8 bit 0...7 */
1150 insns
[0].reloc
= RELOC_0_8
;
1153 case 'I': /* 26 bit immediate */
1154 insns
[0].reloc
= RELOC_0_25
;
1166 getExpression (s
, &insns
[0]);
1168 /* Handle overflow in certain instructions by converting
1169 to other instructions. */
1170 if (insns
[0].reloc
[0].code
== BFD_RELOC_8
1171 && insns
[0].reloc
[0].exp
.X_op
== O_constant
1172 && (insns
[0].reloc
[0].exp
.X_add_number
< 0
1173 || insns
[0].reloc
[0].exp
.X_add_number
> 0xff))
1175 if (OPCODE (opcode
) == 0x10
1176 && (OP_FCN (opcode
) == 0x00 /* addl */
1177 || OP_FCN (opcode
) == 0x40 /* addl/v */
1178 || OP_FCN (opcode
) == 0x20 /* addq */
1179 || OP_FCN (opcode
) == 0x60 /* addq/v */
1180 || OP_FCN (opcode
) == 0x09 /* subl */
1181 || OP_FCN (opcode
) == 0x49 /* subl/v */
1182 || OP_FCN (opcode
) == 0x29 /* subq */
1183 || OP_FCN (opcode
) == 0x69 /* subq/v */
1184 || OP_FCN (opcode
) == 0x02 /* s4addl */
1185 || OP_FCN (opcode
) == 0x22 /* s4addq */
1186 || OP_FCN (opcode
) == 0x0b /* s4subl */
1187 || OP_FCN (opcode
) == 0x2b /* s4subq */
1188 || OP_FCN (opcode
) == 0x12 /* s8addl */
1189 || OP_FCN (opcode
) == 0x32 /* s8addq */
1190 || OP_FCN (opcode
) == 0x1b /* s8subl */
1191 || OP_FCN (opcode
) == 0x3b /* s8subq */
1193 /* Can we make it fit by negating? */
1194 && -insns
[0].reloc
[0].exp
.X_add_number
< 0xff
1195 && -insns
[0].reloc
[0].exp
.X_add_number
> 0)
1197 opcode
^= 0x120; /* convert add<=>sub */
1198 insns
[0].reloc
[0].exp
.X_add_number
*= -1;
1200 else if (at_ok
&& macro_ok
)
1202 /* Constant value supplied, but it's too large. */
1204 sprintf (expansion
, "lda $%d,%d($%d)", AT
,
1205 insns
[0].reloc
[0].exp
.X_add_number
, ZERO
);
1206 md_assemble (expansion
);
1207 opcode
|= 0x1000 /* use reg */ | (AT
<< SB
);
1208 insns
[0].reloc
[0].code
= BFD_RELOC_NONE
;
1211 as_bad ("overflow in 8-bit literal field in `operate' format insn");
1217 int format
, length
, mode
, i
, size
;
1218 char temp
[20 /*MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT*/];
1220 static const char formats
[4] = "FGfd";
1221 bfd_vma bits
, offset
;
1222 char *old_input_line_pointer
= input_line_pointer
;
1224 input_line_pointer
= s
;
1226 memset (temp
, 0, sizeof (temp
));
1227 mode
= (opcode
>> 26) & 3;
1228 format
= formats
[mode
];
1229 err
= md_atof (format
, temp
, &length
);
1232 as_bad ("Bad floating literal: %s", err
);
1237 /* Generate little-endian number from byte sequence. */
1239 for (i
= length
- 1; i
>= 0; i
--)
1240 bits
+= ((bfd_vma
)(temp
[i
] & 0xff)) << (i
* 8);
1245 offset
= get_lit8_offset (bits
) - 0x8000;
1246 insns
[0].reloc
[0].exp
.X_add_symbol
= lit8_sym
;
1247 insns
[0].reloc
[0].exp
.X_add_number
= 0x8000;
1250 offset
= get_lit4_offset (bits
) - 0x8000;
1251 insns
[0].reloc
[0].exp
.X_add_symbol
= lit4_sym
;
1252 insns
[0].reloc
[0].exp
.X_add_number
= 0x8000;
1257 insns
[0].reloc
[0].exp
.X_op
= O_symbol
;
1259 num_gen
= load_expression (AT
, &insns
[0]);
1260 insns
[num_gen
].reloc
[0].code
= BFD_RELOC_ALPHA_LITUSE
;
1261 insns
[num_gen
].reloc
[0].exp
= lituse_basereg
;
1262 insns
[num_gen
++].opcode
= opcode
| (AT
<< SB
) | offset
;
1263 opcode
= insns
[0].opcode
;
1264 s
= input_line_pointer
;
1265 input_line_pointer
= old_input_line_pointer
;
1269 /* The following two.. take advantage of the fact that
1270 opcode already contains most of what we need to know.
1271 We just prepend to the instr an "ldah
1272 $r,%ml(expr)($base)" and turn this one (done later
1273 after we return) into something like "stq
1274 $r,%lo(expr)(at)" or "ldq $r,%lo(expr)($r)".
1276 NOTE: This can fail later on at link time if the
1277 offset from $base actually turns out to be more than
1278 2**31 or 2**47 if use_large_offsets is set. */
1279 case 'P': /* Addressing macros: PUT */
1280 mask
= AT
; /* register 'at' */
1283 case 'G': /* Addressing macros: GET */
1285 /* All it is missing is the expression, which is what we
1290 getExpression (s
, &insns
[0]);
1293 /* Must check for "lda ..,number" too */
1294 if (insns
[0].reloc
[0].exp
.X_op
== O_big
)
1296 as_warn ("Sorry, not yet. Put bignums in .data section yourself.");
1299 if (insns
[0].reloc
[0].exp
.X_op
== O_constant
)
1301 /* This only handles 32bit numbers */
1302 register int val
= insns
[0].reloc
[0].exp
.X_add_number
;
1303 register short sval
;
1305 insns
[0].reloc
[0].code
= BFD_RELOC_NONE
;
1306 insns
[1].reloc
[0].code
= BFD_RELOC_NONE
;
1309 if ((sval
!= val
) && (val
& 0x8000))
1315 if (optnum
&& (sval
== val
))
1317 /* optimize away the ldah */
1319 opcode
|= (ZERO
<< SB
) | (val
& 0xffff);
1324 insns
[1].opcode
= opcode
| (mask
<< SB
) | (val
& 0xffff);
1325 opcode
= 0x24000000 /*ldah*/ |
1326 mask
<< SA
| (ZERO
<< SB
) |
1327 ((val
>> 16) & 0xffff);
1330 else if (insns
[0].reloc
[0].exp
.X_op
== O_symbol
)
1332 unsigned long old_opcode
= opcode
;
1336 as_bad ("insn requires expansion but `nomacro' specified");
1337 else if (*args
== 'G')
1340 as_bad ("insn expansion requires AT use, but `noat' specified");
1343 num_gen
= load_expression (tmp_reg
, insns
);
1344 opcode
= insns
[0].opcode
;
1345 /* lda is opcode 8, 0x20000000 */
1346 if (OPCODE (old_opcode
) != 0x08)
1349 i
= &insns
[num_gen
++];
1350 i
->opcode
= old_opcode
| (tmp_reg
<< SB
);
1352 i
->reloc
[0].code
= BFD_RELOC_ALPHA_LITUSE
;
1353 i
->reloc
[0].exp
= lituse_basereg
;
1360 insns
[1].reloc
[0].exp
= insns
[0].reloc
[0].exp
;
1362 /* Generate: ldah REG,x1(GP); OP ?,x0(REG) */
1364 abort (); /* relocs need fixing */
1366 insns
[1].reloc
= RELOC_0_15
;
1367 insns
[1].opcode
= opcode
| mask
<< SB
;
1369 insns
[0].reloc
= RELOC_16_31
;
1370 opcode
= 0x24000000 /*ldah*/ | mask
<< SA
| (base_register
<< SB
);
1376 /* Same failure modes as above, actually most of the
1377 same code shared. */
1378 case 'B': /* Builtins */
1383 case 'a': /* ldgp */
1385 if (first_32bit_quadrant
|| no_mixed_code
)
1387 switch (OUTPUT_FLAVOR
)
1389 case bfd_target_aout_flavour
:
1390 /* this is cmu's a.out version */
1391 insns
[0].reloc
[0].code
= BFD_RELOC_NONE
;
1392 /* generate "zap %r,0xf,%r" to take high 32 bits */
1393 opcode
|= 0x48001600 /* zap ?,#,?*/ | (0xf << SN
);
1395 case bfd_target_ecoff_flavour
:
1396 /* Given "ldgp R1,N(R2)", turn it into something
1397 like "ldah R1,###(R2) ; lda R1,###(R1)" with
1398 appropriate constants and relocations. */
1400 unsigned long r1
, r2
;
1401 unsigned long addend
= 0;
1406 insns
[0].reloc
[0].code
= BFD_RELOC_ALPHA_GPDISP_HI16
;
1407 insns
[0].reloc
[0].pcrel
= 1;
1408 insns
[0].reloc
[0].exp
.X_op
= O_symbol
;
1409 insns
[0].reloc
[0].exp
.X_add_symbol
= gp
;
1410 insns
[0].reloc
[0].exp
.X_add_number
= 0;
1411 insns
[0].opcode
= (0x24000000 /* ldah */
1414 insns
[1].reloc
[0].code
= BFD_RELOC_ALPHA_GPDISP_LO16
;
1415 insns
[1].reloc
[0].exp
.X_op
= O_symbol
;
1416 insns
[1].reloc
[0].exp
.X_add_symbol
= gp
;
1417 insns
[1].reloc
[0].exp
.X_add_number
= 4;
1418 insns
[1].reloc
[0].pcrel
= 1;
1419 insns
[1].opcode
= 0x20000000 | (r1
<< SA
) | (r1
<< SB
);
1420 opcode
= insns
[0].opcode
;
1421 /* merge in addend */
1422 insns
[1].opcode
|= addend
& 0xffff;
1423 insns
[0].opcode
|= ((addend
>> 16)
1424 + (addend
& 0x8000 ? 1 : 0));
1425 ecoff_set_gp_prolog_size (0);
1434 case 'b': /* setgp */
1435 switch (OUTPUT_FLAVOR
)
1437 case bfd_target_aout_flavour
:
1438 /* generate "zap %r,0xf,$gp" to take high 32 bits */
1439 opcode
|= 0x48001600 /* zap ?,#,?*/
1440 | (0xf << SN
) | (base_register
);
1447 case 'c': /* jsr $r,foo becomes
1450 Register 27, t12, is used by convention
1453 struct alpha_it
*jsr
;
1455 struct reloc_data
*r
;
1457 /* We still have to parse the function name */
1460 getExpression (s
, &insns
[0]);
1461 etmp
= insns
[0].reloc
[0].exp
;
1463 num_gen
= load_expression (PV
, &insns
[0]);
1466 jsr
= &insns
[num_gen
++];
1467 jsr
->opcode
= (0x68004000 /* jsr */
1473 /* LITUSE wasn't emitted yet */
1474 jsr
->reloc
[0].code
= BFD_RELOC_ALPHA_LITUSE
;
1475 jsr
->reloc
[0].exp
= lituse_jsr
;
1481 r
->code
= BFD_RELOC_ALPHA_HINT
;
1483 opcode
= insns
[0].opcode
;
1487 /* DIVISION and MODULUS. Yech.
1488 Convert OP x,y,result
1494 with appropriate optimizations if t10,t11,t12
1495 are the registers specified by the compiler.
1496 We are missing an obvious optimization
1497 opportunity here; if the ldq generated by the
1498 jsr assembly requires a cycle or two to make
1499 the value available, initiating it before one
1500 or two of the mov instructions would result in
1501 faster execution. */
1502 case '0': /* reml */
1503 case '1': /* divl */
1504 case '2': /* remq */
1505 case '3': /* divq */
1506 case '4': /* remlu */
1507 case '5': /* divlu */
1508 case '6': /* remqu */
1509 case '7': /* divqu */
1511 static char func
[8][6] = {
1512 "reml", "divl", "remq", "divq",
1513 "remlu", "divlu", "remqu", "divqu"
1518 /* All regs parsed, in opcode */
1520 /* Do the expansions, one instr at a time */
1522 reg
= (opcode
>> SA
) & 31;
1526 sprintf (expansion
, "mov $%d,$%d", reg
, T10
);
1527 md_assemble (expansion
);
1529 reg
= (opcode
>> SB
) & 31;
1531 /* we already overwrote it! */
1533 else if (reg
!= T11
)
1536 sprintf (expansion
, "mov $%d,$%d", reg
, T11
);
1537 md_assemble (expansion
);
1539 sprintf (expansion
, "lda $%d,__%s", PV
, func
[*args
- '0']);
1540 md_assemble (expansion
);
1541 sprintf (expansion
, "jsr $%d,($%d),__%s", T9
, PV
,
1543 md_assemble (expansion
);
1545 if (!first_32bit_quadrant
)
1550 md_assemble (expansion
);
1553 sprintf (expansion
, "ldgp $%d,0($%d)",
1555 md_assemble (expansion
);
1557 /* Use insns[0] to get at the result */
1558 if ((reg
= (opcode
& 31)) != PV
)
1559 opcode
= (0x47e00400 /* or zero,zero,zero */
1561 | reg
/* Rc */ ); /* pv->z */
1577 /* Args don't match. */
1578 if (&pattern
[1] - alpha_opcodes
< NUMOPCODES
1579 && !strcmp (pattern
->name
, pattern
[1].name
))
1587 as_warn ("Illegal operands");
1593 /* Args match, see if a float instructions and -nofloats */
1594 if (nofloats
&& pattern
->isa_float
)
1600 insns
[0].opcode
= opcode
;
1604 /* Turn a string in input_line_pointer into a floating point constant
1605 of type type, and store the appropriate bytes in *litP. The number
1606 of LITTLENUMS emitted is stored in *sizeP. An error message is
1607 returned, or NULL on OK. */
1609 /* Equal to MAX_PRECISION in atof-ieee.c */
1610 #define MAX_LITTLENUMS 6
1613 md_atof (type
, litP
, sizeP
)
1619 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
1620 LITTLENUM_TYPE
*wordP
;
1622 char *atof_ieee (), *vax_md_atof ();
1628 /* VAX md_atof doesn't like "G" for some reason. */
1632 return vax_md_atof (type
, litP
, sizeP
);
1655 return "Bad call to MD_ATOF()";
1657 t
= atof_ieee (input_line_pointer
, type
, words
);
1659 input_line_pointer
= t
;
1660 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
1662 for (wordP
= words
+ prec
- 1; prec
--;)
1664 md_number_to_chars (litP
, (long) (*wordP
--), sizeof (LITTLENUM_TYPE
));
1665 litP
+= sizeof (LITTLENUM_TYPE
);
1672 md_bignum_to_chars (buf
, bignum
, nchars
)
1674 LITTLENUM_TYPE
*bignum
;
1679 LITTLENUM_TYPE work
= *bignum
++;
1680 int nb
= CHARS_PER_LITTLENUM
;
1684 *buf
++ = work
& ((1 << BITS_PER_CHAR
) - 1);
1687 work
>>= BITS_PER_CHAR
;
1694 md_parse_option (argP
, cntP
, vecP
)
1704 #if 0 /* I have no idea if this stuff would work any more. And it's
1705 probably not right for ECOFF anyways. */
1706 /* Use base-register addressing, e.g. PIC code */
1709 if (first_32bit_quadrant
)
1711 first_32bit_quadrant
= 0;
1716 first_32bit_quadrant
= 1;
1717 base_register
= ZERO
;
1719 if (argP
[0][1] == 'k')
1725 if (!strcmp (*argP
, "32addr"))
1731 if (!strcmp (*argP
, "nocpp"))
1742 /* XXXX Align to cache linesize XXXXX */
1749 /* Takes ".proc name,nargs" */
1750 name
= input_line_pointer
;
1751 c
= get_symbol_end ();
1752 p
= input_line_pointer
;
1753 symbolP
= symbol_find_or_make (name
);
1756 if (*input_line_pointer
!= ',')
1759 as_warn ("Expected comma after name \"%s\"", name
);
1762 ignore_rest_of_line ();
1766 input_line_pointer
++;
1767 temp
= get_absolute_expression ();
1769 /* symbolP->sy_other = (signed char) temp; */
1770 as_warn ("unhandled: .proc %s,%d", name
, temp
);
1771 demand_empty_rest_of_line ();
1778 char *name
= input_line_pointer
, ch
, *s
;
1781 while (!is_end_of_line
[(unsigned char) *input_line_pointer
])
1782 input_line_pointer
++;
1783 ch
= *input_line_pointer
;
1784 *input_line_pointer
= '\0';
1787 if (s
[0] == 'n' && s
[1] == 'o')
1792 if (!strcmp ("reorder", s
))
1794 else if (!strcmp ("at", s
))
1796 else if (!strcmp ("macro", s
))
1799 as_warn ("Tried to set unrecognized symbol: %s", name
);
1800 *input_line_pointer
= ch
;
1801 demand_empty_rest_of_line ();
1804 /* @@ Is this right?? */
1806 md_pcrel_from (fixP
)
1809 valueT addr
= fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
1810 switch (fixP
->fx_r_type
)
1812 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1813 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1816 return fixP
->fx_size
+ addr
;
1821 alpha_do_align (n
, fill
)
1826 && (now_seg
== text_section
1827 || !strcmp (now_seg
->name
, ".init")
1828 || !strcmp (now_seg
->name
, ".fini")))
1830 static const unsigned char nop_pattern
[] = { 0x1f, 0x04, 0xff, 0x47 };
1831 frag_align_pattern (n
, nop_pattern
, sizeof (nop_pattern
));
1838 md_apply_fix (fixP
, valueP
)
1845 char *p
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
1849 switch (fixP
->fx_r_type
)
1851 /* The GPDISP relocations are processed internally with a symbol
1852 referring to the current function; we need to drop in a value
1853 which, when added to the address of the start of the function,
1854 gives the desired GP. */
1855 case BFD_RELOC_ALPHA_GPDISP_HI16
:
1856 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1858 if (fixP
->fx_r_type
== BFD_RELOC_ALPHA_GPDISP_HI16
)
1860 assert (fixP
->fx_next
->fx_r_type
== BFD_RELOC_ALPHA_GPDISP_LO16
);
1863 fprintf_vma (stdout
, addend
);
1866 if (addend
& 0x8000)
1869 fixP
->fx_offset
= 4; /* @@ Compute this using fx_next. */
1875 fprintf_vma (stdout
, addend
);
1879 fixP
->fx_offset
= 0;
1881 md_number_to_chars (fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
,
1883 fixP
->fx_addsy
= section_symbol (absolute_section
);
1884 fixP
->fx_offset
+= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
1888 /* Write 8 bits, shifted left 13 bit positions. */
1892 *p
|= (value
<< 5) & 0xe0;
1901 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
1902 "overflow in type-%d reloc", (int) fixP
->fx_r_type
);
1912 /* Don't want overflow checking. */
1915 if (fixP
->fx_pcrel
== 0
1916 && fixP
->fx_addsy
== 0)
1918 md_number_to_chars (p
, value
, size
);
1919 /* @@ Overflow checks?? */
1925 if (fixP
->fx_addsy
!= 0
1926 && fixP
->fx_addsy
->bsym
->section
!= absolute_section
)
1927 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
1928 "ret/jsr_coroutine requires constant in displacement field");
1929 else if (value
>> 14 != 0)
1930 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
1931 "overflow in 14-bit operand field of ret or jsr_coroutine");
1932 *p
++ = value
& 0xff;
1934 *p
= (*p
& 0xc0) | (value
& 0x3f);
1937 case BFD_RELOC_23_PCREL_S2
:
1938 /* Write 21 bits only. */
1940 *p
++ = value
& 0xff;
1942 *p
++ = value
& 0xff;
1945 *p
|= (value
& 0x1f);
1948 case BFD_RELOC_ALPHA_LITERAL
:
1949 case BFD_RELOC_ALPHA_LITUSE
:
1952 case BFD_RELOC_GPREL32
:
1953 assert (fixP
->fx_subsy
== gp
);
1954 value
= - alpha_gp_value
; /* huh? this works... */
1956 md_number_to_chars (p
, value
, 4);
1959 case BFD_RELOC_ALPHA_HINT
:
1960 if (fixP
->fx_addsy
== 0 && fixP
->fx_pcrel
== 0)
1968 as_fatal ("unknown relocation type %d?", fixP
->fx_r_type
);
1972 if (fixP
->fx_addsy
== 0 && fixP
->fx_pcrel
== 0)
1974 printf ("type %d reloc done?\n", fixP
->fx_r_type
);
1984 alpha_frob_ecoff_data ()
1987 /* $zero and $f31 are read-only */
1988 alpha_gprmask
&= ~1;
1989 alpha_fprmask
&= ~1;
1992 /* The Alpha has support for some VAX floating point types, as well as for
1993 IEEE floating point. We consider IEEE to be the primary floating point
1994 format, and sneak in the VAX floating point support here. */
1995 #define md_atof vax_md_atof
1996 #include "config/atof-vax.c"