FreeBSD/contrib/binutils/gas/config/tc-mips.c
/* See whether instruction IP reads register REG.  CLASS is the type
   of register.  */
See whether instruction IP reads register REG.  CLASS is the type
of register.
See whether instruction IP reads register REG . CLASS is the type of register .
static int
insn_uses_reg (const struct mips_cl_insn *ip, unsigned int reg,
	       enum mips_regclass class)
{
  if (class == MIPS16_REG)
    {
      assert (mips_opts.mips16);
      reg = mips16_to_32_reg_map[reg];
      class = MIPS_GR_REG;
    }
  if (class == MIPS_GR_REG && reg == ZERO)
    return 0;
  if (class == MIPS_FP_REG)
    {
      assert (! mips_opts.mips16);
      if ((ip->insn_mo->pinfo & INSN_READ_FPR_S)
	  && ((EXTRACT_OPERAND (FS, *ip) & ~(unsigned) 1)
	      == (reg &~ (unsigned) 1)))
	return 1;
      if ((ip->insn_mo->pinfo & INSN_READ_FPR_T)
	  && ((EXTRACT_OPERAND (FT, *ip) & ~(unsigned) 1)
	      == (reg &~ (unsigned) 1)))
	return 1;
    }
  else if (! mips_opts.mips16)
    {
      if ((ip->insn_mo->pinfo & INSN_READ_GPR_S)
	  && EXTRACT_OPERAND (RS, *ip) == reg)
	return 1;
      if ((ip->insn_mo->pinfo & INSN_READ_GPR_T)
	  && EXTRACT_OPERAND (RT, *ip) == reg)
	return 1;
    }
  else
    {
      if ((ip->insn_mo->pinfo & MIPS16_INSN_READ_X)
	  && mips16_to_32_reg_map[MIPS16_EXTRACT_OPERAND (RX, *ip)] == reg)
	return 1;
      if ((ip->insn_mo->pinfo & MIPS16_INSN_READ_Y)
	  && mips16_to_32_reg_map[MIPS16_EXTRACT_OPERAND (RY, *ip)] == reg)
	return 1;
      if ((ip->insn_mo->pinfo & MIPS16_INSN_READ_Z)
	  && (mips16_to_32_reg_map[MIPS16_EXTRACT_OPERAND (MOVE32Z, *ip)]
	      == reg))
	return 1;
      if ((ip->insn_mo->pinfo & MIPS16_INSN_READ_T) && reg == TREG)
	return 1;
      if ((ip->insn_mo->pinfo & MIPS16_INSN_READ_SP) && reg == SP)
	return 1;
      if ((ip->insn_mo->pinfo & MIPS16_INSN_READ_31) && reg == RA)
	return 1;
      if ((ip->insn_mo->pinfo & MIPS16_INSN_READ_GPR_X)
	  && MIPS16_EXTRACT_OPERAND (REGR32, *ip) == reg)
	return 1;
    }
  return 0;
}
static int insn_uses_reg ( const struct mips_cl_insn * ip , unsigned int reg , enum mips_regclass class ) { if ( class == MIPS16_REG ) { assert ( mips_opts . mips16 ) ; reg = mips16_to_32_reg_map [ reg ] ; class = MIPS_GR_REG ; } if ( class == MIPS_GR_REG && reg == ZERO ) return 0 ; if ( class == MIPS_FP_REG ) { assert ( ! mips_opts . mips16 ) ; if ( ( ip -> insn_mo -> pinfo & INSN_READ_FPR_S ) && ( ( EXTRACT_OPERAND ( FS , * ip ) & ~ ( unsigned ) 1 ) == ( reg & ~ ( unsigned ) 1 ) ) ) return 1 ; if ( ( ip -> insn_mo -> pinfo & INSN_READ_FPR_T ) && ( ( EXTRACT_OPERAND ( FT , * ip ) & ~ ( unsigned ) 1 ) == ( reg & ~ ( unsigned ) 1 ) ) ) return 1 ; } else if ( ! mips_opts . mips16 ) { if ( ( ip -> insn_mo -> pinfo & INSN_READ_GPR_S ) && EXTRACT_OPERAND ( RS , * ip ) == reg ) return 1 ; if ( ( ip -> insn_mo -> pinfo & INSN_READ_GPR_T ) && EXTRACT_OPERAND ( RT , * ip ) == reg ) return 1 ; } else { if ( ( ip -> insn_mo -> pinfo & MIPS16_INSN_READ_X ) && mips16_to_32_reg_map [ MIPS16_EXTRACT_OPERAND ( RX , * ip ) ] == reg ) return 1 ; if ( ( ip -> insn_mo -> pinfo & MIPS16_INSN_READ_Y ) && mips16_to_32_reg_map [ MIPS16_EXTRACT_OPERAND ( RY , * ip ) ] == reg ) return 1 ; if ( ( ip -> insn_mo -> pinfo & MIPS16_INSN_READ_Z ) && ( mips16_to_32_reg_map [ MIPS16_EXTRACT_OPERAND ( MOVE32Z , * ip ) ] == reg ) ) return 1 ; if ( ( ip -> insn_mo -> pinfo & MIPS16_INSN_READ_T ) && reg == TREG ) return 1 ; if ( ( ip -> insn_mo -> pinfo & MIPS16_INSN_READ_SP ) && reg == SP ) return 1 ; if ( ( ip -> insn_mo -> pinfo & MIPS16_INSN_READ_31 ) && reg == RA ) return 1 ; if ( ( ip -> insn_mo -> pinfo & MIPS16_INSN_READ_GPR_X ) && MIPS16_EXTRACT_OPERAND ( REGR32 , * ip ) == reg ) return 1 ; } return 0 ; }
See whether instruction IP reads register REG.
See whether instruction IP reads register REG .
/* Don't report on general register ZERO, since it never changes.  */ /* If we are called with either $f0 or $f1, we must check $f0.
	 This is not optimal, because it will introduce an unnecessary
	 NOP between "lwc1 $f0" and "swc1 $f1".  To fix this we would
	 need to distinguish reading both $f0 and $f1 or just one of
	 them.  Note that we don't have to check the other way,
	 because there is no instruction that sets both $f0 and $f1
	 and requires a delay.  */