mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-02-15 08:49:20 +01:00
[AArch64] Implement loadstore unscaled.
This commit is contained in:
parent
2ebe57ed3f
commit
120df4c688
@ -540,6 +540,15 @@ void ARM64XEmitter::EncodeAddressInst(u32 op, ARM64Reg Rd, s32 imm)
|
|||||||
((imm & 0x1FFFFC) << 3) | Rd);
|
((imm & 0x1FFFFC) << 3) | Rd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ARM64XEmitter::EncodeLoadStoreUnscaled(u32 size, u32 op, ARM64Reg Rt, ARM64Reg Rn, s32 imm)
|
||||||
|
{
|
||||||
|
_assert_msg_(DYNA_REC, !(imm < -256 || imm > 255), "%s received too large offset: %d", __FUNCTION__, imm);
|
||||||
|
Rt = DecodeReg(Rt);
|
||||||
|
Rn = DecodeReg(Rn);
|
||||||
|
|
||||||
|
Write32((size << 30) | (0b111 << 27) | (op << 22) | ((imm & 0x1FF) << 12) | (Rn << 5) | Rt);
|
||||||
|
}
|
||||||
|
|
||||||
// FixupBranch branching
|
// FixupBranch branching
|
||||||
void ARM64XEmitter::SetJumpTarget(FixupBranch const& branch)
|
void ARM64XEmitter::SetJumpTarget(FixupBranch const& branch)
|
||||||
{
|
{
|
||||||
@ -1424,6 +1433,45 @@ void ARM64XEmitter::PRFM(ARM64Reg Rt, ARM64Reg Rn, ArithOption Rm)
|
|||||||
EncodeLoadStoreRegisterOffset(3, 2, Rt, Rn, Rm);
|
EncodeLoadStoreRegisterOffset(3, 2, Rt, Rn, Rm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Load/Store register (unscaled offset)
|
||||||
|
void ARM64XEmitter::STURB(ARM64Reg Rt, ARM64Reg Rn, s32 imm)
|
||||||
|
{
|
||||||
|
EncodeLoadStoreUnscaled(0, 0, Rt, Rn, imm);
|
||||||
|
}
|
||||||
|
void ARM64XEmitter::LDURB(ARM64Reg Rt, ARM64Reg Rn, s32 imm)
|
||||||
|
{
|
||||||
|
EncodeLoadStoreUnscaled(0, 1, Rt, Rn, imm);
|
||||||
|
}
|
||||||
|
void ARM64XEmitter::LDURSB(ARM64Reg Rt, ARM64Reg Rn, s32 imm)
|
||||||
|
{
|
||||||
|
EncodeLoadStoreUnscaled(0, Is64Bit(Rt) ? 2 : 3, Rt, Rn, imm);
|
||||||
|
}
|
||||||
|
void ARM64XEmitter::STURH(ARM64Reg Rt, ARM64Reg Rn, s32 imm)
|
||||||
|
{
|
||||||
|
EncodeLoadStoreUnscaled(1, 0, Rt, Rn, imm);
|
||||||
|
}
|
||||||
|
void ARM64XEmitter::LDURH(ARM64Reg Rt, ARM64Reg Rn, s32 imm)
|
||||||
|
{
|
||||||
|
EncodeLoadStoreUnscaled(1, 1, Rt, Rn, imm);
|
||||||
|
}
|
||||||
|
void ARM64XEmitter::LDURSH(ARM64Reg Rt, ARM64Reg Rn, s32 imm)
|
||||||
|
{
|
||||||
|
EncodeLoadStoreUnscaled(1, Is64Bit(Rt) ? 2 : 3, Rt, Rn, imm);
|
||||||
|
}
|
||||||
|
void ARM64XEmitter::STUR(ARM64Reg Rt, ARM64Reg Rn, s32 imm)
|
||||||
|
{
|
||||||
|
EncodeLoadStoreUnscaled(Is64Bit(Rt) ? 3 : 2, 0, Rt, Rn, imm);
|
||||||
|
}
|
||||||
|
void ARM64XEmitter::LDUR(ARM64Reg Rt, ARM64Reg Rn, s32 imm)
|
||||||
|
{
|
||||||
|
EncodeLoadStoreUnscaled(Is64Bit(Rt) ? 3 : 2, 1, Rt, Rn, imm);
|
||||||
|
}
|
||||||
|
void ARM64XEmitter::LDURSW(ARM64Reg Rt, ARM64Reg Rn, s32 imm)
|
||||||
|
{
|
||||||
|
_assert_msg_(DYNA_REC, !Is64Bit(Rt), "%s must have a 64bit destination register!", __FUNCTION__);
|
||||||
|
EncodeLoadStoreUnscaled(2, 2, Rt, Rn, imm);
|
||||||
|
}
|
||||||
|
|
||||||
// Address of label/page PC-relative
|
// Address of label/page PC-relative
|
||||||
void ARM64XEmitter::ADR(ARM64Reg Rd, s32 imm)
|
void ARM64XEmitter::ADR(ARM64Reg Rd, s32 imm)
|
||||||
{
|
{
|
||||||
@ -1866,6 +1914,15 @@ void ARM64FloatEmitter::EmitVectorxElement(bool U, u32 size, bool L, u32 opcode,
|
|||||||
(Rm << 16) | (opcode << 12) | (H << 11) | (Rn << 5) | Rd);
|
(Rm << 16) | (opcode << 12) | (H << 11) | (Rn << 5) | Rd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ARM64FloatEmitter::EmitLoadStoreUnscaled(u32 size, u32 op, ARM64Reg Rt, ARM64Reg Rn, s32 imm)
|
||||||
|
{
|
||||||
|
_assert_msg_(DYNA_REC, !(imm < -256 || imm > 255), "%s received too large offset: %d", __FUNCTION__, imm);
|
||||||
|
Rt = DecodeReg(Rt);
|
||||||
|
Rn = DecodeReg(Rn);
|
||||||
|
|
||||||
|
Write32((size << 30) | (0b1111 << 26) | (op << 22) | ((imm & 0x1FF) << 12) | (Rn << 5) | Rt);
|
||||||
|
}
|
||||||
|
|
||||||
void ARM64FloatEmitter::LDR(u8 size, IndexType type, ARM64Reg Rt, ARM64Reg Rn, s32 imm)
|
void ARM64FloatEmitter::LDR(u8 size, IndexType type, ARM64Reg Rt, ARM64Reg Rn, s32 imm)
|
||||||
{
|
{
|
||||||
EmitLoadStoreImmediate(size, 1, type, Rt, Rn, imm);
|
EmitLoadStoreImmediate(size, 1, type, Rt, Rn, imm);
|
||||||
@ -1875,6 +1932,75 @@ void ARM64FloatEmitter::STR(u8 size, IndexType type, ARM64Reg Rt, ARM64Reg Rn, s
|
|||||||
EmitLoadStoreImmediate(size, 0, type, Rt, Rn, imm);
|
EmitLoadStoreImmediate(size, 0, type, Rt, Rn, imm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Loadstore unscaled
|
||||||
|
void ARM64FloatEmitter::LDUR(u8 size, ARM64Reg Rt, ARM64Reg Rn, s32 imm)
|
||||||
|
{
|
||||||
|
u32 encoded_size = 0;
|
||||||
|
u32 encoded_op = 0;
|
||||||
|
|
||||||
|
if (size == 8)
|
||||||
|
{
|
||||||
|
encoded_size = 0;
|
||||||
|
encoded_op = 1;
|
||||||
|
}
|
||||||
|
else if (size == 16)
|
||||||
|
{
|
||||||
|
encoded_size = 1;
|
||||||
|
encoded_op = 1;
|
||||||
|
}
|
||||||
|
else if (size == 32)
|
||||||
|
{
|
||||||
|
encoded_size = 2;
|
||||||
|
encoded_op = 1;
|
||||||
|
}
|
||||||
|
else if (size == 64)
|
||||||
|
{
|
||||||
|
encoded_size = 3;
|
||||||
|
encoded_op = 1;
|
||||||
|
}
|
||||||
|
else if (size == 128)
|
||||||
|
{
|
||||||
|
encoded_size = 0;
|
||||||
|
encoded_op = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
EmitLoadStoreUnscaled(encoded_size, encoded_op, Rt, Rn, imm);
|
||||||
|
}
|
||||||
|
void ARM64FloatEmitter::STUR(u8 size, ARM64Reg Rt, ARM64Reg Rn, s32 imm)
|
||||||
|
{
|
||||||
|
u32 encoded_size = 0;
|
||||||
|
u32 encoded_op = 0;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
EmitLoadStoreUnscaled(encoded_size, encoded_op, Rt, Rn, imm);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// Loadstore single structure
|
// Loadstore single structure
|
||||||
void ARM64FloatEmitter::LD1(u8 size, ARM64Reg Rt, u8 index, ARM64Reg Rn)
|
void ARM64FloatEmitter::LD1(u8 size, ARM64Reg Rt, u8 index, ARM64Reg Rn)
|
||||||
{
|
{
|
||||||
|
@ -334,6 +334,7 @@ private:
|
|||||||
void EncodeLogicalImmInst(u32 op, ARM64Reg Rd, ARM64Reg Rn, u32 immr, u32 imms);
|
void EncodeLogicalImmInst(u32 op, ARM64Reg Rd, ARM64Reg Rn, u32 immr, u32 imms);
|
||||||
void EncodeLoadStorePair(u32 op, u32 load, IndexType type, ARM64Reg Rt, ARM64Reg Rt2, ARM64Reg Rn, s32 imm);
|
void EncodeLoadStorePair(u32 op, u32 load, IndexType type, ARM64Reg Rt, ARM64Reg Rt2, ARM64Reg Rn, s32 imm);
|
||||||
void EncodeAddressInst(u32 op, ARM64Reg Rd, s32 imm);
|
void EncodeAddressInst(u32 op, ARM64Reg Rd, s32 imm);
|
||||||
|
void EncodeLoadStoreUnscaled(u32 size, u32 op, ARM64Reg Rt, ARM64Reg Rn, s32 imm);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
inline void Write32(u32 value)
|
inline void Write32(u32 value)
|
||||||
@ -585,6 +586,17 @@ public:
|
|||||||
void LDRSW(ARM64Reg Rt, ARM64Reg Rn, ArithOption Rm);
|
void LDRSW(ARM64Reg Rt, ARM64Reg Rn, ArithOption Rm);
|
||||||
void PRFM(ARM64Reg Rt, ARM64Reg Rn, ArithOption Rm);
|
void PRFM(ARM64Reg Rt, ARM64Reg Rn, ArithOption Rm);
|
||||||
|
|
||||||
|
// Load/Store register (unscaled offset)
|
||||||
|
void STURB(ARM64Reg Rt, ARM64Reg Rn, s32 imm);
|
||||||
|
void LDURB(ARM64Reg Rt, ARM64Reg Rn, s32 imm);
|
||||||
|
void LDURSB(ARM64Reg Rt, ARM64Reg Rn, s32 imm);
|
||||||
|
void STURH(ARM64Reg Rt, ARM64Reg Rn, s32 imm);
|
||||||
|
void LDURH(ARM64Reg Rt, ARM64Reg Rn, s32 imm);
|
||||||
|
void LDURSH(ARM64Reg Rt, ARM64Reg Rn, s32 imm);
|
||||||
|
void STUR(ARM64Reg Rt, ARM64Reg Rn, s32 imm);
|
||||||
|
void LDUR(ARM64Reg Rt, ARM64Reg Rn, s32 imm);
|
||||||
|
void LDURSW(ARM64Reg Rt, ARM64Reg Rn, s32 imm);
|
||||||
|
|
||||||
// Load/Store pair
|
// Load/Store pair
|
||||||
void LDP(IndexType type, ARM64Reg Rt, ARM64Reg Rt2, ARM64Reg Rn, s32 imm);
|
void LDP(IndexType type, ARM64Reg Rt, ARM64Reg Rt2, ARM64Reg Rn, s32 imm);
|
||||||
void LDPSW(IndexType type, ARM64Reg Rt, ARM64Reg Rt2, ARM64Reg Rn, s32 imm);
|
void LDPSW(IndexType type, ARM64Reg Rt, ARM64Reg Rt2, ARM64Reg Rn, s32 imm);
|
||||||
@ -633,6 +645,10 @@ public:
|
|||||||
void LDR(u8 size, IndexType type, ARM64Reg Rt, ARM64Reg Rn, s32 imm);
|
void LDR(u8 size, IndexType type, ARM64Reg Rt, ARM64Reg Rn, s32 imm);
|
||||||
void STR(u8 size, IndexType type, ARM64Reg Rt, ARM64Reg Rn, s32 imm);
|
void STR(u8 size, IndexType type, ARM64Reg Rt, ARM64Reg Rn, s32 imm);
|
||||||
|
|
||||||
|
// Loadstore unscaled
|
||||||
|
void LDUR(u8 size, ARM64Reg Rt, ARM64Reg Rn, s32 imm);
|
||||||
|
void STUR(u8 size, ARM64Reg Rt, ARM64Reg Rn, s32 imm);
|
||||||
|
|
||||||
// Loadstore single structure
|
// Loadstore single structure
|
||||||
void LD1(u8 size, ARM64Reg Rt, u8 index, ARM64Reg Rn);
|
void LD1(u8 size, ARM64Reg Rt, u8 index, ARM64Reg Rn);
|
||||||
void LD1(u8 size, ARM64Reg Rt, u8 index, ARM64Reg Rn, ARM64Reg Rm);
|
void LD1(u8 size, ARM64Reg Rt, u8 index, ARM64Reg Rn, ARM64Reg Rm);
|
||||||
@ -756,6 +772,7 @@ private:
|
|||||||
void EmitLoadStoreMultipleStructure(u32 size, bool L, u32 opcode, ARM64Reg Rt, ARM64Reg Rn);
|
void EmitLoadStoreMultipleStructure(u32 size, bool L, u32 opcode, ARM64Reg Rt, ARM64Reg Rn);
|
||||||
void EmitScalar1Source(bool M, bool S, u32 type, u32 opcode, ARM64Reg Rd, ARM64Reg Rn);
|
void EmitScalar1Source(bool M, bool S, u32 type, u32 opcode, ARM64Reg Rd, ARM64Reg Rn);
|
||||||
void EmitVectorxElement(bool U, u32 size, bool L, u32 opcode, bool H, ARM64Reg Rd, ARM64Reg Rn, ARM64Reg Rm);
|
void EmitVectorxElement(bool U, u32 size, bool L, u32 opcode, bool H, ARM64Reg Rd, ARM64Reg Rn, ARM64Reg Rm);
|
||||||
|
void EmitLoadStoreUnscaled(u32 size, u32 op, ARM64Reg Rt, ARM64Reg Rn, s32 imm);
|
||||||
};
|
};
|
||||||
|
|
||||||
class ARM64CodeBlock : public CodeBlock<ARM64XEmitter>
|
class ARM64CodeBlock : public CodeBlock<ARM64XEmitter>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user