1 /* tc-alpha.c - Processor-specific code for the DEC Alpha CPU.
2 Copyright (C) 1989, 1993, 1994 Free Software Foundation, Inc.
3 Contributed by Carnegie Mellon University, 1993.
4 Written by Alessandro Forin, based on earlier gas-1.38 target CPU files.
5 Modified by Ken Raeburn for gas-2.x and ECOFF support.
7 This file is part of GAS, the GNU Assembler.
9 GAS is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2, or (at your option)
14 GAS is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GAS; see the file COPYING. If not, write to
21 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
24 * Mach Operating System
25 * Copyright (c) 1993 Carnegie Mellon University
26 * All Rights Reserved.
28 * Permission to use, copy, modify and distribute this software and its
29 * documentation is hereby granted, provided that both the copyright
30 * notice and this permission notice appear in all copies of the
31 * software, derivative works or modified versions, and any portions
32 * thereof, and that both notices appear in supporting documentation.
34 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
35 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
36 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
38 * Carnegie Mellon requests users of this software to return to
40 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
41 * School of Computer Science
42 * Carnegie Mellon University
43 * Pittsburgh PA 15213-3890
45 * any improvements or extensions that they make and grant Carnegie the
46 * rights to redistribute these changes.
50 * 5-Oct-93 Alessandro Forin (af) at Carnegie-Mellon University
53 * Author: Alessandro Forin, Carnegie Mellon University
60 #include "alpha-opcode.h"
63 /* @@ Will a simple 0x8000 work here? If not, why not? */
64 #define GP_ADJUSTMENT (0x8000 - 0x10)
66 /* Which machine type is this? Currently stores an integer for the
67 model, one of: 21064, 21066, 21164. */
68 static unsigned long machine
;
70 /* These are exported to relaxing code, even though we don't do any
71 relaxing on this processor currently. */
72 const relax_typeS md_relax_table
[1];
73 int md_short_jump_size
= 4;
74 int md_long_jump_size
= 4;
76 /* handle of the OPCODE hash table */
77 static struct hash_control
*op_hash
;
79 /* Sections and symbols we'll want to keep track of. */
80 static segT lita_sec
, rdata
, sdata
, lit8_sec
, lit4_sec
;
81 static symbolS
*lit8_sym
, *lit4_sym
;
83 /* Setting for ".set [no]{at,macro}". */
84 static int at_ok
= 1, macro_ok
= 1;
86 /* Keep track of global pointer. */
87 valueT alpha_gp_value
;
90 /* We'll probably be using this relocation frequently, and we
91 will want to compare for it. */
92 static const reloc_howto_type
*gpdisp_hi16_howto
;
94 /* These are exported to ECOFF code. */
95 unsigned long alpha_gprmask
, alpha_fprmask
;
97 /* Used for LITUSE relocations. */
98 static expressionS lituse_basereg
, lituse_byteoff
, lituse_jsr
;
100 /* Address size: In OSF/1 1.3, an undocumented "-32addr" option will
101 cause all addresses to be treated as 32-bit values in memory. (The
102 in-register versions are all sign-extended to 64 bits, of course.)
103 Some other systems may want this option too. */
106 /* Imported functions -- they should be defined in header files somewhere. */
107 extern segT
subseg_get ();
108 extern PTR
bfd_alloc_by_size_t ();
109 extern void s_globl (), s_long (), s_short (), s_space (), cons (), s_text (),
110 s_data (), float_cons ();
112 /* Static functions, needing forward declarations. */
113 static void s_base (), s_proc (), s_alpha_set ();
114 static void s_gprel32 (), s_rdata (), s_sdata (), s_alpha_comm ();
115 static int alpha_ip ();
117 const pseudo_typeS md_pseudo_table
[] =
119 {"common", s_comm
, 0}, /* is this used? */
120 {"comm", s_alpha_comm
, 0}, /* osf1 compiler does this */
121 {"rdata", s_rdata
, 0},
122 {"sdata", s_sdata
, 0},
123 {"gprel32", s_gprel32
, 0},
124 {"t_floating", float_cons
, 'd'},
125 {"s_floating", float_cons
, 'f'},
126 {"f_floating", float_cons
, 'F'},
127 {"g_floating", float_cons
, 'G'},
128 {"d_floating", float_cons
, 'D'},
131 {"aproc", s_proc
, 1},
132 {"set", s_alpha_set
, 0},
133 {"reguse", s_ignore
, 0},
134 {"livereg", s_ignore
, 0},
135 {"extern", s_ignore
, 0}, /*??*/
136 {"base", s_base
, 0}, /*??*/
137 {"option", s_ignore
, 0},
138 {"prologue", s_ignore
, 0},
139 {"aent", s_ignore
, 0},
140 {"ugen", s_ignore
, 0},
142 /* We don't do any optimizing, so we can safely ignore these. */
143 {"noalias", s_ignore
, 0},
144 {"alias", s_ignore
, 0},
149 #define SA 21 /* shift for register Ra */
150 #define SB 16 /* shift for register Rb */
151 #define SC 0 /* shift for register Rc */
152 #define SN 13 /* shift for 8 bit immediate # */
158 #define RA 26 /* note: same as T12 */
165 #define OPCODE(X) (((X) >> 26) & 0x3f)
166 #define OP_FCN(X) (((X) >> 5) & 0x7f)
168 #ifndef FIRST_32BIT_QUADRANT
169 #define FIRST_32BIT_QUADRANT 0
172 int first_32bit_quadrant
= FIRST_32BIT_QUADRANT
;
173 int base_register
= FIRST_32BIT_QUADRANT
? ZERO
: GP
;
175 int no_mixed_code
= 0;
178 /* This array holds the chars that always start a comment. If the
179 pre-processor is disabled, these aren't very useful */
180 const char comment_chars
[] = "#";
182 /* This array holds the chars that only start a comment at the beginning of
183 a line. If the line seems to have the form '# 123 filename'
184 .line and .file directives will appear in the pre-processed output */
185 /* Note that input_file.c hand checks for '#' at the beginning of the
186 first line of the input file. This is because the compiler outputs
187 #NO_APP at the beginning of its output. */
188 /* Also note that C style comments are always recognized. */
189 const char line_comment_chars
[] = "#!";
191 /* Chars that can be used to separate mant from exp in floating point nums */
192 const char EXP_CHARS
[] = "eE";
194 const char line_separator_chars
[1];
196 /* Chars that mean this number is a floating point constant, as in
197 "0f12.456" or "0d1.2345e12". */
198 /* @@ Do all of these really get used on the alpha?? */
199 char FLT_CHARS
[] = "rRsSfFdDxXpP";
201 /* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
202 changed in read.c. Ideally it shouldn't have to know about it at all,
203 but nothing is ideal around here. */
208 bfd_reloc_code_real_type code
;
211 /* Occasionally, two relocations will be desired for one address.
212 Mainly only in cases like "jsr $r,foo" where we want both a LITUSE
217 unsigned long opcode
; /* need at least 32 bits */
218 struct reloc_data reloc
[MAX_RELOCS
];
221 static void getExpression (char *str
, struct alpha_it
*insn
);
222 static char *expr_end
;
224 #define note_gpreg(R) (alpha_gprmask |= (1 << (R)))
225 #define note_fpreg(R) (alpha_fprmask |= (1 << (R)))
228 tc_get_register (frame
)
234 if (*input_line_pointer
== '$')
236 input_line_pointer
++;
237 if (input_line_pointer
[0] == 's'
238 && input_line_pointer
[1] == 'p')
240 input_line_pointer
+= 2;
244 framereg
= get_absolute_expression ();
245 framereg
&= 31; /* ? */
248 as_warn ("frame reg expected, using $%d.", framereg
);
250 note_gpreg (framereg
);
260 temp
= get_absolute_expression ();
263 rdata
= subseg_get (".rdata", 0);
264 subseg_set (rdata
, (subsegT
) temp
);
266 rdata
= subseg_new (".rdata", 0);
268 demand_empty_rest_of_line ();
277 temp
= get_absolute_expression ();
280 sdata
= subseg_get (".sdata", 0);
281 subseg_set (sdata
, (subsegT
) temp
);
283 sdata
= subseg_new (".sdata", 0);
285 demand_empty_rest_of_line ();
289 s_alpha_comm (ignore
)
296 register symbolS
*symbolP
;
298 name
= input_line_pointer
;
299 c
= get_symbol_end ();
300 /* just after name is now '\0' */
301 p
= input_line_pointer
;
304 /* Alpha OSF/1 compiler doesn't provide the comma, gcc does. */
305 if (*input_line_pointer
== ',')
307 input_line_pointer
++;
310 if ((temp
= get_absolute_expression ()) < 0)
312 as_warn (".COMMon length (%ld.) <0! Ignored.", (long) temp
);
313 ignore_rest_of_line ();
317 symbolP
= symbol_find_or_make (name
);
319 if (S_IS_DEFINED (symbolP
))
321 as_bad ("Ignoring attempt to re-define symbol");
322 ignore_rest_of_line ();
325 if (S_GET_VALUE (symbolP
))
327 if (S_GET_VALUE (symbolP
) != (valueT
) temp
)
328 as_bad ("Length of .comm \"%s\" is already %ld. Not changed to %ld.",
329 S_GET_NAME (symbolP
),
330 (long) S_GET_VALUE (symbolP
),
335 S_SET_VALUE (symbolP
, (valueT
) temp
);
336 S_SET_EXTERNAL (symbolP
);
339 know (symbolP
->sy_frag
== &zero_address_frag
);
340 demand_empty_rest_of_line ();
344 tc_gen_reloc (sec
, fixp
)
350 reloc
= (arelent
*) bfd_alloc_by_size_t (stdoutput
, sizeof (arelent
));
351 reloc
->sym_ptr_ptr
= &fixp
->fx_addsy
->bsym
;
352 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
354 if (fixp
->fx_r_type
> BFD_RELOC_UNUSED
)
357 if (fixp
->fx_r_type
== BFD_RELOC_ALPHA_GPDISP_HI16
)
359 if (!gpdisp_hi16_howto
)
360 gpdisp_hi16_howto
= bfd_reloc_type_lookup (stdoutput
,
362 reloc
->howto
= gpdisp_hi16_howto
;
365 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
366 assert (reloc
->howto
!= 0);
367 if (!fixp
->fx_pcrel
!= !reloc
->howto
->pc_relative
)
369 as_fatal ("bug in handling type-%d relocs", fixp
->fx_r_type
);
372 assert (!fixp
->fx_pcrel
== !reloc
->howto
->pc_relative
);
374 if (fixp
->fx_r_type
== BFD_RELOC_ALPHA_LITERAL
)
376 /* fake out bfd_perform_relocation. sigh */
377 reloc
->addend
= -alpha_gp_value
;
379 else if (reloc
->howto
->pc_relative
&& reloc
->howto
->pcrel_offset
)
381 reloc
->addend
= fixp
->fx_offset
- reloc
->address
;
384 reloc
->addend
= fixp
->fx_offset
;
391 if (first_32bit_quadrant
)
393 /* not fatal, but it might not work in the end */
394 as_warn ("File overrides no-base-register option.");
395 first_32bit_quadrant
= 0;
399 if (*input_line_pointer
== '$')
401 input_line_pointer
++;
402 if (*input_line_pointer
== 'r')
403 input_line_pointer
++;
406 base_register
= get_absolute_expression ();
407 if (base_register
< 0 || base_register
> 31)
410 as_warn ("Bad base register, using $%d.", base_register
);
412 demand_empty_rest_of_line ();
426 e
.X_add_symbol
= section_symbol (absolute_section
);
437 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 4, &e
, 0,
442 create_literal_section (secp
, name
)
446 segT current_section
= now_seg
;
447 int current_subsec
= now_subseg
;
450 *secp
= new_sec
= subseg_new (name
, 0);
451 subseg_set (current_section
, current_subsec
);
452 bfd_set_section_alignment (stdoutput
, new_sec
, 3);
453 bfd_set_section_flags (stdoutput
, new_sec
,
454 SEC_RELOC
| SEC_ALLOC
| SEC_LOAD
| SEC_READONLY
458 #define create_lita_section() create_literal_section (&lita_sec, ".lita")
461 get_lit8_offset (val
)
467 create_literal_section (&lit8_sec
, ".lit8");
468 lit8_sym
= section_symbol (lit8_sec
);
470 retval
= add_to_literal_pool ((symbolS
*) 0, val
, lit8_sec
, 8);
471 if (retval
>= 0xfff0)
472 as_fatal ("overflow in fp literal (.lit8) table");
477 get_lit4_offset (val
)
483 create_literal_section (&lit4_sec
, ".lit4");
484 lit4_sym
= section_symbol (lit4_sec
);
486 retval
= add_to_literal_pool ((symbolS
*) 0, val
, lit4_sec
, 4);
487 if (retval
>= 0xfff0)
488 as_fatal ("overflow in fp literal (.lit4) table");
492 #define load_insn(NAME, OP) (hash_insert (op_hash, (NAME), (PTR) (OP)))
495 load_insn_table (ops
, size
)
496 struct alpha_opcode
*ops
;
499 struct alpha_opcode
*end
= ops
+ size
;
500 struct alpha_opcode
*op
;
503 for (op
= ops
; op
< end
; )
509 retval
= load_insn (op
->name
, op
);
511 as_fatal ("internal error: can't hash opcode `%s': %s",
518 || !strcmp (op
->name
, name
)));
520 /* Some opcodes include modifiers of various sorts with a "/mod"
521 syntax, like the architecture documentation suggests. However,
522 for use with gcc at least, we also need to access those same
523 opcodes without the "/". */
524 for (op
= ops
; op
< end
; )
528 if (strchr (name
, '/'))
533 name2
= xmalloc (strlen (name
));
543 /* Ignore failures -- the opcode table does duplicate some
544 variants in different forms, like "hw_stq" and "hw_st/q".
545 Maybe the variants can be eliminated, and this error checking
547 load_insn (name2
, op
);
554 || !strcmp (op
->name
, name
)));
558 /* This function is called once, at assembler startup time. It should
559 set up all the tables, etc. that the MD part of the assembler will
560 need, that can be determined before arguments are parsed. */
564 op_hash
= hash_new ();
565 load_insn_table (alpha_opcodes
, NUMOPCODES
);
567 /* Default to 21064 PAL instructions. */
575 load_insn_table (alpha_pal21064_opcodes
, NUM21064OPCODES
);
578 load_insn_table (alpha_pal21164_opcodes
, NUM21164OPCODES
);
581 as_fatal ("palcode set unknown (internal error)");
584 lituse_basereg
.X_op
= O_constant
;
585 lituse_basereg
.X_add_number
= 1;
586 lituse_byteoff
.X_op
= O_constant
;
587 lituse_byteoff
.X_add_number
= 2;
588 lituse_jsr
.X_op
= O_constant
;
589 lituse_jsr
.X_add_number
= 3;
591 /* So .sbss will get used for tiny objects. */
592 bfd_set_gp_size (stdoutput
, 8);
593 create_lita_section ();
594 /* For handling the GP, create a symbol that won't be output in the
595 symbol table. We'll edit it out of relocs later. */
596 gp
= symbol_new ("<GP value>", lita_sec
, 0x8000, &zero_address_frag
);
597 symbol_remove (gp
, &symbol_rootP
, &symbol_lastP
);
604 struct alpha_it
*insn
;
611 /* put out the opcode */
612 md_number_to_chars (toP
, insn
->opcode
, 4);
614 /* put out the symbol-dependent stuff */
615 for (j
= 0; j
< MAX_RELOCS
; j
++)
617 struct reloc_data
*r
= &insn
->reloc
[j
];
620 if (r
->code
!= BFD_RELOC_NONE
)
622 if (r
->exp
.X_op
== O_constant
)
624 r
->exp
.X_add_symbol
= section_symbol (absolute_section
);
625 r
->exp
.X_op
= O_symbol
;
627 f
= fix_new_exp (frag_now
, (toP
- frag_now
->fr_literal
), 4,
628 &r
->exp
, r
->pcrel
, r
->code
);
630 if (r
->code
== BFD_RELOC_ALPHA_GPDISP_LO16
)
632 static bit_fixS cookie
;
633 /* @@ This'll make the range checking in write.c shut up. */
634 f
->fx_bit_fixP
= &cookie
;
645 struct alpha_it insns
[MAX_INSNS
];
647 count
= alpha_ip (str
, insns
);
651 for (i
= 0; i
< count
; i
++)
652 emit_insn (&insns
[i
]);
662 vma
= bfd_get_section_vma (foo
, sec
);
663 if (vma
&& vma
< alpha_gp_value
)
664 alpha_gp_value
= vma
;
670 if (alpha_gp_value
!= 0)
673 /* Get minus-one in whatever width... */
674 alpha_gp_value
= 0; alpha_gp_value
--;
676 /* Select the smallest VMA of these existing sections. */
677 maybe_set_gp (lita_sec
);
678 /* maybe_set_gp (sdata); Was disabled before -- should we use it? */
680 maybe_set_gp (lit8_sec
);
681 maybe_set_gp (lit4_sec
);
684 alpha_gp_value
+= GP_ADJUSTMENT
;
686 S_SET_VALUE (gp
, alpha_gp_value
);
689 printf ("Chose GP value of %lx\n", alpha_gp_value
);
694 alpha_force_relocation (f
)
697 switch (f
->fx_r_type
)
699 case BFD_RELOC_ALPHA_GPDISP_HI16
:
700 case BFD_RELOC_ALPHA_GPDISP_LO16
:
701 case BFD_RELOC_ALPHA_LITERAL
:
702 case BFD_RELOC_ALPHA_LITUSE
:
703 case BFD_RELOC_GPREL32
:
705 case BFD_RELOC_ALPHA_HINT
:
710 case BFD_RELOC_23_PCREL_S2
:
721 alpha_fix_adjustable (f
)
724 /* Are there any relocation types for which we must generate a reloc
725 but we can adjust the values contained within it? */
726 switch (f
->fx_r_type
)
728 case BFD_RELOC_ALPHA_GPDISP_HI16
:
729 case BFD_RELOC_ALPHA_GPDISP_LO16
:
731 case BFD_RELOC_GPREL32
:
734 return !alpha_force_relocation (f
);
740 md_section_align (seg
, size
)
745 /* This should probably be handled within BFD, or by pulling the
746 number from BFD at least. */
754 /* Add this thing to the .lita section and produce a LITERAL reloc referring
757 /* Are we currently eligible to emit a LITUSE reloc for the literal
758 references just generated? */
759 static int lituse_pending
;
762 load_symbol_address (reg
, insn
)
764 struct alpha_it
*insn
;
766 static symbolS
*lita_sym
;
773 lita_sym
= section_symbol (lita_sec
);
774 S_CLEAR_EXTERNAL (lita_sym
);
777 retval
= add_to_literal_pool (insn
->reloc
[0].exp
.X_add_symbol
,
778 insn
->reloc
[0].exp
.X_add_number
,
781 /* Now emit a LITERAL relocation for the original section. */
782 insn
->reloc
[0].exp
.X_op
= O_symbol
;
783 insn
->reloc
[0].exp
.X_add_symbol
= lita_sym
;
784 insn
->reloc
[0].exp
.X_add_number
= retval
;
785 insn
->reloc
[0].code
= BFD_RELOC_ALPHA_LITERAL
;
788 if (retval
== 0x8000)
790 as_fatal ("overflow in literal (.lita) table");
793 insn
->opcode
= (0xa0000000 /* ldl */
795 | (base_register
<< SB
)
798 insn
->opcode
= (0xa4000000 /* ldq */
800 | (base_register
<< SB
)
802 note_gpreg (base_register
);
805 /* To load an address with a single instruction,
806 emit a LITERAL reloc in this section, and a REFQUAD
807 for the .lita section, so that we'll be able to access
809 lda REG, xx -> ldq REG, -32752(gp)
810 lda REG, xx+4 -> ldq REG, -32752(gp)
813 The offsets need to start near -0x8000, and the generated LITERAL
814 relocations should negate the offset. I don't completely grok the
818 load_expression (reg
, insn
)
820 struct alpha_it
*insn
;
822 valueT addend
, addendhi
, addendlo
;
825 if (insn
->reloc
[0].exp
.X_add_symbol
->bsym
->flags
& BSF_SECTION_SYM
)
831 addend
= insn
->reloc
[0].exp
.X_add_number
;
832 insn
->reloc
[0].exp
.X_add_number
= 0;
834 load_symbol_address (reg
, insn
);
837 if ((addend
& ~0x7fffffff) != 0
838 && (addend
& ~0x7fffffff) + 0x80000000 != 0)
840 as_bad ("assembler not prepared to handle constants >32 bits yet");
843 addendlo
= addend
& 0xffff;
845 addendhi
= addend
>> 16;
846 if (addendlo
& 0x8000)
848 /* It appears that the BASEREG LITUSE reloc should not be used on
849 an LDAH instruction. */
852 insn
[1].opcode
= (0x20000000 /* lda */
855 | (addendlo
& 0xffff));
856 insn
[1].reloc
[0].code
= BFD_RELOC_ALPHA_LITUSE
;
857 insn
[1].reloc
[0].exp
= lituse_basereg
;
862 insn
[num_insns
].opcode
= (0x24000000
865 | (addendhi
& 0xffff));
876 getExpression (str
, this_insn
)
878 struct alpha_it
*this_insn
;
883 #if 0 /* Not converted to bfd yet, and I don't think we need them
884 for ECOFF. Re-adding a.out support will probably require
886 static const struct am
{
888 bfd_reloc_code_real_type reloc
;
890 { "hi", RELOC_48_63
},
891 { "lo", RELOC_0_15
},
892 { "ml", RELOC_16_31
},
893 { "mh", RELOC_32_47
},
894 { "uhi", RELOC_U_48_63
},
895 { "uml", RELOC_U_16_31
},
896 { "umh", RELOC_U_32_47
},
900 /* Handle macros: "%macroname(expr)" */
911 while (*q
&& *p
== *q
)
919 str
= p
; /* keep the '(' */
920 this_insn
->reloc
= m
->reloc
;
925 save_in
= input_line_pointer
;
926 input_line_pointer
= str
;
928 seg
= expression (&this_insn
->reloc
[0].exp
);
929 /* XXX validate seg and exp, make sure they're reasonable */
930 expr_end
= input_line_pointer
;
931 input_line_pointer
= save_in
;
934 /* All of these should soon be changed to just emit words to the
937 emit_unaligned_io (dir
, addr_reg
, addr_offset
, reg
)
943 sprintf (buf
, "%sq_u $%d,%ld($%d)", dir
, reg
, (long) addr_offset
, addr_reg
);
948 emit_load_unal (addr_reg
, addr_offset
, reg
)
952 emit_unaligned_io ("ld", addr_reg
, addr_offset
, reg
);
956 emit_store_unal (addr_reg
, addr_offset
, reg
)
960 emit_unaligned_io ("st", addr_reg
, addr_offset
, reg
);
964 emit_byte_manip_r (op
, in
, mask
, out
, mode
, which
)
966 int in
, mask
, out
, mode
, which
;
969 sprintf (buf
, "%s%c%c $%d,$%d,$%d", op
, mode
, which
, in
, mask
, out
);
974 emit_extract_r (in
, mask
, out
, mode
, which
)
975 int in
, mask
, out
, mode
, which
;
977 emit_byte_manip_r ("ext", in
, mask
, out
, mode
, which
);
981 emit_insert_r (in
, mask
, out
, mode
, which
)
982 int in
, mask
, out
, mode
, which
;
984 emit_byte_manip_r ("ins", in
, mask
, out
, mode
, which
);
988 emit_mask_r (in
, mask
, out
, mode
, which
)
989 int in
, mask
, out
, mode
, which
;
991 emit_byte_manip_r ("msk", in
, mask
, out
, mode
, which
);
995 emit_sign_extend (reg
, size
)
999 sprintf (buf
, "sll $%d,0x%x,$%d", reg
, 64 - size
, reg
);
1001 sprintf (buf
, "sra $%d,0x%x,$%d", reg
, 64 - size
, reg
);
1006 emit_bis_r (in1
, in2
, out
)
1010 sprintf (buf
, "bis $%d,$%d,$%d", in1
, in2
, out
);
1014 /* Note that for now, this function is called recursively (by way of
1015 calling md_assemble again). Some of the macros defined as part of
1016 the assembly language are currently rewritten as sequences of
1017 strings to be assembled. See, for example, the handling of "divq".
1019 For efficiency, this should be fixed someday. */
1021 alpha_ip (str
, insns
)
1023 struct alpha_it insns
[];
1029 struct alpha_opcode
*pattern
;
1031 unsigned int opcode
;
1033 int match
= 0, num_gen
= 1;
1037 islower (*s
) || *s
== '_' || *s
== '/' || *s
== '4' || *s
== '8';
1056 as_warn ("Unknown opcode: `%s'", str
);
1059 if ((pattern
= (struct alpha_opcode
*) hash_find (op_hash
, str
)) == NULL
)
1061 as_warn ("Unknown opcode: `%s'", str
);
1070 opcode
= pattern
->match
;
1072 memset (insns
, 0, sizeof (*insns
));
1073 for (i
= 0; i
< MAX_RELOCS
; i
++)
1074 insns
[0].reloc
[i
].code
= BFD_RELOC_NONE
;
1075 for (i
= 1; i
< MAX_INSNS
; i
++)
1076 insns
[i
] = insns
[0];
1078 /* Build the opcode, checking as we go to make sure that the
1080 for (args
= pattern
->args
;; ++args
)
1085 case '\0': /* end of args */
1104 case '(': /* these must match exactly */
1113 case '1': /* next operand must be a register */
1123 case 'a': /* $at: as temporary */
1129 case 'g': /* $gp: base register */
1132 mask
= base_register
;
1135 case 's': /* $sp: stack pointer */
1142 case 'r': /* any register */
1143 if (!isdigit (c
= *s
++))
1160 if ((c
= 10 * (c
- '0') + (*s
++ - '0')) >= 32)
1169 if ((c
== GP
) && first_32bit_quadrant
)
1179 /* Got the register, now figure out where it goes in
1187 opcode
|= mask
<< SA
;
1192 opcode
|= mask
<< SB
;
1201 opcode
|= (mask
<< SA
) | mask
;
1204 case 'R': /* ra and rb are the same */
1205 opcode
|= (mask
<< SA
) | (mask
<< SB
);
1209 opcode
|= (mask
<< SA
) | (mask
<< SB
) | (mask
);
1215 case 'e': /* next operand is a floating point register */
1219 if (*s
++ == '$' && *s
++ == 'f' && isdigit (*s
))
1224 mask
= 10 * (mask
- '0') + (*s
++ - '0');
1235 /* same encoding as gp registers */
1241 case 'h': /* bits 16..31 */
1242 insns
[0].reloc
= RELOC_16_31
;
1246 case 'l': /* bits 0..15 */
1247 insns
[0].reloc
[0].code
= BFD_RELOC_16
;
1250 case 'L': /* 21 bit PC relative immediate */
1251 insns
[0].reloc
[0].code
= BFD_RELOC_23_PCREL_S2
;
1252 insns
[0].reloc
[0].pcrel
= 1;
1255 case 'i': /* 14 bit immediate */
1256 if (OPCODE (opcode
) != 0x1a)
1257 /* Not a jmp variant?? */
1259 else if (opcode
& 0x8000)
1260 /* ret or jsr_coroutine */
1262 insns
[0].reloc
[0].code
= BFD_RELOC_14
;
1263 insns
[0].reloc
[0].pcrel
= 0;
1268 insns
[0].reloc
[0].code
= BFD_RELOC_ALPHA_HINT
;
1269 insns
[0].reloc
[0].pcrel
= 1;
1273 case 'b': /* 8 bit immediate */
1274 insns
[0].reloc
[0].code
= BFD_RELOC_8
;
1277 case 'I': /* 26 bit immediate, for PALcode */
1278 insns
[0].reloc
[0].code
= BFD_RELOC_26
;
1282 case 't': /* 12 bit 0...11 */
1283 insns
[0].reloc
= RELOC_0_12
;
1286 case '8': /* 8 bit 0...7 */
1287 insns
[0].reloc
= RELOC_0_8
;
1290 case 'I': /* 26 bit immediate */
1291 insns
[0].reloc
= RELOC_0_25
;
1302 getExpression (s
, &insns
[0]);
1304 /* Handle overflow in certain instructions by converting
1305 to other instructions. */
1306 if (insns
[0].reloc
[0].code
== BFD_RELOC_8
1307 && insns
[0].reloc
[0].exp
.X_op
== O_constant
1308 && (insns
[0].reloc
[0].exp
.X_add_number
< 0
1309 || insns
[0].reloc
[0].exp
.X_add_number
> 0xff))
1311 if (OPCODE (opcode
) == 0x10
1312 && (OP_FCN (opcode
) == 0x00 /* addl */
1313 || OP_FCN (opcode
) == 0x40 /* addl/v */
1314 || OP_FCN (opcode
) == 0x20 /* addq */
1315 || OP_FCN (opcode
) == 0x60 /* addq/v */
1316 || OP_FCN (opcode
) == 0x09 /* subl */
1317 || OP_FCN (opcode
) == 0x49 /* subl/v */
1318 || OP_FCN (opcode
) == 0x29 /* subq */
1319 || OP_FCN (opcode
) == 0x69 /* subq/v */
1320 || OP_FCN (opcode
) == 0x02 /* s4addl */
1321 || OP_FCN (opcode
) == 0x22 /* s4addq */
1322 || OP_FCN (opcode
) == 0x0b /* s4subl */
1323 || OP_FCN (opcode
) == 0x2b /* s4subq */
1324 || OP_FCN (opcode
) == 0x12 /* s8addl */
1325 || OP_FCN (opcode
) == 0x32 /* s8addq */
1326 || OP_FCN (opcode
) == 0x1b /* s8subl */
1327 || OP_FCN (opcode
) == 0x3b /* s8subq */
1329 /* Can we make it fit by negating? */
1330 && -insns
[0].reloc
[0].exp
.X_add_number
< 0xff
1331 && -insns
[0].reloc
[0].exp
.X_add_number
> 0)
1333 opcode
^= 0x120; /* convert add<=>sub */
1334 insns
[0].reloc
[0].exp
.X_add_number
*= -1;
1336 else if (at_ok
&& macro_ok
)
1338 /* Constant value supplied, but it's too large. */
1341 sprint_value (buf
, insns
[0].reloc
[0].exp
.X_add_number
);
1342 sprintf (expansion
, "lda $%d,%s($%d)", AT
, buf
, ZERO
);
1343 md_assemble (expansion
);
1344 opcode
|= 0x1000 /* use reg */ | (AT
<< SB
);
1345 insns
[0].reloc
[0].code
= BFD_RELOC_NONE
;
1348 as_bad ("overflow in 8-bit literal field in `operate' format insn");
1354 int format
, length
, mode
, i
;
1355 char temp
[20 /*MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT*/];
1357 static const char formats
[4] = "FGfd";
1358 bfd_vma bits
, offset
;
1359 char *old_input_line_pointer
= input_line_pointer
;
1361 input_line_pointer
= s
;
1363 memset (temp
, 0, sizeof (temp
));
1364 mode
= (opcode
>> 26) & 3;
1365 format
= formats
[mode
];
1366 err
= md_atof (format
, temp
, &length
);
1369 as_bad ("Bad floating literal: %s", err
);
1374 /* Generate little-endian number from byte sequence. */
1376 for (i
= length
- 1; i
>= 0; i
--)
1377 bits
+= ((bfd_vma
)(temp
[i
] & 0xff)) << (i
* 8);
1382 offset
= get_lit8_offset (bits
) - 0x8000;
1383 insns
[0].reloc
[0].exp
.X_add_symbol
= lit8_sym
;
1384 insns
[0].reloc
[0].exp
.X_add_number
= 0x8000;
1387 offset
= get_lit4_offset (bits
) - 0x8000;
1388 insns
[0].reloc
[0].exp
.X_add_symbol
= lit4_sym
;
1389 insns
[0].reloc
[0].exp
.X_add_number
= 0x8000;
1394 insns
[0].reloc
[0].exp
.X_op
= O_symbol
;
1396 num_gen
= load_expression (AT
, &insns
[0]);
1399 insns
[num_gen
].reloc
[0].code
= BFD_RELOC_ALPHA_LITUSE
;
1400 insns
[num_gen
].reloc
[0].exp
= lituse_basereg
;
1403 insns
[num_gen
++].opcode
= opcode
| (AT
<< SB
) | offset
;
1404 opcode
= insns
[0].opcode
;
1405 s
= input_line_pointer
;
1406 input_line_pointer
= old_input_line_pointer
;
1410 /* The following two.. take advantage of the fact that
1411 opcode already contains most of what we need to know.
1412 We just prepend to the instr an "ldah
1413 $r,%ml(expr)($base)" and turn this one (done later
1414 after we return) into something like "stq
1415 $r,%lo(expr)(at)" or "ldq $r,%lo(expr)($r)".
1417 NOTE: This can fail later on at link time if the
1418 offset from $base actually turns out to be more than
1419 2**31 or 2**47 if use_large_offsets is set. */
1420 case 'P': /* Addressing macros: PUT */
1421 mask
= AT
; /* register 'at' */
1424 case 'G': /* Addressing macros: GET */
1425 /* All it is missing is the expression, which is what we
1430 getExpression (s
, &insns
[0]);
1433 /* Must check for "lda ..,number" too */
1434 if (insns
[0].reloc
[0].exp
.X_op
== O_big
)
1436 as_warn ("Sorry, not yet. Put bignums in .data section yourself.");
1439 if (insns
[0].reloc
[0].exp
.X_op
== O_constant
)
1441 /* This only handles 32bit numbers */
1442 register int val
= insns
[0].reloc
[0].exp
.X_add_number
;
1443 register short sval
;
1445 insns
[0].reloc
[0].code
= BFD_RELOC_NONE
;
1446 insns
[1].reloc
[0].code
= BFD_RELOC_NONE
;
1449 if ((sval
!= val
) && (val
& 0x8000))
1455 if (optnum
&& (sval
== val
))
1457 /* optimize away the ldah */
1459 opcode
|= (ZERO
<< SB
) | (val
& 0xffff);
1464 insns
[1].opcode
= opcode
| (mask
<< SB
) | (val
& 0xffff);
1465 opcode
= 0x24000000 /*ldah*/ |
1466 mask
<< SA
| (ZERO
<< SB
) |
1467 ((val
>> 16) & 0xffff);
1470 else if (insns
[0].reloc
[0].exp
.X_op
== O_symbol
)
1472 unsigned long old_opcode
= opcode
;
1476 as_bad ("insn requires expansion but `nomacro' specified");
1477 else if (*args
== 'G')
1480 as_bad ("insn expansion requires AT use, but `noat' specified");
1483 num_gen
= load_expression (tmp_reg
, insns
);
1484 opcode
= insns
[0].opcode
;
1485 /* lda is opcode 8, 0x20000000, and the macros that use
1486 this code have an opcode field of 0. The latter
1487 require further processing, and we don't have the
1488 true opcode here. */
1489 if (OPCODE (old_opcode
) != 0
1490 && OPCODE (old_opcode
) != 0x08)
1493 i
= &insns
[num_gen
++];
1494 i
->opcode
= old_opcode
| (tmp_reg
<< SB
);
1498 i
->reloc
[0].code
= BFD_RELOC_ALPHA_LITUSE
;
1499 i
->reloc
[0].exp
= lituse_basereg
;
1508 insns
[1].reloc
[0].exp
= insns
[0].reloc
[0].exp
;
1510 /* Generate: ldah REG,x1(GP); OP ?,x0(REG) */
1512 abort (); /* relocs need fixing */
1514 insns
[1].reloc
= RELOC_0_15
;
1515 insns
[1].opcode
= opcode
| mask
<< SB
;
1517 insns
[0].reloc
= RELOC_16_31
;
1518 opcode
= 0x24000000 /*ldah*/ | mask
<< SA
| (base_register
<< SB
);
1524 /* Same failure modes as above, actually most of the
1525 same code shared. */
1526 case 'B': /* Builtins */
1531 case 'a': /* ldgp */
1533 if (first_32bit_quadrant
|| no_mixed_code
)
1535 switch (OUTPUT_FLAVOR
)
1537 case bfd_target_aout_flavour
:
1538 /* this is cmu's a.out version */
1539 insns
[0].reloc
[0].code
= BFD_RELOC_NONE
;
1540 /* generate "zap %r,0xf,%r" to take high 32 bits */
1541 opcode
|= 0x48001600 /* zap ?,#,?*/ | (0xf << SN
);
1543 case bfd_target_ecoff_flavour
:
1544 /* Given "ldgp R1,N(R2)", turn it into something
1545 like "ldah R1,###(R2) ; lda R1,###(R1)" with
1546 appropriate constants and relocations. */
1548 unsigned long r1
, r2
;
1549 unsigned long addend
= 0;
1554 insns
[0].reloc
[0].code
= BFD_RELOC_ALPHA_GPDISP_HI16
;
1555 insns
[0].reloc
[0].pcrel
= 1;
1556 insns
[0].reloc
[0].exp
.X_op
= O_symbol
;
1557 insns
[0].reloc
[0].exp
.X_add_symbol
= gp
;
1558 insns
[0].reloc
[0].exp
.X_add_number
= 0;
1559 insns
[0].opcode
= (0x24000000 /* ldah */
1562 insns
[1].reloc
[0].code
= BFD_RELOC_ALPHA_GPDISP_LO16
;
1563 insns
[1].reloc
[0].exp
.X_op
= O_symbol
;
1564 insns
[1].reloc
[0].exp
.X_add_symbol
= gp
;
1565 insns
[1].reloc
[0].exp
.X_add_number
= 4;
1566 insns
[1].reloc
[0].pcrel
= 1;
1567 insns
[1].opcode
= 0x20000000 | (r1
<< SA
) | (r1
<< SB
);
1568 opcode
= insns
[0].opcode
;
1569 /* merge in addend */
1570 insns
[1].opcode
|= addend
& 0xffff;
1571 insns
[0].opcode
|= ((addend
>> 16)
1572 + (addend
& 0x8000 ? 1 : 0));
1574 ecoff_set_gp_prolog_size (0);
1583 case 'b': /* setgp */
1584 switch (OUTPUT_FLAVOR
)
1586 case bfd_target_aout_flavour
:
1587 /* generate "zap %r,0xf,$gp" to take high 32 bits */
1588 opcode
|= 0x48001600 /* zap ?,#,?*/
1589 | (0xf << SN
) | (base_register
);
1596 case 'c': /* jsr $r,foo becomes
1599 Register 27, t12, is used by convention
1602 struct alpha_it
*jsr
;
1604 struct reloc_data
*r
;
1606 /* We still have to parse the function name */
1609 getExpression (s
, &insns
[0]);
1610 etmp
= insns
[0].reloc
[0].exp
;
1612 num_gen
= load_expression (PV
, &insns
[0]);
1615 jsr
= &insns
[num_gen
++];
1616 jsr
->opcode
= (0x68004000 /* jsr */
1622 /* LITUSE wasn't emitted yet */
1623 jsr
->reloc
[0].code
= BFD_RELOC_ALPHA_LITUSE
;
1624 jsr
->reloc
[0].exp
= lituse_jsr
;
1631 r
->code
= BFD_RELOC_ALPHA_HINT
;
1633 opcode
= insns
[0].opcode
;
1638 /* Sub-word loads and stores. We load the address into
1639 $at, which might involve using the `P' parameter
1640 processing too, then emit a sequence to get the job
1641 done, using unaligned memory accesses and byte
1642 manipulation, with t9 and t10 as temporaries. */
1644 /* Characteristics of access. */
1645 int is_load
, is_unsigned
= 0, is_unaligned
= 0;
1646 int mode_size
, mode
;
1647 /* Register operand. */
1649 /* Addend for loads and stores. */
1651 /* Which register do we use for the address? */
1655 /* Pick apart name and set flags. */
1656 const char *s
= pattern
->name
;
1664 if (s
[0] == 'l' && s
[1] == 'd')
1666 else if (s
[0] == 's' && s
[1] == 't')
1669 as_fatal ("unrecognized sub-word access insn `%s'",
1674 if (mode
== 'b') mode_size
= 1;
1675 else if (mode
== 'w') mode_size
= 2;
1676 else if (mode
== 'l') mode_size
= 4;
1677 else if (mode
== 'q') mode_size
= 8;
1688 /* Longwords are always kept sign-extended. */
1689 if (mode
== 'l' && is_unsigned
)
1691 /* There's no special unaligned byte handling. */
1692 if (mode
== 'b' && is_unaligned
)
1694 /* Stores don't care about signedness. */
1695 if (!is_load
&& is_unsigned
)
1699 if (args
[-2] == 'P')
1708 r1 -> (opcode >> SA) & 31
1709 num -> insns->reloc[0].*
1711 We want to emit "lda at,num(r2)", since these
1712 operations require the use of a single register
1713 with the starting address of the memory operand
1716 We could probably get away without doing this
1717 (and use r2 below, with the addend for the
1718 actual reads and writes) in cases where the
1719 addend is known to be a multiple of 8. */
1721 int r1
= (opcode
>> SA
) & 31;
1723 if (insns
[0].reloc
[0].code
== BFD_RELOC_NONE
)
1725 else if (insns
[0].reloc
[0].code
== BFD_RELOC_16
)
1727 if (insns
[0].reloc
[0].exp
.X_op
!= O_constant
)
1729 addend
= insns
[0].reloc
[0].exp
.X_add_number
;
1734 if (addend
+ mode_size
- 1 < 0x7fff
1735 && (addend
% 8) == 0
1736 && (r2
< T9
|| r2
> T12
))
1743 /* Let later relocation processing deal
1744 with the addend field. */
1745 insns
[num_gen
-1].opcode
= (0x20000000 /* lda */
1754 /* Because the emit_* routines append directly to
1755 the current frag, we now need to flush any
1759 for (i
= 0; i
< num_gen
; i
++)
1760 emit_insn (&insns
[i
]);
1769 reg2
= T9
, reg3
= T10
;
1773 emit_load_unal (addr
, addend
, T9
);
1775 emit_load_unal (addr
, addend
+ mode_size
- 1, T10
);
1776 emit_extract_r (T9
, addr
, reg2
, mode
, 'l');
1779 emit_extract_r (T10
, addr
, reg3
, mode
, 'h');
1780 emit_bis_r (T9
, T10
, reg
);
1783 emit_sign_extend (reg
, mode_size
* 8);
1787 /* The second word gets processed first
1788 because if the address does turn out to be
1789 aligned, the processing for the second word
1790 will be pushing around all-zeros, and the
1791 entire value will be handled as the `first'
1792 word. So we want to store the `first' word
1794 /* Pair these up so that the memory loads get
1795 separated from each other, as well as being
1796 well in advance of the uses of the values
1800 emit_load_unal (addr
, addend
+ mode_size
- 1, T11
);
1801 emit_insert_r (reg
, addr
, T12
, mode
, 'h');
1803 emit_load_unal (addr
, addend
, T9
);
1804 emit_insert_r (reg
, addr
, T10
, mode
, 'l');
1806 emit_mask_r (T12
, addr
, T12
, mode
, 'h');
1807 emit_mask_r (T10
, addr
, T10
, mode
, 'l');
1809 emit_bis_r (T11
, T12
, T11
);
1810 emit_bis_r (T9
, T10
, T9
);
1812 emit_store_unal (addr
, addend
+ mode_size
- 1, T11
);
1813 emit_store_unal (addr
, addend
, T9
);
1818 /* DIVISION and MODULUS. Yech.
1819 Convert OP x,y,result
1825 with appropriate optimizations if t10,t11,t12
1826 are the registers specified by the compiler.
1827 We are missing an obvious optimization
1828 opportunity here; if the ldq generated by the
1829 jsr assembly requires a cycle or two to make
1830 the value available, initiating it before one
1831 or two of the mov instructions would result in
1832 faster execution. */
1833 case '0': /* reml */
1834 case '1': /* divl */
1835 case '2': /* remq */
1836 case '3': /* divq */
1837 case '4': /* remlu */
1838 case '5': /* divlu */
1839 case '6': /* remqu */
1840 case '7': /* divqu */
1842 static char func
[8][6] = {
1843 "reml", "divl", "remq", "divq",
1844 "remlu", "divlu", "remqu", "divqu"
1849 /* All regs parsed, in opcode */
1851 /* Do the expansions, one instr at a time */
1853 reg
= (opcode
>> SA
) & 31;
1857 sprintf (expansion
, "mov $%d,$%d", reg
, T10
);
1858 md_assemble (expansion
);
1860 reg
= (opcode
>> SB
) & 31;
1862 /* we already overwrote it! */
1864 else if (reg
!= T11
)
1867 sprintf (expansion
, "mov $%d,$%d", reg
, T11
);
1868 md_assemble (expansion
);
1870 sprintf (expansion
, "lda $%d,__%s", PV
, func
[*args
- '0']);
1871 md_assemble (expansion
);
1872 sprintf (expansion
, "jsr $%d,($%d),__%s", T9
, PV
,
1874 md_assemble (expansion
);
1876 if (!first_32bit_quadrant
)
1881 md_assemble (expansion
);
1884 sprintf (expansion
, "ldgp $%d,0($%d)",
1886 md_assemble (expansion
);
1888 /* Use insns[0] to get at the result */
1889 if ((reg
= (opcode
& 31)) != PV
)
1890 opcode
= (0x47e00400 /* or zero,zero,zero */
1892 | reg
/* Rc */ ); /* pv->z */
1908 /* Args don't match. */
1909 if (&pattern
[1] - alpha_opcodes
< NUMOPCODES
1910 && !strcmp (pattern
->name
, pattern
[1].name
))
1918 as_warn ("Illegal operands");
1924 /* Args match, see if a float instructions and -nofloats */
1925 if (nofloats
&& pattern
->isa_float
)
1931 insns
[0].opcode
= opcode
;
1935 /* Turn a string in input_line_pointer into a floating point constant
1936 of type type, and store the appropriate bytes in *litP. The number
1937 of LITTLENUMS emitted is stored in *sizeP. An error message is
1938 returned, or NULL on OK. */
1940 /* Equal to MAX_PRECISION in atof-ieee.c */
1941 #define MAX_LITTLENUMS 6
1944 md_atof (type
, litP
, sizeP
)
1950 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
1951 LITTLENUM_TYPE
*wordP
;
1953 char *atof_ieee (), *vax_md_atof ();
1959 /* VAX md_atof doesn't like "G" for some reason. */
1963 return vax_md_atof (type
, litP
, sizeP
);
1986 return "Bad call to MD_ATOF()";
1988 t
= atof_ieee (input_line_pointer
, type
, words
);
1990 input_line_pointer
= t
;
1991 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
1993 for (wordP
= words
+ prec
- 1; prec
--;)
1995 md_number_to_chars (litP
, (long) (*wordP
--), sizeof (LITTLENUM_TYPE
));
1996 litP
+= sizeof (LITTLENUM_TYPE
);
2003 md_bignum_to_chars (buf
, bignum
, nchars
)
2005 LITTLENUM_TYPE
*bignum
;
2010 LITTLENUM_TYPE work
= *bignum
++;
2011 int nb
= CHARS_PER_LITTLENUM
;
2015 *buf
++ = work
& ((1 << BITS_PER_CHAR
) - 1);
2018 work
>>= BITS_PER_CHAR
;
2024 CONST
char *md_shortopts
= "Fm:";
2025 struct option md_longopts
[] = {
2026 #define OPTION_32ADDR (OPTION_MD_BASE)
2027 {"32addr", no_argument
, NULL
, OPTION_32ADDR
},
2028 {NULL
, no_argument
, NULL
, 0}
2030 size_t md_longopts_size
= sizeof(md_longopts
);
2033 md_parse_option (c
, arg
)
2051 if (!strcmp (arg
, "21064"))
2053 else if (!strcmp (arg
, "21066"))
2055 else if (!strcmp (arg
, "21164"))
2059 as_bad ("invalid architecture %s", arg
);
2063 if (machine
!= 0 && machine
!= mach
)
2065 as_warn ("machine type %lu already chosen, overriding with %lu",
2080 md_show_usage (stream
)
2085 -32addr treat addresses as 32-bit values\n\
2086 -F lack floating point instructions support\n\
2087 -m21064 | -m21066 | -m21164\n\
2088 specify variant of Alpha architecture\n");
2095 /* XXXX Align to cache linesize XXXXX */
2102 /* Takes ".proc name,nargs" */
2103 name
= input_line_pointer
;
2104 c
= get_symbol_end ();
2105 p
= input_line_pointer
;
2106 symbolP
= symbol_find_or_make (name
);
2109 if (*input_line_pointer
!= ',')
2112 as_warn ("Expected comma after name \"%s\"", name
);
2115 ignore_rest_of_line ();
2119 input_line_pointer
++;
2120 temp
= get_absolute_expression ();
2122 /* symbolP->sy_other = (signed char) temp; */
2123 as_warn ("unhandled: .proc %s,%d", name
, temp
);
2124 demand_empty_rest_of_line ();
2131 char *name
= input_line_pointer
, ch
, *s
;
2134 while (!is_end_of_line
[(unsigned char) *input_line_pointer
])
2135 input_line_pointer
++;
2136 ch
= *input_line_pointer
;
2137 *input_line_pointer
= '\0';
2140 if (s
[0] == 'n' && s
[1] == 'o')
2145 if (!strcmp ("reorder", s
))
2147 else if (!strcmp ("at", s
))
2149 else if (!strcmp ("macro", s
))
2152 as_warn ("Tried to set unrecognized symbol: %s", name
);
2153 *input_line_pointer
= ch
;
2154 demand_empty_rest_of_line ();
2157 /* @@ Is this right?? */
2159 md_pcrel_from (fixP
)
2162 valueT addr
= fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
2163 switch (fixP
->fx_r_type
)
2165 case BFD_RELOC_ALPHA_GPDISP_HI16
:
2166 case BFD_RELOC_ALPHA_GPDISP_LO16
:
2169 return fixP
->fx_size
+ addr
;
2174 alpha_do_align (n
, fill
)
2179 && (now_seg
== text_section
2180 || !strcmp (now_seg
->name
, ".init")
2181 || !strcmp (now_seg
->name
, ".fini")))
2183 static const unsigned char nop_pattern
[] = { 0x1f, 0x04, 0xff, 0x47 };
2184 frag_align_pattern (n
, nop_pattern
, sizeof (nop_pattern
));
2191 md_apply_fix (fixP
, valueP
)
2198 char *p
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
2202 switch (fixP
->fx_r_type
)
2204 /* The GPDISP relocations are processed internally with a symbol
2205 referring to the current function; we need to drop in a value
2206 which, when added to the address of the start of the function,
2207 gives the desired GP. */
2208 case BFD_RELOC_ALPHA_GPDISP_HI16
:
2209 case BFD_RELOC_ALPHA_GPDISP_LO16
:
2211 if (fixP
->fx_r_type
== BFD_RELOC_ALPHA_GPDISP_HI16
)
2213 assert (fixP
->fx_next
->fx_r_type
== BFD_RELOC_ALPHA_GPDISP_LO16
);
2216 fprintf_vma (stdout
, addend
);
2219 if (addend
& 0x8000)
2222 fixP
->fx_offset
= 4; /* @@ Compute this using fx_next. */
2228 fprintf_vma (stdout
, addend
);
2232 fixP
->fx_offset
= 0;
2234 md_number_to_chars (fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
,
2236 fixP
->fx_addsy
= section_symbol (absolute_section
);
2237 fixP
->fx_offset
+= fixP
->fx_frag
->fr_address
+ fixP
->fx_where
;
2241 /* Write 8 bits, shifted left 13 bit positions. */
2245 *p
|= (value
<< 5) & 0xe0;
2253 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2254 "overflow in type-%d reloc", (int) fixP
->fx_r_type
);
2264 /* Don't want overflow checking. */
2267 if (fixP
->fx_pcrel
== 0
2268 && fixP
->fx_addsy
== 0)
2270 md_number_to_chars (p
, value
, size
);
2271 /* @@ Overflow checks?? */
2277 if (fixP
->fx_addsy
!= 0
2278 && fixP
->fx_addsy
->bsym
->section
!= absolute_section
)
2279 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2280 "PALcode instructions require immediate constant function code");
2281 else if (value
>> 26 != 0)
2282 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2283 "overflow in 26-bit PALcode function field");
2284 *p
++ = value
& 0xff;
2286 *p
++ = value
& 0xff;
2288 *p
++ = value
& 0xff;
2299 if (fixP
->fx_addsy
!= 0
2300 && fixP
->fx_addsy
->bsym
->section
!= absolute_section
)
2301 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2302 "ret/jsr_coroutine requires constant in displacement field");
2303 else if (value
>> 14 != 0)
2304 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2305 "overflow in 14-bit operand field of ret or jsr_coroutine");
2306 *p
++ = value
& 0xff;
2308 *p
= (*p
& 0xc0) | (value
& 0x3f);
2311 case BFD_RELOC_23_PCREL_S2
:
2312 /* Write 21 bits only. */
2314 *p
++ = value
& 0xff;
2316 *p
++ = value
& 0xff;
2319 *p
|= (value
& 0x1f);
2322 case BFD_RELOC_ALPHA_LITERAL
:
2323 case BFD_RELOC_ALPHA_LITUSE
:
2326 case BFD_RELOC_GPREL32
:
2327 assert (fixP
->fx_subsy
== gp
);
2328 value
= - alpha_gp_value
; /* huh? this works... */
2330 md_number_to_chars (p
, value
, 4);
2333 case BFD_RELOC_ALPHA_HINT
:
2334 if (fixP
->fx_addsy
== 0 && fixP
->fx_pcrel
== 0)
2342 as_fatal ("unknown relocation type %d?", fixP
->fx_r_type
);
2346 if (fixP
->fx_addsy
== 0 && fixP
->fx_pcrel
== 0)
2348 printf ("type %d reloc done?\n", fixP
->fx_r_type
);
2358 alpha_frob_ecoff_data ()
2361 /* $zero and $f31 are read-only */
2362 alpha_gprmask
&= ~1;
2363 alpha_fprmask
&= ~1;
2366 /* The Alpha has support for some VAX floating point types, as well as for
2367 IEEE floating point. We consider IEEE to be the primary floating point
2368 format, and sneak in the VAX floating point support here. */
2369 #define md_atof vax_md_atof
2370 #include "config/atof-vax.c"