diff --git a/src/frontend/A32/translate/translate_arm/extension.cpp b/src/frontend/A32/translate/translate_arm/extension.cpp index a7c6edf6..15b1d3b2 100644 --- a/src/frontend/A32/translate/translate_arm/extension.cpp +++ b/src/frontend/A32/translate/translate_arm/extension.cpp @@ -13,170 +13,217 @@ static IR::U32 Rotate(A32::IREmitter& ir, Reg m, SignExtendRotation rotate) { return ir.RotateRight(ir.GetRegister(m), ir.Imm8(rotate_by), ir.Imm1(0)).result; } +// SXTAB , , {, } bool ArmTranslatorVisitor::arm_SXTAB(Cond cond, Reg n, Reg d, SignExtendRotation rotate, Reg m) { - if (d == Reg::PC || m == Reg::PC) + if (d == Reg::PC || m == Reg::PC) { return UnpredictableInstruction(); - - // SXTAB , , , - if (ConditionPassed(cond)) { - auto rotated = Rotate(ir, m, rotate); - auto reg_n = ir.GetRegister(n); - auto result = ir.Add(reg_n, ir.SignExtendByteToWord(ir.LeastSignificantByte(rotated))); - ir.SetRegister(d, result); } + + if (!ConditionPassed(cond)) { + return true; + } + + const auto rotated = Rotate(ir, m, rotate); + const auto reg_n = ir.GetRegister(n); + const auto result = ir.Add(reg_n, ir.SignExtendByteToWord(ir.LeastSignificantByte(rotated))); + + ir.SetRegister(d, result); return true; } +// SXTAB16 , , {, } bool ArmTranslatorVisitor::arm_SXTAB16(Cond cond, Reg n, Reg d, SignExtendRotation rotate, Reg m) { - if (d == Reg::PC || m == Reg::PC) + if (d == Reg::PC || m == Reg::PC) { return UnpredictableInstruction(); - - // SXTAB16 , , , - if (ConditionPassed(cond)) { - auto rotated = Rotate(ir, m, rotate); - auto low_byte = ir.And(rotated, ir.Imm32(0x00FF00FF)); - auto sign_bit = ir.And(rotated, ir.Imm32(0x00800080)); - auto addend = ir.Or(low_byte, ir.Mul(sign_bit, ir.Imm32(0x1FE))); - auto result = ir.PackedAddU16(addend, ir.GetRegister(n)).result; - ir.SetRegister(d, result); } + + if (!ConditionPassed(cond)) { + return true; + } + + const auto rotated = Rotate(ir, m, rotate); + const auto low_byte = ir.And(rotated, ir.Imm32(0x00FF00FF)); + const auto sign_bit = ir.And(rotated, ir.Imm32(0x00800080)); + const auto addend = ir.Or(low_byte, ir.Mul(sign_bit, ir.Imm32(0x1FE))); + const auto result = ir.PackedAddU16(addend, ir.GetRegister(n)).result; + + ir.SetRegister(d, result); return true; } +// SXTAH , , {, } bool ArmTranslatorVisitor::arm_SXTAH(Cond cond, Reg n, Reg d, SignExtendRotation rotate, Reg m) { - if (d == Reg::PC || m == Reg::PC) + if (d == Reg::PC || m == Reg::PC) { return UnpredictableInstruction(); - - // SXTAH , , , - if (ConditionPassed(cond)) { - auto rotated = Rotate(ir, m, rotate); - auto reg_n = ir.GetRegister(n); - auto result = ir.Add(reg_n, ir.SignExtendHalfToWord(ir.LeastSignificantHalf(rotated))); - ir.SetRegister(d, result); } + + if (!ConditionPassed(cond)) { + return true; + } + + const auto rotated = Rotate(ir, m, rotate); + const auto reg_n = ir.GetRegister(n); + const auto result = ir.Add(reg_n, ir.SignExtendHalfToWord(ir.LeastSignificantHalf(rotated))); + + ir.SetRegister(d, result); return true; } +// SXTB , {, } bool ArmTranslatorVisitor::arm_SXTB(Cond cond, Reg d, SignExtendRotation rotate, Reg m) { - if (d == Reg::PC || m == Reg::PC) + if (d == Reg::PC || m == Reg::PC) { return UnpredictableInstruction(); - - // SXTB , , - if (ConditionPassed(cond)) { - auto rotated = Rotate(ir, m, rotate); - auto result = ir.SignExtendByteToWord(ir.LeastSignificantByte(rotated)); - ir.SetRegister(d, result); } + + if (!ConditionPassed(cond)) { + return true; + } + + const auto rotated = Rotate(ir, m, rotate); + const auto result = ir.SignExtendByteToWord(ir.LeastSignificantByte(rotated)); + + ir.SetRegister(d, result); return true; } +// SXTB16 , {, } bool ArmTranslatorVisitor::arm_SXTB16(Cond cond, Reg d, SignExtendRotation rotate, Reg m) { - if (d == Reg::PC || m == Reg::PC) + if (d == Reg::PC || m == Reg::PC) { return UnpredictableInstruction(); - - // SXTB16 , , - if (ConditionPassed(cond)) { - auto rotated = Rotate(ir, m, rotate); - auto low_byte = ir.And(rotated, ir.Imm32(0x00FF00FF)); - auto sign_bit = ir.And(rotated, ir.Imm32(0x00800080)); - auto result = ir.Or(low_byte, ir.Mul(sign_bit, ir.Imm32(0x1FE))); - ir.SetRegister(d, result); } + + if (!ConditionPassed(cond)) { + return true; + } + + const auto rotated = Rotate(ir, m, rotate); + const auto low_byte = ir.And(rotated, ir.Imm32(0x00FF00FF)); + const auto sign_bit = ir.And(rotated, ir.Imm32(0x00800080)); + const auto result = ir.Or(low_byte, ir.Mul(sign_bit, ir.Imm32(0x1FE))); + + ir.SetRegister(d, result); return true; } +// SXTH , {, } bool ArmTranslatorVisitor::arm_SXTH(Cond cond, Reg d, SignExtendRotation rotate, Reg m) { - if (d == Reg::PC || m == Reg::PC) + if (d == Reg::PC || m == Reg::PC) { return UnpredictableInstruction(); - - // SXTH , , - if (ConditionPassed(cond)) { - auto rotated = Rotate(ir, m, rotate); - auto result = ir.SignExtendHalfToWord(ir.LeastSignificantHalf(rotated)); - ir.SetRegister(d, result); } + + if (!ConditionPassed(cond)) { + return true; + } + + const auto rotated = Rotate(ir, m, rotate); + const auto result = ir.SignExtendHalfToWord(ir.LeastSignificantHalf(rotated)); + + ir.SetRegister(d, result); return true; } +// UXTAB , , {, } bool ArmTranslatorVisitor::arm_UXTAB(Cond cond, Reg n, Reg d, SignExtendRotation rotate, Reg m) { - if (d == Reg::PC || m == Reg::PC) + if (d == Reg::PC || m == Reg::PC) { return UnpredictableInstruction(); - - // UXTAB , , , - if (ConditionPassed(cond)) { - auto rotated = Rotate(ir, m, rotate); - auto reg_n = ir.GetRegister(n); - auto result = ir.Add(reg_n, ir.ZeroExtendByteToWord(ir.LeastSignificantByte(rotated))); - ir.SetRegister(d, result); } + + if (!ConditionPassed(cond)) { + return true; + } + + const auto rotated = Rotate(ir, m, rotate); + const auto reg_n = ir.GetRegister(n); + const auto result = ir.Add(reg_n, ir.ZeroExtendByteToWord(ir.LeastSignificantByte(rotated))); + + ir.SetRegister(d, result); return true; } +// UXTAB16 , , {, } bool ArmTranslatorVisitor::arm_UXTAB16(Cond cond, Reg n, Reg d, SignExtendRotation rotate, Reg m) { - if (d == Reg::PC || m == Reg::PC || n == Reg::PC) + if (d == Reg::PC || m == Reg::PC || n == Reg::PC) { return UnpredictableInstruction(); - - // UXTAB16 , , , - if (ConditionPassed(cond)) { - auto rotated = Rotate(ir, m, rotate); - auto result = ir.And(rotated, ir.Imm32(0x00FF00FF)); - auto reg_n = ir.GetRegister(n); - result = ir.PackedAddU16(reg_n, result).result; - ir.SetRegister(d, result); } + + if (!ConditionPassed(cond)) { + return true; + } + + const auto rotated = Rotate(ir, m, rotate); + auto result = ir.And(rotated, ir.Imm32(0x00FF00FF)); + const auto reg_n = ir.GetRegister(n); + result = ir.PackedAddU16(reg_n, result).result; + + ir.SetRegister(d, result); return true; } +// UXTAH , , {, } bool ArmTranslatorVisitor::arm_UXTAH(Cond cond, Reg n, Reg d, SignExtendRotation rotate, Reg m) { - if (d == Reg::PC || m == Reg::PC) + if (d == Reg::PC || m == Reg::PC) { return UnpredictableInstruction(); - - // UXTAH , , , - if (ConditionPassed(cond)) { - auto rotated = Rotate(ir, m, rotate); - auto reg_n = ir.GetRegister(n); - auto result = ir.Add(reg_n, ir.ZeroExtendHalfToWord(ir.LeastSignificantHalf(rotated))); - ir.SetRegister(d, result); } + + if (!ConditionPassed(cond)) { + return true; + } + + const auto rotated = Rotate(ir, m, rotate); + const auto reg_n = ir.GetRegister(n); + const auto result = ir.Add(reg_n, ir.ZeroExtendHalfToWord(ir.LeastSignificantHalf(rotated))); + + ir.SetRegister(d, result); return true; } +// UXTB , {, } bool ArmTranslatorVisitor::arm_UXTB(Cond cond, Reg d, SignExtendRotation rotate, Reg m) { - if (d == Reg::PC || m == Reg::PC) + if (d == Reg::PC || m == Reg::PC) { return UnpredictableInstruction(); - - // UXTB , , - if (ConditionPassed(cond)) { - auto rotated = Rotate(ir, m, rotate); - auto result = ir.ZeroExtendByteToWord(ir.LeastSignificantByte(rotated)); - ir.SetRegister(d, result); } + + if (!ConditionPassed(cond)) { + return true; + } + + const auto rotated = Rotate(ir, m, rotate); + const auto result = ir.ZeroExtendByteToWord(ir.LeastSignificantByte(rotated)); + ir.SetRegister(d, result); return true; } +// UXTB16 , {, } bool ArmTranslatorVisitor::arm_UXTB16(Cond cond, Reg d, SignExtendRotation rotate, Reg m) { - if (d == Reg::PC || m == Reg::PC) + if (d == Reg::PC || m == Reg::PC) { return UnpredictableInstruction(); - - // UXTB16 , , - if (ConditionPassed(cond)) { - auto rotated = Rotate(ir, m, rotate); - auto result = ir.And(rotated, ir.Imm32(0x00FF00FF)); - ir.SetRegister(d, result); } + + if (!ConditionPassed(cond)) { + return true; + } + + const auto rotated = Rotate(ir, m, rotate); + const auto result = ir.And(rotated, ir.Imm32(0x00FF00FF)); + + ir.SetRegister(d, result); return true; } +// UXTH , {, } bool ArmTranslatorVisitor::arm_UXTH(Cond cond, Reg d, SignExtendRotation rotate, Reg m) { - if (d == Reg::PC || m == Reg::PC) + if (d == Reg::PC || m == Reg::PC) { return UnpredictableInstruction(); - - // UXTH , , - if (ConditionPassed(cond)) { - auto rotated = Rotate(ir, m, rotate); - auto result = ir.ZeroExtendHalfToWord(ir.LeastSignificantHalf(rotated)); - ir.SetRegister(d, result); } + + if (!ConditionPassed(cond)) { + return true; + } + + const auto rotated = Rotate(ir, m, rotate); + const auto result = ir.ZeroExtendHalfToWord(ir.LeastSignificantHalf(rotated)); + + ir.SetRegister(d, result); return true; }