[AArch64] Add loadstore paired emitter instructions.

This commit is contained in:
Ryan Houdek 2014-12-02 18:08:40 -06:00
parent e40f129fdd
commit 2c39d4044d
3 changed files with 63 additions and 1 deletions

View File

@ -491,6 +491,42 @@ void ARM64XEmitter::EncodeLogicalImmInst(u32 op, ARM64Reg Rd, ARM64Reg Rn, u32 i
(immr << 16) | (imms << 10) | (Rn << 5) | Rd); (immr << 16) | (imms << 10) | (Rn << 5) | Rd);
} }
void ARM64XEmitter::EncodeLoadStorePair(u32 op, u32 load, IndexType type, ARM64Reg Rt, ARM64Reg Rt2, ARM64Reg Rn, s32 imm)
{
bool b64Bit = Is64Bit(Rt);
u32 type_encode = 0;
switch (type)
{
case INDEX_UNSIGNED:
type_encode = 0b010;
break;
case INDEX_POST:
type_encode = 0b001;
break;
case INDEX_PRE:
type_encode = 0b011;
break;
}
if (b64Bit)
{
op |= 0b10;
imm >>= 3;
}
else
{
imm >>= 2;
}
Rt = DecodeReg(Rt);
Rt2 = DecodeReg(Rt2);
Rn = DecodeReg(Rn);
Write32((op << 30) | (0b101 << 27) | (type_encode << 23) | (load << 22) | \
((imm & 0x7F) << 15) | (Rt2 << 10) | (Rn << 5) | Rt);
}
// FixupBranch branching // FixupBranch branching
void ARM64XEmitter::SetJumpTarget(FixupBranch const& branch) void ARM64XEmitter::SetJumpTarget(FixupBranch const& branch)
{ {
@ -1120,6 +1156,20 @@ void ARM64XEmitter::PRFM(ARM64Reg Rt, u32 imm)
EncodeLoadRegisterInst(3, Rt, imm); EncodeLoadRegisterInst(3, Rt, imm);
} }
// Load/Store pair
void ARM64XEmitter::LDP(IndexType type, ARM64Reg Rt, ARM64Reg Rt2, ARM64Reg Rn, s32 imm)
{
EncodeLoadStorePair(0, 1, type, Rt, Rt2, Rn, imm);
}
void ARM64XEmitter::LDPSW(IndexType type, ARM64Reg Rt, ARM64Reg Rt2, ARM64Reg Rn, s32 imm)
{
EncodeLoadStorePair(1, 1, type, Rt, Rt2, Rn, imm);
}
void ARM64XEmitter::STP(IndexType type, ARM64Reg Rt, ARM64Reg Rt2, ARM64Reg Rn, s32 imm)
{
EncodeLoadStorePair(0, 0, type, Rt, Rt2, Rn, imm);
}
// Load/Store Exclusive // Load/Store Exclusive
void ARM64XEmitter::STXRB(ARM64Reg Rs, ARM64Reg Rt, ARM64Reg Rn) void ARM64XEmitter::STXRB(ARM64Reg Rs, ARM64Reg Rt, ARM64Reg Rn)
{ {

View File

@ -299,6 +299,7 @@ private:
void EncodeLoadStoreRegisterOffset(u32 size, u32 opc, ARM64Reg Rt, ARM64Reg Rn, ARM64Reg Rm, ExtendType extend); void EncodeLoadStoreRegisterOffset(u32 size, u32 opc, ARM64Reg Rt, ARM64Reg Rn, ARM64Reg Rm, ExtendType extend);
void EncodeAddSubImmInst(u32 op, bool flags, u32 shift, u32 imm, ARM64Reg Rn, ARM64Reg Rd); void EncodeAddSubImmInst(u32 op, bool flags, u32 shift, u32 imm, ARM64Reg Rn, ARM64Reg Rd);
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);
protected: protected:
inline void Write32(u32 value) inline void Write32(u32 value)
@ -313,6 +314,12 @@ public:
{ {
} }
ARM64XEmitter(u8* code_ptr) {
m_code = code_ptr;
m_lastCacheFlushEnd = code_ptr;
m_startcode = code_ptr;
}
virtual ~ARM64XEmitter() virtual ~ARM64XEmitter()
{ {
} }
@ -539,6 +546,11 @@ public:
void LDRSW(ARM64Reg Rt, ARM64Reg Rn, ARM64Reg Rm, ExtendType extend = EXTEND_LSL); void LDRSW(ARM64Reg Rt, ARM64Reg Rn, ARM64Reg Rm, ExtendType extend = EXTEND_LSL);
void PRFM(ARM64Reg Rt, ARM64Reg Rn, ARM64Reg Rm, ExtendType extend = EXTEND_LSL); void PRFM(ARM64Reg Rt, ARM64Reg Rn, ARM64Reg Rm, ExtendType extend = EXTEND_LSL);
// Load/Store pair
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 STP(IndexType type, ARM64Reg Rt, ARM64Reg Rt2, ARM64Reg Rn, s32 imm);
// Wrapper around MOVZ+MOVK // Wrapper around MOVZ+MOVK
void MOVI2R(ARM64Reg Rd, u64 imm, bool optimize = true); void MOVI2R(ARM64Reg Rd, u64 imm, bool optimize = true);
}; };

View File

@ -351,7 +351,7 @@ public:
ARMXEmitter() : code(nullptr), startcode(nullptr), lastCacheFlushEnd(nullptr) { ARMXEmitter() : code(nullptr), startcode(nullptr), lastCacheFlushEnd(nullptr) {
condition = CC_AL << 28; condition = CC_AL << 28;
} }
ARMXEmitter(u8 *code_ptr) { ARMXEmitter(u8* code_ptr) {
code = code_ptr; code = code_ptr;
lastCacheFlushEnd = code_ptr; lastCacheFlushEnd = code_ptr;
startcode = code_ptr; startcode = code_ptr;