A64: Implement SRSHL and URSHL
Implements both scalar and vector variants.
This commit is contained in:
parent
0efa2ce3b0
commit
29f8b30634
4 changed files with 70 additions and 8 deletions
|
@ -2385,25 +2385,25 @@ void EmitX64::EmitVectorRoundingShiftLeftS64(EmitContext& ctx, IR::Inst* inst) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitX64::EmitVectorRoundingShiftLeftU8(EmitContext& ctx, IR::Inst* inst) {
|
void EmitX64::EmitVectorRoundingShiftLeftU8(EmitContext& ctx, IR::Inst* inst) {
|
||||||
EmitTwoArgumentFallback(code, ctx, inst, [](VectorArray<u8>& result, const VectorArray<u8>& lhs, const VectorArray<u8>& rhs) {
|
EmitTwoArgumentFallback(code, ctx, inst, [](VectorArray<u8>& result, const VectorArray<u8>& lhs, const VectorArray<s8>& rhs) {
|
||||||
RoundingShiftLeft(result, lhs, rhs);
|
RoundingShiftLeft(result, lhs, rhs);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitX64::EmitVectorRoundingShiftLeftU16(EmitContext& ctx, IR::Inst* inst) {
|
void EmitX64::EmitVectorRoundingShiftLeftU16(EmitContext& ctx, IR::Inst* inst) {
|
||||||
EmitTwoArgumentFallback(code, ctx, inst, [](VectorArray<u16>& result, const VectorArray<u16>& lhs, const VectorArray<u16>& rhs) {
|
EmitTwoArgumentFallback(code, ctx, inst, [](VectorArray<u16>& result, const VectorArray<u16>& lhs, const VectorArray<s16>& rhs) {
|
||||||
RoundingShiftLeft(result, lhs, rhs);
|
RoundingShiftLeft(result, lhs, rhs);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitX64::EmitVectorRoundingShiftLeftU32(EmitContext& ctx, IR::Inst* inst) {
|
void EmitX64::EmitVectorRoundingShiftLeftU32(EmitContext& ctx, IR::Inst* inst) {
|
||||||
EmitTwoArgumentFallback(code, ctx, inst, [](VectorArray<u32>& result, const VectorArray<u32>& lhs, const VectorArray<u32>& rhs) {
|
EmitTwoArgumentFallback(code, ctx, inst, [](VectorArray<u32>& result, const VectorArray<u32>& lhs, const VectorArray<s32>& rhs) {
|
||||||
RoundingShiftLeft(result, lhs, rhs);
|
RoundingShiftLeft(result, lhs, rhs);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitX64::EmitVectorRoundingShiftLeftU64(EmitContext& ctx, IR::Inst* inst) {
|
void EmitX64::EmitVectorRoundingShiftLeftU64(EmitContext& ctx, IR::Inst* inst) {
|
||||||
EmitTwoArgumentFallback(code, ctx, inst, [](VectorArray<u64>& result, const VectorArray<u64>& lhs, const VectorArray<u64>& rhs) {
|
EmitTwoArgumentFallback(code, ctx, inst, [](VectorArray<u64>& result, const VectorArray<u64>& lhs, const VectorArray<s64>& rhs) {
|
||||||
RoundingShiftLeft(result, lhs, rhs);
|
RoundingShiftLeft(result, lhs, rhs);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -450,7 +450,7 @@ INST(CMGT_reg_1, "CMGT (register)", "01011
|
||||||
INST(CMGE_reg_1, "CMGE (register)", "01011110zz1mmmmm001111nnnnnddddd")
|
INST(CMGE_reg_1, "CMGE (register)", "01011110zz1mmmmm001111nnnnnddddd")
|
||||||
INST(SSHL_1, "SSHL", "01011110zz1mmmmm010001nnnnnddddd")
|
INST(SSHL_1, "SSHL", "01011110zz1mmmmm010001nnnnnddddd")
|
||||||
//INST(SQSHL_reg_1, "SQSHL (register)", "01011110zz1mmmmm010011nnnnnddddd")
|
//INST(SQSHL_reg_1, "SQSHL (register)", "01011110zz1mmmmm010011nnnnnddddd")
|
||||||
//INST(SRSHL_1, "SRSHL", "01011110zz1mmmmm010101nnnnnddddd")
|
INST(SRSHL_1, "SRSHL", "01011110zz1mmmmm010101nnnnnddddd")
|
||||||
//INST(SQRSHL_1, "SQRSHL", "01011110zz1mmmmm010111nnnnnddddd")
|
//INST(SQRSHL_1, "SQRSHL", "01011110zz1mmmmm010111nnnnnddddd")
|
||||||
INST(ADD_1, "ADD (vector)", "01011110zz1mmmmm100001nnnnnddddd")
|
INST(ADD_1, "ADD (vector)", "01011110zz1mmmmm100001nnnnnddddd")
|
||||||
INST(CMTST_1, "CMTST", "01011110zz1mmmmm100011nnnnnddddd")
|
INST(CMTST_1, "CMTST", "01011110zz1mmmmm100011nnnnnddddd")
|
||||||
|
@ -461,7 +461,7 @@ INST(CMHI_1, "CMHI (register)", "01111
|
||||||
INST(CMHS_1, "CMHS (register)", "01111110zz1mmmmm001111nnnnnddddd")
|
INST(CMHS_1, "CMHS (register)", "01111110zz1mmmmm001111nnnnnddddd")
|
||||||
INST(USHL_1, "USHL", "01111110zz1mmmmm010001nnnnnddddd")
|
INST(USHL_1, "USHL", "01111110zz1mmmmm010001nnnnnddddd")
|
||||||
//INST(UQSHL_reg_1, "UQSHL (register)", "01111110zz1mmmmm010011nnnnnddddd")
|
//INST(UQSHL_reg_1, "UQSHL (register)", "01111110zz1mmmmm010011nnnnnddddd")
|
||||||
//INST(URSHL_1, "URSHL", "01111110zz1mmmmm010101nnnnnddddd")
|
INST(URSHL_1, "URSHL", "01111110zz1mmmmm010101nnnnnddddd")
|
||||||
//INST(UQRSHL_1, "UQRSHL", "01111110zz1mmmmm010111nnnnnddddd")
|
//INST(UQRSHL_1, "UQRSHL", "01111110zz1mmmmm010111nnnnnddddd")
|
||||||
INST(SUB_1, "SUB (vector)", "01111110zz1mmmmm100001nnnnnddddd")
|
INST(SUB_1, "SUB (vector)", "01111110zz1mmmmm100001nnnnnddddd")
|
||||||
INST(CMEQ_reg_1, "CMEQ (register)", "01111110zz1mmmmm100011nnnnnddddd")
|
INST(CMEQ_reg_1, "CMEQ (register)", "01111110zz1mmmmm100011nnnnnddddd")
|
||||||
|
@ -710,7 +710,7 @@ INST(CMGT_reg_2, "CMGT (register)", "0Q001
|
||||||
INST(CMGE_reg_2, "CMGE (register)", "0Q001110zz1mmmmm001111nnnnnddddd")
|
INST(CMGE_reg_2, "CMGE (register)", "0Q001110zz1mmmmm001111nnnnnddddd")
|
||||||
INST(SSHL_2, "SSHL", "0Q001110zz1mmmmm010001nnnnnddddd")
|
INST(SSHL_2, "SSHL", "0Q001110zz1mmmmm010001nnnnnddddd")
|
||||||
//INST(SQSHL_reg_2, "SQSHL (register)", "0Q001110zz1mmmmm010011nnnnnddddd")
|
//INST(SQSHL_reg_2, "SQSHL (register)", "0Q001110zz1mmmmm010011nnnnnddddd")
|
||||||
//INST(SRSHL_2, "SRSHL", "0Q001110zz1mmmmm010101nnnnnddddd")
|
INST(SRSHL_2, "SRSHL", "0Q001110zz1mmmmm010101nnnnnddddd")
|
||||||
//INST(SQRSHL_2, "SQRSHL", "0Q001110zz1mmmmm010111nnnnnddddd")
|
//INST(SQRSHL_2, "SQRSHL", "0Q001110zz1mmmmm010111nnnnnddddd")
|
||||||
INST(SMAX, "SMAX", "0Q001110zz1mmmmm011001nnnnnddddd")
|
INST(SMAX, "SMAX", "0Q001110zz1mmmmm011001nnnnnddddd")
|
||||||
INST(SMIN, "SMIN", "0Q001110zz1mmmmm011011nnnnnddddd")
|
INST(SMIN, "SMIN", "0Q001110zz1mmmmm011011nnnnnddddd")
|
||||||
|
@ -751,7 +751,7 @@ INST(CMHI_2, "CMHI (register)", "0Q101
|
||||||
INST(CMHS_2, "CMHS (register)", "0Q101110zz1mmmmm001111nnnnnddddd")
|
INST(CMHS_2, "CMHS (register)", "0Q101110zz1mmmmm001111nnnnnddddd")
|
||||||
INST(USHL_2, "USHL", "0Q101110zz1mmmmm010001nnnnnddddd")
|
INST(USHL_2, "USHL", "0Q101110zz1mmmmm010001nnnnnddddd")
|
||||||
//INST(UQSHL_reg_2, "UQSHL (register)", "0Q101110zz1mmmmm010011nnnnnddddd")
|
//INST(UQSHL_reg_2, "UQSHL (register)", "0Q101110zz1mmmmm010011nnnnnddddd")
|
||||||
//INST(URSHL_2, "URSHL", "0Q101110zz1mmmmm010101nnnnnddddd")
|
INST(URSHL_2, "URSHL", "0Q101110zz1mmmmm010101nnnnnddddd")
|
||||||
//INST(UQRSHL_2, "UQRSHL", "0Q101110zz1mmmmm010111nnnnnddddd")
|
//INST(UQRSHL_2, "UQRSHL", "0Q101110zz1mmmmm010111nnnnnddddd")
|
||||||
INST(UMAX, "UMAX", "0Q101110zz1mmmmm011001nnnnnddddd")
|
INST(UMAX, "UMAX", "0Q101110zz1mmmmm011001nnnnnddddd")
|
||||||
INST(UMIN, "UMIN", "0Q101110zz1mmmmm011011nnnnnddddd")
|
INST(UMIN, "UMIN", "0Q101110zz1mmmmm011011nnnnnddddd")
|
||||||
|
|
|
@ -25,6 +25,30 @@ enum class ComparisonVariant {
|
||||||
Zero,
|
Zero,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class Signedness {
|
||||||
|
Signed,
|
||||||
|
Unsigned,
|
||||||
|
};
|
||||||
|
|
||||||
|
bool RoundingShiftLeft(TranslatorVisitor& v, Imm<2> size, Vec Vm, Vec Vn, Vec Vd, Signedness sign) {
|
||||||
|
if (size != 0b11) {
|
||||||
|
return v.ReservedValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
const IR::U128 operand1 = v.V(64, Vn);
|
||||||
|
const IR::U128 operand2 = v.V(64, Vm);
|
||||||
|
const IR::U128 result = [&] {
|
||||||
|
if (sign == Signedness::Signed) {
|
||||||
|
return v.ir.VectorRoundingShiftLeftSigned(64, operand1, operand2);
|
||||||
|
}
|
||||||
|
|
||||||
|
return v.ir.VectorRoundingShiftLeftUnsigned(64, operand1, operand2);
|
||||||
|
}();
|
||||||
|
|
||||||
|
v.V(64, Vd, result);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool ScalarCompare(TranslatorVisitor& v, Imm<2> size, boost::optional<Vec> Vm, Vec Vn, Vec Vd,
|
bool ScalarCompare(TranslatorVisitor& v, Imm<2> size, boost::optional<Vec> Vm, Vec Vn, Vec Vd,
|
||||||
ComparisonType type, ComparisonVariant variant) {
|
ComparisonType type, ComparisonVariant variant) {
|
||||||
if (size != 0b11) {
|
if (size != 0b11) {
|
||||||
|
@ -278,6 +302,10 @@ bool TranslatorVisitor::FCMGT_reg_2(bool sz, Vec Vm, Vec Vn, Vec Vd) {
|
||||||
return ScalarFPCompareRegister(*this, sz, Vm, Vn, Vd, FPComparisonType::GT);
|
return ScalarFPCompareRegister(*this, sz, Vm, Vn, Vd, FPComparisonType::GT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool TranslatorVisitor::SRSHL_1(Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||||
|
return RoundingShiftLeft(*this, size, Vm, Vn, Vd, Signedness::Signed);
|
||||||
|
}
|
||||||
|
|
||||||
bool TranslatorVisitor::SSHL_1(Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
bool TranslatorVisitor::SSHL_1(Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||||
if (size != 0b11) {
|
if (size != 0b11) {
|
||||||
return ReservedValue();
|
return ReservedValue();
|
||||||
|
@ -305,6 +333,10 @@ bool TranslatorVisitor::SUB_1(Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool TranslatorVisitor::URSHL_1(Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||||
|
return RoundingShiftLeft(*this, size, Vm, Vn, Vd, Signedness::Unsigned);
|
||||||
|
}
|
||||||
|
|
||||||
bool TranslatorVisitor::USHL_1(Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
bool TranslatorVisitor::USHL_1(Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||||
if (size != 0b11) {
|
if (size != 0b11) {
|
||||||
return ReservedValue();
|
return ReservedValue();
|
||||||
|
|
|
@ -102,6 +102,28 @@ bool RoundingHalvingAdd(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vm, Vec V
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool RoundingShiftLeft(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd, Signedness sign) {
|
||||||
|
if (size == 0b11 && !Q) {
|
||||||
|
return v.ReservedValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_t esize = 8 << size.ZeroExtend();
|
||||||
|
const size_t datasize = Q ? 128 : 64;
|
||||||
|
|
||||||
|
const IR::U128 operand1 = v.V(datasize, Vn);
|
||||||
|
const IR::U128 operand2 = v.V(datasize, Vm);
|
||||||
|
const IR::U128 result = [&] {
|
||||||
|
if (sign == Signedness::Signed) {
|
||||||
|
return v.ir.VectorRoundingShiftLeftSigned(esize, operand1, operand2);
|
||||||
|
}
|
||||||
|
|
||||||
|
return v.ir.VectorRoundingShiftLeftUnsigned(esize, operand1, operand2);
|
||||||
|
}();
|
||||||
|
|
||||||
|
v.V(datasize, Vd, result);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
enum class ComparisonType {
|
enum class ComparisonType {
|
||||||
EQ,
|
EQ,
|
||||||
GE,
|
GE,
|
||||||
|
@ -723,6 +745,10 @@ bool TranslatorVisitor::CMTST_2(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool TranslatorVisitor::SRSHL_2(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||||
|
return RoundingShiftLeft(*this, Q, size, Vm, Vn, Vd, Signedness::Signed);
|
||||||
|
}
|
||||||
|
|
||||||
bool TranslatorVisitor::SSHL_2(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
bool TranslatorVisitor::SSHL_2(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||||
if (size == 0b11 && !Q) {
|
if (size == 0b11 && !Q) {
|
||||||
return ReservedValue();
|
return ReservedValue();
|
||||||
|
@ -737,6 +763,10 @@ bool TranslatorVisitor::SSHL_2(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool TranslatorVisitor::URSHL_2(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||||
|
return RoundingShiftLeft(*this, Q, size, Vm, Vn, Vd, Signedness::Unsigned);
|
||||||
|
}
|
||||||
|
|
||||||
bool TranslatorVisitor::USHL_2(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
bool TranslatorVisitor::USHL_2(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||||
if (size == 0b11 && !Q) {
|
if (size == 0b11 && !Q) {
|
||||||
return ReservedValue();
|
return ReservedValue();
|
||||||
|
|
Loading…
Reference in a new issue