Fiddling with FPSCR and such. Still not implemented, but wiring done.
This commit is contained in:
parent
0482ffad5a
commit
214532a3e8
|
@ -37,12 +37,7 @@ int InstrEmit_faddx(PPCHIRBuilder& f, const InstrData& i) {
|
|||
// frD <- (frA) + (frB)
|
||||
Value* v = f.Add(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRB));
|
||||
f.StoreFPR(i.A.FRT, v);
|
||||
// f.UpdateFPRF(v);
|
||||
if (i.A.Rc) {
|
||||
// e.update_cr_with_cond(1, v);
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
f.UpdateFPSCR(v, i.A.Rc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -51,12 +46,7 @@ int InstrEmit_faddsx(PPCHIRBuilder& f, const InstrData& i) {
|
|||
Value* v = f.Add(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRB));
|
||||
v = f.Convert(f.Convert(v, FLOAT32_TYPE), FLOAT64_TYPE);
|
||||
f.StoreFPR(i.A.FRT, v);
|
||||
// f.UpdateFPRF(v);
|
||||
if (i.A.Rc) {
|
||||
// e.update_cr_with_cond(1, v);
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
f.UpdateFPSCR(v, i.A.Rc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -64,12 +54,7 @@ int InstrEmit_fdivx(PPCHIRBuilder& f, const InstrData& i) {
|
|||
// frD <- frA / frB
|
||||
Value* v = f.Div(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRB));
|
||||
f.StoreFPR(i.A.FRT, v);
|
||||
// f.UpdateFPRF(v);
|
||||
if (i.A.Rc) {
|
||||
// e.update_cr_with_cond(1, v);
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
f.UpdateFPSCR(v, i.A.Rc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -78,12 +63,7 @@ int InstrEmit_fdivsx(PPCHIRBuilder& f, const InstrData& i) {
|
|||
Value* v = f.Div(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRB));
|
||||
v = f.Convert(f.Convert(v, FLOAT32_TYPE), FLOAT64_TYPE);
|
||||
f.StoreFPR(i.A.FRT, v);
|
||||
// f.UpdateFPRF(v);
|
||||
if (i.A.Rc) {
|
||||
// e.update_cr_with_cond(1, v);
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
f.UpdateFPSCR(v, i.A.Rc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -91,12 +71,7 @@ int InstrEmit_fmulx(PPCHIRBuilder& f, const InstrData& i) {
|
|||
// frD <- (frA) x (frC)
|
||||
Value* v = f.Mul(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRC));
|
||||
f.StoreFPR(i.A.FRT, v);
|
||||
// f.UpdateFPRF(v);
|
||||
if (i.A.Rc) {
|
||||
// e.update_cr_with_cond(1, v);
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
f.UpdateFPSCR(v, i.A.Rc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -105,12 +80,7 @@ int InstrEmit_fmulsx(PPCHIRBuilder& f, const InstrData& i) {
|
|||
Value* v = f.Mul(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRC));
|
||||
v = f.Convert(f.Convert(v, FLOAT32_TYPE), FLOAT64_TYPE);
|
||||
f.StoreFPR(i.A.FRT, v);
|
||||
// f.UpdateFPRF(v);
|
||||
if (i.A.Rc) {
|
||||
// e.update_cr_with_cond(1, v);
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
f.UpdateFPSCR(v, i.A.Rc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -120,12 +90,7 @@ int InstrEmit_fresx(PPCHIRBuilder& f, const InstrData& i) {
|
|||
f.Convert(f.LoadFPR(i.A.FRB), FLOAT32_TYPE)),
|
||||
FLOAT64_TYPE);
|
||||
f.StoreFPR(i.A.FRT, v);
|
||||
// f.UpdateFPRF(v);
|
||||
if (i.A.Rc) {
|
||||
// e.update_cr_with_cond(1, v);
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
f.UpdateFPSCR(v, i.A.Rc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -134,12 +99,7 @@ int InstrEmit_frsqrtex(PPCHIRBuilder& f, const InstrData& i) {
|
|||
// frD <- 1/sqrt(frB)
|
||||
Value* v = f.RSqrt(f.LoadFPR(i.A.FRB));
|
||||
f.StoreFPR(i.A.FRT, v);
|
||||
// f.UpdateFPRF(v);
|
||||
if (i.A.Rc) {
|
||||
// e.update_cr_with_cond(1, v);
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
f.UpdateFPSCR(v, i.A.Rc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -147,12 +107,7 @@ int InstrEmit_fsubx(PPCHIRBuilder& f, const InstrData& i) {
|
|||
// frD <- (frA) - (frB)
|
||||
Value* v = f.Sub(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRB));
|
||||
f.StoreFPR(i.A.FRT, v);
|
||||
// f.UpdateFPRF(v);
|
||||
if (i.A.Rc) {
|
||||
// e.update_cr_with_cond(1, v);
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
f.UpdateFPSCR(v, i.A.Rc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -161,12 +116,7 @@ int InstrEmit_fsubsx(PPCHIRBuilder& f, const InstrData& i) {
|
|||
Value* v = f.Sub(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRB));
|
||||
v = f.Convert(f.Convert(v, FLOAT32_TYPE), FLOAT64_TYPE);
|
||||
f.StoreFPR(i.A.FRT, v);
|
||||
// f.UpdateFPRF(v);
|
||||
if (i.A.Rc) {
|
||||
// e.update_cr_with_cond(1, v);
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
f.UpdateFPSCR(v, i.A.Rc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -177,11 +127,7 @@ int InstrEmit_fselx(PPCHIRBuilder& f, const InstrData& i) {
|
|||
Value* ge = f.CompareSGE(f.LoadFPR(i.A.FRA), f.LoadZeroFloat64());
|
||||
Value* v = f.Select(ge, f.LoadFPR(i.A.FRC), f.LoadFPR(i.A.FRB));
|
||||
f.StoreFPR(i.A.FRT, v);
|
||||
if (i.A.Rc) {
|
||||
// e.update_cr_with_cond(1, v);
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
f.UpdateFPSCR(v, i.A.Rc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -190,12 +136,7 @@ int InstrEmit_fsqrtx(PPCHIRBuilder& f, const InstrData& i) {
|
|||
// frD <- sqrt(frB)
|
||||
Value* v = f.Sqrt(f.LoadFPR(i.A.FRB));
|
||||
f.StoreFPR(i.A.FRT, v);
|
||||
// f.UpdateFPRF(v);
|
||||
if (i.A.Rc) {
|
||||
// e.update_cr_with_cond(1, v);
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
f.UpdateFPSCR(v, i.A.Rc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -205,12 +146,7 @@ int InstrEmit_fsqrtsx(PPCHIRBuilder& f, const InstrData& i) {
|
|||
Value* v = f.Sqrt(f.LoadFPR(i.A.FRB));
|
||||
v = f.Convert(f.Convert(v, FLOAT32_TYPE), FLOAT64_TYPE);
|
||||
f.StoreFPR(i.A.FRT, v);
|
||||
// f.UpdateFPRF(v);
|
||||
if (i.A.Rc) {
|
||||
// e.update_cr_with_cond(1, v);
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
f.UpdateFPSCR(v, i.A.Rc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -221,12 +157,7 @@ int InstrEmit_fmaddx(PPCHIRBuilder& f, const InstrData& i) {
|
|||
Value* v =
|
||||
f.MulAdd(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRC), f.LoadFPR(i.A.FRB));
|
||||
f.StoreFPR(i.A.FRT, v);
|
||||
// f.UpdateFPRF(v);
|
||||
if (i.A.Rc) {
|
||||
// e.update_cr_with_cond(1, v);
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
f.UpdateFPSCR(v, i.A.Rc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -236,12 +167,7 @@ int InstrEmit_fmaddsx(PPCHIRBuilder& f, const InstrData& i) {
|
|||
f.MulAdd(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRC), f.LoadFPR(i.A.FRB));
|
||||
v = f.Convert(f.Convert(v, FLOAT32_TYPE), FLOAT64_TYPE);
|
||||
f.StoreFPR(i.A.FRT, v);
|
||||
// f.UpdateFPRF(v);
|
||||
if (i.A.Rc) {
|
||||
// e.update_cr_with_cond(1, v);
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
f.UpdateFPSCR(v, i.A.Rc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -250,12 +176,7 @@ int InstrEmit_fmsubx(PPCHIRBuilder& f, const InstrData& i) {
|
|||
Value* v =
|
||||
f.MulSub(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRC), f.LoadFPR(i.A.FRB));
|
||||
f.StoreFPR(i.A.FRT, v);
|
||||
// f.UpdateFPRF(v);
|
||||
if (i.A.Rc) {
|
||||
// e.update_cr_with_cond(1, v);
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
f.UpdateFPSCR(v, i.A.Rc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -265,12 +186,7 @@ int InstrEmit_fmsubsx(PPCHIRBuilder& f, const InstrData& i) {
|
|||
f.MulSub(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRC), f.LoadFPR(i.A.FRB));
|
||||
v = f.Convert(f.Convert(v, FLOAT32_TYPE), FLOAT64_TYPE);
|
||||
f.StoreFPR(i.A.FRT, v);
|
||||
// f.UpdateFPRF(v);
|
||||
if (i.A.Rc) {
|
||||
// e.update_cr_with_cond(1, v);
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
f.UpdateFPSCR(v, i.A.Rc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -279,12 +195,7 @@ int InstrEmit_fnmaddx(PPCHIRBuilder& f, const InstrData& i) {
|
|||
Value* v = f.Neg(
|
||||
f.MulAdd(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRC), f.LoadFPR(i.A.FRB)));
|
||||
f.StoreFPR(i.A.FRT, v);
|
||||
// f.UpdateFPRF(v);
|
||||
if (i.A.Rc) {
|
||||
// e.update_cr_with_cond(1, v);
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
f.UpdateFPSCR(v, i.A.Rc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -294,12 +205,7 @@ int InstrEmit_fnmaddsx(PPCHIRBuilder& f, const InstrData& i) {
|
|||
f.MulAdd(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRC), f.LoadFPR(i.A.FRB)));
|
||||
v = f.Convert(f.Convert(v, FLOAT32_TYPE), FLOAT64_TYPE);
|
||||
f.StoreFPR(i.A.FRT, v);
|
||||
// f.UpdateFPRF(v);
|
||||
if (i.A.Rc) {
|
||||
// e.update_cr_with_cond(1, v);
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
f.UpdateFPSCR(v, i.A.Rc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -308,12 +214,7 @@ int InstrEmit_fnmsubx(PPCHIRBuilder& f, const InstrData& i) {
|
|||
Value* v = f.Neg(
|
||||
f.MulSub(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRC), f.LoadFPR(i.A.FRB)));
|
||||
f.StoreFPR(i.A.FRT, v);
|
||||
// f.UpdateFPRF(v);
|
||||
if (i.A.Rc) {
|
||||
// e.update_cr_with_cond(1, v);
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
f.UpdateFPSCR(v, i.A.Rc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -323,12 +224,7 @@ int InstrEmit_fnmsubsx(PPCHIRBuilder& f, const InstrData& i) {
|
|||
f.MulSub(f.LoadFPR(i.A.FRA), f.LoadFPR(i.A.FRC), f.LoadFPR(i.A.FRB)));
|
||||
v = f.Convert(f.Convert(v, FLOAT32_TYPE), FLOAT64_TYPE);
|
||||
f.StoreFPR(i.A.FRT, v);
|
||||
// f.UpdateFPRF(v);
|
||||
if (i.A.Rc) {
|
||||
// e.update_cr_with_cond(1, v);
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
f.UpdateFPSCR(v, i.A.Rc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -338,12 +234,7 @@ int InstrEmit_fcfidx(PPCHIRBuilder& f, const InstrData& i) {
|
|||
// frD <- signed_int64_to_double( frB )
|
||||
Value* v = f.Convert(f.Cast(f.LoadFPR(i.X.RB), INT64_TYPE), FLOAT64_TYPE);
|
||||
f.StoreFPR(i.X.RT, v);
|
||||
// f.UpdateFPRF(v);
|
||||
if (i.A.Rc) {
|
||||
// e.update_cr_with_cond(1, v);
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
f.UpdateFPSCR(v, i.A.Rc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -354,12 +245,7 @@ int InstrEmit_fctidx(PPCHIRBuilder& f, const InstrData& i) {
|
|||
Value* v = f.Convert(f.LoadFPR(i.X.RB), INT64_TYPE, round_mode);
|
||||
v = f.Cast(v, FLOAT64_TYPE);
|
||||
f.StoreFPR(i.X.RT, v);
|
||||
// f.UpdateFPRF(v);
|
||||
if (i.X.Rc) {
|
||||
// e.update_cr_with_cond(1, v);
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
f.UpdateFPSCR(v, i.X.Rc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -375,12 +261,7 @@ int InstrEmit_fctiwx(PPCHIRBuilder& f, const InstrData& i) {
|
|||
Value* v = f.Convert(f.LoadFPR(i.X.RB), INT32_TYPE, round_mode);
|
||||
v = f.Cast(f.ZeroExtend(v, INT64_TYPE), FLOAT64_TYPE);
|
||||
f.StoreFPR(i.X.RT, v);
|
||||
// f.UpdateFPRF(v);
|
||||
if (i.X.Rc) {
|
||||
// e.update_cr_with_cond(1, v);
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
f.UpdateFPSCR(v, i.X.Rc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -396,12 +277,7 @@ int InstrEmit_frspx(PPCHIRBuilder& f, const InstrData& i) {
|
|||
Value* v = f.Convert(f.LoadFPR(i.X.RB), FLOAT32_TYPE, round_mode);
|
||||
v = f.Convert(v, FLOAT64_TYPE);
|
||||
f.StoreFPR(i.X.RT, v);
|
||||
// f.UpdateFPRF(v);
|
||||
if (i.X.Rc) {
|
||||
// e.update_cr_with_cond(1, v);
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
f.UpdateFPSCR(v, i.X.Rc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -425,8 +301,7 @@ int InstrEmit_fcmpx_(PPCHIRBuilder& f, const InstrData& i, bool ordered) {
|
|||
// TODO(benvanik): update FPCC for mffsx/etc
|
||||
// TODO(benvanik): update VXSNAN
|
||||
const uint32_t crf = i.X.RT >> 2;
|
||||
// f.UpdateFPRF(v);
|
||||
f.UpdateCR(crf, f.LoadFPR(i.X.RA), f.LoadFPR(i.X.RB), false);
|
||||
f.UpdateCR(crf, f.LoadFPR(i.X.RA), f.LoadFPR(i.X.RB));
|
||||
return 0;
|
||||
}
|
||||
int InstrEmit_fcmpo(PPCHIRBuilder& f, const InstrData& i) {
|
||||
|
@ -448,7 +323,7 @@ int InstrEmit_mffsx(PPCHIRBuilder& f, const InstrData& i) {
|
|||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
Value* v = f.Cast(f.LoadFPSCR(), FLOAT64_TYPE);
|
||||
Value* v = f.Cast(f.ZeroExtend(f.LoadFPSCR(), INT64_TYPE), FLOAT64_TYPE);
|
||||
f.StoreFPR(i.X.RT, v);
|
||||
return 0;
|
||||
}
|
||||
|
@ -464,10 +339,6 @@ int InstrEmit_mtfsb1x(PPCHIRBuilder& f, const InstrData& i) {
|
|||
}
|
||||
|
||||
int InstrEmit_mtfsfx(PPCHIRBuilder& f, const InstrData& i) {
|
||||
if (i.XFL.Rc) {
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
if (i.XFL.L) {
|
||||
// Move/shift.
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
|
@ -477,7 +348,11 @@ int InstrEmit_mtfsfx(PPCHIRBuilder& f, const InstrData& i) {
|
|||
// TODO(benvanik): use w/field mask to select bits.
|
||||
// i.XFL.W;
|
||||
// i.XFL.FM;
|
||||
f.StoreFPSCR(f.Cast(f.LoadFPR(i.XFL.RB), INT64_TYPE));
|
||||
f.StoreFPSCR(
|
||||
f.Truncate(f.Cast(f.LoadFPR(i.XFL.RB), INT64_TYPE), INT32_TYPE));
|
||||
}
|
||||
if (i.XFL.Rc) {
|
||||
f.CopyFPSCRToCR1();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -493,11 +368,7 @@ int InstrEmit_fabsx(PPCHIRBuilder& f, const InstrData& i) {
|
|||
// frD <- abs(frB)
|
||||
Value* v = f.Abs(f.LoadFPR(i.X.RB));
|
||||
f.StoreFPR(i.X.RT, v);
|
||||
if (i.X.Rc) {
|
||||
// e.update_cr_with_cond(1, v);
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
f.UpdateFPSCR(v, i.X.Rc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -505,11 +376,7 @@ int InstrEmit_fmrx(PPCHIRBuilder& f, const InstrData& i) {
|
|||
// frD <- (frB)
|
||||
Value* v = f.LoadFPR(i.X.RB);
|
||||
f.StoreFPR(i.X.RT, v);
|
||||
if (i.X.Rc) {
|
||||
// e.update_cr_with_cond(1, v);
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
f.UpdateFPSCR(v, i.X.Rc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -517,11 +384,7 @@ int InstrEmit_fnabsx(PPCHIRBuilder& f, const InstrData& i) {
|
|||
// frD <- !abs(frB)
|
||||
Value* v = f.Neg(f.Abs(f.LoadFPR(i.X.RB)));
|
||||
f.StoreFPR(i.X.RT, v);
|
||||
if (i.X.Rc) {
|
||||
// e.update_cr_with_cond(1, v);
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
f.UpdateFPSCR(v, i.X.Rc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -529,11 +392,7 @@ int InstrEmit_fnegx(PPCHIRBuilder& f, const InstrData& i) {
|
|||
// frD <- ¬ frB[0] || frB[1-63]
|
||||
Value* v = f.Neg(f.LoadFPR(i.X.RB));
|
||||
f.StoreFPR(i.X.RT, v);
|
||||
if (i.X.Rc) {
|
||||
// e.update_cr_with_cond(1, v);
|
||||
XEINSTRNOTIMPLEMENTED();
|
||||
return 1;
|
||||
}
|
||||
f.UpdateFPSCR(v, i.X.Rc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -380,11 +380,11 @@ void PPCHIRBuilder::UpdateCR6(Value* src_value) {
|
|||
}
|
||||
|
||||
Value* PPCHIRBuilder::LoadFPSCR() {
|
||||
return LoadContext(offsetof(PPCContext, fpscr), INT64_TYPE);
|
||||
return LoadContext(offsetof(PPCContext, fpscr), INT32_TYPE);
|
||||
}
|
||||
|
||||
void PPCHIRBuilder::StoreFPSCR(Value* value) {
|
||||
assert_true(value->type == INT64_TYPE);
|
||||
assert_true(value->type == INT32_TYPE);
|
||||
StoreContext(offsetof(PPCContext, fpscr), value);
|
||||
|
||||
auto& trace_reg = trace_info_.dests[trace_info_.dest_count++];
|
||||
|
@ -392,13 +392,59 @@ void PPCHIRBuilder::StoreFPSCR(Value* value) {
|
|||
trace_reg.value = value;
|
||||
}
|
||||
|
||||
void PPCHIRBuilder::UpdateFPSCR(Value* result, bool update_cr1) {
|
||||
// TODO(benvanik): detect overflow and nan cases.
|
||||
// fx and vx are the most important.
|
||||
Value* fx = LoadConstantInt8(0);
|
||||
Value* fex = LoadConstantInt8(0);
|
||||
Value* vx = LoadConstantInt8(0);
|
||||
Value* ox = LoadConstantInt8(0);
|
||||
|
||||
if (update_cr1) {
|
||||
// Store into the CR1 field.
|
||||
// We do this instead of just calling CopyFPSCRToCR1 so that we don't
|
||||
// have to read back the bits and do shifting work.
|
||||
StoreContext(offsetof(PPCContext, cr1.cr1_fx), fx);
|
||||
StoreContext(offsetof(PPCContext, cr1.cr1_fex), fex);
|
||||
StoreContext(offsetof(PPCContext, cr1.cr1_vx), vx);
|
||||
StoreContext(offsetof(PPCContext, cr1.cr1_ox), ox);
|
||||
}
|
||||
|
||||
// Generate our new bits.
|
||||
Value* new_bits = Shl(ZeroExtend(fx, INT32_TYPE), 31);
|
||||
new_bits = Or(new_bits, Shl(ZeroExtend(fex, INT32_TYPE), 30));
|
||||
new_bits = Or(new_bits, Shl(ZeroExtend(vx, INT32_TYPE), 29));
|
||||
new_bits = Or(new_bits, Shl(ZeroExtend(ox, INT32_TYPE), 28));
|
||||
|
||||
// Mix into fpscr while preserving sticky bits (FX and OX).
|
||||
Value* bits = LoadFPSCR();
|
||||
bits = Or(And(bits, LoadConstantUint32(0x9FFFFFFF)), new_bits);
|
||||
StoreFPSCR(bits);
|
||||
}
|
||||
|
||||
void PPCHIRBuilder::CopyFPSCRToCR1() {
|
||||
// Pull out of FPSCR.
|
||||
Value* fpscr = LoadFPSCR();
|
||||
StoreContext(offsetof(PPCContext, cr1.cr1_fx),
|
||||
And(Truncate(Shr(fpscr, 31), INT8_TYPE), LoadConstantInt8(1)));
|
||||
StoreContext(offsetof(PPCContext, cr1.cr1_fex),
|
||||
And(Truncate(Shr(fpscr, 30), INT8_TYPE), LoadConstantInt8(1)));
|
||||
StoreContext(offsetof(PPCContext, cr1.cr1_vx),
|
||||
And(Truncate(Shr(fpscr, 29), INT8_TYPE), LoadConstantInt8(1)));
|
||||
StoreContext(offsetof(PPCContext, cr1.cr1_ox),
|
||||
And(Truncate(Shr(fpscr, 28), INT8_TYPE), LoadConstantInt8(1)));
|
||||
}
|
||||
|
||||
Value* PPCHIRBuilder::LoadXER() {
|
||||
Value* v = Shl(ZeroExtend(LoadCA(), INT64_TYPE), 29);
|
||||
// TODO(benvanik): construct with other flags; overflow, etc?
|
||||
return v;
|
||||
}
|
||||
|
||||
void PPCHIRBuilder::StoreXER(Value* value) { assert_always(); }
|
||||
void PPCHIRBuilder::StoreXER(Value* value) {
|
||||
// TODO(benvanik): use other fields? For now, just pull out CA.
|
||||
StoreCA(Truncate(And(Shr(value, 29), LoadConstantInt64(1)), INT8_TYPE));
|
||||
}
|
||||
|
||||
Value* PPCHIRBuilder::LoadCA() {
|
||||
return LoadContext(offsetof(PPCContext, xer_ca), INT8_TYPE);
|
||||
|
|
|
@ -59,6 +59,8 @@ class PPCHIRBuilder : public hir::HIRBuilder {
|
|||
void UpdateCR6(Value* src_value);
|
||||
Value* LoadFPSCR();
|
||||
void StoreFPSCR(Value* value);
|
||||
void UpdateFPSCR(Value* result, bool update_cr1);
|
||||
void CopyFPSCRToCR1();
|
||||
Value* LoadXER();
|
||||
void StoreXER(Value* value);
|
||||
// void UpdateXERWithOverflow();
|
||||
|
|
|
@ -504,7 +504,8 @@ X_STATUS Emulator::CompleteLaunch(const std::wstring& path,
|
|||
XELOGI("Launching module %s", next_module.c_str());
|
||||
auto module = kernel_state_->LoadUserModule(next_module.c_str());
|
||||
if (!module) {
|
||||
XELOGE("Failed to load user module %s", path);
|
||||
auto path_str = xe::to_string(path);
|
||||
XELOGE("Failed to load user module %s", path.c_str());
|
||||
return X_STATUS_NOT_FOUND;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue