summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMason Reed <mason@vector35.com>2024-08-22 20:24:52 -0400
committermason <35282038+emesare@users.noreply.github.com>2024-08-27 11:16:59 -0700
commit0dc3f33a04b2f3fc746c1cce5f02fd61a7308cb6 (patch)
tree702d719ef78e74bd74850f8340638f3e90ffd817
parentf8218903868c0822d986a0ea43024420ccd6016d (diff)
Lift VSTMIA, VLDMIA
-rw-r--r--arch/armv7/thumb2_disasm/il_thumb2.cpp49
1 files changed, 49 insertions, 0 deletions
diff --git a/arch/armv7/thumb2_disasm/il_thumb2.cpp b/arch/armv7/thumb2_disasm/il_thumb2.cpp
index 7dbad75a..110d2511 100644
--- a/arch/armv7/thumb2_disasm/il_thumb2.cpp
+++ b/arch/armv7/thumb2_disasm/il_thumb2.cpp
@@ -1540,6 +1540,55 @@ bool GetLowLevelILForNEONInstruction(Architecture* arch, LowLevelILFunction& il,
il.AddInstruction(WriteILOperand(il, instr, 0, ReadILOperand(il, instr, 1)));
}
break;
+ case armv7::ARMV7_VSTMDB:
+ {
+ // TODO: Clean this code up...
+ const char* prefix = "d";
+ if (IS_FIELD_PRESENT(instr, FIELD_single_regs)){
+ if (instr->fields[FIELD_single_regs] == 1) {
+ prefix = "s";
+ }
+ }
+ auto regSize = RegisterSizeFromPrefix(prefix);
+ unsigned int d = instr->fields[FIELD_d];
+ unsigned int inc = 1;
+ if(IS_FIELD_PRESENT(instr, FIELD_inc))
+ inc = instr->fields[FIELD_inc];
+ int regs = instr->fields[FIELD_regs];
+ for(int i=0; i<regs; ++i) {
+ if (d+(i*inc) >= 32 && strcmp(prefix, "s") == 0) break;
+ if (i >= 16 && strcmp(prefix, "d") == 0) break;
+ int regIdx = (d + i * inc) % 32;
+ il.Store(regSize, il.Add(4, ReadILOperand(il, instr, 0), il.Const(4, i * regSize)),
+ il.Register(regSize, GetRegisterByIndex(regIdx, prefix)));
+ }
+ }
+ break;
+ case armv7::ARMV7_VLDMDB:
+ {
+ // TODO: Clean this code up...
+ const char* prefix = "d";
+ if (IS_FIELD_PRESENT(instr, FIELD_single_regs)){
+ if (instr->fields[FIELD_single_regs] == 1) {
+ prefix = "s";
+ }
+ }
+ auto regSize = RegisterSizeFromPrefix(prefix);
+ unsigned int d = instr->fields[FIELD_d];
+ unsigned int inc = 1;
+ if(IS_FIELD_PRESENT(instr, FIELD_inc))
+ inc = instr->fields[FIELD_inc];
+ int regs = instr->fields[FIELD_regs];
+ for(int i=0; i<regs; ++i) {
+ if (d+(i*inc) >= 32 && strcmp(prefix, "s") == 0) break;
+ if (i >= 16 && strcmp(prefix, "d") == 0) break;
+ int regIdx = (d + i * inc) % 32;
+ il.AddInstruction(il.SetRegister(regSize, GetRegisterByIndex(regIdx, prefix),
+ il.Load(regSize, il.Add(4, ReadILOperand(il, instr, 0),
+ il.Const(4, i * regSize)))));
+ }
+ }
+ break;
case armv7::ARMV7_VPUSH:
{
// TODO: Clean this code up...