void Interpreter::psq_stux(UGeckoInstruction _inst)
{
	const UGQR gqr(rSPR(SPR_GQR0 + _inst.Ix));
	const EQuantizeType stType = static_cast<EQuantizeType>(gqr.ST_TYPE);
	const unsigned int stScale = gqr.ST_SCALE;
	const u32 EA = m_GPR[_inst.RA] + m_GPR[_inst.RB];

	int c = 4;
	if (stType == QUANTIZE_U8 || stType == QUANTIZE_S8)
		c = 0x1;
	else if (stType == QUANTIZE_U16 || stType == QUANTIZE_S16)
		c = 0x2;

	if (_inst.Wx == 0)
	{
		Helper_Quantize(EA,     rPS0(_inst.RS), stType, stScale);
		Helper_Quantize(EA + c, rPS1(_inst.RS), stType, stScale);
	}
	else
	{
		Helper_Quantize(EA, rPS0(_inst.RS), stType, stScale);
	}
	if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI)
	{
		return;
	}
	m_GPR[_inst.RA] = EA;

}  // namespace=======
void Interpreter::psq_lux(UGeckoInstruction _inst)
{
	const UGQR gqr(rSPR(SPR_GQR0 + _inst.Ix));
	const EQuantizeType ldType = static_cast<EQuantizeType>(gqr.LD_TYPE);
	const unsigned int ldScale = gqr.LD_SCALE;
	const u32 EA = m_GPR[_inst.RA] + m_GPR[_inst.RB];

	int c = 4;
	if ((ldType == 4) || (ldType == 6)) c = 0x1;
	if ((ldType == 5) || (ldType == 7)) c = 0x2;

	if (_inst.Wx == 0)
	{
		float ps0 = Helper_Dequantize( EA,   ldType, ldScale );
		float ps1 = Helper_Dequantize( EA+c, ldType, ldScale );
		if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI)
		{
			return;
		}
		rPS0(_inst.RS) = ps0;
		rPS1(_inst.RS) = ps1;
	}
	else
	{
		float ps0 = Helper_Dequantize( EA, ldType, ldScale );
		if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI)
		{
			return;
		}
		rPS0(_inst.RS) = ps0;
		rPS1(_inst.RS) = 1.0f;
	}
	m_GPR[_inst.RA] = EA;
}
void Interpreter::psq_stu(UGeckoInstruction _inst)
{
	const UGQR gqr(rSPR(SPR_GQR0 + _inst.I));
	const EQuantizeType stType = static_cast<EQuantizeType>(gqr.ST_TYPE);
	const unsigned int stScale = gqr.ST_SCALE;
	const u32 EA = m_GPR[_inst.RA] + _inst.SIMM_12;

	int c = 4;
	if ((stType == 4) || (stType == 6)) c = 0x1;
	if ((stType == 5) || (stType == 7)) c = 0x2;

	if (_inst.W == 0)
	{
		Helper_Quantize(EA,   rPS0(_inst.RS), stType, stScale);
		Helper_Quantize(EA+c, rPS1(_inst.RS), stType, stScale);
	}
	else
	{
		Helper_Quantize(EA,   rPS0(_inst.RS), stType, stScale);
	}
	if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI)
	{
		return;
	}
	m_GPR[_inst.RA] = EA;
}
Пример #4
0
// Internal inverse square root function in the crazy math lib. 
void FZ_rsqrt_internal()
{
	double f = 1.0 / sqrt(rPS0(1));
	rPS0(1) = f;
	rPS1(1) = f;
	NPC = LR;
}
void Interpreter::psq_l(UGeckoInstruction _inst)
{
	const UGQR gqr(rSPR(SPR_GQR0 + _inst.I));
	const EQuantizeType ldType = static_cast<EQuantizeType>(gqr.LD_TYPE);
	const unsigned int ldScale = gqr.LD_SCALE;
	const u32 EA = _inst.RA ?
		(m_GPR[_inst.RA] + _inst.SIMM_12) : (u32)_inst.SIMM_12;

	int c = 4;
	if ((ldType == QUANTIZE_U8)  || (ldType == QUANTIZE_S8))  c = 0x1;
	if ((ldType == QUANTIZE_U16) || (ldType == QUANTIZE_S16)) c = 0x2;

	if (_inst.W == 0)
	{
		float ps0 = Helper_Dequantize(EA,   ldType, ldScale);
		float ps1 = Helper_Dequantize(EA+c, ldType, ldScale);
		if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI)
		{
			return;
		}
		rPS0(_inst.RS) = ps0;
		rPS1(_inst.RS) = ps1;
	}
	else
	{
		float ps0 = Helper_Dequantize(EA,   ldType, ldScale);
		if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI)
		{
			return;
		}
		rPS0(_inst.RS) = ps0;
		rPS1(_inst.RS) = 1.0f;
	}
}
Пример #6
0
void FZ_sqrt() {
	u32 r3 = GPR(3);
	double x = rPS0(0);
	x = sqrt(x);
	FW(r3, (float)x);
	rPS0(0) = x;
	NPC = LR;
}
Пример #7
0
// Internal square root function in the crazy math lib. Acts a bit odd, just read it. It's not a bug :p
void FZ_sqrt_internal()
{
	double f = sqrt(rPS0(1));
	rPS0(0) = rPS0(1);
	rPS1(0) = rPS0(1);
	rPS0(1) = f;
	rPS1(1) = f;
	NPC = LR;
}
Пример #8
0
void SMB_atan2()
{
	// in: f1 = x, f2 = y
	// out: r3 = angle
	double angle = atan2(rPS0(1), rPS0(2));
	int angle_fixpt = (int)(angle / 3.14159 * 32767);
	if (angle_fixpt < -32767) angle_fixpt = -32767;
	if (angle_fixpt > 32767) angle_fixpt = 32767;
	GPR(3) = angle_fixpt;
	NPC = LR;
}
Пример #9
0
void FZero_evil_vec_normalize()
{
	u32 r3 = GPR(3);
	float x = F(r3);
	float y = F(r3 + 4);
	float z = F(r3 + 8);
	float sq_len = x*x + y*y + z*z;
	float inv_len = 1.0f / sqrtf(sq_len);
	x *= inv_len;
	y *= inv_len;
	z *= inv_len;
	FW(r3, x);
	FW(r3 + 4, y);
	FW(r3 + 8, z);
	rPS0(1) = inv_len * sq_len;  // len
	rPS1(1) = inv_len * sq_len;  // len
	NPC = LR;

	/*
.evil_vec_something

(f6, f7, f8) <- [r3]
f1 = f6 * f6
f1 += f7 * f7
f1 += f8 * f8
f2 = mystery
f4 = f2 * f1
f3 = f2 + f2
f1 = 1/f0

f6 *= f1
f7 *= f1
f8 *= f1

8006d668: lis	r5, 0xE000
8006d684: lfs	f2, 0x01A0 (r5)
8006d69c: fmr	f0,f2
8006d6a0: fmuls	f4,f2,f1
8006d6a4: fadds	f3,f2,f2
8006d6a8: frsqrte	f1,f0,f1
8006d6ac: fadds	f3,f3,f2
8006d6b0: fmuls	f5,f1,f1
8006d6b4: fnmsubs	f5,f5,f4,f3
8006d6b8: fmuls	f1,f1,f5
8006d6bc: fmuls	f5,f1,f1
8006d6c0: fnmsubs	f5,f5,f4,f3
8006d6c4: fmuls	f1,f1,f5
8006d6c8: fmuls	f6,f6,f1
8006d6cc: stfs	f6, 0 (r3)
8006d6d0: fmuls	f7,f7,f1
8006d6d4: stfs	f7, 0x0004 (r3)
8006d6d8: fmuls	f8,f8,f1
8006d6dc: stfs	f8, 0x0008 (r3)
8006d6e0: fmuls	f1,f1,f0
8006d6e4: blr	
*/
	NPC = LR;
}
Пример #10
0
void Interpreter::lfsx(UGeckoInstruction _inst)
{
	u32 uTemp = Memory::Read_U32(Helper_Get_EA_X(_inst));
	if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
	{
		double value = *(float*)&uTemp;
		rPS0(_inst.FD) = value;
		rPS1(_inst.FD) = value;
	}
}
Пример #11
0
wxString CRegTable::FormatFPR(int reg_index, int reg_part)
{
  if (m_formatFRegs[reg_index][reg_part] == FormatSpecifier::Double)
  {
    double reg = (reg_part == 0) ? rPS0(reg_index) : rPS1(reg_index);
    return wxString::Format(GetFormatString(m_formatFRegs[reg_index][reg_part]), reg);
  }
  u64 reg = (reg_part == 0) ? riPS0(reg_index) : riPS1(reg_index);
  return wxString::Format(GetFormatString(m_formatFRegs[reg_index][reg_part]), reg);
}
void Interpreter::psq_stx(UGeckoInstruction _inst)
{
	const UGQR gqr(rSPR(SPR_GQR0 + _inst.Ix));
	const EQuantizeType stType = static_cast<EQuantizeType>(gqr.ST_TYPE);
	const unsigned int stScale = gqr.ST_SCALE;
	const u32 EA = _inst.RA ? (m_GPR[_inst.RA] + m_GPR[_inst.RB]) : m_GPR[_inst.RB];

	int c = 4;
	if ((stType == 4) || (stType == 6)) c = 0x1;
	if ((stType == 5) || (stType == 7)) c = 0x2;

	if (_inst.Wx == 0)
	{
		Helper_Quantize(EA,   rPS0(_inst.RS), stType, stScale);
		Helper_Quantize(EA+c, rPS1(_inst.RS), stType, stScale);
	}
	else
	{
		Helper_Quantize(EA,   rPS0(_inst.RS), stType, stScale);
	}
}
Пример #13
0
void Interpreter::lfsux(UGeckoInstruction _inst)
{
	u32 uAddress = Helper_Get_EA_UX(_inst);
	u32 uTemp = Memory::Read_U32(uAddress);
	if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
	{
		double value = *(float*)&uTemp;
		rPS0(_inst.FD) = value;
		rPS1(_inst.FD) = value;
		m_GPR[_inst.RA] = uAddress;
	}
}
void Interpreter::psq_st(UGeckoInstruction _inst)
{
	const UGQR gqr(rSPR(SPR_GQR0 + _inst.I));
	const EQuantizeType stType = static_cast<EQuantizeType>(gqr.ST_TYPE);
	const unsigned int stScale = gqr.ST_SCALE;
	const u32 EA = _inst.RA ?
		(m_GPR[_inst.RA] + _inst.SIMM_12) : (u32)_inst.SIMM_12;

	int c = 4;
	if (stType == QUANTIZE_U8 || stType == QUANTIZE_S8)
		c = 0x1;
	else if (stType == QUANTIZE_U16 || stType == QUANTIZE_S16)
		c = 0x2;

	if (_inst.W == 0)
	{
		Helper_Quantize(EA,     rPS0(_inst.RS), stType, stScale);
		Helper_Quantize(EA + c, rPS1(_inst.RS), stType, stScale);
	}
	else
	{
		Helper_Quantize(EA, rPS0(_inst.RS), stType, stScale);
	}
}
Пример #15
0
// Scales the vector pointed at by r3 to the length specified by f0.
// Writes results to vector pointed at by r4.
void SMB_evil_vec_setlength()
{
	u32 r3 = GPR(3);
	u32 r4 = GPR(4);
	float x = F(r3);
	float y = F(r3 + 4);
	float z = F(r3 + 8);
	float inv_len = (float)(rPS0(0) / sqrt(x*x + y*y + z*z));
	x *= inv_len;
	y *= inv_len;
	z *= inv_len;
	FW(r4, x);
	FW(r4 + 4, y);
	FW(r4 + 8, z);
	NPC = LR;
}
Пример #16
0
// Computes the cosine of the angle between the two fvec3s pointed at by r3 and r4.
void SMB_EvilVecCosine()
{
	u32 r3 = GPR(3);
	u32 r4 = GPR(4);

	float x1 = F(r3);
	float y1 = F(r3 + 4);
	float z1 = F(r3 + 8);

	float x2 = F(r4);
	float y2 = F(r4 + 4);
	float z2 = F(r4 + 8);

	float s1 = x1*x1 + y1*y1 + z1*z1;
	float s2 = x2*x2 + y2*y2 + z2*z2;
	
	float dot = x1*x2 + y1*y2 + z1*z2;

	rPS0(1) = dot / sqrtf(s1 * s2);
    NPC = LR;
}
Пример #17
0
void GetStringVA(std::string& _rOutBuffer, u32 strReg)
{
	_rOutBuffer = "";
	char ArgumentBuffer[256];
	u32 ParameterCounter = strReg+1;
	u32 FloatingParameterCounter = 1;
	char *pString = (char*)Memory::GetPointer(GPR(strReg));
	if (!pString)
	{
		ERROR_LOG(OSREPORT, "r%i invalid", strReg);
		return;
	}

	while (*pString)
	{
		if (*pString == '%')
		{
			char* pArgument = ArgumentBuffer;
			*pArgument++ = *pString++;
			if (*pString == '%') {
				_rOutBuffer += "%";
				pString++;
				continue;
			}
			while (*pString < 'A' || *pString > 'z' || *pString == 'l' || *pString == '-')
				*pArgument++ = *pString++;

			*pArgument++ = *pString;
			*pArgument = 0;

			u64 Parameter;
			if (ParameterCounter > 10)
			{
				Parameter = Memory::Read_U32(GPR(1) + 0x8 + ((ParameterCounter - 11) * 4));
			}
			else
			{
				if ((*(pString-2) == 'l') && (*(pString-1) == 'l')) // hax, just seen this on sysmenu osreport
				{
					Parameter = GPR(++ParameterCounter);
					Parameter = (Parameter<<32)|GPR(++ParameterCounter);
				}
				else // normal, 32bit
					Parameter = GPR(ParameterCounter);
			}
			ParameterCounter++;

			switch (*pString)
			{
			case 's':
				_rOutBuffer += StringFromFormat(ArgumentBuffer, (char*)Memory::GetPointer((u32)Parameter));
				break;

			case 'd':
			case 'i':
			{
				//u64 Double = Memory::Read_U64(Parameter);
				_rOutBuffer += StringFromFormat(ArgumentBuffer, Parameter);
				break;
			}

			case 'f':
			{
				_rOutBuffer += StringFromFormat(ArgumentBuffer,
												rPS0(FloatingParameterCounter));
				FloatingParameterCounter++;
				ParameterCounter--;
				break;
			}

			case 'p':
				// Override, so 64bit dolphin prints 32bit pointers, since the ppc is 32bit :)
				_rOutBuffer += StringFromFormat("%x", (u32)Parameter);
				break;

			default:
				_rOutBuffer += StringFromFormat(ArgumentBuffer, Parameter);
				break;
			}
			pString++;
		}
		else
		{
			_rOutBuffer += StringFromFormat("%c", *pString);
			pString++;
		}
	}
	if (_rOutBuffer[_rOutBuffer.length() - 1] == '\n')
		_rOutBuffer.resize(_rOutBuffer.length() - 1);
}
Пример #18
0
void GetStringVA(std::string& _rOutBuffer, u32 strReg)
{
  _rOutBuffer = "";
  std::string ArgumentBuffer = "";
  u32 ParameterCounter = strReg + 1;
  u32 FloatingParameterCounter = 1;
  std::string string = PowerPC::HostGetString(GPR(strReg));

  for (u32 i = 0; i < string.size(); i++)
  {
    if (string[i] == '%')
    {
      ArgumentBuffer = "%";
      i++;
      if (string[i] == '%')
      {
        _rOutBuffer += "%";
        continue;
      }
      while (string[i] < 'A' || string[i] > 'z' || string[i] == 'l' || string[i] == '-')
        ArgumentBuffer += string[i++];

      ArgumentBuffer += string[i];

      u64 Parameter;
      if (ParameterCounter > 10)
      {
        Parameter = PowerPC::HostRead_U32(GPR(1) + 0x8 + ((ParameterCounter - 11) * 4));
      }
      else
      {
        if (string[i - 1] == 'l' &&
            string[i - 2] == 'l')  // hax, just seen this on sysmenu osreport
        {
          Parameter = GPR(++ParameterCounter);
          Parameter = (Parameter << 32) | GPR(++ParameterCounter);
        }
        else  // normal, 32bit
          Parameter = GPR(ParameterCounter);
      }
      ParameterCounter++;

      switch (string[i])
      {
      case 's':
        _rOutBuffer += StringFromFormat(ArgumentBuffer.c_str(),
                                        PowerPC::HostGetString((u32)Parameter).c_str());
        break;

      case 'd':
      case 'i':
      {
        _rOutBuffer += StringFromFormat(ArgumentBuffer.c_str(), Parameter);
        break;
      }

      case 'f':
      {
        _rOutBuffer += StringFromFormat(ArgumentBuffer.c_str(), rPS0(FloatingParameterCounter));
        FloatingParameterCounter++;
        ParameterCounter--;
        break;
      }

      case 'p':
        // Override, so 64bit Dolphin prints 32bit pointers, since the ppc is 32bit :)
        _rOutBuffer += StringFromFormat("%x", (u32)Parameter);
        break;

      default:
        _rOutBuffer += StringFromFormat(ArgumentBuffer.c_str(), Parameter);
        break;
      }
    }
    else
    {
      _rOutBuffer += string[i];
    }
  }
  if (!_rOutBuffer.empty() && _rOutBuffer[_rOutBuffer.length() - 1] == '\n')
    _rOutBuffer.resize(_rOutBuffer.length() - 1);
}
Пример #19
0
std::string GetStringVA(u32 strReg)
{
  std::string ArgumentBuffer;
  u32 ParameterCounter = strReg + 1;
  u32 FloatingParameterCounter = 1;

  std::string result;
  std::string string = PowerPC::HostGetString(GPR(strReg));

  for (size_t i = 0; i < string.size(); i++)
  {
    if (string[i] == '%')
    {
      ArgumentBuffer = '%';
      i++;
      if (string[i] == '%')
      {
        result += '%';
        continue;
      }
      while (string[i] < 'A' || string[i] > 'z' || string[i] == 'l' || string[i] == '-')
        ArgumentBuffer += string[i++];

      ArgumentBuffer += string[i];

      u64 Parameter;
      if (ParameterCounter > 10)
      {
        Parameter = PowerPC::HostRead_U32(GPR(1) + 0x8 + ((ParameterCounter - 11) * 4));
      }
      else
      {
        if (string[i - 1] == 'l' &&
            string[i - 2] == 'l')  // hax, just seen this on sysmenu osreport
        {
          Parameter = GPR(++ParameterCounter);
          Parameter = (Parameter << 32) | GPR(++ParameterCounter);
        }
        else  // normal, 32bit
          Parameter = GPR(ParameterCounter);
      }
      ParameterCounter++;

      switch (string[i])
      {
      case 's':
        result += StringFromFormat(ArgumentBuffer.c_str(),
                                   PowerPC::HostGetString((u32)Parameter).c_str());
        break;

      case 'd':
      case 'i':
      {
        result += StringFromFormat(ArgumentBuffer.c_str(), Parameter);
        break;
      }

      case 'f':
      {
        result += StringFromFormat(ArgumentBuffer.c_str(), rPS0(FloatingParameterCounter));
        FloatingParameterCounter++;
        ParameterCounter--;
        break;
      }

      case 'p':
        // Override, so 64bit Dolphin prints 32bit pointers, since the ppc is 32bit :)
        result += StringFromFormat("%x", (u32)Parameter);
        break;

      default:
        result += StringFromFormat(ArgumentBuffer.c_str(), Parameter);
        break;
      }
    }
    else
    {
      result += string[i];
    }
  }

  if (!result.empty() && result.back() == '\n')
    result.pop_back();

  return result;
}
Пример #20
0
double HLE::SystemVABI::VAList::GetFPR(u32 fpr) const
{
  return rPS0(fpr);
}