Back to index

cell-binutils  2.17cvs20070401
tc-mmix.c
Go to the documentation of this file.
00001 /* tc-mmix.c -- Assembler for Don Knuth's MMIX.
00002    Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006
00003    Free Software Foundation.
00004 
00005    This file is part of GAS, the GNU Assembler.
00006 
00007    GAS is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU General Public License as published by
00009    the Free Software Foundation; either version 2, or (at your option)
00010    any later version.
00011 
00012    GAS is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015    GNU General Public License for more details.
00016 
00017    You should have received a copy of the GNU General Public License
00018    along with GAS; see the file COPYING.  If not, write to
00019    the Free Software Foundation, 51 Franklin Street - Fifth Floor,
00020    Boston, MA 02110-1301, USA.  */
00021 
00022 /* Knuth's assembler mmixal does not provide a relocatable format; mmo is
00023    to be considered a final link-format.  In the final link, we make mmo,
00024    but for relocatable files, we use ELF.
00025 
00026    One goal is to provide a superset of what mmixal does, including
00027    compatible syntax, but the main purpose is to serve GCC.  */
00028 
00029 
00030 #include <limits.h>
00031 #include "as.h"
00032 #include "subsegs.h"
00033 #include "elf/mmix.h"
00034 #include "opcode/mmix.h"
00035 #include "safe-ctype.h"
00036 #include "dwarf2dbg.h"
00037 #include "obstack.h"
00038 
00039 /* Something to describe what we need to do with a fixup before output,
00040    for example assert something of what it became or make a relocation.  */
00041 
00042 enum mmix_fixup_action
00043  {
00044    mmix_fixup_byte,
00045    mmix_fixup_register,
00046    mmix_fixup_register_or_adjust_for_byte
00047  };
00048 
00049 static int get_spec_regno (char *);
00050 static int get_operands (int, char *, expressionS *);
00051 static int get_putget_operands (struct mmix_opcode *, char *, expressionS *);
00052 static void s_prefix (int);
00053 static void s_greg (int);
00054 static void s_loc (int);
00055 static void s_bspec (int);
00056 static void s_espec (int);
00057 static void mmix_s_local (int);
00058 static void mmix_greg_internal (char *);
00059 static void mmix_set_geta_branch_offset (char *, offsetT);
00060 static void mmix_set_jmp_offset (char *, offsetT);
00061 static void mmix_fill_nops (char *, int);
00062 static int cmp_greg_symbol_fixes (const void *, const void *);
00063 static int cmp_greg_val_greg_symbol_fixes (const void *, const void *);
00064 static void mmix_handle_rest_of_empty_line (void);
00065 static void mmix_discard_rest_of_line (void);
00066 static void mmix_byte (void);
00067 static void mmix_cons (int);
00068 
00069 /* Continue the tradition of symbols.c; use control characters to enforce
00070    magic.  These are used when replacing e.g. 8F and 8B so we can handle
00071    such labels correctly with the common parser hooks.  */
00072 #define MAGIC_FB_BACKWARD_CHAR '\003'
00073 #define MAGIC_FB_FORWARD_CHAR '\004'
00074 
00075 /* Copy the location of a frag to a fix.  */
00076 #define COPY_FR_WHERE_TO_FX(FRAG, FIX)           \
00077  do                                       \
00078    {                                      \
00079      (FIX)->fx_file = (FRAG)->fr_file;           \
00080      (FIX)->fx_line = (FRAG)->fr_line;           \
00081    }                                      \
00082  while (0)
00083 
00084 const char *md_shortopts = "x";
00085 static int current_fb_label = -1;
00086 static char *pending_label = NULL;
00087 
00088 static bfd_vma lowest_text_loc = (bfd_vma) -1;
00089 static int text_has_contents = 0;
00090 
00091 /* The alignment of the previous instruction, and a boolean for whether we
00092    want to avoid aligning the next WYDE, TETRA, OCTA or insn.  */
00093 static int last_alignment = 0;
00094 static int want_unaligned = 0;
00095 
00096 static bfd_vma lowest_data_loc = (bfd_vma) -1;
00097 static int data_has_contents = 0;
00098 
00099 /* The fragS of the instruction being assembled.  Only valid from within
00100    md_assemble.  */
00101 fragS *mmix_opcode_frag = NULL;
00102 
00103 /* Raw GREGs as appearing in input.  These may be fewer than the number
00104    after relaxing.  */
00105 static int n_of_raw_gregs = 0;
00106 static struct
00107  {
00108    char *label;
00109    expressionS exp;
00110  } mmix_raw_gregs[MAX_GREGS];
00111 
00112 /* Fixups for all unique GREG registers.  We store the fixups here in
00113    md_convert_frag, then we use the array to convert
00114    BFD_RELOC_MMIX_BASE_PLUS_OFFSET fixups in tc_gen_reloc.  The index is
00115    just a running number and is not supposed to be correlated to a
00116    register number.  */
00117 static fixS *mmix_gregs[MAX_GREGS];
00118 static int n_of_cooked_gregs = 0;
00119 
00120 /* Pointing to the register section we use for output.  */
00121 static asection *real_reg_section;
00122 
00123 /* For each symbol; unknown or section symbol, we keep a list of GREG
00124    definitions sorted on increasing offset.  It seems no use keeping count
00125    to allocate less room than the maximum number of gregs when we've found
00126    one for a section or symbol.  */
00127 struct mmix_symbol_gregs
00128  {
00129    int n_gregs;
00130    struct mmix_symbol_greg_fixes
00131    {
00132      fixS *fix;
00133 
00134      /* A signed type, since we may have GREGs pointing slightly before the
00135        contents of a section.  */
00136      offsetT offs;
00137    } greg_fixes[MAX_GREGS];
00138  };
00139 
00140 /* Should read insert a colon on something that starts in column 0 on
00141    this line?  */
00142 static int label_without_colon_this_line = 1;
00143 
00144 /* Should we automatically expand instructions into multiple insns in
00145    order to generate working code?  */
00146 static int expand_op = 1;
00147 
00148 /* Should we warn when expanding operands?  FIXME: test-cases for when -x
00149    is absent.  */
00150 static int warn_on_expansion = 1;
00151 
00152 /* Should we merge non-zero GREG register definitions?  */
00153 static int merge_gregs = 1;
00154 
00155 /* Should we pass on undefined BFD_RELOC_MMIX_BASE_PLUS_OFFSET relocs
00156    (missing suitable GREG definitions) to the linker?  */
00157 static int allocate_undefined_gregs_in_linker = 0;
00158 
00159 /* Should we emit built-in symbols?  */
00160 static int predefined_syms = 1;
00161 
00162 /* Should we allow anything but the listed special register name
00163    (e.g. equated symbols)?  */
00164 static int equated_spec_regs = 1;
00165 
00166 /* Do we require standard GNU syntax?  */
00167 int mmix_gnu_syntax = 0;
00168 
00169 /* Do we globalize all symbols?  */
00170 int mmix_globalize_symbols = 0;
00171 
00172 /* When expanding insns, do we want to expand PUSHJ as a call to a stub
00173    (or else as a series of insns)?  */
00174 int pushj_stubs = 1;
00175 
00176 /* Do we know that the next semicolon is at the end of the operands field
00177    (in mmixal mode; constant 1 in GNU mode)?  */
00178 int mmix_next_semicolon_is_eoln = 1;
00179 
00180 /* Do we have a BSPEC in progress?  */
00181 static int doing_bspec = 0;
00182 static char *bspec_file;
00183 static unsigned int bspec_line;
00184 
00185 struct option md_longopts[] =
00186  {
00187 #define OPTION_RELAX  (OPTION_MD_BASE)
00188 #define OPTION_NOEXPAND  (OPTION_RELAX + 1)
00189 #define OPTION_NOMERGEGREG  (OPTION_NOEXPAND + 1)
00190 #define OPTION_NOSYMS  (OPTION_NOMERGEGREG + 1)
00191 #define OPTION_GNU_SYNTAX  (OPTION_NOSYMS + 1)
00192 #define OPTION_GLOBALIZE_SYMBOLS  (OPTION_GNU_SYNTAX + 1)
00193 #define OPTION_FIXED_SPEC_REGS  (OPTION_GLOBALIZE_SYMBOLS + 1)
00194 #define OPTION_LINKER_ALLOCATED_GREGS  (OPTION_FIXED_SPEC_REGS + 1)
00195 #define OPTION_NOPUSHJSTUBS  (OPTION_LINKER_ALLOCATED_GREGS + 1)
00196    {"linkrelax", no_argument, NULL, OPTION_RELAX},
00197    {"no-expand", no_argument, NULL, OPTION_NOEXPAND},
00198    {"no-merge-gregs", no_argument, NULL, OPTION_NOMERGEGREG},
00199    {"no-predefined-syms", no_argument, NULL, OPTION_NOSYMS},
00200    {"gnu-syntax", no_argument, NULL, OPTION_GNU_SYNTAX},
00201    {"globalize-symbols", no_argument, NULL, OPTION_GLOBALIZE_SYMBOLS},
00202    {"fixed-special-register-names", no_argument, NULL,
00203     OPTION_FIXED_SPEC_REGS},
00204    {"linker-allocated-gregs", no_argument, NULL,
00205     OPTION_LINKER_ALLOCATED_GREGS},
00206    {"no-pushj-stubs", no_argument, NULL, OPTION_NOPUSHJSTUBS},
00207    {"no-stubs", no_argument, NULL, OPTION_NOPUSHJSTUBS},
00208    {NULL, no_argument, NULL, 0}
00209  };
00210 
00211 size_t md_longopts_size = sizeof (md_longopts);
00212 
00213 static struct hash_control *mmix_opcode_hash;
00214 
00215 /* We use these when implementing the PREFIX pseudo.  */
00216 char *mmix_current_prefix;
00217 struct obstack mmix_sym_obstack;
00218 
00219 
00220 /* For MMIX, we encode the relax_substateT:s (in e.g. fr_substate) as one
00221    bit length, and the relax-type shifted on top of that.  There seems to
00222    be no point in making the relaxation more fine-grained; the linker does
00223    that better and we might interfere by changing non-optimal relaxations
00224    into other insns that cannot be relaxed as easily.
00225 
00226    Groups for MMIX relaxing:
00227 
00228    1. GETA
00229       extra length: zero or three insns.
00230 
00231    2. Bcc
00232       extra length: zero or five insns.
00233 
00234    3. PUSHJ
00235       extra length: zero or four insns.
00236       Special handling to deal with transition to PUSHJSTUB.
00237 
00238    4. JMP
00239       extra length: zero or four insns.
00240 
00241    5. GREG
00242       special handling, allocates a named global register unless another
00243       is within reach for all uses.
00244 
00245    6. PUSHJSTUB
00246       special handling (mostly) for external references; assumes the
00247       linker will generate a stub if target is no longer than 256k from
00248       the end of the section plus max size of previous stubs.  Zero or
00249       four insns.  */
00250 
00251 #define STATE_GETA   (1)
00252 #define STATE_BCC    (2)
00253 #define STATE_PUSHJ  (3)
00254 #define STATE_JMP    (4)
00255 #define STATE_GREG   (5)
00256 #define STATE_PUSHJSTUB     (6)
00257 
00258 /* No fine-grainedness here.  */
00259 #define STATE_LENGTH_MASK       (1)
00260 
00261 #define STATE_ZERO              (0)
00262 #define STATE_MAX               (1)
00263 
00264 /* More descriptive name for convenience.  */
00265 /* FIXME: We should start on something different, not MAX.  */
00266 #define STATE_UNDF              STATE_MAX
00267 
00268 /* FIXME: For GREG, we must have other definitions; UNDF == MAX isn't
00269    appropriate; we need it the other way round.  This value together with
00270    fragP->tc_frag_data shows what state the frag is in: tc_frag_data
00271    non-NULL means 0, NULL means 8 bytes.  */
00272 #define STATE_GREG_UNDF ENCODE_RELAX (STATE_GREG, STATE_ZERO)
00273 #define STATE_GREG_DEF ENCODE_RELAX (STATE_GREG, STATE_MAX)
00274 
00275 /* These displacements are relative to the address following the opcode
00276    word of the instruction.  The catch-all states have zero for "reach"
00277    and "next" entries.  */
00278 
00279 #define GETA_0F (65536 * 4 - 8)
00280 #define GETA_0B (-65536 * 4 - 4)
00281 
00282 #define GETA_MAX_LEN 4 * 4
00283 #define GETA_3F 0
00284 #define GETA_3B 0
00285 
00286 #define BCC_0F GETA_0F
00287 #define BCC_0B GETA_0B
00288 
00289 #define BCC_MAX_LEN 6 * 4
00290 #define BCC_5F GETA_3F
00291 #define BCC_5B GETA_3B
00292 
00293 #define PUSHJ_0F GETA_0F
00294 #define PUSHJ_0B GETA_0B
00295 
00296 #define PUSHJ_MAX_LEN 5 * 4
00297 #define PUSHJ_4F GETA_3F
00298 #define PUSHJ_4B GETA_3B
00299 
00300 /* We'll very rarely have sections longer than LONG_MAX, but we'll make a
00301    feeble attempt at getting 64-bit values.  */
00302 #define PUSHJSTUB_MAX ((offsetT) (((addressT) -1) >> 1))
00303 #define PUSHJSTUB_MIN (-PUSHJSTUB_MAX - 1)
00304 
00305 #define JMP_0F (65536 * 256 * 4 - 8)
00306 #define JMP_0B (-65536 * 256 * 4 - 4)
00307 
00308 #define JMP_MAX_LEN 5 * 4
00309 #define JMP_4F 0
00310 #define JMP_4B 0
00311 
00312 #define RELAX_ENCODE_SHIFT 1
00313 #define ENCODE_RELAX(what, length) (((what) << RELAX_ENCODE_SHIFT) + (length))
00314 
00315 const relax_typeS mmix_relax_table[] =
00316  {
00317    /* Error sentinel (0, 0).  */
00318    {1,        1,            0,     0},
00319 
00320    /* Unused (0, 1).  */
00321    {1,        1,            0,     0},
00322 
00323    /* GETA (1, 0).  */
00324    {GETA_0F,  GETA_0B,      0,     ENCODE_RELAX (STATE_GETA, STATE_MAX)},
00325 
00326    /* GETA (1, 1).  */
00327    {GETA_3F,  GETA_3B,
00328               GETA_MAX_LEN - 4,    0},
00329 
00330    /* BCC (2, 0).  */
00331    {BCC_0F,   BCC_0B,              0,     ENCODE_RELAX (STATE_BCC, STATE_MAX)},
00332 
00333    /* BCC (2, 1).  */
00334    {BCC_5F,   BCC_5B,
00335               BCC_MAX_LEN - 4,     0},
00336 
00337    /* PUSHJ (3, 0).  Next state is actually PUSHJSTUB (6, 0).  */
00338    {PUSHJ_0F, PUSHJ_0B,     0,     ENCODE_RELAX (STATE_PUSHJSTUB, STATE_ZERO)},
00339 
00340    /* PUSHJ (3, 1).  */
00341    {PUSHJ_4F, PUSHJ_4B,
00342               PUSHJ_MAX_LEN - 4,   0},
00343 
00344    /* JMP (4, 0).  */
00345    {JMP_0F,   JMP_0B,              0,     ENCODE_RELAX (STATE_JMP, STATE_MAX)},
00346 
00347    /* JMP (4, 1).  */
00348    {JMP_4F,   JMP_4B,
00349               JMP_MAX_LEN - 4,     0},
00350 
00351    /* GREG (5, 0), (5, 1), though the table entry isn't used.  */
00352    {0, 0, 0, 0}, {0, 0, 0, 0},
00353 
00354    /* PUSHJSTUB (6, 0).  PUSHJ (3, 0) uses the range, so we set it to infinite.  */
00355    {PUSHJSTUB_MAX, PUSHJSTUB_MIN,
00356               0,                   ENCODE_RELAX (STATE_PUSHJ, STATE_MAX)},
00357    /* PUSHJSTUB (6, 1) isn't used.  */
00358    {0, 0,     PUSHJ_MAX_LEN,              0}
00359 };
00360 
00361 const pseudo_typeS md_pseudo_table[] =
00362  {
00363    /* Support " .greg sym,expr" syntax.  */
00364    {"greg", s_greg, 0},
00365 
00366    /* Support " .bspec expr" syntax.  */
00367    {"bspec", s_bspec, 1},
00368 
00369    /* Support " .espec" syntax.  */
00370    {"espec", s_espec, 1},
00371 
00372    /* Support " .local $45" syntax.  */
00373    {"local", mmix_s_local, 1},
00374 
00375    {NULL, 0, 0}
00376  };
00377 
00378 const char mmix_comment_chars[] = "%!";
00379 
00380 /* A ':' is a valid symbol character in mmixal.  It's the prefix
00381    delimiter, but other than that, it works like a symbol character,
00382    except that we strip one off at the beginning of symbols.  An '@' is a
00383    symbol by itself (for the current location); space around it must not
00384    be stripped.  */
00385 const char mmix_symbol_chars[] = ":@";
00386 
00387 const char line_comment_chars[] = "*#";
00388 
00389 const char line_separator_chars[] = ";";
00390 
00391 const char mmix_exp_chars[] = "eE";
00392 
00393 const char mmix_flt_chars[] = "rf";
00394 
00395 
00396 /* Fill in the offset-related part of GETA or Bcc.  */
00397 
00398 static void
00399 mmix_set_geta_branch_offset (char *opcodep, offsetT value)
00400 {
00401   if (value < 0)
00402     {
00403       value += 65536 * 4;
00404       opcodep[0] |= 1;
00405     }
00406 
00407   value /= 4;
00408   md_number_to_chars (opcodep + 2, value, 2);
00409 }
00410 
00411 /* Fill in the offset-related part of JMP.  */
00412 
00413 static void
00414 mmix_set_jmp_offset (char *opcodep, offsetT value)
00415 {
00416   if (value < 0)
00417     {
00418       value += 65536 * 256 * 4;
00419       opcodep[0] |= 1;
00420     }
00421 
00422   value /= 4;
00423   md_number_to_chars (opcodep + 1, value, 3);
00424 }
00425 
00426 /* Fill in NOP:s for the expanded part of GETA/JMP/Bcc/PUSHJ.  */
00427 
00428 static void
00429 mmix_fill_nops (char *opcodep, int n)
00430 {
00431   int i;
00432 
00433   for (i = 0; i < n; i++)
00434     md_number_to_chars (opcodep + i * 4, SWYM_INSN_BYTE << 24, 4);
00435 }
00436 
00437 /* See macro md_parse_name in tc-mmix.h.  */
00438 
00439 int
00440 mmix_current_location (void (*fn) (expressionS *), expressionS *exp)
00441 {
00442   (*fn) (exp);
00443 
00444   return 1;
00445 }
00446 
00447 /* Get up to three operands, filling them into the exp array.
00448    General idea and code stolen from the tic80 port.  */
00449 
00450 static int
00451 get_operands (int max_operands, char *s, expressionS *exp)
00452 {
00453   char *p = s;
00454   int numexp = 0;
00455   int nextchar = ',';
00456 
00457   while (nextchar == ',')
00458     {
00459       /* Skip leading whitespace */
00460       while (*p == ' ' || *p == '\t')
00461        p++;
00462 
00463       /* Check to see if we have any operands left to parse */
00464       if (*p == 0 || *p == '\n' || *p == '\r')
00465        {
00466          break;
00467        }
00468       else if (numexp == max_operands)
00469        {
00470          /* This seems more sane than saying "too many operands".  We'll
00471             get here only if the trailing trash starts with a comma.  */
00472          as_bad (_("invalid operands"));
00473          mmix_discard_rest_of_line ();
00474          return 0;
00475        }
00476 
00477       /* Begin operand parsing at the current scan point.  */
00478 
00479       input_line_pointer = p;
00480       expression (&exp[numexp]);
00481 
00482       if (exp[numexp].X_op == O_illegal)
00483        {
00484          as_bad (_("invalid operands"));
00485        }
00486       else if (exp[numexp].X_op == O_absent)
00487        {
00488          as_bad (_("missing operand"));
00489        }
00490 
00491       numexp++;
00492       p = input_line_pointer;
00493 
00494       /* Skip leading whitespace */
00495       while (*p == ' ' || *p == '\t')
00496        p++;
00497       nextchar = *p++;
00498     }
00499 
00500   /* If we allow "naked" comments, ignore the rest of the line.  */
00501   if (nextchar != ',')
00502     {
00503       mmix_handle_rest_of_empty_line ();
00504       input_line_pointer--;
00505     }
00506 
00507   /* Mark the end of the valid operands with an illegal expression.  */
00508   exp[numexp].X_op = O_illegal;
00509 
00510   return (numexp);
00511 }
00512 
00513 /* Get the value of a special register, or -1 if the name does not match
00514    one.  NAME is a null-terminated string.  */
00515 
00516 static int
00517 get_spec_regno (char *name)
00518 {
00519   int i;
00520 
00521   if (name == NULL)
00522     return -1;
00523 
00524   if (*name == ':')
00525     name++;
00526 
00527   /* Well, it's a short array and we'll most often just match the first
00528      entry, rJ.  */
00529   for (i = 0; mmix_spec_regs[i].name != NULL; i++)
00530     if (strcmp (name, mmix_spec_regs[i].name) == 0)
00531       return mmix_spec_regs[i].number;
00532 
00533   return -1;
00534 }
00535 
00536 /* For GET and PUT, parse the register names "manually", so we don't use
00537    user labels.  */
00538 static int
00539 get_putget_operands (struct mmix_opcode *insn, char *operands,
00540                    expressionS *exp)
00541 {
00542   expressionS *expp_reg;
00543   expressionS *expp_sreg;
00544   char *sregp = NULL;
00545   char *sregend = operands;
00546   char *p = operands;
00547   char c = *sregend;
00548   int regno;
00549 
00550   /* Skip leading whitespace */
00551   while (*p == ' ' || *p == '\t')
00552     p++;
00553 
00554   input_line_pointer = p;
00555 
00556   /* Initialize both possible operands to error state, in case we never
00557      get further.  */
00558   exp[0].X_op = O_illegal;
00559   exp[1].X_op = O_illegal;
00560 
00561   if (insn->operands == mmix_operands_get)
00562     {
00563       expp_reg = &exp[0];
00564       expp_sreg = &exp[1];
00565 
00566       expression (expp_reg);
00567 
00568       p = input_line_pointer;
00569 
00570       /* Skip whitespace */
00571       while (*p == ' ' || *p == '\t')
00572        p++;
00573 
00574       if (*p == ',')
00575        {
00576          p++;
00577 
00578          /* Skip whitespace */
00579          while (*p == ' ' || *p == '\t')
00580            p++;
00581          sregp = p;
00582          input_line_pointer = sregp;
00583          c = get_symbol_end ();
00584          sregend = input_line_pointer;
00585        }
00586     }
00587   else
00588     {
00589       expp_sreg = &exp[0];
00590       expp_reg = &exp[1];
00591 
00592       sregp = p;
00593       c = get_symbol_end ();
00594       sregend = p = input_line_pointer;
00595       *p = c;
00596 
00597       /* Skip whitespace */
00598       while (*p == ' ' || *p == '\t')
00599        p++;
00600 
00601       if (*p == ',')
00602        {
00603          p++;
00604 
00605          /* Skip whitespace */
00606          while (*p == ' ' || *p == '\t')
00607            p++;
00608 
00609          input_line_pointer = p;
00610          expression (expp_reg);
00611        }
00612       *sregend = 0;
00613     }
00614 
00615   regno = get_spec_regno (sregp);
00616   *sregend = c;
00617 
00618   /* Let the caller issue errors; we've made sure the operands are
00619      invalid.  */
00620   if (expp_reg->X_op != O_illegal
00621       && expp_reg->X_op != O_absent
00622       && regno != -1)
00623     {
00624       expp_sreg->X_op = O_register;
00625       expp_sreg->X_add_number = regno + 256;
00626     }
00627 
00628   return 2;
00629 }
00630 
00631 /* Handle MMIX-specific option.  */
00632 
00633 int
00634 md_parse_option (int c, char *arg ATTRIBUTE_UNUSED)
00635 {
00636   switch (c)
00637     {
00638     case 'x':
00639       warn_on_expansion = 0;
00640       allocate_undefined_gregs_in_linker = 1;
00641       break;
00642 
00643     case OPTION_RELAX:
00644       linkrelax = 1;
00645       break;
00646 
00647     case OPTION_NOEXPAND:
00648       expand_op = 0;
00649       break;
00650 
00651     case OPTION_NOMERGEGREG:
00652       merge_gregs = 0;
00653       break;
00654 
00655     case OPTION_NOSYMS:
00656       predefined_syms = 0;
00657       equated_spec_regs = 0;
00658       break;
00659 
00660     case OPTION_GNU_SYNTAX:
00661       mmix_gnu_syntax = 1;
00662       label_without_colon_this_line = 0;
00663       break;
00664 
00665     case OPTION_GLOBALIZE_SYMBOLS:
00666       mmix_globalize_symbols = 1;
00667       break;
00668 
00669     case OPTION_FIXED_SPEC_REGS:
00670       equated_spec_regs = 0;
00671       break;
00672 
00673     case OPTION_LINKER_ALLOCATED_GREGS:
00674       allocate_undefined_gregs_in_linker = 1;
00675       break;
00676 
00677     case OPTION_NOPUSHJSTUBS:
00678       pushj_stubs = 0;
00679       break;
00680 
00681     default:
00682       return 0;
00683     }
00684 
00685   return 1;
00686 }
00687 
00688 /* Display MMIX-specific help text.  */
00689 
00690 void
00691 md_show_usage (FILE * stream)
00692 {
00693   fprintf (stream, _(" MMIX-specific command line options:\n"));
00694   fprintf (stream, _("\
00695   -fixed-special-register-names\n\
00696                           Allow only the original special register names.\n"));
00697   fprintf (stream, _("\
00698   -globalize-symbols      Make all symbols global.\n"));
00699   fprintf (stream, _("\
00700   -gnu-syntax             Turn off mmixal syntax compatibility.\n"));
00701   fprintf (stream, _("\
00702   -relax                  Create linker relaxable code.\n"));
00703   fprintf (stream, _("\
00704   -no-predefined-syms     Do not provide mmixal built-in constants.\n\
00705                           Implies -fixed-special-register-names.\n"));
00706   fprintf (stream, _("\
00707   -no-expand              Do not expand GETA, branches, PUSHJ or JUMP\n\
00708                           into multiple instructions.\n"));
00709   fprintf (stream, _("\
00710   -no-merge-gregs         Do not merge GREG definitions with nearby values.\n"));
00711   fprintf (stream, _("\
00712   -linker-allocated-gregs If there's no suitable GREG definition for the\
00713                           operands of an instruction, let the linker resolve.\n"));
00714   fprintf (stream, _("\
00715   -x                      Do not warn when an operand to GETA, a branch,\n\
00716                           PUSHJ or JUMP is not known to be within range.\n\
00717                           The linker will catch any errors.  Implies\n\
00718                           -linker-allocated-gregs."));
00719 }
00720 
00721 /* Step to end of line, but don't step over the end of the line.  */
00722 
00723 static void
00724 mmix_discard_rest_of_line (void)
00725 {
00726   while (*input_line_pointer
00727         && (! is_end_of_line[(unsigned char) *input_line_pointer]
00728             || TC_EOL_IN_INSN (input_line_pointer)))
00729     input_line_pointer++;
00730 }
00731 
00732 /* Act as demand_empty_rest_of_line if we're in strict GNU syntax mode,
00733    otherwise just ignore the rest of the line (and skip the end-of-line
00734    delimiter).  */
00735 
00736 static void
00737 mmix_handle_rest_of_empty_line (void)
00738 {
00739   if (mmix_gnu_syntax)
00740     demand_empty_rest_of_line ();
00741   else
00742     {
00743       mmix_discard_rest_of_line ();
00744       input_line_pointer++;
00745     }
00746 }
00747 
00748 /* Initialize GAS MMIX specifics.  */
00749 
00750 void
00751 mmix_md_begin (void)
00752 {
00753   int i;
00754   const struct mmix_opcode *opcode;
00755 
00756   /* We assume nobody will use this, so don't allocate any room.  */
00757   obstack_begin (&mmix_sym_obstack, 0);
00758 
00759   /* This will break the day the "lex" thingy changes.  For now, it's the
00760      only way to make ':' part of a name, and a name beginner.  */
00761   lex_type[':'] = (LEX_NAME | LEX_BEGIN_NAME);
00762 
00763   mmix_opcode_hash = hash_new ();
00764 
00765   real_reg_section
00766     = bfd_make_section_old_way (stdoutput, MMIX_REG_SECTION_NAME);
00767 
00768   for (opcode = mmix_opcodes; opcode->name; opcode++)
00769     hash_insert (mmix_opcode_hash, opcode->name, (char *) opcode);
00770 
00771   /* We always insert the ordinary registers 0..255 as registers.  */
00772   for (i = 0; i < 256; i++)
00773     {
00774       char buf[5];
00775 
00776       /* Alternatively, we could diddle with '$' and the following number,
00777         but keeping the registers as symbols helps keep parsing simple.  */
00778       sprintf (buf, "$%d", i);
00779       symbol_table_insert (symbol_new (buf, reg_section, i,
00780                                    &zero_address_frag));
00781     }
00782 
00783   /* Insert mmixal built-in names if allowed.  */
00784   if (predefined_syms)
00785     {
00786       for (i = 0; mmix_spec_regs[i].name != NULL; i++)
00787        symbol_table_insert (symbol_new (mmix_spec_regs[i].name,
00788                                     reg_section,
00789                                     mmix_spec_regs[i].number + 256,
00790                                     &zero_address_frag));
00791 
00792       /* FIXME: Perhaps these should be recognized as specials; as field
00793         names for those instructions.  */
00794       symbol_table_insert (symbol_new ("ROUND_CURRENT", reg_section, 512,
00795                                    &zero_address_frag));
00796       symbol_table_insert (symbol_new ("ROUND_OFF", reg_section, 512 + 1,
00797                                    &zero_address_frag));
00798       symbol_table_insert (symbol_new ("ROUND_UP", reg_section, 512 + 2,
00799                                    &zero_address_frag));
00800       symbol_table_insert (symbol_new ("ROUND_DOWN", reg_section, 512 + 3,
00801                                    &zero_address_frag));
00802       symbol_table_insert (symbol_new ("ROUND_NEAR", reg_section, 512 + 4,
00803                                    &zero_address_frag));
00804     }
00805 }
00806 
00807 /* Assemble one insn in STR.  */
00808 
00809 void
00810 md_assemble (char *str)
00811 {
00812   char *operands = str;
00813   char modified_char = 0;
00814   struct mmix_opcode *instruction;
00815   fragS *opc_fragP = NULL;
00816   int max_operands = 3;
00817 
00818   /* Note that the struct frag member fr_literal in frags.h is char[], so
00819      I have to make this a plain char *.  */
00820   /* unsigned */ char *opcodep = NULL;
00821 
00822   expressionS exp[4];
00823   int n_operands = 0;
00824 
00825   /* Move to end of opcode.  */
00826   for (operands = str;
00827        is_part_of_name (*operands);
00828        ++operands)
00829     ;
00830 
00831   if (ISSPACE (*operands))
00832     {
00833       modified_char = *operands;
00834       *operands++ = '\0';
00835     }
00836 
00837   instruction = (struct mmix_opcode *) hash_find (mmix_opcode_hash, str);
00838   if (instruction == NULL)
00839     {
00840       as_bad (_("unknown opcode: `%s'"), str);
00841 
00842       /* Avoid "unhandled label" errors.  */
00843       pending_label = NULL;
00844       return;
00845     }
00846 
00847   /* Put back the character after the opcode.  */
00848   if (modified_char != 0)
00849     operands[-1] = modified_char;
00850 
00851   input_line_pointer = operands;
00852 
00853   /* Is this a mmixal pseudodirective?  */
00854   if (instruction->type == mmix_type_pseudo)
00855     {
00856       /* For mmixal compatibility, a label for an instruction (and
00857         emitting pseudo) refers to the _aligned_ address.  We emit the
00858         label here for the pseudos that don't handle it themselves.  When
00859         having an fb-label, emit it here, and increment the counter after
00860         the pseudo.  */
00861       switch (instruction->operands)
00862        {
00863        case mmix_operands_loc:
00864        case mmix_operands_byte:
00865        case mmix_operands_prefix:
00866        case mmix_operands_local:
00867        case mmix_operands_bspec:
00868        case mmix_operands_espec:
00869          if (current_fb_label >= 0)
00870            colon (fb_label_name (current_fb_label, 1));
00871          else if (pending_label != NULL)
00872            {
00873              colon (pending_label);
00874              pending_label = NULL;
00875            }
00876          break;
00877 
00878        default:
00879          break;
00880        }
00881 
00882       /* Some of the pseudos emit contents, others don't.  Set a
00883         contents-emitted flag when we emit something into .text   */
00884       switch (instruction->operands)
00885        {
00886        case mmix_operands_loc:
00887          /* LOC */
00888          s_loc (0);
00889          break;
00890 
00891        case mmix_operands_byte:
00892          /* BYTE */
00893          mmix_byte ();
00894          break;
00895 
00896        case mmix_operands_wyde:
00897          /* WYDE */
00898          mmix_cons (2);
00899          break;
00900 
00901        case mmix_operands_tetra:
00902          /* TETRA */
00903          mmix_cons (4);
00904          break;
00905 
00906        case mmix_operands_octa:
00907          /* OCTA */
00908          mmix_cons (8);
00909          break;
00910 
00911        case mmix_operands_prefix:
00912          /* PREFIX */
00913          s_prefix (0);
00914          break;
00915 
00916        case mmix_operands_local:
00917          /* LOCAL */
00918          mmix_s_local (0);
00919          break;
00920 
00921        case mmix_operands_bspec:
00922          /* BSPEC */
00923          s_bspec (0);
00924          break;
00925 
00926        case mmix_operands_espec:
00927          /* ESPEC */
00928          s_espec (0);
00929          break;
00930 
00931        default:
00932          BAD_CASE (instruction->operands);
00933        }
00934 
00935       /* These are all working like the pseudo functions in read.c:s_...,
00936         in that they step over the end-of-line marker at the end of the
00937         line.  We don't want that here.  */
00938       input_line_pointer--;
00939 
00940       /* Step up the fb-label counter if there was a definition on this
00941         line.  */
00942       if (current_fb_label >= 0)
00943        {
00944          fb_label_instance_inc (current_fb_label);
00945          current_fb_label = -1;
00946        }
00947 
00948       /* Reset any don't-align-next-datum request, unless this was a LOC
00949          directive.  */
00950       if (instruction->operands != mmix_operands_loc)
00951        want_unaligned = 0;
00952 
00953       return;
00954     }
00955 
00956   /* Not a pseudo; we *will* emit contents.  */
00957   if (now_seg == data_section)
00958     {
00959       if (lowest_data_loc != (bfd_vma) -1 && (lowest_data_loc & 3) != 0)
00960        {
00961          if (data_has_contents)
00962            as_bad (_("specified location wasn't TETRA-aligned"));
00963          else if (want_unaligned)
00964            as_bad (_("unaligned data at an absolute location is not supported"));
00965 
00966          lowest_data_loc &= ~(bfd_vma) 3;
00967          lowest_data_loc += 4;
00968        }
00969 
00970       data_has_contents = 1;
00971     }
00972   else if (now_seg == text_section)
00973     {
00974       if (lowest_text_loc != (bfd_vma) -1 && (lowest_text_loc & 3) != 0)
00975        {
00976          if (text_has_contents)
00977            as_bad (_("specified location wasn't TETRA-aligned"));
00978          else if (want_unaligned)
00979            as_bad (_("unaligned data at an absolute location is not supported"));
00980 
00981          lowest_text_loc &= ~(bfd_vma) 3;
00982          lowest_text_loc += 4;
00983        }
00984 
00985       text_has_contents = 1;
00986     }
00987 
00988   /* After a sequence of BYTEs or WYDEs, we need to get to instruction
00989      alignment.  For other pseudos, a ".p2align 2" is supposed to be
00990      inserted by the user.  */
00991   if (last_alignment < 2 && ! want_unaligned)
00992     {
00993       frag_align (2, 0, 0);
00994       record_alignment (now_seg, 2);
00995       last_alignment = 2;
00996     }
00997   else
00998     /* Reset any don't-align-next-datum request.  */
00999     want_unaligned = 0;
01000 
01001   /* For mmixal compatibility, a label for an instruction (and emitting
01002      pseudo) refers to the _aligned_ address.  So we have to emit the
01003      label here.  */
01004   if (pending_label != NULL)
01005     {
01006       colon (pending_label);
01007       pending_label = NULL;
01008     }
01009 
01010   /* We assume that mmix_opcodes keeps having unique mnemonics for each
01011      opcode, so we don't have to iterate over more than one opcode; if the
01012      syntax does not match, then there's a syntax error.  */
01013 
01014   /* Operands have little or no context and are all comma-separated; it is
01015      easier to parse each expression first.   */
01016   switch (instruction->operands)
01017     {
01018     case mmix_operands_reg_yz:
01019     case mmix_operands_pop:
01020     case mmix_operands_regaddr:
01021     case mmix_operands_pushj:
01022     case mmix_operands_get:
01023     case mmix_operands_put:
01024     case mmix_operands_set:
01025     case mmix_operands_save:
01026     case mmix_operands_unsave:
01027       max_operands = 2;
01028       break;
01029 
01030     case mmix_operands_sync:
01031     case mmix_operands_jmp:
01032     case mmix_operands_resume:
01033       max_operands = 1;
01034       break;
01035 
01036       /* The original 3 is fine for the rest.  */
01037     default:
01038       break;
01039     }
01040 
01041   /* If this is GET or PUT, and we don't do allow those names to be
01042      equated, we need to parse the names ourselves, so we don't pick up a
01043      user label instead of the special register.  */
01044   if (! equated_spec_regs
01045       && (instruction->operands == mmix_operands_get
01046          || instruction->operands == mmix_operands_put))
01047     n_operands = get_putget_operands (instruction, operands, exp);
01048   else
01049     n_operands = get_operands (max_operands, operands, exp);
01050 
01051   /* If there's a fb-label on the current line, set that label.  This must
01052      be done *after* evaluating expressions of operands, since neither a
01053      "1B" nor a "1F" refers to "1H" on the same line.  */
01054   if (current_fb_label >= 0)
01055     {
01056       fb_label_instance_inc (current_fb_label);
01057       colon (fb_label_name (current_fb_label, 0));
01058       current_fb_label = -1;
01059     }
01060 
01061   /* We also assume that the length of the instruction is at least 4, the
01062      size of an unexpanded instruction.  We need a self-contained frag
01063      since we want the relocation to point to the instruction, not the
01064      variant part.  */
01065 
01066   opcodep = frag_more (4);
01067   mmix_opcode_frag = opc_fragP = frag_now;
01068   frag_now->fr_opcode = opcodep;
01069 
01070   /* Mark start of insn for DWARF2 debug features.  */
01071   if (OUTPUT_FLAVOR == bfd_target_elf_flavour)
01072     dwarf2_emit_insn (4);
01073 
01074   md_number_to_chars (opcodep, instruction->match, 4);
01075 
01076   switch (instruction->operands)
01077     {
01078     case mmix_operands_jmp:
01079       if (n_operands == 0 && ! mmix_gnu_syntax)
01080        /* Zeros are in place - nothing needs to be done when we have no
01081           operands.  */
01082        break;
01083 
01084       /* Add a frag for a JMP relaxation; we need room for max four
01085         extra instructions.  We don't do any work around here to check if
01086         we can determine the offset right away.  */
01087       if (n_operands != 1 || exp[0].X_op == O_register)
01088        {
01089          as_bad (_("invalid operand to opcode %s: `%s'"),
01090                 instruction->name, operands);
01091          return;
01092        }
01093 
01094       if (expand_op)
01095        frag_var (rs_machine_dependent, 4 * 4, 0,
01096                 ENCODE_RELAX (STATE_JMP, STATE_UNDF),
01097                 exp[0].X_add_symbol,
01098                 exp[0].X_add_number,
01099                 opcodep);
01100       else
01101        fix_new_exp (opc_fragP, opcodep - opc_fragP->fr_literal, 4,
01102                    exp + 0, 1, BFD_RELOC_MMIX_ADDR27);
01103       break;
01104 
01105     case mmix_operands_pushj:
01106       /* We take care of PUSHJ in full here.  */
01107       if (n_operands != 2
01108          || ((exp[0].X_op == O_constant || exp[0].X_op == O_register)
01109              && (exp[0].X_add_number > 255 || exp[0].X_add_number < 0)))
01110        {
01111          as_bad (_("invalid operands to opcode %s: `%s'"),
01112                 instruction->name, operands);
01113          return;
01114        }
01115 
01116       if (exp[0].X_op == O_register || exp[0].X_op == O_constant)
01117        opcodep[1] = exp[0].X_add_number;
01118       else
01119        fix_new_exp (opc_fragP, opcodep - opc_fragP->fr_literal + 1,
01120                    1, exp + 0, 0, BFD_RELOC_MMIX_REG_OR_BYTE);
01121 
01122       if (expand_op)
01123        frag_var (rs_machine_dependent, PUSHJ_MAX_LEN - 4, 0,
01124                 ENCODE_RELAX (STATE_PUSHJ, STATE_UNDF),
01125                 exp[1].X_add_symbol,
01126                 exp[1].X_add_number,
01127                 opcodep);
01128       else
01129        fix_new_exp (opc_fragP, opcodep - opc_fragP->fr_literal, 4,
01130                    exp + 1, 1, BFD_RELOC_MMIX_ADDR19);
01131       break;
01132 
01133     case mmix_operands_regaddr:
01134       /* GETA/branch: Add a frag for relaxation.  We don't do any work
01135         around here to check if we can determine the offset right away.  */
01136       if (n_operands != 2 || exp[1].X_op == O_register)
01137        {
01138          as_bad (_("invalid operands to opcode %s: `%s'"),
01139                 instruction->name, operands);
01140          return;
01141        }
01142 
01143       if (! expand_op)
01144        fix_new_exp (opc_fragP, opcodep - opc_fragP->fr_literal, 4,
01145                    exp + 1, 1, BFD_RELOC_MMIX_ADDR19);
01146       else if (instruction->type == mmix_type_condbranch)
01147        frag_var (rs_machine_dependent, BCC_MAX_LEN - 4, 0,
01148                 ENCODE_RELAX (STATE_BCC, STATE_UNDF),
01149                 exp[1].X_add_symbol,
01150                 exp[1].X_add_number,
01151                 opcodep);
01152       else
01153        frag_var (rs_machine_dependent, GETA_MAX_LEN - 4, 0,
01154                 ENCODE_RELAX (STATE_GETA, STATE_UNDF),
01155                 exp[1].X_add_symbol,
01156                 exp[1].X_add_number,
01157                 opcodep);
01158       break;
01159 
01160     default:
01161       break;
01162     }
01163 
01164   switch (instruction->operands)
01165     {
01166     case mmix_operands_regs:
01167       /* We check the number of operands here, since we're in a
01168         FALLTHROUGH sequence in the next switch.  */
01169       if (n_operands != 3 || exp[2].X_op == O_constant)
01170        {
01171          as_bad (_("invalid operands to opcode %s: `%s'"),
01172                 instruction->name, operands);
01173          return;
01174        }
01175       /* FALLTHROUGH.  */
01176     case mmix_operands_regs_z:
01177       if (n_operands != 3)
01178        {
01179          as_bad (_("invalid operands to opcode %s: `%s'"),
01180                 instruction->name, operands);
01181          return;
01182        }
01183       /* FALLTHROUGH.  */
01184     case mmix_operands_reg_yz:
01185     case mmix_operands_roundregs_z:
01186     case mmix_operands_roundregs:
01187     case mmix_operands_regs_z_opt:
01188     case mmix_operands_neg:
01189     case mmix_operands_regaddr:
01190     case mmix_operands_get:
01191     case mmix_operands_set:
01192     case mmix_operands_save:
01193       if (n_operands < 1
01194          || (exp[0].X_op == O_register && exp[0].X_add_number > 255))
01195        {
01196          as_bad (_("invalid operands to opcode %s: `%s'"),
01197                 instruction->name, operands);
01198          return;
01199        }
01200 
01201       if (exp[0].X_op == O_register)
01202        opcodep[1] = exp[0].X_add_number;
01203       else
01204        fix_new_exp (opc_fragP, opcodep - opc_fragP->fr_literal + 1,
01205                    1, exp + 0, 0, BFD_RELOC_MMIX_REG);
01206       break;
01207 
01208     default:
01209       ;
01210     }
01211 
01212   /* A corresponding once-over for those who take an 8-bit constant as
01213      their first operand.  */
01214   switch (instruction->operands)
01215     {
01216     case mmix_operands_pushgo:
01217       /* PUSHGO: X is a constant, but can be expressed as a register.
01218         We handle X here and use the common machinery of T,X,3,$ for
01219         the rest of the operands.  */
01220       if (n_operands < 2
01221          || ((exp[0].X_op == O_constant || exp[0].X_op == O_register)
01222              && (exp[0].X_add_number > 255 || exp[0].X_add_number < 0)))
01223        {
01224          as_bad (_("invalid operands to opcode %s: `%s'"),
01225                 instruction->name, operands);
01226          return;
01227        }
01228       else if (exp[0].X_op == O_constant || exp[0].X_op == O_register)
01229        opcodep[1] = exp[0].X_add_number;
01230       else
01231        fix_new_exp (opc_fragP, opcodep - opc_fragP->fr_literal + 1,
01232                    1, exp + 0, 0, BFD_RELOC_MMIX_REG_OR_BYTE);
01233       break;
01234 
01235     case mmix_operands_pop:
01236       if ((n_operands == 0 || n_operands == 1) && ! mmix_gnu_syntax)
01237        break;
01238       /* FALLTHROUGH.  */
01239     case mmix_operands_x_regs_z:
01240       if (n_operands < 1
01241          || (exp[0].X_op == O_constant
01242              && (exp[0].X_add_number > 255
01243                 || exp[0].X_add_number < 0)))
01244        {
01245          as_bad (_("invalid operands to opcode %s: `%s'"),
01246                 instruction->name, operands);
01247          return;
01248        }
01249 
01250       if (exp[0].X_op == O_constant)
01251        opcodep[1] = exp[0].X_add_number;
01252       else
01253        /* FIXME: This doesn't bring us unsignedness checking.  */
01254        fix_new_exp (opc_fragP, opcodep - opc_fragP->fr_literal + 1,
01255                    1, exp + 0, 0, BFD_RELOC_8);
01256     default:
01257       ;
01258     }
01259 
01260   /* Handle the rest.  */
01261   switch (instruction->operands)
01262     {
01263     case mmix_operands_set:
01264       /* SET: Either two registers, "$X,$Y", with Z field as zero, or
01265         "$X,YZ", meaning change the opcode to SETL.  */
01266       if (n_operands != 2
01267          || (exp[1].X_op == O_constant
01268              && (exp[1].X_add_number > 0xffff || exp[1].X_add_number < 0)))
01269        {
01270          as_bad (_("invalid operands to opcode %s: `%s'"),
01271                 instruction->name, operands);
01272          return;
01273        }
01274 
01275       if (exp[1].X_op == O_constant)
01276        {
01277          /* There's an ambiguity with "SET $0,Y" when Y isn't defined
01278             yet.  To keep things simple, we assume that Y is then a
01279             register, and only change the opcode if Y is defined at this
01280             point.
01281 
01282             There's no compatibility problem with mmixal, since it emits
01283             errors if the field is not defined at this point.  */
01284          md_number_to_chars (opcodep, SETL_INSN_BYTE, 1);
01285 
01286          opcodep[2] = (exp[1].X_add_number >> 8) & 255;
01287          opcodep[3] = exp[1].X_add_number & 255;
01288          break;
01289        }
01290       /* FALLTHROUGH.  */
01291     case mmix_operands_x_regs_z:
01292       /* SYNCD: "X,$Y,$Z|Z".  */
01293       /* FALLTHROUGH.  */
01294     case mmix_operands_regs:
01295       /* Three registers, $X,$Y,$Z.  */
01296       /* FALLTHROUGH.  */
01297     case mmix_operands_regs_z:
01298       /* Operands "$X,$Y,$Z|Z", number of arguments checked above.  */
01299       /* FALLTHROUGH.  */
01300     case mmix_operands_pushgo:
01301       /* Operands "$X|X,$Y,$Z|Z", optional Z.  */
01302       /* FALLTHROUGH.  */
01303     case mmix_operands_regs_z_opt:
01304       /* Operands "$X,$Y,$Z|Z", with $Z|Z being optional, default 0.  Any
01305         operands not completely decided yet are postponed to later in
01306         assembly (but not until link-time yet).  */
01307 
01308       if ((n_operands != 2 && n_operands != 3)
01309          || (exp[1].X_op == O_register && exp[1].X_add_number > 255)
01310          || (n_operands == 3
01311              && ((exp[2].X_op == O_register
01312                  && exp[2].X_add_number > 255
01313                  && mmix_gnu_syntax)
01314                 || (exp[2].X_op == O_constant
01315                     && (exp[2].X_add_number > 255
01316                        || exp[2].X_add_number < 0)))))
01317        {
01318          as_bad (_("invalid operands to opcode %s: `%s'"),
01319                 instruction->name, operands);
01320          return;
01321        }
01322 
01323       if (n_operands == 2)
01324        {
01325          symbolS *sym;
01326 
01327          /* The last operand is immediate whenever we see just two
01328             operands.  */
01329          opcodep[0] |= IMM_OFFSET_BIT;
01330 
01331          /* Now, we could either have an implied "0" as the Z operand, or
01332             it could be the constant of a "base address plus offset".  It
01333             depends on whether it is allowed; only memory operations, as
01334             signified by instruction->type and "T" and "X" operand types,
01335             and it depends on whether we find a register in the second
01336             operand, exp[1].  */
01337          if (exp[1].X_op == O_register && exp[1].X_add_number <= 255)
01338            {
01339              /* A zero then; all done.  */
01340              opcodep[2] = exp[1].X_add_number;
01341              break;
01342            }
01343 
01344          /* Not known as a register.  Is base address plus offset
01345             allowed, or can we assume that it is a register anyway?  */
01346          if ((instruction->operands != mmix_operands_regs_z_opt
01347               && instruction->operands != mmix_operands_x_regs_z
01348               && instruction->operands != mmix_operands_pushgo)
01349              || (instruction->type != mmix_type_memaccess_octa
01350                 && instruction->type != mmix_type_memaccess_tetra
01351                 && instruction->type != mmix_type_memaccess_wyde
01352                 && instruction->type != mmix_type_memaccess_byte
01353                 && instruction->type != mmix_type_memaccess_block
01354                 && instruction->type != mmix_type_jsr
01355                 && instruction->type != mmix_type_branch))
01356            {
01357              fix_new_exp (opc_fragP, opcodep - opc_fragP->fr_literal + 2,
01358                         1, exp + 1, 0, BFD_RELOC_MMIX_REG);
01359              break;
01360            }
01361 
01362          /* To avoid getting a NULL add_symbol for constants and then
01363             catching a SEGV in write_relocs since it doesn't handle
01364             constants well for relocs other than PC-relative, we need to
01365             pass expressions as symbols and use fix_new, not fix_new_exp.  */
01366          sym = make_expr_symbol (exp + 1);
01367 
01368          /* Now we know it can be a "base address plus offset".  Add
01369             proper fixup types so we can handle this later, when we've
01370             parsed everything.  */
01371          fix_new (opc_fragP, opcodep - opc_fragP->fr_literal + 2,
01372                  8, sym, 0, 0, BFD_RELOC_MMIX_BASE_PLUS_OFFSET);
01373          break;
01374        }
01375 
01376       if (exp[1].X_op == O_register)
01377        opcodep[2] = exp[1].X_add_number;
01378       else
01379        fix_new_exp (opc_fragP, opcodep - opc_fragP->fr_literal + 2,
01380                    1, exp + 1, 0, BFD_RELOC_MMIX_REG);
01381 
01382       /* In mmixal compatibility mode, we allow special registers as
01383         constants for the Z operand.  They have 256 added to their
01384         register numbers, so the right thing will happen if we just treat
01385         those as constants.  */
01386       if (exp[2].X_op == O_register && exp[2].X_add_number <= 255)
01387        opcodep[3] = exp[2].X_add_number;
01388       else if (exp[2].X_op == O_constant
01389               || (exp[2].X_op == O_register && exp[2].X_add_number > 255))
01390        {
01391          opcodep[3] = exp[2].X_add_number;
01392          opcodep[0] |= IMM_OFFSET_BIT;
01393        }
01394       else
01395        fix_new_exp (opc_fragP, opcodep - opc_fragP->fr_literal + 3,
01396                    1, exp + 2, 0,
01397                    (instruction->operands == mmix_operands_set
01398                     || instruction->operands == mmix_operands_regs)
01399                    ? BFD_RELOC_MMIX_REG : BFD_RELOC_MMIX_REG_OR_BYTE);
01400       break;
01401 
01402     case mmix_operands_pop:
01403       /* POP, one eight and one 16-bit operand.  */
01404       if (n_operands == 0 && ! mmix_gnu_syntax)
01405        break;
01406       if (n_operands == 1 && ! mmix_gnu_syntax)
01407        goto a_single_24_bit_number_operand;
01408       /* FALLTHROUGH.  */
01409     case mmix_operands_reg_yz:
01410       /* A register and a 16-bit unsigned number.  */
01411       if (n_operands != 2
01412          || exp[1].X_op == O_register
01413          || (exp[1].X_op == O_constant
01414              && (exp[1].X_add_number > 0xffff || exp[1].X_add_number < 0)))
01415        {
01416          as_bad (_("invalid operands to opcode %s: `%s'"),
01417                 instruction->name, operands);
01418          return;
01419        }
01420 
01421       if (exp[1].X_op == O_constant)
01422        {
01423          opcodep[2] = (exp[1].X_add_number >> 8) & 255;
01424          opcodep[3] = exp[1].X_add_number & 255;
01425        }
01426       else
01427        /* FIXME: This doesn't bring us unsignedness checking.  */
01428        fix_new_exp (opc_fragP, opcodep - opc_fragP->fr_literal + 2,
01429                    2, exp + 1, 0, BFD_RELOC_16);
01430       break;
01431 
01432     case mmix_operands_jmp:
01433       /* A JMP.  Everything is already done.  */
01434       break;
01435 
01436     case mmix_operands_roundregs:
01437       /* Two registers with optional rounding mode or constant in between.  */
01438       if ((n_operands == 3 && exp[2].X_op == O_constant)
01439          || (n_operands == 2 && exp[1].X_op == O_constant))
01440        {
01441          as_bad (_("invalid operands to opcode %s: `%s'"),
01442                 instruction->name, operands);
01443          return;
01444        }
01445       /* FALLTHROUGH.  */
01446     case mmix_operands_roundregs_z:
01447       /* Like FLOT, "$X,ROUND_MODE,$Z|Z", but the rounding mode is
01448         optional and can be the corresponding constant.  */
01449       {
01450        /* Which exp index holds the second operand (not the rounding
01451           mode).  */
01452        int op2no = n_operands - 1;
01453 
01454        if ((n_operands != 2 && n_operands != 3)
01455            || ((exp[op2no].X_op == O_register
01456                && exp[op2no].X_add_number > 255)
01457               || (exp[op2no].X_op == O_constant
01458                   && (exp[op2no].X_add_number > 255
01459                      || exp[op2no].X_add_number < 0)))
01460            || (n_operands == 3
01461               /* We don't allow for the rounding mode to be deferred; it
01462                  must be determined in the "first pass".  It cannot be a
01463                  symbol equated to a rounding mode, but defined after
01464                  the first use.  */
01465               && ((exp[1].X_op == O_register
01466                    && exp[1].X_add_number < 512)
01467                   || (exp[1].X_op == O_constant
01468                      && exp[1].X_add_number < 0
01469                      && exp[1].X_add_number > 4)
01470                   || (exp[1].X_op != O_register
01471                      && exp[1].X_op != O_constant))))
01472          {
01473            as_bad (_("invalid operands to opcode %s: `%s'"),
01474                   instruction->name, operands);
01475            return;
01476          }
01477 
01478        /* Add rounding mode if present.  */
01479        if (n_operands == 3)
01480          opcodep[2] = exp[1].X_add_number & 255;
01481 
01482        if (exp[op2no].X_op == O_register)
01483          opcodep[3] = exp[op2no].X_add_number;
01484        else if (exp[op2no].X_op == O_constant)
01485          {
01486            opcodep[3] = exp[op2no].X_add_number;
01487            opcodep[0] |= IMM_OFFSET_BIT;
01488          }
01489        else
01490          fix_new_exp (opc_fragP, opcodep - opc_fragP->fr_literal + 3,
01491                      1, exp + op2no, 0,
01492                      instruction->operands == mmix_operands_roundregs
01493                      ? BFD_RELOC_MMIX_REG
01494                      : BFD_RELOC_MMIX_REG_OR_BYTE);
01495        break;
01496       }
01497 
01498     case mmix_operands_sync:
01499     a_single_24_bit_number_operand:
01500       if (n_operands != 1
01501          || exp[0].X_op == O_register
01502          || (exp[0].X_op == O_constant
01503              && (exp[0].X_add_number > 0xffffff || exp[0].X_add_number < 0)))
01504        {
01505          as_bad (_("invalid operands to opcode %s: `%s'"),
01506                 instruction->name, operands);
01507          return;
01508        }
01509 
01510       if (exp[0].X_op == O_constant)
01511        {
01512          opcodep[1] = (exp[0].X_add_number >> 16) & 255;
01513          opcodep[2] = (exp[0].X_add_number >> 8) & 255;
01514          opcodep[3] = exp[0].X_add_number & 255;
01515        }
01516       else
01517        /* FIXME: This doesn't bring us unsignedness checking.  */
01518        fix_new_exp (opc_fragP, opcodep - opc_fragP->fr_literal + 1,
01519                    3, exp + 0, 0, BFD_RELOC_24);
01520       break;
01521 
01522     case mmix_operands_neg:
01523       /* Operands "$X,Y,$Z|Z"; NEG or NEGU.  Y is optional, 0 is default.  */
01524 
01525       if ((n_operands != 3 && n_operands != 2)
01526          || (n_operands == 3 && exp[1].X_op == O_register)
01527          || ((exp[1].X_op == O_constant || exp[1].X_op == O_register)
01528              && (exp[1].X_add_number > 255 || exp[1].X_add_number < 0))
01529          || (n_operands == 3
01530              && ((exp[2].X_op == O_register && exp[2].X_add_number > 255)
01531                 || (exp[2].X_op == O_constant
01532                     && (exp[2].X_add_number > 255
01533                        || exp[2].X_add_number < 0)))))
01534        {
01535          as_bad (_("invalid operands to opcode %s: `%s'"),
01536                 instruction->name, operands);
01537          return;
01538        }
01539 
01540       if (n_operands == 2)
01541        {
01542          if (exp[1].X_op == O_register)
01543            opcodep[3] = exp[1].X_add_number;
01544          else if (exp[1].X_op == O_constant)
01545            {
01546              opcodep[3] = exp[1].X_add_number;
01547              opcodep[0] |= IMM_OFFSET_BIT;
01548            }
01549          else
01550            fix_new_exp (opc_fragP, opcodep - opc_fragP->fr_literal + 3,
01551                       1, exp + 1, 0, BFD_RELOC_MMIX_REG_OR_BYTE);
01552          break;
01553        }
01554 
01555       if (exp[1].X_op == O_constant)
01556        opcodep[2] = exp[1].X_add_number;
01557       else
01558        fix_new_exp (opc_fragP, opcodep - opc_fragP->fr_literal + 2,
01559                    1, exp + 1, 0, BFD_RELOC_8);
01560 
01561       if (exp[2].X_op == O_register)
01562        opcodep[3] = exp[2].X_add_number;
01563       else if (exp[2].X_op == O_constant)
01564        {
01565          opcodep[3] = exp[2].X_add_number;
01566          opcodep[0] |= IMM_OFFSET_BIT;
01567        }
01568       else
01569        fix_new_exp (opc_fragP, opcodep - opc_fragP->fr_literal + 3,
01570                    1, exp + 2, 0, BFD_RELOC_MMIX_REG_OR_BYTE);
01571       break;
01572 
01573     case mmix_operands_regaddr:
01574       /* A GETA/branch-type.  */
01575       break;
01576 
01577     case mmix_operands_get:
01578       /* "$X,spec_reg"; GET.
01579         Like with rounding modes, we demand that the special register or
01580         symbol is already defined when we get here at the point of use.  */
01581       if (n_operands != 2
01582          || (exp[1].X_op == O_register
01583              && (exp[1].X_add_number < 256 || exp[1].X_add_number >= 512))
01584          || (exp[1].X_op == O_constant
01585              && (exp[1].X_add_number < 0 || exp[1].X_add_number > 256))
01586          || (exp[1].X_op != O_constant && exp[1].X_op != O_register))
01587        {
01588          as_bad (_("invalid operands to opcode %s: `%s'"),
01589                 instruction->name, operands);
01590          return;
01591        }
01592 
01593       opcodep[3] = exp[1].X_add_number - 256;
01594       break;
01595 
01596     case mmix_operands_put:
01597       /* "spec_reg,$Z|Z"; PUT.  */
01598       if (n_operands != 2
01599          || (exp[0].X_op == O_register
01600              && (exp[0].X_add_number < 256 || exp[0].X_add_number >= 512))
01601          || (exp[0].X_op == O_constant
01602              && (exp[0].X_add_number < 0 || exp[0].X_add_number > 256))
01603          || (exp[0].X_op != O_constant && exp[0].X_op != O_register))
01604        {
01605          as_bad (_("invalid operands to opcode %s: `%s'"),
01606                 instruction->name, operands);
01607          return;
01608        }
01609 
01610       opcodep[1] = exp[0].X_add_number - 256;
01611 
01612       /* Note that the Y field is zero.  */
01613 
01614       if (exp[1].X_op == O_register)
01615        opcodep[3] = exp[1].X_add_number;
01616       else if (exp[1].X_op == O_constant)
01617        {
01618          opcodep[3] = exp[1].X_add_number;
01619          opcodep[0] |= IMM_OFFSET_BIT;
01620        }
01621       else
01622        fix_new_exp (opc_fragP, opcodep - opc_fragP->fr_literal + 3,
01623                    1, exp + 1, 0, BFD_RELOC_MMIX_REG_OR_BYTE);
01624       break;
01625 
01626     case mmix_operands_save:
01627       /* "$X,0"; SAVE.  */
01628       if (n_operands != 2
01629          || exp[1].X_op != O_constant
01630          || exp[1].X_add_number != 0)
01631        {
01632          as_bad (_("invalid operands to opcode %s: `%s'"),
01633                 instruction->name, operands);
01634          return;
01635        }
01636       break;
01637 
01638     case mmix_operands_unsave:
01639       if (n_operands < 2 && ! mmix_gnu_syntax)
01640        {
01641          if (n_operands == 1)
01642            {
01643              if (exp[0].X_op == O_register)
01644               opcodep[3] = exp[0].X_add_number;
01645              else
01646               fix_new_exp (opc_fragP, opcodep - opc_fragP->fr_literal + 3,
01647                           1, exp, 0, BFD_RELOC_MMIX_REG);
01648            }
01649          break;
01650        }
01651 
01652       /* "0,$Z"; UNSAVE.  */
01653       if (n_operands != 2
01654          || exp[0].X_op != O_constant
01655          || exp[0].X_add_number != 0
01656          || exp[1].X_op == O_constant
01657          || (exp[1].X_op == O_register
01658              && exp[1].X_add_number > 255))
01659        {
01660          as_bad (_("invalid operands to opcode %s: `%s'"),
01661                 instruction->name, operands);
01662          return;
01663        }
01664 
01665       if (exp[1].X_op == O_register)
01666        opcodep[3] = exp[1].X_add_number;
01667       else
01668        fix_new_exp (opc_fragP, opcodep - opc_fragP->fr_literal + 3,
01669                    1, exp + 1, 0, BFD_RELOC_MMIX_REG);
01670       break;
01671 
01672     case mmix_operands_xyz_opt:
01673       /* SWYM, TRIP, TRAP: zero, one, two or three operands.  */
01674       if (n_operands == 0 && ! mmix_gnu_syntax)
01675        /* Zeros are in place - nothing needs to be done for zero
01676           operands.  We don't allow this in GNU syntax mode, because it
01677           was believed that the risk of missing to supply an operand is
01678           higher than the benefit of not having to specify a zero.  */
01679        ;
01680       else if (n_operands == 1 && exp[0].X_op != O_register)
01681        {
01682          if (exp[0].X_op == O_constant)
01683            {
01684              if (exp[0].X_add_number > 255*255*255
01685                 || exp[0].X_add_number < 0)
01686               {
01687                 as_bad (_("invalid operands to opcode %s: `%s'"),
01688                        instruction->name, operands);
01689                 return;
01690               }
01691              else
01692               {
01693                 opcodep[1] = (exp[0].X_add_number >> 16) & 255;
01694                 opcodep[2] = (exp[0].X_add_number >> 8) & 255;
01695                 opcodep[3] = exp[0].X_add_number & 255;
01696               }
01697            }
01698          else
01699            fix_new_exp (opc_fragP, opcodep - opc_fragP->fr_literal + 1,
01700                       3, exp, 0, BFD_RELOC_24);
01701        }
01702       else if (n_operands == 2
01703               && exp[0].X_op != O_register
01704               && exp[1].X_op != O_register)
01705        {
01706          /* Two operands.  */
01707 
01708          if (exp[0].X_op == O_constant)
01709            {
01710              if (exp[0].X_add_number > 255
01711                 || exp[0].X_add_number < 0)
01712               {
01713                 as_bad (_("invalid operands to opcode %s: `%s'"),
01714                        instruction->name, operands);
01715                 return;
01716               }
01717              else
01718               opcodep[1] = exp[0].X_add_number & 255;
01719            }
01720          else
01721            fix_new_exp (opc_fragP, opcodep - opc_fragP->fr_literal + 1,
01722                       1, exp, 0, BFD_RELOC_8);
01723 
01724          if (exp[1].X_op == O_constant)
01725            {
01726              if (exp[1].X_add_number > 255*255
01727                 || exp[1].X_add_number < 0)
01728               {
01729                 as_bad (_("invalid operands to opcode %s: `%s'"),
01730                        instruction->name, operands);
01731                 return;
01732               }
01733              else
01734               {
01735                 opcodep[2] = (exp[1].X_add_number >> 8) & 255;
01736                 opcodep[3] = exp[1].X_add_number & 255;
01737               }
01738            }
01739          else
01740            fix_new_exp (opc_fragP, opcodep - opc_fragP->fr_literal + 2,
01741                       2, exp + 1, 0, BFD_RELOC_16);
01742        }
01743       else if (n_operands == 3
01744               && exp[0].X_op != O_register
01745               && exp[1].X_op != O_register
01746               && exp[2].X_op != O_register)
01747        {
01748          /* Three operands.  */
01749 
01750          if (exp[0].X_op == O_constant)
01751            {
01752              if (exp[0].X_add_number > 255
01753                 || exp[0].X_add_number < 0)
01754               {
01755                 as_bad (_("invalid operands to opcode %s: `%s'"),
01756                        instruction->name, operands);
01757                 return;
01758               }
01759              else
01760               opcodep[1] = exp[0].X_add_number & 255;
01761            }
01762          else
01763            fix_new_exp (opc_fragP, opcodep - opc_fragP->fr_literal + 1,
01764                       1, exp, 0, BFD_RELOC_8);
01765 
01766          if (exp[1].X_op == O_constant)
01767            {
01768              if (exp[1].X_add_number > 255
01769                 || exp[1].X_add_number < 0)
01770               {
01771                 as_bad (_("invalid operands to opcode %s: `%s'"),
01772                        instruction->name, operands);
01773                 return;
01774               }
01775              else
01776               opcodep[2] = exp[1].X_add_number & 255;
01777            }
01778          else
01779            fix_new_exp (opc_fragP, opcodep - opc_fragP->fr_literal + 2,
01780                       1, exp + 1, 0, BFD_RELOC_8);
01781 
01782          if (exp[2].X_op == O_constant)
01783            {
01784              if (exp[2].X_add_number > 255
01785                 || exp[2].X_add_number < 0)
01786               {
01787                 as_bad (_("invalid operands to opcode %s: `%s'"),
01788                        instruction->name, operands);
01789                 return;
01790               }
01791              else
01792               opcodep[3] = exp[2].X_add_number & 255;
01793            }
01794          else
01795            fix_new_exp (opc_fragP, opcodep - opc_fragP->fr_literal + 3,
01796                       1, exp + 2, 0, BFD_RELOC_8);
01797        }
01798       else if (n_operands <= 3
01799               && (strcmp (instruction->name, "trip") == 0
01800                  || strcmp (instruction->name, "trap") == 0))
01801        {
01802          /* The meaning of operands to TRIP and TRAP are not defined, so
01803             we add combinations not handled above here as we find them.  */
01804          if (n_operands == 3)
01805            {
01806              /* Don't require non-register operands.  Always generate
01807                fixups, so we don't have to copy lots of code and create
01808                maintenance problems.  TRIP is supposed to be a rare
01809                instruction, so the overhead should not matter.  We
01810                aren't allowed to fix_new_exp for an expression which is
01811                an  O_register at this point, however.  */
01812              if (exp[0].X_op == O_register)
01813               opcodep[1] = exp[0].X_add_number;
01814              else
01815               fix_new_exp (opc_fragP, opcodep - opc_fragP->fr_literal + 1,
01816                           1, exp, 0, BFD_RELOC_MMIX_REG_OR_BYTE);
01817              if (exp[1].X_op == O_register)
01818               opcodep[2] = exp[1].X_add_number;
01819              else
01820               fix_new_exp (opc_fragP, opcodep - opc_fragP->fr_literal + 2,
01821                           1, exp + 1, 0, BFD_RELOC_MMIX_REG_OR_BYTE);
01822              if (exp[2].X_op == O_register)
01823               opcodep[3] = exp[2].X_add_number;
01824              else
01825               fix_new_exp (opc_fragP, opcodep - opc_fragP->fr_literal + 3,
01826                           1, exp + 2, 0, BFD_RELOC_MMIX_REG_OR_BYTE);
01827            }
01828          else if (n_operands == 2)
01829            {
01830              if (exp[0].X_op == O_register)
01831               opcodep[2] = exp[0].X_add_number;
01832              else
01833               fix_new_exp (opc_fragP, opcodep - opc_fragP->fr_literal + 2,
01834                           1, exp, 0, BFD_RELOC_MMIX_REG_OR_BYTE);
01835              if (exp[1].X_op == O_register)
01836               opcodep[3] = exp[1].X_add_number;
01837              else
01838               fix_new_exp (opc_fragP, opcodep - opc_fragP->fr_literal + 3,
01839                           1, exp + 1, 0, BFD_RELOC_MMIX_REG_OR_BYTE);
01840            }
01841          else
01842            {
01843              as_bad (_("unsupported operands to %s: `%s'"),
01844                     instruction->name, operands);
01845              return;
01846            }
01847        }
01848       else
01849        {
01850          as_bad (_("invalid operands to opcode %s: `%s'"),
01851                 instruction->name, operands);
01852          return;
01853        }
01854       break;
01855 
01856     case mmix_operands_resume:
01857       if (n_operands == 0 && ! mmix_gnu_syntax)
01858        break;
01859 
01860       if (n_operands != 1
01861          || exp[0].X_op == O_register
01862          || (exp[0].X_op == O_constant
01863              && (exp[0].X_add_number < 0
01864                 || exp[0].X_add_number > 255)))
01865        {
01866          as_bad (_("invalid operands to opcode %s: `%s'"),
01867                 instruction->name, operands);
01868          return;
01869        }
01870 
01871       if (exp[0].X_op == O_constant)
01872        opcodep[3] = exp[0].X_add_number;
01873       else
01874        fix_new_exp (opc_fragP, opcodep - opc_fragP->fr_literal + 3,
01875                    1, exp + 0, 0, BFD_RELOC_8);
01876       break;
01877 
01878     case mmix_operands_pushj:
01879       /* All is done for PUSHJ already.  */
01880       break;
01881 
01882     default:
01883       BAD_CASE (instruction->operands);
01884     }
01885 }
01886 
01887 /* For the benefit of insns that start with a digit, we assemble by way of
01888    tc_unrecognized_line too, through this function.  */
01889 
01890 int
01891 mmix_assemble_return_nonzero (char *str)
01892 {
01893   int last_error_count = had_errors ();
01894   char *s2 = str;
01895   char c;
01896 
01897   /* Normal instruction handling downcases, so we must too.  */
01898   while (ISALNUM (*s2))
01899     {
01900       if (ISUPPER ((unsigned char) *s2))
01901        *s2 = TOLOWER (*s2);
01902       s2++;
01903     }
01904 
01905   /* Cut the line for sake of the assembly.  */
01906   for (s2 = str; *s2 && *s2 != '\n'; s2++)
01907     ;
01908 
01909   c = *s2;
01910   *s2 = 0;
01911   md_assemble (str);
01912   *s2 = c;
01913 
01914   return had_errors () == last_error_count;
01915 }
01916 
01917 /* The PREFIX pseudo.  */
01918 
01919 static void
01920 s_prefix (int unused ATTRIBUTE_UNUSED)
01921 {
01922   char *p;
01923   int c;
01924 
01925   SKIP_WHITESPACE ();
01926 
01927   p = input_line_pointer;
01928 
01929   c = get_symbol_end ();
01930 
01931   /* Reseting prefix?  */
01932   if (*p == ':' && p[1] == 0)
01933     mmix_current_prefix = NULL;
01934   else
01935     {
01936       /* Put this prefix on the mmix symbols obstack.  We could malloc and
01937         free it separately, but then we'd have to worry about that.
01938         People using up memory on prefixes have other problems.  */
01939       obstack_grow (&mmix_sym_obstack, p, strlen (p) + 1);
01940       p = obstack_finish (&mmix_sym_obstack);
01941 
01942       /* Accumulate prefixes, and strip a leading ':'.  */
01943       if (mmix_current_prefix != NULL || *p == ':')
01944        p = mmix_prefix_name (p);
01945 
01946       mmix_current_prefix = p;
01947     }
01948 
01949   *input_line_pointer = c;
01950 
01951   mmix_handle_rest_of_empty_line ();
01952 }
01953 
01954 /* We implement prefixes by using the tc_canonicalize_symbol_name hook,
01955    and store each prefixed name on a (separate) obstack.  This means that
01956    the name is on the "notes" obstack in non-prefixed form and on the
01957    mmix_sym_obstack in prefixed form, but currently it is not worth
01958    rewriting the whole GAS symbol handling to improve "hooking" to avoid
01959    that.  (It might be worth a rewrite for other reasons, though).  */
01960 
01961 char *
01962 mmix_prefix_name (char *shortname)
01963 {
01964   if (*shortname == ':')
01965     return shortname + 1;
01966 
01967   if (mmix_current_prefix == NULL)
01968     as_fatal (_("internal: mmix_prefix_name but empty prefix"));
01969 
01970   if (*shortname == '$')
01971     return shortname;
01972 
01973   obstack_grow (&mmix_sym_obstack, mmix_current_prefix,
01974               strlen (mmix_current_prefix));
01975   obstack_grow (&mmix_sym_obstack, shortname, strlen (shortname) + 1);
01976   return obstack_finish (&mmix_sym_obstack);
01977 }
01978 
01979 /* The GREG pseudo.  At LABEL, we have the name of a symbol that we
01980    want to make a register symbol, and which should be initialized with
01981    the value in the expression at INPUT_LINE_POINTER (defaulting to 0).
01982    Either and (perhaps less meaningful) both may be missing.  LABEL must
01983    be persistent, perhaps allocated on an obstack.  */
01984 
01985 static void
01986 mmix_greg_internal (char *label)
01987 {
01988   expressionS *expP = &mmix_raw_gregs[n_of_raw_gregs].exp;
01989 
01990   /* Don't set the section to register contents section before the
01991      expression has been parsed; it may refer to the current position.  */
01992   expression (expP);
01993 
01994   /* FIXME: Check that no expression refers to the register contents
01995      section.  May need to be done in elf64-mmix.c.  */
01996   if (expP->X_op == O_absent)
01997     {
01998       /* Default to zero if the expression was absent.  */
01999       expP->X_op = O_constant;
02000       expP->X_add_number = 0;
02001       expP->X_unsigned = 0;
02002       expP->X_add_symbol = NULL;
02003       expP->X_op_symbol = NULL;
02004     }
02005 
02006   /* We must handle prefixes here, as we save the labels and expressions
02007      to be output later.  */
02008   mmix_raw_gregs[n_of_raw_gregs].label
02009     = mmix_current_prefix == NULL ? label : mmix_prefix_name (label);
02010 
02011   if (n_of_raw_gregs == MAX_GREGS - 1)
02012     as_bad (_("too many GREG registers allocated (max %d)"), MAX_GREGS);
02013   else
02014     n_of_raw_gregs++;
02015 
02016   mmix_handle_rest_of_empty_line ();
02017 }
02018 
02019 /* The ".greg label,expr" worker.  */
02020 
02021 static void
02022 s_greg (int unused ATTRIBUTE_UNUSED)
02023 {
02024   char *p;
02025   char c;
02026   p = input_line_pointer;
02027 
02028   /* This will skip over what can be a symbol and zero out the next
02029      character, which we assume is a ',' or other meaningful delimiter.
02030      What comes after that is the initializer expression for the
02031      register.  */
02032   c = get_symbol_end ();
02033 
02034   if (! is_end_of_line[(unsigned char) c])
02035     input_line_pointer++;
02036 
02037   if (*p)
02038     {
02039       /* The label must be persistent; it's not used until after all input
02040         has been seen.  */
02041       obstack_grow (&mmix_sym_obstack, p, strlen (p) + 1);
02042       mmix_greg_internal (obstack_finish (&mmix_sym_obstack));
02043     }
02044   else
02045     mmix_greg_internal (NULL);
02046 }
02047 
02048 /* The "BSPEC expr" worker.  */
02049 
02050 static void
02051 s_bspec (int unused ATTRIBUTE_UNUSED)
02052 {
02053   asection *expsec;
02054   asection *sec;
02055   char secname[sizeof (MMIX_OTHER_SPEC_SECTION_PREFIX) + 20]
02056     = MMIX_OTHER_SPEC_SECTION_PREFIX;
02057   expressionS exp;
02058   int n;
02059 
02060   /* Get a constant expression which we can evaluate *now*.  Supporting
02061      more complex (though assembly-time computable) expressions is
02062      feasible but Too Much Work for something of unknown usefulness like
02063      BSPEC-ESPEC.  */
02064   expsec = expression (&exp);
02065   mmix_handle_rest_of_empty_line ();
02066 
02067   /* Check that we don't have another BSPEC in progress.  */
02068   if (doing_bspec)
02069     {
02070       as_bad (_("BSPEC already active.  Nesting is not supported."));
02071       return;
02072     }
02073 
02074   if (exp.X_op != O_constant
02075       || expsec != absolute_section
02076       || exp.X_add_number < 0
02077       || exp.X_add_number > 65535)
02078     {
02079       as_bad (_("invalid BSPEC expression"));
02080       exp.X_add_number = 0;
02081     }
02082 
02083   n = (int) exp.X_add_number;
02084 
02085   sprintf (secname + strlen (MMIX_OTHER_SPEC_SECTION_PREFIX), "%d", n);
02086   sec = bfd_get_section_by_name (stdoutput, secname);
02087   if (sec == NULL)
02088     {
02089       /* We need a non-volatile name as it will be stored in the section
02090          struct.  */
02091       char *newsecname = xstrdup (secname);
02092       sec = bfd_make_section (stdoutput, newsecname);
02093 
02094       if (sec == NULL)
02095        as_fatal (_("can't create section %s"), newsecname);
02096 
02097       if (!bfd_set_section_flags (stdoutput, sec,
02098                               bfd_get_section_flags (stdoutput, sec)
02099                               | SEC_READONLY))
02100        as_fatal (_("can't set section flags for section %s"), newsecname);
02101     }
02102 
02103   /* Tell ELF about the pending section change.  */
02104   obj_elf_section_change_hook ();
02105   subseg_set (sec, 0);
02106 
02107   /* Save position for missing ESPEC.  */
02108   as_where (&bspec_file, &bspec_line);
02109 
02110   doing_bspec = 1;
02111 }
02112 
02113 /* The "ESPEC" worker.  */
02114 
02115 static void
02116 s_espec (int unused ATTRIBUTE_UNUSED)
02117 {
02118   /* First, check that we *do* have a BSPEC in progress.  */
02119   if (! doing_bspec)
02120     {
02121       as_bad (_("ESPEC without preceding BSPEC"));
02122       return;
02123     }
02124 
02125   mmix_handle_rest_of_empty_line ();
02126   doing_bspec = 0;
02127 
02128   /* When we told ELF about the section change in s_bspec, it stored the
02129      previous section for us so we can get at it with the equivalent of a
02130      .previous pseudo.  */
02131   obj_elf_previous (0);
02132 }
02133 
02134 /* The " .local expr" and " local expr" worker.  We make a BFD_MMIX_LOCAL
02135    relocation against the current position against the expression.
02136    Implementing this by means of contents in a section lost.  */
02137 
02138 static void
02139 mmix_s_local (int unused ATTRIBUTE_UNUSED)
02140 {
02141   expressionS exp;
02142 
02143   /* Don't set the section to register contents section before the
02144      expression has been parsed; it may refer to the current position in
02145      some contorted way.  */
02146   expression (&exp);
02147 
02148   if (exp.X_op == O_absent)
02149     {
02150       as_bad (_("missing local expression"));
02151       return;
02152     }
02153   else if (exp.X_op == O_register)
02154     {
02155       /* fix_new_exp doesn't like O_register.  Should be configurable.
02156         We're fine with a constant here, though.  */
02157       exp.X_op = O_constant;
02158     }
02159 
02160   fix_new_exp (frag_now, 0, 0, &exp, 0, BFD_RELOC_MMIX_LOCAL);
02161   mmix_handle_rest_of_empty_line ();
02162 }
02163 
02164 /* Set fragP->fr_var to the initial guess of the size of a relaxable insn
02165    and return it.  Sizes of other instructions are not known.  This
02166    function may be called multiple times.  */
02167 
02168 int
02169 md_estimate_size_before_relax (fragS *fragP, segT segment)
02170 {
02171   int length;
02172 
02173 #define HANDLE_RELAXABLE(state)                                       \
02174  case ENCODE_RELAX (state, STATE_UNDF):                               \
02175    if (fragP->fr_symbol != NULL                                       \
02176        && S_GET_SEGMENT (fragP->fr_symbol) == segment                 \
02177        && !S_IS_WEAK (fragP->fr_symbol))                       \
02178      {                                                         \
02179        /* The symbol lies in the same segment - a relaxable case.  */ \
02180        fragP->fr_subtype                                       \
02181         = ENCODE_RELAX (state, STATE_ZERO);                           \
02182      }                                                         \
02183    break;
02184 
02185   switch (fragP->fr_subtype)
02186     {
02187       HANDLE_RELAXABLE (STATE_GETA);
02188       HANDLE_RELAXABLE (STATE_BCC);
02189       HANDLE_RELAXABLE (STATE_JMP);
02190 
02191     case ENCODE_RELAX (STATE_PUSHJ, STATE_UNDF):
02192       if (fragP->fr_symbol != NULL
02193          && S_GET_SEGMENT (fragP->fr_symbol) == segment
02194          && !S_IS_WEAK (fragP->fr_symbol))
02195        /* The symbol lies in the same segment - a relaxable case.  */
02196        fragP->fr_subtype = ENCODE_RELAX (STATE_PUSHJ, STATE_ZERO);
02197       else if (pushj_stubs)
02198        /* If we're to generate stubs, assume we can reach a stub after
02199            the section.  */
02200        fragP->fr_subtype = ENCODE_RELAX (STATE_PUSHJSTUB, STATE_ZERO);
02201       /* FALLTHROUGH.  */
02202     case ENCODE_RELAX (STATE_PUSHJ, STATE_ZERO):
02203     case ENCODE_RELAX (STATE_PUSHJSTUB, STATE_ZERO):
02204       /* We need to distinguish different relaxation rounds.  */
02205       seg_info (segment)->tc_segment_info_data.last_stubfrag = fragP;
02206       break;
02207 
02208     case ENCODE_RELAX (STATE_GETA, STATE_ZERO):
02209     case ENCODE_RELAX (STATE_BCC, STATE_ZERO):
02210     case ENCODE_RELAX (STATE_JMP, STATE_ZERO):
02211       /* When relaxing a section for the second time, we don't need to do
02212         anything except making sure that fr_var is set right.  */
02213       break;
02214 
02215     case STATE_GREG_DEF:
02216       length = fragP->tc_frag_data != NULL ? 0 : 8;
02217       fragP->fr_var = length;
02218 
02219       /* Don't consult the relax_table; it isn't valid for this
02220         relaxation.  */
02221       return length;
02222       break;
02223 
02224     default:
02225       BAD_CASE (fragP->fr_subtype);
02226     }
02227 
02228   length = mmix_relax_table[fragP->fr_subtype].rlx_length;
02229   fragP->fr_var = length;
02230 
02231   return length;
02232 }
02233 
02234 /* Turn a string in input_line_pointer into a floating point constant of type
02235    type, and store the appropriate bytes in *litP.  The number of LITTLENUMS
02236    emitted is stored in *sizeP .  An error message is returned, or NULL on
02237    OK.  */
02238 
02239 char *
02240 md_atof (int type, char *litP, int *sizeP)
02241 {
02242   int prec;
02243   LITTLENUM_TYPE words[4];
02244   char *t;
02245   int i;
02246 
02247   switch (type)
02248     {
02249       /* FIXME: Having 'f' in mmix_flt_chars (and here) makes it
02250         problematic to also have a forward reference in an expression.
02251         The testsuite wants it, and it's customary.
02252         We'll deal with the real problems when they come; we share the
02253         problem with most other ports.  */
02254     case 'f':
02255     case 'r':
02256       prec = 2;
02257       break;
02258     case 'd':
02259       prec = 4;
02260       break;
02261     default:
02262       *sizeP = 0;
02263       return _("bad call to md_atof");
02264     }
02265 
02266   t = atof_ieee (input_line_pointer, type, words);
02267   if (t)
02268     input_line_pointer = t;
02269 
02270   *sizeP = prec * 2;
02271 
02272   for (i = 0; i < prec; i++)
02273     {
02274       md_number_to_chars (litP, (valueT) words[i], 2);
02275       litP += 2;
02276     }
02277   return NULL;
02278 }
02279 
02280 /* Convert variable-sized frags into one or more fixups.  */
02281 
02282 void
02283 md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT sec ATTRIBUTE_UNUSED,
02284                fragS *fragP)
02285 {
02286   /* Pointer to first byte in variable-sized part of the frag.  */
02287   char *var_partp;
02288 
02289   /* Pointer to first opcode byte in frag.  */
02290   char *opcodep;
02291 
02292   /* Size in bytes of variable-sized part of frag.  */
02293   int var_part_size = 0;
02294 
02295   /* This is part of *fragP.  It contains all information about addresses
02296      and offsets to varying parts.  */
02297   symbolS *symbolP;
02298   unsigned long var_part_offset;
02299 
02300   /* This is the frag for the opcode.  It, rather than fragP, must be used
02301      when emitting a frag for the opcode.  */
02302   fragS *opc_fragP = fragP->tc_frag_data;
02303   fixS *tmpfixP;
02304 
02305   /* Where, in file space, does addr point?  */
02306   bfd_vma target_address;
02307   bfd_vma opcode_address;
02308 
02309   know (fragP->fr_type == rs_machine_dependent);
02310 
02311   var_part_offset = fragP->fr_fix;
02312   var_partp = fragP->fr_literal + var_part_offset;
02313   opcodep = fragP->fr_opcode;
02314 
02315   symbolP = fragP->fr_symbol;
02316 
02317   target_address
02318     = ((symbolP ? S_GET_VALUE (symbolP) : 0) + fragP->fr_offset);
02319 
02320   /* The opcode that would be extended is the last four "fixed" bytes.  */
02321   opcode_address = fragP->fr_address + fragP->fr_fix - 4;
02322 
02323   switch (fragP->fr_subtype)
02324     {
02325     case ENCODE_RELAX (STATE_PUSHJSTUB, STATE_ZERO):
02326       /* Setting the unknown bits to 0 seems the most appropriate.  */
02327       mmix_set_geta_branch_offset (opcodep, 0);
02328       tmpfixP = fix_new (opc_fragP, opcodep - opc_fragP->fr_literal, 8,
02329                       fragP->fr_symbol, fragP->fr_offset, 1,
02330                       BFD_RELOC_MMIX_PUSHJ_STUBBABLE);
02331       COPY_FR_WHERE_TO_FX (fragP, tmpfixP);
02332       var_part_size = 0;
02333       break;
02334 
02335     case ENCODE_RELAX (STATE_GETA, STATE_ZERO):
02336     case ENCODE_RELAX (STATE_BCC, STATE_ZERO):
02337     case ENCODE_RELAX (STATE_PUSHJ, STATE_ZERO):
02338       mmix_set_geta_branch_offset (opcodep, target_address - opcode_address);
02339       if (linkrelax)
02340        {
02341          tmpfixP
02342            = fix_new (opc_fragP, opcodep - opc_fragP->fr_literal, 4,
02343                      fragP->fr_symbol, fragP->fr_offset, 1,
02344                      BFD_RELOC_MMIX_ADDR19);
02345          COPY_FR_WHERE_TO_FX (fragP, tmpfixP);
02346        }
02347       var_part_size = 0;
02348       break;
02349 
02350     case ENCODE_RELAX (STATE_JMP, STATE_ZERO):
02351       mmix_set_jmp_offset (opcodep, target_address - opcode_address);
02352       if (linkrelax)
02353        {
02354          tmpfixP
02355            = fix_new (opc_fragP, opcodep - opc_fragP->fr_literal, 4,
02356                      fragP->fr_symbol, fragP->fr_offset, 1,
02357                      BFD_RELOC_MMIX_ADDR27);
02358          COPY_FR_WHERE_TO_FX (fragP, tmpfixP);
02359        }
02360       var_part_size = 0;
02361       break;
02362 
02363     case STATE_GREG_DEF:
02364       if (fragP->tc_frag_data == NULL)
02365        {
02366          /* We must initialize data that's supposed to be "fixed up" to
02367             avoid emitting garbage, because md_apply_fix won't do
02368             anything for undefined symbols.  */
02369          md_number_to_chars (var_partp, 0, 8);
02370          tmpfixP
02371            = fix_new (fragP, var_partp - fragP->fr_literal, 8,
02372                      fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_64);
02373          COPY_FR_WHERE_TO_FX (fragP, tmpfixP);
02374          mmix_gregs[n_of_cooked_gregs++] = tmpfixP;
02375          var_part_size = 8;
02376        }
02377       else
02378        var_part_size = 0;
02379       break;
02380 
02381 #define HANDLE_MAX_RELOC(state, reloc)                                \
02382   case ENCODE_RELAX (state, STATE_MAX):                               \
02383     var_part_size                                              \
02384       = mmix_relax_table[ENCODE_RELAX (state, STATE_MAX)].rlx_length; \
02385     mmix_fill_nops (var_partp, var_part_size / 4);                    \
02386     if (warn_on_expansion)                                     \
02387       as_warn_where (fragP->fr_file, fragP->fr_line,                  \
02388                    _("operand out of range, instruction expanded"));  \
02389     tmpfixP = fix_new (fragP, var_partp - fragP->fr_literal - 4, 8,   \
02390                      fragP->fr_symbol, fragP->fr_offset, 1, reloc);   \
02391     COPY_FR_WHERE_TO_FX (fragP, tmpfixP);                      \
02392     break
02393 
02394       HANDLE_MAX_RELOC (STATE_GETA, BFD_RELOC_MMIX_GETA);
02395       HANDLE_MAX_RELOC (STATE_BCC, BFD_RELOC_MMIX_CBRANCH);
02396       HANDLE_MAX_RELOC (STATE_PUSHJ, BFD_RELOC_MMIX_PUSHJ);
02397       HANDLE_MAX_RELOC (STATE_JMP, BFD_RELOC_MMIX_JMP);
02398 
02399     default:
02400       BAD_CASE (fragP->fr_subtype);
02401       break;
02402     }
02403 
02404   fragP->fr_fix += var_part_size;
02405   fragP->fr_var = 0;
02406 }
02407 
02408 /* Applies the desired value to the specified location.
02409    Also sets up addends for RELA type relocations.
02410    Stolen from tc-mcore.c.
02411 
02412    Note that this function isn't called when linkrelax != 0.  */
02413 
02414 void
02415 md_apply_fix (fixS *fixP, valueT *valP, segT segment)
02416 {
02417   char *buf  = fixP->fx_where + fixP->fx_frag->fr_literal;
02418   /* Note: use offsetT because it is signed, valueT is unsigned.  */
02419   offsetT val  = (offsetT) * valP;
02420   segT symsec
02421     = (fixP->fx_addsy == NULL
02422        ? absolute_section : S_GET_SEGMENT (fixP->fx_addsy));
02423 
02424   /* If the fix is relative to a symbol which is not defined, or, (if
02425      pcrel), not in the same segment as the fix, we cannot resolve it
02426      here.  */
02427   if (fixP->fx_addsy != NULL
02428       && (! S_IS_DEFINED (fixP->fx_addsy)
02429          || S_IS_WEAK (fixP->fx_addsy)
02430          || (fixP->fx_pcrel && symsec != segment)
02431          || (! fixP->fx_pcrel
02432              && symsec != absolute_section
02433              && ((fixP->fx_r_type != BFD_RELOC_MMIX_REG
02434                  && fixP->fx_r_type != BFD_RELOC_MMIX_REG_OR_BYTE)
02435                 || symsec != reg_section))))
02436     {
02437       fixP->fx_done = 0;
02438       return;
02439     }
02440   else if (fixP->fx_r_type == BFD_RELOC_MMIX_LOCAL
02441           || fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
02442           || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
02443     {
02444       /* These are never "fixed".  */
02445       fixP->fx_done = 0;
02446       return;
02447     }
02448   else
02449     /* We assume every other relocation is "fixed".  */
02450     fixP->fx_done = 1;
02451 
02452   switch (fixP->fx_r_type)
02453     {
02454     case BFD_RELOC_64:
02455     case BFD_RELOC_32:
02456     case BFD_RELOC_24:
02457     case BFD_RELOC_16:
02458     case BFD_RELOC_8:
02459     case BFD_RELOC_64_PCREL:
02460     case BFD_RELOC_32_PCREL:
02461     case BFD_RELOC_24_PCREL:
02462     case BFD_RELOC_16_PCREL:
02463     case BFD_RELOC_8_PCREL:
02464       md_number_to_chars (buf, val, fixP->fx_size);
02465       break;
02466 
02467     case BFD_RELOC_MMIX_ADDR19:
02468       if (expand_op)
02469        {
02470          /* This shouldn't happen.  */
02471          BAD_CASE (fixP->fx_r_type);
02472          break;
02473        }
02474       /* FALLTHROUGH.  */
02475     case BFD_RELOC_MMIX_GETA:
02476     case BFD_RELOC_MMIX_CBRANCH:
02477     case BFD_RELOC_MMIX_PUSHJ:
02478     case BFD_RELOC_MMIX_PUSHJ_STUBBABLE:
02479       /* If this fixup is out of range, punt to the linker to emit an
02480         error.  This should only happen with -no-expand.  */
02481       if (val < -(((offsetT) 1 << 19)/2)
02482          || val >= ((offsetT) 1 << 19)/2 - 1
02483          || (val & 3) != 0)
02484        {
02485          if (warn_on_expansion)
02486            as_warn_where (fixP->fx_file, fixP->fx_line,
02487                         _("operand out of range"));
02488          fixP->fx_done = 0;
02489          val = 0;
02490        }
02491       mmix_set_geta_branch_offset (buf, val);
02492       break;
02493 
02494     case BFD_RELOC_MMIX_ADDR27:
02495       if (expand_op)
02496        {
02497          /* This shouldn't happen.  */
02498          BAD_CASE (fixP->fx_r_type);
02499          break;
02500        }
02501       /* FALLTHROUGH.  */
02502     case BFD_RELOC_MMIX_JMP:
02503       /* If this fixup is out of range, punt to the linker to emit an
02504         error.  This should only happen with -no-expand.  */
02505       if (val < -(((offsetT) 1 << 27)/2)
02506          || val >= ((offsetT) 1 << 27)/2 - 1
02507          || (val & 3) != 0)
02508        {
02509          if (warn_on_expansion)
02510            as_warn_where (fixP->fx_file, fixP->fx_line,
02511                         _("operand out of range"));
02512          fixP->fx_done = 0;
02513          val = 0;
02514        }
02515       mmix_set_jmp_offset (buf, val);
02516       break;
02517 
02518     case BFD_RELOC_MMIX_REG_OR_BYTE:
02519       if (fixP->fx_addsy != NULL
02520          && (S_GET_SEGMENT (fixP->fx_addsy) != reg_section
02521              || S_GET_VALUE (fixP->fx_addsy) > 255)
02522          && S_GET_SEGMENT (fixP->fx_addsy) != absolute_section)
02523        {
02524          as_bad_where (fixP->fx_file, fixP->fx_line,
02525                      _("invalid operands"));
02526          /* We don't want this "symbol" appearing in output, because
02527             that will fail.  */
02528          fixP->fx_done = 1;
02529        }
02530 
02531       buf[0] = val;
02532 
02533       /* If this reloc is for a Z field, we need to adjust
02534         the opcode if we got a constant here.
02535         FIXME: Can we make this more robust?  */
02536 
02537       if ((fixP->fx_where & 3) == 3
02538          && (fixP->fx_addsy == NULL
02539              || S_GET_SEGMENT (fixP->fx_addsy) == absolute_section))
02540        buf[-3] |= IMM_OFFSET_BIT;
02541       break;
02542 
02543     case BFD_RELOC_MMIX_REG:
02544       if (fixP->fx_addsy == NULL
02545          || S_GET_SEGMENT (fixP->fx_addsy) != reg_section
02546          || S_GET_VALUE (fixP->fx_addsy) > 255)
02547        {
02548          as_bad_where (fixP->fx_file, fixP->fx_line,
02549                      _("invalid operands"));
02550          fixP->fx_done = 1;
02551        }
02552 
02553       *buf = val;
02554       break;
02555 
02556     case BFD_RELOC_MMIX_BASE_PLUS_OFFSET:
02557       /* These are never "fixed".  */
02558       fixP->fx_done = 0;
02559       return;
02560 
02561     case BFD_RELOC_MMIX_PUSHJ_1:
02562     case BFD_RELOC_MMIX_PUSHJ_2:
02563     case BFD_RELOC_MMIX_PUSHJ_3:
02564     case BFD_RELOC_MMIX_CBRANCH_J:
02565     case BFD_RELOC_MMIX_CBRANCH_1:
02566     case BFD_RELOC_MMIX_CBRANCH_2:
02567     case BFD_RELOC_MMIX_CBRANCH_3:
02568     case BFD_RELOC_MMIX_GETA_1:
02569     case BFD_RELOC_MMIX_GETA_2:
02570     case BFD_RELOC_MMIX_GETA_3:
02571     case BFD_RELOC_MMIX_JMP_1:
02572     case BFD_RELOC_MMIX_JMP_2:
02573     case BFD_RELOC_MMIX_JMP_3:
02574     default:
02575       BAD_CASE (fixP->fx_r_type);
02576       break;
02577     }
02578 
02579   if (fixP->fx_done)
02580     /* Make sure that for completed fixups we have the value around for
02581        use by e.g. mmix_frob_file.  */
02582     fixP->fx_offset = val;
02583 }
02584 
02585 /* A bsearch function for looking up a value against offsets for GREG
02586    definitions.  */
02587 
02588 static int
02589 cmp_greg_val_greg_symbol_fixes (const void *p1, const void *p2)
02590 {
02591   offsetT val1 = *(offsetT *) p1;
02592   offsetT val2 = ((struct mmix_symbol_greg_fixes *) p2)->offs;
02593 
02594   if (val1 >= val2 && val1 < val2 + 255)
02595     return 0;
02596 
02597   if (val1 > val2)
02598     return 1;
02599 
02600   return -1;
02601 }
02602 
02603 /* Generate a machine-dependent relocation.  */
02604 
02605 arelent *
02606 tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixP)
02607 {
02608   bfd_signed_vma val
02609     = fixP->fx_offset
02610     + (fixP->fx_addsy != NULL
02611        && !S_IS_WEAK (fixP->fx_addsy)
02612        && !S_IS_COMMON (fixP->fx_addsy)
02613        ? S_GET_VALUE (fixP->fx_addsy) : 0);
02614   arelent *relP;
02615   bfd_reloc_code_real_type code = BFD_RELOC_NONE;
02616   char *buf  = fixP->fx_where + fixP->fx_frag->fr_literal;
02617   symbolS *addsy = fixP->fx_addsy;
02618   asection *addsec = addsy == NULL ? NULL : S_GET_SEGMENT (addsy);
02619   asymbol *baddsy = addsy != NULL ? symbol_get_bfdsym (addsy) : NULL;
02620   bfd_vma addend
02621     = val - (baddsy == NULL || S_IS_COMMON (addsy) || S_IS_WEAK (addsy)
02622             ? 0 : bfd_asymbol_value (baddsy));
02623 
02624   /* A single " LOCAL expression" in the wrong section will not work when
02625      linking to MMO; relocations for zero-content sections are then
02626      ignored.  Normally, relocations would modify section contents, and
02627      you'd never think or be able to do something like that.  The
02628      relocation resulting from a LOCAL directive doesn't have an obvious
02629      and mandatory location.  I can't figure out a way to do this better
02630      than just helping the user around this limitation here; hopefully the
02631      code using the local expression is around.  Putting the LOCAL
02632      semantics in a relocation still seems right; a section didn't do.  */
02633   if (bfd_section_size (section->owner, section) == 0)
02634     as_bad_where
02635       (fixP->fx_file, fixP->fx_line,
02636        fixP->fx_r_type == BFD_RELOC_MMIX_LOCAL
02637        /* The BFD_RELOC_MMIX_LOCAL-specific message is supposed to be
02638          user-friendly, though a little bit non-substantial.  */
02639        ? _("directive LOCAL must be placed in code or data")
02640        : _("internal confusion: relocation in a section without contents"));
02641 
02642   /* FIXME: Range tests for all these.  */
02643   switch (fixP->fx_r_type)
02644     {
02645     case BFD_RELOC_64:
02646     case BFD_RELOC_32:
02647     case BFD_RELOC_24:
02648     case BFD_RELOC_16:
02649     case BFD_RELOC_8:
02650       code = fixP->fx_r_type;
02651 
02652       if (addsy == NULL || bfd_is_abs_section (addsec))
02653        {
02654          /* Resolve this reloc now, as md_apply_fix would have done (not
02655             called if -linkrelax).  There is no point in keeping a reloc
02656             to an absolute symbol.  No reloc that is subject to
02657             relaxation must be to an absolute symbol; difference
02658             involving symbols in a specific section must be signalled as
02659             an error if the relaxing cannot be expressed; having a reloc
02660             to the resolved (now absolute) value does not help.  */
02661          md_number_to_chars (buf, val, fixP->fx_size);
02662          return NULL;
02663        }
02664       break;
02665 
02666     case BFD_RELOC_64_PCREL:
02667     case BFD_RELOC_32_PCREL:
02668     case BFD_RELOC_24_PCREL:
02669     case BFD_RELOC_16_PCREL:
02670     case BFD_RELOC_8_PCREL:
02671     case BFD_RELOC_MMIX_LOCAL:
02672     case BFD_RELOC_VTABLE_INHERIT:
02673     case BFD_RELOC_VTABLE_ENTRY:
02674     case BFD_RELOC_MMIX_GETA:
02675     case BFD_RELOC_MMIX_GETA_1:
02676     case BFD_RELOC_MMIX_GETA_2:
02677     case BFD_RELOC_MMIX_GETA_3:
02678     case BFD_RELOC_MMIX_CBRANCH:
02679     case BFD_RELOC_MMIX_CBRANCH_J:
02680     case BFD_RELOC_MMIX_CBRANCH_1:
02681     case BFD_RELOC_MMIX_CBRANCH_2:
02682     case BFD_RELOC_MMIX_CBRANCH_3:
02683     case BFD_RELOC_MMIX_PUSHJ:
02684     case BFD_RELOC_MMIX_PUSHJ_1:
02685     case BFD_RELOC_MMIX_PUSHJ_2:
02686     case BFD_RELOC_MMIX_PUSHJ_3:
02687     case BFD_RELOC_MMIX_PUSHJ_STUBBABLE:
02688     case BFD_RELOC_MMIX_JMP:
02689     case BFD_RELOC_MMIX_JMP_1:
02690     case BFD_RELOC_MMIX_JMP_2:
02691     case BFD_RELOC_MMIX_JMP_3:
02692     case BFD_RELOC_MMIX_ADDR19:
02693     case BFD_RELOC_MMIX_ADDR27:
02694       code = fixP->fx_r_type;
02695       break;
02696 
02697     case BFD_RELOC_MMIX_REG_OR_BYTE:
02698       /* If we have this kind of relocation to an unknown symbol or to the
02699         register contents section (that is, to a register), then we can't
02700         resolve the relocation here.  */
02701       if (addsy != NULL
02702          && (bfd_is_und_section (addsec)
02703              || strcmp (bfd_get_section_name (addsec->owner, addsec),
02704                       MMIX_REG_CONTENTS_SECTION_NAME) == 0))
02705        {
02706          code = fixP->fx_r_type;
02707          break;
02708        }
02709 
02710       /* If the relocation is not to the register section or to the
02711         absolute section (a numeric value), then we have an error.  */
02712       if (addsy != NULL
02713          && (S_GET_SEGMENT (addsy) != real_reg_section
02714              || val > 255
02715              || val < 0)
02716          && ! bfd_is_abs_section (addsec))
02717        goto badop;
02718 
02719       /* Set the "immediate" bit of the insn if this relocation is to Z
02720         field when the value is a numeric value, i.e. not a register.  */
02721       if ((fixP->fx_where & 3) == 3
02722          && (addsy == NULL || bfd_is_abs_section (addsec)))
02723        buf[-3] |= IMM_OFFSET_BIT;
02724 
02725       buf[0] = val;
02726       return NULL;
02727 
02728     case BFD_RELOC_MMIX_BASE_PLUS_OFFSET:
02729       if (addsy != NULL
02730          && strcmp (bfd_get_section_name (addsec->owner, addsec),
02731                    MMIX_REG_CONTENTS_SECTION_NAME) == 0)
02732        {
02733          /* This changed into a register; the relocation is for the
02734             register-contents section.  The constant part remains zero.  */
02735          code = BFD_RELOC_MMIX_REG;
02736          break;
02737        }
02738 
02739       /* If we've found out that this was indeed a register, then replace
02740         with the register number.  The constant part is already zero.
02741 
02742         If we encounter any other defined symbol, then we must find a
02743         suitable register and emit a reloc.  */
02744       if (addsy == NULL || addsec != real_reg_section)
02745        {
02746          struct mmix_symbol_gregs *gregs;
02747          struct mmix_symbol_greg_fixes *fix;
02748 
02749          if (S_IS_DEFINED (addsy)
02750              && !bfd_is_com_section (addsec)
02751              && !S_IS_WEAK (addsy))
02752            {
02753              if (! symbol_section_p (addsy) && ! bfd_is_abs_section (addsec))
02754               as_fatal (_("internal: BFD_RELOC_MMIX_BASE_PLUS_OFFSET not resolved to section"));
02755 
02756              /* If this is an absolute symbol sufficiently near
02757                lowest_data_loc, then we canonicalize on the data
02758                section.  Note that val is signed here; we may subtract
02759                lowest_data_loc which is unsigned.  Careful with those
02760                comparisons.  */
02761              if (lowest_data_loc != (bfd_vma) -1
02762                 && (bfd_vma) val + 256 > lowest_data_loc
02763                 && bfd_is_abs_section (addsec))
02764               {
02765                 val -= (offsetT) lowest_data_loc;
02766                 addsy = section_symbol (data_section);
02767               }
02768              /* Likewise text section.  */
02769              else if (lowest_text_loc != (bfd_vma) -1
02770                      && (bfd_vma) val + 256 > lowest_text_loc
02771                      && bfd_is_abs_section (addsec))
02772               {
02773                 val -= (offsetT) lowest_text_loc;
02774                 addsy = section_symbol (text_section);
02775               }
02776            }
02777 
02778          gregs = *symbol_get_tc (addsy);
02779 
02780          /* If that symbol does not have any associated GREG definitions,
02781             we can't do anything.  */
02782          if (gregs == NULL
02783              || (fix = bsearch (&val, gregs->greg_fixes, gregs->n_gregs,
02784                              sizeof (gregs->greg_fixes[0]),
02785                              cmp_greg_val_greg_symbol_fixes)) == NULL
02786              /* The register must not point *after* the address we want.  */
02787              || fix->offs > val
02788              /* Neither must the register point more than 255 bytes
02789                before the address we want.  */
02790              || fix->offs + 255 < val)
02791            {
02792              /* We can either let the linker allocate GREGs
02793                automatically, or emit an error.  */
02794              if (allocate_undefined_gregs_in_linker)
02795               {
02796                 /* The values in baddsy and addend are right.  */
02797                 code = fixP->fx_r_type;
02798                 break;
02799               }
02800              else
02801               as_bad_where (fixP->fx_file, fixP->fx_line,
02802                            _("no suitable GREG definition for operands"));
02803              return NULL;
02804            }
02805          else
02806            {
02807              /* Transform the base-plus-offset reloc for the actual area
02808                to a reloc for the register with the address of the area.
02809                Put addend for register in Z operand.  */
02810              buf[1] = val - fix->offs;
02811              code = BFD_RELOC_MMIX_REG;
02812              baddsy
02813               = (bfd_get_section_by_name (stdoutput,
02814                                        MMIX_REG_CONTENTS_SECTION_NAME)
02815                  ->symbol);
02816 
02817              addend = fix->fix->fx_frag->fr_address + fix->fix->fx_where;
02818            }
02819        }
02820       else if (S_GET_VALUE (addsy) > 255)
02821        as_bad_where (fixP->fx_file, fixP->fx_line,
02822                     _("invalid operands"));
02823       else
02824        {
02825          *buf = val;
02826          return NULL;
02827        }
02828       break;
02829 
02830     case BFD_RELOC_MMIX_REG:
02831       if (addsy != NULL
02832          && (bfd_is_und_section (addsec)
02833              || strcmp (bfd_get_section_name (addsec->owner, addsec),
02834                       MMIX_REG_CONTENTS_SECTION_NAME) == 0))
02835        {
02836          code = fixP->fx_r_type;
02837          break;
02838        }
02839 
02840       if (addsy != NULL
02841          && (addsec != real_reg_section
02842              || val > 255
02843              || val < 0)
02844          && ! bfd_is_und_section (addsec))
02845        /* Drop through to error message.  */
02846        ;
02847       else
02848        {
02849          buf[0] = val;
02850          return NULL;
02851        }
02852       /* FALLTHROUGH.  */
02853 
02854       /* The others are supposed to be handled by md_apply_fix.
02855         FIXME: ... which isn't called when -linkrelax.  Move over
02856         md_apply_fix code here for everything reasonable.  */
02857     badop:
02858     default:
02859       as_bad_where
02860        (fixP->fx_file, fixP->fx_line,
02861         _("operands were not reducible at assembly-time"));
02862 
02863       /* Unmark this symbol as used in a reloc, so we don't bump into a BFD
02864         assert when trying to output reg_section.  FIXME: A gas bug.  */
02865       fixP->fx_addsy = NULL;
02866       return NULL;
02867     }
02868 
02869   relP = (arelent *) xmalloc (sizeof (arelent));
02870   assert (relP != 0);
02871   relP->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
02872   *relP->sym_ptr_ptr = baddsy;
02873   relP->address = fixP->fx_frag->fr_address + fixP->fx_where;
02874 
02875   relP->addend = addend;
02876 
02877   /* If this had been a.out, we would have had a kludge for weak symbols
02878      here.  */
02879 
02880   relP->howto = bfd_reloc_type_lookup (stdoutput, code);
02881   if (! relP->howto)
02882     {
02883       const char *name;
02884 
02885       name = S_GET_NAME (addsy);
02886       if (name == NULL)
02887        name = _("<unknown>");
02888       as_fatal (_("cannot generate relocation type for symbol %s, code %s"),
02889               name, bfd_get_reloc_code_name (code));
02890     }
02891 
02892   return relP;
02893 }
02894 
02895 /* Do some reformatting of a line.  FIXME: We could transform a mmixal
02896    line into traditional (GNU?) format, unless #NO_APP, and get rid of all
02897    ugly labels_without_colons etc.  */
02898 
02899 void
02900 mmix_handle_mmixal (void)
02901 {
02902   char *insn;
02903   char *s = input_line_pointer;
02904   char *label = NULL;
02905   char c;
02906 
02907   if (pending_label != NULL)
02908     as_fatal (_("internal: unhandled label %s"), pending_label);
02909 
02910   if (mmix_gnu_syntax)
02911     return;
02912 
02913   /* If we're on a line with a label, check if it's a mmixal fb-label.
02914      Save an indicator and skip the label; it must be set only after all
02915      fb-labels of expressions are evaluated.  */
02916   if (ISDIGIT (s[0]) && s[1] == 'H' && ISSPACE (s[2]))
02917     {
02918       current_fb_label = s[0] - '0';
02919 
02920       /* We have to skip the label, but also preserve the newlineness of
02921         the previous character, since the caller checks that.  It's a
02922         mess we blame on the caller.  */
02923       s[1] = s[-1];
02924       s += 2;
02925       input_line_pointer = s;
02926 
02927       while (*s && ISSPACE (*s) && ! is_end_of_line[(unsigned int) *s])
02928        s++;
02929 
02930       /* For errors emitted here, the book-keeping is off by one; the
02931         caller is about to bump the counters.  Adjust the error messages.  */
02932       if (is_end_of_line[(unsigned int) *s])
02933        {
02934          char *name;
02935          unsigned int line;
02936          as_where (&name, &line);
02937          as_bad_where (name, line + 1,
02938                      _("[0-9]H labels may not appear alone on a line"));
02939          current_fb_label = -1;
02940        }
02941       if (*s == '.')
02942        {
02943          char *name;
02944          unsigned int line;
02945          as_where (&name, &line);
02946          as_bad_where (name, line + 1,
02947                      _("[0-9]H labels do not mix with dot-pseudos"));
02948          current_fb_label = -1;
02949        }
02950 
02951       /* Back off to the last space before the opcode so we don't handle
02952         the opcode as a label.  */
02953       s--;
02954     }
02955   else
02956     current_fb_label = -1;
02957 
02958   if (*s == '.')
02959     {
02960       /* If the first character is a '.', then it's a pseudodirective, not a
02961         label.  Make GAS not handle label-without-colon on this line.  We
02962         also don't do mmixal-specific stuff on this line.  */
02963       label_without_colon_this_line = 0;
02964       return;
02965     }
02966 
02967   if (*s == 0 || is_end_of_line[(unsigned int) *s])
02968     /* We avoid handling empty lines here.  */
02969     return;
02970       
02971   if (is_name_beginner (*s))
02972     label = s;
02973 
02974   /* If there is a label, skip over it.  */
02975   while (*s && is_part_of_name (*s))
02976     s++;
02977 
02978   /* Find the start of the instruction or pseudo following the label,
02979      if there is one.  */
02980   for (insn = s;
02981        *insn && ISSPACE (*insn) && ! is_end_of_line[(unsigned int) *insn];
02982        insn++)
02983     /* Empty */
02984     ;
02985 
02986   /* Remove a trailing ":" off labels, as they'd otherwise be considered
02987      part of the name.  But don't do this for local labels.  */
02988   if (s != input_line_pointer && s[-1] == ':'
02989       && (s - 2 != input_line_pointer
02990          || ! ISDIGIT (s[-2])))
02991     s[-1] = ' ';
02992   else if (label != NULL
02993           /* For a lone label on a line, we don't attach it to the next
02994              instruction or MMIXAL-pseudo (getting its alignment).  Thus
02995              is acts like a "normal" :-ended label.  Ditto if it's
02996              followed by a non-MMIXAL pseudo.  */
02997           && !is_end_of_line[(unsigned int) *insn]
02998           && *insn != '.')
02999     {
03000       /* For labels that don't end in ":", we save it so we can later give
03001         it the same alignment and address as the associated instruction.  */
03002 
03003       /* Make room for the label including the ending nul.  */
03004       int len_0 = s - label + 1;
03005 
03006       /* Save this label on the MMIX symbol obstack.  Saving it on an
03007         obstack is needless for "IS"-pseudos, but it's harmless and we
03008         avoid a little code-cluttering.  */
03009       obstack_grow (&mmix_sym_obstack, label, len_0);
03010       pending_label = obstack_finish (&mmix_sym_obstack);
03011       pending_label[len_0 - 1] = 0;
03012     }
03013 
03014   /* If we have a non-MMIXAL pseudo, we have not business with the rest of
03015      the line.  */
03016   if (*insn == '.')
03017     return;
03018 
03019   /* Find local labels of operands.  Look for "[0-9][FB]" where the
03020      characters before and after are not part of words.  Break if a single
03021      or double quote is seen anywhere.  It means we can't have local
03022      labels as part of list with mixed quoted and unquoted members for
03023      mmixal compatibility but we can't have it all.  For the moment.
03024      Replace the '<N>B' or '<N>F' with MAGIC_FB_BACKWARD_CHAR<N> and
03025      MAGIC_FB_FORWARD_CHAR<N> respectively.  */
03026 
03027   /* First make sure we don't have any of the magic characters on the line
03028      appearing as input.  */
03029   while (*s)
03030     {
03031       c = *s++;
03032       if (is_end_of_line[(unsigned int) c])
03033        break;
03034       if (c == MAGIC_FB_BACKWARD_CHAR || c == MAGIC_FB_FORWARD_CHAR)
03035        as_bad (_("invalid characters in input"));
03036     }
03037 
03038   /* Scan again, this time looking for ';' after operands.  */
03039   s = insn;
03040 
03041   /* Skip the insn.  */
03042   while (*s
03043         && ! ISSPACE (*s)
03044         && *s != ';'
03045         && ! is_end_of_line[(unsigned int) *s])
03046     s++;
03047 
03048   /* Skip the spaces after the insn.  */
03049   while (*s
03050         && ISSPACE (*s)
03051         && *s != ';'
03052         && ! is_end_of_line[(unsigned int) *s])
03053     s++;
03054 
03055   /* Skip the operands.  While doing this, replace [0-9][BF] with
03056      (MAGIC_FB_BACKWARD_CHAR|MAGIC_FB_FORWARD_CHAR)[0-9].  */
03057   while ((c = *s) != 0
03058         && ! ISSPACE (c)
03059         && c != ';'
03060         && ! is_end_of_line[(unsigned int) c])
03061     {
03062       if (c == '"')
03063        {
03064          s++;
03065 
03066          /* FIXME: Test-case for semi-colon in string.  */
03067          while (*s
03068                && *s != '"'
03069                && (! is_end_of_line[(unsigned int) *s] || *s == ';'))
03070            s++;
03071 
03072          if (*s == '"')
03073            s++;
03074        }
03075       else if (ISDIGIT (c))
03076        {
03077          if ((s[1] != 'B' && s[1] != 'F')
03078              || is_part_of_name (s[-1])
03079              || is_part_of_name (s[2])
03080              /* Don't treat e.g. #1F as a local-label reference.  */
03081              || (s != input_line_pointer && s[-1] == '#'))
03082            s++;
03083          else
03084            {
03085              s[0] = (s[1] == 'B'
03086                     ? MAGIC_FB_BACKWARD_CHAR : MAGIC_FB_FORWARD_CHAR);
03087              s[1] = c;
03088            }
03089        }
03090       else
03091        s++;
03092     }
03093 
03094   /* Skip any spaces after the operands.  */
03095   while (*s
03096         && ISSPACE (*s)
03097         && *s != ';'
03098         && !is_end_of_line[(unsigned int) *s])
03099     s++;
03100 
03101   /* If we're now looking at a semi-colon, then it's an end-of-line
03102      delimiter.  */
03103   mmix_next_semicolon_is_eoln = (*s == ';');
03104 
03105   /* Make IS into an EQU by replacing it with "= ".  Only match upper-case
03106      though; let lower-case be a syntax error.  */
03107   s = insn;
03108   if (s[0] == 'I' && s[1] == 'S' && ISSPACE (s[2]))
03109     {
03110       *s = '=';
03111       s[1] = ' ';
03112 
03113       /* Since labels can start without ":", we have to handle "X IS 42"
03114         in full here, or "X" will be parsed as a label to be set at ".".  */
03115       input_line_pointer = s;
03116 
03117       /* Right after this function ends, line numbers will be bumped if
03118         input_line_pointer[-1] = '\n'.  We want accurate line numbers for
03119         the equals call, so we bump them before the call, and make sure
03120         they aren't bumped afterwards.  */
03121       bump_line_counters ();
03122 
03123       /* A fb-label is valid as an IS-label.  */
03124       if (current_fb_label >= 0)
03125        {
03126          char *fb_name;
03127 
03128          /* We need to save this name on our symbol obstack, since the
03129             string we got in fb_label_name is volatile and will change
03130             with every call to fb_label_name, like those resulting from
03131             parsing the IS-operand.  */
03132          fb_name = fb_label_name (current_fb_label, 1);
03133          obstack_grow (&mmix_sym_obstack, fb_name, strlen (fb_name) + 1);
03134          equals (obstack_finish (&mmix_sym_obstack), 0);
03135          fb_label_instance_inc (current_fb_label);
03136          current_fb_label = -1;
03137        }
03138       else
03139        {
03140          if (pending_label == NULL)
03141            as_bad (_("empty label field for IS"));
03142          else
03143            equals (pending_label, 0);
03144          pending_label = NULL;
03145        }
03146 
03147       /* For mmixal, we can have comments without a comment-start
03148         character.   */
03149       mmix_handle_rest_of_empty_line ();
03150       input_line_pointer--;
03151 
03152       input_line_pointer[-1] = ' ';
03153     }
03154   else if (s[0] == 'G'
03155           && s[1] == 'R'
03156           && strncmp (s, "GREG", 4) == 0
03157           && (ISSPACE (s[4]) || is_end_of_line[(unsigned char) s[4]]))
03158     {
03159       input_line_pointer = s + 4;
03160 
03161       /* Right after this function ends, line numbers will be bumped if
03162         input_line_pointer[-1] = '\n'.  We want accurate line numbers for
03163         the s_greg call, so we bump them before the call, and make sure
03164         they aren't bumped afterwards.  */
03165       bump_line_counters ();
03166 
03167       /* A fb-label is valid as a GREG-label.  */
03168       if (current_fb_label >= 0)
03169        {
03170          char *fb_name;
03171 
03172          /* We need to save this name on our symbol obstack, since the
03173             string we got in fb_label_name is volatile and will change
03174             with every call to fb_label_name, like those resulting from
03175             parsing the IS-operand.  */
03176          fb_name = fb_label_name (current_fb_label, 1);
03177 
03178          /* Make sure we save the canonical name and don't get bitten by
03179              prefixes.  */
03180          obstack_1grow (&mmix_sym_obstack, ':');
03181          obstack_grow (&mmix_sym_obstack, fb_name, strlen (fb_name) + 1);
03182          mmix_greg_internal (obstack_finish (&mmix_sym_obstack));
03183          fb_label_instance_inc (current_fb_label);
03184          current_fb_label = -1;
03185        }
03186       else
03187        mmix_greg_internal (pending_label);
03188 
03189       /* Back up before the end-of-line marker that was skipped in
03190         mmix_greg_internal.  */
03191       input_line_pointer--;
03192       input_line_pointer[-1] = ' ';
03193 
03194       pending_label = NULL;
03195     }
03196   else if (pending_label != NULL)
03197     {
03198       input_line_pointer += strlen (pending_label);
03199 
03200       /* See comment above about getting line numbers bumped.  */
03201       input_line_pointer[-1] = '\n';
03202     }
03203 }
03204 
03205 /* Give the value of an fb-label rewritten as in mmix_handle_mmixal, when
03206    parsing an expression.
03207 
03208    On valid calls, input_line_pointer points at a MAGIC_FB_BACKWARD_CHAR
03209    or MAGIC_FB_BACKWARD_CHAR, followed by an ascii digit for the label.
03210    We fill in the label as an expression.  */
03211 
03212 void
03213 mmix_fb_label (expressionS *expP)
03214 {
03215   symbolS *sym;
03216   char *fb_internal_name;
03217 
03218   /* This doesn't happen when not using mmixal syntax.  */
03219   if (mmix_gnu_syntax
03220       || (input_line_pointer[0] != MAGIC_FB_BACKWARD_CHAR
03221          && input_line_pointer[0] != MAGIC_FB_FORWARD_CHAR))
03222     return;
03223 
03224   /* The current backward reference has augmentation 0.  A forward
03225      reference has augmentation 1, unless it's the same as a fb-label on
03226      _this_ line, in which case we add one more so we don't refer to it.
03227      This is the semantics of mmixal; it differs to that of common
03228      fb-labels which refer to a here-label on the current line as a
03229      backward reference.  */
03230   fb_internal_name
03231     = fb_label_name (input_line_pointer[1] - '0',
03232                    (input_line_pointer[0] == MAGIC_FB_FORWARD_CHAR ? 1 : 0)
03233                    + ((input_line_pointer[1] - '0' == current_fb_label
03234                       && input_line_pointer[0] == MAGIC_FB_FORWARD_CHAR)
03235                      ? 1 : 0));
03236 
03237   input_line_pointer += 2;
03238   sym = symbol_find_or_make (fb_internal_name);
03239 
03240   /* We don't have to clean up unrelated fields here; we just do what the
03241      expr machinery does, but *not* just what it does for [0-9][fb], since
03242      we need to treat those as ordinary symbols sometimes; see testcases
03243      err-byte2.s and fb-2.s.  */
03244   if (S_GET_SEGMENT (sym) == absolute_section)
03245     {
03246       expP->X_op = O_constant;
03247       expP->X_add_number = S_GET_VALUE (sym);
03248     }
03249   else
03250     {
03251       expP->X_op = O_symbol;
03252       expP->X_add_symbol = sym;
03253       expP->X_add_number = 0;
03254     }
03255 }
03256 
03257 /* See whether we need to force a relocation into the output file.
03258    This is used to force out switch and PC relative relocations when
03259    relaxing.  */
03260 
03261 int
03262 mmix_force_relocation (fixS *fixP)
03263 {
03264   if (fixP->fx_r_type == BFD_RELOC_MMIX_LOCAL
03265       || fixP->fx_r_type == BFD_RELOC_MMIX_BASE_PLUS_OFFSET)
03266     return 1;
03267 
03268   if (linkrelax)
03269     return 1;
03270 
03271   /* All our pcrel relocations are must-keep.  Note that md_apply_fix is
03272      called *after* this, and will handle getting rid of the presumed
03273      reloc; a relocation isn't *forced* other than to be handled by
03274      md_apply_fix (or tc_gen_reloc if linkrelax).  */
03275   if (fixP->fx_pcrel)
03276     return 1;
03277 
03278   return generic_force_reloc (fixP);
03279 }
03280 
03281 /* The location from which a PC relative jump should be calculated,
03282    given a PC relative reloc.  */
03283 
03284 long
03285 md_pcrel_from_section (fixS *fixP, segT sec)
03286 {
03287   if (fixP->fx_addsy != (symbolS *) NULL
03288       && (! S_IS_DEFINED (fixP->fx_addsy)
03289          || S_GET_SEGMENT (fixP->fx_addsy) != sec))
03290     {
03291       /* The symbol is undefined (or is defined but not in this section).
03292         Let the linker figure it out.  */
03293       return 0;
03294     }
03295 
03296   return (fixP->fx_frag->fr_address + fixP->fx_where);
03297 }
03298 
03299 /* Adjust the symbol table.  We make reg_section relative to the real
03300    register section.  */
03301 
03302 void
03303 mmix_adjust_symtab (void)
03304 {
03305   symbolS *sym;
03306   symbolS *regsec = section_symbol (reg_section);
03307 
03308   for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
03309     if (S_GET_SEGMENT (sym) == reg_section)
03310       {
03311        if (sym == regsec)
03312          {
03313            if (S_IS_EXTERNAL (sym) || symbol_used_in_reloc_p (sym))
03314              abort ();
03315            symbol_remove (sym, &symbol_rootP, &symbol_lastP);
03316          }
03317        else
03318          /* Change section to the *real* register section, so it gets
03319             proper treatment when writing it out.  Only do this for
03320             global symbols.  This also means we don't have to check for
03321             $0..$255.  */
03322          S_SET_SEGMENT (sym, real_reg_section);
03323       }
03324 }
03325 
03326 /* This is the expansion of LABELS_WITHOUT_COLONS.
03327    We let md_start_line_hook tweak label_without_colon_this_line, and then
03328    this function returns the tweaked value, and sets it to 1 for the next
03329    line.  FIXME: Very, very brittle.  Not sure it works the way I
03330    thought at the time I first wrote this.  */
03331 
03332 int
03333 mmix_label_without_colon_this_line (void)
03334 {
03335   int retval = label_without_colon_this_line;
03336 
03337   if (! mmix_gnu_syntax)
03338     label_without_colon_this_line = 1;
03339 
03340   return retval;
03341 }
03342 
03343 /* This is the expansion of md_relax_frag.  We go through the ordinary
03344    relax table function except when the frag is for a GREG.  Then we have
03345    to check whether there's another GREG by the same value that we can
03346    join with.  */
03347 
03348 long
03349 mmix_md_relax_frag (segT seg, fragS *fragP, long stretch)
03350 {
03351   switch (fragP->fr_subtype)
03352     {
03353       /* Growth for this type has been handled by mmix_md_end and
03354         correctly estimated, so there's nothing more to do here.  */
03355     case STATE_GREG_DEF:
03356       return 0;
03357 
03358     case ENCODE_RELAX (STATE_PUSHJ, STATE_ZERO):
03359       {
03360        /* We need to handle relaxation type ourselves, since relax_frag
03361           doesn't update fr_subtype if there's no size increase in the
03362           current section; when going from plain PUSHJ to a stub.  This
03363           is otherwise functionally the same as relax_frag in write.c,
03364           simplified for this case.  */
03365        offsetT aim;
03366        addressT target;
03367        addressT address;
03368        symbolS *symbolP;
03369        target = fragP->fr_offset;
03370        address = fragP->fr_address;
03371        symbolP = fragP->fr_symbol;
03372 
03373        if (symbolP)
03374          {
03375            fragS *sym_frag;
03376 
03377            sym_frag = symbol_get_frag (symbolP);
03378            know (S_GET_SEGMENT (symbolP) != absolute_section
03379                 || sym_frag == &zero_address_frag);
03380            target += S_GET_VALUE (symbolP);
03381 
03382            /* If frag has yet to be reached on this pass, assume it will
03383               move by STRETCH just as we did.  If this is not so, it will
03384               be because some frag between grows, and that will force
03385               another pass.  */
03386 
03387            if (stretch != 0
03388               && sym_frag->relax_marker != fragP->relax_marker
03389               && S_GET_SEGMENT (symbolP) == seg)
03390              target += stretch;
03391          }
03392 
03393        aim = target - address - fragP->fr_fix;
03394        if (aim >= PUSHJ_0B && aim <= PUSHJ_0F)
03395          {
03396            /* Target is reachable with a PUSHJ.  */
03397            segment_info_type *seginfo = seg_info (seg);
03398 
03399            /* If we're at the end of a relaxation round, clear the stub
03400               counter as initialization for the next round.  */
03401            if (fragP == seginfo->tc_segment_info_data.last_stubfrag)
03402              seginfo->tc_segment_info_data.nstubs = 0;
03403            return 0;
03404          }
03405 
03406        /* Not reachable.  Try a stub.  */
03407        fragP->fr_subtype = ENCODE_RELAX (STATE_PUSHJSTUB, STATE_ZERO);
03408       }
03409       /* FALLTHROUGH.  */
03410     
03411       /* See if this PUSHJ is redirectable to a stub.  */
03412     case ENCODE_RELAX (STATE_PUSHJSTUB, STATE_ZERO):
03413       {
03414        segment_info_type *seginfo = seg_info (seg);
03415        fragS *lastfrag = seginfo->frchainP->frch_last;
03416        relax_substateT prev_type = fragP->fr_subtype;
03417 
03418        /* The last frag is always an empty frag, so it suffices to look
03419           at its address to know the ending address of this section.  */
03420        know (lastfrag->fr_type == rs_fill
03421              && lastfrag->fr_fix == 0
03422              && lastfrag->fr_var == 0);
03423 
03424        /* For this PUSHJ to be relaxable into a call to a stub, the
03425           distance must be no longer than 256k bytes from the PUSHJ to
03426           the end of the section plus the maximum size of stubs so far.  */
03427        if ((lastfrag->fr_address
03428             + stretch
03429             + PUSHJ_MAX_LEN * seginfo->tc_segment_info_data.nstubs)
03430            - (fragP->fr_address + fragP->fr_fix)
03431            > GETA_0F
03432            || !pushj_stubs)
03433          fragP->fr_subtype = mmix_relax_table[prev_type].rlx_more;
03434        else
03435          seginfo->tc_segment_info_data.nstubs++;
03436 
03437        /* If we're at the end of a relaxation round, clear the stub
03438           counter as initialization for the next round.  */
03439        if (fragP == seginfo->tc_segment_info_data.last_stubfrag)
03440          seginfo->tc_segment_info_data.nstubs = 0;
03441 
03442        return
03443           (mmix_relax_table[fragP->fr_subtype].rlx_length
03444            - mmix_relax_table[prev_type].rlx_length);
03445       }
03446 
03447     case ENCODE_RELAX (STATE_PUSHJ, STATE_MAX):
03448       {
03449        segment_info_type *seginfo = seg_info (seg);
03450 
03451        /* Need to cover all STATE_PUSHJ states to act on the last stub
03452           frag (the end of this relax round; initialization for the
03453           next).  */
03454        if (fragP == seginfo->tc_segment_info_data.last_stubfrag)
03455          seginfo->tc_segment_info_data.nstubs = 0;
03456 
03457        return 0;
03458       }
03459 
03460     default:
03461       return relax_frag (seg, fragP, stretch);
03462 
03463     case STATE_GREG_UNDF:
03464       BAD_CASE (fragP->fr_subtype);
03465     }
03466 
03467   as_fatal (_("internal: unexpected relax type %d:%d"),
03468            fragP->fr_type, fragP->fr_subtype);
03469   return 0;
03470 }
03471 
03472 /* Various things we punt until all input is seen.  */
03473 
03474 void
03475 mmix_md_end (void)
03476 {
03477   fragS *fragP;
03478   symbolS *mainsym;
03479   int i;
03480 
03481   /* The first frag of GREG:s going into the register contents section.  */
03482   fragS *mmix_reg_contents_frags = NULL;
03483 
03484   /* Reset prefix.  All labels reachable at this point must be
03485      canonicalized.  */
03486   mmix_current_prefix = NULL;
03487 
03488   if (doing_bspec)
03489     as_bad_where (bspec_file, bspec_line, _("BSPEC without ESPEC."));
03490 
03491   /* Emit the low LOC setting of .text.  */
03492   if (text_has_contents && lowest_text_loc != (bfd_vma) -1)
03493     {
03494       symbolS *symbolP;
03495       char locsymbol[sizeof (":") - 1
03496                   + sizeof (MMIX_LOC_SECTION_START_SYMBOL_PREFIX) - 1
03497                   + sizeof (".text")];
03498 
03499       /* An exercise in non-ISO-C-ness, this one.  */
03500       sprintf (locsymbol, ":%s%s", MMIX_LOC_SECTION_START_SYMBOL_PREFIX,
03501               ".text");
03502       symbolP
03503        = symbol_new (locsymbol, absolute_section, lowest_text_loc,
03504                     &zero_address_frag);
03505       S_SET_EXTERNAL (symbolP);
03506     }
03507 
03508   /* Ditto .data.  */
03509   if (data_has_contents && lowest_data_loc != (bfd_vma) -1)
03510     {
03511       symbolS *symbolP;
03512       char locsymbol[sizeof (":") - 1
03513                    + sizeof (MMIX_LOC_SECTION_START_SYMBOL_PREFIX) - 1
03514                    + sizeof (".data")];
03515 
03516       sprintf (locsymbol, ":%s%s", MMIX_LOC_SECTION_START_SYMBOL_PREFIX,
03517               ".data");
03518       symbolP
03519        = symbol_new (locsymbol, absolute_section, lowest_data_loc,
03520                     &zero_address_frag);
03521       S_SET_EXTERNAL (symbolP);
03522     }
03523 
03524   /* Unless GNU syntax mode, set "Main" to be a function, so the
03525      disassembler doesn't get confused when we write truly
03526      mmixal-compatible code (and don't use .type).  Similarly set it
03527      global (regardless of -globalize-symbols), so the linker sees it as
03528      the start symbol in ELF mode.  */
03529   mainsym = symbol_find (MMIX_START_SYMBOL_NAME);
03530   if (mainsym != NULL && ! mmix_gnu_syntax)
03531     {
03532       symbol_get_bfdsym (mainsym)->flags |= BSF_FUNCTION;
03533       S_SET_EXTERNAL (mainsym);
03534     }
03535 
03536   if (n_of_raw_gregs != 0)
03537     {
03538       /* Emit GREGs.  They are collected in order of appearance, but must
03539         be emitted in opposite order to both have section address regno*8
03540         and the same allocation order (within a file) as mmixal.  */
03541       segT this_segment = now_seg;
03542       subsegT this_subsegment = now_subseg;
03543       asection *regsec
03544        = bfd_make_section_old_way (stdoutput,
03545                                 MMIX_REG_CONTENTS_SECTION_NAME);
03546       subseg_set (regsec, 0);
03547 
03548       /* Finally emit the initialization-value.  Emit a variable frag, which
03549         we'll fix in md_estimate_size_before_relax.  We set the initializer
03550         for the tc_frag_data field to NULL, so we can use that field for
03551         relaxation purposes.  */
03552       mmix_opcode_frag = NULL;
03553 
03554       frag_grow (0);
03555       mmix_reg_contents_frags = frag_now;
03556 
03557       for (i = n_of_raw_gregs - 1; i >= 0; i--)
03558        {
03559          if (mmix_raw_gregs[i].label != NULL)
03560            /* There's a symbol.  Let it refer to this location in the
03561               register contents section.  The symbol must be globalized
03562               separately.  */
03563            colon (mmix_raw_gregs[i].label);
03564 
03565          frag_var (rs_machine_dependent, 8, 0, STATE_GREG_UNDF,
03566                   make_expr_symbol (&mmix_raw_gregs[i].exp), 0, NULL);
03567        }
03568 
03569       subseg_set (this_segment, this_subsegment);
03570     }
03571 
03572   /* Iterate over frags resulting from GREGs and move those that evidently
03573      have the same value together and point one to another.
03574 
03575      This works in time O(N^2) but since the upper bound for non-error use
03576      is 223, it's best to keep this simpler algorithm.  */
03577   for (fragP = mmix_reg_contents_frags; fragP != NULL; fragP = fragP->fr_next)
03578     {
03579       fragS **fpp;
03580       fragS *fp = NULL;
03581       fragS *osymfrag;
03582       offsetT osymval;
03583       expressionS *oexpP;
03584       symbolS *symbolP = fragP->fr_symbol;
03585 
03586       if (fragP->fr_type != rs_machine_dependent
03587          || fragP->fr_subtype != STATE_GREG_UNDF)
03588        continue;
03589 
03590       /* Whatever the outcome, we will have this GREG judged merged or
03591         non-merged.  Since the tc_frag_data is NULL at this point, we
03592         default to non-merged.  */
03593       fragP->fr_subtype = STATE_GREG_DEF;
03594 
03595       /* If we're not supposed to merge GREG definitions, then just don't
03596         look for equivalents.  */
03597       if (! merge_gregs)
03598        continue;
03599 
03600       osymval = (offsetT) S_GET_VALUE (symbolP);
03601       osymfrag = symbol_get_frag (symbolP);
03602 
03603       /* If the symbol isn't defined, we can't say that another symbol
03604         equals this frag, then.  FIXME: We can look at the "deepest"
03605         defined name; if a = c and b = c then obviously a == b.  */
03606       if (! S_IS_DEFINED (symbolP))
03607        continue;
03608 
03609       oexpP = symbol_get_value_expression (fragP->fr_symbol);
03610 
03611       /* If the initialization value is zero, then we must not merge them.  */
03612       if (oexpP->X_op == O_constant && osymval == 0)
03613        continue;
03614 
03615       /* Iterate through the frags downward this one.  If we find one that
03616         has the same non-zero value, move it to after this one and point
03617         to it as the equivalent.  */
03618       for (fpp = &fragP->fr_next; *fpp != NULL; fpp = &fpp[0]->fr_next)
03619        {
03620          fp = *fpp;
03621 
03622          if (fp->fr_type != rs_machine_dependent
03623              || fp->fr_subtype != STATE_GREG_UNDF)
03624            continue;
03625 
03626          /* Calling S_GET_VALUE may simplify the symbol, changing from
03627             expr_section etc. so call it first.  */
03628          if ((offsetT) S_GET_VALUE (fp->fr_symbol) == osymval
03629              && symbol_get_frag (fp->fr_symbol) == osymfrag)
03630            {
03631              /* Move the frag links so the one we found equivalent comes
03632                after the current one, carefully considering that
03633                sometimes fpp == &fragP->fr_next and the moves must be a
03634                NOP then.  */
03635              *fpp = fp->fr_next;
03636              fp->fr_next = fragP->fr_next;
03637              fragP->fr_next = fp;
03638              break;
03639            }
03640        }
03641 
03642       if (*fpp != NULL)
03643        fragP->tc_frag_data = fp;
03644     }
03645 }
03646 
03647 /* qsort function for mmix_symbol_gregs.  */
03648 
03649 static int
03650 cmp_greg_symbol_fixes (const void *parg, const void *qarg)
03651 {
03652   const struct mmix_symbol_greg_fixes *p
03653     = (const struct mmix_symbol_greg_fixes *) parg;
03654   const struct mmix_symbol_greg_fixes *q
03655     = (const struct mmix_symbol_greg_fixes *) qarg;
03656 
03657   return p->offs > q->offs ? 1 : p->offs < q->offs ? -1 : 0;
03658 }
03659 
03660 /* Collect GREG definitions from mmix_gregs and hang them as lists sorted
03661    on increasing offsets onto each section symbol or undefined symbol.
03662 
03663    Also, remove the register convenience section so it doesn't get output
03664    as an ELF section.  */
03665 
03666 void
03667 mmix_frob_file (void)
03668 {
03669   int i;
03670   struct mmix_symbol_gregs *all_greg_symbols[MAX_GREGS];
03671   int n_greg_symbols = 0;
03672 
03673   /* Collect all greg fixups and decorate each corresponding symbol with
03674      the greg fixups for it.  */
03675   for (i = 0; i < n_of_cooked_gregs; i++)
03676     {
03677       offsetT offs;
03678       symbolS *sym;
03679       struct mmix_symbol_gregs *gregs;
03680       fixS *fixP;
03681 
03682       fixP = mmix_gregs[i];
03683       know (fixP->fx_r_type == BFD_RELOC_64);
03684 
03685       /* This case isn't doable in general anyway, methinks.  */
03686       if (fixP->fx_subsy != NULL)
03687        {
03688          as_bad_where (fixP->fx_file, fixP->fx_line,
03689                      _("GREG expression too complicated"));
03690          continue;
03691        }
03692 
03693       sym = fixP->fx_addsy;
03694       offs = (offsetT) fixP->fx_offset;
03695 
03696       /* If the symbol is defined, then it must be resolved to a section
03697         symbol at this time, or else we don't know how to handle it.  */
03698       if (S_IS_DEFINED (sym)
03699          && !bfd_is_com_section (S_GET_SEGMENT (sym))
03700          && !S_IS_WEAK (sym))
03701        {
03702          if (! symbol_section_p (sym)
03703              && ! bfd_is_abs_section (S_GET_SEGMENT (sym)))
03704            as_fatal (_("internal: GREG expression not resolved to section"));
03705 
03706          offs += S_GET_VALUE (sym);
03707        }
03708 
03709       /* If this is an absolute symbol sufficiently near lowest_data_loc,
03710         then we canonicalize on the data section.  Note that offs is
03711         signed here; we may subtract lowest_data_loc which is unsigned.
03712         Careful with those comparisons.  */
03713       if (lowest_data_loc != (bfd_vma) -1
03714          && (bfd_vma) offs + 256 > lowest_data_loc
03715          && bfd_is_abs_section (S_GET_SEGMENT (sym)))
03716        {
03717          offs -= (offsetT) lowest_data_loc;
03718          sym = section_symbol (data_section);
03719        }
03720       /* Likewise text section.  */
03721       else if (lowest_text_loc != (bfd_vma) -1
03722               && (bfd_vma) offs + 256 > lowest_text_loc
03723               && bfd_is_abs_section (S_GET_SEGMENT (sym)))
03724        {
03725          offs -= (offsetT) lowest_text_loc;
03726          sym = section_symbol (text_section);
03727        }
03728 
03729       gregs = *symbol_get_tc (sym);
03730 
03731       if (gregs == NULL)
03732        {
03733          gregs = xmalloc (sizeof (*gregs));
03734          gregs->n_gregs = 0;
03735          symbol_set_tc (sym, &gregs);
03736          all_greg_symbols[n_greg_symbols++] = gregs;
03737        }
03738 
03739       gregs->greg_fixes[gregs->n_gregs].fix = fixP;
03740       gregs->greg_fixes[gregs->n_gregs++].offs = offs;
03741     }
03742 
03743   /* For each symbol having a GREG definition, sort those definitions on
03744      offset.  */
03745   for (i = 0; i < n_greg_symbols; i++)
03746     qsort (all_greg_symbols[i]->greg_fixes, all_greg_symbols[i]->n_gregs,
03747           sizeof (all_greg_symbols[i]->greg_fixes[0]), cmp_greg_symbol_fixes);
03748 
03749   if (real_reg_section != NULL)
03750     {
03751       /* FIXME: Pass error state gracefully.  */
03752       if (bfd_get_section_flags (stdoutput, real_reg_section) & SEC_HAS_CONTENTS)
03753        as_fatal (_("register section has contents\n"));
03754 
03755       bfd_section_list_remove (stdoutput, real_reg_section);
03756       --stdoutput->section_count;
03757     }
03758 
03759 }
03760 
03761 /* Provide an expression for a built-in name provided when-used.
03762    Either a symbol that is a handler; living in 0x10*[1..8] and having
03763    name [DVWIOUZX]_Handler, or a mmixal built-in symbol.
03764 
03765    If the name isn't a built-in name and parsed into *EXPP, return zero.  */
03766 
03767 int
03768 mmix_parse_predefined_name (char *name, expressionS *expP)
03769 {
03770   char *canon_name;
03771   char *handler_charp;
03772   const char handler_chars[] = "DVWIOUZX";
03773   symbolS *symp;
03774 
03775   if (! predefined_syms)
03776     return 0;
03777 
03778   canon_name = tc_canonicalize_symbol_name (name);
03779 
03780   if (canon_name[1] == '_'
03781       && strcmp (canon_name + 2, "Handler") == 0
03782       && (handler_charp = strchr (handler_chars, *canon_name)) != NULL)
03783     {
03784       /* If the symbol doesn't exist, provide one relative to the .text
03785         section.
03786 
03787         FIXME: We should provide separate sections, mapped in the linker
03788         script.  */
03789       symp = symbol_find (name);
03790       if (symp == NULL)
03791        symp = symbol_new (name, text_section,
03792                         0x10 * (handler_charp + 1 - handler_chars),
03793                         &zero_address_frag);
03794     }
03795   else
03796     {
03797       /* These symbols appear when referenced; needed for
03798          mmixal-compatible programs.  */
03799       unsigned int i;
03800 
03801       static const struct
03802       {
03803        const char *name;
03804        valueT val;
03805       } predefined_abs_syms[] =
03806        {
03807          {"Data_Segment", (valueT) 0x20 << 56},
03808          {"Pool_Segment", (valueT) 0x40 << 56},
03809          {"Stack_Segment", (valueT) 0x60 << 56},
03810          {"StdIn", 0},
03811          {"StdOut", 1},
03812          {"StdErr", 2},
03813          {"TextRead", 0},
03814          {"TextWrite", 1},
03815          {"BinaryRead", 2},
03816          {"BinaryWrite", 3},
03817          {"BinaryReadWrite", 4},
03818          {"Halt", 0},
03819          {"Fopen", 1},
03820          {"Fclose", 2},
03821          {"Fread", 3},
03822          {"Fgets", 4},
03823          {"Fgetws", 5},
03824          {"Fwrite", 6},
03825          {"Fputs", 7},
03826          {"Fputws", 8},
03827          {"Fseek", 9},
03828          {"Ftell", 10},
03829          {"D_BIT", 0x80},
03830          {"V_BIT", 0x40},
03831          {"W_BIT", 0x20},
03832          {"I_BIT", 0x10},
03833          {"O_BIT", 0x08},
03834          {"U_BIT", 0x04},
03835          {"Z_BIT", 0x02},
03836          {"X_BIT", 0x01},
03837          {"Inf", 0x7ff00000}
03838        };
03839 
03840       /* If it's already in the symbol table, we shouldn't do anything.  */
03841       symp = symbol_find (name);
03842       if (symp != NULL)
03843        return 0;
03844 
03845       for (i = 0;
03846           i < sizeof (predefined_abs_syms) / sizeof (predefined_abs_syms[0]);
03847           i++)
03848        if (strcmp (canon_name, predefined_abs_syms[i].name) == 0)
03849          {
03850            symbol_table_insert (symbol_new (predefined_abs_syms[i].name,
03851                                         absolute_section,
03852                                         predefined_abs_syms[i].val,
03853                                         &zero_address_frag));
03854 
03855            /* Let gas find the symbol we just created, through its
03856                ordinary lookup.  */
03857            return 0;
03858          }
03859 
03860       /* Not one of those symbols.  Let gas handle it.  */
03861       return 0;
03862     }
03863 
03864   expP->X_op = O_symbol;
03865   expP->X_add_number = 0;
03866   expP->X_add_symbol = symp;
03867   expP->X_op_symbol = NULL;
03868 
03869   return 1;
03870 }
03871 
03872 /* Just check that we don't have a BSPEC/ESPEC pair active when changing
03873    sections "normally", and get knowledge about alignment from the new
03874    section.  */
03875 
03876 void
03877 mmix_md_elf_section_change_hook (void)
03878 {
03879   if (doing_bspec)
03880     as_bad (_("section change from within a BSPEC/ESPEC pair is not supported"));
03881 
03882   last_alignment = bfd_get_section_alignment (now_seg->owner, now_seg);
03883   want_unaligned = 0;
03884 }
03885 
03886 /* The LOC worker.  This is like s_org, but we have to support changing
03887    section too.   */
03888 
03889 static void
03890 s_loc (int ignore ATTRIBUTE_UNUSED)
03891 {
03892   segT section;
03893   expressionS exp;
03894   char *p;
03895   symbolS *sym;
03896   offsetT off;
03897 
03898   /* Must not have a BSPEC in progress.  */
03899   if (doing_bspec)
03900     {
03901       as_bad (_("directive LOC from within a BSPEC/ESPEC pair is not supported"));
03902       return;
03903     }
03904 
03905   section = expression (&exp);
03906 
03907   if (exp.X_op == O_illegal
03908       || exp.X_op == O_absent
03909       || exp.X_op == O_big
03910       || section == undefined_section)
03911     {
03912       as_bad (_("invalid LOC expression"));
03913       return;
03914     }
03915 
03916   if (section == absolute_section)
03917     {
03918       /* Translate a constant into a suitable section.  */
03919 
03920       if (exp.X_add_number < ((offsetT) 0x20 << 56))
03921        {
03922          /* Lower than Data_Segment - assume it's .text.  */
03923          section = text_section;
03924 
03925          /* Save the lowest seen location, so we can pass on this
03926             information to the linker.  We don't actually org to this
03927             location here, we just pass on information to the linker so
03928             it can put the code there for us.  */
03929 
03930          /* If there was already a loc (that has to be set lower than
03931             this one), we org at (this - lower).  There's an implicit
03932             "LOC 0" before any entered code.  FIXME: handled by spurious
03933             settings of text_has_contents.  */
03934          if (exp.X_add_number < 0
03935              || exp.X_add_number < (offsetT) lowest_text_loc)
03936            {
03937              as_bad (_("LOC expression stepping backwards is not supported"));
03938              exp.X_op = O_absent;
03939            }
03940          else
03941            {
03942              if (text_has_contents && lowest_text_loc == (bfd_vma) -1)
03943               lowest_text_loc = 0;
03944 
03945              if (lowest_text_loc == (bfd_vma) -1)
03946               {
03947                 lowest_text_loc = exp.X_add_number;
03948 
03949                 /* We want only to change the section, not set an offset.  */
03950                 exp.X_op = O_absent;
03951               }
03952              else
03953               exp.X_add_number -= lowest_text_loc;
03954            }
03955        }
03956       else
03957        {
03958          /* Do the same for the .data section.  */
03959          section = data_section;
03960 
03961          if (exp.X_add_number < (offsetT) lowest_data_loc)
03962            {
03963              as_bad (_("LOC expression stepping backwards is not supported"));
03964              exp.X_op = O_absent;
03965            }
03966          else
03967            {
03968              if (data_has_contents && lowest_data_loc == (bfd_vma) -1)
03969               lowest_data_loc = (bfd_vma) 0x20 << 56;
03970 
03971              if (lowest_data_loc == (bfd_vma) -1)
03972               {
03973                 lowest_data_loc = exp.X_add_number;
03974 
03975                 /* We want only to change the section, not set an offset.  */
03976                 exp.X_op = O_absent;
03977               }
03978              else
03979               exp.X_add_number -= lowest_data_loc;
03980            }
03981        }
03982     }
03983 
03984   if (section != now_seg)
03985     {
03986       obj_elf_section_change_hook ();
03987       subseg_set (section, 0);
03988 
03989       /* Call our section change hooks using the official hook.  */
03990       md_elf_section_change_hook ();
03991     }
03992 
03993   if (exp.X_op != O_absent)
03994     {
03995       if (exp.X_op != O_constant && exp.X_op != O_symbol)
03996        {
03997          /* Handle complex expressions.  */
03998          sym = make_expr_symbol (&exp);
03999          off = 0;
04000        }
04001       else
04002        {
04003          sym = exp.X_add_symbol;
04004          off = exp.X_add_number;
04005        }
04006 
04007       p = frag_var (rs_org, 1, 1, (relax_substateT) 0, sym, off, (char *) 0);
04008       *p = 0;
04009     }
04010 
04011   mmix_handle_rest_of_empty_line ();
04012 }
04013 
04014 /* The BYTE worker.  We have to support sequences of mixed "strings",
04015    numbers and other constant "first-pass" reducible expressions separated
04016    by comma.  */
04017 
04018 static void
04019 mmix_byte (void)
04020 {
04021   unsigned int c;
04022   char *start;
04023 
04024   if (now_seg == text_section)
04025     text_has_contents = 1;
04026   else if (now_seg == data_section)
04027     data_has_contents = 1;
04028 
04029   do
04030     {
04031       SKIP_WHITESPACE ();
04032       switch (*input_line_pointer)
04033        {
04034        case '\"':
04035          ++input_line_pointer;
04036          start = input_line_pointer;
04037          while (is_a_char (c = next_char_of_string ()))
04038            {
04039              FRAG_APPEND_1_CHAR (c);
04040            }
04041 
04042          if (input_line_pointer[-1] != '\"')
04043            {
04044              /* We will only get here in rare cases involving #NO_APP,
04045                where the unterminated string is not recognized by the
04046                preformatting pass.  */
04047              as_bad (_("unterminated string"));
04048              mmix_discard_rest_of_line ();
04049              return;
04050            }
04051          break;
04052 
04053        default:
04054          {
04055            expressionS exp;
04056            segT expseg = expression (&exp);
04057 
04058            /* We have to allow special register names as constant numbers.  */
04059            if ((expseg != absolute_section && expseg != reg_section)
04060               || (exp.X_op != O_constant
04061                   && (exp.X_op != O_register
04062                      || exp.X_add_number <= 255)))
04063              {
04064               as_bad (_("BYTE expression not a pure number"));
04065               mmix_discard_rest_of_line ();
04066               return;
04067              }
04068            else if ((exp.X_add_number > 255 && exp.X_op != O_register)
04069                    || exp.X_add_number < 0)
04070              {
04071               /* Note that mmixal does not allow negative numbers in
04072                  BYTE sequences, so neither should we.  */
04073               as_bad (_("BYTE expression not in the range 0..255"));
04074               mmix_discard_rest_of_line ();
04075               return;
04076              }
04077 
04078            FRAG_APPEND_1_CHAR (exp.X_add_number);
04079          }
04080          break;
04081        }
04082 
04083       SKIP_WHITESPACE ();
04084       c = *input_line_pointer++;
04085     }
04086   while (c == ',');
04087 
04088   input_line_pointer--;
04089 
04090   if (mmix_gnu_syntax)
04091     demand_empty_rest_of_line ();
04092   else
04093     {
04094       mmix_discard_rest_of_line ();
04095       /* Do like demand_empty_rest_of_line and step over the end-of-line
04096          boundary.  */
04097       input_line_pointer++;
04098     }
04099 
04100   /* Make sure we align for the next instruction.  */
04101   last_alignment = 0;
04102 }
04103 
04104 /* Like cons_worker, but we have to ignore "naked comments", not barf on
04105    them.  Implements WYDE, TETRA and OCTA.  We're a little bit more
04106    lenient than mmix_byte but FIXME: they should eventually merge.  */
04107 
04108 static void
04109 mmix_cons (int nbytes)
04110 {
04111   expressionS exp;
04112   char *start;
04113 
04114   /* If we don't have any contents, then it's ok to have a specified start
04115      address that is not a multiple of the max data size.  We will then
04116      align it as necessary when we get here.  Otherwise, it's a fatal sin.  */
04117   if (now_seg == text_section)
04118     {
04119       if (lowest_text_loc != (bfd_vma) -1
04120          && (lowest_text_loc & (nbytes - 1)) != 0)
04121        {
04122          if (text_has_contents)
04123            as_bad (_("data item with alignment larger than location"));
04124          else if (want_unaligned)
04125            as_bad (_("unaligned data at an absolute location is not supported"));
04126 
04127          lowest_text_loc &= ~((bfd_vma) nbytes - 1);
04128          lowest_text_loc += (bfd_vma) nbytes;
04129        }
04130 
04131       text_has_contents = 1;
04132     }
04133   else if (now_seg == data_section)
04134     {
04135       if (lowest_data_loc != (bfd_vma) -1
04136          && (lowest_data_loc & (nbytes - 1)) != 0)
04137        {
04138          if (data_has_contents)
04139            as_bad (_("data item with alignment larger than location"));
04140          else if (want_unaligned)
04141            as_bad (_("unaligned data at an absolute location is not supported"));
04142 
04143          lowest_data_loc &= ~((bfd_vma) nbytes - 1);
04144          lowest_data_loc += (bfd_vma) nbytes;
04145        }
04146 
04147       data_has_contents = 1;
04148     }
04149 
04150   /* Always align these unless asked not to (valid for the current pseudo).  */
04151   if (! want_unaligned)
04152     {
04153       last_alignment = nbytes == 2 ? 1 : (nbytes == 4 ? 2 : 3);
04154       frag_align (last_alignment, 0, 0);
04155       record_alignment (now_seg, last_alignment);
04156     }
04157 
04158   /* For mmixal compatibility, a label for an instruction (and emitting
04159      pseudo) refers to the _aligned_ address.  So we have to emit the
04160      label here.  */
04161   if (current_fb_label >= 0)
04162     colon (fb_label_name (current_fb_label, 1));
04163   else if (pending_label != NULL)
04164     {
04165       colon (pending_label);
04166       pending_label = NULL;
04167     }
04168 
04169   SKIP_WHITESPACE ();
04170 
04171   if (is_end_of_line[(unsigned int) *input_line_pointer])
04172     {
04173       /* Default to zero if the expression was absent.  */
04174 
04175       exp.X_op = O_constant;
04176       exp.X_add_number = 0;
04177       exp.X_unsigned = 0;
04178       exp.X_add_symbol = NULL;
04179       exp.X_op_symbol = NULL;
04180       emit_expr (&exp, (unsigned int) nbytes);
04181     }
04182   else
04183     do
04184       {
04185        unsigned int c;
04186 
04187        switch (*input_line_pointer)
04188          {
04189            /* We support strings here too; each character takes up nbytes
04190               bytes.  */
04191          case '\"':
04192            ++input_line_pointer;
04193            start = input_line_pointer;
04194            while (is_a_char (c = next_char_of_string ()))
04195              {
04196               exp.X_op = O_constant;
04197               exp.X_add_number = c;
04198               exp.X_unsigned = 1;
04199               emit_expr (&exp, (unsigned int) nbytes);
04200              }
04201 
04202            if (input_line_pointer[-1] != '\"')
04203              {
04204               /* We will only get here in rare cases involving #NO_APP,
04205                  where the unterminated string is not recognized by the
04206                  preformatting pass.  */
04207               as_bad (_("unterminated string"));
04208               mmix_discard_rest_of_line ();
04209               return;
04210              }
04211            break;
04212 
04213          default:
04214            {
04215              expression (&exp);
04216              emit_expr (&exp, (unsigned int) nbytes);
04217              SKIP_WHITESPACE ();
04218            }
04219            break;
04220          }
04221       }
04222     while (*input_line_pointer++ == ',');
04223 
04224   input_line_pointer--;            /* Put terminator back into stream.  */
04225 
04226   mmix_handle_rest_of_empty_line ();
04227 
04228   /* We don't need to step up the counter for the current_fb_label here;
04229      that's handled by the caller.  */
04230 }
04231 
04232 /* The md_do_align worker.  At present, we just record an alignment to
04233    nullify the automatic alignment we do for WYDE, TETRA and OCTA, as gcc
04234    does not use the unaligned macros when attribute packed is used.
04235    Arguably this is a GCC bug.  */
04236 
04237 void
04238 mmix_md_do_align (int n, char *fill ATTRIBUTE_UNUSED,
04239                 int len ATTRIBUTE_UNUSED, int max ATTRIBUTE_UNUSED)
04240 {
04241   last_alignment = n;
04242   want_unaligned = n == 0;
04243 }