1 /* tc-alpha.c - Processor-specific code for the DEC Alpha AXP CPU.
2 Copyright (C) 1989, 93, 94, 95, 1996 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.
6 Modified by Richard Henderson for ELF support.
8 This file is part of GAS, the GNU Assembler.
10 GAS is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2, or (at your option)
15 GAS is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with GAS; see the file COPYING. If not, write to the Free
22 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
26 * Mach Operating System
27 * Copyright (c) 1993 Carnegie Mellon University
28 * All Rights Reserved.
30 * Permission to use, copy, modify and distribute this software and its
31 * documentation is hereby granted, provided that both the copyright
32 * notice and this permission notice appear in all copies of the
33 * software, derivative works or modified versions, and any portions
34 * thereof, and that both notices appear in supporting documentation.
36 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
37 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
38 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
40 * Carnegie Mellon requests users of this software to return to
42 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
43 * School of Computer Science
44 * Carnegie Mellon University
45 * Pittsburgh PA 15213-3890
47 * any improvements or extensions that they make and grant Carnegie the
48 * rights to redistribute these changes.
54 #include "opcode/alpha.h"
57 #include "elf/alpha.h"
65 #define MAX_INSN_FIXUPS 2
66 #define MAX_INSN_ARGS 5
71 bfd_reloc_code_real_type reloc
;
78 struct alpha_fixup fixups
[MAX_INSN_FIXUPS
];
83 MACRO_EOA
= 1, MACRO_IR
, MACRO_PIR
, MACRO_CPIR
, MACRO_FPR
, MACRO_EXP
89 void (*emit
) PARAMS((const expressionS
*, int, void *));
91 enum alpha_macro_arg argsets
[16];
94 /* Two extra symbols we want to see in our input. This is a blatent
95 misuse of the expressionS.X_op field. */
97 #define O_pregister (O_max+1) /* O_register, but in parentheses */
98 #define O_cpregister (O_pregister+1) /* + a leading comma */
100 /* Macros for extracting the type and number of encoded register tokens */
102 #define is_ir_num(x) (((x) & 32) == 0)
103 #define is_fpr_num(x) (((x) & 32) != 0)
104 #define regno(x) ((x) & 31)
106 /* Something odd inherited from the old assembler */
108 #define note_gpreg(R) (alpha_gprmask |= (1 << (R)))
109 #define note_fpreg(R) (alpha_fprmask |= (1 << (R)))
111 /* Predicates for 16- and 32-bit ranges */
113 #define range_signed_16(x) ((offsetT)(x) >= -(offsetT)0x8000 && \
114 (offsetT)(x) <= (offsetT)0x7FFF)
115 #define range_signed_32(x) ((offsetT)(x) >= -(offsetT)0x80000000 && \
116 (offsetT)(x) <= (offsetT)0x7FFFFFFF)
118 /* Macros for sign extending from 16- and 32-bits. */
119 /* XXX: The cast macros will work on all the systems that I care about,
120 but really a predicate should be found to use the non-cast forms. */
123 #define sign_extend_16(x) ((short)(x))
124 #define sign_extend_32(x) ((int)(x))
126 #define sign_extend_16(x) ((offsetT)(((x) & 0xFFFF) ^ 0x8000) - 0x8000)
127 #define sign_extend_32(x) ((offsetT)(((x) & 0xFFFFFFFF) \
128 ^ 0x80000000) - 0x80000000)
131 /* Macros to build tokens */
133 #define set_tok_reg(t, r) (memset(&(t), 0, sizeof(t)), \
134 (t).X_op = O_register, \
135 (t).X_add_number = (r))
136 #define set_tok_preg(t, r) (memset(&(t), 0, sizeof(t)), \
137 (t).X_op = O_pregister, \
138 (t).X_add_number = (r))
139 #define set_tok_cpreg(t, r) (memset(&(t), 0, sizeof(t)), \
140 (t).X_op = O_cpregister, \
141 (t).X_add_number = (r))
142 #define set_tok_freg(t, r) (memset(&(t), 0, sizeof(t)), \
143 (t).X_op = O_register, \
144 (t).X_add_number = (r)+32)
145 #define set_tok_sym(t, s, a) (memset(&(t), 0, sizeof(t)), \
146 (t).X_op = O_symbol, \
147 (t).X_add_symbol = (s), \
148 (t).X_add_number = (a))
149 #define set_tok_const(t, n) (memset(&(t), 0, sizeof(t)), \
150 (t).X_op = O_constant, \
151 (t).X_add_number = (n))
154 /* Prototypes for all local functions */
156 static int tokenize_arguments
PARAMS((char *, expressionS
*, int));
157 static const struct alpha_opcode
*find_opcode_match
158 PARAMS((const struct alpha_opcode
*, const expressionS
*, int*, int*));
159 static const struct alpha_macro
*find_macro_match
160 PARAMS((const struct alpha_macro
*, const expressionS
*, int*));
161 static unsigned insert_operand
PARAMS((unsigned, const struct alpha_operand
*,
162 offsetT
, char *, unsigned));
163 static void assemble_insn
PARAMS((const struct alpha_opcode
*,
164 const expressionS
*, int,
165 struct alpha_insn
*));
166 static void emit_insn
PARAMS((struct alpha_insn
*));
167 static void assemble_tokens_to_insn
PARAMS((const char *, const expressionS
*,
168 int, struct alpha_insn
*));
169 static void assemble_tokens
PARAMS((const char *, const expressionS
*,
172 static int load_expression
PARAMS((int, const expressionS
*, int *,
175 static void emit_ldgp
PARAMS((const expressionS
*, int, void*));
176 static void emit_division
PARAMS((const expressionS
*, int, void*));
177 static void emit_lda
PARAMS((const expressionS
*, int, void*));
178 static void emit_ir_load
PARAMS((const expressionS
*, int, void*));
179 static void emit_loadstore
PARAMS((const expressionS
*, int, void*));
180 static void emit_jsrjmp
PARAMS((const expressionS
*, int, void*));
182 static void s_alpha_text
PARAMS((int));
183 static void s_alpha_data
PARAMS((int));
185 static void s_alpha_comm
PARAMS((int));
188 static void s_alpha_rdata
PARAMS((int));
189 static void s_alpha_sdata
PARAMS((int));
192 static void s_alpha_section
PARAMS((int));
194 static void s_alpha_gprel32
PARAMS((int));
195 static void s_alpha_float_cons
PARAMS((int));
196 static void s_alpha_proc
PARAMS((int));
197 static void s_alpha_set
PARAMS((int));
198 static void s_alpha_base
PARAMS((int));
199 static void s_alpha_align
PARAMS((int));
200 static void s_alpha_stringer
PARAMS((int));
201 static void s_alpha_space
PARAMS((int));
203 static void create_literal_section
PARAMS((const char *, segT
*, symbolS
**));
205 static void select_gp_value
PARAMS((void));
207 static void alpha_align
PARAMS((int, char *, symbolS
*));
210 /* Generic assembler global variables which must be defined by all
213 /* These are exported to relaxing code, even though we don't do any
214 relaxing on this processor currently. */
215 int md_short_jump_size
= 4;
216 int md_long_jump_size
= 4;
218 /* Characters which always start a comment. */
219 const char comment_chars
[] = "#";
221 /* Characters which start a comment at the beginning of a line. */
222 const char line_comment_chars
[] = "#";
224 /* Characters which may be used to separate multiple commands on a
226 const char line_separator_chars
[] = ";";
228 /* Characters which are used to indicate an exponent in a floating
230 const char EXP_CHARS
[] = "eE";
232 /* Characters which mean that a number is a floating point constant,
235 const char FLT_CHARS
[] = "dD";
237 /* XXX: Do all of these really get used on the alpha?? */
238 char FLT_CHARS
[] = "rRsSfFdDxXpP";
241 const char *md_shortopts
= "Fm:g";
243 struct option md_longopts
[] = {
244 #define OPTION_32ADDR (OPTION_MD_BASE)
245 { "32addr", no_argument
, NULL
, OPTION_32ADDR
},
246 { NULL
, no_argument
, NULL
, 0 }
249 size_t md_longopts_size
= sizeof(md_longopts
);
252 /* The cpu for which we are generating code */
253 static unsigned alpha_target
= AXP_OPCODE_ALL
;
254 static const char *alpha_target_name
= "<all>";
256 /* Forward declaration of the table of macros */
257 static const struct alpha_macro alpha_macros
[];
258 static const int alpha_num_macros
;
260 /* The hash table of instruction opcodes */
261 static struct hash_control
*alpha_opcode_hash
;
263 /* The hash table of macro opcodes */
264 static struct hash_control
*alpha_macro_hash
;
267 /* The $gp relocation symbol */
268 static symbolS
*alpha_gp_symbol
;
270 /* XXX: what is this, and why is it exported? */
271 valueT alpha_gp_value
;
274 /* The current $gp register */
275 static int alpha_gp_register
= AXP_REG_GP
;
277 /* A table of the register symbols */
278 static symbolS
*alpha_register_table
[64];
280 /* Constant sections, or sections of constants */
282 static segT alpha_lita_section
;
283 static segT alpha_lit4_section
;
285 static segT alpha_lit8_section
;
287 /* Symbols referring to said sections. */
289 static symbolS
*alpha_lita_symbol
;
290 static symbolS
*alpha_lit4_symbol
;
292 static symbolS
*alpha_lit8_symbol
;
294 /* Is the assembler not allowed to use $at? */
295 static int alpha_noat_on
= 0;
297 /* Are macros enabled? */
298 static int alpha_macros_on
= 1;
300 /* Are floats disabled? */
301 static int alpha_nofloats_on
= 0;
303 /* Are addresses 32 bit? */
304 static int alpha_addr32_on
= 0;
306 /* Symbol labelling the current insn. When the Alpha gas sees
309 and the section happens to not be on an eight byte boundary, it
310 will align both the symbol and the .quad to an eight byte boundary. */
311 static symbolS
*alpha_insn_label
;
313 /* Whether we should automatically align data generation pseudo-ops.
314 .align 0 will turn this off. */
315 static int alpha_auto_align_on
= 1;
317 /* The known current alignment of the current section. */
318 static int alpha_current_align
;
320 /* These are exported to ECOFF code. */
321 unsigned long alpha_gprmask
, alpha_fprmask
;
324 /* Public interface functions */
326 /* This function is called once, at assembler startup time. It sets
327 up all the tables, etc. that the MD part of the assembler will
328 need, that can be determined before arguments are parsed. */
335 /* Create the opcode hash table */
337 alpha_opcode_hash
= hash_new ();
338 for (i
= 0; i
< alpha_num_opcodes
; )
340 const char *name
, *retval
;
342 name
= alpha_opcodes
[i
].name
;
343 retval
= hash_insert (alpha_opcode_hash
, name
, (PTR
)&alpha_opcodes
[i
]);
345 as_fatal ("internal error: can't hash opcode `%s': %s", name
, retval
);
347 while (++i
< alpha_num_opcodes
348 && (alpha_opcodes
[i
].name
== name
349 || !strcmp (alpha_opcodes
[i
].name
, name
)))
353 /* Some opcodes include modifiers of various sorts with a "/mod" syntax,
354 like the architecture manual suggests. However, for use with gcc at
355 least, we also need access to those same opcodes without the "/". */
356 for (i
= 0; i
< alpha_num_opcodes
; )
358 const char *name
, *slash
;
359 name
= alpha_opcodes
[i
].name
;
360 if ((slash
= strchr(name
, '/')) != NULL
)
362 char *p
= xmalloc (strlen (name
));
363 memcpy(p
, name
, slash
-name
);
364 strcpy(p
+(slash
-name
), slash
+1);
366 (void)hash_insert(alpha_opcode_hash
, p
, (PTR
)&alpha_opcodes
[i
]);
367 /* Ignore failures -- the opcode table does duplicate some
368 variants in different forms, like "hw_stq" and "hw_st/q". */
371 while (++i
< alpha_num_opcodes
372 && (alpha_opcodes
[i
].name
== name
373 || !strcmp (alpha_opcodes
[i
].name
, name
)))
377 /* Create the macro hash table */
379 alpha_macro_hash
= hash_new ();
380 for (i
= 0; i
< alpha_num_macros
; )
382 const char *name
, *retval
;
384 name
= alpha_macros
[i
].name
;
385 retval
= hash_insert (alpha_macro_hash
, name
, (PTR
)&alpha_macros
[i
]);
387 as_fatal ("internal error: can't hash macro `%s': %s", name
, retval
);
389 while (++i
< alpha_num_macros
390 && (alpha_macros
[i
].name
== name
391 || !strcmp (alpha_macros
[i
].name
, name
)))
395 /* Construct symbols for each of the registers */
397 for (i
= 0; i
< 32; ++i
)
400 sprintf(name
, "$%d", i
);
401 alpha_register_table
[i
] = symbol_create(name
, reg_section
, i
,
407 sprintf(name
, "$f%d", i
-32);
408 alpha_register_table
[i
] = symbol_create(name
, reg_section
, i
,
412 /* Create the special symbols and sections we'll be using */
414 /* So .sbss will get used for tiny objects. */
415 bfd_set_gp_size (stdoutput
, 8);
418 create_literal_section (".lita", &alpha_lita_section
, &alpha_lita_symbol
);
420 /* For handling the GP, create a symbol that won't be output in the
421 symbol table. We'll edit it out of relocs later. */
422 alpha_gp_symbol
= symbol_create ("<GP value>", alpha_lita_section
, 0x8000,
431 sec
= subseg_new(".mdebug", (subsegT
)0);
432 bfd_set_section_flags(stdoutput
, sec
, SEC_HAS_CONTENTS
|SEC_READONLY
);
433 bfd_set_section_alignment(stdoutput
, sec
, 3);
436 sec
= subseg_new(".reginfo", (subsegT
)0);
437 /* The ABI says this section should be loaded so that the running
438 program can access it. */
439 bfd_set_section_flags(stdoutput
, sec
,
440 SEC_ALLOC
|SEC_LOAD
|SEC_READONLY
|SEC_DATA
);
441 bfd_set_section_alignement(stdoutput
, sec
, 3);
446 subseg_set(text_section
, 0);
449 /* The public interface to the instruction assembler. */
455 char opname
[32]; /* current maximum is 13 */
456 expressionS tok
[MAX_INSN_ARGS
];
457 int ntok
, opnamelen
, trunclen
;
459 /* split off the opcode */
460 opnamelen
= strspn (str
, "abcdefghijklmnopqrstuvwxyz_/48");
461 trunclen
= (opnamelen
< sizeof (opname
) - 1
463 : sizeof (opname
) - 1);
464 memcpy (opname
, str
, trunclen
);
465 opname
[trunclen
] = '\0';
467 /* tokenize the rest of the line */
468 if ((ntok
= tokenize_arguments (str
+ opnamelen
, tok
, MAX_INSN_ARGS
)) < 0)
470 as_bad ("syntax error");
475 assemble_tokens (opname
, tok
, ntok
, alpha_macros_on
);
478 /* Round up a section's size to the appropriate boundary. */
481 md_section_align (seg
, size
)
485 int align
= bfd_get_section_alignment(stdoutput
, seg
);
486 valueT mask
= ((valueT
)1 << align
) - 1;
488 return (size
+ mask
) & ~mask
;
491 /* Turn a string in input_line_pointer into a floating point constant
492 of type type, and store the appropriate bytes in *litP. The number
493 of LITTLENUMS emitted is stored in *sizeP. An error message is
494 returned, or NULL on OK. */
496 /* Equal to MAX_PRECISION in atof-ieee.c */
497 #define MAX_LITTLENUMS 6
500 md_atof (type
, litP
, sizeP
)
506 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
507 LITTLENUM_TYPE
*wordP
;
509 char *atof_ieee (), *vax_md_atof ();
515 /* VAX md_atof doesn't like "G" for some reason. */
519 return vax_md_atof (type
, litP
, sizeP
);
542 return "Bad call to MD_ATOF()";
544 t
= atof_ieee (input_line_pointer
, type
, words
);
546 input_line_pointer
= t
;
547 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
549 for (wordP
= words
+ prec
- 1; prec
--;)
551 md_number_to_chars (litP
, (long) (*wordP
--), sizeof (LITTLENUM_TYPE
));
552 litP
+= sizeof (LITTLENUM_TYPE
);
558 /* Take care of the target-specific command-line options. */
561 md_parse_option (c
, arg
)
568 alpha_nofloats_on
= 1;
576 /* Ignore `-g' so gcc can provide this option to the Digital
577 UNIX assembler, which otherwise would throw away info that
583 static const struct machine
589 { "21064", AXP_OPCODE_EV4
|AXP_OPCODE_ALL
},
590 { "21066", AXP_OPCODE_EV4
|AXP_OPCODE_ALL
},
591 { "21164", AXP_OPCODE_EV5
|AXP_OPCODE_ALL
},
592 { "21164a", AXP_OPCODE_EV56
|AXP_OPCODE_ALL
},
593 { "ev4", AXP_OPCODE_EV4
|AXP_OPCODE_ALL
},
594 { "ev45", AXP_OPCODE_EV4
|AXP_OPCODE_ALL
},
595 { "ev5", AXP_OPCODE_EV5
|AXP_OPCODE_ALL
},
596 { "ev56", AXP_OPCODE_EV56
|AXP_OPCODE_ALL
},
597 { "all", AXP_OPCODE_ALL
},
601 for (p
= m
; p
->name
; ++p
)
602 if (strcmp(arg
, p
->name
) == 0)
604 alpha_target_name
= p
->name
, alpha_target
= p
->flags
;
607 as_warn("Unknown CPU identifier `%s'", arg
);
619 /* Print a description of the command-line options that we accept. */
622 md_show_usage (stream
)
627 -32addr treat addresses as 32-bit values\n\
628 -F lack floating point instructions support\n\
629 -m21064 | -m21066 | -m21164 | -m21164a\n\
630 -mev4 | -mev45 | -mev5 | -mev56 | -mall\n\
631 specify variant of Alpha architecture\n",
635 /* Decide from what point a pc-relative relocation is relative to,
636 relative to the pc-relative fixup. Er, relatively speaking. */
642 valueT addr
= fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
643 switch (fixP
->fx_r_type
)
645 case BFD_RELOC_ALPHA_GPDISP
:
646 case BFD_RELOC_ALPHA_GPDISP_HI16
:
647 case BFD_RELOC_ALPHA_GPDISP_LO16
:
650 return fixP
->fx_size
+ addr
;
654 /* Attempt to simplify or even eliminate a fixup. The return value is
655 ignored; perhaps it was once meaningful, but now it is historical.
656 To indicate that a fixup has been eliminated, set fixP->fx_done.
658 For ELF, here it is that we transform the GPDISP_HI16 reloc we used
659 internally into the GPDISP reloc used externally. We had to do
660 this so that we'd have the GPDISP_LO16 reloc as a tag to compute
661 the distance to the "lda" instruction for setting the addend to
665 md_apply_fix (fixP
, valueP
)
669 char * const fixpos
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
670 valueT value
= *valueP
;
671 unsigned image
, size
;
673 switch (fixP
->fx_r_type
)
675 /* The GPDISP relocations are processed internally with a symbol
676 referring to the current function; we need to drop in a value
677 which, when added to the address of the start of the function,
678 gives the desired GP. */
679 case BFD_RELOC_ALPHA_GPDISP_HI16
:
681 fixS
*next
= fixP
->fx_next
;
682 assert (next
->fx_r_type
== BFD_RELOC_ALPHA_GPDISP_LO16
);
684 fixP
->fx_offset
= (next
->fx_frag
->fr_address
+ next
->fx_where
685 - fixP
->fx_frag
->fr_address
- fixP
->fx_where
);
687 value
= (value
- sign_extend_16 (value
)) >> 16;
690 fixP
->fx_r_type
= BFD_RELOC_ALPHA_GPDISP
;
694 case BFD_RELOC_ALPHA_GPDISP_LO16
:
695 value
= sign_extend_16 (value
);
702 fixP
->fx_addsy
= section_symbol (absolute_section
);
703 md_number_to_chars (fixpos
, value
, 2);
715 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
717 md_number_to_chars (fixpos
, value
, size
);
723 case BFD_RELOC_GPREL32
:
724 assert (fixP
->fx_subsy
== alpha_gp_symbol
);
726 /* FIXME: inherited this obliviousness of `value' -- why? */
727 md_number_to_chars (fixpos
, -alpha_gp_value
, 4);
731 case BFD_RELOC_GPREL32
:
735 case BFD_RELOC_23_PCREL_S2
:
736 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
738 image
= bfd_getl32(fixpos
);
739 image
= (image
& ~0x1FFFFF) | ((value
>> 2) & 0x1FFFFF);
744 case BFD_RELOC_ALPHA_HINT
:
745 if (fixP
->fx_pcrel
== 0 && fixP
->fx_addsy
== 0)
747 image
= bfd_getl32(fixpos
);
748 image
= (image
& ~0x3FFF) | ((value
>> 2) & 0x3FFF);
754 case BFD_RELOC_ALPHA_LITERAL
:
755 md_number_to_chars (fixpos
, value
, 2);
758 case BFD_RELOC_ALPHA_LITUSE
:
762 case BFD_RELOC_ALPHA_LITERAL
:
763 case BFD_RELOC_ALPHA_LITUSE
:
769 const struct alpha_operand
*operand
;
771 if (fixP
->fx_r_type
<= BFD_RELOC_UNUSED
)
772 as_fatal ("unhandled relocation type %s",
773 bfd_get_reloc_code_name (fixP
->fx_r_type
));
775 assert (fixP
->fx_r_type
< BFD_RELOC_UNUSED
+ alpha_num_operands
);
776 operand
= &alpha_operands
[fixP
->fx_r_type
- BFD_RELOC_UNUSED
];
778 /* The rest of these fixups only exist internally during symbol
779 resolution and have no representation in the object file.
780 Therefore they must be completely resolved as constants. */
782 if (fixP
->fx_addsy
!= 0
783 && fixP
->fx_addsy
->bsym
->section
!= absolute_section
)
784 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
785 "non-absolute expression in constant field");
787 image
= bfd_getl32(fixpos
);
788 image
= insert_operand(image
, operand
, (offsetT
)value
,
789 fixP
->fx_file
, fixP
->fx_line
);
794 if (fixP
->fx_addsy
!= 0 || fixP
->fx_pcrel
!= 0)
798 as_warn_where(fixP
->fx_file
, fixP
->fx_line
,
799 "type %d reloc done?\n", fixP
->fx_r_type
);
804 md_number_to_chars(fixpos
, image
, 4);
812 * Look for a register name in the given symbol.
816 md_undefined_symbol(name
)
821 int is_float
= 0, num
;
826 if (name
[1] == 'p' && name
[2] == '\0')
827 return alpha_register_table
[AXP_REG_FP
];
832 if (!isdigit(*++name
))
836 case '0': case '1': case '2': case '3': case '4':
837 case '5': case '6': case '7': case '8': case '9':
840 else if (name
[0] != '0' && isdigit(name
[1]) && name
[2] == '\0')
842 num
= (name
[0] - '0')*10 + name
[1] - '0';
849 if (!alpha_noat_on
&& num
== AXP_REG_AT
)
850 as_warn("Used $at without \".set noat\"");
851 return alpha_register_table
[num
+ is_float
];
854 if (name
[1] == 't' && name
[2] == '\0')
857 as_warn("Used $at without \".set noat\"");
858 return alpha_register_table
[AXP_REG_AT
];
863 if (name
[1] == 'p' && name
[2] == '\0')
864 return alpha_register_table
[alpha_gp_register
];
868 if (name
[1] == 'p' && name
[2] == '\0')
869 return alpha_register_table
[AXP_REG_SP
];
877 /* @@@ Magic ECOFF bits. */
880 alpha_frob_ecoff_data ()
883 /* $zero and $f31 are read-only */
889 /* Hook to remember a recently defined label so that the auto-align
890 code can adjust the symbol after we know what alignment will be
894 alpha_define_label (sym
)
897 alpha_insn_label
= sym
;
900 /* Return true if we must always emit a reloc for a type and false if
901 there is some hope of resolving it a assembly time. */
904 alpha_force_relocation (f
)
907 switch (f
->fx_r_type
)
909 case BFD_RELOC_ALPHA_GPDISP_HI16
:
910 case BFD_RELOC_ALPHA_GPDISP_LO16
:
911 case BFD_RELOC_ALPHA_GPDISP
:
912 case BFD_RELOC_ALPHA_LITERAL
:
913 case BFD_RELOC_ALPHA_LITUSE
:
914 case BFD_RELOC_GPREL32
:
917 case BFD_RELOC_23_PCREL_S2
:
920 case BFD_RELOC_ALPHA_HINT
:
924 assert(f
->fx_r_type
> BFD_RELOC_UNUSED
&&
925 f
->fx_r_type
< BFD_RELOC_UNUSED
+ alpha_num_operands
);
930 /* Return true if we can partially resolve a relocation now. */
933 alpha_fix_adjustable (f
)
937 /* Prevent all adjustments to global symbols */
938 if (S_IS_EXTERN (f
->fx_addsy
))
942 /* Are there any relocation types for which we must generate a reloc
943 but we can adjust the values contained within it? */
944 switch (f
->fx_r_type
)
946 case BFD_RELOC_GPREL32
:
949 return !alpha_force_relocation (f
);
954 /* Generate the BFD reloc to be stuck in the object file from the
955 fixup used internally in the assembler. */
958 tc_gen_reloc (sec
, fixp
)
964 reloc
= (arelent
*) bfd_alloc_by_size_t (stdoutput
, sizeof (arelent
));
965 reloc
->sym_ptr_ptr
= &fixp
->fx_addsy
->bsym
;
966 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
968 /* Make sure none of our internal relocations make it this far.
969 They'd better have been fully resolved by this point. */
970 assert (fixp
->fx_r_type
< BFD_RELOC_UNUSED
);
972 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
973 if (reloc
->howto
== NULL
)
975 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
976 "cannot represent `%s' relocation in object file",
977 bfd_get_reloc_code_name (fixp
->fx_r_type
));
981 if (!fixp
->fx_pcrel
!= !reloc
->howto
->pc_relative
)
983 as_fatal ("internal error? cannot generate `%s' relocation",
984 bfd_get_reloc_code_name (fixp
->fx_r_type
));
986 assert (!fixp
->fx_pcrel
== !reloc
->howto
->pc_relative
);
989 if (fixp
->fx_r_type
== BFD_RELOC_ALPHA_LITERAL
)
991 /* fake out bfd_perform_relocation. sigh */
992 reloc
->addend
= -alpha_gp_value
;
997 reloc
->addend
= fixp
->fx_offset
;
1000 * Ohhh, this is ugly. The problem is that if this is a local global
1001 * symbol, the relocation will entirely be performed at link time, not
1002 * at assembly time. bfd_perform_reloc doesn't know about this sort
1003 * of thing, and as a result we need to fake it out here.
1005 if (S_IS_EXTERN (fixp
->fx_addsy
) && !S_IS_COMMON(fixp
->fx_addsy
))
1006 reloc
->addend
-= fixp
->fx_addsy
->bsym
->value
;
1013 /* Parse a register name off of the input_line and return a register
1014 number. Gets md_undefined_symbol above to do the register name
1017 Only called as a part of processing the ECOFF .frame directive. */
1020 tc_get_register (frame
)
1023 int framereg
= AXP_REG_SP
;
1026 if (*input_line_pointer
== '$')
1028 char *s
= input_line_pointer
;
1029 char c
= get_symbol_end ();
1030 symbolS
*sym
= md_undefined_symbol (s
);
1032 *strchr(s
, '\0') = c
;
1033 if (sym
&& (framereg
= S_GET_VALUE (sym
)) <= 31)
1036 as_warn ("frame reg expected, using $%d.", framereg
);
1039 note_gpreg (framereg
);
1044 /* Parse the arguments to an opcode. */
1047 tokenize_arguments (str
, tok
, ntok
)
1052 expressionS
*end_tok
= tok
+ ntok
;
1053 char *old_input_line_pointer
;
1054 int saw_comma
= 0, saw_arg
= 0;
1056 memset (tok
, 0, sizeof(*tok
)*ntok
);
1058 /* Save and restore input_line_pointer around this function */
1059 old_input_line_pointer
= input_line_pointer
;
1060 input_line_pointer
= str
;
1062 while (tok
< end_tok
&& *input_line_pointer
)
1065 switch (*input_line_pointer
)
1071 ++input_line_pointer
;
1072 if (saw_comma
|| !saw_arg
)
1079 char *hold
= input_line_pointer
++;
1081 /* First try for parenthesized register ... */
1083 if (*input_line_pointer
== ')' && tok
->X_op
== O_register
)
1085 tok
->X_op
= (saw_comma
? O_cpregister
: O_pregister
);
1088 ++input_line_pointer
;
1093 /* ... then fall through to plain expression */
1094 input_line_pointer
= hold
;
1098 if (saw_arg
&& !saw_comma
)
1101 if (tok
->X_op
== O_illegal
|| tok
->X_op
== O_absent
)
1114 input_line_pointer
= old_input_line_pointer
;
1115 return ntok
- (end_tok
- tok
);
1118 input_line_pointer
= old_input_line_pointer
;
1122 /* Search forward through all variants of an opcode looking for a
1125 static const struct alpha_opcode
*
1126 find_opcode_match(first_opcode
, tok
, pntok
, pcpumatch
)
1127 const struct alpha_opcode
*first_opcode
;
1128 const expressionS
*tok
;
1132 const struct alpha_opcode
*opcode
= first_opcode
;
1134 int got_cpu_match
= 0;
1138 const unsigned char *opidx
;
1141 /* Don't match opcodes that don't exist on this architecture */
1142 if (!(opcode
->flags
& alpha_target
))
1147 for (opidx
= opcode
->operands
; *opidx
; ++opidx
)
1149 const struct alpha_operand
*operand
= &alpha_operands
[*opidx
];
1151 /* only take input from real operands */
1152 if (operand
->flags
& AXP_OPERAND_FAKE
)
1155 /* when we expect input, make sure we have it */
1158 if ((operand
->flags
& AXP_OPERAND_OPTIONAL_MASK
) == 0)
1163 /* match operand type with expression type */
1164 switch (operand
->flags
& AXP_OPERAND_TYPECHECK_MASK
)
1166 case AXP_OPERAND_IR
:
1167 if (tok
[tokidx
].X_op
!= O_register
1168 || !is_ir_num(tok
[tokidx
].X_add_number
))
1171 case AXP_OPERAND_FPR
:
1172 if (tok
[tokidx
].X_op
!= O_register
1173 || !is_fpr_num(tok
[tokidx
].X_add_number
))
1176 case AXP_OPERAND_IR
|AXP_OPERAND_PARENS
:
1177 if (tok
[tokidx
].X_op
!= O_pregister
1178 || !is_ir_num(tok
[tokidx
].X_add_number
))
1181 case AXP_OPERAND_IR
|AXP_OPERAND_PARENS
|AXP_OPERAND_COMMA
:
1182 if (tok
[tokidx
].X_op
!= O_cpregister
1183 || !is_ir_num(tok
[tokidx
].X_add_number
))
1187 case AXP_OPERAND_RELATIVE
:
1188 case AXP_OPERAND_SIGNED
:
1189 case AXP_OPERAND_UNSIGNED
:
1190 switch (tok
[tokidx
].X_op
)
1202 /* everything else should have been fake */
1208 /* possible match -- did we use all of our input? */
1217 while (++opcode
-alpha_opcodes
< alpha_num_opcodes
1218 && !strcmp(opcode
->name
, first_opcode
->name
));
1221 *pcpumatch
= got_cpu_match
;
1226 /* Search forward through all variants of a macro looking for a syntax
1229 static const struct alpha_macro
*
1230 find_macro_match(first_macro
, tok
, pntok
)
1231 const struct alpha_macro
*first_macro
;
1232 const expressionS
*tok
;
1235 const struct alpha_macro
*macro
= first_macro
;
1240 const enum alpha_macro_arg
*arg
= macro
->argsets
;
1255 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_register
1256 || !is_ir_num(tok
[tokidx
].X_add_number
))
1261 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_pregister
1262 || !is_ir_num(tok
[tokidx
].X_add_number
))
1267 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_cpregister
1268 || !is_ir_num(tok
[tokidx
].X_add_number
))
1273 if (tokidx
>= ntok
|| tok
[tokidx
].X_op
!= O_register
1274 || !is_fpr_num(tok
[tokidx
].X_add_number
))
1282 switch (tok
[tokidx
].X_op
)
1295 while (*arg
!= MACRO_EOA
)
1303 while (++macro
-alpha_macros
< alpha_num_macros
1304 && !strcmp(macro
->name
, first_macro
->name
));
1309 /* Insert an operand value into an instruction. */
1312 insert_operand(insn
, operand
, val
, file
, line
)
1314 const struct alpha_operand
*operand
;
1319 if (operand
->bits
!= 32 && !(operand
->flags
& AXP_OPERAND_NOOVERFLOW
))
1323 if (operand
->flags
& AXP_OPERAND_SIGNED
)
1325 max
= (1 << (operand
->bits
- 1)) - 1;
1326 min
= -(1 << (operand
->bits
- 1));
1330 max
= (1 << operand
->bits
) - 1;
1334 if (val
< min
|| val
> max
)
1337 "operand out of range (%s not between %d and %d)";
1338 char buf
[sizeof(val
)*3+2];
1340 sprint_value(buf
, val
);
1342 as_warn_where(file
, line
, err
, buf
, min
, max
);
1344 as_warn(err
, buf
, min
, max
);
1348 if (operand
->insert
)
1350 const char *errmsg
= NULL
;
1352 insn
= (*operand
->insert
)(insn
, val
, &errmsg
);
1357 insn
|= ((val
& ((1 << operand
->bits
) - 1)) << operand
->shift
);
1363 * Turn an opcode description and a set of arguments into
1364 * an instruction and a fixup.
1368 assemble_insn(opcode
, tok
, ntok
, insn
)
1369 const struct alpha_opcode
*opcode
;
1370 const expressionS
*tok
;
1372 struct alpha_insn
*insn
;
1374 const unsigned char *argidx
;
1378 memset(insn
, 0, sizeof(*insn
));
1379 image
= opcode
->opcode
;
1381 for (argidx
= opcode
->operands
; *argidx
; ++argidx
)
1383 const struct alpha_operand
*operand
= &alpha_operands
[*argidx
];
1384 const expressionS
*t
;
1386 if (operand
->flags
& AXP_OPERAND_FAKE
)
1388 /* fake operands take no value and generate no fixup */
1389 image
= insert_operand(image
, operand
, 0, NULL
, 0);
1395 switch (operand
->flags
& AXP_OPERAND_OPTIONAL_MASK
)
1397 case AXP_OPERAND_DEFAULT_FIRST
:
1400 case AXP_OPERAND_DEFAULT_SECOND
:
1403 case AXP_OPERAND_DEFAULT_ZERO
:
1405 static const expressionS zero_exp
= { 0, 0, 0, O_constant
, 1 };
1421 image
= insert_operand(image
, operand
, regno(t
->X_add_number
),
1426 image
= insert_operand(image
, operand
, t
->X_add_number
, NULL
, 0);
1431 struct alpha_fixup
*fixup
;
1433 if (insn
->nfixups
>= MAX_INSN_FIXUPS
)
1434 as_fatal("too many fixups");
1436 fixup
= &insn
->fixups
[insn
->nfixups
++];
1439 fixup
->reloc
= operand
->default_reloc
;
1449 * Actually output an instruction with its fixup.
1454 struct alpha_insn
*insn
;
1459 /* Take care of alignment duties */
1460 if (alpha_auto_align_on
&& alpha_current_align
< 2)
1461 alpha_align (2, (char *) NULL
, alpha_insn_label
);
1462 if (alpha_current_align
> 2)
1463 alpha_current_align
= 2;
1464 alpha_insn_label
= NULL
;
1466 /* Write out the instruction. */
1468 md_number_to_chars (f
, insn
->insn
, 4);
1470 /* Apply the fixups in order */
1471 for (i
= 0; i
< insn
->nfixups
; ++i
)
1473 struct alpha_fixup
*fixup
= &insn
->fixups
[i
];
1477 /* Some fixups are only used internally and so have no howto */
1478 if (fixup
->reloc
> BFD_RELOC_UNUSED
)
1479 size
= 4, pcrel
= 0;
1481 /* These relocation types are only used internally. */
1482 else if (fixup
->reloc
== BFD_RELOC_ALPHA_GPDISP_HI16
1483 || fixup
->reloc
== BFD_RELOC_ALPHA_GPDISP_LO16
)
1485 size
= 2, pcrel
= 0;
1490 reloc_howto_type
*reloc_howto
1491 = bfd_reloc_type_lookup (stdoutput
, fixup
->reloc
);
1492 assert (reloc_howto
);
1494 size
= bfd_get_reloc_size (reloc_howto
);
1495 pcrel
= reloc_howto
->pc_relative
;
1497 assert (size
>= 1 && size
<= 4);
1499 fixP
= fix_new_exp (frag_now
, f
- frag_now
->fr_literal
, size
,
1500 &fixup
->exp
, pcrel
, fixup
->reloc
);
1502 /* Turn off complaints that the addend is too large for some fixups */
1503 switch (fixup
->reloc
)
1505 case BFD_RELOC_ALPHA_GPDISP_LO16
:
1506 case BFD_RELOC_ALPHA_LITERAL
:
1507 case BFD_RELOC_GPREL32
:
1508 fixP
->fx_no_overflow
= 1;
1516 /* Given an opcode name and a pre-tokenized set of arguments, assemble
1517 the insn, but do not emit it.
1519 Note that this implies no macros allowed, since we can't store more
1520 than one insn in an insn structure. */
1523 assemble_tokens_to_insn(opname
, tok
, ntok
, insn
)
1525 const expressionS
*tok
;
1527 struct alpha_insn
*insn
;
1529 const struct alpha_opcode
*opcode
;
1531 /* search opcodes */
1532 opcode
= (const struct alpha_opcode
*) hash_find (alpha_opcode_hash
, opname
);
1536 opcode
= find_opcode_match (opcode
, tok
, &ntok
, &cpumatch
);
1539 assemble_insn (opcode
, tok
, ntok
, insn
);
1543 as_bad ("inappropriate arguments for opcode `%s'", opname
);
1545 as_bad ("opcode `%s' not supported for target %s", opname
,
1549 as_bad ("unknown opcode `%s'", opname
);
1552 /* Given an opcode name and a pre-tokenized set of arguments, take the
1553 opcode all the way through emission. */
1556 assemble_tokens (opname
, tok
, ntok
, local_macros_on
)
1558 const expressionS
*tok
;
1560 int local_macros_on
;
1562 int found_something
= 0;
1563 const struct alpha_opcode
*opcode
;
1564 const struct alpha_macro
*macro
;
1568 if (local_macros_on
)
1570 macro
= ((const struct alpha_macro
*)
1571 hash_find (alpha_macro_hash
, opname
));
1574 found_something
= 1;
1575 macro
= find_macro_match (macro
, tok
, &ntok
);
1578 (*macro
->emit
) (tok
, ntok
, macro
->arg
);
1584 /* search opcodes */
1585 opcode
= (const struct alpha_opcode
*) hash_find (alpha_opcode_hash
, opname
);
1588 found_something
= 1;
1589 opcode
= find_opcode_match (opcode
, tok
, &ntok
, &cpumatch
);
1592 struct alpha_insn insn
;
1593 assemble_insn (opcode
, tok
, ntok
, &insn
);
1599 if (found_something
)
1601 as_bad ("inappropriate arguments for opcode `%s'", opname
);
1603 as_bad ("opcode `%s' not supported for target %s", opname
,
1606 as_bad ("unknown opcode `%s'", opname
);
1610 /* Some instruction sets indexed by lg(size) */
1611 static const char * const sextX_op
[] = { "sextb", "sextw", "sextl", NULL
};
1612 static const char * const insXl_op
[] = { "insbl", "inswl", "insll", "insql" };
1613 static const char * const insXh_op
[] = { NULL
, "inswh", "inslh", "insqh" };
1614 static const char * const extXl_op
[] = { "extbl", "extwl", "extll", "extql" };
1615 static const char * const extXh_op
[] = { NULL
, "extwh", "extlh", "extqh" };
1616 static const char * const mskXl_op
[] = { "mskbl", "mskwl", "mskll", "mskql" };
1617 static const char * const mskXh_op
[] = { NULL
, "mskwh", "msklh", "mskqh" };
1619 /* Implement the ldgp macro. */
1622 emit_ldgp (tok
, ntok
, unused
)
1623 const expressionS
*tok
;
1630 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
1631 /* from "ldgp r1,n(r2)", generate "ldah r1,X(R2); lda r1,Y(r1)"
1632 with appropriate constants and relocations. */
1633 struct alpha_insn insn
;
1634 expressionS newtok
[3];
1637 /* We're going to need this symbol in md_apply_fix(). */
1638 (void) section_symbol (absolute_section
);
1641 if (regno (tok
[2].X_add_number
) == AXP_REG_PV
)
1642 ecoff_set_gp_prolog_size (0);
1646 set_tok_const (newtok
[1], 0);
1649 assemble_tokens_to_insn ("ldah", newtok
, 3, &insn
);
1654 assert (addend
.X_op
== O_constant
);
1655 addend
.X_op
= O_symbol
;
1656 addend
.X_add_symbol
= alpha_gp_symbol
;
1660 insn
.fixups
[0].exp
= addend
;
1661 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_GPDISP_HI16
;
1665 set_tok_preg (newtok
[2], tok
[0].X_add_number
);
1667 assemble_tokens_to_insn ("lda", newtok
, 3, &insn
);
1670 addend
.X_add_number
+= 4;
1674 insn
.fixups
[0].exp
= addend
;
1675 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_GPDISP_LO16
;
1678 #endif /* OBJ_ECOFF || OBJ_ELF */
1681 /* Load a (partial) expression into a target register.
1683 If poffset is not null, after the call it will either contain
1684 O_constant 0, or a 16-bit offset appropriate for any MEM format
1685 instruction. In addition, pbasereg will be modified to point to
1686 the base register to use in that MEM format instruction.
1688 In any case, *pbasereg should contain a base register to add to the
1689 expression. This will normally be either AXP_REG_ZERO or
1690 alpha_gp_register. Symbol addresses will always be loaded via $gp,
1691 so "foo($0)" is interpreted as adding the address of foo to $0;
1692 i.e. "ldq $targ, LIT($gp); addq $targ, $0, $targ". Odd, perhaps,
1693 but this is what OSF/1 does.
1695 Finally, the return value is true if the calling macro may emit a
1696 LITUSE reloc if otherwise appropriate. */
1699 load_expression (targreg
, exp
, pbasereg
, poffset
)
1701 const expressionS
*exp
;
1703 expressionS
*poffset
;
1705 int emit_lituse
= 0;
1706 offsetT addend
= exp
->X_add_number
;
1707 int basereg
= *pbasereg
;
1708 struct alpha_insn insn
;
1709 expressionS newtok
[3];
1718 /* attempt to reduce .lit load by splitting the offset from
1719 its symbol when possible, but don't create a situation in
1721 if (!range_signed_32 (addend
) &&
1722 (alpha_noat_on
|| targreg
== AXP_REG_AT
))
1724 lit
= add_to_literal_pool (exp
->X_add_symbol
, addend
,
1725 alpha_lita_section
, 8);
1730 lit
= add_to_literal_pool (exp
->X_add_symbol
, 0,
1731 alpha_lita_section
, 8);
1735 as_fatal ("overflow in literal (.lita) table");
1737 /* emit "ldq r, lit(gp)" */
1739 if (basereg
!= alpha_gp_register
&& targreg
== basereg
)
1742 as_bad ("macro requires $at register while noat in effect");
1743 if (targreg
== AXP_REG_AT
)
1744 as_bad ("macro requires $at while $at in use");
1746 set_tok_reg (newtok
[0], AXP_REG_AT
);
1749 set_tok_reg (newtok
[0], targreg
);
1750 set_tok_sym (newtok
[1], alpha_lita_symbol
, lit
);
1751 set_tok_preg (newtok
[2], alpha_gp_register
);
1753 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
1755 assert (insn
.nfixups
== 1);
1756 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITERAL
;
1757 #endif /* OBJ_ECOFF */
1759 /* emit "ldq r, gotoff(gp)" */
1761 if (basereg
!= alpha_gp_register
&& targreg
== basereg
)
1764 as_bad ("macro requires $at register while noat in effect");
1765 if (targreg
== AXP_REG_AT
)
1766 as_bad ("macro requires $at while $at in use");
1768 set_tok_reg (newtok
[0], AXP_REG_AT
);
1771 set_tok_reg (newtok
[0], targreg
);
1773 if (!range_signed_32 (addend
)
1774 && (alpha_noat_on
|| targreg
== AXP_REG_AT
))
1781 set_tok_sym (newtok
[1], exp
->X_add_symbol
, 0);
1784 set_tok_preg (newtok
[2], alpha_gp_register
);
1786 assemble_tokens_to_insn ("ldq", newtok
, 3, &insn
);
1788 assert (insn
.nfixups
== 1);
1789 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITERAL
;
1790 #endif /* OBJ_ELF */
1795 if (basereg
!= alpha_gp_register
&& basereg
!= AXP_REG_ZERO
)
1797 /* emit "addq r, base, r" */
1799 set_tok_reg (newtok
[1], basereg
);
1800 set_tok_reg (newtok
[2], targreg
);
1801 assemble_tokens ("addq", newtok
, 3, 0);
1812 /* Assume that this difference expression will be resolved to an
1813 absolute value and that that value will fit in 16 bits. */
1815 set_tok_reg (newtok
[0], targreg
);
1817 set_tok_preg (newtok
[2], basereg
);
1818 assemble_tokens ("lda", newtok
, 3, 0);
1821 set_tok_const (*poffset
, 0);
1828 if (!range_signed_32 (addend
))
1832 /* for 64-bit addends, just put it in the literal pool */
1834 if (alpha_lit8_section
== NULL
)
1836 create_literal_section (".lit8",
1837 &alpha_lit8_section
,
1838 &alpha_lit8_symbol
);
1841 lit
= add_to_literal_pool (NULL
, addend
, alpha_lit8_section
, 8) - 0x8000;
1843 as_fatal ("overflow in literal (.lit8) table");
1845 /* emit "ldq litreg, .lit8+lit" */
1847 if (targreg
== basereg
)
1850 as_bad ("macro requires $at register while noat in effect");
1851 if (targreg
== AXP_REG_AT
)
1852 as_bad ("macro requires $at while $at in use");
1854 set_tok_reg (newtok
[0], AXP_REG_AT
);
1857 set_tok_reg (newtok
[0], targreg
);
1858 set_tok_sym (newtok
[1], alpha_lit8_symbol
, lit
);
1860 assemble_tokens ("ldq", newtok
, 2, 1); /* note this does recurse */
1862 /* emit "addq litreg, base, target" */
1864 if (basereg
!= AXP_REG_ZERO
)
1866 set_tok_reg (newtok
[1], basereg
);
1867 set_tok_reg (newtok
[2], targreg
);
1868 assemble_tokens ("addq", newtok
, 3, 0);
1872 set_tok_const (*poffset
, 0);
1873 *pbasereg
= targreg
;
1877 offsetT low
, high
, extra
, tmp
;
1879 /* for 32-bit operands, break up the addend */
1881 low
= sign_extend_16 (addend
);
1883 high
= sign_extend_16 (tmp
>> 16);
1885 if (tmp
- (high
<< 16))
1889 high
= sign_extend_16 (tmp
>> 16);
1894 set_tok_reg (newtok
[0], targreg
);
1895 set_tok_preg (newtok
[2], basereg
);
1899 /* emit "ldah r, extra(r) */
1900 set_tok_const (newtok
[1], extra
);
1901 assemble_tokens ("ldah", newtok
, 3, 0);
1902 set_tok_preg (newtok
[2], basereg
= targreg
);
1907 /* emit "ldah r, high(r) */
1908 set_tok_const (newtok
[1], high
);
1909 assemble_tokens ("ldah", newtok
, 3, 0);
1911 set_tok_preg (newtok
[2], basereg
);
1914 if ((low
&& !poffset
) || (!poffset
&& basereg
!= targreg
))
1916 /* emit "lda r, low(base)" */
1917 set_tok_const (newtok
[1], low
);
1918 assemble_tokens ("lda", newtok
, 3, 0);
1924 set_tok_const (*poffset
, low
);
1925 *pbasereg
= basereg
;
1931 /* The lda macro differs from the lda instruction in that it handles
1932 most simple expressions, particualrly symbol address loads and
1936 emit_lda (tok
, ntok
, unused
)
1937 const expressionS
*tok
;
1944 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
1946 basereg
= tok
[2].X_add_number
;
1948 (void) load_expression (tok
[0].X_add_number
, &tok
[1], &basereg
, NULL
);
1951 /* The ldah macro differs from the ldah instruction in that it has $31
1952 as an implied base register. */
1955 emit_ldah (tok
, ntok
, unused
)
1956 const expressionS
*tok
;
1960 expressionS newtok
[3];
1964 set_tok_preg (newtok
[2], AXP_REG_ZERO
);
1966 assemble_tokens ("ldah", newtok
, 3, 0);
1969 /* Handle all "simple" integer register loads -- ldq, ldq_l, ldq_u,
1970 etc. They differ from the real instructions in that they do simple
1971 expressions like the lda macro. */
1974 emit_ir_load (tok
, ntok
, opname
)
1975 const expressionS
*tok
;
1979 int basereg
, lituse
;
1980 expressionS newtok
[3];
1981 struct alpha_insn insn
;
1984 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
1986 basereg
= tok
[2].X_add_number
;
1988 lituse
= load_expression (tok
[0].X_add_number
, &tok
[1], &basereg
,
1992 set_tok_preg (newtok
[2], basereg
);
1994 assemble_tokens_to_insn ((const char *)opname
, newtok
, 3, &insn
);
1998 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
1999 if (insn
.nfixups
> 0)
2001 memmove (&insn
.fixups
[1], &insn
.fixups
[0],
2002 sizeof(struct alpha_fixup
) * insn
.nfixups
);
2005 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITUSE
;
2006 insn
.fixups
[0].exp
.X_op
= O_constant
;
2007 insn
.fixups
[0].exp
.X_add_number
= 1;
2013 /* Handle fp register loads, and both integer and fp register stores.
2014 Again, we handle simple expressions. */
2017 emit_loadstore (tok
, ntok
, opname
)
2018 const expressionS
*tok
;
2022 int basereg
, lituse
;
2023 expressionS newtok
[3];
2024 struct alpha_insn insn
;
2027 basereg
= (tok
[1].X_op
== O_constant
? AXP_REG_ZERO
: alpha_gp_register
);
2029 basereg
= tok
[2].X_add_number
;
2031 if (tok
[1].X_op
!= O_constant
|| !range_signed_16(tok
[1].X_add_number
))
2034 as_bad ("macro requires $at register while noat in effect");
2036 lituse
= load_expression (AXP_REG_AT
, &tok
[1], &basereg
, &newtok
[1]);
2045 set_tok_preg (newtok
[2], basereg
);
2047 assemble_tokens_to_insn ((const char *)opname
, newtok
, 3, &insn
);
2051 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
2052 if (insn
.nfixups
> 0)
2054 memmove (&insn
.fixups
[1], &insn
.fixups
[0],
2055 sizeof(struct alpha_fixup
) * insn
.nfixups
);
2058 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITUSE
;
2059 insn
.fixups
[0].exp
.X_op
= O_constant
;
2060 insn
.fixups
[0].exp
.X_add_number
= 1;
2066 /* Load a half-word or byte as an unsigned value. */
2069 emit_ldXu (tok
, ntok
, vlgsize
)
2070 const expressionS
*tok
;
2074 expressionS newtok
[3];
2077 as_bad ("macro requires $at register while noat in effect");
2079 /* emit "lda $at, exp" */
2081 memcpy (newtok
, tok
, sizeof(expressionS
)*ntok
);
2082 newtok
[0].X_add_number
= AXP_REG_AT
;
2083 assemble_tokens ("lda", newtok
, ntok
, 1);
2085 /* emit "ldq_u targ, 0($at)" */
2088 set_tok_const (newtok
[1], 0);
2089 set_tok_preg (newtok
[2], AXP_REG_AT
);
2090 assemble_tokens ("ldq_u", newtok
, 3, 1);
2092 /* emit "extXl targ, $at, targ" */
2094 set_tok_reg (newtok
[1], AXP_REG_AT
);
2095 newtok
[2] = newtok
[0];
2096 assemble_tokens (extXl_op
[(long)vlgsize
], newtok
, 3, 1);
2099 /* Load a half-word or byte as a signed value. */
2102 emit_ldX (tok
, ntok
, vlgsize
)
2103 const expressionS
*tok
;
2107 emit_ldXu (tok
, ntok
, vlgsize
);
2108 assemble_tokens (sextX_op
[(long)vlgsize
], tok
, 1, 1);
2111 /* Load an integral value from an unaligned address as an unsigned
2115 emit_uldXu (tok
, ntok
, vlgsize
)
2116 const expressionS
*tok
;
2120 long lgsize
= (long)vlgsize
;
2121 expressionS newtok
[3];
2124 as_bad ("macro requires $at register while noat in effect");
2126 /* emit "lda $at, exp" */
2128 memcpy (newtok
, tok
, sizeof(expressionS
)*ntok
);
2129 newtok
[0].X_add_number
= AXP_REG_AT
;
2130 assemble_tokens ("lda", newtok
, ntok
, 1);
2132 /* emit "ldq_u $t9, 0($at)" */
2134 set_tok_reg (newtok
[0], AXP_REG_T9
);
2135 set_tok_const (newtok
[1], 0);
2136 set_tok_preg (newtok
[2], AXP_REG_AT
);
2137 assemble_tokens ("ldq_u", newtok
, 3, 1);
2139 /* emit "ldq_u $t10, size-1($at)" */
2141 set_tok_reg (newtok
[0], AXP_REG_T10
);
2142 set_tok_const (newtok
[1], (1<<lgsize
)-1);
2143 assemble_tokens ("ldq_u", newtok
, 3, 1);
2145 /* emit "extXl $t9, $at, $t9" */
2147 set_tok_reg (newtok
[0], AXP_REG_T9
);
2148 set_tok_reg (newtok
[1], AXP_REG_AT
);
2149 set_tok_reg (newtok
[2], AXP_REG_T9
);
2150 assemble_tokens (extXl_op
[lgsize
], newtok
, 3, 1);
2152 /* emit "extXh $t10, $at, $t10" */
2154 set_tok_reg (newtok
[0], AXP_REG_T10
);
2155 set_tok_reg (newtok
[2], AXP_REG_T10
);
2156 assemble_tokens (extXh_op
[lgsize
], newtok
, 3, 1);
2158 /* emit "or $t9, $t10, targ" */
2160 set_tok_reg (newtok
[0], AXP_REG_T9
);
2161 set_tok_reg (newtok
[1], AXP_REG_T10
);
2163 assemble_tokens ("or", newtok
, 3, 1);
2166 /* Load an integral value from an unaligned address as a signed value.
2167 Note that quads should get funneled to the unsigned load since we
2168 don't have to do the sign extension. */
2171 emit_uldX (tok
, ntok
, vlgsize
)
2172 const expressionS
*tok
;
2176 emit_uldXu (tok
, ntok
, vlgsize
);
2177 assemble_tokens (sextX_op
[(long)vlgsize
], tok
, 1, 1);
2180 /* Implement the ldil macro. */
2183 emit_ldil (tok
, ntok
, unused
)
2184 const expressionS
*tok
;
2188 expressionS newtok
[2];
2190 memcpy (newtok
, tok
, sizeof(newtok
));
2191 newtok
[1].X_add_number
= sign_extend_32 (tok
[1].X_add_number
);
2193 assemble_tokens ("lda", newtok
, ntok
, 1);
2196 /* Store a half-word or byte. */
2199 emit_stX (tok
, ntok
, vlgsize
)
2200 const expressionS
*tok
;
2203 int lgsize
= (int)(long)vlgsize
;
2204 expressionS newtok
[3];
2207 as_bad("macro requires $at register while noat in effect");
2209 /* emit "lda $at, exp" */
2211 memcpy (newtok
, tok
, sizeof(expressionS
)*ntok
);
2212 newtok
[0].X_add_number
= AXP_REG_AT
;
2213 assemble_tokens ("lda", newtok
, ntok
, 1);
2215 /* emit "ldq_u $t9, 0($at)" */
2217 set_tok_reg (newtok
[0], AXP_REG_T9
);
2218 set_tok_const (newtok
[1], 0);
2219 set_tok_preg (newtok
[2], AXP_REG_AT
);
2220 assemble_tokens ("ldq_u", newtok
, 3, 1);
2222 /* emit "insXl src, $at, $t10" */
2225 set_tok_reg (newtok
[1], AXP_REG_AT
);
2226 set_tok_reg (newtok
[2], AXP_REG_T10
);
2227 assemble_tokens (insXl_op
[lgsize
], newtok
, 3, 1);
2229 /* emit "mskXl $t9, $at, $t9" */
2231 set_tok_reg (newtok
[0], AXP_REG_T9
);
2232 newtok
[2] = newtok
[0];
2233 assemble_tokens (mskXl_op
[lgsize
], newtok
, 3, 1);
2235 /* emit "or $t9, $t10, $t9" */
2237 set_tok_reg (newtok
[1], AXP_REG_T10
);
2238 assemble_tokens ("or", newtok
, 3, 1);
2240 /* emit "stq_u $t9, 0($at) */
2242 set_tok_const (newtok
[1], 0);
2243 set_tok_preg (newtok
[2], AXP_REG_AT
);
2244 assemble_tokens ("stq_u", newtok
, 3, 1);
2247 /* Store an integer to an unaligned address. */
2250 emit_ustX (tok
, ntok
, vlgsize
)
2251 const expressionS
*tok
;
2255 int lgsize
= (int)(long)vlgsize
;
2256 expressionS newtok
[3];
2258 /* emit "lda $at, exp" */
2260 memcpy (newtok
, tok
, sizeof(expressionS
)*ntok
);
2261 newtok
[0].X_add_number
= AXP_REG_AT
;
2262 assemble_tokens ("lda", newtok
, ntok
, 1);
2264 /* emit "ldq_u $9, 0($at)" */
2266 set_tok_reg (newtok
[0], AXP_REG_T9
);
2267 set_tok_const (newtok
[1], 0);
2268 set_tok_preg (newtok
[2], AXP_REG_AT
);
2269 assemble_tokens ("ldq_u", newtok
, 3, 1);
2271 /* emit "ldq_u $10, size-1($at)" */
2273 set_tok_reg (newtok
[0], AXP_REG_T10
);
2274 set_tok_const (newtok
[1], (1 << lgsize
)-1);
2275 assemble_tokens ("ldq_u", newtok
, 3, 1);
2277 /* emit "insXl src, $at, $t11" */
2280 set_tok_reg (newtok
[1], AXP_REG_AT
);
2281 set_tok_reg (newtok
[2], AXP_REG_T11
);
2282 assemble_tokens (insXl_op
[lgsize
], newtok
, 3, 1);
2284 /* emit "insXh src, $at, $t12" */
2286 set_tok_reg (newtok
[2], AXP_REG_T12
);
2287 assemble_tokens (insXh_op
[lgsize
], newtok
, 3, 1);
2289 /* emit "mskXl $t9, $at, $t9" */
2291 set_tok_reg (newtok
[0], AXP_REG_T9
);
2292 newtok
[2] = newtok
[0];
2293 assemble_tokens (mskXl_op
[lgsize
], newtok
, 3, 1);
2295 /* emit "mskXh $t10, $at, $t10" */
2297 set_tok_reg (newtok
[0], AXP_REG_T10
);
2298 newtok
[2] = newtok
[0];
2299 assemble_tokens (mskXh_op
[lgsize
], newtok
, 3, 1);
2301 /* emit "or $t9, $t11, $t9" */
2303 set_tok_reg (newtok
[0], AXP_REG_T9
);
2304 set_tok_reg (newtok
[1], AXP_REG_T11
);
2305 newtok
[2] = newtok
[0];
2306 assemble_tokens ("or", newtok
, 3, 1);
2308 /* emit "or $t10, $t12, $t10" */
2310 set_tok_reg (newtok
[0], AXP_REG_T10
);
2311 set_tok_reg (newtok
[1], AXP_REG_T12
);
2312 newtok
[2] = newtok
[0];
2313 assemble_tokens ("or", newtok
, 3, 1);
2315 /* emit "stq_u $t9, 0($at)" */
2317 set_tok_reg (newtok
[0], AXP_REG_T9
);
2318 set_tok_const (newtok
[1], 0);
2319 set_tok_preg (newtok
[2], AXP_REG_AT
);
2320 assemble_tokens ("stq_u", newtok
, 3, 1);
2322 /* emit "stq_u $t10, size-1($at)" */
2324 set_tok_reg (newtok
[0], AXP_REG_T10
);
2325 set_tok_const (newtok
[1], (1 << lgsize
)-1);
2326 assemble_tokens ("stq_u", newtok
, 3, 1);
2329 /* Sign extend a half-word or byte. The 32-bit sign extend is
2330 implemented as "addl $31, $r, $t" in the opcode table. */
2333 emit_sextX (tok
, ntok
, vlgsize
)
2334 const expressionS
*tok
;
2338 int bitshift
= 64 - 8*(1 << (long)vlgsize
);
2339 expressionS newtok
[3];
2341 /* emit "sll src,bits,dst" */
2344 set_tok_const (newtok
[1], bitshift
);
2345 newtok
[2] = tok
[ntok
- 1];
2346 assemble_tokens ("sll", newtok
, 3, 1);
2348 /* emit "sra dst,bits,dst" */
2350 newtok
[0] = newtok
[2];
2351 assemble_tokens ("sra", newtok
, 3, 1);
2354 /* Implement the division and modulus macros. */
2357 emit_division (tok
, ntok
, symname
)
2358 const expressionS
*tok
;
2362 /* DIVISION and MODULUS. Yech.
2372 * with appropriate optimizations if t10,t11,t12 are the registers
2373 * specified by the compiler.
2378 expressionS newtok
[3];
2380 xr
= regno (tok
[0].X_add_number
);
2381 yr
= regno (tok
[1].X_add_number
);
2386 rr
= regno (tok
[2].X_add_number
);
2388 sym
= symbol_find_or_make ((const char *)symname
);
2390 /* Move the operands into the right place */
2391 if (yr
== AXP_REG_T10
&& xr
== AXP_REG_T11
)
2393 /* They are in exactly the wrong order -- swap through AT */
2396 as_bad ("macro requires $at register while noat in effect");
2398 set_tok_reg (newtok
[0], AXP_REG_T10
);
2399 set_tok_reg (newtok
[1], AXP_REG_AT
);
2400 assemble_tokens ("mov", newtok
, 2, 1);
2402 set_tok_reg (newtok
[0], AXP_REG_T11
);
2403 set_tok_reg (newtok
[1], AXP_REG_T10
);
2404 assemble_tokens ("mov", newtok
, 2, 1);
2406 set_tok_reg (newtok
[0], AXP_REG_AT
);
2407 set_tok_reg (newtok
[1], AXP_REG_T11
);
2408 assemble_tokens ("mov", newtok
, 2, 1);
2412 if (yr
== AXP_REG_T10
)
2414 set_tok_reg (newtok
[0], AXP_REG_T10
);
2415 set_tok_reg (newtok
[1], AXP_REG_T11
);
2416 assemble_tokens ("mov", newtok
, 2, 1);
2419 if (xr
!= AXP_REG_T10
)
2421 set_tok_reg (newtok
[0], xr
);
2422 set_tok_reg (newtok
[1], AXP_REG_T10
);
2423 assemble_tokens ("mov", newtok
, 2, 1);
2426 if (yr
!= AXP_REG_T10
&& yr
!= AXP_REG_T11
)
2428 set_tok_reg (newtok
[0], yr
);
2429 set_tok_reg (newtok
[1], AXP_REG_T11
);
2430 assemble_tokens ("mov", newtok
, 2, 1);
2434 /* Call the division routine */
2435 set_tok_reg (newtok
[0], AXP_REG_T9
);
2436 set_tok_sym (newtok
[1], sym
, 0);
2437 assemble_tokens ("jsr", newtok
, 2, 1);
2439 /* Reload the GP register */
2443 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
2444 set_tok_reg (newtok
[0], alpha_gp_register
);
2445 set_tok_const (newtok
[1], 0);
2446 set_tok_preg (newtok
[2], AXP_REG_T9
);
2447 assemble_tokens ("ldgp", newtok
, 3, 1);
2450 /* Move the result to the right place */
2451 if (rr
!= AXP_REG_T12
)
2453 set_tok_reg (newtok
[0], AXP_REG_T12
);
2454 set_tok_reg (newtok
[1], rr
);
2455 assemble_tokens ("mov", newtok
, 2, 1);
2459 /* The jsr and jmp macros differ from their instruction counterparts
2460 in that they can load the target address and default most
2464 emit_jsrjmp (tok
, ntok
, vopname
)
2465 const expressionS
*tok
;
2469 const char *opname
= (const char *) vopname
;
2470 struct alpha_insn insn
;
2471 expressionS newtok
[3];
2472 int r
, tokidx
= 0, lituse
= 0;
2474 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_register
)
2475 r
= regno (tok
[tokidx
++].X_add_number
);
2477 r
= strcmp (opname
, "jmp") == 0 ? AXP_REG_ZERO
: AXP_REG_RA
;
2479 set_tok_reg (newtok
[0], r
);
2481 if (tokidx
< ntok
&&
2482 (tok
[tokidx
].X_op
== O_pregister
|| tok
[tokidx
].X_op
== O_cpregister
))
2483 r
= regno (tok
[tokidx
++].X_add_number
);
2486 int basereg
= alpha_gp_register
;
2487 lituse
= load_expression (r
= AXP_REG_PV
, &tok
[tokidx
], &basereg
, NULL
);
2490 set_tok_cpreg (newtok
[1], r
);
2493 newtok
[2] = tok
[tokidx
];
2495 set_tok_const (newtok
[2], 0);
2497 assemble_tokens_to_insn (opname
, newtok
, 3, &insn
);
2499 /* add the LITUSE fixup */
2502 assert (insn
.nfixups
< MAX_INSN_FIXUPS
);
2503 if (insn
.nfixups
> 0)
2505 memmove (&insn
.fixups
[1], &insn
.fixups
[0],
2506 sizeof(struct alpha_fixup
) * insn
.nfixups
);
2509 insn
.fixups
[0].reloc
= BFD_RELOC_ALPHA_LITUSE
;
2510 insn
.fixups
[0].exp
.X_op
= O_constant
;
2511 insn
.fixups
[0].exp
.X_add_number
= 3;
2517 /* The ret and jcr instructions differ from their instruction
2518 counterparts in that everything can be defaulted. */
2521 emit_retjcr (tok
, ntok
, vopname
)
2522 const expressionS
*tok
;
2526 const char *opname
= (const char *)vopname
;
2527 expressionS newtok
[3];
2530 if (tokidx
< ntok
&& tok
[tokidx
].X_op
== O_register
)
2531 r
= regno (tok
[tokidx
++].X_add_number
);
2535 set_tok_reg (newtok
[0], r
);
2537 if (tokidx
< ntok
&&
2538 (tok
[tokidx
].X_op
== O_pregister
|| tok
[tokidx
].X_op
== O_cpregister
))
2539 r
= regno (tok
[tokidx
++].X_add_number
);
2543 set_tok_cpreg (newtok
[1], r
);
2546 newtok
[2] = tok
[tokidx
];
2548 set_tok_const (newtok
[2], strcmp(opname
, "ret") == 0);
2550 assemble_tokens (opname
, newtok
, 3, 0);
2553 /* Assembler directives */
2555 /* Handle the .text pseudo-op. This is like the usual one, but it
2556 clears alpha_insn_label and restores auto alignment. */
2564 alpha_insn_label
= NULL
;
2565 alpha_auto_align_on
= 1;
2566 alpha_current_align
= 0;
2569 /* Handle the .data pseudo-op. This is like the usual one, but it
2570 clears alpha_insn_label and restores auto alignment. */
2577 alpha_insn_label
= NULL
;
2578 alpha_auto_align_on
= 1;
2579 alpha_current_align
= 0;
2584 /* Handle the OSF/1 .comm pseudo quirks. */
2587 s_alpha_comm (ignore
)
2590 register char *name
;
2594 register symbolS
*symbolP
;
2596 name
= input_line_pointer
;
2597 c
= get_symbol_end ();
2599 /* just after name is now '\0' */
2600 p
= input_line_pointer
;
2605 /* Alpha OSF/1 compiler doesn't provide the comma, gcc does. */
2606 if (*input_line_pointer
== ',')
2608 input_line_pointer
++;
2611 if ((temp
= get_absolute_expression ()) < 0)
2613 as_warn (".COMMon length (%ld.) <0! Ignored.", (long) temp
);
2614 ignore_rest_of_line ();
2619 symbolP
= symbol_find_or_make (name
);
2622 if (S_IS_DEFINED (symbolP
))
2624 as_bad ("Ignoring attempt to re-define symbol");
2625 ignore_rest_of_line ();
2628 if (S_GET_VALUE (symbolP
))
2630 if (S_GET_VALUE (symbolP
) != (valueT
) temp
)
2631 as_bad ("Length of .comm \"%s\" is already %ld. Not changed to %ld.",
2632 S_GET_NAME (symbolP
),
2633 (long) S_GET_VALUE (symbolP
),
2638 S_SET_VALUE (symbolP
, (valueT
) temp
);
2639 S_SET_EXTERNAL (symbolP
);
2642 know (symbolP
->sy_frag
== &zero_address_frag
);
2643 demand_empty_rest_of_line ();
2646 #endif /* ! OBJ_ELF */
2650 /* Handle the .rdata pseudo-op. This is like the usual one, but it
2651 clears alpha_insn_label and restores auto alignment. */
2654 s_alpha_rdata (ignore
)
2659 temp
= get_absolute_expression ();
2660 subseg_new (".rdata", 0);
2661 demand_empty_rest_of_line ();
2662 alpha_insn_label
= NULL
;
2663 alpha_auto_align_on
= 1;
2664 alpha_current_align
= 0;
2667 /* Handle the .sdata pseudo-op. This is like the usual one, but it
2668 clears alpha_insn_label and restores auto alignment. */
2671 s_alpha_sdata (ignore
)
2676 temp
= get_absolute_expression ();
2677 subseg_new (".sdata", 0);
2678 demand_empty_rest_of_line ();
2679 alpha_insn_label
= NULL
;
2680 alpha_auto_align_on
= 1;
2681 alpha_current_align
= 0;
2687 /* Handle the .section pseudo-op. This is like the usual one, but it
2688 clears alpha_insn_label and restores auto alignment. */
2691 s_alpha_section (ignore
)
2694 obj_elf_section (ignore
);
2696 alpha_insn_label
= NULL
;
2697 alpha_auto_align_on
= 1;
2698 alpha_current_align
= 0;
2703 /* Handle the .gprel32 pseudo op. */
2706 s_alpha_gprel32 (ignore
)
2719 e
.X_add_symbol
= section_symbol(absolute_section
);
2731 e
.X_add_symbol
= section_symbol (absolute_section
);
2734 e
.X_op
= O_subtract
;
2735 e
.X_op_symbol
= alpha_gp_symbol
;
2742 if (alpha_auto_align_on
&& alpha_current_align
< 2)
2743 alpha_align (2, (char *) NULL
, alpha_insn_label
);
2744 if (alpha_current_align
> 2)
2745 alpha_current_align
= 2;
2746 alpha_insn_label
= NULL
;
2750 fix_new_exp (frag_now
, p
-frag_now
->fr_literal
, 4,
2751 &e
, 0, BFD_RELOC_GPREL32
);
2754 /* Handle floating point allocation pseudo-ops. This is like the
2755 generic vresion, but it makes sure the current label, if any, is
2756 correctly aligned. */
2759 s_alpha_float_cons (type
)
2786 if (alpha_auto_align_on
&& alpha_current_align
< log_size
)
2787 alpha_align (log_size
, (char *) NULL
, alpha_insn_label
);
2788 if (alpha_current_align
> log_size
)
2789 alpha_current_align
= log_size
;
2790 alpha_insn_label
= NULL
;
2795 /* Handle the .proc pseudo op. We don't really do much with it except
2799 s_alpha_proc (is_static
)
2808 /* Takes ".proc name,nargs" */
2809 name
= input_line_pointer
;
2810 c
= get_symbol_end ();
2811 p
= input_line_pointer
;
2812 symbolP
= symbol_find_or_make (name
);
2815 if (*input_line_pointer
!= ',')
2818 as_warn ("Expected comma after name \"%s\"", name
);
2821 ignore_rest_of_line ();
2825 input_line_pointer
++;
2826 temp
= get_absolute_expression ();
2828 /* symbolP->sy_other = (signed char) temp; */
2829 as_warn ("unhandled: .proc %s,%d", name
, temp
);
2830 demand_empty_rest_of_line ();
2833 /* Handle the .set pseudo op. This is used to turn on and off most of
2834 the assembler features. */
2840 char *name
= input_line_pointer
, ch
, *s
;
2843 while (!is_end_of_line
[(unsigned char) *input_line_pointer
])
2844 input_line_pointer
++;
2845 ch
= *input_line_pointer
;
2846 *input_line_pointer
= '\0';
2849 if (s
[0] == 'n' && s
[1] == 'o')
2854 if (!strcmp ("reorder", s
))
2856 else if (!strcmp ("at", s
))
2857 alpha_noat_on
= !yesno
;
2858 else if (!strcmp ("macro", s
))
2859 alpha_macros_on
= yesno
;
2860 else if (!strcmp ("move", s
))
2862 else if (!strcmp ("volatile", s
))
2865 as_warn ("Tried to .set unrecognized mode `%s'", name
);
2867 *input_line_pointer
= ch
;
2868 demand_empty_rest_of_line ();
2871 /* Handle the .base pseudo op. This changes the assembler's notion of
2872 the $gp register. */
2875 s_alpha_base (ignore
)
2879 if (first_32bit_quadrant
)
2881 /* not fatal, but it might not work in the end */
2882 as_warn ("File overrides no-base-register option.");
2883 first_32bit_quadrant
= 0;
2888 if (*input_line_pointer
== '$')
2890 input_line_pointer
++;
2891 if (*input_line_pointer
== 'r')
2892 input_line_pointer
++;
2895 alpha_gp_register
= get_absolute_expression ();
2896 if (alpha_gp_register
< 0 || alpha_gp_register
> 31)
2898 alpha_gp_register
= AXP_REG_GP
;
2899 as_warn ("Bad base register, using $%d.", alpha_gp_register
);
2902 demand_empty_rest_of_line ();
2905 /* Handle the .align pseudo-op. This aligns to a power of two. It
2906 also adjusts any current instruction label. We treat this the same
2907 way the MIPS port does: .align 0 turns off auto alignment. */
2910 s_alpha_align (ignore
)
2915 long max_alignment
= 15;
2917 align
= get_absolute_expression ();
2918 if (align
> max_alignment
)
2920 align
= max_alignment
;
2921 as_bad ("Alignment too large: %d. assumed", align
);
2925 as_warn ("Alignment negative: 0 assumed");
2929 if (*input_line_pointer
== ',')
2931 input_line_pointer
++;
2932 fill
= get_absolute_expression ();
2940 alpha_auto_align_on
= 1;
2941 alpha_align (align
, pfill
, alpha_insn_label
);
2945 alpha_auto_align_on
= 0;
2948 demand_empty_rest_of_line ();
2951 /* Hook the normal string processor to reset known alignment. */
2954 s_alpha_stringer (terminate
)
2957 alpha_current_align
= 0;
2958 alpha_insn_label
= NULL
;
2959 stringer (terminate
);
2962 /* Hook the normal space processing to reset known alignment. */
2965 s_alpha_space (ignore
)
2968 alpha_current_align
= 0;
2969 alpha_insn_label
= NULL
;
2973 /* Hook into cons for auto-alignment. */
2976 alpha_cons_align (size
)
2982 while ((size
>>= 1) != 0)
2985 if (alpha_auto_align_on
&& alpha_current_align
< log_size
)
2986 alpha_align (log_size
, (char *) NULL
, alpha_insn_label
);
2987 if (alpha_current_align
> log_size
)
2988 alpha_current_align
= log_size
;
2989 alpha_insn_label
= NULL
;
2992 /* The macro table */
2994 const struct alpha_macro alpha_macros
[] = {
2995 /* Load/Store macros */
2996 { "lda", emit_lda
, NULL
,
2997 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
2998 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
2999 { "ldah", emit_ldah
, NULL
,
3000 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
3002 { "ldl", emit_ir_load
, "ldl",
3003 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
3004 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
3005 { "ldl_l", emit_ir_load
, "ldl_l",
3006 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
3007 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
3008 { "ldq", emit_ir_load
, "ldq",
3009 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
3010 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
3011 { "ldq_l", emit_ir_load
, "ldq_l",
3012 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
3013 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
3014 { "ldq_u", emit_ir_load
, "ldq_u",
3015 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
3016 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
3017 { "ldf", emit_loadstore
, "ldf",
3018 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
3019 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
3020 { "ldg", emit_loadstore
, "ldg",
3021 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
3022 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
3023 { "lds", emit_loadstore
, "lds",
3024 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
3025 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
3026 { "ldt", emit_loadstore
, "ldt",
3027 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
3028 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
3030 { "ldb", emit_ldX
, (void *)0,
3031 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
3032 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
3033 { "ldbu", emit_ldXu
, (void *)0,
3034 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
3035 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
3036 { "ldw", emit_ldX
, (void *)1,
3037 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
3038 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
3039 { "ldwu", emit_ldXu
, (void *)1,
3040 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
3041 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
3043 { "uldw", emit_uldX
, (void*)1,
3044 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
3045 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
3046 { "uldwu", emit_uldXu
, (void*)1,
3047 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
3048 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
3049 { "uldl", emit_uldX
, (void*)2,
3050 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
3051 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
3052 { "uldlu", emit_uldXu
, (void*)2,
3053 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
3054 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
3055 { "uldq", emit_uldXu
, (void*)3,
3056 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
3057 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
3059 { "ldgp", emit_ldgp
, NULL
,
3060 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
} },
3062 { "ldi", emit_lda
, NULL
,
3063 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
3064 { "ldil", emit_ldil
, NULL
,
3065 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
3066 { "ldiq", emit_lda
, NULL
,
3067 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
3069 { "ldif" emit_ldiq
, NULL
,
3070 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
3071 { "ldid" emit_ldiq
, NULL
,
3072 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
3073 { "ldig" emit_ldiq
, NULL
,
3074 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
3075 { "ldis" emit_ldiq
, NULL
,
3076 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
3077 { "ldit" emit_ldiq
, NULL
,
3078 { MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
3081 { "stl", emit_loadstore
, "stl",
3082 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
3083 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
3084 { "stl_c", emit_loadstore
, "stl_c",
3085 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
3086 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
3087 { "stq", emit_loadstore
, "stq",
3088 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
3089 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
3090 { "stq_c", emit_loadstore
, "stq_c",
3091 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
3092 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
3093 { "stq_u", emit_loadstore
, "stq_u",
3094 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
3095 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
3096 { "stf", emit_loadstore
, "stf",
3097 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
3098 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
3099 { "stg", emit_loadstore
, "stg",
3100 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
3101 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
3102 { "sts", emit_loadstore
, "sts",
3103 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
3104 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
3105 { "stt", emit_loadstore
, "stt",
3106 { MACRO_FPR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
3107 MACRO_FPR
, MACRO_EXP
, MACRO_EOA
} },
3109 { "stb", emit_stX
, (void*)0,
3110 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
3111 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
3112 { "stw", emit_stX
, (void*)1,
3113 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
3114 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
3115 { "ustw", emit_ustX
, (void*)1,
3116 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
3117 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
3118 { "ustl", emit_ustX
, (void*)2,
3119 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
3120 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
3121 { "ustq", emit_ustX
, (void*)3,
3122 { MACRO_IR
, MACRO_EXP
, MACRO_PIR
, MACRO_EOA
,
3123 MACRO_IR
, MACRO_EXP
, MACRO_EOA
} },
3125 /* Arithmetic macros */
3127 { "absl" emit_absl
, 1, { IR
} },
3128 { "absl" emit_absl
, 2, { IR
, IR
} },
3129 { "absl" emit_absl
, 2, { EXP
, IR
} },
3130 { "absq" emit_absq
, 1, { IR
} },
3131 { "absq" emit_absq
, 2, { IR
, IR
} },
3132 { "absq" emit_absq
, 2, { EXP
, IR
} },
3135 { "sextb", emit_sextX
, (void *)0,
3136 { MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3137 MACRO_IR
, MACRO_EOA
,
3138 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
3139 { "sextw", emit_sextX
, (void *)1,
3140 { MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3141 MACRO_IR
, MACRO_EOA
,
3142 /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
3144 { "divl", emit_division
, "__divl",
3145 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3146 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3147 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
3148 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
3149 { "divlu", emit_division
, "__divlu",
3150 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3151 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3152 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
3153 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
3154 { "divq", emit_division
, "__divq",
3155 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3156 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3157 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
3158 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
3159 { "divqu", emit_division
, "__divqu",
3160 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3161 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3162 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
3163 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
3164 { "reml", emit_division
, "__reml",
3165 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3166 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3167 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
3168 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
3169 { "remlu", emit_division
, "__remlu",
3170 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3171 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3172 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
3173 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
3174 { "remq", emit_division
, "__remq",
3175 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3176 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3177 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
3178 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
3179 { "remqu", emit_division
, "__remqu",
3180 { MACRO_IR
, MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3181 MACRO_IR
, MACRO_IR
, MACRO_EOA
,
3182 /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
3183 MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
3185 { "jsr", emit_jsrjmp
, "jsr",
3186 { MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
3187 MACRO_PIR
, MACRO_EOA
,
3188 MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
3189 MACRO_EXP
, MACRO_EOA
} },
3190 { "jmp", emit_jsrjmp
, "jmp",
3191 { MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
3192 MACRO_PIR
, MACRO_EOA
,
3193 MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
3194 MACRO_EXP
, MACRO_EOA
} },
3195 { "ret", emit_retjcr
, "ret",
3196 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
3197 MACRO_IR
, MACRO_EOA
,
3198 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
3199 MACRO_PIR
, MACRO_EOA
,
3200 MACRO_EXP
, MACRO_EOA
,
3202 { "jcr", emit_retjcr
, "jcr",
3203 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
3204 MACRO_IR
, MACRO_EOA
,
3205 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
3206 MACRO_PIR
, MACRO_EOA
,
3207 MACRO_EXP
, MACRO_EOA
,
3209 { "jsr_coroutine", emit_retjcr
, "jcr",
3210 { MACRO_IR
, MACRO_EXP
, MACRO_EOA
,
3211 MACRO_IR
, MACRO_EOA
,
3212 MACRO_PIR
, MACRO_EXP
, MACRO_EOA
,
3213 MACRO_PIR
, MACRO_EOA
,
3214 MACRO_EXP
, MACRO_EOA
,
3218 static const int alpha_num_macros
3219 = sizeof(alpha_macros
) / sizeof(*alpha_macros
);
3221 /* The target specific pseudo-ops which we support. */
3223 const pseudo_typeS md_pseudo_table
[] =
3225 {"common", s_comm
, 0}, /* is this used? */
3227 {"comm", s_alpha_comm
, 0}, /* osf1 compiler does this */
3229 {"text", s_alpha_text
, 0},
3230 {"data", s_alpha_data
, 0},
3232 {"rdata", s_alpha_rdata
, 0},
3233 {"sdata", s_alpha_sdata
, 0},
3236 {"section", s_alpha_section
, 0},
3237 {"section.s", s_alpha_section
, 0},
3238 {"sect", s_alpha_section
, 0},
3239 {"sect.s", s_alpha_section
, 0},
3241 {"gprel32", s_alpha_gprel32
, 0},
3242 {"t_floating", s_alpha_float_cons
, 'd'},
3243 {"s_floating", s_alpha_float_cons
, 'f'},
3244 {"f_floating", s_alpha_float_cons
, 'F'},
3245 {"g_floating", s_alpha_float_cons
, 'G'},
3246 {"d_floating", s_alpha_float_cons
, 'D'},
3248 {"proc", s_alpha_proc
, 0},
3249 {"aproc", s_alpha_proc
, 1},
3250 {"set", s_alpha_set
, 0},
3251 {"reguse", s_ignore
, 0},
3252 {"livereg", s_ignore
, 0},
3253 {"base", s_alpha_base
, 0}, /*??*/
3254 {"option", s_ignore
, 0},
3255 {"prologue", s_ignore
, 0},
3256 {"aent", s_ignore
, 0},
3257 {"ugen", s_ignore
, 0},
3258 {"eflag", s_ignore
, 0},
3260 {"align", s_alpha_align
, 0},
3261 {"double", s_alpha_float_cons
, 'd'},
3262 {"float", s_alpha_float_cons
, 'f'},
3263 {"single", s_alpha_float_cons
, 'f'},
3264 {"ascii", s_alpha_stringer
, 0},
3265 {"asciz", s_alpha_stringer
, 1},
3266 {"string", s_alpha_stringer
, 1},
3267 {"space", s_alpha_space
, 0},
3268 {"skip", s_alpha_space
, 0},
3269 {"zero", s_alpha_space
, 0},
3271 /* We don't do any optimizing, so we can safely ignore these. */
3272 {"noalias", s_ignore
, 0},
3273 {"alias", s_ignore
, 0},
3279 /* Build a BFD section with its flags set appropriately for the .lita,
3280 .lit8, or .lit4 sections. */
3283 create_literal_section (name
, secp
, symp
)
3288 segT current_section
= now_seg
;
3289 int current_subsec
= now_subseg
;
3292 *secp
= new_sec
= subseg_new (name
, 0);
3293 subseg_set (current_section
, current_subsec
);
3294 bfd_set_section_alignment (stdoutput
, new_sec
, 4);
3295 bfd_set_section_flags (stdoutput
, new_sec
,
3296 SEC_RELOC
| SEC_ALLOC
| SEC_LOAD
| SEC_READONLY
3299 S_CLEAR_EXTERNAL (*symp
= section_symbol (new_sec
));
3304 /* @@@ GP selection voodoo. All of this seems overly complicated and
3305 unnecessary; which is the primary reason I nixed it for ELF. */
3314 vma
= bfd_get_section_vma (foo
, sec
);
3315 if (vma
&& vma
< alpha_gp_value
)
3316 alpha_gp_value
= vma
;
3322 assert (alpha_gp_value
== 0);
3324 /* Get minus-one in whatever width... */
3325 alpha_gp_value
= 0; alpha_gp_value
--;
3327 /* Select the smallest VMA of these existing sections. */
3328 maybe_set_gp (alpha_lita_section
);
3330 /* These were disabled before -- should we use them? */
3331 maybe_set_gp (sdata
);
3332 maybe_set_gp (lit8_sec
);
3333 maybe_set_gp (lit4_sec
);
3336 /* @@ Will a simple 0x8000 work here? If not, why not? */
3337 #define GP_ADJUSTMENT (0x8000 - 0x10)
3339 alpha_gp_value
+= GP_ADJUSTMENT
;
3341 S_SET_VALUE (alpha_gp_symbol
, alpha_gp_value
);
3344 printf ("Chose GP value of %lx\n", alpha_gp_value
);
3347 #endif /* !OBJ_ELF */
3349 /* Called internally to handle all alignment needs. This takes care
3350 of eliding calls to frag_align if'n the cached current alignment
3351 says we've already got it, as well as taking care of the auto-align
3352 feature wrt labels. */
3355 alpha_align (n
, pfill
, label
)
3360 if (alpha_current_align
>= n
)
3366 && (bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
) != 0)
3368 static char const nop
[4] = { 0x1f, 0x04, 0xff, 0x47 };
3370 /* First, make sure we're on a four-byte boundary, in case
3371 someone has been putting .byte values into the text
3372 section. The DEC assembler silently fills with unaligned
3373 no-op instructions. This will zero-fill, then nop-fill
3374 with proper alignment. */
3375 if (alpha_current_align
< 2)
3377 frag_align_pattern (n
, nop
, sizeof nop
);
3383 frag_align (n
, *pfill
);
3385 alpha_current_align
= n
;
3389 assert (S_GET_SEGMENT (label
) == now_seg
);
3390 label
->sy_frag
= frag_now
;
3391 S_SET_VALUE (label
, (valueT
) frag_now_fix ());
3394 record_alignment(now_seg
, n
);
3397 /* The Alpha has support for some VAX floating point types, as well as for
3398 IEEE floating point. We consider IEEE to be the primary floating point
3399 format, and sneak in the VAX floating point support here. */
3400 #define md_atof vax_md_atof
3401 #include "config/atof-vax.c"