mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-23 08:00:39 +02:00
Merge pull request #2398 from lioncash/sve2acc
ARMEmitter: Handle SVE2 Accumulate category
This commit is contained in:
2 files changed
+322
-13
No files matched your search
+208
-7
@@ -1966,18 +1966,72 @@ public:
|
||||
|
||||
// SVE2 Accumulate
|
||||
// SVE2 complex integer add
|
||||
// XXX:
|
||||
void cadd(SubRegSize size, ZRegister zd, ZRegister zn, ZRegister zm, Rotation rot) {
|
||||
SVE2ComplexIntAdd(size, 0b0, rot, zd, zn, zm);
|
||||
}
|
||||
void sqcadd(SubRegSize size, ZRegister zd, ZRegister zn, ZRegister zm, Rotation rot) {
|
||||
SVE2ComplexIntAdd(size, 0b1, rot, zd, zn, zm);
|
||||
}
|
||||
|
||||
// SVE2 integer absolute difference and accumulate long
|
||||
// XXX:
|
||||
void sabalb(SubRegSize size, ZRegister zda, ZRegister zn, ZRegister zm) {
|
||||
SVE2IntegerAddSubInterleavedLong(size, 0b10000, zda, zn, zm);
|
||||
}
|
||||
void sabalt(SubRegSize size, ZRegister zda, ZRegister zn, ZRegister zm) {
|
||||
SVE2IntegerAddSubInterleavedLong(size, 0b10001, zda, zn, zm);
|
||||
}
|
||||
void uabalb(SubRegSize size, ZRegister zda, ZRegister zn, ZRegister zm) {
|
||||
SVE2IntegerAddSubInterleavedLong(size, 0b10010, zda, zn, zm);
|
||||
}
|
||||
void uabalt(SubRegSize size, ZRegister zda, ZRegister zn, ZRegister zm) {
|
||||
SVE2IntegerAddSubInterleavedLong(size, 0b10011, zda, zn, zm);
|
||||
}
|
||||
|
||||
// SVE2 integer add/subtract long with carry
|
||||
// XXX:
|
||||
void adclb(SubRegSize size, ZRegister zda, ZRegister zn, ZRegister zm) {
|
||||
SVE2IntegerAddSubLongWithCarry(size, 0, 0, zda, zn, zm);
|
||||
}
|
||||
void adclt(SubRegSize size, ZRegister zda, ZRegister zn, ZRegister zm) {
|
||||
SVE2IntegerAddSubLongWithCarry(size, 0, 1, zda, zn, zm);
|
||||
}
|
||||
void sbclb(SubRegSize size, ZRegister zda, ZRegister zn, ZRegister zm) {
|
||||
SVE2IntegerAddSubLongWithCarry(size, 1, 0, zda, zn, zm);
|
||||
}
|
||||
void sbclt(SubRegSize size, ZRegister zda, ZRegister zn, ZRegister zm) {
|
||||
SVE2IntegerAddSubLongWithCarry(size, 1, 1, zda, zn, zm);
|
||||
}
|
||||
|
||||
// SVE2 bitwise shift right and accumulate
|
||||
// XXX:
|
||||
void ssra(SubRegSize size, ZRegister zda, ZRegister zn, uint32_t shift) {
|
||||
SVE2BitwiseShiftRightAndAccumulate(size, 0b00, zda, zn, shift);
|
||||
}
|
||||
void usra(SubRegSize size, ZRegister zda, ZRegister zn, uint32_t shift) {
|
||||
SVE2BitwiseShiftRightAndAccumulate(size, 0b01, zda, zn, shift);
|
||||
}
|
||||
void srsra(SubRegSize size, ZRegister zda, ZRegister zn, uint32_t shift) {
|
||||
SVE2BitwiseShiftRightAndAccumulate(size, 0b10, zda, zn, shift);
|
||||
}
|
||||
void ursra(SubRegSize size, ZRegister zda, ZRegister zn, uint32_t shift) {
|
||||
SVE2BitwiseShiftRightAndAccumulate(size, 0b11, zda, zn, shift);
|
||||
}
|
||||
|
||||
// SVE2 bitwise shift and insert
|
||||
// XXX:
|
||||
void sri(SubRegSize size, ZRegister zda, ZRegister zn, uint32_t shift) {
|
||||
SVE2BitwiseShiftAndInsert(size, 0b0, zda, zn, shift);
|
||||
}
|
||||
void sli(SubRegSize size, ZRegister zda, ZRegister zn, uint32_t shift) {
|
||||
SVE2BitwiseShiftAndInsert(size, 0b1, zda, zn, shift);
|
||||
}
|
||||
|
||||
|
||||
// SVE2 integer absolute difference and accumulate
|
||||
// XXX:
|
||||
//
|
||||
void saba(SubRegSize size, ZRegister zda, ZRegister zn, ZRegister zm) {
|
||||
SVE2IntegerAbsDiffAndAccumulate(size, 0b0, zda, zn, zm);
|
||||
}
|
||||
void uaba(SubRegSize size, ZRegister zda, ZRegister zn, ZRegister zm) {
|
||||
SVE2IntegerAbsDiffAndAccumulate(size, 0b1, zda, zn, zm);
|
||||
}
|
||||
|
||||
// SVE2 Narrowing
|
||||
// SVE2 saturating extract narrow
|
||||
void sqxtnb(SubRegSize size, ZRegister zd, ZRegister zn) {
|
||||
@@ -3625,6 +3679,123 @@ private:
|
||||
dc32(Instr);
|
||||
}
|
||||
|
||||
void SVE2IntegerAbsDiffAndAccumulate(SubRegSize size, uint32_t opc, ZRegister zda, ZRegister zn, ZRegister zm) {
|
||||
LOGMAN_THROW_A_FMT(size != SubRegSize::i128Bit, "Can't use 128-bit element size");
|
||||
|
||||
uint32_t Instr = 0b0100'0101'0000'0000'1111'1000'0000'0000;
|
||||
Instr |= FEXCore::ToUnderlying(size) << 22;
|
||||
Instr |= zm.Idx() << 16;
|
||||
Instr |= opc << 10;
|
||||
Instr |= zn.Idx() << 5;
|
||||
Instr |= zda.Idx();
|
||||
dc32(Instr);
|
||||
}
|
||||
|
||||
void SVE2IntegerAddSubLongWithCarry(SubRegSize size, uint32_t sizep1, uint32_t T, ZRegister zda, ZRegister zn, ZRegister zm) {
|
||||
LOGMAN_THROW_A_FMT(size == SubRegSize::i32Bit || size == SubRegSize::i64Bit,
|
||||
"Element size must be 32-bit or 64-bit");
|
||||
|
||||
const uint32_t NewSize = size == SubRegSize::i32Bit ? 0 : 1;
|
||||
|
||||
uint32_t Instr = 0b0100'0101'0000'0000'1101'0000'0000'0000;
|
||||
Instr |= sizep1 << 23;
|
||||
Instr |= NewSize << 22;
|
||||
Instr |= zm.Idx() << 16;
|
||||
Instr |= T << 10;
|
||||
Instr |= zn.Idx() << 5;
|
||||
Instr |= zda.Idx();
|
||||
dc32(Instr);
|
||||
}
|
||||
|
||||
void SVE2BitwiseShiftRightAndAccumulate(SubRegSize size, uint32_t opc, ZRegister zda, ZRegister zn, uint32_t shift) {
|
||||
LOGMAN_THROW_A_FMT(size != SubRegSize::i128Bit, "Element size cannot be 128-bit");
|
||||
|
||||
const auto ElementSize = SubRegSizeInBits(size);
|
||||
|
||||
LOGMAN_THROW_A_FMT(shift > 0 && shift <= ElementSize, "Incorrect right shift: {}", shift);
|
||||
|
||||
uint32_t tszh = 0;
|
||||
uint32_t tszl = 0;
|
||||
uint32_t imm3 = 0;
|
||||
const uint32_t InverseShift = (2 * ElementSize) - shift;
|
||||
|
||||
if (size == SubRegSize::i8Bit) {
|
||||
tszh = 0b00;
|
||||
tszl = 0b01;
|
||||
imm3 = InverseShift & 0b111;
|
||||
} else if (size == SubRegSize::i16Bit) {
|
||||
tszh = 0b00;
|
||||
tszl = 0b10 | ((InverseShift >> 3) & 0b1);
|
||||
imm3 = InverseShift & 0b111;
|
||||
} else if (size == SubRegSize::i32Bit) {
|
||||
tszh = 0b01;
|
||||
tszl = (InverseShift >> 3) & 0b11;
|
||||
imm3 = InverseShift & 0b111;
|
||||
} else if (size == SubRegSize::i64Bit) {
|
||||
tszh = 0b10 | ((InverseShift >> 5) & 1);
|
||||
tszl = (InverseShift >> 3) & 0b11;
|
||||
imm3 = InverseShift & 0b111;
|
||||
} else {
|
||||
FEX_UNREACHABLE;
|
||||
}
|
||||
|
||||
uint32_t Instr = 0b0100'0101'0000'0000'1110'0000'0000'0000;
|
||||
Instr |= tszh << 22;
|
||||
Instr |= tszl << 19;
|
||||
Instr |= imm3 << 16;
|
||||
Instr |= opc << 10;
|
||||
Instr |= zn.Idx() << 5;
|
||||
Instr |= zda.Idx();
|
||||
dc32(Instr);
|
||||
}
|
||||
|
||||
void SVE2BitwiseShiftAndInsert(SubRegSize size, uint32_t opc, ZRegister zd, ZRegister zn, uint32_t shift) {
|
||||
LOGMAN_THROW_A_FMT(size != SubRegSize::i128Bit, "Element size cannot be 128-bit");
|
||||
|
||||
const auto ElementSize = SubRegSizeInBits(size);
|
||||
const bool IsLeftShift = opc != 0;
|
||||
if (IsLeftShift) {
|
||||
LOGMAN_THROW_A_FMT(shift >= 0 && shift < ElementSize, "Incorrect left shift: {}", shift);
|
||||
} else {
|
||||
LOGMAN_THROW_A_FMT(shift > 0 && shift <= ElementSize, "Incorrect right shift: {}", shift);
|
||||
}
|
||||
|
||||
uint32_t tszh = 0;
|
||||
uint32_t tszl = 0;
|
||||
uint32_t imm3 = 0;
|
||||
const uint32_t InverseShift = IsLeftShift ? shift
|
||||
:(2 * ElementSize) - shift;
|
||||
|
||||
if (size == SubRegSize::i8Bit) {
|
||||
tszh = 0b00;
|
||||
tszl = 0b01;
|
||||
imm3 = InverseShift & 0b111;
|
||||
} else if (size == SubRegSize::i16Bit) {
|
||||
tszh = 0b00;
|
||||
tszl = 0b10 | ((InverseShift >> 3) & 0b1);
|
||||
imm3 = InverseShift & 0b111;
|
||||
} else if (size == SubRegSize::i32Bit) {
|
||||
tszh = 0b01;
|
||||
tszl = (InverseShift >> 3) & 0b11;
|
||||
imm3 = InverseShift & 0b111;
|
||||
} else if (size == SubRegSize::i64Bit) {
|
||||
tszh = 0b10 | ((InverseShift >> 5) & 1);
|
||||
tszl = (InverseShift >> 3) & 0b11;
|
||||
imm3 = InverseShift & 0b111;
|
||||
} else {
|
||||
FEX_UNREACHABLE;
|
||||
}
|
||||
|
||||
uint32_t Instr = 0b0100'0101'0000'0000'1111'0000'0000'0000;
|
||||
Instr |= tszh << 22;
|
||||
Instr |= tszl << 19;
|
||||
Instr |= imm3 << 16;
|
||||
Instr |= opc << 10;
|
||||
Instr |= zn.Idx() << 5;
|
||||
Instr |= zd.Idx();
|
||||
dc32(Instr);
|
||||
}
|
||||
|
||||
void SVE2BitwiseShiftLeftLong(SubRegSize size, uint32_t opc, ZRegister zd, ZRegister zn, uint32_t shift) {
|
||||
LOGMAN_THROW_A_FMT(size != SubRegSize::i8Bit && size != SubRegSize::i128Bit,
|
||||
"Can't use 8-bit or 128-bit element size");
|
||||
@@ -3649,6 +3820,36 @@ private:
|
||||
dc32(Instr);
|
||||
}
|
||||
|
||||
void SVE2ComplexIntAdd(SubRegSize size, uint32_t opc, Rotation rot, ZRegister zd, ZRegister zn, ZRegister zm) {
|
||||
LOGMAN_THROW_A_FMT(size != SubRegSize::i128Bit, "Complex add cannot use 128-bit element size");
|
||||
LOGMAN_THROW_A_FMT(zd.Idx() == zn.Idx(), "zd and zn must be the same register");
|
||||
LOGMAN_THROW_A_FMT(rot == Rotation::ROTATE_90 || rot == Rotation::ROTATE_270,
|
||||
"Rotation must be 90 or 270 degrees");
|
||||
|
||||
const uint32_t SanitizedRot = rot == Rotation::ROTATE_90 ? 0 : 1;
|
||||
|
||||
uint32_t Instr = 0b0100'0101'0000'0000'1101'1000'0000'0000;
|
||||
Instr |= FEXCore::ToUnderlying(size) << 22;
|
||||
Instr |= opc << 16;
|
||||
Instr |= SanitizedRot << 10;
|
||||
Instr |= zm.Idx() << 5;
|
||||
Instr |= zd.Idx();
|
||||
dc32(Instr);
|
||||
}
|
||||
|
||||
void SVE2AbsDiffAccLong(SubRegSize size, uint32_t opc, ZRegister zda, ZRegister zn, ZRegister zm) {
|
||||
LOGMAN_THROW_A_FMT(size != SubRegSize::i8Bit && size != SubRegSize::i128Bit,
|
||||
"Cannot use 8-bit or 128-bit element size");
|
||||
|
||||
uint32_t Instr = 0b0100'0101'0000'0000'1100'0000'0000'0000;
|
||||
Instr |= FEXCore::ToUnderlying(size) << 22;
|
||||
Instr |= zm.Idx() << 16;
|
||||
Instr |= opc << 10;
|
||||
Instr |= zn.Idx() << 5;
|
||||
Instr |= zda.Idx();
|
||||
dc32(Instr);
|
||||
}
|
||||
|
||||
// SVE floating-point round to integral value
|
||||
void frintX(uint32_t opc, FEXCore::ARMEmitter::SubRegSize size, FEXCore::ARMEmitter::ZRegister zd, FEXCore::ARMEmitter::PRegister pg, FEXCore::ARMEmitter::ZRegister zn) {
|
||||
// opc = round mode
|
||||
|
||||
+114
-6
@@ -1857,22 +1857,130 @@ TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE2 bitwise permute") {
|
||||
TEST_SINGLE(bgrp(SubRegSize::i64Bit, ZReg::z30, ZReg::z29, ZReg::z28), "bgrp z30.d, z29.d, z28.d");
|
||||
}
|
||||
TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE2 complex integer add") {
|
||||
// TODO: Implement in emitter.
|
||||
TEST_SINGLE(cadd(SubRegSize::i8Bit, ZReg::z30, ZReg::z30, ZReg::z29, Rotation::ROTATE_90), "cadd z30.b, z30.b, z29.b, #90");
|
||||
TEST_SINGLE(cadd(SubRegSize::i16Bit, ZReg::z30, ZReg::z30, ZReg::z29, Rotation::ROTATE_90), "cadd z30.h, z30.h, z29.h, #90");
|
||||
TEST_SINGLE(cadd(SubRegSize::i32Bit, ZReg::z30, ZReg::z30, ZReg::z29, Rotation::ROTATE_90), "cadd z30.s, z30.s, z29.s, #90");
|
||||
TEST_SINGLE(cadd(SubRegSize::i64Bit, ZReg::z30, ZReg::z30, ZReg::z29, Rotation::ROTATE_90), "cadd z30.d, z30.d, z29.d, #90");
|
||||
|
||||
TEST_SINGLE(cadd(SubRegSize::i8Bit, ZReg::z30, ZReg::z30, ZReg::z29, Rotation::ROTATE_270), "cadd z30.b, z30.b, z29.b, #270");
|
||||
TEST_SINGLE(cadd(SubRegSize::i16Bit, ZReg::z30, ZReg::z30, ZReg::z29, Rotation::ROTATE_270), "cadd z30.h, z30.h, z29.h, #270");
|
||||
TEST_SINGLE(cadd(SubRegSize::i32Bit, ZReg::z30, ZReg::z30, ZReg::z29, Rotation::ROTATE_270), "cadd z30.s, z30.s, z29.s, #270");
|
||||
TEST_SINGLE(cadd(SubRegSize::i64Bit, ZReg::z30, ZReg::z30, ZReg::z29, Rotation::ROTATE_270), "cadd z30.d, z30.d, z29.d, #270");
|
||||
|
||||
TEST_SINGLE(sqcadd(SubRegSize::i8Bit, ZReg::z30, ZReg::z30, ZReg::z29, Rotation::ROTATE_90), "sqcadd z30.b, z30.b, z29.b, #90");
|
||||
TEST_SINGLE(sqcadd(SubRegSize::i16Bit, ZReg::z30, ZReg::z30, ZReg::z29, Rotation::ROTATE_90), "sqcadd z30.h, z30.h, z29.h, #90");
|
||||
TEST_SINGLE(sqcadd(SubRegSize::i32Bit, ZReg::z30, ZReg::z30, ZReg::z29, Rotation::ROTATE_90), "sqcadd z30.s, z30.s, z29.s, #90");
|
||||
TEST_SINGLE(sqcadd(SubRegSize::i64Bit, ZReg::z30, ZReg::z30, ZReg::z29, Rotation::ROTATE_90), "sqcadd z30.d, z30.d, z29.d, #90");
|
||||
|
||||
TEST_SINGLE(sqcadd(SubRegSize::i8Bit, ZReg::z30, ZReg::z30, ZReg::z29, Rotation::ROTATE_270), "sqcadd z30.b, z30.b, z29.b, #270");
|
||||
TEST_SINGLE(sqcadd(SubRegSize::i16Bit, ZReg::z30, ZReg::z30, ZReg::z29, Rotation::ROTATE_270), "sqcadd z30.h, z30.h, z29.h, #270");
|
||||
TEST_SINGLE(sqcadd(SubRegSize::i32Bit, ZReg::z30, ZReg::z30, ZReg::z29, Rotation::ROTATE_270), "sqcadd z30.s, z30.s, z29.s, #270");
|
||||
TEST_SINGLE(sqcadd(SubRegSize::i64Bit, ZReg::z30, ZReg::z30, ZReg::z29, Rotation::ROTATE_270), "sqcadd z30.d, z30.d, z29.d, #270");
|
||||
}
|
||||
TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE2 integer absolute difference and accumulate long") {
|
||||
// TODO: Implement in emitter.
|
||||
TEST_SINGLE(sabalb(SubRegSize::i16Bit, ZReg::z28, ZReg::z29, ZReg::z30), "sabalb z28.h, z29.b, z30.b");
|
||||
TEST_SINGLE(sabalb(SubRegSize::i32Bit, ZReg::z28, ZReg::z29, ZReg::z30), "sabalb z28.s, z29.h, z30.h");
|
||||
TEST_SINGLE(sabalb(SubRegSize::i64Bit, ZReg::z28, ZReg::z29, ZReg::z30), "sabalb z28.d, z29.s, z30.s");
|
||||
|
||||
TEST_SINGLE(sabalt(SubRegSize::i16Bit, ZReg::z28, ZReg::z29, ZReg::z30), "sabalt z28.h, z29.b, z30.b");
|
||||
TEST_SINGLE(sabalt(SubRegSize::i32Bit, ZReg::z28, ZReg::z29, ZReg::z30), "sabalt z28.s, z29.h, z30.h");
|
||||
TEST_SINGLE(sabalt(SubRegSize::i64Bit, ZReg::z28, ZReg::z29, ZReg::z30), "sabalt z28.d, z29.s, z30.s");
|
||||
|
||||
TEST_SINGLE(uabalb(SubRegSize::i16Bit, ZReg::z28, ZReg::z29, ZReg::z30), "uabalb z28.h, z29.b, z30.b");
|
||||
TEST_SINGLE(uabalb(SubRegSize::i32Bit, ZReg::z28, ZReg::z29, ZReg::z30), "uabalb z28.s, z29.h, z30.h");
|
||||
TEST_SINGLE(uabalb(SubRegSize::i64Bit, ZReg::z28, ZReg::z29, ZReg::z30), "uabalb z28.d, z29.s, z30.s");
|
||||
|
||||
TEST_SINGLE(uabalt(SubRegSize::i16Bit, ZReg::z28, ZReg::z29, ZReg::z30), "uabalt z28.h, z29.b, z30.b");
|
||||
TEST_SINGLE(uabalt(SubRegSize::i32Bit, ZReg::z28, ZReg::z29, ZReg::z30), "uabalt z28.s, z29.h, z30.h");
|
||||
TEST_SINGLE(uabalt(SubRegSize::i64Bit, ZReg::z28, ZReg::z29, ZReg::z30), "uabalt z28.d, z29.s, z30.s");
|
||||
}
|
||||
TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE2 integer add/subtract long with carry") {
|
||||
// TODO: Implement in emitter.
|
||||
TEST_SINGLE(adclb(SubRegSize::i32Bit, ZReg::z28, ZReg::z29, ZReg::z30), "adclb z28.s, z29.s, z30.s");
|
||||
TEST_SINGLE(adclb(SubRegSize::i64Bit, ZReg::z28, ZReg::z29, ZReg::z30), "adclb z28.d, z29.d, z30.d");
|
||||
|
||||
TEST_SINGLE(adclt(SubRegSize::i32Bit, ZReg::z28, ZReg::z29, ZReg::z30), "adclt z28.s, z29.s, z30.s");
|
||||
TEST_SINGLE(adclt(SubRegSize::i64Bit, ZReg::z28, ZReg::z29, ZReg::z30), "adclt z28.d, z29.d, z30.d");
|
||||
|
||||
TEST_SINGLE(sbclb(SubRegSize::i32Bit, ZReg::z28, ZReg::z29, ZReg::z30), "sbclb z28.s, z29.s, z30.s");
|
||||
TEST_SINGLE(sbclb(SubRegSize::i64Bit, ZReg::z28, ZReg::z29, ZReg::z30), "sbclb z28.d, z29.d, z30.d");
|
||||
|
||||
TEST_SINGLE(sbclt(SubRegSize::i32Bit, ZReg::z28, ZReg::z29, ZReg::z30), "sbclt z28.s, z29.s, z30.s");
|
||||
TEST_SINGLE(sbclt(SubRegSize::i64Bit, ZReg::z28, ZReg::z29, ZReg::z30), "sbclt z28.d, z29.d, z30.d");
|
||||
}
|
||||
TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE2 bitwise shift right and accumulate") {
|
||||
// TODO: Implement in emitter.
|
||||
TEST_SINGLE(ssra(SubRegSize::i8Bit, ZReg::z30, ZReg::z29, 1), "ssra z30.b, z29.b, #1");
|
||||
TEST_SINGLE(ssra(SubRegSize::i8Bit, ZReg::z30, ZReg::z29, 8), "ssra z30.b, z29.b, #8");
|
||||
TEST_SINGLE(ssra(SubRegSize::i16Bit, ZReg::z30, ZReg::z29, 1), "ssra z30.h, z29.h, #1");
|
||||
TEST_SINGLE(ssra(SubRegSize::i16Bit, ZReg::z30, ZReg::z29, 16), "ssra z30.h, z29.h, #16");
|
||||
TEST_SINGLE(ssra(SubRegSize::i32Bit, ZReg::z30, ZReg::z29, 1), "ssra z30.s, z29.s, #1");
|
||||
TEST_SINGLE(ssra(SubRegSize::i32Bit, ZReg::z30, ZReg::z29, 32), "ssra z30.s, z29.s, #32");
|
||||
TEST_SINGLE(ssra(SubRegSize::i64Bit, ZReg::z30, ZReg::z29, 1), "ssra z30.d, z29.d, #1");
|
||||
TEST_SINGLE(ssra(SubRegSize::i64Bit, ZReg::z30, ZReg::z29, 64), "ssra z30.d, z29.d, #64");
|
||||
|
||||
TEST_SINGLE(usra(SubRegSize::i8Bit, ZReg::z30, ZReg::z29, 1), "usra z30.b, z29.b, #1");
|
||||
TEST_SINGLE(usra(SubRegSize::i8Bit, ZReg::z30, ZReg::z29, 8), "usra z30.b, z29.b, #8");
|
||||
TEST_SINGLE(usra(SubRegSize::i16Bit, ZReg::z30, ZReg::z29, 1), "usra z30.h, z29.h, #1");
|
||||
TEST_SINGLE(usra(SubRegSize::i16Bit, ZReg::z30, ZReg::z29, 16), "usra z30.h, z29.h, #16");
|
||||
TEST_SINGLE(usra(SubRegSize::i32Bit, ZReg::z30, ZReg::z29, 1), "usra z30.s, z29.s, #1");
|
||||
TEST_SINGLE(usra(SubRegSize::i32Bit, ZReg::z30, ZReg::z29, 32), "usra z30.s, z29.s, #32");
|
||||
TEST_SINGLE(usra(SubRegSize::i64Bit, ZReg::z30, ZReg::z29, 1), "usra z30.d, z29.d, #1");
|
||||
TEST_SINGLE(usra(SubRegSize::i64Bit, ZReg::z30, ZReg::z29, 64), "usra z30.d, z29.d, #64");
|
||||
|
||||
TEST_SINGLE(srsra(SubRegSize::i8Bit, ZReg::z30, ZReg::z29, 1), "srsra z30.b, z29.b, #1");
|
||||
TEST_SINGLE(srsra(SubRegSize::i8Bit, ZReg::z30, ZReg::z29, 8), "srsra z30.b, z29.b, #8");
|
||||
TEST_SINGLE(srsra(SubRegSize::i16Bit, ZReg::z30, ZReg::z29, 1), "srsra z30.h, z29.h, #1");
|
||||
TEST_SINGLE(srsra(SubRegSize::i16Bit, ZReg::z30, ZReg::z29, 16), "srsra z30.h, z29.h, #16");
|
||||
TEST_SINGLE(srsra(SubRegSize::i32Bit, ZReg::z30, ZReg::z29, 1), "srsra z30.s, z29.s, #1");
|
||||
TEST_SINGLE(srsra(SubRegSize::i32Bit, ZReg::z30, ZReg::z29, 32), "srsra z30.s, z29.s, #32");
|
||||
TEST_SINGLE(srsra(SubRegSize::i64Bit, ZReg::z30, ZReg::z29, 1), "srsra z30.d, z29.d, #1");
|
||||
TEST_SINGLE(srsra(SubRegSize::i64Bit, ZReg::z30, ZReg::z29, 64), "srsra z30.d, z29.d, #64");
|
||||
|
||||
TEST_SINGLE(ursra(SubRegSize::i8Bit, ZReg::z30, ZReg::z29, 1), "ursra z30.b, z29.b, #1");
|
||||
TEST_SINGLE(ursra(SubRegSize::i8Bit, ZReg::z30, ZReg::z29, 8), "ursra z30.b, z29.b, #8");
|
||||
TEST_SINGLE(ursra(SubRegSize::i16Bit, ZReg::z30, ZReg::z29, 1), "ursra z30.h, z29.h, #1");
|
||||
TEST_SINGLE(ursra(SubRegSize::i16Bit, ZReg::z30, ZReg::z29, 16), "ursra z30.h, z29.h, #16");
|
||||
TEST_SINGLE(ursra(SubRegSize::i32Bit, ZReg::z30, ZReg::z29, 1), "ursra z30.s, z29.s, #1");
|
||||
TEST_SINGLE(ursra(SubRegSize::i32Bit, ZReg::z30, ZReg::z29, 32), "ursra z30.s, z29.s, #32");
|
||||
TEST_SINGLE(ursra(SubRegSize::i64Bit, ZReg::z30, ZReg::z29, 1), "ursra z30.d, z29.d, #1");
|
||||
TEST_SINGLE(ursra(SubRegSize::i64Bit, ZReg::z30, ZReg::z29, 64), "ursra z30.d, z29.d, #64");
|
||||
}
|
||||
TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE2 bitwise shift and insert") {
|
||||
// TODO: Implement in emitter.
|
||||
TEST_SINGLE(sri(SubRegSize::i8Bit, ZReg::z30, ZReg::z29, 1), "sri z30.b, z29.b, #1");\
|
||||
TEST_SINGLE(sri(SubRegSize::i8Bit, ZReg::z30, ZReg::z29, 4), "sri z30.b, z29.b, #4");
|
||||
TEST_SINGLE(sri(SubRegSize::i8Bit, ZReg::z30, ZReg::z29, 8), "sri z30.b, z29.b, #8");
|
||||
TEST_SINGLE(sri(SubRegSize::i16Bit, ZReg::z30, ZReg::z29, 1), "sri z30.h, z29.h, #1");
|
||||
TEST_SINGLE(sri(SubRegSize::i16Bit, ZReg::z30, ZReg::z29, 15), "sri z30.h, z29.h, #15");
|
||||
TEST_SINGLE(sri(SubRegSize::i16Bit, ZReg::z30, ZReg::z29, 16), "sri z30.h, z29.h, #16");
|
||||
TEST_SINGLE(sri(SubRegSize::i32Bit, ZReg::z30, ZReg::z29, 1), "sri z30.s, z29.s, #1");
|
||||
TEST_SINGLE(sri(SubRegSize::i32Bit, ZReg::z30, ZReg::z29, 15), "sri z30.s, z29.s, #15");
|
||||
TEST_SINGLE(sri(SubRegSize::i32Bit, ZReg::z30, ZReg::z29, 32), "sri z30.s, z29.s, #32");
|
||||
TEST_SINGLE(sri(SubRegSize::i64Bit, ZReg::z30, ZReg::z29, 1), "sri z30.d, z29.d, #1");
|
||||
TEST_SINGLE(sri(SubRegSize::i64Bit, ZReg::z30, ZReg::z29, 31), "sri z30.d, z29.d, #31");
|
||||
TEST_SINGLE(sri(SubRegSize::i64Bit, ZReg::z30, ZReg::z29, 64), "sri z30.d, z29.d, #64");
|
||||
|
||||
TEST_SINGLE(sli(SubRegSize::i8Bit, ZReg::z30, ZReg::z29, 0), "sli z30.b, z29.b, #0");
|
||||
TEST_SINGLE(sli(SubRegSize::i8Bit, ZReg::z30, ZReg::z29, 4), "sli z30.b, z29.b, #4");
|
||||
TEST_SINGLE(sli(SubRegSize::i8Bit, ZReg::z30, ZReg::z29, 7), "sli z30.b, z29.b, #7");
|
||||
TEST_SINGLE(sli(SubRegSize::i16Bit, ZReg::z30, ZReg::z29, 0), "sli z30.h, z29.h, #0");
|
||||
TEST_SINGLE(sli(SubRegSize::i16Bit, ZReg::z30, ZReg::z29, 7), "sli z30.h, z29.h, #7");
|
||||
TEST_SINGLE(sli(SubRegSize::i16Bit, ZReg::z30, ZReg::z29, 15), "sli z30.h, z29.h, #15");
|
||||
TEST_SINGLE(sli(SubRegSize::i32Bit, ZReg::z30, ZReg::z29, 0), "sli z30.s, z29.s, #0");
|
||||
TEST_SINGLE(sli(SubRegSize::i32Bit, ZReg::z30, ZReg::z29, 15), "sli z30.s, z29.s, #15");
|
||||
TEST_SINGLE(sli(SubRegSize::i32Bit, ZReg::z30, ZReg::z29, 31), "sli z30.s, z29.s, #31");
|
||||
TEST_SINGLE(sli(SubRegSize::i64Bit, ZReg::z30, ZReg::z29, 0), "sli z30.d, z29.d, #0");
|
||||
TEST_SINGLE(sli(SubRegSize::i64Bit, ZReg::z30, ZReg::z29, 31), "sli z30.d, z29.d, #31");
|
||||
TEST_SINGLE(sli(SubRegSize::i64Bit, ZReg::z30, ZReg::z29, 63), "sli z30.d, z29.d, #63");
|
||||
}
|
||||
TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE2 integer absolute difference and accumulate") {
|
||||
// TODO: Implement in emitter.
|
||||
TEST_SINGLE(saba(SubRegSize::i8Bit, ZReg::z28, ZReg::z29, ZReg::z30), "saba z28.b, z29.b, z30.b");
|
||||
TEST_SINGLE(saba(SubRegSize::i16Bit, ZReg::z28, ZReg::z29, ZReg::z30), "saba z28.h, z29.h, z30.h");
|
||||
TEST_SINGLE(saba(SubRegSize::i32Bit, ZReg::z28, ZReg::z29, ZReg::z30), "saba z28.s, z29.s, z30.s");
|
||||
TEST_SINGLE(saba(SubRegSize::i64Bit, ZReg::z28, ZReg::z29, ZReg::z30), "saba z28.d, z29.d, z30.d");
|
||||
|
||||
TEST_SINGLE(uaba(SubRegSize::i8Bit, ZReg::z28, ZReg::z29, ZReg::z30), "uaba z28.b, z29.b, z30.b");
|
||||
TEST_SINGLE(uaba(SubRegSize::i16Bit, ZReg::z28, ZReg::z29, ZReg::z30), "uaba z28.h, z29.h, z30.h");
|
||||
TEST_SINGLE(uaba(SubRegSize::i32Bit, ZReg::z28, ZReg::z29, ZReg::z30), "uaba z28.s, z29.s, z30.s");
|
||||
TEST_SINGLE(uaba(SubRegSize::i64Bit, ZReg::z28, ZReg::z29, ZReg::z30), "uaba z28.d, z29.d, z30.d");
|
||||
}
|
||||
TEST_CASE_METHOD(TestDisassembler, "Emitter: SVE: SVE2 saturating extract narrow") {
|
||||
TEST_SINGLE(sqxtnb(SubRegSize::i8Bit, ZReg::z30, ZReg::z29), "sqxtnb z30.b, z29.h");
|
||||
|
||||
Reference in new issue
Block a user