Home | History | Annotate | Line # | Download | only in config
tc-alpha.c revision 1.2
      1  1.1  skrll /* tc-alpha.c - Processor-specific code for the DEC Alpha AXP CPU.
      2  1.1  skrll    Copyright 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
      3  1.1  skrll    2001, 2002, 2003, 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
      4  1.1  skrll    Contributed by Carnegie Mellon University, 1993.
      5  1.1  skrll    Written by Alessandro Forin, based on earlier gas-1.38 target CPU files.
      6  1.1  skrll    Modified by Ken Raeburn for gas-2.x and ECOFF support.
      7  1.1  skrll    Modified by Richard Henderson for ELF support.
      8  1.1  skrll    Modified by Klaus K"ampf for EVAX (OpenVMS/Alpha) support.
      9  1.1  skrll 
     10  1.1  skrll    This file is part of GAS, the GNU Assembler.
     11  1.1  skrll 
     12  1.1  skrll    GAS is free software; you can redistribute it and/or modify
     13  1.1  skrll    it under the terms of the GNU General Public License as published by
     14  1.1  skrll    the Free Software Foundation; either version 3, or (at your option)
     15  1.1  skrll    any later version.
     16  1.1  skrll 
     17  1.1  skrll    GAS is distributed in the hope that it will be useful,
     18  1.1  skrll    but WITHOUT ANY WARRANTY; without even the implied warranty of
     19  1.1  skrll    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     20  1.1  skrll    GNU General Public License for more details.
     21  1.1  skrll 
     22  1.1  skrll    You should have received a copy of the GNU General Public License
     23  1.1  skrll    along with GAS; see the file COPYING.  If not, write to the Free
     24  1.1  skrll    Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
     25  1.1  skrll    02110-1301, USA.  */
     26  1.1  skrll 
     27  1.1  skrll /* Mach Operating System
     28  1.1  skrll    Copyright (c) 1993 Carnegie Mellon University
     29  1.1  skrll    All Rights Reserved.
     30  1.1  skrll 
     31  1.1  skrll    Permission to use, copy, modify and distribute this software and its
     32  1.1  skrll    documentation is hereby granted, provided that both the copyright
     33  1.1  skrll    notice and this permission notice appear in all copies of the
     34  1.1  skrll    software, derivative works or modified versions, and any portions
     35  1.1  skrll    thereof, and that both notices appear in supporting documentation.
     36  1.1  skrll 
     37  1.1  skrll    CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
     38  1.1  skrll    CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
     39  1.1  skrll    ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
     40  1.1  skrll 
     41  1.1  skrll    Carnegie Mellon requests users of this software to return to
     42  1.1  skrll 
     43  1.1  skrll     Software Distribution Coordinator  or  Software.Distribution (at) CS.CMU.EDU
     44  1.1  skrll     School of Computer Science
     45  1.1  skrll     Carnegie Mellon University
     46  1.1  skrll     Pittsburgh PA 15213-3890
     47  1.1  skrll 
     48  1.1  skrll    any improvements or extensions that they make and grant Carnegie the
     49  1.1  skrll    rights to redistribute these changes.  */
     50  1.1  skrll 
     51  1.1  skrll #include "as.h"
     52  1.1  skrll #include "subsegs.h"
     53  1.1  skrll #include "struc-symbol.h"
     54  1.1  skrll #include "ecoff.h"
     55  1.1  skrll 
     56  1.1  skrll #include "opcode/alpha.h"
     57  1.1  skrll 
     58  1.1  skrll #ifdef OBJ_ELF
     59  1.1  skrll #include "elf/alpha.h"
     60  1.1  skrll #include "dwarf2dbg.h"
     61  1.1  skrll #endif
     62  1.1  skrll 
     63  1.1  skrll #include "dw2gencfi.h"
     64  1.1  skrll #include "safe-ctype.h"
     65  1.1  skrll 
     66  1.1  skrll /* Local types.  */
     68  1.1  skrll 
     69  1.1  skrll #define TOKENIZE_ERROR 		-1
     70  1.1  skrll #define TOKENIZE_ERROR_REPORT	-2
     71  1.1  skrll #define MAX_INSN_FIXUPS		 2
     72  1.1  skrll #define MAX_INSN_ARGS		 5
     73  1.1  skrll 
     74  1.1  skrll struct alpha_fixup
     75  1.1  skrll {
     76  1.1  skrll   expressionS exp;
     77  1.1  skrll   bfd_reloc_code_real_type reloc;
     78  1.1  skrll };
     79  1.1  skrll 
     80  1.1  skrll struct alpha_insn
     81  1.1  skrll {
     82  1.1  skrll   unsigned insn;
     83  1.1  skrll   int nfixups;
     84  1.1  skrll   struct alpha_fixup fixups[MAX_INSN_FIXUPS];
     85  1.1  skrll   long sequence;
     86  1.1  skrll };
     87  1.1  skrll 
     88  1.1  skrll enum alpha_macro_arg
     89  1.1  skrll   {
     90  1.1  skrll     MACRO_EOA = 1,
     91  1.1  skrll     MACRO_IR,
     92  1.1  skrll     MACRO_PIR,
     93  1.1  skrll     MACRO_OPIR,
     94  1.1  skrll     MACRO_CPIR,
     95  1.1  skrll     MACRO_FPR,
     96  1.1  skrll     MACRO_EXP,
     97  1.1  skrll   };
     98  1.1  skrll 
     99  1.1  skrll struct alpha_macro
    100  1.1  skrll {
    101  1.1  skrll   const char *name;
    102  1.1  skrll   void (*emit) (const expressionS *, int, const void *);
    103  1.1  skrll   const void * arg;
    104  1.1  skrll   enum alpha_macro_arg argsets[16];
    105  1.1  skrll };
    106  1.1  skrll 
    107  1.1  skrll /* Extra expression types.  */
    108  1.1  skrll 
    109  1.1  skrll #define O_pregister	O_md1	/* O_register, in parentheses.  */
    110  1.1  skrll #define O_cpregister	O_md2	/* + a leading comma.  */
    111  1.1  skrll 
    112  1.1  skrll /* The alpha_reloc_op table below depends on the ordering of these.  */
    113  1.1  skrll #define O_literal	O_md3		/* !literal relocation.  */
    114  1.1  skrll #define O_lituse_addr	O_md4		/* !lituse_addr relocation.  */
    115  1.1  skrll #define O_lituse_base	O_md5		/* !lituse_base relocation.  */
    116  1.1  skrll #define O_lituse_bytoff	O_md6		/* !lituse_bytoff relocation.  */
    117  1.1  skrll #define O_lituse_jsr	O_md7		/* !lituse_jsr relocation.  */
    118  1.1  skrll #define O_lituse_tlsgd	O_md8		/* !lituse_tlsgd relocation.  */
    119  1.1  skrll #define O_lituse_tlsldm	O_md9		/* !lituse_tlsldm relocation.  */
    120  1.1  skrll #define O_lituse_jsrdirect O_md10	/* !lituse_jsrdirect relocation.  */
    121  1.1  skrll #define O_gpdisp	O_md11		/* !gpdisp relocation.  */
    122  1.1  skrll #define O_gprelhigh	O_md12		/* !gprelhigh relocation.  */
    123  1.1  skrll #define O_gprellow	O_md13		/* !gprellow relocation.  */
    124  1.1  skrll #define O_gprel		O_md14		/* !gprel relocation.  */
    125  1.1  skrll #define O_samegp	O_md15		/* !samegp relocation.  */
    126  1.1  skrll #define O_tlsgd		O_md16		/* !tlsgd relocation.  */
    127  1.1  skrll #define O_tlsldm	O_md17		/* !tlsldm relocation.  */
    128  1.1  skrll #define O_gotdtprel	O_md18		/* !gotdtprel relocation.  */
    129  1.1  skrll #define O_dtprelhi	O_md19		/* !dtprelhi relocation.  */
    130  1.1  skrll #define O_dtprello	O_md20		/* !dtprello relocation.  */
    131  1.1  skrll #define O_dtprel	O_md21		/* !dtprel relocation.  */
    132  1.1  skrll #define O_gottprel	O_md22		/* !gottprel relocation.  */
    133  1.1  skrll #define O_tprelhi	O_md23		/* !tprelhi relocation.  */
    134  1.1  skrll #define O_tprello	O_md24		/* !tprello relocation.  */
    135  1.1  skrll #define O_tprel		O_md25		/* !tprel relocation.  */
    136  1.1  skrll 
    137  1.1  skrll #define DUMMY_RELOC_LITUSE_ADDR		(BFD_RELOC_UNUSED + 1)
    138  1.1  skrll #define DUMMY_RELOC_LITUSE_BASE		(BFD_RELOC_UNUSED + 2)
    139  1.1  skrll #define DUMMY_RELOC_LITUSE_BYTOFF	(BFD_RELOC_UNUSED + 3)
    140  1.1  skrll #define DUMMY_RELOC_LITUSE_JSR		(BFD_RELOC_UNUSED + 4)
    141  1.1  skrll #define DUMMY_RELOC_LITUSE_TLSGD	(BFD_RELOC_UNUSED + 5)
    142  1.1  skrll #define DUMMY_RELOC_LITUSE_TLSLDM	(BFD_RELOC_UNUSED + 6)
    143  1.1  skrll #define DUMMY_RELOC_LITUSE_JSRDIRECT	(BFD_RELOC_UNUSED + 7)
    144  1.1  skrll 
    145  1.1  skrll #define USER_RELOC_P(R) ((R) >= O_literal && (R) <= O_tprel)
    146  1.1  skrll 
    147  1.1  skrll /* Macros for extracting the type and number of encoded register tokens.  */
    148  1.1  skrll 
    149  1.1  skrll #define is_ir_num(x)		(((x) & 32) == 0)
    150  1.1  skrll #define is_fpr_num(x)		(((x) & 32) != 0)
    151  1.1  skrll #define regno(x)		((x) & 31)
    152  1.1  skrll 
    153  1.1  skrll /* Something odd inherited from the old assembler.  */
    154  1.1  skrll 
    155  1.1  skrll #define note_gpreg(R)		(alpha_gprmask |= (1 << (R)))
    156  1.1  skrll #define note_fpreg(R)		(alpha_fprmask |= (1 << (R)))
    157  1.1  skrll 
    158  1.1  skrll /* Predicates for 16- and 32-bit ranges */
    159  1.1  skrll /* XXX: The non-shift version appears to trigger a compiler bug when
    160  1.1  skrll    cross-assembling from x86 w/ gcc 2.7.2.  */
    161  1.1  skrll 
    162  1.1  skrll #if 1
    163  1.1  skrll #define range_signed_16(x) \
    164  1.1  skrll 	(((offsetT) (x) >> 15) == 0 || ((offsetT) (x) >> 15) == -1)
    165  1.1  skrll #define range_signed_32(x) \
    166  1.1  skrll 	(((offsetT) (x) >> 31) == 0 || ((offsetT) (x) >> 31) == -1)
    167  1.1  skrll #else
    168  1.1  skrll #define range_signed_16(x)	((offsetT) (x) >= -(offsetT) 0x8000 &&	\
    169  1.1  skrll 				 (offsetT) (x) <=  (offsetT) 0x7FFF)
    170  1.1  skrll #define range_signed_32(x)	((offsetT) (x) >= -(offsetT) 0x80000000 && \
    171  1.1  skrll 				 (offsetT) (x) <=  (offsetT) 0x7FFFFFFF)
    172  1.1  skrll #endif
    173  1.1  skrll 
    174  1.1  skrll /* Macros for sign extending from 16- and 32-bits.  */
    175  1.1  skrll /* XXX: The cast macros will work on all the systems that I care about,
    176  1.1  skrll    but really a predicate should be found to use the non-cast forms.  */
    177  1.1  skrll 
    178  1.1  skrll #if 1
    179  1.1  skrll #define sign_extend_16(x)	((short) (x))
    180  1.1  skrll #define sign_extend_32(x)	((int) (x))
    181  1.1  skrll #else
    182  1.1  skrll #define sign_extend_16(x)	((offsetT) (((x) & 0xFFFF) ^ 0x8000) - 0x8000)
    183  1.1  skrll #define sign_extend_32(x)	((offsetT) (((x) & 0xFFFFFFFF) \
    184  1.1  skrll 					   ^ 0x80000000) - 0x80000000)
    185  1.1  skrll #endif
    186  1.1  skrll 
    187  1.1  skrll /* Macros to build tokens.  */
    188  1.1  skrll 
    189  1.1  skrll #define set_tok_reg(t, r)	(memset (&(t), 0, sizeof (t)),		\
    190  1.1  skrll 				 (t).X_op = O_register,			\
    191  1.1  skrll 				 (t).X_add_number = (r))
    192  1.1  skrll #define set_tok_preg(t, r)	(memset (&(t), 0, sizeof (t)),		\
    193  1.1  skrll 				 (t).X_op = O_pregister,		\
    194  1.1  skrll 				 (t).X_add_number = (r))
    195  1.1  skrll #define set_tok_cpreg(t, r)	(memset (&(t), 0, sizeof (t)),		\
    196  1.1  skrll 				 (t).X_op = O_cpregister,		\
    197  1.1  skrll 				 (t).X_add_number = (r))
    198  1.1  skrll #define set_tok_freg(t, r)	(memset (&(t), 0, sizeof (t)),		\
    199  1.1  skrll 				 (t).X_op = O_register,			\
    200  1.1  skrll 				 (t).X_add_number = (r) + 32)
    201  1.1  skrll #define set_tok_sym(t, s, a)	(memset (&(t), 0, sizeof (t)),		\
    202  1.1  skrll 				 (t).X_op = O_symbol,			\
    203  1.1  skrll 				 (t).X_add_symbol = (s),		\
    204  1.1  skrll 				 (t).X_add_number = (a))
    205  1.1  skrll #define set_tok_const(t, n)	(memset (&(t), 0, sizeof (t)),		\
    206  1.1  skrll 				 (t).X_op = O_constant,			\
    207  1.1  skrll 				 (t).X_add_number = (n))
    208  1.1  skrll 
    209  1.1  skrll /* Generic assembler global variables which must be defined by all
    211  1.1  skrll    targets.  */
    212  1.1  skrll 
    213  1.1  skrll /* Characters which always start a comment.  */
    214  1.1  skrll const char comment_chars[] = "#";
    215  1.1  skrll 
    216  1.1  skrll /* Characters which start a comment at the beginning of a line.  */
    217  1.1  skrll const char line_comment_chars[] = "#";
    218  1.1  skrll 
    219  1.1  skrll /* Characters which may be used to separate multiple commands on a
    220  1.1  skrll    single line.  */
    221  1.1  skrll const char line_separator_chars[] = ";";
    222  1.1  skrll 
    223  1.1  skrll /* Characters which are used to indicate an exponent in a floating
    224  1.1  skrll    point number.  */
    225  1.1  skrll const char EXP_CHARS[] = "eE";
    226  1.1  skrll 
    227  1.1  skrll /* Characters which mean that a number is a floating point constant,
    228  1.1  skrll    as in 0d1.0.  */
    229  1.1  skrll /* XXX: Do all of these really get used on the alpha??  */
    230  1.1  skrll char FLT_CHARS[] = "rRsSfFdDxXpP";
    231  1.1  skrll 
    232  1.1  skrll #ifdef OBJ_EVAX
    233  1.1  skrll const char *md_shortopts = "Fm:g+1h:HG:";
    234  1.1  skrll #else
    235  1.1  skrll const char *md_shortopts = "Fm:gG:";
    236  1.1  skrll #endif
    237  1.1  skrll 
    238  1.1  skrll struct option md_longopts[] =
    239  1.1  skrll   {
    240  1.1  skrll #define OPTION_32ADDR (OPTION_MD_BASE)
    241  1.1  skrll     { "32addr", no_argument, NULL, OPTION_32ADDR },
    242  1.1  skrll #define OPTION_RELAX (OPTION_32ADDR + 1)
    243  1.1  skrll     { "relax", no_argument, NULL, OPTION_RELAX },
    244  1.1  skrll #ifdef OBJ_ELF
    245  1.1  skrll #define OPTION_MDEBUG (OPTION_RELAX + 1)
    246  1.1  skrll #define OPTION_NO_MDEBUG (OPTION_MDEBUG + 1)
    247  1.1  skrll     { "mdebug", no_argument, NULL, OPTION_MDEBUG },
    248  1.1  skrll     { "no-mdebug", no_argument, NULL, OPTION_NO_MDEBUG },
    249  1.1  skrll #endif
    250  1.1  skrll     { NULL, no_argument, NULL, 0 }
    251  1.1  skrll   };
    252  1.1  skrll 
    253  1.1  skrll size_t md_longopts_size = sizeof (md_longopts);
    254  1.1  skrll 
    255  1.1  skrll #ifdef OBJ_EVAX
    257  1.1  skrll #define AXP_REG_R0     0
    258  1.1  skrll #define AXP_REG_R16    16
    259  1.1  skrll #define AXP_REG_R17    17
    260  1.1  skrll #undef AXP_REG_T9
    261  1.1  skrll #define AXP_REG_T9     22
    262  1.1  skrll #undef AXP_REG_T10
    263  1.1  skrll #define AXP_REG_T10    23
    264  1.1  skrll #undef AXP_REG_T11
    265  1.1  skrll #define AXP_REG_T11    24
    266  1.1  skrll #undef AXP_REG_T12
    267  1.1  skrll #define AXP_REG_T12    25
    268  1.1  skrll #define AXP_REG_AI     25
    269  1.1  skrll #undef AXP_REG_FP
    270  1.1  skrll #define AXP_REG_FP     29
    271  1.1  skrll 
    272  1.1  skrll #undef AXP_REG_GP
    273  1.1  skrll #define AXP_REG_GP AXP_REG_PV
    274  1.1  skrll #endif /* OBJ_EVAX  */
    275  1.1  skrll 
    276  1.1  skrll /* The cpu for which we are generating code.  */
    277  1.1  skrll static unsigned alpha_target = AXP_OPCODE_BASE;
    278  1.1  skrll static const char *alpha_target_name = "<all>";
    279  1.1  skrll 
    280  1.1  skrll /* The hash table of instruction opcodes.  */
    281  1.1  skrll static struct hash_control *alpha_opcode_hash;
    282  1.1  skrll 
    283  1.1  skrll /* The hash table of macro opcodes.  */
    284  1.1  skrll static struct hash_control *alpha_macro_hash;
    285  1.1  skrll 
    286  1.1  skrll #ifdef OBJ_ECOFF
    287  1.1  skrll /* The $gp relocation symbol.  */
    288  1.1  skrll static symbolS *alpha_gp_symbol;
    289  1.1  skrll 
    290  1.1  skrll /* XXX: what is this, and why is it exported? */
    291  1.1  skrll valueT alpha_gp_value;
    292  1.1  skrll #endif
    293  1.1  skrll 
    294  1.1  skrll /* The current $gp register.  */
    295  1.1  skrll static int alpha_gp_register = AXP_REG_GP;
    296  1.1  skrll 
    297  1.1  skrll /* A table of the register symbols.  */
    298  1.1  skrll static symbolS *alpha_register_table[64];
    299  1.1  skrll 
    300  1.1  skrll /* Constant sections, or sections of constants.  */
    301  1.1  skrll #ifdef OBJ_ECOFF
    302  1.1  skrll static segT alpha_lita_section;
    303  1.1  skrll #endif
    304  1.1  skrll #ifdef OBJ_EVAX
    305  1.1  skrll static segT alpha_link_section;
    306  1.1  skrll static segT alpha_ctors_section;
    307  1.1  skrll static segT alpha_dtors_section;
    308  1.1  skrll #endif
    309  1.1  skrll static segT alpha_lit8_section;
    310  1.1  skrll 
    311  1.1  skrll /* Symbols referring to said sections.  */
    312  1.1  skrll #ifdef OBJ_ECOFF
    313  1.1  skrll static symbolS *alpha_lita_symbol;
    314  1.1  skrll #endif
    315  1.1  skrll #ifdef OBJ_EVAX
    316  1.1  skrll static symbolS *alpha_link_symbol;
    317  1.1  skrll static symbolS *alpha_ctors_symbol;
    318  1.1  skrll static symbolS *alpha_dtors_symbol;
    319  1.1  skrll #endif
    320  1.1  skrll static symbolS *alpha_lit8_symbol;
    321  1.1  skrll 
    322  1.1  skrll /* Literal for .litX+0x8000 within .lita.  */
    323  1.1  skrll #ifdef OBJ_ECOFF
    324  1.1  skrll static offsetT alpha_lit8_literal;
    325  1.1  skrll #endif
    326  1.1  skrll 
    327  1.1  skrll /* Is the assembler not allowed to use $at?  */
    328  1.1  skrll static int alpha_noat_on = 0;
    329  1.1  skrll 
    330  1.1  skrll /* Are macros enabled?  */
    331  1.1  skrll static int alpha_macros_on = 1;
    332  1.1  skrll 
    333  1.1  skrll /* Are floats disabled?  */
    334  1.1  skrll static int alpha_nofloats_on = 0;
    335  1.1  skrll 
    336  1.1  skrll /* Are addresses 32 bit?  */
    337  1.1  skrll static int alpha_addr32_on = 0;
    338  1.1  skrll 
    339  1.1  skrll /* Symbol labelling the current insn.  When the Alpha gas sees
    340  1.1  skrll      foo:
    341  1.1  skrll        .quad 0
    342  1.1  skrll    and the section happens to not be on an eight byte boundary, it
    343  1.1  skrll    will align both the symbol and the .quad to an eight byte boundary.  */
    344  1.1  skrll static symbolS *alpha_insn_label;
    345  1.1  skrll 
    346  1.1  skrll /* Whether we should automatically align data generation pseudo-ops.
    347  1.1  skrll    .align 0 will turn this off.  */
    348  1.1  skrll static int alpha_auto_align_on = 1;
    349  1.1  skrll 
    350  1.1  skrll /* The known current alignment of the current section.  */
    351  1.1  skrll static int alpha_current_align;
    352  1.1  skrll 
    353  1.1  skrll /* These are exported to ECOFF code.  */
    354  1.1  skrll unsigned long alpha_gprmask, alpha_fprmask;
    355  1.1  skrll 
    356  1.1  skrll /* Whether the debugging option was seen.  */
    357  1.1  skrll static int alpha_debug;
    358  1.1  skrll 
    359  1.1  skrll #ifdef OBJ_ELF
    360  1.1  skrll /* Whether we are emitting an mdebug section.  */
    361  1.1  skrll int alpha_flag_mdebug = -1;
    362  1.1  skrll #endif
    363  1.1  skrll 
    364  1.1  skrll /* Don't fully resolve relocations, allowing code movement in the linker.  */
    365  1.1  skrll static int alpha_flag_relax;
    366  1.1  skrll 
    367  1.1  skrll /* What value to give to bfd_set_gp_size.  */
    368  1.1  skrll static int g_switch_value = 8;
    369  1.1  skrll 
    370  1.1  skrll #ifdef OBJ_EVAX
    371  1.1  skrll /* Collect information about current procedure here.  */
    372  1.1  skrll static struct
    373  1.1  skrll {
    374  1.1  skrll   symbolS *symbol;	/* Proc pdesc symbol.  */
    375  1.1  skrll   int pdsckind;
    376  1.1  skrll   int framereg;		/* Register for frame pointer.  */
    377  1.1  skrll   int framesize;	/* Size of frame.  */
    378  1.1  skrll   int rsa_offset;
    379  1.1  skrll   int ra_save;
    380  1.1  skrll   int fp_save;
    381  1.1  skrll   long imask;
    382  1.1  skrll   long fmask;
    383  1.1  skrll   int type;
    384  1.1  skrll   int prologue;
    385  1.1  skrll } alpha_evax_proc;
    386  1.1  skrll 
    387  1.1  skrll static int alpha_flag_hash_long_names = 0;		/* -+ */
    388  1.1  skrll static int alpha_flag_show_after_trunc = 0;		/* -H */
    389  1.1  skrll 
    390  1.1  skrll /* If the -+ switch is given, then a hash is appended to any name that is
    391  1.1  skrll    longer than 64 characters, else longer symbol names are truncated.  */
    392  1.1  skrll 
    393  1.1  skrll #endif
    394  1.1  skrll 
    395  1.1  skrll #ifdef RELOC_OP_P
    397  1.1  skrll /* A table to map the spelling of a relocation operand into an appropriate
    398  1.1  skrll    bfd_reloc_code_real_type type.  The table is assumed to be ordered such
    399  1.1  skrll    that op-O_literal indexes into it.  */
    400  1.1  skrll 
    401  1.1  skrll #define ALPHA_RELOC_TABLE(op)						\
    402  1.1  skrll (&alpha_reloc_op[ ((!USER_RELOC_P (op))					\
    403  1.1  skrll 		  ? (abort (), 0)					\
    404  1.1  skrll 		  : (int) (op) - (int) O_literal) ])
    405  1.1  skrll 
    406  1.1  skrll #define DEF(NAME, RELOC, REQ, ALLOW) \
    407  1.1  skrll  { #NAME, sizeof(#NAME)-1, O_##NAME, RELOC, REQ, ALLOW}
    408  1.1  skrll 
    409  1.1  skrll static const struct alpha_reloc_op_tag
    410  1.1  skrll {
    411  1.1  skrll   const char *name;				/* String to lookup.  */
    412  1.1  skrll   size_t length;				/* Size of the string.  */
    413  1.1  skrll   operatorT op;					/* Which operator to use.  */
    414  1.1  skrll   bfd_reloc_code_real_type reloc;		/* Relocation before frob.  */
    415  1.1  skrll   unsigned int require_seq : 1;			/* Require a sequence number.  */
    416  1.1  skrll   unsigned int allow_seq : 1;			/* Allow a sequence number.  */
    417  1.1  skrll }
    418  1.1  skrll alpha_reloc_op[] =
    419  1.1  skrll {
    420  1.1  skrll   DEF (literal, BFD_RELOC_ALPHA_ELF_LITERAL, 0, 1),
    421  1.1  skrll   DEF (lituse_addr, DUMMY_RELOC_LITUSE_ADDR, 1, 1),
    422  1.1  skrll   DEF (lituse_base, DUMMY_RELOC_LITUSE_BASE, 1, 1),
    423  1.1  skrll   DEF (lituse_bytoff, DUMMY_RELOC_LITUSE_BYTOFF, 1, 1),
    424  1.1  skrll   DEF (lituse_jsr, DUMMY_RELOC_LITUSE_JSR, 1, 1),
    425  1.1  skrll   DEF (lituse_tlsgd, DUMMY_RELOC_LITUSE_TLSGD, 1, 1),
    426  1.1  skrll   DEF (lituse_tlsldm, DUMMY_RELOC_LITUSE_TLSLDM, 1, 1),
    427  1.1  skrll   DEF (lituse_jsrdirect, DUMMY_RELOC_LITUSE_JSRDIRECT, 1, 1),
    428  1.1  skrll   DEF (gpdisp, BFD_RELOC_ALPHA_GPDISP, 1, 1),
    429  1.1  skrll   DEF (gprelhigh, BFD_RELOC_ALPHA_GPREL_HI16, 0, 0),
    430  1.1  skrll   DEF (gprellow, BFD_RELOC_ALPHA_GPREL_LO16, 0, 0),
    431  1.1  skrll   DEF (gprel, BFD_RELOC_GPREL16, 0, 0),
    432  1.1  skrll   DEF (samegp, BFD_RELOC_ALPHA_BRSGP, 0, 0),
    433  1.1  skrll   DEF (tlsgd, BFD_RELOC_ALPHA_TLSGD, 0, 1),
    434  1.1  skrll   DEF (tlsldm, BFD_RELOC_ALPHA_TLSLDM, 0, 1),
    435  1.1  skrll   DEF (gotdtprel, BFD_RELOC_ALPHA_GOTDTPREL16, 0, 0),
    436  1.1  skrll   DEF (dtprelhi, BFD_RELOC_ALPHA_DTPREL_HI16, 0, 0),
    437  1.1  skrll   DEF (dtprello, BFD_RELOC_ALPHA_DTPREL_LO16, 0, 0),
    438  1.1  skrll   DEF (dtprel, BFD_RELOC_ALPHA_DTPREL16, 0, 0),
    439  1.1  skrll   DEF (gottprel, BFD_RELOC_ALPHA_GOTTPREL16, 0, 0),
    440  1.1  skrll   DEF (tprelhi, BFD_RELOC_ALPHA_TPREL_HI16, 0, 0),
    441  1.1  skrll   DEF (tprello, BFD_RELOC_ALPHA_TPREL_LO16, 0, 0),
    442  1.1  skrll   DEF (tprel, BFD_RELOC_ALPHA_TPREL16, 0, 0),
    443  1.1  skrll };
    444  1.1  skrll 
    445  1.1  skrll #undef DEF
    446  1.1  skrll 
    447  1.1  skrll static const int alpha_num_reloc_op
    448  1.1  skrll   = sizeof (alpha_reloc_op) / sizeof (*alpha_reloc_op);
    449  1.1  skrll #endif /* RELOC_OP_P */
    450  1.1  skrll 
    451  1.1  skrll /* Maximum # digits needed to hold the largest sequence #.  */
    452  1.1  skrll #define ALPHA_RELOC_DIGITS 25
    453  1.1  skrll 
    454  1.1  skrll /* Structure to hold explicit sequence information.  */
    455  1.1  skrll struct alpha_reloc_tag
    456  1.1  skrll {
    457  1.1  skrll   fixS *master;			/* The literal reloc.  */
    458  1.1  skrll   fixS *slaves;			/* Head of linked list of lituses.  */
    459  1.1  skrll   segT segment;			/* Segment relocs are in or undefined_section.  */
    460  1.1  skrll   long sequence;		/* Sequence #.  */
    461  1.1  skrll   unsigned n_master;		/* # of literals.  */
    462  1.1  skrll   unsigned n_slaves;		/* # of lituses.  */
    463  1.1  skrll   unsigned saw_tlsgd : 1;	/* True if ...  */
    464  1.1  skrll   unsigned saw_tlsldm : 1;
    465  1.1  skrll   unsigned saw_lu_tlsgd : 1;
    466  1.1  skrll   unsigned saw_lu_tlsldm : 1;
    467  1.1  skrll   unsigned multi_section_p : 1;	/* True if more than one section was used.  */
    468  1.1  skrll   char string[1];		/* Printable form of sequence to hash with.  */
    469  1.1  skrll };
    470  1.1  skrll 
    471  1.1  skrll /* Hash table to link up literals with the appropriate lituse.  */
    472  1.1  skrll static struct hash_control *alpha_literal_hash;
    473  1.1  skrll 
    474  1.1  skrll /* Sequence numbers for internal use by macros.  */
    475  1.1  skrll static long next_sequence_num = -1;
    476  1.1  skrll 
    477  1.1  skrll /* A table of CPU names and opcode sets.  */
    479  1.1  skrll 
    480  1.1  skrll static const struct cpu_type
    481  1.1  skrll {
    482  1.1  skrll   const char *name;
    483  1.1  skrll   unsigned flags;
    484  1.1  skrll }
    485  1.1  skrll cpu_types[] =
    486  1.1  skrll {
    487  1.1  skrll   /* Ad hoc convention: cpu number gets palcode, process code doesn't.
    488  1.1  skrll      This supports usage under DU 4.0b that does ".arch ev4", and
    489  1.1  skrll      usage in MILO that does -m21064.  Probably something more
    490  1.1  skrll      specific like -m21064-pal should be used, but oh well.  */
    491  1.1  skrll 
    492  1.1  skrll   { "21064", AXP_OPCODE_BASE|AXP_OPCODE_EV4 },
    493  1.1  skrll   { "21064a", AXP_OPCODE_BASE|AXP_OPCODE_EV4 },
    494  1.1  skrll   { "21066", AXP_OPCODE_BASE|AXP_OPCODE_EV4 },
    495  1.1  skrll   { "21068", AXP_OPCODE_BASE|AXP_OPCODE_EV4 },
    496  1.1  skrll   { "21164", AXP_OPCODE_BASE|AXP_OPCODE_EV5 },
    497  1.1  skrll   { "21164a", AXP_OPCODE_BASE|AXP_OPCODE_EV5|AXP_OPCODE_BWX },
    498  1.1  skrll   { "21164pc", (AXP_OPCODE_BASE|AXP_OPCODE_EV5|AXP_OPCODE_BWX
    499  1.1  skrll 		|AXP_OPCODE_MAX) },
    500  1.1  skrll   { "21264", (AXP_OPCODE_BASE|AXP_OPCODE_EV6|AXP_OPCODE_BWX
    501  1.1  skrll 	      |AXP_OPCODE_MAX|AXP_OPCODE_CIX) },
    502  1.1  skrll   { "21264a", (AXP_OPCODE_BASE|AXP_OPCODE_EV6|AXP_OPCODE_BWX
    503  1.1  skrll 	      |AXP_OPCODE_MAX|AXP_OPCODE_CIX) },
    504  1.1  skrll   { "21264b", (AXP_OPCODE_BASE|AXP_OPCODE_EV6|AXP_OPCODE_BWX
    505  1.1  skrll 	      |AXP_OPCODE_MAX|AXP_OPCODE_CIX) },
    506  1.1  skrll 
    507  1.1  skrll   { "ev4", AXP_OPCODE_BASE },
    508  1.1  skrll   { "ev45", AXP_OPCODE_BASE },
    509  1.1  skrll   { "lca45", AXP_OPCODE_BASE },
    510  1.1  skrll   { "ev5", AXP_OPCODE_BASE },
    511  1.1  skrll   { "ev56", AXP_OPCODE_BASE|AXP_OPCODE_BWX },
    512  1.1  skrll   { "pca56", AXP_OPCODE_BASE|AXP_OPCODE_BWX|AXP_OPCODE_MAX },
    513  1.1  skrll   { "ev6", AXP_OPCODE_BASE|AXP_OPCODE_BWX|AXP_OPCODE_MAX|AXP_OPCODE_CIX },
    514  1.1  skrll   { "ev67", AXP_OPCODE_BASE|AXP_OPCODE_BWX|AXP_OPCODE_MAX|AXP_OPCODE_CIX },
    515  1.1  skrll   { "ev68", AXP_OPCODE_BASE|AXP_OPCODE_BWX|AXP_OPCODE_MAX|AXP_OPCODE_CIX },
    516  1.1  skrll 
    517  1.1  skrll   { "all", AXP_OPCODE_BASE },
    518  1.1  skrll   { 0, 0 }
    519  1.1  skrll };
    520  1.1  skrll 
    521  1.1  skrll /* Some instruction sets indexed by lg(size).  */
    522  1.1  skrll static const char * const sextX_op[] = { "sextb", "sextw", "sextl", NULL };
    523  1.1  skrll static const char * const insXl_op[] = { "insbl", "inswl", "insll", "insql" };
    524  1.1  skrll static const char * const insXh_op[] = { NULL,    "inswh", "inslh", "insqh" };
    525  1.1  skrll static const char * const extXl_op[] = { "extbl", "extwl", "extll", "extql" };
    526  1.1  skrll static const char * const extXh_op[] = { NULL,    "extwh", "extlh", "extqh" };
    527  1.1  skrll static const char * const mskXl_op[] = { "mskbl", "mskwl", "mskll", "mskql" };
    528  1.1  skrll static const char * const mskXh_op[] = { NULL,    "mskwh", "msklh", "mskqh" };
    529  1.1  skrll static const char * const stX_op[] = { "stb", "stw", "stl", "stq" };
    530  1.1  skrll static const char * const ldXu_op[] = { "ldbu", "ldwu", NULL, NULL };
    531  1.1  skrll 
    532  1.1  skrll static void assemble_insn (const struct alpha_opcode *, const expressionS *, int, struct alpha_insn *, bfd_reloc_code_real_type);
    533  1.1  skrll static void emit_insn (struct alpha_insn *);
    534  1.1  skrll static void assemble_tokens (const char *, const expressionS *, int, int);
    535  1.1  skrll 
    536  1.1  skrll static struct alpha_reloc_tag *
    538  1.1  skrll get_alpha_reloc_tag (long sequence)
    539  1.1  skrll {
    540  1.1  skrll   char buffer[ALPHA_RELOC_DIGITS];
    541  1.1  skrll   struct alpha_reloc_tag *info;
    542  1.1  skrll 
    543  1.1  skrll   sprintf (buffer, "!%ld", sequence);
    544  1.1  skrll 
    545  1.1  skrll   info = (struct alpha_reloc_tag *) hash_find (alpha_literal_hash, buffer);
    546  1.1  skrll   if (! info)
    547  1.1  skrll     {
    548  1.1  skrll       size_t len = strlen (buffer);
    549  1.1  skrll       const char *errmsg;
    550  1.1  skrll 
    551  1.1  skrll       info = xcalloc (sizeof (struct alpha_reloc_tag) + len, 1);
    552  1.2    snj 
    553  1.1  skrll       info->segment = now_seg;
    554  1.1  skrll       info->sequence = sequence;
    555  1.1  skrll       strcpy (info->string, buffer);
    556  1.1  skrll       errmsg = hash_insert (alpha_literal_hash, info->string, (void *) info);
    557  1.1  skrll       if (errmsg)
    558  1.1  skrll 	as_fatal ("%s", errmsg);
    559  1.1  skrll     }
    560  1.1  skrll 
    561  1.1  skrll   return info;
    562  1.1  skrll }
    563  1.1  skrll 
    564  1.1  skrll static void
    565  1.1  skrll alpha_adjust_relocs (bfd *abfd ATTRIBUTE_UNUSED,
    566  1.1  skrll 		     asection *sec,
    567  1.1  skrll 		     void * ptr ATTRIBUTE_UNUSED)
    568  1.1  skrll {
    569  1.1  skrll   segment_info_type *seginfo = seg_info (sec);
    570  1.1  skrll   fixS **prevP;
    571  1.1  skrll   fixS *fixp;
    572  1.1  skrll   fixS *next;
    573  1.1  skrll   fixS *slave;
    574  1.1  skrll 
    575  1.1  skrll   /* If seginfo is NULL, we did not create this section; don't do
    576  1.1  skrll      anything with it.  By using a pointer to a pointer, we can update
    577  1.1  skrll      the links in place.  */
    578  1.1  skrll   if (seginfo == NULL)
    579  1.1  skrll     return;
    580  1.1  skrll 
    581  1.1  skrll   /* If there are no relocations, skip the section.  */
    582  1.1  skrll   if (! seginfo->fix_root)
    583  1.1  skrll     return;
    584  1.1  skrll 
    585  1.1  skrll   /* First rebuild the fixup chain without the explicit lituse and
    586  1.1  skrll      gpdisp_lo16 relocs.  */
    587  1.1  skrll   prevP = &seginfo->fix_root;
    588  1.1  skrll   for (fixp = seginfo->fix_root; fixp; fixp = next)
    589  1.1  skrll     {
    590  1.1  skrll       next = fixp->fx_next;
    591  1.1  skrll       fixp->fx_next = (fixS *) 0;
    592  1.1  skrll 
    593  1.1  skrll       switch (fixp->fx_r_type)
    594  1.1  skrll 	{
    595  1.1  skrll 	case BFD_RELOC_ALPHA_LITUSE:
    596  1.1  skrll 	  if (fixp->tc_fix_data.info->n_master == 0)
    597  1.1  skrll 	    as_bad_where (fixp->fx_file, fixp->fx_line,
    598  1.1  skrll 			  _("No !literal!%ld was found"),
    599  1.1  skrll 			  fixp->tc_fix_data.info->sequence);
    600  1.1  skrll #ifdef RELOC_OP_P
    601  1.1  skrll 	  if (fixp->fx_offset == LITUSE_ALPHA_TLSGD)
    602  1.1  skrll 	    {
    603  1.1  skrll 	      if (! fixp->tc_fix_data.info->saw_tlsgd)
    604  1.1  skrll 		as_bad_where (fixp->fx_file, fixp->fx_line,
    605  1.1  skrll 			      _("No !tlsgd!%ld was found"),
    606  1.1  skrll 			      fixp->tc_fix_data.info->sequence);
    607  1.1  skrll 	    }
    608  1.1  skrll 	  else if (fixp->fx_offset == LITUSE_ALPHA_TLSLDM)
    609  1.1  skrll 	    {
    610  1.1  skrll 	      if (! fixp->tc_fix_data.info->saw_tlsldm)
    611  1.1  skrll 		as_bad_where (fixp->fx_file, fixp->fx_line,
    612  1.1  skrll 			      _("No !tlsldm!%ld was found"),
    613  1.1  skrll 			      fixp->tc_fix_data.info->sequence);
    614  1.1  skrll 	    }
    615  1.1  skrll #endif
    616  1.1  skrll 	  break;
    617  1.1  skrll 
    618  1.1  skrll 	case BFD_RELOC_ALPHA_GPDISP_LO16:
    619  1.1  skrll 	  if (fixp->tc_fix_data.info->n_master == 0)
    620  1.1  skrll 	    as_bad_where (fixp->fx_file, fixp->fx_line,
    621  1.1  skrll 			  _("No ldah !gpdisp!%ld was found"),
    622  1.1  skrll 			  fixp->tc_fix_data.info->sequence);
    623  1.1  skrll 	  break;
    624  1.1  skrll 
    625  1.1  skrll 	case BFD_RELOC_ALPHA_ELF_LITERAL:
    626  1.1  skrll 	  if (fixp->tc_fix_data.info
    627  1.1  skrll 	      && (fixp->tc_fix_data.info->saw_tlsgd
    628  1.1  skrll 	          || fixp->tc_fix_data.info->saw_tlsldm))
    629  1.1  skrll 	    break;
    630  1.1  skrll 	  /* FALLTHRU */
    631  1.1  skrll 
    632  1.1  skrll 	default:
    633  1.1  skrll 	  *prevP = fixp;
    634  1.1  skrll 	  prevP = &fixp->fx_next;
    635  1.1  skrll 	  break;
    636  1.1  skrll 	}
    637  1.1  skrll     }
    638  1.1  skrll 
    639  1.1  skrll   /* Go back and re-chain dependent relocations.  They are currently
    640  1.1  skrll      linked through the next_reloc field in reverse order, so as we
    641  1.1  skrll      go through the next_reloc chain, we effectively reverse the chain
    642  1.1  skrll      once again.
    643  1.1  skrll 
    644  1.1  skrll      Except if there is more than one !literal for a given sequence
    645  1.1  skrll      number.  In that case, the programmer and/or compiler is not sure
    646  1.1  skrll      how control flows from literal to lituse, and we can't be sure to
    647  1.1  skrll      get the relaxation correct.
    648  1.1  skrll 
    649  1.1  skrll      ??? Well, actually we could, if there are enough lituses such that
    650  1.1  skrll      we can make each literal have at least one of each lituse type
    651  1.1  skrll      present.  Not implemented.
    652  1.1  skrll 
    653  1.1  skrll      Also suppress the optimization if the !literals/!lituses are spread
    654  1.1  skrll      in different segments.  This can happen with "intersting" uses of
    655  1.1  skrll      inline assembly; examples are present in the Linux kernel semaphores.  */
    656  1.1  skrll 
    657  1.1  skrll   for (fixp = seginfo->fix_root; fixp; fixp = next)
    658  1.1  skrll     {
    659  1.1  skrll       next = fixp->fx_next;
    660  1.1  skrll       switch (fixp->fx_r_type)
    661  1.1  skrll 	{
    662  1.1  skrll 	case BFD_RELOC_ALPHA_TLSGD:
    663  1.1  skrll 	case BFD_RELOC_ALPHA_TLSLDM:
    664  1.1  skrll 	  if (!fixp->tc_fix_data.info)
    665  1.1  skrll 	    break;
    666  1.1  skrll 	  if (fixp->tc_fix_data.info->n_master == 0)
    667  1.1  skrll 	    break;
    668  1.1  skrll 	  else if (fixp->tc_fix_data.info->n_master > 1)
    669  1.1  skrll 	    {
    670  1.1  skrll 	      as_bad_where (fixp->fx_file, fixp->fx_line,
    671  1.1  skrll 			    _("too many !literal!%ld for %s"),
    672  1.1  skrll 			    fixp->tc_fix_data.info->sequence,
    673  1.1  skrll 			    (fixp->fx_r_type == BFD_RELOC_ALPHA_TLSGD
    674  1.1  skrll 			     ? "!tlsgd" : "!tlsldm"));
    675  1.1  skrll 	      break;
    676  1.1  skrll 	    }
    677  1.1  skrll 
    678  1.1  skrll 	  fixp->tc_fix_data.info->master->fx_next = fixp->fx_next;
    679  1.1  skrll 	  fixp->fx_next = fixp->tc_fix_data.info->master;
    680  1.1  skrll 	  fixp = fixp->fx_next;
    681  1.1  skrll 	  /* Fall through.  */
    682  1.1  skrll 
    683  1.1  skrll 	case BFD_RELOC_ALPHA_ELF_LITERAL:
    684  1.1  skrll 	  if (fixp->tc_fix_data.info
    685  1.1  skrll 	      && fixp->tc_fix_data.info->n_master == 1
    686  1.1  skrll 	      && ! fixp->tc_fix_data.info->multi_section_p)
    687  1.1  skrll 	    {
    688  1.1  skrll 	      for (slave = fixp->tc_fix_data.info->slaves;
    689  1.1  skrll 		   slave != (fixS *) 0;
    690  1.1  skrll 		   slave = slave->tc_fix_data.next_reloc)
    691  1.1  skrll 		{
    692  1.1  skrll 		  slave->fx_next = fixp->fx_next;
    693  1.1  skrll 		  fixp->fx_next = slave;
    694  1.1  skrll 		}
    695  1.1  skrll 	    }
    696  1.1  skrll 	  break;
    697  1.1  skrll 
    698  1.1  skrll 	case BFD_RELOC_ALPHA_GPDISP_HI16:
    699  1.1  skrll 	  if (fixp->tc_fix_data.info->n_slaves == 0)
    700  1.1  skrll 	    as_bad_where (fixp->fx_file, fixp->fx_line,
    701  1.1  skrll 			  _("No lda !gpdisp!%ld was found"),
    702  1.1  skrll 			  fixp->tc_fix_data.info->sequence);
    703  1.1  skrll 	  else
    704  1.1  skrll 	    {
    705  1.1  skrll 	      slave = fixp->tc_fix_data.info->slaves;
    706  1.1  skrll 	      slave->fx_next = next;
    707  1.1  skrll 	      fixp->fx_next = slave;
    708  1.1  skrll 	    }
    709  1.1  skrll 	  break;
    710  1.1  skrll 
    711  1.1  skrll 	default:
    712  1.1  skrll 	  break;
    713  1.1  skrll 	}
    714  1.1  skrll     }
    715  1.1  skrll }
    716  1.1  skrll 
    717  1.1  skrll /* Before the relocations are written, reorder them, so that user
    718  1.1  skrll    supplied !lituse relocations follow the appropriate !literal
    719  1.1  skrll    relocations, and similarly for !gpdisp relocations.  */
    720  1.1  skrll 
    721  1.1  skrll void
    722  1.1  skrll alpha_before_fix (void)
    723  1.1  skrll {
    724  1.1  skrll   if (alpha_literal_hash)
    725  1.1  skrll     bfd_map_over_sections (stdoutput, alpha_adjust_relocs, NULL);
    726  1.1  skrll }
    727  1.1  skrll 
    728  1.1  skrll #ifdef DEBUG_ALPHA
    730  1.1  skrll static void
    731  1.1  skrll debug_exp (expressionS tok[], int ntok)
    732  1.1  skrll {
    733  1.1  skrll   int i;
    734  1.1  skrll 
    735  1.1  skrll   fprintf (stderr, "debug_exp: %d tokens", ntok);
    736  1.1  skrll   for (i = 0; i < ntok; i++)
    737  1.1  skrll     {
    738  1.1  skrll       expressionS *t = &tok[i];
    739  1.1  skrll       const char *name;
    740  1.1  skrll 
    741  1.1  skrll       switch (t->X_op)
    742  1.1  skrll 	{
    743  1.1  skrll 	default:			name = "unknown";		break;
    744  1.1  skrll 	case O_illegal:			name = "O_illegal";		break;
    745  1.1  skrll 	case O_absent:			name = "O_absent";		break;
    746  1.1  skrll 	case O_constant:		name = "O_constant";		break;
    747  1.1  skrll 	case O_symbol:			name = "O_symbol";		break;
    748  1.1  skrll 	case O_symbol_rva:		name = "O_symbol_rva";		break;
    749  1.1  skrll 	case O_register:		name = "O_register";		break;
    750  1.1  skrll 	case O_big:			name = "O_big";			break;
    751  1.1  skrll 	case O_uminus:			name = "O_uminus";		break;
    752  1.1  skrll 	case O_bit_not:			name = "O_bit_not";		break;
    753  1.1  skrll 	case O_logical_not:		name = "O_logical_not";		break;
    754  1.1  skrll 	case O_multiply:		name = "O_multiply";		break;
    755  1.1  skrll 	case O_divide:			name = "O_divide";		break;
    756  1.1  skrll 	case O_modulus:			name = "O_modulus";		break;
    757  1.1  skrll 	case O_left_shift:		name = "O_left_shift";		break;
    758  1.1  skrll 	case O_right_shift:		name = "O_right_shift";		break;
    759  1.1  skrll 	case O_bit_inclusive_or:	name = "O_bit_inclusive_or";	break;
    760  1.1  skrll 	case O_bit_or_not:		name = "O_bit_or_not";		break;
    761  1.1  skrll 	case O_bit_exclusive_or:	name = "O_bit_exclusive_or";	break;
    762  1.1  skrll 	case O_bit_and:			name = "O_bit_and";		break;
    763  1.1  skrll 	case O_add:			name = "O_add";			break;
    764  1.1  skrll 	case O_subtract:		name = "O_subtract";		break;
    765  1.1  skrll 	case O_eq:			name = "O_eq";			break;
    766  1.1  skrll 	case O_ne:			name = "O_ne";			break;
    767  1.1  skrll 	case O_lt:			name = "O_lt";			break;
    768  1.1  skrll 	case O_le:			name = "O_le";			break;
    769  1.1  skrll 	case O_ge:			name = "O_ge";			break;
    770  1.1  skrll 	case O_gt:			name = "O_gt";			break;
    771  1.1  skrll 	case O_logical_and:		name = "O_logical_and";		break;
    772  1.1  skrll 	case O_logical_or:		name = "O_logical_or";		break;
    773  1.1  skrll 	case O_index:			name = "O_index";		break;
    774  1.1  skrll 	case O_pregister:		name = "O_pregister";		break;
    775  1.1  skrll 	case O_cpregister:		name = "O_cpregister";		break;
    776  1.1  skrll 	case O_literal:			name = "O_literal";		break;
    777  1.1  skrll 	case O_lituse_addr:		name = "O_lituse_addr";		break;
    778  1.1  skrll 	case O_lituse_base:		name = "O_lituse_base";		break;
    779  1.1  skrll 	case O_lituse_bytoff:		name = "O_lituse_bytoff";	break;
    780  1.1  skrll 	case O_lituse_jsr:		name = "O_lituse_jsr";		break;
    781  1.1  skrll 	case O_lituse_tlsgd:		name = "O_lituse_tlsgd";	break;
    782  1.1  skrll 	case O_lituse_tlsldm:		name = "O_lituse_tlsldm";	break;
    783  1.1  skrll 	case O_lituse_jsrdirect:	name = "O_lituse_jsrdirect";	break;
    784  1.1  skrll 	case O_gpdisp:			name = "O_gpdisp";		break;
    785  1.1  skrll 	case O_gprelhigh:		name = "O_gprelhigh";		break;
    786  1.1  skrll 	case O_gprellow:		name = "O_gprellow";		break;
    787  1.1  skrll 	case O_gprel:			name = "O_gprel";		break;
    788  1.1  skrll 	case O_samegp:			name = "O_samegp";		break;
    789  1.1  skrll 	case O_tlsgd:			name = "O_tlsgd";		break;
    790  1.1  skrll 	case O_tlsldm:			name = "O_tlsldm";		break;
    791  1.1  skrll 	case O_gotdtprel:		name = "O_gotdtprel";		break;
    792  1.1  skrll 	case O_dtprelhi:		name = "O_dtprelhi";		break;
    793  1.1  skrll 	case O_dtprello:		name = "O_dtprello";		break;
    794  1.1  skrll 	case O_dtprel:			name = "O_dtprel";		break;
    795  1.1  skrll 	case O_gottprel:		name = "O_gottprel";		break;
    796  1.1  skrll 	case O_tprelhi:			name = "O_tprelhi";		break;
    797  1.1  skrll 	case O_tprello:			name = "O_tprello";		break;
    798  1.1  skrll 	case O_tprel:			name = "O_tprel";		break;
    799  1.1  skrll 	}
    800  1.1  skrll 
    801  1.1  skrll       fprintf (stderr, ", %s(%s, %s, %d)", name,
    802  1.1  skrll 	       (t->X_add_symbol) ? S_GET_NAME (t->X_add_symbol) : "--",
    803  1.1  skrll 	       (t->X_op_symbol) ? S_GET_NAME (t->X_op_symbol) : "--",
    804  1.1  skrll 	       (int) t->X_add_number);
    805  1.1  skrll     }
    806  1.1  skrll   fprintf (stderr, "\n");
    807  1.1  skrll   fflush (stderr);
    808  1.1  skrll }
    809  1.1  skrll #endif
    810  1.1  skrll 
    811  1.1  skrll /* Parse the arguments to an opcode.  */
    812  1.1  skrll 
    813  1.1  skrll static int
    814  1.1  skrll tokenize_arguments (char *str,
    815  1.1  skrll 		    expressionS tok[],
    816  1.1  skrll 		    int ntok)
    817  1.1  skrll {
    818  1.1  skrll   expressionS *end_tok = tok + ntok;
    819  1.1  skrll   char *old_input_line_pointer;
    820  1.1  skrll   int saw_comma = 0, saw_arg = 0;
    821  1.1  skrll #ifdef DEBUG_ALPHA
    822  1.1  skrll   expressionS *orig_tok = tok;
    823  1.1  skrll #endif
    824  1.1  skrll #ifdef RELOC_OP_P
    825  1.1  skrll   char *p;
    826  1.1  skrll   const struct alpha_reloc_op_tag *r;
    827  1.1  skrll   int c, i;
    828  1.1  skrll   size_t len;
    829  1.1  skrll   int reloc_found_p = 0;
    830  1.1  skrll #endif
    831  1.1  skrll 
    832  1.1  skrll   memset (tok, 0, sizeof (*tok) * ntok);
    833  1.1  skrll 
    834  1.1  skrll   /* Save and restore input_line_pointer around this function.  */
    835  1.1  skrll   old_input_line_pointer = input_line_pointer;
    836  1.1  skrll   input_line_pointer = str;
    837  1.1  skrll 
    838  1.1  skrll #ifdef RELOC_OP_P
    839  1.1  skrll   /* ??? Wrest control of ! away from the regular expression parser.  */
    840  1.1  skrll   is_end_of_line[(unsigned char) '!'] = 1;
    841  1.1  skrll #endif
    842  1.1  skrll 
    843  1.1  skrll   while (tok < end_tok && *input_line_pointer)
    844  1.1  skrll     {
    845  1.1  skrll       SKIP_WHITESPACE ();
    846  1.1  skrll       switch (*input_line_pointer)
    847  1.1  skrll 	{
    848  1.1  skrll 	case '\0':
    849  1.1  skrll 	  goto fini;
    850  1.1  skrll 
    851  1.1  skrll #ifdef RELOC_OP_P
    852  1.1  skrll 	case '!':
    853  1.1  skrll 	  /* A relocation operand can be placed after the normal operand on an
    854  1.1  skrll 	     assembly language statement, and has the following form:
    855  1.1  skrll 		!relocation_type!sequence_number.  */
    856  1.1  skrll 	  if (reloc_found_p)
    857  1.1  skrll 	    {
    858  1.1  skrll 	      /* Only support one relocation op per insn.  */
    859  1.1  skrll 	      as_bad (_("More than one relocation op per insn"));
    860  1.1  skrll 	      goto err_report;
    861  1.1  skrll 	    }
    862  1.1  skrll 
    863  1.1  skrll 	  if (!saw_arg)
    864  1.1  skrll 	    goto err;
    865  1.1  skrll 
    866  1.1  skrll 	  ++input_line_pointer;
    867  1.1  skrll 	  SKIP_WHITESPACE ();
    868  1.1  skrll 	  p = input_line_pointer;
    869  1.1  skrll 	  c = get_symbol_end ();
    870  1.1  skrll 
    871  1.1  skrll 	  /* Parse !relocation_type.  */
    872  1.1  skrll 	  len = input_line_pointer - p;
    873  1.1  skrll 	  if (len == 0)
    874  1.1  skrll 	    {
    875  1.1  skrll 	      as_bad (_("No relocation operand"));
    876  1.1  skrll 	      goto err_report;
    877  1.1  skrll 	    }
    878  1.1  skrll 
    879  1.1  skrll 	  r = &alpha_reloc_op[0];
    880  1.1  skrll 	  for (i = alpha_num_reloc_op - 1; i >= 0; i--, r++)
    881  1.1  skrll 	    if (len == r->length && memcmp (p, r->name, len) == 0)
    882  1.1  skrll 	      break;
    883  1.1  skrll 	  if (i < 0)
    884  1.1  skrll 	    {
    885  1.1  skrll 	      as_bad (_("Unknown relocation operand: !%s"), p);
    886  1.1  skrll 	      goto err_report;
    887  1.1  skrll 	    }
    888  1.1  skrll 
    889  1.1  skrll 	  *input_line_pointer = c;
    890  1.1  skrll 	  SKIP_WHITESPACE ();
    891  1.1  skrll 	  if (*input_line_pointer != '!')
    892  1.1  skrll 	    {
    893  1.1  skrll 	      if (r->require_seq)
    894  1.1  skrll 		{
    895  1.1  skrll 		  as_bad (_("no sequence number after !%s"), p);
    896  1.1  skrll 		  goto err_report;
    897  1.1  skrll 		}
    898  1.1  skrll 
    899  1.1  skrll 	      tok->X_add_number = 0;
    900  1.1  skrll 	    }
    901  1.1  skrll 	  else
    902  1.1  skrll 	    {
    903  1.1  skrll 	      if (! r->allow_seq)
    904  1.1  skrll 		{
    905  1.1  skrll 		  as_bad (_("!%s does not use a sequence number"), p);
    906  1.1  skrll 		  goto err_report;
    907  1.1  skrll 		}
    908  1.1  skrll 
    909  1.1  skrll 	      input_line_pointer++;
    910  1.1  skrll 
    911  1.1  skrll 	      /* Parse !sequence_number.  */
    912  1.1  skrll 	      expression (tok);
    913  1.1  skrll 	      if (tok->X_op != O_constant || tok->X_add_number <= 0)
    914  1.1  skrll 		{
    915  1.1  skrll 		  as_bad (_("Bad sequence number: !%s!%s"),
    916  1.1  skrll 			  r->name, input_line_pointer);
    917  1.1  skrll 		  goto err_report;
    918  1.1  skrll 		}
    919  1.1  skrll 	    }
    920  1.1  skrll 
    921  1.1  skrll 	  tok->X_op = r->op;
    922  1.1  skrll 	  reloc_found_p = 1;
    923  1.1  skrll 	  ++tok;
    924  1.1  skrll 	  break;
    925  1.1  skrll #endif /* RELOC_OP_P */
    926  1.1  skrll 
    927  1.1  skrll 	case ',':
    928  1.1  skrll 	  ++input_line_pointer;
    929  1.1  skrll 	  if (saw_comma || !saw_arg)
    930  1.1  skrll 	    goto err;
    931  1.1  skrll 	  saw_comma = 1;
    932  1.1  skrll 	  break;
    933  1.1  skrll 
    934  1.1  skrll 	case '(':
    935  1.1  skrll 	  {
    936  1.1  skrll 	    char *hold = input_line_pointer++;
    937  1.1  skrll 
    938  1.1  skrll 	    /* First try for parenthesized register ...  */
    939  1.1  skrll 	    expression (tok);
    940  1.1  skrll 	    if (*input_line_pointer == ')' && tok->X_op == O_register)
    941  1.1  skrll 	      {
    942  1.1  skrll 		tok->X_op = (saw_comma ? O_cpregister : O_pregister);
    943  1.1  skrll 		saw_comma = 0;
    944  1.1  skrll 		saw_arg = 1;
    945  1.1  skrll 		++input_line_pointer;
    946  1.1  skrll 		++tok;
    947  1.1  skrll 		break;
    948  1.1  skrll 	      }
    949  1.1  skrll 
    950  1.1  skrll 	    /* ... then fall through to plain expression.  */
    951  1.1  skrll 	    input_line_pointer = hold;
    952  1.1  skrll 	  }
    953  1.1  skrll 
    954  1.1  skrll 	default:
    955  1.1  skrll 	  if (saw_arg && !saw_comma)
    956  1.1  skrll 	    goto err;
    957  1.1  skrll 
    958  1.1  skrll 	  expression (tok);
    959  1.1  skrll 	  if (tok->X_op == O_illegal || tok->X_op == O_absent)
    960  1.1  skrll 	    goto err;
    961  1.1  skrll 
    962  1.1  skrll 	  saw_comma = 0;
    963  1.1  skrll 	  saw_arg = 1;
    964  1.1  skrll 	  ++tok;
    965  1.1  skrll 	  break;
    966  1.1  skrll 	}
    967  1.1  skrll     }
    968  1.1  skrll 
    969  1.1  skrll fini:
    970  1.1  skrll   if (saw_comma)
    971  1.1  skrll     goto err;
    972  1.1  skrll   input_line_pointer = old_input_line_pointer;
    973  1.1  skrll 
    974  1.1  skrll #ifdef DEBUG_ALPHA
    975  1.1  skrll   debug_exp (orig_tok, ntok - (end_tok - tok));
    976  1.1  skrll #endif
    977  1.1  skrll #ifdef RELOC_OP_P
    978  1.1  skrll   is_end_of_line[(unsigned char) '!'] = 0;
    979  1.1  skrll #endif
    980  1.1  skrll 
    981  1.1  skrll   return ntok - (end_tok - tok);
    982  1.1  skrll 
    983  1.1  skrll err:
    984  1.1  skrll #ifdef RELOC_OP_P
    985  1.1  skrll   is_end_of_line[(unsigned char) '!'] = 0;
    986  1.1  skrll #endif
    987  1.1  skrll   input_line_pointer = old_input_line_pointer;
    988  1.1  skrll   return TOKENIZE_ERROR;
    989  1.1  skrll 
    990  1.1  skrll #ifdef RELOC_OP_P
    991  1.1  skrll err_report:
    992  1.1  skrll   is_end_of_line[(unsigned char) '!'] = 0;
    993  1.1  skrll #endif
    994  1.1  skrll   input_line_pointer = old_input_line_pointer;
    995  1.1  skrll   return TOKENIZE_ERROR_REPORT;
    996  1.1  skrll }
    997  1.1  skrll 
    998  1.1  skrll /* Search forward through all variants of an opcode looking for a
    999  1.1  skrll    syntax match.  */
   1000  1.1  skrll 
   1001  1.1  skrll static const struct alpha_opcode *
   1002  1.1  skrll find_opcode_match (const struct alpha_opcode *first_opcode,
   1003  1.1  skrll 		   const expressionS *tok,
   1004  1.1  skrll 		   int *pntok,
   1005  1.1  skrll 		   int *pcpumatch)
   1006  1.1  skrll {
   1007  1.1  skrll   const struct alpha_opcode *opcode = first_opcode;
   1008  1.1  skrll   int ntok = *pntok;
   1009  1.1  skrll   int got_cpu_match = 0;
   1010  1.1  skrll 
   1011  1.1  skrll   do
   1012  1.1  skrll     {
   1013  1.1  skrll       const unsigned char *opidx;
   1014  1.1  skrll       int tokidx = 0;
   1015  1.1  skrll 
   1016  1.1  skrll       /* Don't match opcodes that don't exist on this architecture.  */
   1017  1.1  skrll       if (!(opcode->flags & alpha_target))
   1018  1.1  skrll 	goto match_failed;
   1019  1.1  skrll 
   1020  1.1  skrll       got_cpu_match = 1;
   1021  1.1  skrll 
   1022  1.1  skrll       for (opidx = opcode->operands; *opidx; ++opidx)
   1023  1.1  skrll 	{
   1024  1.1  skrll 	  const struct alpha_operand *operand = &alpha_operands[*opidx];
   1025  1.1  skrll 
   1026  1.1  skrll 	  /* Only take input from real operands.  */
   1027  1.1  skrll 	  if (operand->flags & AXP_OPERAND_FAKE)
   1028  1.1  skrll 	    continue;
   1029  1.1  skrll 
   1030  1.1  skrll 	  /* When we expect input, make sure we have it.  */
   1031  1.1  skrll 	  if (tokidx >= ntok)
   1032  1.1  skrll 	    {
   1033  1.1  skrll 	      if ((operand->flags & AXP_OPERAND_OPTIONAL_MASK) == 0)
   1034  1.1  skrll 		goto match_failed;
   1035  1.1  skrll 	      continue;
   1036  1.1  skrll 	    }
   1037  1.1  skrll 
   1038  1.1  skrll 	  /* Match operand type with expression type.  */
   1039  1.1  skrll 	  switch (operand->flags & AXP_OPERAND_TYPECHECK_MASK)
   1040  1.1  skrll 	    {
   1041  1.1  skrll 	    case AXP_OPERAND_IR:
   1042  1.1  skrll 	      if (tok[tokidx].X_op != O_register
   1043  1.1  skrll 		  || !is_ir_num (tok[tokidx].X_add_number))
   1044  1.1  skrll 		goto match_failed;
   1045  1.1  skrll 	      break;
   1046  1.1  skrll 	    case AXP_OPERAND_FPR:
   1047  1.1  skrll 	      if (tok[tokidx].X_op != O_register
   1048  1.1  skrll 		  || !is_fpr_num (tok[tokidx].X_add_number))
   1049  1.1  skrll 		goto match_failed;
   1050  1.1  skrll 	      break;
   1051  1.1  skrll 	    case AXP_OPERAND_IR | AXP_OPERAND_PARENS:
   1052  1.1  skrll 	      if (tok[tokidx].X_op != O_pregister
   1053  1.1  skrll 		  || !is_ir_num (tok[tokidx].X_add_number))
   1054  1.1  skrll 		goto match_failed;
   1055  1.1  skrll 	      break;
   1056  1.1  skrll 	    case AXP_OPERAND_IR | AXP_OPERAND_PARENS | AXP_OPERAND_COMMA:
   1057  1.1  skrll 	      if (tok[tokidx].X_op != O_cpregister
   1058  1.1  skrll 		  || !is_ir_num (tok[tokidx].X_add_number))
   1059  1.1  skrll 		goto match_failed;
   1060  1.1  skrll 	      break;
   1061  1.1  skrll 
   1062  1.1  skrll 	    case AXP_OPERAND_RELATIVE:
   1063  1.1  skrll 	    case AXP_OPERAND_SIGNED:
   1064  1.1  skrll 	    case AXP_OPERAND_UNSIGNED:
   1065  1.1  skrll 	      switch (tok[tokidx].X_op)
   1066  1.1  skrll 		{
   1067  1.1  skrll 		case O_illegal:
   1068  1.1  skrll 		case O_absent:
   1069  1.1  skrll 		case O_register:
   1070  1.1  skrll 		case O_pregister:
   1071  1.1  skrll 		case O_cpregister:
   1072  1.1  skrll 		  goto match_failed;
   1073  1.1  skrll 
   1074  1.1  skrll 		default:
   1075  1.1  skrll 		  break;
   1076  1.1  skrll 		}
   1077  1.1  skrll 	      break;
   1078  1.1  skrll 
   1079  1.1  skrll 	    default:
   1080  1.1  skrll 	      /* Everything else should have been fake.  */
   1081  1.1  skrll 	      abort ();
   1082  1.1  skrll 	    }
   1083  1.1  skrll 	  ++tokidx;
   1084  1.1  skrll 	}
   1085  1.1  skrll 
   1086  1.1  skrll       /* Possible match -- did we use all of our input?  */
   1087  1.1  skrll       if (tokidx == ntok)
   1088  1.1  skrll 	{
   1089  1.1  skrll 	  *pntok = ntok;
   1090  1.1  skrll 	  return opcode;
   1091  1.1  skrll 	}
   1092  1.1  skrll 
   1093  1.1  skrll     match_failed:;
   1094  1.1  skrll     }
   1095  1.1  skrll   while (++opcode - alpha_opcodes < (int) alpha_num_opcodes
   1096  1.1  skrll 	 && !strcmp (opcode->name, first_opcode->name));
   1097  1.1  skrll 
   1098  1.1  skrll   if (*pcpumatch)
   1099  1.1  skrll     *pcpumatch = got_cpu_match;
   1100  1.1  skrll 
   1101  1.1  skrll   return NULL;
   1102  1.1  skrll }
   1103  1.1  skrll 
   1104  1.1  skrll /* Given an opcode name and a pre-tokenized set of arguments, assemble
   1105  1.1  skrll    the insn, but do not emit it.
   1106  1.1  skrll 
   1107  1.1  skrll    Note that this implies no macros allowed, since we can't store more
   1108  1.1  skrll    than one insn in an insn structure.  */
   1109  1.1  skrll 
   1110  1.1  skrll static void
   1111  1.1  skrll assemble_tokens_to_insn (const char *opname,
   1112  1.1  skrll 			 const expressionS *tok,
   1113  1.1  skrll 			 int ntok,
   1114  1.1  skrll 			 struct alpha_insn *insn)
   1115  1.1  skrll {
   1116  1.1  skrll   const struct alpha_opcode *opcode;
   1117  1.1  skrll 
   1118  1.1  skrll   /* Search opcodes.  */
   1119  1.1  skrll   opcode = (const struct alpha_opcode *) hash_find (alpha_opcode_hash, opname);
   1120  1.1  skrll   if (opcode)
   1121  1.1  skrll     {
   1122  1.1  skrll       int cpumatch;
   1123  1.1  skrll       opcode = find_opcode_match (opcode, tok, &ntok, &cpumatch);
   1124  1.1  skrll       if (opcode)
   1125  1.1  skrll 	{
   1126  1.1  skrll 	  assemble_insn (opcode, tok, ntok, insn, BFD_RELOC_UNUSED);
   1127  1.1  skrll 	  return;
   1128  1.1  skrll 	}
   1129  1.1  skrll       else if (cpumatch)
   1130  1.1  skrll 	as_bad (_("inappropriate arguments for opcode `%s'"), opname);
   1131  1.1  skrll       else
   1132  1.1  skrll 	as_bad (_("opcode `%s' not supported for target %s"), opname,
   1133  1.1  skrll 		alpha_target_name);
   1134  1.1  skrll     }
   1135  1.1  skrll   else
   1136  1.1  skrll     as_bad (_("unknown opcode `%s'"), opname);
   1137  1.1  skrll }
   1138  1.1  skrll 
   1139  1.1  skrll /* Build a BFD section with its flags set appropriately for the .lita,
   1140  1.1  skrll    .lit8, or .lit4 sections.  */
   1141  1.1  skrll 
   1142  1.1  skrll static void
   1143  1.1  skrll create_literal_section (const char *name,
   1144  1.1  skrll 			segT *secp,
   1145  1.1  skrll 			symbolS **symp)
   1146  1.1  skrll {
   1147  1.1  skrll   segT current_section = now_seg;
   1148  1.1  skrll   int current_subsec = now_subseg;
   1149  1.1  skrll   segT new_sec;
   1150  1.1  skrll 
   1151  1.1  skrll   *secp = new_sec = subseg_new (name, 0);
   1152  1.1  skrll   subseg_set (current_section, current_subsec);
   1153  1.1  skrll   bfd_set_section_alignment (stdoutput, new_sec, 4);
   1154  1.1  skrll   bfd_set_section_flags (stdoutput, new_sec,
   1155  1.1  skrll 			 SEC_RELOC | SEC_ALLOC | SEC_LOAD | SEC_READONLY
   1156  1.1  skrll 			 | SEC_DATA);
   1157  1.1  skrll 
   1158  1.1  skrll   S_CLEAR_EXTERNAL (*symp = section_symbol (new_sec));
   1159  1.1  skrll }
   1160  1.1  skrll 
   1161  1.1  skrll /* Load a (partial) expression into a target register.
   1162  1.1  skrll 
   1163  1.1  skrll    If poffset is not null, after the call it will either contain
   1164  1.1  skrll    O_constant 0, or a 16-bit offset appropriate for any MEM format
   1165  1.1  skrll    instruction.  In addition, pbasereg will be modified to point to
   1166  1.1  skrll    the base register to use in that MEM format instruction.
   1167  1.1  skrll 
   1168  1.1  skrll    In any case, *pbasereg should contain a base register to add to the
   1169  1.1  skrll    expression.  This will normally be either AXP_REG_ZERO or
   1170  1.1  skrll    alpha_gp_register.  Symbol addresses will always be loaded via $gp,
   1171  1.1  skrll    so "foo($0)" is interpreted as adding the address of foo to $0;
   1172  1.1  skrll    i.e. "ldq $targ, LIT($gp); addq $targ, $0, $targ".  Odd, perhaps,
   1173  1.1  skrll    but this is what OSF/1 does.
   1174  1.1  skrll 
   1175  1.1  skrll    If explicit relocations of the form !literal!<number> are allowed,
   1176  1.1  skrll    and used, then explicit_reloc with be an expression pointer.
   1177  1.1  skrll 
   1178  1.1  skrll    Finally, the return value is nonzero if the calling macro may emit
   1179  1.1  skrll    a LITUSE reloc if otherwise appropriate; the return value is the
   1180  1.1  skrll    sequence number to use.  */
   1181  1.1  skrll 
   1182  1.1  skrll static long
   1183  1.1  skrll load_expression (int targreg,
   1184  1.1  skrll 		 const expressionS *exp,
   1185  1.1  skrll 		 int *pbasereg,
   1186  1.1  skrll 		 expressionS *poffset)
   1187  1.1  skrll {
   1188  1.1  skrll   long emit_lituse = 0;
   1189  1.1  skrll   offsetT addend = exp->X_add_number;
   1190  1.1  skrll   int basereg = *pbasereg;
   1191  1.1  skrll   struct alpha_insn insn;
   1192  1.1  skrll   expressionS newtok[3];
   1193  1.1  skrll 
   1194  1.1  skrll   switch (exp->X_op)
   1195  1.1  skrll     {
   1196  1.1  skrll     case O_symbol:
   1197  1.1  skrll       {
   1198  1.1  skrll #ifdef OBJ_ECOFF
   1199  1.1  skrll 	offsetT lit;
   1200  1.1  skrll 
   1201  1.1  skrll 	/* Attempt to reduce .lit load by splitting the offset from
   1202  1.1  skrll 	   its symbol when possible, but don't create a situation in
   1203  1.1  skrll 	   which we'd fail.  */
   1204  1.1  skrll 	if (!range_signed_32 (addend) &&
   1205  1.1  skrll 	    (alpha_noat_on || targreg == AXP_REG_AT))
   1206  1.1  skrll 	  {
   1207  1.1  skrll 	    lit = add_to_literal_pool (exp->X_add_symbol, addend,
   1208  1.1  skrll 				       alpha_lita_section, 8);
   1209  1.1  skrll 	    addend = 0;
   1210  1.1  skrll 	  }
   1211  1.1  skrll 	else
   1212  1.1  skrll 	  lit = add_to_literal_pool (exp->X_add_symbol, 0,
   1213  1.1  skrll 				     alpha_lita_section, 8);
   1214  1.1  skrll 
   1215  1.1  skrll 	if (lit >= 0x8000)
   1216  1.1  skrll 	  as_fatal (_("overflow in literal (.lita) table"));
   1217  1.1  skrll 
   1218  1.1  skrll 	/* Emit "ldq r, lit(gp)".  */
   1219  1.1  skrll 
   1220  1.1  skrll 	if (basereg != alpha_gp_register && targreg == basereg)
   1221  1.1  skrll 	  {
   1222  1.1  skrll 	    if (alpha_noat_on)
   1223  1.1  skrll 	      as_bad (_("macro requires $at register while noat in effect"));
   1224  1.1  skrll 	    if (targreg == AXP_REG_AT)
   1225  1.1  skrll 	      as_bad (_("macro requires $at while $at in use"));
   1226  1.1  skrll 
   1227  1.1  skrll 	    set_tok_reg (newtok[0], AXP_REG_AT);
   1228  1.1  skrll 	  }
   1229  1.1  skrll 	else
   1230  1.1  skrll 	  set_tok_reg (newtok[0], targreg);
   1231  1.1  skrll 
   1232  1.1  skrll 	set_tok_sym (newtok[1], alpha_lita_symbol, lit);
   1233  1.1  skrll 	set_tok_preg (newtok[2], alpha_gp_register);
   1234  1.1  skrll 
   1235  1.1  skrll 	assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
   1236  1.1  skrll 
   1237  1.1  skrll 	assert (insn.nfixups == 1);
   1238  1.1  skrll 	insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITERAL;
   1239  1.1  skrll 	insn.sequence = emit_lituse = next_sequence_num--;
   1240  1.1  skrll #endif /* OBJ_ECOFF */
   1241  1.1  skrll #ifdef OBJ_ELF
   1242  1.1  skrll 	/* Emit "ldq r, gotoff(gp)".  */
   1243  1.1  skrll 
   1244  1.1  skrll 	if (basereg != alpha_gp_register && targreg == basereg)
   1245  1.1  skrll 	  {
   1246  1.1  skrll 	    if (alpha_noat_on)
   1247  1.1  skrll 	      as_bad (_("macro requires $at register while noat in effect"));
   1248  1.1  skrll 	    if (targreg == AXP_REG_AT)
   1249  1.1  skrll 	      as_bad (_("macro requires $at while $at in use"));
   1250  1.1  skrll 
   1251  1.1  skrll 	    set_tok_reg (newtok[0], AXP_REG_AT);
   1252  1.1  skrll 	  }
   1253  1.1  skrll 	else
   1254  1.1  skrll 	  set_tok_reg (newtok[0], targreg);
   1255  1.1  skrll 
   1256  1.1  skrll 	/* XXX: Disable this .got minimizing optimization so that we can get
   1257  1.1  skrll 	   better instruction offset knowledge in the compiler.  This happens
   1258  1.1  skrll 	   very infrequently anyway.  */
   1259  1.1  skrll 	if (1
   1260  1.1  skrll 	    || (!range_signed_32 (addend)
   1261  1.1  skrll 		&& (alpha_noat_on || targreg == AXP_REG_AT)))
   1262  1.1  skrll 	  {
   1263  1.1  skrll 	    newtok[1] = *exp;
   1264  1.1  skrll 	    addend = 0;
   1265  1.1  skrll 	  }
   1266  1.1  skrll 	else
   1267  1.1  skrll 	  set_tok_sym (newtok[1], exp->X_add_symbol, 0);
   1268  1.1  skrll 
   1269  1.1  skrll 	set_tok_preg (newtok[2], alpha_gp_register);
   1270  1.1  skrll 
   1271  1.1  skrll 	assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
   1272  1.1  skrll 
   1273  1.1  skrll 	assert (insn.nfixups == 1);
   1274  1.1  skrll 	insn.fixups[0].reloc = BFD_RELOC_ALPHA_ELF_LITERAL;
   1275  1.1  skrll 	insn.sequence = emit_lituse = next_sequence_num--;
   1276  1.1  skrll #endif /* OBJ_ELF */
   1277  1.1  skrll #ifdef OBJ_EVAX
   1278  1.1  skrll 	offsetT link;
   1279  1.1  skrll 
   1280  1.1  skrll 	/* Find symbol or symbol pointer in link section.  */
   1281  1.1  skrll 
   1282  1.1  skrll 	if (exp->X_add_symbol == alpha_evax_proc.symbol)
   1283  1.1  skrll 	  {
   1284  1.1  skrll 	    if (range_signed_16 (addend))
   1285  1.1  skrll 	      {
   1286  1.1  skrll 		set_tok_reg (newtok[0], targreg);
   1287  1.1  skrll 		set_tok_const (newtok[1], addend);
   1288  1.1  skrll 		set_tok_preg (newtok[2], basereg);
   1289  1.1  skrll 		assemble_tokens_to_insn ("lda", newtok, 3, &insn);
   1290  1.1  skrll 		addend = 0;
   1291  1.1  skrll 	      }
   1292  1.1  skrll 	    else
   1293  1.1  skrll 	      {
   1294  1.1  skrll 		set_tok_reg (newtok[0], targreg);
   1295  1.1  skrll 		set_tok_const (newtok[1], 0);
   1296  1.1  skrll 		set_tok_preg (newtok[2], basereg);
   1297  1.1  skrll 		assemble_tokens_to_insn ("lda", newtok, 3, &insn);
   1298  1.1  skrll 	      }
   1299  1.1  skrll 	  }
   1300  1.1  skrll 	else
   1301  1.1  skrll 	  {
   1302  1.1  skrll 	    if (!range_signed_32 (addend))
   1303  1.1  skrll 	      {
   1304  1.1  skrll 		link = add_to_link_pool (alpha_evax_proc.symbol,
   1305  1.1  skrll 					 exp->X_add_symbol, addend);
   1306  1.1  skrll 		addend = 0;
   1307  1.1  skrll 	      }
   1308  1.1  skrll 	    else
   1309  1.1  skrll 	      link = add_to_link_pool (alpha_evax_proc.symbol,
   1310  1.1  skrll 				       exp->X_add_symbol, 0);
   1311  1.1  skrll 
   1312  1.1  skrll 	    set_tok_reg (newtok[0], targreg);
   1313  1.1  skrll 	    set_tok_const (newtok[1], link);
   1314  1.1  skrll 	    set_tok_preg (newtok[2], basereg);
   1315  1.1  skrll 	    assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
   1316  1.1  skrll 	  }
   1317  1.1  skrll #endif /* OBJ_EVAX */
   1318  1.1  skrll 
   1319  1.1  skrll 	emit_insn (&insn);
   1320  1.1  skrll 
   1321  1.1  skrll #ifndef OBJ_EVAX
   1322  1.1  skrll 	if (basereg != alpha_gp_register && basereg != AXP_REG_ZERO)
   1323  1.1  skrll 	  {
   1324  1.1  skrll 	    /* Emit "addq r, base, r".  */
   1325  1.1  skrll 
   1326  1.1  skrll 	    set_tok_reg (newtok[1], basereg);
   1327  1.1  skrll 	    set_tok_reg (newtok[2], targreg);
   1328  1.1  skrll 	    assemble_tokens ("addq", newtok, 3, 0);
   1329  1.1  skrll 	  }
   1330  1.1  skrll #endif
   1331  1.1  skrll 	basereg = targreg;
   1332  1.1  skrll       }
   1333  1.1  skrll       break;
   1334  1.1  skrll 
   1335  1.1  skrll     case O_constant:
   1336  1.1  skrll       break;
   1337  1.1  skrll 
   1338  1.1  skrll     case O_subtract:
   1339  1.1  skrll       /* Assume that this difference expression will be resolved to an
   1340  1.1  skrll 	 absolute value and that that value will fit in 16 bits.  */
   1341  1.1  skrll 
   1342  1.1  skrll       set_tok_reg (newtok[0], targreg);
   1343  1.1  skrll       newtok[1] = *exp;
   1344  1.1  skrll       set_tok_preg (newtok[2], basereg);
   1345  1.1  skrll       assemble_tokens ("lda", newtok, 3, 0);
   1346  1.1  skrll 
   1347  1.1  skrll       if (poffset)
   1348  1.1  skrll 	set_tok_const (*poffset, 0);
   1349  1.1  skrll       return 0;
   1350  1.1  skrll 
   1351  1.1  skrll     case O_big:
   1352  1.1  skrll       if (exp->X_add_number > 0)
   1353  1.1  skrll 	as_bad (_("bignum invalid; zero assumed"));
   1354  1.1  skrll       else
   1355  1.1  skrll 	as_bad (_("floating point number invalid; zero assumed"));
   1356  1.1  skrll       addend = 0;
   1357  1.1  skrll       break;
   1358  1.1  skrll 
   1359  1.1  skrll     default:
   1360  1.1  skrll       as_bad (_("can't handle expression"));
   1361  1.1  skrll       addend = 0;
   1362  1.1  skrll       break;
   1363  1.1  skrll     }
   1364  1.1  skrll 
   1365  1.1  skrll   if (!range_signed_32 (addend))
   1366  1.1  skrll     {
   1367  1.1  skrll       offsetT lit;
   1368  1.1  skrll       long seq_num = next_sequence_num--;
   1369  1.1  skrll 
   1370  1.1  skrll       /* For 64-bit addends, just put it in the literal pool.  */
   1371  1.1  skrll #ifdef OBJ_EVAX
   1372  1.1  skrll       /* Emit "ldq targreg, lit(basereg)".  */
   1373  1.1  skrll       lit = add_to_link_pool (alpha_evax_proc.symbol,
   1374  1.1  skrll 			      section_symbol (absolute_section), addend);
   1375  1.1  skrll       set_tok_reg (newtok[0], targreg);
   1376  1.1  skrll       set_tok_const (newtok[1], lit);
   1377  1.1  skrll       set_tok_preg (newtok[2], alpha_gp_register);
   1378  1.1  skrll       assemble_tokens ("ldq", newtok, 3, 0);
   1379  1.1  skrll #else
   1380  1.1  skrll 
   1381  1.1  skrll       if (alpha_lit8_section == NULL)
   1382  1.1  skrll 	{
   1383  1.1  skrll 	  create_literal_section (".lit8",
   1384  1.1  skrll 				  &alpha_lit8_section,
   1385  1.1  skrll 				  &alpha_lit8_symbol);
   1386  1.1  skrll 
   1387  1.1  skrll #ifdef OBJ_ECOFF
   1388  1.1  skrll 	  alpha_lit8_literal = add_to_literal_pool (alpha_lit8_symbol, 0x8000,
   1389  1.1  skrll 						    alpha_lita_section, 8);
   1390  1.1  skrll 	  if (alpha_lit8_literal >= 0x8000)
   1391  1.1  skrll 	    as_fatal (_("overflow in literal (.lita) table"));
   1392  1.1  skrll #endif
   1393  1.1  skrll 	}
   1394  1.1  skrll 
   1395  1.1  skrll       lit = add_to_literal_pool (NULL, addend, alpha_lit8_section, 8) - 0x8000;
   1396  1.1  skrll       if (lit >= 0x8000)
   1397  1.1  skrll 	as_fatal (_("overflow in literal (.lit8) table"));
   1398  1.1  skrll 
   1399  1.1  skrll       /* Emit "lda litreg, .lit8+0x8000".  */
   1400  1.1  skrll 
   1401  1.1  skrll       if (targreg == basereg)
   1402  1.1  skrll 	{
   1403  1.1  skrll 	  if (alpha_noat_on)
   1404  1.1  skrll 	    as_bad (_("macro requires $at register while noat in effect"));
   1405  1.1  skrll 	  if (targreg == AXP_REG_AT)
   1406  1.1  skrll 	    as_bad (_("macro requires $at while $at in use"));
   1407  1.1  skrll 
   1408  1.1  skrll 	  set_tok_reg (newtok[0], AXP_REG_AT);
   1409  1.1  skrll 	}
   1410  1.1  skrll       else
   1411  1.1  skrll 	set_tok_reg (newtok[0], targreg);
   1412  1.1  skrll #ifdef OBJ_ECOFF
   1413  1.1  skrll       set_tok_sym (newtok[1], alpha_lita_symbol, alpha_lit8_literal);
   1414  1.1  skrll #endif
   1415  1.1  skrll #ifdef OBJ_ELF
   1416  1.1  skrll       set_tok_sym (newtok[1], alpha_lit8_symbol, 0x8000);
   1417  1.1  skrll #endif
   1418  1.1  skrll       set_tok_preg (newtok[2], alpha_gp_register);
   1419  1.1  skrll 
   1420  1.1  skrll       assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
   1421  1.1  skrll 
   1422  1.1  skrll       assert (insn.nfixups == 1);
   1423  1.1  skrll #ifdef OBJ_ECOFF
   1424  1.1  skrll       insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITERAL;
   1425  1.1  skrll #endif
   1426  1.1  skrll #ifdef OBJ_ELF
   1427  1.1  skrll       insn.fixups[0].reloc = BFD_RELOC_ALPHA_ELF_LITERAL;
   1428  1.1  skrll #endif
   1429  1.1  skrll       insn.sequence = seq_num;
   1430  1.1  skrll 
   1431  1.1  skrll       emit_insn (&insn);
   1432  1.1  skrll 
   1433  1.1  skrll       /* Emit "ldq litreg, lit(litreg)".  */
   1434  1.1  skrll 
   1435  1.1  skrll       set_tok_const (newtok[1], lit);
   1436  1.1  skrll       set_tok_preg (newtok[2], newtok[0].X_add_number);
   1437  1.1  skrll 
   1438  1.1  skrll       assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
   1439  1.1  skrll 
   1440  1.1  skrll       assert (insn.nfixups < MAX_INSN_FIXUPS);
   1441  1.1  skrll       insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
   1442  1.1  skrll       insn.fixups[insn.nfixups].exp.X_op = O_absent;
   1443  1.1  skrll       insn.nfixups++;
   1444  1.1  skrll       insn.sequence = seq_num;
   1445  1.1  skrll       emit_lituse = 0;
   1446  1.1  skrll 
   1447  1.1  skrll       emit_insn (&insn);
   1448  1.1  skrll 
   1449  1.1  skrll       /* Emit "addq litreg, base, target".  */
   1450  1.1  skrll 
   1451  1.1  skrll       if (basereg != AXP_REG_ZERO)
   1452  1.1  skrll 	{
   1453  1.1  skrll 	  set_tok_reg (newtok[1], basereg);
   1454  1.1  skrll 	  set_tok_reg (newtok[2], targreg);
   1455  1.1  skrll 	  assemble_tokens ("addq", newtok, 3, 0);
   1456  1.1  skrll 	}
   1457  1.1  skrll #endif /* !OBJ_EVAX */
   1458  1.1  skrll 
   1459  1.1  skrll       if (poffset)
   1460  1.1  skrll 	set_tok_const (*poffset, 0);
   1461  1.1  skrll       *pbasereg = targreg;
   1462  1.1  skrll     }
   1463  1.1  skrll   else
   1464  1.1  skrll     {
   1465  1.1  skrll       offsetT low, high, extra, tmp;
   1466  1.1  skrll 
   1467  1.1  skrll       /* For 32-bit operands, break up the addend.  */
   1468  1.1  skrll 
   1469  1.1  skrll       low = sign_extend_16 (addend);
   1470  1.1  skrll       tmp = addend - low;
   1471  1.1  skrll       high = sign_extend_16 (tmp >> 16);
   1472  1.1  skrll 
   1473  1.1  skrll       if (tmp - (high << 16))
   1474  1.1  skrll 	{
   1475  1.1  skrll 	  extra = 0x4000;
   1476  1.1  skrll 	  tmp -= 0x40000000;
   1477  1.1  skrll 	  high = sign_extend_16 (tmp >> 16);
   1478  1.1  skrll 	}
   1479  1.1  skrll       else
   1480  1.1  skrll 	extra = 0;
   1481  1.1  skrll 
   1482  1.1  skrll       set_tok_reg (newtok[0], targreg);
   1483  1.1  skrll       set_tok_preg (newtok[2], basereg);
   1484  1.1  skrll 
   1485  1.1  skrll       if (extra)
   1486  1.1  skrll 	{
   1487  1.1  skrll 	  /* Emit "ldah r, extra(r).  */
   1488  1.1  skrll 	  set_tok_const (newtok[1], extra);
   1489  1.1  skrll 	  assemble_tokens ("ldah", newtok, 3, 0);
   1490  1.1  skrll 	  set_tok_preg (newtok[2], basereg = targreg);
   1491  1.1  skrll 	}
   1492  1.1  skrll 
   1493  1.1  skrll       if (high)
   1494  1.1  skrll 	{
   1495  1.1  skrll 	  /* Emit "ldah r, high(r).  */
   1496  1.1  skrll 	  set_tok_const (newtok[1], high);
   1497  1.1  skrll 	  assemble_tokens ("ldah", newtok, 3, 0);
   1498  1.1  skrll 	  basereg = targreg;
   1499  1.1  skrll 	  set_tok_preg (newtok[2], basereg);
   1500  1.1  skrll 	}
   1501  1.1  skrll 
   1502  1.1  skrll       if ((low && !poffset) || (!poffset && basereg != targreg))
   1503  1.1  skrll 	{
   1504  1.1  skrll 	  /* Emit "lda r, low(base)".  */
   1505  1.1  skrll 	  set_tok_const (newtok[1], low);
   1506  1.1  skrll 	  assemble_tokens ("lda", newtok, 3, 0);
   1507  1.1  skrll 	  basereg = targreg;
   1508  1.1  skrll 	  low = 0;
   1509  1.1  skrll 	}
   1510  1.1  skrll 
   1511  1.1  skrll       if (poffset)
   1512  1.1  skrll 	set_tok_const (*poffset, low);
   1513  1.1  skrll       *pbasereg = basereg;
   1514  1.1  skrll     }
   1515  1.1  skrll 
   1516  1.1  skrll   return emit_lituse;
   1517  1.1  skrll }
   1518  1.1  skrll 
   1519  1.1  skrll /* The lda macro differs from the lda instruction in that it handles
   1520  1.1  skrll    most simple expressions, particularly symbol address loads and
   1521  1.1  skrll    large constants.  */
   1522  1.1  skrll 
   1523  1.1  skrll static void
   1524  1.1  skrll emit_lda (const expressionS *tok,
   1525  1.1  skrll 	  int ntok,
   1526  1.1  skrll 	  const void * unused ATTRIBUTE_UNUSED)
   1527  1.1  skrll {
   1528  1.1  skrll   int basereg;
   1529  1.1  skrll 
   1530  1.1  skrll   if (ntok == 2)
   1531  1.1  skrll     basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
   1532  1.1  skrll   else
   1533  1.1  skrll     basereg = tok[2].X_add_number;
   1534  1.1  skrll 
   1535  1.1  skrll   (void) load_expression (tok[0].X_add_number, &tok[1], &basereg, NULL);
   1536  1.1  skrll }
   1537  1.1  skrll 
   1538  1.1  skrll /* The ldah macro differs from the ldah instruction in that it has $31
   1539  1.1  skrll    as an implied base register.  */
   1540  1.1  skrll 
   1541  1.1  skrll static void
   1542  1.1  skrll emit_ldah (const expressionS *tok,
   1543  1.1  skrll 	   int ntok ATTRIBUTE_UNUSED,
   1544  1.1  skrll 	   const void * unused ATTRIBUTE_UNUSED)
   1545  1.1  skrll {
   1546  1.1  skrll   expressionS newtok[3];
   1547  1.1  skrll 
   1548  1.1  skrll   newtok[0] = tok[0];
   1549  1.1  skrll   newtok[1] = tok[1];
   1550  1.1  skrll   set_tok_preg (newtok[2], AXP_REG_ZERO);
   1551  1.1  skrll 
   1552  1.1  skrll   assemble_tokens ("ldah", newtok, 3, 0);
   1553  1.1  skrll }
   1554  1.1  skrll 
   1555  1.1  skrll /* Called internally to handle all alignment needs.  This takes care
   1556  1.1  skrll    of eliding calls to frag_align if'n the cached current alignment
   1557  1.1  skrll    says we've already got it, as well as taking care of the auto-align
   1558  1.1  skrll    feature wrt labels.  */
   1559  1.1  skrll 
   1560  1.1  skrll static void
   1561  1.1  skrll alpha_align (int n,
   1562  1.1  skrll 	     char *pfill,
   1563  1.1  skrll 	     symbolS *label,
   1564  1.1  skrll 	     int force ATTRIBUTE_UNUSED)
   1565  1.1  skrll {
   1566  1.1  skrll   if (alpha_current_align >= n)
   1567  1.1  skrll     return;
   1568  1.1  skrll 
   1569  1.1  skrll   if (pfill == NULL)
   1570  1.1  skrll     {
   1571  1.1  skrll       if (subseg_text_p (now_seg))
   1572  1.1  skrll 	frag_align_code (n, 0);
   1573  1.1  skrll       else
   1574  1.1  skrll 	frag_align (n, 0, 0);
   1575  1.1  skrll     }
   1576  1.1  skrll   else
   1577  1.1  skrll     frag_align (n, *pfill, 0);
   1578  1.1  skrll 
   1579  1.1  skrll   alpha_current_align = n;
   1580  1.1  skrll 
   1581  1.1  skrll   if (label != NULL && S_GET_SEGMENT (label) == now_seg)
   1582  1.1  skrll     {
   1583  1.1  skrll       symbol_set_frag (label, frag_now);
   1584  1.1  skrll       S_SET_VALUE (label, (valueT) frag_now_fix ());
   1585  1.1  skrll     }
   1586  1.1  skrll 
   1587  1.1  skrll   record_alignment (now_seg, n);
   1588  1.1  skrll 
   1589  1.1  skrll   /* ??? If alpha_flag_relax && force && elf, record the requested alignment
   1590  1.1  skrll      in a reloc for the linker to see.  */
   1591  1.1  skrll }
   1592  1.1  skrll 
   1593  1.1  skrll /* Actually output an instruction with its fixup.  */
   1594  1.1  skrll 
   1595  1.1  skrll static void
   1596  1.1  skrll emit_insn (struct alpha_insn *insn)
   1597  1.1  skrll {
   1598  1.1  skrll   char *f;
   1599  1.1  skrll   int i;
   1600  1.1  skrll 
   1601  1.1  skrll   /* Take care of alignment duties.  */
   1602  1.1  skrll   if (alpha_auto_align_on && alpha_current_align < 2)
   1603  1.1  skrll     alpha_align (2, (char *) NULL, alpha_insn_label, 0);
   1604  1.1  skrll   if (alpha_current_align > 2)
   1605  1.1  skrll     alpha_current_align = 2;
   1606  1.1  skrll   alpha_insn_label = NULL;
   1607  1.1  skrll 
   1608  1.1  skrll   /* Write out the instruction.  */
   1609  1.1  skrll   f = frag_more (4);
   1610  1.1  skrll   md_number_to_chars (f, insn->insn, 4);
   1611  1.1  skrll 
   1612  1.1  skrll #ifdef OBJ_ELF
   1613  1.1  skrll   dwarf2_emit_insn (4);
   1614  1.1  skrll #endif
   1615  1.1  skrll 
   1616  1.1  skrll   /* Apply the fixups in order.  */
   1617  1.1  skrll   for (i = 0; i < insn->nfixups; ++i)
   1618  1.1  skrll     {
   1619  1.1  skrll       const struct alpha_operand *operand = (const struct alpha_operand *) 0;
   1620  1.1  skrll       struct alpha_fixup *fixup = &insn->fixups[i];
   1621  1.1  skrll       struct alpha_reloc_tag *info = NULL;
   1622  1.1  skrll       int size, pcrel;
   1623  1.1  skrll       fixS *fixP;
   1624  1.1  skrll 
   1625  1.1  skrll       /* Some fixups are only used internally and so have no howto.  */
   1626  1.1  skrll       if ((int) fixup->reloc < 0)
   1627  1.1  skrll 	{
   1628  1.1  skrll 	  operand = &alpha_operands[-(int) fixup->reloc];
   1629  1.1  skrll 	  size = 4;
   1630  1.1  skrll 	  pcrel = ((operand->flags & AXP_OPERAND_RELATIVE) != 0);
   1631  1.1  skrll 	}
   1632  1.1  skrll       else if (fixup->reloc > BFD_RELOC_UNUSED
   1633  1.1  skrll 	       || fixup->reloc == BFD_RELOC_ALPHA_GPDISP_HI16
   1634  1.1  skrll 	       || fixup->reloc == BFD_RELOC_ALPHA_GPDISP_LO16)
   1635  1.1  skrll 	{
   1636  1.1  skrll 	  size = 2;
   1637  1.1  skrll 	  pcrel = 0;
   1638  1.1  skrll 	}
   1639  1.1  skrll       else
   1640  1.1  skrll 	{
   1641  1.1  skrll 	  reloc_howto_type *reloc_howto
   1642  1.1  skrll 	    = bfd_reloc_type_lookup (stdoutput, fixup->reloc);
   1643  1.1  skrll 	  assert (reloc_howto);
   1644  1.1  skrll 
   1645  1.1  skrll 	  size = bfd_get_reloc_size (reloc_howto);
   1646  1.1  skrll 	  assert (size >= 1 && size <= 4);
   1647  1.1  skrll 
   1648  1.1  skrll 	  pcrel = reloc_howto->pc_relative;
   1649  1.1  skrll 	}
   1650  1.1  skrll 
   1651  1.1  skrll       fixP = fix_new_exp (frag_now, f - frag_now->fr_literal, size,
   1652  1.1  skrll 			  &fixup->exp, pcrel, fixup->reloc);
   1653  1.1  skrll 
   1654  1.1  skrll       /* Turn off complaints that the addend is too large for some fixups,
   1655  1.1  skrll          and copy in the sequence number for the explicit relocations.  */
   1656  1.1  skrll       switch (fixup->reloc)
   1657  1.1  skrll 	{
   1658  1.1  skrll 	case BFD_RELOC_ALPHA_HINT:
   1659  1.1  skrll 	case BFD_RELOC_GPREL32:
   1660  1.1  skrll 	case BFD_RELOC_GPREL16:
   1661  1.1  skrll 	case BFD_RELOC_ALPHA_GPREL_HI16:
   1662  1.1  skrll 	case BFD_RELOC_ALPHA_GPREL_LO16:
   1663  1.1  skrll 	case BFD_RELOC_ALPHA_GOTDTPREL16:
   1664  1.1  skrll 	case BFD_RELOC_ALPHA_DTPREL_HI16:
   1665  1.1  skrll 	case BFD_RELOC_ALPHA_DTPREL_LO16:
   1666  1.1  skrll 	case BFD_RELOC_ALPHA_DTPREL16:
   1667  1.1  skrll 	case BFD_RELOC_ALPHA_GOTTPREL16:
   1668  1.1  skrll 	case BFD_RELOC_ALPHA_TPREL_HI16:
   1669  1.1  skrll 	case BFD_RELOC_ALPHA_TPREL_LO16:
   1670  1.1  skrll 	case BFD_RELOC_ALPHA_TPREL16:
   1671  1.1  skrll 	  fixP->fx_no_overflow = 1;
   1672  1.1  skrll 	  break;
   1673  1.1  skrll 
   1674  1.1  skrll 	case BFD_RELOC_ALPHA_GPDISP_HI16:
   1675  1.1  skrll 	  fixP->fx_no_overflow = 1;
   1676  1.1  skrll 	  fixP->fx_addsy = section_symbol (now_seg);
   1677  1.1  skrll 	  fixP->fx_offset = 0;
   1678  1.1  skrll 
   1679  1.1  skrll 	  info = get_alpha_reloc_tag (insn->sequence);
   1680  1.1  skrll 	  if (++info->n_master > 1)
   1681  1.1  skrll 	    as_bad (_("too many ldah insns for !gpdisp!%ld"), insn->sequence);
   1682  1.1  skrll 	  if (info->segment != now_seg)
   1683  1.1  skrll 	    as_bad (_("both insns for !gpdisp!%ld must be in the same section"),
   1684  1.1  skrll 		    insn->sequence);
   1685  1.1  skrll 	  fixP->tc_fix_data.info = info;
   1686  1.1  skrll 	  break;
   1687  1.1  skrll 
   1688  1.1  skrll 	case BFD_RELOC_ALPHA_GPDISP_LO16:
   1689  1.1  skrll 	  fixP->fx_no_overflow = 1;
   1690  1.1  skrll 
   1691  1.1  skrll 	  info = get_alpha_reloc_tag (insn->sequence);
   1692  1.1  skrll 	  if (++info->n_slaves > 1)
   1693  1.1  skrll 	    as_bad (_("too many lda insns for !gpdisp!%ld"), insn->sequence);
   1694  1.1  skrll 	  if (info->segment != now_seg)
   1695  1.1  skrll 	    as_bad (_("both insns for !gpdisp!%ld must be in the same section"),
   1696  1.1  skrll 		    insn->sequence);
   1697  1.1  skrll 	  fixP->tc_fix_data.info = info;
   1698  1.1  skrll 	  info->slaves = fixP;
   1699  1.1  skrll 	  break;
   1700  1.1  skrll 
   1701  1.1  skrll 	case BFD_RELOC_ALPHA_LITERAL:
   1702  1.1  skrll 	case BFD_RELOC_ALPHA_ELF_LITERAL:
   1703  1.1  skrll 	  fixP->fx_no_overflow = 1;
   1704  1.1  skrll 
   1705  1.1  skrll 	  if (insn->sequence == 0)
   1706  1.1  skrll 	    break;
   1707  1.1  skrll 	  info = get_alpha_reloc_tag (insn->sequence);
   1708  1.1  skrll 	  info->master = fixP;
   1709  1.1  skrll 	  info->n_master++;
   1710  1.1  skrll 	  if (info->segment != now_seg)
   1711  1.1  skrll 	    info->multi_section_p = 1;
   1712  1.1  skrll 	  fixP->tc_fix_data.info = info;
   1713  1.1  skrll 	  break;
   1714  1.1  skrll 
   1715  1.1  skrll #ifdef RELOC_OP_P
   1716  1.1  skrll 	case DUMMY_RELOC_LITUSE_ADDR:
   1717  1.1  skrll 	  fixP->fx_offset = LITUSE_ALPHA_ADDR;
   1718  1.1  skrll 	  goto do_lituse;
   1719  1.1  skrll 	case DUMMY_RELOC_LITUSE_BASE:
   1720  1.1  skrll 	  fixP->fx_offset = LITUSE_ALPHA_BASE;
   1721  1.1  skrll 	  goto do_lituse;
   1722  1.1  skrll 	case DUMMY_RELOC_LITUSE_BYTOFF:
   1723  1.1  skrll 	  fixP->fx_offset = LITUSE_ALPHA_BYTOFF;
   1724  1.1  skrll 	  goto do_lituse;
   1725  1.1  skrll 	case DUMMY_RELOC_LITUSE_JSR:
   1726  1.1  skrll 	  fixP->fx_offset = LITUSE_ALPHA_JSR;
   1727  1.1  skrll 	  goto do_lituse;
   1728  1.1  skrll 	case DUMMY_RELOC_LITUSE_TLSGD:
   1729  1.1  skrll 	  fixP->fx_offset = LITUSE_ALPHA_TLSGD;
   1730  1.1  skrll 	  goto do_lituse;
   1731  1.1  skrll 	case DUMMY_RELOC_LITUSE_TLSLDM:
   1732  1.1  skrll 	  fixP->fx_offset = LITUSE_ALPHA_TLSLDM;
   1733  1.1  skrll 	  goto do_lituse;
   1734  1.1  skrll 	case DUMMY_RELOC_LITUSE_JSRDIRECT:
   1735  1.1  skrll 	  fixP->fx_offset = LITUSE_ALPHA_JSRDIRECT;
   1736  1.1  skrll 	  goto do_lituse;
   1737  1.1  skrll 	do_lituse:
   1738  1.1  skrll 	  fixP->fx_addsy = section_symbol (now_seg);
   1739  1.1  skrll 	  fixP->fx_r_type = BFD_RELOC_ALPHA_LITUSE;
   1740  1.1  skrll 
   1741  1.1  skrll 	  info = get_alpha_reloc_tag (insn->sequence);
   1742  1.1  skrll 	  if (fixup->reloc == DUMMY_RELOC_LITUSE_TLSGD)
   1743  1.1  skrll 	    info->saw_lu_tlsgd = 1;
   1744  1.1  skrll 	  else if (fixup->reloc == DUMMY_RELOC_LITUSE_TLSLDM)
   1745  1.1  skrll 	    info->saw_lu_tlsldm = 1;
   1746  1.1  skrll 	  if (++info->n_slaves > 1)
   1747  1.1  skrll 	    {
   1748  1.1  skrll 	      if (info->saw_lu_tlsgd)
   1749  1.1  skrll 		as_bad (_("too many lituse insns for !lituse_tlsgd!%ld"),
   1750  1.1  skrll 		        insn->sequence);
   1751  1.1  skrll 	      else if (info->saw_lu_tlsldm)
   1752  1.1  skrll 		as_bad (_("too many lituse insns for !lituse_tlsldm!%ld"),
   1753  1.1  skrll 		        insn->sequence);
   1754  1.1  skrll 	    }
   1755  1.1  skrll 	  fixP->tc_fix_data.info = info;
   1756  1.1  skrll 	  fixP->tc_fix_data.next_reloc = info->slaves;
   1757  1.1  skrll 	  info->slaves = fixP;
   1758  1.1  skrll 	  if (info->segment != now_seg)
   1759  1.1  skrll 	    info->multi_section_p = 1;
   1760  1.1  skrll 	  break;
   1761  1.1  skrll 
   1762  1.1  skrll 	case BFD_RELOC_ALPHA_TLSGD:
   1763  1.1  skrll 	  fixP->fx_no_overflow = 1;
   1764  1.1  skrll 
   1765  1.1  skrll 	  if (insn->sequence == 0)
   1766  1.1  skrll 	    break;
   1767  1.1  skrll 	  info = get_alpha_reloc_tag (insn->sequence);
   1768  1.1  skrll 	  if (info->saw_tlsgd)
   1769  1.1  skrll 	    as_bad (_("duplicate !tlsgd!%ld"), insn->sequence);
   1770  1.1  skrll 	  else if (info->saw_tlsldm)
   1771  1.1  skrll 	    as_bad (_("sequence number in use for !tlsldm!%ld"),
   1772  1.1  skrll 		    insn->sequence);
   1773  1.1  skrll 	  else
   1774  1.1  skrll 	    info->saw_tlsgd = 1;
   1775  1.1  skrll 	  fixP->tc_fix_data.info = info;
   1776  1.1  skrll 	  break;
   1777  1.1  skrll 
   1778  1.1  skrll 	case BFD_RELOC_ALPHA_TLSLDM:
   1779  1.1  skrll 	  fixP->fx_no_overflow = 1;
   1780  1.1  skrll 
   1781  1.1  skrll 	  if (insn->sequence == 0)
   1782  1.1  skrll 	    break;
   1783  1.1  skrll 	  info = get_alpha_reloc_tag (insn->sequence);
   1784  1.1  skrll 	  if (info->saw_tlsldm)
   1785  1.1  skrll 	    as_bad (_("duplicate !tlsldm!%ld"), insn->sequence);
   1786  1.1  skrll 	  else if (info->saw_tlsgd)
   1787  1.1  skrll 	    as_bad (_("sequence number in use for !tlsgd!%ld"),
   1788  1.1  skrll 		    insn->sequence);
   1789  1.1  skrll 	  else
   1790  1.1  skrll 	    info->saw_tlsldm = 1;
   1791  1.1  skrll 	  fixP->tc_fix_data.info = info;
   1792  1.1  skrll 	  break;
   1793  1.1  skrll #endif
   1794  1.1  skrll 	default:
   1795  1.1  skrll 	  if ((int) fixup->reloc < 0)
   1796  1.1  skrll 	    {
   1797  1.1  skrll 	      if (operand->flags & AXP_OPERAND_NOOVERFLOW)
   1798  1.1  skrll 		fixP->fx_no_overflow = 1;
   1799  1.1  skrll 	    }
   1800  1.1  skrll 	  break;
   1801  1.1  skrll 	}
   1802  1.1  skrll     }
   1803  1.1  skrll }
   1804  1.1  skrll 
   1805  1.1  skrll /* Insert an operand value into an instruction.  */
   1806  1.1  skrll 
   1807  1.1  skrll static unsigned
   1808  1.1  skrll insert_operand (unsigned insn,
   1809  1.1  skrll 		const struct alpha_operand *operand,
   1810  1.1  skrll 		offsetT val,
   1811  1.1  skrll 		char *file,
   1812  1.1  skrll 		unsigned line)
   1813  1.1  skrll {
   1814  1.1  skrll   if (operand->bits != 32 && !(operand->flags & AXP_OPERAND_NOOVERFLOW))
   1815  1.1  skrll     {
   1816  1.1  skrll       offsetT min, max;
   1817  1.1  skrll 
   1818  1.1  skrll       if (operand->flags & AXP_OPERAND_SIGNED)
   1819  1.1  skrll 	{
   1820  1.1  skrll 	  max = (1 << (operand->bits - 1)) - 1;
   1821  1.1  skrll 	  min = -(1 << (operand->bits - 1));
   1822  1.1  skrll 	}
   1823  1.1  skrll       else
   1824  1.1  skrll 	{
   1825  1.1  skrll 	  max = (1 << operand->bits) - 1;
   1826  1.1  skrll 	  min = 0;
   1827  1.1  skrll 	}
   1828  1.1  skrll 
   1829  1.1  skrll       if (val < min || val > max)
   1830  1.1  skrll 	as_warn_value_out_of_range (_("operand"), val, min, max, file, line);
   1831  1.1  skrll     }
   1832  1.2    snj 
   1833  1.1  skrll   if (operand->insert)
   1834  1.1  skrll     {
   1835  1.1  skrll       const char *errmsg = NULL;
   1836  1.1  skrll 
   1837  1.1  skrll       insn = (*operand->insert) (insn, val, &errmsg);
   1838  1.1  skrll       if (errmsg)
   1839  1.1  skrll 	as_warn ("%s", errmsg);
   1840  1.1  skrll     }
   1841  1.1  skrll   else
   1842  1.1  skrll     insn |= ((val & ((1 << operand->bits) - 1)) << operand->shift);
   1843  1.1  skrll 
   1844  1.1  skrll   return insn;
   1845  1.1  skrll }
   1846  1.1  skrll 
   1847  1.1  skrll /* Turn an opcode description and a set of arguments into
   1848  1.1  skrll    an instruction and a fixup.  */
   1849  1.1  skrll 
   1850  1.1  skrll static void
   1851  1.1  skrll assemble_insn (const struct alpha_opcode *opcode,
   1852  1.1  skrll 	       const expressionS *tok,
   1853  1.1  skrll 	       int ntok,
   1854  1.1  skrll 	       struct alpha_insn *insn,
   1855  1.1  skrll 	       bfd_reloc_code_real_type reloc)
   1856  1.1  skrll {
   1857  1.1  skrll   const struct alpha_operand *reloc_operand = NULL;
   1858  1.1  skrll   const expressionS *reloc_exp = NULL;
   1859  1.1  skrll   const unsigned char *argidx;
   1860  1.1  skrll   unsigned image;
   1861  1.1  skrll   int tokidx = 0;
   1862  1.1  skrll 
   1863  1.1  skrll   memset (insn, 0, sizeof (*insn));
   1864  1.1  skrll   image = opcode->opcode;
   1865  1.1  skrll 
   1866  1.1  skrll   for (argidx = opcode->operands; *argidx; ++argidx)
   1867  1.1  skrll     {
   1868  1.1  skrll       const struct alpha_operand *operand = &alpha_operands[*argidx];
   1869  1.1  skrll       const expressionS *t = (const expressionS *) 0;
   1870  1.1  skrll 
   1871  1.1  skrll       if (operand->flags & AXP_OPERAND_FAKE)
   1872  1.1  skrll 	{
   1873  1.1  skrll 	  /* Fake operands take no value and generate no fixup.  */
   1874  1.1  skrll 	  image = insert_operand (image, operand, 0, NULL, 0);
   1875  1.1  skrll 	  continue;
   1876  1.1  skrll 	}
   1877  1.1  skrll 
   1878  1.1  skrll       if (tokidx >= ntok)
   1879  1.1  skrll 	{
   1880  1.1  skrll 	  switch (operand->flags & AXP_OPERAND_OPTIONAL_MASK)
   1881  1.1  skrll 	    {
   1882  1.1  skrll 	    case AXP_OPERAND_DEFAULT_FIRST:
   1883  1.1  skrll 	      t = &tok[0];
   1884  1.1  skrll 	      break;
   1885  1.1  skrll 	    case AXP_OPERAND_DEFAULT_SECOND:
   1886  1.1  skrll 	      t = &tok[1];
   1887  1.1  skrll 	      break;
   1888  1.1  skrll 	    case AXP_OPERAND_DEFAULT_ZERO:
   1889  1.1  skrll 	      {
   1890  1.1  skrll 		static expressionS zero_exp;
   1891  1.1  skrll 		t = &zero_exp;
   1892  1.1  skrll 		zero_exp.X_op = O_constant;
   1893  1.1  skrll 		zero_exp.X_unsigned = 1;
   1894  1.1  skrll 	      }
   1895  1.1  skrll 	      break;
   1896  1.1  skrll 	    default:
   1897  1.1  skrll 	      abort ();
   1898  1.1  skrll 	    }
   1899  1.1  skrll 	}
   1900  1.1  skrll       else
   1901  1.1  skrll 	t = &tok[tokidx++];
   1902  1.1  skrll 
   1903  1.1  skrll       switch (t->X_op)
   1904  1.1  skrll 	{
   1905  1.1  skrll 	case O_register:
   1906  1.1  skrll 	case O_pregister:
   1907  1.1  skrll 	case O_cpregister:
   1908  1.1  skrll 	  image = insert_operand (image, operand, regno (t->X_add_number),
   1909  1.1  skrll 				  NULL, 0);
   1910  1.1  skrll 	  break;
   1911  1.1  skrll 
   1912  1.1  skrll 	case O_constant:
   1913  1.1  skrll 	  image = insert_operand (image, operand, t->X_add_number, NULL, 0);
   1914  1.1  skrll 	  assert (reloc_operand == NULL);
   1915  1.1  skrll 	  reloc_operand = operand;
   1916  1.1  skrll 	  reloc_exp = t;
   1917  1.1  skrll 	  break;
   1918  1.1  skrll 
   1919  1.1  skrll 	default:
   1920  1.1  skrll 	  /* This is only 0 for fields that should contain registers,
   1921  1.1  skrll 	     which means this pattern shouldn't have matched.  */
   1922  1.1  skrll 	  if (operand->default_reloc == 0)
   1923  1.1  skrll 	    abort ();
   1924  1.1  skrll 
   1925  1.1  skrll 	  /* There is one special case for which an insn receives two
   1926  1.1  skrll 	     relocations, and thus the user-supplied reloc does not
   1927  1.1  skrll 	     override the operand reloc.  */
   1928  1.1  skrll 	  if (operand->default_reloc == BFD_RELOC_ALPHA_HINT)
   1929  1.1  skrll 	    {
   1930  1.1  skrll 	      struct alpha_fixup *fixup;
   1931  1.1  skrll 
   1932  1.1  skrll 	      if (insn->nfixups >= MAX_INSN_FIXUPS)
   1933  1.1  skrll 		as_fatal (_("too many fixups"));
   1934  1.1  skrll 
   1935  1.1  skrll 	      fixup = &insn->fixups[insn->nfixups++];
   1936  1.1  skrll 	      fixup->exp = *t;
   1937  1.1  skrll 	      fixup->reloc = BFD_RELOC_ALPHA_HINT;
   1938  1.1  skrll 	    }
   1939  1.1  skrll 	  else
   1940  1.1  skrll 	    {
   1941  1.1  skrll 	      if (reloc == BFD_RELOC_UNUSED)
   1942  1.1  skrll 		reloc = operand->default_reloc;
   1943  1.1  skrll 
   1944  1.1  skrll 	      assert (reloc_operand == NULL);
   1945  1.1  skrll 	      reloc_operand = operand;
   1946  1.1  skrll 	      reloc_exp = t;
   1947  1.1  skrll 	    }
   1948  1.1  skrll 	  break;
   1949  1.1  skrll 	}
   1950  1.1  skrll     }
   1951  1.1  skrll 
   1952  1.1  skrll   if (reloc != BFD_RELOC_UNUSED)
   1953  1.1  skrll     {
   1954  1.1  skrll       struct alpha_fixup *fixup;
   1955  1.1  skrll 
   1956  1.1  skrll       if (insn->nfixups >= MAX_INSN_FIXUPS)
   1957  1.1  skrll 	as_fatal (_("too many fixups"));
   1958  1.1  skrll 
   1959  1.1  skrll       /* ??? My but this is hacky.  But the OSF/1 assembler uses the same
   1960  1.1  skrll 	 relocation tag for both ldah and lda with gpdisp.  Choose the
   1961  1.1  skrll 	 correct internal relocation based on the opcode.  */
   1962  1.1  skrll       if (reloc == BFD_RELOC_ALPHA_GPDISP)
   1963  1.1  skrll 	{
   1964  1.1  skrll 	  if (strcmp (opcode->name, "ldah") == 0)
   1965  1.1  skrll 	    reloc = BFD_RELOC_ALPHA_GPDISP_HI16;
   1966  1.1  skrll 	  else if (strcmp (opcode->name, "lda") == 0)
   1967  1.1  skrll 	    reloc = BFD_RELOC_ALPHA_GPDISP_LO16;
   1968  1.1  skrll 	  else
   1969  1.1  skrll 	    as_bad (_("invalid relocation for instruction"));
   1970  1.1  skrll 	}
   1971  1.1  skrll 
   1972  1.1  skrll       /* If this is a real relocation (as opposed to a lituse hint), then
   1973  1.1  skrll 	 the relocation width should match the operand width.  */
   1974  1.1  skrll       else if (reloc < BFD_RELOC_UNUSED)
   1975  1.1  skrll 	{
   1976  1.1  skrll 	  reloc_howto_type *reloc_howto
   1977  1.1  skrll 	    = bfd_reloc_type_lookup (stdoutput, reloc);
   1978  1.1  skrll 	  if (reloc_operand == NULL
   1979  1.1  skrll 	      || reloc_howto->bitsize != reloc_operand->bits)
   1980  1.1  skrll 	    {
   1981  1.1  skrll 	      as_bad (_("invalid relocation for field"));
   1982  1.1  skrll 	      return;
   1983  1.1  skrll 	    }
   1984  1.1  skrll 	}
   1985  1.1  skrll 
   1986  1.1  skrll       fixup = &insn->fixups[insn->nfixups++];
   1987  1.1  skrll       if (reloc_exp)
   1988  1.1  skrll 	fixup->exp = *reloc_exp;
   1989  1.1  skrll       else
   1990  1.1  skrll 	fixup->exp.X_op = O_absent;
   1991  1.1  skrll       fixup->reloc = reloc;
   1992  1.1  skrll     }
   1993  1.1  skrll 
   1994  1.1  skrll   insn->insn = image;
   1995  1.1  skrll }
   1996  1.1  skrll 
   1997  1.1  skrll /* Handle all "simple" integer register loads -- ldq, ldq_l, ldq_u,
   1998  1.1  skrll    etc.  They differ from the real instructions in that they do simple
   1999  1.1  skrll    expressions like the lda macro.  */
   2000  1.1  skrll 
   2001  1.1  skrll static void
   2002  1.1  skrll emit_ir_load (const expressionS *tok,
   2003  1.1  skrll 	      int ntok,
   2004  1.1  skrll 	      const void * opname)
   2005  1.1  skrll {
   2006  1.1  skrll   int basereg;
   2007  1.1  skrll   long lituse;
   2008  1.1  skrll   expressionS newtok[3];
   2009  1.1  skrll   struct alpha_insn insn;
   2010  1.1  skrll 
   2011  1.1  skrll   if (ntok == 2)
   2012  1.1  skrll     basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
   2013  1.1  skrll   else
   2014  1.1  skrll     basereg = tok[2].X_add_number;
   2015  1.1  skrll 
   2016  1.1  skrll   lituse = load_expression (tok[0].X_add_number, &tok[1], &basereg,
   2017  1.1  skrll 			    &newtok[1]);
   2018  1.1  skrll 
   2019  1.1  skrll   newtok[0] = tok[0];
   2020  1.1  skrll   set_tok_preg (newtok[2], basereg);
   2021  1.1  skrll 
   2022  1.1  skrll   assemble_tokens_to_insn ((const char *) opname, newtok, 3, &insn);
   2023  1.1  skrll 
   2024  1.1  skrll   if (lituse)
   2025  1.1  skrll     {
   2026  1.1  skrll       assert (insn.nfixups < MAX_INSN_FIXUPS);
   2027  1.1  skrll       insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
   2028  1.1  skrll       insn.fixups[insn.nfixups].exp.X_op = O_absent;
   2029  1.1  skrll       insn.nfixups++;
   2030  1.1  skrll       insn.sequence = lituse;
   2031  1.1  skrll     }
   2032  1.1  skrll 
   2033  1.1  skrll   emit_insn (&insn);
   2034  1.1  skrll }
   2035  1.1  skrll 
   2036  1.1  skrll /* Handle fp register loads, and both integer and fp register stores.
   2037  1.1  skrll    Again, we handle simple expressions.  */
   2038  1.1  skrll 
   2039  1.1  skrll static void
   2040  1.1  skrll emit_loadstore (const expressionS *tok,
   2041  1.1  skrll 		int ntok,
   2042  1.1  skrll 		const void * opname)
   2043  1.1  skrll {
   2044  1.1  skrll   int basereg;
   2045  1.1  skrll   long lituse;
   2046  1.1  skrll   expressionS newtok[3];
   2047  1.1  skrll   struct alpha_insn insn;
   2048  1.1  skrll 
   2049  1.1  skrll   if (ntok == 2)
   2050  1.1  skrll     basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
   2051  1.1  skrll   else
   2052  1.1  skrll     basereg = tok[2].X_add_number;
   2053  1.1  skrll 
   2054  1.1  skrll   if (tok[1].X_op != O_constant || !range_signed_16 (tok[1].X_add_number))
   2055  1.1  skrll     {
   2056  1.1  skrll       if (alpha_noat_on)
   2057  1.1  skrll 	as_bad (_("macro requires $at register while noat in effect"));
   2058  1.1  skrll 
   2059  1.1  skrll       lituse = load_expression (AXP_REG_AT, &tok[1], &basereg, &newtok[1]);
   2060  1.1  skrll     }
   2061  1.1  skrll   else
   2062  1.1  skrll     {
   2063  1.1  skrll       newtok[1] = tok[1];
   2064  1.1  skrll       lituse = 0;
   2065  1.1  skrll     }
   2066  1.1  skrll 
   2067  1.1  skrll   newtok[0] = tok[0];
   2068  1.1  skrll   set_tok_preg (newtok[2], basereg);
   2069  1.1  skrll 
   2070  1.1  skrll   assemble_tokens_to_insn ((const char *) opname, newtok, 3, &insn);
   2071  1.1  skrll 
   2072  1.1  skrll   if (lituse)
   2073  1.1  skrll     {
   2074  1.1  skrll       assert (insn.nfixups < MAX_INSN_FIXUPS);
   2075  1.1  skrll       insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
   2076  1.1  skrll       insn.fixups[insn.nfixups].exp.X_op = O_absent;
   2077  1.1  skrll       insn.nfixups++;
   2078  1.1  skrll       insn.sequence = lituse;
   2079  1.1  skrll     }
   2080  1.1  skrll 
   2081  1.1  skrll   emit_insn (&insn);
   2082  1.1  skrll }
   2083  1.1  skrll 
   2084  1.1  skrll /* Load a half-word or byte as an unsigned value.  */
   2085  1.1  skrll 
   2086  1.1  skrll static void
   2087  1.1  skrll emit_ldXu (const expressionS *tok,
   2088  1.1  skrll 	   int ntok,
   2089  1.1  skrll 	   const void * vlgsize)
   2090  1.1  skrll {
   2091  1.1  skrll   if (alpha_target & AXP_OPCODE_BWX)
   2092  1.1  skrll     emit_ir_load (tok, ntok, ldXu_op[(long) vlgsize]);
   2093  1.1  skrll   else
   2094  1.1  skrll     {
   2095  1.1  skrll       expressionS newtok[3];
   2096  1.1  skrll       struct alpha_insn insn;
   2097  1.1  skrll       int basereg;
   2098  1.1  skrll       long lituse;
   2099  1.1  skrll 
   2100  1.1  skrll       if (alpha_noat_on)
   2101  1.1  skrll 	as_bad (_("macro requires $at register while noat in effect"));
   2102  1.1  skrll 
   2103  1.1  skrll       if (ntok == 2)
   2104  1.1  skrll 	basereg = (tok[1].X_op == O_constant
   2105  1.1  skrll 		   ? AXP_REG_ZERO : alpha_gp_register);
   2106  1.1  skrll       else
   2107  1.1  skrll 	basereg = tok[2].X_add_number;
   2108  1.1  skrll 
   2109  1.1  skrll       /* Emit "lda $at, exp".  */
   2110  1.1  skrll       lituse = load_expression (AXP_REG_AT, &tok[1], &basereg, NULL);
   2111  1.1  skrll 
   2112  1.1  skrll       /* Emit "ldq_u targ, 0($at)".  */
   2113  1.1  skrll       newtok[0] = tok[0];
   2114  1.1  skrll       set_tok_const (newtok[1], 0);
   2115  1.1  skrll       set_tok_preg (newtok[2], basereg);
   2116  1.1  skrll       assemble_tokens_to_insn ("ldq_u", newtok, 3, &insn);
   2117  1.1  skrll 
   2118  1.1  skrll       if (lituse)
   2119  1.1  skrll 	{
   2120  1.1  skrll 	  assert (insn.nfixups < MAX_INSN_FIXUPS);
   2121  1.1  skrll 	  insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
   2122  1.1  skrll 	  insn.fixups[insn.nfixups].exp.X_op = O_absent;
   2123  1.1  skrll 	  insn.nfixups++;
   2124  1.1  skrll 	  insn.sequence = lituse;
   2125  1.1  skrll 	}
   2126  1.1  skrll 
   2127  1.1  skrll       emit_insn (&insn);
   2128  1.1  skrll 
   2129  1.1  skrll       /* Emit "extXl targ, $at, targ".  */
   2130  1.1  skrll       set_tok_reg (newtok[1], basereg);
   2131  1.1  skrll       newtok[2] = newtok[0];
   2132  1.1  skrll       assemble_tokens_to_insn (extXl_op[(long) vlgsize], newtok, 3, &insn);
   2133  1.1  skrll 
   2134  1.1  skrll       if (lituse)
   2135  1.1  skrll 	{
   2136  1.1  skrll 	  assert (insn.nfixups < MAX_INSN_FIXUPS);
   2137  1.1  skrll 	  insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF;
   2138  1.1  skrll 	  insn.fixups[insn.nfixups].exp.X_op = O_absent;
   2139  1.1  skrll 	  insn.nfixups++;
   2140  1.1  skrll 	  insn.sequence = lituse;
   2141  1.1  skrll 	}
   2142  1.1  skrll 
   2143  1.1  skrll       emit_insn (&insn);
   2144  1.1  skrll     }
   2145  1.1  skrll }
   2146  1.1  skrll 
   2147  1.1  skrll /* Load a half-word or byte as a signed value.  */
   2148  1.1  skrll 
   2149  1.1  skrll static void
   2150  1.1  skrll emit_ldX (const expressionS *tok,
   2151  1.1  skrll 	  int ntok,
   2152  1.1  skrll 	  const void * vlgsize)
   2153  1.1  skrll {
   2154  1.1  skrll   emit_ldXu (tok, ntok, vlgsize);
   2155  1.1  skrll   assemble_tokens (sextX_op[(long) vlgsize], tok, 1, 1);
   2156  1.1  skrll }
   2157  1.1  skrll 
   2158  1.1  skrll /* Load an integral value from an unaligned address as an unsigned
   2159  1.1  skrll    value.  */
   2160  1.1  skrll 
   2161  1.1  skrll static void
   2162  1.1  skrll emit_uldXu (const expressionS *tok,
   2163  1.1  skrll 	    int ntok,
   2164  1.1  skrll 	    const void * vlgsize)
   2165  1.1  skrll {
   2166  1.1  skrll   long lgsize = (long) vlgsize;
   2167  1.1  skrll   expressionS newtok[3];
   2168  1.1  skrll 
   2169  1.1  skrll   if (alpha_noat_on)
   2170  1.1  skrll     as_bad (_("macro requires $at register while noat in effect"));
   2171  1.1  skrll 
   2172  1.1  skrll   /* Emit "lda $at, exp".  */
   2173  1.1  skrll   memcpy (newtok, tok, sizeof (expressionS) * ntok);
   2174  1.1  skrll   newtok[0].X_add_number = AXP_REG_AT;
   2175  1.1  skrll   assemble_tokens ("lda", newtok, ntok, 1);
   2176  1.1  skrll 
   2177  1.1  skrll   /* Emit "ldq_u $t9, 0($at)".  */
   2178  1.1  skrll   set_tok_reg (newtok[0], AXP_REG_T9);
   2179  1.1  skrll   set_tok_const (newtok[1], 0);
   2180  1.1  skrll   set_tok_preg (newtok[2], AXP_REG_AT);
   2181  1.1  skrll   assemble_tokens ("ldq_u", newtok, 3, 1);
   2182  1.1  skrll 
   2183  1.1  skrll   /* Emit "ldq_u $t10, size-1($at)".  */
   2184  1.1  skrll   set_tok_reg (newtok[0], AXP_REG_T10);
   2185  1.1  skrll   set_tok_const (newtok[1], (1 << lgsize) - 1);
   2186  1.1  skrll   assemble_tokens ("ldq_u", newtok, 3, 1);
   2187  1.1  skrll 
   2188  1.1  skrll   /* Emit "extXl $t9, $at, $t9".  */
   2189  1.1  skrll   set_tok_reg (newtok[0], AXP_REG_T9);
   2190  1.1  skrll   set_tok_reg (newtok[1], AXP_REG_AT);
   2191  1.1  skrll   set_tok_reg (newtok[2], AXP_REG_T9);
   2192  1.1  skrll   assemble_tokens (extXl_op[lgsize], newtok, 3, 1);
   2193  1.1  skrll 
   2194  1.1  skrll   /* Emit "extXh $t10, $at, $t10".  */
   2195  1.1  skrll   set_tok_reg (newtok[0], AXP_REG_T10);
   2196  1.1  skrll   set_tok_reg (newtok[2], AXP_REG_T10);
   2197  1.1  skrll   assemble_tokens (extXh_op[lgsize], newtok, 3, 1);
   2198  1.1  skrll 
   2199  1.1  skrll   /* Emit "or $t9, $t10, targ".  */
   2200  1.1  skrll   set_tok_reg (newtok[0], AXP_REG_T9);
   2201  1.1  skrll   set_tok_reg (newtok[1], AXP_REG_T10);
   2202  1.1  skrll   newtok[2] = tok[0];
   2203  1.1  skrll   assemble_tokens ("or", newtok, 3, 1);
   2204  1.1  skrll }
   2205  1.1  skrll 
   2206  1.1  skrll /* Load an integral value from an unaligned address as a signed value.
   2207  1.1  skrll    Note that quads should get funneled to the unsigned load since we
   2208  1.1  skrll    don't have to do the sign extension.  */
   2209  1.1  skrll 
   2210  1.1  skrll static void
   2211  1.1  skrll emit_uldX (const expressionS *tok,
   2212  1.1  skrll 	   int ntok,
   2213  1.1  skrll 	   const void * vlgsize)
   2214  1.1  skrll {
   2215  1.1  skrll   emit_uldXu (tok, ntok, vlgsize);
   2216  1.1  skrll   assemble_tokens (sextX_op[(long) vlgsize], tok, 1, 1);
   2217  1.1  skrll }
   2218  1.1  skrll 
   2219  1.1  skrll /* Implement the ldil macro.  */
   2220  1.1  skrll 
   2221  1.1  skrll static void
   2222  1.1  skrll emit_ldil (const expressionS *tok,
   2223  1.1  skrll 	   int ntok,
   2224  1.1  skrll 	   const void * unused ATTRIBUTE_UNUSED)
   2225  1.1  skrll {
   2226  1.1  skrll   expressionS newtok[2];
   2227  1.1  skrll 
   2228  1.1  skrll   memcpy (newtok, tok, sizeof (newtok));
   2229  1.1  skrll   newtok[1].X_add_number = sign_extend_32 (tok[1].X_add_number);
   2230  1.1  skrll 
   2231  1.1  skrll   assemble_tokens ("lda", newtok, ntok, 1);
   2232  1.1  skrll }
   2233  1.1  skrll 
   2234  1.1  skrll /* Store a half-word or byte.  */
   2235  1.1  skrll 
   2236  1.1  skrll static void
   2237  1.1  skrll emit_stX (const expressionS *tok,
   2238  1.1  skrll 	  int ntok,
   2239  1.1  skrll 	  const void * vlgsize)
   2240  1.1  skrll {
   2241  1.1  skrll   int lgsize = (int) (long) vlgsize;
   2242  1.1  skrll 
   2243  1.1  skrll   if (alpha_target & AXP_OPCODE_BWX)
   2244  1.1  skrll     emit_loadstore (tok, ntok, stX_op[lgsize]);
   2245  1.1  skrll   else
   2246  1.1  skrll     {
   2247  1.1  skrll       expressionS newtok[3];
   2248  1.1  skrll       struct alpha_insn insn;
   2249  1.1  skrll       int basereg;
   2250  1.1  skrll       long lituse;
   2251  1.1  skrll 
   2252  1.1  skrll       if (alpha_noat_on)
   2253  1.1  skrll 	as_bad (_("macro requires $at register while noat in effect"));
   2254  1.1  skrll 
   2255  1.1  skrll       if (ntok == 2)
   2256  1.1  skrll 	basereg = (tok[1].X_op == O_constant
   2257  1.1  skrll 		   ? AXP_REG_ZERO : alpha_gp_register);
   2258  1.1  skrll       else
   2259  1.1  skrll 	basereg = tok[2].X_add_number;
   2260  1.1  skrll 
   2261  1.1  skrll       /* Emit "lda $at, exp".  */
   2262  1.1  skrll       lituse = load_expression (AXP_REG_AT, &tok[1], &basereg, NULL);
   2263  1.1  skrll 
   2264  1.1  skrll       /* Emit "ldq_u $t9, 0($at)".  */
   2265  1.1  skrll       set_tok_reg (newtok[0], AXP_REG_T9);
   2266  1.1  skrll       set_tok_const (newtok[1], 0);
   2267  1.1  skrll       set_tok_preg (newtok[2], basereg);
   2268  1.1  skrll       assemble_tokens_to_insn ("ldq_u", newtok, 3, &insn);
   2269  1.1  skrll 
   2270  1.1  skrll       if (lituse)
   2271  1.1  skrll 	{
   2272  1.1  skrll 	  assert (insn.nfixups < MAX_INSN_FIXUPS);
   2273  1.1  skrll 	  insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
   2274  1.1  skrll 	  insn.fixups[insn.nfixups].exp.X_op = O_absent;
   2275  1.1  skrll 	  insn.nfixups++;
   2276  1.1  skrll 	  insn.sequence = lituse;
   2277  1.1  skrll 	}
   2278  1.1  skrll 
   2279  1.1  skrll       emit_insn (&insn);
   2280  1.1  skrll 
   2281  1.1  skrll       /* Emit "insXl src, $at, $t10".  */
   2282  1.1  skrll       newtok[0] = tok[0];
   2283  1.1  skrll       set_tok_reg (newtok[1], basereg);
   2284  1.1  skrll       set_tok_reg (newtok[2], AXP_REG_T10);
   2285  1.1  skrll       assemble_tokens_to_insn (insXl_op[lgsize], newtok, 3, &insn);
   2286  1.1  skrll 
   2287  1.1  skrll       if (lituse)
   2288  1.1  skrll 	{
   2289  1.1  skrll 	  assert (insn.nfixups < MAX_INSN_FIXUPS);
   2290  1.1  skrll 	  insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF;
   2291  1.1  skrll 	  insn.fixups[insn.nfixups].exp.X_op = O_absent;
   2292  1.1  skrll 	  insn.nfixups++;
   2293  1.1  skrll 	  insn.sequence = lituse;
   2294  1.1  skrll 	}
   2295  1.1  skrll 
   2296  1.1  skrll       emit_insn (&insn);
   2297  1.1  skrll 
   2298  1.1  skrll       /* Emit "mskXl $t9, $at, $t9".  */
   2299  1.1  skrll       set_tok_reg (newtok[0], AXP_REG_T9);
   2300  1.1  skrll       newtok[2] = newtok[0];
   2301  1.1  skrll       assemble_tokens_to_insn (mskXl_op[lgsize], newtok, 3, &insn);
   2302  1.1  skrll 
   2303  1.1  skrll       if (lituse)
   2304  1.1  skrll 	{
   2305  1.1  skrll 	  assert (insn.nfixups < MAX_INSN_FIXUPS);
   2306  1.1  skrll 	  insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF;
   2307  1.1  skrll 	  insn.fixups[insn.nfixups].exp.X_op = O_absent;
   2308  1.1  skrll 	  insn.nfixups++;
   2309  1.1  skrll 	  insn.sequence = lituse;
   2310  1.1  skrll 	}
   2311  1.1  skrll 
   2312  1.1  skrll       emit_insn (&insn);
   2313  1.1  skrll 
   2314  1.1  skrll       /* Emit "or $t9, $t10, $t9".  */
   2315  1.1  skrll       set_tok_reg (newtok[1], AXP_REG_T10);
   2316  1.1  skrll       assemble_tokens ("or", newtok, 3, 1);
   2317  1.1  skrll 
   2318  1.1  skrll       /* Emit "stq_u $t9, 0($at).  */
   2319  1.1  skrll       set_tok_const(newtok[1], 0);
   2320  1.1  skrll       set_tok_preg (newtok[2], AXP_REG_AT);
   2321  1.1  skrll       assemble_tokens_to_insn ("stq_u", newtok, 3, &insn);
   2322  1.1  skrll 
   2323  1.1  skrll       if (lituse)
   2324  1.1  skrll 	{
   2325  1.1  skrll 	  assert (insn.nfixups < MAX_INSN_FIXUPS);
   2326  1.1  skrll 	  insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
   2327  1.1  skrll 	  insn.fixups[insn.nfixups].exp.X_op = O_absent;
   2328  1.1  skrll 	  insn.nfixups++;
   2329  1.1  skrll 	  insn.sequence = lituse;
   2330  1.1  skrll 	}
   2331  1.1  skrll 
   2332  1.1  skrll       emit_insn (&insn);
   2333  1.1  skrll     }
   2334  1.1  skrll }
   2335  1.1  skrll 
   2336  1.1  skrll /* Store an integer to an unaligned address.  */
   2337  1.1  skrll 
   2338  1.1  skrll static void
   2339  1.1  skrll emit_ustX (const expressionS *tok,
   2340  1.1  skrll 	   int ntok,
   2341  1.1  skrll 	   const void * vlgsize)
   2342  1.1  skrll {
   2343  1.1  skrll   int lgsize = (int) (long) vlgsize;
   2344  1.1  skrll   expressionS newtok[3];
   2345  1.1  skrll 
   2346  1.1  skrll   /* Emit "lda $at, exp".  */
   2347  1.1  skrll   memcpy (newtok, tok, sizeof (expressionS) * ntok);
   2348  1.1  skrll   newtok[0].X_add_number = AXP_REG_AT;
   2349  1.1  skrll   assemble_tokens ("lda", newtok, ntok, 1);
   2350  1.1  skrll 
   2351  1.1  skrll   /* Emit "ldq_u $9, 0($at)".  */
   2352  1.1  skrll   set_tok_reg (newtok[0], AXP_REG_T9);
   2353  1.1  skrll   set_tok_const (newtok[1], 0);
   2354  1.1  skrll   set_tok_preg (newtok[2], AXP_REG_AT);
   2355  1.1  skrll   assemble_tokens ("ldq_u", newtok, 3, 1);
   2356  1.1  skrll 
   2357  1.1  skrll   /* Emit "ldq_u $10, size-1($at)".  */
   2358  1.1  skrll   set_tok_reg (newtok[0], AXP_REG_T10);
   2359  1.1  skrll   set_tok_const (newtok[1], (1 << lgsize) - 1);
   2360  1.1  skrll   assemble_tokens ("ldq_u", newtok, 3, 1);
   2361  1.1  skrll 
   2362  1.1  skrll   /* Emit "insXl src, $at, $t11".  */
   2363  1.1  skrll   newtok[0] = tok[0];
   2364  1.1  skrll   set_tok_reg (newtok[1], AXP_REG_AT);
   2365  1.1  skrll   set_tok_reg (newtok[2], AXP_REG_T11);
   2366  1.1  skrll   assemble_tokens (insXl_op[lgsize], newtok, 3, 1);
   2367  1.1  skrll 
   2368  1.1  skrll   /* Emit "insXh src, $at, $t12".  */
   2369  1.1  skrll   set_tok_reg (newtok[2], AXP_REG_T12);
   2370  1.1  skrll   assemble_tokens (insXh_op[lgsize], newtok, 3, 1);
   2371  1.1  skrll 
   2372  1.1  skrll   /* Emit "mskXl $t9, $at, $t9".  */
   2373  1.1  skrll   set_tok_reg (newtok[0], AXP_REG_T9);
   2374  1.1  skrll   newtok[2] = newtok[0];
   2375  1.1  skrll   assemble_tokens (mskXl_op[lgsize], newtok, 3, 1);
   2376  1.1  skrll 
   2377  1.1  skrll   /* Emit "mskXh $t10, $at, $t10".  */
   2378  1.1  skrll   set_tok_reg (newtok[0], AXP_REG_T10);
   2379  1.1  skrll   newtok[2] = newtok[0];
   2380  1.1  skrll   assemble_tokens (mskXh_op[lgsize], newtok, 3, 1);
   2381  1.1  skrll 
   2382  1.1  skrll   /* Emit "or $t9, $t11, $t9".  */
   2383  1.1  skrll   set_tok_reg (newtok[0], AXP_REG_T9);
   2384  1.1  skrll   set_tok_reg (newtok[1], AXP_REG_T11);
   2385  1.1  skrll   newtok[2] = newtok[0];
   2386  1.1  skrll   assemble_tokens ("or", newtok, 3, 1);
   2387  1.1  skrll 
   2388  1.1  skrll   /* Emit "or $t10, $t12, $t10".  */
   2389  1.1  skrll   set_tok_reg (newtok[0], AXP_REG_T10);
   2390  1.1  skrll   set_tok_reg (newtok[1], AXP_REG_T12);
   2391  1.1  skrll   newtok[2] = newtok[0];
   2392  1.1  skrll   assemble_tokens ("or", newtok, 3, 1);
   2393  1.1  skrll 
   2394  1.1  skrll   /* Emit "stq_u $t10, size-1($at)".  */
   2395  1.1  skrll   set_tok_reg (newtok[0], AXP_REG_T10);
   2396  1.1  skrll   set_tok_const (newtok[1], (1 << lgsize) - 1);
   2397  1.1  skrll   set_tok_preg (newtok[2], AXP_REG_AT);
   2398  1.1  skrll   assemble_tokens ("stq_u", newtok, 3, 1);
   2399  1.1  skrll 
   2400  1.1  skrll   /* Emit "stq_u $t9, 0($at)".  */
   2401  1.1  skrll   set_tok_reg (newtok[0], AXP_REG_T9);
   2402  1.1  skrll   set_tok_const (newtok[1], 0);
   2403  1.1  skrll   assemble_tokens ("stq_u", newtok, 3, 1);
   2404  1.1  skrll }
   2405  1.1  skrll 
   2406  1.1  skrll /* Sign extend a half-word or byte.  The 32-bit sign extend is
   2407  1.1  skrll    implemented as "addl $31, $r, $t" in the opcode table.  */
   2408  1.1  skrll 
   2409  1.1  skrll static void
   2410  1.1  skrll emit_sextX (const expressionS *tok,
   2411  1.1  skrll 	    int ntok,
   2412  1.1  skrll 	    const void * vlgsize)
   2413  1.1  skrll {
   2414  1.1  skrll   long lgsize = (long) vlgsize;
   2415  1.1  skrll 
   2416  1.1  skrll   if (alpha_target & AXP_OPCODE_BWX)
   2417  1.1  skrll     assemble_tokens (sextX_op[lgsize], tok, ntok, 0);
   2418  1.1  skrll   else
   2419  1.1  skrll     {
   2420  1.1  skrll       int bitshift = 64 - 8 * (1 << lgsize);
   2421  1.1  skrll       expressionS newtok[3];
   2422  1.1  skrll 
   2423  1.1  skrll       /* Emit "sll src,bits,dst".  */
   2424  1.1  skrll       newtok[0] = tok[0];
   2425  1.1  skrll       set_tok_const (newtok[1], bitshift);
   2426  1.1  skrll       newtok[2] = tok[ntok - 1];
   2427  1.1  skrll       assemble_tokens ("sll", newtok, 3, 1);
   2428  1.1  skrll 
   2429  1.1  skrll       /* Emit "sra dst,bits,dst".  */
   2430  1.1  skrll       newtok[0] = newtok[2];
   2431  1.1  skrll       assemble_tokens ("sra", newtok, 3, 1);
   2432  1.1  skrll     }
   2433  1.1  skrll }
   2434  1.1  skrll 
   2435  1.1  skrll /* Implement the division and modulus macros.  */
   2436  1.1  skrll 
   2437  1.1  skrll #ifdef OBJ_EVAX
   2438  1.1  skrll 
   2439  1.1  skrll /* Make register usage like in normal procedure call.
   2440  1.1  skrll    Don't clobber PV and RA.  */
   2441  1.1  skrll 
   2442  1.1  skrll static void
   2443  1.1  skrll emit_division (const expressionS *tok,
   2444  1.1  skrll 	       int ntok,
   2445  1.1  skrll 	       const void * symname)
   2446  1.1  skrll {
   2447  1.1  skrll   /* DIVISION and MODULUS. Yech.
   2448  1.1  skrll 
   2449  1.1  skrll      Convert
   2450  1.1  skrll         OP x,y,result
   2451  1.1  skrll      to
   2452  1.1  skrll         mov x,R16	# if x != R16
   2453  1.1  skrll         mov y,R17	# if y != R17
   2454  1.1  skrll         lda AT,__OP
   2455  1.1  skrll         jsr AT,(AT),0
   2456  1.1  skrll         mov R0,result
   2457  1.1  skrll 
   2458  1.1  skrll      with appropriate optimizations if R0,R16,R17 are the registers
   2459  1.1  skrll      specified by the compiler.  */
   2460  1.1  skrll 
   2461  1.1  skrll   int xr, yr, rr;
   2462  1.1  skrll   symbolS *sym;
   2463  1.1  skrll   expressionS newtok[3];
   2464  1.1  skrll 
   2465  1.1  skrll   xr = regno (tok[0].X_add_number);
   2466  1.1  skrll   yr = regno (tok[1].X_add_number);
   2467  1.1  skrll 
   2468  1.1  skrll   if (ntok < 3)
   2469  1.1  skrll     rr = xr;
   2470  1.1  skrll   else
   2471  1.1  skrll     rr = regno (tok[2].X_add_number);
   2472  1.1  skrll 
   2473  1.1  skrll   /* Move the operands into the right place.  */
   2474  1.1  skrll   if (yr == AXP_REG_R16 && xr == AXP_REG_R17)
   2475  1.1  skrll     {
   2476  1.1  skrll       /* They are in exactly the wrong order -- swap through AT.  */
   2477  1.1  skrll       if (alpha_noat_on)
   2478  1.1  skrll 	as_bad (_("macro requires $at register while noat in effect"));
   2479  1.1  skrll 
   2480  1.1  skrll       set_tok_reg (newtok[0], AXP_REG_R16);
   2481  1.1  skrll       set_tok_reg (newtok[1], AXP_REG_AT);
   2482  1.1  skrll       assemble_tokens ("mov", newtok, 2, 1);
   2483  1.1  skrll 
   2484  1.1  skrll       set_tok_reg (newtok[0], AXP_REG_R17);
   2485  1.1  skrll       set_tok_reg (newtok[1], AXP_REG_R16);
   2486  1.1  skrll       assemble_tokens ("mov", newtok, 2, 1);
   2487  1.1  skrll 
   2488  1.1  skrll       set_tok_reg (newtok[0], AXP_REG_AT);
   2489  1.1  skrll       set_tok_reg (newtok[1], AXP_REG_R17);
   2490  1.1  skrll       assemble_tokens ("mov", newtok, 2, 1);
   2491  1.1  skrll     }
   2492  1.1  skrll   else
   2493  1.1  skrll     {
   2494  1.1  skrll       if (yr == AXP_REG_R16)
   2495  1.1  skrll 	{
   2496  1.1  skrll 	  set_tok_reg (newtok[0], AXP_REG_R16);
   2497  1.1  skrll 	  set_tok_reg (newtok[1], AXP_REG_R17);
   2498  1.1  skrll 	  assemble_tokens ("mov", newtok, 2, 1);
   2499  1.1  skrll 	}
   2500  1.1  skrll 
   2501  1.1  skrll       if (xr != AXP_REG_R16)
   2502  1.1  skrll 	{
   2503  1.1  skrll 	  set_tok_reg (newtok[0], xr);
   2504  1.1  skrll 	  set_tok_reg (newtok[1], AXP_REG_R16);
   2505  1.1  skrll 	  assemble_tokens ("mov", newtok, 2, 1);
   2506  1.1  skrll 	}
   2507  1.1  skrll 
   2508  1.1  skrll       if (yr != AXP_REG_R16 && yr != AXP_REG_R17)
   2509  1.1  skrll 	{
   2510  1.1  skrll 	  set_tok_reg (newtok[0], yr);
   2511  1.1  skrll 	  set_tok_reg (newtok[1], AXP_REG_R17);
   2512  1.1  skrll 	  assemble_tokens ("mov", newtok, 2, 1);
   2513  1.1  skrll 	}
   2514  1.1  skrll     }
   2515  1.1  skrll 
   2516  1.1  skrll   sym = symbol_find_or_make ((const char *) symname);
   2517  1.1  skrll 
   2518  1.1  skrll   set_tok_reg (newtok[0], AXP_REG_AT);
   2519  1.1  skrll   set_tok_sym (newtok[1], sym, 0);
   2520  1.1  skrll   assemble_tokens ("lda", newtok, 2, 1);
   2521  1.1  skrll 
   2522  1.1  skrll   /* Call the division routine.  */
   2523  1.1  skrll   set_tok_reg (newtok[0], AXP_REG_AT);
   2524  1.1  skrll   set_tok_cpreg (newtok[1], AXP_REG_AT);
   2525  1.1  skrll   set_tok_const (newtok[2], 0);
   2526  1.1  skrll   assemble_tokens ("jsr", newtok, 3, 1);
   2527  1.1  skrll 
   2528  1.1  skrll   /* Move the result to the right place.  */
   2529  1.1  skrll   if (rr != AXP_REG_R0)
   2530  1.1  skrll     {
   2531  1.1  skrll       set_tok_reg (newtok[0], AXP_REG_R0);
   2532  1.1  skrll       set_tok_reg (newtok[1], rr);
   2533  1.1  skrll       assemble_tokens ("mov", newtok, 2, 1);
   2534  1.1  skrll     }
   2535  1.1  skrll }
   2536  1.1  skrll 
   2537  1.1  skrll #else /* !OBJ_EVAX */
   2538  1.1  skrll 
   2539  1.1  skrll static void
   2540  1.1  skrll emit_division (const expressionS *tok,
   2541  1.1  skrll 	       int ntok,
   2542  1.1  skrll 	       const void * symname)
   2543  1.1  skrll {
   2544  1.1  skrll   /* DIVISION and MODULUS. Yech.
   2545  1.1  skrll      Convert
   2546  1.1  skrll         OP x,y,result
   2547  1.1  skrll      to
   2548  1.1  skrll         lda pv,__OP
   2549  1.1  skrll         mov x,t10
   2550  1.1  skrll         mov y,t11
   2551  1.1  skrll         jsr t9,(pv),__OP
   2552  1.1  skrll         mov t12,result
   2553  1.1  skrll 
   2554  1.1  skrll      with appropriate optimizations if t10,t11,t12 are the registers
   2555  1.1  skrll      specified by the compiler.  */
   2556  1.1  skrll 
   2557  1.1  skrll   int xr, yr, rr;
   2558  1.1  skrll   symbolS *sym;
   2559  1.1  skrll   expressionS newtok[3];
   2560  1.1  skrll 
   2561  1.1  skrll   xr = regno (tok[0].X_add_number);
   2562  1.1  skrll   yr = regno (tok[1].X_add_number);
   2563  1.1  skrll 
   2564  1.1  skrll   if (ntok < 3)
   2565  1.1  skrll     rr = xr;
   2566  1.1  skrll   else
   2567  1.1  skrll     rr = regno (tok[2].X_add_number);
   2568  1.1  skrll 
   2569  1.1  skrll   sym = symbol_find_or_make ((const char *) symname);
   2570  1.1  skrll 
   2571  1.1  skrll   /* Move the operands into the right place.  */
   2572  1.1  skrll   if (yr == AXP_REG_T10 && xr == AXP_REG_T11)
   2573  1.1  skrll     {
   2574  1.1  skrll       /* They are in exactly the wrong order -- swap through AT.  */
   2575  1.1  skrll       if (alpha_noat_on)
   2576  1.1  skrll 	as_bad (_("macro requires $at register while noat in effect"));
   2577  1.1  skrll 
   2578  1.1  skrll       set_tok_reg (newtok[0], AXP_REG_T10);
   2579  1.1  skrll       set_tok_reg (newtok[1], AXP_REG_AT);
   2580  1.1  skrll       assemble_tokens ("mov", newtok, 2, 1);
   2581  1.1  skrll 
   2582  1.1  skrll       set_tok_reg (newtok[0], AXP_REG_T11);
   2583  1.1  skrll       set_tok_reg (newtok[1], AXP_REG_T10);
   2584  1.1  skrll       assemble_tokens ("mov", newtok, 2, 1);
   2585  1.1  skrll 
   2586  1.1  skrll       set_tok_reg (newtok[0], AXP_REG_AT);
   2587  1.1  skrll       set_tok_reg (newtok[1], AXP_REG_T11);
   2588  1.1  skrll       assemble_tokens ("mov", newtok, 2, 1);
   2589  1.1  skrll     }
   2590  1.1  skrll   else
   2591  1.1  skrll     {
   2592  1.1  skrll       if (yr == AXP_REG_T10)
   2593  1.1  skrll 	{
   2594  1.1  skrll 	  set_tok_reg (newtok[0], AXP_REG_T10);
   2595  1.1  skrll 	  set_tok_reg (newtok[1], AXP_REG_T11);
   2596  1.1  skrll 	  assemble_tokens ("mov", newtok, 2, 1);
   2597  1.1  skrll 	}
   2598  1.1  skrll 
   2599  1.1  skrll       if (xr != AXP_REG_T10)
   2600  1.1  skrll 	{
   2601  1.1  skrll 	  set_tok_reg (newtok[0], xr);
   2602  1.1  skrll 	  set_tok_reg (newtok[1], AXP_REG_T10);
   2603  1.1  skrll 	  assemble_tokens ("mov", newtok, 2, 1);
   2604  1.1  skrll 	}
   2605  1.1  skrll 
   2606  1.1  skrll       if (yr != AXP_REG_T10 && yr != AXP_REG_T11)
   2607  1.1  skrll 	{
   2608  1.1  skrll 	  set_tok_reg (newtok[0], yr);
   2609  1.1  skrll 	  set_tok_reg (newtok[1], AXP_REG_T11);
   2610  1.1  skrll 	  assemble_tokens ("mov", newtok, 2, 1);
   2611  1.1  skrll 	}
   2612  1.1  skrll     }
   2613  1.1  skrll 
   2614  1.1  skrll   /* Call the division routine.  */
   2615  1.1  skrll   set_tok_reg (newtok[0], AXP_REG_T9);
   2616  1.1  skrll   set_tok_sym (newtok[1], sym, 0);
   2617  1.1  skrll   assemble_tokens ("jsr", newtok, 2, 1);
   2618  1.1  skrll 
   2619  1.1  skrll   /* Reload the GP register.  */
   2620  1.1  skrll #ifdef OBJ_AOUT
   2621  1.1  skrll FIXME
   2622  1.1  skrll #endif
   2623  1.1  skrll #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
   2624  1.1  skrll   set_tok_reg (newtok[0], alpha_gp_register);
   2625  1.1  skrll   set_tok_const (newtok[1], 0);
   2626  1.1  skrll   set_tok_preg (newtok[2], AXP_REG_T9);
   2627  1.1  skrll   assemble_tokens ("ldgp", newtok, 3, 1);
   2628  1.1  skrll #endif
   2629  1.1  skrll 
   2630  1.1  skrll   /* Move the result to the right place.  */
   2631  1.1  skrll   if (rr != AXP_REG_T12)
   2632  1.1  skrll     {
   2633  1.1  skrll       set_tok_reg (newtok[0], AXP_REG_T12);
   2634  1.1  skrll       set_tok_reg (newtok[1], rr);
   2635  1.1  skrll       assemble_tokens ("mov", newtok, 2, 1);
   2636  1.1  skrll     }
   2637  1.1  skrll }
   2638  1.1  skrll 
   2639  1.1  skrll #endif /* !OBJ_EVAX */
   2640  1.1  skrll 
   2641  1.1  skrll /* The jsr and jmp macros differ from their instruction counterparts
   2642  1.1  skrll    in that they can load the target address and default most
   2643  1.1  skrll    everything.  */
   2644  1.1  skrll 
   2645  1.1  skrll static void
   2646  1.1  skrll emit_jsrjmp (const expressionS *tok,
   2647  1.1  skrll 	     int ntok,
   2648  1.1  skrll 	     const void * vopname)
   2649  1.1  skrll {
   2650  1.1  skrll   const char *opname = (const char *) vopname;
   2651  1.1  skrll   struct alpha_insn insn;
   2652  1.1  skrll   expressionS newtok[3];
   2653  1.1  skrll   int r, tokidx = 0;
   2654  1.1  skrll   long lituse = 0;
   2655  1.1  skrll 
   2656  1.1  skrll   if (tokidx < ntok && tok[tokidx].X_op == O_register)
   2657  1.1  skrll     r = regno (tok[tokidx++].X_add_number);
   2658  1.1  skrll   else
   2659  1.1  skrll     r = strcmp (opname, "jmp") == 0 ? AXP_REG_ZERO : AXP_REG_RA;
   2660  1.1  skrll 
   2661  1.1  skrll   set_tok_reg (newtok[0], r);
   2662  1.1  skrll 
   2663  1.1  skrll   if (tokidx < ntok &&
   2664  1.1  skrll       (tok[tokidx].X_op == O_pregister || tok[tokidx].X_op == O_cpregister))
   2665  1.1  skrll     r = regno (tok[tokidx++].X_add_number);
   2666  1.1  skrll #ifdef OBJ_EVAX
   2667  1.1  skrll   /* Keep register if jsr $n.<sym>.  */
   2668  1.1  skrll #else
   2669  1.1  skrll   else
   2670  1.1  skrll     {
   2671  1.1  skrll       int basereg = alpha_gp_register;
   2672  1.1  skrll       lituse = load_expression (r = AXP_REG_PV, &tok[tokidx], &basereg, NULL);
   2673  1.1  skrll     }
   2674  1.1  skrll #endif
   2675  1.1  skrll 
   2676  1.1  skrll   set_tok_cpreg (newtok[1], r);
   2677  1.1  skrll 
   2678  1.1  skrll #ifdef OBJ_EVAX
   2679  1.1  skrll   /* FIXME: Add hint relocs to BFD for evax.  */
   2680  1.1  skrll #else
   2681  1.1  skrll   if (tokidx < ntok)
   2682  1.1  skrll     newtok[2] = tok[tokidx];
   2683  1.1  skrll   else
   2684  1.1  skrll #endif
   2685  1.1  skrll     set_tok_const (newtok[2], 0);
   2686  1.1  skrll 
   2687  1.1  skrll   assemble_tokens_to_insn (opname, newtok, 3, &insn);
   2688  1.1  skrll 
   2689  1.1  skrll   if (lituse)
   2690  1.1  skrll     {
   2691  1.1  skrll       assert (insn.nfixups < MAX_INSN_FIXUPS);
   2692  1.1  skrll       insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_JSR;
   2693  1.1  skrll       insn.fixups[insn.nfixups].exp.X_op = O_absent;
   2694  1.1  skrll       insn.nfixups++;
   2695  1.1  skrll       insn.sequence = lituse;
   2696  1.1  skrll     }
   2697  1.1  skrll 
   2698  1.1  skrll   emit_insn (&insn);
   2699  1.1  skrll }
   2700  1.1  skrll 
   2701  1.1  skrll /* The ret and jcr instructions differ from their instruction
   2702  1.1  skrll    counterparts in that everything can be defaulted.  */
   2703  1.1  skrll 
   2704  1.1  skrll static void
   2705  1.1  skrll emit_retjcr (const expressionS *tok,
   2706  1.1  skrll 	     int ntok,
   2707  1.1  skrll 	     const void * vopname)
   2708  1.1  skrll {
   2709  1.1  skrll   const char *opname = (const char *) vopname;
   2710  1.1  skrll   expressionS newtok[3];
   2711  1.1  skrll   int r, tokidx = 0;
   2712  1.1  skrll 
   2713  1.1  skrll   if (tokidx < ntok && tok[tokidx].X_op == O_register)
   2714  1.1  skrll     r = regno (tok[tokidx++].X_add_number);
   2715  1.1  skrll   else
   2716  1.1  skrll     r = AXP_REG_ZERO;
   2717  1.1  skrll 
   2718  1.1  skrll   set_tok_reg (newtok[0], r);
   2719  1.1  skrll 
   2720  1.1  skrll   if (tokidx < ntok &&
   2721  1.1  skrll       (tok[tokidx].X_op == O_pregister || tok[tokidx].X_op == O_cpregister))
   2722  1.1  skrll     r = regno (tok[tokidx++].X_add_number);
   2723  1.1  skrll   else
   2724  1.1  skrll     r = AXP_REG_RA;
   2725  1.1  skrll 
   2726  1.1  skrll   set_tok_cpreg (newtok[1], r);
   2727  1.1  skrll 
   2728  1.1  skrll   if (tokidx < ntok)
   2729  1.1  skrll     newtok[2] = tok[tokidx];
   2730  1.1  skrll   else
   2731  1.1  skrll     set_tok_const (newtok[2], strcmp (opname, "ret") == 0);
   2732  1.1  skrll 
   2733  1.1  skrll   assemble_tokens (opname, newtok, 3, 0);
   2734  1.1  skrll }
   2735  1.1  skrll 
   2736  1.1  skrll /* Implement the ldgp macro.  */
   2737  1.1  skrll 
   2738  1.1  skrll static void
   2739  1.1  skrll emit_ldgp (const expressionS *tok,
   2740  1.1  skrll 	   int ntok ATTRIBUTE_UNUSED,
   2741  1.1  skrll 	   const void * unused ATTRIBUTE_UNUSED)
   2742  1.1  skrll {
   2743  1.1  skrll #ifdef OBJ_AOUT
   2744  1.1  skrll FIXME
   2745  1.1  skrll #endif
   2746  1.1  skrll #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
   2747  1.1  skrll   /* from "ldgp r1,n(r2)", generate "ldah r1,X(R2); lda r1,Y(r1)"
   2748  1.1  skrll      with appropriate constants and relocations.  */
   2749  1.1  skrll   struct alpha_insn insn;
   2750  1.1  skrll   expressionS newtok[3];
   2751  1.1  skrll   expressionS addend;
   2752  1.1  skrll 
   2753  1.1  skrll #ifdef OBJ_ECOFF
   2754  1.1  skrll   if (regno (tok[2].X_add_number) == AXP_REG_PV)
   2755  1.1  skrll     ecoff_set_gp_prolog_size (0);
   2756  1.1  skrll #endif
   2757  1.1  skrll 
   2758  1.1  skrll   newtok[0] = tok[0];
   2759  1.1  skrll   set_tok_const (newtok[1], 0);
   2760  1.1  skrll   newtok[2] = tok[2];
   2761  1.1  skrll 
   2762  1.1  skrll   assemble_tokens_to_insn ("ldah", newtok, 3, &insn);
   2763  1.1  skrll 
   2764  1.1  skrll   addend = tok[1];
   2765  1.1  skrll 
   2766  1.1  skrll #ifdef OBJ_ECOFF
   2767  1.1  skrll   if (addend.X_op != O_constant)
   2768  1.1  skrll     as_bad (_("can not resolve expression"));
   2769  1.1  skrll   addend.X_op = O_symbol;
   2770  1.1  skrll   addend.X_add_symbol = alpha_gp_symbol;
   2771  1.1  skrll #endif
   2772  1.1  skrll 
   2773  1.1  skrll   insn.nfixups = 1;
   2774  1.1  skrll   insn.fixups[0].exp = addend;
   2775  1.1  skrll   insn.fixups[0].reloc = BFD_RELOC_ALPHA_GPDISP_HI16;
   2776  1.1  skrll   insn.sequence = next_sequence_num;
   2777  1.1  skrll 
   2778  1.1  skrll   emit_insn (&insn);
   2779  1.1  skrll 
   2780  1.1  skrll   set_tok_preg (newtok[2], tok[0].X_add_number);
   2781  1.1  skrll 
   2782  1.1  skrll   assemble_tokens_to_insn ("lda", newtok, 3, &insn);
   2783  1.1  skrll 
   2784  1.1  skrll #ifdef OBJ_ECOFF
   2785  1.1  skrll   addend.X_add_number += 4;
   2786  1.1  skrll #endif
   2787  1.1  skrll 
   2788  1.1  skrll   insn.nfixups = 1;
   2789  1.1  skrll   insn.fixups[0].exp = addend;
   2790  1.1  skrll   insn.fixups[0].reloc = BFD_RELOC_ALPHA_GPDISP_LO16;
   2791  1.1  skrll   insn.sequence = next_sequence_num--;
   2792  1.1  skrll 
   2793  1.1  skrll   emit_insn (&insn);
   2794  1.1  skrll #endif /* OBJ_ECOFF || OBJ_ELF */
   2795  1.1  skrll }
   2796  1.1  skrll 
   2797  1.1  skrll /* The macro table.  */
   2798  1.1  skrll 
   2799  1.1  skrll static const struct alpha_macro alpha_macros[] =
   2800  1.1  skrll {
   2801  1.1  skrll /* Load/Store macros.  */
   2802  1.1  skrll   { "lda",	emit_lda, NULL,
   2803  1.1  skrll     { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
   2804  1.1  skrll   { "ldah",	emit_ldah, NULL,
   2805  1.1  skrll     { MACRO_IR, MACRO_EXP, MACRO_EOA } },
   2806  1.1  skrll 
   2807  1.1  skrll   { "ldl",	emit_ir_load, "ldl",
   2808  1.1  skrll     { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
   2809  1.1  skrll   { "ldl_l",	emit_ir_load, "ldl_l",
   2810  1.1  skrll     { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
   2811  1.1  skrll   { "ldq",	emit_ir_load, "ldq",
   2812  1.1  skrll     { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
   2813  1.1  skrll   { "ldq_l",	emit_ir_load, "ldq_l",
   2814  1.1  skrll     { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
   2815  1.1  skrll   { "ldq_u",	emit_ir_load, "ldq_u",
   2816  1.1  skrll     { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
   2817  1.1  skrll   { "ldf",	emit_loadstore, "ldf",
   2818  1.1  skrll     { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
   2819  1.1  skrll   { "ldg",	emit_loadstore, "ldg",
   2820  1.1  skrll     { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
   2821  1.1  skrll   { "lds",	emit_loadstore, "lds",
   2822  1.1  skrll     { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
   2823  1.1  skrll   { "ldt",	emit_loadstore, "ldt",
   2824  1.1  skrll     { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
   2825  1.1  skrll 
   2826  1.1  skrll   { "ldb",	emit_ldX, (void *) 0,
   2827  1.1  skrll     { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
   2828  1.1  skrll   { "ldbu",	emit_ldXu, (void *) 0,
   2829  1.1  skrll     { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
   2830  1.1  skrll   { "ldw",	emit_ldX, (void *) 1,
   2831  1.1  skrll     { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
   2832  1.1  skrll   { "ldwu",	emit_ldXu, (void *) 1,
   2833  1.1  skrll     { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
   2834  1.1  skrll 
   2835  1.1  skrll   { "uldw",	emit_uldX, (void *) 1,
   2836  1.1  skrll     { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
   2837  1.1  skrll   { "uldwu",	emit_uldXu, (void *) 1,
   2838  1.1  skrll     { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
   2839  1.1  skrll   { "uldl",	emit_uldX, (void *) 2,
   2840  1.1  skrll     { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
   2841  1.1  skrll   { "uldlu",	emit_uldXu, (void *) 2,
   2842  1.1  skrll     { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
   2843  1.1  skrll   { "uldq",	emit_uldXu, (void *) 3,
   2844  1.1  skrll     { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
   2845  1.1  skrll 
   2846  1.1  skrll   { "ldgp",	emit_ldgp, NULL,
   2847  1.1  skrll     { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA } },
   2848  1.1  skrll 
   2849  1.1  skrll   { "ldi",	emit_lda, NULL,
   2850  1.1  skrll     { MACRO_IR, MACRO_EXP, MACRO_EOA } },
   2851  1.1  skrll   { "ldil",	emit_ldil, NULL,
   2852  1.1  skrll     { MACRO_IR, MACRO_EXP, MACRO_EOA } },
   2853  1.1  skrll   { "ldiq",	emit_lda, NULL,
   2854  1.1  skrll     { MACRO_IR, MACRO_EXP, MACRO_EOA } },
   2855  1.1  skrll 
   2856  1.1  skrll   { "stl",	emit_loadstore, "stl",
   2857  1.1  skrll     { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
   2858  1.1  skrll   { "stl_c",	emit_loadstore, "stl_c",
   2859  1.1  skrll     { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
   2860  1.1  skrll   { "stq",	emit_loadstore, "stq",
   2861  1.1  skrll     { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
   2862  1.1  skrll   { "stq_c",	emit_loadstore, "stq_c",
   2863  1.1  skrll     { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
   2864  1.1  skrll   { "stq_u",	emit_loadstore, "stq_u",
   2865  1.1  skrll     { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
   2866  1.1  skrll   { "stf",	emit_loadstore, "stf",
   2867  1.1  skrll     { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
   2868  1.1  skrll   { "stg",	emit_loadstore, "stg",
   2869  1.1  skrll     { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
   2870  1.1  skrll   { "sts",	emit_loadstore, "sts",
   2871  1.1  skrll     { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
   2872  1.1  skrll   { "stt",	emit_loadstore, "stt",
   2873  1.1  skrll     { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
   2874  1.1  skrll 
   2875  1.1  skrll   { "stb",	emit_stX, (void *) 0,
   2876  1.1  skrll     { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
   2877  1.1  skrll   { "stw",	emit_stX, (void *) 1,
   2878  1.1  skrll     { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
   2879  1.1  skrll   { "ustw",	emit_ustX, (void *) 1,
   2880  1.1  skrll     { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
   2881  1.1  skrll   { "ustl",	emit_ustX, (void *) 2,
   2882  1.1  skrll     { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
   2883  1.1  skrll   { "ustq",	emit_ustX, (void *) 3,
   2884  1.1  skrll     { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
   2885  1.1  skrll 
   2886  1.1  skrll /* Arithmetic macros.  */
   2887  1.1  skrll 
   2888  1.1  skrll   { "sextb",	emit_sextX, (void *) 0,
   2889  1.1  skrll     { MACRO_IR, MACRO_IR, MACRO_EOA,
   2890  1.1  skrll       MACRO_IR, MACRO_EOA,
   2891  1.1  skrll       /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
   2892  1.1  skrll   { "sextw",	emit_sextX, (void *) 1,
   2893  1.1  skrll     { MACRO_IR, MACRO_IR, MACRO_EOA,
   2894  1.1  skrll       MACRO_IR, MACRO_EOA,
   2895  1.1  skrll       /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
   2896  1.1  skrll 
   2897  1.1  skrll   { "divl",	emit_division, "__divl",
   2898  1.1  skrll     { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
   2899  1.1  skrll       MACRO_IR, MACRO_IR, MACRO_EOA,
   2900  1.1  skrll       /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
   2901  1.1  skrll       MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
   2902  1.1  skrll   { "divlu",	emit_division, "__divlu",
   2903  1.1  skrll     { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
   2904  1.1  skrll       MACRO_IR, MACRO_IR, MACRO_EOA,
   2905  1.1  skrll       /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
   2906  1.1  skrll       MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
   2907  1.1  skrll   { "divq",	emit_division, "__divq",
   2908  1.1  skrll     { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
   2909  1.1  skrll       MACRO_IR, MACRO_IR, MACRO_EOA,
   2910  1.1  skrll       /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
   2911  1.1  skrll       MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
   2912  1.1  skrll   { "divqu",	emit_division, "__divqu",
   2913  1.1  skrll     { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
   2914  1.1  skrll       MACRO_IR, MACRO_IR, MACRO_EOA,
   2915  1.1  skrll       /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
   2916  1.1  skrll       MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
   2917  1.1  skrll   { "reml",	emit_division, "__reml",
   2918  1.1  skrll     { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
   2919  1.1  skrll       MACRO_IR, MACRO_IR, MACRO_EOA,
   2920  1.1  skrll       /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
   2921  1.1  skrll       MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
   2922  1.1  skrll   { "remlu",	emit_division, "__remlu",
   2923  1.1  skrll     { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
   2924  1.1  skrll       MACRO_IR, MACRO_IR, MACRO_EOA,
   2925  1.1  skrll       /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
   2926  1.1  skrll       MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
   2927  1.1  skrll   { "remq",	emit_division, "__remq",
   2928  1.1  skrll     { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
   2929  1.1  skrll       MACRO_IR, MACRO_IR, MACRO_EOA,
   2930  1.1  skrll       /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
   2931  1.1  skrll       MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
   2932  1.1  skrll   { "remqu",	emit_division, "__remqu",
   2933  1.1  skrll     { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
   2934  1.1  skrll       MACRO_IR, MACRO_IR, MACRO_EOA,
   2935  1.1  skrll       /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
   2936  1.1  skrll       MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
   2937  1.1  skrll 
   2938  1.1  skrll   { "jsr",	emit_jsrjmp, "jsr",
   2939  1.1  skrll     { MACRO_PIR, MACRO_EXP, MACRO_EOA,
   2940  1.1  skrll       MACRO_PIR, MACRO_EOA,
   2941  1.1  skrll       MACRO_IR,  MACRO_EXP, MACRO_EOA,
   2942  1.1  skrll       MACRO_EXP, MACRO_EOA } },
   2943  1.1  skrll   { "jmp",	emit_jsrjmp, "jmp",
   2944  1.1  skrll     { MACRO_PIR, MACRO_EXP, MACRO_EOA,
   2945  1.1  skrll       MACRO_PIR, MACRO_EOA,
   2946  1.1  skrll       MACRO_IR,  MACRO_EXP, MACRO_EOA,
   2947  1.1  skrll       MACRO_EXP, MACRO_EOA } },
   2948  1.1  skrll   { "ret",	emit_retjcr, "ret",
   2949  1.1  skrll     { MACRO_IR, MACRO_EXP, MACRO_EOA,
   2950  1.1  skrll       MACRO_IR, MACRO_EOA,
   2951  1.1  skrll       MACRO_PIR, MACRO_EXP, MACRO_EOA,
   2952  1.1  skrll       MACRO_PIR, MACRO_EOA,
   2953  1.1  skrll       MACRO_EXP, MACRO_EOA,
   2954  1.1  skrll       MACRO_EOA } },
   2955  1.1  skrll   { "jcr",	emit_retjcr, "jcr",
   2956  1.1  skrll     { MACRO_IR,  MACRO_EXP, MACRO_EOA,
   2957  1.1  skrll       MACRO_IR,  MACRO_EOA,
   2958  1.1  skrll       MACRO_PIR, MACRO_EXP, MACRO_EOA,
   2959  1.1  skrll       MACRO_PIR, MACRO_EOA,
   2960  1.1  skrll       MACRO_EXP, MACRO_EOA,
   2961  1.1  skrll       MACRO_EOA } },
   2962  1.1  skrll   { "jsr_coroutine",	emit_retjcr, "jcr",
   2963  1.1  skrll     { MACRO_IR,  MACRO_EXP, MACRO_EOA,
   2964  1.1  skrll       MACRO_IR,  MACRO_EOA,
   2965  1.1  skrll       MACRO_PIR, MACRO_EXP, MACRO_EOA,
   2966  1.1  skrll       MACRO_PIR, MACRO_EOA,
   2967  1.1  skrll       MACRO_EXP, MACRO_EOA,
   2968  1.1  skrll       MACRO_EOA } },
   2969  1.1  skrll };
   2970  1.1  skrll 
   2971  1.1  skrll static const unsigned int alpha_num_macros
   2972  1.1  skrll   = sizeof (alpha_macros) / sizeof (*alpha_macros);
   2973  1.1  skrll 
   2974  1.1  skrll /* Search forward through all variants of a macro looking for a syntax
   2975  1.1  skrll    match.  */
   2976  1.1  skrll 
   2977  1.1  skrll static const struct alpha_macro *
   2978  1.1  skrll find_macro_match (const struct alpha_macro *first_macro,
   2979  1.1  skrll 		  const expressionS *tok,
   2980  1.1  skrll 		  int *pntok)
   2981  1.1  skrll 
   2982  1.1  skrll {
   2983  1.1  skrll   const struct alpha_macro *macro = first_macro;
   2984  1.1  skrll   int ntok = *pntok;
   2985  1.1  skrll 
   2986  1.1  skrll   do
   2987  1.1  skrll     {
   2988  1.1  skrll       const enum alpha_macro_arg *arg = macro->argsets;
   2989  1.1  skrll       int tokidx = 0;
   2990  1.1  skrll 
   2991  1.1  skrll       while (*arg)
   2992  1.1  skrll 	{
   2993  1.1  skrll 	  switch (*arg)
   2994  1.1  skrll 	    {
   2995  1.1  skrll 	    case MACRO_EOA:
   2996  1.1  skrll 	      if (tokidx == ntok)
   2997  1.1  skrll 		return macro;
   2998  1.1  skrll 	      else
   2999  1.1  skrll 		tokidx = 0;
   3000  1.1  skrll 	      break;
   3001  1.1  skrll 
   3002  1.1  skrll 	      /* Index register.  */
   3003  1.1  skrll 	    case MACRO_IR:
   3004  1.1  skrll 	      if (tokidx >= ntok || tok[tokidx].X_op != O_register
   3005  1.1  skrll 		  || !is_ir_num (tok[tokidx].X_add_number))
   3006  1.1  skrll 		goto match_failed;
   3007  1.1  skrll 	      ++tokidx;
   3008  1.1  skrll 	      break;
   3009  1.1  skrll 
   3010  1.1  skrll 	      /* Parenthesized index register.  */
   3011  1.1  skrll 	    case MACRO_PIR:
   3012  1.1  skrll 	      if (tokidx >= ntok || tok[tokidx].X_op != O_pregister
   3013  1.1  skrll 		  || !is_ir_num (tok[tokidx].X_add_number))
   3014  1.1  skrll 		goto match_failed;
   3015  1.1  skrll 	      ++tokidx;
   3016  1.1  skrll 	      break;
   3017  1.1  skrll 
   3018  1.1  skrll 	      /* Optional parenthesized index register.  */
   3019  1.1  skrll 	    case MACRO_OPIR:
   3020  1.1  skrll 	      if (tokidx < ntok && tok[tokidx].X_op == O_pregister
   3021  1.1  skrll 		  && is_ir_num (tok[tokidx].X_add_number))
   3022  1.1  skrll 		++tokidx;
   3023  1.1  skrll 	      break;
   3024  1.1  skrll 
   3025  1.1  skrll 	      /* Leading comma with a parenthesized index register.  */
   3026  1.1  skrll 	    case MACRO_CPIR:
   3027  1.1  skrll 	      if (tokidx >= ntok || tok[tokidx].X_op != O_cpregister
   3028  1.1  skrll 		  || !is_ir_num (tok[tokidx].X_add_number))
   3029  1.1  skrll 		goto match_failed;
   3030  1.1  skrll 	      ++tokidx;
   3031  1.1  skrll 	      break;
   3032  1.1  skrll 
   3033  1.1  skrll 	      /* Floating point register.  */
   3034  1.1  skrll 	    case MACRO_FPR:
   3035  1.1  skrll 	      if (tokidx >= ntok || tok[tokidx].X_op != O_register
   3036  1.1  skrll 		  || !is_fpr_num (tok[tokidx].X_add_number))
   3037  1.1  skrll 		goto match_failed;
   3038  1.1  skrll 	      ++tokidx;
   3039  1.1  skrll 	      break;
   3040  1.1  skrll 
   3041  1.1  skrll 	      /* Normal expression.  */
   3042  1.1  skrll 	    case MACRO_EXP:
   3043  1.1  skrll 	      if (tokidx >= ntok)
   3044  1.1  skrll 		goto match_failed;
   3045  1.1  skrll 	      switch (tok[tokidx].X_op)
   3046  1.1  skrll 		{
   3047  1.1  skrll 		case O_illegal:
   3048  1.1  skrll 		case O_absent:
   3049  1.1  skrll 		case O_register:
   3050  1.1  skrll 		case O_pregister:
   3051  1.1  skrll 		case O_cpregister:
   3052  1.1  skrll 		case O_literal:
   3053  1.1  skrll 		case O_lituse_base:
   3054  1.1  skrll 		case O_lituse_bytoff:
   3055  1.1  skrll 		case O_lituse_jsr:
   3056  1.1  skrll 		case O_gpdisp:
   3057  1.1  skrll 		case O_gprelhigh:
   3058  1.1  skrll 		case O_gprellow:
   3059  1.1  skrll 		case O_gprel:
   3060  1.1  skrll 		case O_samegp:
   3061  1.1  skrll 		  goto match_failed;
   3062  1.1  skrll 
   3063  1.1  skrll 		default:
   3064  1.1  skrll 		  break;
   3065  1.1  skrll 		}
   3066  1.1  skrll 	      ++tokidx;
   3067  1.1  skrll 	      break;
   3068  1.1  skrll 
   3069  1.1  skrll 	    match_failed:
   3070  1.1  skrll 	      while (*arg != MACRO_EOA)
   3071  1.1  skrll 		++arg;
   3072  1.1  skrll 	      tokidx = 0;
   3073  1.1  skrll 	      break;
   3074  1.1  skrll 	    }
   3075  1.1  skrll 	  ++arg;
   3076  1.1  skrll 	}
   3077  1.1  skrll     }
   3078  1.1  skrll   while (++macro - alpha_macros < (int) alpha_num_macros
   3079  1.1  skrll 	 && !strcmp (macro->name, first_macro->name));
   3080  1.1  skrll 
   3081  1.1  skrll   return NULL;
   3082  1.1  skrll }
   3083  1.1  skrll 
   3084  1.1  skrll /* Given an opcode name and a pre-tokenized set of arguments, take the
   3085  1.1  skrll    opcode all the way through emission.  */
   3086  1.1  skrll 
   3087  1.1  skrll static void
   3088  1.1  skrll assemble_tokens (const char *opname,
   3089  1.1  skrll 		 const expressionS *tok,
   3090  1.1  skrll 		 int ntok,
   3091  1.1  skrll 		 int local_macros_on)
   3092  1.1  skrll {
   3093  1.1  skrll   int found_something = 0;
   3094  1.1  skrll   const struct alpha_opcode *opcode;
   3095  1.1  skrll   const struct alpha_macro *macro;
   3096  1.1  skrll   int cpumatch = 1;
   3097  1.1  skrll   bfd_reloc_code_real_type reloc = BFD_RELOC_UNUSED;
   3098  1.1  skrll 
   3099  1.1  skrll #ifdef RELOC_OP_P
   3100  1.1  skrll   /* If a user-specified relocation is present, this is not a macro.  */
   3101  1.1  skrll   if (ntok && USER_RELOC_P (tok[ntok - 1].X_op))
   3102  1.1  skrll     {
   3103  1.1  skrll       reloc = ALPHA_RELOC_TABLE (tok[ntok - 1].X_op)->reloc;
   3104  1.1  skrll       ntok--;
   3105  1.1  skrll     }
   3106  1.1  skrll   else
   3107  1.1  skrll #endif
   3108  1.1  skrll   if (local_macros_on)
   3109  1.1  skrll     {
   3110  1.1  skrll       macro = ((const struct alpha_macro *)
   3111  1.1  skrll 	       hash_find (alpha_macro_hash, opname));
   3112  1.1  skrll       if (macro)
   3113  1.1  skrll 	{
   3114  1.1  skrll 	  found_something = 1;
   3115  1.1  skrll 	  macro = find_macro_match (macro, tok, &ntok);
   3116  1.1  skrll 	  if (macro)
   3117  1.1  skrll 	    {
   3118  1.1  skrll 	      (*macro->emit) (tok, ntok, macro->arg);
   3119  1.1  skrll 	      return;
   3120  1.1  skrll 	    }
   3121  1.1  skrll 	}
   3122  1.1  skrll     }
   3123  1.1  skrll 
   3124  1.1  skrll   /* Search opcodes.  */
   3125  1.1  skrll   opcode = (const struct alpha_opcode *) hash_find (alpha_opcode_hash, opname);
   3126  1.1  skrll   if (opcode)
   3127  1.1  skrll     {
   3128  1.1  skrll       found_something = 1;
   3129  1.1  skrll       opcode = find_opcode_match (opcode, tok, &ntok, &cpumatch);
   3130  1.1  skrll       if (opcode)
   3131  1.1  skrll 	{
   3132  1.1  skrll 	  struct alpha_insn insn;
   3133  1.1  skrll 	  assemble_insn (opcode, tok, ntok, &insn, reloc);
   3134  1.1  skrll 
   3135  1.1  skrll 	  /* Copy the sequence number for the reloc from the reloc token.  */
   3136  1.1  skrll 	  if (reloc != BFD_RELOC_UNUSED)
   3137  1.1  skrll 	    insn.sequence = tok[ntok].X_add_number;
   3138  1.1  skrll 
   3139  1.1  skrll 	  emit_insn (&insn);
   3140  1.1  skrll 	  return;
   3141  1.1  skrll 	}
   3142  1.1  skrll     }
   3143  1.1  skrll 
   3144  1.1  skrll   if (found_something)
   3145  1.1  skrll     {
   3146  1.1  skrll       if (cpumatch)
   3147  1.1  skrll 	as_bad (_("inappropriate arguments for opcode `%s'"), opname);
   3148  1.1  skrll       else
   3149  1.1  skrll 	as_bad (_("opcode `%s' not supported for target %s"), opname,
   3150  1.1  skrll 		alpha_target_name);
   3151  1.1  skrll     }
   3152  1.1  skrll   else
   3153  1.1  skrll     as_bad (_("unknown opcode `%s'"), opname);
   3154  1.1  skrll }
   3155  1.1  skrll 
   3156  1.1  skrll #ifdef OBJ_EVAX
   3158  1.1  skrll 
   3159  1.1  skrll /* Add symbol+addend to link pool.
   3160  1.1  skrll    Return offset from basesym to entry in link pool.
   3161  1.1  skrll 
   3162  1.1  skrll    Add new fixup only if offset isn't 16bit.  */
   3163  1.1  skrll 
   3164  1.1  skrll valueT
   3165  1.1  skrll add_to_link_pool (symbolS *basesym,
   3166  1.1  skrll 		  symbolS *sym,
   3167  1.1  skrll 		  offsetT addend)
   3168  1.1  skrll {
   3169  1.1  skrll   segT current_section = now_seg;
   3170  1.1  skrll   int current_subsec = now_subseg;
   3171  1.1  skrll   valueT offset;
   3172  1.1  skrll   bfd_reloc_code_real_type reloc_type;
   3173  1.1  skrll   char *p;
   3174  1.1  skrll   segment_info_type *seginfo = seg_info (alpha_link_section);
   3175  1.1  skrll   fixS *fixp;
   3176  1.1  skrll 
   3177  1.1  skrll   offset = - *symbol_get_obj (basesym);
   3178  1.1  skrll 
   3179  1.1  skrll   /* @@ This assumes all entries in a given section will be of the same
   3180  1.1  skrll      size...  Probably correct, but unwise to rely on.  */
   3181  1.1  skrll   /* This must always be called with the same subsegment.  */
   3182  1.1  skrll 
   3183  1.1  skrll   if (seginfo->frchainP)
   3184  1.1  skrll     for (fixp = seginfo->frchainP->fix_root;
   3185  1.1  skrll 	 fixp != (fixS *) NULL;
   3186  1.1  skrll 	 fixp = fixp->fx_next, offset += 8)
   3187  1.1  skrll       {
   3188  1.1  skrll 	if (fixp->fx_addsy == sym && fixp->fx_offset == addend)
   3189  1.1  skrll 	  {
   3190  1.1  skrll 	    if (range_signed_16 (offset))
   3191  1.1  skrll 	      {
   3192  1.1  skrll 		return offset;
   3193  1.1  skrll 	      }
   3194  1.1  skrll 	  }
   3195  1.1  skrll       }
   3196  1.1  skrll 
   3197  1.1  skrll   /* Not found in 16bit signed range.  */
   3198  1.1  skrll 
   3199  1.1  skrll   subseg_set (alpha_link_section, 0);
   3200  1.1  skrll   p = frag_more (8);
   3201  1.1  skrll   memset (p, 0, 8);
   3202  1.1  skrll 
   3203  1.1  skrll   fix_new (frag_now, p - frag_now->fr_literal, 8, sym, addend, 0,
   3204  1.1  skrll 	   BFD_RELOC_64);
   3205  1.1  skrll 
   3206  1.1  skrll   subseg_set (current_section, current_subsec);
   3207  1.1  skrll   seginfo->literal_pool_size += 8;
   3208  1.1  skrll   return offset;
   3209  1.1  skrll }
   3210  1.1  skrll 
   3211  1.1  skrll #endif /* OBJ_EVAX */
   3212  1.1  skrll 
   3213  1.1  skrll /* Assembler directives.  */
   3215  1.1  skrll 
   3216  1.1  skrll /* Handle the .text pseudo-op.  This is like the usual one, but it
   3217  1.1  skrll    clears alpha_insn_label and restores auto alignment.  */
   3218  1.1  skrll 
   3219  1.1  skrll static void
   3220  1.1  skrll s_alpha_text (int i)
   3221  1.1  skrll 
   3222  1.1  skrll {
   3223  1.1  skrll #ifdef OBJ_ELF
   3224  1.1  skrll   obj_elf_text (i);
   3225  1.1  skrll #else
   3226  1.1  skrll   s_text (i);
   3227  1.1  skrll #endif
   3228  1.1  skrll   alpha_insn_label = NULL;
   3229  1.1  skrll   alpha_auto_align_on = 1;
   3230  1.1  skrll   alpha_current_align = 0;
   3231  1.1  skrll }
   3232  1.1  skrll 
   3233  1.1  skrll /* Handle the .data pseudo-op.  This is like the usual one, but it
   3234  1.1  skrll    clears alpha_insn_label and restores auto alignment.  */
   3235  1.1  skrll 
   3236  1.1  skrll static void
   3237  1.1  skrll s_alpha_data (int i)
   3238  1.1  skrll {
   3239  1.1  skrll #ifdef OBJ_ELF
   3240  1.1  skrll   obj_elf_data (i);
   3241  1.1  skrll #else
   3242  1.1  skrll   s_data (i);
   3243  1.1  skrll #endif
   3244  1.1  skrll   alpha_insn_label = NULL;
   3245  1.1  skrll   alpha_auto_align_on = 1;
   3246  1.1  skrll   alpha_current_align = 0;
   3247  1.1  skrll }
   3248  1.1  skrll 
   3249  1.1  skrll #if defined (OBJ_ECOFF) || defined (OBJ_EVAX)
   3250  1.1  skrll 
   3251  1.1  skrll /* Handle the OSF/1 and openVMS .comm pseudo quirks.
   3252  1.1  skrll    openVMS constructs a section for every common symbol.  */
   3253  1.1  skrll 
   3254  1.1  skrll static void
   3255  1.1  skrll s_alpha_comm (int ignore ATTRIBUTE_UNUSED)
   3256  1.1  skrll {
   3257  1.1  skrll   char *name;
   3258  1.1  skrll   char c;
   3259  1.1  skrll   char *p;
   3260  1.1  skrll   offsetT temp;
   3261  1.1  skrll   symbolS *symbolP;
   3262  1.1  skrll #ifdef OBJ_EVAX
   3263  1.1  skrll   segT current_section = now_seg;
   3264  1.1  skrll   int current_subsec = now_subseg;
   3265  1.1  skrll   segT new_seg;
   3266  1.1  skrll #endif
   3267  1.1  skrll 
   3268  1.1  skrll   name = input_line_pointer;
   3269  1.1  skrll   c = get_symbol_end ();
   3270  1.1  skrll 
   3271  1.1  skrll   /* Just after name is now '\0'.  */
   3272  1.1  skrll   p = input_line_pointer;
   3273  1.1  skrll   *p = c;
   3274  1.1  skrll 
   3275  1.1  skrll   SKIP_WHITESPACE ();
   3276  1.1  skrll 
   3277  1.1  skrll   /* Alpha OSF/1 compiler doesn't provide the comma, gcc does.  */
   3278  1.1  skrll   if (*input_line_pointer == ',')
   3279  1.1  skrll     {
   3280  1.1  skrll       input_line_pointer++;
   3281  1.1  skrll       SKIP_WHITESPACE ();
   3282  1.1  skrll     }
   3283  1.1  skrll   if ((temp = get_absolute_expression ()) < 0)
   3284  1.1  skrll     {
   3285  1.1  skrll       as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) temp);
   3286  1.1  skrll       ignore_rest_of_line ();
   3287  1.1  skrll       return;
   3288  1.1  skrll     }
   3289  1.1  skrll 
   3290  1.1  skrll   *p = 0;
   3291  1.1  skrll   symbolP = symbol_find_or_make (name);
   3292  1.1  skrll 
   3293  1.1  skrll #ifdef OBJ_EVAX
   3294  1.1  skrll   /* Make a section for the common symbol.  */
   3295  1.1  skrll   new_seg = subseg_new (xstrdup (name), 0);
   3296  1.1  skrll #endif
   3297  1.1  skrll 
   3298  1.1  skrll   *p = c;
   3299  1.1  skrll 
   3300  1.1  skrll #ifdef OBJ_EVAX
   3301  1.1  skrll   /* Alignment might follow.  */
   3302  1.1  skrll   if (*input_line_pointer == ',')
   3303  1.1  skrll     {
   3304  1.1  skrll       offsetT align;
   3305  1.1  skrll 
   3306  1.1  skrll       input_line_pointer++;
   3307  1.1  skrll       align = get_absolute_expression ();
   3308  1.1  skrll       bfd_set_section_alignment (stdoutput, new_seg, align);
   3309  1.1  skrll     }
   3310  1.1  skrll #endif
   3311  1.1  skrll 
   3312  1.1  skrll   if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
   3313  1.1  skrll     {
   3314  1.1  skrll       as_bad (_("Ignoring attempt to re-define symbol"));
   3315  1.1  skrll       ignore_rest_of_line ();
   3316  1.1  skrll       return;
   3317  1.1  skrll     }
   3318  1.1  skrll 
   3319  1.1  skrll #ifdef OBJ_EVAX
   3320  1.1  skrll   if (bfd_section_size (stdoutput, new_seg) > 0)
   3321  1.1  skrll     {
   3322  1.1  skrll       if (bfd_section_size (stdoutput, new_seg) != temp)
   3323  1.1  skrll 	as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
   3324  1.1  skrll 		S_GET_NAME (symbolP),
   3325  1.1  skrll 		(long) bfd_section_size (stdoutput, new_seg),
   3326  1.1  skrll 		(long) temp);
   3327  1.1  skrll     }
   3328  1.1  skrll #else
   3329  1.1  skrll   if (S_GET_VALUE (symbolP))
   3330  1.1  skrll     {
   3331  1.1  skrll       if (S_GET_VALUE (symbolP) != (valueT) temp)
   3332  1.1  skrll 	as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
   3333  1.1  skrll 		S_GET_NAME (symbolP),
   3334  1.1  skrll 		(long) S_GET_VALUE (symbolP),
   3335  1.1  skrll 		(long) temp);
   3336  1.1  skrll     }
   3337  1.1  skrll #endif
   3338  1.1  skrll   else
   3339  1.1  skrll     {
   3340  1.1  skrll #ifdef OBJ_EVAX
   3341  1.1  skrll       subseg_set (new_seg, 0);
   3342  1.1  skrll       p = frag_more (temp);
   3343  1.1  skrll       new_seg->flags |= SEC_IS_COMMON;
   3344  1.1  skrll       S_SET_SEGMENT (symbolP, new_seg);
   3345  1.1  skrll #else
   3346  1.1  skrll       S_SET_VALUE (symbolP, (valueT) temp);
   3347  1.1  skrll       S_SET_SEGMENT (symbolP, bfd_com_section_ptr);
   3348  1.1  skrll #endif
   3349  1.1  skrll       S_SET_EXTERNAL (symbolP);
   3350  1.1  skrll     }
   3351  1.1  skrll 
   3352  1.1  skrll #ifdef OBJ_EVAX
   3353  1.1  skrll   subseg_set (current_section, current_subsec);
   3354  1.1  skrll #endif
   3355  1.1  skrll 
   3356  1.1  skrll   know (symbol_get_frag (symbolP) == &zero_address_frag);
   3357  1.1  skrll 
   3358  1.1  skrll   demand_empty_rest_of_line ();
   3359  1.1  skrll }
   3360  1.1  skrll 
   3361  1.1  skrll #endif /* ! OBJ_ELF */
   3362  1.1  skrll 
   3363  1.1  skrll #ifdef OBJ_ECOFF
   3364  1.1  skrll 
   3365  1.1  skrll /* Handle the .rdata pseudo-op.  This is like the usual one, but it
   3366  1.1  skrll    clears alpha_insn_label and restores auto alignment.  */
   3367  1.1  skrll 
   3368  1.1  skrll static void
   3369  1.1  skrll s_alpha_rdata (int ignore ATTRIBUTE_UNUSED)
   3370  1.1  skrll {
   3371  1.1  skrll   int temp;
   3372  1.1  skrll 
   3373  1.1  skrll   temp = get_absolute_expression ();
   3374  1.1  skrll   subseg_new (".rdata", 0);
   3375  1.1  skrll   demand_empty_rest_of_line ();
   3376  1.1  skrll   alpha_insn_label = NULL;
   3377  1.1  skrll   alpha_auto_align_on = 1;
   3378  1.1  skrll   alpha_current_align = 0;
   3379  1.1  skrll }
   3380  1.1  skrll 
   3381  1.1  skrll #endif
   3382  1.1  skrll 
   3383  1.1  skrll #ifdef OBJ_ECOFF
   3384  1.1  skrll 
   3385  1.1  skrll /* Handle the .sdata pseudo-op.  This is like the usual one, but it
   3386  1.1  skrll    clears alpha_insn_label and restores auto alignment.  */
   3387  1.1  skrll 
   3388  1.1  skrll static void
   3389  1.1  skrll s_alpha_sdata (int ignore ATTRIBUTE_UNUSED)
   3390  1.1  skrll {
   3391  1.1  skrll   int temp;
   3392  1.1  skrll 
   3393  1.1  skrll   temp = get_absolute_expression ();
   3394  1.1  skrll   subseg_new (".sdata", 0);
   3395  1.1  skrll   demand_empty_rest_of_line ();
   3396  1.1  skrll   alpha_insn_label = NULL;
   3397  1.1  skrll   alpha_auto_align_on = 1;
   3398  1.1  skrll   alpha_current_align = 0;
   3399  1.1  skrll }
   3400  1.1  skrll #endif
   3401  1.1  skrll 
   3402  1.1  skrll #ifdef OBJ_ELF
   3403  1.1  skrll struct alpha_elf_frame_data
   3404  1.1  skrll {
   3405  1.1  skrll   symbolS *func_sym;
   3406  1.1  skrll   symbolS *func_end_sym;
   3407  1.1  skrll   symbolS *prologue_sym;
   3408  1.1  skrll   unsigned int mask;
   3409  1.1  skrll   unsigned int fmask;
   3410  1.1  skrll   int fp_regno;
   3411  1.1  skrll   int ra_regno;
   3412  1.1  skrll   offsetT frame_size;
   3413  1.1  skrll   offsetT mask_offset;
   3414  1.1  skrll   offsetT fmask_offset;
   3415  1.1  skrll 
   3416  1.1  skrll   struct alpha_elf_frame_data *next;
   3417  1.1  skrll };
   3418  1.1  skrll 
   3419  1.1  skrll static struct alpha_elf_frame_data *all_frame_data;
   3420  1.1  skrll static struct alpha_elf_frame_data **plast_frame_data = &all_frame_data;
   3421  1.1  skrll static struct alpha_elf_frame_data *cur_frame_data;
   3422  1.1  skrll 
   3423  1.1  skrll /* Handle the .section pseudo-op.  This is like the usual one, but it
   3424  1.1  skrll    clears alpha_insn_label and restores auto alignment.  */
   3425  1.1  skrll 
   3426  1.1  skrll static void
   3427  1.1  skrll s_alpha_section (int ignore ATTRIBUTE_UNUSED)
   3428  1.1  skrll {
   3429  1.1  skrll   obj_elf_section (ignore);
   3430  1.1  skrll 
   3431  1.1  skrll   alpha_insn_label = NULL;
   3432  1.1  skrll   alpha_auto_align_on = 1;
   3433  1.1  skrll   alpha_current_align = 0;
   3434  1.1  skrll }
   3435  1.1  skrll 
   3436  1.1  skrll static void
   3437  1.1  skrll s_alpha_ent (int dummy ATTRIBUTE_UNUSED)
   3438  1.1  skrll {
   3439  1.1  skrll   if (ECOFF_DEBUGGING)
   3440  1.1  skrll     ecoff_directive_ent (0);
   3441  1.1  skrll   else
   3442  1.1  skrll     {
   3443  1.1  skrll       char *name, name_end;
   3444  1.1  skrll       name = input_line_pointer;
   3445  1.1  skrll       name_end = get_symbol_end ();
   3446  1.1  skrll 
   3447  1.1  skrll       if (! is_name_beginner (*name))
   3448  1.1  skrll 	{
   3449  1.1  skrll 	  as_warn (_(".ent directive has no name"));
   3450  1.1  skrll 	  *input_line_pointer = name_end;
   3451  1.1  skrll 	}
   3452  1.1  skrll       else
   3453  1.1  skrll 	{
   3454  1.1  skrll 	  symbolS *sym;
   3455  1.1  skrll 
   3456  1.1  skrll 	  if (cur_frame_data)
   3457  1.1  skrll 	    as_warn (_("nested .ent directives"));
   3458  1.1  skrll 
   3459  1.1  skrll 	  sym = symbol_find_or_make (name);
   3460  1.1  skrll 	  symbol_get_bfdsym (sym)->flags |= BSF_FUNCTION;
   3461  1.1  skrll 
   3462  1.1  skrll 	  cur_frame_data = calloc (1, sizeof (*cur_frame_data));
   3463  1.1  skrll 	  cur_frame_data->func_sym = sym;
   3464  1.1  skrll 
   3465  1.1  skrll 	  /* Provide sensible defaults.  */
   3466  1.1  skrll 	  cur_frame_data->fp_regno = 30;	/* sp */
   3467  1.1  skrll 	  cur_frame_data->ra_regno = 26;	/* ra */
   3468  1.1  skrll 
   3469  1.1  skrll 	  *plast_frame_data = cur_frame_data;
   3470  1.1  skrll 	  plast_frame_data = &cur_frame_data->next;
   3471  1.1  skrll 
   3472  1.1  skrll 	  /* The .ent directive is sometimes followed by a number.  Not sure
   3473  1.1  skrll 	     what it really means, but ignore it.  */
   3474  1.1  skrll 	  *input_line_pointer = name_end;
   3475  1.1  skrll 	  SKIP_WHITESPACE ();
   3476  1.1  skrll 	  if (*input_line_pointer == ',')
   3477  1.1  skrll 	    {
   3478  1.1  skrll 	      input_line_pointer++;
   3479  1.1  skrll 	      SKIP_WHITESPACE ();
   3480  1.1  skrll 	    }
   3481  1.1  skrll 	  if (ISDIGIT (*input_line_pointer) || *input_line_pointer == '-')
   3482  1.1  skrll 	    (void) get_absolute_expression ();
   3483  1.1  skrll 	}
   3484  1.1  skrll       demand_empty_rest_of_line ();
   3485  1.1  skrll     }
   3486  1.1  skrll }
   3487  1.1  skrll 
   3488  1.1  skrll static void
   3489  1.1  skrll s_alpha_end (int dummy ATTRIBUTE_UNUSED)
   3490  1.1  skrll {
   3491  1.1  skrll   if (ECOFF_DEBUGGING)
   3492  1.1  skrll     ecoff_directive_end (0);
   3493  1.1  skrll   else
   3494  1.1  skrll     {
   3495  1.1  skrll       char *name, name_end;
   3496  1.1  skrll       name = input_line_pointer;
   3497  1.1  skrll       name_end = get_symbol_end ();
   3498  1.1  skrll 
   3499  1.1  skrll       if (! is_name_beginner (*name))
   3500  1.1  skrll 	{
   3501  1.1  skrll 	  as_warn (_(".end directive has no name"));
   3502  1.1  skrll 	  *input_line_pointer = name_end;
   3503  1.1  skrll 	}
   3504  1.1  skrll       else
   3505  1.1  skrll 	{
   3506  1.1  skrll 	  symbolS *sym;
   3507  1.1  skrll 
   3508  1.1  skrll 	  sym = symbol_find (name);
   3509  1.1  skrll 	  if (!cur_frame_data)
   3510  1.1  skrll 	    as_warn (_(".end directive without matching .ent"));
   3511  1.1  skrll 	  else if (sym != cur_frame_data->func_sym)
   3512  1.1  skrll 	    as_warn (_(".end directive names different symbol than .ent"));
   3513  1.1  skrll 
   3514  1.1  skrll 	  /* Create an expression to calculate the size of the function.  */
   3515  1.1  skrll 	  if (sym && cur_frame_data)
   3516  1.1  skrll 	    {
   3517  1.1  skrll 	      OBJ_SYMFIELD_TYPE *obj = symbol_get_obj (sym);
   3518  1.1  skrll 	      expressionS *exp = xmalloc (sizeof (expressionS));
   3519  1.1  skrll 
   3520  1.1  skrll 	      obj->size = exp;
   3521  1.1  skrll 	      exp->X_op = O_subtract;
   3522  1.1  skrll 	      exp->X_add_symbol = symbol_temp_new_now ();
   3523  1.1  skrll 	      exp->X_op_symbol = sym;
   3524  1.1  skrll 	      exp->X_add_number = 0;
   3525  1.1  skrll 
   3526  1.1  skrll 	      cur_frame_data->func_end_sym = exp->X_add_symbol;
   3527  1.1  skrll 	    }
   3528  1.1  skrll 
   3529  1.1  skrll 	  cur_frame_data = NULL;
   3530  1.1  skrll 
   3531  1.1  skrll 	  *input_line_pointer = name_end;
   3532  1.1  skrll 	}
   3533  1.1  skrll       demand_empty_rest_of_line ();
   3534  1.1  skrll     }
   3535  1.1  skrll }
   3536  1.1  skrll 
   3537  1.1  skrll static void
   3538  1.1  skrll s_alpha_mask (int fp)
   3539  1.1  skrll {
   3540  1.1  skrll   if (ECOFF_DEBUGGING)
   3541  1.1  skrll     {
   3542  1.1  skrll       if (fp)
   3543  1.1  skrll 	ecoff_directive_fmask (0);
   3544  1.1  skrll       else
   3545  1.1  skrll 	ecoff_directive_mask (0);
   3546  1.1  skrll     }
   3547  1.1  skrll   else
   3548  1.1  skrll     {
   3549  1.1  skrll       long val;
   3550  1.1  skrll       offsetT offset;
   3551  1.1  skrll 
   3552  1.1  skrll       if (!cur_frame_data)
   3553  1.1  skrll 	{
   3554  1.1  skrll 	  if (fp)
   3555  1.1  skrll 	    as_warn (_(".fmask outside of .ent"));
   3556  1.1  skrll 	  else
   3557  1.1  skrll 	    as_warn (_(".mask outside of .ent"));
   3558  1.1  skrll 	  discard_rest_of_line ();
   3559  1.1  skrll 	  return;
   3560  1.1  skrll 	}
   3561  1.1  skrll 
   3562  1.1  skrll       if (get_absolute_expression_and_terminator (&val) != ',')
   3563  1.1  skrll 	{
   3564  1.1  skrll 	  if (fp)
   3565  1.1  skrll 	    as_warn (_("bad .fmask directive"));
   3566  1.1  skrll 	  else
   3567  1.1  skrll 	    as_warn (_("bad .mask directive"));
   3568  1.1  skrll 	  --input_line_pointer;
   3569  1.1  skrll 	  discard_rest_of_line ();
   3570  1.1  skrll 	  return;
   3571  1.1  skrll 	}
   3572  1.1  skrll 
   3573  1.1  skrll       offset = get_absolute_expression ();
   3574  1.1  skrll       demand_empty_rest_of_line ();
   3575  1.1  skrll 
   3576  1.1  skrll       if (fp)
   3577  1.1  skrll 	{
   3578  1.1  skrll 	  cur_frame_data->fmask = val;
   3579  1.1  skrll           cur_frame_data->fmask_offset = offset;
   3580  1.1  skrll 	}
   3581  1.1  skrll       else
   3582  1.1  skrll 	{
   3583  1.1  skrll 	  cur_frame_data->mask = val;
   3584  1.1  skrll 	  cur_frame_data->mask_offset = offset;
   3585  1.1  skrll 	}
   3586  1.1  skrll     }
   3587  1.1  skrll }
   3588  1.1  skrll 
   3589  1.1  skrll static void
   3590  1.1  skrll s_alpha_frame (int dummy ATTRIBUTE_UNUSED)
   3591  1.1  skrll {
   3592  1.1  skrll   if (ECOFF_DEBUGGING)
   3593  1.1  skrll     ecoff_directive_frame (0);
   3594  1.1  skrll   else
   3595  1.1  skrll     {
   3596  1.1  skrll       long val;
   3597  1.1  skrll 
   3598  1.1  skrll       if (!cur_frame_data)
   3599  1.1  skrll 	{
   3600  1.1  skrll 	  as_warn (_(".frame outside of .ent"));
   3601  1.1  skrll 	  discard_rest_of_line ();
   3602  1.1  skrll 	  return;
   3603  1.1  skrll 	}
   3604  1.1  skrll 
   3605  1.1  skrll       cur_frame_data->fp_regno = tc_get_register (1);
   3606  1.1  skrll 
   3607  1.1  skrll       SKIP_WHITESPACE ();
   3608  1.1  skrll       if (*input_line_pointer++ != ','
   3609  1.1  skrll 	  || get_absolute_expression_and_terminator (&val) != ',')
   3610  1.1  skrll 	{
   3611  1.1  skrll 	  as_warn (_("bad .frame directive"));
   3612  1.1  skrll 	  --input_line_pointer;
   3613  1.1  skrll 	  discard_rest_of_line ();
   3614  1.1  skrll 	  return;
   3615  1.1  skrll 	}
   3616  1.1  skrll       cur_frame_data->frame_size = val;
   3617  1.1  skrll 
   3618  1.1  skrll       cur_frame_data->ra_regno = tc_get_register (0);
   3619  1.1  skrll 
   3620  1.1  skrll       /* Next comes the "offset of saved $a0 from $sp".  In gcc terms
   3621  1.1  skrll 	 this is current_function_pretend_args_size.  There's no place
   3622  1.1  skrll 	 to put this value, so ignore it.  */
   3623  1.1  skrll       s_ignore (42);
   3624  1.1  skrll     }
   3625  1.1  skrll }
   3626  1.1  skrll 
   3627  1.1  skrll static void
   3628  1.1  skrll s_alpha_prologue (int ignore ATTRIBUTE_UNUSED)
   3629  1.1  skrll {
   3630  1.1  skrll   symbolS *sym;
   3631  1.1  skrll   int arg;
   3632  1.1  skrll 
   3633  1.1  skrll   arg = get_absolute_expression ();
   3634  1.1  skrll   demand_empty_rest_of_line ();
   3635  1.1  skrll 
   3636  1.1  skrll   if (ECOFF_DEBUGGING)
   3637  1.1  skrll     sym = ecoff_get_cur_proc_sym ();
   3638  1.1  skrll   else
   3639  1.1  skrll     sym = cur_frame_data ? cur_frame_data->func_sym : NULL;
   3640  1.1  skrll 
   3641  1.1  skrll   if (sym == NULL)
   3642  1.1  skrll     {
   3643  1.1  skrll       as_bad (_(".prologue directive without a preceding .ent directive"));
   3644  1.1  skrll       return;
   3645  1.1  skrll     }
   3646  1.1  skrll 
   3647  1.1  skrll   switch (arg)
   3648  1.1  skrll     {
   3649  1.1  skrll     case 0: /* No PV required.  */
   3650  1.1  skrll       S_SET_OTHER (sym, STO_ALPHA_NOPV
   3651  1.1  skrll 		   | (S_GET_OTHER (sym) & ~STO_ALPHA_STD_GPLOAD));
   3652  1.1  skrll       break;
   3653  1.1  skrll     case 1: /* Std GP load.  */
   3654  1.1  skrll       S_SET_OTHER (sym, STO_ALPHA_STD_GPLOAD
   3655  1.1  skrll 		   | (S_GET_OTHER (sym) & ~STO_ALPHA_STD_GPLOAD));
   3656  1.1  skrll       break;
   3657  1.1  skrll     case 2: /* Non-std use of PV.  */
   3658  1.1  skrll       break;
   3659  1.1  skrll 
   3660  1.1  skrll     default:
   3661  1.1  skrll       as_bad (_("Invalid argument %d to .prologue."), arg);
   3662  1.1  skrll       break;
   3663  1.1  skrll     }
   3664  1.1  skrll 
   3665  1.1  skrll   if (cur_frame_data)
   3666  1.1  skrll     cur_frame_data->prologue_sym = symbol_temp_new_now ();
   3667  1.1  skrll }
   3668  1.1  skrll 
   3669  1.1  skrll static char *first_file_directive;
   3670  1.1  skrll 
   3671  1.1  skrll static void
   3672  1.1  skrll s_alpha_file (int ignore ATTRIBUTE_UNUSED)
   3673  1.1  skrll {
   3674  1.1  skrll   /* Save the first .file directive we see, so that we can change our
   3675  1.1  skrll      minds about whether ecoff debugging should or shouldn't be enabled.  */
   3676  1.1  skrll   if (alpha_flag_mdebug < 0 && ! first_file_directive)
   3677  1.1  skrll     {
   3678  1.1  skrll       char *start = input_line_pointer;
   3679  1.1  skrll       size_t len;
   3680  1.1  skrll 
   3681  1.1  skrll       discard_rest_of_line ();
   3682  1.1  skrll 
   3683  1.1  skrll       len = input_line_pointer - start;
   3684  1.1  skrll       first_file_directive = xmalloc (len + 1);
   3685  1.1  skrll       memcpy (first_file_directive, start, len);
   3686  1.1  skrll       first_file_directive[len] = '\0';
   3687  1.1  skrll 
   3688  1.1  skrll       input_line_pointer = start;
   3689  1.1  skrll     }
   3690  1.1  skrll 
   3691  1.1  skrll   if (ECOFF_DEBUGGING)
   3692  1.1  skrll     ecoff_directive_file (0);
   3693  1.1  skrll   else
   3694  1.1  skrll     dwarf2_directive_file (0);
   3695  1.1  skrll }
   3696  1.1  skrll 
   3697  1.1  skrll static void
   3698  1.1  skrll s_alpha_loc (int ignore ATTRIBUTE_UNUSED)
   3699  1.1  skrll {
   3700  1.1  skrll   if (ECOFF_DEBUGGING)
   3701  1.1  skrll     ecoff_directive_loc (0);
   3702  1.1  skrll   else
   3703  1.1  skrll     dwarf2_directive_loc (0);
   3704  1.1  skrll }
   3705  1.1  skrll 
   3706  1.1  skrll static void
   3707  1.1  skrll s_alpha_stab (int n)
   3708  1.1  skrll {
   3709  1.1  skrll   /* If we've been undecided about mdebug, make up our minds in favour.  */
   3710  1.1  skrll   if (alpha_flag_mdebug < 0)
   3711  1.1  skrll     {
   3712  1.1  skrll       segT sec = subseg_new (".mdebug", 0);
   3713  1.1  skrll       bfd_set_section_flags (stdoutput, sec, SEC_HAS_CONTENTS | SEC_READONLY);
   3714  1.1  skrll       bfd_set_section_alignment (stdoutput, sec, 3);
   3715  1.1  skrll 
   3716  1.1  skrll       ecoff_read_begin_hook ();
   3717  1.1  skrll 
   3718  1.1  skrll       if (first_file_directive)
   3719  1.1  skrll 	{
   3720  1.1  skrll 	  char *save_ilp = input_line_pointer;
   3721  1.1  skrll 	  input_line_pointer = first_file_directive;
   3722  1.1  skrll 	  ecoff_directive_file (0);
   3723  1.1  skrll 	  input_line_pointer = save_ilp;
   3724  1.1  skrll 	  free (first_file_directive);
   3725  1.1  skrll 	}
   3726  1.1  skrll 
   3727  1.1  skrll       alpha_flag_mdebug = 1;
   3728  1.1  skrll     }
   3729  1.1  skrll   s_stab (n);
   3730  1.1  skrll }
   3731  1.1  skrll 
   3732  1.1  skrll static void
   3733  1.1  skrll s_alpha_coff_wrapper (int which)
   3734  1.1  skrll {
   3735  1.1  skrll   static void (* const fns[]) (int) = {
   3736  1.1  skrll     ecoff_directive_begin,
   3737  1.1  skrll     ecoff_directive_bend,
   3738  1.1  skrll     ecoff_directive_def,
   3739  1.1  skrll     ecoff_directive_dim,
   3740  1.1  skrll     ecoff_directive_endef,
   3741  1.1  skrll     ecoff_directive_scl,
   3742  1.1  skrll     ecoff_directive_tag,
   3743  1.1  skrll     ecoff_directive_val,
   3744  1.1  skrll   };
   3745  1.1  skrll 
   3746  1.1  skrll   assert (which >= 0 && which < (int) (sizeof (fns)/sizeof (*fns)));
   3747  1.1  skrll 
   3748  1.1  skrll   if (ECOFF_DEBUGGING)
   3749  1.1  skrll     (*fns[which]) (0);
   3750  1.1  skrll   else
   3751  1.1  skrll     {
   3752  1.1  skrll       as_bad (_("ECOFF debugging is disabled."));
   3753  1.1  skrll       ignore_rest_of_line ();
   3754  1.1  skrll     }
   3755  1.1  skrll }
   3756  1.1  skrll 
   3757  1.1  skrll /* Called at the end of assembly.  Here we emit unwind info for frames
   3758  1.1  skrll    unless the compiler has done it for us.  */
   3759  1.1  skrll 
   3760  1.1  skrll void
   3761  1.1  skrll alpha_elf_md_end (void)
   3762  1.1  skrll {
   3763  1.1  skrll   struct alpha_elf_frame_data *p;
   3764  1.1  skrll 
   3765  1.1  skrll   if (cur_frame_data)
   3766  1.1  skrll     as_warn (_(".ent directive without matching .end"));
   3767  1.1  skrll 
   3768  1.1  skrll   /* If someone has generated the unwind info themselves, great.  */
   3769  1.1  skrll   if (bfd_get_section_by_name (stdoutput, ".eh_frame") != NULL)
   3770  1.1  skrll     return;
   3771  1.1  skrll 
   3772  1.1  skrll   /* Generate .eh_frame data for the unwind directives specified.  */
   3773  1.1  skrll   for (p = all_frame_data; p ; p = p->next)
   3774  1.1  skrll     if (p->prologue_sym)
   3775  1.1  skrll       {
   3776  1.1  skrll 	/* Create a temporary symbol at the same location as our
   3777  1.1  skrll 	   function symbol.  This prevents problems with globals.  */
   3778  1.1  skrll 	cfi_new_fde (symbol_temp_new (S_GET_SEGMENT (p->func_sym),
   3779  1.1  skrll 				      S_GET_VALUE (p->func_sym),
   3780  1.1  skrll 				      symbol_get_frag (p->func_sym)));
   3781  1.1  skrll 
   3782  1.1  skrll 	cfi_set_return_column (p->ra_regno);
   3783  1.1  skrll 	cfi_add_CFA_def_cfa_register (30);
   3784  1.1  skrll 	if (p->fp_regno != 30 || p->mask || p->fmask || p->frame_size)
   3785  1.1  skrll 	  {
   3786  1.1  skrll 	    unsigned int mask;
   3787  1.1  skrll 	    offsetT offset;
   3788  1.1  skrll 
   3789  1.1  skrll 	    cfi_add_advance_loc (p->prologue_sym);
   3790  1.1  skrll 
   3791  1.1  skrll 	    if (p->fp_regno != 30)
   3792  1.1  skrll 	      if (p->frame_size != 0)
   3793  1.1  skrll 		cfi_add_CFA_def_cfa (p->fp_regno, p->frame_size);
   3794  1.1  skrll 	      else
   3795  1.1  skrll 		cfi_add_CFA_def_cfa_register (p->fp_regno);
   3796  1.1  skrll 	    else if (p->frame_size != 0)
   3797  1.1  skrll 	      cfi_add_CFA_def_cfa_offset (p->frame_size);
   3798  1.1  skrll 
   3799  1.1  skrll 	    mask = p->mask;
   3800  1.1  skrll 	    offset = p->mask_offset;
   3801  1.1  skrll 
   3802  1.1  skrll 	    /* Recall that $26 is special-cased and stored first.  */
   3803  1.1  skrll 	    if ((mask >> 26) & 1)
   3804  1.1  skrll 	      {
   3805  1.1  skrll 	        cfi_add_CFA_offset (26, offset);
   3806  1.1  skrll 		offset += 8;
   3807  1.1  skrll 		mask &= ~(1 << 26);
   3808  1.1  skrll 	      }
   3809  1.1  skrll 	    while (mask)
   3810  1.1  skrll 	      {
   3811  1.1  skrll 		unsigned int i;
   3812  1.1  skrll 		i = mask & -mask;
   3813  1.1  skrll 		mask ^= i;
   3814  1.1  skrll 		i = ffs (i) - 1;
   3815  1.1  skrll 
   3816  1.1  skrll 		cfi_add_CFA_offset (i, offset);
   3817  1.1  skrll 		offset += 8;
   3818  1.1  skrll 	      }
   3819  1.1  skrll 
   3820  1.1  skrll 	    mask = p->fmask;
   3821  1.1  skrll 	    offset = p->fmask_offset;
   3822  1.1  skrll 	    while (mask)
   3823  1.1  skrll 	      {
   3824  1.1  skrll 		unsigned int i;
   3825  1.1  skrll 		i = mask & -mask;
   3826  1.1  skrll 		mask ^= i;
   3827  1.1  skrll 		i = ffs (i) - 1;
   3828  1.1  skrll 
   3829  1.1  skrll 		cfi_add_CFA_offset (i + 32, offset);
   3830  1.1  skrll 		offset += 8;
   3831  1.1  skrll 	      }
   3832  1.1  skrll 	  }
   3833  1.1  skrll 
   3834  1.1  skrll 	cfi_end_fde (p->func_end_sym);
   3835  1.1  skrll       }
   3836  1.1  skrll }
   3837  1.1  skrll 
   3838  1.1  skrll static void
   3839  1.1  skrll s_alpha_usepv (int unused ATTRIBUTE_UNUSED)
   3840  1.1  skrll {
   3841  1.1  skrll   char *name, name_end;
   3842  1.1  skrll   char *which, which_end;
   3843  1.1  skrll   symbolS *sym;
   3844  1.1  skrll   int other;
   3845  1.1  skrll 
   3846  1.1  skrll   name = input_line_pointer;
   3847  1.1  skrll   name_end = get_symbol_end ();
   3848  1.1  skrll 
   3849  1.1  skrll   if (! is_name_beginner (*name))
   3850  1.1  skrll     {
   3851  1.1  skrll       as_bad (_(".usepv directive has no name"));
   3852  1.1  skrll       *input_line_pointer = name_end;
   3853  1.1  skrll       ignore_rest_of_line ();
   3854  1.1  skrll       return;
   3855  1.1  skrll     }
   3856  1.1  skrll 
   3857  1.1  skrll   sym = symbol_find_or_make (name);
   3858  1.1  skrll   *input_line_pointer++ = name_end;
   3859  1.1  skrll 
   3860  1.1  skrll   if (name_end != ',')
   3861  1.1  skrll     {
   3862  1.1  skrll       as_bad (_(".usepv directive has no type"));
   3863  1.1  skrll       ignore_rest_of_line ();
   3864  1.1  skrll       return;
   3865  1.1  skrll     }
   3866  1.1  skrll 
   3867  1.1  skrll   SKIP_WHITESPACE ();
   3868  1.1  skrll   which = input_line_pointer;
   3869  1.1  skrll   which_end = get_symbol_end ();
   3870  1.1  skrll 
   3871  1.1  skrll   if (strcmp (which, "no") == 0)
   3872  1.1  skrll     other = STO_ALPHA_NOPV;
   3873  1.1  skrll   else if (strcmp (which, "std") == 0)
   3874  1.1  skrll     other = STO_ALPHA_STD_GPLOAD;
   3875  1.1  skrll   else
   3876  1.1  skrll     {
   3877  1.1  skrll       as_bad (_("unknown argument for .usepv"));
   3878  1.1  skrll       other = 0;
   3879  1.1  skrll     }
   3880  1.1  skrll 
   3881  1.1  skrll   *input_line_pointer = which_end;
   3882  1.1  skrll   demand_empty_rest_of_line ();
   3883  1.1  skrll 
   3884  1.1  skrll   S_SET_OTHER (sym, other | (S_GET_OTHER (sym) & ~STO_ALPHA_STD_GPLOAD));
   3885  1.1  skrll }
   3886  1.1  skrll #endif /* OBJ_ELF */
   3887  1.1  skrll 
   3888  1.1  skrll /* Standard calling conventions leaves the CFA at $30 on entry.  */
   3889  1.1  skrll 
   3890  1.1  skrll void
   3891  1.1  skrll alpha_cfi_frame_initial_instructions (void)
   3892  1.1  skrll {
   3893  1.1  skrll   cfi_add_CFA_def_cfa_register (30);
   3894  1.1  skrll }
   3895  1.1  skrll 
   3896  1.1  skrll #ifdef OBJ_EVAX
   3897  1.1  skrll 
   3898  1.1  skrll /* Handle the section specific pseudo-op.  */
   3899  1.1  skrll 
   3900  1.1  skrll static void
   3901  1.1  skrll s_alpha_section (int secid)
   3902  1.1  skrll {
   3903  1.1  skrll   int temp;
   3904  1.1  skrll #define EVAX_SECTION_COUNT 5
   3905  1.1  skrll   static char *section_name[EVAX_SECTION_COUNT + 1] =
   3906  1.1  skrll     { "NULL", ".rdata", ".comm", ".link", ".ctors", ".dtors" };
   3907  1.1  skrll 
   3908  1.1  skrll   if ((secid <= 0) || (secid > EVAX_SECTION_COUNT))
   3909  1.1  skrll     {
   3910  1.1  skrll       as_fatal (_("Unknown section directive"));
   3911  1.1  skrll       demand_empty_rest_of_line ();
   3912  1.1  skrll       return;
   3913  1.1  skrll     }
   3914  1.1  skrll   temp = get_absolute_expression ();
   3915  1.1  skrll   subseg_new (section_name[secid], 0);
   3916  1.1  skrll   demand_empty_rest_of_line ();
   3917  1.1  skrll   alpha_insn_label = NULL;
   3918  1.1  skrll   alpha_auto_align_on = 1;
   3919  1.1  skrll   alpha_current_align = 0;
   3920  1.1  skrll }
   3921  1.1  skrll 
   3922  1.1  skrll /* Parse .ent directives.  */
   3923  1.1  skrll 
   3924  1.1  skrll static void
   3925  1.1  skrll s_alpha_ent (int ignore ATTRIBUTE_UNUSED)
   3926  1.1  skrll {
   3927  1.1  skrll   symbolS *symbol;
   3928  1.1  skrll   expressionS symexpr;
   3929  1.1  skrll 
   3930  1.1  skrll   alpha_evax_proc.pdsckind = 0;
   3931  1.1  skrll   alpha_evax_proc.framereg = -1;
   3932  1.1  skrll   alpha_evax_proc.framesize = 0;
   3933  1.1  skrll   alpha_evax_proc.rsa_offset = 0;
   3934  1.1  skrll   alpha_evax_proc.ra_save = AXP_REG_RA;
   3935  1.1  skrll   alpha_evax_proc.fp_save = -1;
   3936  1.1  skrll   alpha_evax_proc.imask = 0;
   3937  1.1  skrll   alpha_evax_proc.fmask = 0;
   3938  1.1  skrll   alpha_evax_proc.prologue = 0;
   3939  1.1  skrll   alpha_evax_proc.type = 0;
   3940  1.1  skrll 
   3941  1.1  skrll   expression (&symexpr);
   3942  1.1  skrll 
   3943  1.1  skrll   if (symexpr.X_op != O_symbol)
   3944  1.1  skrll     {
   3945  1.1  skrll       as_fatal (_(".ent directive has no symbol"));
   3946  1.1  skrll       demand_empty_rest_of_line ();
   3947  1.1  skrll       return;
   3948  1.1  skrll     }
   3949  1.1  skrll 
   3950  1.1  skrll   symbol = make_expr_symbol (&symexpr);
   3951  1.1  skrll   symbol_get_bfdsym (symbol)->flags |= BSF_FUNCTION;
   3952  1.1  skrll   alpha_evax_proc.symbol = symbol;
   3953  1.1  skrll 
   3954  1.1  skrll   demand_empty_rest_of_line ();
   3955  1.1  skrll }
   3956  1.1  skrll 
   3957  1.1  skrll /* Parse .frame <framreg>,<framesize>,RA,<rsa_offset> directives.  */
   3958  1.1  skrll 
   3959  1.1  skrll static void
   3960  1.1  skrll s_alpha_frame (int ignore ATTRIBUTE_UNUSED)
   3961  1.1  skrll {
   3962  1.1  skrll   long val;
   3963  1.1  skrll 
   3964  1.1  skrll   alpha_evax_proc.framereg = tc_get_register (1);
   3965  1.1  skrll 
   3966  1.1  skrll   SKIP_WHITESPACE ();
   3967  1.1  skrll   if (*input_line_pointer++ != ','
   3968  1.1  skrll       || get_absolute_expression_and_terminator (&val) != ',')
   3969  1.1  skrll     {
   3970  1.1  skrll       as_warn (_("Bad .frame directive 1./2. param"));
   3971  1.1  skrll       --input_line_pointer;
   3972  1.1  skrll       demand_empty_rest_of_line ();
   3973  1.1  skrll       return;
   3974  1.1  skrll     }
   3975  1.1  skrll 
   3976  1.1  skrll   alpha_evax_proc.framesize = val;
   3977  1.1  skrll 
   3978  1.1  skrll   (void) tc_get_register (1);
   3979  1.1  skrll   SKIP_WHITESPACE ();
   3980  1.1  skrll   if (*input_line_pointer++ != ',')
   3981  1.1  skrll     {
   3982  1.1  skrll       as_warn (_("Bad .frame directive 3./4. param"));
   3983  1.1  skrll       --input_line_pointer;
   3984  1.1  skrll       demand_empty_rest_of_line ();
   3985  1.1  skrll       return;
   3986  1.1  skrll     }
   3987  1.1  skrll   alpha_evax_proc.rsa_offset = get_absolute_expression ();
   3988  1.1  skrll }
   3989  1.1  skrll 
   3990  1.1  skrll static void
   3991  1.1  skrll s_alpha_pdesc (int ignore ATTRIBUTE_UNUSED)
   3992  1.1  skrll {
   3993  1.1  skrll   char *name;
   3994  1.1  skrll   char name_end;
   3995  1.1  skrll   long val;
   3996  1.1  skrll   register char *p;
   3997  1.1  skrll   expressionS exp;
   3998  1.1  skrll   symbolS *entry_sym;
   3999  1.1  skrll   fixS *fixp;
   4000  1.1  skrll   segment_info_type *seginfo = seg_info (alpha_link_section);
   4001  1.1  skrll 
   4002  1.1  skrll   if (now_seg != alpha_link_section)
   4003  1.1  skrll     {
   4004  1.1  skrll       as_bad (_(".pdesc directive not in link (.link) section"));
   4005  1.1  skrll       demand_empty_rest_of_line ();
   4006  1.1  skrll       return;
   4007  1.1  skrll     }
   4008  1.1  skrll 
   4009  1.1  skrll   if ((alpha_evax_proc.symbol == 0)
   4010  1.1  skrll       || (!S_IS_DEFINED (alpha_evax_proc.symbol)))
   4011  1.1  skrll     {
   4012  1.1  skrll       as_fatal (_(".pdesc has no matching .ent"));
   4013  1.1  skrll       demand_empty_rest_of_line ();
   4014  1.1  skrll       return;
   4015  1.1  skrll     }
   4016  1.1  skrll 
   4017  1.1  skrll   *symbol_get_obj (alpha_evax_proc.symbol) =
   4018  1.1  skrll     (valueT) seginfo->literal_pool_size;
   4019  1.1  skrll 
   4020  1.1  skrll   expression (&exp);
   4021  1.1  skrll   if (exp.X_op != O_symbol)
   4022  1.1  skrll     {
   4023  1.1  skrll       as_warn (_(".pdesc directive has no entry symbol"));
   4024  1.1  skrll       demand_empty_rest_of_line ();
   4025  1.1  skrll       return;
   4026  1.1  skrll     }
   4027  1.1  skrll 
   4028  1.1  skrll   entry_sym = make_expr_symbol (&exp);
   4029  1.1  skrll   /* Save bfd symbol of proc desc in function symbol.  */
   4030  1.1  skrll   symbol_get_bfdsym (alpha_evax_proc.symbol)->udata.p
   4031  1.1  skrll     = symbol_get_bfdsym (entry_sym);
   4032  1.1  skrll 
   4033  1.1  skrll   SKIP_WHITESPACE ();
   4034  1.1  skrll   if (*input_line_pointer++ != ',')
   4035  1.1  skrll     {
   4036  1.1  skrll       as_warn (_("No comma after .pdesc <entryname>"));
   4037  1.1  skrll       demand_empty_rest_of_line ();
   4038  1.1  skrll       return;
   4039  1.1  skrll     }
   4040  1.1  skrll 
   4041  1.1  skrll   SKIP_WHITESPACE ();
   4042  1.1  skrll   name = input_line_pointer;
   4043  1.1  skrll   name_end = get_symbol_end ();
   4044  1.1  skrll 
   4045  1.1  skrll   if (strncmp (name, "stack", 5) == 0)
   4046  1.1  skrll     alpha_evax_proc.pdsckind = PDSC_S_K_KIND_FP_STACK;
   4047  1.1  skrll 
   4048  1.1  skrll   else if (strncmp (name, "reg", 3) == 0)
   4049  1.1  skrll     alpha_evax_proc.pdsckind = PDSC_S_K_KIND_FP_REGISTER;
   4050  1.1  skrll 
   4051  1.1  skrll   else if (strncmp (name, "null", 4) == 0)
   4052  1.1  skrll     alpha_evax_proc.pdsckind = PDSC_S_K_KIND_NULL;
   4053  1.1  skrll 
   4054  1.1  skrll   else
   4055  1.1  skrll     {
   4056  1.1  skrll       as_fatal (_("unknown procedure kind"));
   4057  1.1  skrll       demand_empty_rest_of_line ();
   4058  1.1  skrll       return;
   4059  1.1  skrll     }
   4060  1.1  skrll 
   4061  1.1  skrll   *input_line_pointer = name_end;
   4062  1.1  skrll   demand_empty_rest_of_line ();
   4063  1.1  skrll 
   4064  1.1  skrll #ifdef md_flush_pending_output
   4065  1.1  skrll   md_flush_pending_output ();
   4066  1.1  skrll #endif
   4067  1.1  skrll 
   4068  1.1  skrll   frag_align (3, 0, 0);
   4069  1.1  skrll   p = frag_more (16);
   4070  1.1  skrll   fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
   4071  1.1  skrll   fixp->fx_done = 1;
   4072  1.1  skrll   seginfo->literal_pool_size += 16;
   4073  1.1  skrll 
   4074  1.1  skrll   *p = alpha_evax_proc.pdsckind
   4075  1.1  skrll     | ((alpha_evax_proc.framereg == 29) ? PDSC_S_M_BASE_REG_IS_FP : 0);
   4076  1.1  skrll   *(p + 1) = PDSC_S_M_NATIVE | PDSC_S_M_NO_JACKET;
   4077  1.1  skrll 
   4078  1.1  skrll   switch (alpha_evax_proc.pdsckind)
   4079  1.1  skrll     {
   4080  1.1  skrll     case PDSC_S_K_KIND_NULL:
   4081  1.1  skrll       *(p + 2) = 0;
   4082  1.1  skrll       *(p + 3) = 0;
   4083  1.1  skrll       break;
   4084  1.1  skrll     case PDSC_S_K_KIND_FP_REGISTER:
   4085  1.1  skrll       *(p + 2) = alpha_evax_proc.fp_save;
   4086  1.1  skrll       *(p + 3) = alpha_evax_proc.ra_save;
   4087  1.1  skrll       break;
   4088  1.1  skrll     case PDSC_S_K_KIND_FP_STACK:
   4089  1.1  skrll       md_number_to_chars (p + 2, (valueT) alpha_evax_proc.rsa_offset, 2);
   4090  1.1  skrll       break;
   4091  1.1  skrll     default:		/* impossible */
   4092  1.1  skrll       break;
   4093  1.1  skrll     }
   4094  1.1  skrll 
   4095  1.1  skrll   *(p + 4) = 0;
   4096  1.1  skrll   *(p + 5) = alpha_evax_proc.type & 0x0f;
   4097  1.1  skrll 
   4098  1.1  skrll   /* Signature offset.  */
   4099  1.1  skrll   md_number_to_chars (p + 6, (valueT) 0, 2);
   4100  1.1  skrll 
   4101  1.1  skrll   fix_new_exp (frag_now, p - frag_now->fr_literal+8, 8, &exp, 0, BFD_RELOC_64);
   4102  1.1  skrll 
   4103  1.1  skrll   if (alpha_evax_proc.pdsckind == PDSC_S_K_KIND_NULL)
   4104  1.1  skrll     return;
   4105  1.1  skrll 
   4106  1.1  skrll   /* Add dummy fix to make add_to_link_pool work.  */
   4107  1.1  skrll   p = frag_more (8);
   4108  1.1  skrll   fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
   4109  1.1  skrll   fixp->fx_done = 1;
   4110  1.1  skrll   seginfo->literal_pool_size += 8;
   4111  1.1  skrll 
   4112  1.1  skrll   /* pdesc+16: Size.  */
   4113  1.1  skrll   md_number_to_chars (p, (valueT) alpha_evax_proc.framesize, 4);
   4114  1.1  skrll 
   4115  1.1  skrll   md_number_to_chars (p + 4, (valueT) 0, 2);
   4116  1.1  skrll 
   4117  1.1  skrll   /* Entry length.  */
   4118  1.1  skrll   md_number_to_chars (p + 6, alpha_evax_proc.prologue, 2);
   4119  1.1  skrll 
   4120  1.1  skrll   if (alpha_evax_proc.pdsckind == PDSC_S_K_KIND_FP_REGISTER)
   4121  1.1  skrll     return;
   4122  1.1  skrll 
   4123  1.1  skrll   /* Add dummy fix to make add_to_link_pool work.  */
   4124  1.1  skrll   p = frag_more (8);
   4125  1.1  skrll   fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
   4126  1.1  skrll   fixp->fx_done = 1;
   4127  1.1  skrll   seginfo->literal_pool_size += 8;
   4128  1.1  skrll 
   4129  1.1  skrll   /* pdesc+24: register masks.  */
   4130  1.1  skrll 
   4131  1.1  skrll   md_number_to_chars (p, alpha_evax_proc.imask, 4);
   4132  1.1  skrll   md_number_to_chars (p + 4, alpha_evax_proc.fmask, 4);
   4133  1.1  skrll }
   4134  1.1  skrll 
   4135  1.1  skrll /* Support for crash debug on vms.  */
   4136  1.1  skrll 
   4137  1.1  skrll static void
   4138  1.1  skrll s_alpha_name (int ignore ATTRIBUTE_UNUSED)
   4139  1.1  skrll {
   4140  1.1  skrll   char *p;
   4141  1.1  skrll   expressionS exp;
   4142  1.1  skrll   segment_info_type *seginfo = seg_info (alpha_link_section);
   4143  1.1  skrll 
   4144  1.1  skrll   if (now_seg != alpha_link_section)
   4145  1.1  skrll     {
   4146  1.1  skrll       as_bad (_(".name directive not in link (.link) section"));
   4147  1.1  skrll       demand_empty_rest_of_line ();
   4148  1.1  skrll       return;
   4149  1.1  skrll     }
   4150  1.1  skrll 
   4151  1.1  skrll   expression (&exp);
   4152  1.1  skrll   if (exp.X_op != O_symbol)
   4153  1.1  skrll     {
   4154  1.1  skrll       as_warn (_(".name directive has no symbol"));
   4155  1.1  skrll       demand_empty_rest_of_line ();
   4156  1.1  skrll       return;
   4157  1.1  skrll     }
   4158  1.1  skrll 
   4159  1.1  skrll   demand_empty_rest_of_line ();
   4160  1.1  skrll 
   4161  1.1  skrll #ifdef md_flush_pending_output
   4162  1.1  skrll   md_flush_pending_output ();
   4163  1.1  skrll #endif
   4164  1.1  skrll 
   4165  1.1  skrll   frag_align (3, 0, 0);
   4166  1.1  skrll   p = frag_more (8);
   4167  1.1  skrll   seginfo->literal_pool_size += 8;
   4168  1.1  skrll 
   4169  1.1  skrll   fix_new_exp (frag_now, p - frag_now->fr_literal, 8, &exp, 0, BFD_RELOC_64);
   4170  1.1  skrll }
   4171  1.1  skrll 
   4172  1.1  skrll static void
   4173  1.1  skrll s_alpha_linkage (int ignore ATTRIBUTE_UNUSED)
   4174  1.1  skrll {
   4175  1.1  skrll   expressionS exp;
   4176  1.1  skrll   char *p;
   4177  1.1  skrll 
   4178  1.1  skrll #ifdef md_flush_pending_output
   4179  1.1  skrll   md_flush_pending_output ();
   4180  1.1  skrll #endif
   4181  1.1  skrll 
   4182  1.1  skrll   expression (&exp);
   4183  1.1  skrll   if (exp.X_op != O_symbol)
   4184  1.1  skrll     {
   4185  1.1  skrll       as_fatal (_("No symbol after .linkage"));
   4186  1.1  skrll     }
   4187  1.1  skrll   else
   4188  1.1  skrll     {
   4189  1.1  skrll       p = frag_more (LKP_S_K_SIZE);
   4190  1.1  skrll       memset (p, 0, LKP_S_K_SIZE);
   4191  1.1  skrll       fix_new_exp (frag_now, p - frag_now->fr_literal, LKP_S_K_SIZE, &exp, 0,\
   4192  1.1  skrll 		   BFD_RELOC_ALPHA_LINKAGE);
   4193  1.1  skrll     }
   4194  1.1  skrll   demand_empty_rest_of_line ();
   4195  1.1  skrll }
   4196  1.1  skrll 
   4197  1.1  skrll static void
   4198  1.1  skrll s_alpha_code_address (int ignore ATTRIBUTE_UNUSED)
   4199  1.1  skrll {
   4200  1.1  skrll   expressionS exp;
   4201  1.1  skrll   char *p;
   4202  1.1  skrll 
   4203  1.1  skrll #ifdef md_flush_pending_output
   4204  1.1  skrll   md_flush_pending_output ();
   4205  1.1  skrll #endif
   4206  1.1  skrll 
   4207  1.1  skrll   expression (&exp);
   4208  1.1  skrll   if (exp.X_op != O_symbol)
   4209  1.1  skrll     as_fatal (_("No symbol after .code_address"));
   4210  1.1  skrll   else
   4211  1.1  skrll     {
   4212  1.1  skrll       p = frag_more (8);
   4213  1.1  skrll       memset (p, 0, 8);
   4214  1.1  skrll       fix_new_exp (frag_now, p - frag_now->fr_literal, 8, &exp, 0,\
   4215  1.1  skrll 		   BFD_RELOC_ALPHA_CODEADDR);
   4216  1.1  skrll     }
   4217  1.1  skrll   demand_empty_rest_of_line ();
   4218  1.1  skrll }
   4219  1.1  skrll 
   4220  1.1  skrll static void
   4221  1.1  skrll s_alpha_fp_save (int ignore ATTRIBUTE_UNUSED)
   4222  1.1  skrll {
   4223  1.1  skrll 
   4224  1.1  skrll   alpha_evax_proc.fp_save = tc_get_register (1);
   4225  1.1  skrll 
   4226  1.1  skrll   demand_empty_rest_of_line ();
   4227  1.1  skrll }
   4228  1.1  skrll 
   4229  1.1  skrll static void
   4230  1.1  skrll s_alpha_mask (int ignore ATTRIBUTE_UNUSED)
   4231  1.1  skrll {
   4232  1.1  skrll   long val;
   4233  1.1  skrll 
   4234  1.1  skrll   if (get_absolute_expression_and_terminator (&val) != ',')
   4235  1.1  skrll     {
   4236  1.1  skrll       as_warn (_("Bad .mask directive"));
   4237  1.1  skrll       --input_line_pointer;
   4238  1.1  skrll     }
   4239  1.1  skrll   else
   4240  1.1  skrll     {
   4241  1.1  skrll       alpha_evax_proc.imask = val;
   4242  1.1  skrll       (void) get_absolute_expression ();
   4243  1.1  skrll     }
   4244  1.1  skrll   demand_empty_rest_of_line ();
   4245  1.1  skrll }
   4246  1.1  skrll 
   4247  1.1  skrll static void
   4248  1.1  skrll s_alpha_fmask (int ignore ATTRIBUTE_UNUSED)
   4249  1.1  skrll {
   4250  1.1  skrll   long val;
   4251  1.1  skrll 
   4252  1.1  skrll   if (get_absolute_expression_and_terminator (&val) != ',')
   4253  1.1  skrll     {
   4254  1.1  skrll       as_warn (_("Bad .fmask directive"));
   4255  1.1  skrll       --input_line_pointer;
   4256  1.1  skrll     }
   4257  1.1  skrll   else
   4258  1.1  skrll     {
   4259  1.1  skrll       alpha_evax_proc.fmask = val;
   4260  1.1  skrll       (void) get_absolute_expression ();
   4261  1.1  skrll     }
   4262  1.1  skrll   demand_empty_rest_of_line ();
   4263  1.1  skrll }
   4264  1.1  skrll 
   4265  1.1  skrll static void
   4266  1.1  skrll s_alpha_end (int ignore ATTRIBUTE_UNUSED)
   4267  1.1  skrll {
   4268  1.1  skrll   char c;
   4269  1.1  skrll 
   4270  1.1  skrll   c = get_symbol_end ();
   4271  1.1  skrll   *input_line_pointer = c;
   4272  1.1  skrll   demand_empty_rest_of_line ();
   4273  1.1  skrll   alpha_evax_proc.symbol = 0;
   4274  1.1  skrll }
   4275  1.1  skrll 
   4276  1.1  skrll static void
   4277  1.1  skrll s_alpha_file (int ignore ATTRIBUTE_UNUSED)
   4278  1.1  skrll {
   4279  1.1  skrll   symbolS *s;
   4280  1.1  skrll   int length;
   4281  1.1  skrll   static char case_hack[32];
   4282  1.1  skrll 
   4283  1.1  skrll   sprintf (case_hack, "<CASE:%01d%01d>",
   4284  1.1  skrll 	   alpha_flag_hash_long_names, alpha_flag_show_after_trunc);
   4285  1.1  skrll 
   4286  1.1  skrll   s = symbol_find_or_make (case_hack);
   4287  1.1  skrll   symbol_get_bfdsym (s)->flags |= BSF_FILE;
   4288  1.1  skrll 
   4289  1.1  skrll   get_absolute_expression ();
   4290  1.1  skrll   s = symbol_find_or_make (demand_copy_string (&length));
   4291  1.1  skrll   symbol_get_bfdsym (s)->flags |= BSF_FILE;
   4292  1.1  skrll   demand_empty_rest_of_line ();
   4293  1.1  skrll }
   4294  1.1  skrll #endif /* OBJ_EVAX  */
   4295  1.1  skrll 
   4296  1.1  skrll /* Handle the .gprel32 pseudo op.  */
   4297  1.1  skrll 
   4298  1.1  skrll static void
   4299  1.1  skrll s_alpha_gprel32 (int ignore ATTRIBUTE_UNUSED)
   4300  1.1  skrll {
   4301  1.1  skrll   expressionS e;
   4302  1.1  skrll   char *p;
   4303  1.1  skrll 
   4304  1.1  skrll   SKIP_WHITESPACE ();
   4305  1.1  skrll   expression (&e);
   4306  1.1  skrll 
   4307  1.1  skrll #ifdef OBJ_ELF
   4308  1.1  skrll   switch (e.X_op)
   4309  1.1  skrll     {
   4310  1.1  skrll     case O_constant:
   4311  1.1  skrll       e.X_add_symbol = section_symbol (absolute_section);
   4312  1.1  skrll       e.X_op = O_symbol;
   4313  1.1  skrll       /* FALLTHRU */
   4314  1.1  skrll     case O_symbol:
   4315  1.1  skrll       break;
   4316  1.1  skrll     default:
   4317  1.1  skrll       abort ();
   4318  1.1  skrll     }
   4319  1.1  skrll #else
   4320  1.1  skrll #ifdef OBJ_ECOFF
   4321  1.1  skrll   switch (e.X_op)
   4322  1.1  skrll     {
   4323  1.1  skrll     case O_constant:
   4324  1.1  skrll       e.X_add_symbol = section_symbol (absolute_section);
   4325  1.1  skrll       /* fall through */
   4326  1.1  skrll     case O_symbol:
   4327  1.1  skrll       e.X_op = O_subtract;
   4328  1.1  skrll       e.X_op_symbol = alpha_gp_symbol;
   4329  1.1  skrll       break;
   4330  1.1  skrll     default:
   4331  1.1  skrll       abort ();
   4332  1.1  skrll     }
   4333  1.1  skrll #endif
   4334  1.1  skrll #endif
   4335  1.1  skrll 
   4336  1.1  skrll   if (alpha_auto_align_on && alpha_current_align < 2)
   4337  1.1  skrll     alpha_align (2, (char *) NULL, alpha_insn_label, 0);
   4338  1.1  skrll   if (alpha_current_align > 2)
   4339  1.1  skrll     alpha_current_align = 2;
   4340  1.1  skrll   alpha_insn_label = NULL;
   4341  1.1  skrll 
   4342  1.1  skrll   p = frag_more (4);
   4343  1.1  skrll   memset (p, 0, 4);
   4344  1.1  skrll   fix_new_exp (frag_now, p - frag_now->fr_literal, 4,
   4345  1.1  skrll 	       &e, 0, BFD_RELOC_GPREL32);
   4346  1.1  skrll }
   4347  1.1  skrll 
   4348  1.1  skrll /* Handle floating point allocation pseudo-ops.  This is like the
   4349  1.1  skrll    generic vresion, but it makes sure the current label, if any, is
   4350  1.1  skrll    correctly aligned.  */
   4351  1.1  skrll 
   4352  1.1  skrll static void
   4353  1.1  skrll s_alpha_float_cons (int type)
   4354  1.1  skrll {
   4355  1.1  skrll   int log_size;
   4356  1.1  skrll 
   4357  1.1  skrll   switch (type)
   4358  1.1  skrll     {
   4359  1.1  skrll     default:
   4360  1.1  skrll     case 'f':
   4361  1.1  skrll     case 'F':
   4362  1.1  skrll       log_size = 2;
   4363  1.1  skrll       break;
   4364  1.1  skrll 
   4365  1.1  skrll     case 'd':
   4366  1.1  skrll     case 'D':
   4367  1.1  skrll     case 'G':
   4368  1.1  skrll       log_size = 3;
   4369  1.1  skrll       break;
   4370  1.1  skrll 
   4371  1.1  skrll     case 'x':
   4372  1.1  skrll     case 'X':
   4373  1.1  skrll     case 'p':
   4374  1.1  skrll     case 'P':
   4375  1.1  skrll       log_size = 4;
   4376  1.1  skrll       break;
   4377  1.1  skrll     }
   4378  1.1  skrll 
   4379  1.1  skrll   if (alpha_auto_align_on && alpha_current_align < log_size)
   4380  1.1  skrll     alpha_align (log_size, (char *) NULL, alpha_insn_label, 0);
   4381  1.1  skrll   if (alpha_current_align > log_size)
   4382  1.1  skrll     alpha_current_align = log_size;
   4383  1.1  skrll   alpha_insn_label = NULL;
   4384  1.1  skrll 
   4385  1.1  skrll   float_cons (type);
   4386  1.1  skrll }
   4387  1.1  skrll 
   4388  1.1  skrll /* Handle the .proc pseudo op.  We don't really do much with it except
   4389  1.1  skrll    parse it.  */
   4390  1.1  skrll 
   4391  1.1  skrll static void
   4392  1.1  skrll s_alpha_proc (int is_static ATTRIBUTE_UNUSED)
   4393  1.1  skrll {
   4394  1.1  skrll   char *name;
   4395  1.1  skrll   char c;
   4396  1.1  skrll   char *p;
   4397  1.1  skrll   symbolS *symbolP;
   4398  1.1  skrll   int temp;
   4399  1.1  skrll 
   4400  1.1  skrll   /* Takes ".proc name,nargs".  */
   4401  1.1  skrll   SKIP_WHITESPACE ();
   4402  1.1  skrll   name = input_line_pointer;
   4403  1.1  skrll   c = get_symbol_end ();
   4404  1.1  skrll   p = input_line_pointer;
   4405  1.1  skrll   symbolP = symbol_find_or_make (name);
   4406  1.1  skrll   *p = c;
   4407  1.1  skrll   SKIP_WHITESPACE ();
   4408  1.1  skrll   if (*input_line_pointer != ',')
   4409  1.1  skrll     {
   4410  1.1  skrll       *p = 0;
   4411  1.1  skrll       as_warn (_("Expected comma after name \"%s\""), name);
   4412  1.1  skrll       *p = c;
   4413  1.1  skrll       temp = 0;
   4414  1.1  skrll       ignore_rest_of_line ();
   4415  1.1  skrll     }
   4416  1.1  skrll   else
   4417  1.1  skrll     {
   4418  1.1  skrll       input_line_pointer++;
   4419  1.1  skrll       temp = get_absolute_expression ();
   4420  1.1  skrll     }
   4421  1.1  skrll   /*  *symbol_get_obj (symbolP) = (signed char) temp; */
   4422  1.1  skrll   as_warn (_("unhandled: .proc %s,%d"), name, temp);
   4423  1.1  skrll   demand_empty_rest_of_line ();
   4424  1.1  skrll }
   4425  1.1  skrll 
   4426  1.1  skrll /* Handle the .set pseudo op.  This is used to turn on and off most of
   4427  1.1  skrll    the assembler features.  */
   4428  1.1  skrll 
   4429  1.1  skrll static void
   4430  1.1  skrll s_alpha_set (int x ATTRIBUTE_UNUSED)
   4431  1.1  skrll {
   4432  1.1  skrll   char *name, ch, *s;
   4433  1.1  skrll   int yesno = 1;
   4434  1.1  skrll 
   4435  1.1  skrll   SKIP_WHITESPACE ();
   4436  1.1  skrll   name = input_line_pointer;
   4437  1.1  skrll   ch = get_symbol_end ();
   4438  1.1  skrll 
   4439  1.1  skrll   s = name;
   4440  1.1  skrll   if (s[0] == 'n' && s[1] == 'o')
   4441  1.1  skrll     {
   4442  1.1  skrll       yesno = 0;
   4443  1.1  skrll       s += 2;
   4444  1.1  skrll     }
   4445  1.1  skrll   if (!strcmp ("reorder", s))
   4446  1.1  skrll     /* ignore */ ;
   4447  1.1  skrll   else if (!strcmp ("at", s))
   4448  1.1  skrll     alpha_noat_on = !yesno;
   4449  1.1  skrll   else if (!strcmp ("macro", s))
   4450  1.1  skrll     alpha_macros_on = yesno;
   4451  1.1  skrll   else if (!strcmp ("move", s))
   4452  1.1  skrll     /* ignore */ ;
   4453  1.1  skrll   else if (!strcmp ("volatile", s))
   4454  1.1  skrll     /* ignore */ ;
   4455  1.1  skrll   else
   4456  1.1  skrll     as_warn (_("Tried to .set unrecognized mode `%s'"), name);
   4457  1.1  skrll 
   4458  1.1  skrll   *input_line_pointer = ch;
   4459  1.1  skrll   demand_empty_rest_of_line ();
   4460  1.1  skrll }
   4461  1.1  skrll 
   4462  1.1  skrll /* Handle the .base pseudo op.  This changes the assembler's notion of
   4463  1.1  skrll    the $gp register.  */
   4464  1.1  skrll 
   4465  1.1  skrll static void
   4466  1.1  skrll s_alpha_base (int ignore ATTRIBUTE_UNUSED)
   4467  1.1  skrll {
   4468  1.1  skrll   SKIP_WHITESPACE ();
   4469  1.1  skrll 
   4470  1.1  skrll   if (*input_line_pointer == '$')
   4471  1.1  skrll     {
   4472  1.1  skrll       /* $rNN form.  */
   4473  1.1  skrll       input_line_pointer++;
   4474  1.1  skrll       if (*input_line_pointer == 'r')
   4475  1.1  skrll 	input_line_pointer++;
   4476  1.1  skrll     }
   4477  1.1  skrll 
   4478  1.1  skrll   alpha_gp_register = get_absolute_expression ();
   4479  1.1  skrll   if (alpha_gp_register < 0 || alpha_gp_register > 31)
   4480  1.1  skrll     {
   4481  1.1  skrll       alpha_gp_register = AXP_REG_GP;
   4482  1.1  skrll       as_warn (_("Bad base register, using $%d."), alpha_gp_register);
   4483  1.1  skrll     }
   4484  1.1  skrll 
   4485  1.1  skrll   demand_empty_rest_of_line ();
   4486  1.1  skrll }
   4487  1.1  skrll 
   4488  1.1  skrll /* Handle the .align pseudo-op.  This aligns to a power of two.  It
   4489  1.1  skrll    also adjusts any current instruction label.  We treat this the same
   4490  1.1  skrll    way the MIPS port does: .align 0 turns off auto alignment.  */
   4491  1.1  skrll 
   4492  1.1  skrll static void
   4493  1.1  skrll s_alpha_align (int ignore ATTRIBUTE_UNUSED)
   4494  1.1  skrll {
   4495  1.1  skrll   int align;
   4496  1.1  skrll   char fill, *pfill;
   4497  1.1  skrll   long max_alignment = 15;
   4498  1.1  skrll 
   4499  1.1  skrll   align = get_absolute_expression ();
   4500  1.1  skrll   if (align > max_alignment)
   4501  1.1  skrll     {
   4502  1.1  skrll       align = max_alignment;
   4503  1.1  skrll       as_bad (_("Alignment too large: %d. assumed"), align);
   4504  1.1  skrll     }
   4505  1.1  skrll   else if (align < 0)
   4506  1.1  skrll     {
   4507  1.1  skrll       as_warn (_("Alignment negative: 0 assumed"));
   4508  1.1  skrll       align = 0;
   4509  1.1  skrll     }
   4510  1.1  skrll 
   4511  1.1  skrll   if (*input_line_pointer == ',')
   4512  1.1  skrll     {
   4513  1.1  skrll       input_line_pointer++;
   4514  1.1  skrll       fill = get_absolute_expression ();
   4515  1.1  skrll       pfill = &fill;
   4516  1.1  skrll     }
   4517  1.1  skrll   else
   4518  1.1  skrll     pfill = NULL;
   4519  1.1  skrll 
   4520  1.1  skrll   if (align != 0)
   4521  1.1  skrll     {
   4522  1.1  skrll       alpha_auto_align_on = 1;
   4523  1.1  skrll       alpha_align (align, pfill, alpha_insn_label, 1);
   4524  1.1  skrll     }
   4525  1.1  skrll   else
   4526  1.1  skrll     {
   4527  1.1  skrll       alpha_auto_align_on = 0;
   4528  1.1  skrll     }
   4529  1.1  skrll 
   4530  1.1  skrll   demand_empty_rest_of_line ();
   4531  1.1  skrll }
   4532  1.1  skrll 
   4533  1.1  skrll /* Hook the normal string processor to reset known alignment.  */
   4534  1.1  skrll 
   4535  1.1  skrll static void
   4536  1.1  skrll s_alpha_stringer (int terminate)
   4537  1.1  skrll {
   4538  1.1  skrll   alpha_current_align = 0;
   4539  1.1  skrll   alpha_insn_label = NULL;
   4540  1.1  skrll   stringer (8 + terminate);
   4541  1.1  skrll }
   4542  1.1  skrll 
   4543  1.1  skrll /* Hook the normal space processing to reset known alignment.  */
   4544  1.1  skrll 
   4545  1.1  skrll static void
   4546  1.1  skrll s_alpha_space (int ignore)
   4547  1.1  skrll {
   4548  1.1  skrll   alpha_current_align = 0;
   4549  1.1  skrll   alpha_insn_label = NULL;
   4550  1.1  skrll   s_space (ignore);
   4551  1.1  skrll }
   4552  1.1  skrll 
   4553  1.1  skrll /* Hook into cons for auto-alignment.  */
   4554  1.1  skrll 
   4555  1.1  skrll void
   4556  1.1  skrll alpha_cons_align (int size)
   4557  1.1  skrll {
   4558  1.1  skrll   int log_size;
   4559  1.1  skrll 
   4560  1.1  skrll   log_size = 0;
   4561  1.1  skrll   while ((size >>= 1) != 0)
   4562  1.1  skrll     ++log_size;
   4563  1.1  skrll 
   4564  1.1  skrll   if (alpha_auto_align_on && alpha_current_align < log_size)
   4565  1.1  skrll     alpha_align (log_size, (char *) NULL, alpha_insn_label, 0);
   4566  1.1  skrll   if (alpha_current_align > log_size)
   4567  1.1  skrll     alpha_current_align = log_size;
   4568  1.1  skrll   alpha_insn_label = NULL;
   4569  1.1  skrll }
   4570  1.1  skrll 
   4571  1.1  skrll /* Here come the .uword, .ulong, and .uquad explicitly unaligned
   4572  1.1  skrll    pseudos.  We just turn off auto-alignment and call down to cons.  */
   4573  1.1  skrll 
   4574  1.1  skrll static void
   4575  1.1  skrll s_alpha_ucons (int bytes)
   4576  1.1  skrll {
   4577  1.1  skrll   int hold = alpha_auto_align_on;
   4578  1.1  skrll   alpha_auto_align_on = 0;
   4579  1.1  skrll   cons (bytes);
   4580  1.1  skrll   alpha_auto_align_on = hold;
   4581  1.1  skrll }
   4582  1.1  skrll 
   4583  1.1  skrll /* Switch the working cpu type.  */
   4584  1.1  skrll 
   4585  1.1  skrll static void
   4586  1.1  skrll s_alpha_arch (int ignored ATTRIBUTE_UNUSED)
   4587  1.1  skrll {
   4588  1.1  skrll   char *name, ch;
   4589  1.1  skrll   const struct cpu_type *p;
   4590  1.1  skrll 
   4591  1.1  skrll   SKIP_WHITESPACE ();
   4592  1.1  skrll   name = input_line_pointer;
   4593  1.1  skrll   ch = get_symbol_end ();
   4594  1.1  skrll 
   4595  1.1  skrll   for (p = cpu_types; p->name; ++p)
   4596  1.1  skrll     if (strcmp (name, p->name) == 0)
   4597  1.1  skrll       {
   4598  1.1  skrll 	alpha_target_name = p->name, alpha_target = p->flags;
   4599  1.1  skrll 	goto found;
   4600  1.1  skrll       }
   4601  1.1  skrll   as_warn ("Unknown CPU identifier `%s'", name);
   4602  1.1  skrll 
   4603  1.1  skrll found:
   4604  1.1  skrll   *input_line_pointer = ch;
   4605  1.1  skrll   demand_empty_rest_of_line ();
   4606  1.1  skrll }
   4607  1.1  skrll 
   4608  1.1  skrll #ifdef DEBUG1
   4610  1.1  skrll /* print token expression with alpha specific extension.  */
   4611  1.1  skrll 
   4612  1.1  skrll static void
   4613  1.1  skrll alpha_print_token (FILE *f, const expressionS *exp)
   4614  1.1  skrll {
   4615  1.1  skrll   switch (exp->X_op)
   4616  1.1  skrll     {
   4617  1.1  skrll     case O_cpregister:
   4618  1.1  skrll       putc (',', f);
   4619  1.1  skrll       /* FALLTHRU */
   4620  1.1  skrll     case O_pregister:
   4621  1.1  skrll       putc ('(', f);
   4622  1.1  skrll       {
   4623  1.1  skrll 	expressionS nexp = *exp;
   4624  1.1  skrll 	nexp.X_op = O_register;
   4625  1.1  skrll 	print_expr (f, &nexp);
   4626  1.1  skrll       }
   4627  1.1  skrll       putc (')', f);
   4628  1.1  skrll       break;
   4629  1.1  skrll     default:
   4630  1.1  skrll       print_expr (f, exp);
   4631  1.1  skrll       break;
   4632  1.1  skrll     }
   4633  1.1  skrll }
   4634  1.1  skrll #endif
   4635  1.1  skrll 
   4636  1.1  skrll /* The target specific pseudo-ops which we support.  */
   4638  1.1  skrll 
   4639  1.1  skrll const pseudo_typeS md_pseudo_table[] =
   4640  1.1  skrll {
   4641  1.1  skrll #ifdef OBJ_ECOFF
   4642  1.1  skrll   {"comm", s_alpha_comm, 0},	/* OSF1 compiler does this.  */
   4643  1.1  skrll   {"rdata", s_alpha_rdata, 0},
   4644  1.1  skrll #endif
   4645  1.1  skrll   {"text", s_alpha_text, 0},
   4646  1.1  skrll   {"data", s_alpha_data, 0},
   4647  1.1  skrll #ifdef OBJ_ECOFF
   4648  1.1  skrll   {"sdata", s_alpha_sdata, 0},
   4649  1.1  skrll #endif
   4650  1.1  skrll #ifdef OBJ_ELF
   4651  1.1  skrll   {"section", s_alpha_section, 0},
   4652  1.1  skrll   {"section.s", s_alpha_section, 0},
   4653  1.1  skrll   {"sect", s_alpha_section, 0},
   4654  1.1  skrll   {"sect.s", s_alpha_section, 0},
   4655  1.1  skrll #endif
   4656  1.1  skrll #ifdef OBJ_EVAX
   4657  1.1  skrll   { "pdesc", s_alpha_pdesc, 0},
   4658  1.1  skrll   { "name", s_alpha_name, 0},
   4659  1.1  skrll   { "linkage", s_alpha_linkage, 0},
   4660  1.1  skrll   { "code_address", s_alpha_code_address, 0},
   4661  1.1  skrll   { "ent", s_alpha_ent, 0},
   4662  1.1  skrll   { "frame", s_alpha_frame, 0},
   4663  1.1  skrll   { "fp_save", s_alpha_fp_save, 0},
   4664  1.1  skrll   { "mask", s_alpha_mask, 0},
   4665  1.1  skrll   { "fmask", s_alpha_fmask, 0},
   4666  1.1  skrll   { "end", s_alpha_end, 0},
   4667  1.1  skrll   { "file", s_alpha_file, 0},
   4668  1.1  skrll   { "rdata", s_alpha_section, 1},
   4669  1.1  skrll   { "comm", s_alpha_comm, 0},
   4670  1.1  skrll   { "link", s_alpha_section, 3},
   4671  1.1  skrll   { "ctors", s_alpha_section, 4},
   4672  1.1  skrll   { "dtors", s_alpha_section, 5},
   4673  1.1  skrll #endif
   4674  1.1  skrll #ifdef OBJ_ELF
   4675  1.1  skrll   /* Frame related pseudos.  */
   4676  1.1  skrll   {"ent", s_alpha_ent, 0},
   4677  1.1  skrll   {"end", s_alpha_end, 0},
   4678  1.1  skrll   {"mask", s_alpha_mask, 0},
   4679  1.1  skrll   {"fmask", s_alpha_mask, 1},
   4680  1.1  skrll   {"frame", s_alpha_frame, 0},
   4681  1.1  skrll   {"prologue", s_alpha_prologue, 0},
   4682  1.1  skrll   {"file", s_alpha_file, 5},
   4683  1.1  skrll   {"loc", s_alpha_loc, 9},
   4684  1.1  skrll   {"stabs", s_alpha_stab, 's'},
   4685  1.1  skrll   {"stabn", s_alpha_stab, 'n'},
   4686  1.1  skrll   {"usepv", s_alpha_usepv, 0},
   4687  1.1  skrll   /* COFF debugging related pseudos.  */
   4688  1.1  skrll   {"begin", s_alpha_coff_wrapper, 0},
   4689  1.1  skrll   {"bend", s_alpha_coff_wrapper, 1},
   4690  1.1  skrll   {"def", s_alpha_coff_wrapper, 2},
   4691  1.1  skrll   {"dim", s_alpha_coff_wrapper, 3},
   4692  1.1  skrll   {"endef", s_alpha_coff_wrapper, 4},
   4693  1.1  skrll   {"scl", s_alpha_coff_wrapper, 5},
   4694  1.1  skrll   {"tag", s_alpha_coff_wrapper, 6},
   4695  1.1  skrll   {"val", s_alpha_coff_wrapper, 7},
   4696  1.1  skrll #else
   4697  1.1  skrll   {"prologue", s_ignore, 0},
   4698  1.1  skrll #endif
   4699  1.1  skrll   {"gprel32", s_alpha_gprel32, 0},
   4700  1.1  skrll   {"t_floating", s_alpha_float_cons, 'd'},
   4701  1.1  skrll   {"s_floating", s_alpha_float_cons, 'f'},
   4702  1.1  skrll   {"f_floating", s_alpha_float_cons, 'F'},
   4703  1.1  skrll   {"g_floating", s_alpha_float_cons, 'G'},
   4704  1.1  skrll   {"d_floating", s_alpha_float_cons, 'D'},
   4705  1.1  skrll 
   4706  1.1  skrll   {"proc", s_alpha_proc, 0},
   4707  1.1  skrll   {"aproc", s_alpha_proc, 1},
   4708  1.1  skrll   {"set", s_alpha_set, 0},
   4709  1.1  skrll   {"reguse", s_ignore, 0},
   4710  1.1  skrll   {"livereg", s_ignore, 0},
   4711  1.1  skrll   {"base", s_alpha_base, 0},		/*??*/
   4712  1.1  skrll   {"option", s_ignore, 0},
   4713  1.1  skrll   {"aent", s_ignore, 0},
   4714  1.1  skrll   {"ugen", s_ignore, 0},
   4715  1.1  skrll   {"eflag", s_ignore, 0},
   4716  1.1  skrll 
   4717  1.1  skrll   {"align", s_alpha_align, 0},
   4718  1.1  skrll   {"double", s_alpha_float_cons, 'd'},
   4719  1.1  skrll   {"float", s_alpha_float_cons, 'f'},
   4720  1.1  skrll   {"single", s_alpha_float_cons, 'f'},
   4721  1.1  skrll   {"ascii", s_alpha_stringer, 0},
   4722  1.1  skrll   {"asciz", s_alpha_stringer, 1},
   4723  1.1  skrll   {"string", s_alpha_stringer, 1},
   4724  1.1  skrll   {"space", s_alpha_space, 0},
   4725  1.1  skrll   {"skip", s_alpha_space, 0},
   4726  1.1  skrll   {"zero", s_alpha_space, 0},
   4727  1.1  skrll 
   4728  1.1  skrll /* Unaligned data pseudos.  */
   4729  1.1  skrll   {"uword", s_alpha_ucons, 2},
   4730  1.1  skrll   {"ulong", s_alpha_ucons, 4},
   4731  1.1  skrll   {"uquad", s_alpha_ucons, 8},
   4732  1.1  skrll 
   4733  1.1  skrll #ifdef OBJ_ELF
   4734  1.1  skrll /* Dwarf wants these versions of unaligned.  */
   4735  1.1  skrll   {"2byte", s_alpha_ucons, 2},
   4736  1.1  skrll   {"4byte", s_alpha_ucons, 4},
   4737  1.1  skrll   {"8byte", s_alpha_ucons, 8},
   4738  1.1  skrll #endif
   4739  1.1  skrll 
   4740  1.1  skrll /* We don't do any optimizing, so we can safely ignore these.  */
   4741  1.1  skrll   {"noalias", s_ignore, 0},
   4742  1.1  skrll   {"alias", s_ignore, 0},
   4743  1.1  skrll 
   4744  1.1  skrll   {"arch", s_alpha_arch, 0},
   4745  1.1  skrll 
   4746  1.1  skrll   {NULL, 0, 0},
   4747  1.1  skrll };
   4748  1.1  skrll 
   4749  1.1  skrll #ifdef OBJ_ECOFF
   4751  1.1  skrll 
   4752  1.1  skrll /* @@@ GP selection voodoo.  All of this seems overly complicated and
   4753  1.1  skrll    unnecessary; which is the primary reason it's for ECOFF only.  */
   4754  1.1  skrll 
   4755  1.1  skrll static inline void
   4756  1.1  skrll maybe_set_gp (asection *sec)
   4757  1.1  skrll {
   4758  1.1  skrll   bfd_vma vma;
   4759  1.1  skrll 
   4760  1.1  skrll   if (!sec)
   4761  1.1  skrll     return;
   4762  1.1  skrll   vma = bfd_get_section_vma (foo, sec);
   4763  1.1  skrll   if (vma && vma < alpha_gp_value)
   4764  1.1  skrll     alpha_gp_value = vma;
   4765  1.1  skrll }
   4766  1.1  skrll 
   4767  1.1  skrll static void
   4768  1.1  skrll select_gp_value (void)
   4769  1.1  skrll {
   4770  1.1  skrll   assert (alpha_gp_value == 0);
   4771  1.1  skrll 
   4772  1.1  skrll   /* Get minus-one in whatever width...  */
   4773  1.1  skrll   alpha_gp_value = 0;
   4774  1.1  skrll   alpha_gp_value--;
   4775  1.1  skrll 
   4776  1.1  skrll   /* Select the smallest VMA of these existing sections.  */
   4777  1.1  skrll   maybe_set_gp (alpha_lita_section);
   4778  1.1  skrll 
   4779  1.1  skrll /* @@ Will a simple 0x8000 work here?  If not, why not?  */
   4780  1.1  skrll #define GP_ADJUSTMENT	(0x8000 - 0x10)
   4781  1.1  skrll 
   4782  1.1  skrll   alpha_gp_value += GP_ADJUSTMENT;
   4783  1.1  skrll 
   4784  1.1  skrll   S_SET_VALUE (alpha_gp_symbol, alpha_gp_value);
   4785  1.1  skrll 
   4786  1.1  skrll #ifdef DEBUG1
   4787  1.1  skrll   printf (_("Chose GP value of %lx\n"), alpha_gp_value);
   4788  1.1  skrll #endif
   4789  1.1  skrll }
   4790  1.1  skrll #endif /* OBJ_ECOFF */
   4791  1.1  skrll 
   4792  1.1  skrll #ifdef OBJ_ELF
   4793  1.1  skrll /* Map 's' to SHF_ALPHA_GPREL.  */
   4794  1.1  skrll 
   4795  1.1  skrll int
   4796  1.1  skrll alpha_elf_section_letter (int letter, char **ptr_msg)
   4797  1.1  skrll {
   4798  1.1  skrll   if (letter == 's')
   4799  1.1  skrll     return SHF_ALPHA_GPREL;
   4800  1.1  skrll 
   4801  1.1  skrll   *ptr_msg = _("Bad .section directive: want a,s,w,x,M,S,G,T in string");
   4802  1.1  skrll   return -1;
   4803  1.1  skrll }
   4804  1.1  skrll 
   4805  1.1  skrll /* Map SHF_ALPHA_GPREL to SEC_SMALL_DATA.  */
   4806  1.1  skrll 
   4807  1.1  skrll flagword
   4808  1.1  skrll alpha_elf_section_flags (flagword flags, int attr, int type ATTRIBUTE_UNUSED)
   4809  1.1  skrll {
   4810  1.1  skrll   if (attr & SHF_ALPHA_GPREL)
   4811  1.1  skrll     flags |= SEC_SMALL_DATA;
   4812  1.1  skrll   return flags;
   4813  1.1  skrll }
   4814  1.1  skrll #endif /* OBJ_ELF */
   4815  1.1  skrll 
   4816  1.1  skrll /* This is called from HANDLE_ALIGN in write.c.  Fill in the contents
   4817  1.1  skrll    of an rs_align_code fragment.  */
   4818  1.1  skrll 
   4819  1.1  skrll void
   4820  1.1  skrll alpha_handle_align (fragS *fragp)
   4821  1.1  skrll {
   4822  1.1  skrll   static char const unop[4] = { 0x00, 0x00, 0xfe, 0x2f };
   4823  1.1  skrll   static char const nopunop[8] =
   4824  1.1  skrll   {
   4825  1.1  skrll     0x1f, 0x04, 0xff, 0x47,
   4826  1.1  skrll     0x00, 0x00, 0xfe, 0x2f
   4827  1.1  skrll   };
   4828  1.1  skrll 
   4829  1.1  skrll   int bytes, fix;
   4830  1.1  skrll   char *p;
   4831  1.1  skrll 
   4832  1.1  skrll   if (fragp->fr_type != rs_align_code)
   4833  1.1  skrll     return;
   4834  1.1  skrll 
   4835  1.1  skrll   bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix;
   4836  1.1  skrll   p = fragp->fr_literal + fragp->fr_fix;
   4837  1.1  skrll   fix = 0;
   4838  1.1  skrll 
   4839  1.1  skrll   if (bytes & 3)
   4840  1.1  skrll     {
   4841  1.1  skrll       fix = bytes & 3;
   4842  1.1  skrll       memset (p, 0, fix);
   4843  1.1  skrll       p += fix;
   4844  1.1  skrll       bytes -= fix;
   4845  1.1  skrll     }
   4846  1.1  skrll 
   4847  1.1  skrll   if (bytes & 4)
   4848  1.1  skrll     {
   4849  1.1  skrll       memcpy (p, unop, 4);
   4850  1.1  skrll       p += 4;
   4851  1.1  skrll       bytes -= 4;
   4852  1.1  skrll       fix += 4;
   4853  1.1  skrll     }
   4854  1.1  skrll 
   4855  1.1  skrll   memcpy (p, nopunop, 8);
   4856  1.1  skrll 
   4857  1.1  skrll   fragp->fr_fix += fix;
   4858  1.1  skrll   fragp->fr_var = 8;
   4859  1.1  skrll }
   4860  1.1  skrll 
   4861  1.1  skrll /* Public interface functions.  */
   4863  1.1  skrll 
   4864  1.1  skrll /* This function is called once, at assembler startup time.  It sets
   4865  1.1  skrll    up all the tables, etc. that the MD part of the assembler will
   4866  1.1  skrll    need, that can be determined before arguments are parsed.  */
   4867  1.1  skrll 
   4868  1.1  skrll void
   4869  1.1  skrll md_begin (void)
   4870  1.1  skrll {
   4871  1.1  skrll   unsigned int i;
   4872  1.1  skrll 
   4873  1.1  skrll   /* Verify that X_op field is wide enough.  */
   4874  1.1  skrll   {
   4875  1.1  skrll     expressionS e;
   4876  1.1  skrll 
   4877  1.1  skrll     e.X_op = O_max;
   4878  1.1  skrll     assert (e.X_op == O_max);
   4879  1.1  skrll   }
   4880  1.1  skrll 
   4881  1.1  skrll   /* Create the opcode hash table.  */
   4882  1.1  skrll   alpha_opcode_hash = hash_new ();
   4883  1.1  skrll 
   4884  1.1  skrll   for (i = 0; i < alpha_num_opcodes;)
   4885  1.1  skrll     {
   4886  1.1  skrll       const char *name, *retval, *slash;
   4887  1.1  skrll 
   4888  1.1  skrll       name = alpha_opcodes[i].name;
   4889  1.1  skrll       retval = hash_insert (alpha_opcode_hash, name, (void *) &alpha_opcodes[i]);
   4890  1.1  skrll       if (retval)
   4891  1.1  skrll 	as_fatal (_("internal error: can't hash opcode `%s': %s"),
   4892  1.1  skrll 		  name, retval);
   4893  1.1  skrll 
   4894  1.1  skrll       /* Some opcodes include modifiers of various sorts with a "/mod"
   4895  1.1  skrll 	 syntax, like the architecture manual suggests.  However, for
   4896  1.1  skrll 	 use with gcc at least, we also need access to those same opcodes
   4897  1.1  skrll 	 without the "/".  */
   4898  1.1  skrll 
   4899  1.1  skrll       if ((slash = strchr (name, '/')) != NULL)
   4900  1.1  skrll 	{
   4901  1.1  skrll 	  char *p = xmalloc (strlen (name));
   4902  1.1  skrll 
   4903  1.1  skrll 	  memcpy (p, name, slash - name);
   4904  1.1  skrll 	  strcpy (p + (slash - name), slash + 1);
   4905  1.1  skrll 
   4906  1.1  skrll 	  (void) hash_insert (alpha_opcode_hash, p, (void *) &alpha_opcodes[i]);
   4907  1.1  skrll 	  /* Ignore failures -- the opcode table does duplicate some
   4908  1.1  skrll 	     variants in different forms, like "hw_stq" and "hw_st/q".  */
   4909  1.1  skrll 	}
   4910  1.1  skrll 
   4911  1.1  skrll       while (++i < alpha_num_opcodes
   4912  1.1  skrll 	     && (alpha_opcodes[i].name == name
   4913  1.1  skrll 		 || !strcmp (alpha_opcodes[i].name, name)))
   4914  1.1  skrll 	continue;
   4915  1.1  skrll     }
   4916  1.1  skrll 
   4917  1.1  skrll   /* Create the macro hash table.  */
   4918  1.1  skrll   alpha_macro_hash = hash_new ();
   4919  1.1  skrll 
   4920  1.1  skrll   for (i = 0; i < alpha_num_macros;)
   4921  1.1  skrll     {
   4922  1.1  skrll       const char *name, *retval;
   4923  1.1  skrll 
   4924  1.1  skrll       name = alpha_macros[i].name;
   4925  1.1  skrll       retval = hash_insert (alpha_macro_hash, name, (void *) &alpha_macros[i]);
   4926  1.1  skrll       if (retval)
   4927  1.1  skrll 	as_fatal (_("internal error: can't hash macro `%s': %s"),
   4928  1.1  skrll 		  name, retval);
   4929  1.1  skrll 
   4930  1.1  skrll       while (++i < alpha_num_macros
   4931  1.1  skrll 	     && (alpha_macros[i].name == name
   4932  1.1  skrll 		 || !strcmp (alpha_macros[i].name, name)))
   4933  1.1  skrll 	continue;
   4934  1.1  skrll     }
   4935  1.1  skrll 
   4936  1.1  skrll   /* Construct symbols for each of the registers.  */
   4937  1.1  skrll   for (i = 0; i < 32; ++i)
   4938  1.1  skrll     {
   4939  1.1  skrll       char name[4];
   4940  1.1  skrll 
   4941  1.1  skrll       sprintf (name, "$%d", i);
   4942  1.1  skrll       alpha_register_table[i] = symbol_create (name, reg_section, i,
   4943  1.1  skrll 					       &zero_address_frag);
   4944  1.1  skrll     }
   4945  1.1  skrll 
   4946  1.1  skrll   for (; i < 64; ++i)
   4947  1.1  skrll     {
   4948  1.1  skrll       char name[5];
   4949  1.1  skrll 
   4950  1.1  skrll       sprintf (name, "$f%d", i - 32);
   4951  1.1  skrll       alpha_register_table[i] = symbol_create (name, reg_section, i,
   4952  1.1  skrll 					       &zero_address_frag);
   4953  1.1  skrll     }
   4954  1.1  skrll 
   4955  1.1  skrll   /* Create the special symbols and sections we'll be using.  */
   4956  1.1  skrll 
   4957  1.1  skrll   /* So .sbss will get used for tiny objects.  */
   4958  1.1  skrll   bfd_set_gp_size (stdoutput, g_switch_value);
   4959  1.1  skrll 
   4960  1.1  skrll #ifdef OBJ_ECOFF
   4961  1.1  skrll   create_literal_section (".lita", &alpha_lita_section, &alpha_lita_symbol);
   4962  1.1  skrll 
   4963  1.1  skrll   /* For handling the GP, create a symbol that won't be output in the
   4964  1.1  skrll      symbol table.  We'll edit it out of relocs later.  */
   4965  1.1  skrll   alpha_gp_symbol = symbol_create ("<GP value>", alpha_lita_section, 0x8000,
   4966  1.1  skrll 				   &zero_address_frag);
   4967  1.1  skrll #endif
   4968  1.1  skrll 
   4969  1.1  skrll #ifdef OBJ_EVAX
   4970  1.1  skrll   create_literal_section (".link", &alpha_link_section, &alpha_link_symbol);
   4971  1.1  skrll #endif
   4972  1.1  skrll 
   4973  1.1  skrll #ifdef OBJ_ELF
   4974  1.1  skrll   if (ECOFF_DEBUGGING)
   4975  1.1  skrll     {
   4976  1.1  skrll       segT sec = subseg_new (".mdebug", (subsegT) 0);
   4977  1.1  skrll       bfd_set_section_flags (stdoutput, sec, SEC_HAS_CONTENTS | SEC_READONLY);
   4978  1.1  skrll       bfd_set_section_alignment (stdoutput, sec, 3);
   4979  1.1  skrll     }
   4980  1.1  skrll #endif
   4981  1.1  skrll 
   4982  1.1  skrll   /* Create literal lookup hash table.  */
   4983  1.1  skrll   alpha_literal_hash = hash_new ();
   4984  1.1  skrll 
   4985  1.1  skrll   subseg_set (text_section, 0);
   4986  1.1  skrll }
   4987  1.1  skrll 
   4988  1.1  skrll /* The public interface to the instruction assembler.  */
   4989  1.1  skrll 
   4990  1.1  skrll void
   4991  1.1  skrll md_assemble (char *str)
   4992  1.1  skrll {
   4993  1.1  skrll   /* Current maximum is 13.  */
   4994  1.1  skrll   char opname[32];
   4995  1.1  skrll   expressionS tok[MAX_INSN_ARGS];
   4996  1.1  skrll   int ntok, trunclen;
   4997  1.1  skrll   size_t opnamelen;
   4998  1.1  skrll 
   4999  1.1  skrll   /* Split off the opcode.  */
   5000  1.1  skrll   opnamelen = strspn (str, "abcdefghijklmnopqrstuvwxyz_/46819");
   5001  1.1  skrll   trunclen = (opnamelen < sizeof (opname) - 1
   5002  1.1  skrll 	      ? opnamelen
   5003  1.1  skrll 	      : sizeof (opname) - 1);
   5004  1.1  skrll   memcpy (opname, str, trunclen);
   5005  1.1  skrll   opname[trunclen] = '\0';
   5006  1.1  skrll 
   5007  1.1  skrll   /* Tokenize the rest of the line.  */
   5008  1.1  skrll   if ((ntok = tokenize_arguments (str + opnamelen, tok, MAX_INSN_ARGS)) < 0)
   5009  1.1  skrll     {
   5010  1.1  skrll       if (ntok != TOKENIZE_ERROR_REPORT)
   5011  1.1  skrll 	as_bad (_("syntax error"));
   5012  1.1  skrll 
   5013  1.1  skrll       return;
   5014  1.1  skrll     }
   5015  1.1  skrll 
   5016  1.1  skrll   /* Finish it off.  */
   5017  1.1  skrll   assemble_tokens (opname, tok, ntok, alpha_macros_on);
   5018  1.1  skrll }
   5019  1.1  skrll 
   5020  1.1  skrll /* Round up a section's size to the appropriate boundary.  */
   5021  1.1  skrll 
   5022  1.1  skrll valueT
   5023  1.1  skrll md_section_align (segT seg, valueT size)
   5024  1.1  skrll {
   5025  1.1  skrll   int align = bfd_get_section_alignment (stdoutput, seg);
   5026  1.1  skrll   valueT mask = ((valueT) 1 << align) - 1;
   5027  1.1  skrll 
   5028  1.1  skrll   return (size + mask) & ~mask;
   5029  1.1  skrll }
   5030  1.1  skrll 
   5031  1.1  skrll /* Turn a string in input_line_pointer into a floating point constant
   5032  1.1  skrll    of type TYPE, and store the appropriate bytes in *LITP.  The number
   5033  1.1  skrll    of LITTLENUMS emitted is stored in *SIZEP.  An error message is
   5034  1.1  skrll    returned, or NULL on OK.  */
   5035  1.1  skrll 
   5036  1.1  skrll char *
   5037  1.1  skrll md_atof (int type, char *litP, int *sizeP)
   5038  1.1  skrll {
   5039  1.1  skrll   extern char *vax_md_atof (int, char *, int *);
   5040  1.1  skrll 
   5041  1.1  skrll   switch (type)
   5042  1.1  skrll     {
   5043  1.1  skrll       /* VAX floats.  */
   5044  1.1  skrll     case 'G':
   5045  1.1  skrll       /* vax_md_atof() doesn't like "G" for some reason.  */
   5046  1.1  skrll       type = 'g';
   5047  1.1  skrll     case 'F':
   5048  1.1  skrll     case 'D':
   5049  1.1  skrll       return vax_md_atof (type, litP, sizeP);
   5050  1.1  skrll 
   5051  1.1  skrll     default:
   5052  1.1  skrll       return ieee_md_atof (type, litP, sizeP, FALSE);
   5053  1.1  skrll     }
   5054  1.1  skrll }
   5055  1.1  skrll 
   5056  1.1  skrll /* Take care of the target-specific command-line options.  */
   5057  1.1  skrll 
   5058  1.1  skrll int
   5059  1.1  skrll md_parse_option (int c, char *arg)
   5060  1.1  skrll {
   5061  1.1  skrll   switch (c)
   5062  1.1  skrll     {
   5063  1.1  skrll     case 'F':
   5064  1.1  skrll       alpha_nofloats_on = 1;
   5065  1.1  skrll       break;
   5066  1.1  skrll 
   5067  1.1  skrll     case OPTION_32ADDR:
   5068  1.1  skrll       alpha_addr32_on = 1;
   5069  1.1  skrll       break;
   5070  1.1  skrll 
   5071  1.1  skrll     case 'g':
   5072  1.1  skrll       alpha_debug = 1;
   5073  1.1  skrll       break;
   5074  1.1  skrll 
   5075  1.1  skrll     case 'G':
   5076  1.1  skrll       g_switch_value = atoi (arg);
   5077  1.1  skrll       break;
   5078  1.1  skrll 
   5079  1.1  skrll     case 'm':
   5080  1.1  skrll       {
   5081  1.1  skrll 	const struct cpu_type *p;
   5082  1.1  skrll 
   5083  1.1  skrll 	for (p = cpu_types; p->name; ++p)
   5084  1.1  skrll 	  if (strcmp (arg, p->name) == 0)
   5085  1.1  skrll 	    {
   5086  1.1  skrll 	      alpha_target_name = p->name, alpha_target = p->flags;
   5087  1.1  skrll 	      goto found;
   5088  1.1  skrll 	    }
   5089  1.1  skrll 	as_warn (_("Unknown CPU identifier `%s'"), arg);
   5090  1.1  skrll       found:;
   5091  1.1  skrll       }
   5092  1.1  skrll       break;
   5093  1.1  skrll 
   5094  1.1  skrll #ifdef OBJ_EVAX
   5095  1.1  skrll     case '+':			/* For g++.  Hash any name > 63 chars long.  */
   5096  1.1  skrll       alpha_flag_hash_long_names = 1;
   5097  1.1  skrll       break;
   5098  1.1  skrll 
   5099  1.1  skrll     case 'H':			/* Show new symbol after hash truncation.  */
   5100  1.1  skrll       alpha_flag_show_after_trunc = 1;
   5101  1.1  skrll       break;
   5102  1.1  skrll 
   5103  1.1  skrll     case 'h':			/* For gnu-c/vax compatibility.  */
   5104  1.1  skrll       break;
   5105  1.1  skrll #endif
   5106  1.1  skrll 
   5107  1.1  skrll     case OPTION_RELAX:
   5108  1.1  skrll       alpha_flag_relax = 1;
   5109  1.1  skrll       break;
   5110  1.1  skrll 
   5111  1.1  skrll #ifdef OBJ_ELF
   5112  1.1  skrll     case OPTION_MDEBUG:
   5113  1.1  skrll       alpha_flag_mdebug = 1;
   5114  1.1  skrll       break;
   5115  1.1  skrll     case OPTION_NO_MDEBUG:
   5116  1.1  skrll       alpha_flag_mdebug = 0;
   5117  1.1  skrll       break;
   5118  1.1  skrll #endif
   5119  1.1  skrll 
   5120  1.1  skrll     default:
   5121  1.1  skrll       return 0;
   5122  1.1  skrll     }
   5123  1.1  skrll 
   5124  1.1  skrll   return 1;
   5125  1.1  skrll }
   5126  1.1  skrll 
   5127  1.1  skrll /* Print a description of the command-line options that we accept.  */
   5128  1.1  skrll 
   5129  1.1  skrll void
   5130  1.1  skrll md_show_usage (FILE *stream)
   5131  1.1  skrll {
   5132  1.1  skrll   fputs (_("\
   5133  1.1  skrll Alpha options:\n\
   5134  1.1  skrll -32addr			treat addresses as 32-bit values\n\
   5135  1.1  skrll -F			lack floating point instructions support\n\
   5136  1.1  skrll -mev4 | -mev45 | -mev5 | -mev56 | -mpca56 | -mev6 | -mev67 | -mev68 | -mall\n\
   5137  1.1  skrll 			specify variant of Alpha architecture\n\
   5138  1.1  skrll -m21064 | -m21066 | -m21164 | -m21164a | -m21164pc | -m21264 | -m21264a | -m21264b\n\
   5139  1.1  skrll 			these variants include PALcode opcodes\n"),
   5140  1.1  skrll 	stream);
   5141  1.1  skrll #ifdef OBJ_EVAX
   5142  1.1  skrll   fputs (_("\
   5143  1.1  skrll VMS options:\n\
   5144  1.1  skrll -+			hash encode (don't truncate) names longer than 64 characters\n\
   5145  1.1  skrll -H			show new symbol after hash truncation\n"),
   5146  1.1  skrll 	stream);
   5147  1.1  skrll #endif
   5148  1.1  skrll }
   5149  1.1  skrll 
   5150  1.1  skrll /* Decide from what point a pc-relative relocation is relative to,
   5151  1.1  skrll    relative to the pc-relative fixup.  Er, relatively speaking.  */
   5152  1.1  skrll 
   5153  1.1  skrll long
   5154  1.1  skrll md_pcrel_from (fixS *fixP)
   5155  1.1  skrll {
   5156  1.1  skrll   valueT addr = fixP->fx_where + fixP->fx_frag->fr_address;
   5157  1.1  skrll 
   5158  1.1  skrll   switch (fixP->fx_r_type)
   5159  1.1  skrll     {
   5160  1.1  skrll     case BFD_RELOC_23_PCREL_S2:
   5161  1.1  skrll     case BFD_RELOC_ALPHA_HINT:
   5162  1.1  skrll     case BFD_RELOC_ALPHA_BRSGP:
   5163  1.1  skrll       return addr + 4;
   5164  1.1  skrll     default:
   5165  1.1  skrll       return addr;
   5166  1.1  skrll     }
   5167  1.1  skrll }
   5168  1.1  skrll 
   5169  1.1  skrll /* Attempt to simplify or even eliminate a fixup.  The return value is
   5170  1.1  skrll    ignored; perhaps it was once meaningful, but now it is historical.
   5171  1.1  skrll    To indicate that a fixup has been eliminated, set fixP->fx_done.
   5172  1.1  skrll 
   5173  1.1  skrll    For ELF, here it is that we transform the GPDISP_HI16 reloc we used
   5174  1.1  skrll    internally into the GPDISP reloc used externally.  We had to do
   5175  1.1  skrll    this so that we'd have the GPDISP_LO16 reloc as a tag to compute
   5176  1.1  skrll    the distance to the "lda" instruction for setting the addend to
   5177  1.1  skrll    GPDISP.  */
   5178  1.1  skrll 
   5179  1.1  skrll void
   5180  1.1  skrll md_apply_fix (fixS *fixP, valueT * valP, segT seg)
   5181  1.1  skrll {
   5182  1.1  skrll   char * const fixpos = fixP->fx_frag->fr_literal + fixP->fx_where;
   5183  1.1  skrll   valueT value = * valP;
   5184  1.1  skrll   unsigned image, size;
   5185  1.1  skrll 
   5186  1.1  skrll   switch (fixP->fx_r_type)
   5187  1.1  skrll     {
   5188  1.1  skrll       /* The GPDISP relocations are processed internally with a symbol
   5189  1.1  skrll 	 referring to the current function's section;  we need to drop
   5190  1.1  skrll 	 in a value which, when added to the address of the start of
   5191  1.1  skrll 	 the function, gives the desired GP.  */
   5192  1.1  skrll     case BFD_RELOC_ALPHA_GPDISP_HI16:
   5193  1.1  skrll       {
   5194  1.1  skrll 	fixS *next = fixP->fx_next;
   5195  1.1  skrll 
   5196  1.1  skrll 	/* With user-specified !gpdisp relocations, we can be missing
   5197  1.1  skrll 	   the matching LO16 reloc.  We will have already issued an
   5198  1.1  skrll 	   error message.  */
   5199  1.1  skrll 	if (next)
   5200  1.1  skrll 	  fixP->fx_offset = (next->fx_frag->fr_address + next->fx_where
   5201  1.1  skrll 			     - fixP->fx_frag->fr_address - fixP->fx_where);
   5202  1.1  skrll 
   5203  1.1  skrll 	value = (value - sign_extend_16 (value)) >> 16;
   5204  1.1  skrll       }
   5205  1.1  skrll #ifdef OBJ_ELF
   5206  1.1  skrll       fixP->fx_r_type = BFD_RELOC_ALPHA_GPDISP;
   5207  1.1  skrll #endif
   5208  1.1  skrll       goto do_reloc_gp;
   5209  1.1  skrll 
   5210  1.1  skrll     case BFD_RELOC_ALPHA_GPDISP_LO16:
   5211  1.1  skrll       value = sign_extend_16 (value);
   5212  1.1  skrll       fixP->fx_offset = 0;
   5213  1.1  skrll #ifdef OBJ_ELF
   5214  1.1  skrll       fixP->fx_done = 1;
   5215  1.1  skrll #endif
   5216  1.1  skrll 
   5217  1.1  skrll     do_reloc_gp:
   5218  1.1  skrll       fixP->fx_addsy = section_symbol (seg);
   5219  1.1  skrll       md_number_to_chars (fixpos, value, 2);
   5220  1.1  skrll       break;
   5221  1.1  skrll 
   5222  1.1  skrll     case BFD_RELOC_16:
   5223  1.1  skrll       if (fixP->fx_pcrel)
   5224  1.1  skrll 	fixP->fx_r_type = BFD_RELOC_16_PCREL;
   5225  1.1  skrll       size = 2;
   5226  1.1  skrll       goto do_reloc_xx;
   5227  1.1  skrll 
   5228  1.1  skrll     case BFD_RELOC_32:
   5229  1.1  skrll       if (fixP->fx_pcrel)
   5230  1.1  skrll 	fixP->fx_r_type = BFD_RELOC_32_PCREL;
   5231  1.1  skrll       size = 4;
   5232  1.1  skrll       goto do_reloc_xx;
   5233  1.1  skrll 
   5234  1.1  skrll     case BFD_RELOC_64:
   5235  1.1  skrll       if (fixP->fx_pcrel)
   5236  1.1  skrll 	fixP->fx_r_type = BFD_RELOC_64_PCREL;
   5237  1.1  skrll       size = 8;
   5238  1.1  skrll 
   5239  1.1  skrll     do_reloc_xx:
   5240  1.1  skrll       if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0)
   5241  1.1  skrll 	{
   5242  1.1  skrll 	  md_number_to_chars (fixpos, value, size);
   5243  1.1  skrll 	  goto done;
   5244  1.1  skrll 	}
   5245  1.1  skrll       return;
   5246  1.1  skrll 
   5247  1.1  skrll #ifdef OBJ_ECOFF
   5248  1.1  skrll     case BFD_RELOC_GPREL32:
   5249  1.1  skrll       assert (fixP->fx_subsy == alpha_gp_symbol);
   5250  1.1  skrll       fixP->fx_subsy = 0;
   5251  1.1  skrll       /* FIXME: inherited this obliviousness of `value' -- why?  */
   5252  1.1  skrll       md_number_to_chars (fixpos, -alpha_gp_value, 4);
   5253  1.1  skrll       break;
   5254  1.1  skrll #else
   5255  1.1  skrll     case BFD_RELOC_GPREL32:
   5256  1.1  skrll #endif
   5257  1.1  skrll     case BFD_RELOC_GPREL16:
   5258  1.1  skrll     case BFD_RELOC_ALPHA_GPREL_HI16:
   5259  1.1  skrll     case BFD_RELOC_ALPHA_GPREL_LO16:
   5260  1.1  skrll       return;
   5261  1.1  skrll 
   5262  1.1  skrll     case BFD_RELOC_23_PCREL_S2:
   5263  1.1  skrll       if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0)
   5264  1.1  skrll 	{
   5265  1.1  skrll 	  image = bfd_getl32 (fixpos);
   5266  1.1  skrll 	  image = (image & ~0x1FFFFF) | ((value >> 2) & 0x1FFFFF);
   5267  1.1  skrll 	  goto write_done;
   5268  1.1  skrll 	}
   5269  1.1  skrll       return;
   5270  1.1  skrll 
   5271  1.1  skrll     case BFD_RELOC_ALPHA_HINT:
   5272  1.1  skrll       if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0)
   5273  1.1  skrll 	{
   5274  1.1  skrll 	  image = bfd_getl32 (fixpos);
   5275  1.1  skrll 	  image = (image & ~0x3FFF) | ((value >> 2) & 0x3FFF);
   5276  1.1  skrll 	  goto write_done;
   5277  1.1  skrll 	}
   5278  1.1  skrll       return;
   5279  1.1  skrll 
   5280  1.1  skrll #ifdef OBJ_ELF
   5281  1.1  skrll     case BFD_RELOC_ALPHA_BRSGP:
   5282  1.1  skrll       return;
   5283  1.1  skrll 
   5284  1.1  skrll     case BFD_RELOC_ALPHA_TLSGD:
   5285  1.1  skrll     case BFD_RELOC_ALPHA_TLSLDM:
   5286  1.1  skrll     case BFD_RELOC_ALPHA_GOTDTPREL16:
   5287  1.1  skrll     case BFD_RELOC_ALPHA_DTPREL_HI16:
   5288  1.1  skrll     case BFD_RELOC_ALPHA_DTPREL_LO16:
   5289  1.1  skrll     case BFD_RELOC_ALPHA_DTPREL16:
   5290  1.1  skrll     case BFD_RELOC_ALPHA_GOTTPREL16:
   5291  1.1  skrll     case BFD_RELOC_ALPHA_TPREL_HI16:
   5292  1.1  skrll     case BFD_RELOC_ALPHA_TPREL_LO16:
   5293  1.1  skrll     case BFD_RELOC_ALPHA_TPREL16:
   5294  1.1  skrll       if (fixP->fx_addsy)
   5295  1.1  skrll 	S_SET_THREAD_LOCAL (fixP->fx_addsy);
   5296  1.1  skrll       return;
   5297  1.1  skrll #endif
   5298  1.1  skrll 
   5299  1.1  skrll #ifdef OBJ_ECOFF
   5300  1.1  skrll     case BFD_RELOC_ALPHA_LITERAL:
   5301  1.1  skrll       md_number_to_chars (fixpos, value, 2);
   5302  1.1  skrll       return;
   5303  1.1  skrll #endif
   5304  1.1  skrll     case BFD_RELOC_ALPHA_ELF_LITERAL:
   5305  1.1  skrll     case BFD_RELOC_ALPHA_LITUSE:
   5306  1.1  skrll     case BFD_RELOC_ALPHA_LINKAGE:
   5307  1.1  skrll     case BFD_RELOC_ALPHA_CODEADDR:
   5308  1.1  skrll       return;
   5309  1.1  skrll 
   5310  1.1  skrll     case BFD_RELOC_VTABLE_INHERIT:
   5311  1.1  skrll     case BFD_RELOC_VTABLE_ENTRY:
   5312  1.1  skrll       return;
   5313  1.1  skrll 
   5314  1.1  skrll     default:
   5315  1.1  skrll       {
   5316  1.1  skrll 	const struct alpha_operand *operand;
   5317  1.1  skrll 
   5318  1.1  skrll 	if ((int) fixP->fx_r_type >= 0)
   5319  1.1  skrll 	  as_fatal (_("unhandled relocation type %s"),
   5320  1.1  skrll 		    bfd_get_reloc_code_name (fixP->fx_r_type));
   5321  1.1  skrll 
   5322  1.1  skrll 	assert (-(int) fixP->fx_r_type < (int) alpha_num_operands);
   5323  1.1  skrll 	operand = &alpha_operands[-(int) fixP->fx_r_type];
   5324  1.1  skrll 
   5325  1.1  skrll 	/* The rest of these fixups only exist internally during symbol
   5326  1.1  skrll 	   resolution and have no representation in the object file.
   5327  1.1  skrll 	   Therefore they must be completely resolved as constants.  */
   5328  1.1  skrll 
   5329  1.1  skrll 	if (fixP->fx_addsy != 0
   5330  1.1  skrll 	    && S_GET_SEGMENT (fixP->fx_addsy) != absolute_section)
   5331  1.1  skrll 	  as_bad_where (fixP->fx_file, fixP->fx_line,
   5332  1.1  skrll 			_("non-absolute expression in constant field"));
   5333  1.1  skrll 
   5334  1.1  skrll 	image = bfd_getl32 (fixpos);
   5335  1.1  skrll 	image = insert_operand (image, operand, (offsetT) value,
   5336  1.1  skrll 				fixP->fx_file, fixP->fx_line);
   5337  1.1  skrll       }
   5338  1.1  skrll       goto write_done;
   5339  1.1  skrll     }
   5340  1.1  skrll 
   5341  1.1  skrll   if (fixP->fx_addsy != 0 || fixP->fx_pcrel != 0)
   5342  1.1  skrll     return;
   5343  1.1  skrll   else
   5344  1.1  skrll     {
   5345  1.1  skrll       as_warn_where (fixP->fx_file, fixP->fx_line,
   5346  1.1  skrll 		     _("type %d reloc done?\n"), (int) fixP->fx_r_type);
   5347  1.1  skrll       goto done;
   5348  1.1  skrll     }
   5349  1.1  skrll 
   5350  1.1  skrll write_done:
   5351  1.1  skrll   md_number_to_chars (fixpos, image, 4);
   5352  1.1  skrll 
   5353  1.1  skrll done:
   5354  1.1  skrll   fixP->fx_done = 1;
   5355  1.1  skrll }
   5356  1.1  skrll 
   5357  1.1  skrll /* Look for a register name in the given symbol.  */
   5358  1.1  skrll 
   5359  1.1  skrll symbolS *
   5360  1.1  skrll md_undefined_symbol (char *name)
   5361  1.1  skrll {
   5362  1.1  skrll   if (*name == '$')
   5363  1.1  skrll     {
   5364  1.1  skrll       int is_float = 0, num;
   5365  1.1  skrll 
   5366  1.1  skrll       switch (*++name)
   5367  1.1  skrll 	{
   5368  1.1  skrll 	case 'f':
   5369  1.1  skrll 	  if (name[1] == 'p' && name[2] == '\0')
   5370  1.1  skrll 	    return alpha_register_table[AXP_REG_FP];
   5371  1.1  skrll 	  is_float = 32;
   5372  1.1  skrll 	  /* Fall through.  */
   5373  1.1  skrll 
   5374  1.1  skrll 	case 'r':
   5375  1.1  skrll 	  if (!ISDIGIT (*++name))
   5376  1.1  skrll 	    break;
   5377  1.1  skrll 	  /* Fall through.  */
   5378  1.1  skrll 
   5379  1.1  skrll 	case '0': case '1': case '2': case '3': case '4':
   5380  1.1  skrll 	case '5': case '6': case '7': case '8': case '9':
   5381  1.1  skrll 	  if (name[1] == '\0')
   5382  1.1  skrll 	    num = name[0] - '0';
   5383  1.1  skrll 	  else if (name[0] != '0' && ISDIGIT (name[1]) && name[2] == '\0')
   5384  1.1  skrll 	    {
   5385  1.1  skrll 	      num = (name[0] - '0') * 10 + name[1] - '0';
   5386  1.1  skrll 	      if (num >= 32)
   5387  1.1  skrll 		break;
   5388  1.1  skrll 	    }
   5389  1.1  skrll 	  else
   5390  1.1  skrll 	    break;
   5391  1.1  skrll 
   5392  1.1  skrll 	  if (!alpha_noat_on && (num + is_float) == AXP_REG_AT)
   5393  1.1  skrll 	    as_warn (_("Used $at without \".set noat\""));
   5394  1.1  skrll 	  return alpha_register_table[num + is_float];
   5395  1.1  skrll 
   5396  1.1  skrll 	case 'a':
   5397  1.1  skrll 	  if (name[1] == 't' && name[2] == '\0')
   5398  1.1  skrll 	    {
   5399  1.1  skrll 	      if (!alpha_noat_on)
   5400  1.1  skrll 		as_warn (_("Used $at without \".set noat\""));
   5401  1.1  skrll 	      return alpha_register_table[AXP_REG_AT];
   5402  1.1  skrll 	    }
   5403  1.1  skrll 	  break;
   5404  1.1  skrll 
   5405  1.1  skrll 	case 'g':
   5406  1.1  skrll 	  if (name[1] == 'p' && name[2] == '\0')
   5407  1.1  skrll 	    return alpha_register_table[alpha_gp_register];
   5408  1.1  skrll 	  break;
   5409  1.1  skrll 
   5410  1.1  skrll 	case 's':
   5411  1.1  skrll 	  if (name[1] == 'p' && name[2] == '\0')
   5412  1.1  skrll 	    return alpha_register_table[AXP_REG_SP];
   5413  1.1  skrll 	  break;
   5414  1.1  skrll 	}
   5415  1.1  skrll     }
   5416  1.1  skrll   return NULL;
   5417  1.1  skrll }
   5418  1.1  skrll 
   5419  1.1  skrll #ifdef OBJ_ECOFF
   5420  1.1  skrll /* @@@ Magic ECOFF bits.  */
   5421  1.1  skrll 
   5422  1.1  skrll void
   5423  1.1  skrll alpha_frob_ecoff_data (void)
   5424  1.1  skrll {
   5425  1.1  skrll   select_gp_value ();
   5426  1.1  skrll   /* $zero and $f31 are read-only.  */
   5427  1.1  skrll   alpha_gprmask &= ~1;
   5428  1.1  skrll   alpha_fprmask &= ~1;
   5429  1.1  skrll }
   5430  1.1  skrll #endif
   5431  1.1  skrll 
   5432  1.1  skrll /* Hook to remember a recently defined label so that the auto-align
   5433  1.1  skrll    code can adjust the symbol after we know what alignment will be
   5434  1.1  skrll    required.  */
   5435  1.1  skrll 
   5436  1.1  skrll void
   5437  1.1  skrll alpha_define_label (symbolS *sym)
   5438  1.1  skrll {
   5439  1.1  skrll   alpha_insn_label = sym;
   5440  1.1  skrll #ifdef OBJ_ELF
   5441  1.1  skrll   dwarf2_emit_label (sym);
   5442  1.1  skrll #endif
   5443  1.1  skrll }
   5444  1.1  skrll 
   5445  1.1  skrll /* Return true if we must always emit a reloc for a type and false if
   5446  1.1  skrll    there is some hope of resolving it at assembly time.  */
   5447  1.1  skrll 
   5448  1.1  skrll int
   5449  1.1  skrll alpha_force_relocation (fixS *f)
   5450  1.1  skrll {
   5451  1.1  skrll   if (alpha_flag_relax)
   5452  1.1  skrll     return 1;
   5453  1.1  skrll 
   5454  1.1  skrll   switch (f->fx_r_type)
   5455  1.1  skrll     {
   5456  1.1  skrll     case BFD_RELOC_ALPHA_GPDISP_HI16:
   5457  1.1  skrll     case BFD_RELOC_ALPHA_GPDISP_LO16:
   5458  1.1  skrll     case BFD_RELOC_ALPHA_GPDISP:
   5459  1.1  skrll     case BFD_RELOC_ALPHA_LITERAL:
   5460  1.1  skrll     case BFD_RELOC_ALPHA_ELF_LITERAL:
   5461  1.1  skrll     case BFD_RELOC_ALPHA_LITUSE:
   5462  1.1  skrll     case BFD_RELOC_GPREL16:
   5463  1.1  skrll     case BFD_RELOC_GPREL32:
   5464  1.1  skrll     case BFD_RELOC_ALPHA_GPREL_HI16:
   5465  1.1  skrll     case BFD_RELOC_ALPHA_GPREL_LO16:
   5466  1.1  skrll     case BFD_RELOC_ALPHA_LINKAGE:
   5467  1.1  skrll     case BFD_RELOC_ALPHA_CODEADDR:
   5468  1.1  skrll     case BFD_RELOC_ALPHA_BRSGP:
   5469  1.1  skrll     case BFD_RELOC_ALPHA_TLSGD:
   5470  1.1  skrll     case BFD_RELOC_ALPHA_TLSLDM:
   5471  1.1  skrll     case BFD_RELOC_ALPHA_GOTDTPREL16:
   5472  1.1  skrll     case BFD_RELOC_ALPHA_DTPREL_HI16:
   5473  1.1  skrll     case BFD_RELOC_ALPHA_DTPREL_LO16:
   5474  1.1  skrll     case BFD_RELOC_ALPHA_DTPREL16:
   5475  1.1  skrll     case BFD_RELOC_ALPHA_GOTTPREL16:
   5476  1.1  skrll     case BFD_RELOC_ALPHA_TPREL_HI16:
   5477  1.1  skrll     case BFD_RELOC_ALPHA_TPREL_LO16:
   5478  1.1  skrll     case BFD_RELOC_ALPHA_TPREL16:
   5479  1.1  skrll       return 1;
   5480  1.1  skrll 
   5481  1.1  skrll     default:
   5482  1.1  skrll       break;
   5483  1.1  skrll     }
   5484  1.1  skrll 
   5485  1.1  skrll   return generic_force_reloc (f);
   5486  1.1  skrll }
   5487  1.1  skrll 
   5488  1.1  skrll /* Return true if we can partially resolve a relocation now.  */
   5489  1.1  skrll 
   5490  1.1  skrll int
   5491  1.1  skrll alpha_fix_adjustable (fixS *f)
   5492  1.1  skrll {
   5493  1.1  skrll   /* Are there any relocation types for which we must generate a
   5494  1.1  skrll      reloc but we can adjust the values contained within it?   */
   5495  1.1  skrll   switch (f->fx_r_type)
   5496  1.1  skrll     {
   5497  1.1  skrll     case BFD_RELOC_ALPHA_GPDISP_HI16:
   5498  1.1  skrll     case BFD_RELOC_ALPHA_GPDISP_LO16:
   5499  1.1  skrll     case BFD_RELOC_ALPHA_GPDISP:
   5500  1.1  skrll       return 0;
   5501  1.1  skrll 
   5502  1.1  skrll     case BFD_RELOC_ALPHA_LITERAL:
   5503  1.1  skrll     case BFD_RELOC_ALPHA_ELF_LITERAL:
   5504  1.1  skrll     case BFD_RELOC_ALPHA_LITUSE:
   5505  1.1  skrll     case BFD_RELOC_ALPHA_LINKAGE:
   5506  1.1  skrll     case BFD_RELOC_ALPHA_CODEADDR:
   5507  1.1  skrll       return 1;
   5508  1.1  skrll 
   5509  1.1  skrll     case BFD_RELOC_VTABLE_ENTRY:
   5510  1.1  skrll     case BFD_RELOC_VTABLE_INHERIT:
   5511  1.1  skrll       return 0;
   5512  1.1  skrll 
   5513  1.1  skrll     case BFD_RELOC_GPREL16:
   5514  1.1  skrll     case BFD_RELOC_GPREL32:
   5515  1.1  skrll     case BFD_RELOC_ALPHA_GPREL_HI16:
   5516  1.1  skrll     case BFD_RELOC_ALPHA_GPREL_LO16:
   5517  1.1  skrll     case BFD_RELOC_23_PCREL_S2:
   5518  1.1  skrll     case BFD_RELOC_32:
   5519  1.1  skrll     case BFD_RELOC_64:
   5520  1.1  skrll     case BFD_RELOC_ALPHA_HINT:
   5521  1.1  skrll       return 1;
   5522  1.1  skrll 
   5523  1.1  skrll     case BFD_RELOC_ALPHA_TLSGD:
   5524  1.1  skrll     case BFD_RELOC_ALPHA_TLSLDM:
   5525  1.1  skrll     case BFD_RELOC_ALPHA_GOTDTPREL16:
   5526  1.1  skrll     case BFD_RELOC_ALPHA_DTPREL_HI16:
   5527  1.1  skrll     case BFD_RELOC_ALPHA_DTPREL_LO16:
   5528  1.1  skrll     case BFD_RELOC_ALPHA_DTPREL16:
   5529  1.1  skrll     case BFD_RELOC_ALPHA_GOTTPREL16:
   5530  1.1  skrll     case BFD_RELOC_ALPHA_TPREL_HI16:
   5531  1.1  skrll     case BFD_RELOC_ALPHA_TPREL_LO16:
   5532  1.1  skrll     case BFD_RELOC_ALPHA_TPREL16:
   5533  1.1  skrll       /* ??? No idea why we can't return a reference to .tbss+10, but
   5534  1.1  skrll 	 we're preventing this in the other assemblers.  Follow for now.  */
   5535  1.1  skrll       return 0;
   5536  1.1  skrll 
   5537  1.1  skrll #ifdef OBJ_ELF
   5538  1.1  skrll     case BFD_RELOC_ALPHA_BRSGP:
   5539  1.1  skrll       /* If we have a BRSGP reloc to a local symbol, adjust it to BRADDR and
   5540  1.1  skrll          let it get resolved at assembly time.  */
   5541  1.1  skrll       {
   5542  1.1  skrll 	symbolS *sym = f->fx_addsy;
   5543  1.1  skrll 	const char *name;
   5544  1.1  skrll 	int offset = 0;
   5545  1.1  skrll 
   5546  1.1  skrll 	if (generic_force_reloc (f))
   5547  1.1  skrll 	  return 0;
   5548  1.1  skrll 
   5549  1.1  skrll 	switch (S_GET_OTHER (sym) & STO_ALPHA_STD_GPLOAD)
   5550  1.1  skrll 	  {
   5551  1.1  skrll 	  case STO_ALPHA_NOPV:
   5552  1.1  skrll 	    break;
   5553  1.1  skrll 	  case STO_ALPHA_STD_GPLOAD:
   5554  1.1  skrll 	    offset = 8;
   5555  1.1  skrll 	    break;
   5556  1.1  skrll 	  default:
   5557  1.1  skrll 	    if (S_IS_LOCAL (sym))
   5558  1.1  skrll 	      name = "<local>";
   5559  1.1  skrll 	    else
   5560  1.1  skrll 	      name = S_GET_NAME (sym);
   5561  1.1  skrll 	    as_bad_where (f->fx_file, f->fx_line,
   5562  1.1  skrll 		_("!samegp reloc against symbol without .prologue: %s"),
   5563  1.1  skrll 		name);
   5564  1.1  skrll 	    break;
   5565  1.1  skrll 	  }
   5566  1.1  skrll 	f->fx_r_type = BFD_RELOC_23_PCREL_S2;
   5567  1.1  skrll 	f->fx_offset += offset;
   5568  1.1  skrll 	return 1;
   5569  1.1  skrll       }
   5570  1.1  skrll #endif
   5571  1.1  skrll 
   5572  1.1  skrll     default:
   5573  1.1  skrll       return 1;
   5574  1.1  skrll     }
   5575  1.1  skrll }
   5576  1.1  skrll 
   5577  1.1  skrll /* Generate the BFD reloc to be stuck in the object file from the
   5578  1.1  skrll    fixup used internally in the assembler.  */
   5579  1.1  skrll 
   5580  1.1  skrll arelent *
   5581  1.1  skrll tc_gen_reloc (asection *sec ATTRIBUTE_UNUSED,
   5582  1.1  skrll 	      fixS *fixp)
   5583  1.1  skrll {
   5584  1.1  skrll   arelent *reloc;
   5585  1.1  skrll 
   5586  1.1  skrll   reloc = xmalloc (sizeof (* reloc));
   5587  1.1  skrll   reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
   5588  1.1  skrll   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
   5589  1.1  skrll   reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
   5590  1.1  skrll 
   5591  1.1  skrll   /* Make sure none of our internal relocations make it this far.
   5592  1.1  skrll      They'd better have been fully resolved by this point.  */
   5593  1.1  skrll   assert ((int) fixp->fx_r_type > 0);
   5594  1.1  skrll 
   5595  1.1  skrll   reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
   5596  1.1  skrll   if (reloc->howto == NULL)
   5597  1.1  skrll     {
   5598  1.1  skrll       as_bad_where (fixp->fx_file, fixp->fx_line,
   5599  1.1  skrll 		    _("cannot represent `%s' relocation in object file"),
   5600  1.1  skrll 		    bfd_get_reloc_code_name (fixp->fx_r_type));
   5601  1.1  skrll       return NULL;
   5602  1.1  skrll     }
   5603  1.1  skrll 
   5604  1.1  skrll   if (!fixp->fx_pcrel != !reloc->howto->pc_relative)
   5605  1.1  skrll     as_fatal (_("internal error? cannot generate `%s' relocation"),
   5606  1.1  skrll 	      bfd_get_reloc_code_name (fixp->fx_r_type));
   5607  1.1  skrll 
   5608  1.1  skrll   assert (!fixp->fx_pcrel == !reloc->howto->pc_relative);
   5609  1.1  skrll 
   5610  1.1  skrll #ifdef OBJ_ECOFF
   5611  1.1  skrll   if (fixp->fx_r_type == BFD_RELOC_ALPHA_LITERAL)
   5612  1.1  skrll     /* Fake out bfd_perform_relocation. sigh.  */
   5613  1.1  skrll     reloc->addend = -alpha_gp_value;
   5614  1.1  skrll   else
   5615  1.1  skrll #endif
   5616  1.1  skrll     {
   5617  1.1  skrll       reloc->addend = fixp->fx_offset;
   5618  1.1  skrll #ifdef OBJ_ELF
   5619  1.1  skrll       /* Ohhh, this is ugly.  The problem is that if this is a local global
   5620  1.1  skrll          symbol, the relocation will entirely be performed at link time, not
   5621  1.1  skrll          at assembly time.  bfd_perform_reloc doesn't know about this sort
   5622  1.1  skrll          of thing, and as a result we need to fake it out here.  */
   5623  1.1  skrll       if ((S_IS_EXTERNAL (fixp->fx_addsy) || S_IS_WEAK (fixp->fx_addsy)
   5624  1.1  skrll 	   || (S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_MERGE)
   5625  1.1  skrll 	   || (S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_THREAD_LOCAL))
   5626  1.1  skrll 	  && !S_IS_COMMON (fixp->fx_addsy))
   5627  1.1  skrll 	reloc->addend -= symbol_get_bfdsym (fixp->fx_addsy)->value;
   5628  1.1  skrll #endif
   5629  1.1  skrll     }
   5630  1.1  skrll 
   5631  1.1  skrll   return reloc;
   5632  1.1  skrll }
   5633  1.1  skrll 
   5634  1.1  skrll /* Parse a register name off of the input_line and return a register
   5635  1.1  skrll    number.  Gets md_undefined_symbol above to do the register name
   5636  1.1  skrll    matching for us.
   5637  1.1  skrll 
   5638  1.1  skrll    Only called as a part of processing the ECOFF .frame directive.  */
   5639  1.1  skrll 
   5640  1.1  skrll int
   5641  1.1  skrll tc_get_register (int frame ATTRIBUTE_UNUSED)
   5642  1.1  skrll {
   5643  1.1  skrll   int framereg = AXP_REG_SP;
   5644  1.1  skrll 
   5645  1.1  skrll   SKIP_WHITESPACE ();
   5646  1.1  skrll   if (*input_line_pointer == '$')
   5647  1.1  skrll     {
   5648  1.1  skrll       char *s = input_line_pointer;
   5649  1.1  skrll       char c = get_symbol_end ();
   5650  1.1  skrll       symbolS *sym = md_undefined_symbol (s);
   5651  1.1  skrll 
   5652  1.1  skrll       *strchr (s, '\0') = c;
   5653  1.1  skrll       if (sym && (framereg = S_GET_VALUE (sym)) <= 31)
   5654  1.1  skrll 	goto found;
   5655  1.1  skrll     }
   5656  1.1  skrll   as_warn (_("frame reg expected, using $%d."), framereg);
   5657  1.1  skrll 
   5658  1.1  skrll found:
   5659  1.1  skrll   note_gpreg (framereg);
   5660  1.1  skrll   return framereg;
   5661  1.1  skrll }
   5662  1.1  skrll 
   5663  1.1  skrll /* This is called before the symbol table is processed.  In order to
   5664  1.1  skrll    work with gcc when using mips-tfile, we must keep all local labels.
   5665  1.1  skrll    However, in other cases, we want to discard them.  If we were
   5666  1.1  skrll    called with -g, but we didn't see any debugging information, it may
   5667  1.1  skrll    mean that gcc is smuggling debugging information through to
   5668  1.1  skrll    mips-tfile, in which case we must generate all local labels.  */
   5669  1.1  skrll 
   5670  1.1  skrll #ifdef OBJ_ECOFF
   5671  1.1  skrll 
   5672  1.1  skrll void
   5673             alpha_frob_file_before_adjust (void)
   5674             {
   5675               if (alpha_debug != 0
   5676                   && ! ecoff_debugging_seen)
   5677                 flag_keep_locals = 1;
   5678             }
   5679             
   5680             #endif /* OBJ_ECOFF */
   5681             
   5682             /* The Alpha has support for some VAX floating point types, as well as for
   5683                IEEE floating point.  We consider IEEE to be the primary floating point
   5684                format, and sneak in the VAX floating point support here.  */
   5685             #include "config/atof-vax.c"
   5686