mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-23 03:02:53 +01:00
Support some instructions
This commit is contained in:
parent
1bd235616f
commit
3e7d42b023
@ -2404,7 +2404,7 @@ private:
|
|||||||
|
|
||||||
CPU.GPR[ra] = i;
|
CPU.GPR[ra] = i;
|
||||||
|
|
||||||
if(rc) CPU.SetCRBit(CR_LT, false);
|
if(rc) CPU.UpdateCR0<s64>(CPU.GPR[ra]);
|
||||||
}
|
}
|
||||||
void SLD(u32 ra, u32 rs, u32 rb, bool rc)
|
void SLD(u32 ra, u32 rs, u32 rb, bool rc)
|
||||||
{
|
{
|
||||||
@ -2488,7 +2488,7 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
CPU.GPR[ra] = i;
|
CPU.GPR[ra] = i;
|
||||||
if(rc) CPU.SetCRBit(CR_LT, false);
|
if(rc) CPU.UpdateCR0<s64>(CPU.GPR[ra]);
|
||||||
}
|
}
|
||||||
void ANDC(u32 ra, u32 rs, u32 rb, bool rc)
|
void ANDC(u32 ra, u32 rs, u32 rb, bool rc)
|
||||||
{
|
{
|
||||||
|
@ -146,7 +146,7 @@ void PPULLVMRecompiler::RequestCompilation(u32 address) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
u32 PPULLVMRecompiler::GetCurrentRevision() {
|
u32 PPULLVMRecompiler::GetCurrentRevision() {
|
||||||
return m_revision;
|
return m_revision.load(std::memory_order_relaxed);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPULLVMRecompiler::Task() {
|
void PPULLVMRecompiler::Task() {
|
||||||
@ -1244,6 +1244,7 @@ void PPULLVMRecompiler::CRANDC(u32 crbd, u32 crba, u32 crbb) {
|
|||||||
|
|
||||||
void PPULLVMRecompiler::ISYNC() {
|
void PPULLVMRecompiler::ISYNC() {
|
||||||
m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_mfence));
|
m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_mfence));
|
||||||
|
//InterpreterCall("ISYNC", &PPUInterpreter::ISYNC);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPULLVMRecompiler::CRXOR(u32 crbd, u32 crba, u32 crbb) {
|
void PPULLVMRecompiler::CRXOR(u32 crbd, u32 crba, u32 crbb) {
|
||||||
@ -1634,15 +1635,51 @@ void PPULLVMRecompiler::LWZX(u32 rd, u32 ra, u32 rb) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void PPULLVMRecompiler::SLW(u32 ra, u32 rs, u32 rb, bool rc) {
|
void PPULLVMRecompiler::SLW(u32 ra, u32 rs, u32 rb, bool rc) {
|
||||||
InterpreterCall("SLW", &PPUInterpreter::SLW, ra, rs, rb, rc);
|
auto rs_i32 = GetGpr(rs, 32);
|
||||||
|
auto rs_i64 = m_ir_builder->CreateZExt(rs_i32, m_ir_builder->getInt64Ty());
|
||||||
|
auto rb_i8 = GetGpr(rb, 8);
|
||||||
|
rb_i8 = m_ir_builder->CreateAnd(rb_i8, 0x3F);
|
||||||
|
auto rb_i64 = m_ir_builder->CreateZExt(rb_i8, m_ir_builder->getInt64Ty());
|
||||||
|
auto res_i64 = m_ir_builder->CreateShl(rs_i64, rb_i64);
|
||||||
|
auto res_i32 = m_ir_builder->CreateTrunc(res_i64, m_ir_builder->getInt32Ty());
|
||||||
|
res_i64 = m_ir_builder->CreateZExt(res_i32, m_ir_builder->getInt64Ty());
|
||||||
|
SetGpr(ra, res_i64);
|
||||||
|
|
||||||
|
if (rc) {
|
||||||
|
SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
//InterpreterCall("SLW", &PPUInterpreter::SLW, ra, rs, rb, rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPULLVMRecompiler::CNTLZW(u32 ra, u32 rs, bool rc) {
|
void PPULLVMRecompiler::CNTLZW(u32 ra, u32 rs, bool rc) {
|
||||||
InterpreterCall("CNTLZW", &PPUInterpreter::CNTLZW, ra, rs, rc);
|
auto rs_i32 = GetGpr(rs, 32);
|
||||||
|
auto res_i32 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::ctlz, {m_ir_builder->getInt32Ty()}), rs_i32, m_ir_builder->getInt1(false));
|
||||||
|
auto res_i64 = m_ir_builder->CreateZExt(res_i32, m_ir_builder->getInt64Ty());
|
||||||
|
SetGpr(ra, res_i64);
|
||||||
|
|
||||||
|
if (rc) {
|
||||||
|
SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
//InterpreterCall("CNTLZW", &PPUInterpreter::CNTLZW, ra, rs, rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPULLVMRecompiler::SLD(u32 ra, u32 rs, u32 rb, bool rc) {
|
void PPULLVMRecompiler::SLD(u32 ra, u32 rs, u32 rb, bool rc) {
|
||||||
InterpreterCall("SLD", &PPUInterpreter::SLD, ra, rs, rb, rc);
|
auto rs_i64 = GetGpr(rs);
|
||||||
|
auto rs_i128 = m_ir_builder->CreateZExt(rs_i64, m_ir_builder->getIntNTy(128));
|
||||||
|
auto rb_i8 = GetGpr(rb, 8);
|
||||||
|
rb_i8 = m_ir_builder->CreateAnd(rb_i8, 0x7F);
|
||||||
|
auto rb_i128 = m_ir_builder->CreateZExt(rb_i8, m_ir_builder->getIntNTy(128));
|
||||||
|
auto res_i128 = m_ir_builder->CreateShl(rs_i128, rb_i128);
|
||||||
|
auto res_i64 = m_ir_builder->CreateTrunc(res_i128, m_ir_builder->getInt64Ty());
|
||||||
|
SetGpr(ra, res_i64);
|
||||||
|
|
||||||
|
if (rc) {
|
||||||
|
SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
//InterpreterCall("SLD", &PPUInterpreter::SLD, ra, rs, rb, rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPULLVMRecompiler::AND(u32 ra, u32 rs, u32 rb, bool rc) {
|
void PPULLVMRecompiler::AND(u32 ra, u32 rs, u32 rb, bool rc) {
|
||||||
@ -1724,7 +1761,15 @@ void PPULLVMRecompiler::LWZUX(u32 rd, u32 ra, u32 rb) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void PPULLVMRecompiler::CNTLZD(u32 ra, u32 rs, bool rc) {
|
void PPULLVMRecompiler::CNTLZD(u32 ra, u32 rs, bool rc) {
|
||||||
InterpreterCall("CNTLZD", &PPUInterpreter::CNTLZD, ra, rs, rc);
|
auto rs_i64 = GetGpr(rs);
|
||||||
|
auto res_i64 = m_ir_builder->CreateCall2(Intrinsic::getDeclaration(m_module, Intrinsic::ctlz, {m_ir_builder->getInt64Ty()}), rs_i64, m_ir_builder->getInt1(false));
|
||||||
|
SetGpr(ra, res_i64);
|
||||||
|
|
||||||
|
if (rc) {
|
||||||
|
SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
//InterpreterCall("CNTLZD", &PPUInterpreter::CNTLZD, ra, rs, rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPULLVMRecompiler::ANDC(u32 ra, u32 rs, u32 rb, bool rc) {
|
void PPULLVMRecompiler::ANDC(u32 ra, u32 rs, u32 rb, bool rc) {
|
||||||
@ -2353,11 +2398,36 @@ void PPULLVMRecompiler::LFSX(u32 frd, u32 ra, u32 rb) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void PPULLVMRecompiler::SRW(u32 ra, u32 rs, u32 rb, bool rc) {
|
void PPULLVMRecompiler::SRW(u32 ra, u32 rs, u32 rb, bool rc) {
|
||||||
InterpreterCall("SRW", &PPUInterpreter::SRW, ra, rs, rb, rc);
|
auto rs_i32 = GetGpr(rs, 32);
|
||||||
|
auto rs_i64 = m_ir_builder->CreateZExt(rs_i32, m_ir_builder->getInt64Ty());
|
||||||
|
auto rb_i8 = GetGpr(rb, 8);
|
||||||
|
rb_i8 = m_ir_builder->CreateAnd(rb_i8, 0x3F);
|
||||||
|
auto rb_i64 = m_ir_builder->CreateZExt(rb_i8, m_ir_builder->getInt64Ty());
|
||||||
|
auto res_i64 = m_ir_builder->CreateLShr(rs_i64, rb_i64);
|
||||||
|
SetGpr(ra, res_i64);
|
||||||
|
|
||||||
|
if (rc) {
|
||||||
|
SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
//InterpreterCall("SRW", &PPUInterpreter::SRW, ra, rs, rb, rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPULLVMRecompiler::SRD(u32 ra, u32 rs, u32 rb, bool rc) {
|
void PPULLVMRecompiler::SRD(u32 ra, u32 rs, u32 rb, bool rc) {
|
||||||
InterpreterCall("SRD", &PPUInterpreter::SRD, ra, rs, rb, rc);
|
auto rs_i64 = GetGpr(rs);
|
||||||
|
auto rs_i128 = m_ir_builder->CreateZExt(rs_i64, m_ir_builder->getIntNTy(128));
|
||||||
|
auto rb_i8 = GetGpr(rb, 8);
|
||||||
|
rb_i8 = m_ir_builder->CreateAnd(rb_i8, 0x7F);
|
||||||
|
auto rb_i128 = m_ir_builder->CreateZExt(rb_i8, m_ir_builder->getIntNTy(128));
|
||||||
|
auto res_i128 = m_ir_builder->CreateLShr(rs_i128, rb_i128);
|
||||||
|
auto res_i64 = m_ir_builder->CreateTrunc(res_i128, m_ir_builder->getInt64Ty());
|
||||||
|
SetGpr(ra, res_i64);
|
||||||
|
|
||||||
|
if (rc) {
|
||||||
|
SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
//InterpreterCall("SRD", &PPUInterpreter::SRD, ra, rs, rb, rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPULLVMRecompiler::LVRX(u32 vd, u32 ra, u32 rb) {
|
void PPULLVMRecompiler::LVRX(u32 vd, u32 ra, u32 rb) {
|
||||||
@ -2495,11 +2565,52 @@ void PPULLVMRecompiler::LHBRX(u32 rd, u32 ra, u32 rb) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void PPULLVMRecompiler::SRAW(u32 ra, u32 rs, u32 rb, bool rc) {
|
void PPULLVMRecompiler::SRAW(u32 ra, u32 rs, u32 rb, bool rc) {
|
||||||
InterpreterCall("SRAW", &PPUInterpreter::SRAW, ra, rs, rb, rc);
|
auto rs_i32 = GetGpr(rs, 32);
|
||||||
|
auto rs_i64 = m_ir_builder->CreateZExt(rs_i32, m_ir_builder->getInt64Ty());
|
||||||
|
rs_i64 = m_ir_builder->CreateShl(rs_i64, 32);
|
||||||
|
auto rb_i8 = GetGpr(rb, 8);
|
||||||
|
rb_i8 = m_ir_builder->CreateAnd(rb_i8, 0x3F);
|
||||||
|
auto rb_i64 = m_ir_builder->CreateZExt(rb_i8, m_ir_builder->getInt64Ty());
|
||||||
|
auto res_i64 = m_ir_builder->CreateAShr(rs_i64, rb_i64);
|
||||||
|
auto ra_i64 = m_ir_builder->CreateAShr(res_i64, 32);
|
||||||
|
SetGpr(ra, ra_i64);
|
||||||
|
|
||||||
|
auto res_i32 = m_ir_builder->CreateTrunc(res_i64, m_ir_builder->getInt32Ty());
|
||||||
|
auto ca1_i1 = m_ir_builder->CreateICmpSLT(ra_i64, m_ir_builder->getInt64(0));
|
||||||
|
auto ca2_i1 = m_ir_builder->CreateICmpNE(res_i32, m_ir_builder->getInt32(0));
|
||||||
|
auto ca_i1 = m_ir_builder->CreateAnd(ca1_i1, ca2_i1);
|
||||||
|
SetXerCa(ca_i1);
|
||||||
|
|
||||||
|
if (rc) {
|
||||||
|
SetCrFieldSignedCmp(0, ra_i64, m_ir_builder->getInt64(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
//InterpreterCall("SRAW", &PPUInterpreter::SRAW, ra, rs, rb, rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPULLVMRecompiler::SRAD(u32 ra, u32 rs, u32 rb, bool rc) {
|
void PPULLVMRecompiler::SRAD(u32 ra, u32 rs, u32 rb, bool rc) {
|
||||||
InterpreterCall("SRAD", &PPUInterpreter::SRAD, ra, rs, rb, rc);
|
auto rs_i64 = GetGpr(rs);
|
||||||
|
auto rs_i128 = m_ir_builder->CreateZExt(rs_i64, m_ir_builder->getIntNTy(128));
|
||||||
|
rs_i128 = m_ir_builder->CreateShl(rs_i128, 64);
|
||||||
|
auto rb_i8 = GetGpr(rb, 8);
|
||||||
|
rb_i8 = m_ir_builder->CreateAnd(rb_i8, 0x7F);
|
||||||
|
auto rb_i128 = m_ir_builder->CreateZExt(rb_i8, m_ir_builder->getIntNTy(128));
|
||||||
|
auto res_i128 = m_ir_builder->CreateAShr(rs_i128, rb_i128);
|
||||||
|
auto ra_i128 = m_ir_builder->CreateAShr(res_i128, 64);
|
||||||
|
auto ra_i64 = m_ir_builder->CreateTrunc(ra_i128, m_ir_builder->getInt64Ty());
|
||||||
|
SetGpr(ra, ra_i64);
|
||||||
|
|
||||||
|
auto res_i64 = m_ir_builder->CreateTrunc(res_i128, m_ir_builder->getInt64Ty());
|
||||||
|
auto ca1_i1 = m_ir_builder->CreateICmpSLT(ra_i64, m_ir_builder->getInt64(0));
|
||||||
|
auto ca2_i1 = m_ir_builder->CreateICmpNE(res_i64, m_ir_builder->getInt64(0));
|
||||||
|
auto ca_i1 = m_ir_builder->CreateAnd(ca1_i1, ca2_i1);
|
||||||
|
SetXerCa(ca_i1);
|
||||||
|
|
||||||
|
if (rc) {
|
||||||
|
SetCrFieldSignedCmp(0, ra_i64, m_ir_builder->getInt64(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
//InterpreterCall("SRAD", &PPUInterpreter::SRAD, ra, rs, rb, rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPULLVMRecompiler::LVRXL(u32 vd, u32 ra, u32 rb) {
|
void PPULLVMRecompiler::LVRXL(u32 vd, u32 ra, u32 rb) {
|
||||||
@ -2511,39 +2622,56 @@ void PPULLVMRecompiler::DSS(u32 strm, u32 a) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void PPULLVMRecompiler::SRAWI(u32 ra, u32 rs, u32 sh, bool rc) {
|
void PPULLVMRecompiler::SRAWI(u32 ra, u32 rs, u32 sh, bool rc) {
|
||||||
//auto rs_i32 = GetGpr(rs, 32);
|
auto rs_i32 = GetGpr(rs, 32);
|
||||||
//auto res_i32 = m_ir_builder->CreateAShr(rs_i32, sh);
|
auto rs_i64 = m_ir_builder->CreateZExt(rs_i32, m_ir_builder->getInt64Ty());
|
||||||
//auto res_i64 = m_ir_builder->CreateSExt(rs_i32, m_ir_builder->getInt64Ty());
|
rs_i64 = m_ir_builder->CreateShl(rs_i64, 32);
|
||||||
//SetGpr(ra, res_i64);
|
auto res_i64 = m_ir_builder->CreateAShr(rs_i64, sh);
|
||||||
|
auto ra_i64 = m_ir_builder->CreateAShr(res_i64, 32);
|
||||||
|
SetGpr(ra, ra_i64);
|
||||||
|
|
||||||
//if (rc) {
|
auto res_i32 = m_ir_builder->CreateTrunc(res_i64, m_ir_builder->getInt32Ty());
|
||||||
// SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0));
|
auto ca1_i1 = m_ir_builder->CreateICmpSLT(ra_i64, m_ir_builder->getInt64(0));
|
||||||
//}
|
auto ca2_i1 = m_ir_builder->CreateICmpNE(res_i32, m_ir_builder->getInt32(0));
|
||||||
|
auto ca_i1 = m_ir_builder->CreateAnd(ca1_i1, ca2_i1);
|
||||||
|
SetXerCa(ca_i1);
|
||||||
|
|
||||||
// TODO: Set XER.CA
|
if (rc) {
|
||||||
InterpreterCall("SRAWI", &PPUInterpreter::SRAWI, ra, rs, sh, rc);
|
SetCrFieldSignedCmp(0, ra_i64, m_ir_builder->getInt64(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
//InterpreterCall("SRAWI", &PPUInterpreter::SRAWI, ra, rs, sh, rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPULLVMRecompiler::SRADI1(u32 ra, u32 rs, u32 sh, bool rc) {
|
void PPULLVMRecompiler::SRADI1(u32 ra, u32 rs, u32 sh, bool rc) {
|
||||||
//auto rs_i64 = GetGpr(rs);
|
auto rs_i64 = GetGpr(rs);
|
||||||
//auto res_i64 = m_ir_builder->CreateAShr(rs_i64, sh);
|
auto rs_i128 = m_ir_builder->CreateZExt(rs_i64, m_ir_builder->getIntNTy(128));
|
||||||
//SetGpr(ra, res_i64);
|
rs_i128 = m_ir_builder->CreateShl(rs_i128, 64);
|
||||||
|
auto res_i128 = m_ir_builder->CreateAShr(rs_i128, sh);
|
||||||
|
auto ra_i128 = m_ir_builder->CreateAShr(res_i128, 64);
|
||||||
|
auto ra_i64 = m_ir_builder->CreateTrunc(ra_i128, m_ir_builder->getInt64Ty());
|
||||||
|
SetGpr(ra, ra_i64);
|
||||||
|
|
||||||
//if (rc) {
|
auto res_i64 = m_ir_builder->CreateTrunc(res_i128, m_ir_builder->getInt64Ty());
|
||||||
// SetCrFieldSignedCmp(0, res_i64, m_ir_builder->getInt64(0));
|
auto ca1_i1 = m_ir_builder->CreateICmpSLT(ra_i64, m_ir_builder->getInt64(0));
|
||||||
//}
|
auto ca2_i1 = m_ir_builder->CreateICmpNE(res_i64, m_ir_builder->getInt64(0));
|
||||||
|
auto ca_i1 = m_ir_builder->CreateAnd(ca1_i1, ca2_i1);
|
||||||
|
SetXerCa(ca_i1);
|
||||||
|
|
||||||
// TODO: Set XER.CA
|
if (rc) {
|
||||||
InterpreterCall("SRADI1", &PPUInterpreter::SRADI1, ra, rs, sh, rc);
|
SetCrFieldSignedCmp(0, ra_i64, m_ir_builder->getInt64(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
//InterpreterCall("SRADI1", &PPUInterpreter::SRADI1, ra, rs, sh, rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPULLVMRecompiler::SRADI2(u32 ra, u32 rs, u32 sh, bool rc) {
|
void PPULLVMRecompiler::SRADI2(u32 ra, u32 rs, u32 sh, bool rc) {
|
||||||
//SRADI1(ra, rs, sh, rc);
|
SRADI1(ra, rs, sh, rc);
|
||||||
InterpreterCall("SRADI2", &PPUInterpreter::SRADI2, ra, rs, sh, rc);
|
//InterpreterCall("SRADI2", &PPUInterpreter::SRADI2, ra, rs, sh, rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPULLVMRecompiler::EIEIO() {
|
void PPULLVMRecompiler::EIEIO() {
|
||||||
InterpreterCall("EIEIO", &PPUInterpreter::EIEIO);
|
m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_mfence));
|
||||||
|
//InterpreterCall("EIEIO", &PPUInterpreter::EIEIO);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPULLVMRecompiler::STVLXL(u32 vs, u32 ra, u32 rb) {
|
void PPULLVMRecompiler::STVLXL(u32 vs, u32 ra, u32 rb) {
|
||||||
@ -2918,24 +3046,36 @@ void PPULLVMRecompiler::LWA(u32 rd, u32 ra, s32 ds) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void PPULLVMRecompiler::FDIVS(u32 frd, u32 fra, u32 frb, bool rc) {
|
void PPULLVMRecompiler::FDIVS(u32 frd, u32 fra, u32 frb, bool rc) {
|
||||||
auto ra_f32 = GetFpr(fra, 32);
|
auto ra_f64 = GetFpr(fra);
|
||||||
auto rb_f32 = GetFpr(frb, 32);
|
auto rb_f64 = GetFpr(frb);
|
||||||
auto res_f32 = m_ir_builder->CreateFDiv(ra_f32, rb_f32);
|
auto res_f64 = m_ir_builder->CreateFDiv(ra_f64, rb_f64);
|
||||||
SetFpr(frd, res_f32);
|
auto res_f32 = m_ir_builder->CreateFPTrunc(res_f64, m_ir_builder->getFloatTy());
|
||||||
|
res_f64 = m_ir_builder->CreateFPExt(res_f32, m_ir_builder->getDoubleTy());
|
||||||
|
SetFpr(frd, res_f64);
|
||||||
|
|
||||||
// TODO: Set flags
|
// TODO: Set flags
|
||||||
//InterpreterCall("FDIVS", &PPUInterpreter::FDIVS, frd, fra, frb, rc);
|
//InterpreterCall("FDIVS", &PPUInterpreter::FDIVS, frd, fra, frb, rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPULLVMRecompiler::FSUBS(u32 frd, u32 fra, u32 frb, bool rc) {
|
void PPULLVMRecompiler::FSUBS(u32 frd, u32 fra, u32 frb, bool rc) {
|
||||||
InterpreterCall("FSUBS", &PPUInterpreter::FSUBS, frd, fra, frb, rc);
|
auto ra_f64 = GetFpr(fra);
|
||||||
|
auto rb_f64 = GetFpr(frb);
|
||||||
|
auto res_f64 = m_ir_builder->CreateFSub(ra_f64, rb_f64);
|
||||||
|
auto res_f32 = m_ir_builder->CreateFPTrunc(res_f64, m_ir_builder->getFloatTy());
|
||||||
|
res_f64 = m_ir_builder->CreateFPExt(res_f32, m_ir_builder->getDoubleTy());
|
||||||
|
SetFpr(frd, res_f64);
|
||||||
|
|
||||||
|
// TODO: Set flags
|
||||||
|
//InterpreterCall("FSUBS", &PPUInterpreter::FSUBS, frd, fra, frb, rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPULLVMRecompiler::FADDS(u32 frd, u32 fra, u32 frb, bool rc) {
|
void PPULLVMRecompiler::FADDS(u32 frd, u32 fra, u32 frb, bool rc) {
|
||||||
auto ra_f32 = GetFpr(fra, 32);
|
auto ra_f64 = GetFpr(fra);
|
||||||
auto rb_f32 = GetFpr(frb, 32);
|
auto rb_f64 = GetFpr(frb);
|
||||||
auto res_f32 = m_ir_builder->CreateFAdd(ra_f32, rb_f32);
|
auto res_f64 = m_ir_builder->CreateFAdd(ra_f64, rb_f64);
|
||||||
SetFpr(frd, res_f32);
|
auto res_f32 = m_ir_builder->CreateFPTrunc(res_f64, m_ir_builder->getFloatTy());
|
||||||
|
res_f64 = m_ir_builder->CreateFPExt(res_f32, m_ir_builder->getDoubleTy());
|
||||||
|
SetFpr(frd, res_f64);
|
||||||
|
|
||||||
// TODO: Set flags
|
// TODO: Set flags
|
||||||
//InterpreterCall("FADDS", &PPUInterpreter::FADDS, frd, fra, frb, rc);
|
//InterpreterCall("FADDS", &PPUInterpreter::FADDS, frd, fra, frb, rc);
|
||||||
@ -2950,10 +3090,12 @@ void PPULLVMRecompiler::FRES(u32 frd, u32 frb, bool rc) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void PPULLVMRecompiler::FMULS(u32 frd, u32 fra, u32 frc, bool rc) {
|
void PPULLVMRecompiler::FMULS(u32 frd, u32 fra, u32 frc, bool rc) {
|
||||||
auto ra_f32 = GetFpr(fra, 32);
|
auto ra_f64 = GetFpr(fra);
|
||||||
auto rc_f32 = GetFpr(frc, 32);
|
auto rc_f64 = GetFpr(frc);
|
||||||
auto res_f32 = m_ir_builder->CreateFMul(ra_f32, rc_f32);
|
auto res_f64 = m_ir_builder->CreateFMul(ra_f64, rc_f64);
|
||||||
SetFpr(frd, res_f32);
|
auto res_f32 = m_ir_builder->CreateFPTrunc(res_f64, m_ir_builder->getFloatTy());
|
||||||
|
res_f64 = m_ir_builder->CreateFPExt(res_f32, m_ir_builder->getDoubleTy());
|
||||||
|
SetFpr(frd, res_f64);
|
||||||
|
|
||||||
// TODO: Set flags
|
// TODO: Set flags
|
||||||
//InterpreterCall("FMULS", &PPUInterpreter::FMULS, frd, fra, frc, rc);
|
//InterpreterCall("FMULS", &PPUInterpreter::FMULS, frd, fra, frc, rc);
|
||||||
@ -2963,7 +3105,9 @@ void PPULLVMRecompiler::FMADDS(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) {
|
|||||||
auto ra_f64 = GetFpr(fra);
|
auto ra_f64 = GetFpr(fra);
|
||||||
auto rb_f64 = GetFpr(frb);
|
auto rb_f64 = GetFpr(frb);
|
||||||
auto rc_f64 = GetFpr(frc);
|
auto rc_f64 = GetFpr(frc);
|
||||||
auto res_f64 = m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::fma, {m_ir_builder->getDoubleTy()}), ra_f64, rc_f64, rb_f64);
|
auto res_f64 = (Value *)m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::fma, {m_ir_builder->getDoubleTy()}), ra_f64, rc_f64, rb_f64);
|
||||||
|
auto res_f32 = m_ir_builder->CreateFPTrunc(res_f64, m_ir_builder->getFloatTy());
|
||||||
|
res_f64 = m_ir_builder->CreateFPExt(res_f32, m_ir_builder->getDoubleTy());
|
||||||
SetFpr(frd, res_f64);
|
SetFpr(frd, res_f64);
|
||||||
|
|
||||||
// TODO: Set flags
|
// TODO: Set flags
|
||||||
@ -2971,12 +3115,14 @@ void PPULLVMRecompiler::FMADDS(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void PPULLVMRecompiler::FMSUBS(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) {
|
void PPULLVMRecompiler::FMSUBS(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) {
|
||||||
//auto ra_f64 = GetFpr(fra);
|
auto ra_f64 = GetFpr(fra);
|
||||||
//auto rb_f64 = GetFpr(frb);
|
auto rb_f64 = GetFpr(frb);
|
||||||
//auto rc_f64 = GetFpr(frc);
|
auto rc_f64 = GetFpr(frc);
|
||||||
//rb_f64 = m_ir_builder->CreateNeg(rb_f64);
|
rb_f64 = m_ir_builder->CreateFNeg(rb_f64);
|
||||||
//auto res_f64 = m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::fma, {m_ir_builder->getDoubleTy()}), ra_f64, rc_f64, rb_f64);
|
auto res_f64 = (Value *)m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::fma, {m_ir_builder->getDoubleTy()}), ra_f64, rc_f64, rb_f64);
|
||||||
//SetFpr(frd, res_f64);
|
auto res_f32 = m_ir_builder->CreateFPTrunc(res_f64, m_ir_builder->getFloatTy());
|
||||||
|
res_f64 = m_ir_builder->CreateFPExt(res_f32, m_ir_builder->getDoubleTy());
|
||||||
|
SetFpr(frd, res_f64);
|
||||||
|
|
||||||
// TODO: Set flags
|
// TODO: Set flags
|
||||||
InterpreterCall("FMSUBS", &PPUInterpreter::FMSUBS, frd, fra, frc, frb, rc);
|
InterpreterCall("FMSUBS", &PPUInterpreter::FMSUBS, frd, fra, frc, frb, rc);
|
||||||
@ -3040,11 +3186,7 @@ void PPULLVMRecompiler::FCMPU(u32 crfd, u32 fra, u32 frb) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void PPULLVMRecompiler::FRSP(u32 frd, u32 frb, bool rc) {
|
void PPULLVMRecompiler::FRSP(u32 frd, u32 frb, bool rc) {
|
||||||
auto rb_f64 = GetFpr(frb);
|
InterpreterCall("FRSP", &PPUInterpreter::FRSP, frd, frb, rc);
|
||||||
SetFpr(frd, rb_f64);
|
|
||||||
|
|
||||||
// TODO: Set flags
|
|
||||||
//InterpreterCall("FRSP", &PPUInterpreter::FRSP, frd, frb, rc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPULLVMRecompiler::FCTIW(u32 frd, u32 frb, bool rc) {
|
void PPULLVMRecompiler::FCTIW(u32 frd, u32 frb, bool rc) {
|
||||||
@ -3108,15 +3250,15 @@ void PPULLVMRecompiler::FRSQRTE(u32 frd, u32 frb, bool rc) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void PPULLVMRecompiler::FMSUB(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) {
|
void PPULLVMRecompiler::FMSUB(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) {
|
||||||
//auto ra_f64 = GetFpr(fra);
|
auto ra_f64 = GetFpr(fra);
|
||||||
//auto rb_f64 = GetFpr(frb);
|
auto rb_f64 = GetFpr(frb);
|
||||||
//auto rc_f64 = GetFpr(frc);
|
auto rc_f64 = GetFpr(frc);
|
||||||
//rb_f64 = m_ir_builder->CreateNeg(rb_f64);
|
rb_f64 = m_ir_builder->CreateFNeg(rb_f64);
|
||||||
//auto res_f64 = m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::fma, {m_ir_builder->getDoubleTy()}), ra_f64, rc_f64, rb_f64);
|
auto res_f64 = m_ir_builder->CreateCall3(Intrinsic::getDeclaration(m_module, Intrinsic::fma, {m_ir_builder->getDoubleTy()}), ra_f64, rc_f64, rb_f64);
|
||||||
//SetFpr(frd, res_f64);
|
SetFpr(frd, res_f64);
|
||||||
|
|
||||||
// TODO: Set flags
|
// TODO: Set flags
|
||||||
InterpreterCall("FMSUB", &PPUInterpreter::FMSUB, frd, fra, frc, frb, rc);
|
//InterpreterCall("FMSUB", &PPUInterpreter::FMSUB, frd, fra, frc, frb, rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPULLVMRecompiler::FMADD(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) {
|
void PPULLVMRecompiler::FMADD(u32 frd, u32 fra, u32 frc, u32 frb, bool rc) {
|
||||||
@ -3143,12 +3285,12 @@ void PPULLVMRecompiler::FCMPO(u32 crfd, u32 fra, u32 frb) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void PPULLVMRecompiler::FNEG(u32 frd, u32 frb, bool rc) {
|
void PPULLVMRecompiler::FNEG(u32 frd, u32 frb, bool rc) {
|
||||||
//auto rb_f64 = GetFpr(frb);
|
auto rb_f64 = GetFpr(frb);
|
||||||
//rb_f64 = m_ir_builder->CreateSub(ConstantFP::getZeroValueForNegation(rb_f64->getType()), rb_f64);
|
rb_f64 = m_ir_builder->CreateFNeg(rb_f64);
|
||||||
//SetGpr(frd, rb_f64);
|
SetFpr(frd, rb_f64);
|
||||||
|
|
||||||
// TODO: Set flags
|
// TODO: Set flags
|
||||||
InterpreterCall("FNEG", &PPUInterpreter::FNEG, frd, frb, rc);
|
//InterpreterCall("FNEG", &PPUInterpreter::FNEG, frd, frb, rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPULLVMRecompiler::FMR(u32 frd, u32 frb, bool rc) {
|
void PPULLVMRecompiler::FMR(u32 frd, u32 frb, bool rc) {
|
||||||
@ -3294,7 +3436,7 @@ void PPULLVMRecompiler::Compile(u32 address) {
|
|||||||
|
|
||||||
auto compilation_end = std::chrono::high_resolution_clock::now();
|
auto compilation_end = std::chrono::high_resolution_clock::now();
|
||||||
m_compilation_time += std::chrono::duration_cast<std::chrono::nanoseconds>(compilation_end - compilation_start);
|
m_compilation_time += std::chrono::duration_cast<std::chrono::nanoseconds>(compilation_end - compilation_start);
|
||||||
m_revision++;
|
m_revision.fetch_add(1, std::memory_order_relaxed);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PPULLVMRecompiler::RemoveUnusedOldVersions() {
|
void PPULLVMRecompiler::RemoveUnusedOldVersions() {
|
||||||
@ -3426,7 +3568,7 @@ Value * PPULLVMRecompiler::GetNibble(Value * val, u32 n) {
|
|||||||
} else {
|
} else {
|
||||||
#endif
|
#endif
|
||||||
if ((val->getType()->getIntegerBitWidth() >> 2) != (n + 1)) {
|
if ((val->getType()->getIntegerBitWidth() >> 2) != (n + 1)) {
|
||||||
nibble = m_ir_builder->CreateLShr(val, (((val->getType()->getIntegerBitWidth() >> 2) - 1) - n) * 4);
|
val = m_ir_builder->CreateLShr(val, (((val->getType()->getIntegerBitWidth() >> 2) - 1) - n) * 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
nibble = m_ir_builder->CreateAnd(val, 0xF);
|
nibble = m_ir_builder->CreateAnd(val, 0xF);
|
||||||
@ -3946,7 +4088,7 @@ Type * PPULLVMRecompiler::CppToLlvmType() {
|
|||||||
} else if (std::is_same<T, short>::value || std::is_same<T, unsigned short>::value) {
|
} else if (std::is_same<T, short>::value || std::is_same<T, unsigned short>::value) {
|
||||||
return m_ir_builder->getInt16Ty();
|
return m_ir_builder->getInt16Ty();
|
||||||
} else if (std::is_same<T, char>::value || std::is_same<T, unsigned char>::value) {
|
} else if (std::is_same<T, char>::value || std::is_same<T, unsigned char>::value) {
|
||||||
return m_ir_builder->getInt8Ty();
|
return m_ir_builder->getInt8Ty();
|
||||||
} else if (std::is_same<T, float>::value) {
|
} else if (std::is_same<T, float>::value) {
|
||||||
return m_ir_builder->getFloatTy();
|
return m_ir_builder->getFloatTy();
|
||||||
} else if (std::is_same<T, double>::value) {
|
} else if (std::is_same<T, double>::value) {
|
||||||
@ -3997,7 +4139,7 @@ PPULLVMEmulator::PPULLVMEmulator(PPUThread & ppu)
|
|||||||
s_num_instances++;
|
s_num_instances++;
|
||||||
if (!s_recompiler) {
|
if (!s_recompiler) {
|
||||||
s_recompiler = new PPULLVMRecompiler();
|
s_recompiler = new PPULLVMRecompiler();
|
||||||
//s_recompiler->RunAllTests(&m_ppu, (u64)Memory.GetBaseAddr(), m_interpreter);
|
s_recompiler->RunAllTests(&m_ppu, (u64)Memory.GetBaseAddr(), m_interpreter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -449,7 +449,32 @@ void PPULLVMRecompiler::RunAllTests(PPUThread * ppu_state, u64 base_address, PPU
|
|||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MFSPR, 10, 5, 5, 0x120);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MFSPR, 10, 5, 5, 0x120);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MFSPR, 15, 5, 5, 0x8);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(MFSPR, 15, 5, 5, 0x8);
|
||||||
|
|
||||||
//VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FADD, 0, 5, 25, 29, 1, 0);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRAWI, 0, 5, 5, 6, 0, 0);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRAWI, 5, 5, 5, 6, 12, 0);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRAWI, 10, 5, 5, 6, 22, 1);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRAWI, 15, 5, 5, 6, 31, 1);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRAW, 0, 5, 5, 6, 7, 0);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRAW, 5, 5, 5, 6, 7, 1);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRADI1, 0, 5, 5, 6, 0, 0);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRADI1, 5, 5, 5, 6, 12, 0);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRADI1, 10, 5, 5, 6, 48, 1);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRADI1, 15, 5, 5, 6, 63, 1);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRAD, 0, 5, 5, 6, 7, 0);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRAD, 5, 5, 5, 6, 7, 1);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SLW, 0, 5, 5, 6, 7, 0);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SLW, 5, 5, 5, 6, 7, 1);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRW, 0, 5, 5, 6, 7, 0);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRW, 5, 5, 5, 6, 7, 1);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SLD, 0, 5, 5, 6, 7, 0);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SLD, 5, 5, 5, 6, 7, 1);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRD, 0, 5, 5, 6, 7, 0);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(SRD, 5, 5, 5, 6, 7, 1);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CNTLZW, 0, 5, 5, 6, 0);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CNTLZW, 5, 5, 5, 6, 1);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CNTLZD, 0, 5, 5, 6, 0);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CNTLZD, 5, 5, 5, 6, 1);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ISYNC, 0, 5);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(EIEIO, 0, 5);
|
||||||
|
|
||||||
PPURegState input;
|
PPURegState input;
|
||||||
input.SetRandom();
|
input.SetRandom();
|
||||||
|
Loading…
Reference in New Issue
Block a user