Speed up MIPSGetInstruction() by 35%.

It's not that hot, but gets called a lot when loading modules / running
tests.  Well, and also interpreter.

Some of the previous checks were just not necessary (we never have Rese in
the tables, for example, and let's just not.)
This commit is contained in:
Unknown W. Brackets 2014-03-01 21:34:41 -08:00
parent eca06c60c7
commit f300f46b9c

View File

@ -60,11 +60,14 @@ enum MipsEncoding
Emu,
Rese,
NumEncodings,
Instruc = -1,
Inval = -2,
};
struct MIPSInstruction
{
int altEncoding;
MipsEncoding altEncoding;
const char *name;
MIPSComp::MIPSCompileFunc compile;
#ifndef FINAL
@ -75,16 +78,16 @@ struct MIPSInstruction
MIPSInfo flags;
};
#define INVALID {-2}
#define INVALID {Inval}
#define INVALID_X_8 INVALID,INVALID,INVALID,INVALID,INVALID,INVALID,INVALID,INVALID
#define N(a) a
#ifndef FINAL
#define ENCODING(a) {a}
#define INSTR(name, comp, dis, inter, flags) {-1, N(name), comp, dis, inter, MIPSInfo(flags)}
#define INSTR(name, comp, dis, inter, flags) {Instruc, N(name), comp, dis, inter, MIPSInfo(flags)}
#else
#define ENCODING(a) {a}
#define INSTR(name, comp, dis, inter, flags) {-1, comp, inter, flags}
#define INSTR(name, comp, dis, inter, flags) {Instruc, comp, inter, flags}
#endif
@ -816,36 +819,44 @@ const MIPSInstruction tableEMU[4] = {
INVALID,
};
const int encodingBits[NumEncodings][2] =
{
{26, 6}, //IMME
{0, 6}, //Special
{0, 6}, //special2
{0, 6}, //special3
{16, 5}, //RegImm
{21, 5}, //Cop0
{0, 6}, //Cop0CO
{21, 5}, //Cop1
{16, 5}, //Cop1BC
{0, 6}, //Cop1S
{0, 6}, //Cop1W
{21, 5}, //Cop2
{16, 2}, //Cop2BC2
{0, 0}, //Cop2Rese
{23, 3}, //VFPU0
{23, 3}, //VFPU1
{23, 3}, //VFPU3
{21, 5}, //VFPU4Jump
{16, 5}, //VFPU7
{16, 5}, //VFPU4
{23, 3}, //VFPU5
{21, 5}, //VFPU6
{16, 4}, //VFPUMatrix1
{16, 5}, //VFPU9
{6, 5}, //ALLEGREX0
{24, 2}, //EMUHACK
struct EncodingBitsInfo {
EncodingBitsInfo(u8 shift_, u8 maskBits_) : shift(shift_) {
mask = (1 << maskBits_) - 1;
}
u8 shift;
u32 mask;
};
const EncodingBitsInfo encodingBits[NumEncodings] =
{
EncodingBitsInfo(26, 6), //IMME
EncodingBitsInfo(0, 6), //Special
EncodingBitsInfo(0, 6), //special2
EncodingBitsInfo(0, 6), //special3
EncodingBitsInfo(16, 5), //RegImm
EncodingBitsInfo(21, 5), //Cop0
EncodingBitsInfo(0, 6), //Cop0CO
EncodingBitsInfo(21, 5), //Cop1
EncodingBitsInfo(16, 5), //Cop1BC
EncodingBitsInfo(0, 6), //Cop1S
EncodingBitsInfo(0, 6), //Cop1W
EncodingBitsInfo(21, 5), //Cop2
EncodingBitsInfo(16, 2), //Cop2BC2
EncodingBitsInfo(0, 0), //Cop2Rese
EncodingBitsInfo(23, 3), //VFPU0
EncodingBitsInfo(23, 3), //VFPU1
EncodingBitsInfo(23, 3), //VFPU3
EncodingBitsInfo(21, 5), //VFPU4Jump
EncodingBitsInfo(16, 5), //VFPU7
EncodingBitsInfo(16, 5), //VFPU4
EncodingBitsInfo(23, 3), //VFPU5
EncodingBitsInfo(21, 5), //VFPU6
EncodingBitsInfo(16, 4), //VFPUMatrix1
EncodingBitsInfo(16, 5), //VFPU9
EncodingBitsInfo(6, 5), //ALLEGREX0
EncodingBitsInfo(24, 2), //EMUHACK
EncodingBitsInfo(0, 0), //Rese
};
const MIPSInstruction *mipsTables[NumEncodings] =
{
@ -874,7 +885,8 @@ const MIPSInstruction *mipsTables[NumEncodings] =
tableVFPUMatrixSet1,
tableVFPU9,
tableALLEGREX0,
tableEMU
tableEMU,
0,
};
@ -896,23 +908,18 @@ const MIPSInstruction *MIPSGetInstruction(MIPSOpcode op)
{
MipsEncoding encoding = Imme;
const MIPSInstruction *instr = &tableImmediate[op>>26];
while (instr->altEncoding != -1)
while (instr->altEncoding != Instruc)
{
const MIPSInstruction *table = mipsTables[encoding];
int mask = ((1<<encodingBits[encoding][1])-1);
int shift = encodingBits[encoding][0];
int subop = (op >> shift) & mask;
instr = &table[subop];
if (encoding == Rese)
return 0; //invalid instruction
if (!instr)
return 0;
if (instr->altEncoding == -2)
if (instr->altEncoding == Inval)
{
//ERROR_LOG(CPU, "Invalid instruction %08x in table %i, entry %i", op, (int)encoding, subop);
return 0; //invalid instruction
}
encoding = (MipsEncoding)instr->altEncoding;
encoding = instr->altEncoding;
const MIPSInstruction *table = mipsTables[encoding];
const u32 subop = (op >> encodingBits[encoding].shift) & encodingBits[encoding].mask;
instr = &table[subop];
}
//alright, we have a valid MIPS instruction!
return instr;