/* tc-mmix.c -- Assembler for Don Knuth's MMIX.
   Copyright (C) 2001-2016 Free Software Foundation, Inc.

   This file is part of GAS, the GNU Assembler.

   GAS is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3, or (at your option)
   any later version.

   GAS is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with GAS; see the file COPYING.  If not, write to
   the Free Software Foundation, 51 Franklin Street - Fifth Floor,
   Boston, MA 02110-1301, USA.  */

/* Knuth's assembler mmixal does not provide a relocatable format; mmo is
   to be considered a final link-format.  In the final link, we make mmo,
   but for relocatable files, we use ELF.

   One goal is to provide a superset of what mmixal does, including
   compatible syntax, but the main purpose is to serve GCC.  */


#include "as.h"
#include <limits.h>
#include "subsegs.h"
#include "elf/mmix.h"
#include "opcode/mmix.h"
#include "safe-ctype.h"
#include "dwarf2dbg.h"
#include "obstack.h"

/* Something to describe what we need to do with a fixup before output,
   for example assert something of what it became or make a relocation.  */

enum mmix_fixup_action
{
  mmix_fixup_byte,
  mmix_fixup_register,
  mmix_fixup_register_or_adjust_for_byte
};

static int get_spec_regno (char *);
static int get_operands (int, char *, expressionS *);
static int get_putget_operands (struct mmix_opcode *, char *, expressionS *);
static void s_prefix (int);
static void s_greg (int);
static void s_loc (int);
static void s_bspec (int);
static void s_espec (int);
static void mmix_s_local (int);
static void mmix_greg_internal (char *);
static void mmix_set_geta_branch_offset (char *, offsetT);
static void mmix_set_jmp_offset (char *, offsetT);
static void mmix_fill_nops (char *, int);
static int cmp_greg_symbol_fixes (const void *, const void *);
static int cmp_greg_val_greg_symbol_fixes (const void *, const void *);
static void mmix_handle_rest_of_empty_line (void);
static void mmix_discard_rest_of_line (void);
static void mmix_byte (void);
static void mmix_cons (int);

/* Continue the tradition of symbols.c; use control characters to enforce
   magic.  These are used when replacing e.g. 8F and 8B so we can handle
   such labels correctly with the common parser hooks.  */
#define MAGIC_FB_BACKWARD_CHAR '\003'
#define MAGIC_FB_FORWARD_CHAR '\004'

/* Copy the location of a frag to a fix.  */
#define COPY_FR_WHERE_TO_FX(FRAG, FIX)		\
 do						\
   {						\
     (FIX)->fx_file = (FRAG)->fr_file;		\
     (FIX)->fx_line = (FRAG)->fr_line;		\
   }						\
 while (0)

const char *md_shortopts = "x";
static int current_fb_label = -1;
static char *pending_label = NULL;

static bfd_vma lowest_text_loc = (bfd_vma) -1;
static int text_has_contents = 0;

/* The alignment of the previous instruction, and a boolean for whether we
   want to avoid aligning the next WYDE, TETRA, OCTA or insn.  */
static int last_alignment = 0;
static int want_unaligned = 0;

static bfd_vma lowest_data_loc = (bfd_vma) -1;
static int data_has_contents = 0;

/* The fragS of the instruction being assembled.  Only valid from within
   md_assemble.  */
fragS *mmix_opcode_frag = NULL;

/* Raw GREGs as appearing in input.  These may be fewer than the number
   after relaxing.  */
static int n_of_raw_gregs = 0;
static struct
 {
   char *label;
   expressionS exp;
 } mmix_raw_gregs[MAX_GREGS];

static struct loc_assert_s
 {
   segT old_seg;
   symbolS *loc_sym;
   fragS *frag;
   struct loc_assert_s *next;
 } *loc_asserts = NULL;

/* Fixups for all unique GREG registers.  We store the fixups here in
   md_convert_frag, then we use the array to convert
   BFD_RELOC_MMIX_BASE_PLUS_OFFSET fixups in tc_gen_reloc.  The index is
   just a running number and is not supposed to be correlated to a
   register number.  */
static fixS *mmix_gregs[MAX_GREGS];
static int n_of_cooked_gregs = 0;

/* Pointing to the register section we use for output.  */
static asection *real_reg_section;

/* For each symbol; unknown or section symbol, we keep a list of GREG
   definitions sorted on increasing offset.  It seems no use keeping count
   to allocate less room than the maximum number of gregs when we've found
   one for a section or symbol.  */
struct mmix_symbol_gregs
 {
   int n_gregs;
   struct mmix_symbol_greg_fixes
   {
     fixS *fix;

     /* A signed type, since we may have GREGs pointing slightly before the
	contents of a section.  */
     offsetT offs;
   } greg_fixes[MAX_GREGS];
 };

/* Should read insert a colon on something that starts in column 0 on
   this line?  */
static int label_without_colon_this_line = 1;

/* Should we automatically expand instructions into multiple insns in
   order to generate working code?  */
static int expand_op = 1;

/* Should we warn when expanding operands?  FIXME: test-cases for when -x
   is absent.  */
static int warn_on_expansion = 1;

/* Should we merge non-zero GREG register definitions?  */
static int merge_gregs = 1;

/* Should we pass on undefined BFD_RELOC_MMIX_BASE_PLUS_OFFSET relocs
   (missing suitable GREG definitions) to the linker?  */
static int allocate_undefined_gregs_in_linker = 0;

/* Should we emit built-in symbols?  */
static int predefined_syms = 1;

/* Should we allow anything but the listed special register name
   (e.g. equated symbols)?  */
static int equated_spec_regs = 1;

/* Do we require standard GNU syntax?  */
int mmix_gnu_syntax = 0;

/* Do we globalize all symbols?  */
int mmix_globalize_symbols = 0;

/* When expanding insns, do we want to expand PUSHJ as a call to a stub
   (or else as a series of insns)?  */
int pushj_stubs = 1;

/* Do we know that the next semicolon is at the end of the operands field
   (in mmixal mode; constant 1 in GNU mode)?  */
int mmix_next_semicolon_is_eoln = 1;

/* Do we have a BSPEC in progress?  */
static int doing_bspec = 0;
static const char *bspec_file;
static unsigned int bspec_line;

struct option md_longopts[] =
 {
#define OPTION_RELAX  (OPTION_MD_BASE)
#define OPTION_NOEXPAND  (OPTION_RELAX + 1)
#define OPTION_NOMERGEGREG  (OPTION_NOEXPAND + 1)
#define OPTION_NOSYMS  (OPTION_NOMERGEGREG + 1)
#define OPTION_GNU_SYNTAX  (OPTION_NOSYMS + 1)
#define OPTION_GLOBALIZE_SYMBOLS  (OPTION_GNU_SYNTAX + 1)
#define OPTION_FIXED_SPEC_REGS  (OPTION_GLOBALIZE_SYMBOLS + 1)
#define OPTION_LINKER_ALLOCATED_GREGS  (OPTION_FIXED_SPEC_REGS + 1)
#define OPTION_NOPUSHJSTUBS  (OPTION_LINKER_ALLOCATED_GREGS + 1)
   {"linkrelax", no_argument, NULL, OPTION_RELAX},
   {"no-expand", no_argument, NULL, OPTION_NOEXPAND},
   {"no-merge-gregs", no_argument, NULL, OPTION_NOMERGEGREG},
   {"no-predefined-syms", no_argument, NULL, OPTION_NOSYMS},
   {"gnu-syntax", no_argument, NULL, OPTION_GNU_SYNTAX},
   {"globalize-symbols", no_argument, NULL, OPTION_GLOBALIZE_SYMBOLS},
   {"fixed-special-register-names", no_argument, NULL,
    OPTION_FIXED_SPEC_REGS},
   {"linker-allocated-gregs", no_argument, NULL,
    OPTION_LINKER_ALLOCATED_GREGS},
   {"no-pushj-stubs", no_argument, NULL, OPTION_NOPUSHJSTUBS},
   {"no-stubs", no_argument, NULL, OPTION_NOPUSHJSTUBS},
   {NULL, no_argument, NULL, 0}
 };

size_t md_longopts_size = sizeof (md_longopts);

static struct hash_control *mmix_opcode_hash;

/* We use these when implementing the PREFIX pseudo.  */
char *mmix_current_prefix;
struct obstack mmix_sym_obstack;


/* For MMIX, we encode the relax_substateT:s (in e.g. fr_substate) as one
   bit length, and the relax-type shifted on top of that.  There seems to
   be no point in making the relaxation more fine-grained; the linker does
   that better and we might interfere by changing non-optimal relaxations
   into other insns that cannot be relaxed as easily.

   Groups for MMIX relaxing:

   1. GETA
      extra length: zero or three insns.

   2. Bcc
      extra length: zero or five insns.

   3. PUSHJ
      extra length: zero or four insns.
      Special handling to deal with transition to PUSHJSTUB.

   4. JMP
      extra length: zero or four insns.

   5. GREG
      special handling, allocates a named global register unless another
      is within reach for all uses.

   6. PUSHJSTUB
      special handling (mostly) for external references; assumes the
      linker will generate a stub if target is no longer than 256k from
      the end of the section plus max size of previous stubs.  Zero or
      four insns.  */

#define STATE_GETA	(1)
#define STATE_BCC	(2)
#define STATE_PUSHJ	(3)
#define STATE_JMP	(4)
#define STATE_GREG	(5)
#define STATE_PUSHJSTUB	(6)

/* No fine-grainedness here.  */
#define STATE_LENGTH_MASK	    (1)

#define STATE_ZERO		    (0)
#define STATE_MAX		    (1)

/* More descriptive name for convenience.  */
/* FIXME: We should start on something different, not MAX.  */
#define STATE_UNDF		    STATE_MAX

/* FIXME: For GREG, we must have other definitions; UNDF == MAX isn't
   appropriate; we need it the other way round.  This value together with
   fragP->tc_frag_data shows what state the frag is in: tc_frag_data
   non-NULL means 0, NULL means 8 bytes.  */
#define STATE_GREG_UNDF ENCODE_RELAX (STATE_GREG, STATE_ZERO)
#define STATE_GREG_DEF ENCODE_RELAX (STATE_GREG, STATE_MAX)

/* These displacements are relative to the address following the opcode
   word of the instruction.  The catch-all states have zero for "reach"
   and "next" entries.  */

#define GETA_0F (65536 * 4 - 8)
#define GETA_0B (-65536 * 4 - 4)

#define GETA_MAX_LEN 4 * 4
#define GETA_3F 0
#define GETA_3B 0

#define BCC_0F GETA_0F
#define BCC_0B GETA_0B

#define BCC_MAX_LEN 6 * 4
#define BCC_5F GETA_3F
#define BCC_5B GETA_3B

#define PUSHJ_0F GETA_0F
#define PUSHJ_0B GETA_0B

#define PUSHJ_MAX_LEN 5 * 4
#define PUSHJ_4F GETA_3F
#define PUSHJ_4B GETA_3B

/* We'll very rarely have sections longer than LONG_MAX, but we'll make a
   feeble attempt at getting 64-bit values.  */
#define PUSHJSTUB_MAX ((offsetT) (((addressT) -1) >> 1))
#define PUSHJSTUB_MIN (-PUSHJSTUB_MAX - 1)

#define JMP_0F (65536 * 256 * 4 - 8)
#define JMP_0B (-65536 * 256 * 4 - 4)

#define JMP_MAX_LEN 5 * 4
#define JMP_4F 0
#define JMP_4B 0

#define RELAX_ENCODE_SHIFT 1
#define ENCODE_RELAX(what, length) (((what) << RELAX_ENCODE_SHIFT) + (length))

const relax_typeS mmix_relax_table[] =
 {
   /* Error sentinel (0, 0).  */
   {1,		1,		0,	0},

   /* Unused (0, 1).  */
   {1,		1,		0,	0},

   /* GETA (1, 0).  */
   {GETA_0F,	GETA_0B,	0,	ENCODE_RELAX (STATE_GETA, STATE_MAX)},

   /* GETA (1, 1).  */
   {GETA_3F,	GETA_3B,
		GETA_MAX_LEN - 4,	0},

   /* BCC (2, 0).  */
   {BCC_0F,	BCC_0B,		0,	ENCODE_RELAX (STATE_BCC, STATE_MAX)},

   /* BCC (2, 1).  */
   {BCC_5F,	BCC_5B,
		BCC_MAX_LEN - 4,	0},

   /* PUSHJ (3, 0).  Next state is actually PUSHJSTUB (6, 0).  */
   {PUSHJ_0F,	PUSHJ_0B,	0,	ENCODE_RELAX (STATE_PUSHJSTUB, STATE_ZERO)},

   /* PUSHJ (3, 1).  */
   {PUSHJ_4F,	PUSHJ_4B,
		PUSHJ_MAX_LEN - 4,	0},

   /* JMP (4, 0).  */
   {JMP_0F,	JMP_0B,		0,	ENCODE_RELAX (STATE_JMP, STATE_MAX)},

   /* JMP (4, 1).  */
   {JMP_4F,	JMP_4B,
		JMP_MAX_LEN - 4,	0},

   /* GREG (5, 0), (5, 1), though the table entry isn't used.  */
   {0, 0, 0, 0}, {0, 0, 0, 0},

   /* PUSHJSTUB (6, 0).  PUSHJ (3, 0) uses the range, so we set it to infinite.  */
   {PUSHJSTUB_MAX, PUSHJSTUB_MIN,
    		0,			ENCODE_RELAX (STATE_PUSHJ, STATE_MAX)},
   /* PUSHJSTUB (6, 1) isn't used.  */
   {0, 0,	PUSHJ_MAX_LEN, 		0}
};

const pseudo_typeS md_pseudo_table[] =
 {
   /* Support " .greg sym,expr" syntax.  */
   {"greg", s_greg, 0},

   /* Support " .bspec expr" syntax.  */
   {"bspec", s_bspec, 1},

   /* Support " .espec" syntax.  */
   {"espec", s_espec, 1},

   /* Support " .local $45" syntax.  */
   {"local", mmix_s_local, 1},

   {NULL, 0, 0}
 };

const char mmix_comment_chars[] = "%!";

/* A ':' is a valid symbol character in mmixal.  It's the prefix
   delimiter, but other than that, it works like a symbol character,
   except that we strip one off at the beginning of symbols.  An '@' is a
   symbol by itself (for the current location); space around it must not
   be stripped.  */
const char mmix_symbol_chars[] = ":@";

const char line_comment_chars[] = "*#";

const char line_separator_chars[] = ";";

const char EXP_CHARS[] = "eE";

const char FLT_CHARS[] = "rf";


/* Fill in the offset-related part of GETA or Bcc.  */

static void
mmix_set_geta_branch_offset (char *opcodep, offsetT value)
{
  if (value < 0)
    {
      value += 65536 * 4;
      opcodep[0] |= 1;
    }

  value /= 4;
  md_number_to_chars (opcodep + 2, value, 2);
}

/* Fill in the offset-related part of JMP.  */

static void
mmix_set_jmp_offset (char *opcodep, offsetT value)
{
  if (value < 0)
    {
      value += 65536 * 256 * 4;
      opcodep[0] |= 1;
    }

  value /= 4;
  md_number_to_chars (opcodep + 1, value, 3);
}

/* Fill in NOP:s for the expanded part of GETA/JMP/Bcc/PUSHJ.  */

static void
mmix_fill_nops (char *opcodep, int n)
{
  int i;

  for (i = 0; i < n; i++)
    md_number_to_chars (opcodep + i * 4, SWYM_INSN_BYTE << 24, 4);
}

/* See macro md_parse_name in tc-mmix.h.  */

int
mmix_current_location (void (*fn) (expressionS *), expressionS *exp)
{
  (*fn) (exp);

  return 1;
}

/* Get up to three operands, filling them into the exp array.
   General idea and code stolen from the tic80 port.  */

static int
get_operands (int max_operands, char *s, expressionS *exp)
{
  char *p = s;
  int numexp = 0;
  int nextchar = ',';

  while (nextchar == ',')
    {
      /* Skip leading whitespace */
      while (*p == ' ' || *p == '\t')
	p++;

      /* Check to see if we have any operands left to parse */
      if (*p == 0 || *p == '\n' || *p == '\r')
	{
	  break;
	}
      else if (numexp == max_operands)
	{
	  /* This seems more sane than saying "too many operands".  We'll
	     get here only if the trailing trash starts with a comma.  */
	  as_bad (_("invalid operands"));
	  mmix_discard_rest_of_line ();
	  return 0;
	}

      /* Begin operand parsing at the current scan point.  */

      input_line_pointer = p;
      expression (&exp[numexp]);

      if (exp[numexp].X_op == O_illegal)
	{
	  as_bad (_("invalid operands"));
	}
      else if (exp[numexp].X_op == O_absent)
	{
	  as_bad (_("missing operand"));
	}

      numexp++;
      p = input_line_pointer;

      /* Skip leading whitespace */
      while (*p == ' ' || *p == '\t')
	p++;
      nextchar = *p++;
    }

  /* If we allow "naked" comments, ignore the rest of the line.  */
  if (nextchar != ',')
    {
      mmix_handle_rest_of_empty_line ();
      input_line_pointer--;
    }

  /* Mark the end of the valid operands with an illegal expression.  */
  exp[numexp].X_op = O_illegal;

  return (numexp);
}

/* Get the value of a special register, or -1 if the name does not match
   one.  NAME is a null-terminated string.  */

static int
get_spec_regno (char *name)
{
  int i;

  if (name == NULL)
    return -1;

  if (*name == ':')
    name++;

  /* Well, it's a short array and we'll most often just match the first
     entry, rJ.  */
  for (i = 0; mmix_spec_regs[i].name != NULL; i++)
    if (strcmp (name, mmix_spec_regs[i].name) == 0)
      return mmix_spec_regs[i].number;

  return -1;
}

/* For GET and PUT, parse the register names "manually", so we don't use
   user labels.  */
static int
get_putget_operands (struct mmix_opcode *insn, char *operands,
		     expressionS *exp)
{
  expressionS *expp_reg;
  expressionS *expp_sreg;
  char *sregp = NULL;
  char *sregend = operands;
  char *p = operands;
  char c = *sregend;
  int regno;

  /* Skip leading whitespace */
  while (*p == ' ' || *p == '\t')
    p++;

  input_line_pointer = p;

  /* Initialize both possible operands to error state, in case we never
     get further.  */
  exp[0].X_op = O_illegal;
  exp[1].X_op = O_illegal;

  if (insn->operands == mmix_operands_get)
    {
      expp_reg = &exp[0];
      expp_sreg = &exp[1];

      expression (expp_reg);

      p = input_line_pointer;

      /* Skip whitespace */
      while (*p == ' ' || *p == '\t')
	p++;

      if (*p == ',')
	{
	  p++;

	  /* Skip whitespace */
	  while (*p == ' ' || *p == '\t')
	    p++;
	  sregp = p;
	  input_line_pointer = sregp;
	  c = get_symbol_name (&sregp);
	  sregend = input_line_pointer;
	  if (c == '"')
	    ++ input_line_pointer;
	}
    }
  else
    {
      expp_sreg = &exp[0];
      expp_reg = &exp[1];

      c = get_symbol_name (&sregp);
      sregend = input_line_pointer;
      restore_line_pointer (c);
      p = input_line_pointer;

      /* Skip whitespace */
      while (*p == ' ' || *p == '\t')
	p++;

      if (*p == ',')
	{
	  p++;

	  /* Skip whitespace */
	  while (*p == ' ' || *p == '\t')
	    p++;

	  input_line_pointer = p;
	  expression (expp_reg);
	}
      *sregend = 0;
    }

  regno = get_spec_regno (sregp);
  *sregend = c;

  /* Let the caller issue errors; we've made sure the operands are
     invalid.  */
  if (expp_reg->X_op != O_illegal
      && expp_reg->X_op != O_absent
      && regno != -1)
    {
      expp_sreg->X_op = O_register;
      expp_sreg->X_add_number = regno + 256;
    }

  return 2;
}

/* Handle MMIX-specific option.  */

int
md_parse_option (int c, const char *arg ATTRIBUTE_UNUSED)
{
  switch (c)
    {
    case 'x':
      warn_on_expansion = 0;
      allocate_undefined_gregs_in_linker = 1;
      break;

    case OPTION_RELAX:
      linkrelax = 1;
      break;

    case OPTION_NOEXPAND:
      expand_op = 0;
      break;

    case OPTION_NOMERGEGREG:
      merge_gregs = 0;
      break;

    case OPTION_NOSYMS:
      predefined_syms = 0;
      equated_spec_regs = 0;
      break;

    case OPTION_GNU_SYNTAX:
      mmix_gnu_syntax = 1;
      label_without_colon_this_line = 0;
      break;

    case OPTION_GLOBALIZE_SYMBOLS:
      mmix_globalize_symbols = 1;
      break;

    case OPTION_FIXED_SPEC_REGS:
      equated_spec_regs = 0;
      break;

    case OPTION_LINKER_ALLOCATED_GREGS:
      allocate_undefined_gregs_in_linker = 1;
      break;

    case OPTION_NOPUSHJSTUBS:
      pushj_stubs = 0;
      break;

    default:
      return 0;
    }

  return 1;
}

/* Display MMIX-specific help text.  */

void
md_show_usage (FILE * stream)
{
  fprintf (stream, _(" MMIX-specific command line options:\n"));
  fprintf (stream, _("\
  -fixed-special-register-names\n\
                          Allow only the original special register names.\n"));
  fprintf (stream, _("\
  -globalize-symbols      Make all symbols global.\n"));
  fprintf (stream, _("\
  -gnu-syntax             Turn off mmixal syntax compatibility.\n"));
  fprintf (stream, _("\
  -relax                  Create linker relaxable code.\n"));
  fprintf (stream, _("\
  -no-predefined-syms     Do not provide mmixal built-in constants.\n\
                          Implies -fixed-special-register-names.\n"));
  fprintf (stream, _("\
  -no-expand              Do not expand GETA, branches, PUSHJ or JUMP\n\
                          into multiple instructions.\n"));
  fprintf (stream, _("\
  -no-merge-gregs         Do not merge GREG definitions with nearby values.\n"));
  fprintf (stream, _("\
  -linker-allocated-gregs If there's no suitable GREG definition for the\
                          operands of an instruction, let the linker resolve.\n"));
  fprintf (stream, _("\
  -x                      Do not warn when an operand to GETA, a branch,\n\
                          PUSHJ or JUMP is not known to be within range.\n\
                          The linker will catch any errors.  Implies\n\
                          -linker-allocated-gregs."));
}

/* Step to end of line, but don't step over the end of the line.  */

static void
mmix_discard_rest_of_line (void)
{
  while (*input_line_pointer
	 && (! is_end_of_line[(unsigned char) *input_line_pointer]
	     || TC_EOL_IN_INSN (input_line_pointer)))
    input_line_pointer++;
}

/* Act as demand_empty_rest_of_line if we're in strict GNU syntax mode,
   otherwise just ignore the rest of the line (and skip the end-of-line
   delimiter).  */

static void
mmix_handle_rest_of_empty_line (void)
{
  if (mmix_gnu_syntax)
    demand_empty_rest_of_line ();
  else
    {
      mmix_discard_rest_of_line ();
      input_line_pointer++;
    }
}

/* Initialize GAS MMIX specifics.  */

void
mmix_md_begin (void)
{
  int i;
  const struct mmix_opcode *opcode;

  /* We assume nobody will use this, so don't allocate any room.  */
  obstack_begin (&mmix_sym_obstack, 0);

  /* This will break the day the "lex" thingy changes.  For now, it's the
     only way to make ':' part of a name, and a name beginner.  */
  lex_type[':'] = (LEX_NAME | LEX_BEGIN_NAME);

  mmix_opcode_hash = hash_new ();

  real_reg_section
    = bfd_make_section_old_way (stdoutput, MMIX_REG_SECTION_NAME);

  for (opcode = mmix_opcodes; opcode->name; opcode++)
    hash_insert (mmix_opcode_hash, opcode->name, (char *) opcode);

  /* We always insert the ordinary registers 0..255 as registers.  */
  for (i = 0; i < 256; i++)
    {
      char buf[5];

      /* Alternatively, we could diddle with '$' and the following number,
	 but keeping the registers as symbols helps keep parsing simple.  */
      sprintf (buf, "$%d", i);
      symbol_table_insert (symbol_new (buf, reg_section, i,
				       &zero_address_frag));
    }

  /* Insert mmixal built-in names if allowed.  */
  if (predefined_syms)
    {
      for (i = 0; mmix_spec_regs[i].name != NULL; i++)
	symbol_table_insert (symbol_new (mmix_spec_regs[i].name,
					 reg_section,
					 mmix_spec_regs[i].number + 256,
					 &zero_address_frag));

      /* FIXME: Perhaps these should be recognized as specials; as field
	 names for those instructions.  */
      symbol_table_insert (symbol_new ("ROUND_CURRENT", reg_section, 512,
				       &zero_address_frag));
      symbol_table_insert (symbol_new ("ROUND_OFF", reg_section, 512 + 1,
				       &zero_address_frag));
      symbol_table_insert (symbol_new ("ROUND_UP", reg_section, 512 + 2,
				       &zero_address_frag));
      symbol_table_insert (symbol_new ("ROUND_DOWN", reg_section, 512 + 3,
				       &zero_address_frag));
      symbol_table_insert (symbol_new ("ROUND_NEAR", reg_section, 512 + 4,
				       &zero_address_frag));
    }
}

/* Assemble one insn in STR.  */

void
md_assemble (char *str)
{
  char *operands = str;
  char modified_char = 0;
  struct mmix_opcode *instruction;
  fragS *opc_fragP = NULL;
  int max_operands = 3;

  /* Note that the struct frag member fr_literal in frags.h is char[], so
     I have to make this a plain char *.  */
  /* unsigned */ char *opcodep = NULL;

  expressionS exp[4];
  int n_operands = 0;

  /* Move to end of opcode.  */
  for (operands = str;
       is_part_of_name (*operands);
       ++operands)
    ;

  if (ISSPACE (*operands))
    {
      modified_char = *operands;
      *operands++ = '\0';
    }

  instruction = (struct mmix_opcode *) hash_find (mmix_opcode_hash, str);
  if (instruction == NULL)
    {
      as_bad (_("unknown opcode: `%s'"), str);

      /* Avoid "unhandled label" errors.  */
      pending_label = NULL;
      return;
    }

  /* Put back the character after the opcode.  */
  if (modified_char != 0)
    operands[-1] = modified_char;

  input_line_pointer = operands;

  /* Is this a mmixal pseudodirective?  */
  if (instruction->type == mmix_type_pseudo)
    {
      /* For mmixal compatibility, a label for an instruction (and
	 emitting pseudo) refers to the _aligned_ address.  We emit the
	 label here for the pseudos that don't handle it themselves.  When
	 having an fb-label, emit it here, and increment the counter after
	 the pseudo.  */
      switch (instruction->operands)
	{
	case mmix_operands_loc:
	case mmix_operands_byte:
	case mmix_operands_prefix:
	case mmix_operands_local:
	case mmix_operands_bspec:
	case mmix_operands_espec:
	  if (current_fb_label >= 0)
	    colon (fb_label_name (current_fb_label, 1));
	  else if (pending_label != NULL)
	    {
	      colon (pending_label);
	      pending_label = NULL;
	    }
	  break;

	default:
	  break;
	}

      /* Some of the pseudos emit contents, others don't.  Set a
	 contents-emitted flag when we emit something into .text   */
      switch (instruction->operands)
	{
	case mmix_operands_loc:
	  /* LOC */
	  s_loc (0);
	  break;

	case mmix_operands_byte:
	  /* BYTE */
	  mmix_byte ();
	  break;

	case mmix_operands_wyde:
	  /* WYDE */
	  mmix_cons (2);
	  break;

	case mmix_operands_tetra:
	  /* TETRA */
	  mmix_cons (4);
	  break;

	case mmix_operands_octa:
	  /* OCTA */
	  mmix_cons (8);
	  break;

	case mmix_operands_prefix:
	  /* PREFIX */
	  s_prefix (0);
	  break;

	case mmix_operands_local:
	  /* LOCAL */
	  mmix_s_local (0);
	  break;

	case mmix_operands_bspec:
	  /* BSPEC */
	  s_bspec (0);
	  break;

	case mmix_operands_espec:
	  /* ESPEC */
	  s_espec (0);
	  break;

	default:
	  BAD_CASE (instruction->operands);
	}

      /* These are all working like the pseudo functions in read.c:s_...,
	 in that they step over the end-of-line marker at the end of the
	 line.  We don't want that here.  */
      input_line_pointer--;

      /* Step up the fb-label counter if there was a definition on this
	 line.  */
      if (current_fb_label >= 0)
	{
	  fb_label_instance_inc (current_fb_label);
	  current_fb_label = -1;
	}

      /* Reset any don't-align-next-datum request, unless this was a LOC
         directive.  */
      if (instruction->operands != mmix_operands_loc)
	want_unaligned = 0;

      return;
    }

  /* Not a pseudo; we *will* emit contents.  */
  if (now_seg == data_section)
    {
      if (lowest_data_loc != (bfd_vma) -1 && (lowest_data_loc & 3) != 0)
	{
	  if (data_has_contents)
	    as_bad (_("specified location wasn't TETRA-aligned"));
	  else if (want_unaligned)
	    as_bad (_("unaligned data at an absolute location is not supported"));

	  lowest_data_loc &= ~(bfd_vma) 3;
	  lowest_data_loc += 4;
	}

      data_has_contents = 1;
    }
  else if (now_seg == text_section)
    {
      if (lowest_text_loc != (bfd_vma) -1 && (lowest_text_loc & 3) != 0)
	{
	  if (text_has_contents)
	    as_bad (_("specified location wasn't TETRA-aligned"));
	  else if (want_unaligned)
	    as_bad (_("unaligned data at an absolute location is not supported"));

	  lowest_text_loc &= ~(bfd_vma) 3;
	  lowest_text_loc += 4;
	}

      text_has_contents = 1;
    }

  /* After a sequence of BYTEs or WYDEs, we need to get to instruction
     alignment.  For other pseudos, a ".p2align 2" is supposed to be
     inserted by the user.  */
  if (last_alignment < 2 && ! want_unaligned)
    {
      frag_align (2, 0, 0);
      record_alignment (now_seg, 2);
      last_alignment = 2;
    }
  else
    /* Reset any don't-align-next-datum request.  */
    want_unaligned = 0;

  /* For mmixal compatibility, a label for an instruction (and emitting
     pseudo) refers to the _aligned_ address.  So we have to emit the
     label here.  */
  if (pending_label != NULL)
    {
      colon (pending_label);
      pending_label = NULL;
    }

  /* We assume that mmix_opcodes keeps having unique mnemonics for each
     opcode, so we don't have to iterate over more than one opcode; if the
     syntax does not match, then there's a syntax error.  */

  /* Operands have little or no context and are all comma-separated; it is
     easier to parse each expression first.   */
  switch (instruction->operands)
    {
    case mmix_operands_reg_yz:
    case mmix_operands_pop:
    case mmix_operands_regaddr:
    case mmix_operands_pushj:
    case mmix_operands_get:
    case mmix_operands_put:
    case mmix_operands_set:
    case mmix_operands_save:
    case mmix_operands_unsave:
      max_operands = 2;
      break;

    case mmix_operands_sync:
    case mmix_operands_jmp:
    case mmix_operands_resume:
      max_operands = 1;
      break;

      /* The original 3 is fine for the rest.  */
    default:
      break;
    }

  /* If this is GET or PUT, and we don't do allow those names to be
     equated, we need to parse the names ourselves, so we don't pick up a
     user label instead of the special register.  */
  if (! equated_spec_regs
      && (instruction->operands == mmix_operands_get
	  || instruction->operands == mmix_operands_put))
    n_operands = get_putget_operands (instruction, operands, exp);
  else
    n_operands = get_operands (max_operands, operands, exp);

  /* If there's a fb-label on the current line, set that label.  This must
     be done *after* evaluating expressions of operands, since neither a
     "1B" nor a "1F" refers to "1H" on the same line.  */
  if (current_fb_label >= 0)
    {
      fb_label_instance_inc (current_fb_label);
      colon (fb_label_name (current_fb_label, 0));
      current_fb_label = -1;
    }

  /* We also assume that the length of the instruction is at least 4, the
     size of an unexpanded instruction.  We need a self-contained frag
     since we want the relocation to point to the instruction, not the
     variant part.  */

  opcodep = frag_more (4);
  mmix_opcode_frag = opc_fragP = frag_now;
  frag_now->fr_opcode = opcodep;

  /* Mark start of insn for DWARF2 debug features.  */
  if (OUTPUT_FLAVOR == bfd_target_elf_flavour)
    dwarf2_emit_insn (4);

  md_number_to_chars (opcodep, instruction->match, 4);

  switch (instruction->operands)
    {
    case mmix_operands_jmp:
      if (n_operands == 0 && ! mmix_gnu_syntax)
	/* Zeros are in place - nothing needs to be done when we have no
	   operands.  */
	break;

      /* Add a frag for a JMP relaxation; we need room for max four
	 extra instructions.  We don't do any work around here to check if
	 we can determine the offset right away.  */
      if (n_operands != 1 || exp[0].X_op == O_register)
	{
	  as_bad (_("invalid operand to opcode %s: `%s'"),
		  instruction->name, operands);
	  return;
	}

      if (expand_op)
	frag_var (rs_machine_dependent, 4 * 4, 0,
		  ENCODE_RELAX (STATE_JMP, STATE_UNDF),
		  exp[0].X_add_symbol,
		  exp[0].X_add_number,
		  opcodep);
      else
	fix_new_exp (opc_fragP, opcodep - opc_fragP->fr_literal, 4,
		     exp + 0, 1, BFD_RELOC_MMIX_ADDR27);
      break;

    case mmix_operands_pushj:
      /* We take care of PUSHJ in full here.  */
      if (n_operands != 2
	  || ((exp[0].X_op == O_constant || exp[0].X_op == O_register)
	      && (exp[0].X_add_number > 255 || exp[0].X_add_number < 0)))
	{
	  as_bad (_("invalid operands to opcode %s: `%s'"),
		  instruction->name, operands);
	  return;
	}

      if (exp[0].X_op == O_register || exp[0].X_op == O_constant)
	opcodep[1] = exp[0].X_add_number;
      else
	fix_new_exp (opc_fragP, opcodep - opc_fragP->fr_literal + 1,
		     1, exp + 0, 0, BFD_RELOC_MMIX_REG_OR_BYTE);

      if (expand_op)
	frag_var (rs_machine_dependent, PUSHJ_MAX_LEN - 4, 0,
		  ENCODE_RELAX (STATE_PUSHJ, STATE_UNDF),
		  exp[1].X_add_symbol,
		  exp[1].X_add_number,
		  opcodep);
      else
	fix_new_exp (opc_fragP, opcodep - opc_fragP->fr_literal, 4,
		     exp + 1, 1, BFD_RELOC_MMIX_ADDR19);
      break;

    case mmix_operands_regaddr:
      /* GETA/branch: Add a frag for relaxation.  We don't do any work
	 around here to check if we can determine the offset right away.  */
      if (n_operands != 2 || exp[1].X_op == O_register)
	{
	  as_bad (_("invalid operands to opcode %s: `%s'"),
		  instruction->name, operands);
	  return;
	}

      if (! expand_op)
	fix_new_exp (opc_fragP, opcodep - opc_fragP->fr_literal, 4,
		     exp + 1, 1, BFD_RELOC_MMIX_ADDR19);
      else if (instruction->type == mmix_type_condbranch)
	frag_var (rs_machine_dependent, BCC_MAX_LEN - 4, 0,
		  ENCODE_RELAX (STATE_BCC, STATE_UNDF),
		  exp[1].X_add_symbol,
		  exp[1].X_add_number,
		  opcodep);
      else
	frag_var (rs_machine_dependent, GETA_MAX_LEN - 4, 0,
		  ENCODE_RELAX (STATE_GETA, STATE_UNDF),
		  exp[1].X_add_symbol,
		  exp[1].X_add_number,
		  opcodep);
      break;

    default:
      break;
    }

  switch (instruction->operands)
    {
    case mmix_operands_regs:
      /* We check the number of operands here, since we're in a
	 FALLTHROUGH sequence in the next switch.  */
      if (n_operands != 3 || exp[2].X_op == O_constant)
	{
	  as_bad (_("invalid operands to opcode %s: `%s'"),
		  instruction->name, operands);
	  return;
	}
      /* FALLTHROUGH.  */
    case mmix_operands_regs_z:
      if (n_operands != 3)
	{
	  as_bad (_("invalid operands to opcode %s: `%s'"),
		  instruction->name, operands);
	  return;
	}
      /* FALLTHROUGH.  */
    case mmix_operands_reg_yz:
    case mmix_operands_roundregs_z:
    case mmix_operands_roundregs:
    case mmix_operands_regs_z_opt:
    case mmix_operands_neg:
    case mmix_operands_regaddr:
    case mmix_operands_get:
    case mmix_operands_set:
    case mmix_operands_save:
      if (n_operands < 1
	  || (exp[0].X_op == O_register && exp[0].X_add_number > 255))
	{
	  as_bad (_("invalid operands to opcode %s: `%s'"),
		  instruction->name, operands);
	  return;
	}

      if (exp[0].X_op == O_register)
	opcodep[1] = exp[0].X_add_number;
      else
	fix_new_exp (opc_fragP, opcodep - opc_fragP->fr_literal + 1,
		     1, exp + 0, 0, BFD_RELOC_MMIX_REG);
      break;

    default:
      ;
    }

  /* A corresponding once-over for those who take an 8-bit constant as
     their first operand.  */
  switch (instruction->operands)
    {
    case mmix_operands_pushgo:
      /* PUSHGO: X is a constant, but can be expressed as a register.
	 We handle X here and use the common machinery of T,X,3,$ for
	 the rest of the operands.  */
      if (n_operands < 2
	  || ((exp[0].X_op == O_constant || exp[0].X_op == O_register)
	      && (exp[0].X_add_number > 255 || exp[0].X_add_number < 0)))
	{
	  as_bad (_("invalid operands to opcode %s: `%s'"),
		  instruction->name, operands);
	  return;
	}
      else if (exp[0].X_op == O_constant || exp[0].X_op == O_register)
	opcodep[1] = exp[0].X_add_number;
      else
	fix_new_exp (opc_fragP, opcodep - opc_fragP->fr_literal + 1,
		     1, exp + 0, 0, BFD_RELOC_MMIX_REG_OR_BYTE);
      break;

    case mmix_operands_pop:
      if ((n_operands == 0 || n_operands == 1) && ! mmix_gnu_syntax)
	break;
      /* FALLTHROUGH.  */
    case mmix_operands_x_regs_z:
      if (n_operands < 1
	  || (exp[0].X_op == O_constant
	      && (exp[0].X_add_number > 255
		  || exp[0].X_add_number < 0)))
	{
	  as_bad (_("invalid operands to opcode %s: `%s'"),
		  instruction->name, operands);
	  return;
	}

      if (exp[0].X_op == O_constant)
	opcodep[1] = exp[0].X_add_number;
      else
	/* FIXME: This doesn't bring us unsignedness checking.  */
	fix_new_exp (opc_fragP, opcodep - opc_fragP->fr_literal + 1,
		     1, exp + 0, 0, BFD_RELOC_8);
    default:
      ;
    }

  /* Handle the rest.  */
  switch (instruction->operands)
    {
    case mmix_operands_set:
      /* SET: Either two registers, "$X,$Y", with Z field as zero, or
	 "$X,YZ", meaning change the opcode to SETL.  */
      if (n_operands != 2
	  || (exp[1].X_op == O_constant
	      && (exp[1].X_add_number > 0xffff || exp[1].X_add_number < 0)))
	{
	  as_bad (_("invalid operands to opcode %s: `%s'"),
		  instruction->name, operands);
	  return;
	}

      if (exp[1].X_op == O_constant)
	{
	  /* There's an ambiguity with "SET $0,Y" when Y isn't defined
	     yet.  To keep things simple, we assume that Y is then a
	     register, and only change the opcode if Y is defined at this
	     point.

	     There's no compatibility problem with mmixal, since it emits
	     errors if the field is not defined at this point.  */
	  md_number_to_chars (opcodep, SETL_INSN_BYTE, 1);

	  opcodep[2] = (exp[1].X_add_number >> 8) & 255;
	  opcodep[3] = exp[1].X_add_number & 255;
	  break;
	}
      /* FALLTHROUGH.  */
    case mmix_operands_x_regs_z:
      /* SYNCD: "X,$Y,$Z|Z".  */
      /* FALLTHROUGH.  */
    case mmix_operands_regs:
      /* Three registers, $X,$Y,$Z.  */
      /* FALLTHROUGH.  */
    case mmix_operands_regs_z:
      /* Operands "$X,$Y,$Z|Z", number of arguments checked above.  */
      /* FALLTHROUGH.  */
    case mmix_operands_pushgo:
      /* Operands "$X|X,$Y,$Z|Z", optional Z.  */
      /* FALLTHROUGH.  */
    case mmix_operands_regs_z_opt:
      /* Operands "$X,$Y,$Z|Z", with $Z|Z being optional, default 0.  Any
	 operands not completely decided yet are postponed to later in
	 assembly (but not until link-time yet).  */

      if ((n_operands != 2 && n_operands != 3)
	  || (exp[1].X_op == O_register && exp[1].X_add_number > 255)
	  || (n_operands == 3
	      && ((exp[2].X_op == O_register
		   && exp[2].X_add_number > 255
		   && mmix_gnu_syntax)
		  || (exp[2].X_op == O_constant
		      && (exp[2].X_add_number > 255
			  || exp[2].X_add_number < 0)))))
	{
	  as_bad (_("invalid operands to opcode %s: `%s'"),
		  instruction->name, operands);
	  return;
	}

      if (n_operands == 2)
	{
	  symbolS *sym;

	  /* The last operand is immediate whenever we see just two
	     operands.  */
	  opcodep[0] |= IMM_OFFSET_BIT;

	  /* Now, we could either have an implied "0" as the Z operand, or
	     it could be the constant of a "base address plus offset".  It
	     depends on whether it is allowed; only memory operations, as
	     signified by instruction->type and "T" and "X" operand types,
	     and it depends on whether we find a register in the second
	     operand, exp[1].  */
	  if (exp[1].X_op == O_register && exp[1].X_add_number <= 255)
	    {
	      /* A zero then; all done.  */
	      opcodep[2] = exp[1].X_add_number;
	      break;
	    }

	  /* Not known as a register.  Is base address plus offset
	     allowed, or can we assume that it is a register anyway?  */
	  if ((instruction->operands != mmix_operands_regs_z_opt
	       && instruction->operands != mmix_operands_x_regs_z
	       && instruction->operands != mmix_operands_pushgo)
	      || (instruction->type != mmix_type_memaccess_octa
		  && instruction->type != mmix_type_memaccess_tetra
		  && instruction->type != mmix_type_memaccess_wyde
		  && instruction->type != mmix_type_memaccess_byte
		  && instruction->type != mmix_type_memaccess_block
		  && instruction->type != mmix_type_jsr
		  && instruction->type != mmix_type_branch))
	    {
	      fix_new_exp (opc_fragP, opcodep - opc_fragP->fr_literal + 2,
			   1, exp + 1, 0, BFD_RELOC_MMIX_REG);
	      break;
	    }

	  /* To avoid getting a NULL add_symbol for constants and then
	     catching a SEGV in write_relocs since it doesn't handle
	     constants well for relocs other than PC-relative, we need to
	     pass expressions as symbols and use fix_new, not fix_new_exp.  */
	  sym = make_expr_symbol (exp + 1);

	  /* Mark the symbol as being OK for a reloc.  */
	  symbol_get_bfdsym (sym)->flags |= BSF_KEEP;

	  /* Now we know it can be a "base address plus offset".  Add
	     proper fixup types so we can handle this later, when we've
	     parsed everything.  */
	  fix_new (opc_fragP, opcodep - opc_fragP->fr_literal + 2,
		   8, sym, 0, 0, BFD_RELOC_MMIX_BASE_PLUS_OFFSET);
	  break;
	}

      if (exp[1].X_op == O_register)
	opcodep[2] = exp[1].X_add_number;
      else
	fix_new_exp (opc_fragP, opcodep - opc_fragP->fr_literal + 2,
		     1, exp + 1, 0, BFD_RELOC_MMIX_REG);

      /* In mmixal compatibility mode, we allow special registers as
	 constants for the Z operand.  They have 256 added to their
	 register numbers, so the right thing will happen if we just treat
	 those as constants.  */
      if (exp[2].X_op == O_register && exp[2].X_add_number <= 255)
	opcodep[3] = exp[2].X_add_number;
      else if (exp[2].X_op == O_constant
	       || (exp[2].X_op == O_register && exp[2].X_add_number > 255))
	{
	  opcodep[3] = exp[2].X_add_number;
	  opcodep[0] |= IMM_OFFSET_BIT;
	}
      else
	fix_new_exp (opc_fragP, opcodep - opc_fragP->fr_literal + 3,
		     1, exp + 2, 0,
		     (instruction->operands == mmix_operands_set
		      || instruction->operands == mmix_operands_regs)
		     ? BFD_RELOC_MMIX_REG : BFD_RELOC_MMIX_REG_OR_BYTE);
      break;

    case mmix_operands_pop:
      /* POP, one eight and one 16-bit operand.  */
      if (n_operands == 0 && ! mmix_gnu_syntax)
	break;
      if (n_operands == 1 && ! mmix_gnu_syntax)
	goto a_single_24_bit_number_operand;
      /* FALLTHROUGH.  */
    case mmix_operands_reg_yz:
      /* A register and a 16-bit unsigned number.  */
      if (n_operands != 2
	  || exp[1].X_op == O_register
	  || (exp[1].X_op == O_constant
	      && (exp[1].X_add_number > 0xffff || exp[1].X_add_number < 0)))
	{
	  as_bad (_("invalid operands to opcode %s: `%s'"),
		  instruction->name, operands);
	  return;
	}

      if (exp[1].X_op == O_constant)
	{
	  opcodep[2] = (exp[1].X_add_number >> 8) & 255;
	  opcodep[3] = exp[1].X_add_number & 255;
	}
      else
	/* FIXME: This doesn't bring us unsignedness checking.  */
	fix_new_exp (opc_fragP, opcodep - opc_fragP->fr_literal + 2,
		     2, exp + 1, 0, BFD_RELOC_16);
      break;

    case mmix_operands_jmp:
      /* A JMP.  Everything is already done.  */
      break;

    case mmix_operands_roundregs:
      /* Two registers with optional rounding mode or constant in between.  */
      if ((n_operands == 3 && exp[2].X_op == O_constant)
	  || (n_operands == 2 && exp[1].X_op == O_constant))
	{
	  as_bad (_("invalid operands to opcode %s: `%s'"),
		  instruction->name, operands);
	  return;
	}
      /* FALLTHROUGH.  */
    case mmix_operands_roundregs_z:
      /* Like FLOT, "$X,ROUND_MODE,$Z|Z", but the rounding mode is
	 optional and can be the corresponding constant.  */
      {
	/* Which exp index holds the second operand (not the rounding
	   mode).  */
	int op2no = n_operands - 1;

	if ((n_operands != 2 && n_operands != 3)
	    || ((exp[op2no].X_op == O_register
		 && exp[op2no].X_add_number > 255)
		|| (exp[op2no].X_op == O_constant
		    && (exp[op2no].X_add_number > 255
			|| exp[op2no].X_add_number < 0)))
	    || (n_operands == 3
		/* We don't allow for the rounding mode to be deferred; it
		   must be determined in the "first pass".  It cannot be a
		   symbol equated to a rounding mode, but defined after
		   the first use.  */
		&& ((exp[1].X_op == O_register
		     && exp[1].X_add_number < 512)
		    || (exp[1].X_op == O_constant
			&& (exp[1].X_add_number < 0
			    || exp[1].X_add_number > 4))
		    || (exp[1].X_op != O_register
			&& exp[1].X_op != O_constant))))
	  {
	    as_bad (_("invalid operands to opcode %s: `%s'"),
		    instruction->name, operands);
	    return;
	  }

	/* Add rounding mode if present.  */
	if (n_operands == 3)
	  opcodep[2] = exp[1].X_add_number & 255;

	if (exp[op2no].X_op == O_register)
	  opcodep[3] = exp[op2no].X_add_number;
	else if (exp[op2no].X_op == O_constant)
	  {
	    opcodep[3] = exp[op2no].X_add_number;
	    opcodep[0] |= IMM_OFFSET_BIT;
	  }
	else
	  fix_new_exp (opc_fragP, opcodep - opc_fragP->fr_literal + 3,
		       1, exp + op2no, 0,
		       instruction->operands == mmix_operands_roundregs
		       ? BFD_RELOC_MMIX_REG
		       : BFD_RELOC_MMIX_REG_OR_BYTE);
	break;
      }

    case mmix_operands_sync:
    a_single_24_bit_number_operand:
      if (n_operands != 1
	  || exp[0].X_op == O_register
	  || (exp[0].X_op == O_constant
	      && (exp[0].X_add_number > 0xffffff || exp[0].X_add_number < 0)))
	{
	  as_bad (_("invalid operands to opcode %s: `%s'"),
		  instruction->name, operands);
	  return;
	}

      if (exp[0].X_op == O_constant)
	{
	  opcodep[1] = (exp[0].X_add_number >> 16) & 255;
	  opcodep[2] = (exp[0].X_add_number >> 8) & 255;
	  opcodep[3] = exp[0].X_add_number & 255;
	}
      else
	/* FIXME: This doesn't bring us unsignedness checking.  */
	fix_new_exp (opc_fragP, opcodep - opc_fragP->fr_literal + 1,
		     3, exp + 0, 0, BFD_RELOC_24);
      break;

    case mmix_operands_neg:
      /* Operands "$X,Y,$Z|Z"; NEG or NEGU.  Y is optional, 0 is default.  */

      if ((n_operands != 3 && n_operands != 2)
	  || (n_operands == 3 && exp[1].X_op == O_register)
	  || ((exp[1].X_op == O_constant || exp[1].X_op == O_register)
	      && (exp[1].X_add_number > 255 || exp[1].X_add_number < 0))
	  || (n_operands == 3
	      && ((exp[2].X_op == O_register && exp[2].X_add_number > 255)
		  || (exp[2].X_op == O_constant
		      && (exp[2].X_add_number > 255
			  || exp[2].X_add_number < 0)))))
	{
	  as_bad (_("invalid operands to opcode %s: `%s'"),
		  instruction->name, operands);
	  return;
	}

      if (n_operands == 2)
	{
	  if (exp[1].X_op == O_register)
	    opcodep[3] = exp[1].X_add_number;
	  else if (exp[1].X_op == O_constant)
	    {
	      opcodep[3] = exp[1].X_add_number;
	      opcodep[0] |= IMM_OFFSET_BIT;
	    }
	  else
	    fix_new_exp (opc_fragP, opcodep - opc_fragP->fr_literal + 3,
			 1, exp + 1, 0, BFD_RELOC_MMIX_REG_OR_BYTE);
	  break;
	}

      if (exp[1].X_op == O_constant)
	opcodep[2] = exp[1].X_add_number;
      else
	fix_new_exp (opc_fragP, opcodep - opc_fragP->fr_literal + 2,
		     1, exp + 1, 0, BFD_RELOC_8);

      if (exp[2].X_op == O_register)
	opcodep[3] = exp[2].X_add_number;
      else if (exp[2].X_op == O_constant)
	{
	  opcodep[3] = exp[2].X_add_number;
	  opcodep[0] |= IMM_OFFSET_BIT;
	}
      else
	fix_new_exp (opc_fragP, opcodep - opc_fragP->fr_literal + 3,
		     1, exp + 2, 0, BFD_RELOC_MMIX_REG_OR_BYTE);
      break;

    case mmix_operands_regaddr:
      /* A GETA/branch-type.  */
      break;

    case mmix_operands_get:
      /* "$X,spec_reg"; GET.
	 Like with rounding modes, we demand that the special register or
	 symbol is already defined when we get here at the point of use.  */
      if (n_operands != 2
	  || (exp[1].X_op == O_register
	      && (exp[1].X_add_number < 256 || exp[1].X_add_number >= 512))
	  || (exp[1].X_op == O_constant
	      && (exp[1].X_add_number < 0 || exp[1].X_add_number > 256))
	  || (exp[1].X_op != O_constant && exp[1].X_op != O_register))
	{
	  as_bad (_("invalid operands to opcode %s: `%s'"),
		  instruction->name, operands);
	  return;
	}

      opcodep[3] = exp[1].X_add_number - 256;
      break;

    case mmix_operands_put:
      /* "spec_reg,$Z|Z"; PUT.  */
      if (n_operands != 2
	  || (exp[0].X_op == O_register
	      && (exp[0].X_add_number < 256 || exp[0].X_add_number >= 512))
	  || (exp[0].X_op == O_constant
	      && (exp[0].X_add_number < 0 || exp[0].X_add_number > 256))
	  || (exp[0].X_op != O_constant && exp[0].X_op != O_register))
	{
	  as_bad (_("invalid operands to opcode %s: `%s'"),
		  instruction->name, operands);
	  return;
	}

      opcodep[1] = exp[0].X_add_number - 256;

      /* Note that the Y field is zero.  */

      if (exp[1].X_op == O_register)
	opcodep[3] = exp[1].X_add_number;
      else if (exp[1].X_op == O_constant)
	{
	  opcodep[3] = exp[1].X_add_number;
	  opcodep[0] |= IMM_OFFSET_BIT;
	}
      else
	fix_new_exp (opc_fragP, opcodep - opc_fragP->fr_literal + 3,
		     1, exp + 1, 0, BFD_RELOC_MMIX_REG_OR_BYTE);
      break;

    case mmix_operands_save:
      /* "$X,0"; SAVE.  */
      if (n_operands != 2
	  || exp[1].X_op != O_constant
	  || exp[1].X_add_number != 0)
	{
	  as_bad (_("invalid operands to opcode %s: `%s'"),
		  instruction->name, operands);
	  return;
	}
      break;

    case mmix_operands_unsave:
      if (n_operands < 2 && ! mmix_gnu_syntax)
	{
	  if (n_operands == 1)
	    {
	      if (exp[0].X_op == O_register)
		opcodep[3] = exp[0].X_add_number;
	      else
		fix_new_exp (opc_fragP, opcodep - opc_fragP->fr_literal + 3,
			     1, exp, 0, BFD_RELOC_MMIX_REG);
	    }
	  break;
	}

      /* "0,$Z"; UNSAVE.  */
      if (n_operands != 2
	  || exp[0].X_op != O_constant
	  || exp[0].X_add_number != 0
	  || exp[1].X_op == O_constant
	  || (exp[1].X_op == O_register
	      && exp[1].X_add_number > 255))
	{
	  as_bad (_("invalid operands to opcode %s: `%s'"),
		  instruction->name, operands);
	  return;
	}

      if (exp[1].X_op == O_register)
	opcodep[3] = exp[1].X_add_number;
      else
	fix_new_exp (opc_fragP, opcodep - opc_fragP->fr_literal + 3,
		     1, exp + 1, 0, BFD_RELOC_MMIX_REG);
      break;

    case mmix_operands_xyz_opt:
      /* SWYM, TRIP, TRAP: zero, one, two or three operands.  It's
	 unspecified whether operands are registers or constants, but
	 when we find register syntax, we require operands to be literal and
	 within 0..255.  */
      if (n_operands == 0 && ! mmix_gnu_syntax)
	/* Zeros are in place - nothing needs to be done for zero
	   operands.  We don't allow this in GNU syntax mode, because it
	   was believed that the risk of missing to supply an operand is
	   higher than the benefit of not having to specify a zero.  */
	;
      else if (n_operands == 1 && exp[0].X_op != O_register)
	{
	  if (exp[0].X_op == O_constant)
	    {
	      if (exp[0].X_add_number > 255*256*256
		  || exp[0].X_add_number < 0)
		{
		  as_bad (_("invalid operands to opcode %s: `%s'"),
			  instruction->name, operands);
		  return;
		}
	      else
		{
		  opcodep[1] = (exp[0].X_add_number >> 16) & 255;
		  opcodep[2] = (exp[0].X_add_number >> 8) & 255;
		  opcodep[3] = exp[0].X_add_number & 255;
		}
	    }
	  else
	    fix_new_exp (opc_fragP, opcodep - opc_fragP->fr_literal + 1,
			 3, exp, 0, BFD_RELOC_24);
	}
      else if (n_operands == 2
	       && exp[0].X_op != O_register
	       && exp[1].X_op != O_register)
	{
	  /* Two operands.  */

	  if (exp[0].X_op == O_constant)
	    {
	      if (exp[0].X_add_number > 255
		  || exp[0].X_add_number < 0)
		{
		  as_bad (_("invalid operands to opcode %s: `%s'"),
			  instruction->name, operands);
		  return;
		}
	      else
		opcodep[1] = exp[0].X_add_number & 255;
	    }
	  else
	    fix_new_exp (opc_fragP, opcodep - opc_fragP->fr_literal + 1,
			 1, exp, 0, BFD_RELOC_8);

	  if (exp[1].X_op == O_constant)
	    {
	      if (exp[1].X_add_number > 255*256
		  || exp[1].X_add_number < 0)
		{
		  as_bad (_("invalid operands to opcode %s: `%s'"),
			  instruction->name, operands);
		  return;
		}
	      else
		{
		  opcodep[2] = (exp[1].X_add_number >> 8) & 255;
		  opcodep[3] = exp[1].X_add_number & 255;
		}
	    }
	  else
	    fix_new_exp (opc_fragP, opcodep - opc_fragP->fr_literal + 2,
			 2, exp + 1, 0, BFD_RELOC_16);
	}
      else if (n_operands == 3
	       && exp[0].X_op != O_register
	       && exp[1].X_op != O_register
	       && exp[2].X_op != O_register)
	{
	  /* Three operands.  */

	  if (exp[0].X_op == O_constant)
	    {
	      if (exp[0].X_add_number > 255
		  || exp[0].X_add_number < 0)
		{
		  as_bad (_("invalid operands to opcode %s: `%s'"),
			  instruction->name, operands);
		  return;
		}
	      else
		opcodep[1] = exp[0].X_add_number & 255;
	    }
	  else
	    fix_new_exp (opc_fragP, opcodep - opc_fragP->fr_literal + 1,
			 1, exp, 0, BFD_RELOC_8);

	  if (exp[1].X_op == O_constant)
	    {
	      if (exp[1].X_add_number > 255
		  || exp[1].X_add_number < 0)
		{
		  as_bad (_("invalid operands to opcode %s: `%s'"),
			  instruction->name, operands);
		  return;
		}
	      else
		opcodep[2] = exp[1].X_add_number & 255;
	    }
	  else
	    fix_new_exp (opc_fragP, opcodep - opc_fragP->fr_literal + 2,
			 1, exp + 1, 0, BFD_RELOC_8);

	  if (exp[2].X_op == O_constant)
	    {
	      if (exp[2].X_add_number > 255
		  || exp[2].X_add_number < 0)
		{
		  as_bad (_("invalid operands to opcode %s: `%s'"),
			  instruction->name, operands);
		  return;
		}
	      else
		opcodep[3] = exp[2].X_add_number & 255;
	    }
	  else
	    fix_new_exp (opc_fragP, opcodep - opc_fragP->fr_literal + 3,
			 1, exp + 2, 0, BFD_RELOC_8);
	}
      else
	{
	  /* We can't get here for other cases.  */
	  gas_assert (n_operands <= 3);

	  /* The meaning of operands to TRIP and TRAP is not defined (and
	     SWYM operands aren't enforced in mmixal, so let's avoid
	     that).  We add combinations not handled above here as we find
	     them and as they're reported.  */
	  if (n_operands == 3)
	    {
	      /* Don't require non-register operands.  Always generate
		 fixups, so we don't have to copy lots of code and create
		 maintenance problems.  TRIP is supposed to be a rare
		 instruction, so the overhead should not matter.  We
		 aren't allowed to fix_new_exp for an expression which is
		 an O_register at this point, however.

		 Don't use BFD_RELOC_MMIX_REG_OR_BYTE as that modifies
		 the insn for a register in the Z field and we want
		 consistency.  */
	      if (exp[0].X_op == O_register)
		opcodep[1] = exp[0].X_add_number;
	      else
		fix_new_exp (opc_fragP, opcodep - opc_fragP->fr_literal + 1,
			     1, exp, 0, BFD_RELOC_8);
	      if (exp[1].X_op == O_register)
		opcodep[2] = exp[1].X_add_number;
	      else
		fix_new_exp (opc_fragP, opcodep - opc_fragP->fr_literal + 2,
			     1, exp + 1, 0, BFD_RELOC_8);
	      if (exp[2].X_op == O_register)
		opcodep[3] = exp[2].X_add_number;
	      else
		fix_new_exp (opc_fragP, opcodep - opc_fragP->fr_literal + 3,
			     1, exp + 2, 0, BFD_RELOC_8);
	    }
	  else if (n_operands == 2)
	    {
	      if (exp[0].X_op == O_register)
		opcodep[1] = exp[0].X_add_number;
	      else
		fix_new_exp (opc_fragP, opcodep - opc_fragP->fr_literal + 1,
			     1, exp, 0, BFD_RELOC_8);
	      if (exp[1].X_op == O_register)
		opcodep[3] = exp[1].X_add_number;
	      else
		fix_new_exp (opc_fragP, opcodep - opc_fragP->fr_literal + 2,
			     2, exp + 1, 0, BFD_RELOC_16);
	    }
	  else
	    {
	      /* We can't get here for other cases.  */
	      gas_assert (n_operands == 1 && exp[0].X_op == O_register);

	      opcodep[3] = exp[0].X_add_number;
	    }
	}
      break;

    case mmix_operands_resume:
      if (n_operands == 0 && ! mmix_gnu_syntax)
	break;

      if (n_operands != 1
	  || exp[0].X_op == O_register
	  || (exp[0].X_op == O_constant
	      && (exp[0].X_add_number < 0
		  || exp[0].X_add_number > 255)))
	{
	  as_bad (_("invalid operands to opcode %s: `%s'"),
		  instruction->name, operands);
	  return;
	}

      if (exp[0].X_op == O_constant)
	opcodep[3] = exp[0].X_add_number;
      else
	fix_new_exp (opc_fragP, opcodep - opc_fragP->fr_literal + 3,
		     1, exp + 0, 0, BFD_RELOC_8);
      break;

    case mmix_operands_pushj:
      /* All is done for PUSHJ already.  */
      break;

    default:
      BAD_CASE (instruction->operands);
    }
}

/* For the benefit of insns that start with a digit, we assemble by way of
   tc_unrecognized_line too, through this function.  */

int
mmix_assemble_return_nonzero (char *str)
{
  int last_error_count = had_errors ();
  char *s2 = str;
  char c;

  /* Normal instruction handling downcases, so we must too.  */
  while (ISALNUM (*s2))
    {
      if (ISUPPER ((unsigned char) *s2))
	*s2 = TOLOWER (*s2);
      s2++;
    }

  /* Cut the line for sake of the assembly.  */
  for (s2 = str; *s2 && *s2 != '\n'; s2++)
    ;

  c = *s2;
  *s2 = 0;
  md_assemble (str);
  *s2 = c;

  return had_errors () == last_error_count;
}

/* The PREFIX pseudo.  */

static void
s_prefix (int unused ATTRIBUTE_UNUSED)
{
  char *p;
  int c;

  SKIP_WHITESPACE ();

  c = get_symbol_name (&p);
  
  /* Reseting prefix?  */
  if (*p == ':' && p[1] == 0)
    mmix_current_prefix = NULL;
  else
    {
      /* Put this prefix on the mmix symbols obstack.  We could malloc and
	 free it separately, but then we'd have to worry about that.
	 People using up memory on prefixes have other problems.  */
      obstack_grow (&mmix_sym_obstack, p, strlen (p) + 1);
      p = obstack_finish (&mmix_sym_obstack);

      /* Accumulate prefixes, and strip a leading ':'.  */
      if (mmix_current_prefix != NULL || *p == ':')
	p = mmix_prefix_name (p);

      mmix_current_prefix = p;
    }

  (void) restore_line_pointer (c);

  mmix_handle_rest_of_empty_line ();
}

/* We implement prefixes by using the tc_canonicalize_symbol_name hook,
   and store each prefixed name on a (separate) obstack.  This means that
   the name is on the "notes" obstack in non-prefixed form and on the
   mmix_sym_obstack in prefixed form, but currently it is not worth
   rewriting the whole GAS symbol handling to improve "hooking" to avoid
   that.  (It might be worth a rewrite for other reasons, though).  */

char *
mmix_prefix_name (char *shortname)
{
  if (*shortname == ':')
    return shortname + 1;

  if (mmix_current_prefix == NULL)
    as_fatal (_("internal: mmix_prefix_name but empty prefix"));

  if (*shortname == '$')
    return shortname;

  obstack_grow (&mmix_sym_obstack, mmix_current_prefix,
		strlen (mmix_current_prefix));
  obstack_grow (&mmix_sym_obstack, shortname, strlen (shortname) + 1);
  return obstack_finish (&mmix_sym_obstack);
}

/* The GREG pseudo.  At LABEL, we have the name of a symbol that we
   want to make a register symbol, and which should be initialized with
   the value in the expression at INPUT_LINE_POINTER (defaulting to 0).
   Either and (perhaps less meaningful) both may be missing.  LABEL must
   be persistent, perhaps allocated on an obstack.  */

static void
mmix_greg_internal (char *label)
{
  expressionS *expP = &mmix_raw_gregs[n_of_raw_gregs].exp;
  segT section;

  /* Don't set the section to register contents section before the
     expression has been parsed; it may refer to the current position.  */
  section = expression (expP);

  /* FIXME: Check that no expression refers to the register contents
     section.  May need to be done in elf64-mmix.c.  */
  if (expP->X_op == O_absent)
    {
      /* Default to zero if the expression was absent.  */
      expP->X_op = O_constant;
      expP->X_add_number = 0;
      expP->X_unsigned = 0;
      expP->X_add_symbol = NULL;
      expP->X_op_symbol = NULL;
    }

  if (section == undefined_section)
    {
      /* This is an error or a LOC with an expression involving
	 forward references.  For the expression to be correctly
	 evaluated, we need to force a proper symbol; gas loses track
	 of the segment for "local symbols".  */
      if (expP->X_op == O_add)
	{
	  symbol_get_value_expression (expP->X_op_symbol);
	  symbol_get_value_expression (expP->X_add_symbol);
	}
      else
	{
	  gas_assert (expP->X_op == O_symbol);
	  symbol_get_value_expression (expP->X_add_symbol);
	}
    }

  /* We must handle prefixes here, as we save the labels and expressions
     to be output later.  */
  mmix_raw_gregs[n_of_raw_gregs].label
    = mmix_current_prefix == NULL ? label : mmix_prefix_name (label);

  if (n_of_raw_gregs == MAX_GREGS - 1)
    as_bad (_("too many GREG registers allocated (max %d)"), MAX_GREGS);
  else
    n_of_raw_gregs++;

  mmix_handle_rest_of_empty_line ();
}

/* The ".greg label,expr" worker.  */

static void
s_greg (int unused ATTRIBUTE_UNUSED)
{
  char *p;
  char c;

  /* This will skip over what can be a symbol and zero out the next
     character, which we assume is a ',' or other meaningful delimiter.
     What comes after that is the initializer expression for the
     register.  */
  c = get_symbol_name (&p);

  if (c == '"')
    c = * ++ input_line_pointer;

  if (! is_end_of_line[(unsigned char) c])
    input_line_pointer++;

  if (*p)
    {
      /* The label must be persistent; it's not used until after all input
	 has been seen.  */
      obstack_grow (&mmix_sym_obstack, p, strlen (p) + 1);
      mmix_greg_internal (obstack_finish (&mmix_sym_obstack));
    }
  else
    mmix_greg_internal (NULL);
}

/* The "BSPEC expr" worker.  */

static void
s_bspec (int unused ATTRIBUTE_UNUSED)
{
  asection *expsec;
  asection *sec;
  char secname[sizeof (MMIX_OTHER_SPEC_SECTION_PREFIX) + 20]
    = MMIX_OTHER_SPEC_SECTION_PREFIX;
  expressionS exp;
  int n;

  /* Get a constant expression which we can evaluate *now*.  Supporting
     more complex (though assembly-time computable) expressions is
     feasible but Too Much Work for something of unknown usefulness like
     BSPEC-ESPEC.  */
  expsec = expression (&exp);
  mmix_handle_rest_of_empty_line ();

  /* Check that we don't have another BSPEC in progress.  */
  if (doing_bspec)
    {
      as_bad (_("BSPEC already active.  Nesting is not supported."));
      return;
    }

  if (exp.X_op != O_constant
      || expsec != absolute_section
      || exp.X_add_number < 0
      || exp.X_add_number > 65535)
    {
      as_bad (_("invalid BSPEC expression"));
      exp.X_add_number = 0;
    }

  n = (int) exp.X_add_number;

  sprintf (secname + strlen (MMIX_OTHER_SPEC_SECTION_PREFIX), "%d", n);
  sec = bfd_get_section_by_name (stdoutput, secname);
  if (sec == NULL)
    {
      /* We need a non-volatile name as it will be stored in the section
         struct.  */
      char *newsecname = xstrdup (secname);
      sec = bfd_make_section (stdoutput, newsecname);

      if (sec == NULL)
	as_fatal (_("can't create section %s"), newsecname);

      if (!bfd_set_section_flags (stdoutput, sec,
				  bfd_get_section_flags (stdoutput, sec)
				  | SEC_READONLY))
	as_fatal (_("can't set section flags for section %s"), newsecname);
    }

  /* Tell ELF about the pending section change.  */
  obj_elf_section_change_hook ();
  subseg_set (sec, 0);

  /* Save position for missing ESPEC.  */
  bspec_file = as_where (&bspec_line);

  doing_bspec = 1;
}

/* The "ESPEC" worker.  */

static void
s_espec (int unused ATTRIBUTE_UNUSED)
{
  /* First, check that we *do* have a BSPEC in progress.  */
  if (! doing_bspec)
    {
      as_bad (_("ESPEC without preceding BSPEC"));
      return;
    }

  mmix_handle_rest_of_empty_line ();
  doing_bspec = 0;

  /* When we told ELF about the section change in s_bspec, it stored the
     previous section for us so we can get at it with the equivalent of a
     .previous pseudo.  */
  obj_elf_previous (0);
}

/* The " .local expr" and " local expr" worker.  We make a BFD_MMIX_LOCAL
   relocation against the current position against the expression.
   Implementing this by means of contents in a section lost.  */

static void
mmix_s_local (int unused ATTRIBUTE_UNUSED)
{
  expressionS exp;

  /* Don't set the section to register contents section before the
     expression has been parsed; it may refer to the current position in
     some contorted way.  */
  expression (&exp);

  if (exp.X_op == O_absent)
    {
      as_bad (_("missing local expression"));
      return;
    }
  else if (exp.X_op == O_register)
    {
      /* fix_new_exp doesn't like O_register.  Should be configurable.
	 We're fine with a constant here, though.  */
      exp.X_op = O_constant;
    }

  fix_new_exp (frag_now, 0, 0, &exp, 0, BFD_RELOC_MMIX_LOCAL);
  mmix_handle_rest_of_empty_line ();
}

/* Set fragP->fr_var to the initial guess of the size of a relaxable insn
   and return it.  Sizes of other instructions are not known.  This
   function may be called multiple times.  */

int
md_estimate_size_before_relax (fragS *fragP, segT segment)
{
  int length;

#define HANDLE_RELAXABLE(state)						\
 case ENCODE_RELAX (state, STATE_UNDF):					\
   if (fragP->fr_symbol != NULL						\
       && S_GET_SEGMENT (fragP->fr_symbol) == segment			\
       && !S_IS_WEAK (fragP->fr_symbol))				\
     {									\
       /* The symbol lies in the same segment - a relaxable case.  */	\
       fragP->fr_subtype						\
	 = ENCODE_RELAX (state, STATE_ZERO);				\
     }									\
   break;

  switch (fragP->fr_subtype)
    {
      HANDLE_RELAXABLE (STATE_GETA);
      HANDLE_RELAXABLE (STATE_BCC);
      HANDLE_RELAXABLE (STATE_JMP);

    case ENCODE_RELAX (STATE_PUSHJ, STATE_UNDF):
      if (fragP->fr_symbol != NULL
	  && S_GET_SEGMENT (fragP->fr_symbol) == segment
	  && !S_IS_WEAK (fragP->fr_symbol))
	/* The symbol lies in the same segment - a relaxable case.  */
	fragP->fr_subtype = ENCODE_RELAX (STATE_PUSHJ, STATE_ZERO);
      else if (pushj_stubs)
	/* If we're to generate stubs, assume we can reach a stub after
           the section.  */
	fragP->fr_subtype = ENCODE_RELAX (STATE_PUSHJSTUB, STATE_ZERO);
      /* FALLTHROUGH.  */
    case ENCODE_RELAX (STATE_PUSHJ, STATE_ZERO):
    case ENCODE_RELAX (STATE_PUSHJSTUB, STATE_ZERO):
      /* We need to distinguish different relaxation rounds.  */
      seg_info (segment)->tc_segment_info_data.last_stubfrag = fragP;
      break;

    case ENCODE_RELAX (STATE_GETA, STATE_ZERO):
    case ENCODE_RELAX (STATE_BCC, STATE_ZERO):
    case ENCODE_RELAX (STATE_JMP, STATE_ZERO):
      /* When relaxing a section for the second time, we don't need to do
	 anything except making sure that fr_var is set right.  */
      break;

    case STATE_GREG_DEF:
      length = fragP->tc_frag_data != NULL ? 0 : 8;
      fragP->fr_var = length;

      /* Don't consult the relax_table; it isn't valid for this
	 relaxation.  */
      return length;
      break;

    default:
      BAD_CASE (fragP->fr_subtype);
    }

  length = mmix_relax_table[fragP->fr_subtype].rlx_length;
  fragP->fr_var = length;

  return length;
}

/* Turn a string in input_line_pointer into a floating point constant of type
   type, and store the appropriate bytes in *litP.  The number of LITTLENUMS
   emitted is stored in *sizeP .  An error message is returned, or NULL on
   OK.  */

const char *
md_atof (int type, char *litP, int *sizeP)
{
  if (type == 'r')
    type = 'f';
  /* FIXME: Having 'f' in FLT_CHARS (and here) makes it
     problematic to also have a forward reference in an expression.
     The testsuite wants it, and it's customary.
     We'll deal with the real problems when they come; we share the
     problem with most other ports.  */
  return ieee_md_atof (type, litP, sizeP, TRUE);
}

/* Convert variable-sized frags into one or more fixups.  */

void
md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT sec ATTRIBUTE_UNUSED,
		 fragS *fragP)
{
  /* Pointer to first byte in variable-sized part of the frag.  */
  char *var_partp;

  /* Pointer to first opcode byte in frag.  */
  char *opcodep;

  /* Size in bytes of variable-sized part of frag.  */
  int var_part_size = 0;

  /* This is part of *fragP.  It contains all information about addresses
     and offsets to varying parts.  */
  symbolS *symbolP;
  unsigned long var_part_offset;

  /* This is the frag for the opcode.  It, rather than fragP, must be used
     when emitting a frag for the opcode.  */
  fragS *opc_fragP = fragP->tc_frag_data;
  fixS *tmpfixP;

  /* Where, in file space, does addr point?  */
  bfd_vma target_address;
  bfd_vma opcode_address;

  know (fragP->fr_type == rs_machine_dependent);

  var_part_offset = fragP->fr_fix;
  var_partp = fragP->fr_literal + var_part_offset;
  opcodep = fragP->fr_opcode;

  symbolP = fragP->fr_symbol;

  target_address
    = ((symbolP ? S_GET_VALUE (symbolP) : 0) + fragP->fr_offset);

  /* The opcode that would be extended is the last four "fixed" bytes.  */
  opcode_address = fragP->fr_address + fragP->fr_fix - 4;

  switch (fragP->fr_subtype)
    {
    case ENCODE_RELAX (STATE_PUSHJSTUB, STATE_ZERO):
      /* Setting the unknown bits to 0 seems the most appropriate.  */
      mmix_set_geta_branch_offset (opcodep, 0);
      tmpfixP = fix_new (opc_fragP, opcodep - opc_fragP->fr_literal, 8,
			 fragP->fr_symbol, fragP->fr_offset, 1,
			 BFD_RELOC_MMIX_PUSHJ_STUBBABLE);
      COPY_FR_WHERE_TO_FX (fragP, tmpfixP);
      var_part_size = 0;
      break;

    case ENCODE_RELAX (STATE_GETA, STATE_ZERO):
    case ENCODE_RELAX (STATE_BCC, STATE_ZERO):
    case ENCODE_RELAX (STATE_PUSHJ, STATE_ZERO):
      mmix_set_geta_branch_offset (opcodep, target_address - opcode_address);
      if (linkrelax)
	{
	  tmpfixP
	    = fix_new (opc_fragP, opcodep - opc_fragP->fr_literal, 4,
		       fragP->fr_symbol, fragP->fr_offset, 1,
		       BFD_RELOC_MMIX_ADDR19);
	  COPY_FR_WHERE_TO_FX (fragP, tmpfixP);
	}
      var_part_size = 0;
      break;

    case ENCODE_RELAX (STATE_JMP, STATE_ZERO):
      mmix_set_jmp_offset (opcodep, target_address - opcode_address);
      if (linkrelax)
	{
	  tmpfixP
	    = fix_new (opc_fragP, opcodep - opc_fragP->fr_literal, 4,
		       fragP->fr_symbol, fragP->fr_offset, 1,
		       BFD_RELOC_MMIX_ADDR27);
	  COPY_FR_WHERE_TO_FX (fragP, tmpfixP);
	}
      var_part_size = 0;
      break;

    case STATE_GREG_DEF:
      if (fragP->tc_frag_data == NULL)
	{
	  /* We must initialize data that's supposed to be "fixed up" to
	     avoid emitting garbage, because md_apply_fix won't do
	     anything for undefined symbols.  */
	  md_number_to_chars (var_partp, 0, 8);
	  tmpfixP
	    = fix_new (fragP, var_partp - fragP->fr_literal, 8,
		       fragP->fr_symbol, fragP->fr_offset, 0, BFD_RELOC_64);
	  COPY_FR_WHERE_TO_FX (fragP, tmpfixP);
	  mmix_gregs[n_of_cooked_gregs++] = tmpfixP;
	  var_part_size = 8;
	}
      else
	var_part_size = 0;
      break;

#define HANDLE_MAX_RELOC(state, reloc)					\
  case ENCODE_RELAX (state, STATE_MAX):					\
    var_part_size							\
      = mmix_relax_table[ENCODE_RELAX (state, STATE_MAX)].rlx_length;	\
    mmix_fill_nops (var_partp, var_part_size / 4);			\
    if (warn_on_expansion)						\
      as_warn_where (fragP->fr_file, fragP->fr_line,			\
		     _("operand out of range, instruction expanded"));	\
    tmpfixP = fix_new (fragP, var_partp - fragP->fr_literal - 4, 8,	\
		       fragP->fr_symbol, fragP->fr_offset, 1, reloc);	\
    COPY_FR_WHERE_TO_FX (fragP, tmpfixP);				\
    break

      HANDLE_MAX_RELOC (STATE_GETA, BFD_RELOC_MMIX_GETA);
      HANDLE_MAX_RELOC (STATE_BCC, BFD_RELOC_MMIX_CBRANCH);
      HANDLE_MAX_RELOC (STATE_PUSHJ, BFD_RELOC_MMIX_PUSHJ);
      HANDLE_MAX_RELOC (STATE_JMP, BFD_RELOC_MMIX_JMP);

    default:
      BAD_CASE (fragP->fr_subtype);
      break;
    }

  fragP->fr_fix += var_part_size;
  fragP->fr_var = 0;
}

/* Applies the desired value to the specified location.
   Also sets up addends for RELA type relocations.
   Stolen from tc-mcore.c.

   Note that this function isn't called when linkrelax != 0.  */

void
md_apply_fix (fixS *fixP, valueT *valP, segT segment)
{
  char *buf  = fixP->fx_where + fixP->fx_frag->fr_literal;
  /* Note: use offsetT because it is signed, valueT is unsigned.  */
  offsetT val  = (offsetT) * valP;
  segT symsec
    = (fixP->fx_addsy == NULL
       ? absolute_section : S_GET_SEGMENT (fixP->fx_addsy));

  /* If the fix is relative to a symbol which is not defined, or, (if
     pcrel), not in the same segment as the fix, we cannot resolve it
     here.  */
  if (fixP->fx_addsy != NULL
      && (! S_IS_DEFINED (fixP->fx_addsy)
	  || S_IS_WEAK (fixP->fx_addsy)
	  || (fixP->fx_pcrel && symsec != segment)
	  || (! fixP->fx_pcrel
	      && symsec != absolute_section
	      && ((fixP->fx_r_type != BFD_RELOC_MMIX_REG
		   && fixP->fx_r_type != BFD_RELOC_MMIX_REG_OR_BYTE)
		  || symsec != reg_section))))
    {
      fixP->fx_done = 0;
      return;
    }
  else if (fixP->fx_r_type == BFD_RELOC_MMIX_LOCAL
	   || fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
	   || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
    {
      /* These are never "fixed".  */
      fixP->fx_done = 0;
      return;
    }
  else
    /* We assume every other relocation is "fixed".  */
    fixP->fx_done = 1;

  switch (fixP->fx_r_type)
    {
    case BFD_RELOC_64:
    case BFD_RELOC_32:
    case BFD_RELOC_24:
    case BFD_RELOC_16:
    case BFD_RELOC_8:
    case BFD_RELOC_64_PCREL:
    case BFD_RELOC_32_PCREL:
    case BFD_RELOC_24_PCREL:
    case BFD_RELOC_16_PCREL:
    case BFD_RELOC_8_PCREL:
      md_number_to_chars (buf, val, fixP->fx_size);
      break;

    case BFD_RELOC_MMIX_ADDR19:
      if (expand_op)
	{
	  /* This shouldn't happen.  */
	  BAD_CASE (fixP->fx_r_type);
	  break;
	}
      /* FALLTHROUGH.  */
    case BFD_RELOC_MMIX_GETA:
    case BFD_RELOC_MMIX_CBRANCH:
    case BFD_RELOC_MMIX_PUSHJ:
    case BFD_RELOC_MMIX_PUSHJ_STUBBABLE:
      /* If this fixup is out of range, punt to the linker to emit an
	 error.  This should only happen with -no-expand.  */
      if (val < -(((offsetT) 1 << 19)/2)
	  || val >= ((offsetT) 1 << 19)/2 - 1
	  || (val & 3) != 0)
	{
	  if (warn_on_expansion)
	    as_warn_where (fixP->fx_file, fixP->fx_line,
			   _("operand out of range"));
	  fixP->fx_done = 0;
	  val = 0;
	}
      mmix_set_geta_branch_offset (buf, val);
      break;

    case BFD_RELOC_MMIX_ADDR27:
      if (expand_op)
	{
	  /* This shouldn't happen.  */
	  BAD_CASE (fixP->fx_r_type);
	  break;
	}
      /* FALLTHROUGH.  */
    case BFD_RELOC_MMIX_JMP:
      /* If this fixup is out of range, punt to the linker to emit an
	 error.  This should only happen with -no-expand.  */
      if (val < -(((offsetT) 1 << 27)/2)
	  || val >= ((offsetT) 1 << 27)/2 - 1
	  || (val & 3) != 0)
	{
	  if (warn_on_expansion)
	    as_warn_where (fixP->fx_file, fixP->fx_line,
			   _("operand out of range"));
	  fixP->fx_done = 0;
	  val = 0;
	}
      mmix_set_jmp_offset (buf, val);
      break;

    case BFD_RELOC_MMIX_REG_OR_BYTE:
      if (fixP->fx_addsy != NULL
	  && (S_GET_SEGMENT (fixP->fx_addsy) != reg_section
	      || S_GET_VALUE (fixP->fx_addsy) > 255)
	  && S_GET_SEGMENT (fixP->fx_addsy) != absolute_section)
	{
	  as_bad_where (fixP->fx_file, fixP->fx_line,
			_("invalid operands"));
	  /* We don't want this "symbol" appearing in output, because
	     that will fail.  */
	  fixP->fx_done = 1;
	}

      buf[0] = val;

      /* If this reloc is for a Z field, we need to adjust
	 the opcode if we got a constant here.
	 FIXME: Can we make this more robust?  */

      if ((fixP->fx_where & 3) == 3
	  && (fixP->fx_addsy == NULL
	      || S_GET_SEGMENT (fixP->fx_addsy) == absolute_section))
	buf[-3] |= IMM_OFFSET_BIT;
      break;

    case BFD_RELOC_MMIX_REG:
      if (fixP->fx_addsy == NULL
	  || S_GET_SEGMENT (fixP->fx_addsy) != reg_section
	  || S_GET_VALUE (fixP->fx_addsy) > 255)
	{
	  as_bad_where (fixP->fx_file, fixP->fx_line,
			_("invalid operands"));
	  fixP->fx_done = 1;
	}

      *buf = val;
      break;

    case BFD_RELOC_MMIX_BASE_PLUS_OFFSET:
      /* These are never "fixed".  */
      fixP->fx_done = 0;
      return;

    case BFD_RELOC_MMIX_PUSHJ_1:
    case BFD_RELOC_MMIX_PUSHJ_2:
    case BFD_RELOC_MMIX_PUSHJ_3:
    case BFD_RELOC_MMIX_CBRANCH_J:
    case BFD_RELOC_MMIX_CBRANCH_1:
    case BFD_RELOC_MMIX_CBRANCH_2:
    case BFD_RELOC_MMIX_CBRANCH_3:
    case BFD_RELOC_MMIX_GETA_1:
    case BFD_RELOC_MMIX_GETA_2:
    case BFD_RELOC_MMIX_GETA_3:
    case BFD_RELOC_MMIX_JMP_1:
    case BFD_RELOC_MMIX_JMP_2:
    case BFD_RELOC_MMIX_JMP_3:
    default:
      BAD_CASE (fixP->fx_r_type);
      break;
    }

  if (fixP->fx_done)
    /* Make sure that for completed fixups we have the value around for
       use by e.g. mmix_frob_file.  */
    fixP->fx_offset = val;
}

/* A bsearch function for looking up a value against offsets for GREG
   definitions.  */

static int
cmp_greg_val_greg_symbol_fixes (const void *p1, const void *p2)
{
  offsetT val1 = *(offsetT *) p1;
  offsetT val2 = ((struct mmix_symbol_greg_fixes *) p2)->offs;

  if (val1 >= val2 && val1 < val2 + 255)
    return 0;

  if (val1 > val2)
    return 1;

  return -1;
}

/* Generate a machine-dependent relocation.  */

arelent *
tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixP)
{
  bfd_signed_vma val
    = fixP->fx_offset
    + (fixP->fx_addsy != NULL
       && !S_IS_WEAK (fixP->fx_addsy)
       && !S_IS_COMMON (fixP->fx_addsy)
       ? S_GET_VALUE (fixP->fx_addsy) : 0);
  arelent *relP;
  bfd_reloc_code_real_type code = BFD_RELOC_NONE;
  char *buf  = fixP->fx_where + fixP->fx_frag->fr_literal;
  symbolS *addsy = fixP->fx_addsy;
  asection *addsec = addsy == NULL ? NULL : S_GET_SEGMENT (addsy);
  asymbol *baddsy = addsy != NULL ? symbol_get_bfdsym (addsy) : NULL;
  bfd_vma addend
    = val - (baddsy == NULL || S_IS_COMMON (addsy) || S_IS_WEAK (addsy)
	     ? 0 : bfd_asymbol_value (baddsy));

  /* A single " LOCAL expression" in the wrong section will not work when
     linking to MMO; relocations for zero-content sections are then
     ignored.  Normally, relocations would modify section contents, and
     you'd never think or be able to do something like that.  The
     relocation resulting from a LOCAL directive doesn't have an obvious
     and mandatory location.  I can't figure out a way to do this better
     than just helping the user around this limitation here; hopefully the
     code using the local expression is around.  Putting the LOCAL
     semantics in a relocation still seems right; a section didn't do.  */
  if (bfd_section_size (section->owner, section) == 0)
    as_bad_where
      (fixP->fx_file, fixP->fx_line,
       fixP->fx_r_type == BFD_RELOC_MMIX_LOCAL
       /* The BFD_RELOC_MMIX_LOCAL-specific message is supposed to be
	  user-friendly, though a little bit non-substantial.  */
       ? _("directive LOCAL must be placed in code or data")
       : _("internal confusion: relocation in a section without contents"));

  /* FIXME: Range tests for all these.  */
  switch (fixP->fx_r_type)
    {
    case BFD_RELOC_64:
    case BFD_RELOC_32:
    case BFD_RELOC_24:
    case BFD_RELOC_16:
    case BFD_RELOC_8:
      code = fixP->fx_r_type;

      if (addsy == NULL || bfd_is_abs_section (addsec))
	{
	  /* Resolve this reloc now, as md_apply_fix would have done (not
	     called if -linkrelax).  There is no point in keeping a reloc
	     to an absolute symbol.  No reloc that is subject to
	     relaxation must be to an absolute symbol; difference
	     involving symbols in a specific section must be signalled as
	     an error if the relaxing cannot be expressed; having a reloc
	     to the resolved (now absolute) value does not help.  */
	  md_number_to_chars (buf, val, fixP->fx_size);
	  return NULL;
	}
      break;

    case BFD_RELOC_64_PCREL:
    case BFD_RELOC_32_PCREL:
    case BFD_RELOC_24_PCREL:
    case BFD_RELOC_16_PCREL:
    case BFD_RELOC_8_PCREL:
    case BFD_RELOC_MMIX_LOCAL:
    case BFD_RELOC_VTABLE_INHERIT:
    case BFD_RELOC_VTABLE_ENTRY:
    case BFD_RELOC_MMIX_GETA:
    case BFD_RELOC_MMIX_GETA_1:
    case BFD_RELOC_MMIX_GETA_2:
    case BFD_RELOC_MMIX_GETA_3:
    case BFD_RELOC_MMIX_CBRANCH:
    case BFD_RELOC_MMIX_CBRANCH_J:
    case BFD_RELOC_MMIX_CBRANCH_1:
    case BFD_RELOC_MMIX_CBRANCH_2:
    case BFD_RELOC_MMIX_CBRANCH_3:
    case BFD_RELOC_MMIX_PUSHJ:
    case BFD_RELOC_MMIX_PUSHJ_1:
    case BFD_RELOC_MMIX_PUSHJ_2:
    case BFD_RELOC_MMIX_PUSHJ_3:
    case BFD_RELOC_MMIX_PUSHJ_STUBBABLE:
    case BFD_RELOC_MMIX_JMP:
    case BFD_RELOC_MMIX_JMP_1:
    case BFD_RELOC_MMIX_JMP_2:
    case BFD_RELOC_MMIX_JMP_3:
    case BFD_RELOC_MMIX_ADDR19:
    case BFD_RELOC_MMIX_ADDR27:
      code = fixP->fx_r_type;
      break;

    case BFD_RELOC_MMIX_REG_OR_BYTE:
      /* If we have this kind of relocation to an unknown symbol or to the
	 register contents section (that is, to a register), then we can't
	 resolve the relocation here.  */
      if (addsy != NULL
	  && (bfd_is_und_section (addsec)
	      || strcmp (bfd_get_section_name (addsec->owner, addsec),
			 MMIX_REG_CONTENTS_SECTION_NAME) == 0))
	{
	  code = fixP->fx_r_type;
	  break;
	}

      /* If the relocation is not to the register section or to the
	 absolute section (a numeric value), then we have an error.  */
      if (addsy != NULL
	  && (S_GET_SEGMENT (addsy) != real_reg_section
	      || val > 255
	      || val < 0)
	  && ! bfd_is_abs_section (addsec))
	goto badop;

      /* Set the "immediate" bit of the insn if this relocation is to Z
	 field when the value is a numeric value, i.e. not a register.  */
      if ((fixP->fx_where & 3) == 3
	  && (addsy == NULL || bfd_is_abs_section (addsec)))
	buf[-3] |= IMM_OFFSET_BIT;

      buf[0] = val;
      return NULL;

    case BFD_RELOC_MMIX_BASE_PLUS_OFFSET:
      if (addsy != NULL
	  && strcmp (bfd_get_section_name (addsec->owner, addsec),
		     MMIX_REG_CONTENTS_SECTION_NAME) == 0)
	{
	  /* This changed into a register; the relocation is for the
	     register-contents section.  The constant part remains zero.  */
	  code = BFD_RELOC_MMIX_REG;
	  break;
	}

      /* If we've found out that this was indeed a register, then replace
	 with the register number.  The constant part is already zero.

	 If we encounter any other defined symbol, then we must find a
	 suitable register and emit a reloc.  */
      if (addsy == NULL || addsec != real_reg_section)
	{
	  struct mmix_symbol_gregs *gregs;
	  struct mmix_symbol_greg_fixes *fix;

	  if (S_IS_DEFINED (addsy)
	      && !bfd_is_com_section (addsec)
	      && !S_IS_WEAK (addsy))
	    {
	      if (! symbol_section_p (addsy) && ! bfd_is_abs_section (addsec))
		as_fatal (_("internal: BFD_RELOC_MMIX_BASE_PLUS_OFFSET not resolved to section"));

	      /* If this is an absolute symbol sufficiently near
		 lowest_data_loc, then we canonicalize on the data
		 section.  Note that val is signed here; we may subtract
		 lowest_data_loc which is unsigned.  Careful with those
		 comparisons.  */
	      if (lowest_data_loc != (bfd_vma) -1
		  && (bfd_vma) val + 256 > lowest_data_loc
		  && bfd_is_abs_section (addsec))
		{
		  val -= (offsetT) lowest_data_loc;
		  addsy = section_symbol (data_section);
		}
	      /* Likewise text section.  */
	      else if (lowest_text_loc != (bfd_vma) -1
		       && (bfd_vma) val + 256 > lowest_text_loc
		       && bfd_is_abs_section (addsec))
		{
		  val -= (offsetT) lowest_text_loc;
		  addsy = section_symbol (text_section);
		}
	    }

	  gregs = *symbol_get_tc (addsy);

	  /* If that symbol does not have any associated GREG definitions,
	     we can't do anything.  */
	  if (gregs == NULL
	      || (fix = bsearch (&val, gregs->greg_fixes, gregs->n_gregs,
				 sizeof (gregs->greg_fixes[0]),
				 cmp_greg_val_greg_symbol_fixes)) == NULL
	      /* The register must not point *after* the address we want.  */
	      || fix->offs > val
	      /* Neither must the register point more than 255 bytes
		 before the address we want.  */
	      || fix->offs + 255 < val)
	    {
	      /* We can either let the linker allocate GREGs
		 automatically, or emit an error.  */
	      if (allocate_undefined_gregs_in_linker)
		{
		  /* The values in baddsy and addend are right.  */
		  code = fixP->fx_r_type;
		  break;
		}
	      else
		as_bad_where (fixP->fx_file, fixP->fx_line,
			      _("no suitable GREG definition for operands"));
	      return NULL;
	    }
	  else
	    {
	      /* Transform the base-plus-offset reloc for the actual area
		 to a reloc for the register with the address of the area.
		 Put addend for register in Z operand.  */
	      buf[1] = val - fix->offs;
	      code = BFD_RELOC_MMIX_REG;
	      baddsy
		= (bfd_get_section_by_name (stdoutput,
					    MMIX_REG_CONTENTS_SECTION_NAME)
		   ->symbol);

	      addend = fix->fix->fx_frag->fr_address + fix->fix->fx_where;
	    }
	}
      else if (S_GET_VALUE (addsy) > 255)
	as_bad_where (fixP->fx_file, fixP->fx_line,
		      _("invalid operands"));
      else
	{
	  *buf = val;
	  return NULL;
	}
      break;

    case BFD_RELOC_MMIX_REG:
      if (addsy != NULL
	  && (bfd_is_und_section (addsec)
	      || strcmp (bfd_get_section_name (addsec->owner, addsec),
			 MMIX_REG_CONTENTS_SECTION_NAME) == 0))
	{
	  code = fixP->fx_r_type;
	  break;
	}

      if (addsy != NULL
	  && (addsec != real_reg_section
	      || val > 255
	      || val < 0)
	  && ! bfd_is_und_section (addsec))
	/* Drop through to error message.  */
	;
      else
	{
	  buf[0] = val;
	  return NULL;
	}
      /* FALLTHROUGH.  */

      /* The others are supposed to be handled by md_apply_fix.
	 FIXME: ... which isn't called when -linkrelax.  Move over
	 md_apply_fix code here for everything reasonable.  */
    badop:
    default:
      as_bad_where
	(fixP->fx_file, fixP->fx_line,
	 _("operands were not reducible at assembly-time"));

      /* Unmark this symbol as used in a reloc, so we don't bump into a BFD
	 assert when trying to output reg_section.  FIXME: A gas bug.  */
      fixP->fx_addsy = NULL;
      return NULL;
    }

  relP = XNEW (arelent);
  gas_assert (relP != 0);
  relP->sym_ptr_ptr = XNEW (asymbol *);
  *relP->sym_ptr_ptr = baddsy;
  relP->address = fixP->fx_frag->fr_address + fixP->fx_where;

  relP->addend = addend;

  /* If this had been a.out, we would have had a kludge for weak symbols
     here.  */

  relP->howto = bfd_reloc_type_lookup (stdoutput, code);
  if (! relP->howto)
    {
      const char *name;

      name = S_GET_NAME (addsy);
      if (name == NULL)
	name = _("<unknown>");
      as_fatal (_("cannot generate relocation type for symbol %s, code %s"),
		name, bfd_get_reloc_code_name (code));
    }

  return relP;
}

/* Do some reformatting of a line.  FIXME: We could transform a mmixal
   line into traditional (GNU?) format, unless #NO_APP, and get rid of all
   ugly labels_without_colons etc.  */

void
mmix_handle_mmixal (void)
{
  char *insn;
  char *s = input_line_pointer;
  char *label = NULL;
  char c;

  if (pending_label != NULL)
    as_fatal (_("internal: unhandled label %s"), pending_label);

  if (mmix_gnu_syntax)
    return;

  /* If we're on a line with a label, check if it's a mmixal fb-label.
     Save an indicator and skip the label; it must be set only after all
     fb-labels of expressions are evaluated.  */
  if (ISDIGIT (s[0]) && s[1] == 'H' && ISSPACE (s[2]))
    {
      current_fb_label = s[0] - '0';

      /* We have to skip the label, but also preserve the newlineness of
	 the previous character, since the caller checks that.  It's a
	 mess we blame on the caller.  */
      s[1] = s[-1];
      s += 2;
      input_line_pointer = s;

      while (*s && ISSPACE (*s) && ! is_end_of_line[(unsigned int) *s])
	s++;

      /* For errors emitted here, the book-keeping is off by one; the
	 caller is about to bump the counters.  Adjust the error messages.  */
      if (is_end_of_line[(unsigned int) *s])
	{
	  unsigned int line;
	  const char * name = as_where (&line);
	  as_bad_where (name, line + 1,
			_("[0-9]H labels may not appear alone on a line"));
	  current_fb_label = -1;
	}
      if (*s == '.')
	{
	  unsigned int line;
	  const char * name  = as_where (&line);
	  as_bad_where (name, line + 1,
			_("[0-9]H labels do not mix with dot-pseudos"));
	  current_fb_label = -1;
	}

      /* Back off to the last space before the opcode so we don't handle
	 the opcode as a label.  */
      s--;
    }
  else
    current_fb_label = -1;

  if (*s == '.')
    {
      /* If the first character is a '.', then it's a pseudodirective, not a
	 label.  Make GAS not handle label-without-colon on this line.  We
	 also don't do mmixal-specific stuff on this line.  */
      label_without_colon_this_line = 0;
      return;
    }

  if (*s == 0 || is_end_of_line[(unsigned int) *s])
    /* We avoid handling empty lines here.  */
    return;

  if (is_name_beginner (*s))
    label = s;

  /* If there is a label, skip over it.  */
  while (*s && is_part_of_name (*s))
    s++;

  /* Find the start of the instruction or pseudo following the label,
     if there is one.  */
  for (insn = s;
       *insn && ISSPACE (*insn) && ! is_end_of_line[(unsigned int) *insn];
       insn++)
    /* Empty */
    ;

  /* Remove a trailing ":" off labels, as they'd otherwise be considered
     part of the name.  But don't do this for local labels.  */
  if (s != input_line_pointer && s[-1] == ':'
      && (s - 2 != input_line_pointer
	  || ! ISDIGIT (s[-2])))
    s[-1] = ' ';
  else if (label != NULL
	   /* For a lone label on a line, we don't attach it to the next
	      instruction or MMIXAL-pseudo (getting its alignment).  Thus
	      is acts like a "normal" :-ended label.  Ditto if it's
	      followed by a non-MMIXAL pseudo.  */
	   && !is_end_of_line[(unsigned int) *insn]
	   && *insn != '.')
    {
      /* For labels that don't end in ":", we save it so we can later give
	 it the same alignment and address as the associated instruction.  */

      /* Make room for the label including the ending nul.  */
      size_t len_0 = s - label + 1;

      /* Save this label on the MMIX symbol obstack.  Saving it on an
	 obstack is needless for "IS"-pseudos, but it's harmless and we
	 avoid a little code-cluttering.  */
      obstack_grow (&mmix_sym_obstack, label, len_0);
      pending_label = obstack_finish (&mmix_sym_obstack);
      pending_label[len_0 - 1] = 0;
    }

  /* If we have a non-MMIXAL pseudo, we have not business with the rest of
     the line.  */
  if (*insn == '.')
    return;

  /* Find local labels of operands.  Look for "[0-9][FB]" where the
     characters before and after are not part of words.  Break if a single
     or double quote is seen anywhere.  It means we can't have local
     labels as part of list with mixed quoted and unquoted members for
     mmixal compatibility but we can't have it all.  For the moment.
     Replace the '<N>B' or '<N>F' with MAGIC_FB_BACKWARD_CHAR<N> and
     MAGIC_FB_FORWARD_CHAR<N> respectively.  */

  /* First make sure we don't have any of the magic characters on the line
     appearing as input.  */
  while (*s)
    {
      c = *s++;
      if (is_end_of_line[(unsigned int) c])
	break;
      if (c == MAGIC_FB_BACKWARD_CHAR || c == MAGIC_FB_FORWARD_CHAR)
	as_bad (_("invalid characters in input"));
    }

  /* Scan again, this time looking for ';' after operands.  */
  s = insn;

  /* Skip the insn.  */
  while (*s
	 && ! ISSPACE (*s)
	 && *s != ';'
	 && ! is_end_of_line[(unsigned int) *s])
    s++;

  /* Skip the spaces after the insn.  */
  while (*s
	 && ISSPACE (*s)
	 && *s != ';'
	 && ! is_end_of_line[(unsigned int) *s])
    s++;

  /* Skip the operands.  While doing this, replace [0-9][BF] with
     (MAGIC_FB_BACKWARD_CHAR|MAGIC_FB_FORWARD_CHAR)[0-9].  */
  while ((c = *s) != 0
	 && ! ISSPACE (c)
	 && c != ';'
	 && ! is_end_of_line[(unsigned int) c])
    {
      if (c == '"')
	{
	  s++;

	  /* FIXME: Test-case for semi-colon in string.  */
	  while (*s
		 && *s != '"'
		 && (! is_end_of_line[(unsigned int) *s] || *s == ';'))
	    s++;

	  if (*s == '"')
	    s++;
	}
      else if (ISDIGIT (c))
	{
	  if ((s[1] != 'B' && s[1] != 'F')
	      || is_part_of_name (s[-1])
	      || is_part_of_name (s[2])
	      /* Don't treat e.g. #1F as a local-label reference.  */
	      || (s != input_line_pointer && s[-1] == '#'))
	    s++;
	  else
	    {
	      s[0] = (s[1] == 'B'
		      ? MAGIC_FB_BACKWARD_CHAR : MAGIC_FB_FORWARD_CHAR);
	      s[1] = c;
	    }
	}
      else
	s++;
    }

  /* Skip any spaces after the operands.  */
  while (*s
	 && ISSPACE (*s)
	 && *s != ';'
	 && !is_end_of_line[(unsigned int) *s])
    s++;

  /* If we're now looking at a semi-colon, then it's an end-of-line
     delimiter.  */
  mmix_next_semicolon_is_eoln = (*s == ';');

  /* Make IS into an EQU by replacing it with "= ".  Only match upper-case
     though; let lower-case be a syntax error.  */
  s = insn;
  if (s[0] == 'I' && s[1] == 'S' && ISSPACE (s[2]))
    {
      *s = '=';
      s[1] = ' ';

      /* Since labels can start without ":", we have to handle "X IS 42"
	 in full here, or "X" will be parsed as a label to be set at ".".  */
      input_line_pointer = s;

      /* Right after this function ends, line numbers will be bumped if
	 input_line_pointer[-1] = '\n'.  We want accurate line numbers for
	 the equals call, so we bump them before the call, and make sure
	 they aren't bumped afterwards.  */
      bump_line_counters ();

      /* A fb-label is valid as an IS-label.  */
      if (current_fb_label >= 0)
	{
	  char *fb_name;

	  /* We need to save this name on our symbol obstack, since the
	     string we got in fb_label_name is volatile and will change
	     with every call to fb_label_name, like those resulting from
	     parsing the IS-operand.  */
	  fb_name = fb_label_name (current_fb_label, 1);
	  obstack_grow (&mmix_sym_obstack, fb_name, strlen (fb_name) + 1);
	  equals (obstack_finish (&mmix_sym_obstack), 0);
	  fb_label_instance_inc (current_fb_label);
	  current_fb_label = -1;
	}
      else
	{
	  if (pending_label == NULL)
	    as_bad (_("empty label field for IS"));
	  else
	    equals (pending_label, 0);
	  pending_label = NULL;
	}

      /* For mmixal, we can have comments without a comment-start
	 character.   */
      mmix_handle_rest_of_empty_line ();
      input_line_pointer--;

      input_line_pointer[-1] = ' ';
    }
  else if (s[0] == 'G'
	   && s[1] == 'R'
	   && strncmp (s, "GREG", 4) == 0
	   && (ISSPACE (s[4]) || is_end_of_line[(unsigned char) s[4]]))
    {
      input_line_pointer = s + 4;

      /* Right after this function ends, line numbers will be bumped if
	 input_line_pointer[-1] = '\n'.  We want accurate line numbers for
	 the s_greg call, so we bump them before the call, and make sure
	 they aren't bumped afterwards.  */
      bump_line_counters ();

      /* A fb-label is valid as a GREG-label.  */
      if (current_fb_label >= 0)
	{
	  char *fb_name;

	  /* We need to save this name on our symbol obstack, since the
	     string we got in fb_label_name is volatile and will change
	     with every call to fb_label_name, like those resulting from
	     parsing the IS-operand.  */
	  fb_name = fb_label_name (current_fb_label, 1);

	  /* Make sure we save the canonical name and don't get bitten by
             prefixes.  */
	  obstack_1grow (&mmix_sym_obstack, ':');
	  obstack_grow (&mmix_sym_obstack, fb_name, strlen (fb_name) + 1);
	  mmix_greg_internal (obstack_finish (&mmix_sym_obstack));
	  fb_label_instance_inc (current_fb_label);
	  current_fb_label = -1;
	}
      else
	mmix_greg_internal (pending_label);

      /* Back up before the end-of-line marker that was skipped in
	 mmix_greg_internal.  */
      input_line_pointer--;
      input_line_pointer[-1] = ' ';

      pending_label = NULL;
    }
  else if (pending_label != NULL)
    {
      input_line_pointer += strlen (pending_label);

      /* See comment above about getting line numbers bumped.  */
      input_line_pointer[-1] = '\n';
    }
}

/* Give the value of an fb-label rewritten as in mmix_handle_mmixal, when
   parsing an expression.

   On valid calls, input_line_pointer points at a MAGIC_FB_BACKWARD_CHAR
   or MAGIC_FB_BACKWARD_CHAR, followed by an ascii digit for the label.
   We fill in the label as an expression.  */

void
mmix_fb_label (expressionS *expP)
{
  symbolS *sym;
  char *fb_internal_name;

  /* This doesn't happen when not using mmixal syntax.  */
  if (mmix_gnu_syntax
      || (input_line_pointer[0] != MAGIC_FB_BACKWARD_CHAR
	  && input_line_pointer[0] != MAGIC_FB_FORWARD_CHAR))
    return;

  /* The current backward reference has augmentation 0.  A forward
     reference has augmentation 1, unless it's the same as a fb-label on
     _this_ line, in which case we add one more so we don't refer to it.
     This is the semantics of mmixal; it differs to that of common
     fb-labels which refer to a here-label on the current line as a
     backward reference.  */
  fb_internal_name
    = fb_label_name (input_line_pointer[1] - '0',
		     (input_line_pointer[0] == MAGIC_FB_FORWARD_CHAR ? 1 : 0)
		     + ((input_line_pointer[1] - '0' == current_fb_label
			 && input_line_pointer[0] == MAGIC_FB_FORWARD_CHAR)
			? 1 : 0));

  input_line_pointer += 2;
  sym = symbol_find_or_make (fb_internal_name);

  /* We don't have to clean up unrelated fields here; we just do what the
     expr machinery does, but *not* just what it does for [0-9][fb], since
     we need to treat those as ordinary symbols sometimes; see testcases
     err-byte2.s and fb-2.s.  */
  if (S_GET_SEGMENT (sym) == absolute_section)
    {
      expP->X_op = O_constant;
      expP->X_add_number = S_GET_VALUE (sym);
    }
  else
    {
      expP->X_op = O_symbol;
      expP->X_add_symbol = sym;
      expP->X_add_number = 0;
    }
}

/* See whether we need to force a relocation into the output file.
   This is used to force out switch and PC relative relocations when
   relaxing.  */

int
mmix_force_relocation (fixS *fixP)
{
  if (fixP->fx_r_type == BFD_RELOC_MMIX_LOCAL
      || fixP->fx_r_type == BFD_RELOC_MMIX_BASE_PLUS_OFFSET)
    return 1;

  if (linkrelax)
    return 1;

  /* All our pcrel relocations are must-keep.  Note that md_apply_fix is
     called *after* this, and will handle getting rid of the presumed
     reloc; a relocation isn't *forced* other than to be handled by
     md_apply_fix (or tc_gen_reloc if linkrelax).  */
  if (fixP->fx_pcrel)
    return 1;

  return generic_force_reloc (fixP);
}

/* The location from which a PC relative jump should be calculated,
   given a PC relative reloc.  */

long
md_pcrel_from_section (fixS *fixP, segT sec)
{
  if (fixP->fx_addsy != (symbolS *) NULL
      && (! S_IS_DEFINED (fixP->fx_addsy)
	  || S_GET_SEGMENT (fixP->fx_addsy) != sec))
    {
      /* The symbol is undefined (or is defined but not in this section).
	 Let the linker figure it out.  */
      return 0;
    }

  return (fixP->fx_frag->fr_address + fixP->fx_where);
}

/* Adjust the symbol table.  We make reg_section relative to the real
   register section.  */

void
mmix_adjust_symtab (void)
{
  symbolS *sym;
  symbolS *regsec = section_symbol (reg_section);

  for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
    if (S_GET_SEGMENT (sym) == reg_section)
      {
	if (sym == regsec)
	  {
	    if (S_IS_EXTERNAL (sym) || symbol_used_in_reloc_p (sym))
	      abort ();
	    symbol_remove (sym, &symbol_rootP, &symbol_lastP);
	  }
	else
	  /* Change section to the *real* register section, so it gets
	     proper treatment when writing it out.  Only do this for
	     global symbols.  This also means we don't have to check for
	     $0..$255.  */
	  S_SET_SEGMENT (sym, real_reg_section);
      }
}

/* This is the expansion of LABELS_WITHOUT_COLONS.
   We let md_start_line_hook tweak label_without_colon_this_line, and then
   this function returns the tweaked value, and sets it to 1 for the next
   line.  FIXME: Very, very brittle.  Not sure it works the way I
   thought at the time I first wrote this.  */

int
mmix_label_without_colon_this_line (void)
{
  int retval = label_without_colon_this_line;

  if (! mmix_gnu_syntax)
    label_without_colon_this_line = 1;

  return retval;
}

/* This is the expansion of md_relax_frag.  We go through the ordinary
   relax table function except when the frag is for a GREG.  Then we have
   to check whether there's another GREG by the same value that we can
   join with.  */

long
mmix_md_relax_frag (segT seg, fragS *fragP, long stretch)
{
  switch (fragP->fr_subtype)
    {
      /* Growth for this type has been handled by mmix_md_end and
	 correctly estimated, so there's nothing more to do here.  */
    case STATE_GREG_DEF:
      return 0;

    case ENCODE_RELAX (STATE_PUSHJ, STATE_ZERO):
      {
	/* We need to handle relaxation type ourselves, since relax_frag
	   doesn't update fr_subtype if there's no size increase in the
	   current section; when going from plain PUSHJ to a stub.  This
	   is otherwise functionally the same as relax_frag in write.c,
	   simplified for this case.  */
	offsetT aim;
	addressT target;
	addressT address;
	symbolS *symbolP;
	target = fragP->fr_offset;
	address = fragP->fr_address;
	symbolP = fragP->fr_symbol;

	if (symbolP)
	  {
	    fragS *sym_frag;

	    sym_frag = symbol_get_frag (symbolP);
	    know (S_GET_SEGMENT (symbolP) != absolute_section
		  || sym_frag == &zero_address_frag);
	    target += S_GET_VALUE (symbolP);

	    /* If frag has yet to be reached on this pass, assume it will
	       move by STRETCH just as we did.  If this is not so, it will
	       be because some frag between grows, and that will force
	       another pass.  */

	    if (stretch != 0
		&& sym_frag->relax_marker != fragP->relax_marker
		&& S_GET_SEGMENT (symbolP) == seg)
	      target += stretch;
	  }

	aim = target - address - fragP->fr_fix;
	if (aim >= PUSHJ_0B && aim <= PUSHJ_0F)
	  {
	    /* Target is reachable with a PUSHJ.  */
	    segment_info_type *seginfo = seg_info (seg);

	    /* If we're at the end of a relaxation round, clear the stub
	       counter as initialization for the next round.  */
	    if (fragP == seginfo->tc_segment_info_data.last_stubfrag)
	      seginfo->tc_segment_info_data.nstubs = 0;
	    return 0;
	  }

	/* Not reachable.  Try a stub.  */
	fragP->fr_subtype = ENCODE_RELAX (STATE_PUSHJSTUB, STATE_ZERO);
      }
      /* FALLTHROUGH.  */

      /* See if this PUSHJ is redirectable to a stub.  */
    case ENCODE_RELAX (STATE_PUSHJSTUB, STATE_ZERO):
      {
	segment_info_type *seginfo = seg_info (seg);
	fragS *lastfrag = seginfo->frchainP->frch_last;
	relax_substateT prev_type = fragP->fr_subtype;

	/* The last frag is always an empty frag, so it suffices to look
	   at its address to know the ending address of this section.  */
	know (lastfrag->fr_type == rs_fill
	      && lastfrag->fr_fix == 0
	      && lastfrag->fr_var == 0);

	/* For this PUSHJ to be relaxable into a call to a stub, the
	   distance must be no longer than 256k bytes from the PUSHJ to
	   the end of the section plus the maximum size of stubs so far.  */
	if ((lastfrag->fr_address
	     + stretch
	     + PUSHJ_MAX_LEN * seginfo->tc_segment_info_data.nstubs)
	    - (fragP->fr_address + fragP->fr_fix)
	    > GETA_0F
	    || !pushj_stubs)
	  fragP->fr_subtype = mmix_relax_table[prev_type].rlx_more;
	else
	  seginfo->tc_segment_info_data.nstubs++;

	/* If we're at the end of a relaxation round, clear the stub
	   counter as initialization for the next round.  */
	if (fragP == seginfo->tc_segment_info_data.last_stubfrag)
	  seginfo->tc_segment_info_data.nstubs = 0;

	return
	   (mmix_relax_table[fragP->fr_subtype].rlx_length
	    - mmix_relax_table[prev_type].rlx_length);
      }

    case ENCODE_RELAX (STATE_PUSHJ, STATE_MAX):
      {
	segment_info_type *seginfo = seg_info (seg);

	/* Need to cover all STATE_PUSHJ states to act on the last stub
	   frag (the end of this relax round; initialization for the
	   next).  */
	if (fragP == seginfo->tc_segment_info_data.last_stubfrag)
	  seginfo->tc_segment_info_data.nstubs = 0;

	return 0;
      }

    default:
      return relax_frag (seg, fragP, stretch);

    case STATE_GREG_UNDF:
      BAD_CASE (fragP->fr_subtype);
    }

  as_fatal (_("internal: unexpected relax type %d:%d"),
	    fragP->fr_type, fragP->fr_subtype);
  return 0;
}

/* Various things we punt until all input is seen.  */

void
mmix_md_end (void)
{
  fragS *fragP;
  symbolS *mainsym;
  asection *regsec;
  struct loc_assert_s *loc_assert;
  int i;

  /* The first frag of GREG:s going into the register contents section.  */
  fragS *mmix_reg_contents_frags = NULL;

  /* Reset prefix.  All labels reachable at this point must be
     canonicalized.  */
  mmix_current_prefix = NULL;

  if (doing_bspec)
    as_bad_where (bspec_file, bspec_line, _("BSPEC without ESPEC."));

  /* Emit the low LOC setting of .text.  */
  if (text_has_contents && lowest_text_loc != (bfd_vma) -1)
    {
      symbolS *symbolP;
      char locsymbol[sizeof (":") - 1
		    + sizeof (MMIX_LOC_SECTION_START_SYMBOL_PREFIX) - 1
		    + sizeof (".text")];

      /* An exercise in non-ISO-C-ness, this one.  */
      sprintf (locsymbol, ":%s%s", MMIX_LOC_SECTION_START_SYMBOL_PREFIX,
	       ".text");
      symbolP
	= symbol_new (locsymbol, absolute_section, lowest_text_loc,
		      &zero_address_frag);
      S_SET_EXTERNAL (symbolP);
    }

  /* Ditto .data.  */
  if (data_has_contents && lowest_data_loc != (bfd_vma) -1)
    {
      symbolS *symbolP;
      char locsymbol[sizeof (":") - 1
		     + sizeof (MMIX_LOC_SECTION_START_SYMBOL_PREFIX) - 1
		     + sizeof (".data")];

      sprintf (locsymbol, ":%s%s", MMIX_LOC_SECTION_START_SYMBOL_PREFIX,
	       ".data");
      symbolP
	= symbol_new (locsymbol, absolute_section, lowest_data_loc,
		      &zero_address_frag);
      S_SET_EXTERNAL (symbolP);
    }

  /* Unless GNU syntax mode, set "Main" to be a function, so the
     disassembler doesn't get confused when we write truly
     mmixal-compatible code (and don't use .type).  Similarly set it
     global (regardless of -globalize-symbols), so the linker sees it as
     the start symbol in ELF mode.  */
  mainsym = symbol_find (MMIX_START_SYMBOL_NAME);
  if (mainsym != NULL && ! mmix_gnu_syntax)
    {
      symbol_get_bfdsym (mainsym)->flags |= BSF_FUNCTION;
      S_SET_EXTERNAL (mainsym);
    }

  /* Check that we didn't LOC into the unknown, or rather that when it
     was unknown, we actually change sections.  */
  for (loc_assert = loc_asserts;
       loc_assert != NULL;
       loc_assert = loc_assert->next)
    {
      segT actual_seg;

      resolve_symbol_value (loc_assert->loc_sym);
      actual_seg = S_GET_SEGMENT (loc_assert->loc_sym);
      if (actual_seg != loc_assert->old_seg)
	{
	  const char *fnam;
	  unsigned int line;
	  int e_valid = expr_symbol_where (loc_assert->loc_sym, &fnam, &line);

	  gas_assert (e_valid == 1);
	  as_bad_where (fnam, line,
			_("LOC to section unknown or indeterminable "
			  "at first pass"));

	  /* Patch up the generic location data to avoid cascading
	     error messages from later passes.  (See original in
	     write.c:relax_segment.)  */
	  fragP = loc_assert->frag;
	  fragP->fr_type = rs_align;
	  fragP->fr_subtype = 0;
	  fragP->fr_offset = 0;
	  fragP->fr_fix = 0;
	}
    }

  if (n_of_raw_gregs != 0)
    {
      /* Emit GREGs.  They are collected in order of appearance, but must
	 be emitted in opposite order to both have section address regno*8
	 and the same allocation order (within a file) as mmixal.  */
      segT this_segment = now_seg;
      subsegT this_subsegment = now_subseg;

      regsec = bfd_make_section_old_way (stdoutput,
					 MMIX_REG_CONTENTS_SECTION_NAME);
      subseg_set (regsec, 0);

      /* Finally emit the initialization-value.  Emit a variable frag, which
	 we'll fix in md_estimate_size_before_relax.  We set the initializer
	 for the tc_frag_data field to NULL, so we can use that field for
	 relaxation purposes.  */
      mmix_opcode_frag = NULL;

      frag_grow (0);
      mmix_reg_contents_frags = frag_now;

      for (i = n_of_raw_gregs - 1; i >= 0; i--)
	{
	  if (mmix_raw_gregs[i].label != NULL)
	    /* There's a symbol.  Let it refer to this location in the
	       register contents section.  The symbol must be globalized
	       separately.  */
	    colon (mmix_raw_gregs[i].label);

	  frag_var (rs_machine_dependent, 8, 0, STATE_GREG_UNDF,
		    make_expr_symbol (&mmix_raw_gregs[i].exp), 0, NULL);
	}

      subseg_set (this_segment, this_subsegment);
    }

  regsec = bfd_get_section_by_name (stdoutput, MMIX_REG_CONTENTS_SECTION_NAME);
  /* Mark the section symbol as being OK for a reloc.  */
  if (regsec != NULL)
    regsec->symbol->flags |= BSF_KEEP;

  /* Iterate over frags resulting from GREGs and move those that evidently
     have the same value together and point one to another.

     This works in time O(N^2) but since the upper bound for non-error use
     is 223, it's best to keep this simpler algorithm.  */
  for (fragP = mmix_reg_contents_frags; fragP != NULL; fragP = fragP->fr_next)
    {
      fragS **fpp;
      fragS *fp = NULL;
      fragS *osymfrag;
      offsetT osymval;
      expressionS *oexpP;
      symbolS *symbolP = fragP->fr_symbol;

      if (fragP->fr_type != rs_machine_dependent
	  || fragP->fr_subtype != STATE_GREG_UNDF)
	continue;

      /* Whatever the outcome, we will have this GREG judged merged or
	 non-merged.  Since the tc_frag_data is NULL at this point, we
	 default to non-merged.  */
      fragP->fr_subtype = STATE_GREG_DEF;

      /* If we're not supposed to merge GREG definitions, then just don't
	 look for equivalents.  */
      if (! merge_gregs)
	continue;

      osymval = (offsetT) S_GET_VALUE (symbolP);
      osymfrag = symbol_get_frag (symbolP);

      /* If the symbol isn't defined, we can't say that another symbol
	 equals this frag, then.  FIXME: We can look at the "deepest"
	 defined name; if a = c and b = c then obviously a == b.  */
      if (! S_IS_DEFINED (symbolP))
	continue;

      oexpP = symbol_get_value_expression (fragP->fr_symbol);

      /* If the initialization value is zero, then we must not merge them.  */
      if (oexpP->X_op == O_constant && osymval == 0)
	continue;

      /* Iterate through the frags downward this one.  If we find one that
	 has the same non-zero value, move it to after this one and point
	 to it as the equivalent.  */
      for (fpp = &fragP->fr_next; *fpp != NULL; fpp = &fpp[0]->fr_next)
	{
	  fp = *fpp;

	  if (fp->fr_type != rs_machine_dependent
	      || fp->fr_subtype != STATE_GREG_UNDF)
	    continue;

	  /* Calling S_GET_VALUE may simplify the symbol, changing from
	     expr_section etc. so call it first.  */
	  if ((offsetT) S_GET_VALUE (fp->fr_symbol) == osymval
	      && symbol_get_frag (fp->fr_symbol) == osymfrag)
	    {
	      /* Move the frag links so the one we found equivalent comes
		 after the current one, carefully considering that
		 sometimes fpp == &fragP->fr_next and the moves must be a
		 NOP then.  */
	      *fpp = fp->fr_next;
	      fp->fr_next = fragP->fr_next;
	      fragP->fr_next = fp;
	      break;
	    }
	}

      if (*fpp != NULL)
	fragP->tc_frag_data = fp;
    }
}

/* qsort function for mmix_symbol_gregs.  */

static int
cmp_greg_symbol_fixes (const void *parg, const void *qarg)
{
  const struct mmix_symbol_greg_fixes *p
    = (const struct mmix_symbol_greg_fixes *) parg;
  const struct mmix_symbol_greg_fixes *q
    = (const struct mmix_symbol_greg_fixes *) qarg;

  return p->offs > q->offs ? 1 : p->offs < q->offs ? -1 : 0;
}

/* Collect GREG definitions from mmix_gregs and hang them as lists sorted
   on increasing offsets onto each section symbol or undefined symbol.

   Also, remove the register convenience section so it doesn't get output
   as an ELF section.  */

void
mmix_frob_file (void)
{
  int i;
  struct mmix_symbol_gregs *all_greg_symbols[MAX_GREGS];
  int n_greg_symbols = 0;

  /* Collect all greg fixups and decorate each corresponding symbol with
     the greg fixups for it.  */
  for (i = 0; i < n_of_cooked_gregs; i++)
    {
      offsetT offs;
      symbolS *sym;
      struct mmix_symbol_gregs *gregs;
      fixS *fixP;

      fixP = mmix_gregs[i];
      know (fixP->fx_r_type == BFD_RELOC_64);

      /* This case isn't doable in general anyway, methinks.  */
      if (fixP->fx_subsy != NULL)
	{
	  as_bad_where (fixP->fx_file, fixP->fx_line,
			_("GREG expression too complicated"));
	  continue;
	}

      sym = fixP->fx_addsy;
      offs = (offsetT) fixP->fx_offset;

      /* If the symbol is defined, then it must be resolved to a section
	 symbol at this time, or else we don't know how to handle it.  */
      if (S_IS_DEFINED (sym)
	  && !bfd_is_com_section (S_GET_SEGMENT (sym))
	  && !S_IS_WEAK (sym))
	{
	  if (! symbol_section_p (sym)
	      && ! bfd_is_abs_section (S_GET_SEGMENT (sym)))
	    as_fatal (_("internal: GREG expression not resolved to section"));

	  offs += S_GET_VALUE (sym);
	}

      /* If this is an absolute symbol sufficiently near lowest_data_loc,
	 then we canonicalize on the data section.  Note that offs is
	 signed here; we may subtract lowest_data_loc which is unsigned.
	 Careful with those comparisons.  */
      if (lowest_data_loc != (bfd_vma) -1
	  && (bfd_vma) offs + 256 > lowest_data_loc
	  && bfd_is_abs_section (S_GET_SEGMENT (sym)))
	{
	  offs -= (offsetT) lowest_data_loc;
	  sym = section_symbol (data_section);
	}
      /* Likewise text section.  */
      else if (lowest_text_loc != (bfd_vma) -1
	       && (bfd_vma) offs + 256 > lowest_text_loc
	       && bfd_is_abs_section (S_GET_SEGMENT (sym)))
	{
	  offs -= (offsetT) lowest_text_loc;
	  sym = section_symbol (text_section);
	}

      gregs = *symbol_get_tc (sym);

      if (gregs == NULL)
	{
	  gregs = XNEW (struct mmix_symbol_gregs);
	  gregs->n_gregs = 0;
	  symbol_set_tc (sym, &gregs);
	  all_greg_symbols[n_greg_symbols++] = gregs;
	}

      gregs->greg_fixes[gregs->n_gregs].fix = fixP;
      gregs->greg_fixes[gregs->n_gregs++].offs = offs;
    }

  /* For each symbol having a GREG definition, sort those definitions on
     offset.  */
  for (i = 0; i < n_greg_symbols; i++)
    qsort (all_greg_symbols[i]->greg_fixes, all_greg_symbols[i]->n_gregs,
	   sizeof (all_greg_symbols[i]->greg_fixes[0]), cmp_greg_symbol_fixes);

  if (real_reg_section != NULL)
    {
      /* FIXME: Pass error state gracefully.  */
      if (bfd_get_section_flags (stdoutput, real_reg_section) & SEC_HAS_CONTENTS)
	as_fatal (_("register section has contents\n"));

      bfd_section_list_remove (stdoutput, real_reg_section);
      --stdoutput->section_count;
    }

}

/* Provide an expression for a built-in name provided when-used.
   Either a symbol that is a handler; living in 0x10*[1..8] and having
   name [DVWIOUZX]_Handler, or a mmixal built-in symbol.

   If the name isn't a built-in name and parsed into *EXPP, return zero.  */

int
mmix_parse_predefined_name (char *name, expressionS *expP)
{
  char *canon_name;
  const char *handler_charp;
  const char handler_chars[] = "DVWIOUZX";
  symbolS *symp;

  if (! predefined_syms)
    return 0;

  canon_name = tc_canonicalize_symbol_name (name);

  if (canon_name[1] == '_'
      && strcmp (canon_name + 2, "Handler") == 0
      && (handler_charp = strchr (handler_chars, *canon_name)) != NULL)
    {
      /* If the symbol doesn't exist, provide one relative to the .text
	 section.

	 FIXME: We should provide separate sections, mapped in the linker
	 script.  */
      symp = symbol_find (name);
      if (symp == NULL)
	symp = symbol_new (name, text_section,
			   0x10 * (handler_charp + 1 - handler_chars),
			   &zero_address_frag);
    }
  else
    {
      /* These symbols appear when referenced; needed for
         mmixal-compatible programs.  */
      unsigned int i;

      static const struct
      {
	const char *name;
	valueT val;
      } predefined_abs_syms[] =
	{
	  {"Data_Segment", (valueT) 0x20 << 56},
	  {"Pool_Segment", (valueT) 0x40 << 56},
	  {"Stack_Segment", (valueT) 0x60 << 56},
	  {"StdIn", 0},
	  {"StdOut", 1},
	  {"StdErr", 2},
	  {"TextRead", 0},
	  {"TextWrite", 1},
	  {"BinaryRead", 2},
	  {"BinaryWrite", 3},
	  {"BinaryReadWrite", 4},
	  {"Halt", 0},
	  {"Fopen", 1},
	  {"Fclose", 2},
	  {"Fread", 3},
	  {"Fgets", 4},
	  {"Fgetws", 5},
	  {"Fwrite", 6},
	  {"Fputs", 7},
	  {"Fputws", 8},
	  {"Fseek", 9},
	  {"Ftell", 10},
	  {"D_BIT", 0x80},
	  {"V_BIT", 0x40},
	  {"W_BIT", 0x20},
	  {"I_BIT", 0x10},
	  {"O_BIT", 0x08},
	  {"U_BIT", 0x04},
	  {"Z_BIT", 0x02},
	  {"X_BIT", 0x01},
	  {"Inf", 0x7ff00000}
	};

      /* If it's already in the symbol table, we shouldn't do anything.  */
      symp = symbol_find (name);
      if (symp != NULL)
	return 0;

      for (i = 0;
	   i < sizeof (predefined_abs_syms) / sizeof (predefined_abs_syms[0]);
	   i++)
	if (strcmp (canon_name, predefined_abs_syms[i].name) == 0)
	  {
	    symbol_table_insert (symbol_new (predefined_abs_syms[i].name,
					     absolute_section,
					     predefined_abs_syms[i].val,
					     &zero_address_frag));

	    /* Let gas find the symbol we just created, through its
               ordinary lookup.  */
	    return 0;
	  }

      /* Not one of those symbols.  Let gas handle it.  */
      return 0;
    }

  expP->X_op = O_symbol;
  expP->X_add_number = 0;
  expP->X_add_symbol = symp;
  expP->X_op_symbol = NULL;

  return 1;
}

/* Just check that we don't have a BSPEC/ESPEC pair active when changing
   sections "normally", and get knowledge about alignment from the new
   section.  */

void
mmix_md_elf_section_change_hook (void)
{
  if (doing_bspec)
    as_bad (_("section change from within a BSPEC/ESPEC pair is not supported"));

  last_alignment = bfd_get_section_alignment (now_seg->owner, now_seg);
  want_unaligned = 0;
}

/* The LOC worker.  This is like s_org, but we have to support changing
   section too.   */

static void
s_loc (int ignore ATTRIBUTE_UNUSED)
{
  segT section;
  expressionS exp;
  char *p;
  symbolS *sym;
  offsetT off;

  /* Must not have a BSPEC in progress.  */
  if (doing_bspec)
    {
      as_bad (_("directive LOC from within a BSPEC/ESPEC pair is not supported"));
      return;
    }

  section = expression (&exp);

  if (exp.X_op == O_illegal
      || exp.X_op == O_absent
      || exp.X_op == O_big)
    {
      as_bad (_("invalid LOC expression"));
      return;
    }

  if (section == undefined_section)
    {
      /* This is an error or a LOC with an expression involving
	 forward references.  For the expression to be correctly
	 evaluated, we need to force a proper symbol; gas loses track
	 of the segment for "local symbols".  */
      if (exp.X_op == O_add)
	{
	  symbol_get_value_expression (exp.X_op_symbol);
	  symbol_get_value_expression (exp.X_add_symbol);
	}
      else
	{
	  gas_assert (exp.X_op == O_symbol);
	  symbol_get_value_expression (exp.X_add_symbol);
	}
    }

  if (section == absolute_section)
    {
      /* Translate a constant into a suitable section.  */

      if (exp.X_add_number < ((offsetT) 0x20 << 56))
	{
	  /* Lower than Data_Segment or in the reserved area (the
	     segment number is >= 0x80, appearing negative) - assume
	     it's .text.  */
	  section = text_section;

	  /* Save the lowest seen location, so we can pass on this
	     information to the linker.  We don't actually org to this
	     location here, we just pass on information to the linker so
	     it can put the code there for us.  */

	  /* If there was already a loc (that has to be set lower than
	     this one), we org at (this - lower).  There's an implicit
	     "LOC 0" before any entered code.  FIXME: handled by spurious
	     settings of text_has_contents.  */
	  if (lowest_text_loc != (bfd_vma) -1
	      && (bfd_vma) exp.X_add_number < lowest_text_loc)
	    {
	      as_bad (_("LOC expression stepping backwards is not supported"));
	      exp.X_op = O_absent;
	    }
	  else
	    {
	      if (text_has_contents && lowest_text_loc == (bfd_vma) -1)
		lowest_text_loc = 0;

	      if (lowest_text_loc == (bfd_vma) -1)
		{
		  lowest_text_loc = exp.X_add_number;

		  /* We want only to change the section, not set an offset.  */
		  exp.X_op = O_absent;
		}
	      else
		exp.X_add_number -= lowest_text_loc;
	    }
	}
      else
	{
	  /* Do the same for the .data section, except we don't have
	     to worry about exp.X_add_number carrying a sign.  */
	  section = data_section;

	  if (exp.X_add_number < (offsetT) lowest_data_loc)
	    {
	      as_bad (_("LOC expression stepping backwards is not supported"));
	      exp.X_op = O_absent;
	    }
	  else
	    {
	      if (data_has_contents && lowest_data_loc == (bfd_vma) -1)
		lowest_data_loc = (bfd_vma) 0x20 << 56;

	      if (lowest_data_loc == (bfd_vma) -1)
		{
		  lowest_data_loc = exp.X_add_number;

		  /* We want only to change the section, not set an offset.  */
		  exp.X_op = O_absent;
		}
	      else
		exp.X_add_number -= lowest_data_loc;
	    }
	}
    }

  /* If we can't deduce the section, it must be the current one.
     Below, we arrange to assert this.  */
  if (section != now_seg && section != undefined_section)
    {
      obj_elf_section_change_hook ();
      subseg_set (section, 0);

      /* Call our section change hooks using the official hook.  */
      md_elf_section_change_hook ();
    }

  if (exp.X_op != O_absent)
    {
      symbolS *esym = NULL;

      if (exp.X_op != O_constant && exp.X_op != O_symbol)
	{
	  /* Handle complex expressions.  */
	  esym = sym = make_expr_symbol (&exp);
	  off = 0;
	}
      else
	{
	  sym = exp.X_add_symbol;
	  off = exp.X_add_number;

	  if (section == undefined_section)
	    {
	      /* We need an expr_symbol when tracking sections.  In
		 order to make this an expr_symbol with file and line
		 tracked, we have to make the exp non-trivial; not an
		 O_symbol with .X_add_number == 0.  The constant part
		 is unused.  */
	      exp.X_add_number = 1;
	      esym = make_expr_symbol (&exp);
	    }
	}

      /* Track the LOC's where we couldn't deduce the section: assert
	 that we weren't supposed to change section.  */
      if (section == undefined_section)
	{
	  struct loc_assert_s *next = loc_asserts;
	  loc_asserts = XNEW (struct loc_assert_s);
	  loc_asserts->next = next;
	  loc_asserts->old_seg = now_seg;
	  loc_asserts->loc_sym = esym;
	  loc_asserts->frag = frag_now;
	}

      p = frag_var (rs_org, 1, 1, (relax_substateT) 0, sym, off, (char *) 0);
      *p = 0;
    }

  mmix_handle_rest_of_empty_line ();
}

/* The BYTE worker.  We have to support sequences of mixed "strings",
   numbers and other constant "first-pass" reducible expressions separated
   by comma.  */

static void
mmix_byte (void)
{
  unsigned int c;

  if (now_seg == text_section)
    text_has_contents = 1;
  else if (now_seg == data_section)
    data_has_contents = 1;

  do
    {
      SKIP_WHITESPACE ();
      switch (*input_line_pointer)
	{
	case '\"':
	  ++input_line_pointer;
	  while (is_a_char (c = next_char_of_string ()))
	    {
	      FRAG_APPEND_1_CHAR (c);
	    }

	  if (input_line_pointer[-1] != '\"')
	    {
	      /* We will only get here in rare cases involving #NO_APP,
		 where the unterminated string is not recognized by the
		 preformatting pass.  */
	      as_bad (_("unterminated string"));
	      mmix_discard_rest_of_line ();
	      return;
	    }
	  break;

	default:
	  {
	    expressionS exp;
	    segT expseg = expression (&exp);

	    /* We have to allow special register names as constant numbers.  */
	    if ((expseg != absolute_section && expseg != reg_section)
		|| (exp.X_op != O_constant
		    && (exp.X_op != O_register
			|| exp.X_add_number <= 255)))
	      {
		as_bad (_("BYTE expression not a pure number"));
		mmix_discard_rest_of_line ();
		return;
	      }
	    else if ((exp.X_add_number > 255 && exp.X_op != O_register)
		     || exp.X_add_number < 0)
	      {
		/* Note that mmixal does not allow negative numbers in
		   BYTE sequences, so neither should we.  */
		as_bad (_("BYTE expression not in the range 0..255"));
		mmix_discard_rest_of_line ();
		return;
	      }

	    FRAG_APPEND_1_CHAR (exp.X_add_number);
	  }
	  break;
	}

      SKIP_WHITESPACE ();
      c = *input_line_pointer++;
    }
  while (c == ',');

  input_line_pointer--;

  if (mmix_gnu_syntax)
    demand_empty_rest_of_line ();
  else
    {
      mmix_discard_rest_of_line ();
      /* Do like demand_empty_rest_of_line and step over the end-of-line
         boundary.  */
      input_line_pointer++;
    }

  /* Make sure we align for the next instruction.  */
  last_alignment = 0;
}

/* Like cons_worker, but we have to ignore "naked comments", not barf on
   them.  Implements WYDE, TETRA and OCTA.  We're a little bit more
   lenient than mmix_byte but FIXME: they should eventually merge.  */

static void
mmix_cons (int nbytes)
{
  expressionS exp;

  /* If we don't have any contents, then it's ok to have a specified start
     address that is not a multiple of the max data size.  We will then
     align it as necessary when we get here.  Otherwise, it's a fatal sin.  */
  if (now_seg == text_section)
    {
      if (lowest_text_loc != (bfd_vma) -1
	  && (lowest_text_loc & (nbytes - 1)) != 0)
	{
	  if (text_has_contents)
	    as_bad (_("data item with alignment larger than location"));
	  else if (want_unaligned)
	    as_bad (_("unaligned data at an absolute location is not supported"));

	  lowest_text_loc &= ~((bfd_vma) nbytes - 1);
	  lowest_text_loc += (bfd_vma) nbytes;
	}

      text_has_contents = 1;
    }
  else if (now_seg == data_section)
    {
      if (lowest_data_loc != (bfd_vma) -1
	  && (lowest_data_loc & (nbytes - 1)) != 0)
	{
	  if (data_has_contents)
	    as_bad (_("data item with alignment larger than location"));
	  else if (want_unaligned)
	    as_bad (_("unaligned data at an absolute location is not supported"));

	  lowest_data_loc &= ~((bfd_vma) nbytes - 1);
	  lowest_data_loc += (bfd_vma) nbytes;
	}

      data_has_contents = 1;
    }

  /* Always align these unless asked not to (valid for the current pseudo).  */
  if (! want_unaligned)
    {
      last_alignment = nbytes == 2 ? 1 : (nbytes == 4 ? 2 : 3);
      frag_align (last_alignment, 0, 0);
      record_alignment (now_seg, last_alignment);
    }

  /* For mmixal compatibility, a label for an instruction (and emitting
     pseudo) refers to the _aligned_ address.  So we have to emit the
     label here.  */
  if (current_fb_label >= 0)
    colon (fb_label_name (current_fb_label, 1));
  else if (pending_label != NULL)
    {
      colon (pending_label);
      pending_label = NULL;
    }

  SKIP_WHITESPACE ();

  if (is_end_of_line[(unsigned int) *input_line_pointer])
    {
      /* Default to zero if the expression was absent.  */

      exp.X_op = O_constant;
      exp.X_add_number = 0;
      exp.X_unsigned = 0;
      exp.X_add_symbol = NULL;
      exp.X_op_symbol = NULL;
      emit_expr (&exp, (unsigned int) nbytes);
    }
  else
    do
      {
	unsigned int c;

	switch (*input_line_pointer)
	  {
	    /* We support strings here too; each character takes up nbytes
	       bytes.  */
	  case '\"':
	    ++input_line_pointer;
	    while (is_a_char (c = next_char_of_string ()))
	      {
		exp.X_op = O_constant;
		exp.X_add_number = c;
		exp.X_unsigned = 1;
		emit_expr (&exp, (unsigned int) nbytes);
	      }

	    if (input_line_pointer[-1] != '\"')
	      {
		/* We will only get here in rare cases involving #NO_APP,
		   where the unterminated string is not recognized by the
		   preformatting pass.  */
		as_bad (_("unterminated string"));
		mmix_discard_rest_of_line ();
		return;
	      }
	    break;

	  default:
	    {
	      expression (&exp);
	      emit_expr (&exp, (unsigned int) nbytes);
	      SKIP_WHITESPACE ();
	    }
	    break;
	  }
      }
    while (*input_line_pointer++ == ',');

  input_line_pointer--;		/* Put terminator back into stream.  */

  mmix_handle_rest_of_empty_line ();

  /* We don't need to step up the counter for the current_fb_label here;
     that's handled by the caller.  */
}

/* The md_do_align worker.  At present, we just record an alignment to
   nullify the automatic alignment we do for WYDE, TETRA and OCTA, as gcc
   does not use the unaligned macros when attribute packed is used.
   Arguably this is a GCC bug.  */

void
mmix_md_do_align (int n, char *fill ATTRIBUTE_UNUSED,
		  int len ATTRIBUTE_UNUSED, int max ATTRIBUTE_UNUSED)
{
  last_alignment = n;
  want_unaligned = n == 0;
}
