TranslateArm: Implement QSUB8.
This commit is contained in:
parent
86fe29c6d2
commit
127fbe99cb
7 changed files with 26 additions and 5 deletions
|
@ -1055,7 +1055,7 @@ void EmitX64::EmitByteReverseDual(IR::Block&, IR::Inst* inst) {
|
|||
code->BSWAP(64, result);
|
||||
}
|
||||
|
||||
void EmitX64::EmitPackedSaturatedSubU8(IR::Block& block, IR::Inst* inst) {
|
||||
static void EmitPackedOperation(BlockOfCode* code, RegAlloc& reg_alloc, IR::Inst* inst, void (XEmitter::*fn)(X64Reg, const OpArg&)) {
|
||||
IR::Value a = inst->GetArg(0);
|
||||
IR::Value b = inst->GetArg(1);
|
||||
|
||||
|
@ -1068,11 +1068,19 @@ void EmitX64::EmitPackedSaturatedSubU8(IR::Block& block, IR::Inst* inst) {
|
|||
code->MOVD_xmm(xmm_scratch_a, R(result));
|
||||
code->MOVD_xmm(xmm_scratch_b, op_arg);
|
||||
|
||||
code->PSUBUSB(xmm_scratch_a, R(xmm_scratch_b));
|
||||
(code->*fn)(xmm_scratch_a, R(xmm_scratch_b));
|
||||
|
||||
code->MOVD_xmm(R(result), xmm_scratch_a);
|
||||
}
|
||||
|
||||
void EmitX64::EmitPackedSaturatedSubU8(IR::Block& block, IR::Inst* inst) {
|
||||
EmitPackedOperation(code, reg_alloc, inst, &XEmitter::PSUBUSB);
|
||||
}
|
||||
|
||||
void EmitX64::EmitPackedSaturatedSubS8(IR::Block& block, IR::Inst* inst) {
|
||||
EmitPackedOperation(code, reg_alloc, inst, &XEmitter::PSUBSB);
|
||||
}
|
||||
|
||||
static void DenormalsAreZero32(BlockOfCode* code, X64Reg xmm_value, X64Reg gpr_scratch) {
|
||||
// We need to report back whether we've found a denormal on input.
|
||||
// SSE doesn't do this for us when SSE's DAZ is enabled.
|
||||
|
|
|
@ -667,7 +667,9 @@ public:
|
|||
std::string arm_QADD16(Cond cond, Reg n, Reg d, Reg m) { return "ice"; }
|
||||
std::string arm_QASX(Cond cond, Reg n, Reg d, Reg m) { return "ice"; }
|
||||
std::string arm_QSAX(Cond cond, Reg n, Reg d, Reg m) { return "ice"; }
|
||||
std::string arm_QSUB8(Cond cond, Reg n, Reg d, Reg m) { return "ice"; }
|
||||
std::string arm_QSUB8(Cond cond, Reg n, Reg d, Reg m) {
|
||||
return Common::StringFromFormat("qsub8%s %s, %s, %s", CondToString(cond), RegToString(d), RegToString(n), RegToString(m));
|
||||
}
|
||||
std::string arm_QSUB16(Cond cond, Reg n, Reg d, Reg m) { return "ice"; }
|
||||
std::string arm_UQADD8(Cond cond, Reg n, Reg d, Reg m) { return "ice"; }
|
||||
std::string arm_UQADD16(Cond cond, Reg n, Reg d, Reg m) { return "ice"; }
|
||||
|
|
|
@ -286,6 +286,10 @@ IR::Value IREmitter::PackedSaturatedSubU8(const IR::Value& a, const IR::Value& b
|
|||
return Inst(IR::Opcode::PackedSaturatedSubU8, {a, b});
|
||||
}
|
||||
|
||||
IR::Value IREmitter::PackedSaturatedSubS8(const IR::Value& a, const IR::Value& b) {
|
||||
return Inst(IR::Opcode::PackedSaturatedSubS8, {a, b});
|
||||
}
|
||||
|
||||
IR::Value IREmitter::TransferToFP32(const IR::Value& a) {
|
||||
return Inst(IR::Opcode::TransferToFP32, {a});
|
||||
}
|
||||
|
|
|
@ -99,6 +99,7 @@ public:
|
|||
IR::Value ByteReverseHalf(const IR::Value& a);
|
||||
IR::Value ByteReverseDual(const IR::Value& a);
|
||||
IR::Value PackedSaturatedSubU8(const IR::Value& a, const IR::Value& b);
|
||||
IR::Value PackedSaturatedSubS8(const IR::Value& a, const IR::Value& b);
|
||||
|
||||
IR::Value TransferToFP32(const IR::Value& a);
|
||||
IR::Value TransferToFP64(const IR::Value& a);
|
||||
|
|
|
@ -61,6 +61,7 @@ OPCODE(ByteReverseWord, T::U32, T::U32
|
|||
OPCODE(ByteReverseHalf, T::U16, T::U16 )
|
||||
OPCODE(ByteReverseDual, T::U64, T::U64 )
|
||||
OPCODE(PackedSaturatedSubU8, T::U32, T::U32, T::U32 )
|
||||
OPCODE(PackedSaturatedSubS8, T::U32, T::U32, T::U32 )
|
||||
|
||||
// Floating-point
|
||||
OPCODE(TransferToFP32, T::F32, T::U32 )
|
||||
|
|
|
@ -77,7 +77,11 @@ bool ArmTranslatorVisitor::arm_QSAX(Cond cond, Reg n, Reg d, Reg m) {
|
|||
}
|
||||
|
||||
bool ArmTranslatorVisitor::arm_QSUB8(Cond cond, Reg n, Reg d, Reg m) {
|
||||
return InterpretThisInstruction();
|
||||
if (ConditionPassed(cond)) {
|
||||
auto result = ir.PackedSaturatedSubS8(ir.GetRegister(n), ir.GetRegister(m));
|
||||
ir.SetRegister(d, result);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ArmTranslatorVisitor::arm_QSUB16(Cond cond, Reg n, Reg d, Reg m) {
|
||||
|
|
|
@ -829,8 +829,9 @@ TEST_CASE("Fuzz ARM parallel instructions", "[JitX64]") {
|
|||
return Bits<0, 3>(instr) != 0b1111 && Bits<12, 15>(instr) != 0b1111 && Bits<16, 19>(instr) != 0b1111;
|
||||
};
|
||||
|
||||
const std::array<InstructionGenerator, 1> saturating_instructions = {{
|
||||
const std::array<InstructionGenerator, 2> saturating_instructions = {{
|
||||
InstructionGenerator("cccc01100110nnnndddd11111111mmmm", is_valid), // UQSUB8
|
||||
InstructionGenerator("cccc01100010nnnndddd11111111mmmm", is_valid), // QSUB8
|
||||
}};
|
||||
|
||||
SECTION("Parallel Add/Subtract (Saturating)") {
|
||||
|
|
Loading…
Reference in a new issue