A64: Implement SRSHL and URSHL

Implements both scalar and vector variants.
This commit is contained in:
Lioncash 2018-08-16 13:55:59 -04:00 committed by MerryMage
parent 0efa2ce3b0
commit 29f8b30634
4 changed files with 70 additions and 8 deletions

View file

@ -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);
}); });
} }

View file

@ -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")

View file

@ -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();

View file

@ -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();