diff options
| author | Mason Reed <mason@vector35.com> | 2024-08-22 20:24:52 -0400 |
|---|---|---|
| committer | mason <35282038+emesare@users.noreply.github.com> | 2024-08-27 11:16:59 -0700 |
| commit | 0dc3f33a04b2f3fc746c1cce5f02fd61a7308cb6 (patch) | |
| tree | 702d719ef78e74bd74850f8340638f3e90ffd817 | |
| parent | f8218903868c0822d986a0ea43024420ccd6016d (diff) | |
Lift VSTMIA, VLDMIA
| -rw-r--r-- | arch/armv7/thumb2_disasm/il_thumb2.cpp | 49 |
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... |
