Back to index

cell-binutils  2.17cvs20070401
tc-alpha.c
Go to the documentation of this file.
00001 /* tc-alpha.c - Processor-specific code for the DEC Alpha AXP CPU.
00002    Copyright 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
00003    2001, 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
00004    Contributed by Carnegie Mellon University, 1993.
00005    Written by Alessandro Forin, based on earlier gas-1.38 target CPU files.
00006    Modified by Ken Raeburn for gas-2.x and ECOFF support.
00007    Modified by Richard Henderson for ELF support.
00008    Modified by Klaus K"ampf for EVAX (OpenVMS/Alpha) support.
00009 
00010    This file is part of GAS, the GNU Assembler.
00011 
00012    GAS is free software; you can redistribute it and/or modify
00013    it under the terms of the GNU General Public License as published by
00014    the Free Software Foundation; either version 2, or (at your option)
00015    any later version.
00016 
00017    GAS is distributed in the hope that it will be useful,
00018    but WITHOUT ANY WARRANTY; without even the implied warranty of
00019    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020    GNU General Public License for more details.
00021 
00022    You should have received a copy of the GNU General Public License
00023    along with GAS; see the file COPYING.  If not, write to the Free
00024    Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
00025    02110-1301, USA.  */
00026 
00027 /* Mach Operating System
00028    Copyright (c) 1993 Carnegie Mellon University
00029    All Rights Reserved.
00030 
00031    Permission to use, copy, modify and distribute this software and its
00032    documentation is hereby granted, provided that both the copyright
00033    notice and this permission notice appear in all copies of the
00034    software, derivative works or modified versions, and any portions
00035    thereof, and that both notices appear in supporting documentation.
00036 
00037    CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
00038    CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
00039    ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
00040 
00041    Carnegie Mellon requests users of this software to return to
00042 
00043     Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
00044     School of Computer Science
00045     Carnegie Mellon University
00046     Pittsburgh PA 15213-3890
00047 
00048    any improvements or extensions that they make and grant Carnegie the
00049    rights to redistribute these changes.  */
00050 
00051 #include "as.h"
00052 #include "subsegs.h"
00053 #include "struc-symbol.h"
00054 #include "ecoff.h"
00055 
00056 #include "opcode/alpha.h"
00057 
00058 #ifdef OBJ_ELF
00059 #include "elf/alpha.h"
00060 #include "dwarf2dbg.h"
00061 #endif
00062 
00063 #include "dw2gencfi.h"
00064 #include "safe-ctype.h"
00065 
00066 /* Local types.  */
00067 
00068 #define TOKENIZE_ERROR             -1
00069 #define TOKENIZE_ERROR_REPORT      -2
00070 #define MAX_INSN_FIXUPS             2
00071 #define MAX_INSN_ARGS               5
00072 
00073 struct alpha_fixup
00074 {
00075   expressionS exp;
00076   bfd_reloc_code_real_type reloc;
00077 };
00078 
00079 struct alpha_insn
00080 {
00081   unsigned insn;
00082   int nfixups;
00083   struct alpha_fixup fixups[MAX_INSN_FIXUPS];
00084   long sequence;
00085 };
00086 
00087 enum alpha_macro_arg
00088   {
00089     MACRO_EOA = 1,
00090     MACRO_IR,
00091     MACRO_PIR,
00092     MACRO_OPIR,
00093     MACRO_CPIR,
00094     MACRO_FPR,
00095     MACRO_EXP,
00096   };
00097 
00098 struct alpha_macro
00099 {
00100   const char *name;
00101   void (*emit) (const expressionS *, int, const void *);
00102   const void * arg;
00103   enum alpha_macro_arg argsets[16];
00104 };
00105 
00106 /* Extra expression types.  */
00107 
00108 #define O_pregister  O_md1  /* O_register, in parentheses.  */
00109 #define O_cpregister O_md2  /* + a leading comma.  */
00110 
00111 /* The alpha_reloc_op table below depends on the ordering of these.  */
00112 #define O_literal    O_md3         /* !literal relocation.  */
00113 #define O_lituse_addr       O_md4         /* !lituse_addr relocation.  */
00114 #define O_lituse_base       O_md5         /* !lituse_base relocation.  */
00115 #define O_lituse_bytoff     O_md6         /* !lituse_bytoff relocation.  */
00116 #define O_lituse_jsr O_md7         /* !lituse_jsr relocation.  */
00117 #define O_lituse_tlsgd      O_md8         /* !lituse_tlsgd relocation.  */
00118 #define O_lituse_tlsldm     O_md9         /* !lituse_tlsldm relocation.  */
00119 #define O_lituse_jsrdirect O_md10  /* !lituse_jsrdirect relocation.  */
00120 #define O_gpdisp     O_md11        /* !gpdisp relocation.  */
00121 #define O_gprelhigh  O_md12        /* !gprelhigh relocation.  */
00122 #define O_gprellow   O_md13        /* !gprellow relocation.  */
00123 #define O_gprel             O_md14        /* !gprel relocation.  */
00124 #define O_samegp     O_md15        /* !samegp relocation.  */
00125 #define O_tlsgd             O_md16        /* !tlsgd relocation.  */
00126 #define O_tlsldm     O_md17        /* !tlsldm relocation.  */
00127 #define O_gotdtprel  O_md18        /* !gotdtprel relocation.  */
00128 #define O_dtprelhi   O_md19        /* !dtprelhi relocation.  */
00129 #define O_dtprello   O_md20        /* !dtprello relocation.  */
00130 #define O_dtprel     O_md21        /* !dtprel relocation.  */
00131 #define O_gottprel   O_md22        /* !gottprel relocation.  */
00132 #define O_tprelhi    O_md23        /* !tprelhi relocation.  */
00133 #define O_tprello    O_md24        /* !tprello relocation.  */
00134 #define O_tprel             O_md25        /* !tprel relocation.  */
00135 
00136 #define DUMMY_RELOC_LITUSE_ADDR           (BFD_RELOC_UNUSED + 1)
00137 #define DUMMY_RELOC_LITUSE_BASE           (BFD_RELOC_UNUSED + 2)
00138 #define DUMMY_RELOC_LITUSE_BYTOFF  (BFD_RELOC_UNUSED + 3)
00139 #define DUMMY_RELOC_LITUSE_JSR            (BFD_RELOC_UNUSED + 4)
00140 #define DUMMY_RELOC_LITUSE_TLSGD   (BFD_RELOC_UNUSED + 5)
00141 #define DUMMY_RELOC_LITUSE_TLSLDM  (BFD_RELOC_UNUSED + 6)
00142 #define DUMMY_RELOC_LITUSE_JSRDIRECT      (BFD_RELOC_UNUSED + 7)
00143 
00144 #define USER_RELOC_P(R) ((R) >= O_literal && (R) <= O_tprel)
00145 
00146 /* Macros for extracting the type and number of encoded register tokens.  */
00147 
00148 #define is_ir_num(x)        (((x) & 32) == 0)
00149 #define is_fpr_num(x)              (((x) & 32) != 0)
00150 #define regno(x)            ((x) & 31)
00151 
00152 /* Something odd inherited from the old assembler.  */
00153 
00154 #define note_gpreg(R)              (alpha_gprmask |= (1 << (R)))
00155 #define note_fpreg(R)              (alpha_fprmask |= (1 << (R)))
00156 
00157 /* Predicates for 16- and 32-bit ranges */
00158 /* XXX: The non-shift version appears to trigger a compiler bug when
00159    cross-assembling from x86 w/ gcc 2.7.2.  */
00160 
00161 #if 1
00162 #define range_signed_16(x) \
00163        (((offsetT) (x) >> 15) == 0 || ((offsetT) (x) >> 15) == -1)
00164 #define range_signed_32(x) \
00165        (((offsetT) (x) >> 31) == 0 || ((offsetT) (x) >> 31) == -1)
00166 #else
00167 #define range_signed_16(x)  ((offsetT) (x) >= -(offsetT) 0x8000 &&    \
00168                              (offsetT) (x) <=  (offsetT) 0x7FFF)
00169 #define range_signed_32(x)  ((offsetT) (x) >= -(offsetT) 0x80000000 && \
00170                              (offsetT) (x) <=  (offsetT) 0x7FFFFFFF)
00171 #endif
00172 
00173 /* Macros for sign extending from 16- and 32-bits.  */
00174 /* XXX: The cast macros will work on all the systems that I care about,
00175    but really a predicate should be found to use the non-cast forms.  */
00176 
00177 #if 1
00178 #define sign_extend_16(x)   ((short) (x))
00179 #define sign_extend_32(x)   ((int) (x))
00180 #else
00181 #define sign_extend_16(x)   ((offsetT) (((x) & 0xFFFF) ^ 0x8000) - 0x8000)
00182 #define sign_extend_32(x)   ((offsetT) (((x) & 0xFFFFFFFF) \
00183                                       ^ 0x80000000) - 0x80000000)
00184 #endif
00185 
00186 /* Macros to build tokens.  */
00187 
00188 #define set_tok_reg(t, r)   (memset (&(t), 0, sizeof (t)),            \
00189                              (t).X_op = O_register,                   \
00190                              (t).X_add_number = (r))
00191 #define set_tok_preg(t, r)  (memset (&(t), 0, sizeof (t)),            \
00192                              (t).X_op = O_pregister,           \
00193                              (t).X_add_number = (r))
00194 #define set_tok_cpreg(t, r) (memset (&(t), 0, sizeof (t)),            \
00195                              (t).X_op = O_cpregister,          \
00196                              (t).X_add_number = (r))
00197 #define set_tok_freg(t, r)  (memset (&(t), 0, sizeof (t)),            \
00198                              (t).X_op = O_register,                   \
00199                              (t).X_add_number = (r) + 32)
00200 #define set_tok_sym(t, s, a)       (memset (&(t), 0, sizeof (t)),            \
00201                              (t).X_op = O_symbol,                     \
00202                              (t).X_add_symbol = (s),           \
00203                              (t).X_add_number = (a))
00204 #define set_tok_const(t, n) (memset (&(t), 0, sizeof (t)),            \
00205                              (t).X_op = O_constant,                   \
00206                              (t).X_add_number = (n))
00207 
00208 /* Generic assembler global variables which must be defined by all
00209    targets.  */
00210 
00211 /* Characters which always start a comment.  */
00212 const char comment_chars[] = "#";
00213 
00214 /* Characters which start a comment at the beginning of a line.  */
00215 const char line_comment_chars[] = "#";
00216 
00217 /* Characters which may be used to separate multiple commands on a
00218    single line.  */
00219 const char line_separator_chars[] = ";";
00220 
00221 /* Characters which are used to indicate an exponent in a floating
00222    point number.  */
00223 const char EXP_CHARS[] = "eE";
00224 
00225 /* Characters which mean that a number is a floating point constant,
00226    as in 0d1.0.  */
00227 /* XXX: Do all of these really get used on the alpha??  */
00228 char FLT_CHARS[] = "rRsSfFdDxXpP";
00229 
00230 #ifdef OBJ_EVAX
00231 const char *md_shortopts = "Fm:g+1h:HG:";
00232 #else
00233 const char *md_shortopts = "Fm:gG:";
00234 #endif
00235 
00236 struct option md_longopts[] =
00237   {
00238 #define OPTION_32ADDR (OPTION_MD_BASE)
00239     { "32addr", no_argument, NULL, OPTION_32ADDR },
00240 #define OPTION_RELAX (OPTION_32ADDR + 1)
00241     { "relax", no_argument, NULL, OPTION_RELAX },
00242 #ifdef OBJ_ELF
00243 #define OPTION_MDEBUG (OPTION_RELAX + 1)
00244 #define OPTION_NO_MDEBUG (OPTION_MDEBUG + 1)
00245     { "mdebug", no_argument, NULL, OPTION_MDEBUG },
00246     { "no-mdebug", no_argument, NULL, OPTION_NO_MDEBUG },
00247 #endif
00248     { NULL, no_argument, NULL, 0 }
00249   };
00250 
00251 size_t md_longopts_size = sizeof (md_longopts);
00252 
00253 #ifdef OBJ_EVAX
00254 #define AXP_REG_R0     0
00255 #define AXP_REG_R16    16
00256 #define AXP_REG_R17    17
00257 #undef AXP_REG_T9
00258 #define AXP_REG_T9     22
00259 #undef AXP_REG_T10
00260 #define AXP_REG_T10    23
00261 #undef AXP_REG_T11
00262 #define AXP_REG_T11    24
00263 #undef AXP_REG_T12
00264 #define AXP_REG_T12    25
00265 #define AXP_REG_AI     25
00266 #undef AXP_REG_FP
00267 #define AXP_REG_FP     29
00268 
00269 #undef AXP_REG_GP
00270 #define AXP_REG_GP AXP_REG_PV
00271 #endif /* OBJ_EVAX  */
00272 
00273 /* The cpu for which we are generating code.  */
00274 static unsigned alpha_target = AXP_OPCODE_BASE;
00275 static const char *alpha_target_name = "<all>";
00276 
00277 /* The hash table of instruction opcodes.  */
00278 static struct hash_control *alpha_opcode_hash;
00279 
00280 /* The hash table of macro opcodes.  */
00281 static struct hash_control *alpha_macro_hash;
00282 
00283 #ifdef OBJ_ECOFF
00284 /* The $gp relocation symbol.  */
00285 static symbolS *alpha_gp_symbol;
00286 
00287 /* XXX: what is this, and why is it exported? */
00288 valueT alpha_gp_value;
00289 #endif
00290 
00291 /* The current $gp register.  */
00292 static int alpha_gp_register = AXP_REG_GP;
00293 
00294 /* A table of the register symbols.  */
00295 static symbolS *alpha_register_table[64];
00296 
00297 /* Constant sections, or sections of constants.  */
00298 #ifdef OBJ_ECOFF
00299 static segT alpha_lita_section;
00300 #endif
00301 #ifdef OBJ_EVAX
00302 static segT alpha_link_section;
00303 static segT alpha_ctors_section;
00304 static segT alpha_dtors_section;
00305 #endif
00306 static segT alpha_lit8_section;
00307 
00308 /* Symbols referring to said sections.  */
00309 #ifdef OBJ_ECOFF
00310 static symbolS *alpha_lita_symbol;
00311 #endif
00312 #ifdef OBJ_EVAX
00313 static symbolS *alpha_link_symbol;
00314 static symbolS *alpha_ctors_symbol;
00315 static symbolS *alpha_dtors_symbol;
00316 #endif
00317 static symbolS *alpha_lit8_symbol;
00318 
00319 /* Literal for .litX+0x8000 within .lita.  */
00320 #ifdef OBJ_ECOFF
00321 static offsetT alpha_lit8_literal;
00322 #endif
00323 
00324 /* Is the assembler not allowed to use $at?  */
00325 static int alpha_noat_on = 0;
00326 
00327 /* Are macros enabled?  */
00328 static int alpha_macros_on = 1;
00329 
00330 /* Are floats disabled?  */
00331 static int alpha_nofloats_on = 0;
00332 
00333 /* Are addresses 32 bit?  */
00334 static int alpha_addr32_on = 0;
00335 
00336 /* Symbol labelling the current insn.  When the Alpha gas sees
00337      foo:
00338        .quad 0
00339    and the section happens to not be on an eight byte boundary, it
00340    will align both the symbol and the .quad to an eight byte boundary.  */
00341 static symbolS *alpha_insn_label;
00342 
00343 /* Whether we should automatically align data generation pseudo-ops.
00344    .align 0 will turn this off.  */
00345 static int alpha_auto_align_on = 1;
00346 
00347 /* The known current alignment of the current section.  */
00348 static int alpha_current_align;
00349 
00350 /* These are exported to ECOFF code.  */
00351 unsigned long alpha_gprmask, alpha_fprmask;
00352 
00353 /* Whether the debugging option was seen.  */
00354 static int alpha_debug;
00355 
00356 #ifdef OBJ_ELF
00357 /* Whether we are emitting an mdebug section.  */
00358 int alpha_flag_mdebug = -1;
00359 #endif
00360 
00361 /* Don't fully resolve relocations, allowing code movement in the linker.  */
00362 static int alpha_flag_relax;
00363 
00364 /* What value to give to bfd_set_gp_size.  */
00365 static int g_switch_value = 8;
00366 
00367 #ifdef OBJ_EVAX
00368 /* Collect information about current procedure here.  */
00369 static struct
00370 {
00371   symbolS *symbol;   /* Proc pdesc symbol.  */
00372   int pdsckind;
00373   int framereg;             /* Register for frame pointer.  */
00374   int framesize;     /* Size of frame.  */
00375   int rsa_offset;
00376   int ra_save;
00377   int fp_save;
00378   long imask;
00379   long fmask;
00380   int type;
00381   int prologue;
00382 } alpha_evax_proc;
00383 
00384 static int alpha_flag_hash_long_names = 0;              /* -+ */
00385 static int alpha_flag_show_after_trunc = 0;             /* -H */
00386 
00387 /* If the -+ switch is given, then a hash is appended to any name that is
00388    longer than 64 characters, else longer symbol names are truncated.  */
00389 
00390 #endif
00391 
00392 #ifdef RELOC_OP_P
00393 /* A table to map the spelling of a relocation operand into an appropriate
00394    bfd_reloc_code_real_type type.  The table is assumed to be ordered such
00395    that op-O_literal indexes into it.  */
00396 
00397 #define ALPHA_RELOC_TABLE(op)                                         \
00398 (&alpha_reloc_op[ ((!USER_RELOC_P (op))                               \
00399                 ? (abort (), 0)                                \
00400                 : (int) (op) - (int) O_literal) ])
00401 
00402 #define DEF(NAME, RELOC, REQ, ALLOW) \
00403  { #NAME, sizeof(#NAME)-1, O_##NAME, RELOC, REQ, ALLOW}
00404 
00405 static const struct alpha_reloc_op_tag
00406 {
00407   const char *name;                       /* String to lookup.  */
00408   size_t length;                          /* Size of the string.  */
00409   operatorT op;                                  /* Which operator to use.  */
00410   bfd_reloc_code_real_type reloc;         /* Relocation before frob.  */
00411   unsigned int require_seq : 1;                  /* Require a sequence number.  */
00412   unsigned int allow_seq : 1;                    /* Allow a sequence number.  */
00413 }
00414 alpha_reloc_op[] =
00415 {
00416   DEF (literal, BFD_RELOC_ALPHA_ELF_LITERAL, 0, 1),
00417   DEF (lituse_addr, DUMMY_RELOC_LITUSE_ADDR, 1, 1),
00418   DEF (lituse_base, DUMMY_RELOC_LITUSE_BASE, 1, 1),
00419   DEF (lituse_bytoff, DUMMY_RELOC_LITUSE_BYTOFF, 1, 1),
00420   DEF (lituse_jsr, DUMMY_RELOC_LITUSE_JSR, 1, 1),
00421   DEF (lituse_tlsgd, DUMMY_RELOC_LITUSE_TLSGD, 1, 1),
00422   DEF (lituse_tlsldm, DUMMY_RELOC_LITUSE_TLSLDM, 1, 1),
00423   DEF (lituse_jsrdirect, DUMMY_RELOC_LITUSE_JSRDIRECT, 1, 1),
00424   DEF (gpdisp, BFD_RELOC_ALPHA_GPDISP, 1, 1),
00425   DEF (gprelhigh, BFD_RELOC_ALPHA_GPREL_HI16, 0, 0),
00426   DEF (gprellow, BFD_RELOC_ALPHA_GPREL_LO16, 0, 0),
00427   DEF (gprel, BFD_RELOC_GPREL16, 0, 0),
00428   DEF (samegp, BFD_RELOC_ALPHA_BRSGP, 0, 0),
00429   DEF (tlsgd, BFD_RELOC_ALPHA_TLSGD, 0, 1),
00430   DEF (tlsldm, BFD_RELOC_ALPHA_TLSLDM, 0, 1),
00431   DEF (gotdtprel, BFD_RELOC_ALPHA_GOTDTPREL16, 0, 0),
00432   DEF (dtprelhi, BFD_RELOC_ALPHA_DTPREL_HI16, 0, 0),
00433   DEF (dtprello, BFD_RELOC_ALPHA_DTPREL_LO16, 0, 0),
00434   DEF (dtprel, BFD_RELOC_ALPHA_DTPREL16, 0, 0),
00435   DEF (gottprel, BFD_RELOC_ALPHA_GOTTPREL16, 0, 0),
00436   DEF (tprelhi, BFD_RELOC_ALPHA_TPREL_HI16, 0, 0),
00437   DEF (tprello, BFD_RELOC_ALPHA_TPREL_LO16, 0, 0),
00438   DEF (tprel, BFD_RELOC_ALPHA_TPREL16, 0, 0),
00439 };
00440 
00441 #undef DEF
00442 
00443 static const int alpha_num_reloc_op
00444   = sizeof (alpha_reloc_op) / sizeof (*alpha_reloc_op);
00445 #endif /* RELOC_OP_P */
00446 
00447 /* Maximum # digits needed to hold the largest sequence #.  */
00448 #define ALPHA_RELOC_DIGITS 25
00449 
00450 /* Structure to hold explicit sequence information.  */
00451 struct alpha_reloc_tag
00452 {
00453   fixS *master;                    /* The literal reloc.  */
00454   fixS *slaves;                    /* Head of linked list of lituses.  */
00455   segT segment;                    /* Segment relocs are in or undefined_section.  */
00456   long sequence;            /* Sequence #.  */
00457   unsigned n_master;        /* # of literals.  */
00458   unsigned n_slaves;        /* # of lituses.  */
00459   unsigned saw_tlsgd : 1;   /* True if ...  */
00460   unsigned saw_tlsldm : 1;
00461   unsigned saw_lu_tlsgd : 1;
00462   unsigned saw_lu_tlsldm : 1;
00463   unsigned multi_section_p : 1;    /* True if more than one section was used.  */
00464   char string[1];           /* Printable form of sequence to hash with.  */
00465 };
00466 
00467 /* Hash table to link up literals with the appropriate lituse.  */
00468 static struct hash_control *alpha_literal_hash;
00469 
00470 /* Sequence numbers for internal use by macros.  */
00471 static long next_sequence_num = -1;
00472 
00473 /* A table of CPU names and opcode sets.  */
00474 
00475 static const struct cpu_type
00476 {
00477   const char *name;
00478   unsigned flags;
00479 }
00480 cpu_types[] =
00481 {
00482   /* Ad hoc convention: cpu number gets palcode, process code doesn't.
00483      This supports usage under DU 4.0b that does ".arch ev4", and
00484      usage in MILO that does -m21064.  Probably something more
00485      specific like -m21064-pal should be used, but oh well.  */
00486 
00487   { "21064", AXP_OPCODE_BASE|AXP_OPCODE_EV4 },
00488   { "21064a", AXP_OPCODE_BASE|AXP_OPCODE_EV4 },
00489   { "21066", AXP_OPCODE_BASE|AXP_OPCODE_EV4 },
00490   { "21068", AXP_OPCODE_BASE|AXP_OPCODE_EV4 },
00491   { "21164", AXP_OPCODE_BASE|AXP_OPCODE_EV5 },
00492   { "21164a", AXP_OPCODE_BASE|AXP_OPCODE_EV5|AXP_OPCODE_BWX },
00493   { "21164pc", (AXP_OPCODE_BASE|AXP_OPCODE_EV5|AXP_OPCODE_BWX
00494               |AXP_OPCODE_MAX) },
00495   { "21264", (AXP_OPCODE_BASE|AXP_OPCODE_EV6|AXP_OPCODE_BWX
00496              |AXP_OPCODE_MAX|AXP_OPCODE_CIX) },
00497   { "21264a", (AXP_OPCODE_BASE|AXP_OPCODE_EV6|AXP_OPCODE_BWX
00498              |AXP_OPCODE_MAX|AXP_OPCODE_CIX) },
00499   { "21264b", (AXP_OPCODE_BASE|AXP_OPCODE_EV6|AXP_OPCODE_BWX
00500              |AXP_OPCODE_MAX|AXP_OPCODE_CIX) },
00501 
00502   { "ev4", AXP_OPCODE_BASE },
00503   { "ev45", AXP_OPCODE_BASE },
00504   { "lca45", AXP_OPCODE_BASE },
00505   { "ev5", AXP_OPCODE_BASE },
00506   { "ev56", AXP_OPCODE_BASE|AXP_OPCODE_BWX },
00507   { "pca56", AXP_OPCODE_BASE|AXP_OPCODE_BWX|AXP_OPCODE_MAX },
00508   { "ev6", AXP_OPCODE_BASE|AXP_OPCODE_BWX|AXP_OPCODE_MAX|AXP_OPCODE_CIX },
00509   { "ev67", AXP_OPCODE_BASE|AXP_OPCODE_BWX|AXP_OPCODE_MAX|AXP_OPCODE_CIX },
00510   { "ev68", AXP_OPCODE_BASE|AXP_OPCODE_BWX|AXP_OPCODE_MAX|AXP_OPCODE_CIX },
00511 
00512   { "all", AXP_OPCODE_BASE },
00513   { 0, 0 }
00514 };
00515 
00516 /* Some instruction sets indexed by lg(size).  */
00517 static const char * const sextX_op[] = { "sextb", "sextw", "sextl", NULL };
00518 static const char * const insXl_op[] = { "insbl", "inswl", "insll", "insql" };
00519 static const char * const insXh_op[] = { NULL,    "inswh", "inslh", "insqh" };
00520 static const char * const extXl_op[] = { "extbl", "extwl", "extll", "extql" };
00521 static const char * const extXh_op[] = { NULL,    "extwh", "extlh", "extqh" };
00522 static const char * const mskXl_op[] = { "mskbl", "mskwl", "mskll", "mskql" };
00523 static const char * const mskXh_op[] = { NULL,    "mskwh", "msklh", "mskqh" };
00524 static const char * const stX_op[] = { "stb", "stw", "stl", "stq" };
00525 static const char * const ldXu_op[] = { "ldbu", "ldwu", NULL, NULL };
00526 
00527 static void assemble_insn (const struct alpha_opcode *, const expressionS *, int, struct alpha_insn *, bfd_reloc_code_real_type);
00528 static void emit_insn (struct alpha_insn *);
00529 static void assemble_tokens (const char *, const expressionS *, int, int);
00530 
00531 static struct alpha_reloc_tag *
00532 get_alpha_reloc_tag (long sequence)
00533 {
00534   char buffer[ALPHA_RELOC_DIGITS];
00535   struct alpha_reloc_tag *info;
00536 
00537   sprintf (buffer, "!%ld", sequence);
00538 
00539   info = (struct alpha_reloc_tag *) hash_find (alpha_literal_hash, buffer);
00540   if (! info)
00541     {
00542       size_t len = strlen (buffer);
00543       const char *errmsg;
00544 
00545       info = xcalloc (sizeof (struct alpha_reloc_tag) + len, 1);
00546 
00547       info->segment = now_seg;
00548       info->sequence = sequence;
00549       strcpy (info->string, buffer);
00550       errmsg = hash_insert (alpha_literal_hash, info->string, (void *) info);
00551       if (errmsg)
00552        as_fatal (errmsg);
00553     }
00554 
00555   return info;
00556 }
00557 
00558 static void
00559 alpha_adjust_relocs (bfd *abfd ATTRIBUTE_UNUSED,
00560                    asection *sec,
00561                    void * ptr ATTRIBUTE_UNUSED)
00562 {
00563   segment_info_type *seginfo = seg_info (sec);
00564   fixS **prevP;
00565   fixS *fixp;
00566   fixS *next;
00567   fixS *slave;
00568 
00569   /* If seginfo is NULL, we did not create this section; don't do
00570      anything with it.  By using a pointer to a pointer, we can update
00571      the links in place.  */
00572   if (seginfo == NULL)
00573     return;
00574 
00575   /* If there are no relocations, skip the section.  */
00576   if (! seginfo->fix_root)
00577     return;
00578 
00579   /* First rebuild the fixup chain without the explicit lituse and
00580      gpdisp_lo16 relocs.  */
00581   prevP = &seginfo->fix_root;
00582   for (fixp = seginfo->fix_root; fixp; fixp = next)
00583     {
00584       next = fixp->fx_next;
00585       fixp->fx_next = (fixS *) 0;
00586 
00587       switch (fixp->fx_r_type)
00588        {
00589        case BFD_RELOC_ALPHA_LITUSE:
00590          if (fixp->tc_fix_data.info->n_master == 0)
00591            as_bad_where (fixp->fx_file, fixp->fx_line,
00592                        _("No !literal!%ld was found"),
00593                        fixp->tc_fix_data.info->sequence);
00594 #ifdef RELOC_OP_P
00595          if (fixp->fx_offset == LITUSE_ALPHA_TLSGD)
00596            {
00597              if (! fixp->tc_fix_data.info->saw_tlsgd)
00598               as_bad_where (fixp->fx_file, fixp->fx_line,
00599                            _("No !tlsgd!%ld was found"),
00600                            fixp->tc_fix_data.info->sequence);
00601            }
00602          else if (fixp->fx_offset == LITUSE_ALPHA_TLSLDM)
00603            {
00604              if (! fixp->tc_fix_data.info->saw_tlsldm)
00605               as_bad_where (fixp->fx_file, fixp->fx_line,
00606                            _("No !tlsldm!%ld was found"),
00607                            fixp->tc_fix_data.info->sequence);
00608            }
00609 #endif
00610          break;
00611 
00612        case BFD_RELOC_ALPHA_GPDISP_LO16:
00613          if (fixp->tc_fix_data.info->n_master == 0)
00614            as_bad_where (fixp->fx_file, fixp->fx_line,
00615                        _("No ldah !gpdisp!%ld was found"),
00616                        fixp->tc_fix_data.info->sequence);
00617          break;
00618 
00619        case BFD_RELOC_ALPHA_ELF_LITERAL:
00620          if (fixp->tc_fix_data.info
00621              && (fixp->tc_fix_data.info->saw_tlsgd
00622                  || fixp->tc_fix_data.info->saw_tlsldm))
00623            break;
00624          /* FALLTHRU */
00625 
00626        default:
00627          *prevP = fixp;
00628          prevP = &fixp->fx_next;
00629          break;
00630        }
00631     }
00632 
00633   /* Go back and re-chain dependent relocations.  They are currently
00634      linked through the next_reloc field in reverse order, so as we
00635      go through the next_reloc chain, we effectively reverse the chain
00636      once again.
00637 
00638      Except if there is more than one !literal for a given sequence
00639      number.  In that case, the programmer and/or compiler is not sure
00640      how control flows from literal to lituse, and we can't be sure to
00641      get the relaxation correct.
00642 
00643      ??? Well, actually we could, if there are enough lituses such that
00644      we can make each literal have at least one of each lituse type
00645      present.  Not implemented.
00646 
00647      Also suppress the optimization if the !literals/!lituses are spread
00648      in different segments.  This can happen with "intersting" uses of
00649      inline assembly; examples are present in the Linux kernel semaphores.  */
00650 
00651   for (fixp = seginfo->fix_root; fixp; fixp = next)
00652     {
00653       next = fixp->fx_next;
00654       switch (fixp->fx_r_type)
00655        {
00656        case BFD_RELOC_ALPHA_TLSGD:
00657        case BFD_RELOC_ALPHA_TLSLDM:
00658          if (!fixp->tc_fix_data.info)
00659            break;
00660          if (fixp->tc_fix_data.info->n_master == 0)
00661            break;
00662          else if (fixp->tc_fix_data.info->n_master > 1)
00663            {
00664              as_bad_where (fixp->fx_file, fixp->fx_line,
00665                          _("too many !literal!%ld for %s"),
00666                          fixp->tc_fix_data.info->sequence,
00667                          (fixp->fx_r_type == BFD_RELOC_ALPHA_TLSGD
00668                           ? "!tlsgd" : "!tlsldm"));
00669              break;
00670            }
00671 
00672          fixp->tc_fix_data.info->master->fx_next = fixp->fx_next;
00673          fixp->fx_next = fixp->tc_fix_data.info->master;
00674          fixp = fixp->fx_next;
00675          /* Fall through.  */
00676 
00677        case BFD_RELOC_ALPHA_ELF_LITERAL:
00678          if (fixp->tc_fix_data.info
00679              && fixp->tc_fix_data.info->n_master == 1
00680              && ! fixp->tc_fix_data.info->multi_section_p)
00681            {
00682              for (slave = fixp->tc_fix_data.info->slaves;
00683                  slave != (fixS *) 0;
00684                  slave = slave->tc_fix_data.next_reloc)
00685               {
00686                 slave->fx_next = fixp->fx_next;
00687                 fixp->fx_next = slave;
00688               }
00689            }
00690          break;
00691 
00692        case BFD_RELOC_ALPHA_GPDISP_HI16:
00693          if (fixp->tc_fix_data.info->n_slaves == 0)
00694            as_bad_where (fixp->fx_file, fixp->fx_line,
00695                        _("No lda !gpdisp!%ld was found"),
00696                        fixp->tc_fix_data.info->sequence);
00697          else
00698            {
00699              slave = fixp->tc_fix_data.info->slaves;
00700              slave->fx_next = next;
00701              fixp->fx_next = slave;
00702            }
00703          break;
00704 
00705        default:
00706          break;
00707        }
00708     }
00709 }
00710 
00711 /* Before the relocations are written, reorder them, so that user
00712    supplied !lituse relocations follow the appropriate !literal
00713    relocations, and similarly for !gpdisp relocations.  */
00714 
00715 void
00716 alpha_before_fix (void)
00717 {
00718   if (alpha_literal_hash)
00719     bfd_map_over_sections (stdoutput, alpha_adjust_relocs, NULL);
00720 }
00721 
00722 #ifdef DEBUG_ALPHA
00723 static void
00724 debug_exp (expressionS tok[], int ntok)
00725 {
00726   int i;
00727 
00728   fprintf (stderr, "debug_exp: %d tokens", ntok);
00729   for (i = 0; i < ntok; i++)
00730     {
00731       expressionS *t = &tok[i];
00732       const char *name;
00733 
00734       switch (t->X_op)
00735        {
00736        default:                    name = "unknown";           break;
00737        case O_illegal:                    name = "O_illegal";         break;
00738        case O_absent:                     name = "O_absent";          break;
00739        case O_constant:            name = "O_constant";        break;
00740        case O_symbol:                     name = "O_symbol";          break;
00741        case O_symbol_rva:          name = "O_symbol_rva";             break;
00742        case O_register:            name = "O_register";        break;
00743        case O_big:                 name = "O_big";                    break;
00744        case O_uminus:                     name = "O_uminus";          break;
00745        case O_bit_not:                    name = "O_bit_not";         break;
00746        case O_logical_not:         name = "O_logical_not";            break;
00747        case O_multiply:            name = "O_multiply";        break;
00748        case O_divide:                     name = "O_divide";          break;
00749        case O_modulus:                    name = "O_modulus";         break;
00750        case O_left_shift:          name = "O_left_shift";             break;
00751        case O_right_shift:         name = "O_right_shift";            break;
00752        case O_bit_inclusive_or:    name = "O_bit_inclusive_or";       break;
00753        case O_bit_or_not:          name = "O_bit_or_not";             break;
00754        case O_bit_exclusive_or:    name = "O_bit_exclusive_or";       break;
00755        case O_bit_and:                    name = "O_bit_and";         break;
00756        case O_add:                 name = "O_add";                    break;
00757        case O_subtract:            name = "O_subtract";        break;
00758        case O_eq:                  name = "O_eq";                     break;
00759        case O_ne:                  name = "O_ne";                     break;
00760        case O_lt:                  name = "O_lt";                     break;
00761        case O_le:                  name = "O_le";                     break;
00762        case O_ge:                  name = "O_ge";                     break;
00763        case O_gt:                  name = "O_gt";                     break;
00764        case O_logical_and:         name = "O_logical_and";            break;
00765        case O_logical_or:          name = "O_logical_or";             break;
00766        case O_index:               name = "O_index";           break;
00767        case O_pregister:           name = "O_pregister";              break;
00768        case O_cpregister:          name = "O_cpregister";             break;
00769        case O_literal:                    name = "O_literal";         break;
00770        case O_lituse_addr:         name = "O_lituse_addr";            break;
00771        case O_lituse_base:         name = "O_lituse_base";            break;
00772        case O_lituse_bytoff:              name = "O_lituse_bytoff";   break;
00773        case O_lituse_jsr:          name = "O_lituse_jsr";             break;
00774        case O_lituse_tlsgd:        name = "O_lituse_tlsgd";    break;
00775        case O_lituse_tlsldm:              name = "O_lituse_tlsldm";   break;
00776        case O_lituse_jsrdirect:    name = "O_lituse_jsrdirect";       break;
00777        case O_gpdisp:                     name = "O_gpdisp";          break;
00778        case O_gprelhigh:           name = "O_gprelhigh";              break;
00779        case O_gprellow:            name = "O_gprellow";        break;
00780        case O_gprel:               name = "O_gprel";           break;
00781        case O_samegp:                     name = "O_samegp";          break;
00782        case O_tlsgd:               name = "O_tlsgd";           break;
00783        case O_tlsldm:                     name = "O_tlsldm";          break;
00784        case O_gotdtprel:           name = "O_gotdtprel";              break;
00785        case O_dtprelhi:            name = "O_dtprelhi";        break;
00786        case O_dtprello:            name = "O_dtprello";        break;
00787        case O_dtprel:                     name = "O_dtprel";          break;
00788        case O_gottprel:            name = "O_gottprel";        break;
00789        case O_tprelhi:                    name = "O_tprelhi";         break;
00790        case O_tprello:                    name = "O_tprello";         break;
00791        case O_tprel:               name = "O_tprel";           break;
00792        }
00793 
00794       fprintf (stderr, ", %s(%s, %s, %d)", name,
00795               (t->X_add_symbol) ? S_GET_NAME (t->X_add_symbol) : "--",
00796               (t->X_op_symbol) ? S_GET_NAME (t->X_op_symbol) : "--",
00797               (int) t->X_add_number);
00798     }
00799   fprintf (stderr, "\n");
00800   fflush (stderr);
00801 }
00802 #endif
00803 
00804 /* Parse the arguments to an opcode.  */
00805 
00806 static int
00807 tokenize_arguments (char *str,
00808                   expressionS tok[],
00809                   int ntok)
00810 {
00811   expressionS *end_tok = tok + ntok;
00812   char *old_input_line_pointer;
00813   int saw_comma = 0, saw_arg = 0;
00814 #ifdef DEBUG_ALPHA
00815   expressionS *orig_tok = tok;
00816 #endif
00817 #ifdef RELOC_OP_P
00818   char *p;
00819   const struct alpha_reloc_op_tag *r;
00820   int c, i;
00821   size_t len;
00822   int reloc_found_p = 0;
00823 #endif
00824 
00825   memset (tok, 0, sizeof (*tok) * ntok);
00826 
00827   /* Save and restore input_line_pointer around this function.  */
00828   old_input_line_pointer = input_line_pointer;
00829   input_line_pointer = str;
00830 
00831 #ifdef RELOC_OP_P
00832   /* ??? Wrest control of ! away from the regular expression parser.  */
00833   is_end_of_line[(unsigned char) '!'] = 1;
00834 #endif
00835 
00836   while (tok < end_tok && *input_line_pointer)
00837     {
00838       SKIP_WHITESPACE ();
00839       switch (*input_line_pointer)
00840        {
00841        case '\0':
00842          goto fini;
00843 
00844 #ifdef RELOC_OP_P
00845        case '!':
00846          /* A relocation operand can be placed after the normal operand on an
00847             assembly language statement, and has the following form:
00848               !relocation_type!sequence_number.  */
00849          if (reloc_found_p)
00850            {
00851              /* Only support one relocation op per insn.  */
00852              as_bad (_("More than one relocation op per insn"));
00853              goto err_report;
00854            }
00855 
00856          if (!saw_arg)
00857            goto err;
00858 
00859          ++input_line_pointer;
00860          SKIP_WHITESPACE ();
00861          p = input_line_pointer;
00862          c = get_symbol_end ();
00863 
00864          /* Parse !relocation_type.  */
00865          len = input_line_pointer - p;
00866          if (len == 0)
00867            {
00868              as_bad (_("No relocation operand"));
00869              goto err_report;
00870            }
00871 
00872          r = &alpha_reloc_op[0];
00873          for (i = alpha_num_reloc_op - 1; i >= 0; i--, r++)
00874            if (len == r->length && memcmp (p, r->name, len) == 0)
00875              break;
00876          if (i < 0)
00877            {
00878              as_bad (_("Unknown relocation operand: !%s"), p);
00879              goto err_report;
00880            }
00881 
00882          *input_line_pointer = c;
00883          SKIP_WHITESPACE ();
00884          if (*input_line_pointer != '!')
00885            {
00886              if (r->require_seq)
00887               {
00888                 as_bad (_("no sequence number after !%s"), p);
00889                 goto err_report;
00890               }
00891 
00892              tok->X_add_number = 0;
00893            }
00894          else
00895            {
00896              if (! r->allow_seq)
00897               {
00898                 as_bad (_("!%s does not use a sequence number"), p);
00899                 goto err_report;
00900               }
00901 
00902              input_line_pointer++;
00903 
00904              /* Parse !sequence_number.  */
00905              expression (tok);
00906              if (tok->X_op != O_constant || tok->X_add_number <= 0)
00907               {
00908                 as_bad (_("Bad sequence number: !%s!%s"),
00909                        r->name, input_line_pointer);
00910                 goto err_report;
00911               }
00912            }
00913 
00914          tok->X_op = r->op;
00915          reloc_found_p = 1;
00916          ++tok;
00917          break;
00918 #endif /* RELOC_OP_P */
00919 
00920        case ',':
00921          ++input_line_pointer;
00922          if (saw_comma || !saw_arg)
00923            goto err;
00924          saw_comma = 1;
00925          break;
00926 
00927        case '(':
00928          {
00929            char *hold = input_line_pointer++;
00930 
00931            /* First try for parenthesized register ...  */
00932            expression (tok);
00933            if (*input_line_pointer == ')' && tok->X_op == O_register)
00934              {
00935               tok->X_op = (saw_comma ? O_cpregister : O_pregister);
00936               saw_comma = 0;
00937               saw_arg = 1;
00938               ++input_line_pointer;
00939               ++tok;
00940               break;
00941              }
00942 
00943            /* ... then fall through to plain expression.  */
00944            input_line_pointer = hold;
00945          }
00946 
00947        default:
00948          if (saw_arg && !saw_comma)
00949            goto err;
00950 
00951          expression (tok);
00952          if (tok->X_op == O_illegal || tok->X_op == O_absent)
00953            goto err;
00954 
00955          saw_comma = 0;
00956          saw_arg = 1;
00957          ++tok;
00958          break;
00959        }
00960     }
00961 
00962 fini:
00963   if (saw_comma)
00964     goto err;
00965   input_line_pointer = old_input_line_pointer;
00966 
00967 #ifdef DEBUG_ALPHA
00968   debug_exp (orig_tok, ntok - (end_tok - tok));
00969 #endif
00970 #ifdef RELOC_OP_P
00971   is_end_of_line[(unsigned char) '!'] = 0;
00972 #endif
00973 
00974   return ntok - (end_tok - tok);
00975 
00976 err:
00977 #ifdef RELOC_OP_P
00978   is_end_of_line[(unsigned char) '!'] = 0;
00979 #endif
00980   input_line_pointer = old_input_line_pointer;
00981   return TOKENIZE_ERROR;
00982 
00983 #ifdef RELOC_OP_P
00984 err_report:
00985   is_end_of_line[(unsigned char) '!'] = 0;
00986 #endif
00987   input_line_pointer = old_input_line_pointer;
00988   return TOKENIZE_ERROR_REPORT;
00989 }
00990 
00991 /* Search forward through all variants of an opcode looking for a
00992    syntax match.  */
00993 
00994 static const struct alpha_opcode *
00995 find_opcode_match (const struct alpha_opcode *first_opcode,
00996                  const expressionS *tok,
00997                  int *pntok,
00998                  int *pcpumatch)
00999 {
01000   const struct alpha_opcode *opcode = first_opcode;
01001   int ntok = *pntok;
01002   int got_cpu_match = 0;
01003 
01004   do
01005     {
01006       const unsigned char *opidx;
01007       int tokidx = 0;
01008 
01009       /* Don't match opcodes that don't exist on this architecture.  */
01010       if (!(opcode->flags & alpha_target))
01011        goto match_failed;
01012 
01013       got_cpu_match = 1;
01014 
01015       for (opidx = opcode->operands; *opidx; ++opidx)
01016        {
01017          const struct alpha_operand *operand = &alpha_operands[*opidx];
01018 
01019          /* Only take input from real operands.  */
01020          if (operand->flags & AXP_OPERAND_FAKE)
01021            continue;
01022 
01023          /* When we expect input, make sure we have it.  */
01024          if (tokidx >= ntok)
01025            {
01026              if ((operand->flags & AXP_OPERAND_OPTIONAL_MASK) == 0)
01027               goto match_failed;
01028              continue;
01029            }
01030 
01031          /* Match operand type with expression type.  */
01032          switch (operand->flags & AXP_OPERAND_TYPECHECK_MASK)
01033            {
01034            case AXP_OPERAND_IR:
01035              if (tok[tokidx].X_op != O_register
01036                 || !is_ir_num (tok[tokidx].X_add_number))
01037               goto match_failed;
01038              break;
01039            case AXP_OPERAND_FPR:
01040              if (tok[tokidx].X_op != O_register
01041                 || !is_fpr_num (tok[tokidx].X_add_number))
01042               goto match_failed;
01043              break;
01044            case AXP_OPERAND_IR | AXP_OPERAND_PARENS:
01045              if (tok[tokidx].X_op != O_pregister
01046                 || !is_ir_num (tok[tokidx].X_add_number))
01047               goto match_failed;
01048              break;
01049            case AXP_OPERAND_IR | AXP_OPERAND_PARENS | AXP_OPERAND_COMMA:
01050              if (tok[tokidx].X_op != O_cpregister
01051                 || !is_ir_num (tok[tokidx].X_add_number))
01052               goto match_failed;
01053              break;
01054 
01055            case AXP_OPERAND_RELATIVE:
01056            case AXP_OPERAND_SIGNED:
01057            case AXP_OPERAND_UNSIGNED:
01058              switch (tok[tokidx].X_op)
01059               {
01060               case O_illegal:
01061               case O_absent:
01062               case O_register:
01063               case O_pregister:
01064               case O_cpregister:
01065                 goto match_failed;
01066 
01067               default:
01068                 break;
01069               }
01070              break;
01071 
01072            default:
01073              /* Everything else should have been fake.  */
01074              abort ();
01075            }
01076          ++tokidx;
01077        }
01078 
01079       /* Possible match -- did we use all of our input?  */
01080       if (tokidx == ntok)
01081        {
01082          *pntok = ntok;
01083          return opcode;
01084        }
01085 
01086     match_failed:;
01087     }
01088   while (++opcode - alpha_opcodes < (int) alpha_num_opcodes
01089         && !strcmp (opcode->name, first_opcode->name));
01090 
01091   if (*pcpumatch)
01092     *pcpumatch = got_cpu_match;
01093 
01094   return NULL;
01095 }
01096 
01097 /* Given an opcode name and a pre-tokenized set of arguments, assemble
01098    the insn, but do not emit it.
01099 
01100    Note that this implies no macros allowed, since we can't store more
01101    than one insn in an insn structure.  */
01102 
01103 static void
01104 assemble_tokens_to_insn (const char *opname,
01105                       const expressionS *tok,
01106                       int ntok,
01107                       struct alpha_insn *insn)
01108 {
01109   const struct alpha_opcode *opcode;
01110 
01111   /* Search opcodes.  */
01112   opcode = (const struct alpha_opcode *) hash_find (alpha_opcode_hash, opname);
01113   if (opcode)
01114     {
01115       int cpumatch;
01116       opcode = find_opcode_match (opcode, tok, &ntok, &cpumatch);
01117       if (opcode)
01118        {
01119          assemble_insn (opcode, tok, ntok, insn, BFD_RELOC_UNUSED);
01120          return;
01121        }
01122       else if (cpumatch)
01123        as_bad (_("inappropriate arguments for opcode `%s'"), opname);
01124       else
01125        as_bad (_("opcode `%s' not supported for target %s"), opname,
01126               alpha_target_name);
01127     }
01128   else
01129     as_bad (_("unknown opcode `%s'"), opname);
01130 }
01131 
01132 /* Build a BFD section with its flags set appropriately for the .lita,
01133    .lit8, or .lit4 sections.  */
01134 
01135 static void
01136 create_literal_section (const char *name,
01137                      segT *secp,
01138                      symbolS **symp)
01139 {
01140   segT current_section = now_seg;
01141   int current_subsec = now_subseg;
01142   segT new_sec;
01143 
01144   *secp = new_sec = subseg_new (name, 0);
01145   subseg_set (current_section, current_subsec);
01146   bfd_set_section_alignment (stdoutput, new_sec, 4);
01147   bfd_set_section_flags (stdoutput, new_sec,
01148                       SEC_RELOC | SEC_ALLOC | SEC_LOAD | SEC_READONLY
01149                       | SEC_DATA);
01150 
01151   S_CLEAR_EXTERNAL (*symp = section_symbol (new_sec));
01152 }
01153 
01154 /* Load a (partial) expression into a target register.
01155 
01156    If poffset is not null, after the call it will either contain
01157    O_constant 0, or a 16-bit offset appropriate for any MEM format
01158    instruction.  In addition, pbasereg will be modified to point to
01159    the base register to use in that MEM format instruction.
01160 
01161    In any case, *pbasereg should contain a base register to add to the
01162    expression.  This will normally be either AXP_REG_ZERO or
01163    alpha_gp_register.  Symbol addresses will always be loaded via $gp,
01164    so "foo($0)" is interpreted as adding the address of foo to $0;
01165    i.e. "ldq $targ, LIT($gp); addq $targ, $0, $targ".  Odd, perhaps,
01166    but this is what OSF/1 does.
01167 
01168    If explicit relocations of the form !literal!<number> are allowed,
01169    and used, then explicit_reloc with be an expression pointer.
01170 
01171    Finally, the return value is nonzero if the calling macro may emit
01172    a LITUSE reloc if otherwise appropriate; the return value is the
01173    sequence number to use.  */
01174 
01175 static long
01176 load_expression (int targreg,
01177                const expressionS *exp,
01178                int *pbasereg,
01179                expressionS *poffset)
01180 {
01181   long emit_lituse = 0;
01182   offsetT addend = exp->X_add_number;
01183   int basereg = *pbasereg;
01184   struct alpha_insn insn;
01185   expressionS newtok[3];
01186 
01187   switch (exp->X_op)
01188     {
01189     case O_symbol:
01190       {
01191 #ifdef OBJ_ECOFF
01192        offsetT lit;
01193 
01194        /* Attempt to reduce .lit load by splitting the offset from
01195           its symbol when possible, but don't create a situation in
01196           which we'd fail.  */
01197        if (!range_signed_32 (addend) &&
01198            (alpha_noat_on || targreg == AXP_REG_AT))
01199          {
01200            lit = add_to_literal_pool (exp->X_add_symbol, addend,
01201                                    alpha_lita_section, 8);
01202            addend = 0;
01203          }
01204        else
01205          lit = add_to_literal_pool (exp->X_add_symbol, 0,
01206                                  alpha_lita_section, 8);
01207 
01208        if (lit >= 0x8000)
01209          as_fatal (_("overflow in literal (.lita) table"));
01210 
01211        /* Emit "ldq r, lit(gp)".  */
01212 
01213        if (basereg != alpha_gp_register && targreg == basereg)
01214          {
01215            if (alpha_noat_on)
01216              as_bad (_("macro requires $at register while noat in effect"));
01217            if (targreg == AXP_REG_AT)
01218              as_bad (_("macro requires $at while $at in use"));
01219 
01220            set_tok_reg (newtok[0], AXP_REG_AT);
01221          }
01222        else
01223          set_tok_reg (newtok[0], targreg);
01224 
01225        set_tok_sym (newtok[1], alpha_lita_symbol, lit);
01226        set_tok_preg (newtok[2], alpha_gp_register);
01227 
01228        assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
01229 
01230        assert (insn.nfixups == 1);
01231        insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITERAL;
01232        insn.sequence = emit_lituse = next_sequence_num--;
01233 #endif /* OBJ_ECOFF */
01234 #ifdef OBJ_ELF
01235        /* Emit "ldq r, gotoff(gp)".  */
01236 
01237        if (basereg != alpha_gp_register && targreg == basereg)
01238          {
01239            if (alpha_noat_on)
01240              as_bad (_("macro requires $at register while noat in effect"));
01241            if (targreg == AXP_REG_AT)
01242              as_bad (_("macro requires $at while $at in use"));
01243 
01244            set_tok_reg (newtok[0], AXP_REG_AT);
01245          }
01246        else
01247          set_tok_reg (newtok[0], targreg);
01248 
01249        /* XXX: Disable this .got minimizing optimization so that we can get
01250           better instruction offset knowledge in the compiler.  This happens
01251           very infrequently anyway.  */
01252        if (1
01253            || (!range_signed_32 (addend)
01254               && (alpha_noat_on || targreg == AXP_REG_AT)))
01255          {
01256            newtok[1] = *exp;
01257            addend = 0;
01258          }
01259        else
01260          set_tok_sym (newtok[1], exp->X_add_symbol, 0);
01261 
01262        set_tok_preg (newtok[2], alpha_gp_register);
01263 
01264        assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
01265 
01266        assert (insn.nfixups == 1);
01267        insn.fixups[0].reloc = BFD_RELOC_ALPHA_ELF_LITERAL;
01268        insn.sequence = emit_lituse = next_sequence_num--;
01269 #endif /* OBJ_ELF */
01270 #ifdef OBJ_EVAX
01271        offsetT link;
01272 
01273        /* Find symbol or symbol pointer in link section.  */
01274 
01275        if (exp->X_add_symbol == alpha_evax_proc.symbol)
01276          {
01277            if (range_signed_16 (addend))
01278              {
01279               set_tok_reg (newtok[0], targreg);
01280               set_tok_const (newtok[1], addend);
01281               set_tok_preg (newtok[2], basereg);
01282               assemble_tokens_to_insn ("lda", newtok, 3, &insn);
01283               addend = 0;
01284              }
01285            else
01286              {
01287               set_tok_reg (newtok[0], targreg);
01288               set_tok_const (newtok[1], 0);
01289               set_tok_preg (newtok[2], basereg);
01290               assemble_tokens_to_insn ("lda", newtok, 3, &insn);
01291              }
01292          }
01293        else
01294          {
01295            if (!range_signed_32 (addend))
01296              {
01297               link = add_to_link_pool (alpha_evax_proc.symbol,
01298                                     exp->X_add_symbol, addend);
01299               addend = 0;
01300              }
01301            else
01302              link = add_to_link_pool (alpha_evax_proc.symbol,
01303                                    exp->X_add_symbol, 0);
01304 
01305            set_tok_reg (newtok[0], targreg);
01306            set_tok_const (newtok[1], link);
01307            set_tok_preg (newtok[2], basereg);
01308            assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
01309          }
01310 #endif /* OBJ_EVAX */
01311 
01312        emit_insn (&insn);
01313 
01314 #ifndef OBJ_EVAX
01315        if (basereg != alpha_gp_register && basereg != AXP_REG_ZERO)
01316          {
01317            /* Emit "addq r, base, r".  */
01318 
01319            set_tok_reg (newtok[1], basereg);
01320            set_tok_reg (newtok[2], targreg);
01321            assemble_tokens ("addq", newtok, 3, 0);
01322          }
01323 #endif
01324        basereg = targreg;
01325       }
01326       break;
01327 
01328     case O_constant:
01329       break;
01330 
01331     case O_subtract:
01332       /* Assume that this difference expression will be resolved to an
01333         absolute value and that that value will fit in 16 bits.  */
01334 
01335       set_tok_reg (newtok[0], targreg);
01336       newtok[1] = *exp;
01337       set_tok_preg (newtok[2], basereg);
01338       assemble_tokens ("lda", newtok, 3, 0);
01339 
01340       if (poffset)
01341        set_tok_const (*poffset, 0);
01342       return 0;
01343 
01344     case O_big:
01345       if (exp->X_add_number > 0)
01346        as_bad (_("bignum invalid; zero assumed"));
01347       else
01348        as_bad (_("floating point number invalid; zero assumed"));
01349       addend = 0;
01350       break;
01351 
01352     default:
01353       as_bad (_("can't handle expression"));
01354       addend = 0;
01355       break;
01356     }
01357 
01358   if (!range_signed_32 (addend))
01359     {
01360       offsetT lit;
01361       long seq_num = next_sequence_num--;
01362 
01363       /* For 64-bit addends, just put it in the literal pool.  */
01364 #ifdef OBJ_EVAX
01365       /* Emit "ldq targreg, lit(basereg)".  */
01366       lit = add_to_link_pool (alpha_evax_proc.symbol,
01367                            section_symbol (absolute_section), addend);
01368       set_tok_reg (newtok[0], targreg);
01369       set_tok_const (newtok[1], lit);
01370       set_tok_preg (newtok[2], alpha_gp_register);
01371       assemble_tokens ("ldq", newtok, 3, 0);
01372 #else
01373 
01374       if (alpha_lit8_section == NULL)
01375        {
01376          create_literal_section (".lit8",
01377                               &alpha_lit8_section,
01378                               &alpha_lit8_symbol);
01379 
01380 #ifdef OBJ_ECOFF
01381          alpha_lit8_literal = add_to_literal_pool (alpha_lit8_symbol, 0x8000,
01382                                               alpha_lita_section, 8);
01383          if (alpha_lit8_literal >= 0x8000)
01384            as_fatal (_("overflow in literal (.lita) table"));
01385 #endif
01386        }
01387 
01388       lit = add_to_literal_pool (NULL, addend, alpha_lit8_section, 8) - 0x8000;
01389       if (lit >= 0x8000)
01390        as_fatal (_("overflow in literal (.lit8) table"));
01391 
01392       /* Emit "lda litreg, .lit8+0x8000".  */
01393 
01394       if (targreg == basereg)
01395        {
01396          if (alpha_noat_on)
01397            as_bad (_("macro requires $at register while noat in effect"));
01398          if (targreg == AXP_REG_AT)
01399            as_bad (_("macro requires $at while $at in use"));
01400 
01401          set_tok_reg (newtok[0], AXP_REG_AT);
01402        }
01403       else
01404        set_tok_reg (newtok[0], targreg);
01405 #ifdef OBJ_ECOFF
01406       set_tok_sym (newtok[1], alpha_lita_symbol, alpha_lit8_literal);
01407 #endif
01408 #ifdef OBJ_ELF
01409       set_tok_sym (newtok[1], alpha_lit8_symbol, 0x8000);
01410 #endif
01411       set_tok_preg (newtok[2], alpha_gp_register);
01412 
01413       assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
01414 
01415       assert (insn.nfixups == 1);
01416 #ifdef OBJ_ECOFF
01417       insn.fixups[0].reloc = BFD_RELOC_ALPHA_LITERAL;
01418 #endif
01419 #ifdef OBJ_ELF
01420       insn.fixups[0].reloc = BFD_RELOC_ALPHA_ELF_LITERAL;
01421 #endif
01422       insn.sequence = seq_num;
01423 
01424       emit_insn (&insn);
01425 
01426       /* Emit "ldq litreg, lit(litreg)".  */
01427 
01428       set_tok_const (newtok[1], lit);
01429       set_tok_preg (newtok[2], newtok[0].X_add_number);
01430 
01431       assemble_tokens_to_insn ("ldq", newtok, 3, &insn);
01432 
01433       assert (insn.nfixups < MAX_INSN_FIXUPS);
01434       insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
01435       insn.fixups[insn.nfixups].exp.X_op = O_absent;
01436       insn.nfixups++;
01437       insn.sequence = seq_num;
01438       emit_lituse = 0;
01439 
01440       emit_insn (&insn);
01441 
01442       /* Emit "addq litreg, base, target".  */
01443 
01444       if (basereg != AXP_REG_ZERO)
01445        {
01446          set_tok_reg (newtok[1], basereg);
01447          set_tok_reg (newtok[2], targreg);
01448          assemble_tokens ("addq", newtok, 3, 0);
01449        }
01450 #endif /* !OBJ_EVAX */
01451 
01452       if (poffset)
01453        set_tok_const (*poffset, 0);
01454       *pbasereg = targreg;
01455     }
01456   else
01457     {
01458       offsetT low, high, extra, tmp;
01459 
01460       /* For 32-bit operands, break up the addend.  */
01461 
01462       low = sign_extend_16 (addend);
01463       tmp = addend - low;
01464       high = sign_extend_16 (tmp >> 16);
01465 
01466       if (tmp - (high << 16))
01467        {
01468          extra = 0x4000;
01469          tmp -= 0x40000000;
01470          high = sign_extend_16 (tmp >> 16);
01471        }
01472       else
01473        extra = 0;
01474 
01475       set_tok_reg (newtok[0], targreg);
01476       set_tok_preg (newtok[2], basereg);
01477 
01478       if (extra)
01479        {
01480          /* Emit "ldah r, extra(r).  */
01481          set_tok_const (newtok[1], extra);
01482          assemble_tokens ("ldah", newtok, 3, 0);
01483          set_tok_preg (newtok[2], basereg = targreg);
01484        }
01485 
01486       if (high)
01487        {
01488          /* Emit "ldah r, high(r).  */
01489          set_tok_const (newtok[1], high);
01490          assemble_tokens ("ldah", newtok, 3, 0);
01491          basereg = targreg;
01492          set_tok_preg (newtok[2], basereg);
01493        }
01494 
01495       if ((low && !poffset) || (!poffset && basereg != targreg))
01496        {
01497          /* Emit "lda r, low(base)".  */
01498          set_tok_const (newtok[1], low);
01499          assemble_tokens ("lda", newtok, 3, 0);
01500          basereg = targreg;
01501          low = 0;
01502        }
01503 
01504       if (poffset)
01505        set_tok_const (*poffset, low);
01506       *pbasereg = basereg;
01507     }
01508 
01509   return emit_lituse;
01510 }
01511 
01512 /* The lda macro differs from the lda instruction in that it handles
01513    most simple expressions, particularly symbol address loads and
01514    large constants.  */
01515 
01516 static void
01517 emit_lda (const expressionS *tok,
01518          int ntok,
01519          const void * unused ATTRIBUTE_UNUSED)
01520 {
01521   int basereg;
01522 
01523   if (ntok == 2)
01524     basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
01525   else
01526     basereg = tok[2].X_add_number;
01527 
01528   (void) load_expression (tok[0].X_add_number, &tok[1], &basereg, NULL);
01529 }
01530 
01531 /* The ldah macro differs from the ldah instruction in that it has $31
01532    as an implied base register.  */
01533 
01534 static void
01535 emit_ldah (const expressionS *tok,
01536           int ntok ATTRIBUTE_UNUSED,
01537           const void * unused ATTRIBUTE_UNUSED)
01538 {
01539   expressionS newtok[3];
01540 
01541   newtok[0] = tok[0];
01542   newtok[1] = tok[1];
01543   set_tok_preg (newtok[2], AXP_REG_ZERO);
01544 
01545   assemble_tokens ("ldah", newtok, 3, 0);
01546 }
01547 
01548 /* Called internally to handle all alignment needs.  This takes care
01549    of eliding calls to frag_align if'n the cached current alignment
01550    says we've already got it, as well as taking care of the auto-align
01551    feature wrt labels.  */
01552 
01553 static void
01554 alpha_align (int n,
01555             char *pfill,
01556             symbolS *label,
01557             int force ATTRIBUTE_UNUSED)
01558 {
01559   if (alpha_current_align >= n)
01560     return;
01561 
01562   if (pfill == NULL)
01563     {
01564       if (subseg_text_p (now_seg))
01565        frag_align_code (n, 0);
01566       else
01567        frag_align (n, 0, 0);
01568     }
01569   else
01570     frag_align (n, *pfill, 0);
01571 
01572   alpha_current_align = n;
01573 
01574   if (label != NULL && S_GET_SEGMENT (label) == now_seg)
01575     {
01576       symbol_set_frag (label, frag_now);
01577       S_SET_VALUE (label, (valueT) frag_now_fix ());
01578     }
01579 
01580   record_alignment (now_seg, n);
01581 
01582   /* ??? If alpha_flag_relax && force && elf, record the requested alignment
01583      in a reloc for the linker to see.  */
01584 }
01585 
01586 /* Actually output an instruction with its fixup.  */
01587 
01588 static void
01589 emit_insn (struct alpha_insn *insn)
01590 {
01591   char *f;
01592   int i;
01593 
01594   /* Take care of alignment duties.  */
01595   if (alpha_auto_align_on && alpha_current_align < 2)
01596     alpha_align (2, (char *) NULL, alpha_insn_label, 0);
01597   if (alpha_current_align > 2)
01598     alpha_current_align = 2;
01599   alpha_insn_label = NULL;
01600 
01601   /* Write out the instruction.  */
01602   f = frag_more (4);
01603   md_number_to_chars (f, insn->insn, 4);
01604 
01605 #ifdef OBJ_ELF
01606   dwarf2_emit_insn (4);
01607 #endif
01608 
01609   /* Apply the fixups in order.  */
01610   for (i = 0; i < insn->nfixups; ++i)
01611     {
01612       const struct alpha_operand *operand = (const struct alpha_operand *) 0;
01613       struct alpha_fixup *fixup = &insn->fixups[i];
01614       struct alpha_reloc_tag *info = NULL;
01615       int size, pcrel;
01616       fixS *fixP;
01617 
01618       /* Some fixups are only used internally and so have no howto.  */
01619       if ((int) fixup->reloc < 0)
01620        {
01621          operand = &alpha_operands[-(int) fixup->reloc];
01622          size = 4;
01623          pcrel = ((operand->flags & AXP_OPERAND_RELATIVE) != 0);
01624        }
01625       else if (fixup->reloc > BFD_RELOC_UNUSED
01626               || fixup->reloc == BFD_RELOC_ALPHA_GPDISP_HI16
01627               || fixup->reloc == BFD_RELOC_ALPHA_GPDISP_LO16)
01628        {
01629          size = 2;
01630          pcrel = 0;
01631        }
01632       else
01633        {
01634          reloc_howto_type *reloc_howto
01635            = bfd_reloc_type_lookup (stdoutput, fixup->reloc);
01636          assert (reloc_howto);
01637 
01638          size = bfd_get_reloc_size (reloc_howto);
01639          assert (size >= 1 && size <= 4);
01640 
01641          pcrel = reloc_howto->pc_relative;
01642        }
01643 
01644       fixP = fix_new_exp (frag_now, f - frag_now->fr_literal, size,
01645                        &fixup->exp, pcrel, fixup->reloc);
01646 
01647       /* Turn off complaints that the addend is too large for some fixups,
01648          and copy in the sequence number for the explicit relocations.  */
01649       switch (fixup->reloc)
01650        {
01651        case BFD_RELOC_ALPHA_HINT:
01652        case BFD_RELOC_GPREL32:
01653        case BFD_RELOC_GPREL16:
01654        case BFD_RELOC_ALPHA_GPREL_HI16:
01655        case BFD_RELOC_ALPHA_GPREL_LO16:
01656        case BFD_RELOC_ALPHA_GOTDTPREL16:
01657        case BFD_RELOC_ALPHA_DTPREL_HI16:
01658        case BFD_RELOC_ALPHA_DTPREL_LO16:
01659        case BFD_RELOC_ALPHA_DTPREL16:
01660        case BFD_RELOC_ALPHA_GOTTPREL16:
01661        case BFD_RELOC_ALPHA_TPREL_HI16:
01662        case BFD_RELOC_ALPHA_TPREL_LO16:
01663        case BFD_RELOC_ALPHA_TPREL16:
01664          fixP->fx_no_overflow = 1;
01665          break;
01666 
01667        case BFD_RELOC_ALPHA_GPDISP_HI16:
01668          fixP->fx_no_overflow = 1;
01669          fixP->fx_addsy = section_symbol (now_seg);
01670          fixP->fx_offset = 0;
01671 
01672          info = get_alpha_reloc_tag (insn->sequence);
01673          if (++info->n_master > 1)
01674            as_bad (_("too many ldah insns for !gpdisp!%ld"), insn->sequence);
01675          if (info->segment != now_seg)
01676            as_bad (_("both insns for !gpdisp!%ld must be in the same section"),
01677                   insn->sequence);
01678          fixP->tc_fix_data.info = info;
01679          break;
01680 
01681        case BFD_RELOC_ALPHA_GPDISP_LO16:
01682          fixP->fx_no_overflow = 1;
01683 
01684          info = get_alpha_reloc_tag (insn->sequence);
01685          if (++info->n_slaves > 1)
01686            as_bad (_("too many lda insns for !gpdisp!%ld"), insn->sequence);
01687          if (info->segment != now_seg)
01688            as_bad (_("both insns for !gpdisp!%ld must be in the same section"),
01689                   insn->sequence);
01690          fixP->tc_fix_data.info = info;
01691          info->slaves = fixP;
01692          break;
01693 
01694        case BFD_RELOC_ALPHA_LITERAL:
01695        case BFD_RELOC_ALPHA_ELF_LITERAL:
01696          fixP->fx_no_overflow = 1;
01697 
01698          if (insn->sequence == 0)
01699            break;
01700          info = get_alpha_reloc_tag (insn->sequence);
01701          info->master = fixP;
01702          info->n_master++;
01703          if (info->segment != now_seg)
01704            info->multi_section_p = 1;
01705          fixP->tc_fix_data.info = info;
01706          break;
01707 
01708 #ifdef RELOC_OP_P
01709        case DUMMY_RELOC_LITUSE_ADDR:
01710          fixP->fx_offset = LITUSE_ALPHA_ADDR;
01711          goto do_lituse;
01712        case DUMMY_RELOC_LITUSE_BASE:
01713          fixP->fx_offset = LITUSE_ALPHA_BASE;
01714          goto do_lituse;
01715        case DUMMY_RELOC_LITUSE_BYTOFF:
01716          fixP->fx_offset = LITUSE_ALPHA_BYTOFF;
01717          goto do_lituse;
01718        case DUMMY_RELOC_LITUSE_JSR:
01719          fixP->fx_offset = LITUSE_ALPHA_JSR;
01720          goto do_lituse;
01721        case DUMMY_RELOC_LITUSE_TLSGD:
01722          fixP->fx_offset = LITUSE_ALPHA_TLSGD;
01723          goto do_lituse;
01724        case DUMMY_RELOC_LITUSE_TLSLDM:
01725          fixP->fx_offset = LITUSE_ALPHA_TLSLDM;
01726          goto do_lituse;
01727        case DUMMY_RELOC_LITUSE_JSRDIRECT:
01728          fixP->fx_offset = LITUSE_ALPHA_JSRDIRECT;
01729          goto do_lituse;
01730        do_lituse:
01731          fixP->fx_addsy = section_symbol (now_seg);
01732          fixP->fx_r_type = BFD_RELOC_ALPHA_LITUSE;
01733 
01734          info = get_alpha_reloc_tag (insn->sequence);
01735          if (fixup->reloc == DUMMY_RELOC_LITUSE_TLSGD)
01736            info->saw_lu_tlsgd = 1;
01737          else if (fixup->reloc == DUMMY_RELOC_LITUSE_TLSLDM)
01738            info->saw_lu_tlsldm = 1;
01739          if (++info->n_slaves > 1)
01740            {
01741              if (info->saw_lu_tlsgd)
01742               as_bad (_("too many lituse insns for !lituse_tlsgd!%ld"),
01743                       insn->sequence);
01744              else if (info->saw_lu_tlsldm)
01745               as_bad (_("too many lituse insns for !lituse_tlsldm!%ld"),
01746                       insn->sequence);
01747            }
01748          fixP->tc_fix_data.info = info;
01749          fixP->tc_fix_data.next_reloc = info->slaves;
01750          info->slaves = fixP;
01751          if (info->segment != now_seg)
01752            info->multi_section_p = 1;
01753          break;
01754 
01755        case BFD_RELOC_ALPHA_TLSGD:
01756          fixP->fx_no_overflow = 1;
01757 
01758          if (insn->sequence == 0)
01759            break;
01760          info = get_alpha_reloc_tag (insn->sequence);
01761          if (info->saw_tlsgd)
01762            as_bad (_("duplicate !tlsgd!%ld"), insn->sequence);
01763          else if (info->saw_tlsldm)
01764            as_bad (_("sequence number in use for !tlsldm!%ld"),
01765                   insn->sequence);
01766          else
01767            info->saw_tlsgd = 1;
01768          fixP->tc_fix_data.info = info;
01769          break;
01770 
01771        case BFD_RELOC_ALPHA_TLSLDM:
01772          fixP->fx_no_overflow = 1;
01773 
01774          if (insn->sequence == 0)
01775            break;
01776          info = get_alpha_reloc_tag (insn->sequence);
01777          if (info->saw_tlsldm)
01778            as_bad (_("duplicate !tlsldm!%ld"), insn->sequence);
01779          else if (info->saw_tlsgd)
01780            as_bad (_("sequence number in use for !tlsgd!%ld"),
01781                   insn->sequence);
01782          else
01783            info->saw_tlsldm = 1;
01784          fixP->tc_fix_data.info = info;
01785          break;
01786 #endif
01787        default:
01788          if ((int) fixup->reloc < 0)
01789            {
01790              if (operand->flags & AXP_OPERAND_NOOVERFLOW)
01791               fixP->fx_no_overflow = 1;
01792            }
01793          break;
01794        }
01795     }
01796 }
01797 
01798 /* Insert an operand value into an instruction.  */
01799 
01800 static unsigned
01801 insert_operand (unsigned insn,
01802               const struct alpha_operand *operand,
01803               offsetT val,
01804               char *file,
01805               unsigned line)
01806 {
01807   if (operand->bits != 32 && !(operand->flags & AXP_OPERAND_NOOVERFLOW))
01808     {
01809       offsetT min, max;
01810 
01811       if (operand->flags & AXP_OPERAND_SIGNED)
01812        {
01813          max = (1 << (operand->bits - 1)) - 1;
01814          min = -(1 << (operand->bits - 1));
01815        }
01816       else
01817        {
01818          max = (1 << operand->bits) - 1;
01819          min = 0;
01820        }
01821 
01822       if (val < min || val > max)
01823        as_warn_value_out_of_range (_("operand"), val, min, max, file, line);
01824     }
01825 
01826   if (operand->insert)
01827     {
01828       const char *errmsg = NULL;
01829 
01830       insn = (*operand->insert) (insn, val, &errmsg);
01831       if (errmsg)
01832        as_warn (errmsg);
01833     }
01834   else
01835     insn |= ((val & ((1 << operand->bits) - 1)) << operand->shift);
01836 
01837   return insn;
01838 }
01839 
01840 /* Turn an opcode description and a set of arguments into
01841    an instruction and a fixup.  */
01842 
01843 static void
01844 assemble_insn (const struct alpha_opcode *opcode,
01845               const expressionS *tok,
01846               int ntok,
01847               struct alpha_insn *insn,
01848               bfd_reloc_code_real_type reloc)
01849 {
01850   const struct alpha_operand *reloc_operand = NULL;
01851   const expressionS *reloc_exp = NULL;
01852   const unsigned char *argidx;
01853   unsigned image;
01854   int tokidx = 0;
01855 
01856   memset (insn, 0, sizeof (*insn));
01857   image = opcode->opcode;
01858 
01859   for (argidx = opcode->operands; *argidx; ++argidx)
01860     {
01861       const struct alpha_operand *operand = &alpha_operands[*argidx];
01862       const expressionS *t = (const expressionS *) 0;
01863 
01864       if (operand->flags & AXP_OPERAND_FAKE)
01865        {
01866          /* Fake operands take no value and generate no fixup.  */
01867          image = insert_operand (image, operand, 0, NULL, 0);
01868          continue;
01869        }
01870 
01871       if (tokidx >= ntok)
01872        {
01873          switch (operand->flags & AXP_OPERAND_OPTIONAL_MASK)
01874            {
01875            case AXP_OPERAND_DEFAULT_FIRST:
01876              t = &tok[0];
01877              break;
01878            case AXP_OPERAND_DEFAULT_SECOND:
01879              t = &tok[1];
01880              break;
01881            case AXP_OPERAND_DEFAULT_ZERO:
01882              {
01883               static expressionS zero_exp;
01884               t = &zero_exp;
01885               zero_exp.X_op = O_constant;
01886               zero_exp.X_unsigned = 1;
01887              }
01888              break;
01889            default:
01890              abort ();
01891            }
01892        }
01893       else
01894        t = &tok[tokidx++];
01895 
01896       switch (t->X_op)
01897        {
01898        case O_register:
01899        case O_pregister:
01900        case O_cpregister:
01901          image = insert_operand (image, operand, regno (t->X_add_number),
01902                               NULL, 0);
01903          break;
01904 
01905        case O_constant:
01906          image = insert_operand (image, operand, t->X_add_number, NULL, 0);
01907          assert (reloc_operand == NULL);
01908          reloc_operand = operand;
01909          reloc_exp = t;
01910          break;
01911 
01912        default:
01913          /* This is only 0 for fields that should contain registers,
01914             which means this pattern shouldn't have matched.  */
01915          if (operand->default_reloc == 0)
01916            abort ();
01917 
01918          /* There is one special case for which an insn receives two
01919             relocations, and thus the user-supplied reloc does not
01920             override the operand reloc.  */
01921          if (operand->default_reloc == BFD_RELOC_ALPHA_HINT)
01922            {
01923              struct alpha_fixup *fixup;
01924 
01925              if (insn->nfixups >= MAX_INSN_FIXUPS)
01926               as_fatal (_("too many fixups"));
01927 
01928              fixup = &insn->fixups[insn->nfixups++];
01929              fixup->exp = *t;
01930              fixup->reloc = BFD_RELOC_ALPHA_HINT;
01931            }
01932          else
01933            {
01934              if (reloc == BFD_RELOC_UNUSED)
01935               reloc = operand->default_reloc;
01936 
01937              assert (reloc_operand == NULL);
01938              reloc_operand = operand;
01939              reloc_exp = t;
01940            }
01941          break;
01942        }
01943     }
01944 
01945   if (reloc != BFD_RELOC_UNUSED)
01946     {
01947       struct alpha_fixup *fixup;
01948 
01949       if (insn->nfixups >= MAX_INSN_FIXUPS)
01950        as_fatal (_("too many fixups"));
01951 
01952       /* ??? My but this is hacky.  But the OSF/1 assembler uses the same
01953         relocation tag for both ldah and lda with gpdisp.  Choose the
01954         correct internal relocation based on the opcode.  */
01955       if (reloc == BFD_RELOC_ALPHA_GPDISP)
01956        {
01957          if (strcmp (opcode->name, "ldah") == 0)
01958            reloc = BFD_RELOC_ALPHA_GPDISP_HI16;
01959          else if (strcmp (opcode->name, "lda") == 0)
01960            reloc = BFD_RELOC_ALPHA_GPDISP_LO16;
01961          else
01962            as_bad (_("invalid relocation for instruction"));
01963        }
01964 
01965       /* If this is a real relocation (as opposed to a lituse hint), then
01966         the relocation width should match the operand width.  */
01967       else if (reloc < BFD_RELOC_UNUSED)
01968        {
01969          reloc_howto_type *reloc_howto
01970            = bfd_reloc_type_lookup (stdoutput, reloc);
01971          if (reloc_howto->bitsize != reloc_operand->bits)
01972            {
01973              as_bad (_("invalid relocation for field"));
01974              return;
01975            }
01976        }
01977 
01978       fixup = &insn->fixups[insn->nfixups++];
01979       if (reloc_exp)
01980        fixup->exp = *reloc_exp;
01981       else
01982        fixup->exp.X_op = O_absent;
01983       fixup->reloc = reloc;
01984     }
01985 
01986   insn->insn = image;
01987 }
01988 
01989 /* Handle all "simple" integer register loads -- ldq, ldq_l, ldq_u,
01990    etc.  They differ from the real instructions in that they do simple
01991    expressions like the lda macro.  */
01992 
01993 static void
01994 emit_ir_load (const expressionS *tok,
01995              int ntok,
01996              const void * opname)
01997 {
01998   int basereg;
01999   long lituse;
02000   expressionS newtok[3];
02001   struct alpha_insn insn;
02002 
02003   if (ntok == 2)
02004     basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
02005   else
02006     basereg = tok[2].X_add_number;
02007 
02008   lituse = load_expression (tok[0].X_add_number, &tok[1], &basereg,
02009                          &newtok[1]);
02010 
02011   newtok[0] = tok[0];
02012   set_tok_preg (newtok[2], basereg);
02013 
02014   assemble_tokens_to_insn ((const char *) opname, newtok, 3, &insn);
02015 
02016   if (lituse)
02017     {
02018       assert (insn.nfixups < MAX_INSN_FIXUPS);
02019       insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
02020       insn.fixups[insn.nfixups].exp.X_op = O_absent;
02021       insn.nfixups++;
02022       insn.sequence = lituse;
02023     }
02024 
02025   emit_insn (&insn);
02026 }
02027 
02028 /* Handle fp register loads, and both integer and fp register stores.
02029    Again, we handle simple expressions.  */
02030 
02031 static void
02032 emit_loadstore (const expressionS *tok,
02033               int ntok,
02034               const void * opname)
02035 {
02036   int basereg;
02037   long lituse;
02038   expressionS newtok[3];
02039   struct alpha_insn insn;
02040 
02041   if (ntok == 2)
02042     basereg = (tok[1].X_op == O_constant ? AXP_REG_ZERO : alpha_gp_register);
02043   else
02044     basereg = tok[2].X_add_number;
02045 
02046   if (tok[1].X_op != O_constant || !range_signed_16 (tok[1].X_add_number))
02047     {
02048       if (alpha_noat_on)
02049        as_bad (_("macro requires $at register while noat in effect"));
02050 
02051       lituse = load_expression (AXP_REG_AT, &tok[1], &basereg, &newtok[1]);
02052     }
02053   else
02054     {
02055       newtok[1] = tok[1];
02056       lituse = 0;
02057     }
02058 
02059   newtok[0] = tok[0];
02060   set_tok_preg (newtok[2], basereg);
02061 
02062   assemble_tokens_to_insn ((const char *) opname, newtok, 3, &insn);
02063 
02064   if (lituse)
02065     {
02066       assert (insn.nfixups < MAX_INSN_FIXUPS);
02067       insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
02068       insn.fixups[insn.nfixups].exp.X_op = O_absent;
02069       insn.nfixups++;
02070       insn.sequence = lituse;
02071     }
02072 
02073   emit_insn (&insn);
02074 }
02075 
02076 /* Load a half-word or byte as an unsigned value.  */
02077 
02078 static void
02079 emit_ldXu (const expressionS *tok,
02080           int ntok,
02081           const void * vlgsize)
02082 {
02083   if (alpha_target & AXP_OPCODE_BWX)
02084     emit_ir_load (tok, ntok, ldXu_op[(long) vlgsize]);
02085   else
02086     {
02087       expressionS newtok[3];
02088       struct alpha_insn insn;
02089       int basereg;
02090       long lituse;
02091 
02092       if (alpha_noat_on)
02093        as_bad (_("macro requires $at register while noat in effect"));
02094 
02095       if (ntok == 2)
02096        basereg = (tok[1].X_op == O_constant
02097                  ? AXP_REG_ZERO : alpha_gp_register);
02098       else
02099        basereg = tok[2].X_add_number;
02100 
02101       /* Emit "lda $at, exp".  */
02102       lituse = load_expression (AXP_REG_AT, &tok[1], &basereg, NULL);
02103 
02104       /* Emit "ldq_u targ, 0($at)".  */
02105       newtok[0] = tok[0];
02106       set_tok_const (newtok[1], 0);
02107       set_tok_preg (newtok[2], basereg);
02108       assemble_tokens_to_insn ("ldq_u", newtok, 3, &insn);
02109 
02110       if (lituse)
02111        {
02112          assert (insn.nfixups < MAX_INSN_FIXUPS);
02113          insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
02114          insn.fixups[insn.nfixups].exp.X_op = O_absent;
02115          insn.nfixups++;
02116          insn.sequence = lituse;
02117        }
02118 
02119       emit_insn (&insn);
02120 
02121       /* Emit "extXl targ, $at, targ".  */
02122       set_tok_reg (newtok[1], basereg);
02123       newtok[2] = newtok[0];
02124       assemble_tokens_to_insn (extXl_op[(long) vlgsize], newtok, 3, &insn);
02125 
02126       if (lituse)
02127        {
02128          assert (insn.nfixups < MAX_INSN_FIXUPS);
02129          insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF;
02130          insn.fixups[insn.nfixups].exp.X_op = O_absent;
02131          insn.nfixups++;
02132          insn.sequence = lituse;
02133        }
02134 
02135       emit_insn (&insn);
02136     }
02137 }
02138 
02139 /* Load a half-word or byte as a signed value.  */
02140 
02141 static void
02142 emit_ldX (const expressionS *tok,
02143          int ntok,
02144          const void * vlgsize)
02145 {
02146   emit_ldXu (tok, ntok, vlgsize);
02147   assemble_tokens (sextX_op[(long) vlgsize], tok, 1, 1);
02148 }
02149 
02150 /* Load an integral value from an unaligned address as an unsigned
02151    value.  */
02152 
02153 static void
02154 emit_uldXu (const expressionS *tok,
02155            int ntok,
02156            const void * vlgsize)
02157 {
02158   long lgsize = (long) vlgsize;
02159   expressionS newtok[3];
02160 
02161   if (alpha_noat_on)
02162     as_bad (_("macro requires $at register while noat in effect"));
02163 
02164   /* Emit "lda $at, exp".  */
02165   memcpy (newtok, tok, sizeof (expressionS) * ntok);
02166   newtok[0].X_add_number = AXP_REG_AT;
02167   assemble_tokens ("lda", newtok, ntok, 1);
02168 
02169   /* Emit "ldq_u $t9, 0($at)".  */
02170   set_tok_reg (newtok[0], AXP_REG_T9);
02171   set_tok_const (newtok[1], 0);
02172   set_tok_preg (newtok[2], AXP_REG_AT);
02173   assemble_tokens ("ldq_u", newtok, 3, 1);
02174 
02175   /* Emit "ldq_u $t10, size-1($at)".  */
02176   set_tok_reg (newtok[0], AXP_REG_T10);
02177   set_tok_const (newtok[1], (1 << lgsize) - 1);
02178   assemble_tokens ("ldq_u", newtok, 3, 1);
02179 
02180   /* Emit "extXl $t9, $at, $t9".  */
02181   set_tok_reg (newtok[0], AXP_REG_T9);
02182   set_tok_reg (newtok[1], AXP_REG_AT);
02183   set_tok_reg (newtok[2], AXP_REG_T9);
02184   assemble_tokens (extXl_op[lgsize], newtok, 3, 1);
02185 
02186   /* Emit "extXh $t10, $at, $t10".  */
02187   set_tok_reg (newtok[0], AXP_REG_T10);
02188   set_tok_reg (newtok[2], AXP_REG_T10);
02189   assemble_tokens (extXh_op[lgsize], newtok, 3, 1);
02190 
02191   /* Emit "or $t9, $t10, targ".  */
02192   set_tok_reg (newtok[0], AXP_REG_T9);
02193   set_tok_reg (newtok[1], AXP_REG_T10);
02194   newtok[2] = tok[0];
02195   assemble_tokens ("or", newtok, 3, 1);
02196 }
02197 
02198 /* Load an integral value from an unaligned address as a signed value.
02199    Note that quads should get funneled to the unsigned load since we
02200    don't have to do the sign extension.  */
02201 
02202 static void
02203 emit_uldX (const expressionS *tok,
02204           int ntok,
02205           const void * vlgsize)
02206 {
02207   emit_uldXu (tok, ntok, vlgsize);
02208   assemble_tokens (sextX_op[(long) vlgsize], tok, 1, 1);
02209 }
02210 
02211 /* Implement the ldil macro.  */
02212 
02213 static void
02214 emit_ldil (const expressionS *tok,
02215           int ntok,
02216           const void * unused ATTRIBUTE_UNUSED)
02217 {
02218   expressionS newtok[2];
02219 
02220   memcpy (newtok, tok, sizeof (newtok));
02221   newtok[1].X_add_number = sign_extend_32 (tok[1].X_add_number);
02222 
02223   assemble_tokens ("lda", newtok, ntok, 1);
02224 }
02225 
02226 /* Store a half-word or byte.  */
02227 
02228 static void
02229 emit_stX (const expressionS *tok,
02230          int ntok,
02231          const void * vlgsize)
02232 {
02233   int lgsize = (int) (long) vlgsize;
02234 
02235   if (alpha_target & AXP_OPCODE_BWX)
02236     emit_loadstore (tok, ntok, stX_op[lgsize]);
02237   else
02238     {
02239       expressionS newtok[3];
02240       struct alpha_insn insn;
02241       int basereg;
02242       long lituse;
02243 
02244       if (alpha_noat_on)
02245        as_bad (_("macro requires $at register while noat in effect"));
02246 
02247       if (ntok == 2)
02248        basereg = (tok[1].X_op == O_constant
02249                  ? AXP_REG_ZERO : alpha_gp_register);
02250       else
02251        basereg = tok[2].X_add_number;
02252 
02253       /* Emit "lda $at, exp".  */
02254       lituse = load_expression (AXP_REG_AT, &tok[1], &basereg, NULL);
02255 
02256       /* Emit "ldq_u $t9, 0($at)".  */
02257       set_tok_reg (newtok[0], AXP_REG_T9);
02258       set_tok_const (newtok[1], 0);
02259       set_tok_preg (newtok[2], basereg);
02260       assemble_tokens_to_insn ("ldq_u", newtok, 3, &insn);
02261 
02262       if (lituse)
02263        {
02264          assert (insn.nfixups < MAX_INSN_FIXUPS);
02265          insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
02266          insn.fixups[insn.nfixups].exp.X_op = O_absent;
02267          insn.nfixups++;
02268          insn.sequence = lituse;
02269        }
02270 
02271       emit_insn (&insn);
02272 
02273       /* Emit "insXl src, $at, $t10".  */
02274       newtok[0] = tok[0];
02275       set_tok_reg (newtok[1], basereg);
02276       set_tok_reg (newtok[2], AXP_REG_T10);
02277       assemble_tokens_to_insn (insXl_op[lgsize], newtok, 3, &insn);
02278 
02279       if (lituse)
02280        {
02281          assert (insn.nfixups < MAX_INSN_FIXUPS);
02282          insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF;
02283          insn.fixups[insn.nfixups].exp.X_op = O_absent;
02284          insn.nfixups++;
02285          insn.sequence = lituse;
02286        }
02287 
02288       emit_insn (&insn);
02289 
02290       /* Emit "mskXl $t9, $at, $t9".  */
02291       set_tok_reg (newtok[0], AXP_REG_T9);
02292       newtok[2] = newtok[0];
02293       assemble_tokens_to_insn (mskXl_op[lgsize], newtok, 3, &insn);
02294 
02295       if (lituse)
02296        {
02297          assert (insn.nfixups < MAX_INSN_FIXUPS);
02298          insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BYTOFF;
02299          insn.fixups[insn.nfixups].exp.X_op = O_absent;
02300          insn.nfixups++;
02301          insn.sequence = lituse;
02302        }
02303 
02304       emit_insn (&insn);
02305 
02306       /* Emit "or $t9, $t10, $t9".  */
02307       set_tok_reg (newtok[1], AXP_REG_T10);
02308       assemble_tokens ("or", newtok, 3, 1);
02309 
02310       /* Emit "stq_u $t9, 0($at).  */
02311       set_tok_const(newtok[1], 0);
02312       set_tok_preg (newtok[2], AXP_REG_AT);
02313       assemble_tokens_to_insn ("stq_u", newtok, 3, &insn);
02314 
02315       if (lituse)
02316        {
02317          assert (insn.nfixups < MAX_INSN_FIXUPS);
02318          insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_BASE;
02319          insn.fixups[insn.nfixups].exp.X_op = O_absent;
02320          insn.nfixups++;
02321          insn.sequence = lituse;
02322        }
02323 
02324       emit_insn (&insn);
02325     }
02326 }
02327 
02328 /* Store an integer to an unaligned address.  */
02329 
02330 static void
02331 emit_ustX (const expressionS *tok,
02332           int ntok,
02333           const void * vlgsize)
02334 {
02335   int lgsize = (int) (long) vlgsize;
02336   expressionS newtok[3];
02337 
02338   /* Emit "lda $at, exp".  */
02339   memcpy (newtok, tok, sizeof (expressionS) * ntok);
02340   newtok[0].X_add_number = AXP_REG_AT;
02341   assemble_tokens ("lda", newtok, ntok, 1);
02342 
02343   /* Emit "ldq_u $9, 0($at)".  */
02344   set_tok_reg (newtok[0], AXP_REG_T9);
02345   set_tok_const (newtok[1], 0);
02346   set_tok_preg (newtok[2], AXP_REG_AT);
02347   assemble_tokens ("ldq_u", newtok, 3, 1);
02348 
02349   /* Emit "ldq_u $10, size-1($at)".  */
02350   set_tok_reg (newtok[0], AXP_REG_T10);
02351   set_tok_const (newtok[1], (1 << lgsize) - 1);
02352   assemble_tokens ("ldq_u", newtok, 3, 1);
02353 
02354   /* Emit "insXl src, $at, $t11".  */
02355   newtok[0] = tok[0];
02356   set_tok_reg (newtok[1], AXP_REG_AT);
02357   set_tok_reg (newtok[2], AXP_REG_T11);
02358   assemble_tokens (insXl_op[lgsize], newtok, 3, 1);
02359 
02360   /* Emit "insXh src, $at, $t12".  */
02361   set_tok_reg (newtok[2], AXP_REG_T12);
02362   assemble_tokens (insXh_op[lgsize], newtok, 3, 1);
02363 
02364   /* Emit "mskXl $t9, $at, $t9".  */
02365   set_tok_reg (newtok[0], AXP_REG_T9);
02366   newtok[2] = newtok[0];
02367   assemble_tokens (mskXl_op[lgsize], newtok, 3, 1);
02368 
02369   /* Emit "mskXh $t10, $at, $t10".  */
02370   set_tok_reg (newtok[0], AXP_REG_T10);
02371   newtok[2] = newtok[0];
02372   assemble_tokens (mskXh_op[lgsize], newtok, 3, 1);
02373 
02374   /* Emit "or $t9, $t11, $t9".  */
02375   set_tok_reg (newtok[0], AXP_REG_T9);
02376   set_tok_reg (newtok[1], AXP_REG_T11);
02377   newtok[2] = newtok[0];
02378   assemble_tokens ("or", newtok, 3, 1);
02379 
02380   /* Emit "or $t10, $t12, $t10".  */
02381   set_tok_reg (newtok[0], AXP_REG_T10);
02382   set_tok_reg (newtok[1], AXP_REG_T12);
02383   newtok[2] = newtok[0];
02384   assemble_tokens ("or", newtok, 3, 1);
02385 
02386   /* Emit "stq_u $t10, size-1($at)".  */
02387   set_tok_reg (newtok[0], AXP_REG_T10);
02388   set_tok_const (newtok[1], (1 << lgsize) - 1);
02389   set_tok_preg (newtok[2], AXP_REG_AT);
02390   assemble_tokens ("stq_u", newtok, 3, 1);
02391 
02392   /* Emit "stq_u $t9, 0($at)".  */
02393   set_tok_reg (newtok[0], AXP_REG_T9);
02394   set_tok_const (newtok[1], 0);
02395   assemble_tokens ("stq_u", newtok, 3, 1);
02396 }
02397 
02398 /* Sign extend a half-word or byte.  The 32-bit sign extend is
02399    implemented as "addl $31, $r, $t" in the opcode table.  */
02400 
02401 static void
02402 emit_sextX (const expressionS *tok,
02403            int ntok,
02404            const void * vlgsize)
02405 {
02406   long lgsize = (long) vlgsize;
02407 
02408   if (alpha_target & AXP_OPCODE_BWX)
02409     assemble_tokens (sextX_op[lgsize], tok, ntok, 0);
02410   else
02411     {
02412       int bitshift = 64 - 8 * (1 << lgsize);
02413       expressionS newtok[3];
02414 
02415       /* Emit "sll src,bits,dst".  */
02416       newtok[0] = tok[0];
02417       set_tok_const (newtok[1], bitshift);
02418       newtok[2] = tok[ntok - 1];
02419       assemble_tokens ("sll", newtok, 3, 1);
02420 
02421       /* Emit "sra dst,bits,dst".  */
02422       newtok[0] = newtok[2];
02423       assemble_tokens ("sra", newtok, 3, 1);
02424     }
02425 }
02426 
02427 /* Implement the division and modulus macros.  */
02428 
02429 #ifdef OBJ_EVAX
02430 
02431 /* Make register usage like in normal procedure call.
02432    Don't clobber PV and RA.  */
02433 
02434 static void
02435 emit_division (const expressionS *tok,
02436               int ntok,
02437               const void * symname)
02438 {
02439   /* DIVISION and MODULUS. Yech.
02440 
02441      Convert
02442         OP x,y,result
02443      to
02444         mov x,R16    # if x != R16
02445         mov y,R17    # if y != R17
02446         lda AT,__OP
02447         jsr AT,(AT),0
02448         mov R0,result
02449 
02450      with appropriate optimizations if R0,R16,R17 are the registers
02451      specified by the compiler.  */
02452 
02453   int xr, yr, rr;
02454   symbolS *sym;
02455   expressionS newtok[3];
02456 
02457   xr = regno (tok[0].X_add_number);
02458   yr = regno (tok[1].X_add_number);
02459 
02460   if (ntok < 3)
02461     rr = xr;
02462   else
02463     rr = regno (tok[2].X_add_number);
02464 
02465   /* Move the operands into the right place.  */
02466   if (yr == AXP_REG_R16 && xr == AXP_REG_R17)
02467     {
02468       /* They are in exactly the wrong order -- swap through AT.  */
02469       if (alpha_noat_on)
02470        as_bad (_("macro requires $at register while noat in effect"));
02471 
02472       set_tok_reg (newtok[0], AXP_REG_R16);
02473       set_tok_reg (newtok[1], AXP_REG_AT);
02474       assemble_tokens ("mov", newtok, 2, 1);
02475 
02476       set_tok_reg (newtok[0], AXP_REG_R17);
02477       set_tok_reg (newtok[1], AXP_REG_R16);
02478       assemble_tokens ("mov", newtok, 2, 1);
02479 
02480       set_tok_reg (newtok[0], AXP_REG_AT);
02481       set_tok_reg (newtok[1], AXP_REG_R17);
02482       assemble_tokens ("mov", newtok, 2, 1);
02483     }
02484   else
02485     {
02486       if (yr == AXP_REG_R16)
02487        {
02488          set_tok_reg (newtok[0], AXP_REG_R16);
02489          set_tok_reg (newtok[1], AXP_REG_R17);
02490          assemble_tokens ("mov", newtok, 2, 1);
02491        }
02492 
02493       if (xr != AXP_REG_R16)
02494        {
02495          set_tok_reg (newtok[0], xr);
02496          set_tok_reg (newtok[1], AXP_REG_R16);
02497          assemble_tokens ("mov", newtok, 2, 1);
02498        }
02499 
02500       if (yr != AXP_REG_R16 && yr != AXP_REG_R17)
02501        {
02502          set_tok_reg (newtok[0], yr);
02503          set_tok_reg (newtok[1], AXP_REG_R17);
02504          assemble_tokens ("mov", newtok, 2, 1);
02505        }
02506     }
02507 
02508   sym = symbol_find_or_make ((const char *) symname);
02509 
02510   set_tok_reg (newtok[0], AXP_REG_AT);
02511   set_tok_sym (newtok[1], sym, 0);
02512   assemble_tokens ("lda", newtok, 2, 1);
02513 
02514   /* Call the division routine.  */
02515   set_tok_reg (newtok[0], AXP_REG_AT);
02516   set_tok_cpreg (newtok[1], AXP_REG_AT);
02517   set_tok_const (newtok[2], 0);
02518   assemble_tokens ("jsr", newtok, 3, 1);
02519 
02520   /* Move the result to the right place.  */
02521   if (rr != AXP_REG_R0)
02522     {
02523       set_tok_reg (newtok[0], AXP_REG_R0);
02524       set_tok_reg (newtok[1], rr);
02525       assemble_tokens ("mov", newtok, 2, 1);
02526     }
02527 }
02528 
02529 #else /* !OBJ_EVAX */
02530 
02531 static void
02532 emit_division (const expressionS *tok,
02533               int ntok,
02534               const void * symname)
02535 {
02536   /* DIVISION and MODULUS. Yech.
02537      Convert
02538         OP x,y,result
02539      to
02540         lda pv,__OP
02541         mov x,t10
02542         mov y,t11
02543         jsr t9,(pv),__OP
02544         mov t12,result
02545 
02546      with appropriate optimizations if t10,t11,t12 are the registers
02547      specified by the compiler.  */
02548 
02549   int xr, yr, rr;
02550   symbolS *sym;
02551   expressionS newtok[3];
02552 
02553   xr = regno (tok[0].X_add_number);
02554   yr = regno (tok[1].X_add_number);
02555 
02556   if (ntok < 3)
02557     rr = xr;
02558   else
02559     rr = regno (tok[2].X_add_number);
02560 
02561   sym = symbol_find_or_make ((const char *) symname);
02562 
02563   /* Move the operands into the right place.  */
02564   if (yr == AXP_REG_T10 && xr == AXP_REG_T11)
02565     {
02566       /* They are in exactly the wrong order -- swap through AT.  */
02567       if (alpha_noat_on)
02568        as_bad (_("macro requires $at register while noat in effect"));
02569 
02570       set_tok_reg (newtok[0], AXP_REG_T10);
02571       set_tok_reg (newtok[1], AXP_REG_AT);
02572       assemble_tokens ("mov", newtok, 2, 1);
02573 
02574       set_tok_reg (newtok[0], AXP_REG_T11);
02575       set_tok_reg (newtok[1], AXP_REG_T10);
02576       assemble_tokens ("mov", newtok, 2, 1);
02577 
02578       set_tok_reg (newtok[0], AXP_REG_AT);
02579       set_tok_reg (newtok[1], AXP_REG_T11);
02580       assemble_tokens ("mov", newtok, 2, 1);
02581     }
02582   else
02583     {
02584       if (yr == AXP_REG_T10)
02585        {
02586          set_tok_reg (newtok[0], AXP_REG_T10);
02587          set_tok_reg (newtok[1], AXP_REG_T11);
02588          assemble_tokens ("mov", newtok, 2, 1);
02589        }
02590 
02591       if (xr != AXP_REG_T10)
02592        {
02593          set_tok_reg (newtok[0], xr);
02594          set_tok_reg (newtok[1], AXP_REG_T10);
02595          assemble_tokens ("mov", newtok, 2, 1);
02596        }
02597 
02598       if (yr != AXP_REG_T10 && yr != AXP_REG_T11)
02599        {
02600          set_tok_reg (newtok[0], yr);
02601          set_tok_reg (newtok[1], AXP_REG_T11);
02602          assemble_tokens ("mov", newtok, 2, 1);
02603        }
02604     }
02605 
02606   /* Call the division routine.  */
02607   set_tok_reg (newtok[0], AXP_REG_T9);
02608   set_tok_sym (newtok[1], sym, 0);
02609   assemble_tokens ("jsr", newtok, 2, 1);
02610 
02611   /* Reload the GP register.  */
02612 #ifdef OBJ_AOUT
02613 FIXME
02614 #endif
02615 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
02616   set_tok_reg (newtok[0], alpha_gp_register);
02617   set_tok_const (newtok[1], 0);
02618   set_tok_preg (newtok[2], AXP_REG_T9);
02619   assemble_tokens ("ldgp", newtok, 3, 1);
02620 #endif
02621 
02622   /* Move the result to the right place.  */
02623   if (rr != AXP_REG_T12)
02624     {
02625       set_tok_reg (newtok[0], AXP_REG_T12);
02626       set_tok_reg (newtok[1], rr);
02627       assemble_tokens ("mov", newtok, 2, 1);
02628     }
02629 }
02630 
02631 #endif /* !OBJ_EVAX */
02632 
02633 /* The jsr and jmp macros differ from their instruction counterparts
02634    in that they can load the target address and default most
02635    everything.  */
02636 
02637 static void
02638 emit_jsrjmp (const expressionS *tok,
02639             int ntok,
02640             const void * vopname)
02641 {
02642   const char *opname = (const char *) vopname;
02643   struct alpha_insn insn;
02644   expressionS newtok[3];
02645   int r, tokidx = 0;
02646   long lituse = 0;
02647 
02648   if (tokidx < ntok && tok[tokidx].X_op == O_register)
02649     r = regno (tok[tokidx++].X_add_number);
02650   else
02651     r = strcmp (opname, "jmp") == 0 ? AXP_REG_ZERO : AXP_REG_RA;
02652 
02653   set_tok_reg (newtok[0], r);
02654 
02655   if (tokidx < ntok &&
02656       (tok[tokidx].X_op == O_pregister || tok[tokidx].X_op == O_cpregister))
02657     r = regno (tok[tokidx++].X_add_number);
02658 #ifdef OBJ_EVAX
02659   /* Keep register if jsr $n.<sym>.  */
02660 #else
02661   else
02662     {
02663       int basereg = alpha_gp_register;
02664       lituse = load_expression (r = AXP_REG_PV, &tok[tokidx], &basereg, NULL);
02665     }
02666 #endif
02667 
02668   set_tok_cpreg (newtok[1], r);
02669 
02670 #ifdef OBJ_EVAX
02671   /* FIXME: Add hint relocs to BFD for evax.  */
02672 #else
02673   if (tokidx < ntok)
02674     newtok[2] = tok[tokidx];
02675   else
02676 #endif
02677     set_tok_const (newtok[2], 0);
02678 
02679   assemble_tokens_to_insn (opname, newtok, 3, &insn);
02680 
02681   if (lituse)
02682     {
02683       assert (insn.nfixups < MAX_INSN_FIXUPS);
02684       insn.fixups[insn.nfixups].reloc = DUMMY_RELOC_LITUSE_JSR;
02685       insn.fixups[insn.nfixups].exp.X_op = O_absent;
02686       insn.nfixups++;
02687       insn.sequence = lituse;
02688     }
02689 
02690   emit_insn (&insn);
02691 }
02692 
02693 /* The ret and jcr instructions differ from their instruction
02694    counterparts in that everything can be defaulted.  */
02695 
02696 static void
02697 emit_retjcr (const expressionS *tok,
02698             int ntok,
02699             const void * vopname)
02700 {
02701   const char *opname = (const char *) vopname;
02702   expressionS newtok[3];
02703   int r, tokidx = 0;
02704 
02705   if (tokidx < ntok && tok[tokidx].X_op == O_register)
02706     r = regno (tok[tokidx++].X_add_number);
02707   else
02708     r = AXP_REG_ZERO;
02709 
02710   set_tok_reg (newtok[0], r);
02711 
02712   if (tokidx < ntok &&
02713       (tok[tokidx].X_op == O_pregister || tok[tokidx].X_op == O_cpregister))
02714     r = regno (tok[tokidx++].X_add_number);
02715   else
02716     r = AXP_REG_RA;
02717 
02718   set_tok_cpreg (newtok[1], r);
02719 
02720   if (tokidx < ntok)
02721     newtok[2] = tok[tokidx];
02722   else
02723     set_tok_const (newtok[2], strcmp (opname, "ret") == 0);
02724 
02725   assemble_tokens (opname, newtok, 3, 0);
02726 }
02727 
02728 /* Implement the ldgp macro.  */
02729 
02730 static void
02731 emit_ldgp (const expressionS *tok,
02732           int ntok ATTRIBUTE_UNUSED,
02733           const void * unused ATTRIBUTE_UNUSED)
02734 {
02735 #ifdef OBJ_AOUT
02736 FIXME
02737 #endif
02738 #if defined(OBJ_ECOFF) || defined(OBJ_ELF)
02739   /* from "ldgp r1,n(r2)", generate "ldah r1,X(R2); lda r1,Y(r1)"
02740      with appropriate constants and relocations.  */
02741   struct alpha_insn insn;
02742   expressionS newtok[3];
02743   expressionS addend;
02744 
02745 #ifdef OBJ_ECOFF
02746   if (regno (tok[2].X_add_number) == AXP_REG_PV)
02747     ecoff_set_gp_prolog_size (0);
02748 #endif
02749 
02750   newtok[0] = tok[0];
02751   set_tok_const (newtok[1], 0);
02752   newtok[2] = tok[2];
02753 
02754   assemble_tokens_to_insn ("ldah", newtok, 3, &insn);
02755 
02756   addend = tok[1];
02757 
02758 #ifdef OBJ_ECOFF
02759   if (addend.X_op != O_constant)
02760     as_bad (_("can not resolve expression"));
02761   addend.X_op = O_symbol;
02762   addend.X_add_symbol = alpha_gp_symbol;
02763 #endif
02764 
02765   insn.nfixups = 1;
02766   insn.fixups[0].exp = addend;
02767   insn.fixups[0].reloc = BFD_RELOC_ALPHA_GPDISP_HI16;
02768   insn.sequence = next_sequence_num;
02769 
02770   emit_insn (&insn);
02771 
02772   set_tok_preg (newtok[2], tok[0].X_add_number);
02773 
02774   assemble_tokens_to_insn ("lda", newtok, 3, &insn);
02775 
02776 #ifdef OBJ_ECOFF
02777   addend.X_add_number += 4;
02778 #endif
02779 
02780   insn.nfixups = 1;
02781   insn.fixups[0].exp = addend;
02782   insn.fixups[0].reloc = BFD_RELOC_ALPHA_GPDISP_LO16;
02783   insn.sequence = next_sequence_num--;
02784 
02785   emit_insn (&insn);
02786 #endif /* OBJ_ECOFF || OBJ_ELF */
02787 }
02788 
02789 /* The macro table.  */
02790 
02791 static const struct alpha_macro alpha_macros[] =
02792 {
02793 /* Load/Store macros.  */
02794   { "lda",    emit_lda, NULL,
02795     { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
02796   { "ldah",   emit_ldah, NULL,
02797     { MACRO_IR, MACRO_EXP, MACRO_EOA } },
02798 
02799   { "ldl",    emit_ir_load, "ldl",
02800     { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
02801   { "ldl_l",  emit_ir_load, "ldl_l",
02802     { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
02803   { "ldq",    emit_ir_load, "ldq",
02804     { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
02805   { "ldq_l",  emit_ir_load, "ldq_l",
02806     { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
02807   { "ldq_u",  emit_ir_load, "ldq_u",
02808     { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
02809   { "ldf",    emit_loadstore, "ldf",
02810     { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
02811   { "ldg",    emit_loadstore, "ldg",
02812     { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
02813   { "lds",    emit_loadstore, "lds",
02814     { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
02815   { "ldt",    emit_loadstore, "ldt",
02816     { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
02817 
02818   { "ldb",    emit_ldX, (void *) 0,
02819     { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
02820   { "ldbu",   emit_ldXu, (void *) 0,
02821     { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
02822   { "ldw",    emit_ldX, (void *) 1,
02823     { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
02824   { "ldwu",   emit_ldXu, (void *) 1,
02825     { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
02826 
02827   { "uldw",   emit_uldX, (void *) 1,
02828     { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
02829   { "uldwu",  emit_uldXu, (void *) 1,
02830     { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
02831   { "uldl",   emit_uldX, (void *) 2,
02832     { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
02833   { "uldlu",  emit_uldXu, (void *) 2,
02834     { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
02835   { "uldq",   emit_uldXu, (void *) 3,
02836     { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
02837 
02838   { "ldgp",   emit_ldgp, NULL,
02839     { MACRO_IR, MACRO_EXP, MACRO_PIR, MACRO_EOA } },
02840 
02841   { "ldi",    emit_lda, NULL,
02842     { MACRO_IR, MACRO_EXP, MACRO_EOA } },
02843   { "ldil",   emit_ldil, NULL,
02844     { MACRO_IR, MACRO_EXP, MACRO_EOA } },
02845   { "ldiq",   emit_lda, NULL,
02846     { MACRO_IR, MACRO_EXP, MACRO_EOA } },
02847 
02848   { "stl",    emit_loadstore, "stl",
02849     { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
02850   { "stl_c",  emit_loadstore, "stl_c",
02851     { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
02852   { "stq",    emit_loadstore, "stq",
02853     { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
02854   { "stq_c",  emit_loadstore, "stq_c",
02855     { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
02856   { "stq_u",  emit_loadstore, "stq_u",
02857     { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
02858   { "stf",    emit_loadstore, "stf",
02859     { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
02860   { "stg",    emit_loadstore, "stg",
02861     { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
02862   { "sts",    emit_loadstore, "sts",
02863     { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
02864   { "stt",    emit_loadstore, "stt",
02865     { MACRO_FPR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
02866 
02867   { "stb",    emit_stX, (void *) 0,
02868     { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
02869   { "stw",    emit_stX, (void *) 1,
02870     { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
02871   { "ustw",   emit_ustX, (void *) 1,
02872     { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
02873   { "ustl",   emit_ustX, (void *) 2,
02874     { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
02875   { "ustq",   emit_ustX, (void *) 3,
02876     { MACRO_IR, MACRO_EXP, MACRO_OPIR, MACRO_EOA } },
02877 
02878 /* Arithmetic macros.  */
02879 
02880   { "sextb",  emit_sextX, (void *) 0,
02881     { MACRO_IR, MACRO_IR, MACRO_EOA,
02882       MACRO_IR, MACRO_EOA,
02883       /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
02884   { "sextw",  emit_sextX, (void *) 1,
02885     { MACRO_IR, MACRO_IR, MACRO_EOA,
02886       MACRO_IR, MACRO_EOA,
02887       /* MACRO_EXP, MACRO_IR, MACRO_EOA */ } },
02888 
02889   { "divl",   emit_division, "__divl",
02890     { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
02891       MACRO_IR, MACRO_IR, MACRO_EOA,
02892       /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
02893       MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
02894   { "divlu",  emit_division, "__divlu",
02895     { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
02896       MACRO_IR, MACRO_IR, MACRO_EOA,
02897       /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
02898       MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
02899   { "divq",   emit_division, "__divq",
02900     { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
02901       MACRO_IR, MACRO_IR, MACRO_EOA,
02902       /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
02903       MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
02904   { "divqu",  emit_division, "__divqu",
02905     { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
02906       MACRO_IR, MACRO_IR, MACRO_EOA,
02907       /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
02908       MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
02909   { "reml",   emit_division, "__reml",
02910     { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
02911       MACRO_IR, MACRO_IR, MACRO_EOA,
02912       /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
02913       MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
02914   { "remlu",  emit_division, "__remlu",
02915     { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
02916       MACRO_IR, MACRO_IR, MACRO_EOA,
02917       /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
02918       MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
02919   { "remq",   emit_division, "__remq",
02920     { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
02921       MACRO_IR, MACRO_IR, MACRO_EOA,
02922       /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
02923       MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
02924   { "remqu",  emit_division, "__remqu",
02925     { MACRO_IR, MACRO_IR, MACRO_IR, MACRO_EOA,
02926       MACRO_IR, MACRO_IR, MACRO_EOA,
02927       /* MACRO_IR, MACRO_EXP, MACRO_IR, MACRO_EOA,
02928       MACRO_IR, MACRO_EXP, MACRO_EOA */ } },
02929 
02930   { "jsr",    emit_jsrjmp, "jsr",
02931     { MACRO_PIR, MACRO_EXP, MACRO_EOA,
02932       MACRO_PIR, MACRO_EOA,
02933       MACRO_IR,  MACRO_EXP, MACRO_EOA,
02934       MACRO_EXP, MACRO_EOA } },
02935   { "jmp",    emit_jsrjmp, "jmp",
02936     { MACRO_PIR, MACRO_EXP, MACRO_EOA,
02937       MACRO_PIR, MACRO_EOA,
02938       MACRO_IR,  MACRO_EXP, MACRO_EOA,
02939       MACRO_EXP, MACRO_EOA } },
02940   { "ret",    emit_retjcr, "ret",
02941     { MACRO_IR, MACRO_EXP, MACRO_EOA,
02942       MACRO_IR, MACRO_EOA,
02943       MACRO_PIR, MACRO_EXP, MACRO_EOA,
02944       MACRO_PIR, MACRO_EOA,
02945       MACRO_EXP, MACRO_EOA,
02946       MACRO_EOA } },
02947   { "jcr",    emit_retjcr, "jcr",
02948     { MACRO_IR,  MACRO_EXP, MACRO_EOA,
02949       MACRO_IR,  MACRO_EOA,
02950       MACRO_PIR, MACRO_EXP, MACRO_EOA,
02951       MACRO_PIR, MACRO_EOA,
02952       MACRO_EXP, MACRO_EOA,
02953       MACRO_EOA } },
02954   { "jsr_coroutine", emit_retjcr, "jcr",
02955     { MACRO_IR,  MACRO_EXP, MACRO_EOA,
02956       MACRO_IR,  MACRO_EOA,
02957       MACRO_PIR, MACRO_EXP, MACRO_EOA,
02958       MACRO_PIR, MACRO_EOA,
02959       MACRO_EXP, MACRO_EOA,
02960       MACRO_EOA } },
02961 };
02962 
02963 static const unsigned int alpha_num_macros
02964   = sizeof (alpha_macros) / sizeof (*alpha_macros);
02965 
02966 /* Search forward through all variants of a macro looking for a syntax
02967    match.  */
02968 
02969 static const struct alpha_macro *
02970 find_macro_match (const struct alpha_macro *first_macro,
02971                 const expressionS *tok,
02972                 int *pntok)
02973 
02974 {
02975   const struct alpha_macro *macro = first_macro;
02976   int ntok = *pntok;
02977 
02978   do
02979     {
02980       const enum alpha_macro_arg *arg = macro->argsets;
02981       int tokidx = 0;
02982 
02983       while (*arg)
02984        {
02985          switch (*arg)
02986            {
02987            case MACRO_EOA:
02988              if (tokidx == ntok)
02989               return macro;
02990              else
02991               tokidx = 0;
02992              break;
02993 
02994              /* Index register.  */
02995            case MACRO_IR:
02996              if (tokidx >= ntok || tok[tokidx].X_op != O_register
02997                 || !is_ir_num (tok[tokidx].X_add_number))
02998               goto match_failed;
02999              ++tokidx;
03000              break;
03001 
03002              /* Parenthesized index register.  */
03003            case MACRO_PIR:
03004              if (tokidx >= ntok || tok[tokidx].X_op != O_pregister
03005                 || !is_ir_num (tok[tokidx].X_add_number))
03006               goto match_failed;
03007              ++tokidx;
03008              break;
03009 
03010              /* Optional parenthesized index register.  */
03011            case MACRO_OPIR:
03012              if (tokidx < ntok && tok[tokidx].X_op == O_pregister
03013                 && is_ir_num (tok[tokidx].X_add_number))
03014               ++tokidx;
03015              break;
03016 
03017              /* Leading comma with a parenthesized index register.  */
03018            case MACRO_CPIR:
03019              if (tokidx >= ntok || tok[tokidx].X_op != O_cpregister
03020                 || !is_ir_num (tok[tokidx].X_add_number))
03021               goto match_failed;
03022              ++tokidx;
03023              break;
03024 
03025              /* Floating point register.  */
03026            case MACRO_FPR:
03027              if (tokidx >= ntok || tok[tokidx].X_op != O_register
03028                 || !is_fpr_num (tok[tokidx].X_add_number))
03029               goto match_failed;
03030              ++tokidx;
03031              break;
03032 
03033              /* Normal expression.  */
03034            case MACRO_EXP:
03035              if (tokidx >= ntok)
03036               goto match_failed;
03037              switch (tok[tokidx].X_op)
03038               {
03039               case O_illegal:
03040               case O_absent:
03041               case O_register:
03042               case O_pregister:
03043               case O_cpregister:
03044               case O_literal:
03045               case O_lituse_base:
03046               case O_lituse_bytoff:
03047               case O_lituse_jsr:
03048               case O_gpdisp:
03049               case O_gprelhigh:
03050               case O_gprellow:
03051               case O_gprel:
03052               case O_samegp:
03053                 goto match_failed;
03054 
03055               default:
03056                 break;
03057               }
03058              ++tokidx;
03059              break;
03060 
03061            match_failed:
03062              while (*arg != MACRO_EOA)
03063               ++arg;
03064              tokidx = 0;
03065              break;
03066            }
03067          ++arg;
03068        }
03069     }
03070   while (++macro - alpha_macros < (int) alpha_num_macros
03071         && !strcmp (macro->name, first_macro->name));
03072 
03073   return NULL;
03074 }
03075 
03076 /* Given an opcode name and a pre-tokenized set of arguments, take the
03077    opcode all the way through emission.  */
03078 
03079 static void
03080 assemble_tokens (const char *opname,
03081                const expressionS *tok,
03082                int ntok,
03083                int local_macros_on)
03084 {
03085   int found_something = 0;
03086   const struct alpha_opcode *opcode;
03087   const struct alpha_macro *macro;
03088   int cpumatch = 1;
03089   bfd_reloc_code_real_type reloc = BFD_RELOC_UNUSED;
03090 
03091 #ifdef RELOC_OP_P
03092   /* If a user-specified relocation is present, this is not a macro.  */
03093   if (ntok && USER_RELOC_P (tok[ntok - 1].X_op))
03094     {
03095       reloc = ALPHA_RELOC_TABLE (tok[ntok - 1].X_op)->reloc;
03096       ntok--;
03097     }
03098   else
03099 #endif
03100   if (local_macros_on)
03101     {
03102       macro = ((const struct alpha_macro *)
03103               hash_find (alpha_macro_hash, opname));
03104       if (macro)
03105        {
03106          found_something = 1;
03107          macro = find_macro_match (macro, tok, &ntok);
03108          if (macro)
03109            {
03110              (*macro->emit) (tok, ntok, macro->arg);
03111              return;
03112            }
03113        }
03114     }
03115 
03116   /* Search opcodes.  */
03117   opcode = (const struct alpha_opcode *) hash_find (alpha_opcode_hash, opname);
03118   if (opcode)
03119     {
03120       found_something = 1;
03121       opcode = find_opcode_match (opcode, tok, &ntok, &cpumatch);
03122       if (opcode)
03123        {
03124          struct alpha_insn insn;
03125          assemble_insn (opcode, tok, ntok, &insn, reloc);
03126 
03127          /* Copy the sequence number for the reloc from the reloc token.  */
03128          if (reloc != BFD_RELOC_UNUSED)
03129            insn.sequence = tok[ntok].X_add_number;
03130 
03131          emit_insn (&insn);
03132          return;
03133        }
03134     }
03135 
03136   if (found_something)
03137     {
03138       if (cpumatch)
03139        as_bad (_("inappropriate arguments for opcode `%s'"), opname);
03140       else
03141        as_bad (_("opcode `%s' not supported for target %s"), opname,
03142               alpha_target_name);
03143     }
03144   else
03145     as_bad (_("unknown opcode `%s'"), opname);
03146 }
03147 
03148 #ifdef OBJ_EVAX
03149 
03150 /* Add symbol+addend to link pool.
03151    Return offset from basesym to entry in link pool.
03152 
03153    Add new fixup only if offset isn't 16bit.  */
03154 
03155 valueT
03156 add_to_link_pool (symbolS *basesym,
03157                 symbolS *sym,
03158                 offsetT addend)
03159 {
03160   segT current_section = now_seg;
03161   int current_subsec = now_subseg;
03162   valueT offset;
03163   bfd_reloc_code_real_type reloc_type;
03164   char *p;
03165   segment_info_type *seginfo = seg_info (alpha_link_section);
03166   fixS *fixp;
03167 
03168   offset = - *symbol_get_obj (basesym);
03169 
03170   /* @@ This assumes all entries in a given section will be of the same
03171      size...  Probably correct, but unwise to rely on.  */
03172   /* This must always be called with the same subsegment.  */
03173 
03174   if (seginfo->frchainP)
03175     for (fixp = seginfo->frchainP->fix_root;
03176         fixp != (fixS *) NULL;
03177         fixp = fixp->fx_next, offset += 8)
03178       {
03179        if (fixp->fx_addsy == sym && fixp->fx_offset == addend)
03180          {
03181            if (range_signed_16 (offset))
03182              {
03183               return offset;
03184              }
03185          }
03186       }
03187 
03188   /* Not found in 16bit signed range.  */
03189 
03190   subseg_set (alpha_link_section, 0);
03191   p = frag_more (8);
03192   memset (p, 0, 8);
03193 
03194   fix_new (frag_now, p - frag_now->fr_literal, 8, sym, addend, 0,
03195           BFD_RELOC_64);
03196 
03197   subseg_set (current_section, current_subsec);
03198   seginfo->literal_pool_size += 8;
03199   return offset;
03200 }
03201 
03202 #endif /* OBJ_EVAX */
03203 
03204 /* Assembler directives.  */
03205 
03206 /* Handle the .text pseudo-op.  This is like the usual one, but it
03207    clears alpha_insn_label and restores auto alignment.  */
03208 
03209 static void
03210 s_alpha_text (int i)
03211 
03212 {
03213 #ifdef OBJ_ELF
03214   obj_elf_text (i);
03215 #else
03216   s_text (i);
03217 #endif
03218   alpha_insn_label = NULL;
03219   alpha_auto_align_on = 1;
03220   alpha_current_align = 0;
03221 }
03222 
03223 /* Handle the .data pseudo-op.  This is like the usual one, but it
03224    clears alpha_insn_label and restores auto alignment.  */
03225 
03226 static void
03227 s_alpha_data (int i)
03228 {
03229 #ifdef OBJ_ELF
03230   obj_elf_data (i);
03231 #else
03232   s_data (i);
03233 #endif
03234   alpha_insn_label = NULL;
03235   alpha_auto_align_on = 1;
03236   alpha_current_align = 0;
03237 }
03238 
03239 #if defined (OBJ_ECOFF) || defined (OBJ_EVAX)
03240 
03241 /* Handle the OSF/1 and openVMS .comm pseudo quirks.
03242    openVMS constructs a section for every common symbol.  */
03243 
03244 static void
03245 s_alpha_comm (int ignore ATTRIBUTE_UNUSED)
03246 {
03247   char *name;
03248   char c;
03249   char *p;
03250   offsetT temp;
03251   symbolS *symbolP;
03252 #ifdef OBJ_EVAX
03253   segT current_section = now_seg;
03254   int current_subsec = now_subseg;
03255   segT new_seg;
03256 #endif
03257 
03258   name = input_line_pointer;
03259   c = get_symbol_end ();
03260 
03261   /* Just after name is now '\0'.  */
03262   p = input_line_pointer;
03263   *p = c;
03264 
03265   SKIP_WHITESPACE ();
03266 
03267   /* Alpha OSF/1 compiler doesn't provide the comma, gcc does.  */
03268   if (*input_line_pointer == ',')
03269     {
03270       input_line_pointer++;
03271       SKIP_WHITESPACE ();
03272     }
03273   if ((temp = get_absolute_expression ()) < 0)
03274     {
03275       as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) temp);
03276       ignore_rest_of_line ();
03277       return;
03278     }
03279 
03280   *p = 0;
03281   symbolP = symbol_find_or_make (name);
03282 
03283 #ifdef OBJ_EVAX
03284   /* Make a section for the common symbol.  */
03285   new_seg = subseg_new (xstrdup (name), 0);
03286 #endif
03287 
03288   *p = c;
03289 
03290 #ifdef OBJ_EVAX
03291   /* Alignment might follow.  */
03292   if (*input_line_pointer == ',')
03293     {
03294       offsetT align;
03295 
03296       input_line_pointer++;
03297       align = get_absolute_expression ();
03298       bfd_set_section_alignment (stdoutput, new_seg, align);
03299     }
03300 #endif
03301 
03302   if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
03303     {
03304       as_bad (_("Ignoring attempt to re-define symbol"));
03305       ignore_rest_of_line ();
03306       return;
03307     }
03308 
03309 #ifdef OBJ_EVAX
03310   if (bfd_section_size (stdoutput, new_seg) > 0)
03311     {
03312       if (bfd_section_size (stdoutput, new_seg) != temp)
03313        as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
03314               S_GET_NAME (symbolP),
03315               (long) bfd_section_size (stdoutput, new_seg),
03316               (long) temp);
03317     }
03318 #else
03319   if (S_GET_VALUE (symbolP))
03320     {
03321       if (S_GET_VALUE (symbolP) != (valueT) temp)
03322        as_bad (_("Length of .comm \"%s\" is already %ld. Not changed to %ld."),
03323               S_GET_NAME (symbolP),
03324               (long) S_GET_VALUE (symbolP),
03325               (long) temp);
03326     }
03327 #endif
03328   else
03329     {
03330 #ifdef OBJ_EVAX
03331       subseg_set (new_seg, 0);
03332       p = frag_more (temp);
03333       new_seg->flags |= SEC_IS_COMMON;
03334       S_SET_SEGMENT (symbolP, new_seg);
03335 #else
03336       S_SET_VALUE (symbolP, (valueT) temp);
03337       S_SET_SEGMENT (symbolP, bfd_com_section_ptr);
03338 #endif
03339       S_SET_EXTERNAL (symbolP);
03340     }
03341 
03342 #ifdef OBJ_EVAX
03343   subseg_set (current_section, current_subsec);
03344 #endif
03345 
03346   know (symbol_get_frag (symbolP) == &zero_address_frag);
03347 
03348   demand_empty_rest_of_line ();
03349 }
03350 
03351 #endif /* ! OBJ_ELF */
03352 
03353 #ifdef OBJ_ECOFF
03354 
03355 /* Handle the .rdata pseudo-op.  This is like the usual one, but it
03356    clears alpha_insn_label and restores auto alignment.  */
03357 
03358 static void
03359 s_alpha_rdata (int ignore ATTRIBUTE_UNUSED)
03360 {
03361   int temp;
03362 
03363   temp = get_absolute_expression ();
03364   subseg_new (".rdata", 0);
03365   demand_empty_rest_of_line ();
03366   alpha_insn_label = NULL;
03367   alpha_auto_align_on = 1;
03368   alpha_current_align = 0;
03369 }
03370 
03371 #endif
03372 
03373 #ifdef OBJ_ECOFF
03374 
03375 /* Handle the .sdata pseudo-op.  This is like the usual one, but it
03376    clears alpha_insn_label and restores auto alignment.  */
03377 
03378 static void
03379 s_alpha_sdata (int ignore ATTRIBUTE_UNUSED)
03380 {
03381   int temp;
03382 
03383   temp = get_absolute_expression ();
03384   subseg_new (".sdata", 0);
03385   demand_empty_rest_of_line ();
03386   alpha_insn_label = NULL;
03387   alpha_auto_align_on = 1;
03388   alpha_current_align = 0;
03389 }
03390 #endif
03391 
03392 #ifdef OBJ_ELF
03393 struct alpha_elf_frame_data
03394 {
03395   symbolS *func_sym;
03396   symbolS *func_end_sym;
03397   symbolS *prologue_sym;
03398   unsigned int mask;
03399   unsigned int fmask;
03400   int fp_regno;
03401   int ra_regno;
03402   offsetT frame_size;
03403   offsetT mask_offset;
03404   offsetT fmask_offset;
03405 
03406   struct alpha_elf_frame_data *next;
03407 };
03408 
03409 static struct alpha_elf_frame_data *all_frame_data;
03410 static struct alpha_elf_frame_data **plast_frame_data = &all_frame_data;
03411 static struct alpha_elf_frame_data *cur_frame_data;
03412 
03413 /* Handle the .section pseudo-op.  This is like the usual one, but it
03414    clears alpha_insn_label and restores auto alignment.  */
03415 
03416 static void
03417 s_alpha_section (int ignore ATTRIBUTE_UNUSED)
03418 {
03419   obj_elf_section (ignore);
03420 
03421   alpha_insn_label = NULL;
03422   alpha_auto_align_on = 1;
03423   alpha_current_align = 0;
03424 }
03425 
03426 static void
03427 s_alpha_ent (int dummy ATTRIBUTE_UNUSED)
03428 {
03429   if (ECOFF_DEBUGGING)
03430     ecoff_directive_ent (0);
03431   else
03432     {
03433       char *name, name_end;
03434       name = input_line_pointer;
03435       name_end = get_symbol_end ();
03436 
03437       if (! is_name_beginner (*name))
03438        {
03439          as_warn (_(".ent directive has no name"));
03440          *input_line_pointer = name_end;
03441        }
03442       else
03443        {
03444          symbolS *sym;
03445 
03446          if (cur_frame_data)
03447            as_warn (_("nested .ent directives"));
03448 
03449          sym = symbol_find_or_make (name);
03450          symbol_get_bfdsym (sym)->flags |= BSF_FUNCTION;
03451 
03452          cur_frame_data = calloc (1, sizeof (*cur_frame_data));
03453          cur_frame_data->func_sym = sym;
03454 
03455          /* Provide sensible defaults.  */
03456          cur_frame_data->fp_regno = 30;   /* sp */
03457          cur_frame_data->ra_regno = 26;   /* ra */
03458 
03459          *plast_frame_data = cur_frame_data;
03460          plast_frame_data = &cur_frame_data->next;
03461 
03462          /* The .ent directive is sometimes followed by a number.  Not sure
03463             what it really means, but ignore it.  */
03464          *input_line_pointer = name_end;
03465          SKIP_WHITESPACE ();
03466          if (*input_line_pointer == ',')
03467            {
03468              input_line_pointer++;
03469              SKIP_WHITESPACE ();
03470            }
03471          if (ISDIGIT (*input_line_pointer) || *input_line_pointer == '-')
03472            (void) get_absolute_expression ();
03473        }
03474       demand_empty_rest_of_line ();
03475     }
03476 }
03477 
03478 static void
03479 s_alpha_end (int dummy ATTRIBUTE_UNUSED)
03480 {
03481   if (ECOFF_DEBUGGING)
03482     ecoff_directive_end (0);
03483   else
03484     {
03485       char *name, name_end;
03486       name = input_line_pointer;
03487       name_end = get_symbol_end ();
03488 
03489       if (! is_name_beginner (*name))
03490        {
03491          as_warn (_(".end directive has no name"));
03492          *input_line_pointer = name_end;
03493        }
03494       else
03495        {
03496          symbolS *sym;
03497 
03498          sym = symbol_find (name);
03499          if (!cur_frame_data)
03500            as_warn (_(".end directive without matching .ent"));
03501          else if (sym != cur_frame_data->func_sym)
03502            as_warn (_(".end directive names different symbol than .ent"));
03503 
03504          /* Create an expression to calculate the size of the function.  */
03505          if (sym && cur_frame_data)
03506            {
03507              OBJ_SYMFIELD_TYPE *obj = symbol_get_obj (sym);
03508              expressionS *exp = xmalloc (sizeof (expressionS));
03509 
03510              obj->size = exp;
03511              exp->X_op = O_subtract;
03512              exp->X_add_symbol = symbol_temp_new_now ();
03513              exp->X_op_symbol = sym;
03514              exp->X_add_number = 0;
03515 
03516              cur_frame_data->func_end_sym = exp->X_add_symbol;
03517            }
03518 
03519          cur_frame_data = NULL;
03520 
03521          *input_line_pointer = name_end;
03522        }
03523       demand_empty_rest_of_line ();
03524     }
03525 }
03526 
03527 static void
03528 s_alpha_mask (int fp)
03529 {
03530   if (ECOFF_DEBUGGING)
03531     {
03532       if (fp)
03533        ecoff_directive_fmask (0);
03534       else
03535        ecoff_directive_mask (0);
03536     }
03537   else
03538     {
03539       long val;
03540       offsetT offset;
03541 
03542       if (!cur_frame_data)
03543        {
03544          if (fp)
03545            as_warn (_(".fmask outside of .ent"));
03546          else
03547            as_warn (_(".mask outside of .ent"));
03548          discard_rest_of_line ();
03549          return;
03550        }
03551 
03552       if (get_absolute_expression_and_terminator (&val) != ',')
03553        {
03554          if (fp)
03555            as_warn (_("bad .fmask directive"));
03556          else
03557            as_warn (_("bad .mask directive"));
03558          --input_line_pointer;
03559          discard_rest_of_line ();
03560          return;
03561        }
03562 
03563       offset = get_absolute_expression ();
03564       demand_empty_rest_of_line ();
03565 
03566       if (fp)
03567        {
03568          cur_frame_data->fmask = val;
03569           cur_frame_data->fmask_offset = offset;
03570        }
03571       else
03572        {
03573          cur_frame_data->mask = val;
03574          cur_frame_data->mask_offset = offset;
03575        }
03576     }
03577 }
03578 
03579 static void
03580 s_alpha_frame (int dummy ATTRIBUTE_UNUSED)
03581 {
03582   if (ECOFF_DEBUGGING)
03583     ecoff_directive_frame (0);
03584   else
03585     {
03586       long val;
03587 
03588       if (!cur_frame_data)
03589        {
03590          as_warn (_(".frame outside of .ent"));
03591          discard_rest_of_line ();
03592          return;
03593        }
03594 
03595       cur_frame_data->fp_regno = tc_get_register (1);
03596 
03597       SKIP_WHITESPACE ();
03598       if (*input_line_pointer++ != ','
03599          || get_absolute_expression_and_terminator (&val) != ',')
03600        {
03601          as_warn (_("bad .frame directive"));
03602          --input_line_pointer;
03603          discard_rest_of_line ();
03604          return;
03605        }
03606       cur_frame_data->frame_size = val;
03607 
03608       cur_frame_data->ra_regno = tc_get_register (0);
03609 
03610       /* Next comes the "offset of saved $a0 from $sp".  In gcc terms
03611         this is current_function_pretend_args_size.  There's no place
03612         to put this value, so ignore it.  */
03613       s_ignore (42);
03614     }
03615 }
03616 
03617 static void
03618 s_alpha_prologue (int ignore ATTRIBUTE_UNUSED)
03619 {
03620   symbolS *sym;
03621   int arg;
03622 
03623   arg = get_absolute_expression ();
03624   demand_empty_rest_of_line ();
03625 
03626   if (ECOFF_DEBUGGING)
03627     sym = ecoff_get_cur_proc_sym ();
03628   else
03629     sym = cur_frame_data ? cur_frame_data->func_sym : NULL;
03630 
03631   if (sym == NULL)
03632     {
03633       as_bad (_(".prologue directive without a preceding .ent directive"));
03634       return;
03635     }
03636 
03637   switch (arg)
03638     {
03639     case 0: /* No PV required.  */
03640       S_SET_OTHER (sym, STO_ALPHA_NOPV
03641                  | (S_GET_OTHER (sym) & ~STO_ALPHA_STD_GPLOAD));
03642       break;
03643     case 1: /* Std GP load.  */
03644       S_SET_OTHER (sym, STO_ALPHA_STD_GPLOAD
03645                  | (S_GET_OTHER (sym) & ~STO_ALPHA_STD_GPLOAD));
03646       break;
03647     case 2: /* Non-std use of PV.  */
03648       break;
03649 
03650     default:
03651       as_bad (_("Invalid argument %d to .prologue."), arg);
03652       break;
03653     }
03654 
03655   if (cur_frame_data)
03656     cur_frame_data->prologue_sym = symbol_temp_new_now ();
03657 }
03658 
03659 static char *first_file_directive;
03660 
03661 static void
03662 s_alpha_file (int ignore ATTRIBUTE_UNUSED)
03663 {
03664   /* Save the first .file directive we see, so that we can change our
03665      minds about whether ecoff debugging should or shouldn't be enabled.  */
03666   if (alpha_flag_mdebug < 0 && ! first_file_directive)
03667     {
03668       char *start = input_line_pointer;
03669       size_t len;
03670 
03671       discard_rest_of_line ();
03672 
03673       len = input_line_pointer - start;
03674       first_file_directive = xmalloc (len + 1);
03675       memcpy (first_file_directive, start, len);
03676       first_file_directive[len] = '\0';
03677 
03678       input_line_pointer = start;
03679     }
03680 
03681   if (ECOFF_DEBUGGING)
03682     ecoff_directive_file (0);
03683   else
03684     dwarf2_directive_file (0);
03685 }
03686 
03687 static void
03688 s_alpha_loc (int ignore ATTRIBUTE_UNUSED)
03689 {
03690   if (ECOFF_DEBUGGING)
03691     ecoff_directive_loc (0);
03692   else
03693     dwarf2_directive_loc (0);
03694 }
03695 
03696 static void
03697 s_alpha_stab (int n)
03698 {
03699   /* If we've been undecided about mdebug, make up our minds in favour.  */
03700   if (alpha_flag_mdebug < 0)
03701     {
03702       segT sec = subseg_new (".mdebug", 0);
03703       bfd_set_section_flags (stdoutput, sec, SEC_HAS_CONTENTS | SEC_READONLY);
03704       bfd_set_section_alignment (stdoutput, sec, 3);
03705 
03706       ecoff_read_begin_hook ();
03707 
03708       if (first_file_directive)
03709        {
03710          char *save_ilp = input_line_pointer;
03711          input_line_pointer = first_file_directive;
03712          ecoff_directive_file (0);
03713          input_line_pointer = save_ilp;
03714          free (first_file_directive);
03715        }
03716 
03717       alpha_flag_mdebug = 1;
03718     }
03719   s_stab (n);
03720 }
03721 
03722 static void
03723 s_alpha_coff_wrapper (int which)
03724 {
03725   static void (* const fns[]) PARAMS ((int)) = {
03726     ecoff_directive_begin,
03727     ecoff_directive_bend,
03728     ecoff_directive_def,
03729     ecoff_directive_dim,
03730     ecoff_directive_endef,
03731     ecoff_directive_scl,
03732     ecoff_directive_tag,
03733     ecoff_directive_val,
03734   };
03735 
03736   assert (which >= 0 && which < (int) (sizeof (fns)/sizeof (*fns)));
03737 
03738   if (ECOFF_DEBUGGING)
03739     (*fns[which]) (0);
03740   else
03741     {
03742       as_bad (_("ECOFF debugging is disabled."));
03743       ignore_rest_of_line ();
03744     }
03745 }
03746 
03747 /* Called at the end of assembly.  Here we emit unwind info for frames
03748    unless the compiler has done it for us.  */
03749 
03750 void
03751 alpha_elf_md_end (void)
03752 {
03753   struct alpha_elf_frame_data *p;
03754 
03755   if (cur_frame_data)
03756     as_warn (_(".ent directive without matching .end"));
03757 
03758   /* If someone has generated the unwind info themselves, great.  */
03759   if (bfd_get_section_by_name (stdoutput, ".eh_frame") != NULL)
03760     return;
03761 
03762   /* Generate .eh_frame data for the unwind directives specified.  */
03763   for (p = all_frame_data; p ; p = p->next)
03764     if (p->prologue_sym)
03765       {
03766        /* Create a temporary symbol at the same location as our
03767           function symbol.  This prevents problems with globals.  */
03768        cfi_new_fde (symbol_temp_new (S_GET_SEGMENT (p->func_sym),
03769                                   S_GET_VALUE (p->func_sym),
03770                                   symbol_get_frag (p->func_sym)));
03771 
03772        cfi_set_return_column (p->ra_regno);
03773        cfi_add_CFA_def_cfa_register (30);
03774        if (p->fp_regno != 30 || p->mask || p->fmask || p->frame_size)
03775          {
03776            unsigned int mask;
03777            offsetT offset;
03778 
03779            cfi_add_advance_loc (p->prologue_sym);
03780 
03781            if (p->fp_regno != 30)
03782              if (p->frame_size != 0)
03783               cfi_add_CFA_def_cfa (p->fp_regno, p->frame_size);
03784              else
03785               cfi_add_CFA_def_cfa_register (p->fp_regno);
03786            else if (p->frame_size != 0)
03787              cfi_add_CFA_def_cfa_offset (p->frame_size);
03788 
03789            mask = p->mask;
03790            offset = p->mask_offset;
03791 
03792            /* Recall that $26 is special-cased and stored first.  */
03793            if ((mask >> 26) & 1)
03794              {
03795                cfi_add_CFA_offset (26, offset);
03796               offset += 8;
03797               mask &= ~(1 << 26);
03798              }
03799            while (mask)
03800              {
03801               unsigned int i;
03802               i = mask & -mask;
03803               mask ^= i;
03804               i = ffs (i) - 1;
03805 
03806               cfi_add_CFA_offset (i, offset);
03807               offset += 8;
03808              }
03809 
03810            mask = p->fmask;
03811            offset = p->fmask_offset;
03812            while (mask)
03813              {
03814               unsigned int i;
03815               i = mask & -mask;
03816               mask ^= i;
03817               i = ffs (i) - 1;
03818 
03819               cfi_add_CFA_offset (i + 32, offset);
03820               offset += 8;
03821              }
03822          }
03823 
03824        cfi_end_fde (p->func_end_sym);
03825       }
03826 }
03827 
03828 static void
03829 s_alpha_usepv (int unused ATTRIBUTE_UNUSED)
03830 {
03831   char *name, name_end;
03832   char *which, which_end;
03833   symbolS *sym;
03834   int other;
03835 
03836   name = input_line_pointer;
03837   name_end = get_symbol_end ();
03838 
03839   if (! is_name_beginner (*name))
03840     {
03841       as_bad (_(".usepv directive has no name"));
03842       *input_line_pointer = name_end;
03843       ignore_rest_of_line ();
03844       return;
03845     }
03846 
03847   sym = symbol_find_or_make (name);
03848   *input_line_pointer++ = name_end;
03849 
03850   if (name_end != ',')
03851     {
03852       as_bad (_(".usepv directive has no type"));
03853       ignore_rest_of_line ();
03854       return;
03855     }
03856 
03857   SKIP_WHITESPACE ();
03858   which = input_line_pointer;
03859   which_end = get_symbol_end ();
03860 
03861   if (strcmp (which, "no") == 0)
03862     other = STO_ALPHA_NOPV;
03863   else if (strcmp (which, "std") == 0)
03864     other = STO_ALPHA_STD_GPLOAD;
03865   else
03866     {
03867       as_bad (_("unknown argument for .usepv"));
03868       other = 0;
03869     }
03870 
03871   *input_line_pointer = which_end;
03872   demand_empty_rest_of_line ();
03873 
03874   S_SET_OTHER (sym, other | (S_GET_OTHER (sym) & ~STO_ALPHA_STD_GPLOAD));
03875 }
03876 #endif /* OBJ_ELF */
03877 
03878 /* Standard calling conventions leaves the CFA at $30 on entry.  */
03879 
03880 void
03881 alpha_cfi_frame_initial_instructions (void)
03882 {
03883   cfi_add_CFA_def_cfa_register (30);
03884 }
03885 
03886 #ifdef OBJ_EVAX
03887 
03888 /* Handle the section specific pseudo-op.  */
03889 
03890 static void
03891 s_alpha_section (int secid)
03892 {
03893   int temp;
03894 #define EVAX_SECTION_COUNT 5
03895   static char *section_name[EVAX_SECTION_COUNT + 1] =
03896     { "NULL", ".rdata", ".comm", ".link", ".ctors", ".dtors" };
03897 
03898   if ((secid <= 0) || (secid > EVAX_SECTION_COUNT))
03899     {
03900       as_fatal (_("Unknown section directive"));
03901       demand_empty_rest_of_line ();
03902       return;
03903     }
03904   temp = get_absolute_expression ();
03905   subseg_new (section_name[secid], 0);
03906   demand_empty_rest_of_line ();
03907   alpha_insn_label = NULL;
03908   alpha_auto_align_on = 1;
03909   alpha_current_align = 0;
03910 }
03911 
03912 /* Parse .ent directives.  */
03913 
03914 static void
03915 s_alpha_ent (int ignore ATTRIBUTE_UNUSED)
03916 {
03917   symbolS *symbol;
03918   expressionS symexpr;
03919 
03920   alpha_evax_proc.pdsckind = 0;
03921   alpha_evax_proc.framereg = -1;
03922   alpha_evax_proc.framesize = 0;
03923   alpha_evax_proc.rsa_offset = 0;
03924   alpha_evax_proc.ra_save = AXP_REG_RA;
03925   alpha_evax_proc.fp_save = -1;
03926   alpha_evax_proc.imask = 0;
03927   alpha_evax_proc.fmask = 0;
03928   alpha_evax_proc.prologue = 0;
03929   alpha_evax_proc.type = 0;
03930 
03931   expression (&symexpr);
03932 
03933   if (symexpr.X_op != O_symbol)
03934     {
03935       as_fatal (_(".ent directive has no symbol"));
03936       demand_empty_rest_of_line ();
03937       return;
03938     }
03939 
03940   symbol = make_expr_symbol (&symexpr);
03941   symbol_get_bfdsym (symbol)->flags |= BSF_FUNCTION;
03942   alpha_evax_proc.symbol = symbol;
03943 
03944   demand_empty_rest_of_line ();
03945 }
03946 
03947 /* Parse .frame <framreg>,<framesize>,RA,<rsa_offset> directives.  */
03948 
03949 static void
03950 s_alpha_frame (int ignore ATTRIBUTE_UNUSED)
03951 {
03952   long val;
03953 
03954   alpha_evax_proc.framereg = tc_get_register (1);
03955 
03956   SKIP_WHITESPACE ();
03957   if (*input_line_pointer++ != ','
03958       || get_absolute_expression_and_terminator (&val) != ',')
03959     {
03960       as_warn (_("Bad .frame directive 1./2. param"));
03961       --input_line_pointer;
03962       demand_empty_rest_of_line ();
03963       return;
03964     }
03965 
03966   alpha_evax_proc.framesize = val;
03967 
03968   (void) tc_get_register (1);
03969   SKIP_WHITESPACE ();
03970   if (*input_line_pointer++ != ',')
03971     {
03972       as_warn (_("Bad .frame directive 3./4. param"));
03973       --input_line_pointer;
03974       demand_empty_rest_of_line ();
03975       return;
03976     }
03977   alpha_evax_proc.rsa_offset = get_absolute_expression ();
03978 }
03979 
03980 static void
03981 s_alpha_pdesc (int ignore ATTRIBUTE_UNUSED)
03982 {
03983   char *name;
03984   char name_end;
03985   long val;
03986   register char *p;
03987   expressionS exp;
03988   symbolS *entry_sym;
03989   fixS *fixp;
03990   segment_info_type *seginfo = seg_info (alpha_link_section);
03991 
03992   if (now_seg != alpha_link_section)
03993     {
03994       as_bad (_(".pdesc directive not in link (.link) section"));
03995       demand_empty_rest_of_line ();
03996       return;
03997     }
03998 
03999   if ((alpha_evax_proc.symbol == 0)
04000       || (!S_IS_DEFINED (alpha_evax_proc.symbol)))
04001     {
04002       as_fatal (_(".pdesc has no matching .ent"));
04003       demand_empty_rest_of_line ();
04004       return;
04005     }
04006 
04007   *symbol_get_obj (alpha_evax_proc.symbol) =
04008     (valueT) seginfo->literal_pool_size;
04009 
04010   expression (&exp);
04011   if (exp.X_op != O_symbol)
04012     {
04013       as_warn (_(".pdesc directive has no entry symbol"));
04014       demand_empty_rest_of_line ();
04015       return;
04016     }
04017 
04018   entry_sym = make_expr_symbol (&exp);
04019   /* Save bfd symbol of proc desc in function symbol.  */
04020   symbol_get_bfdsym (alpha_evax_proc.symbol)->udata.p
04021     = symbol_get_bfdsym (entry_sym);
04022 
04023   SKIP_WHITESPACE ();
04024   if (*input_line_pointer++ != ',')
04025     {
04026       as_warn (_("No comma after .pdesc <entryname>"));
04027       demand_empty_rest_of_line ();
04028       return;
04029     }
04030 
04031   SKIP_WHITESPACE ();
04032   name = input_line_pointer;
04033   name_end = get_symbol_end ();
04034 
04035   if (strncmp (name, "stack", 5) == 0)
04036     alpha_evax_proc.pdsckind = PDSC_S_K_KIND_FP_STACK;
04037 
04038   else if (strncmp (name, "reg", 3) == 0)
04039     alpha_evax_proc.pdsckind = PDSC_S_K_KIND_FP_REGISTER;
04040 
04041   else if (strncmp (name, "null", 4) == 0)
04042     alpha_evax_proc.pdsckind = PDSC_S_K_KIND_NULL;
04043 
04044   else
04045     {
04046       as_fatal (_("unknown procedure kind"));
04047       demand_empty_rest_of_line ();
04048       return;
04049     }
04050 
04051   *input_line_pointer = name_end;
04052   demand_empty_rest_of_line ();
04053 
04054 #ifdef md_flush_pending_output
04055   md_flush_pending_output ();
04056 #endif
04057 
04058   frag_align (3, 0, 0);
04059   p = frag_more (16);
04060   fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
04061   fixp->fx_done = 1;
04062   seginfo->literal_pool_size += 16;
04063 
04064   *p = alpha_evax_proc.pdsckind
04065     | ((alpha_evax_proc.framereg == 29) ? PDSC_S_M_BASE_REG_IS_FP : 0);
04066   *(p + 1) = PDSC_S_M_NATIVE | PDSC_S_M_NO_JACKET;
04067 
04068   switch (alpha_evax_proc.pdsckind)
04069     {
04070     case PDSC_S_K_KIND_NULL:
04071       *(p + 2) = 0;
04072       *(p + 3) = 0;
04073       break;
04074     case PDSC_S_K_KIND_FP_REGISTER:
04075       *(p + 2) = alpha_evax_proc.fp_save;
04076       *(p + 3) = alpha_evax_proc.ra_save;
04077       break;
04078     case PDSC_S_K_KIND_FP_STACK:
04079       md_number_to_chars (p + 2, (valueT) alpha_evax_proc.rsa_offset, 2);
04080       break;
04081     default:         /* impossible */
04082       break;
04083     }
04084 
04085   *(p + 4) = 0;
04086   *(p + 5) = alpha_evax_proc.type & 0x0f;
04087 
04088   /* Signature offset.  */
04089   md_number_to_chars (p + 6, (valueT) 0, 2);
04090 
04091   fix_new_exp (frag_now, p - frag_now->fr_literal+8, 8, &exp, 0, BFD_RELOC_64);
04092 
04093   if (alpha_evax_proc.pdsckind == PDSC_S_K_KIND_NULL)
04094     return;
04095 
04096   /* Add dummy fix to make add_to_link_pool work.  */
04097   p = frag_more (8);
04098   fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
04099   fixp->fx_done = 1;
04100   seginfo->literal_pool_size += 8;
04101 
04102   /* pdesc+16: Size.  */
04103   md_number_to_chars (p, (valueT) alpha_evax_proc.framesize, 4);
04104 
04105   md_number_to_chars (p + 4, (valueT) 0, 2);
04106 
04107   /* Entry length.  */
04108   md_number_to_chars (p + 6, alpha_evax_proc.prologue, 2);
04109 
04110   if (alpha_evax_proc.pdsckind == PDSC_S_K_KIND_FP_REGISTER)
04111     return;
04112 
04113   /* Add dummy fix to make add_to_link_pool work.  */
04114   p = frag_more (8);
04115   fixp = fix_new (frag_now, p - frag_now->fr_literal, 8, 0, 0, 0, 0);
04116   fixp->fx_done = 1;
04117   seginfo->literal_pool_size += 8;
04118 
04119   /* pdesc+24: register masks.  */
04120 
04121   md_number_to_chars (p, alpha_evax_proc.imask, 4);
04122   md_number_to_chars (p + 4, alpha_evax_proc.fmask, 4);
04123 }
04124 
04125 /* Support for crash debug on vms.  */
04126 
04127 static void
04128 s_alpha_name (int ignore ATTRIBUTE_UNUSED)
04129 {
04130   char *p;
04131   expressionS exp;
04132   segment_info_type *seginfo = seg_info (alpha_link_section);
04133 
04134   if (now_seg != alpha_link_section)
04135     {
04136       as_bad (_(".name directive not in link (.link) section"));
04137       demand_empty_rest_of_line ();
04138       return;
04139     }
04140 
04141   expression (&exp);
04142   if (exp.X_op != O_symbol)
04143     {
04144       as_warn (_(".name directive has no symbol"));
04145       demand_empty_rest_of_line ();
04146       return;
04147     }
04148 
04149   demand_empty_rest_of_line ();
04150 
04151 #ifdef md_flush_pending_output
04152   md_flush_pending_output ();
04153 #endif
04154 
04155   frag_align (3, 0, 0);
04156   p = frag_more (8);
04157   seginfo->literal_pool_size += 8;
04158 
04159   fix_new_exp (frag_now, p - frag_now->fr_literal, 8, &exp, 0, BFD_RELOC_64);
04160 }
04161 
04162 static void
04163 s_alpha_linkage (int ignore ATTRIBUTE_UNUSED)
04164 {
04165   expressionS exp;
04166   char *p;
04167 
04168 #ifdef md_flush_pending_output
04169   md_flush_pending_output ();
04170 #endif
04171 
04172   expression (&exp);
04173   if (exp.X_op != O_symbol)
04174     {
04175       as_fatal (_("No symbol after .linkage"));
04176     }
04177   else
04178     {
04179       p = frag_more (LKP_S_K_SIZE);
04180       memset (p, 0, LKP_S_K_SIZE);
04181       fix_new_exp (frag_now, p - frag_now->fr_literal, LKP_S_K_SIZE, &exp, 0,\
04182                  BFD_RELOC_ALPHA_LINKAGE);
04183     }
04184   demand_empty_rest_of_line ();
04185 }
04186 
04187 static void
04188 s_alpha_code_address (int ignore ATTRIBUTE_UNUSED)
04189 {
04190   expressionS exp;
04191   char *p;
04192 
04193 #ifdef md_flush_pending_output
04194   md_flush_pending_output ();
04195 #endif
04196 
04197   expression (&exp);
04198   if (exp.X_op != O_symbol)
04199     as_fatal (_("No symbol after .code_address"));
04200   else
04201     {
04202       p = frag_more (8);
04203       memset (p, 0, 8);
04204       fix_new_exp (frag_now, p - frag_now->fr_literal, 8, &exp, 0,\
04205                  BFD_RELOC_ALPHA_CODEADDR);
04206     }
04207   demand_empty_rest_of_line ();
04208 }
04209 
04210 static void
04211 s_alpha_fp_save (int ignore ATTRIBUTE_UNUSED)
04212 {
04213 
04214   alpha_evax_proc.fp_save = tc_get_register (1);
04215 
04216   demand_empty_rest_of_line ();
04217 }
04218 
04219 static void
04220 s_alpha_mask (int ignore ATTRIBUTE_UNUSED)
04221 {
04222   long val;
04223 
04224   if (get_absolute_expression_and_terminator (&val) != ',')
04225     {
04226       as_warn (_("Bad .mask directive"));
04227       --input_line_pointer;
04228     }
04229   else
04230     {
04231       alpha_evax_proc.imask = val;
04232       (void) get_absolute_expression ();
04233     }
04234   demand_empty_rest_of_line ();
04235 }
04236 
04237 static void
04238 s_alpha_fmask (int ignore ATTRIBUTE_UNUSED)
04239 {
04240   long val;
04241 
04242   if (get_absolute_expression_and_terminator (&val) != ',')
04243     {
04244       as_warn (_("Bad .fmask directive"));
04245       --input_line_pointer;
04246     }
04247   else
04248     {
04249       alpha_evax_proc.fmask = val;
04250       (void) get_absolute_expression ();
04251     }
04252   demand_empty_rest_of_line ();
04253 }
04254 
04255 static void
04256 s_alpha_end (int ignore ATTRIBUTE_UNUSED)
04257 {
04258   char c;
04259 
04260   c = get_symbol_end ();
04261   *input_line_pointer = c;
04262   demand_empty_rest_of_line ();
04263   alpha_evax_proc.symbol = 0;
04264 }
04265 
04266 static void
04267 s_alpha_file (int ignore ATTRIBUTE_UNUSED)
04268 {
04269   symbolS *s;
04270   int length;
04271   static char case_hack[32];
04272 
04273   sprintf (case_hack, "<CASE:%01d%01d>",
04274           alpha_flag_hash_long_names, alpha_flag_show_after_trunc);
04275 
04276   s = symbol_find_or_make (case_hack);
04277   symbol_get_bfdsym (s)->flags |= BSF_FILE;
04278 
04279   get_absolute_expression ();
04280   s = symbol_find_or_make (demand_copy_string (&length));
04281   symbol_get_bfdsym (s)->flags |= BSF_FILE;
04282   demand_empty_rest_of_line ();
04283 }
04284 #endif /* OBJ_EVAX  */
04285 
04286 /* Handle the .gprel32 pseudo op.  */
04287 
04288 static void
04289 s_alpha_gprel32 (int ignore ATTRIBUTE_UNUSED)
04290 {
04291   expressionS e;
04292   char *p;
04293 
04294   SKIP_WHITESPACE ();
04295   expression (&e);
04296 
04297 #ifdef OBJ_ELF
04298   switch (e.X_op)
04299     {
04300     case O_constant:
04301       e.X_add_symbol = section_symbol (absolute_section);
04302       e.X_op = O_symbol;
04303       /* FALLTHRU */
04304     case O_symbol:
04305       break;
04306     default:
04307       abort ();
04308     }
04309 #else
04310 #ifdef OBJ_ECOFF
04311   switch (e.X_op)
04312     {
04313     case O_constant:
04314       e.X_add_symbol = section_symbol (absolute_section);
04315       /* fall through */
04316     case O_symbol:
04317       e.X_op = O_subtract;
04318       e.X_op_symbol = alpha_gp_symbol;
04319       break;
04320     default:
04321       abort ();
04322     }
04323 #endif
04324 #endif
04325 
04326   if (alpha_auto_align_on && alpha_current_align < 2)
04327     alpha_align (2, (char *) NULL, alpha_insn_label, 0);
04328   if (alpha_current_align > 2)
04329     alpha_current_align = 2;
04330   alpha_insn_label = NULL;
04331 
04332   p = frag_more (4);
04333   memset (p, 0, 4);
04334   fix_new_exp (frag_now, p - frag_now->fr_literal, 4,
04335               &e, 0, BFD_RELOC_GPREL32);
04336 }
04337 
04338 /* Handle floating point allocation pseudo-ops.  This is like the
04339    generic vresion, but it makes sure the current label, if any, is
04340    correctly aligned.  */
04341 
04342 static void
04343 s_alpha_float_cons (int type)
04344 {
04345   int log_size;
04346 
04347   switch (type)
04348     {
04349     default:
04350     case 'f':
04351     case 'F':
04352       log_size = 2;
04353       break;
04354 
04355     case 'd':
04356     case 'D':
04357     case 'G':
04358       log_size = 3;
04359       break;
04360 
04361     case 'x':
04362     case 'X':
04363     case 'p':
04364     case 'P':
04365       log_size = 4;
04366       break;
04367     }
04368 
04369   if (alpha_auto_align_on && alpha_current_align < log_size)
04370     alpha_align (log_size, (char *) NULL, alpha_insn_label, 0);
04371   if (alpha_current_align > log_size)
04372     alpha_current_align = log_size;
04373   alpha_insn_label = NULL;
04374 
04375   float_cons (type);
04376 }
04377 
04378 /* Handle the .proc pseudo op.  We don't really do much with it except
04379    parse it.  */
04380 
04381 static void
04382 s_alpha_proc (int is_static ATTRIBUTE_UNUSED)
04383 {
04384   char *name;
04385   char c;
04386   char *p;
04387   symbolS *symbolP;
04388   int temp;
04389 
04390   /* Takes ".proc name,nargs".  */
04391   SKIP_WHITESPACE ();
04392   name = input_line_pointer;
04393   c = get_symbol_end ();
04394   p = input_line_pointer;
04395   symbolP = symbol_find_or_make (name);
04396   *p = c;
04397   SKIP_WHITESPACE ();
04398   if (*input_line_pointer != ',')
04399     {
04400       *p = 0;
04401       as_warn (_("Expected comma after name \"%s\""), name);
04402       *p = c;
04403       temp = 0;
04404       ignore_rest_of_line ();
04405     }
04406   else
04407     {
04408       input_line_pointer++;
04409       temp = get_absolute_expression ();
04410     }
04411   /*  *symbol_get_obj (symbolP) = (signed char) temp; */
04412   as_warn (_("unhandled: .proc %s,%d"), name, temp);
04413   demand_empty_rest_of_line ();
04414 }
04415 
04416 /* Handle the .set pseudo op.  This is used to turn on and off most of
04417    the assembler features.  */
04418 
04419 static void
04420 s_alpha_set (int x ATTRIBUTE_UNUSED)
04421 {
04422   char *name, ch, *s;
04423   int yesno = 1;
04424 
04425   SKIP_WHITESPACE ();
04426   name = input_line_pointer;
04427   ch = get_symbol_end ();
04428 
04429   s = name;
04430   if (s[0] == 'n' && s[1] == 'o')
04431     {
04432       yesno = 0;
04433       s += 2;
04434     }
04435   if (!strcmp ("reorder", s))
04436     /* ignore */ ;
04437   else if (!strcmp ("at", s))
04438     alpha_noat_on = !yesno;
04439   else if (!strcmp ("macro", s))
04440     alpha_macros_on = yesno;
04441   else if (!strcmp ("move", s))
04442     /* ignore */ ;
04443   else if (!strcmp ("volatile", s))
04444     /* ignore */ ;
04445   else
04446     as_warn (_("Tried to .set unrecognized mode `%s'"), name);
04447 
04448   *input_line_pointer = ch;
04449   demand_empty_rest_of_line ();
04450 }
04451 
04452 /* Handle the .base pseudo op.  This changes the assembler's notion of
04453    the $gp register.  */
04454 
04455 static void
04456 s_alpha_base (int ignore ATTRIBUTE_UNUSED)
04457 {
04458   SKIP_WHITESPACE ();
04459 
04460   if (*input_line_pointer == '$')
04461     {
04462       /* $rNN form.  */
04463       input_line_pointer++;
04464       if (*input_line_pointer == 'r')
04465        input_line_pointer++;
04466     }
04467 
04468   alpha_gp_register = get_absolute_expression ();
04469   if (alpha_gp_register < 0 || alpha_gp_register > 31)
04470     {
04471       alpha_gp_register = AXP_REG_GP;
04472       as_warn (_("Bad base register, using $%d."), alpha_gp_register);
04473     }
04474 
04475   demand_empty_rest_of_line ();
04476 }
04477 
04478 /* Handle the .align pseudo-op.  This aligns to a power of two.  It
04479    also adjusts any current instruction label.  We treat this the same
04480    way the MIPS port does: .align 0 turns off auto alignment.  */
04481 
04482 static void
04483 s_alpha_align (int ignore ATTRIBUTE_UNUSED)
04484 {
04485   int align;
04486   char fill, *pfill;
04487   long max_alignment = 15;
04488 
04489   align = get_absolute_expression ();
04490   if (align > max_alignment)
04491     {
04492       align = max_alignment;
04493       as_bad (_("Alignment too large: %d. assumed"), align);
04494     }
04495   else if (align < 0)
04496     {
04497       as_warn (_("Alignment negative: 0 assumed"));
04498       align = 0;
04499     }
04500 
04501   if (*input_line_pointer == ',')
04502     {
04503       input_line_pointer++;
04504       fill = get_absolute_expression ();
04505       pfill = &fill;
04506     }
04507   else
04508     pfill = NULL;
04509 
04510   if (align != 0)
04511     {
04512       alpha_auto_align_on = 1;
04513       alpha_align (align, pfill, alpha_insn_label, 1);
04514     }
04515   else
04516     {
04517       alpha_auto_align_on = 0;
04518     }
04519 
04520   demand_empty_rest_of_line ();
04521 }
04522 
04523 /* Hook the normal string processor to reset known alignment.  */
04524 
04525 static void
04526 s_alpha_stringer (int terminate)
04527 {
04528   alpha_current_align = 0;
04529   alpha_insn_label = NULL;
04530   stringer (terminate);
04531 }
04532 
04533 /* Hook the normal space processing to reset known alignment.  */
04534 
04535 static void
04536 s_alpha_space (int ignore)
04537 {
04538   alpha_current_align = 0;
04539   alpha_insn_label = NULL;
04540   s_space (ignore);
04541 }
04542 
04543 /* Hook into cons for auto-alignment.  */
04544 
04545 void
04546 alpha_cons_align (int size)
04547 {
04548   int log_size;
04549 
04550   log_size = 0;
04551   while ((size >>= 1) != 0)
04552     ++log_size;
04553 
04554   if (alpha_auto_align_on && alpha_current_align < log_size)
04555     alpha_align (log_size, (char *) NULL, alpha_insn_label, 0);
04556   if (alpha_current_align > log_size)
04557     alpha_current_align = log_size;
04558   alpha_insn_label = NULL;
04559 }
04560 
04561 /* Here come the .uword, .ulong, and .uquad explicitly unaligned
04562    pseudos.  We just turn off auto-alignment and call down to cons.  */
04563 
04564 static void
04565 s_alpha_ucons (int bytes)
04566 {
04567   int hold = alpha_auto_align_on;
04568   alpha_auto_align_on = 0;
04569   cons (bytes);
04570   alpha_auto_align_on = hold;
04571 }
04572 
04573 /* Switch the working cpu type.  */
04574 
04575 static void
04576 s_alpha_arch (int ignored ATTRIBUTE_UNUSED)
04577 {
04578   char *name, ch;
04579   const struct cpu_type *p;
04580 
04581   SKIP_WHITESPACE ();
04582   name = input_line_pointer;
04583   ch = get_symbol_end ();
04584 
04585   for (p = cpu_types; p->name; ++p)
04586     if (strcmp (name, p->name) == 0)
04587       {
04588        alpha_target_name = p->name, alpha_target = p->flags;
04589        goto found;
04590       }
04591   as_warn ("Unknown CPU identifier `%s'", name);
04592 
04593 found:
04594   *input_line_pointer = ch;
04595   demand_empty_rest_of_line ();
04596 }
04597 
04598 #ifdef DEBUG1
04599 /* print token expression with alpha specific extension.  */
04600 
04601 static void
04602 alpha_print_token (FILE *f, const expressionS *exp)
04603 {
04604   switch (exp->X_op)
04605     {
04606     case O_cpregister:
04607       putc (',', f);
04608       /* FALLTHRU */
04609     case O_pregister:
04610       putc ('(', f);
04611       {
04612        expressionS nexp = *exp;
04613        nexp.X_op = O_register;
04614        print_expr (f, &nexp);
04615       }
04616       putc (')', f);
04617       break;
04618     default:
04619       print_expr (f, exp);
04620       break;
04621     }
04622 }
04623 #endif
04624 
04625 /* The target specific pseudo-ops which we support.  */
04626 
04627 const pseudo_typeS md_pseudo_table[] =
04628 {
04629 #ifdef OBJ_ECOFF
04630   {"comm", s_alpha_comm, 0},       /* OSF1 compiler does this.  */
04631   {"rdata", s_alpha_rdata, 0},
04632 #endif
04633   {"text", s_alpha_text, 0},
04634   {"data", s_alpha_data, 0},
04635 #ifdef OBJ_ECOFF
04636   {"sdata", s_alpha_sdata, 0},
04637 #endif
04638 #ifdef OBJ_ELF
04639   {"section", s_alpha_section, 0},
04640   {"section.s", s_alpha_section, 0},
04641   {"sect", s_alpha_section, 0},
04642   {"sect.s", s_alpha_section, 0},
04643 #endif
04644 #ifdef OBJ_EVAX
04645   { "pdesc", s_alpha_pdesc, 0},
04646   { "name", s_alpha_name, 0},
04647   { "linkage", s_alpha_linkage, 0},
04648   { "code_address", s_alpha_code_address, 0},
04649   { "ent", s_alpha_ent, 0},
04650   { "frame", s_alpha_frame, 0},
04651   { "fp_save", s_alpha_fp_save, 0},
04652   { "mask", s_alpha_mask, 0},
04653   { "fmask", s_alpha_fmask, 0},
04654   { "end", s_alpha_end, 0},
04655   { "file", s_alpha_file, 0},
04656   { "rdata", s_alpha_section, 1},
04657   { "comm", s_alpha_comm, 0},
04658   { "link", s_alpha_section, 3},
04659   { "ctors", s_alpha_section, 4},
04660   { "dtors", s_alpha_section, 5},
04661 #endif
04662 #ifdef OBJ_ELF
04663   /* Frame related pseudos.  */
04664   {"ent", s_alpha_ent, 0},
04665   {"end", s_alpha_end, 0},
04666   {"mask", s_alpha_mask, 0},
04667   {"fmask", s_alpha_mask, 1},
04668   {"frame", s_alpha_frame, 0},
04669   {"prologue", s_alpha_prologue, 0},
04670   {"file", s_alpha_file, 5},
04671   {"loc", s_alpha_loc, 9},
04672   {"stabs", s_alpha_stab, 's'},
04673   {"stabn", s_alpha_stab, 'n'},
04674   {"usepv", s_alpha_usepv, 0},
04675   /* COFF debugging related pseudos.  */
04676   {"begin", s_alpha_coff_wrapper, 0},
04677   {"bend", s_alpha_coff_wrapper, 1},
04678   {"def", s_alpha_coff_wrapper, 2},
04679   {"dim", s_alpha_coff_wrapper, 3},
04680   {"endef", s_alpha_coff_wrapper, 4},
04681   {"scl", s_alpha_coff_wrapper, 5},
04682   {"tag", s_alpha_coff_wrapper, 6},
04683   {"val", s_alpha_coff_wrapper, 7},
04684 #else
04685   {"prologue", s_ignore, 0},
04686 #endif
04687   {"gprel32", s_alpha_gprel32, 0},
04688   {"t_floating", s_alpha_float_cons, 'd'},
04689   {"s_floating", s_alpha_float_cons, 'f'},
04690   {"f_floating", s_alpha_float_cons, 'F'},
04691   {"g_floating", s_alpha_float_cons, 'G'},
04692   {"d_floating", s_alpha_float_cons, 'D'},
04693 
04694   {"proc", s_alpha_proc, 0},
04695   {"aproc", s_alpha_proc, 1},
04696   {"set", s_alpha_set, 0},
04697   {"reguse", s_ignore, 0},
04698   {"livereg", s_ignore, 0},
04699   {"base", s_alpha_base, 0},              /*??*/
04700   {"option", s_ignore, 0},
04701   {"aent", s_ignore, 0},
04702   {"ugen", s_ignore, 0},
04703   {"eflag", s_ignore, 0},
04704 
04705   {"align", s_alpha_align, 0},
04706   {"double", s_alpha_float_cons, 'd'},
04707   {"float", s_alpha_float_cons, 'f'},
04708   {"single", s_alpha_float_cons, 'f'},
04709   {"ascii", s_alpha_stringer, 0},
04710   {"asciz", s_alpha_stringer, 1},
04711   {"string", s_alpha_stringer, 1},
04712   {"space", s_alpha_space, 0},
04713   {"skip", s_alpha_space, 0},
04714   {"zero", s_alpha_space, 0},
04715 
04716 /* Unaligned data pseudos.  */
04717   {"uword", s_alpha_ucons, 2},
04718   {"ulong", s_alpha_ucons, 4},
04719   {"uquad", s_alpha_ucons, 8},
04720 
04721 #ifdef OBJ_ELF
04722 /* Dwarf wants these versions of unaligned.  */
04723   {"2byte", s_alpha_ucons, 2},
04724   {"4byte", s_alpha_ucons, 4},
04725   {"8byte", s_alpha_ucons, 8},
04726 #endif
04727 
04728 /* We don't do any optimizing, so we can safely ignore these.  */
04729   {"noalias", s_ignore, 0},
04730   {"alias", s_ignore, 0},
04731 
04732   {"arch", s_alpha_arch, 0},
04733 
04734   {NULL, 0, 0},
04735 };
04736 
04737 #ifdef OBJ_ECOFF
04738 
04739 /* @@@ GP selection voodoo.  All of this seems overly complicated and
04740    unnecessary; which is the primary reason it's for ECOFF only.  */
04741 static inline void maybe_set_gp PARAMS ((asection *));
04742 
04743 static inline void
04744 maybe_set_gp (asection *sec)
04745 {
04746   bfd_vma vma;
04747 
04748   if (!sec)
04749     return;
04750   vma = bfd_get_section_vma (foo, sec);
04751   if (vma && vma < alpha_gp_value)
04752     alpha_gp_value = vma;
04753 }
04754 
04755 static void
04756 select_gp_value (void)
04757 {
04758   assert (alpha_gp_value == 0);
04759 
04760   /* Get minus-one in whatever width...  */
04761   alpha_gp_value = 0;
04762   alpha_gp_value--;
04763 
04764   /* Select the smallest VMA of these existing sections.  */
04765   maybe_set_gp (alpha_lita_section);
04766 
04767 /* @@ Will a simple 0x8000 work here?  If not, why not?  */
04768 #define GP_ADJUSTMENT       (0x8000 - 0x10)
04769 
04770   alpha_gp_value += GP_ADJUSTMENT;
04771 
04772   S_SET_VALUE (alpha_gp_symbol, alpha_gp_value);
04773 
04774 #ifdef DEBUG1
04775   printf (_("Chose GP value of %lx\n"), alpha_gp_value);
04776 #endif
04777 }
04778 #endif /* OBJ_ECOFF */
04779 
04780 #ifdef OBJ_ELF
04781 /* Map 's' to SHF_ALPHA_GPREL.  */
04782 
04783 int
04784 alpha_elf_section_letter (int letter, char **ptr_msg)
04785 {
04786   if (letter == 's')
04787     return SHF_ALPHA_GPREL;
04788 
04789   *ptr_msg = _("Bad .section directive: want a,s,w,x,M,S,G,T in string");
04790   return -1;
04791 }
04792 
04793 /* Map SHF_ALPHA_GPREL to SEC_SMALL_DATA.  */
04794 
04795 flagword
04796 alpha_elf_section_flags (flagword flags, int attr, int type ATTRIBUTE_UNUSED)
04797 {
04798   if (attr & SHF_ALPHA_GPREL)
04799     flags |= SEC_SMALL_DATA;
04800   return flags;
04801 }
04802 #endif /* OBJ_ELF */
04803 
04804 /* This is called from HANDLE_ALIGN in write.c.  Fill in the contents
04805    of an rs_align_code fragment.  */
04806 
04807 void
04808 alpha_handle_align (fragS *fragp)
04809 {
04810   static char const unop[4] = { 0x00, 0x00, 0xfe, 0x2f };
04811   static char const nopunop[8] =
04812   {
04813     0x1f, 0x04, 0xff, 0x47,
04814     0x00, 0x00, 0xfe, 0x2f
04815   };
04816 
04817   int bytes, fix;
04818   char *p;
04819 
04820   if (fragp->fr_type != rs_align_code)
04821     return;
04822 
04823   bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix;
04824   p = fragp->fr_literal + fragp->fr_fix;
04825   fix = 0;
04826 
04827   if (bytes & 3)
04828     {
04829       fix = bytes & 3;
04830       memset (p, 0, fix);
04831       p += fix;
04832       bytes -= fix;
04833     }
04834 
04835   if (bytes & 4)
04836     {
04837       memcpy (p, unop, 4);
04838       p += 4;
04839       bytes -= 4;
04840       fix += 4;
04841     }
04842 
04843   memcpy (p, nopunop, 8);
04844 
04845   fragp->fr_fix += fix;
04846   fragp->fr_var = 8;
04847 }
04848 
04849 /* Public interface functions.  */
04850 
04851 /* This function is called once, at assembler startup time.  It sets
04852    up all the tables, etc. that the MD part of the assembler will
04853    need, that can be determined before arguments are parsed.  */
04854 
04855 void
04856 md_begin (void)
04857 {
04858   unsigned int i;
04859 
04860   /* Verify that X_op field is wide enough.  */
04861   {
04862     expressionS e;
04863 
04864     e.X_op = O_max;
04865     assert (e.X_op == O_max);
04866   }
04867 
04868   /* Create the opcode hash table.  */
04869   alpha_opcode_hash = hash_new ();
04870 
04871   for (i = 0; i < alpha_num_opcodes;)
04872     {
04873       const char *name, *retval, *slash;
04874 
04875       name = alpha_opcodes[i].name;
04876       retval = hash_insert (alpha_opcode_hash, name, (void *) &alpha_opcodes[i]);
04877       if (retval)
04878        as_fatal (_("internal error: can't hash opcode `%s': %s"),
04879                 name, retval);
04880 
04881       /* Some opcodes include modifiers of various sorts with a "/mod"
04882         syntax, like the architecture manual suggests.  However, for
04883         use with gcc at least, we also need access to those same opcodes
04884         without the "/".  */
04885 
04886       if ((slash = strchr (name, '/')) != NULL)
04887        {
04888          char *p = xmalloc (strlen (name));
04889 
04890          memcpy (p, name, slash - name);
04891          strcpy (p + (slash - name), slash + 1);
04892 
04893          (void) hash_insert (alpha_opcode_hash, p, (void *) &alpha_opcodes[i]);
04894          /* Ignore failures -- the opcode table does duplicate some
04895             variants in different forms, like "hw_stq" and "hw_st/q".  */
04896        }
04897 
04898       while (++i < alpha_num_opcodes
04899             && (alpha_opcodes[i].name == name
04900                || !strcmp (alpha_opcodes[i].name, name)))
04901        continue;
04902     }
04903 
04904   /* Create the macro hash table.  */
04905   alpha_macro_hash = hash_new ();
04906 
04907   for (i = 0; i < alpha_num_macros;)
04908     {
04909       const char *name, *retval;
04910 
04911       name = alpha_macros[i].name;
04912       retval = hash_insert (alpha_macro_hash, name, (void *) &alpha_macros[i]);
04913       if (retval)
04914        as_fatal (_("internal error: can't hash macro `%s': %s"),
04915                 name, retval);
04916 
04917       while (++i < alpha_num_macros
04918             && (alpha_macros[i].name == name
04919                || !strcmp (alpha_macros[i].name, name)))
04920        continue;
04921     }
04922 
04923   /* Construct symbols for each of the registers.  */
04924   for (i = 0; i < 32; ++i)
04925     {
04926       char name[4];
04927 
04928       sprintf (name, "$%d", i);
04929       alpha_register_table[i] = symbol_create (name, reg_section, i,
04930                                           &zero_address_frag);
04931     }
04932 
04933   for (; i < 64; ++i)
04934     {
04935       char name[5];
04936 
04937       sprintf (name, "$f%d", i - 32);
04938       alpha_register_table[i] = symbol_create (name, reg_section, i,
04939                                           &zero_address_frag);
04940     }
04941 
04942   /* Create the special symbols and sections we'll be using.  */
04943 
04944   /* So .sbss will get used for tiny objects.  */
04945   bfd_set_gp_size (stdoutput, g_switch_value);
04946 
04947 #ifdef OBJ_ECOFF
04948   create_literal_section (".lita", &alpha_lita_section, &alpha_lita_symbol);
04949 
04950   /* For handling the GP, create a symbol that won't be output in the
04951      symbol table.  We'll edit it out of relocs later.  */
04952   alpha_gp_symbol = symbol_create ("<GP value>", alpha_lita_section, 0x8000,
04953                                &zero_address_frag);
04954 #endif
04955 
04956 #ifdef OBJ_EVAX
04957   create_literal_section (".link", &alpha_link_section, &alpha_link_symbol);
04958 #endif
04959 
04960 #ifdef OBJ_ELF
04961   if (ECOFF_DEBUGGING)
04962     {
04963       segT sec = subseg_new (".mdebug", (subsegT) 0);
04964       bfd_set_section_flags (stdoutput, sec, SEC_HAS_CONTENTS | SEC_READONLY);
04965       bfd_set_section_alignment (stdoutput, sec, 3);
04966     }
04967 #endif
04968 
04969   /* Create literal lookup hash table.  */
04970   alpha_literal_hash = hash_new ();
04971 
04972   subseg_set (text_section, 0);
04973 }
04974 
04975 /* The public interface to the instruction assembler.  */
04976 
04977 void
04978 md_assemble (char *str)
04979 {
04980   /* Current maximum is 13.  */
04981   char opname[32];
04982   expressionS tok[MAX_INSN_ARGS];
04983   int ntok, trunclen;
04984   size_t opnamelen;
04985 
04986   /* Split off the opcode.  */
04987   opnamelen = strspn (str, "abcdefghijklmnopqrstuvwxyz_/46819");
04988   trunclen = (opnamelen < sizeof (opname) - 1
04989              ? opnamelen
04990              : sizeof (opname) - 1);
04991   memcpy (opname, str, trunclen);
04992   opname[trunclen] = '\0';
04993 
04994   /* Tokenize the rest of the line.  */
04995   if ((ntok = tokenize_arguments (str + opnamelen, tok, MAX_INSN_ARGS)) < 0)
04996     {
04997       if (ntok != TOKENIZE_ERROR_REPORT)
04998        as_bad (_("syntax error"));
04999 
05000       return;
05001     }
05002 
05003   /* Finish it off.  */
05004   assemble_tokens (opname, tok, ntok, alpha_macros_on);
05005 }
05006 
05007 /* Round up a section's size to the appropriate boundary.  */
05008 
05009 valueT
05010 md_section_align (segT seg, valueT size)
05011 {
05012   int align = bfd_get_section_alignment (stdoutput, seg);
05013   valueT mask = ((valueT) 1 << align) - 1;
05014 
05015   return (size + mask) & ~mask;
05016 }
05017 
05018 /* Turn a string in input_line_pointer into a floating point constant
05019    of type TYPE, and store the appropriate bytes in *LITP.  The number
05020    of LITTLENUMS emitted is stored in *SIZEP.  An error message is
05021    returned, or NULL on OK.  */
05022 
05023 /* Equal to MAX_PRECISION in atof-ieee.c.  */
05024 #define MAX_LITTLENUMS 6
05025 
05026 extern char *vax_md_atof (int, char *, int *);
05027 
05028 char *
05029 md_atof (int type, char *litP, int *sizeP)
05030 {
05031   int prec;
05032   LITTLENUM_TYPE words[MAX_LITTLENUMS];
05033   LITTLENUM_TYPE *wordP;
05034   char *t;
05035 
05036   switch (type)
05037     {
05038       /* VAX floats.  */
05039     case 'G':
05040       /* VAX md_atof doesn't like "G" for some reason.  */
05041       type = 'g';
05042     case 'F':
05043     case 'D':
05044       return vax_md_atof (type, litP, sizeP);
05045 
05046       /* IEEE floats.  */
05047     case 'f':
05048       prec = 2;
05049       break;
05050 
05051     case 'd':
05052       prec = 4;
05053       break;
05054 
05055     case 'x':
05056     case 'X':
05057       prec = 6;
05058       break;
05059 
05060     case 'p':
05061     case 'P':
05062       prec = 6;
05063       break;
05064 
05065     default:
05066       *sizeP = 0;
05067       return _("Bad call to MD_ATOF()");
05068     }
05069   t = atof_ieee (input_line_pointer, type, words);
05070   if (t)
05071     input_line_pointer = t;
05072   *sizeP = prec * sizeof (LITTLENUM_TYPE);
05073 
05074   for (wordP = words + prec - 1; prec--;)
05075     {
05076       md_number_to_chars (litP, (long) (*wordP--), sizeof (LITTLENUM_TYPE));
05077       litP += sizeof (LITTLENUM_TYPE);
05078     }
05079 
05080   return 0;
05081 }
05082 
05083 /* Take care of the target-specific command-line options.  */
05084 
05085 int
05086 md_parse_option (int c, char *arg)
05087 {
05088   switch (c)
05089     {
05090     case 'F':
05091       alpha_nofloats_on = 1;
05092       break;
05093 
05094     case OPTION_32ADDR:
05095       alpha_addr32_on = 1;
05096       break;
05097 
05098     case 'g':
05099       alpha_debug = 1;
05100       break;
05101 
05102     case 'G':
05103       g_switch_value = atoi (arg);
05104       break;
05105 
05106     case 'm':
05107       {
05108        const struct cpu_type *p;
05109 
05110        for (p = cpu_types; p->name; ++p)
05111          if (strcmp (arg, p->name) == 0)
05112            {
05113              alpha_target_name = p->name, alpha_target = p->flags;
05114              goto found;
05115            }
05116        as_warn (_("Unknown CPU identifier `%s'"), arg);
05117       found:;
05118       }
05119       break;
05120 
05121 #ifdef OBJ_EVAX
05122     case '+':               /* For g++.  Hash any name > 63 chars long.  */
05123       alpha_flag_hash_long_names = 1;
05124       break;
05125 
05126     case 'H':               /* Show new symbol after hash truncation.  */
05127       alpha_flag_show_after_trunc = 1;
05128       break;
05129 
05130     case 'h':               /* For gnu-c/vax compatibility.  */
05131       break;
05132 #endif
05133 
05134     case OPTION_RELAX:
05135       alpha_flag_relax = 1;
05136       break;
05137 
05138 #ifdef OBJ_ELF
05139     case OPTION_MDEBUG:
05140       alpha_flag_mdebug = 1;
05141       break;
05142     case OPTION_NO_MDEBUG:
05143       alpha_flag_mdebug = 0;
05144       break;
05145 #endif
05146 
05147     default:
05148       return 0;
05149     }
05150 
05151   return 1;
05152 }
05153 
05154 /* Print a description of the command-line options that we accept.  */
05155 
05156 void
05157 md_show_usage (FILE *stream)
05158 {
05159   fputs (_("\
05160 Alpha options:\n\
05161 -32addr                     treat addresses as 32-bit values\n\
05162 -F                   lack floating point instructions support\n\
05163 -mev4 | -mev45 | -mev5 | -mev56 | -mpca56 | -mev6 | -mev67 | -mev68 | -mall\n\
05164                      specify variant of Alpha architecture\n\
05165 -m21064 | -m21066 | -m21164 | -m21164a | -m21164pc | -m21264 | -m21264a | -m21264b\n\
05166                      these variants include PALcode opcodes\n"),
05167        stream);
05168 #ifdef OBJ_EVAX
05169   fputs (_("\
05170 VMS options:\n\
05171 -+                   hash encode (don't truncate) names longer than 64 characters\n\
05172 -H                   show new symbol after hash truncation\n"),
05173        stream);
05174 #endif
05175 }
05176 
05177 /* Decide from what point a pc-relative relocation is relative to,
05178    relative to the pc-relative fixup.  Er, relatively speaking.  */
05179 
05180 long
05181 md_pcrel_from (fixS *fixP)
05182 {
05183   valueT addr = fixP->fx_where + fixP->fx_frag->fr_address;
05184 
05185   switch (fixP->fx_r_type)
05186     {
05187     case BFD_RELOC_23_PCREL_S2:
05188     case BFD_RELOC_ALPHA_HINT:
05189     case BFD_RELOC_ALPHA_BRSGP:
05190       return addr + 4;
05191     default:
05192       return addr;
05193     }
05194 }
05195 
05196 /* Attempt to simplify or even eliminate a fixup.  The return value is
05197    ignored; perhaps it was once meaningful, but now it is historical.
05198    To indicate that a fixup has been eliminated, set fixP->fx_done.
05199 
05200    For ELF, here it is that we transform the GPDISP_HI16 reloc we used
05201    internally into the GPDISP reloc used externally.  We had to do
05202    this so that we'd have the GPDISP_LO16 reloc as a tag to compute
05203    the distance to the "lda" instruction for setting the addend to
05204    GPDISP.  */
05205 
05206 void
05207 md_apply_fix (fixS *fixP, valueT * valP, segT seg)
05208 {
05209   char * const fixpos = fixP->fx_frag->fr_literal + fixP->fx_where;
05210   valueT value = * valP;
05211   unsigned image, size;
05212 
05213   switch (fixP->fx_r_type)
05214     {
05215       /* The GPDISP relocations are processed internally with a symbol
05216         referring to the current function's section;  we need to drop
05217         in a value which, when added to the address of the start of
05218         the function, gives the desired GP.  */
05219     case BFD_RELOC_ALPHA_GPDISP_HI16:
05220       {
05221        fixS *next = fixP->fx_next;
05222 
05223        /* With user-specified !gpdisp relocations, we can be missing
05224           the matching LO16 reloc.  We will have already issued an
05225           error message.  */
05226        if (next)
05227          fixP->fx_offset = (next->fx_frag->fr_address + next->fx_where
05228                           - fixP->fx_frag->fr_address - fixP->fx_where);
05229 
05230        value = (value - sign_extend_16 (value)) >> 16;
05231       }
05232 #ifdef OBJ_ELF
05233       fixP->fx_r_type = BFD_RELOC_ALPHA_GPDISP;
05234 #endif
05235       goto do_reloc_gp;
05236 
05237     case BFD_RELOC_ALPHA_GPDISP_LO16:
05238       value = sign_extend_16 (value);
05239       fixP->fx_offset = 0;
05240 #ifdef OBJ_ELF
05241       fixP->fx_done = 1;
05242 #endif
05243 
05244     do_reloc_gp:
05245       fixP->fx_addsy = section_symbol (seg);
05246       md_number_to_chars (fixpos, value, 2);
05247       break;
05248 
05249     case BFD_RELOC_16:
05250       if (fixP->fx_pcrel)
05251        fixP->fx_r_type = BFD_RELOC_16_PCREL;
05252       size = 2;
05253       goto do_reloc_xx;
05254 
05255     case BFD_RELOC_32:
05256       if (fixP->fx_pcrel)
05257        fixP->fx_r_type = BFD_RELOC_32_PCREL;
05258       size = 4;
05259       goto do_reloc_xx;
05260 
05261     case BFD_RELOC_64:
05262       if (fixP->fx_pcrel)
05263        fixP->fx_r_type = BFD_RELOC_64_PCREL;
05264       size = 8;
05265 
05266     do_reloc_xx:
05267       if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0)
05268        {
05269          md_number_to_chars (fixpos, value, size);
05270          goto done;
05271        }
05272       return;
05273 
05274 #ifdef OBJ_ECOFF
05275     case BFD_RELOC_GPREL32:
05276       assert (fixP->fx_subsy == alpha_gp_symbol);
05277       fixP->fx_subsy = 0;
05278       /* FIXME: inherited this obliviousness of `value' -- why?  */
05279       md_number_to_chars (fixpos, -alpha_gp_value, 4);
05280       break;
05281 #else
05282     case BFD_RELOC_GPREL32:
05283 #endif
05284     case BFD_RELOC_GPREL16:
05285     case BFD_RELOC_ALPHA_GPREL_HI16:
05286     case BFD_RELOC_ALPHA_GPREL_LO16:
05287       return;
05288 
05289     case BFD_RELOC_23_PCREL_S2:
05290       if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0)
05291        {
05292          image = bfd_getl32 (fixpos);
05293          image = (image & ~0x1FFFFF) | ((value >> 2) & 0x1FFFFF);
05294          goto write_done;
05295        }
05296       return;
05297 
05298     case BFD_RELOC_ALPHA_HINT:
05299       if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0)
05300        {
05301          image = bfd_getl32 (fixpos);
05302          image = (image & ~0x3FFF) | ((value >> 2) & 0x3FFF);
05303          goto write_done;
05304        }
05305       return;
05306 
05307 #ifdef OBJ_ELF
05308     case BFD_RELOC_ALPHA_BRSGP:
05309       return;
05310 
05311     case BFD_RELOC_ALPHA_TLSGD:
05312     case BFD_RELOC_ALPHA_TLSLDM:
05313     case BFD_RELOC_ALPHA_GOTDTPREL16:
05314     case BFD_RELOC_ALPHA_DTPREL_HI16:
05315     case BFD_RELOC_ALPHA_DTPREL_LO16:
05316     case BFD_RELOC_ALPHA_DTPREL16:
05317     case BFD_RELOC_ALPHA_GOTTPREL16:
05318     case BFD_RELOC_ALPHA_TPREL_HI16:
05319     case BFD_RELOC_ALPHA_TPREL_LO16:
05320     case BFD_RELOC_ALPHA_TPREL16:
05321       if (fixP->fx_addsy)
05322        S_SET_THREAD_LOCAL (fixP->fx_addsy);
05323       return;
05324 #endif
05325 
05326 #ifdef OBJ_ECOFF
05327     case BFD_RELOC_ALPHA_LITERAL:
05328       md_number_to_chars (fixpos, value, 2);
05329       return;
05330 #endif
05331     case BFD_RELOC_ALPHA_ELF_LITERAL:
05332     case BFD_RELOC_ALPHA_LITUSE:
05333     case BFD_RELOC_ALPHA_LINKAGE:
05334     case BFD_RELOC_ALPHA_CODEADDR:
05335       return;
05336 
05337     case BFD_RELOC_VTABLE_INHERIT:
05338     case BFD_RELOC_VTABLE_ENTRY:
05339       return;
05340 
05341     default:
05342       {
05343        const struct alpha_operand *operand;
05344 
05345        if ((int) fixP->fx_r_type >= 0)
05346          as_fatal (_("unhandled relocation type %s"),
05347                   bfd_get_reloc_code_name (fixP->fx_r_type));
05348 
05349        assert (-(int) fixP->fx_r_type < (int) alpha_num_operands);
05350        operand = &alpha_operands[-(int) fixP->fx_r_type];
05351 
05352        /* The rest of these fixups only exist internally during symbol
05353           resolution and have no representation in the object file.
05354           Therefore they must be completely resolved as constants.  */
05355 
05356        if (fixP->fx_addsy != 0
05357            && S_GET_SEGMENT (fixP->fx_addsy) != absolute_section)
05358          as_bad_where (fixP->fx_file, fixP->fx_line,
05359                      _("non-absolute expression in constant field"));
05360 
05361        image = bfd_getl32 (fixpos);
05362        image = insert_operand (image, operand, (offsetT) value,
05363                             fixP->fx_file, fixP->fx_line);
05364       }
05365       goto write_done;
05366     }
05367 
05368   if (fixP->fx_addsy != 0 || fixP->fx_pcrel != 0)
05369     return;
05370   else
05371     {
05372       as_warn_where (fixP->fx_file, fixP->fx_line,
05373                    _("type %d reloc done?\n"), (int) fixP->fx_r_type);
05374       goto done;
05375     }
05376 
05377 write_done:
05378   md_number_to_chars (fixpos, image, 4);
05379 
05380 done:
05381   fixP->fx_done = 1;
05382 }
05383 
05384 /* Look for a register name in the given symbol.  */
05385 
05386 symbolS *
05387 md_undefined_symbol (char *name)
05388 {
05389   if (*name == '$')
05390     {
05391       int is_float = 0, num;
05392 
05393       switch (*++name)
05394        {
05395        case 'f':
05396          if (name[1] == 'p' && name[2] == '\0')
05397            return alpha_register_table[AXP_REG_FP];
05398          is_float = 32;
05399          /* Fall through.  */
05400 
05401        case 'r':
05402          if (!ISDIGIT (*++name))
05403            break;
05404          /* Fall through.  */
05405 
05406        case '0': case '1': case '2': case '3': case '4':
05407        case '5': case '6': case '7': case '8': case '9':
05408          if (name[1] == '\0')
05409            num = name[0] - '0';
05410          else if (name[0] != '0' && ISDIGIT (name[1]) && name[2] == '\0')
05411            {
05412              num = (name[0] - '0') * 10 + name[1] - '0';
05413              if (num >= 32)
05414               break;
05415            }
05416          else
05417            break;
05418 
05419          if (!alpha_noat_on && (num + is_float) == AXP_REG_AT)
05420            as_warn (_("Used $at without \".set noat\""));
05421          return alpha_register_table[num + is_float];
05422 
05423        case 'a':
05424          if (name[1] == 't' && name[2] == '\0')
05425            {
05426              if (!alpha_noat_on)
05427               as_warn (_("Used $at without \".set noat\""));
05428              return alpha_register_table[AXP_REG_AT];
05429            }
05430          break;
05431 
05432        case 'g':
05433          if (name[1] == 'p' && name[2] == '\0')
05434            return alpha_register_table[alpha_gp_register];
05435          break;
05436 
05437        case 's':
05438          if (name[1] == 'p' && name[2] == '\0')
05439            return alpha_register_table[AXP_REG_SP];
05440          break;
05441        }
05442     }
05443   return NULL;
05444 }
05445 
05446 #ifdef OBJ_ECOFF
05447 /* @@@ Magic ECOFF bits.  */
05448 
05449 void
05450 alpha_frob_ecoff_data (void)
05451 {
05452   select_gp_value ();
05453   /* $zero and $f31 are read-only.  */
05454   alpha_gprmask &= ~1;
05455   alpha_fprmask &= ~1;
05456 }
05457 #endif
05458 
05459 /* Hook to remember a recently defined label so that the auto-align
05460    code can adjust the symbol after we know what alignment will be
05461    required.  */
05462 
05463 void
05464 alpha_define_label (symbolS *sym)
05465 {
05466   alpha_insn_label = sym;
05467 #ifdef OBJ_ELF
05468   dwarf2_emit_label (sym);
05469 #endif
05470 }
05471 
05472 /* Return true if we must always emit a reloc for a type and false if
05473    there is some hope of resolving it at assembly time.  */
05474 
05475 int
05476 alpha_force_relocation (fixS *f)
05477 {
05478   if (alpha_flag_relax)
05479     return 1;
05480 
05481   switch (f->fx_r_type)
05482     {
05483     case BFD_RELOC_ALPHA_GPDISP_HI16:
05484     case BFD_RELOC_ALPHA_GPDISP_LO16:
05485     case BFD_RELOC_ALPHA_GPDISP:
05486     case BFD_RELOC_ALPHA_LITERAL:
05487     case BFD_RELOC_ALPHA_ELF_LITERAL:
05488     case BFD_RELOC_ALPHA_LITUSE:
05489     case BFD_RELOC_GPREL16:
05490     case BFD_RELOC_GPREL32:
05491     case BFD_RELOC_ALPHA_GPREL_HI16:
05492     case BFD_RELOC_ALPHA_GPREL_LO16:
05493     case BFD_RELOC_ALPHA_LINKAGE:
05494     case BFD_RELOC_ALPHA_CODEADDR:
05495     case BFD_RELOC_ALPHA_BRSGP:
05496     case BFD_RELOC_ALPHA_TLSGD:
05497     case BFD_RELOC_ALPHA_TLSLDM:
05498     case BFD_RELOC_ALPHA_GOTDTPREL16:
05499     case BFD_RELOC_ALPHA_DTPREL_HI16:
05500     case BFD_RELOC_ALPHA_DTPREL_LO16:
05501     case BFD_RELOC_ALPHA_DTPREL16:
05502     case BFD_RELOC_ALPHA_GOTTPREL16:
05503     case BFD_RELOC_ALPHA_TPREL_HI16:
05504     case BFD_RELOC_ALPHA_TPREL_LO16:
05505     case BFD_RELOC_ALPHA_TPREL16:
05506       return 1;
05507 
05508     default:
05509       break;
05510     }
05511 
05512   return generic_force_reloc (f);
05513 }
05514 
05515 /* Return true if we can partially resolve a relocation now.  */
05516 
05517 int
05518 alpha_fix_adjustable (fixS *f)
05519 {
05520   /* Are there any relocation types for which we must generate a
05521      reloc but we can adjust the values contained within it?   */
05522   switch (f->fx_r_type)
05523     {
05524     case BFD_RELOC_ALPHA_GPDISP_HI16:
05525     case BFD_RELOC_ALPHA_GPDISP_LO16:
05526     case BFD_RELOC_ALPHA_GPDISP:
05527       return 0;
05528 
05529     case BFD_RELOC_ALPHA_LITERAL:
05530     case BFD_RELOC_ALPHA_ELF_LITERAL:
05531     case BFD_RELOC_ALPHA_LITUSE:
05532     case BFD_RELOC_ALPHA_LINKAGE:
05533     case BFD_RELOC_ALPHA_CODEADDR:
05534       return 1;
05535 
05536     case BFD_RELOC_VTABLE_ENTRY:
05537     case BFD_RELOC_VTABLE_INHERIT:
05538       return 0;
05539 
05540     case BFD_RELOC_GPREL16:
05541     case BFD_RELOC_GPREL32:
05542     case BFD_RELOC_ALPHA_GPREL_HI16:
05543     case BFD_RELOC_ALPHA_GPREL_LO16:
05544     case BFD_RELOC_23_PCREL_S2:
05545     case BFD_RELOC_32:
05546     case BFD_RELOC_64:
05547     case BFD_RELOC_ALPHA_HINT:
05548       return 1;
05549 
05550     case BFD_RELOC_ALPHA_TLSGD:
05551     case BFD_RELOC_ALPHA_TLSLDM:
05552     case BFD_RELOC_ALPHA_GOTDTPREL16:
05553     case BFD_RELOC_ALPHA_DTPREL_HI16:
05554     case BFD_RELOC_ALPHA_DTPREL_LO16:
05555     case BFD_RELOC_ALPHA_DTPREL16:
05556     case BFD_RELOC_ALPHA_GOTTPREL16:
05557     case BFD_RELOC_ALPHA_TPREL_HI16:
05558     case BFD_RELOC_ALPHA_TPREL_LO16:
05559     case BFD_RELOC_ALPHA_TPREL16:
05560       /* ??? No idea why we can't return a reference to .tbss+10, but
05561         we're preventing this in the other assemblers.  Follow for now.  */
05562       return 0;
05563 
05564 #ifdef OBJ_ELF
05565     case BFD_RELOC_ALPHA_BRSGP:
05566       /* If we have a BRSGP reloc to a local symbol, adjust it to BRADDR and
05567          let it get resolved at assembly time.  */
05568       {
05569        symbolS *sym = f->fx_addsy;
05570        const char *name;
05571        int offset = 0;
05572 
05573        if (generic_force_reloc (f))
05574          return 0;
05575 
05576        switch (S_GET_OTHER (sym) & STO_ALPHA_STD_GPLOAD)
05577          {
05578          case STO_ALPHA_NOPV:
05579            break;
05580          case STO_ALPHA_STD_GPLOAD:
05581            offset = 8;
05582            break;
05583          default:
05584            if (S_IS_LOCAL (sym))
05585              name = "<local>";
05586            else
05587              name = S_GET_NAME (sym);
05588            as_bad_where (f->fx_file, f->fx_line,
05589               _("!samegp reloc against symbol without .prologue: %s"),
05590               name);
05591            break;
05592          }
05593        f->fx_r_type = BFD_RELOC_23_PCREL_S2;
05594        f->fx_offset += offset;
05595        return 1;
05596       }
05597 #endif
05598 
05599     default:
05600       return 1;
05601     }
05602 }
05603 
05604 /* Generate the BFD reloc to be stuck in the object file from the
05605    fixup used internally in the assembler.  */
05606 
05607 arelent *
05608 tc_gen_reloc (asection *sec ATTRIBUTE_UNUSED,
05609              fixS *fixp)
05610 {
05611   arelent *reloc;
05612 
05613   reloc = xmalloc (sizeof (* reloc));
05614   reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
05615   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
05616   reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
05617 
05618   /* Make sure none of our internal relocations make it this far.
05619      They'd better have been fully resolved by this point.  */
05620   assert ((int) fixp->fx_r_type > 0);
05621 
05622   reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
05623   if (reloc->howto == NULL)
05624     {
05625       as_bad_where (fixp->fx_file, fixp->fx_line,
05626                   _("cannot represent `%s' relocation in object file"),
05627                   bfd_get_reloc_code_name (fixp->fx_r_type));
05628       return NULL;
05629     }
05630 
05631   if (!fixp->fx_pcrel != !reloc->howto->pc_relative)
05632     as_fatal (_("internal error? cannot generate `%s' relocation"),
05633              bfd_get_reloc_code_name (fixp->fx_r_type));
05634 
05635   assert (!fixp->fx_pcrel == !reloc->howto->pc_relative);
05636 
05637 #ifdef OBJ_ECOFF
05638   if (fixp->fx_r_type == BFD_RELOC_ALPHA_LITERAL)
05639     /* Fake out bfd_perform_relocation. sigh.  */
05640     reloc->addend = -alpha_gp_value;
05641   else
05642 #endif
05643     {
05644       reloc->addend = fixp->fx_offset;
05645 #ifdef OBJ_ELF
05646       /* Ohhh, this is ugly.  The problem is that if this is a local global
05647          symbol, the relocation will entirely be performed at link time, not
05648          at assembly time.  bfd_perform_reloc doesn't know about this sort
05649          of thing, and as a result we need to fake it out here.  */
05650       if ((S_IS_EXTERNAL (fixp->fx_addsy) || S_IS_WEAK (fixp->fx_addsy)
05651           || (S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_MERGE)
05652           || (S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_THREAD_LOCAL))
05653          && !S_IS_COMMON (fixp->fx_addsy))
05654        reloc->addend -= symbol_get_bfdsym (fixp->fx_addsy)->value;
05655 #endif
05656     }
05657 
05658   return reloc;
05659 }
05660 
05661 /* Parse a register name off of the input_line and return a register
05662    number.  Gets md_undefined_symbol above to do the register name
05663    matching for us.
05664 
05665    Only called as a part of processing the ECOFF .frame directive.  */
05666 
05667 int
05668 tc_get_register (int frame ATTRIBUTE_UNUSED)
05669 {
05670   int framereg = AXP_REG_SP;
05671 
05672   SKIP_WHITESPACE ();
05673   if (*input_line_pointer == '$')
05674     {
05675       char *s = input_line_pointer;
05676       char c = get_symbol_end ();
05677       symbolS *sym = md_undefined_symbol (s);
05678 
05679       *strchr (s, '\0') = c;
05680       if (sym && (framereg = S_GET_VALUE (sym)) <= 31)
05681        goto found;
05682     }
05683   as_warn (_("frame reg expected, using $%d."), framereg);
05684 
05685 found:
05686   note_gpreg (framereg);
05687   return framereg;
05688 }
05689 
05690 /* This is called before the symbol table is processed.  In order to
05691    work with gcc when using mips-tfile, we must keep all local labels.
05692    However, in other cases, we want to discard them.  If we were
05693    called with -g, but we didn't see any debugging information, it may
05694    mean that gcc is smuggling debugging information through to
05695    mips-tfile, in which case we must generate all local labels.  */
05696 
05697 #ifdef OBJ_ECOFF
05698 
05699 void
05700 alpha_frob_file_before_adjust (void)
05701 {
05702   if (alpha_debug != 0
05703       && ! ecoff_debugging_seen)
05704     flag_keep_locals = 1;
05705 }
05706 
05707 #endif /* OBJ_ECOFF */
05708 
05709 /* The Alpha has support for some VAX floating point types, as well as for
05710    IEEE floating point.  We consider IEEE to be the primary floating point
05711    format, and sneak in the VAX floating point support here.  */
05712 #define md_atof vax_md_atof
05713 #include "config/atof-vax.c"