11#include " il.h"
22
33#include " mips.h"
4+ #include " arch/powerpc/capstone/arch/AArch64/AArch64GenRegisterInfo.inc"
45
56using namespace BinaryNinja ;
67using namespace mips ;
@@ -529,6 +530,18 @@ ExprId GetConditionForInstruction(LowLevelILFunction& il, Instruction& instr, st
529530 if (instr.operands [0 ].operandClass == FLAG)
530531 return il.Flag (instr.operands [0 ].reg );
531532 return il.Flag (FPCCREG_FCC0);
533+ case MIPS_BC0F:
534+ case MIPS_BC0FL:
535+ return il.Not (0 , il.Flag (CCREG_COC0));
536+ case MIPS_BC0T:
537+ case MIPS_BC0TL:
538+ return il.Flag (CCREG_COC0);
539+ case MIPS_BC2F:
540+ case MIPS_BC2FL:
541+ return il.Not (0 , il.Flag (CCREG_COC2));
542+ case MIPS_BC2T:
543+ case MIPS_BC2TL:
544+ return il.Flag (CCREG_COC2);
532545 case CNMIPS_BBIT0:
533546 return il.CompareEqual (registerSize (op1),
534547 il.And (registerSize (op1),
@@ -1322,6 +1335,58 @@ bool GetLowLevelILForInstruction(Architecture* arch, uint64_t addr, LowLevelILFu
13221335 ConditionalJump (arch, il, il.Flag (FPCCREG_FCC0), addrSize, op1.immediate , addr + 8 );
13231336 return false ;
13241337
1338+ case MIPS_BC2F:
1339+ case MIPS_BC2FL:
1340+ if (op1.operandClass == FLAG)
1341+ ConditionalJump (arch, il, il.Not (0 , il.Flag (op1.reg )), addrSize, op2.immediate , addr + 8 );
1342+ else
1343+ ConditionalJump (arch, il, il.Not (0 , il.Flag (CCREG_COC2)), addrSize, op1.immediate , addr + 8 );
1344+ return false ;
1345+
1346+ case MIPS_BC2T:
1347+ case MIPS_BC2TL:
1348+ if (op1.operandClass == FLAG)
1349+ ConditionalJump (arch, il, il.Flag (op1.reg ), addrSize, op2.immediate , addr + 8 );
1350+ else
1351+ ConditionalJump (arch, il, il.Flag (CCREG_COC2), addrSize, op1.immediate , addr + 8 );
1352+ return false ;
1353+
1354+ case MIPS_BC0F:
1355+ case MIPS_BC0FL:
1356+ {
1357+ // il.AddInstruction(il.Intrinsic({RegisterOrFlag(true, LLIL_TEMP(0))}, MIPS_INTRIN_COP0_CONDITION, {}));
1358+ il.AddInstruction (il.Intrinsic ({RegisterOrFlag (true , CCREG_COC0)}, MIPS_INTRIN_COP0_CONDITION, {}));
1359+ // il.AddInstruction(il.Intrinsic({}, MIPS_INTRIN_COP0_CONDITION, {}, CCREG_COC0));
1360+ ConditionalJump (arch, il, GetConditionForInstruction (il, instr, registerSize), addrSize, op1.immediate , addr + 8 );
1361+ // ConditionalJump(arch, il, il.Not(0, il.Flag(LLIL_TEMP(0))), addrSize, op1.immediate, addr + 8);
1362+ // il.AddInstruction(il.If(il.Not(0, il.Flag(LLIL_TEMP(0))), trueCode, falseCode));
1363+ // il.MarkLabel(trueCode);
1364+ // il.AddInstruction(il.Jump(il.ConstPointer(addrSize, op1.immediate)));
1365+ // il.MarkLabel(falseCode);
1366+ // il.AddInstruction(il.Jump(il.ConstPointer(addrSize, addr + 8)));
1367+ return false ;
1368+ }
1369+ case MIPS_BC0T:
1370+ case MIPS_BC0TL:
1371+ // il.AddInstruction(il.Intrinsic({RegisterOrFlag(true, LLIL_TEMP(0))}, MIPS_INTRIN_COP0_CONDITION, {}));
1372+ // // ConditionalJump(arch, il, il.Intrinsic({}, MIPS_INTRIN_COP0_CONDITION, {}, Flag::CCREG_COC0), addrSize, op1.immediate, addr + 8);
1373+ // // ConditionalJump(arch, il, GetConditionForInstruction(il, instr, registerSize), addrSize, op1.immediate, addr + 8);
1374+ // ConditionalJump(arch, il, il.Flag(LLIL_TEMP(0)), addrSize, op1.immediate, addr + 8);
1375+ // return false;
1376+ {
1377+ // il.AddInstruction(il.Intrinsic({RegisterOrFlag(true, LLIL_TEMP(0))}, MIPS_INTRIN_COP0_CONDITION, {}));
1378+ il.AddInstruction (il.Intrinsic ({RegisterOrFlag (true , CCREG_COC0)}, MIPS_INTRIN_COP0_CONDITION, {}));
1379+ // il.AddInstruction(il.Intrinsic({}, MIPS_INTRIN_COP0_CONDITION, {}, CCREG_COC0));
1380+ ConditionalJump (arch, il, GetConditionForInstruction (il, instr, registerSize), addrSize, op1.immediate , addr + 8 );
1381+ // ConditionalJump(arch, il, il.Flag(LLIL_TEMP(0)), addrSize, op1.immediate, addr + 8);
1382+ // il.AddInstruction(il.If(il.Flag(LLIL_TEMP(0)), trueCode, falseCode));
1383+ // il.MarkLabel(trueCode);
1384+ // il.AddInstruction(il.Jump(il.ConstPointer(addrSize, op1.immediate)));
1385+ // il.MarkLabel(falseCode);
1386+ // il.AddInstruction(il.Jump(il.ConstPointer(addrSize, addr + 8)));
1387+ return false ;
1388+ }
1389+
13251390 case MIPS_BGEZAL:
13261391 case MIPS_BLTZAL:
13271392 il.AddInstruction (il.If (GetConditionForInstruction (il, instr, registerSize), trueCode, falseCode));
@@ -3134,7 +3199,7 @@ bool GetLowLevelILForInstruction(Architecture* arch, uint64_t addr, LowLevelILFu
31343199 if (op2.operandClass == V_REG && reg < REG_VF0)
31353200 reg += REG_VF0;
31363201 il.AddInstruction (
3137- SetRegisterOrNop (il,4 , 4 , op1.reg , il.Register (4 , reg)));
3202+ SetRegisterOrNop (il,16 , 16 , op1.reg , il.Register (16 , reg)));
31383203 break ;
31393204 }
31403205 case MIPS_QMTC2:
@@ -3145,7 +3210,7 @@ bool GetLowLevelILForInstruction(Architecture* arch, uint64_t addr, LowLevelILFu
31453210 if (op2.operandClass == V_REG && reg < REG_VF0)
31463211 reg += REG_VF0;
31473212 il.AddInstruction (
3148- il.SetRegister (4 , reg, il.Register (4 , op1.reg )));
3213+ il.SetRegister (16 , reg, il.Register (16 , op1.reg )));
31493214 break ;
31503215 }
31513216
@@ -3640,6 +3705,11 @@ bool GetLowLevelILForInstruction(Architecture* arch, uint64_t addr, LowLevelILFu
36403705 // Floating point instructions
36413706 case MIPS_RSQRT_D:
36423707 case MIPS_RSQRT_S:
3708+ if (version == MIPS_R5900)
3709+ {
3710+ il.AddInstruction (il.SetRegister (4 , op1.reg , il.FloatDiv (4 , il.Register (4 , op3.reg ), il.FloatSqrt (4 , il.Register (4 , op3.reg )))));
3711+ break ;
3712+ }
36433713 case MIPS_RSQRT:
36443714 case MIPS_RSQRT1:
36453715 case MIPS_RSQRT2:
@@ -3780,21 +3850,48 @@ bool GetLowLevelILForInstruction(Architecture* arch, uint64_t addr, LowLevelILFu
37803850 case MIPS_PEXCH:
37813851 // case MIPS_PCPYH:
37823852 case MIPS_PEXCW:
3783- case MIPS_BC0F:
3784- case MIPS_BC0T:
3785- case MIPS_BC0FL:
3786- case MIPS_BC0TL:
3853+ // case MIPS_BC0F:
3854+ // case MIPS_BC0T:
3855+ // case MIPS_BC0FL:
3856+ // case MIPS_BC0TL:
37873857 // case MIPS_MADDA_S:
37883858 // case MIPS_MSUBA_S:
3789- case MIPS_MAX_S:
3790- case MIPS_MIN_S:
3859+ // case MIPS_MAX_S:
3860+ // case MIPS_MIN_S:
37913861 case MIPS_MMI0:
37923862 case MIPS_MMI1:
37933863 case MIPS_MMI2:
37943864 case MIPS_MMI3:
37953865 il.AddInstruction (il.Unimplemented ());
37963866 break ;
37973867
3868+ case MIPS_MAX_S:
3869+ {
3870+ ConditionExecute (il,
3871+ il.FloatCompareGreaterEqual (4 , il.Register (4 , op2.reg ), il.Register (4 , op3.reg )),
3872+ // il.CompareSignedGreaterEqual(4,
3873+ // il.FloatToInt(4, il.FloatSub(4,
3874+ // il.Register(4, op2.reg), il.Register(4, op3.reg))), il.Const(4, 0)
3875+ // ),
3876+ il.SetRegister (4 , op1.reg , il.Register (4 , op2.reg )),
3877+ il.SetRegister (4 , op1.reg , il.Register (4 , op3.reg )));
3878+ break ;
3879+ }
3880+ case MIPS_MIN_S:
3881+ {
3882+ ConditionExecute (il,
3883+ il.FloatCompareLessEqual (4 , il.Register (4 , op2.reg ), il.Register (4 , op3.reg )),
3884+ // il.CompareSignedLessEqual(4,
3885+ // il.FloatToInt(4, il.FloatSub(4,
3886+ // il.Register(4, op2.reg), il.Register(4, op3.reg))), il.Const(4, 0)
3887+ // ),
3888+ il.SetRegister (4 , op1.reg , il.Register (4 , op2.reg )),
3889+ il.SetRegister (4 , op1.reg , il.Register (4 , op3.reg )));
3890+ break ;
3891+ }
3892+
3893+
3894+ // Emotion Engine VPU0 (macro) instructions
37983895 case MIPS_VNOP:
37993896 il.AddInstruction (il.Nop ());
38003897 break ;
@@ -3815,6 +3912,19 @@ bool GetLowLevelILForInstruction(Architecture* arch, uint64_t addr, LowLevelILFu
38153912 il.AddInstruction (il.SetRegister (4 , op2.reg + REG_VF0_W, il.Register (4 , op3.reg + REG_VF0_X)));
38163913 break ;
38173914 }
3915+ case MIPS_VABS:
3916+ {
3917+ unsigned char dest = op1.reg ;
3918+ if (dest & (1 << 3 ))
3919+ il.AddInstruction (il.SetRegister (4 , op2.reg + REG_VF0_X, il.FloatAbs (4 , il.Register (4 , op3.reg + REG_VF0_Y))));
3920+ if (dest & (1 << 2 ))
3921+ il.AddInstruction (il.SetRegister (4 , op2.reg + REG_VF0_Y, il.FloatAbs (4 , il.Register (4 , op3.reg + REG_VF0_Z))));
3922+ if (dest & (1 << 1 ))
3923+ il.AddInstruction (il.SetRegister (4 , op2.reg + REG_VF0_Z, il.FloatAbs (4 , il.Register (4 , op3.reg + REG_VF0_W))));
3924+ if (dest & (1 << 0 ))
3925+ il.AddInstruction (il.SetRegister (4 , op2.reg + REG_VF0_W, il.FloatAbs (4 , il.Register (4 , op3.reg + REG_VF0_X))));
3926+ break ;
3927+ }
38183928 case MIPS_VMOVE:
38193929 {
38203930 unsigned char dest = op1.reg ;
@@ -4170,19 +4280,73 @@ bool GetLowLevelILForInstruction(Architecture* arch, uint64_t addr, LowLevelILFu
41704280 {
41714281 unsigned char dest = op1.reg ;
41724282 if (dest & (1 << 3 ))
4173- il.AddInstruction (il.SetRegister (4 , op2.reg + REG_VF0_X, il.FloatSub (4 , il.Register (4 , REG_VACC_X), il.FloatMult (4 , il.Register (4 , op3.reg + REG_VF0_X ), il.Register (4 , op4.reg + REG_VF0_X )))));
4283+ il.AddInstruction (il.SetRegister (4 , op2.reg + REG_VF0_X, il.FloatSub (4 , il.Register (4 , REG_VACC_X), il.FloatMult (4 , il.Register (4 , op3.reg + REG_VF0_Y ), il.Register (4 , op4.reg + REG_VF0_Z )))));
41744284 if (dest & (1 << 2 ))
4175- il.AddInstruction (il.SetRegister (4 , op2.reg + REG_VF0_Y, il.FloatSub (4 , il.Register (4 , REG_VACC_Y), il.FloatMult (4 , il.Register (4 , op3.reg + REG_VF0_Y ), il.Register (4 , op4.reg + REG_VF0_Y )))));
4285+ il.AddInstruction (il.SetRegister (4 , op2.reg + REG_VF0_Y, il.FloatSub (4 , il.Register (4 , REG_VACC_Y), il.FloatMult (4 , il.Register (4 , op3.reg + REG_VF0_Z ), il.Register (4 , op4.reg + REG_VF0_X )))));
41764286 if (dest & (1 << 1 ))
4177- il.AddInstruction (il.SetRegister (4 , op2.reg + REG_VF0_Z, il.FloatSub (4 , il.Register (4 , REG_VACC_Z), il.FloatMult (4 , il.Register (4 , op3.reg + REG_VF0_Z), il.Register (4 , op4.reg + REG_VF0_Z)))));
4178- if (dest & (1 << 0 ))
4179- il.AddInstruction (il.SetRegister (4 , op2.reg + REG_VF0_W, il.FloatSub (4 , il.Register (4 , REG_VACC_W), il.FloatMult (4 , il.Register (4 , op3.reg + REG_VF0_W), il.Register (4 , op4.reg + REG_VF0_Z)))));
4287+ il.AddInstruction (il.SetRegister (4 , op2.reg + REG_VF0_Z, il.FloatSub (4 , il.Register (4 , REG_VACC_Z), il.FloatMult (4 , il.Register (4 , op3.reg + REG_VF0_X), il.Register (4 , op4.reg + REG_VF0_Y)))));
41804288 break ;
41814289 }
41824290 // ACCx = VF[fs]y × VF[ft]z
41834291 // ACCy = VF[fs]z × VF[ft]x
41844292 // ACCz = VF[fs]x × VF[ft]y
41854293 case MIPS_VOPMULA:
4294+ {
4295+ unsigned char dest = op1.reg ;
4296+ if (dest & (1 << 3 ))
4297+ il.AddInstruction (il.SetRegister (4 , REG_VACC_X, il.FloatMult (4 , il.Register (4 , op2.reg + REG_VF0_Y), il.Register (4 , op3.reg + REG_VF0_Z))));
4298+ if (dest & (1 << 2 ))
4299+ il.AddInstruction (il.SetRegister (4 , REG_VACC_Y, il.FloatMult (4 , il.Register (4 , op2.reg + REG_VF0_Z), il.Register (4 , op3.reg + REG_VF0_X))));
4300+ if (dest & (1 << 1 ))
4301+ il.AddInstruction (il.SetRegister (4 , REG_VACC_Z, il.FloatMult (4 , il.Register (4 , op2.reg + REG_VF0_X), il.Register (4 , op3.reg + REG_VF0_Y))));
4302+ break ;
4303+ }
4304+
4305+ case MIPS_VLQI:
4306+ case MIPS_VLQD:
4307+ {
4308+ // il.AddInstruction(il.Intrinsic({RegisterOrFlag::Register(LLIL_TEMP(0))}, MIPS_INTRIN_R5900_VU_MEM_LOAD, {il.Mult(4, il.Register(4, op2.reg), il.Const(4, 16))}));
4309+ unsigned char dest = op1.reg ;
4310+ if (dest & (1 << 3 ))
4311+ il.AddInstruction (il.Intrinsic ({RegisterOrFlag::Register (op2.reg + REG_VF0_X)}, MIPS_INTRIN_R5900_VU_MEM_LOAD, {il.Mult (4 , il.Register (4 , op3.reg ), il.Const (4 , 16 )), il.Const (2 , 0 )}));
4312+ if (dest & (1 << 2 ))
4313+ il.AddInstruction (il.Intrinsic ({RegisterOrFlag::Register (op2.reg + REG_VF0_Y)}, MIPS_INTRIN_R5900_VU_MEM_LOAD, {il.Mult (4 , il.Register (4 , op3.reg ), il.Const (4 , 16 )), il.Const (2 , 1 )}));
4314+ if (dest & (1 << 1 ))
4315+ il.AddInstruction (il.Intrinsic ({RegisterOrFlag::Register (op2.reg + REG_VF0_Z)}, MIPS_INTRIN_R5900_VU_MEM_LOAD, {il.Mult (4 , il.Register (4 , op3.reg ), il.Const (4 , 16 )), il.Const (2 , 2 )}));
4316+ if (dest & (1 << 0 ))
4317+ il.AddInstruction (il.Intrinsic ({RegisterOrFlag::Register (op2.reg + REG_VF0_W)}, MIPS_INTRIN_R5900_VU_MEM_LOAD, {il.Mult (4 , il.Register (4 , op3.reg ), il.Const (4 , 16 )), il.Const (2 , 3 )}));
4318+ il.AddInstruction (il.SetRegister (2 , op3.reg , il.Add (2 , il.Register (2 , op3.reg ), il.Const (2 , op1.immediate ))));
4319+ break ;
4320+ }
4321+
4322+ case MIPS_VSQI:
4323+ case MIPS_VSQD:
4324+ {
4325+ // il.AddInstruction(il.Intrinsic({RegisterOrFlag::Register(LLIL_TEMP(0))}, MIPS_INTRIN_R5900_VU_MEM_LOAD, {il.Mult(4, il.Register(4, op2.reg), il.Const(4, 16))}));
4326+ unsigned char dest = op1.reg ;
4327+ if (dest & (1 << 3 ))
4328+ il.AddInstruction (il.Intrinsic ({}, MIPS_INTRIN_R5900_VU_MEM_STORE, {il.Mult (4 , il.Register (4 , op3.reg ), il.Const (4 , 16 )), il.Const (2 , 0 ), il.Register (4 , op2.reg + REG_VF0_X)}));
4329+ if (dest & (1 << 2 ))
4330+ il.AddInstruction (il.Intrinsic ({}, MIPS_INTRIN_R5900_VU_MEM_STORE, {il.Mult (4 , il.Register (4 , op3.reg ), il.Const (4 , 16 )), il.Const (2 , 1 ), il.Register (4 , op2.reg + REG_VF0_Y)}));
4331+ if (dest & (1 << 1 ))
4332+ il.AddInstruction (il.Intrinsic ({}, MIPS_INTRIN_R5900_VU_MEM_STORE, {il.Mult (4 , il.Register (4 , op3.reg ), il.Const (4 , 16 )), il.Const (2 , 2 ), il.Register (4 , op2.reg + REG_VF0_Z)}));
4333+ if (dest & (1 << 0 ))
4334+ il.AddInstruction (il.Intrinsic ({}, MIPS_INTRIN_R5900_VU_MEM_STORE, {il.Mult (4 , il.Register (4 , op3.reg ), il.Const (4 , 16 )), il.Const (2 , 3 ), il.Register (4 , op2.reg + REG_VF0_W)}));
4335+ il.AddInstruction (il.SetRegister (2 , op3.reg , il.Add (2 , il.Register (2 , op3.reg ), il.Const (2 , op1.immediate ))));
4336+ break ;
4337+ }
4338+
4339+ case MIPS_VCALLMS:
4340+ {
4341+ il.AddInstruction (il.Intrinsic ({}, MIPS_INTRIN_R5900_VU0_CALLMS, {il.Const (4 , op1.immediate )}));
4342+ break ;
4343+ }
4344+ case MIPS_VCALLMSR:
4345+ {
4346+ il.AddInstruction (il.Intrinsic ({}, MIPS_INTRIN_R5900_VU0_CALLMSR, {}));
4347+ break ;
4348+ }
4349+
41864350
41874351 // case MIPS_VDIV:
41884352 case MIPS_VIADD:
@@ -4237,20 +4401,14 @@ bool GetLowLevelILForInstruction(Architecture* arch, uint64_t addr, LowLevelILFu
42374401 // case MIPS_VRSQRT:
42384402 // case MIPS_VSQRT:
42394403
4240- case MIPS_VCALLMS:
4241- case MIPS_VCALLMSR:
4242-
42434404 case MIPS_VFTOI0:
42444405 case MIPS_VFTOI15:
42454406 case MIPS_VFTOI4:
42464407 case MIPS_VITOF0:
42474408 case MIPS_VITOF15:
42484409 case MIPS_VITOF4:
42494410
4250- case MIPS_VLQI:
4251- case MIPS_VSQI:
4252- il.AddInstruction (il.Unimplemented ());
4253- break ;
4411+
42544412
42554413 // instructions that are just internal placeholders for other
42564414 // decode tables; these will never be implemented because they're
0 commit comments