diff --git a/include/dynarmic/coprocessor.h b/include/dynarmic/coprocessor.h index 5731bdb1..212ee335 100644 --- a/include/dynarmic/coprocessor.h +++ b/include/dynarmic/coprocessor.h @@ -21,7 +21,7 @@ class Coprocessor { public: virtual ~Coprocessor() = default; - using CoprocReg = Arm::CoprocReg; + using CoprocReg = A32::CoprocReg; struct Callback { /** diff --git a/include/dynarmic/coprocessor_util.h b/include/dynarmic/coprocessor_util.h index 8318e812..ac7c4f73 100644 --- a/include/dynarmic/coprocessor_util.h +++ b/include/dynarmic/coprocessor_util.h @@ -7,11 +7,11 @@ #pragma once namespace Dynarmic { -namespace Arm { +namespace A32 { enum class CoprocReg { C0, C1, C2, C3, C4, C5, C6, C7, C8, C9, C10, C11, C12, C13, C14, C15 }; -} // namespace Arm +} // namespace A32 } // namespace Dynarmic diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8fbd2dcf..7486fe62 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,39 +1,4 @@ add_library(dynarmic - # Source files - common/memory_pool.cpp - frontend/arm/types.cpp - frontend/disassembler/disassembler_arm.cpp - frontend/disassembler/disassembler_thumb.cpp - frontend/ir/basic_block.cpp - frontend/ir/ir_emitter.cpp - frontend/ir/location_descriptor.cpp - frontend/ir/microinstruction.cpp - frontend/ir/opcodes.cpp - frontend/ir/value.cpp - frontend/translate/translate.cpp - frontend/translate/translate_arm.cpp - frontend/translate/translate_arm/branch.cpp - frontend/translate/translate_arm/coprocessor.cpp - frontend/translate/translate_arm/data_processing.cpp - frontend/translate/translate_arm/exception_generating.cpp - frontend/translate/translate_arm/extension.cpp - frontend/translate/translate_arm/load_store.cpp - frontend/translate/translate_arm/misc.cpp - frontend/translate/translate_arm/multiply.cpp - frontend/translate/translate_arm/packing.cpp - frontend/translate/translate_arm/parallel.cpp - frontend/translate/translate_arm/reversal.cpp - frontend/translate/translate_arm/saturated.cpp - frontend/translate/translate_arm/status_register_access.cpp - frontend/translate/translate_arm/synchronization.cpp - frontend/translate/translate_arm/vfp2.cpp - frontend/translate/translate_thumb.cpp - ir_opt/constant_propagation_pass.cpp - ir_opt/dead_code_elimination_pass.cpp - ir_opt/get_set_elimination_pass.cpp - ir_opt/verification_pass.cpp - - # Header files ../include/dynarmic/callbacks.h ../include/dynarmic/coprocessor.h ../include/dynarmic/coprocessor_util.h @@ -45,53 +10,84 @@ add_library(dynarmic common/common_types.h common/intrusive_list.h common/iterator_util.h + common/memory_pool.cpp common/memory_pool.h common/mp.h common/scope_exit.h common/string_util.h common/variant_util.h - frontend/arm/FPSCR.h - frontend/arm/PSR.h - frontend/arm/types.h - frontend/decoder/arm.h + frontend/A32/decoder/arm.h + frontend/A32/decoder/thumb16.h + frontend/A32/decoder/thumb32.h + frontend/A32/decoder/vfp2.h + frontend/A32/disassembler/disassembler.h + frontend/A32/disassembler/disassembler_arm.cpp + frontend/A32/disassembler/disassembler_thumb.cpp + frontend/A32/FPSCR.h + frontend/A32/location_descriptor.cpp + frontend/A32/location_descriptor.h + frontend/A32/PSR.h + frontend/A32/translate/translate.cpp + frontend/A32/translate/translate.h + frontend/A32/translate/translate_arm.cpp + frontend/A32/translate/translate_arm/branch.cpp + frontend/A32/translate/translate_arm/coprocessor.cpp + frontend/A32/translate/translate_arm/data_processing.cpp + frontend/A32/translate/translate_arm/exception_generating.cpp + frontend/A32/translate/translate_arm/extension.cpp + frontend/A32/translate/translate_arm/load_store.cpp + frontend/A32/translate/translate_arm/misc.cpp + frontend/A32/translate/translate_arm/multiply.cpp + frontend/A32/translate/translate_arm/packing.cpp + frontend/A32/translate/translate_arm/parallel.cpp + frontend/A32/translate/translate_arm/reversal.cpp + frontend/A32/translate/translate_arm/saturated.cpp + frontend/A32/translate/translate_arm/status_register_access.cpp + frontend/A32/translate/translate_arm/synchronization.cpp + frontend/A32/translate/translate_arm/translate_arm.h + frontend/A32/translate/translate_arm/vfp2.cpp + frontend/A32/translate/translate_thumb.cpp + frontend/A32/types.cpp + frontend/A32/types.h frontend/decoder/decoder_detail.h frontend/decoder/matcher.h - frontend/decoder/thumb16.h - frontend/decoder/thumb32.h - frontend/decoder/vfp2.h - frontend/disassembler/disassembler.h + frontend/ir/basic_block.cpp frontend/ir/basic_block.h + frontend/ir/ir_emitter.cpp frontend/ir/ir_emitter.h + frontend/ir/location_descriptor.cpp frontend/ir/location_descriptor.h + frontend/ir/microinstruction.cpp frontend/ir/microinstruction.h + frontend/ir/opcodes.cpp frontend/ir/opcodes.h frontend/ir/terminal.h + frontend/ir/value.cpp frontend/ir/value.h - frontend/translate/translate.h - frontend/translate/translate_arm/translate_arm.h + ir_opt/constant_propagation_pass.cpp + ir_opt/dead_code_elimination_pass.cpp + ir_opt/get_set_elimination_pass.cpp ir_opt/passes.h + ir_opt/verification_pass.cpp ) if (ARCHITECTURE_x86_64) target_sources(dynarmic PRIVATE - # Source files backend_x64/abi.cpp + backend_x64/abi.h backend_x64/block_of_code.cpp + backend_x64/block_of_code.h backend_x64/constant_pool.cpp + backend_x64/constant_pool.h backend_x64/emit_x64.cpp + backend_x64/emit_x64.h backend_x64/hostloc.cpp + backend_x64/hostloc.h backend_x64/interface_x64.cpp backend_x64/jitstate.cpp - backend_x64/reg_alloc.cpp - - # Headers - backend_x64/abi.h - backend_x64/block_of_code.h - backend_x64/constant_pool.h - backend_x64/emit_x64.h - backend_x64/hostloc.h backend_x64/jitstate.h backend_x64/oparg.h + backend_x64/reg_alloc.cpp backend_x64/reg_alloc.h ) diff --git a/src/backend_x64/emit_x64.cpp b/src/backend_x64/emit_x64.cpp index d00c7617..3d2be2d5 100644 --- a/src/backend_x64/emit_x64.cpp +++ b/src/backend_x64/emit_x64.cpp @@ -17,9 +17,9 @@ #include "common/bit_util.h" #include "common/common_types.h" #include "common/variant_util.h" -#include "frontend/arm/types.h" +#include "frontend/A32/location_descriptor.h" +#include "frontend/A32/types.h" #include "frontend/ir/basic_block.h" -#include "frontend/ir/location_descriptor.h" #include "frontend/ir/microinstruction.h" #include "frontend/ir/opcodes.h" @@ -44,17 +44,17 @@ constexpr u64 f64_min_s32 = 0xc1e0000000000000u; // -2147483648 as a double constexpr u64 f64_max_s32 = 0x41dfffffffc00000u; // 2147483647 as a double constexpr u64 f64_min_u32 = 0x0000000000000000u; // 0 as a double -static Xbyak::Address MJitStateReg(Arm::Reg reg) { +static Xbyak::Address MJitStateReg(A32::Reg reg) { return dword[r15 + offsetof(JitState, Reg) + sizeof(u32) * static_cast(reg)]; } -static Xbyak::Address MJitStateExtReg(Arm::ExtReg reg) { - if (Arm::IsSingleExtReg(reg)) { - size_t index = static_cast(reg) - static_cast(Arm::ExtReg::S0); +static Xbyak::Address MJitStateExtReg(A32::ExtReg reg) { + if (A32::IsSingleExtReg(reg)) { + size_t index = static_cast(reg) - static_cast(A32::ExtReg::S0); return dword[r15 + offsetof(JitState, ExtReg) + sizeof(u32) * index]; } - if (Arm::IsDoubleExtReg(reg)) { - size_t index = static_cast(reg) - static_cast(Arm::ExtReg::D0); + if (A32::IsDoubleExtReg(reg)) { + size_t index = static_cast(reg) - static_cast(A32::ExtReg::D0); return qword[r15 + offsetof(JitState, ExtReg) + sizeof(u64) * index]; } ASSERT_MSG(false, "Should never happen."); @@ -65,11 +65,11 @@ static void EraseInstruction(IR::Block& block, IR::Inst* inst) { inst->Invalidate(); } -EmitX64::EmitX64(BlockOfCode* code, UserCallbacks cb, Jit* jit_interface) +A32EmitX64::A32EmitX64(BlockOfCode* code, UserCallbacks cb, Jit* jit_interface) : code(code), cb(cb), jit_interface(jit_interface) { } -EmitX64::BlockDescriptor EmitX64::Emit(IR::Block& block) { +A32EmitX64::BlockDescriptor A32EmitX64::Emit(IR::Block& block) { code->align(); const u8* const entrypoint = code->getCurr(); @@ -86,7 +86,7 @@ EmitX64::BlockDescriptor EmitX64::Emit(IR::Block& block) { #define OPCODE(name, type, ...) \ case IR::Opcode::name: \ - EmitX64::Emit##name(reg_alloc, block, inst); \ + A32EmitX64::Emit##name(reg_alloc, block, inst); \ break; #include "frontend/ir/opcodes.inc" #undef OPCODE @@ -105,68 +105,69 @@ EmitX64::BlockDescriptor EmitX64::Emit(IR::Block& block) { EmitTerminal(block.GetTerminal(), block.Location()); code->int3(); - const IR::LocationDescriptor descriptor = block.Location(); + const A32::LocationDescriptor descriptor = block.Location(); Patch(descriptor, entrypoint); const size_t size = static_cast(code->getCurr() - entrypoint); - EmitX64::BlockDescriptor block_desc{entrypoint, size, block.Location(), block.EndLocation().PC()}; + const A32::LocationDescriptor end_location = block.EndLocation(); + const auto range = boost::icl::discrete_interval::closed(descriptor.PC(), end_location.PC() - 1); + A32EmitX64::BlockDescriptor block_desc{entrypoint, size, block.Location(), range}; block_descriptors.emplace(descriptor.UniqueHash(), block_desc); - - block_ranges.add(std::make_pair(boost::icl::discrete_interval::closed(block.Location().PC(), block.EndLocation().PC() - 1), std::set{descriptor})); + block_ranges.add(std::make_pair(range, std::set{descriptor})); return block_desc; } -boost::optional EmitX64::GetBasicBlock(IR::LocationDescriptor descriptor) const { +boost::optional A32EmitX64::GetBasicBlock(A32::LocationDescriptor descriptor) const { auto iter = block_descriptors.find(descriptor.UniqueHash()); if (iter == block_descriptors.end()) return boost::none; return iter->second; } -void EmitX64::EmitVoid(RegAlloc&, IR::Block&, IR::Inst*) { +void A32EmitX64::EmitVoid(RegAlloc&, IR::Block&, IR::Inst*) { } -void EmitX64::EmitBreakpoint(RegAlloc&, IR::Block&, IR::Inst*) { +void A32EmitX64::EmitBreakpoint(RegAlloc&, IR::Block&, IR::Inst*) { code->int3(); } -void EmitX64::EmitIdentity(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitIdentity(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); if (!args[0].IsImmediate()) { reg_alloc.DefineValue(inst, args[0]); } } -void EmitX64::EmitGetRegister(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { - Arm::Reg reg = inst->GetArg(0).GetRegRef(); +void A32EmitX64::EmitGetRegister(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { + A32::Reg reg = inst->GetArg(0).GetA32RegRef(); Xbyak::Reg32 result = reg_alloc.ScratchGpr().cvt32(); code->mov(result, MJitStateReg(reg)); reg_alloc.DefineValue(inst, result); } -void EmitX64::EmitGetExtendedRegister32(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { - Arm::ExtReg reg = inst->GetArg(0).GetExtRegRef(); - ASSERT(Arm::IsSingleExtReg(reg)); +void A32EmitX64::EmitGetExtendedRegister32(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { + A32::ExtReg reg = inst->GetArg(0).GetA32ExtRegRef(); + ASSERT(A32::IsSingleExtReg(reg)); Xbyak::Xmm result = reg_alloc.ScratchXmm(); code->movss(result, MJitStateExtReg(reg)); reg_alloc.DefineValue(inst, result); } -void EmitX64::EmitGetExtendedRegister64(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { - Arm::ExtReg reg = inst->GetArg(0).GetExtRegRef(); - ASSERT(Arm::IsDoubleExtReg(reg)); +void A32EmitX64::EmitGetExtendedRegister64(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { + A32::ExtReg reg = inst->GetArg(0).GetA32ExtRegRef(); + ASSERT(A32::IsDoubleExtReg(reg)); Xbyak::Xmm result = reg_alloc.ScratchXmm(); code->movsd(result, MJitStateExtReg(reg)); reg_alloc.DefineValue(inst, result); } -void EmitX64::EmitSetRegister(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitSetRegister(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); - Arm::Reg reg = inst->GetArg(0).GetRegRef(); + A32::Reg reg = inst->GetArg(0).GetA32RegRef(); if (args[1].IsImmediate()) { code->mov(MJitStateReg(reg), args[1].GetImmediateU32()); } else if (args[1].IsInXmm()) { @@ -178,10 +179,10 @@ void EmitX64::EmitSetRegister(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { } } -void EmitX64::EmitSetExtendedRegister32(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitSetExtendedRegister32(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); - Arm::ExtReg reg = inst->GetArg(0).GetExtRegRef(); - ASSERT(Arm::IsSingleExtReg(reg)); + A32::ExtReg reg = inst->GetArg(0).GetA32ExtRegRef(); + ASSERT(A32::IsSingleExtReg(reg)); if (args[1].IsInXmm()) { Xbyak::Xmm to_store = reg_alloc.UseXmm(args[1]); code->movss(MJitStateExtReg(reg), to_store); @@ -191,10 +192,10 @@ void EmitX64::EmitSetExtendedRegister32(RegAlloc& reg_alloc, IR::Block&, IR::Ins } } -void EmitX64::EmitSetExtendedRegister64(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitSetExtendedRegister64(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); - Arm::ExtReg reg = inst->GetArg(0).GetExtRegRef(); - ASSERT(Arm::IsDoubleExtReg(reg)); + A32::ExtReg reg = inst->GetArg(0).GetA32ExtRegRef(); + ASSERT(A32::IsDoubleExtReg(reg)); if (args[1].IsInXmm()) { Xbyak::Xmm to_store = reg_alloc.UseXmm(args[1]); code->movsd(MJitStateExtReg(reg), to_store); @@ -208,7 +209,7 @@ static u32 GetCpsrImpl(JitState* jit_state) { return jit_state->Cpsr(); } -void EmitX64::EmitGetCpsr(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitGetCpsr(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { if (code->DoesCpuSupport(Xbyak::util::Cpu::tBMI2)) { Xbyak::Reg32 result = reg_alloc.ScratchGpr().cvt32(); Xbyak::Reg32 b = reg_alloc.ScratchGpr().cvt32(); @@ -244,14 +245,14 @@ static void SetCpsrImpl(u32 value, JitState* jit_state) { jit_state->SetCpsr(value); } -void EmitX64::EmitSetCpsr(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitSetCpsr(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); reg_alloc.HostCall(nullptr, args[0]); code->mov(code->ABI_PARAM2, code->r15); code->CallFunction(&SetCpsrImpl); } -void EmitX64::EmitSetCpsrNZCV(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitSetCpsrNZCV(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); if (args[0].IsImmediate()) { u32 imm = args[0].GetImmediateU32(); @@ -265,7 +266,7 @@ void EmitX64::EmitSetCpsrNZCV(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { } } -void EmitX64::EmitSetCpsrNZCVQ(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitSetCpsrNZCVQ(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); if (args[0].IsImmediate()) { u32 imm = args[0].GetImmediateU32(); @@ -282,14 +283,14 @@ void EmitX64::EmitSetCpsrNZCVQ(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) } } -void EmitX64::EmitGetNFlag(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitGetNFlag(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { Xbyak::Reg32 result = reg_alloc.ScratchGpr().cvt32(); code->mov(result, dword[r15 + offsetof(JitState, CPSR_nzcv)]); code->shr(result, 31); reg_alloc.DefineValue(inst, result); } -void EmitX64::EmitSetNFlag(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitSetNFlag(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { constexpr size_t flag_bit = 31; constexpr u32 flag_mask = 1u << flag_bit; auto args = reg_alloc.GetArgumentInfo(inst); @@ -308,7 +309,7 @@ void EmitX64::EmitSetNFlag(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { } } -void EmitX64::EmitGetZFlag(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitGetZFlag(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { Xbyak::Reg32 result = reg_alloc.ScratchGpr().cvt32(); code->mov(result, dword[r15 + offsetof(JitState, CPSR_nzcv)]); code->shr(result, 30); @@ -316,7 +317,7 @@ void EmitX64::EmitGetZFlag(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { reg_alloc.DefineValue(inst, result); } -void EmitX64::EmitSetZFlag(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitSetZFlag(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { constexpr size_t flag_bit = 30; constexpr u32 flag_mask = 1u << flag_bit; auto args = reg_alloc.GetArgumentInfo(inst); @@ -335,7 +336,7 @@ void EmitX64::EmitSetZFlag(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { } } -void EmitX64::EmitGetCFlag(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitGetCFlag(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { Xbyak::Reg32 result = reg_alloc.ScratchGpr().cvt32(); code->mov(result, dword[r15 + offsetof(JitState, CPSR_nzcv)]); code->shr(result, 29); @@ -343,7 +344,7 @@ void EmitX64::EmitGetCFlag(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { reg_alloc.DefineValue(inst, result); } -void EmitX64::EmitSetCFlag(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitSetCFlag(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { constexpr size_t flag_bit = 29; constexpr u32 flag_mask = 1u << flag_bit; auto args = reg_alloc.GetArgumentInfo(inst); @@ -362,7 +363,7 @@ void EmitX64::EmitSetCFlag(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { } } -void EmitX64::EmitGetVFlag(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitGetVFlag(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { Xbyak::Reg32 result = reg_alloc.ScratchGpr().cvt32(); code->mov(result, dword[r15 + offsetof(JitState, CPSR_nzcv)]); code->shr(result, 28); @@ -370,7 +371,7 @@ void EmitX64::EmitGetVFlag(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { reg_alloc.DefineValue(inst, result); } -void EmitX64::EmitSetVFlag(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitSetVFlag(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { constexpr size_t flag_bit = 28; constexpr u32 flag_mask = 1u << flag_bit; auto args = reg_alloc.GetArgumentInfo(inst); @@ -389,7 +390,7 @@ void EmitX64::EmitSetVFlag(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { } } -void EmitX64::EmitOrQFlag(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitOrQFlag(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); if (args[0].IsImmediate()) { if (args[0].GetImmediateU1()) @@ -401,13 +402,13 @@ void EmitX64::EmitOrQFlag(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { } } -void EmitX64::EmitGetGEFlags(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitGetGEFlags(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { Xbyak::Xmm result = reg_alloc.ScratchXmm(); code->movd(result, dword[r15 + offsetof(JitState, CPSR_ge)]); reg_alloc.DefineValue(inst, result); } -void EmitX64::EmitSetGEFlags(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitSetGEFlags(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); ASSERT(!args[0].IsImmediate()); @@ -420,7 +421,7 @@ void EmitX64::EmitSetGEFlags(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { } } -void EmitX64::EmitSetGEFlagsCompressed(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitSetGEFlagsCompressed(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); if (args[0].IsImmediate()) { u32 imm = args[0].GetImmediateU32(); @@ -452,7 +453,7 @@ void EmitX64::EmitSetGEFlagsCompressed(RegAlloc& reg_alloc, IR::Block&, IR::Inst } } -void EmitX64::EmitBXWritePC(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { +void A32EmitX64::EmitBXWritePC(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); auto& arg = args[0]; @@ -470,13 +471,13 @@ void EmitX64::EmitBXWritePC(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* ins u32 new_pc = arg.GetImmediateU32(); u32 mask = Common::Bit<0>(new_pc) ? 0xFFFFFFFE : 0xFFFFFFFC; u32 et = 0; - et |= block.Location().EFlag() ? 2 : 0; + et |= A32::LocationDescriptor{block.Location()}.EFlag() ? 2 : 0; et |= Common::Bit<0>(new_pc) ? 1 : 0; - code->mov(MJitStateReg(Arm::Reg::PC), new_pc & mask); + code->mov(MJitStateReg(A32::Reg::PC), new_pc & mask); code->mov(dword[r15 + offsetof(JitState, CPSR_et)], et); } else { - if (block.Location().EFlag()) { + if (A32::LocationDescriptor{block.Location()}.EFlag()) { Xbyak::Reg32 new_pc = reg_alloc.UseScratchGpr(arg).cvt32(); Xbyak::Reg32 mask = reg_alloc.ScratchGpr().cvt32(); Xbyak::Reg32 et = reg_alloc.ScratchGpr().cvt32(); @@ -487,7 +488,7 @@ void EmitX64::EmitBXWritePC(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* ins code->mov(dword[r15 + offsetof(JitState, CPSR_et)], et); code->lea(mask, ptr[mask.cvt64() + mask.cvt64() * 1 - 4]); // mask = pc & 1 ? 0xFFFFFFFE : 0xFFFFFFFC code->and_(new_pc, mask); - code->mov(MJitStateReg(Arm::Reg::PC), new_pc); + code->mov(MJitStateReg(A32::Reg::PC), new_pc); } else { Xbyak::Reg32 new_pc = reg_alloc.UseScratchGpr(arg).cvt32(); Xbyak::Reg32 mask = reg_alloc.ScratchGpr().cvt32(); @@ -497,12 +498,12 @@ void EmitX64::EmitBXWritePC(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* ins code->mov(dword[r15 + offsetof(JitState, CPSR_et)], mask); code->lea(mask, ptr[mask.cvt64() + mask.cvt64() * 1 - 4]); // mask = pc & 1 ? 0xFFFFFFFE : 0xFFFFFFFC code->and_(new_pc, mask); - code->mov(MJitStateReg(Arm::Reg::PC), new_pc); + code->mov(MJitStateReg(A32::Reg::PC), new_pc); } } } -void EmitX64::EmitCallSupervisor(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitCallSupervisor(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { reg_alloc.HostCall(nullptr); code->SwitchMxcsrOnExit(); @@ -523,7 +524,7 @@ static u32 GetFpscrImpl(JitState* jit_state) { return jit_state->Fpscr(); } -void EmitX64::EmitGetFpscr(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitGetFpscr(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { reg_alloc.HostCall(inst); code->mov(code->ABI_PARAM1, code->r15); @@ -535,7 +536,7 @@ static void SetFpscrImpl(u32 value, JitState* jit_state) { jit_state->SetFpscr(value); } -void EmitX64::EmitSetFpscr(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitSetFpscr(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); reg_alloc.HostCall(nullptr, args[0]); code->mov(code->ABI_PARAM2, code->r15); @@ -544,20 +545,20 @@ void EmitX64::EmitSetFpscr(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { code->ldmxcsr(code->dword[code->r15 + offsetof(JitState, guest_MXCSR)]); } -void EmitX64::EmitGetFpscrNZCV(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitGetFpscrNZCV(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { Xbyak::Reg32 result = reg_alloc.ScratchGpr().cvt32(); code->mov(result, dword[r15 + offsetof(JitState, FPSCR_nzcv)]); reg_alloc.DefineValue(inst, result); } -void EmitX64::EmitSetFpscrNZCV(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitSetFpscrNZCV(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); Xbyak::Reg32 value = reg_alloc.UseGpr(args[0]).cvt32(); code->mov(dword[r15 + offsetof(JitState, FPSCR_nzcv)], value); } -void EmitX64::PushRSBHelper(Xbyak::Reg64 loc_desc_reg, Xbyak::Reg64 index_reg, u64 target_hash) { +void A32EmitX64::PushRSBHelper(Xbyak::Reg64 loc_desc_reg, Xbyak::Reg64 index_reg, u64 target_hash) { using namespace Xbyak::util; auto iter = block_descriptors.find(target_hash); @@ -580,7 +581,7 @@ void EmitX64::PushRSBHelper(Xbyak::Reg64 loc_desc_reg, Xbyak::Reg64 index_reg, u code->mov(dword[r15 + offsetof(JitState, rsb_ptr)], index_reg.cvt32()); } -void EmitX64::EmitPushRSB(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitPushRSB(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); ASSERT(args[0].IsImmediate()); u64 unique_hash_of_target = args[0].GetImmediateU64(); @@ -592,19 +593,19 @@ void EmitX64::EmitPushRSB(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { PushRSBHelper(loc_desc_reg, index_reg, unique_hash_of_target); } -void EmitX64::EmitGetCarryFromOp(RegAlloc&, IR::Block&, IR::Inst*) { +void A32EmitX64::EmitGetCarryFromOp(RegAlloc&, IR::Block&, IR::Inst*) { ASSERT_MSG(false, "should never happen"); } -void EmitX64::EmitGetOverflowFromOp(RegAlloc&, IR::Block&, IR::Inst*) { +void A32EmitX64::EmitGetOverflowFromOp(RegAlloc&, IR::Block&, IR::Inst*) { ASSERT_MSG(false, "should never happen"); } -void EmitX64::EmitGetGEFromOp(RegAlloc&, IR::Block&, IR::Inst*) { +void A32EmitX64::EmitGetGEFromOp(RegAlloc&, IR::Block&, IR::Inst*) { ASSERT_MSG(false, "should never happen"); } -void EmitX64::EmitPack2x32To1x64(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitPack2x32To1x64(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); Xbyak::Reg64 lo = reg_alloc.UseScratchGpr(args[0]); Xbyak::Reg64 hi = reg_alloc.UseScratchGpr(args[1]); @@ -616,12 +617,12 @@ void EmitX64::EmitPack2x32To1x64(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst reg_alloc.DefineValue(inst, lo); } -void EmitX64::EmitLeastSignificantWord(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitLeastSignificantWord(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); reg_alloc.DefineValue(inst, args[0]); } -void EmitX64::EmitMostSignificantWord(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { +void A32EmitX64::EmitMostSignificantWord(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { auto carry_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetCarryFromOp); auto args = reg_alloc.GetArgumentInfo(inst); @@ -638,17 +639,17 @@ void EmitX64::EmitMostSignificantWord(RegAlloc& reg_alloc, IR::Block& block, IR: reg_alloc.DefineValue(inst, result); } -void EmitX64::EmitLeastSignificantHalf(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitLeastSignificantHalf(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); reg_alloc.DefineValue(inst, args[0]); } -void EmitX64::EmitLeastSignificantByte(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitLeastSignificantByte(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); reg_alloc.DefineValue(inst, args[0]); } -void EmitX64::EmitMostSignificantBit(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitMostSignificantBit(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); Xbyak::Reg32 result = reg_alloc.UseScratchGpr(args[0]).cvt32(); // TODO: Flag optimization @@ -656,7 +657,7 @@ void EmitX64::EmitMostSignificantBit(RegAlloc& reg_alloc, IR::Block&, IR::Inst* reg_alloc.DefineValue(inst, result); } -void EmitX64::EmitIsZero(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitIsZero(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); Xbyak::Reg32 result = reg_alloc.UseScratchGpr(args[0]).cvt32(); // TODO: Flag optimization @@ -666,7 +667,7 @@ void EmitX64::EmitIsZero(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { reg_alloc.DefineValue(inst, result); } -void EmitX64::EmitIsZero64(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitIsZero64(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); Xbyak::Reg64 result = reg_alloc.UseScratchGpr(args[0]); // TODO: Flag optimization @@ -676,7 +677,7 @@ void EmitX64::EmitIsZero64(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { reg_alloc.DefineValue(inst, result); } -void EmitX64::EmitLogicalShiftLeft(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { +void A32EmitX64::EmitLogicalShiftLeft(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { auto carry_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetCarryFromOp); auto args = reg_alloc.GetArgumentInfo(inst); @@ -776,7 +777,7 @@ void EmitX64::EmitLogicalShiftLeft(RegAlloc& reg_alloc, IR::Block& block, IR::In } } -void EmitX64::EmitLogicalShiftRight(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { +void A32EmitX64::EmitLogicalShiftRight(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { auto carry_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetCarryFromOp); auto args = reg_alloc.GetArgumentInfo(inst); @@ -875,7 +876,7 @@ void EmitX64::EmitLogicalShiftRight(RegAlloc& reg_alloc, IR::Block& block, IR::I } } -void EmitX64::EmitLogicalShiftRight64(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitLogicalShiftRight64(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); auto& operand_arg = args[0]; auto& shift_arg = args[1]; @@ -891,7 +892,7 @@ void EmitX64::EmitLogicalShiftRight64(RegAlloc& reg_alloc, IR::Block&, IR::Inst* reg_alloc.DefineValue(inst, result); } -void EmitX64::EmitArithmeticShiftRight(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { +void A32EmitX64::EmitArithmeticShiftRight(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { auto carry_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetCarryFromOp); auto args = reg_alloc.GetArgumentInfo(inst); @@ -979,7 +980,7 @@ void EmitX64::EmitArithmeticShiftRight(RegAlloc& reg_alloc, IR::Block& block, IR } } -void EmitX64::EmitRotateRight(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { +void A32EmitX64::EmitRotateRight(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { auto carry_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetCarryFromOp); auto args = reg_alloc.GetArgumentInfo(inst); @@ -1058,7 +1059,7 @@ void EmitX64::EmitRotateRight(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* i } } -void EmitX64::EmitRotateRightExtended(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { +void A32EmitX64::EmitRotateRightExtended(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { auto carry_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetCarryFromOp); auto args = reg_alloc.GetArgumentInfo(inst); @@ -1090,7 +1091,7 @@ static Xbyak::Reg8 DoCarry(RegAlloc& reg_alloc, Argument& carry_in, IR::Inst* ca } } -void EmitX64::EmitAddWithCarry(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { +void A32EmitX64::EmitAddWithCarry(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { auto carry_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetCarryFromOp); auto overflow_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetOverflowFromOp); @@ -1146,7 +1147,7 @@ void EmitX64::EmitAddWithCarry(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* reg_alloc.DefineValue(inst, result); } -void EmitX64::EmitAdd64(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitAdd64(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); Xbyak::Reg64 result = reg_alloc.UseScratchGpr(args[0]); @@ -1157,7 +1158,7 @@ void EmitX64::EmitAdd64(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { reg_alloc.DefineValue(inst, result); } -void EmitX64::EmitSubWithCarry(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { +void A32EmitX64::EmitSubWithCarry(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { auto carry_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetCarryFromOp); auto overflow_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetOverflowFromOp); @@ -1217,7 +1218,7 @@ void EmitX64::EmitSubWithCarry(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* reg_alloc.DefineValue(inst, result); } -void EmitX64::EmitSub64(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitSub64(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); Xbyak::Reg64 result = reg_alloc.UseScratchGpr(args[0]); @@ -1228,7 +1229,7 @@ void EmitX64::EmitSub64(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { reg_alloc.DefineValue(inst, result); } -void EmitX64::EmitMul(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitMul(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); Xbyak::Reg32 result = reg_alloc.UseScratchGpr(args[0]).cvt32(); @@ -1243,7 +1244,7 @@ void EmitX64::EmitMul(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { reg_alloc.DefineValue(inst, result); } -void EmitX64::EmitMul64(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitMul64(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); Xbyak::Reg64 result = reg_alloc.UseScratchGpr(args[0]); @@ -1254,7 +1255,7 @@ void EmitX64::EmitMul64(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { reg_alloc.DefineValue(inst, result); } -void EmitX64::EmitAnd(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitAnd(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); Xbyak::Reg32 result = reg_alloc.UseScratchGpr(args[0]).cvt32(); @@ -1273,7 +1274,7 @@ void EmitX64::EmitAnd(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { reg_alloc.DefineValue(inst, result); } -void EmitX64::EmitEor(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitEor(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); Xbyak::Reg32 result = reg_alloc.UseScratchGpr(args[0]).cvt32(); @@ -1292,7 +1293,7 @@ void EmitX64::EmitEor(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { reg_alloc.DefineValue(inst, result); } -void EmitX64::EmitOr(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitOr(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); Xbyak::Reg32 result = reg_alloc.UseScratchGpr(args[0]).cvt32(); @@ -1311,7 +1312,7 @@ void EmitX64::EmitOr(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { reg_alloc.DefineValue(inst, result); } -void EmitX64::EmitNot(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitNot(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); Xbyak::Reg32 result; @@ -1325,70 +1326,70 @@ void EmitX64::EmitNot(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { reg_alloc.DefineValue(inst, result); } -void EmitX64::EmitSignExtendWordToLong(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitSignExtendWordToLong(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); Xbyak::Reg64 result = reg_alloc.UseScratchGpr(args[0]); code->movsxd(result.cvt64(), result.cvt32()); reg_alloc.DefineValue(inst, result); } -void EmitX64::EmitSignExtendHalfToWord(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitSignExtendHalfToWord(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); Xbyak::Reg64 result = reg_alloc.UseScratchGpr(args[0]); code->movsx(result.cvt32(), result.cvt16()); reg_alloc.DefineValue(inst, result); } -void EmitX64::EmitSignExtendByteToWord(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitSignExtendByteToWord(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); Xbyak::Reg64 result = reg_alloc.UseScratchGpr(args[0]); code->movsx(result.cvt32(), result.cvt8()); reg_alloc.DefineValue(inst, result); } -void EmitX64::EmitZeroExtendWordToLong(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitZeroExtendWordToLong(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); Xbyak::Reg64 result = reg_alloc.UseScratchGpr(args[0]); code->mov(result.cvt32(), result.cvt32()); // x64 zeros upper 32 bits on a 32-bit move reg_alloc.DefineValue(inst, result); } -void EmitX64::EmitZeroExtendHalfToWord(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitZeroExtendHalfToWord(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); Xbyak::Reg64 result = reg_alloc.UseScratchGpr(args[0]); code->movzx(result.cvt32(), result.cvt16()); reg_alloc.DefineValue(inst, result); } -void EmitX64::EmitZeroExtendByteToWord(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitZeroExtendByteToWord(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); Xbyak::Reg64 result = reg_alloc.UseScratchGpr(args[0]); code->movzx(result.cvt32(), result.cvt8()); reg_alloc.DefineValue(inst, result); } -void EmitX64::EmitByteReverseWord(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitByteReverseWord(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); Xbyak::Reg32 result = reg_alloc.UseScratchGpr(args[0]).cvt32(); code->bswap(result); reg_alloc.DefineValue(inst, result); } -void EmitX64::EmitByteReverseHalf(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitByteReverseHalf(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); Xbyak::Reg16 result = reg_alloc.UseScratchGpr(args[0]).cvt16(); code->rol(result, 8); reg_alloc.DefineValue(inst, result); } -void EmitX64::EmitByteReverseDual(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitByteReverseDual(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); Xbyak::Reg64 result = reg_alloc.UseScratchGpr(args[0]); code->bswap(result); reg_alloc.DefineValue(inst, result); } -void EmitX64::EmitCountLeadingZeros(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitCountLeadingZeros(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); if (code->DoesCpuSupport(Xbyak::util::Cpu::tLZCNT)) { Xbyak::Reg32 source = reg_alloc.UseGpr(args[0]).cvt32(); @@ -1412,7 +1413,7 @@ void EmitX64::EmitCountLeadingZeros(RegAlloc& reg_alloc, IR::Block&, IR::Inst* i } } -void EmitX64::EmitSignedSaturatedAdd(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { +void A32EmitX64::EmitSignedSaturatedAdd(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { auto overflow_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetOverflowFromOp); auto args = reg_alloc.GetArgumentInfo(inst); @@ -1439,7 +1440,7 @@ void EmitX64::EmitSignedSaturatedAdd(RegAlloc& reg_alloc, IR::Block& block, IR:: reg_alloc.DefineValue(inst, result); } -void EmitX64::EmitSignedSaturatedSub(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { +void A32EmitX64::EmitSignedSaturatedSub(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { auto overflow_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetOverflowFromOp); auto args = reg_alloc.GetArgumentInfo(inst); @@ -1466,7 +1467,7 @@ void EmitX64::EmitSignedSaturatedSub(RegAlloc& reg_alloc, IR::Block& block, IR:: reg_alloc.DefineValue(inst, result); } -void EmitX64::EmitUnsignedSaturation(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { +void A32EmitX64::EmitUnsignedSaturation(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { auto overflow_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetOverflowFromOp); auto args = reg_alloc.GetArgumentInfo(inst); @@ -1497,7 +1498,7 @@ void EmitX64::EmitUnsignedSaturation(RegAlloc& reg_alloc, IR::Block& block, IR:: reg_alloc.DefineValue(inst, result); } -void EmitX64::EmitSignedSaturation(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { +void A32EmitX64::EmitSignedSaturation(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { auto overflow_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetOverflowFromOp); auto args = reg_alloc.GetArgumentInfo(inst); @@ -1547,7 +1548,7 @@ void EmitX64::EmitSignedSaturation(RegAlloc& reg_alloc, IR::Block& block, IR::In reg_alloc.DefineValue(inst, result); } -void EmitX64::EmitPackedAddU8(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { +void A32EmitX64::EmitPackedAddU8(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); auto ge_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetGEFromOp); @@ -1575,7 +1576,7 @@ void EmitX64::EmitPackedAddU8(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* i reg_alloc.DefineValue(inst, xmm_a); } -void EmitX64::EmitPackedAddS8(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { +void A32EmitX64::EmitPackedAddS8(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); auto ge_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetGEFromOp); @@ -1603,7 +1604,7 @@ void EmitX64::EmitPackedAddS8(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* i reg_alloc.DefineValue(inst, xmm_a); } -void EmitX64::EmitPackedAddU16(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { +void A32EmitX64::EmitPackedAddU16(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); auto ge_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetGEFromOp); @@ -1645,7 +1646,7 @@ void EmitX64::EmitPackedAddU16(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* reg_alloc.DefineValue(inst, xmm_a); } -void EmitX64::EmitPackedAddS16(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { +void A32EmitX64::EmitPackedAddS16(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); auto ge_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetGEFromOp); @@ -1673,7 +1674,7 @@ void EmitX64::EmitPackedAddS16(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* reg_alloc.DefineValue(inst, xmm_a); } -void EmitX64::EmitPackedSubU8(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { +void A32EmitX64::EmitPackedSubU8(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); auto ge_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetGEFromOp); @@ -1698,7 +1699,7 @@ void EmitX64::EmitPackedSubU8(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* i } -void EmitX64::EmitPackedSubS8(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { +void A32EmitX64::EmitPackedSubS8(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); auto ge_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetGEFromOp); @@ -1726,7 +1727,7 @@ void EmitX64::EmitPackedSubS8(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* i reg_alloc.DefineValue(inst, xmm_a); } -void EmitX64::EmitPackedSubU16(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { +void A32EmitX64::EmitPackedSubU16(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); auto ge_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetGEFromOp); @@ -1765,7 +1766,7 @@ void EmitX64::EmitPackedSubU16(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* reg_alloc.DefineValue(inst, xmm_a); } -void EmitX64::EmitPackedSubS16(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { +void A32EmitX64::EmitPackedSubS16(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); auto ge_inst = inst->GetAssociatedPseudoOperation(IR::Opcode::GetGEFromOp); @@ -1793,7 +1794,7 @@ void EmitX64::EmitPackedSubS16(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* reg_alloc.DefineValue(inst, xmm_a); } -void EmitX64::EmitPackedHalvingAddU8(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitPackedHalvingAddU8(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); if (args[0].IsInXmm() || args[1].IsInXmm()) { @@ -1836,7 +1837,7 @@ void EmitX64::EmitPackedHalvingAddU8(RegAlloc& reg_alloc, IR::Block&, IR::Inst* } } -void EmitX64::EmitPackedHalvingAddU16(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitPackedHalvingAddU16(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); if (args[0].IsInXmm() || args[1].IsInXmm()) { @@ -1874,7 +1875,7 @@ void EmitX64::EmitPackedHalvingAddU16(RegAlloc& reg_alloc, IR::Block&, IR::Inst* } } -void EmitX64::EmitPackedHalvingAddS8(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitPackedHalvingAddS8(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); Xbyak::Reg32 reg_a = reg_alloc.UseScratchGpr(args[0]).cvt32(); @@ -1903,7 +1904,7 @@ void EmitX64::EmitPackedHalvingAddS8(RegAlloc& reg_alloc, IR::Block&, IR::Inst* reg_alloc.DefineValue(inst, result); } -void EmitX64::EmitPackedHalvingAddS16(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitPackedHalvingAddS16(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); Xbyak::Xmm xmm_a = reg_alloc.UseScratchXmm(args[0]); @@ -1924,7 +1925,7 @@ void EmitX64::EmitPackedHalvingAddS16(RegAlloc& reg_alloc, IR::Block&, IR::Inst* reg_alloc.DefineValue(inst, xmm_a); } -void EmitX64::EmitPackedHalvingSubU8(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitPackedHalvingSubU8(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); Xbyak::Reg32 minuend = reg_alloc.UseScratchGpr(args[0]).cvt32(); @@ -1954,7 +1955,7 @@ void EmitX64::EmitPackedHalvingSubU8(RegAlloc& reg_alloc, IR::Block&, IR::Inst* reg_alloc.DefineValue(inst, minuend); } -void EmitX64::EmitPackedHalvingSubS8(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitPackedHalvingSubS8(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); Xbyak::Reg32 minuend = reg_alloc.UseScratchGpr(args[0]).cvt32(); @@ -1990,7 +1991,7 @@ void EmitX64::EmitPackedHalvingSubS8(RegAlloc& reg_alloc, IR::Block&, IR::Inst* reg_alloc.DefineValue(inst, minuend); } -void EmitX64::EmitPackedHalvingSubU16(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitPackedHalvingSubU16(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); Xbyak::Xmm minuend = reg_alloc.UseScratchXmm(args[0]); @@ -2013,7 +2014,7 @@ void EmitX64::EmitPackedHalvingSubU16(RegAlloc& reg_alloc, IR::Block&, IR::Inst* reg_alloc.DefineValue(inst, minuend); } -void EmitX64::EmitPackedHalvingSubS16(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitPackedHalvingSubS16(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); Xbyak::Xmm minuend = reg_alloc.UseScratchXmm(args[0]); @@ -2110,35 +2111,35 @@ void EmitPackedSubAdd(BlockOfCode* code, RegAlloc& reg_alloc, IR::Block& block, reg_alloc.DefineValue(inst, reg_a_hi); } -void EmitX64::EmitPackedAddSubU16(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { +void A32EmitX64::EmitPackedAddSubU16(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { EmitPackedSubAdd(code, reg_alloc, block, inst, true, false, false); } -void EmitX64::EmitPackedAddSubS16(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { +void A32EmitX64::EmitPackedAddSubS16(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { EmitPackedSubAdd(code, reg_alloc, block, inst, true, true, false); } -void EmitX64::EmitPackedSubAddU16(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { +void A32EmitX64::EmitPackedSubAddU16(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { EmitPackedSubAdd(code, reg_alloc, block, inst, false, false, false); } -void EmitX64::EmitPackedSubAddS16(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { +void A32EmitX64::EmitPackedSubAddS16(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { EmitPackedSubAdd(code, reg_alloc, block, inst, false, true, false); } -void EmitX64::EmitPackedHalvingAddSubU16(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { +void A32EmitX64::EmitPackedHalvingAddSubU16(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { EmitPackedSubAdd(code, reg_alloc, block, inst, true, false, true); } -void EmitX64::EmitPackedHalvingAddSubS16(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { +void A32EmitX64::EmitPackedHalvingAddSubS16(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { EmitPackedSubAdd(code, reg_alloc, block, inst, true, true, true); } -void EmitX64::EmitPackedHalvingSubAddU16(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { +void A32EmitX64::EmitPackedHalvingSubAddU16(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { EmitPackedSubAdd(code, reg_alloc, block, inst, false, false, true); } -void EmitX64::EmitPackedHalvingSubAddS16(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { +void A32EmitX64::EmitPackedHalvingSubAddS16(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { EmitPackedSubAdd(code, reg_alloc, block, inst, false, true, true); } @@ -2153,43 +2154,43 @@ static void EmitPackedOperation(BlockOfCode* code, RegAlloc& reg_alloc, IR::Inst reg_alloc.DefineValue(inst, xmm_a); } -void EmitX64::EmitPackedSaturatedAddU8(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitPackedSaturatedAddU8(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { EmitPackedOperation(code, reg_alloc, inst, &Xbyak::CodeGenerator::paddusb); } -void EmitX64::EmitPackedSaturatedAddS8(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitPackedSaturatedAddS8(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { EmitPackedOperation(code, reg_alloc, inst, &Xbyak::CodeGenerator::paddsb); } -void EmitX64::EmitPackedSaturatedSubU8(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitPackedSaturatedSubU8(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { EmitPackedOperation(code, reg_alloc, inst, &Xbyak::CodeGenerator::psubusb); } -void EmitX64::EmitPackedSaturatedSubS8(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitPackedSaturatedSubS8(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { EmitPackedOperation(code, reg_alloc, inst, &Xbyak::CodeGenerator::psubsb); } -void EmitX64::EmitPackedSaturatedAddU16(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitPackedSaturatedAddU16(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { EmitPackedOperation(code, reg_alloc, inst, &Xbyak::CodeGenerator::paddusw); } -void EmitX64::EmitPackedSaturatedAddS16(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitPackedSaturatedAddS16(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { EmitPackedOperation(code, reg_alloc, inst, &Xbyak::CodeGenerator::paddsw); } -void EmitX64::EmitPackedSaturatedSubU16(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitPackedSaturatedSubU16(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { EmitPackedOperation(code, reg_alloc, inst, &Xbyak::CodeGenerator::psubusw); } -void EmitX64::EmitPackedSaturatedSubS16(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitPackedSaturatedSubS16(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { EmitPackedOperation(code, reg_alloc, inst, &Xbyak::CodeGenerator::psubsw); } -void EmitX64::EmitPackedAbsDiffSumS8(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitPackedAbsDiffSumS8(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { EmitPackedOperation(code, reg_alloc, inst, &Xbyak::CodeGenerator::psadbw); } -void EmitX64::EmitPackedSelect(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitPackedSelect(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); size_t num_args_in_xmm = args[0].IsInXmm() + args[1].IsInXmm() + args[2].IsInXmm(); @@ -2324,15 +2325,15 @@ static void FPThreeOp32(BlockOfCode* code, RegAlloc& reg_alloc, IR::Block& block Xbyak::Xmm operand = reg_alloc.UseScratchXmm(args[1]); Xbyak::Reg32 gpr_scratch = reg_alloc.ScratchGpr().cvt32(); - if (block.Location().FPSCR().FTZ()) { + if (A32::LocationDescriptor{block.Location()}.FPSCR().FTZ()) { DenormalsAreZero32(code, result, gpr_scratch); DenormalsAreZero32(code, operand, gpr_scratch); } (code->*fn)(result, operand); - if (block.Location().FPSCR().FTZ()) { + if (A32::LocationDescriptor{block.Location()}.FPSCR().FTZ()) { FlushToZero32(code, result, gpr_scratch); } - if (block.Location().FPSCR().DN()) { + if (A32::LocationDescriptor{block.Location()}.FPSCR().DN()) { DefaultNaN32(code, result); } @@ -2346,15 +2347,15 @@ static void FPThreeOp64(BlockOfCode* code, RegAlloc& reg_alloc, IR::Block& block Xbyak::Xmm operand = reg_alloc.UseScratchXmm(args[1]); Xbyak::Reg64 gpr_scratch = reg_alloc.ScratchGpr(); - if (block.Location().FPSCR().FTZ()) { + if (A32::LocationDescriptor{block.Location()}.FPSCR().FTZ()) { DenormalsAreZero64(code, result, gpr_scratch); DenormalsAreZero64(code, operand, gpr_scratch); } (code->*fn)(result, operand); - if (block.Location().FPSCR().FTZ()) { + if (A32::LocationDescriptor{block.Location()}.FPSCR().FTZ()) { FlushToZero64(code, result, gpr_scratch); } - if (block.Location().FPSCR().DN()) { + if (A32::LocationDescriptor{block.Location()}.FPSCR().DN()) { DefaultNaN64(code, result); } @@ -2367,15 +2368,15 @@ static void FPTwoOp32(BlockOfCode* code, RegAlloc& reg_alloc, IR::Block& block, Xbyak::Xmm result = reg_alloc.UseScratchXmm(args[0]); Xbyak::Reg32 gpr_scratch = reg_alloc.ScratchGpr().cvt32(); - if (block.Location().FPSCR().FTZ()) { + if (A32::LocationDescriptor{block.Location()}.FPSCR().FTZ()) { DenormalsAreZero32(code, result, gpr_scratch); } (code->*fn)(result, result); - if (block.Location().FPSCR().FTZ()) { + if (A32::LocationDescriptor{block.Location()}.FPSCR().FTZ()) { FlushToZero32(code, result, gpr_scratch); } - if (block.Location().FPSCR().DN()) { + if (A32::LocationDescriptor{block.Location()}.FPSCR().DN()) { DefaultNaN32(code, result); } @@ -2388,32 +2389,32 @@ static void FPTwoOp64(BlockOfCode* code, RegAlloc& reg_alloc, IR::Block& block, Xbyak::Xmm result = reg_alloc.UseScratchXmm(args[0]); Xbyak::Reg64 gpr_scratch = reg_alloc.ScratchGpr(); - if (block.Location().FPSCR().FTZ()) { + if (A32::LocationDescriptor{block.Location()}.FPSCR().FTZ()) { DenormalsAreZero64(code, result, gpr_scratch); } (code->*fn)(result, result); - if (block.Location().FPSCR().FTZ()) { + if (A32::LocationDescriptor{block.Location()}.FPSCR().FTZ()) { FlushToZero64(code, result, gpr_scratch); } - if (block.Location().FPSCR().DN()) { + if (A32::LocationDescriptor{block.Location()}.FPSCR().DN()) { DefaultNaN64(code, result); } reg_alloc.DefineValue(inst, result); } -void EmitX64::EmitTransferFromFP32(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitTransferFromFP32(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); reg_alloc.DefineValue(inst, args[0]); } -void EmitX64::EmitTransferFromFP64(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitTransferFromFP64(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); reg_alloc.DefineValue(inst, args[0]); } -void EmitX64::EmitTransferToFP32(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitTransferToFP32(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); if (args[0].IsImmediate() && args[0].GetImmediateU32() == 0) { Xbyak::Xmm result = reg_alloc.ScratchXmm(); @@ -2424,7 +2425,7 @@ void EmitX64::EmitTransferToFP32(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst } } -void EmitX64::EmitTransferToFP64(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitTransferToFP64(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); if (args[0].IsImmediate() && args[0].GetImmediateU64() == 0) { Xbyak::Xmm result = reg_alloc.ScratchXmm(); @@ -2435,7 +2436,7 @@ void EmitX64::EmitTransferToFP64(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst } } -void EmitX64::EmitFPAbs32(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitFPAbs32(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); Xbyak::Xmm result = reg_alloc.UseScratchXmm(args[0]); @@ -2444,7 +2445,7 @@ void EmitX64::EmitFPAbs32(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { reg_alloc.DefineValue(inst, result); } -void EmitX64::EmitFPAbs64(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitFPAbs64(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); Xbyak::Xmm result = reg_alloc.UseScratchXmm(args[0]); @@ -2453,7 +2454,7 @@ void EmitX64::EmitFPAbs64(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { reg_alloc.DefineValue(inst, result); } -void EmitX64::EmitFPNeg32(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitFPNeg32(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); Xbyak::Xmm result = reg_alloc.UseScratchXmm(args[0]); @@ -2462,7 +2463,7 @@ void EmitX64::EmitFPNeg32(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { reg_alloc.DefineValue(inst, result); } -void EmitX64::EmitFPNeg64(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitFPNeg64(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); Xbyak::Xmm result = reg_alloc.UseScratchXmm(args[0]); @@ -2471,43 +2472,43 @@ void EmitX64::EmitFPNeg64(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { reg_alloc.DefineValue(inst, result); } -void EmitX64::EmitFPAdd32(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { +void A32EmitX64::EmitFPAdd32(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { FPThreeOp32(code, reg_alloc, block, inst, &Xbyak::CodeGenerator::addss); } -void EmitX64::EmitFPAdd64(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { +void A32EmitX64::EmitFPAdd64(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { FPThreeOp64(code, reg_alloc, block, inst, &Xbyak::CodeGenerator::addsd); } -void EmitX64::EmitFPDiv32(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { +void A32EmitX64::EmitFPDiv32(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { FPThreeOp32(code, reg_alloc, block, inst, &Xbyak::CodeGenerator::divss); } -void EmitX64::EmitFPDiv64(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { +void A32EmitX64::EmitFPDiv64(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { FPThreeOp64(code, reg_alloc, block, inst, &Xbyak::CodeGenerator::divsd); } -void EmitX64::EmitFPMul32(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { +void A32EmitX64::EmitFPMul32(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { FPThreeOp32(code, reg_alloc, block, inst, &Xbyak::CodeGenerator::mulss); } -void EmitX64::EmitFPMul64(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { +void A32EmitX64::EmitFPMul64(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { FPThreeOp64(code, reg_alloc, block, inst, &Xbyak::CodeGenerator::mulsd); } -void EmitX64::EmitFPSqrt32(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { +void A32EmitX64::EmitFPSqrt32(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { FPTwoOp32(code, reg_alloc, block, inst, &Xbyak::CodeGenerator::sqrtss); } -void EmitX64::EmitFPSqrt64(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { +void A32EmitX64::EmitFPSqrt64(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { FPTwoOp64(code, reg_alloc, block, inst, &Xbyak::CodeGenerator::sqrtsd); } -void EmitX64::EmitFPSub32(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { +void A32EmitX64::EmitFPSub32(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { FPThreeOp32(code, reg_alloc, block, inst, &Xbyak::CodeGenerator::subss); } -void EmitX64::EmitFPSub64(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { +void A32EmitX64::EmitFPSub64(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { FPThreeOp64(code, reg_alloc, block, inst, &Xbyak::CodeGenerator::subsd); } @@ -2524,7 +2525,7 @@ static void SetFpscrNzcvFromFlags(BlockOfCode* code, RegAlloc& reg_alloc) { code->mov(dword[r15 + offsetof(JitState, FPSCR_nzcv)], nzcv); } -void EmitX64::EmitFPCompare32(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitFPCompare32(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); Xbyak::Xmm reg_a = reg_alloc.UseXmm(args[0]); Xbyak::Xmm reg_b = reg_alloc.UseXmm(args[1]); @@ -2539,7 +2540,7 @@ void EmitX64::EmitFPCompare32(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { SetFpscrNzcvFromFlags(code, reg_alloc); } -void EmitX64::EmitFPCompare64(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitFPCompare64(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); Xbyak::Xmm reg_a = reg_alloc.UseXmm(args[0]); Xbyak::Xmm reg_b = reg_alloc.UseXmm(args[1]); @@ -2554,45 +2555,45 @@ void EmitX64::EmitFPCompare64(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { SetFpscrNzcvFromFlags(code, reg_alloc); } -void EmitX64::EmitFPSingleToDouble(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { +void A32EmitX64::EmitFPSingleToDouble(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); Xbyak::Xmm result = reg_alloc.UseScratchXmm(args[0]); Xbyak::Reg64 gpr_scratch = reg_alloc.ScratchGpr(); - if (block.Location().FPSCR().FTZ()) { + if (A32::LocationDescriptor{block.Location()}.FPSCR().FTZ()) { DenormalsAreZero32(code, result, gpr_scratch.cvt32()); } code->cvtss2sd(result, result); - if (block.Location().FPSCR().FTZ()) { + if (A32::LocationDescriptor{block.Location()}.FPSCR().FTZ()) { FlushToZero64(code, result, gpr_scratch); } - if (block.Location().FPSCR().DN()) { + if (A32::LocationDescriptor{block.Location()}.FPSCR().DN()) { DefaultNaN64(code, result); } reg_alloc.DefineValue(inst, result); } -void EmitX64::EmitFPDoubleToSingle(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { +void A32EmitX64::EmitFPDoubleToSingle(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); Xbyak::Xmm result = reg_alloc.UseScratchXmm(args[0]); Xbyak::Reg64 gpr_scratch = reg_alloc.ScratchGpr(); - if (block.Location().FPSCR().FTZ()) { + if (A32::LocationDescriptor{block.Location()}.FPSCR().FTZ()) { DenormalsAreZero64(code, result, gpr_scratch); } code->cvtsd2ss(result, result); - if (block.Location().FPSCR().FTZ()) { + if (A32::LocationDescriptor{block.Location()}.FPSCR().FTZ()) { FlushToZero32(code, result, gpr_scratch.cvt32()); } - if (block.Location().FPSCR().DN()) { + if (A32::LocationDescriptor{block.Location()}.FPSCR().DN()) { DefaultNaN32(code, result); } reg_alloc.DefineValue(inst, result); } -void EmitX64::EmitFPSingleToS32(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { +void A32EmitX64::EmitFPSingleToS32(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); Xbyak::Xmm from = reg_alloc.UseScratchXmm(args[0]); Xbyak::Reg32 to = reg_alloc.ScratchGpr().cvt32(); @@ -2602,7 +2603,7 @@ void EmitX64::EmitFPSingleToS32(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* // ARM saturates on conversion; this differs from x64 which returns a sentinel value. // Conversion to double is lossless, and allows for clamping. - if (block.Location().FPSCR().FTZ()) { + if (A32::LocationDescriptor{block.Location()}.FPSCR().FTZ()) { DenormalsAreZero32(code, from, to); } code->cvtss2sd(from, from); @@ -2626,7 +2627,7 @@ void EmitX64::EmitFPSingleToS32(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* reg_alloc.DefineValue(inst, to); } -void EmitX64::EmitFPSingleToU32(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { +void A32EmitX64::EmitFPSingleToU32(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); Xbyak::Xmm from = reg_alloc.UseScratchXmm(args[0]); Xbyak::Reg32 to = reg_alloc.ScratchGpr().cvt32(); @@ -2640,8 +2641,8 @@ void EmitX64::EmitFPSingleToU32(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* // // FIXME: Inexact exception not correctly signalled with the below code - if (block.Location().FPSCR().RMode() != Arm::FPSCR::RoundingMode::TowardsZero && !round_towards_zero) { - if (block.Location().FPSCR().FTZ()) { + if (A32::LocationDescriptor{block.Location()}.FPSCR().RMode() != A32::FPSCR::RoundingMode::TowardsZero && !round_towards_zero) { + if (A32::LocationDescriptor{block.Location()}.FPSCR().FTZ()) { DenormalsAreZero32(code, from, to); } code->cvtss2sd(from, from); @@ -2661,7 +2662,7 @@ void EmitX64::EmitFPSingleToU32(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* Xbyak::Xmm xmm_mask = reg_alloc.ScratchXmm(); Xbyak::Reg32 gpr_mask = reg_alloc.ScratchGpr().cvt32(); - if (block.Location().FPSCR().FTZ()) { + if (A32::LocationDescriptor{block.Location()}.FPSCR().FTZ()) { DenormalsAreZero32(code, from, to); } code->cvtss2sd(from, from); @@ -2688,7 +2689,7 @@ void EmitX64::EmitFPSingleToU32(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* reg_alloc.DefineValue(inst, to); } -void EmitX64::EmitFPDoubleToS32(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { +void A32EmitX64::EmitFPDoubleToS32(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); Xbyak::Xmm from = reg_alloc.UseScratchXmm(args[0]); Xbyak::Reg32 to = reg_alloc.ScratchGpr().cvt32(); @@ -2698,7 +2699,7 @@ void EmitX64::EmitFPDoubleToS32(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* // ARM saturates on conversion; this differs from x64 which returns a sentinel value. - if (block.Location().FPSCR().FTZ()) { + if (A32::LocationDescriptor{block.Location()}.FPSCR().FTZ()) { DenormalsAreZero64(code, from, gpr_scratch.cvt64()); } // First time is to set flags @@ -2721,7 +2722,7 @@ void EmitX64::EmitFPDoubleToS32(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* reg_alloc.DefineValue(inst, to); } -void EmitX64::EmitFPDoubleToU32(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { +void A32EmitX64::EmitFPDoubleToU32(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); Xbyak::Xmm from = reg_alloc.UseScratchXmm(args[0]); Xbyak::Reg32 to = reg_alloc.ScratchGpr().cvt32(); @@ -2733,8 +2734,8 @@ void EmitX64::EmitFPDoubleToU32(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* // TODO: Use VCVTPD2UDQ when AVX512VL is available. // FIXME: Inexact exception not correctly signalled with the below code - if (block.Location().FPSCR().RMode() != Arm::FPSCR::RoundingMode::TowardsZero && !round_towards_zero) { - if (block.Location().FPSCR().FTZ()) { + if (A32::LocationDescriptor{block.Location()}.FPSCR().RMode() != A32::FPSCR::RoundingMode::TowardsZero && !round_towards_zero) { + if (A32::LocationDescriptor{block.Location()}.FPSCR().FTZ()) { DenormalsAreZero64(code, from, gpr_scratch.cvt64()); } ZeroIfNaN64(code, from, xmm_scratch); @@ -2753,7 +2754,7 @@ void EmitX64::EmitFPDoubleToU32(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* Xbyak::Xmm xmm_mask = reg_alloc.ScratchXmm(); Xbyak::Reg32 gpr_mask = reg_alloc.ScratchGpr().cvt32(); - if (block.Location().FPSCR().FTZ()) { + if (A32::LocationDescriptor{block.Location()}.FPSCR().FTZ()) { DenormalsAreZero64(code, from, gpr_scratch.cvt64()); } ZeroIfNaN64(code, from, xmm_scratch); @@ -2779,7 +2780,7 @@ void EmitX64::EmitFPDoubleToU32(RegAlloc& reg_alloc, IR::Block& block, IR::Inst* reg_alloc.DefineValue(inst, to); } -void EmitX64::EmitFPS32ToSingle(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitFPS32ToSingle(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); Xbyak::Reg32 from = reg_alloc.UseGpr(args[0]).cvt32(); Xbyak::Xmm to = reg_alloc.ScratchXmm(); @@ -2791,7 +2792,7 @@ void EmitX64::EmitFPS32ToSingle(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) reg_alloc.DefineValue(inst, to); } -void EmitX64::EmitFPU32ToSingle(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitFPU32ToSingle(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); Xbyak::Reg64 from = reg_alloc.UseGpr(args[0]); Xbyak::Xmm to = reg_alloc.ScratchXmm(); @@ -2805,7 +2806,7 @@ void EmitX64::EmitFPU32ToSingle(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) reg_alloc.DefineValue(inst, to); } -void EmitX64::EmitFPS32ToDouble(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitFPS32ToDouble(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); Xbyak::Reg32 from = reg_alloc.UseGpr(args[0]).cvt32(); Xbyak::Xmm to = reg_alloc.ScratchXmm(); @@ -2817,7 +2818,7 @@ void EmitX64::EmitFPS32ToDouble(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) reg_alloc.DefineValue(inst, to); } -void EmitX64::EmitFPU32ToDouble(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitFPU32ToDouble(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); Xbyak::Reg64 from = reg_alloc.UseGpr(args[0]); Xbyak::Xmm to = reg_alloc.ScratchXmm(); @@ -2832,11 +2833,11 @@ void EmitX64::EmitFPU32ToDouble(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) } -void EmitX64::EmitClearExclusive(RegAlloc&, IR::Block&, IR::Inst*) { +void A32EmitX64::EmitClearExclusive(RegAlloc&, IR::Block&, IR::Inst*) { code->mov(code->byte[r15 + offsetof(JitState, exclusive_state)], u8(0)); } -void EmitX64::EmitSetExclusive(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitSetExclusive(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); ASSERT(args[1].IsImmediate()); Xbyak::Reg32 address = reg_alloc.UseGpr(args[0]).cvt32(); @@ -2951,35 +2952,35 @@ static void WriteMemory(BlockOfCode* code, RegAlloc& reg_alloc, IR::Inst* inst, code->L(end); } -void EmitX64::EmitReadMemory8(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitReadMemory8(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { ReadMemory(code, reg_alloc, inst, cb, 8, cb.memory.Read8); } -void EmitX64::EmitReadMemory16(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitReadMemory16(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { ReadMemory(code, reg_alloc, inst, cb, 16, cb.memory.Read16); } -void EmitX64::EmitReadMemory32(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitReadMemory32(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { ReadMemory(code, reg_alloc, inst, cb, 32, cb.memory.Read32); } -void EmitX64::EmitReadMemory64(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitReadMemory64(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { ReadMemory(code, reg_alloc, inst, cb, 64, cb.memory.Read64); } -void EmitX64::EmitWriteMemory8(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitWriteMemory8(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { WriteMemory(code, reg_alloc, inst, cb, 8, cb.memory.Write8); } -void EmitX64::EmitWriteMemory16(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitWriteMemory16(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { WriteMemory(code, reg_alloc, inst, cb, 16, cb.memory.Write16); } -void EmitX64::EmitWriteMemory32(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitWriteMemory32(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { WriteMemory(code, reg_alloc, inst, cb, 32, cb.memory.Write32); } -void EmitX64::EmitWriteMemory64(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitWriteMemory64(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { WriteMemory(code, reg_alloc, inst, cb, 64, cb.memory.Write64); } @@ -3016,19 +3017,19 @@ static void ExclusiveWrite(BlockOfCode* code, RegAlloc& reg_alloc, IR::Inst* ins reg_alloc.DefineValue(inst, passed); } -void EmitX64::EmitExclusiveWriteMemory8(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitExclusiveWriteMemory8(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { ExclusiveWrite(code, reg_alloc, inst, cb.memory.Write8, false); } -void EmitX64::EmitExclusiveWriteMemory16(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitExclusiveWriteMemory16(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { ExclusiveWrite(code, reg_alloc, inst, cb.memory.Write16, false); } -void EmitX64::EmitExclusiveWriteMemory32(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitExclusiveWriteMemory32(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { ExclusiveWrite(code, reg_alloc, inst, cb.memory.Write32, false); } -void EmitX64::EmitExclusiveWriteMemory64(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitExclusiveWriteMemory64(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { ExclusiveWrite(code, reg_alloc, inst, cb.memory.Write64, true); } @@ -3047,15 +3048,15 @@ static void CallCoprocCallback(BlockOfCode* code, RegAlloc& reg_alloc, Jit* jit_ code->CallFunction(callback.function); } -void EmitX64::EmitCoprocInternalOperation(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitCoprocInternalOperation(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto coproc_info = inst->GetArg(0).GetCoprocInfo(); size_t coproc_num = coproc_info[0]; bool two = coproc_info[1] != 0; unsigned opc1 = static_cast(coproc_info[2]); - Arm::CoprocReg CRd = static_cast(coproc_info[3]); - Arm::CoprocReg CRn = static_cast(coproc_info[4]); - Arm::CoprocReg CRm = static_cast(coproc_info[5]); + A32::CoprocReg CRd = static_cast(coproc_info[3]); + A32::CoprocReg CRn = static_cast(coproc_info[4]); + A32::CoprocReg CRm = static_cast(coproc_info[5]); unsigned opc2 = static_cast(coproc_info[6]); std::shared_ptr coproc = cb.coprocessors[coproc_num]; @@ -3073,15 +3074,15 @@ void EmitX64::EmitCoprocInternalOperation(RegAlloc& reg_alloc, IR::Block&, IR::I CallCoprocCallback(code, reg_alloc, jit_interface, *action); } -void EmitX64::EmitCoprocSendOneWord(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitCoprocSendOneWord(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); auto coproc_info = inst->GetArg(0).GetCoprocInfo(); size_t coproc_num = coproc_info[0]; bool two = coproc_info[1] != 0; unsigned opc1 = static_cast(coproc_info[2]); - Arm::CoprocReg CRn = static_cast(coproc_info[3]); - Arm::CoprocReg CRm = static_cast(coproc_info[4]); + A32::CoprocReg CRn = static_cast(coproc_info[3]); + A32::CoprocReg CRm = static_cast(coproc_info[4]); unsigned opc2 = static_cast(coproc_info[5]); std::shared_ptr coproc = cb.coprocessors[coproc_num]; @@ -3114,14 +3115,14 @@ void EmitX64::EmitCoprocSendOneWord(RegAlloc& reg_alloc, IR::Block&, IR::Inst* i } } -void EmitX64::EmitCoprocSendTwoWords(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitCoprocSendTwoWords(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); auto coproc_info = inst->GetArg(0).GetCoprocInfo(); size_t coproc_num = coproc_info[0]; bool two = coproc_info[1] != 0; unsigned opc = static_cast(coproc_info[2]); - Arm::CoprocReg CRm = static_cast(coproc_info[3]); + A32::CoprocReg CRm = static_cast(coproc_info[3]); std::shared_ptr coproc = cb.coprocessors[coproc_num]; if (!coproc) { @@ -3156,14 +3157,14 @@ void EmitX64::EmitCoprocSendTwoWords(RegAlloc& reg_alloc, IR::Block&, IR::Inst* } } -void EmitX64::EmitCoprocGetOneWord(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitCoprocGetOneWord(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto coproc_info = inst->GetArg(0).GetCoprocInfo(); size_t coproc_num = coproc_info[0]; bool two = coproc_info[1] != 0; unsigned opc1 = static_cast(coproc_info[2]); - Arm::CoprocReg CRn = static_cast(coproc_info[3]); - Arm::CoprocReg CRm = static_cast(coproc_info[4]); + A32::CoprocReg CRn = static_cast(coproc_info[3]); + A32::CoprocReg CRm = static_cast(coproc_info[4]); unsigned opc2 = static_cast(coproc_info[5]); std::shared_ptr coproc = cb.coprocessors[coproc_num]; @@ -3198,13 +3199,13 @@ void EmitX64::EmitCoprocGetOneWord(RegAlloc& reg_alloc, IR::Block&, IR::Inst* in } } -void EmitX64::EmitCoprocGetTwoWords(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitCoprocGetTwoWords(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto coproc_info = inst->GetArg(0).GetCoprocInfo(); size_t coproc_num = coproc_info[0]; bool two = coproc_info[1] != 0; unsigned opc = coproc_info[2]; - Arm::CoprocReg CRm = static_cast(coproc_info[3]); + A32::CoprocReg CRm = static_cast(coproc_info[3]); std::shared_ptr coproc = cb.coprocessors[coproc_num]; if (!coproc) { @@ -3243,14 +3244,14 @@ void EmitX64::EmitCoprocGetTwoWords(RegAlloc& reg_alloc, IR::Block&, IR::Inst* i } } -void EmitX64::EmitCoprocLoadWords(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitCoprocLoadWords(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); auto coproc_info = inst->GetArg(0).GetCoprocInfo(); size_t coproc_num = coproc_info[0]; bool two = coproc_info[1] != 0; bool long_transfer = coproc_info[2] != 0; - Arm::CoprocReg CRd = static_cast(coproc_info[3]); + A32::CoprocReg CRd = static_cast(coproc_info[3]); bool has_option = coproc_info[4] != 0; boost::optional option{has_option, coproc_info[5]}; @@ -3269,14 +3270,14 @@ void EmitX64::EmitCoprocLoadWords(RegAlloc& reg_alloc, IR::Block&, IR::Inst* ins CallCoprocCallback(code, reg_alloc, jit_interface, *action, nullptr, args[1]); } -void EmitX64::EmitCoprocStoreWords(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { +void A32EmitX64::EmitCoprocStoreWords(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { auto args = reg_alloc.GetArgumentInfo(inst); auto coproc_info = inst->GetArg(0).GetCoprocInfo(); size_t coproc_num = coproc_info[0]; bool two = coproc_info[1] != 0; bool long_transfer = coproc_info[2] != 0; - Arm::CoprocReg CRd = static_cast(coproc_info[3]); + A32::CoprocReg CRd = static_cast(coproc_info[3]); bool has_option = coproc_info[4] != 0; boost::optional option{has_option, coproc_info[5]}; @@ -3295,12 +3296,12 @@ void EmitX64::EmitCoprocStoreWords(RegAlloc& reg_alloc, IR::Block&, IR::Inst* in CallCoprocCallback(code, reg_alloc, jit_interface, *action, nullptr, args[1]); } -void EmitX64::EmitAddCycles(size_t cycles) { +void A32EmitX64::EmitAddCycles(size_t cycles) { ASSERT(cycles < std::numeric_limits::max()); code->sub(qword[r15 + offsetof(JitState, cycles_remaining)], static_cast(cycles)); } -static Xbyak::Label EmitCond(BlockOfCode* code, Arm::Cond cond) { +static Xbyak::Label EmitCond(BlockOfCode* code, IR::Cond cond) { Xbyak::Label label; const Xbyak::Reg32 cpsr = eax; @@ -3316,58 +3317,58 @@ static Xbyak::Label EmitCond(BlockOfCode* code, Arm::Cond cond) { constexpr u32 v_mask = 1u << v_shift; switch (cond) { - case Arm::Cond::EQ: //z + case IR::Cond::EQ: //z code->test(cpsr, z_mask); code->jnz(label); break; - case Arm::Cond::NE: //!z + case IR::Cond::NE: //!z code->test(cpsr, z_mask); code->jz(label); break; - case Arm::Cond::CS: //c + case IR::Cond::CS: //c code->test(cpsr, c_mask); code->jnz(label); break; - case Arm::Cond::CC: //!c + case IR::Cond::CC: //!c code->test(cpsr, c_mask); code->jz(label); break; - case Arm::Cond::MI: //n + case IR::Cond::MI: //n code->test(cpsr, n_mask); code->jnz(label); break; - case Arm::Cond::PL: //!n + case IR::Cond::PL: //!n code->test(cpsr, n_mask); code->jz(label); break; - case Arm::Cond::VS: //v + case IR::Cond::VS: //v code->test(cpsr, v_mask); code->jnz(label); break; - case Arm::Cond::VC: //!v + case IR::Cond::VC: //!v code->test(cpsr, v_mask); code->jz(label); break; - case Arm::Cond::HI: { //c & !z + case IR::Cond::HI: { //c & !z code->and_(cpsr, z_mask | c_mask); code->cmp(cpsr, c_mask); code->je(label); break; } - case Arm::Cond::LS: { //!c | z + case IR::Cond::LS: { //!c | z code->and_(cpsr, z_mask | c_mask); code->cmp(cpsr, c_mask); code->jne(label); break; } - case Arm::Cond::GE: { // n == v + case IR::Cond::GE: { // n == v code->and_(cpsr, n_mask | v_mask); code->jz(label); code->cmp(cpsr, n_mask | v_mask); code->je(label); break; } - case Arm::Cond::LT: { // n != v + case IR::Cond::LT: { // n != v Xbyak::Label fail; code->and_(cpsr, n_mask | v_mask); code->jz(fail); @@ -3376,7 +3377,7 @@ static Xbyak::Label EmitCond(BlockOfCode* code, Arm::Cond cond) { code->L(fail); break; } - case Arm::Cond::GT: { // !z & (n == v) + case IR::Cond::GT: { // !z & (n == v) const Xbyak::Reg32 tmp1 = ebx; const Xbyak::Reg32 tmp2 = esi; code->mov(tmp1, cpsr); @@ -3390,7 +3391,7 @@ static Xbyak::Label EmitCond(BlockOfCode* code, Arm::Cond cond) { code->jz(label); break; } - case Arm::Cond::LE: { // z | (n != v) + case IR::Cond::LE: { // z | (n != v) const Xbyak::Reg32 tmp1 = ebx; const Xbyak::Reg32 tmp2 = esi; code->mov(tmp1, cpsr); @@ -3412,8 +3413,8 @@ static Xbyak::Label EmitCond(BlockOfCode* code, Arm::Cond cond) { return label; } -void EmitX64::EmitCondPrelude(const IR::Block& block) { - if (block.GetCondition() == Arm::Cond::AL) { +void A32EmitX64::EmitCondPrelude(const IR::Block& block) { + if (block.GetCondition() == IR::Cond::AL) { ASSERT(!block.HasConditionFailedLocation()); return; } @@ -3426,44 +3427,44 @@ void EmitX64::EmitCondPrelude(const IR::Block& block) { code->L(pass); } -void EmitX64::EmitTerminal(IR::Terminal terminal, IR::LocationDescriptor initial_location) { +void A32EmitX64::EmitTerminal(IR::Terminal terminal, A32::LocationDescriptor initial_location) { Common::VisitVariant(terminal, [this, &initial_location](auto x) { this->EmitTerminal(x, initial_location); }); } -void EmitX64::EmitTerminal(IR::Term::Interpret terminal, IR::LocationDescriptor initial_location) { - ASSERT_MSG(terminal.next.TFlag() == initial_location.TFlag(), "Unimplemented"); - ASSERT_MSG(terminal.next.EFlag() == initial_location.EFlag(), "Unimplemented"); +void A32EmitX64::EmitTerminal(IR::Term::Interpret terminal, A32::LocationDescriptor initial_location) { + ASSERT_MSG(A32::LocationDescriptor{terminal.next}.TFlag() == initial_location.TFlag(), "Unimplemented"); + ASSERT_MSG(A32::LocationDescriptor{terminal.next}.EFlag() == initial_location.EFlag(), "Unimplemented"); - code->mov(code->ABI_PARAM1.cvt32(), terminal.next.PC()); + code->mov(code->ABI_PARAM1.cvt32(), A32::LocationDescriptor{terminal.next}.PC()); code->mov(code->ABI_PARAM2, reinterpret_cast(jit_interface)); code->mov(code->ABI_PARAM3, reinterpret_cast(cb.user_arg)); - code->mov(MJitStateReg(Arm::Reg::PC), code->ABI_PARAM1.cvt32()); + code->mov(MJitStateReg(A32::Reg::PC), code->ABI_PARAM1.cvt32()); code->SwitchMxcsrOnExit(); code->CallFunction(cb.InterpreterFallback); code->ReturnFromRunCode(true); // TODO: Check cycles } -void EmitX64::EmitTerminal(IR::Term::ReturnToDispatch, IR::LocationDescriptor) { +void A32EmitX64::EmitTerminal(IR::Term::ReturnToDispatch, A32::LocationDescriptor) { code->ReturnFromRunCode(); } -static u32 CalculateCpsr_et(const IR::LocationDescriptor& desc) { +static u32 CalculateCpsr_et(const A32::LocationDescriptor& desc) { u32 et = 0; et |= desc.EFlag() ? 2 : 0; et |= desc.TFlag() ? 1 : 0; return et; } -void EmitX64::EmitTerminal(IR::Term::LinkBlock terminal, IR::LocationDescriptor initial_location) { +void A32EmitX64::EmitTerminal(IR::Term::LinkBlock terminal, A32::LocationDescriptor initial_location) { if (CalculateCpsr_et(terminal.next) != CalculateCpsr_et(initial_location)) { code->mov(dword[r15 + offsetof(JitState, CPSR_et)], CalculateCpsr_et(terminal.next)); } code->cmp(qword[r15 + offsetof(JitState, cycles_remaining)], 0); - patch_information[terminal.next.UniqueHash()].jg.emplace_back(code->getCurr()); + patch_information[terminal.next.value].jg.emplace_back(code->getCurr()); if (auto next_bb = GetBasicBlock(terminal.next)) { EmitPatchJg(terminal.next, next_bb->entrypoint); } else { @@ -3475,18 +3476,18 @@ void EmitX64::EmitTerminal(IR::Term::LinkBlock terminal, IR::LocationDescriptor code->SwitchToFarCode(); code->align(16); code->L(dest); - code->mov(MJitStateReg(Arm::Reg::PC), terminal.next.PC()); - PushRSBHelper(rax, rbx, terminal.next.UniqueHash()); + code->mov(MJitStateReg(A32::Reg::PC), A32::LocationDescriptor{terminal.next}.PC()); + PushRSBHelper(rax, rbx, terminal.next.value); code->ForceReturnFromRunCode(); code->SwitchToNearCode(); } -void EmitX64::EmitTerminal(IR::Term::LinkBlockFast terminal, IR::LocationDescriptor initial_location) { +void A32EmitX64::EmitTerminal(IR::Term::LinkBlockFast terminal, A32::LocationDescriptor initial_location) { if (CalculateCpsr_et(terminal.next) != CalculateCpsr_et(initial_location)) { code->mov(dword[r15 + offsetof(JitState, CPSR_et)], CalculateCpsr_et(terminal.next)); } - patch_information[terminal.next.UniqueHash()].jmp.emplace_back(code->getCurr()); + patch_information[terminal.next.value].jmp.emplace_back(code->getCurr()); if (auto next_bb = GetBasicBlock(terminal.next)) { EmitPatchJmp(terminal.next, next_bb->entrypoint); } else { @@ -3494,10 +3495,10 @@ void EmitX64::EmitTerminal(IR::Term::LinkBlockFast terminal, IR::LocationDescrip } } -void EmitX64::EmitTerminal(IR::Term::PopRSBHint, IR::LocationDescriptor) { +void A32EmitX64::EmitTerminal(IR::Term::PopRSBHint, A32::LocationDescriptor) { // This calculation has to match up with IREmitter::PushRSB // TODO: Optimization is available here based on known state of FPSCR_mode and CPSR_et. - code->mov(ecx, MJitStateReg(Arm::Reg::PC)); + code->mov(ecx, MJitStateReg(A32::Reg::PC)); code->shl(rcx, 32); code->mov(ebx, dword[r15 + offsetof(JitState, FPSCR_mode)]); code->or_(ebx, dword[r15 + offsetof(JitState, CPSR_et)]); @@ -3513,20 +3514,20 @@ void EmitX64::EmitTerminal(IR::Term::PopRSBHint, IR::LocationDescriptor) { code->jmp(rax); } -void EmitX64::EmitTerminal(IR::Term::If terminal, IR::LocationDescriptor initial_location) { +void A32EmitX64::EmitTerminal(IR::Term::If terminal, A32::LocationDescriptor initial_location) { Xbyak::Label pass = EmitCond(code, terminal.if_); EmitTerminal(terminal.else_, initial_location); code->L(pass); EmitTerminal(terminal.then_, initial_location); } -void EmitX64::EmitTerminal(IR::Term::CheckHalt terminal, IR::LocationDescriptor initial_location) { +void A32EmitX64::EmitTerminal(IR::Term::CheckHalt terminal, A32::LocationDescriptor initial_location) { code->cmp(code->byte[r15 + offsetof(JitState, halt_requested)], u8(0)); code->jne(code->GetForceReturnFromRunCodeAddress()); EmitTerminal(terminal.else_, initial_location); } -void EmitX64::Patch(const IR::LocationDescriptor& desc, CodePtr bb) { +void A32EmitX64::Patch(const A32::LocationDescriptor& desc, CodePtr bb) { const CodePtr save_code_ptr = code->getCurr(); const PatchInformation& patch_info = patch_information[desc.UniqueHash()]; @@ -3548,33 +3549,33 @@ void EmitX64::Patch(const IR::LocationDescriptor& desc, CodePtr bb) { code->SetCodePtr(save_code_ptr); } -void EmitX64::Unpatch(const IR::LocationDescriptor& desc) { +void A32EmitX64::Unpatch(const A32::LocationDescriptor& desc) { Patch(desc, nullptr); } -void EmitX64::EmitPatchJg(const IR::LocationDescriptor& target_desc, CodePtr target_code_ptr) { +void A32EmitX64::EmitPatchJg(const A32::LocationDescriptor& target_desc, CodePtr target_code_ptr) { const CodePtr patch_location = code->getCurr(); if (target_code_ptr) { code->jg(target_code_ptr); } else { - code->mov(MJitStateReg(Arm::Reg::PC), target_desc.PC()); + code->mov(MJitStateReg(A32::Reg::PC), target_desc.PC()); code->jg(code->GetReturnFromRunCodeAddress()); } code->EnsurePatchLocationSize(patch_location, 14); } -void EmitX64::EmitPatchJmp(const IR::LocationDescriptor& target_desc, CodePtr target_code_ptr) { +void A32EmitX64::EmitPatchJmp(const A32::LocationDescriptor& target_desc, CodePtr target_code_ptr) { const CodePtr patch_location = code->getCurr(); if (target_code_ptr) { code->jmp(target_code_ptr); } else { - code->mov(MJitStateReg(Arm::Reg::PC), target_desc.PC()); + code->mov(MJitStateReg(A32::Reg::PC), target_desc.PC()); code->jmp(code->GetReturnFromRunCodeAddress()); } code->EnsurePatchLocationSize(patch_location, 13); } -void EmitX64::EmitPatchMovRcx(CodePtr target_code_ptr) { +void A32EmitX64::EmitPatchMovRcx(CodePtr target_code_ptr) { if (!target_code_ptr) { target_code_ptr = code->GetReturnFromRunCodeAddress(); } @@ -3583,12 +3584,12 @@ void EmitX64::EmitPatchMovRcx(CodePtr target_code_ptr) { code->EnsurePatchLocationSize(patch_location, 10); } -void EmitX64::ClearCache() { +void A32EmitX64::ClearCache() { block_descriptors.clear(); patch_information.clear(); } -void EmitX64::InvalidateCacheRanges(const boost::icl::interval_set& ranges) { +void A32EmitX64::InvalidateCacheRanges(const boost::icl::interval_set& ranges) { // Remove cached block descriptors and patch information overlapping with the given range. for (auto invalidate_interval : ranges) { auto pair = block_ranges.equal_range(invalidate_interval); diff --git a/src/backend_x64/emit_x64.h b/src/backend_x64/emit_x64.h index 6d7d4865..5654c3e2 100644 --- a/src/backend_x64/emit_x64.h +++ b/src/backend_x64/emit_x64.h @@ -18,7 +18,7 @@ #include "backend_x64/reg_alloc.h" #include "common/address_range.h" #include "dynarmic/callbacks.h" -#include "frontend/ir/location_descriptor.h" +#include "frontend/A32/location_descriptor.h" #include "frontend/ir/terminal.h" namespace Dynarmic { @@ -34,17 +34,17 @@ namespace BackendX64 { class BlockOfCode; -class EmitX64 final { +class A32EmitX64 final { public: struct BlockDescriptor { CodePtr entrypoint; // Entrypoint of emitted code size_t size; // Length in bytes of emitted code - IR::LocationDescriptor start_location; - u32 end_location_pc; + A32::LocationDescriptor start_location; + boost::icl::discrete_interval range; }; - EmitX64(BlockOfCode* code, UserCallbacks cb, Jit* jit_interface); + A32EmitX64(BlockOfCode* code, UserCallbacks cb, Jit* jit_interface); /** * Emit host machine code for a basic block with intermediate representation `ir`. @@ -53,7 +53,7 @@ public: BlockDescriptor Emit(IR::Block& ir); /// Looks up an emitted host block in the cache. - boost::optional GetBasicBlock(IR::LocationDescriptor descriptor) const; + boost::optional GetBasicBlock(A32::LocationDescriptor descriptor) const; /// Empties the entire cache. void ClearCache(); @@ -76,14 +76,14 @@ private: void PushRSBHelper(Xbyak::Reg64 loc_desc_reg, Xbyak::Reg64 index_reg, u64 target_hash); // Terminal instruction emitters - void EmitTerminal(IR::Terminal terminal, IR::LocationDescriptor initial_location); - void EmitTerminal(IR::Term::Interpret terminal, IR::LocationDescriptor initial_location); - void EmitTerminal(IR::Term::ReturnToDispatch terminal, IR::LocationDescriptor initial_location); - void EmitTerminal(IR::Term::LinkBlock terminal, IR::LocationDescriptor initial_location); - void EmitTerminal(IR::Term::LinkBlockFast terminal, IR::LocationDescriptor initial_location); - void EmitTerminal(IR::Term::PopRSBHint terminal, IR::LocationDescriptor initial_location); - void EmitTerminal(IR::Term::If terminal, IR::LocationDescriptor initial_location); - void EmitTerminal(IR::Term::CheckHalt terminal, IR::LocationDescriptor initial_location); + void EmitTerminal(IR::Terminal terminal, A32::LocationDescriptor initial_location); + void EmitTerminal(IR::Term::Interpret terminal, A32::LocationDescriptor initial_location); + void EmitTerminal(IR::Term::ReturnToDispatch terminal, A32::LocationDescriptor initial_location); + void EmitTerminal(IR::Term::LinkBlock terminal, A32::LocationDescriptor initial_location); + void EmitTerminal(IR::Term::LinkBlockFast terminal, A32::LocationDescriptor initial_location); + void EmitTerminal(IR::Term::PopRSBHint terminal, A32::LocationDescriptor initial_location); + void EmitTerminal(IR::Term::If terminal, A32::LocationDescriptor initial_location); + void EmitTerminal(IR::Term::CheckHalt terminal, A32::LocationDescriptor initial_location); // Patching struct PatchInformation { @@ -91,16 +91,16 @@ private: std::vector jmp; std::vector mov_rcx; }; - void Patch(const IR::LocationDescriptor& target_desc, CodePtr target_code_ptr); - void Unpatch(const IR::LocationDescriptor& target_desc); - void EmitPatchJg(const IR::LocationDescriptor& target_desc, CodePtr target_code_ptr = nullptr); - void EmitPatchJmp(const IR::LocationDescriptor& target_desc, CodePtr target_code_ptr = nullptr); + void Patch(const A32::LocationDescriptor& target_desc, CodePtr target_code_ptr); + void Unpatch(const A32::LocationDescriptor& target_desc); + void EmitPatchJg(const A32::LocationDescriptor& target_desc, CodePtr target_code_ptr = nullptr); + void EmitPatchJmp(const A32::LocationDescriptor& target_desc, CodePtr target_code_ptr = nullptr); void EmitPatchMovRcx(CodePtr target_code_ptr = nullptr); // State BlockOfCode* code; UserCallbacks cb; - boost::icl::interval_map> block_ranges; + boost::icl::interval_map> block_ranges; Jit* jit_interface; std::unordered_map block_descriptors; std::unordered_map patch_information; diff --git a/src/backend_x64/interface_x64.cpp b/src/backend_x64/interface_x64.cpp index 945391fe..50d63092 100644 --- a/src/backend_x64/interface_x64.cpp +++ b/src/backend_x64/interface_x64.cpp @@ -22,9 +22,9 @@ #include "common/scope_exit.h" #include "dynarmic/context.h" #include "dynarmic/dynarmic.h" +#include "frontend/A32/translate/translate.h" #include "frontend/ir/basic_block.h" #include "frontend/ir/location_descriptor.h" -#include "frontend/translate/translate.h" #include "ir_opt/passes.h" namespace Dynarmic { @@ -42,7 +42,7 @@ struct Jit::Impl { BlockOfCode block_of_code; JitState jit_state; - EmitX64 emitter; + A32EmitX64 emitter; const UserCallbacks callbacks; // Requests made during execution to invalidate the cache are queued up here. @@ -131,14 +131,14 @@ private: JitState& jit_state = this_.jit_state; u32 pc = jit_state.Reg[15]; - Arm::PSR cpsr{jit_state.Cpsr()}; - Arm::FPSCR fpscr{jit_state.FPSCR_mode}; - IR::LocationDescriptor descriptor{pc, cpsr, fpscr}; + A32::PSR cpsr{jit_state.Cpsr()}; + A32::FPSCR fpscr{jit_state.FPSCR_mode}; + A32::LocationDescriptor descriptor{pc, cpsr, fpscr}; return this_.GetBasicBlock(descriptor).entrypoint; } - EmitX64::BlockDescriptor GetBasicBlock(IR::LocationDescriptor descriptor) { + A32EmitX64::BlockDescriptor GetBasicBlock(IR::LocationDescriptor descriptor) { auto block = emitter.GetBasicBlock(descriptor); if (block) return *block; @@ -149,7 +149,7 @@ private: PerformCacheInvalidation(); } - IR::Block ir_block = Arm::Translate(descriptor, callbacks.memory.ReadCode); + IR::Block ir_block = A32::Translate(descriptor, callbacks.memory.ReadCode); Optimization::GetSetElimination(ir_block); Optimization::DeadCodeElimination(ir_block); Optimization::ConstantPropagation(ir_block, callbacks.memory); diff --git a/src/backend_x64/jitstate.cpp b/src/backend_x64/jitstate.cpp index b4b76223..f7ad6dfe 100644 --- a/src/backend_x64/jitstate.cpp +++ b/src/backend_x64/jitstate.cpp @@ -9,7 +9,7 @@ #include "common/assert.h" #include "common/bit_util.h" #include "common/common_types.h" -#include "frontend/ir/location_descriptor.h" +#include "frontend/A32/location_descriptor.h" namespace Dynarmic { namespace BackendX64 { @@ -150,7 +150,7 @@ void JitState::ResetRSB() { */ // NZCV; QC (ASMID only), AHP; DN, FZ, RMode, Stride; SBZP; Len; trap enables; cumulative bits -constexpr u32 FPSCR_MODE_MASK = IR::LocationDescriptor::FPSCR_MODE_MASK; +constexpr u32 FPSCR_MODE_MASK = A32::LocationDescriptor::FPSCR_MODE_MASK; constexpr u32 FPSCR_NZCV_MASK = 0xF0000000; u32 JitState::Fpscr() const { diff --git a/src/frontend/arm/FPSCR.h b/src/frontend/A32/FPSCR.h similarity index 99% rename from src/frontend/arm/FPSCR.h rename to src/frontend/A32/FPSCR.h index ac64cce7..9e6b2aa8 100644 --- a/src/frontend/arm/FPSCR.h +++ b/src/frontend/A32/FPSCR.h @@ -12,7 +12,7 @@ #include "common/common_types.h" namespace Dynarmic { -namespace Arm { +namespace A32 { /** * Representation of the Floating-Point Status and Control Register. @@ -195,5 +195,5 @@ inline bool operator!=(FPSCR lhs, FPSCR rhs) { return !operator==(lhs, rhs); } -} // namespace Arm +} // namespace A32 } // namespace Dynarmic diff --git a/src/frontend/arm/PSR.h b/src/frontend/A32/PSR.h similarity index 99% rename from src/frontend/arm/PSR.h rename to src/frontend/A32/PSR.h index 9f60f9a0..cb0860f0 100644 --- a/src/frontend/arm/PSR.h +++ b/src/frontend/A32/PSR.h @@ -10,7 +10,7 @@ #include "common/common_types.h" namespace Dynarmic { -namespace Arm { +namespace A32 { /** * Program Status Register @@ -221,5 +221,5 @@ inline bool operator!=(PSR lhs, PSR rhs) { return !operator==(lhs, rhs); } -} // namespace Arm +} // namespace A32 } // namespace Dynarmic diff --git a/src/frontend/decoder/arm.h b/src/frontend/A32/decoder/arm.h similarity index 99% rename from src/frontend/decoder/arm.h rename to src/frontend/A32/decoder/arm.h index cc9ce8bc..31ad8824 100644 --- a/src/frontend/decoder/arm.h +++ b/src/frontend/A32/decoder/arm.h @@ -20,16 +20,16 @@ #include "frontend/decoder/matcher.h" namespace Dynarmic { -namespace Arm { +namespace A32 { template -using ArmMatcher = Matcher; +using ArmMatcher = Decoder::Matcher; template std::vector> GetArmDecodeTable() { std::vector> table = { -#define INST(fn, name, bitstring) detail::detail>::GetMatcher(fn, name, bitstring) +#define INST(fn, name, bitstring) Decoder::detail::detail>::GetMatcher(fn, name, bitstring) // Branch instructions INST(&V::arm_BLX_imm, "BLX (imm)", "1111101hvvvvvvvvvvvvvvvvvvvvvvvv"), // v5 @@ -330,5 +330,5 @@ boost::optional&> DecodeArm(u32 instruction) { return iter != table.end() ? boost::optional&>(*iter) : boost::none; } -} // namespace Arm +} // namespace A32 } // namespace Dynarmic diff --git a/src/frontend/decoder/thumb16.h b/src/frontend/A32/decoder/thumb16.h similarity index 97% rename from src/frontend/decoder/thumb16.h rename to src/frontend/A32/decoder/thumb16.h index 4a745ffb..bd413d80 100644 --- a/src/frontend/decoder/thumb16.h +++ b/src/frontend/A32/decoder/thumb16.h @@ -15,16 +15,16 @@ #include "frontend/decoder/matcher.h" namespace Dynarmic { -namespace Arm { +namespace A32 { template -using Thumb16Matcher = Matcher; +using Thumb16Matcher = Decoder::Matcher; template boost::optional&> DecodeThumb16(u16 instruction) { static const std::vector> table = { -#define INST(fn, name, bitstring) detail::detail>::GetMatcher(fn, name, bitstring) +#define INST(fn, name, bitstring) Decoder::detail::detail>::GetMatcher(fn, name, bitstring) // Shift (immediate), add, subtract, move and compare instructions INST(&V::thumb16_LSL_imm, "LSL (imm)", "00000vvvvvmmmddd"), @@ -123,5 +123,5 @@ boost::optional&> DecodeThumb16(u16 instruction) { return iter != table.end() ? boost::optional&>(*iter) : boost::none; } -} // namespace Arm +} // namespace A32 } // namespace Dynarmic diff --git a/src/frontend/decoder/thumb32.h b/src/frontend/A32/decoder/thumb32.h similarity index 87% rename from src/frontend/decoder/thumb32.h rename to src/frontend/A32/decoder/thumb32.h index 23e99c85..b4913de2 100644 --- a/src/frontend/decoder/thumb32.h +++ b/src/frontend/A32/decoder/thumb32.h @@ -15,16 +15,16 @@ #include "frontend/decoder/matcher.h" namespace Dynarmic { -namespace Arm { +namespace A32 { template -using Thumb32Matcher = Matcher; +using Thumb32Matcher = Decoder::Matcher; template boost::optional&> DecodeThumb32(u32 instruction) { static const std::vector> table = { -#define INST(fn, name, bitstring) detail::detail>::GetMatcher(fn, name, bitstring) +#define INST(fn, name, bitstring) Decoder::detail::detail>::GetMatcher(fn, name, bitstring) // Branch instructions INST(&V::thumb32_BL_imm, "BL (imm)", "11110vvvvvvvvvvv11111vvvvvvvvvvv"), // v4T @@ -43,5 +43,5 @@ boost::optional&> DecodeThumb32(u32 instruction) { return iter != table.end() ? boost::optional&>(*iter) : boost::none; } -} // namespace Arm +} // namespace A32 } // namespace Dynarmic diff --git a/src/frontend/decoder/vfp2.h b/src/frontend/A32/decoder/vfp2.h similarity index 96% rename from src/frontend/decoder/vfp2.h rename to src/frontend/A32/decoder/vfp2.h index d09d9dd4..285f7f3b 100644 --- a/src/frontend/decoder/vfp2.h +++ b/src/frontend/A32/decoder/vfp2.h @@ -15,16 +15,16 @@ #include "frontend/decoder/matcher.h" namespace Dynarmic { -namespace Arm { +namespace A32 { template -using VFP2Matcher = Matcher; +using VFP2Matcher = Decoder::Matcher; template boost::optional&> DecodeVFP2(u32 instruction) { static const std::vector> table = { -#define INST(fn, name, bitstring) detail::detail>::GetMatcher(fn, name, bitstring) +#define INST(fn, name, bitstring) Decoder::detail::detail>::GetMatcher(fn, name, bitstring) // cccc1110________----101-__-0---- @@ -88,5 +88,5 @@ boost::optional&> DecodeVFP2(u32 instruction) { return iter != table.end() ? boost::optional&>(*iter) : boost::none; } -} // namespace Arm +} // namespace A32 } // namespace Dynarmic diff --git a/src/frontend/disassembler/disassembler.h b/src/frontend/A32/disassembler/disassembler.h similarity index 92% rename from src/frontend/disassembler/disassembler.h rename to src/frontend/A32/disassembler/disassembler.h index fce1a6b4..dc7e7149 100644 --- a/src/frontend/disassembler/disassembler.h +++ b/src/frontend/A32/disassembler/disassembler.h @@ -11,10 +11,10 @@ #include "common/common_types.h" namespace Dynarmic { -namespace Arm { +namespace A32 { std::string DisassembleArm(u32 instruction); std::string DisassembleThumb16(u16 instruction); -} // namespace Arm +} // namespace A32 } // namespace Dynarmic diff --git a/src/frontend/disassembler/disassembler_arm.cpp b/src/frontend/A32/disassembler/disassembler_arm.cpp similarity index 99% rename from src/frontend/disassembler/disassembler_arm.cpp rename to src/frontend/A32/disassembler/disassembler_arm.cpp index 636e10be..9d2951c9 100644 --- a/src/frontend/disassembler/disassembler_arm.cpp +++ b/src/frontend/A32/disassembler/disassembler_arm.cpp @@ -12,13 +12,13 @@ #include "common/bit_util.h" #include "common/string_util.h" -#include "frontend/arm/types.h" -#include "frontend/decoder/arm.h" -#include "frontend/decoder/vfp2.h" -#include "frontend/disassembler/disassembler.h" +#include "frontend/A32/decoder/arm.h" +#include "frontend/A32/decoder/vfp2.h" +#include "frontend/A32/disassembler/disassembler.h" +#include "frontend/A32/types.h" namespace Dynarmic { -namespace Arm { +namespace A32 { class DisassemblerVisitor { public: @@ -1079,5 +1079,5 @@ std::string DisassembleArm(u32 instruction) { } } -} // namespace Arm +} // namespace A32 } // namespace Dynarmic diff --git a/src/frontend/disassembler/disassembler_thumb.cpp b/src/frontend/A32/disassembler/disassembler_thumb.cpp similarity index 98% rename from src/frontend/disassembler/disassembler_thumb.cpp rename to src/frontend/A32/disassembler/disassembler_thumb.cpp index 769a06ee..83c4678a 100644 --- a/src/frontend/disassembler/disassembler_thumb.cpp +++ b/src/frontend/A32/disassembler/disassembler_thumb.cpp @@ -12,12 +12,12 @@ #include "common/bit_util.h" #include "common/string_util.h" -#include "frontend/arm/types.h" -#include "frontend/decoder/thumb16.h" -#include "frontend/disassembler/disassembler.h" +#include "frontend/A32/decoder/thumb16.h" +#include "frontend/A32/disassembler/disassembler.h" +#include "frontend/A32/types.h" namespace Dynarmic { -namespace Arm { +namespace A32 { class DisassemblerVisitor { public: @@ -332,5 +332,5 @@ std::string DisassembleThumb16(u16 instruction) { return !decoder ? fmt::format("UNKNOWN: {:x}", instruction) : decoder->call(visitor, instruction); } -} // namespace Arm +} // namespace A32 } // namespace Dynarmic diff --git a/src/frontend/A32/location_descriptor.cpp b/src/frontend/A32/location_descriptor.cpp new file mode 100644 index 00000000..ae459474 --- /dev/null +++ b/src/frontend/A32/location_descriptor.cpp @@ -0,0 +1,24 @@ +/* This file is part of the dynarmic project. + * Copyright (c) 2016 MerryMage + * This software may be used and distributed according to the terms of the GNU + * General Public License version 2 or any later version. + */ + +#include +#include +#include "frontend/A32/location_descriptor.h" + +namespace Dynarmic { +namespace A32 { + +std::ostream& operator<<(std::ostream& o, const LocationDescriptor& loc) { + o << fmt::format("{{{},{},{},{}}}", + loc.PC(), + loc.TFlag() ? "T" : "!T", + loc.EFlag() ? "E" : "!E", + loc.FPSCR().Value()); + return o; +} + +} // namespace A32 +} // namespace Dynarmic diff --git a/src/frontend/A32/location_descriptor.h b/src/frontend/A32/location_descriptor.h new file mode 100644 index 00000000..51cdccd1 --- /dev/null +++ b/src/frontend/A32/location_descriptor.h @@ -0,0 +1,127 @@ +/* This file is part of the dynarmic project. + * Copyright (c) 2016 MerryMage + * This software may be used and distributed according to the terms of the GNU + * General Public License version 2 or any later version. + */ + +#pragma once + +#include +#include +#include +#include "common/common_types.h" +#include "frontend/A32/FPSCR.h" +#include "frontend/A32/PSR.h" +#include "frontend/ir/location_descriptor.h" + +namespace Dynarmic { +namespace A32 { + +/** + * LocationDescriptor describes the location of a basic block. + * The location is not solely based on the PC because other flags influence the way + * instructions should be translated. The CPSR.T flag is most notable since it + * tells us if the processor is in Thumb or Arm mode. + */ +class LocationDescriptor { +public: + // Indicates bits that should be preserved within descriptors. + static constexpr u32 CPSR_MODE_MASK = 0x00000220; + static constexpr u32 FPSCR_MODE_MASK = 0x03F79F00; + + LocationDescriptor(u32 arm_pc, PSR cpsr, FPSCR fpscr) + : arm_pc(arm_pc), cpsr(cpsr.Value() & CPSR_MODE_MASK), fpscr(fpscr.Value() & FPSCR_MODE_MASK) {} + + /*implict*/ LocationDescriptor(const IR::LocationDescriptor& o) { + arm_pc = o.value >> 32; + cpsr.T(o.value & 1); + cpsr.E(o.value & 2); + fpscr = o.value & FPSCR_MODE_MASK; + } + + u32 PC() const { return arm_pc; } + bool TFlag() const { return cpsr.T(); } + bool EFlag() const { return cpsr.E(); } + + PSR CPSR() const { return cpsr; } + FPSCR FPSCR() const { return fpscr; } + + bool operator == (const LocationDescriptor& o) const { + return std::tie(arm_pc, cpsr, fpscr) == std::tie(o.arm_pc, o.cpsr, o.fpscr); + } + + bool operator != (const LocationDescriptor& o) const { + return !operator==(o); + } + + LocationDescriptor SetPC(u32 new_arm_pc) const { + return LocationDescriptor(new_arm_pc, cpsr, fpscr); + } + + LocationDescriptor AdvancePC(int amount) const { + return LocationDescriptor(static_cast(arm_pc + amount), cpsr, fpscr); + } + + LocationDescriptor SetTFlag(bool new_tflag) const { + PSR new_cpsr = cpsr; + new_cpsr.T(new_tflag); + + return LocationDescriptor(arm_pc, new_cpsr, fpscr); + } + + LocationDescriptor SetEFlag(bool new_eflag) const { + PSR new_cpsr = cpsr; + new_cpsr.E(new_eflag); + + return LocationDescriptor(arm_pc, new_cpsr, fpscr); + } + + LocationDescriptor SetFPSCR(u32 new_fpscr) const { + return LocationDescriptor(arm_pc, cpsr, A32::FPSCR{new_fpscr & FPSCR_MODE_MASK}); + } + + u64 UniqueHash() const { + // This value MUST BE UNIQUE. + // This calculation has to match up with EmitX64::EmitTerminalPopRSBHint + u64 pc_u64 = u64(arm_pc) << 32; + u64 fpscr_u64 = u64(fpscr.Value()); + u64 t_u64 = cpsr.T() ? 1 : 0; + u64 e_u64 = cpsr.E() ? 2 : 0; + return pc_u64 | fpscr_u64 | t_u64 | e_u64; + } + + operator IR::LocationDescriptor() const { + return IR::LocationDescriptor{UniqueHash()}; + } + +private: + u32 arm_pc; ///< Current program counter value. + PSR cpsr; ///< Current program status register. + A32::FPSCR fpscr; ///< Floating point status control register. +}; + +/** + * Provides a string representation of a LocationDescriptor. + * + * @param o Output stream + * @param descriptor The descriptor to get a string representation of + */ +std::ostream& operator<<(std::ostream& o, const LocationDescriptor& descriptor); + +} // namespace A32 +} // namespace Dynarmic + +namespace std { +template <> +struct less { + bool operator()(const Dynarmic::A32::LocationDescriptor& x, const Dynarmic::A32::LocationDescriptor& y) const { + return x.UniqueHash() < y.UniqueHash(); + } +}; +template <> +struct hash { + size_t operator()(const Dynarmic::A32::LocationDescriptor& x) const { + return std::hash()(x.UniqueHash()); + } +}; +} // namespace std diff --git a/src/frontend/A32/translate/translate.cpp b/src/frontend/A32/translate/translate.cpp new file mode 100644 index 00000000..de47b6f1 --- /dev/null +++ b/src/frontend/A32/translate/translate.cpp @@ -0,0 +1,22 @@ +/* This file is part of the dynarmic project. + * Copyright (c) 2016 MerryMage + * This software may be used and distributed according to the terms of the GNU + * General Public License version 2 or any later version. + */ + +#include "frontend/A32/location_descriptor.h" +#include "frontend/A32/translate/translate.h" +#include "frontend/ir/basic_block.h" + +namespace Dynarmic { +namespace A32 { + +IR::Block TranslateArm(LocationDescriptor descriptor, MemoryReadCodeFuncType memory_read_code); +IR::Block TranslateThumb(LocationDescriptor descriptor, MemoryReadCodeFuncType memory_read_code); + +IR::Block Translate(LocationDescriptor descriptor, MemoryReadCodeFuncType memory_read_code) { + return (descriptor.TFlag() ? TranslateThumb : TranslateArm)(descriptor, memory_read_code); +} + +} // namespace A32 +} // namespace Dynarmic diff --git a/src/frontend/translate/translate.h b/src/frontend/A32/translate/translate.h similarity index 83% rename from src/frontend/translate/translate.h rename to src/frontend/A32/translate/translate.h index 816d46fe..255d491a 100644 --- a/src/frontend/translate/translate.h +++ b/src/frontend/A32/translate/translate.h @@ -11,12 +11,11 @@ namespace Dynarmic { namespace IR { class Block; -class LocationDescriptor; } // namespace IR -namespace Arm { +namespace A32 { -struct LocationDescriptor; +class LocationDescriptor; using MemoryReadCodeFuncType = u32 (*)(u32 vaddr); @@ -26,7 +25,7 @@ using MemoryReadCodeFuncType = u32 (*)(u32 vaddr); * @param memory_read_code The function we should use to read emulated memory. * @return A translated basic block in the intermediate representation. */ -IR::Block Translate(IR::LocationDescriptor descriptor, MemoryReadCodeFuncType memory_read_code); +IR::Block Translate(LocationDescriptor descriptor, MemoryReadCodeFuncType memory_read_code); -} // namespace Arm +} // namespace A32 } // namespace Dynarmic diff --git a/src/frontend/translate/translate_arm.cpp b/src/frontend/A32/translate/translate_arm.cpp similarity index 85% rename from src/frontend/translate/translate_arm.cpp rename to src/frontend/A32/translate/translate_arm.cpp index 1902c954..86c004d3 100644 --- a/src/frontend/translate/translate_arm.cpp +++ b/src/frontend/A32/translate/translate_arm.cpp @@ -7,18 +7,18 @@ #include #include "common/assert.h" -#include "frontend/arm/types.h" -#include "frontend/decoder/arm.h" -#include "frontend/decoder/vfp2.h" +#include "frontend/A32/decoder/arm.h" +#include "frontend/A32/decoder/vfp2.h" +#include "frontend/A32/translate/translate.h" +#include "frontend/A32/translate/translate_arm/translate_arm.h" +#include "frontend/A32/types.h" #include "frontend/ir/basic_block.h" #include "frontend/ir/location_descriptor.h" -#include "frontend/translate/translate.h" -#include "frontend/translate/translate_arm/translate_arm.h" namespace Dynarmic { -namespace Arm { +namespace A32 { -static bool CondCanContinue(ConditionalState cond_state, const IR::IREmitter& ir) { +static bool CondCanContinue(ConditionalState cond_state, const IR::A32IREmitter& ir) { ASSERT_MSG(cond_state != ConditionalState::Break, "Should never happen."); if (cond_state == ConditionalState::None) @@ -28,7 +28,7 @@ static bool CondCanContinue(ConditionalState cond_state, const IR::IREmitter& ir return std::all_of(ir.block.begin(), ir.block.end(), [](const IR::Inst& inst) { return !inst.WritesToCPSR(); }); } -IR::Block TranslateArm(IR::LocationDescriptor descriptor, MemoryReadCodeFuncType memory_read_code) { +IR::Block TranslateArm(LocationDescriptor descriptor, MemoryReadCodeFuncType memory_read_code) { ArmTranslatorVisitor visitor{descriptor}; bool should_continue = true; @@ -75,7 +75,7 @@ bool ArmTranslatorVisitor::ConditionPassed(Cond cond) { cond_state = ConditionalState::Trailing; } else { if (cond == ir.block.GetCondition()) { - ir.block.SetConditionFailedLocation({ ir.current_location.AdvancePC(4) }); + ir.block.SetConditionFailedLocation(ir.current_location.AdvancePC(4)); ir.block.ConditionFailedCycleCount()++; return true; } @@ -106,7 +106,7 @@ bool ArmTranslatorVisitor::ConditionPassed(Cond cond) { cond_state = ConditionalState::Translating; ir.block.SetCondition(cond); - ir.block.SetConditionFailedLocation({ ir.current_location.AdvancePC(4) }); + ir.block.SetConditionFailedLocation(ir.current_location.AdvancePC(4)); ir.block.ConditionFailedCycleCount() = 1; return true; } @@ -121,7 +121,7 @@ bool ArmTranslatorVisitor::UnpredictableInstruction() { return false; } -IR::IREmitter::ResultAndCarry ArmTranslatorVisitor::EmitImmShift(IR::Value value, ShiftType type, Imm5 imm5, IR::Value carry_in) { +IR::A32IREmitter::ResultAndCarry ArmTranslatorVisitor::EmitImmShift(IR::Value value, ShiftType type, Imm5 imm5, IR::Value carry_in) { switch (type) { case ShiftType::LSL: return ir.LogicalShiftLeft(value, ir.Imm8(imm5), carry_in); @@ -141,7 +141,7 @@ IR::IREmitter::ResultAndCarry ArmTranslatorVisitor::EmitImmShift(IR::Value value return {}; } -IR::IREmitter::ResultAndCarry ArmTranslatorVisitor::EmitRegShift(IR::Value value, ShiftType type, IR::Value amount, IR::Value carry_in) { +IR::A32IREmitter::ResultAndCarry ArmTranslatorVisitor::EmitRegShift(IR::Value value, ShiftType type, IR::Value amount, IR::Value carry_in) { switch (type) { case ShiftType::LSL: return ir.LogicalShiftLeft(value, amount, carry_in); @@ -156,5 +156,5 @@ IR::IREmitter::ResultAndCarry ArmTranslatorVisitor::EmitRegShift(IR::Value value return {}; } -} // namespace Arm +} // namespace A32 } // namespace Dynarmic diff --git a/src/frontend/translate/translate_arm/branch.cpp b/src/frontend/A32/translate/translate_arm/branch.cpp similarity index 98% rename from src/frontend/translate/translate_arm/branch.cpp rename to src/frontend/A32/translate/translate_arm/branch.cpp index 8a5066fc..0d75dcd5 100644 --- a/src/frontend/translate/translate_arm/branch.cpp +++ b/src/frontend/A32/translate/translate_arm/branch.cpp @@ -9,7 +9,7 @@ #include "translate_arm.h" namespace Dynarmic { -namespace Arm { +namespace A32 { bool ArmTranslatorVisitor::arm_B(Cond cond, Imm24 imm24) { u32 imm32 = Common::SignExtend<26, u32>(imm24 << 2) + 8; @@ -77,5 +77,5 @@ bool ArmTranslatorVisitor::arm_BXJ(Cond cond, Reg m) { return arm_BX(cond, m); } -} // namespace Arm +} // namespace A32 } // namespace Dynarmic diff --git a/src/frontend/translate/translate_arm/coprocessor.cpp b/src/frontend/A32/translate/translate_arm/coprocessor.cpp similarity index 99% rename from src/frontend/translate/translate_arm/coprocessor.cpp rename to src/frontend/A32/translate/translate_arm/coprocessor.cpp index 5f5e7a09..10ce4340 100644 --- a/src/frontend/translate/translate_arm/coprocessor.cpp +++ b/src/frontend/A32/translate/translate_arm/coprocessor.cpp @@ -7,7 +7,7 @@ #include "translate_arm.h" namespace Dynarmic { -namespace Arm { +namespace A32 { bool ArmTranslatorVisitor::arm_CDP(Cond cond, size_t opc1, CoprocReg CRn, CoprocReg CRd, size_t coproc_no, size_t opc2, CoprocReg CRm) { if ((coproc_no & 0b1110) == 0b1010) @@ -146,5 +146,5 @@ bool ArmTranslatorVisitor::arm_STC(Cond cond, bool p, bool u, bool d, bool w, Re return true; } -} // namespace Arm +} // namespace A32 } // namespace Dynarmic diff --git a/src/frontend/translate/translate_arm/data_processing.cpp b/src/frontend/A32/translate/translate_arm/data_processing.cpp similarity index 99% rename from src/frontend/translate/translate_arm/data_processing.cpp rename to src/frontend/A32/translate/translate_arm/data_processing.cpp index 3fd57847..bf14f2cb 100644 --- a/src/frontend/translate/translate_arm/data_processing.cpp +++ b/src/frontend/A32/translate/translate_arm/data_processing.cpp @@ -7,7 +7,7 @@ #include "translate_arm.h" namespace Dynarmic { -namespace Arm { +namespace A32 { bool ArmTranslatorVisitor::arm_ADC_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm8 imm8) { // ADC{S} , , # @@ -889,5 +889,5 @@ bool ArmTranslatorVisitor::arm_TST_rsr(Cond cond, Reg n, Reg s, ShiftType shift, return true; } -} // namespace Arm +} // namespace A32 } // namespace Dynarmic diff --git a/src/frontend/translate/translate_arm/exception_generating.cpp b/src/frontend/A32/translate/translate_arm/exception_generating.cpp similarity index 96% rename from src/frontend/translate/translate_arm/exception_generating.cpp rename to src/frontend/A32/translate/translate_arm/exception_generating.cpp index 4180325d..31d69dac 100644 --- a/src/frontend/translate/translate_arm/exception_generating.cpp +++ b/src/frontend/A32/translate/translate_arm/exception_generating.cpp @@ -7,7 +7,7 @@ #include "translate_arm.h" namespace Dynarmic { -namespace Arm { +namespace A32 { bool ArmTranslatorVisitor::arm_BKPT(Cond /*cond*/, Imm12 /*imm12*/, Imm4 /*imm4*/) { return InterpretThisInstruction(); @@ -30,5 +30,5 @@ bool ArmTranslatorVisitor::arm_UDF() { return InterpretThisInstruction(); } -} // namespace Arm +} // namespace A32 } // namespace Dynarmic diff --git a/src/frontend/translate/translate_arm/extension.cpp b/src/frontend/A32/translate/translate_arm/extension.cpp similarity index 98% rename from src/frontend/translate/translate_arm/extension.cpp rename to src/frontend/A32/translate/translate_arm/extension.cpp index 03009ec0..2fb2623c 100644 --- a/src/frontend/translate/translate_arm/extension.cpp +++ b/src/frontend/A32/translate/translate_arm/extension.cpp @@ -7,9 +7,9 @@ #include "translate_arm.h" namespace Dynarmic { -namespace Arm { +namespace A32 { -static IR::Value Rotate(IR::IREmitter& ir, Reg m, SignExtendRotation rotate) { +static IR::Value Rotate(IR::A32IREmitter& ir, Reg m, SignExtendRotation rotate) { const u8 rotate_by = static_cast(static_cast(rotate) * 8); return ir.RotateRight(ir.GetRegister(m), ir.Imm8(rotate_by), ir.Imm1(0)).result; } @@ -181,5 +181,5 @@ bool ArmTranslatorVisitor::arm_UXTH(Cond cond, Reg d, SignExtendRotation rotate, return true; } -} // namespace Arm +} // namespace A32 } // namespace Dynarmic diff --git a/src/frontend/translate/translate_arm/load_store.cpp b/src/frontend/A32/translate/translate_arm/load_store.cpp similarity index 98% rename from src/frontend/translate/translate_arm/load_store.cpp rename to src/frontend/A32/translate/translate_arm/load_store.cpp index df3f1164..3832f37d 100644 --- a/src/frontend/translate/translate_arm/load_store.cpp +++ b/src/frontend/A32/translate/translate_arm/load_store.cpp @@ -7,7 +7,7 @@ #include "translate_arm.h" namespace Dynarmic { -namespace Arm { +namespace A32 { bool ArmTranslatorVisitor::arm_LDRBT() { ASSERT_MSG(false, "System instructions unimplemented"); @@ -41,7 +41,7 @@ bool ArmTranslatorVisitor::arm_STRT() { ASSERT_MSG(false, "System instructions unimplemented"); } -static IR::Value GetAddress(IR::IREmitter& ir, bool P, bool U, bool W, Reg n, IR::Value offset) { +static IR::Value GetAddress(IR::A32IREmitter& ir, bool P, bool U, bool W, Reg n, IR::Value offset) { const bool index = P; const bool add = U; const bool wback = !P || W; @@ -608,7 +608,7 @@ bool ArmTranslatorVisitor::arm_STRH_reg(Cond cond, bool P, bool U, bool W, Reg n return true; } -static bool LDMHelper(IR::IREmitter& ir, bool W, Reg n, RegList list, IR::Value start_address, IR::Value writeback_address) { +static bool LDMHelper(IR::A32IREmitter& ir, bool W, Reg n, RegList list, IR::Value start_address, IR::Value writeback_address) { auto address = start_address; for (size_t i = 0; i <= 14; i++) { if (Common::Bit(i, list)) { @@ -686,7 +686,7 @@ bool ArmTranslatorVisitor::arm_LDM_eret() { return InterpretThisInstruction(); } -static bool STMHelper(IR::IREmitter& ir, bool W, Reg n, RegList list, IR::Value start_address, IR::Value writeback_address) { +static bool STMHelper(IR::A32IREmitter& ir, bool W, Reg n, RegList list, IR::Value start_address, IR::Value writeback_address) { auto address = start_address; for (size_t i = 0; i <= 14; i++) { if (Common::Bit(i, list)) { @@ -755,5 +755,5 @@ bool ArmTranslatorVisitor::arm_STM_usr() { return InterpretThisInstruction(); } -} // namespace Arm +} // namespace A32 } // namespace Dynarmic diff --git a/src/frontend/translate/translate_arm/misc.cpp b/src/frontend/A32/translate/translate_arm/misc.cpp similarity index 96% rename from src/frontend/translate/translate_arm/misc.cpp rename to src/frontend/A32/translate/translate_arm/misc.cpp index 700565ee..5f3c8ab7 100644 --- a/src/frontend/translate/translate_arm/misc.cpp +++ b/src/frontend/A32/translate/translate_arm/misc.cpp @@ -7,7 +7,7 @@ #include "translate_arm.h" namespace Dynarmic { -namespace Arm { +namespace A32 { bool ArmTranslatorVisitor::arm_CLZ(Cond cond, Reg d, Reg m) { if (d == Reg::PC || m == Reg::PC) @@ -32,5 +32,5 @@ bool ArmTranslatorVisitor::arm_SEL(Cond cond, Reg n, Reg d, Reg m) { return true; } -} // namespace Arm +} // namespace A32 } // namespace Dynarmic diff --git a/src/frontend/translate/translate_arm/multiply.cpp b/src/frontend/A32/translate/translate_arm/multiply.cpp similarity index 99% rename from src/frontend/translate/translate_arm/multiply.cpp rename to src/frontend/A32/translate/translate_arm/multiply.cpp index 3e56b6c8..34e34e63 100644 --- a/src/frontend/translate/translate_arm/multiply.cpp +++ b/src/frontend/A32/translate/translate_arm/multiply.cpp @@ -7,7 +7,7 @@ #include "translate_arm.h" namespace Dynarmic { -namespace Arm { +namespace A32 { // Multiply (Normal) instructions bool ArmTranslatorVisitor::arm_MLA(Cond cond, bool S, Reg d, Reg a, Reg m, Reg n) { @@ -430,5 +430,5 @@ bool ArmTranslatorVisitor::arm_SMUSD(Cond cond, Reg d, Reg m, bool M, Reg n) { return true; } -} // namespace Arm +} // namespace A32 } // namespace Dynarmic diff --git a/src/frontend/translate/translate_arm/packing.cpp b/src/frontend/A32/translate/translate_arm/packing.cpp similarity index 97% rename from src/frontend/translate/translate_arm/packing.cpp rename to src/frontend/A32/translate/translate_arm/packing.cpp index 8c48c6ec..7062044a 100644 --- a/src/frontend/translate/translate_arm/packing.cpp +++ b/src/frontend/A32/translate/translate_arm/packing.cpp @@ -7,7 +7,7 @@ #include "translate_arm.h" namespace Dynarmic { -namespace Arm { +namespace A32 { bool ArmTranslatorVisitor::arm_PKHBT(Cond cond, Reg n, Reg d, Imm5 imm5, Reg m) { if (n == Reg::PC || d == Reg::PC || m == Reg::PC) @@ -37,5 +37,5 @@ bool ArmTranslatorVisitor::arm_PKHTB(Cond cond, Reg n, Reg d, Imm5 imm5, Reg m) return true; } -} // namespace Arm +} // namespace A32 } // namespace Dynarmic diff --git a/src/frontend/translate/translate_arm/parallel.cpp b/src/frontend/A32/translate/translate_arm/parallel.cpp similarity index 99% rename from src/frontend/translate/translate_arm/parallel.cpp rename to src/frontend/A32/translate/translate_arm/parallel.cpp index 9fb5b781..bbba20dc 100644 --- a/src/frontend/translate/translate_arm/parallel.cpp +++ b/src/frontend/A32/translate/translate_arm/parallel.cpp @@ -7,7 +7,7 @@ #include "translate_arm.h" namespace Dynarmic { -namespace Arm { +namespace A32 { // Parallel Add/Subtract (Modulo arithmetic) instructions bool ArmTranslatorVisitor::arm_SADD8(Cond cond, Reg n, Reg d, Reg m) { @@ -365,5 +365,5 @@ bool ArmTranslatorVisitor::arm_UHSUB16(Cond cond, Reg n, Reg d, Reg m) { return true; } -} // namespace Arm +} // namespace A32 } // namespace Dynarmic diff --git a/src/frontend/translate/translate_arm/reversal.cpp b/src/frontend/A32/translate/translate_arm/reversal.cpp similarity index 97% rename from src/frontend/translate/translate_arm/reversal.cpp rename to src/frontend/A32/translate/translate_arm/reversal.cpp index d24d5614..75fe15c7 100644 --- a/src/frontend/translate/translate_arm/reversal.cpp +++ b/src/frontend/A32/translate/translate_arm/reversal.cpp @@ -7,7 +7,7 @@ #include "translate_arm.h" namespace Dynarmic { -namespace Arm { +namespace A32 { bool ArmTranslatorVisitor::arm_REV(Cond cond, Reg d, Reg m) { // REV , @@ -47,5 +47,5 @@ bool ArmTranslatorVisitor::arm_REVSH(Cond cond, Reg d, Reg m) { return true; } -} // namespace Arm +} // namespace A32 } // namespace Dynarmic diff --git a/src/frontend/translate/translate_arm/saturated.cpp b/src/frontend/A32/translate/translate_arm/saturated.cpp similarity index 97% rename from src/frontend/translate/translate_arm/saturated.cpp rename to src/frontend/A32/translate/translate_arm/saturated.cpp index b0efcae0..bc5b8a18 100644 --- a/src/frontend/translate/translate_arm/saturated.cpp +++ b/src/frontend/A32/translate/translate_arm/saturated.cpp @@ -7,13 +7,13 @@ #include "translate_arm.h" namespace Dynarmic { -namespace Arm { +namespace A32 { -static IR::Value Pack2x16To1x32(IR::IREmitter& ir, IR::Value lo, IR::Value hi) { +static IR::Value Pack2x16To1x32(IR::A32IREmitter& ir, IR::Value lo, IR::Value hi) { return ir.Or(ir.And(lo, ir.Imm32(0xFFFF)), ir.LogicalShiftLeft(hi, ir.Imm8(16), ir.Imm1(0)).result); } -static IR::Value MostSignificantHalf(IR::IREmitter& ir, IR::Value value) { +static IR::Value MostSignificantHalf(IR::A32IREmitter& ir, IR::Value value) { return ir.LeastSignificantHalf(ir.LogicalShiftRight(value, ir.Imm8(16), ir.Imm1(0)).result); } @@ -240,5 +240,5 @@ bool ArmTranslatorVisitor::arm_UQSAX(Cond cond, Reg n, Reg d, Reg m) { return true; } -} // namespace Arm +} // namespace A32 } // namespace Dynarmic diff --git a/src/frontend/translate/translate_arm/status_register_access.cpp b/src/frontend/A32/translate/translate_arm/status_register_access.cpp similarity index 98% rename from src/frontend/translate/translate_arm/status_register_access.cpp rename to src/frontend/A32/translate/translate_arm/status_register_access.cpp index 327b31c5..b001bf14 100644 --- a/src/frontend/translate/translate_arm/status_register_access.cpp +++ b/src/frontend/A32/translate/translate_arm/status_register_access.cpp @@ -9,7 +9,7 @@ #include "common/bit_util.h" namespace Dynarmic { -namespace Arm { +namespace A32 { bool ArmTranslatorVisitor::arm_CPS() { return InterpretThisInstruction(); @@ -76,5 +76,5 @@ bool ArmTranslatorVisitor::arm_SRS() { return InterpretThisInstruction(); } -} // namespace Arm +} // namespace A32 } // namespace Dynarmic diff --git a/src/frontend/translate/translate_arm/synchronization.cpp b/src/frontend/A32/translate/translate_arm/synchronization.cpp similarity index 99% rename from src/frontend/translate/translate_arm/synchronization.cpp rename to src/frontend/A32/translate/translate_arm/synchronization.cpp index 40f9efc3..556211dc 100644 --- a/src/frontend/translate/translate_arm/synchronization.cpp +++ b/src/frontend/A32/translate/translate_arm/synchronization.cpp @@ -7,7 +7,7 @@ #include "translate_arm.h" namespace Dynarmic { -namespace Arm { +namespace A32 { bool ArmTranslatorVisitor::arm_CLREX() { // CLREX @@ -158,5 +158,5 @@ bool ArmTranslatorVisitor::arm_SWPB(Cond cond, Reg n, Reg t, Reg t2) { } -} // namespace Arm +} // namespace A32 } // namespace Dynarmic diff --git a/src/frontend/translate/translate_arm/translate_arm.h b/src/frontend/A32/translate/translate_arm/translate_arm.h similarity index 98% rename from src/frontend/translate/translate_arm/translate_arm.h rename to src/frontend/A32/translate/translate_arm/translate_arm.h index a60eae4d..78f63bc7 100644 --- a/src/frontend/translate/translate_arm/translate_arm.h +++ b/src/frontend/A32/translate/translate_arm/translate_arm.h @@ -10,7 +10,7 @@ #include "frontend/ir/location_descriptor.h" namespace Dynarmic { -namespace Arm { +namespace A32 { enum class ConditionalState { /// We haven't met any conditional instructions yet. @@ -26,11 +26,11 @@ enum class ConditionalState { struct ArmTranslatorVisitor final { using instruction_return_type = bool; - explicit ArmTranslatorVisitor(IR::LocationDescriptor descriptor) : ir(descriptor) { + explicit ArmTranslatorVisitor(LocationDescriptor descriptor) : ir(descriptor) { ASSERT_MSG(!descriptor.TFlag(), "The processor must be in Arm mode"); } - IR::IREmitter ir; + IR::A32IREmitter ir; ConditionalState cond_state = ConditionalState::None; bool ConditionPassed(Cond cond); @@ -62,8 +62,8 @@ struct ArmTranslatorVisitor final { return {imm32, carry_out}; } - IR::IREmitter::ResultAndCarry EmitImmShift(IR::Value value, ShiftType type, Imm5 imm5, IR::Value carry_in); - IR::IREmitter::ResultAndCarry EmitRegShift(IR::Value value, ShiftType type, IR::Value amount, IR::Value carry_in); + IR::A32IREmitter::ResultAndCarry EmitImmShift(IR::Value value, ShiftType type, Imm5 imm5, IR::Value carry_in); + IR::A32IREmitter::ResultAndCarry EmitRegShift(IR::Value value, ShiftType type, IR::Value amount, IR::Value carry_in); template bool EmitVfpVectorOperation(bool sz, ExtReg d, ExtReg n, ExtReg m, const FnT& fn); template bool EmitVfpVectorOperation(bool sz, ExtReg d, ExtReg m, const FnT& fn); @@ -384,5 +384,5 @@ struct ArmTranslatorVisitor final { bool vfp2_VLDM_a2(Cond cond, bool p, bool u, bool D, bool w, Reg n, size_t Vd, Imm8 imm8); }; -} // namespace Arm +} // namespace A32 } // namespace Dynarmic diff --git a/src/frontend/translate/translate_arm/vfp2.cpp b/src/frontend/A32/translate/translate_arm/vfp2.cpp similarity index 99% rename from src/frontend/translate/translate_arm/vfp2.cpp rename to src/frontend/A32/translate/translate_arm/vfp2.cpp index 4fa36606..334b3e3a 100644 --- a/src/frontend/translate/translate_arm/vfp2.cpp +++ b/src/frontend/A32/translate/translate_arm/vfp2.cpp @@ -7,7 +7,7 @@ #include "translate_arm.h" namespace Dynarmic { -namespace Arm { +namespace A32 { static ExtReg ToExtReg(bool sz, size_t base, bool bit) { if (sz) { @@ -672,7 +672,7 @@ bool ArmTranslatorVisitor::vfp2_VSTM_a1(Cond cond, bool p, bool u, bool D, bool u32 imm32 = imm8 << 2; size_t regs = imm8 / 2; - if (regs == 0 || regs > 16 || Arm::RegNumber(d)+regs > 32) + if (regs == 0 || regs > 16 || A32::RegNumber(d)+regs > 32) return UnpredictableInstruction(); // VSTM.F64 {!}, @@ -708,7 +708,7 @@ bool ArmTranslatorVisitor::vfp2_VSTM_a2(Cond cond, bool p, bool u, bool D, bool u32 imm32 = imm8 << 2; size_t regs = imm8; - if (regs == 0 || Arm::RegNumber(d)+regs > 32) + if (regs == 0 || A32::RegNumber(d)+regs > 32) return UnpredictableInstruction(); // VSTM.F32 {!}, @@ -739,7 +739,7 @@ bool ArmTranslatorVisitor::vfp2_VLDM_a1(Cond cond, bool p, bool u, bool D, bool u32 imm32 = imm8 << 2; size_t regs = imm8 / 2; - if (regs == 0 || regs > 16 || Arm::RegNumber(d)+regs > 32) + if (regs == 0 || regs > 16 || A32::RegNumber(d)+regs > 32) return UnpredictableInstruction(); // VLDM.F64 {!}, @@ -773,7 +773,7 @@ bool ArmTranslatorVisitor::vfp2_VLDM_a2(Cond cond, bool p, bool u, bool D, bool u32 imm32 = imm8 << 2; size_t regs = imm8; - if (regs == 0 || Arm::RegNumber(d)+regs > 32) + if (regs == 0 || A32::RegNumber(d)+regs > 32) return UnpredictableInstruction(); // VLDM.F32 {!}, @@ -790,5 +790,5 @@ bool ArmTranslatorVisitor::vfp2_VLDM_a2(Cond cond, bool p, bool u, bool D, bool return true; } -} // namespace Arm +} // namespace A32 } // namespace Dynarmic diff --git a/src/frontend/translate/translate_thumb.cpp b/src/frontend/A32/translate/translate_thumb.cpp similarity index 98% rename from src/frontend/translate/translate_thumb.cpp rename to src/frontend/A32/translate/translate_thumb.cpp index 1062d436..d5d30490 100644 --- a/src/frontend/translate/translate_thumb.cpp +++ b/src/frontend/A32/translate/translate_thumb.cpp @@ -8,26 +8,26 @@ #include "common/assert.h" #include "common/bit_util.h" -#include "frontend/arm/types.h" -#include "frontend/decoder/thumb16.h" -#include "frontend/decoder/thumb32.h" +#include "frontend/A32/decoder/thumb16.h" +#include "frontend/A32/decoder/thumb32.h" +#include "frontend/A32/translate/translate.h" +#include "frontend/A32/types.h" #include "frontend/ir/ir_emitter.h" #include "frontend/ir/location_descriptor.h" -#include "frontend/translate/translate.h" namespace Dynarmic { -namespace Arm { +namespace A32 { namespace { struct ThumbTranslatorVisitor final { using instruction_return_type = bool; - explicit ThumbTranslatorVisitor(IR::LocationDescriptor descriptor) : ir(descriptor) { + explicit ThumbTranslatorVisitor(LocationDescriptor descriptor) : ir(descriptor) { ASSERT_MSG(descriptor.TFlag(), "The processor must be in Thumb mode"); } - IR::IREmitter ir; + IR::A32IREmitter ir; bool InterpretThisInstruction() { ir.SetTerm(IR::Term::Interpret(ir.current_location)); @@ -877,7 +877,7 @@ std::tuple ReadThumbInstruction(u32 arm_pc, MemoryReadCodeFu } // local namespace -IR::Block TranslateThumb(IR::LocationDescriptor descriptor, MemoryReadCodeFuncType memory_read_code) { +IR::Block TranslateThumb(LocationDescriptor descriptor, MemoryReadCodeFuncType memory_read_code) { ThumbTranslatorVisitor visitor{descriptor}; bool should_continue = true; @@ -914,5 +914,5 @@ IR::Block TranslateThumb(IR::LocationDescriptor descriptor, MemoryReadCodeFuncTy return std::move(visitor.ir.block); } -} // namespace Arm +} // namespace A32 } // namepsace Dynarmic diff --git a/src/frontend/arm/types.cpp b/src/frontend/A32/types.cpp similarity index 97% rename from src/frontend/arm/types.cpp rename to src/frontend/A32/types.cpp index 3e3bb541..da418cee 100644 --- a/src/frontend/arm/types.cpp +++ b/src/frontend/A32/types.cpp @@ -8,10 +8,10 @@ #include #include "common/bit_util.h" -#include "frontend/arm/types.h" +#include "frontend/A32/types.h" namespace Dynarmic { -namespace Arm { +namespace A32 { const char* CondToString(Cond cond, bool explicit_al) { constexpr std::array cond_strs = { @@ -78,5 +78,5 @@ std::ostream& operator<<(std::ostream& o, RegList reg_list) { return o; } -} // namespace Arm +} // namespace A32 } // namespace Dynarmic diff --git a/src/frontend/arm/types.h b/src/frontend/A32/types.h similarity index 95% rename from src/frontend/arm/types.h rename to src/frontend/A32/types.h index b6783863..5320ad8a 100644 --- a/src/frontend/arm/types.h +++ b/src/frontend/A32/types.h @@ -14,13 +14,12 @@ #include "common/assert.h" #include "common/common_types.h" +#include "frontend/ir/cond.h" namespace Dynarmic { -namespace Arm { +namespace A32 { -enum class Cond { - EQ, NE, CS, CC, MI, PL, VS, VC, HI, LS, GE, LT, GT, LE, AL, NV -}; +using Cond = IR::Cond; enum class Reg { R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R15, @@ -119,5 +118,5 @@ inline ExtReg operator+(ExtReg reg, size_t number) { return new_reg; } -} // namespace Arm +} // namespace A32 } // namespace Dynarmic diff --git a/src/frontend/decoder/decoder_detail.h b/src/frontend/decoder/decoder_detail.h index bd4acf4f..9bfce2ef 100644 --- a/src/frontend/decoder/decoder_detail.h +++ b/src/frontend/decoder/decoder_detail.h @@ -15,7 +15,7 @@ #include "common/mp.h" namespace Dynarmic { -namespace Arm { +namespace Decoder { namespace detail { /** @@ -163,5 +163,5 @@ public: }; } // namespace detail -} // namespace Arm +} // namespace Decoder } // namespace Dynarmic diff --git a/src/frontend/decoder/matcher.h b/src/frontend/decoder/matcher.h index f58825f4..80802258 100644 --- a/src/frontend/decoder/matcher.h +++ b/src/frontend/decoder/matcher.h @@ -11,7 +11,7 @@ #include "common/assert.h" namespace Dynarmic { -namespace Arm { +namespace Decoder { /** * Generic instruction handling construct. @@ -75,5 +75,5 @@ private: handler_function fn; }; -} // namespace Arm +} // namespace Decoder } // namespace Dynarmic diff --git a/src/frontend/ir/basic_block.cpp b/src/frontend/ir/basic_block.cpp index 1dc78d7f..4f243d3c 100644 --- a/src/frontend/ir/basic_block.cpp +++ b/src/frontend/ir/basic_block.cpp @@ -13,6 +13,7 @@ #include #include "common/assert.h" +#include "frontend/A32/types.h" #include "frontend/ir/basic_block.h" #include "frontend/ir/opcodes.h" @@ -43,11 +44,11 @@ void Block::SetEndLocation(const LocationDescriptor& descriptor) { end_location = descriptor; } -Arm::Cond Block::GetCondition() const { +Cond Block::GetCondition() const { return cond; } -void Block::SetCondition(Arm::Cond condition) { +void Block::SetCondition(Cond condition) { cond = condition; } @@ -122,7 +123,7 @@ static std::string TerminalToString(const Terminal& terminal_variant) { } case 6: { auto terminal = boost::get(terminal_variant); - return fmt::format("If{{{}, {}, {}}}", CondToString(terminal.if_), TerminalToString(terminal.then_), TerminalToString(terminal.else_)); + return fmt::format("If{{{}, {}, {}}}", A32::CondToString(terminal.if_), TerminalToString(terminal.then_), TerminalToString(terminal.else_)); } case 7: { auto terminal = boost::get(terminal_variant); @@ -138,8 +139,8 @@ std::string DumpBlock(const IR::Block& block) { ret += fmt::format("Block: location={}\n", block.Location()); ret += fmt::format("cycles={}", block.CycleCount()); - ret += fmt::format(", entry_cond={}", Arm::CondToString(block.GetCondition(), true)); - if (block.GetCondition() != Arm::Cond::AL) { + ret += fmt::format(", entry_cond={}", A32::CondToString(block.GetCondition(), true)); + if (block.GetCondition() != Cond::AL) { ret += fmt::format(", cond_fail={}", block.ConditionFailedLocation()); } ret += '\n'; @@ -161,9 +162,9 @@ std::string DumpBlock(const IR::Block& block) { case Type::U32: return fmt::format("#{:#x}", arg.GetU32()); case Type::RegRef: - return Arm::RegToString(arg.GetRegRef()); + return A32::RegToString(arg.GetA32RegRef()); case Type::ExtRegRef: - return Arm::ExtRegToString(arg.GetExtRegRef()); + return A32::ExtRegToString(arg.GetA32ExtRegRef()); default: return ""; } diff --git a/src/frontend/ir/basic_block.h b/src/frontend/ir/basic_block.h index b41e81f9..47b59aa9 100644 --- a/src/frontend/ir/basic_block.h +++ b/src/frontend/ir/basic_block.h @@ -15,6 +15,7 @@ #include "common/common_types.h" #include "common/intrusive_list.h" #include "common/memory_pool.h" +#include "frontend/ir/cond.h" #include "frontend/ir/location_descriptor.h" #include "frontend/ir/microinstruction.h" #include "frontend/ir/terminal.h" @@ -85,9 +86,9 @@ public: void SetEndLocation(const LocationDescriptor& descriptor); /// Gets the condition required to pass in order to execute this block. - Arm::Cond GetCondition() const; + Cond GetCondition() const; /// Sets the condition required to pass in order to execute this block. - void SetCondition(Arm::Cond condition); + void SetCondition(Cond condition); /// Gets the location of the block to execute if the predicated condition fails. LocationDescriptor ConditionFailedLocation() const; @@ -124,7 +125,7 @@ private: /// Description of the end location of this block LocationDescriptor end_location; /// Conditional to pass in order to execute this block - Arm::Cond cond = Arm::Cond::AL; + Cond cond = Cond::AL; /// Block to execute next if `cond` did not pass. boost::optional cond_failed = {}; /// Number of cycles this block takes to execute if the conditional fails. diff --git a/src/frontend/ir/cond.h b/src/frontend/ir/cond.h new file mode 100644 index 00000000..1f180cc6 --- /dev/null +++ b/src/frontend/ir/cond.h @@ -0,0 +1,24 @@ +/* This file is part of the dynarmic project. + * Copyright (c) 2016 MerryMage + * This software may be used and distributed according to the terms of the GNU + * General Public License version 2 or any later version. + */ + +#pragma once + +#include "common/common_types.h" + +namespace Dynarmic { +namespace IR { + +enum class Cond { + EQ, NE, CS, CC, MI, PL, VS, VC, HI, LS, GE, LT, GT, LE, AL, NV, + HS = CS, LO = CC, +}; + +inline Cond invert(Cond c) { + return static_cast(static_cast(c) ^ 1); +} + +} // namespace IR +} // namespace Dynarmic diff --git a/src/frontend/ir/ir_emitter.cpp b/src/frontend/ir/ir_emitter.cpp index 7250e5b8..6925c9c6 100644 --- a/src/frontend/ir/ir_emitter.cpp +++ b/src/frontend/ir/ir_emitter.cpp @@ -11,256 +11,256 @@ namespace Dynarmic { namespace IR { -void IREmitter::Unimplemented() { +void A32IREmitter::Unimplemented() { } -u32 IREmitter::PC() { +u32 A32IREmitter::PC() { u32 offset = current_location.TFlag() ? 4 : 8; return current_location.PC() + offset; } -u32 IREmitter::AlignPC(size_t alignment) { +u32 A32IREmitter::AlignPC(size_t alignment) { u32 pc = PC(); return static_cast(pc - pc % alignment); } -Value IREmitter::Imm1(bool imm1) { +Value A32IREmitter::Imm1(bool imm1) { return Value(imm1); } -Value IREmitter::Imm8(u8 imm8) { +Value A32IREmitter::Imm8(u8 imm8) { return Value(imm8); } -Value IREmitter::Imm32(u32 imm32) { +Value A32IREmitter::Imm32(u32 imm32) { return Value(imm32); } -Value IREmitter::Imm64(u64 imm64) { +Value A32IREmitter::Imm64(u64 imm64) { return Value(imm64); } -Value IREmitter::GetRegister(Arm::Reg reg) { - if (reg == Arm::Reg::PC) { +Value A32IREmitter::GetRegister(A32::Reg reg) { + if (reg == A32::Reg::PC) { return Imm32(PC()); } return Inst(Opcode::GetRegister, { Value(reg) }); } -Value IREmitter::GetExtendedRegister(Arm::ExtReg reg) { - if (Arm::IsSingleExtReg(reg)) { +Value A32IREmitter::GetExtendedRegister(A32::ExtReg reg) { + if (A32::IsSingleExtReg(reg)) { return Inst(Opcode::GetExtendedRegister32, {Value(reg)}); } - if (Arm::IsDoubleExtReg(reg)) { + if (A32::IsDoubleExtReg(reg)) { return Inst(Opcode::GetExtendedRegister64, {Value(reg)}); } ASSERT_MSG(false, "Invalid reg."); } -void IREmitter::SetRegister(const Arm::Reg reg, const Value& value) { - ASSERT(reg != Arm::Reg::PC); +void A32IREmitter::SetRegister(const A32::Reg reg, const Value& value) { + ASSERT(reg != A32::Reg::PC); Inst(Opcode::SetRegister, { Value(reg), value }); } -void IREmitter::SetExtendedRegister(const Arm::ExtReg reg, const Value& value) { - if (Arm::IsSingleExtReg(reg)) { +void A32IREmitter::SetExtendedRegister(const A32::ExtReg reg, const Value& value) { + if (A32::IsSingleExtReg(reg)) { Inst(Opcode::SetExtendedRegister32, {Value(reg), value}); - } else if (Arm::IsDoubleExtReg(reg)) { + } else if (A32::IsDoubleExtReg(reg)) { Inst(Opcode::SetExtendedRegister64, {Value(reg), value}); } else { ASSERT_MSG(false, "Invalid reg."); } } -void IREmitter::ALUWritePC(const Value& value) { +void A32IREmitter::ALUWritePC(const Value& value) { // This behaviour is ARM version-dependent. // The below implementation is for ARMv6k BranchWritePC(value); } -void IREmitter::BranchWritePC(const Value& value) { +void A32IREmitter::BranchWritePC(const Value& value) { if (!current_location.TFlag()) { auto new_pc = And(value, Imm32(0xFFFFFFFC)); - Inst(Opcode::SetRegister, { Value(Arm::Reg::PC), new_pc }); + Inst(Opcode::SetRegister, { Value(A32::Reg::PC), new_pc }); } else { auto new_pc = And(value, Imm32(0xFFFFFFFE)); - Inst(Opcode::SetRegister, { Value(Arm::Reg::PC), new_pc }); + Inst(Opcode::SetRegister, { Value(A32::Reg::PC), new_pc }); } } -void IREmitter::BXWritePC(const Value& value) { +void A32IREmitter::BXWritePC(const Value& value) { Inst(Opcode::BXWritePC, {value}); } -void IREmitter::LoadWritePC(const Value& value) { +void A32IREmitter::LoadWritePC(const Value& value) { // This behaviour is ARM version-dependent. // The below implementation is for ARMv6k BXWritePC(value); } -void IREmitter::CallSupervisor(const Value& value) { +void A32IREmitter::CallSupervisor(const Value& value) { Inst(Opcode::CallSupervisor, {value}); } -void IREmitter::PushRSB(const LocationDescriptor& return_location) { +void A32IREmitter::PushRSB(const A32::LocationDescriptor& return_location) { Inst(Opcode::PushRSB, {Value(return_location.UniqueHash())}); } -Value IREmitter::GetCpsr() { +Value A32IREmitter::GetCpsr() { return Inst(Opcode::GetCpsr, {}); } -void IREmitter::SetCpsr(const Value& value) { +void A32IREmitter::SetCpsr(const Value& value) { Inst(Opcode::SetCpsr, {value}); } -void IREmitter::SetCpsrNZCV(const Value& value) { +void A32IREmitter::SetCpsrNZCV(const Value& value) { Inst(Opcode::SetCpsrNZCV, {value}); } -void IREmitter::SetCpsrNZCVQ(const Value& value) { +void A32IREmitter::SetCpsrNZCVQ(const Value& value) { Inst(Opcode::SetCpsrNZCVQ, {value}); } -Value IREmitter::GetCFlag() { +Value A32IREmitter::GetCFlag() { return Inst(Opcode::GetCFlag, {}); } -void IREmitter::SetNFlag(const Value& value) { +void A32IREmitter::SetNFlag(const Value& value) { Inst(Opcode::SetNFlag, {value}); } -void IREmitter::SetZFlag(const Value& value) { +void A32IREmitter::SetZFlag(const Value& value) { Inst(Opcode::SetZFlag, {value}); } -void IREmitter::SetCFlag(const Value& value) { +void A32IREmitter::SetCFlag(const Value& value) { Inst(Opcode::SetCFlag, {value}); } -void IREmitter::SetVFlag(const Value& value) { +void A32IREmitter::SetVFlag(const Value& value) { Inst(Opcode::SetVFlag, {value}); } -void IREmitter::OrQFlag(const Value& value) { +void A32IREmitter::OrQFlag(const Value& value) { Inst(Opcode::OrQFlag, {value}); } -Value IREmitter::GetGEFlags() { +Value A32IREmitter::GetGEFlags() { return Inst(Opcode::GetGEFlags, {}); } -void IREmitter::SetGEFlags(const Value& value) { +void A32IREmitter::SetGEFlags(const Value& value) { Inst(Opcode::SetGEFlags, {value}); } -void IREmitter::SetGEFlagsCompressed(const Value& value) { +void A32IREmitter::SetGEFlagsCompressed(const Value& value) { Inst(Opcode::SetGEFlagsCompressed, {value}); } -Value IREmitter::GetFpscr() { +Value A32IREmitter::GetFpscr() { return Inst(Opcode::GetFpscr, {}); } -void IREmitter::SetFpscr(const Value& new_fpscr) { +void A32IREmitter::SetFpscr(const Value& new_fpscr) { Inst(Opcode::SetFpscr, {new_fpscr}); } -Value IREmitter::GetFpscrNZCV() { +Value A32IREmitter::GetFpscrNZCV() { return Inst(Opcode::GetFpscrNZCV, {}); } -void IREmitter::SetFpscrNZCV(const Value& new_fpscr_nzcv) { +void A32IREmitter::SetFpscrNZCV(const Value& new_fpscr_nzcv) { Inst(Opcode::SetFpscrNZCV, {new_fpscr_nzcv}); } -Value IREmitter::Pack2x32To1x64(const Value& lo, const Value& hi) { +Value A32IREmitter::Pack2x32To1x64(const Value& lo, const Value& hi) { return Inst(Opcode::Pack2x32To1x64, {lo, hi}); } -Value IREmitter::LeastSignificantWord(const Value& value) { +Value A32IREmitter::LeastSignificantWord(const Value& value) { return Inst(Opcode::LeastSignificantWord, {value}); } -IREmitter::ResultAndCarry IREmitter::MostSignificantWord(const Value& value) { +A32IREmitter::ResultAndCarry A32IREmitter::MostSignificantWord(const Value& value) { auto result = Inst(Opcode::MostSignificantWord, {value}); auto carry_out = Inst(Opcode::GetCarryFromOp, {result}); return {result, carry_out}; } -Value IREmitter::LeastSignificantHalf(const Value& value) { +Value A32IREmitter::LeastSignificantHalf(const Value& value) { return Inst(Opcode::LeastSignificantHalf, {value}); } -Value IREmitter::LeastSignificantByte(const Value& value) { +Value A32IREmitter::LeastSignificantByte(const Value& value) { return Inst(Opcode::LeastSignificantByte, {value}); } -Value IREmitter::MostSignificantBit(const Value& value) { +Value A32IREmitter::MostSignificantBit(const Value& value) { return Inst(Opcode::MostSignificantBit, {value}); } -Value IREmitter::IsZero(const Value& value) { +Value A32IREmitter::IsZero(const Value& value) { return Inst(Opcode::IsZero, {value}); } -Value IREmitter::IsZero64(const Value& value) { +Value A32IREmitter::IsZero64(const Value& value) { return Inst(Opcode::IsZero64, {value}); } -IREmitter::ResultAndCarry IREmitter::LogicalShiftLeft(const Value& value_in, const Value& shift_amount, const Value& carry_in) { +A32IREmitter::ResultAndCarry A32IREmitter::LogicalShiftLeft(const Value& value_in, const Value& shift_amount, const Value& carry_in) { auto result = Inst(Opcode::LogicalShiftLeft, {value_in, shift_amount, carry_in}); auto carry_out = Inst(Opcode::GetCarryFromOp, {result}); return {result, carry_out}; } -IREmitter::ResultAndCarry IREmitter::LogicalShiftRight(const Value& value_in, const Value& shift_amount, const Value& carry_in) { +A32IREmitter::ResultAndCarry A32IREmitter::LogicalShiftRight(const Value& value_in, const Value& shift_amount, const Value& carry_in) { auto result = Inst(Opcode::LogicalShiftRight, {value_in, shift_amount, carry_in}); auto carry_out = Inst(Opcode::GetCarryFromOp, {result}); return {result, carry_out}; } -Value IREmitter::LogicalShiftRight64(const Value& value_in, const Value& shift_amount) { +Value A32IREmitter::LogicalShiftRight64(const Value& value_in, const Value& shift_amount) { return Inst(Opcode::LogicalShiftRight64, {value_in, shift_amount}); } -IREmitter::ResultAndCarry IREmitter::ArithmeticShiftRight(const Value& value_in, const Value& shift_amount, const Value& carry_in) { +A32IREmitter::ResultAndCarry A32IREmitter::ArithmeticShiftRight(const Value& value_in, const Value& shift_amount, const Value& carry_in) { auto result = Inst(Opcode::ArithmeticShiftRight, {value_in, shift_amount, carry_in}); auto carry_out = Inst(Opcode::GetCarryFromOp, {result}); return {result, carry_out}; } -IREmitter::ResultAndCarry IREmitter::RotateRight(const Value& value_in, const Value& shift_amount, const Value& carry_in) { +A32IREmitter::ResultAndCarry A32IREmitter::RotateRight(const Value& value_in, const Value& shift_amount, const Value& carry_in) { auto result = Inst(Opcode::RotateRight, {value_in, shift_amount, carry_in}); auto carry_out = Inst(Opcode::GetCarryFromOp, {result}); return {result, carry_out}; } -IREmitter::ResultAndCarry IREmitter::RotateRightExtended(const Value& value_in, const Value& carry_in) { +A32IREmitter::ResultAndCarry A32IREmitter::RotateRightExtended(const Value& value_in, const Value& carry_in) { auto result = Inst(Opcode::RotateRightExtended, {value_in, carry_in}); auto carry_out = Inst(Opcode::GetCarryFromOp, {result}); return {result, carry_out}; } -IREmitter::ResultAndCarryAndOverflow IREmitter::AddWithCarry(const Value& a, const Value& b, const Value& carry_in) { +A32IREmitter::ResultAndCarryAndOverflow A32IREmitter::AddWithCarry(const Value& a, const Value& b, const Value& carry_in) { auto result = Inst(Opcode::AddWithCarry, {a, b, carry_in}); auto carry_out = Inst(Opcode::GetCarryFromOp, {result}); auto overflow = Inst(Opcode::GetOverflowFromOp, {result}); return {result, carry_out, overflow}; } -Value IREmitter::Add(const Value& a, const Value& b) { +Value A32IREmitter::Add(const Value& a, const Value& b) { return Inst(Opcode::AddWithCarry, {a, b, Imm1(0)}); } -Value IREmitter::Add64(const Value& a, const Value& b) { +Value A32IREmitter::Add64(const Value& a, const Value& b) { return Inst(Opcode::Add64, {a, b}); } -IREmitter::ResultAndCarryAndOverflow IREmitter::SubWithCarry(const Value& a, const Value& b, const Value& carry_in) { +A32IREmitter::ResultAndCarryAndOverflow A32IREmitter::SubWithCarry(const Value& a, const Value& b, const Value& carry_in) { // This is equivalent to AddWithCarry(a, Not(b), carry_in). auto result = Inst(Opcode::SubWithCarry, {a, b, carry_in}); auto carry_out = Inst(Opcode::GetCarryFromOp, {result}); @@ -268,437 +268,437 @@ IREmitter::ResultAndCarryAndOverflow IREmitter::SubWithCarry(const Value& a, con return {result, carry_out, overflow}; } -Value IREmitter::Sub(const Value& a, const Value& b) { +Value A32IREmitter::Sub(const Value& a, const Value& b) { return Inst(Opcode::SubWithCarry, {a, b, Imm1(1)}); } -Value IREmitter::Sub64(const Value& a, const Value& b) { +Value A32IREmitter::Sub64(const Value& a, const Value& b) { return Inst(Opcode::Sub64, {a, b}); } -Value IREmitter::Mul(const Value& a, const Value& b) { +Value A32IREmitter::Mul(const Value& a, const Value& b) { return Inst(Opcode::Mul, {a, b}); } -Value IREmitter::Mul64(const Value& a, const Value& b) { +Value A32IREmitter::Mul64(const Value& a, const Value& b) { return Inst(Opcode::Mul64, {a, b}); } -Value IREmitter::And(const Value& a, const Value& b) { +Value A32IREmitter::And(const Value& a, const Value& b) { return Inst(Opcode::And, {a, b}); } -Value IREmitter::Eor(const Value& a, const Value& b) { +Value A32IREmitter::Eor(const Value& a, const Value& b) { return Inst(Opcode::Eor, {a, b}); } -Value IREmitter::Or(const Value& a, const Value& b) { +Value A32IREmitter::Or(const Value& a, const Value& b) { return Inst(Opcode::Or, {a, b}); } -Value IREmitter::Not(const Value& a) { +Value A32IREmitter::Not(const Value& a) { return Inst(Opcode::Not, {a}); } -Value IREmitter::SignExtendWordToLong(const Value& a) { +Value A32IREmitter::SignExtendWordToLong(const Value& a) { return Inst(Opcode::SignExtendWordToLong, {a}); } -Value IREmitter::SignExtendHalfToWord(const Value& a) { +Value A32IREmitter::SignExtendHalfToWord(const Value& a) { return Inst(Opcode::SignExtendHalfToWord, {a}); } -Value IREmitter::SignExtendByteToWord(const Value& a) { +Value A32IREmitter::SignExtendByteToWord(const Value& a) { return Inst(Opcode::SignExtendByteToWord, {a}); } -Value IREmitter::ZeroExtendWordToLong(const Value& a) { +Value A32IREmitter::ZeroExtendWordToLong(const Value& a) { return Inst(Opcode::ZeroExtendWordToLong, {a}); } -Value IREmitter::ZeroExtendHalfToWord(const Value& a) { +Value A32IREmitter::ZeroExtendHalfToWord(const Value& a) { return Inst(Opcode::ZeroExtendHalfToWord, {a}); } -Value IREmitter::ZeroExtendByteToWord(const Value& a) { +Value A32IREmitter::ZeroExtendByteToWord(const Value& a) { return Inst(Opcode::ZeroExtendByteToWord, {a}); } -Value IREmitter::ByteReverseWord(const Value& a) { +Value A32IREmitter::ByteReverseWord(const Value& a) { return Inst(Opcode::ByteReverseWord, {a}); } -Value IREmitter::ByteReverseHalf(const Value& a) { +Value A32IREmitter::ByteReverseHalf(const Value& a) { return Inst(Opcode::ByteReverseHalf, {a}); } -Value IREmitter::ByteReverseDual(const Value& a) { +Value A32IREmitter::ByteReverseDual(const Value& a) { return Inst(Opcode::ByteReverseDual, {a}); } -Value IREmitter::CountLeadingZeros(const Value& a) { +Value A32IREmitter::CountLeadingZeros(const Value& a) { return Inst(Opcode::CountLeadingZeros, {a}); } -IREmitter::ResultAndOverflow IREmitter::SignedSaturatedAdd(const Value& a, const Value& b) { +A32IREmitter::ResultAndOverflow A32IREmitter::SignedSaturatedAdd(const Value& a, const Value& b) { auto result = Inst(Opcode::SignedSaturatedAdd, {a, b}); auto overflow = Inst(Opcode::GetOverflowFromOp, {result}); return {result, overflow}; } -IREmitter::ResultAndOverflow IREmitter::SignedSaturatedSub(const Value& a, const Value& b) { +A32IREmitter::ResultAndOverflow A32IREmitter::SignedSaturatedSub(const Value& a, const Value& b) { auto result = Inst(Opcode::SignedSaturatedSub, {a, b}); auto overflow = Inst(Opcode::GetOverflowFromOp, {result}); return {result, overflow}; } -IREmitter::ResultAndOverflow IREmitter::UnsignedSaturation(const Value& a, size_t bit_size_to_saturate_to) { +A32IREmitter::ResultAndOverflow A32IREmitter::UnsignedSaturation(const Value& a, size_t bit_size_to_saturate_to) { ASSERT(bit_size_to_saturate_to <= 31); auto result = Inst(Opcode::UnsignedSaturation, {a, Imm8(static_cast(bit_size_to_saturate_to))}); auto overflow = Inst(Opcode::GetOverflowFromOp, {result}); return {result, overflow}; } -IREmitter::ResultAndOverflow IREmitter::SignedSaturation(const Value& a, size_t bit_size_to_saturate_to) { +A32IREmitter::ResultAndOverflow A32IREmitter::SignedSaturation(const Value& a, size_t bit_size_to_saturate_to) { ASSERT(bit_size_to_saturate_to >= 1 && bit_size_to_saturate_to <= 32); auto result = Inst(Opcode::SignedSaturation, {a, Imm8(static_cast(bit_size_to_saturate_to))}); auto overflow = Inst(Opcode::GetOverflowFromOp, {result}); return {result, overflow}; } -IREmitter::ResultAndGE IREmitter::PackedAddU8(const Value& a, const Value& b) { +A32IREmitter::ResultAndGE A32IREmitter::PackedAddU8(const Value& a, const Value& b) { auto result = Inst(Opcode::PackedAddU8, {a, b}); auto ge = Inst(Opcode::GetGEFromOp, {result}); return {result, ge}; } -IREmitter::ResultAndGE IREmitter::PackedAddS8(const Value& a, const Value& b) { +A32IREmitter::ResultAndGE A32IREmitter::PackedAddS8(const Value& a, const Value& b) { auto result = Inst(Opcode::PackedAddS8, {a, b}); auto ge = Inst(Opcode::GetGEFromOp, {result}); return {result, ge}; } -IREmitter::ResultAndGE IREmitter::PackedAddU16(const Value& a, const Value& b) { +A32IREmitter::ResultAndGE A32IREmitter::PackedAddU16(const Value& a, const Value& b) { auto result = Inst(Opcode::PackedAddU16, {a, b}); auto ge = Inst(Opcode::GetGEFromOp, {result}); return {result, ge}; } -IREmitter::ResultAndGE IREmitter::PackedAddS16(const Value& a, const Value& b) { +A32IREmitter::ResultAndGE A32IREmitter::PackedAddS16(const Value& a, const Value& b) { auto result = Inst(Opcode::PackedAddS16, {a, b}); auto ge = Inst(Opcode::GetGEFromOp, {result}); return {result, ge}; } -IREmitter::ResultAndGE IREmitter::PackedSubU8(const Value& a, const Value& b) { +A32IREmitter::ResultAndGE A32IREmitter::PackedSubU8(const Value& a, const Value& b) { auto result = Inst(Opcode::PackedSubU8, {a, b}); auto ge = Inst(Opcode::GetGEFromOp, {result}); return {result, ge}; } -IREmitter::ResultAndGE IREmitter::PackedSubS8(const Value& a, const Value& b) { +A32IREmitter::ResultAndGE A32IREmitter::PackedSubS8(const Value& a, const Value& b) { auto result = Inst(Opcode::PackedSubS8, {a, b}); auto ge = Inst(Opcode::GetGEFromOp, {result}); return {result, ge}; } -IREmitter::ResultAndGE IREmitter::PackedSubU16(const Value& a, const Value& b) { +A32IREmitter::ResultAndGE A32IREmitter::PackedSubU16(const Value& a, const Value& b) { auto result = Inst(Opcode::PackedSubU16, {a, b}); auto ge = Inst(Opcode::GetGEFromOp, {result}); return {result, ge}; } -IREmitter::ResultAndGE IREmitter::PackedSubS16(const Value& a, const Value& b) { +A32IREmitter::ResultAndGE A32IREmitter::PackedSubS16(const Value& a, const Value& b) { auto result = Inst(Opcode::PackedSubS16, {a, b}); auto ge = Inst(Opcode::GetGEFromOp, {result}); return {result, ge}; } -IREmitter::ResultAndGE IREmitter::PackedAddSubU16(const Value& a, const Value& b) { +A32IREmitter::ResultAndGE A32IREmitter::PackedAddSubU16(const Value& a, const Value& b) { auto result = Inst(Opcode::PackedAddSubU16, {a, b}); auto ge = Inst(Opcode::GetGEFromOp, {result}); return {result, ge}; } -IREmitter::ResultAndGE IREmitter::PackedAddSubS16(const Value& a, const Value& b) { +A32IREmitter::ResultAndGE A32IREmitter::PackedAddSubS16(const Value& a, const Value& b) { auto result = Inst(Opcode::PackedAddSubS16, {a, b}); auto ge = Inst(Opcode::GetGEFromOp, {result}); return {result, ge}; } -IREmitter::ResultAndGE IREmitter::PackedSubAddU16(const Value& a, const Value& b) { +A32IREmitter::ResultAndGE A32IREmitter::PackedSubAddU16(const Value& a, const Value& b) { auto result = Inst(Opcode::PackedSubAddU16, {a, b}); auto ge = Inst(Opcode::GetGEFromOp, {result}); return {result, ge}; } -IREmitter::ResultAndGE IREmitter::PackedSubAddS16(const Value& a, const Value& b) { +A32IREmitter::ResultAndGE A32IREmitter::PackedSubAddS16(const Value& a, const Value& b) { auto result = Inst(Opcode::PackedSubAddS16, {a, b}); auto ge = Inst(Opcode::GetGEFromOp, {result}); return {result, ge}; } -Value IREmitter::PackedHalvingAddU8(const Value& a, const Value& b) { +Value A32IREmitter::PackedHalvingAddU8(const Value& a, const Value& b) { return Inst(Opcode::PackedHalvingAddU8, {a, b}); } -Value IREmitter::PackedHalvingAddS8(const Value& a, const Value& b) { +Value A32IREmitter::PackedHalvingAddS8(const Value& a, const Value& b) { return Inst(Opcode::PackedHalvingAddS8, {a, b}); } -Value IREmitter::PackedHalvingSubU8(const Value& a, const Value& b) { +Value A32IREmitter::PackedHalvingSubU8(const Value& a, const Value& b) { return Inst(Opcode::PackedHalvingSubU8, {a, b}); } -Value IREmitter::PackedHalvingSubS8(const Value& a, const Value& b) { +Value A32IREmitter::PackedHalvingSubS8(const Value& a, const Value& b) { return Inst(Opcode::PackedHalvingSubS8, {a, b}); } -Value IREmitter::PackedHalvingAddU16(const Value& a, const Value& b) { +Value A32IREmitter::PackedHalvingAddU16(const Value& a, const Value& b) { return Inst(Opcode::PackedHalvingAddU16, {a, b}); } -Value IREmitter::PackedHalvingAddS16(const Value& a, const Value& b) { +Value A32IREmitter::PackedHalvingAddS16(const Value& a, const Value& b) { return Inst(Opcode::PackedHalvingAddS16, {a, b}); } -Value IREmitter::PackedHalvingSubU16(const Value& a, const Value& b) { +Value A32IREmitter::PackedHalvingSubU16(const Value& a, const Value& b) { return Inst(Opcode::PackedHalvingSubU16, {a, b}); } -Value IREmitter::PackedHalvingSubS16(const Value& a, const Value& b) { +Value A32IREmitter::PackedHalvingSubS16(const Value& a, const Value& b) { return Inst(Opcode::PackedHalvingSubS16, {a, b}); } -Value IREmitter::PackedHalvingAddSubU16(const Value& a, const Value& b) { +Value A32IREmitter::PackedHalvingAddSubU16(const Value& a, const Value& b) { return Inst(Opcode::PackedHalvingAddSubU16, {a, b}); } -Value IREmitter::PackedHalvingAddSubS16(const Value& a, const Value& b) { +Value A32IREmitter::PackedHalvingAddSubS16(const Value& a, const Value& b) { return Inst(Opcode::PackedHalvingAddSubS16, {a, b}); } -Value IREmitter::PackedHalvingSubAddU16(const Value& a, const Value& b) { +Value A32IREmitter::PackedHalvingSubAddU16(const Value& a, const Value& b) { return Inst(Opcode::PackedHalvingSubAddU16, {a, b}); } -Value IREmitter::PackedHalvingSubAddS16(const Value& a, const Value& b) { +Value A32IREmitter::PackedHalvingSubAddS16(const Value& a, const Value& b) { return Inst(Opcode::PackedHalvingSubAddS16, {a, b}); } -Value IREmitter::PackedSaturatedAddU8(const Value& a, const Value& b) { +Value A32IREmitter::PackedSaturatedAddU8(const Value& a, const Value& b) { return Inst(Opcode::PackedSaturatedAddU8, {a, b}); } -Value IREmitter::PackedSaturatedAddS8(const Value& a, const Value& b) { +Value A32IREmitter::PackedSaturatedAddS8(const Value& a, const Value& b) { return Inst(Opcode::PackedSaturatedAddS8, {a, b}); } -Value IREmitter::PackedSaturatedSubU8(const Value& a, const Value& b) { +Value A32IREmitter::PackedSaturatedSubU8(const Value& a, const Value& b) { return Inst(Opcode::PackedSaturatedSubU8, {a, b}); } -Value IREmitter::PackedSaturatedSubS8(const Value& a, const Value& b) { +Value A32IREmitter::PackedSaturatedSubS8(const Value& a, const Value& b) { return Inst(Opcode::PackedSaturatedSubS8, {a, b}); } -Value IREmitter::PackedSaturatedAddU16(const Value& a, const Value& b) { +Value A32IREmitter::PackedSaturatedAddU16(const Value& a, const Value& b) { return Inst(Opcode::PackedSaturatedAddU16, {a, b}); } -Value IREmitter::PackedSaturatedAddS16(const Value& a, const Value& b) { +Value A32IREmitter::PackedSaturatedAddS16(const Value& a, const Value& b) { return Inst(Opcode::PackedSaturatedAddS16, {a, b}); } -Value IREmitter::PackedSaturatedSubU16(const Value& a, const Value& b) { +Value A32IREmitter::PackedSaturatedSubU16(const Value& a, const Value& b) { return Inst(Opcode::PackedSaturatedSubU16, {a, b}); } -Value IREmitter::PackedSaturatedSubS16(const Value& a, const Value& b) { +Value A32IREmitter::PackedSaturatedSubS16(const Value& a, const Value& b) { return Inst(Opcode::PackedSaturatedSubS16, {a, b}); } -Value IREmitter::PackedAbsDiffSumS8(const Value& a, const Value& b) { +Value A32IREmitter::PackedAbsDiffSumS8(const Value& a, const Value& b) { return Inst(Opcode::PackedAbsDiffSumS8, {a, b}); } -Value IREmitter::PackedSelect(const Value& ge, const Value& a, const Value& b) { +Value A32IREmitter::PackedSelect(const Value& ge, const Value& a, const Value& b) { return Inst(Opcode::PackedSelect, {ge, a, b}); } -Value IREmitter::TransferToFP32(const Value& a) { +Value A32IREmitter::TransferToFP32(const Value& a) { return Inst(Opcode::TransferToFP32, {a}); } -Value IREmitter::TransferToFP64(const Value& a) { +Value A32IREmitter::TransferToFP64(const Value& a) { return Inst(Opcode::TransferToFP64, {a}); } -Value IREmitter::TransferFromFP32(const Value& a) { +Value A32IREmitter::TransferFromFP32(const Value& a) { return Inst(Opcode::TransferFromFP32, {a}); } -Value IREmitter::TransferFromFP64(const Value& a) { +Value A32IREmitter::TransferFromFP64(const Value& a) { return Inst(Opcode::TransferFromFP64, {a}); } -Value IREmitter::FPAbs32(const Value& a) { +Value A32IREmitter::FPAbs32(const Value& a) { return Inst(Opcode::FPAbs32, {a}); } -Value IREmitter::FPAbs64(const Value& a) { +Value A32IREmitter::FPAbs64(const Value& a) { return Inst(Opcode::FPAbs64, {a}); } -Value IREmitter::FPAdd32(const Value& a, const Value& b, bool fpscr_controlled) { +Value A32IREmitter::FPAdd32(const Value& a, const Value& b, bool fpscr_controlled) { ASSERT(fpscr_controlled); return Inst(Opcode::FPAdd32, {a, b}); } -Value IREmitter::FPAdd64(const Value& a, const Value& b, bool fpscr_controlled) { +Value A32IREmitter::FPAdd64(const Value& a, const Value& b, bool fpscr_controlled) { ASSERT(fpscr_controlled); return Inst(Opcode::FPAdd64, {a, b}); } -void IREmitter::FPCompare32(const Value& a, const Value& b, bool exc_on_qnan, bool fpscr_controlled) { +void A32IREmitter::FPCompare32(const Value& a, const Value& b, bool exc_on_qnan, bool fpscr_controlled) { ASSERT(fpscr_controlled); Inst(Opcode::FPCompare32, {a, b, Imm1(exc_on_qnan)}); } -void IREmitter::FPCompare64(const Value& a, const Value& b, bool exc_on_qnan, bool fpscr_controlled) { +void A32IREmitter::FPCompare64(const Value& a, const Value& b, bool exc_on_qnan, bool fpscr_controlled) { ASSERT(fpscr_controlled); Inst(Opcode::FPCompare64, {a, b, Imm1(exc_on_qnan)}); } -Value IREmitter::FPDiv32(const Value& a, const Value& b, bool fpscr_controlled) { +Value A32IREmitter::FPDiv32(const Value& a, const Value& b, bool fpscr_controlled) { ASSERT(fpscr_controlled); return Inst(Opcode::FPDiv32, {a, b}); } -Value IREmitter::FPDiv64(const Value& a, const Value& b, bool fpscr_controlled) { +Value A32IREmitter::FPDiv64(const Value& a, const Value& b, bool fpscr_controlled) { ASSERT(fpscr_controlled); return Inst(Opcode::FPDiv64, {a, b}); } -Value IREmitter::FPMul32(const Value& a, const Value& b, bool fpscr_controlled) { +Value A32IREmitter::FPMul32(const Value& a, const Value& b, bool fpscr_controlled) { ASSERT(fpscr_controlled); return Inst(Opcode::FPMul32, {a, b}); } -Value IREmitter::FPMul64(const Value& a, const Value& b, bool fpscr_controlled) { +Value A32IREmitter::FPMul64(const Value& a, const Value& b, bool fpscr_controlled) { ASSERT(fpscr_controlled); return Inst(Opcode::FPMul64, {a, b}); } -Value IREmitter::FPNeg32(const Value& a) { +Value A32IREmitter::FPNeg32(const Value& a) { return Inst(Opcode::FPNeg32, {a}); } -Value IREmitter::FPNeg64(const Value& a) { +Value A32IREmitter::FPNeg64(const Value& a) { return Inst(Opcode::FPNeg64, {a}); } -Value IREmitter::FPSqrt32(const Value& a) { +Value A32IREmitter::FPSqrt32(const Value& a) { return Inst(Opcode::FPSqrt32, {a}); } -Value IREmitter::FPSqrt64(const Value& a) { +Value A32IREmitter::FPSqrt64(const Value& a) { return Inst(Opcode::FPSqrt64, {a}); } -Value IREmitter::FPSub32(const Value& a, const Value& b, bool fpscr_controlled) { +Value A32IREmitter::FPSub32(const Value& a, const Value& b, bool fpscr_controlled) { ASSERT(fpscr_controlled); return Inst(Opcode::FPSub32, {a, b}); } -Value IREmitter::FPSub64(const Value& a, const Value& b, bool fpscr_controlled) { +Value A32IREmitter::FPSub64(const Value& a, const Value& b, bool fpscr_controlled) { ASSERT(fpscr_controlled); return Inst(Opcode::FPSub64, {a, b}); } -Value IREmitter::FPDoubleToSingle(const Value& a, bool fpscr_controlled) { +Value A32IREmitter::FPDoubleToSingle(const Value& a, bool fpscr_controlled) { ASSERT(fpscr_controlled); return Inst(Opcode::FPDoubleToSingle, {a}); } -Value IREmitter::FPSingleToDouble(const Value& a, bool fpscr_controlled) { +Value A32IREmitter::FPSingleToDouble(const Value& a, bool fpscr_controlled) { ASSERT(fpscr_controlled); return Inst(Opcode::FPSingleToDouble, {a}); } -Value IREmitter::FPSingleToS32(const Value& a, bool round_towards_zero, bool fpscr_controlled) { +Value A32IREmitter::FPSingleToS32(const Value& a, bool round_towards_zero, bool fpscr_controlled) { ASSERT(fpscr_controlled); return Inst(Opcode::FPSingleToS32, {a, Imm1(round_towards_zero)}); } -Value IREmitter::FPSingleToU32(const Value& a, bool round_towards_zero, bool fpscr_controlled) { +Value A32IREmitter::FPSingleToU32(const Value& a, bool round_towards_zero, bool fpscr_controlled) { ASSERT(fpscr_controlled); return Inst(Opcode::FPSingleToU32, {a, Imm1(round_towards_zero)}); } -Value IREmitter::FPDoubleToS32(const Value& a, bool round_towards_zero, bool fpscr_controlled) { +Value A32IREmitter::FPDoubleToS32(const Value& a, bool round_towards_zero, bool fpscr_controlled) { ASSERT(fpscr_controlled); return Inst(Opcode::FPDoubleToS32, {a, Imm1(round_towards_zero)}); } -Value IREmitter::FPDoubleToU32(const Value& a, bool round_towards_zero, bool fpscr_controlled) { +Value A32IREmitter::FPDoubleToU32(const Value& a, bool round_towards_zero, bool fpscr_controlled) { ASSERT(fpscr_controlled); return Inst(Opcode::FPDoubleToU32, {a, Imm1(round_towards_zero)}); } -Value IREmitter::FPS32ToSingle(const Value& a, bool round_to_nearest, bool fpscr_controlled) { +Value A32IREmitter::FPS32ToSingle(const Value& a, bool round_to_nearest, bool fpscr_controlled) { ASSERT(fpscr_controlled); return Inst(Opcode::FPS32ToSingle, {a, Imm1(round_to_nearest)}); } -Value IREmitter::FPU32ToSingle(const Value& a, bool round_to_nearest, bool fpscr_controlled) { +Value A32IREmitter::FPU32ToSingle(const Value& a, bool round_to_nearest, bool fpscr_controlled) { ASSERT(fpscr_controlled); return Inst(Opcode::FPU32ToSingle, {a, Imm1(round_to_nearest)}); } -Value IREmitter::FPS32ToDouble(const Value& a, bool round_to_nearest, bool fpscr_controlled) { +Value A32IREmitter::FPS32ToDouble(const Value& a, bool round_to_nearest, bool fpscr_controlled) { ASSERT(fpscr_controlled); return Inst(Opcode::FPS32ToDouble, {a, Imm1(round_to_nearest)}); } -Value IREmitter::FPU32ToDouble(const Value& a, bool round_to_nearest, bool fpscr_controlled) { +Value A32IREmitter::FPU32ToDouble(const Value& a, bool round_to_nearest, bool fpscr_controlled) { ASSERT(fpscr_controlled); return Inst(Opcode::FPU32ToDouble, {a, Imm1(round_to_nearest)}); } -void IREmitter::ClearExclusive() { +void A32IREmitter::ClearExclusive() { Inst(Opcode::ClearExclusive, {}); } -void IREmitter::SetExclusive(const Value& vaddr, size_t byte_size) { +void A32IREmitter::SetExclusive(const Value& vaddr, size_t byte_size) { ASSERT(byte_size == 1 || byte_size == 2 || byte_size == 4 || byte_size == 8 || byte_size == 16); Inst(Opcode::SetExclusive, {vaddr, Imm8(u8(byte_size))}); } -Value IREmitter::ReadMemory8(const Value& vaddr) { +Value A32IREmitter::ReadMemory8(const Value& vaddr) { return Inst(Opcode::ReadMemory8, {vaddr}); } -Value IREmitter::ReadMemory16(const Value& vaddr) { +Value A32IREmitter::ReadMemory16(const Value& vaddr) { auto value = Inst(Opcode::ReadMemory16, {vaddr}); return current_location.EFlag() ? ByteReverseHalf(value) : value; } -Value IREmitter::ReadMemory32(const Value& vaddr) { +Value A32IREmitter::ReadMemory32(const Value& vaddr) { auto value = Inst(Opcode::ReadMemory32, {vaddr}); return current_location.EFlag() ? ByteReverseWord(value) : value; } -Value IREmitter::ReadMemory64(const Value& vaddr) { +Value A32IREmitter::ReadMemory64(const Value& vaddr) { auto value = Inst(Opcode::ReadMemory64, {vaddr}); return current_location.EFlag() ? ByteReverseDual(value) : value; } -void IREmitter::WriteMemory8(const Value& vaddr, const Value& value) { +void A32IREmitter::WriteMemory8(const Value& vaddr, const Value& value) { Inst(Opcode::WriteMemory8, {vaddr, value}); } -void IREmitter::WriteMemory16(const Value& vaddr, const Value& value) { +void A32IREmitter::WriteMemory16(const Value& vaddr, const Value& value) { if (current_location.EFlag()) { auto v = ByteReverseHalf(value); Inst(Opcode::WriteMemory16, {vaddr, v}); @@ -707,7 +707,7 @@ void IREmitter::WriteMemory16(const Value& vaddr, const Value& value) { } } -void IREmitter::WriteMemory32(const Value& vaddr, const Value& value) { +void A32IREmitter::WriteMemory32(const Value& vaddr, const Value& value) { if (current_location.EFlag()) { auto v = ByteReverseWord(value); Inst(Opcode::WriteMemory32, {vaddr, v}); @@ -716,7 +716,7 @@ void IREmitter::WriteMemory32(const Value& vaddr, const Value& value) { } } -void IREmitter::WriteMemory64(const Value& vaddr, const Value& value) { +void A32IREmitter::WriteMemory64(const Value& vaddr, const Value& value) { if (current_location.EFlag()) { auto v = ByteReverseDual(value); Inst(Opcode::WriteMemory64, {vaddr, v}); @@ -725,11 +725,11 @@ void IREmitter::WriteMemory64(const Value& vaddr, const Value& value) { } } -Value IREmitter::ExclusiveWriteMemory8(const Value& vaddr, const Value& value) { +Value A32IREmitter::ExclusiveWriteMemory8(const Value& vaddr, const Value& value) { return Inst(Opcode::ExclusiveWriteMemory8, {vaddr, value}); } -Value IREmitter::ExclusiveWriteMemory16(const Value& vaddr, const Value& value) { +Value A32IREmitter::ExclusiveWriteMemory16(const Value& vaddr, const Value& value) { if (current_location.EFlag()) { auto v = ByteReverseHalf(value); return Inst(Opcode::ExclusiveWriteMemory16, {vaddr, v}); @@ -738,7 +738,7 @@ Value IREmitter::ExclusiveWriteMemory16(const Value& vaddr, const Value& value) } } -Value IREmitter::ExclusiveWriteMemory32(const Value& vaddr, const Value& value) { +Value A32IREmitter::ExclusiveWriteMemory32(const Value& vaddr, const Value& value) { if (current_location.EFlag()) { auto v = ByteReverseWord(value); return Inst(Opcode::ExclusiveWriteMemory32, {vaddr, v}); @@ -747,7 +747,7 @@ Value IREmitter::ExclusiveWriteMemory32(const Value& vaddr, const Value& value) } } -Value IREmitter::ExclusiveWriteMemory64(const Value& vaddr, const Value& value_lo, const Value& value_hi) { +Value A32IREmitter::ExclusiveWriteMemory64(const Value& vaddr, const Value& value_lo, const Value& value_hi) { if (current_location.EFlag()) { auto vlo = ByteReverseWord(value_lo); auto vhi = ByteReverseWord(value_hi); @@ -757,7 +757,7 @@ Value IREmitter::ExclusiveWriteMemory64(const Value& vaddr, const Value& value_l } } -void IREmitter::CoprocInternalOperation(size_t coproc_no, bool two, size_t opc1, Arm::CoprocReg CRd, Arm::CoprocReg CRn, Arm::CoprocReg CRm, size_t opc2) { +void A32IREmitter::CoprocInternalOperation(size_t coproc_no, bool two, size_t opc1, A32::CoprocReg CRd, A32::CoprocReg CRn, A32::CoprocReg CRm, size_t opc2) { ASSERT(coproc_no <= 15); std::array coproc_info{static_cast(coproc_no), static_cast(two ? 1 : 0), @@ -769,7 +769,7 @@ void IREmitter::CoprocInternalOperation(size_t coproc_no, bool two, size_t opc1, Inst(Opcode::CoprocInternalOperation, {Value(coproc_info)}); } -void IREmitter::CoprocSendOneWord(size_t coproc_no, bool two, size_t opc1, Arm::CoprocReg CRn, Arm::CoprocReg CRm, size_t opc2, const Value& word) { +void A32IREmitter::CoprocSendOneWord(size_t coproc_no, bool two, size_t opc1, A32::CoprocReg CRn, A32::CoprocReg CRm, size_t opc2, const Value& word) { ASSERT(coproc_no <= 15); std::array coproc_info{static_cast(coproc_no), static_cast(two ? 1 : 0), @@ -780,7 +780,7 @@ void IREmitter::CoprocSendOneWord(size_t coproc_no, bool two, size_t opc1, Arm:: Inst(Opcode::CoprocSendOneWord, {Value(coproc_info), word}); } -void IREmitter::CoprocSendTwoWords(size_t coproc_no, bool two, size_t opc, Arm::CoprocReg CRm, const Value& word1, const Value& word2) { +void A32IREmitter::CoprocSendTwoWords(size_t coproc_no, bool two, size_t opc, A32::CoprocReg CRm, const Value& word1, const Value& word2) { ASSERT(coproc_no <= 15); std::array coproc_info{static_cast(coproc_no), static_cast(two ? 1 : 0), @@ -789,7 +789,7 @@ void IREmitter::CoprocSendTwoWords(size_t coproc_no, bool two, size_t opc, Arm:: Inst(Opcode::CoprocSendTwoWords, {Value(coproc_info), word1, word2}); } -Value IREmitter::CoprocGetOneWord(size_t coproc_no, bool two, size_t opc1, Arm::CoprocReg CRn, Arm::CoprocReg CRm, size_t opc2) { +Value A32IREmitter::CoprocGetOneWord(size_t coproc_no, bool two, size_t opc1, A32::CoprocReg CRn, A32::CoprocReg CRm, size_t opc2) { ASSERT(coproc_no <= 15); std::array coproc_info{static_cast(coproc_no), static_cast(two ? 1 : 0), @@ -800,7 +800,7 @@ Value IREmitter::CoprocGetOneWord(size_t coproc_no, bool two, size_t opc1, Arm:: return Inst(Opcode::CoprocGetOneWord, {Value(coproc_info)}); } -Value IREmitter::CoprocGetTwoWords(size_t coproc_no, bool two, size_t opc, Arm::CoprocReg CRm) { +Value A32IREmitter::CoprocGetTwoWords(size_t coproc_no, bool two, size_t opc, A32::CoprocReg CRm) { ASSERT(coproc_no <= 15); std::array coproc_info{static_cast(coproc_no), static_cast(two ? 1 : 0), @@ -809,7 +809,7 @@ Value IREmitter::CoprocGetTwoWords(size_t coproc_no, bool two, size_t opc, Arm:: return Inst(Opcode::CoprocGetTwoWords, {Value(coproc_info)}); } -void IREmitter::CoprocLoadWords(size_t coproc_no, bool two, bool long_transfer, Arm::CoprocReg CRd, const Value& address, bool has_option, u8 option) { +void A32IREmitter::CoprocLoadWords(size_t coproc_no, bool two, bool long_transfer, A32::CoprocReg CRd, const Value& address, bool has_option, u8 option) { ASSERT(coproc_no <= 15); std::array coproc_info{static_cast(coproc_no), static_cast(two ? 1 : 0), @@ -820,7 +820,7 @@ void IREmitter::CoprocLoadWords(size_t coproc_no, bool two, bool long_transfer, Inst(Opcode::CoprocLoadWords, {Value(coproc_info), address}); } -void IREmitter::CoprocStoreWords(size_t coproc_no, bool two, bool long_transfer, Arm::CoprocReg CRd, const Value& address, bool has_option, u8 option) { +void A32IREmitter::CoprocStoreWords(size_t coproc_no, bool two, bool long_transfer, A32::CoprocReg CRd, const Value& address, bool has_option, u8 option) { ASSERT(coproc_no <= 15); std::array coproc_info{static_cast(coproc_no), static_cast(two ? 1 : 0), @@ -831,15 +831,15 @@ void IREmitter::CoprocStoreWords(size_t coproc_no, bool two, bool long_transfer, Inst(Opcode::CoprocStoreWords, {Value(coproc_info), address}); } -void IREmitter::Breakpoint() { +void A32IREmitter::Breakpoint() { Inst(Opcode::Breakpoint, {}); } -void IREmitter::SetTerm(const Terminal& terminal) { +void A32IREmitter::SetTerm(const Terminal& terminal) { block.SetTerminal(terminal); } -Value IREmitter::Inst(Opcode op, std::initializer_list args) { +Value A32IREmitter::Inst(Opcode op, std::initializer_list args) { block.AppendNewInst(op, args); return Value(&block.back()); } diff --git a/src/frontend/ir/ir_emitter.h b/src/frontend/ir/ir_emitter.h index 2bda008d..7a78431d 100644 --- a/src/frontend/ir/ir_emitter.h +++ b/src/frontend/ir/ir_emitter.h @@ -11,6 +11,8 @@ #include #include "common/common_types.h" +#include "frontend/A32/location_descriptor.h" +#include "frontend/A32/types.h" #include "frontend/ir/basic_block.h" #include "frontend/ir/location_descriptor.h" #include "frontend/ir/terminal.h" @@ -33,12 +35,12 @@ enum class Opcode; * `block` is the resulting block. * The user of this class updates `current_location` as appropriate. */ -class IREmitter { +class A32IREmitter { public: - explicit IREmitter(LocationDescriptor descriptor) : block(descriptor), current_location(descriptor) {} + explicit A32IREmitter(A32::LocationDescriptor descriptor) : block(descriptor), current_location(descriptor) {} Block block; - LocationDescriptor current_location; + A32::LocationDescriptor current_location; struct ResultAndCarry { Value result; @@ -70,17 +72,17 @@ public: Value Imm32(u32 value); Value Imm64(u64 value); - Value GetRegister(Arm::Reg source_reg); - Value GetExtendedRegister(Arm::ExtReg source_reg); - void SetRegister(const Arm::Reg dest_reg, const Value& value); - void SetExtendedRegister(const Arm::ExtReg dest_reg, const Value& value); + Value GetRegister(A32::Reg source_reg); + Value GetExtendedRegister(A32::ExtReg source_reg); + void SetRegister(const A32::Reg dest_reg, const Value& value); + void SetExtendedRegister(const A32::ExtReg dest_reg, const Value& value); void ALUWritePC(const Value& value); void BranchWritePC(const Value& value); void BXWritePC(const Value& value); void LoadWritePC(const Value& value); void CallSupervisor(const Value& value); - void PushRSB(const LocationDescriptor& return_location); + void PushRSB(const A32::LocationDescriptor& return_location); Value GetCpsr(); void SetCpsr(const Value& value); @@ -225,13 +227,13 @@ public: Value ExclusiveWriteMemory32(const Value& vaddr, const Value& value); Value ExclusiveWriteMemory64(const Value& vaddr, const Value& value_lo, const Value& value_hi); - void CoprocInternalOperation(size_t coproc_no, bool two, size_t opc1, Arm::CoprocReg CRd, Arm::CoprocReg CRn, Arm::CoprocReg CRm, size_t opc2); - void CoprocSendOneWord(size_t coproc_no, bool two, size_t opc1, Arm::CoprocReg CRn, Arm::CoprocReg CRm, size_t opc2, const Value& word); - void CoprocSendTwoWords(size_t coproc_no, bool two, size_t opc, Arm::CoprocReg CRm, const Value& word1, const Value& word2); - Value CoprocGetOneWord(size_t coproc_no, bool two, size_t opc1, Arm::CoprocReg CRn, Arm::CoprocReg CRm, size_t opc2); - Value CoprocGetTwoWords(size_t coproc_no, bool two, size_t opc, Arm::CoprocReg CRm); - void CoprocLoadWords(size_t coproc_no, bool two, bool long_transfer, Arm::CoprocReg CRd, const Value& address, bool has_option, u8 option); - void CoprocStoreWords(size_t coproc_no, bool two, bool long_transfer, Arm::CoprocReg CRd, const Value& address, bool has_option, u8 option); + void CoprocInternalOperation(size_t coproc_no, bool two, size_t opc1, A32::CoprocReg CRd, A32::CoprocReg CRn, A32::CoprocReg CRm, size_t opc2); + void CoprocSendOneWord(size_t coproc_no, bool two, size_t opc1, A32::CoprocReg CRn, A32::CoprocReg CRm, size_t opc2, const Value& word); + void CoprocSendTwoWords(size_t coproc_no, bool two, size_t opc, A32::CoprocReg CRm, const Value& word1, const Value& word2); + Value CoprocGetOneWord(size_t coproc_no, bool two, size_t opc1, A32::CoprocReg CRn, A32::CoprocReg CRm, size_t opc2); + Value CoprocGetTwoWords(size_t coproc_no, bool two, size_t opc, A32::CoprocReg CRm); + void CoprocLoadWords(size_t coproc_no, bool two, bool long_transfer, A32::CoprocReg CRd, const Value& address, bool has_option, u8 option); + void CoprocStoreWords(size_t coproc_no, bool two, bool long_transfer, A32::CoprocReg CRd, const Value& address, bool has_option, u8 option); void Breakpoint(); diff --git a/src/frontend/ir/location_descriptor.cpp b/src/frontend/ir/location_descriptor.cpp index e697322d..8c36be92 100644 --- a/src/frontend/ir/location_descriptor.cpp +++ b/src/frontend/ir/location_descriptor.cpp @@ -6,17 +6,14 @@ #include #include + #include "frontend/ir/location_descriptor.h" namespace Dynarmic { namespace IR { -std::ostream& operator<<(std::ostream& o, const LocationDescriptor& loc) { - o << fmt::format("{{{},{},{},{}}}", - loc.PC(), - loc.TFlag() ? "T" : "!T", - loc.EFlag() ? "E" : "!E", - loc.FPSCR().Value()); +std::ostream& operator<<(std::ostream& o, const LocationDescriptor& descriptor) { + o << fmt::format("{{{{}}}}", descriptor.value); return o; } diff --git a/src/frontend/ir/location_descriptor.h b/src/frontend/ir/location_descriptor.h index cf4f3ff2..7d222855 100644 --- a/src/frontend/ir/location_descriptor.h +++ b/src/frontend/ir/location_descriptor.h @@ -6,110 +6,42 @@ #pragma once -#include #include -#include + #include "common/common_types.h" -#include "frontend/arm/FPSCR.h" -#include "frontend/arm/PSR.h" namespace Dynarmic { namespace IR { -/** - * LocationDescriptor describes the location of a basic block. - * The location is not solely based on the PC because other flags influence the way - * instructions should be translated. The CPSR.T flag is most notable since it - * tells us if the processor is in Thumb or Arm mode. - */ class LocationDescriptor { public: - // Indicates bits that should be preserved within descriptors. - static constexpr u32 CPSR_MODE_MASK = 0x00000220; - static constexpr u32 FPSCR_MODE_MASK = 0x03F79F00; - - LocationDescriptor(u32 arm_pc, Arm::PSR cpsr, Arm::FPSCR fpscr) - : arm_pc(arm_pc), cpsr(cpsr.Value() & CPSR_MODE_MASK), fpscr(fpscr.Value() & FPSCR_MODE_MASK) {} - - u32 PC() const { return arm_pc; } - bool TFlag() const { return cpsr.T(); } - bool EFlag() const { return cpsr.E(); } - - Arm::PSR CPSR() const { return cpsr; } - Arm::FPSCR FPSCR() const { return fpscr; } - bool operator == (const LocationDescriptor& o) const { - return std::tie(arm_pc, cpsr, fpscr) == std::tie(o.arm_pc, o.cpsr, o.fpscr); + return value == o.value; } bool operator != (const LocationDescriptor& o) const { return !operator==(o); } - LocationDescriptor SetPC(u32 new_arm_pc) const { - return LocationDescriptor(new_arm_pc, cpsr, fpscr); - } - - LocationDescriptor AdvancePC(int amount) const { - return LocationDescriptor(static_cast(arm_pc + amount), cpsr, fpscr); - } - - LocationDescriptor SetTFlag(bool new_tflag) const { - Arm::PSR new_cpsr = cpsr; - new_cpsr.T(new_tflag); - - return LocationDescriptor(arm_pc, new_cpsr, fpscr); - } - - LocationDescriptor SetEFlag(bool new_eflag) const { - Arm::PSR new_cpsr = cpsr; - new_cpsr.E(new_eflag); - - return LocationDescriptor(arm_pc, new_cpsr, fpscr); - } - - LocationDescriptor SetFPSCR(u32 new_fpscr) const { - return LocationDescriptor(arm_pc, cpsr, Arm::FPSCR{new_fpscr & FPSCR_MODE_MASK}); - } - - u64 UniqueHash() const { - // This value MUST BE UNIQUE. - // This calculation has to match up with EmitX64::EmitTerminalPopRSBHint - u64 pc_u64 = u64(arm_pc) << 32; - u64 fpscr_u64 = u64(fpscr.Value()); - u64 t_u64 = cpsr.T() ? 1 : 0; - u64 e_u64 = cpsr.E() ? 2 : 0; - return pc_u64 | fpscr_u64 | t_u64 | e_u64; - } - -private: - u32 arm_pc; ///< Current program counter value. - Arm::PSR cpsr; ///< Current program status register. - Arm::FPSCR fpscr; ///< Floating point status control register. + u64 value; }; -/** - * Provides a string representation of a LocationDescriptor. - * - * @param o Output stream - * @param descriptor The descriptor to get a string representation of - */ std::ostream& operator<<(std::ostream& o, const LocationDescriptor& descriptor); -} // namespace IR +} // namespace A32 } // namespace Dynarmic namespace std { template <> struct less { bool operator()(const Dynarmic::IR::LocationDescriptor& x, const Dynarmic::IR::LocationDescriptor& y) const { - return x.UniqueHash() < y.UniqueHash(); + return x.value < y.value; } }; template <> struct hash { size_t operator()(const Dynarmic::IR::LocationDescriptor& x) const { - return std::hash()(x.UniqueHash()); + return std::hash()(x.value); } }; } // namespace std diff --git a/src/frontend/ir/terminal.h b/src/frontend/ir/terminal.h index d719c927..7cccdd3d 100644 --- a/src/frontend/ir/terminal.h +++ b/src/frontend/ir/terminal.h @@ -9,6 +9,7 @@ #include #include "common/common_types.h" +#include "frontend/ir/cond.h" #include "frontend/ir/location_descriptor.h" namespace Dynarmic { @@ -83,8 +84,8 @@ using Terminal = boost::variant< * on the run-time state of the ARM flags. */ struct If { - If(Arm::Cond if_, Terminal then_, Terminal else_) : if_(if_), then_(then_), else_(else_) {} - Arm::Cond if_; + If(Cond if_, Terminal then_, Terminal else_) : if_(if_), then_(then_), else_(else_) {} + Cond if_; Terminal then_; Terminal else_; }; diff --git a/src/frontend/ir/value.cpp b/src/frontend/ir/value.cpp index 50ea6e25..cf533727 100644 --- a/src/frontend/ir/value.cpp +++ b/src/frontend/ir/value.cpp @@ -15,12 +15,12 @@ Value::Value(Inst* value) : type(Type::Opaque) { inner.inst = value; } -Value::Value(Arm::Reg value) : type(Type::RegRef) { - inner.imm_regref = value; +Value::Value(A32::Reg value) : type(Type::RegRef) { + inner.imm_a32regref = value; } -Value::Value(Arm::ExtReg value) : type(Type::ExtRegRef) { - inner.imm_extregref = value; +Value::Value(A32::ExtReg value) : type(Type::ExtRegRef) { + inner.imm_a32extregref = value; } Value::Value(bool value) : type(Type::U1) { @@ -68,14 +68,14 @@ Type Value::GetType() const { return type; } -Arm::Reg Value::GetRegRef() const { +A32::Reg Value::GetA32RegRef() const { ASSERT(type == Type::RegRef); - return inner.imm_regref; + return inner.imm_a32regref; } -Arm::ExtReg Value::GetExtRegRef() const { +A32::ExtReg Value::GetA32ExtRegRef() const { ASSERT(type == Type::ExtRegRef); - return inner.imm_extregref; + return inner.imm_a32extregref; } Inst* Value::GetInst() const { diff --git a/src/frontend/ir/value.h b/src/frontend/ir/value.h index 554681ac..033cc528 100644 --- a/src/frontend/ir/value.h +++ b/src/frontend/ir/value.h @@ -7,7 +7,7 @@ #pragma once #include "common/common_types.h" -#include "frontend/arm/types.h" +#include "frontend/A32/types.h" namespace Dynarmic { namespace IR { @@ -22,8 +22,8 @@ class Value final { public: Value() : type(Type::Void) {} explicit Value(Inst* value); - explicit Value(Arm::Reg value); - explicit Value(Arm::ExtReg value); + explicit Value(A32::Reg value); + explicit Value(A32::ExtReg value); explicit Value(bool value); explicit Value(u8 value); explicit Value(u16 value); @@ -36,8 +36,8 @@ public: Type GetType() const; Inst* GetInst() const; - Arm::Reg GetRegRef() const; - Arm::ExtReg GetExtRegRef() const; + A32::Reg GetA32RegRef() const; + A32::ExtReg GetA32ExtRegRef() const; bool GetU1() const; u8 GetU8() const; u16 GetU16() const; @@ -50,8 +50,8 @@ private: union { Inst* inst; // type == Type::Opaque - Arm::Reg imm_regref; - Arm::ExtReg imm_extregref; + A32::Reg imm_a32regref; + A32::ExtReg imm_a32extregref; bool imm_u1; u8 imm_u8; u16 imm_u16; diff --git a/src/frontend/translate/translate.cpp b/src/frontend/translate/translate.cpp deleted file mode 100644 index 57ee49f4..00000000 --- a/src/frontend/translate/translate.cpp +++ /dev/null @@ -1,22 +0,0 @@ -/* This file is part of the dynarmic project. - * Copyright (c) 2016 MerryMage - * This software may be used and distributed according to the terms of the GNU - * General Public License version 2 or any later version. - */ - -#include "frontend/ir/basic_block.h" -#include "frontend/ir/location_descriptor.h" -#include "frontend/translate/translate.h" - -namespace Dynarmic { -namespace Arm { - -IR::Block TranslateArm(IR::LocationDescriptor descriptor, MemoryReadCodeFuncType memory_read_code); -IR::Block TranslateThumb(IR::LocationDescriptor descriptor, MemoryReadCodeFuncType memory_read_code); - -IR::Block Translate(IR::LocationDescriptor descriptor, MemoryReadCodeFuncType memory_read_code) { - return (descriptor.TFlag() ? TranslateThumb : TranslateArm)(descriptor, memory_read_code); -} - -} // namespace Arm -} // namespace Dynarmic diff --git a/src/ir_opt/get_set_elimination_pass.cpp b/src/ir_opt/get_set_elimination_pass.cpp index 2fbefabb..da4172e4 100644 --- a/src/ir_opt/get_set_elimination_pass.cpp +++ b/src/ir_opt/get_set_elimination_pass.cpp @@ -55,23 +55,23 @@ void GetSetElimination(IR::Block& block) { for (auto inst = block.begin(); inst != block.end(); ++inst) { switch (inst->GetOpcode()) { case IR::Opcode::SetRegister: { - Arm::Reg reg = inst->GetArg(0).GetRegRef(); - if (reg == Arm::Reg::PC) + A32::Reg reg = inst->GetArg(0).GetA32RegRef(); + if (reg == A32::Reg::PC) break; size_t reg_index = static_cast(reg); do_set(reg_info[reg_index], inst->GetArg(1), inst); break; } case IR::Opcode::GetRegister: { - Arm::Reg reg = inst->GetArg(0).GetRegRef(); - ASSERT(reg != Arm::Reg::PC); + A32::Reg reg = inst->GetArg(0).GetA32RegRef(); + ASSERT(reg != A32::Reg::PC); size_t reg_index = static_cast(reg); do_get(reg_info[reg_index], inst); break; } case IR::Opcode::SetExtendedRegister32: { - Arm::ExtReg reg = inst->GetArg(0).GetExtRegRef(); - size_t reg_index = Arm::RegNumber(reg); + A32::ExtReg reg = inst->GetArg(0).GetA32ExtRegRef(); + size_t reg_index = A32::RegNumber(reg); do_set(ext_reg_singles_info[reg_index], inst->GetArg(1), inst); size_t doubles_reg_index = reg_index / 2; @@ -81,8 +81,8 @@ void GetSetElimination(IR::Block& block) { break; } case IR::Opcode::GetExtendedRegister32: { - Arm::ExtReg reg = inst->GetArg(0).GetExtRegRef(); - size_t reg_index = Arm::RegNumber(reg); + A32::ExtReg reg = inst->GetArg(0).GetA32ExtRegRef(); + size_t reg_index = A32::RegNumber(reg); do_get(ext_reg_singles_info[reg_index], inst); size_t doubles_reg_index = reg_index / 2; @@ -92,8 +92,8 @@ void GetSetElimination(IR::Block& block) { break; } case IR::Opcode::SetExtendedRegister64: { - Arm::ExtReg reg = inst->GetArg(0).GetExtRegRef(); - size_t reg_index = Arm::RegNumber(reg); + A32::ExtReg reg = inst->GetArg(0).GetA32ExtRegRef(); + size_t reg_index = A32::RegNumber(reg); do_set(ext_reg_doubles_info[reg_index], inst->GetArg(1), inst); size_t singles_reg_index = reg_index * 2; @@ -104,8 +104,8 @@ void GetSetElimination(IR::Block& block) { break; } case IR::Opcode::GetExtendedRegister64: { - Arm::ExtReg reg = inst->GetArg(0).GetExtRegRef(); - size_t reg_index = Arm::RegNumber(reg); + A32::ExtReg reg = inst->GetArg(0).GetA32ExtRegRef(); + size_t reg_index = A32::RegNumber(reg); do_get(ext_reg_doubles_info[reg_index], inst); size_t singles_reg_index = reg_index * 2; diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 2097f481..7e779b0d 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,34 +1,31 @@ add_executable(dynarmic_tests - # Source files arm/fuzz_arm.cpp arm/fuzz_thumb.cpp arm/test_arm_disassembler.cpp arm/test_thumb_instructions.cpp main.cpp + rand_int.h skyeye_interpreter/dyncom/arm_dyncom_dec.cpp + skyeye_interpreter/dyncom/arm_dyncom_dec.h skyeye_interpreter/dyncom/arm_dyncom_interpreter.cpp + skyeye_interpreter/dyncom/arm_dyncom_interpreter.h + skyeye_interpreter/dyncom/arm_dyncom_run.h skyeye_interpreter/dyncom/arm_dyncom_thumb.cpp + skyeye_interpreter/dyncom/arm_dyncom_thumb.h skyeye_interpreter/dyncom/arm_dyncom_trans.cpp + skyeye_interpreter/dyncom/arm_dyncom_trans.h + skyeye_interpreter/skyeye_common/arm_regformat.h skyeye_interpreter/skyeye_common/armstate.cpp + skyeye_interpreter/skyeye_common/armstate.h skyeye_interpreter/skyeye_common/armsupp.cpp + skyeye_interpreter/skyeye_common/armsupp.h + skyeye_interpreter/skyeye_common/vfp/asm_vfp.h skyeye_interpreter/skyeye_common/vfp/vfp.cpp + skyeye_interpreter/skyeye_common/vfp/vfp.h + skyeye_interpreter/skyeye_common/vfp/vfp_helper.h skyeye_interpreter/skyeye_common/vfp/vfpdouble.cpp skyeye_interpreter/skyeye_common/vfp/vfpinstr.cpp skyeye_interpreter/skyeye_common/vfp/vfpsingle.cpp - - # Header files - rand_int.h - skyeye_interpreter/dyncom/arm_dyncom_dec.h - skyeye_interpreter/dyncom/arm_dyncom_interpreter.h - skyeye_interpreter/dyncom/arm_dyncom_run.h - skyeye_interpreter/dyncom/arm_dyncom_thumb.h - skyeye_interpreter/dyncom/arm_dyncom_trans.h - skyeye_interpreter/skyeye_common/arm_regformat.h - skyeye_interpreter/skyeye_common/armstate.h - skyeye_interpreter/skyeye_common/armsupp.h - skyeye_interpreter/skyeye_common/vfp/asm_vfp.h - skyeye_interpreter/skyeye_common/vfp/vfp.h - skyeye_interpreter/skyeye_common/vfp/vfp_helper.h ) include(CreateDirectoryGroups) diff --git a/tests/arm/fuzz_arm.cpp b/tests/arm/fuzz_arm.cpp index 74547148..f41fb31b 100644 --- a/tests/arm/fuzz_arm.cpp +++ b/tests/arm/fuzz_arm.cpp @@ -19,10 +19,13 @@ #include "common/bit_util.h" #include "common/common_types.h" -#include "frontend/disassembler/disassembler.h" +#include "frontend/A32/disassembler/disassembler.h" +#include "frontend/A32/FPSCR.h" +#include "frontend/A32/location_descriptor.h" +#include "frontend/A32/PSR.h" +#include "frontend/A32/translate/translate.h" #include "frontend/ir/basic_block.h" #include "frontend/ir/location_descriptor.h" -#include "frontend/translate/translate.h" #include "ir_opt/passes.h" #include "rand_int.h" #include "skyeye_interpreter/dyncom/arm_dyncom_interpreter.h" @@ -270,12 +273,12 @@ void FuzzJitArm(const size_t instruction_count, const size_t instructions_to_exe printf("\nInstruction Listing: \n"); for (size_t i = 0; i < instruction_count; i++) { - printf("%x: %s\n", code_mem[i], Dynarmic::Arm::DisassembleArm(code_mem[i]).c_str()); + printf("%x: %s\n", code_mem[i], Dynarmic::A32::DisassembleArm(code_mem[i]).c_str()); } printf("\nInitial Register Listing: \n"); for (int i = 0; i <= 15; i++) { - auto reg = Dynarmic::Arm::RegToString(static_cast(i)); + auto reg = Dynarmic::A32::RegToString(static_cast(i)); printf("%4s: %08x\n", reg, initial_regs[i]); } printf("CPSR: %08x\n", initial_cpsr); @@ -287,7 +290,7 @@ void FuzzJitArm(const size_t instruction_count, const size_t instructions_to_exe printf("\nFinal Register Listing: \n"); printf(" interp jit\n"); for (int i = 0; i <= 15; i++) { - auto reg = Dynarmic::Arm::RegToString(static_cast(i)); + auto reg = Dynarmic::A32::RegToString(static_cast(i)); printf("%4s: %08x %08x %s\n", reg, interp.Reg[i], jit.Regs()[i], interp.Reg[i] != jit.Regs()[i] ? "*" : ""); } printf("CPSR: %08x %08x %s\n", interp.Cpsr, jit.Cpsr(), interp.Cpsr != jit.Cpsr() ? "*" : ""); @@ -308,8 +311,8 @@ void FuzzJitArm(const size_t instruction_count, const size_t instructions_to_exe size_t num_insts = 0; while (num_insts < instructions_to_execute_count) { - Dynarmic::IR::LocationDescriptor descriptor = {u32(num_insts * 4), Dynarmic::Arm::PSR{}, Dynarmic::Arm::FPSCR{}}; - Dynarmic::IR::Block ir_block = Dynarmic::Arm::Translate(descriptor, &MemoryReadCode); + Dynarmic::A32::LocationDescriptor descriptor = {u32(num_insts * 4), Dynarmic::A32::PSR{}, Dynarmic::A32::FPSCR{}}; + Dynarmic::IR::Block ir_block = Dynarmic::A32::Translate(descriptor, &MemoryReadCode); Dynarmic::Optimization::GetSetElimination(ir_block); Dynarmic::Optimization::DeadCodeElimination(ir_block); Dynarmic::Optimization::VerificationPass(ir_block); diff --git a/tests/arm/fuzz_thumb.cpp b/tests/arm/fuzz_thumb.cpp index 519ce013..0c8ddde0 100644 --- a/tests/arm/fuzz_thumb.cpp +++ b/tests/arm/fuzz_thumb.cpp @@ -18,9 +18,12 @@ #include "common/bit_util.h" #include "common/common_types.h" -#include "frontend/disassembler/disassembler.h" +#include "frontend/A32/disassembler/disassembler.h" +#include "frontend/A32/FPSCR.h" +#include "frontend/A32/location_descriptor.h" +#include "frontend/A32/PSR.h" +#include "frontend/A32/translate/translate.h" #include "frontend/ir/basic_block.h" -#include "frontend/translate/translate.h" #include "ir_opt/passes.h" #include "rand_int.h" #include "skyeye_interpreter/dyncom/arm_dyncom_interpreter.h" @@ -230,7 +233,7 @@ void FuzzJitThumb(const size_t instruction_count, const size_t instructions_to_e printf("\nInstruction Listing: \n"); for (size_t i = 0; i < instruction_count; i++) { - printf("%s\n", Dynarmic::Arm::DisassembleThumb16(code_mem[i]).c_str()); + printf("%s\n", Dynarmic::A32::DisassembleThumb16(code_mem[i]).c_str()); } printf("\nInitial Register Listing: \n"); @@ -255,13 +258,13 @@ void FuzzJitThumb(const size_t instruction_count, const size_t instructions_to_e printf("%zu [%x] = %" PRIu64 "\n", record.size, record.address, record.data); } - Dynarmic::Arm::PSR cpsr; + Dynarmic::A32::PSR cpsr; cpsr.T(true); size_t num_insts = 0; while (num_insts < instructions_to_execute_count) { - Dynarmic::IR::LocationDescriptor descriptor = {u32(num_insts * 4), cpsr, Dynarmic::Arm::FPSCR{}}; - Dynarmic::IR::Block ir_block = Dynarmic::Arm::Translate(descriptor, &MemoryReadCode); + Dynarmic::A32::LocationDescriptor descriptor = {u32(num_insts * 4), cpsr, Dynarmic::A32::FPSCR{}}; + Dynarmic::IR::Block ir_block = Dynarmic::A32::Translate(descriptor, &MemoryReadCode); Dynarmic::Optimization::GetSetElimination(ir_block); Dynarmic::Optimization::DeadCodeElimination(ir_block); Dynarmic::Optimization::VerificationPass(ir_block); diff --git a/tests/arm/test_arm_disassembler.cpp b/tests/arm/test_arm_disassembler.cpp index d81d48cb..daab197b 100644 --- a/tests/arm/test_arm_disassembler.cpp +++ b/tests/arm/test_arm_disassembler.cpp @@ -6,9 +6,9 @@ #include -#include "frontend/disassembler/disassembler.h" +#include "frontend/A32/disassembler/disassembler.h" -using Dynarmic::Arm::DisassembleArm; +using Dynarmic::A32::DisassembleArm; TEST_CASE("Disassemble branch instructions", "[arm][disassembler]") { REQUIRE(DisassembleArm(0xEAFFFFFE) == "b +#0");