frontend: Relocate advanced SIMD expansion to a common file
Deduplicates code a little bit.
This commit is contained in:
parent
fc112e61f2
commit
1900df5340
6 changed files with 70 additions and 107 deletions
|
@ -76,6 +76,7 @@ add_library(dynarmic
|
|||
frontend/A64/types.h
|
||||
frontend/decoder/decoder_detail.h
|
||||
frontend/decoder/matcher.h
|
||||
frontend/imm.cpp
|
||||
frontend/imm.h
|
||||
frontend/ir/basic_block.cpp
|
||||
frontend/ir/basic_block.h
|
||||
|
|
|
@ -13,59 +13,6 @@ namespace {
|
|||
ExtReg ToExtRegD(size_t base, bool bit) {
|
||||
return ExtReg::D0 + (base + (bit ? 16 : 0));
|
||||
}
|
||||
|
||||
u64 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();
|
||||
}
|
||||
} // Anonymous namespace
|
||||
|
||||
bool ArmTranslatorVisitor::asimd_VMOV_imm(Imm<1> a, bool D, Imm<1> b, Imm<1> c, Imm<1> d, size_t Vd,
|
||||
|
|
|
@ -61,59 +61,6 @@ std::optional<TranslatorVisitor::BitMasks> TranslatorVisitor::DecodeBitMasks(boo
|
|||
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();
|
||||
}
|
||||
|
||||
IR::UAny TranslatorVisitor::I(size_t bitsize, u64 value) {
|
||||
switch (bitsize) {
|
||||
case 8:
|
||||
|
|
|
@ -35,7 +35,6 @@ struct TranslatorVisitor final {
|
|||
};
|
||||
|
||||
static std::optional<BitMasks> DecodeBitMasks(bool immN, Imm<6> imms, Imm<6> immr, bool immediate);
|
||||
static u64 AdvSIMDExpandImm(bool op, Imm<4> cmode, Imm<8> imm8);
|
||||
|
||||
IR::UAny I(size_t bitsize, u64 value);
|
||||
IR::UAny X(size_t bitsize, Reg reg);
|
||||
|
|
66
src/frontend/imm.cpp
Normal file
66
src/frontend/imm.cpp
Normal file
|
@ -0,0 +1,66 @@
|
|||
/* This file is part of the dynarmic project.
|
||||
* Copyright (c) 2018 MerryMage
|
||||
* SPDX-License-Identifier: 0BSD
|
||||
*/
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "common/bit_util.h"
|
||||
#include "common/common_types.h"
|
||||
#include "frontend/imm.h"
|
||||
|
||||
namespace Dynarmic {
|
||||
|
||||
u64 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();
|
||||
}
|
||||
|
||||
} // namespace Dynarmic
|
|
@ -157,4 +157,7 @@ auto concatenate(Imm<first_bit_size> first, Imm<rest_bit_sizes> ...rest) {
|
|||
}
|
||||
}
|
||||
|
||||
/// Expands an Advanced SIMD modified immediate.
|
||||
u64 AdvSIMDExpandImm(bool op, Imm<4> cmode, Imm<8> imm8);
|
||||
|
||||
} // namespace Dynarmic
|
||||
|
|
Loading…
Reference in a new issue