/* 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(imm8.ZeroExtend(), 32); case 0b001: return Common::Replicate(imm8.ZeroExtend() << 8, 32); case 0b010: return Common::Replicate(imm8.ZeroExtend() << 16, 32); case 0b011: return Common::Replicate(imm8.ZeroExtend() << 24, 32); case 0b100: return Common::Replicate(imm8.ZeroExtend(), 16); case 0b101: return Common::Replicate(imm8.ZeroExtend() << 8, 16); case 0b110: if (!cmode.Bit<0>()) { return Common::Replicate((imm8.ZeroExtend() << 8) | Common::Ones(8), 32); } return Common::Replicate((imm8.ZeroExtend() << 16) | Common::Ones(16), 32); case 0b111: if (!cmode.Bit<0>() && !op) { return Common::Replicate(imm8.ZeroExtend(), 8); } if (!cmode.Bit<0>() && op) { u64 result = 0; result |= imm8.Bit<0>() ? Common::Ones(8) << (0 * 8) : 0; result |= imm8.Bit<1>() ? Common::Ones(8) << (1 * 8) : 0; result |= imm8.Bit<2>() ? Common::Ones(8) << (2 * 8) : 0; result |= imm8.Bit<3>() ? Common::Ones(8) << (3 * 8) : 0; result |= imm8.Bit<4>() ? Common::Ones(8) << (4 * 8) : 0; result |= imm8.Bit<5>() ? Common::Ones(8) << (5 * 8) : 0; result |= imm8.Bit<6>() ? Common::Ones(8) << (6 * 8) : 0; result |= imm8.Bit<7>() ? Common::Ones(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(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