Add ARMv6 fallback to jit (it doesn't have MOVW/MOVT)

This commit is contained in:
Henrik Rydgard 2013-01-11 15:20:06 +01:00
parent ba804cfa89
commit 51fd025064
5 changed files with 48 additions and 26 deletions

View file

@ -76,30 +76,6 @@ void ARMXEmitter::ARMABI_PopAllCalleeSavedRegsAndAdjustStack() {
POP(4, R0, R1, R2, R3);
}
void ARMXEmitter::ARMABI_MOVI2R(ARMReg reg, u32 val)
{
Operand2 op2;
bool inverse;
if (TryMakeOperand2_AllowInverse(val, op2, &inverse)) {
if (!inverse)
MOV(reg, op2);
else
MVN(reg, op2);
} else {
MOVW(reg, val);
if(val & 0xFFFF0000)
MOVT(reg, val, true);
}
}
// Moves IMM to memory location
void ARMXEmitter::ARMABI_MOVI2M(Operand2 op, Operand2 val)
{
// This moves imm to a memory location
MOVW(R14, val); MOVT(R14, val, true);
MOVW(R12, op); MOVT(R12, op, true);
STR(R12, R14); // R10 is what we want to store
}
const char *conditions[] = {"EQ", "NEQ", "CS", "CC", "MI", "PL", "VS", "VC", "HI", "LS", "GE", "LT", "GT", "LE", "AL" };
static void ShowCondition(u32 cond)
{

View file

@ -41,6 +41,7 @@ char *GetCPUString()
continue;
cpu_string = buf + sizeof(marker) - 1;
cpu_string = strndup(cpu_string, strlen(cpu_string) - 1); // Strip the newline
// INFO_LOG(BOOT, "CPU: %s", cpu_string);
break;
}
return cpu_string;
@ -150,6 +151,13 @@ void CPUInfo::Detect()
bFP = false;
bASIMD = false;
#endif
// On android, we build a separate library for ARMv7 so this is fine.
// TODO: Check for ARMv7 on other platforms.
#if defined(__ARM_ARCH_7A__)
bArmV7 = true;
#else
bArmV7 = false;
#endif
}
// Turn the cpu info into a string we can show

View file

@ -78,6 +78,44 @@ bool TryMakeOperand2_AllowNegation(s32 imm, Operand2 &op2, bool *negated)
}
}
void ARMXEmitter::ARMABI_MOVI2R(ARMReg reg, u32 val)
{
Operand2 op2;
bool inverse;
if (TryMakeOperand2_AllowInverse(val, op2, &inverse)) {
if (!inverse)
MOV(reg, op2);
else
MVN(reg, op2);
} else {
if (cpu_info.bArmV7) {
// ARMv7 - can use MOVT/MOVW, best choice
MOVW(reg, val & 0xFFFF);
if(val & 0xFFFF0000)
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;
}
}
}
}
void ARMXEmitter::QuickCallFunction(ARMReg reg, void *func) {
ARMABI_MOVI2R(reg, (u32)(func));
BL(reg);

View file

@ -481,8 +481,6 @@ public:
void ARMABI_PushAllCalleeSavedRegsAndAdjustStack();
void ARMABI_PopAllCalleeSavedRegsAndAdjustStack();
void ARMABI_MOVI2R(ARMReg reg, u32 val);
void ARMABI_MOVI2M(Operand2 op, Operand2 val);
void ARMABI_MOVI2M(u32 addr, Operand2 val);
void ARMABI_ShowConditions();
void ARMABI_Return();

View file

@ -71,6 +71,8 @@ struct CPUInfo
bool bVFPv4;
bool bIDIVa;
bool bIDIVt;
bool bArmV7; // enable MOVT, MOVW etc
// ARMv8 specific
bool bFP;
bool bASIMD;