From 6c1a731f22f5094c4751ca88254d6cd4c88b0319 Mon Sep 17 00:00:00 2001 From: Mason Reed Date: Thu, 22 Aug 2024 20:27:16 -0400 Subject: Lift VSUB, VDIV, VMUL, VFMA VSUB already existed but it was lifted as a regular SUB instruction --- arch/armv7/thumb2_disasm/il_thumb2.cpp | 49 +++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/arch/armv7/thumb2_disasm/il_thumb2.cpp b/arch/armv7/thumb2_disasm/il_thumb2.cpp index 0609f134..df205c73 100644 --- a/arch/armv7/thumb2_disasm/il_thumb2.cpp +++ b/arch/armv7/thumb2_disasm/il_thumb2.cpp @@ -1480,7 +1480,54 @@ bool GetLowLevelILForNEONInstruction(Architecture* arch, LowLevelILFunction& il, il.AddInstruction(WriteArithOperand(il, instr, il.Xor(GetRegisterSize(instr, 0), ReadILOperand(il, instr, 1), ReadILOperand(il, instr, 2)))); break; case armv7::ARMV7_VSUB: - il.AddInstruction(WriteArithOperand(il, instr, il.Sub(GetRegisterSize(instr, 0), ReadILOperand(il, instr, 1), ReadILOperand(il, instr, 2)))); + if (strcmp(instr->format->operation, "vsub.f64") == 0 || strcmp(instr->format->operation, "vsub.f32") == 0) + { + il.AddInstruction(WriteArithOperand( + il, instr, il.FloatSub(GetRegisterSize(instr, 0), ReadILOperand(il, instr, 1), + ReadILOperand(il, instr, 2)))); + } else + { + il.AddInstruction(il.Unimplemented()); + } + break; + case armv7::ARMV7_VFMA: + if (strcmp(instr->format->operation, "vfma.f64") == 0 || strcmp(instr->format->operation, "vfma.f32") == 0) + { + il.AddInstruction(WriteArithOperand(il, instr,il.FloatAdd( + GetRegisterSize(instr, 0), ReadILOperand(il, instr, 0), + il.FloatMult(GetRegisterSize(instr, 0), + ReadILOperand(il, instr, 1), + ReadILOperand(il, instr, 2))))); + } + else if (strcmp(instr->format->operation, "vfms.f64") == 0 || strcmp(instr->format->operation, "vfms.f32") == 0) + { + il.AddInstruction(WriteArithOperand(il, instr,il.FloatSub( + GetRegisterSize(instr, 0), ReadILOperand(il, instr, 0), + il.FloatMult(GetRegisterSize(instr, 0), + ReadILOperand(il, instr, 1), + ReadILOperand(il, instr, 2))))); + } + else + { + il.AddInstruction(il.Unimplemented()); + } + break; + case armv7::ARMV7_VMUL: + // TODO: This is not the correct way to get the vmul format right lol? + if (strcmp(instr->format->operation, "vmul.f64") == 0 || strcmp(instr->format->operation, "vmul.f32") == 0) + { + il.AddInstruction(WriteArithOperand( + il, instr, il.FloatMult(GetRegisterSize(instr, 0), ReadILOperand(il, instr, 1), + ReadILOperand(il, instr, 2)))); + } else + { + il.AddInstruction(il.Unimplemented()); + } + break; + case armv7::ARMV7_VDIV: + il.AddInstruction(WriteArithOperand( + il, instr, il.FloatDiv(GetRegisterSize(instr, 0), ReadILOperand(il, instr, 1), + ReadILOperand(il, instr, 2)))); break; case armv7::ARMV7_VMRS: // TODO: If this sets the apsr register we do not track that in the core flag group. -- cgit v1.3.1