A64: Implement RMIF
This commit is contained in:
parent
51b526e453
commit
20ffe568d0
2 changed files with 45 additions and 1 deletions
|
@ -82,7 +82,7 @@ INST(MRS, "MRS", "11010
|
|||
|
||||
// System - Flag manipulation instructions
|
||||
INST(CFINV, "CFINV", "11010101000000000100000000011111") // ARMv8.4
|
||||
//INST(RMIF, "RMIF", "10111010000iiiiii00001nnnnn0IIII") // ARMv8.4
|
||||
INST(RMIF, "RMIF", "10111010000iiiiii00001nnnnn0IIII") // ARMv8.4
|
||||
//INST(SETF8, "SETF8", "0011101000000000000010nnnnn01101") // ARMv8.4
|
||||
//INST(SETF16, "SETF16", "0011101000000000010010nnnnn01101") // ARMv8.4
|
||||
|
||||
|
|
|
@ -16,4 +16,48 @@ bool TranslatorVisitor::CFINV() {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::RMIF(Imm<6> lsb, Reg Rn, Imm<4> mask) {
|
||||
const u32 mask_value = mask.ZeroExtend();
|
||||
|
||||
// If no bits are to be moved into the NZCV bits, then we
|
||||
// just preserve the bits and do no extra work.
|
||||
if (mask_value == 0) {
|
||||
ir.SetNZCVRaw(ir.GetNZCVRaw());
|
||||
return true;
|
||||
}
|
||||
|
||||
const IR::U64 tmp_reg = ir.GetX(Rn);
|
||||
const IR::U64 rotated = ir.RotateRight(tmp_reg, ir.Imm8(lsb.ZeroExtend<u8>()));
|
||||
const IR::U32 shifted = ir.LeastSignificantWord(ir.LogicalShiftLeft(rotated, ir.Imm8(28)));
|
||||
|
||||
// On the other hand, if all mask bits are set, then we move all four
|
||||
// relevant bits in the source register to the NZCV bits.
|
||||
if (mask_value == 0b1111) {
|
||||
ir.SetNZCVRaw(shifted);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Determine which bits from the PSTATE will be preserved during the operation.
|
||||
u32 preservation_mask = 0;
|
||||
if ((mask_value & 0b1000) == 0) {
|
||||
preservation_mask |= 1U << 31;
|
||||
}
|
||||
if ((mask_value & 0b0100) == 0) {
|
||||
preservation_mask |= 1U << 30;
|
||||
}
|
||||
if ((mask_value & 0b0010) == 0) {
|
||||
preservation_mask |= 1U << 29;
|
||||
}
|
||||
if ((mask_value & 0b0001) == 0) {
|
||||
preservation_mask |= 1U << 28;
|
||||
}
|
||||
|
||||
const IR::U32 masked = ir.And(shifted, ir.Imm32(~preservation_mask));
|
||||
const IR::U32 nzcv = ir.And(ir.GetNZCVRaw(), ir.Imm32(preservation_mask));
|
||||
const IR::U32 result = ir.Or(nzcv, masked);
|
||||
|
||||
ir.SetNZCVRaw(result);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace Dynarmic::A64
|
||||
|
|
Loading…
Reference in a new issue