[CPU/PPC] Implement and fix FPSCR-related instructions

mcrfs: Implement Move CR from FPSCR instruction
Copies a 4-bit FPSCR field to CR and clears the FPSCR exception bits.

mffsx: Fix Rc bit handling
Properly update CR1 from FPSCR when Rc=1 instead of returning error.
Previously treated Rc=1 as unimplemented.

fcfidx: Fix Rc field access
Use i.X.Rc instead of i.A.Rc for correct instruction format.
fcfid uses X format, not A format.
This commit is contained in:
Herman S.
2025-10-19 14:10:56 +09:00
parent fb76cbb291
commit f4af1e2a77

View File

@@ -237,7 +237,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.UpdateFPSCR(v, i.A.Rc);
f.UpdateFPSCR(v, i.X.Rc);
return 0;
}
@@ -352,17 +352,37 @@ int InstrEmit_fcmpu(PPCHIRBuilder& f, const InstrData& i) {
// Floating-point status and control register (A
int InstrEmit_mcrfs(PPCHIRBuilder& f, const InstrData& i) {
XEINSTRNOTIMPLEMENTED();
return 1;
// mcrfs CRFD, CRFS
// CR[4*CRFD:4*CRFD+3] <- FPSCR[4*CRFS:4*CRFS+3]
// FPSCR[4*CRFS:4*CRFS+3] <- 0 (exception bits cleared)
uint32_t crfd = i.X.RT >> 2; // Destination CR field
uint32_t crfs = i.X.RA >> 2; // Source FPSCR field
Value* fpscr = f.LoadFPSCR();
// Extract 4-bit field from FPSCR
// FPSCR fields are numbered from left to right (0-7), with field 0 being bits
// 0-3
uint32_t shift = 4 * (7 - crfs);
Value* fpscr_field = f.And(f.Shr(fpscr, shift), f.LoadConstantUint32(0xF));
// Store to CR field (need to shift to proper position in 64-bit CR)
f.StoreCR(crfd, f.Shl(f.ZeroExtend(fpscr_field, INT64_TYPE), 4 * (7 - crfd)));
// Clear the FPSCR field (set to 0)
uint32_t mask = ~(0xF << shift);
f.StoreFPSCR(f.And(fpscr, f.LoadConstantUint32(mask)));
return 0;
}
int InstrEmit_mffsx(PPCHIRBuilder& f, const InstrData& i) {
if (i.X.Rc) {
XEINSTRNOTIMPLEMENTED();
return 1;
}
Value* v = f.Cast(f.ZeroExtend(f.LoadFPSCR(), INT64_TYPE), FLOAT64_TYPE);
f.StoreFPR(i.X.RT, v);
if (i.X.Rc) {
f.CopyFPSCRToCR1();
}
return 0;
}