Fix SRAW on non PowerPC platforms.

This commit is contained in:
gbeauche 2003-11-27 23:53:41 +00:00
parent 8711c4afd6
commit 8ca440d0b5
2 changed files with 24 additions and 12 deletions

View File

@ -680,11 +680,18 @@ void OPPROTO op_srw_T0_T1(void)
void OPPROTO op_sraw_T0_T1(void) void OPPROTO op_sraw_T0_T1(void)
{ {
const uint32 n = T1 & 0x3f; T1 &= 0x3f;
const uint32 RD = ((int32)T0) >> n; if (T1 & 0x20) {
const bool ca = (((int32)T0) < 0) && (T0 & ~(0xffffffff << n)); const uint32 SB = T0 >> 31;
powerpc_dyngen_helper::xer().set_ca(ca); powerpc_dyngen_helper::xer().set_ca(SB);
T0 = RD; T0 = -SB;
}
else {
const uint32 RD = ((int32)T0) >> T1;
const bool CA = (int32)T0 < 0 && (T0 & ~(0xffffffff << T1));
powerpc_dyngen_helper::xer().set_ca(CA);
T0 = RD;
}
dyngen_barrier(); dyngen_barrier();
} }

View File

@ -272,15 +272,20 @@ void powerpc_cpu::execute_shift(uint32 opcode)
{ {
const uint32 n = SO::apply(SH::get(this, opcode)); const uint32 n = SO::apply(SH::get(this, opcode));
const uint32 r = RA::get(this, opcode); const uint32 r = RA::get(this, opcode);
uint32 d;
// Shift operation is valid only if rB[26] = 0 // Shift operation is valid only if rB[26] = 0
// TODO: optimize srw case where shift operation would zero result if (n & 0x20) {
uint32 d = (n & 0x20) ? invalid_shift<OP>::value(r) : OP::apply(r, n); d = invalid_shift<OP>::value(r);
if (CA::test(opcode))
// Set XER (CA) if instruction is algebraic variant xer().set_ca(d >> 31);
if (CA::test(opcode)) { }
const uint32 carry = (r & 0x80000000) && (r & ~(0xffffffff << n)); else {
xer().set_ca(carry); d = OP::apply(r, n);
if (CA::test(opcode)) {
const uint32 ca = (r & 0x80000000) && (r & ~(0xffffffff << n));
xer().set_ca(ca);
}
} }
// Set CR0 (LT, GT, EQ, SO) if instruction has Rc set // Set CR0 (LT, GT, EQ, SO) if instruction has Rc set