IR: Implement Vector{Signed,Unsigned}Multiply{16,32}

This commit is contained in:
MerryMage
2018-09-14 20:06:11 +01:00
parent b6df34cdde
commit 08c0e017a5
7 changed files with 302 additions and 2 deletions

View File

@@ -1527,6 +1527,24 @@ U128 IREmitter::VectorSignedAbsoluteDifference(size_t esize, const U128& a, cons
return {};
}
UpperAndLower IREmitter::VectorSignedMultiply(size_t esize, const U128& a, const U128& b) {
const Value multiply = [&] {
switch (esize) {
case 16:
return Inst(Opcode::VectorSignedMultiply16, a, b);
case 32:
return Inst(Opcode::VectorSignedMultiply32, a, b);
}
UNREACHABLE();
return Value{};
}();
return {
Inst<U128>(Opcode::GetUpperFromOp, multiply),
Inst<U128>(Opcode::GetLowerFromOp, multiply),
};
}
U128 IREmitter::VectorSignedSaturatedAbs(size_t esize, const U128& a) {
switch (esize) {
case 8:

View File

@@ -52,6 +52,11 @@ struct ResultAndGE {
U32 ge;
};
struct UpperAndLower {
U128 upper;
U128 lower;
};
/**
* Convenience class to construct a basic block of the intermediate representation.
* `block` is the resulting block.
@@ -265,6 +270,7 @@ public:
U128 VectorShuffleWords(const U128& a, u8 mask);
U128 VectorSignExtend(size_t original_esize, const U128& a);
U128 VectorSignedAbsoluteDifference(size_t esize, const U128& a, const U128& b);
UpperAndLower VectorSignedMultiply(size_t esize, const U128& a, const U128& b);
U128 VectorSignedSaturatedAbs(size_t esize, const U128& a);
U128 VectorSignedSaturatedAccumulateUnsigned(size_t esize, const U128& a, const U128& b);
U128 VectorSignedSaturatedDoublingMultiplyReturnHigh(size_t esize, const U128& a, const U128& b);

View File

@@ -437,6 +437,8 @@ bool Inst::IsAPseudoOperation() const {
case Opcode::GetOverflowFromOp:
case Opcode::GetGEFromOp:
case Opcode::GetNZCVFromOp:
case Opcode::GetUpperFromOp:
case Opcode::GetLowerFromOp:
return true;
default:
@@ -470,7 +472,7 @@ bool Inst::AreAllArgsImmediates() const {
}
bool Inst::HasAssociatedPseudoOperation() const {
return carry_inst || overflow_inst || ge_inst || nzcv_inst;
return carry_inst || overflow_inst || ge_inst || nzcv_inst || upper_inst || lower_inst;
}
Inst* Inst::GetAssociatedPseudoOperation(Opcode opcode) {
@@ -488,6 +490,12 @@ Inst* Inst::GetAssociatedPseudoOperation(Opcode opcode) {
case Opcode::GetNZCVFromOp:
ASSERT(!nzcv_inst || nzcv_inst->GetOpcode() == Opcode::GetNZCVFromOp);
return nzcv_inst;
case Opcode::GetUpperFromOp:
ASSERT(!upper_inst || upper_inst->GetOpcode() == Opcode::GetUpperFromOp);
return upper_inst;
case Opcode::GetLowerFromOp:
ASSERT(!lower_inst || lower_inst->GetOpcode() == Opcode::GetLowerFromOp);
return lower_inst;
default:
break;
}
@@ -574,6 +582,14 @@ void Inst::Use(const Value& value) {
ASSERT_MSG(value.GetInst()->MayGetNZCVFromOp(), "This value doesn't support the GetNZCVFromOp pseduo-op");
value.GetInst()->nzcv_inst = this;
break;
case Opcode::GetUpperFromOp:
ASSERT_MSG(!value.GetInst()->upper_inst, "Only one of each type of pseudo-op allowed");
value.GetInst()->upper_inst = this;
break;
case Opcode::GetLowerFromOp:
ASSERT_MSG(!value.GetInst()->lower_inst, "Only one of each type of pseudo-op allowed");
value.GetInst()->lower_inst = this;
break;
default:
break;
}
@@ -599,6 +615,14 @@ void Inst::UndoUse(const Value& value) {
ASSERT(value.GetInst()->nzcv_inst->GetOpcode() == Opcode::GetNZCVFromOp);
value.GetInst()->nzcv_inst = nullptr;
break;
case Opcode::GetUpperFromOp:
ASSERT(value.GetInst()->upper_inst->GetOpcode() == Opcode::GetUpperFromOp);
value.GetInst()->upper_inst = nullptr;
break;
case Opcode::GetLowerFromOp:
ASSERT(value.GetInst()->lower_inst->GetOpcode() == Opcode::GetLowerFromOp);
value.GetInst()->lower_inst = nullptr;
break;
default:
break;
}

View File

@@ -145,9 +145,13 @@ private:
union {
Inst* carry_inst = nullptr;
Inst* ge_inst;
Inst* upper_inst;
};
Inst* overflow_inst = nullptr;
Inst* nzcv_inst = nullptr;
union {
Inst* nzcv_inst = nullptr;
Inst* lower_inst;
};
};
} // namespace Dynarmic::IR

View File

@@ -79,6 +79,8 @@ OPCODE(GetCarryFromOp, U1, Opaqu
OPCODE(GetOverflowFromOp, U1, Opaque )
OPCODE(GetGEFromOp, U32, Opaque )
OPCODE(GetNZCVFromOp, NZCV, Opaque )
OPCODE(GetUpperFromOp, U128, Opaque )
OPCODE(GetLowerFromOp, U128, Opaque )
OPCODE(NZCVFromPackedFlags, NZCV, U32 )
@@ -396,6 +398,8 @@ OPCODE(VectorSignExtend64, U128, U128
OPCODE(VectorSignedAbsoluteDifference8, U128, U128, U128 )
OPCODE(VectorSignedAbsoluteDifference16, U128, U128, U128 )
OPCODE(VectorSignedAbsoluteDifference32, U128, U128, U128 )
OPCODE(VectorSignedMultiply16, Void, U128, U128 )
OPCODE(VectorSignedMultiply32, Void, U128, U128 )
OPCODE(VectorSignedSaturatedAbs8, U128, U128 )
OPCODE(VectorSignedSaturatedAbs16, U128, U128 )
OPCODE(VectorSignedSaturatedAbs32, U128, U128 )
@@ -425,6 +429,8 @@ OPCODE(VectorTableLookup, U128, U128,
OPCODE(VectorUnsignedAbsoluteDifference8, U128, U128, U128 )
OPCODE(VectorUnsignedAbsoluteDifference16, U128, U128, U128 )
OPCODE(VectorUnsignedAbsoluteDifference32, U128, U128, U128 )
OPCODE(VectorUnsignedMultiply16, Void, U128, U128 )
OPCODE(VectorUnsignedMultiply32, Void, U128, U128 )
OPCODE(VectorUnsignedRecipEstimate, U128, U128 )
OPCODE(VectorUnsignedRecipSqrtEstimate, U128, U128 )
OPCODE(VectorUnsignedSaturatedAccumulateSigned8, U128, U128, U128 )