FreeBSD/contrib/binutils/gas/config/tc-mips.c
/* Handle a mips16 instruction with an immediate value.  This or's the
   small immediate value into *INSN.  It sets *USE_EXTEND to indicate
   whether an extended value is needed; if one is needed, it sets
   *EXTEND to the value.  The argument type is TYPE.  The value is VAL.
   If SMALL is true, an unextended opcode was explicitly requested.
   If EXT is true, an extended opcode was explicitly requested.  If
   WARN is true, warn if EXT does not match reality.  */
Handle a mips16 instruction with an immediate value.  This or's the
small immediate value into *INSN.  It sets *USE_EXTEND to indicate
whether an extended value is needed; if one is needed, it sets
EXTEND to the value.  The argument type is TYPE.  The value is VAL.
If SMALL is true, an unextended opcode was explicitly requested.
If EXT is true, an extended opcode was explicitly requested.  If
WARN is true, warn if EXT does not match reality.
Handle a mips16 instruction with an immediate value . This or ' s the small immediate value into * INSN . It sets * USE_EXTEND to indicate whether an extended value is needed ; if one is needed it sets EXTEND to the value . The argument type is TYPE . The value is VAL . If SMALL is true an unextended opcode was explicitly requested . If EXT is true an extended opcode was explicitly requested . If WARN is true warn if EXT does not match reality .
static void
mips16_immed (char *file, unsigned int line, int type, offsetT val,
	      bfd_boolean warn, bfd_boolean small, bfd_boolean ext,
	      unsigned long *insn, bfd_boolean *use_extend,
	      unsigned short *extend)
{
  const struct mips16_immed_operand *op;
  int mintiny, maxtiny;
  bfd_boolean needext;
  op = mips16_immed_operands;
  while (op->type != type)
    {
      ++op;
      assert (op < mips16_immed_operands + MIPS16_NUM_IMMED);
    }
  if (op->unsp)
    {
      if (type == '<' || type == '>' || type == '[' || type == ']')
	{
	  mintiny = 1;
	  maxtiny = 1 << op->nbits;
	}
      else
	{
	  mintiny = 0;
	  maxtiny = (1 << op->nbits) - 1;
	}
    }
  else
    {
      mintiny = - (1 << (op->nbits - 1));
      maxtiny = (1 << (op->nbits - 1)) - 1;
    }
  if (type == 'p' || type == 'q')
    val /= 2;
  if ((val & ((1 << op->shift) - 1)) != 0
      || val < (mintiny << op->shift)
      || val > (maxtiny << op->shift))
    needext = TRUE;
  else
    needext = FALSE;
  if (warn && ext && ! needext)
    as_warn_where (file, line,
		   _("extended operand requested but not required"));
  if (small && needext)
    as_bad_where (file, line, _("invalid unextended operand value"));
  if (small || (! ext && ! needext))
    {
      int insnval;
      *use_extend = FALSE;
      insnval = ((val >> op->shift) & ((1 << op->nbits) - 1));
      insnval <<= op->op_shift;
      *insn |= insnval;
    }
  else
    {
      long minext, maxext;
      int extval;
      if (op->extu)
	{
	  minext = 0;
	  maxext = (1 << op->extbits) - 1;
	}
      else
	{
	  minext = - (1 << (op->extbits - 1));
	  maxext = (1 << (op->extbits - 1)) - 1;
	}
      if (val < minext || val > maxext)
	as_bad_where (file, line,
		      _("operand value out of range for instruction"));
      *use_extend = TRUE;
      if (op->extbits == 16)
	{
	  extval = ((val >> 11) & 0x1f) | (val & 0x7e0);
	  val &= 0x1f;
	}
      else if (op->extbits == 15)
	{
	  extval = ((val >> 11) & 0xf) | (val & 0x7f0);
	  val &= 0xf;
	}
      else
	{
	  extval = ((val & 0x1f) << 6) | (val & 0x20);
	  val = 0;
	}
      *extend = (unsigned short) extval;
      *insn |= val;
    }
}
static void mips16_immed ( char * file , unsigned int line , int type , offsetT val , bfd_boolean warn , bfd_boolean small , bfd_boolean ext , unsigned long * insn , bfd_boolean * use_extend , unsigned short * extend ) { const struct mips16_immed_operand * op ; int mintiny , maxtiny ; bfd_boolean needext ; op = mips16_immed_operands ; while ( op -> type != type ) { ++ op ; assert ( op < mips16_immed_operands + MIPS16_NUM_IMMED ) ; } if ( op -> unsp ) { if ( type == ' ' || type == ' ' || type == ' ' || type == ' ' ) { mintiny = 1 ; maxtiny = 1 << op -> nbits ; } else { mintiny = 0 ; maxtiny = ( 1 << op -> nbits ) - 1 ; } } else { mintiny = - ( 1 << ( op -> nbits - 1 ) ) ; maxtiny = ( 1 << ( op -> nbits - 1 ) ) - 1 ; } if ( type == ' ' || type == ' ' ) val /= 2 ; if ( ( val & ( ( 1 << op -> shift ) - 1 ) ) != 0 || val < ( mintiny << op -> shift ) || val > ( maxtiny << op -> shift ) ) needext = TRUE ; else needext = FALSE ; if ( warn && ext && ! needext ) as_warn_where ( file , line , _ ( " " ) ) ; if ( small && needext ) as_bad_where ( file , line , _ ( " " ) ) ; if ( small || ( ! ext && ! needext ) ) { int insnval ; * use_extend = FALSE ; insnval = ( ( val >> op -> shift ) & ( ( 1 << op -> nbits ) - 1 ) ) ; insnval <<= op -> op_shift ; * insn |= insnval ; } else { long minext , maxext ; int extval ; if ( op -> extu ) { minext = 0 ; maxext = ( 1 << op -> extbits ) - 1 ; } else { minext = - ( 1 << ( op -> extbits - 1 ) ) ; maxext = ( 1 << ( op -> extbits - 1 ) ) - 1 ; } if ( val < minext || val > maxext ) as_bad_where ( file , line , _ ( " " ) ) ; * use_extend = TRUE ; if ( op -> extbits == 16 ) { extval = ( ( val >> 11 ) & 0x1f ) | ( val & 0x7e0 ) ; val &= 0x1f ; } else if ( op -> extbits == 15 ) { extval = ( ( val >> 11 ) & 0xf ) | ( val & 0x7f0 ) ; val &= 0xf ; } else { extval = ( ( val & 0x1f ) << 6 ) | ( val & 0x20 ) ; val = 0 ; } * extend = ( unsigned short ) extval ; * insn |= val ; } }
Handle a mips16 instruction with an immediate value.
Handle a mips16 instruction with an immediate value .
/* Branch offsets have an implicit 0 in the lowest bit.  */