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