Skip to content

Commit 742b25d

Browse files
jonathanzetiergalenbwill
authored andcommitted
Add IL for thumb2 CP instructions
1 parent cd2f20b commit 742b25d

File tree

2 files changed

+146
-1
lines changed

2 files changed

+146
-1
lines changed

arch/armv7/thumb2_disasm/arch_thumb2.cpp

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1177,7 +1177,7 @@ class Thumb2Architecture: public ArmCommonArchitecture
11771177
if(reg == 15)
11781178
result.emplace_back(RegisterToken, "apsr_nzcv");
11791179
else {
1180-
snprintf(regname, sizeof(regname), "R%d", reg);
1180+
get_reg_name(REG_R0 + reg, regname);
11811181
result.emplace_back(RegisterToken, regname);
11821182
}
11831183
break;
@@ -1347,6 +1347,14 @@ class Thumb2Architecture: public ArmCommonArchitecture
13471347
{
13481348
switch (intrinsic)
13491349
{
1350+
case ARMV7_INTRIN_COPROC_GETONEWORD:
1351+
return "Coproc_GetOneWord";
1352+
case ARMV7_INTRIN_COPROC_GETTWOWORDS:
1353+
return "Coproc_GetTwoWords";
1354+
case ARMV7_INTRIN_COPROC_SENDONEWORD:
1355+
return "Coproc_SendOneWord";
1356+
case ARMV7_INTRIN_COPROC_SENDTWOWORDS:
1357+
return "Coproc_SendTwoWords";
13501358
case ARMV7_INTRIN_DBG:
13511359
return "__dbg";
13521360
case ARMV7_INTRIN_DMB_SY:
@@ -1403,6 +1411,10 @@ class Thumb2Architecture: public ArmCommonArchitecture
14031411
virtual vector<uint32_t> GetAllIntrinsics() override
14041412
{
14051413
return vector<uint32_t> {
1414+
ARMV7_INTRIN_COPROC_GETONEWORD,
1415+
ARMV7_INTRIN_COPROC_GETTWOWORDS,
1416+
ARMV7_INTRIN_COPROC_SENDONEWORD,
1417+
ARMV7_INTRIN_COPROC_SENDTWOWORDS,
14061418
ARMV7_INTRIN_DBG,
14071419
ARMV7_INTRIN_DMB_SY,
14081420
ARMV7_INTRIN_DMB_ST,
@@ -1433,6 +1445,37 @@ class Thumb2Architecture: public ArmCommonArchitecture
14331445
{
14341446
switch (intrinsic)
14351447
{
1448+
case ARMV7_INTRIN_COPROC_GETONEWORD:
1449+
return {
1450+
NameAndType("cp", Type::IntegerType(1, false)),
1451+
NameAndType(Type::IntegerType(1, false)),
1452+
NameAndType("n", Type::IntegerType(1, false)),
1453+
NameAndType("m", Type::IntegerType(1, false)),
1454+
NameAndType(Type::IntegerType(1, false)),
1455+
};
1456+
case ARMV7_INTRIN_COPROC_GETTWOWORDS:
1457+
return {
1458+
NameAndType("cp", Type::IntegerType(1, false)),
1459+
NameAndType(Type::IntegerType(1, false)),
1460+
NameAndType("m", Type::IntegerType(1, false)),
1461+
};
1462+
case ARMV7_INTRIN_COPROC_SENDONEWORD:
1463+
return {
1464+
NameAndType(Type::IntegerType(4, false)),
1465+
NameAndType("cp", Type::IntegerType(1, false)),
1466+
NameAndType(Type::IntegerType(1, false)),
1467+
NameAndType("n", Type::IntegerType(1, false)),
1468+
NameAndType("m", Type::IntegerType(1, false)),
1469+
NameAndType(Type::IntegerType(1, false)),
1470+
};
1471+
case ARMV7_INTRIN_COPROC_SENDTWOWORDS:
1472+
return {
1473+
NameAndType(Type::IntegerType(4, false)),
1474+
NameAndType(Type::IntegerType(4, false)),
1475+
NameAndType("cp", Type::IntegerType(1, false)),
1476+
NameAndType(Type::IntegerType(1, false)),
1477+
NameAndType("m", Type::IntegerType(1, false)),
1478+
};
14361479
case ARMV7_INTRIN_MRS:
14371480
return {NameAndType(Type::IntegerType(4, false))};
14381481
case ARMV7_INTRIN_MSR:
@@ -1448,6 +1491,10 @@ class Thumb2Architecture: public ArmCommonArchitecture
14481491
{
14491492
switch (intrinsic)
14501493
{
1494+
case ARMV7_INTRIN_COPROC_GETONEWORD:
1495+
return { Type::IntegerType(4, false) };
1496+
case ARMV7_INTRIN_COPROC_GETTWOWORDS:
1497+
return { Type::IntegerType(4, false), Type::IntegerType(4, false) };
14511498
case ARMV7_INTRIN_MRS:
14521499
return {Type::IntegerType(4, false)};
14531500
case ARMV7_INTRIN_MSR:

arch/armv7/thumb2_disasm/il_thumb2.cpp

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -973,6 +973,44 @@ bool GetLowLevelILForThumbInstruction(Architecture* arch, LowLevelILFunction& il
973973
il.AddInstruction(WriteArithOperand(il, instr, il.LogicalShiftRight(4, ReadArithOperand(il, instr, 0),
974974
ReadArithOperand(il, instr, 1), ifThenBlock ? 0 : IL_FLAGWRITE_CNZ)));
975975
break;
976+
case armv7::ARMV7_MCR:
977+
case armv7::ARMV7_MCR2:
978+
{
979+
int dest_reg_field = instr->fields[instr->format->operands[2].field0];
980+
int dest_reg = GetRegisterByIndex(dest_reg_field, instr->format->operands[2].prefix);
981+
982+
il.AddInstruction(
983+
il.Intrinsic({ }, ARMV7_INTRIN_COPROC_SENDONEWORD,
984+
{
985+
il.Register(4, dest_reg),
986+
il.Const(1, instr->fields[instr->format->operands[0].field0]),
987+
il.Const(1, instr->fields[instr->format->operands[1].field0]),
988+
il.Const(1, instr->fields[instr->format->operands[3].field0]),
989+
il.Const(1, instr->fields[instr->format->operands[4].field0]),
990+
il.Const(1, instr->fields[instr->format->operands[5].field0]),
991+
}
992+
)
993+
);
994+
break;
995+
}
996+
case ARMV7_MCRR:
997+
case ARMV7_MCRR2:
998+
{
999+
int rt = instr->fields[instr->format->operands[2].field0];
1000+
int rt2 = instr->fields[instr->format->operands[3].field0];
1001+
il.AddInstruction(
1002+
il.Intrinsic({ }, ARMV7_INTRIN_COPROC_SENDTWOWORDS,
1003+
{
1004+
il.Register(4, rt2),
1005+
il.Register(4, rt),
1006+
il.Const(1, instr->fields[instr->format->operands[0].field0]),
1007+
il.Const(1, instr->fields[instr->format->operands[1].field0]),
1008+
il.Const(1, instr->fields[instr->format->operands[4].field0]),
1009+
}
1010+
)
1011+
);
1012+
break;
1013+
}
9761014
case armv7::ARMV7_MLA:
9771015
il.AddInstruction(WriteILOperand(il, instr, 0, il.Add(4, ReadILOperand(il, instr, 3), il.Mult(4, ReadILOperand(il, instr, 1), ReadILOperand(il, instr, 2)))));
9781016
break;
@@ -993,6 +1031,66 @@ bool GetLowLevelILForThumbInstruction(Architecture* arch, LowLevelILFunction& il
9931031
il.ShiftLeft(4, il.Const(2, instr->fields[instr->format->operands[1].field0]), il.Const(1, 16)),
9941032
il.And(4, il.Const(4, 0x0000ffff), ReadILOperand(il, instr, 0)))));
9951033
break;
1034+
case armv7::ARMV7_MRC:
1035+
case armv7::ARMV7_MRC2:
1036+
{
1037+
auto params = {
1038+
il.Const(1, instr->fields[instr->format->operands[0].field0]), /* cp */
1039+
il.Const(1, instr->fields[instr->format->operands[1].field0]), /* opc1 */
1040+
il.Const(1, instr->fields[instr->format->operands[3].field0]), /* crn */
1041+
il.Const(1, instr->fields[instr->format->operands[4].field0]), /* crm */
1042+
il.Const(1, instr->fields[instr->format->operands[5].field0]), /* opc2 */
1043+
};
1044+
1045+
int dest_reg_field = instr->fields[instr->format->operands[2].field0];
1046+
if (dest_reg_field == 15)
1047+
{
1048+
il.AddInstruction(
1049+
il.Intrinsic(
1050+
{ RegisterOrFlag::Register(LLIL_TEMP(0)) },
1051+
ARMV7_INTRIN_COPROC_GETONEWORD,
1052+
params
1053+
)
1054+
);
1055+
il.AddInstruction(il.SetFlag(IL_FLAG_N, il.TestBit(4, il.Register(4, LLIL_TEMP(0)), il.Const(1, 31))));
1056+
il.AddInstruction(il.SetFlag(IL_FLAG_Z, il.TestBit(4, il.Register(4, LLIL_TEMP(0)), il.Const(1, 30))));
1057+
il.AddInstruction(il.SetFlag(IL_FLAG_C, il.TestBit(4, il.Register(4, LLIL_TEMP(0)), il.Const(1, 29))));
1058+
il.AddInstruction(il.SetFlag(IL_FLAG_V, il.TestBit(4, il.Register(4, LLIL_TEMP(0)), il.Const(1, 28))));
1059+
break;
1060+
}
1061+
1062+
int dest_reg = GetRegisterByIndex(dest_reg_field, instr->format->operands[2].prefix);
1063+
1064+
il.AddInstruction(
1065+
il.Intrinsic(
1066+
{RegisterOrFlag::Register(dest_reg)}, /* outputs */
1067+
ARMV7_INTRIN_COPROC_GETONEWORD,
1068+
params /* inputs */
1069+
)
1070+
);
1071+
break;
1072+
}
1073+
1074+
case ARMV7_MRRC:
1075+
case ARMV7_MRRC2:
1076+
{
1077+
int rt = instr->fields[instr->format->operands[2].field0];
1078+
int rt2 = instr->fields[instr->format->operands[3].field0];
1079+
1080+
il.AddInstruction(
1081+
il.Intrinsic(
1082+
{ RegisterOrFlag::Register(rt2), RegisterOrFlag::Register(rt) },
1083+
ARMV7_INTRIN_COPROC_GETTWOWORDS,
1084+
{
1085+
il.Const(1, instr->fields[instr->format->operands[0].field0]),
1086+
il.Const(1, instr->fields[instr->format->operands[1].field0]),
1087+
il.Const(1, instr->fields[instr->format->operands[4].field0]),
1088+
}
1089+
)
1090+
);
1091+
break;
1092+
}
1093+
9961094
case armv7::ARMV7_MRS:
9971095
{
9981096
int dest_reg = GetRegisterByIndex(instr->fields[instr->format->operands[0].field0], instr->format->operands[0].prefix);

0 commit comments

Comments
 (0)