PPC: Support FPSCR[RN] (rounding mode)
This commit is contained in:
parent
4e6a51472d
commit
e8f55d8ff2
|
@ -240,10 +240,8 @@ int InstrEmit_fcfidx(PPCHIRBuilder& f, const InstrData& i) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int InstrEmit_fctidx(PPCHIRBuilder& f, const InstrData& i) {
|
int InstrEmit_fctidxx_(PPCHIRBuilder& f, const InstrData& i,
|
||||||
// frD <- double_to_signed_int64( frB )
|
RoundMode round_mode) {
|
||||||
// TODO(benvanik): pull from FPSCR[RN]
|
|
||||||
RoundMode round_mode = ROUND_TO_ZERO;
|
|
||||||
Value* v = f.Convert(f.LoadFPR(i.X.RB), INT64_TYPE, round_mode);
|
Value* v = f.Convert(f.LoadFPR(i.X.RB), INT64_TYPE, round_mode);
|
||||||
v = f.Cast(v, FLOAT64_TYPE);
|
v = f.Cast(v, FLOAT64_TYPE);
|
||||||
f.StoreFPR(i.X.RT, v);
|
f.StoreFPR(i.X.RT, v);
|
||||||
|
@ -251,15 +249,17 @@ int InstrEmit_fctidx(PPCHIRBuilder& f, const InstrData& i) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int InstrEmit_fctidzx(PPCHIRBuilder& f, const InstrData& i) {
|
int InstrEmit_fctidx(PPCHIRBuilder& f, const InstrData& i) {
|
||||||
// TODO(benvanik): assuming round to zero is always set, is that ok?
|
// frD <- double_to_signed_int64( frB )
|
||||||
return InstrEmit_fctidx(f, i);
|
return InstrEmit_fctidxx_(f, i, ROUND_DYNAMIC);
|
||||||
}
|
}
|
||||||
|
|
||||||
int InstrEmit_fctiwx(PPCHIRBuilder& f, const InstrData& i) {
|
int InstrEmit_fctidzx(PPCHIRBuilder& f, const InstrData& i) {
|
||||||
// frD <- double_to_signed_int32( frB )
|
return InstrEmit_fctidxx_(f, i, ROUND_TO_ZERO);
|
||||||
// TODO(benvanik): pull from FPSCR[RN]
|
}
|
||||||
RoundMode round_mode = ROUND_TO_ZERO;
|
|
||||||
|
int InstrEmit_fctiwxx_(PPCHIRBuilder& f, const InstrData& i,
|
||||||
|
RoundMode round_mode) {
|
||||||
Value* v = f.Convert(f.LoadFPR(i.X.RB), INT32_TYPE, round_mode);
|
Value* v = f.Convert(f.LoadFPR(i.X.RB), INT32_TYPE, round_mode);
|
||||||
v = f.Cast(f.SignExtend(v, INT64_TYPE), FLOAT64_TYPE);
|
v = f.Cast(f.SignExtend(v, INT64_TYPE), FLOAT64_TYPE);
|
||||||
f.StoreFPR(i.X.RT, v);
|
f.StoreFPR(i.X.RT, v);
|
||||||
|
@ -267,16 +267,19 @@ int InstrEmit_fctiwx(PPCHIRBuilder& f, const InstrData& i) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int InstrEmit_fctiwx(PPCHIRBuilder& f, const InstrData& i) {
|
||||||
|
// frD <- double_to_signed_int32( frB )
|
||||||
|
return InstrEmit_fctiwxx_(f, i, ROUND_DYNAMIC);
|
||||||
|
}
|
||||||
|
|
||||||
int InstrEmit_fctiwzx(PPCHIRBuilder& f, const InstrData& i) {
|
int InstrEmit_fctiwzx(PPCHIRBuilder& f, const InstrData& i) {
|
||||||
// TODO(benvanik): assuming round to zero is always set, is that ok?
|
// TODO(benvanik): assuming round to zero is always set, is that ok?
|
||||||
return InstrEmit_fctiwx(f, i);
|
return InstrEmit_fctiwxx_(f, i, ROUND_TO_ZERO);
|
||||||
}
|
}
|
||||||
|
|
||||||
int InstrEmit_frspx(PPCHIRBuilder& f, const InstrData& i) {
|
int InstrEmit_frspx(PPCHIRBuilder& f, const InstrData& i) {
|
||||||
// frD <- Round_single(frB)
|
// frD <- Round_single(frB)
|
||||||
// TODO(benvanik): pull from FPSCR[RN]
|
Value* v = f.Convert(f.LoadFPR(i.X.RB), FLOAT32_TYPE, ROUND_DYNAMIC);
|
||||||
RoundMode round_mode = ROUND_TO_ZERO;
|
|
||||||
Value* v = f.Convert(f.LoadFPR(i.X.RB), FLOAT32_TYPE, round_mode);
|
|
||||||
v = f.Convert(v, FLOAT64_TYPE);
|
v = f.Convert(v, FLOAT64_TYPE);
|
||||||
f.StoreFPR(i.X.RT, v);
|
f.StoreFPR(i.X.RT, v);
|
||||||
f.UpdateFPSCR(v, i.X.Rc);
|
f.UpdateFPSCR(v, i.X.Rc);
|
||||||
|
@ -355,15 +358,33 @@ int InstrEmit_mtfsb1x(PPCHIRBuilder& f, const InstrData& i) {
|
||||||
int InstrEmit_mtfsfx(PPCHIRBuilder& f, const InstrData& i) {
|
int InstrEmit_mtfsfx(PPCHIRBuilder& f, const InstrData& i) {
|
||||||
if (i.XFL.L) {
|
if (i.XFL.L) {
|
||||||
// Move/shift.
|
// Move/shift.
|
||||||
XEINSTRNOTIMPLEMENTED();
|
|
||||||
return 1;
|
|
||||||
} else {
|
|
||||||
// Directly store.
|
|
||||||
// TODO(benvanik): use w/field mask to select bits.
|
|
||||||
// i.XFL.W;
|
|
||||||
// i.XFL.FM;
|
|
||||||
f.StoreFPSCR(
|
f.StoreFPSCR(
|
||||||
f.Truncate(f.Cast(f.LoadFPR(i.XFL.RB), INT64_TYPE), INT32_TYPE));
|
f.Truncate(f.Cast(f.LoadFPR(i.XFL.RB), INT64_TYPE), INT32_TYPE));
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
assert_zero(i.XFL.W);
|
||||||
|
|
||||||
|
// Store under control of mask.
|
||||||
|
// Expand the mask from 8 bits -> 32 bits.
|
||||||
|
uint32_t mask = 0;
|
||||||
|
for (int j = 0; j < 8; j++) {
|
||||||
|
if (i.XFL.FM & (1 << (j ^ 7))) {
|
||||||
|
mask |= 0xF << (4 * j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Value* v = f.Truncate(f.Cast(f.LoadFPR(i.XFL.RB), INT64_TYPE), INT32_TYPE);
|
||||||
|
if (mask != 0xFFFFFFFF) {
|
||||||
|
Value* fpscr = f.LoadFPSCR();
|
||||||
|
v = f.And(v, f.LoadConstantInt32(mask));
|
||||||
|
v = f.Or(v, f.And(fpscr, f.LoadConstantInt32(~mask)));
|
||||||
|
}
|
||||||
|
f.StoreFPSCR(v);
|
||||||
|
|
||||||
|
// Update the system rounding mode.
|
||||||
|
if (mask & 0x7) {
|
||||||
|
f.SetRoundingMode(v);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (i.XFL.Rc) {
|
if (i.XFL.Rc) {
|
||||||
f.CopyFPSCRToCR1();
|
f.CopyFPSCRToCR1();
|
||||||
|
@ -372,8 +393,27 @@ int InstrEmit_mtfsfx(PPCHIRBuilder& f, const InstrData& i) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int InstrEmit_mtfsfix(PPCHIRBuilder& f, const InstrData& i) {
|
int InstrEmit_mtfsfix(PPCHIRBuilder& f, const InstrData& i) {
|
||||||
XEINSTRNOTIMPLEMENTED();
|
// FPSCR[crfD] <- IMM
|
||||||
return 1;
|
|
||||||
|
// Create a mask.
|
||||||
|
uint32_t mask = 0xF << (0x1C - (i.X.RT & 0x1C));
|
||||||
|
uint32_t value = i.X.RB << (0x1C - (i.X.RT & 0x1C));
|
||||||
|
|
||||||
|
Value* fpscr = f.LoadFPSCR();
|
||||||
|
fpscr = f.And(fpscr, f.LoadConstantInt32(~mask));
|
||||||
|
fpscr = f.Or(fpscr, f.LoadConstantInt32(value));
|
||||||
|
f.StoreFPSCR(fpscr);
|
||||||
|
|
||||||
|
// Update the system rounding mode.
|
||||||
|
if (mask & 0x7) {
|
||||||
|
f.SetRoundingMode(fpscr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i.X.Rc) {
|
||||||
|
f.CopyFPSCRToCR1();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Floating-point move (A-21)
|
// Floating-point move (A-21)
|
||||||
|
|
Loading…
Reference in New Issue