ARMv6 literal pool method.

This commit is contained in:
Sacha 2013-03-04 04:35:10 +10:00
parent 165cfe53a3
commit bdfe24a86b
3 changed files with 51 additions and 18 deletions

View File

@ -118,6 +118,36 @@ void ARMXEmitter::ORI2R(ARMReg rd, ARMReg rs, u32 val, ARMReg scratch)
}
}
void ARMXEmitter::FlushLitPool()
{
for(std::vector<LiteralPool>::iterator it = currentLitPool.begin(); it != currentLitPool.end(); ++it) {
LiteralPool item = *it;
// Write the constant to Literal Pool
Write32(item.val);
s32 offset = (s32)code - (s32)item.ldr_address;
// Backpatch the LDR
code -= offset;
LDRLIT(item.reg, abs(offset - 8), offset - 8 > 0);
code += offset - 4;
}
// TODO: Save a copy of previous pools in case they are still in range.
currentLitPool.clear();
pool_size = 0;
}
void ARMXEmitter::AddNewLit(ArmGen::ARMReg reg, u32 val)
{
// TODO: Look up current constants,
// return that value instead of generating a new one.
int index = pool_size++;
currentLitPool.push_back();
currentLitPool[index].i = pool_size;
currentLitPool[index].val = val;
currentLitPool[index].reg = reg;
currentLitPool[index].ldr_address = (u32)code;
Write32(0); // To be backpatched later
}
void ARMXEmitter::MOVI2R(ARMReg reg, u32 val, bool optimize)
{
Operand2 op2;
@ -149,23 +179,7 @@ void ARMXEmitter::MOVI2R(ARMReg reg, u32 val, bool optimize)
MOVT(reg, val, true);
} else {
// ARMv6 - fallback sequence.
// TODO: Optimize further. Can for example choose negation etc.
// Literal pools is another way to do this but much more complicated
// so I can't really be bothered for an outdated CPU architecture like ARMv6.
bool first = true;
int shift = 16;
for (int i = 0; i < 4; i++) {
if (val & 0xFF) {
if (first) {
MOV(reg, Operand2((u8)val, (u8)(shift & 0xF)));
first = false;
} else {
ORR(reg, reg, Operand2((u8)val, (u8)(shift & 0xF)));
}
}
shift -= 4;
val >>= 8;
}
AddNewLit(reg, val);
}
}
}
@ -667,6 +681,8 @@ void ARMXEmitter::LDRSB(ARMReg dest, ARMReg base, ARMReg offset, bool Index, boo
{
Write32(condition | (0x01 << 20) | (Index << 24) | (Add << 23) | (base << 16) | (dest << 12) | (0xD << 4) | offset);
}
void ARMXEmitter::LDRLIT (ARMReg dest, u32 offset, bool Add) { Write32(condition | 0x05 << 24 | Add << 23 | 0x1F << 16 | dest << 12 | offset);}
void ARMXEmitter::WriteRegStoreOp(u32 op, ARMReg dest, bool WriteBack, u16 RegList)
{
Write32(condition | (op << 20) | (WriteBack << 21) | (dest << 16) | RegList);

View File

@ -25,6 +25,7 @@
#if defined(__SYMBIAN32__) || defined(PANDORA)
#include <signal.h>
#endif
#include <vector>
#undef _IP
#undef R0
@ -333,6 +334,14 @@ struct FixupBranch
int type; //0 = B 1 = BL
};
struct LiteralPool
{
int i;
u32 ldr_address;
u32 val;
ArmGen::ARMReg reg;
};
typedef const u8* JumpTarget;
class ARMXEmitter
@ -342,6 +351,8 @@ private:
u8 *code, *startcode;
u8 *lastCacheFlushEnd;
u32 condition;
int pool_size;
std::vector<LiteralPool> currentLitPool;
void WriteStoreOp(u32 op, ARMReg dest, ARMReg src, Operand2 op2);
void WriteRegStoreOp(u32 op, ARMReg dest, bool WriteBack, u16 RegList);
@ -359,7 +370,7 @@ protected:
inline void Write32(u32 value) {*(u32*)code = value; code+=4;}
public:
ARMXEmitter() : code(0), startcode(0), lastCacheFlushEnd(0) {
ARMXEmitter() : code(0), startcode(0), lastCacheFlushEnd(0), pool_size(0) {
condition = CC_AL << 28;
}
ARMXEmitter(u8 *code_ptr) {
@ -367,6 +378,7 @@ public:
lastCacheFlushEnd = code_ptr;
startcode = code_ptr;
condition = CC_AL << 28;
pool_size = 0;
}
virtual ~ARMXEmitter() {}
@ -379,6 +391,9 @@ public:
void FlushIcacheSection(u8 *start, u8 *end);
u8 *GetWritableCodePtr();
void FlushLitPool();
void AddNewLit(ArmGen::ARMReg reg, u32 val);
void SetCC(CCFlags cond = CC_AL);
// Special purpose instructions
@ -490,6 +505,7 @@ public:
void LDRSH(ARMReg dest, ARMReg base, ARMReg offset, bool Index, bool Add);
void LDRB (ARMReg dest, ARMReg base, ARMReg offset, bool Index, bool Add);
void LDRSB(ARMReg dest, ARMReg base, ARMReg offset, bool Index, bool Add);
void LDRLIT(ARMReg dest, u32 offset, bool Add);
void STR (ARMReg dest, ARMReg src, Operand2 op2 = 0);
void STRH (ARMReg dest, ARMReg src, Operand2 op2 = 0);

View File

@ -219,6 +219,7 @@ const u8 *Jit::DoJit(u32 em_address, ArmJitBlock *b)
js.compilerPC += 4;
numInstructions++;
}
FlushLitPool();
#ifdef LOGASM
if (logBlocks > 0 && dontLogBlocks == 0) {
for (u32 cpc = em_address; cpc != js.compilerPC + 4; cpc += 4) {