From 8ae12d80053c4b69d0f8a3af470b6f0d0d8d1893 Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Sun, 7 Jun 2015 19:53:05 -0500 Subject: [AArch64] Add ASIMD LDR/STR with register offset --- Source/Core/Common/Arm64Emitter.cpp | 55 +++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) (limited to 'Source/Core/Common/Arm64Emitter.cpp') diff --git a/Source/Core/Common/Arm64Emitter.cpp b/Source/Core/Common/Arm64Emitter.cpp index 8a93a7a0bd..0860d53cf0 100644 --- a/Source/Core/Common/Arm64Emitter.cpp +++ b/Source/Core/Common/Arm64Emitter.cpp @@ -2439,6 +2439,51 @@ void ARM64FloatEmitter::EncodeLoadStorePair(u32 size, bool load, IndexType type, } +void ARM64FloatEmitter::EncodeLoadStoreRegisterOffset(u32 size, bool load, ARM64Reg Rt, ARM64Reg Rn, ArithOption Rm) +{ + _assert_msg_(DYNA_REC, Rm.GetType() == ArithOption::TYPE_EXTENDEDREG, "%s must contain an extended reg as Rm!", __FUNCTION__); + + u32 encoded_size = 0; + u32 encoded_op = 0; + bool shift = false; + + if (size == 8) + { + encoded_size = 0; + encoded_op = 0; + } + else if (size == 16) + { + encoded_size = 1; + encoded_op = 0; + } + else if (size == 32) + { + encoded_size = 2; + encoded_op = 0; + } + else if (size == 64) + { + encoded_size = 3; + encoded_op = 0; + } + else if (size == 128) + { + encoded_size = 0; + encoded_op = 2; + } + + if (load) + encoded_op |= 1; + + Rt = DecodeReg(Rt); + Rn = DecodeReg(Rn); + ARM64Reg decoded_Rm = DecodeReg(Rm.GetReg()); + + Write32((encoded_size << 30) | (encoded_op << 22) | (0b111100001 << 21) | (decoded_Rm << 16) | \ + Rm.GetData() | (1 << 11) | (Rn << 5) | Rt); +} + void ARM64FloatEmitter::LDR(u8 size, IndexType type, ARM64Reg Rt, ARM64Reg Rn, s32 imm) { EmitLoadStoreImmediate(size, 1, type, Rt, Rn, imm); @@ -2840,6 +2885,16 @@ void ARM64FloatEmitter::STP(u8 size, IndexType type, ARM64Reg Rt, ARM64Reg Rt2, EncodeLoadStorePair(size, false, type, Rt, Rt2, Rn, imm); } +// Loadstore register offset +void ARM64FloatEmitter::STR(u8 size, ARM64Reg Rt, ARM64Reg Rn, ArithOption Rm) +{ + EncodeLoadStoreRegisterOffset(size, false, Rt, Rn, Rm); +} +void ARM64FloatEmitter::LDR(u8 size, ARM64Reg Rt, ARM64Reg Rn, ArithOption Rm) +{ + EncodeLoadStoreRegisterOffset(size, true, Rt, Rn, Rm); +} + void ARM64FloatEmitter::FABS(ARM64Reg Rd, ARM64Reg Rn) { EmitScalar1Source(0, 0, IsDouble(Rd), 1, Rd, Rn); -- cgit v1.2.3