mirror of
https://github.com/libretro/ppsspp.git
synced 2024-11-25 01:00:01 +00:00
armjit: Use multiple BICs in ANDI2R if possible.
Rather than a temporary.
This commit is contained in:
parent
4026944b02
commit
83fe874dcc
@ -177,15 +177,47 @@ void ARMXEmitter::ANDI2R(ARMReg rd, ARMReg rs, u32 val, ARMReg scratch)
|
||||
{
|
||||
Operand2 op2;
|
||||
bool inverse;
|
||||
if (TryMakeOperand2_AllowInverse(val, op2, &inverse)) {
|
||||
if (val == 0) {
|
||||
// Avoid the ALU, may improve pipeline.
|
||||
MOV(rd, 0);
|
||||
} else if (TryMakeOperand2_AllowInverse(val, op2, &inverse)) {
|
||||
if (!inverse) {
|
||||
AND(rd, rs, op2);
|
||||
} else {
|
||||
BIC(rd, rs, op2);
|
||||
}
|
||||
} else {
|
||||
MOVI2R(scratch, val);
|
||||
AND(rd, rs, scratch);
|
||||
int ops = 0;
|
||||
for (int i = 0; i < 32; i += 2) {
|
||||
u8 bits = (val >> i) & 0xFF;
|
||||
// If either low bit is not set, we need to use a BIC for them.
|
||||
if ((bits & 3) != 3) {
|
||||
++ops;
|
||||
i += 8 - 2;
|
||||
}
|
||||
}
|
||||
|
||||
// The worst case is 4 (e.g. 0x55555555.)
|
||||
if (ops <= 3) {
|
||||
bool first = true;
|
||||
for (int i = 0; i < 32; i += 2) {
|
||||
u8 bits = (val >> i) & 0xFF;
|
||||
if ((bits & 3) != 3) {
|
||||
u8 rotation = i == 0 ? 0 : 16 - i / 2;
|
||||
if (first) {
|
||||
BIC(rd, rs, Operand2(~bits, rotation));
|
||||
first = false;
|
||||
} else {
|
||||
BIC(rd, rd, Operand2(~bits, rotation));
|
||||
}
|
||||
// Well, we took care of these other bits while we were at it.
|
||||
i += 8 - 2;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
MOVI2R(scratch, val);
|
||||
AND(rd, rs, scratch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user