summaryrefslogtreecommitdiff
path: root/arch/mips
diff options
context:
space:
mode:
authornoone <you@example.com>2024-07-31 19:53:51 -0500
committerAlexander Taylor <alex@vector35.com>2024-08-12 15:50:54 -0400
commit0bf72f94c49f34fc550c2d5c2fbab7a95ac72628 (patch)
treedd5dc1d0298b208bd4d03149e82edba05fc4d8b4 /arch/mips
parentc79af77b50dee80dcba9800e42e94eb6abb3e53a (diff)
Add intrinsics for some system instructions
Except for SYNCI, I didn't have any test cases for these, but they're fairly simple.
Diffstat (limited to 'arch/mips')
-rw-r--r--arch/mips/arch_mips.cpp17
-rw-r--r--arch/mips/il.cpp12
-rw-r--r--arch/mips/il.h3
3 files changed, 29 insertions, 3 deletions
diff --git a/arch/mips/arch_mips.cpp b/arch/mips/arch_mips.cpp
index 25ce265d..fd90daf0 100644
--- a/arch/mips/arch_mips.cpp
+++ b/arch/mips/arch_mips.cpp
@@ -923,6 +923,8 @@ public:
return "moveDwordToCoprocessorUnimplemented";
case MIPS_INTRIN_SYNC:
return "_sync";
+ case MIPS_INTRIN_SYNCI:
+ return "_SynchronizeCacheLines";
case MIPS_INTRIN_EI:
return "_enableInterrupts";
case MIPS_INTRIN_DI:
@@ -931,6 +933,8 @@ public:
return "_clearExecutionHazards";
case MIPS_INTRIN_WAIT:
return "_enterLowPowerMode";
+ case MIPS_INTRIN_PAUSE:
+ return "_waitForLLbitClear";
case MIPS_INTRIN_HWR0:
return "_cpuNum";
case MIPS_INTRIN_HWR1:
@@ -951,6 +955,8 @@ public:
return "_prefetch";
case MIPS_INTRIN_CACHE:
return "_cache";
+ case MIPS_INTRIN_SDBBP:
+ return "_softwareDebugBreakpoint";
case MIPS_INTRIN_GET_LEFT_PART32:
return "_getLeftPart32";
case MIPS_INTRIN_GET_RIGHT_PART32:
@@ -1004,10 +1010,12 @@ public:
MIPS_INTRIN_DMTC0,
MIPS_INTRIN_DMTC_UNIMPLEMENTED,
MIPS_INTRIN_SYNC,
+ MIPS_INTRIN_SYNCI,
MIPS_INTRIN_DI,
MIPS_INTRIN_EHB,
MIPS_INTRIN_EI,
MIPS_INTRIN_WAIT,
+ MIPS_INTRIN_PAUSE,
MIPS_INTRIN_HWR0,
MIPS_INTRIN_HWR1,
MIPS_INTRIN_HWR2,
@@ -1095,6 +1103,10 @@ public:
return {
NameAndType("stype", Type::IntegerType(4, false)),
};
+ case MIPS_INTRIN_SYNCI:
+ return {
+ NameAndType("vaddr", Type::IntegerType(8, false)),
+ };
case MIPS_INTRIN_HWR_UNKNOWN:
return {
NameAndType("hwreg", Type::IntegerType(4, false)),
@@ -1110,6 +1122,11 @@ public:
NameAndType("address", Type::IntegerType(m_bits == 64 ? 8 : 4, false)),
};
+ case MIPS_INTRIN_SDBBP:
+ return {
+ NameAndType("code", Type::IntegerType(1, false)),
+ };
+
// NOTE: SET_x_PARTx could potentially benefit from
// including the old value as an input (since each
// only sets part of the register and keeps the
diff --git a/arch/mips/il.cpp b/arch/mips/il.cpp
index e056c7aa..14639e74 100644
--- a/arch/mips/il.cpp
+++ b/arch/mips/il.cpp
@@ -1599,7 +1599,7 @@ bool GetLowLevelILForInstruction(Architecture* arch, uint64_t addr, LowLevelILFu
il.AddInstruction(SetRegisterOrNop(il, 4, registerSize, op1.reg, il.RotateRight(4, ReadILOperand(il, instr, 2, registerSize), ReadILOperand(il, instr, 3, registerSize))));
break;
case MIPS_SDBBP:
- il.AddInstruction(il.Unimplemented());
+ il.AddInstruction(il.Intrinsic({}, MIPS_INTRIN_SDBBP, { il.Const(1, op1.immediate )}));
break;
case MIPS_SEB:
il.AddInstruction(SetRegisterOrNop(il, registerSize, registerSize, op1.reg, il.SignExtend(registerSize, il.LowPart(1, ReadILOperand(il, instr, 2, registerSize)))));
@@ -1810,6 +1810,10 @@ bool GetLowLevelILForInstruction(Architecture* arch, uint64_t addr, LowLevelILFu
break;
}
+ case MIPS_SYNCI:
+ il.AddInstruction(il.Intrinsic({}, MIPS_INTRIN_SYNCI, { GetILOperandMemoryAddress(il, op1, addrSize) }));
+ break;
+
case MIPS_DI:
il.AddInstruction(SimpleIntrinsic(il, MIPS_INTRIN_DI));
break;
@@ -1822,6 +1826,10 @@ bool GetLowLevelILForInstruction(Architecture* arch, uint64_t addr, LowLevelILFu
il.AddInstruction(SimpleIntrinsic(il, MIPS_INTRIN_EI));
break;
+ case MIPS_PAUSE:
+ il.AddInstruction(SimpleIntrinsic(il, MIPS_INTRIN_PAUSE));
+ break;
+
case MIPS_WAIT:
il.AddInstruction(SimpleIntrinsic(il, MIPS_INTRIN_WAIT));
break;
@@ -2126,9 +2134,7 @@ bool GetLowLevelILForInstruction(Architecture* arch, uint64_t addr, LowLevelILFu
case MIPS_JALX: //Special instruction for switching to MIPS32/microMIPS32/MIPS16e
case MIPS_MTHC1:
case MIPS_MTHC2:
- case MIPS_PAUSE:
case MIPS_PREFX:
- case MIPS_SYNCI:
case MIPS_TLBP:
case MIPS_TLBR:
case MIPS_TLBWI:
diff --git a/arch/mips/il.h b/arch/mips/il.h
index abb3d939..c4ffff75 100644
--- a/arch/mips/il.h
+++ b/arch/mips/il.h
@@ -22,9 +22,11 @@ enum MipsIntrinsic : uint32_t
MIPS_INTRIN_DMTC2,
MIPS_INTRIN_DMTC_UNIMPLEMENTED,
MIPS_INTRIN_SYNC,
+ MIPS_INTRIN_SYNCI,
MIPS_INTRIN_DI,
MIPS_INTRIN_EHB,
MIPS_INTRIN_EI,
+ MIPS_INTRIN_PAUSE,
MIPS_INTRIN_WAIT,
MIPS_INTRIN_HWR0,
MIPS_INTRIN_HWR1,
@@ -36,6 +38,7 @@ enum MipsIntrinsic : uint32_t
MIPS_INTRIN_LLBIT_CHECK,
MIPS_INTRIN_PREFETCH,
MIPS_INTRIN_CACHE,
+ MIPS_INTRIN_SDBBP,
// there's no clean way to lift LWL/LWR, SWL/SWR, etc when not
// a pair of adjacent instructions, since the number and position