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