/* GAS interface for targets using CGEN: Cpu tools GENerator.
   Copyright (C) 1996-2021 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.  */

#include "as.h"
#include <setjmp.h>
#include "symcat.h"
#include "cgen-desc.h"
#include "subsegs.h"
#include "cgen.h"
#include "dwarf2dbg.h"

#include "symbols.h"

#ifdef OBJ_COMPLEX_RELC
static expressionS * make_right_shifted_expr
  (expressionS *, const int, const int);

static unsigned long gas_cgen_encode_addend
  (const unsigned long, const unsigned long, const unsigned long, \
   const unsigned long, const unsigned long, const unsigned long, \
   const unsigned long);

static const char * weak_operand_overflow_check
  (const expressionS *, const CGEN_OPERAND *);

static void queue_fixup_recursively
  (const int, const int, expressionS *, \
   const CGEN_MAYBE_MULTI_IFLD *, const int, const int);

static int rightshift = 0;
#endif
static void queue_fixup (int, int, expressionS *);

/* Opcode table descriptor, must be set by md_begin.  */

CGEN_CPU_DESC gas_cgen_cpu_desc;

/* Callback to insert a register into the symbol table.
   A target may choose to let GAS parse the registers.
   ??? Not currently used.  */

void
cgen_asm_record_register (char *name, int number)
{
  /* Use symbol_create here instead of symbol_new so we don't try to
     output registers into the object file's symbol table.  */
  symbol_table_insert (symbol_create (name, reg_section,
				      &zero_address_frag, number));
}

/* We need to keep a list of fixups.  We can't simply generate them as
   we go, because that would require us to first create the frag, and
   that would screw up references to ``.''.

   This is used by cpu's with simple operands.  It keeps knowledge of what
   an `expressionS' is and what a `fixup' is out of CGEN which for the time
   being is preferable.

   OPINDEX is the index in the operand table.
   OPINFO is something the caller chooses to help in reloc determination.  */

struct fixup
{
  int opindex;
  int opinfo;
  expressionS exp;
  struct cgen_maybe_multi_ifield * field;
  int msb_field_p;
};

static struct fixup fixups[GAS_CGEN_MAX_FIXUPS];
static int num_fixups;

/* Prepare to parse an instruction.
   ??? May wish to make this static and delete calls in md_assemble.  */

void
gas_cgen_init_parse (void)
{
  num_fixups = 0;
}

/* Queue a fixup.  */

static void
queue_fixup (int opindex, int opinfo, expressionS *expP)
{
  /* We need to generate a fixup for this expression.  */
  if (num_fixups >= GAS_CGEN_MAX_FIXUPS)
    as_fatal (_("too many fixups"));
  fixups[num_fixups].exp     = *expP;
  fixups[num_fixups].opindex = opindex;
  fixups[num_fixups].opinfo  = opinfo;
  ++ num_fixups;
}

/* The following functions allow fixup chains to be stored, retrieved,
   and swapped.  They are a generalization of a pre-existing scheme
   for storing, restoring and swapping fixup chains that was used by
   the m32r port.  The functionality is essentially the same, only
   instead of only being able to store a single fixup chain, an entire
   array of fixup chains can be stored.  It is the user's responsibility
   to keep track of how many fixup chains have been stored and which
   elements of the array they are in.

   The algorithms used are the same as in the old scheme.  Other than the
   "array-ness" of the whole thing, the functionality is identical to the
   old scheme.

   gas_cgen_initialize_saved_fixups_array():
      Sets num_fixups_in_chain to 0 for each element. Call this from
      md_begin() if you plan to use these functions and you want the
      fixup count in each element to be set to 0 initially.  This is
      not necessary, but it's included just in case.  It performs
      the same function for each element in the array of fixup chains
      that gas_init_parse() performs for the current fixups.

   gas_cgen_save_fixups (element):
      element - element number of the array you wish to store the fixups
                to.  No mechanism is built in for tracking what element
                was last stored to.

   gas_cgen_restore_fixups (element):
      element - element number of the array you wish to restore the fixups
                from.

   gas_cgen_swap_fixups(int element):
       element - swap the current fixups with those in this element number.
*/

struct saved_fixups
{
  struct fixup fixup_chain[GAS_CGEN_MAX_FIXUPS];
  int num_fixups_in_chain;
};

static struct saved_fixups stored_fixups[MAX_SAVED_FIXUP_CHAINS];

void
gas_cgen_initialize_saved_fixups_array (void)
{
  int i = 0;

  while (i < MAX_SAVED_FIXUP_CHAINS)
    stored_fixups[i++].num_fixups_in_chain = 0;
}

void
gas_cgen_save_fixups (int i)
{
  if (i < 0 || i >= MAX_SAVED_FIXUP_CHAINS)
    {
      as_fatal ("index into stored_fixups[] out of bounds");
      return;
    }

  stored_fixups[i].num_fixups_in_chain = num_fixups;
  memcpy (stored_fixups[i].fixup_chain, fixups,
	  sizeof (fixups[0]) * num_fixups);
  num_fixups = 0;
}

void
gas_cgen_restore_fixups (int i)
{
  if (i < 0 || i >= MAX_SAVED_FIXUP_CHAINS)
    {
      as_fatal ("index into stored_fixups[] out of bounds");
      return;
    }

  num_fixups = stored_fixups[i].num_fixups_in_chain;
  memcpy (fixups, stored_fixups[i].fixup_chain,
	  (sizeof (stored_fixups[i].fixup_chain[0])) * num_fixups);
  stored_fixups[i].num_fixups_in_chain = 0;
}

void
gas_cgen_swap_fixups (int i)
{
  if (i < 0 || i >= MAX_SAVED_FIXUP_CHAINS)
    {
      as_fatal ("index into stored_fixups[] out of bounds");
      return;
    }

  if (num_fixups == 0)
    gas_cgen_restore_fixups (i);

  else if (stored_fixups[i].num_fixups_in_chain == 0)
    gas_cgen_save_fixups (i);

  else
    {
      int tmp;
      struct fixup tmp_fixup;

      tmp = stored_fixups[i].num_fixups_in_chain;
      stored_fixups[i].num_fixups_in_chain = num_fixups;
      num_fixups = tmp;

      for (tmp = GAS_CGEN_MAX_FIXUPS; tmp--;)
	{
	  tmp_fixup = stored_fixups[i].fixup_chain [tmp];
	  stored_fixups[i].fixup_chain[tmp] = fixups [tmp];
	  fixups [tmp] = tmp_fixup;
	}
    }
}

/* Default routine to record a fixup.
   This is a cover function to fix_new.
   It exists because we record INSN with the fixup.

   FRAG and WHERE are their respective arguments to fix_new_exp.
   LENGTH is in bits.
   OPINFO is something the caller chooses to help in reloc determination.

   At this point we do not use a bfd_reloc_code_real_type for
   operands residing in the insn, but instead just use the
   operand index.  This lets us easily handle fixups for any
   operand type.  We pick a BFD reloc type in md_apply_fix.  */

fixS *
gas_cgen_record_fixup (fragS *frag, int where, const CGEN_INSN *insn,
		       int length, const CGEN_OPERAND *operand, int opinfo,
		       symbolS *symbol, offsetT offset)
{
  fixS *fixP;

  /* It may seem strange to use operand->attrs and not insn->attrs here,
     but it is the operand that has a pc relative relocation.  */
  fixP = fix_new (frag, where, length / 8, symbol, offset,
		  CGEN_OPERAND_ATTR_VALUE (operand, CGEN_OPERAND_PCREL_ADDR),
		  (bfd_reloc_code_real_type)
		    ((int) BFD_RELOC_UNUSED
		     + (int) operand->type));
  fixP->fx_cgen.insn = insn;
  fixP->fx_cgen.opinfo = opinfo;
  fixP->fx_cgen.field = NULL;
  fixP->fx_cgen.msb_field_p = 0;

  return fixP;
}

/* Default routine to record a fixup given an expression.
   This is a cover function to fix_new_exp.
   It exists because we record INSN with the fixup.

   FRAG and WHERE are their respective arguments to fix_new_exp.
   LENGTH is in bits.
   OPINFO is something the caller chooses to help in reloc determination.

   At this point we do not use a bfd_reloc_code_real_type for
   operands residing in the insn, but instead just use the
   operand index.  This lets us easily handle fixups for any
   operand type.  We pick a BFD reloc type in md_apply_fix.  */

fixS *
gas_cgen_record_fixup_exp (fragS *frag, int where, const CGEN_INSN *insn,
			   int length, const CGEN_OPERAND *operand, int opinfo,
			   expressionS *exp)
{
  fixS *fixP;

  /* It may seem strange to use operand->attrs and not insn->attrs here,
     but it is the operand that has a pc relative relocation.  */
  fixP = fix_new_exp (frag, where, length / 8, exp,
		      CGEN_OPERAND_ATTR_VALUE (operand, CGEN_OPERAND_PCREL_ADDR),
		      (bfd_reloc_code_real_type)
		        ((int) BFD_RELOC_UNUSED
			 + (int) operand->type));
  fixP->fx_cgen.insn = insn;
  fixP->fx_cgen.opinfo = opinfo;
  fixP->fx_cgen.field = NULL;
  fixP->fx_cgen.msb_field_p = 0;

  return fixP;
}

#ifdef OBJ_COMPLEX_RELC
static symbolS *
expr_build_binary (operatorT op, symbolS * s1, symbolS * s2)
{
  expressionS e;

  e.X_op = op;
  e.X_add_symbol = s1;
  e.X_op_symbol = s2;
  e.X_add_number = 0;
  return make_expr_symbol (& e);
}
#endif

/* Used for communication between the next two procedures.  */
static jmp_buf expr_jmp_buf;
static int expr_jmp_buf_p;

/* Callback for cgen interface.  Parse the expression at *STRP.
   The result is an error message or NULL for success (in which case
   *STRP is advanced past the parsed text).
   WANT is an indication of what the caller is looking for.
   If WANT == CGEN_ASM_PARSE_INIT the caller is beginning to try to match
   a table entry with the insn, reset the queued fixups counter.
   An enum cgen_parse_operand_result is stored in RESULTP.
   OPINDEX is the operand's table entry index.
   OPINFO is something the caller chooses to help in reloc determination.
   The resulting value is stored in VALUEP.  */

const char *
gas_cgen_parse_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
		       	enum cgen_parse_operand_type want, const char **strP,
		       	int opindex, int opinfo,
		       	enum cgen_parse_operand_result *resultP,
		       	bfd_vma *valueP)
{
#ifdef __STDC__
  /* These are volatile to survive the setjmp.  */
  char * volatile hold;
  enum cgen_parse_operand_result * volatile resultP_1;
  volatile int opinfo_1;
#else
  static char *hold;
  static enum cgen_parse_operand_result *resultP_1;
  int opinfo_1;
#endif
  const char *errmsg;
  expressionS exp;

#ifdef OBJ_COMPLEX_RELC
  volatile int              signed_p = 0;
  symbolS *                 stmp = NULL;
  bfd_reloc_code_real_type  reloc_type;
  const CGEN_OPERAND *      operand;
  fixS                      dummy_fixup;
#endif
  if (want == CGEN_PARSE_OPERAND_INIT)
    {
      gas_cgen_init_parse ();
      return NULL;
    }

  resultP_1 = resultP;
  hold = input_line_pointer;
  input_line_pointer = (char *) *strP;
  opinfo_1 = opinfo;

  /* We rely on md_operand to longjmp back to us.
     This is done via gas_cgen_md_operand.  */
  if (setjmp (expr_jmp_buf) != 0)
    {
      expr_jmp_buf_p = 0;
      input_line_pointer = (char *) hold;
      *resultP_1 = CGEN_PARSE_OPERAND_RESULT_ERROR;
      return _("illegal operand");
    }

  expr_jmp_buf_p = 1;
  expression (&exp);
  expr_jmp_buf_p = 0;
  errmsg = NULL;

  *strP = input_line_pointer;
  input_line_pointer = hold;

#ifdef TC_CGEN_PARSE_FIX_EXP
  opinfo_1 = TC_CGEN_PARSE_FIX_EXP (opinfo_1, & exp);
#endif

  /* FIXME: Need to check `want'.  */

  switch (exp.X_op)
    {
    case O_illegal:
      errmsg = _("illegal operand");
      *resultP = CGEN_PARSE_OPERAND_RESULT_ERROR;
      break;
    case O_absent:
      errmsg = _("missing operand");
      *resultP = CGEN_PARSE_OPERAND_RESULT_ERROR;
      break;
    case O_constant:
      if (want == CGEN_PARSE_OPERAND_SYMBOLIC)
	goto de_fault;
      *valueP = exp.X_add_number;
      *resultP = CGEN_PARSE_OPERAND_RESULT_NUMBER;
      break;
    case O_register:
      *valueP = exp.X_add_number;
      *resultP = CGEN_PARSE_OPERAND_RESULT_REGISTER;
      break;
    de_fault:
    default:
#ifdef OBJ_COMPLEX_RELC
      /* Look up operand, check to see if there's an obvious
	 overflow (this helps disambiguate some insn parses).  */
      operand = cgen_operand_lookup_by_num (cd, opindex);
      errmsg = weak_operand_overflow_check (& exp, operand);

      if (! errmsg)
	{
	  asymbol *bsym;

	  /* Fragment the expression as necessary, and queue a reloc.  */
	  memset (& dummy_fixup, 0, sizeof (fixS));

	  reloc_type = md_cgen_lookup_reloc (0, operand, & dummy_fixup);

	  if (exp.X_op == O_symbol
	      && reloc_type == BFD_RELOC_RELC
	      && symbol_constant_p (exp.X_add_symbol)
	      && (!symbol_symbolS (exp.X_add_symbol)
		  || (bsym = symbol_get_bfdsym (exp.X_add_symbol)) == NULL
		  || (bsym->section != expr_section
		      && bsym->section != absolute_section
		      && bsym->section != undefined_section)))
	    {
	      /* Local labels will have been (eagerly) turned into constants
		 by now, due to the inappropriately deep insight of the
		 expression parser.  Unfortunately make_expr_symbol
		 prematurely dives into the symbol evaluator, and in this
		 case it gets a bad answer, so we manually create the
		 expression symbol we want here.  */
	      stmp = symbol_create (FAKE_LABEL_NAME, expr_section,
				    &zero_address_frag, 0);
	      symbol_set_value_expression (stmp, & exp);
	    }
	  else
	    stmp = make_expr_symbol (& exp);

	  /* If this is a pc-relative RELC operand, we
	     need to subtract "." from the expression.  */
 	  if (reloc_type == BFD_RELOC_RELC
	      && CGEN_OPERAND_ATTR_VALUE (operand, CGEN_OPERAND_PCREL_ADDR))
 	    stmp = expr_build_binary (O_subtract, stmp, expr_build_dot ());

	  /* FIXME: this is not a perfect heuristic for figuring out
	     whether an operand is signed: it only works when the operand
	     is an immediate. it's not terribly likely that any other
	     values will be signed relocs, but it's possible. */
	  if (operand && (operand->hw_type == HW_H_SINT))
	    signed_p = 1;

	  if (symbol_symbolS (stmp)
	      && (bsym = symbol_get_bfdsym (stmp)) != NULL
	      && bsym->section == expr_section
	      && ! S_IS_LOCAL (stmp))
	    {
	      if (signed_p)
		bsym->flags |= BSF_SRELC;
	      else
		bsym->flags |= BSF_RELC;
	    }

	  /* Now package it all up for the fixup emitter.  */
	  exp.X_op = O_symbol;
	  exp.X_op_symbol = 0;
	  exp.X_add_symbol = stmp;
	  exp.X_add_number = 0;

	  /* Re-init rightshift quantity, just in case.  */
	  rightshift = operand->length;
	  queue_fixup_recursively (opindex, opinfo_1, & exp,
				   (reloc_type == BFD_RELOC_RELC) ?
				   & (operand->index_fields) : 0,
				   signed_p, -1);
	}
      * resultP = errmsg
	? CGEN_PARSE_OPERAND_RESULT_ERROR
	: CGEN_PARSE_OPERAND_RESULT_QUEUED;
      *valueP = 0;
#else
      queue_fixup (opindex, opinfo_1, &exp);
      *valueP = 0;
      *resultP = CGEN_PARSE_OPERAND_RESULT_QUEUED;
#endif
      break;
    }

  return errmsg;
}

/* md_operand handler to catch unrecognized expressions and halt the
   parsing process so the next entry can be tried.

   ??? This could be done differently by adding code to `expression'.  */

void
gas_cgen_md_operand (expressionS *expressionP ATTRIBUTE_UNUSED)
{
  /* Don't longjmp if we're not called from within cgen_parse_operand().  */
  if (expr_jmp_buf_p)
    longjmp (expr_jmp_buf, 1);
}

/* Finish assembling instruction INSN.
   BUF contains what we've built up so far.
   LENGTH is the size of the insn in bits.
   RELAX_P is non-zero if relaxable insns should be emitted as such.
   Otherwise they're emitted in non-relaxable forms.
   The "result" is stored in RESULT if non-NULL.  */

void
gas_cgen_finish_insn (const CGEN_INSN *insn, CGEN_INSN_BYTES_PTR buf,
		      unsigned int length, int relax_p, finished_insnS *result)
{
  int i;
  int relax_operand;
  char *f;
  unsigned int byte_len = length / 8;

  /* ??? Target foo issues various warnings here, so one might want to provide
     a hook here.  However, our caller is defined in tc-foo.c so there
     shouldn't be a need for a hook.  */

  /* Write out the instruction.
     It is important to fetch enough space in one call to `frag_more'.
     We use (f - frag_now->fr_literal) to compute where we are and we
     don't want frag_now to change between calls.

     Relaxable instructions: We need to ensure we allocate enough
     space for the largest insn.  */

  if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXED))
    /* These currently shouldn't get here.  */
    abort ();

  /* Is there a relaxable insn with the relaxable operand needing a fixup?  */

  relax_operand = -1;
  if (relax_p && CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXABLE))
    {
      /* Scan the fixups for the operand affected by relaxing
	 (i.e. the branch address).  */

      for (i = 0; i < num_fixups; ++i)
	{
	  if (CGEN_OPERAND_ATTR_VALUE (cgen_operand_lookup_by_num (gas_cgen_cpu_desc, fixups[i].opindex),
				       CGEN_OPERAND_RELAX))
	    {
	      relax_operand = i;
	      break;
	    }
	}
    }

  if (relax_operand != -1)
    {
      int max_len;
      fragS *old_frag;
      expressionS *exp;
      symbolS *sym;
      offsetT off;

#ifdef TC_CGEN_MAX_RELAX
      max_len = TC_CGEN_MAX_RELAX (insn, byte_len);
#else
      max_len = CGEN_MAX_INSN_SIZE;
#endif
      /* Ensure variable part and fixed part are in same fragment.  */
      /* FIXME: Having to do this seems like a hack.  */
      frag_grow (max_len);

      /* Allocate space for the fixed part.  */
      f = frag_more (byte_len);

      /* Create a relaxable fragment for this instruction.  */
      old_frag = frag_now;

      exp = &fixups[relax_operand].exp;
      sym = exp->X_add_symbol;
      off = exp->X_add_number;
      if (exp->X_op != O_constant && exp->X_op != O_symbol)
	{
	  /* Handle complex expressions.  */
	  sym = make_expr_symbol (exp);
	  off = 0;
	}

      frag_var (rs_machine_dependent,
		max_len - byte_len /* max chars */,
		0 /* variable part already allocated */,
		/* FIXME: When we machine generate the relax table,
		   machine generate a macro to compute subtype.  */
		1 /* subtype */,
		sym,
		off,
		f);

      /* Record the operand number with the fragment so md_convert_frag
	 can use gas_cgen_md_record_fixup to record the appropriate reloc.  */
      old_frag->fr_cgen.insn    = insn;
      old_frag->fr_cgen.opindex = fixups[relax_operand].opindex;
      old_frag->fr_cgen.opinfo  = fixups[relax_operand].opinfo;
      if (result)
	result->frag = old_frag;
    }
  else
    {
      f = frag_more (byte_len);
      if (result)
	result->frag = frag_now;
    }

  /* If we're recording insns as numbers (rather than a string of bytes),
     target byte order handling is deferred until now.  */
#if CGEN_INT_INSN_P
  cgen_put_insn_value (gas_cgen_cpu_desc, (unsigned char *) f, length, *buf,
                       gas_cgen_cpu_desc->insn_endian);
#else
  memcpy (f, buf, byte_len);
#endif

  /* Emit DWARF2 debugging information.  */
  dwarf2_emit_insn (byte_len);

  /* Create any fixups.  */
  for (i = 0; i < num_fixups; ++i)
    {
      fixS *fixP;
      const CGEN_OPERAND *operand =
	cgen_operand_lookup_by_num (gas_cgen_cpu_desc, fixups[i].opindex);

      /* Don't create fixups for these.  That's done during relaxation.
	 We don't need to test for CGEN_INSN_RELAXED as they can't get here
	 (see above).  */
      if (relax_p
	  && CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXABLE)
	  && CGEN_OPERAND_ATTR_VALUE (operand, CGEN_OPERAND_RELAX))
	continue;

#ifndef md_cgen_record_fixup_exp
#define md_cgen_record_fixup_exp gas_cgen_record_fixup_exp
#endif

      fixP = md_cgen_record_fixup_exp (frag_now, f - frag_now->fr_literal,
				       insn, length, operand,
				       fixups[i].opinfo,
				       &fixups[i].exp);
      fixP->fx_cgen.field = fixups[i].field;
      fixP->fx_cgen.msb_field_p = fixups[i].msb_field_p;
      if (result)
	result->fixups[i] = fixP;
    }

  if (result)
    {
      result->num_fixups = num_fixups;
      result->addr = f;
    }
}

#ifdef OBJ_COMPLEX_RELC
/* Queue many fixups, recursively. If the field is a multi-ifield,
   repeatedly queue its sub-parts, right shifted to fit into the field (we
   assume here multi-fields represent a left-to-right, MSB0-LSB0
   reading). */

static void
queue_fixup_recursively (const int                      opindex,
			 const int                      opinfo,
			 expressionS *                  expP,
			 const CGEN_MAYBE_MULTI_IFLD *  field,
			 const int                      signed_p,
			 const int                      part_of_multi)
{
  if (field && field->count)
    {
      int i;

      for (i = 0; i < field->count; ++ i)
	queue_fixup_recursively (opindex, opinfo, expP,
				 & (field->val.multi[i]), signed_p, i);
    }
  else
    {
      expressionS * new_exp = expP;

#ifdef DEBUG
      printf ("queueing fixup for field %s\n",
	      (field ? field->val.leaf->name : "??"));
      print_symbol_value (expP->X_add_symbol);
#endif
      if (field && part_of_multi != -1)
	{
	  rightshift -= field->val.leaf->length;

	  /* Shift reloc value by number of bits remaining after this
	     field.  */
	  if (rightshift)
	    new_exp = make_right_shifted_expr (expP, rightshift, signed_p);
	}

      /* Truncate reloc values to length, *after* leftmost one.  */
      fixups[num_fixups].msb_field_p = (part_of_multi <= 0);
      fixups[num_fixups].field = (CGEN_MAYBE_MULTI_IFLD *) field;

      queue_fixup (opindex, opinfo, new_exp);
    }
}

/* Encode the self-describing RELC reloc format's addend.  */

static unsigned long
gas_cgen_encode_addend (const unsigned long start,    /* in bits */
			const unsigned long len,      /* in bits */
			const unsigned long oplen,    /* in bits */
			const unsigned long wordsz,   /* in bytes */
			const unsigned long chunksz,  /* in bytes */
			const unsigned long signed_p,
			const unsigned long trunc_p)
{
  unsigned long res = 0L;

  res |= start    & 0x3F;
  res |= (oplen   & 0x3F) << 6;
  res |= (len     & 0x3F) << 12;
  res |= (wordsz  & 0xF)  << 18;
  res |= (chunksz & 0xF)  << 22;
  res |= (CGEN_INSN_LSB0_P ? 1 : 0) << 27;
  res |= signed_p << 28;
  res |= trunc_p << 29;

  return res;
}

/* Purpose: make a weak check that the expression doesn't overflow the
   operand it's to be inserted into.

   Rationale: some insns used to use %operators to disambiguate during a
   parse. when these %operators are translated to expressions by the macro
   expander, the ambiguity returns. we attempt to disambiguate by field
   size.

   Method: check to see if the expression's top node is an O_and operator,
   and the mask is larger than the operand length. This would be an
   overflow, so signal it by returning an error string. Any other case is
   ambiguous, so we assume it's OK and return NULL.  */

static const char *
weak_operand_overflow_check (const expressionS *  exp,
			     const CGEN_OPERAND * operand)
{
  const unsigned long len = operand->length;
  unsigned long mask;
  unsigned long opmask = len == 0 ? 0 : (1UL << (len - 1) << 1) - 1;

  if (!exp)
    return NULL;

  if (exp->X_op != O_bit_and)
    {
      /* Check for implicit overflow flag.  */
      if (CGEN_OPERAND_ATTR_VALUE
	  (operand, CGEN_OPERAND_RELOC_IMPLIES_OVERFLOW))
	return _("a reloc on this operand implies an overflow");
      return NULL;
    }

  mask = exp->X_add_number;

  if (exp->X_add_symbol
      && symbol_constant_p (exp->X_add_symbol))
    mask |= *symbol_X_add_number (exp->X_add_symbol);

  if (exp->X_op_symbol
      && symbol_constant_p (exp->X_op_symbol))
    mask |= *symbol_X_add_number (exp->X_op_symbol);

  /* Want to know if mask covers more bits than opmask.
     this is the same as asking if mask has any bits not in opmask,
     or whether (mask & ~opmask) is nonzero.  */
  if (mask && (mask & ~opmask))
    {
#ifdef DEBUG
      printf ("overflow: (mask = %8.8x, ~opmask = %8.8x, AND = %8.8x)\n",
	      mask, ~opmask, (mask & ~opmask));
#endif
      return _("operand mask overflow");
    }

  return NULL;
}

static expressionS *
make_right_shifted_expr (expressionS * exp,
			 const int     amount,
			 const int     signed_p)
{
  symbolS * stmp = 0;
  expressionS * new_exp;
  asymbol *bsym;

  stmp = expr_build_binary (O_right_shift,
			    make_expr_symbol (exp),
			    expr_build_uconstant (amount));
  bsym = symbol_get_bfdsym (stmp);

  if (signed_p)
    bsym->flags |= BSF_SRELC;
  else
    bsym->flags |= BSF_RELC;

  /* Then wrap that in a "symbol expr" for good measure.  */
  new_exp = XNEW (expressionS);
  memset (new_exp, 0, sizeof (expressionS));
  new_exp->X_op = O_symbol;
  new_exp->X_op_symbol = 0;
  new_exp->X_add_symbol = stmp;
  new_exp->X_add_number = 0;

  return new_exp;
}

#endif

/* Apply a fixup to the object code.  This is called for all the
   fixups we generated by the call to fix_new_exp, above.  In the call
   above we used a reloc code which was the largest legal reloc code
   plus the operand index.  Here we undo that to recover the operand
   index.  At this point all symbol values should be fully resolved,
   and we attempt to completely resolve the reloc.  If we can not do
   that, we determine the correct reloc code and put it back in the fixup.  */

/* FIXME: This function handles some of the fixups and bfd_install_relocation
   handles the rest.  bfd_install_relocation (or some other bfd function)
   should handle them all.  */

void
gas_cgen_md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
{
  char *where = fixP->fx_frag->fr_literal + fixP->fx_where;
  valueT value = * valP;
  /* Canonical name, since used a lot.  */
  CGEN_CPU_DESC cd = gas_cgen_cpu_desc;

  if (fixP->fx_addsy == (symbolS *) NULL)
    fixP->fx_done = 1;

  /* We don't actually support subtracting a symbol.  */
  if (fixP->fx_subsy != (symbolS *) NULL)
    as_bad_where (fixP->fx_file, fixP->fx_line, _("expression too complex"));

  if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED)
    {
      int opindex = (int) fixP->fx_r_type - (int) BFD_RELOC_UNUSED;
      const CGEN_OPERAND *operand = cgen_operand_lookup_by_num (cd, opindex);
      const char *errmsg;
      bfd_reloc_code_real_type reloc_type;
      const CGEN_INSN *insn = fixP->fx_cgen.insn;
#ifdef OBJ_COMPLEX_RELC
      int start;
      int length;
      int signed_p = 0;

      if (fixP->fx_cgen.field)
	{
	  /* Use the twisty little pointer path
	     back to the ifield if it exists.  */
	  start = fixP->fx_cgen.field->val.leaf->start;
	  length = fixP->fx_cgen.field->val.leaf->length;
	}
      else
	{
	  /* Or the far less useful operand-size guesstimate.  */
	  start = operand->start;
	  length = operand->length;
	}

      /* FIXME: this is not a perfect heuristic for figuring out
         whether an operand is signed: it only works when the operand
         is an immediate. it's not terribly likely that any other
         values will be signed relocs, but it's possible. */
      if (operand && (operand->hw_type == HW_H_SINT))
        signed_p = 1;
#endif

      /* If the reloc has been fully resolved finish the operand here.  */
      /* FIXME: This duplicates the capabilities of code in BFD.  */
      if (fixP->fx_done
	  /* FIXME: If partial_inplace isn't set bfd_install_relocation won't
	     finish the job.  Testing for pcrel is a temporary hack.  */
	  || fixP->fx_pcrel)
	{
	  CGEN_FIELDS *fields = xmalloc (CGEN_CPU_SIZEOF_FIELDS (cd));

	  CGEN_CPU_SET_FIELDS_BITSIZE (cd) (fields, CGEN_INSN_BITSIZE (insn));
	  CGEN_CPU_SET_VMA_OPERAND (cd) (cd, opindex, fields, (bfd_vma) value);

#if CGEN_INT_INSN_P
	  {
	    CGEN_INSN_INT insn_value =
	      cgen_get_insn_value (cd, (unsigned char *) where,
				   CGEN_INSN_BITSIZE (insn),
                                   cd->insn_endian);

	    /* ??? 0 is passed for `pc'.  */
	    errmsg = CGEN_CPU_INSERT_OPERAND (cd) (cd, opindex, fields,
						   &insn_value, (bfd_vma) 0);
	    cgen_put_insn_value (cd, (unsigned char *) where,
				 CGEN_INSN_BITSIZE (insn), insn_value,
                                 cd->insn_endian);
	  }
#else
	  /* ??? 0 is passed for `pc'.  */
	  errmsg = CGEN_CPU_INSERT_OPERAND (cd) (cd, opindex, fields,
						 (unsigned char *) where,
						 (bfd_vma) 0);
#endif
	  if (errmsg)
	    as_bad_where (fixP->fx_file, fixP->fx_line, "%s", errmsg);

	  free (fields);
	}

      if (fixP->fx_done)
	return;

      /* The operand isn't fully resolved.  Determine a BFD reloc value
	 based on the operand information and leave it to
	 bfd_install_relocation.  Note that this doesn't work when
	 partial_inplace == false.  */

      reloc_type = md_cgen_lookup_reloc (insn, operand, fixP);
#ifdef OBJ_COMPLEX_RELC
      if (reloc_type == BFD_RELOC_RELC)
	{
	  /* Change addend to "self-describing" form,
	     for BFD to handle in the linker.  */
	  value = gas_cgen_encode_addend (start, operand->length,
					  length, fixP->fx_size,
					  cd->insn_chunk_bitsize / 8,
					  signed_p,
					  ! (fixP->fx_cgen.msb_field_p));
	}
#endif

      if (reloc_type != BFD_RELOC_NONE)
	fixP->fx_r_type = reloc_type;
      else
	{
	  as_bad_where (fixP->fx_file, fixP->fx_line,
			_("unresolved expression that must be resolved"));
	  fixP->fx_done = 1;
	  return;
	}
    }
  else if (fixP->fx_done)
    {
      /* We're finished with this fixup.  Install it because
	 bfd_install_relocation won't be called to do it.  */
      switch (fixP->fx_r_type)
	{
	case BFD_RELOC_8:
	  md_number_to_chars (where, value, 1);
	  break;
	case BFD_RELOC_16:
	  md_number_to_chars (where, value, 2);
	  break;
	case BFD_RELOC_32:
	  md_number_to_chars (where, value, 4);
	  break;
	case BFD_RELOC_64:
	  md_number_to_chars (where, value, 8);
	  break;
	default:
	  as_bad_where (fixP->fx_file, fixP->fx_line,
			_("internal error: can't install fix for reloc type %d (`%s')"),
			fixP->fx_r_type, bfd_get_reloc_code_name (fixP->fx_r_type));
	  break;
	}
    }
  /* else
     bfd_install_relocation will be called to finish things up.  */

  /* Tuck `value' away for use by tc_gen_reloc.
     See the comment describing fx_addnumber in write.h.
     This field is misnamed (or misused :-).  */
  fixP->fx_addnumber = value;
}

bfd_reloc_code_real_type
gas_cgen_pcrel_r_type (bfd_reloc_code_real_type r)
{
  switch (r)
    {
    case BFD_RELOC_8:  r = BFD_RELOC_8_PCREL;  break;
    case BFD_RELOC_16: r = BFD_RELOC_16_PCREL; break;
    case BFD_RELOC_24: r = BFD_RELOC_24_PCREL; break;
    case BFD_RELOC_32: r = BFD_RELOC_32_PCREL; break;
    case BFD_RELOC_64: r = BFD_RELOC_64_PCREL; break;
    default:
      break;
    }
  return r;
}

/* Translate internal representation of relocation info to BFD target format.

   FIXME: To what extent can we get all relevant targets to use this?  */

arelent *
gas_cgen_tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixP)
{
  bfd_reloc_code_real_type r_type = fixP->fx_r_type;
  arelent *reloc;

  reloc = XNEW (arelent);

#ifdef GAS_CGEN_PCREL_R_TYPE
  if (fixP->fx_pcrel)
    r_type = GAS_CGEN_PCREL_R_TYPE (r_type);
#endif
  reloc->howto = bfd_reloc_type_lookup (stdoutput, r_type);

  if (reloc->howto == (reloc_howto_type *) NULL)
    {
      as_bad_where (fixP->fx_file, fixP->fx_line,
		    _("relocation is not supported"));
      return NULL;
    }

  gas_assert (!fixP->fx_pcrel == !reloc->howto->pc_relative);

  reloc->sym_ptr_ptr = XNEW (asymbol *);
  *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);

  /* Use fx_offset for these cases.  */
  if (fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY
      || fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT)
    reloc->addend = fixP->fx_offset;
  else
    reloc->addend = fixP->fx_addnumber;

  reloc->address = fixP->fx_frag->fr_address + fixP->fx_where;
  return reloc;
}

/* Perform any cgen specific initialisation.
   Called after gas_cgen_cpu_desc has been created.  */

void
gas_cgen_begin (void)
{
  if (flag_signed_overflow_ok)
    cgen_set_signed_overflow_ok (gas_cgen_cpu_desc);
  else
    cgen_clear_signed_overflow_ok (gas_cgen_cpu_desc);
}
