mirror of
https://github.com/libretro/ppsspp.git
synced 2025-02-09 02:26:19 +00:00
jit-ir: Implement bit reverse instruction.
This commit is contained in:
parent
d4e45f4e0a
commit
4ac773e8b4
@ -54,7 +54,7 @@ void IRFrontend::Comp_IType(MIPSOpcode op) {
|
||||
MIPSGPReg rs = _RS;
|
||||
|
||||
// noop, won't write to ZERO.
|
||||
if (rt == 0)
|
||||
if (rt == MIPS_REG_ZERO)
|
||||
return;
|
||||
|
||||
switch (op >> 26) {
|
||||
@ -92,7 +92,7 @@ void IRFrontend::Comp_RType2(MIPSOpcode op) {
|
||||
MIPSGPReg rd = _RD;
|
||||
|
||||
// Don't change $zr.
|
||||
if (rd == 0)
|
||||
if (rd == MIPS_REG_ZERO)
|
||||
return;
|
||||
|
||||
switch (op & 63) {
|
||||
@ -104,7 +104,8 @@ void IRFrontend::Comp_RType2(MIPSOpcode op) {
|
||||
ir.Write(IROp::Clz, rd, IRTEMP_0);
|
||||
break;
|
||||
default:
|
||||
DISABLE;
|
||||
Comp_Generic(op);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -198,23 +199,22 @@ void IRFrontend::Comp_ShiftType(MIPSOpcode op) {
|
||||
CONDITIONAL_DISABLE;
|
||||
MIPSGPReg rs = _RS;
|
||||
MIPSGPReg rd = _RD;
|
||||
int fd = _FD;
|
||||
int sa = _SA;
|
||||
|
||||
// noop, won't write to ZERO.
|
||||
if (rd == 0)
|
||||
if (rd == MIPS_REG_ZERO)
|
||||
return;
|
||||
|
||||
// WARNING : ROTR
|
||||
// WARNING: srl/rotr and srlv/rotrv share encodings (differentiated using unused bits.)
|
||||
switch (op & 0x3f) {
|
||||
case 0: CompShiftImm(op, IROp::ShlImm, sa); break; //sll
|
||||
case 2: CompShiftImm(op, (rs == 1 ? IROp::RorImm : IROp::ShrImm), sa); break; //srl
|
||||
case 3: CompShiftImm(op, IROp::SarImm, sa); break; //sra
|
||||
case 4: CompShiftVar(op, IROp::Shl, IROp::ShlImm); break; //sllv
|
||||
case 6: CompShiftVar(op, (fd == 1 ? IROp::Ror : IROp::Shr), (fd == 1 ? IROp::RorImm : IROp::ShrImm)); break; //srlv
|
||||
case 6: CompShiftVar(op, (sa == 1 ? IROp::Ror : IROp::Shr), (sa == 1 ? IROp::RorImm : IROp::ShrImm)); break; //srlv
|
||||
case 7: CompShiftVar(op, IROp::Sar, IROp::SarImm); break; //srav
|
||||
default:
|
||||
DISABLE;
|
||||
Comp_Generic(op);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -229,7 +229,7 @@ void IRFrontend::Comp_Special3(MIPSOpcode op) {
|
||||
u32 mask = 0xFFFFFFFFUL >> (32 - size);
|
||||
|
||||
// Don't change $zr.
|
||||
if (rt == 0)
|
||||
if (rt == MIPS_REG_ZERO)
|
||||
return;
|
||||
|
||||
switch (op & 0x3f) {
|
||||
@ -254,6 +254,10 @@ void IRFrontend::Comp_Special3(MIPSOpcode op) {
|
||||
ir.Write(IROp::Or, rt, rt, IRTEMP_0);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
Comp_Generic(op);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -262,8 +266,9 @@ void IRFrontend::Comp_Allegrex(MIPSOpcode op) {
|
||||
CONDITIONAL_DISABLE;
|
||||
MIPSGPReg rt = _RT;
|
||||
MIPSGPReg rd = _RD;
|
||||
|
||||
// Don't change $zr.
|
||||
if (rd == 0)
|
||||
if (rd == MIPS_REG_ZERO)
|
||||
return;
|
||||
|
||||
switch ((op >> 6) & 31) {
|
||||
@ -275,7 +280,10 @@ void IRFrontend::Comp_Allegrex(MIPSOpcode op) {
|
||||
ir.Write(IROp::Ext16to32, rd, rt);
|
||||
break;
|
||||
|
||||
case 20: //bitrev
|
||||
case 20: // bitrev
|
||||
ir.Write(IROp::ReverseBits, rd, rt);
|
||||
break;
|
||||
|
||||
default:
|
||||
Comp_Generic(op);
|
||||
return;
|
||||
|
@ -53,6 +53,7 @@ static const IRMeta irMeta[] = {
|
||||
{ IROp::MfHi, "MfHi", "G" },
|
||||
{ IROp::Ext8to32, "Ext8to32", "GG" },
|
||||
{ IROp::Ext16to32, "Ext16to32", "GG" },
|
||||
{ IROp::ReverseBits, "ReverseBits", "GG" },
|
||||
{ IROp::Load8, "Load8", "GGC" },
|
||||
{ IROp::Load8Ext, "Load8", "GGC" },
|
||||
{ IROp::Load16, "Load16", "GGC" },
|
||||
|
@ -111,6 +111,7 @@ enum class IROp : u8 {
|
||||
|
||||
Ext8to32,
|
||||
Ext16to32,
|
||||
ReverseBits,
|
||||
|
||||
FAdd,
|
||||
FSub,
|
||||
|
@ -87,6 +87,9 @@ u32 IRInterpret(MIPSState *mips, const IRInst *inst, const u32 *constPool, int c
|
||||
case IROp::Ext16to32:
|
||||
mips->r[inst->dest] = (s32)(s16)mips->r[inst->src1];
|
||||
break;
|
||||
case IROp::ReverseBits:
|
||||
mips->r[inst->dest] = ReverseBits32(mips->r[inst->src1]);
|
||||
break;
|
||||
|
||||
case IROp::Load8:
|
||||
mips->r[inst->dest] = Memory::ReadUnchecked_U8(mips->r[inst->src1] + constPool[inst->src2]);
|
||||
|
@ -5,4 +5,19 @@
|
||||
class MIPSState;
|
||||
struct IRInst;
|
||||
|
||||
inline static u32 ReverseBits32(u32 v) {
|
||||
// http://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel
|
||||
// swap odd and even bits
|
||||
v = ((v >> 1) & 0x55555555) | ((v & 0x55555555) << 1);
|
||||
// swap consecutive pairs
|
||||
v = ((v >> 2) & 0x33333333) | ((v & 0x33333333) << 2);
|
||||
// swap nibbles ...
|
||||
v = ((v >> 4) & 0x0F0F0F0F) | ((v & 0x0F0F0F0F) << 4);
|
||||
// swap bytes
|
||||
v = ((v >> 8) & 0x00FF00FF) | ((v & 0x00FF00FF) << 8);
|
||||
// swap 2-byte long pairs
|
||||
v = ( v >> 16 ) | ( v << 16);
|
||||
return v;
|
||||
}
|
||||
|
||||
u32 IRInterpret(MIPSState *mips, const IRInst *inst, const u32 *constPool, int count);
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include <utility>
|
||||
|
||||
#include "Common/Log.h"
|
||||
#include "Core/MIPS/IR/IRInterpreter.h"
|
||||
#include "Core/MIPS/IR/IRPassSimplify.h"
|
||||
#include "Core/MIPS/IR/IRRegCache.h"
|
||||
|
||||
@ -51,6 +52,7 @@ u32 Evaluate(u32 a, IROp op) {
|
||||
case IROp::BSwap32: return swap32(a);
|
||||
case IROp::Ext8to32: return (u32)(s32)(s8)(u8)a;
|
||||
case IROp::Ext16to32: return (u32)(s32)(s16)(u16)a;
|
||||
case IROp::ReverseBits: return ReverseBits32(a);
|
||||
case IROp::Clz: {
|
||||
int x = 31;
|
||||
int count = 0;
|
||||
@ -277,6 +279,7 @@ bool PropagateConstants(const IRWriter &in, IRWriter &out) {
|
||||
case IROp::BSwap32:
|
||||
case IROp::Ext8to32:
|
||||
case IROp::Ext16to32:
|
||||
case IROp::ReverseBits:
|
||||
case IROp::Clz:
|
||||
if (gpr.IsImm(inst.src1)) {
|
||||
gpr.SetImm(inst.dest, Evaluate(gpr.GetImm(inst.src1), inst.op));
|
||||
|
Loading…
x
Reference in New Issue
Block a user