impl: Add AdvSIMDExpandImm

This commit is contained in:
MerryMage 2018-02-06 23:04:23 +00:00
parent ea69cb4474
commit 8ab7d8175c
2 changed files with 55 additions and 0 deletions

View file

@ -56,6 +56,60 @@ boost::optional<TranslatorVisitor::BitMasks> TranslatorVisitor::DecodeBitMasks(b
return BitMasks{wmask, tmask};
}
u64 TranslatorVisitor::AdvSIMDExpandImm(bool op, Imm<4> cmode, Imm<8> imm8) {
switch (cmode.Bits<1, 3>()) {
case 0b000:
return Common::Replicate<u64>(imm8.ZeroExtend<u64>(), 32);
case 0b001:
return Common::Replicate<u64>(imm8.ZeroExtend<u64>() << 8, 32);
case 0b010:
return Common::Replicate<u64>(imm8.ZeroExtend<u64>() << 16, 32);
case 0b011:
return Common::Replicate<u64>(imm8.ZeroExtend<u64>() << 24, 32);
case 0b100:
return Common::Replicate<u64>(imm8.ZeroExtend<u64>(), 16);
case 0b101:
return Common::Replicate<u64>(imm8.ZeroExtend<u64>() << 8, 16);
case 0b110:
if (!cmode.Bit<0>()) {
return Common::Replicate<u64>((imm8.ZeroExtend<u64>() << 8) | Common::Ones<u64>(8), 32);
}
return Common::Replicate<u64>((imm8.ZeroExtend<u64>() << 16) | Common::Ones<u64>(16), 32);
case 0b111:
if (!cmode.Bit<0>() && !op) {
return Common::Replicate<u64>(imm8.ZeroExtend<u64>(), 8);
}
if (!cmode.Bit<0>() && op) {
u64 result = 0;
result |= imm8.Bit<0>() ? Common::Ones<u64>(8) << (0 * 8) : 0;
result |= imm8.Bit<1>() ? Common::Ones<u64>(8) << (1 * 8) : 0;
result |= imm8.Bit<2>() ? Common::Ones<u64>(8) << (2 * 8) : 0;
result |= imm8.Bit<3>() ? Common::Ones<u64>(8) << (3 * 8) : 0;
result |= imm8.Bit<4>() ? Common::Ones<u64>(8) << (4 * 8) : 0;
result |= imm8.Bit<5>() ? Common::Ones<u64>(8) << (5 * 8) : 0;
result |= imm8.Bit<6>() ? Common::Ones<u64>(8) << (6 * 8) : 0;
result |= imm8.Bit<7>() ? Common::Ones<u64>(8) << (7 * 8) : 0;
return result;
}
if (cmode.Bit<0>() && !op) {
u64 result = 0;
result |= imm8.Bit<7>() ? 0x80000000 : 0;
result |= imm8.Bit<6>() ? 0x3E000000 : 0x40000000;
result |= imm8.Bits<0, 5, u64>() << 19;
return Common::Replicate<u64>(result, 32);
}
if (cmode.Bit<0>() && op) {
u64 result = 0;
result |= imm8.Bit<7>() ? 0x80000000'00000000 : 0;
result |= imm8.Bit<6>() ? 0x3FC00000'00000000 : 0x40000000'00000000;
result |= imm8.Bits<0, 5, u64>() << 48;
return result;
}
}
UNREACHABLE();
return 0;
}
IR::U32U64 TranslatorVisitor::I(size_t bitsize, u64 value) {
switch (bitsize) {
case 32:

View file

@ -40,6 +40,7 @@ struct TranslatorVisitor final {
};
boost::optional<BitMasks> DecodeBitMasks(bool N, Imm<6> immr, Imm<6> imms, bool immediate);
u64 AdvSIMDExpandImm(bool op, Imm<4> cmode, Imm<8> imm8);
IR::U32U64 I(size_t bitsize, u64 value);
IR::UAny X(size_t bitsize, Reg reg);