From 2aa2a28a341a2290fe0328a46dbe8e3d7bb3ba4d Mon Sep 17 00:00:00 2001 From: Galen Williamson Date: Fri, 8 Aug 2025 14:30:49 -0400 Subject: Corrected python docstring for LowLevelILFunction.float_convert [thumb2] removed redundant format suffixes from disassembly of VFP instruction [thumb2] Corrected lifting of VCVT instruction --- arch/armv7/thumb2_disasm/disassembler.cpp | 19 ++-- arch/armv7/thumb2_disasm/il_thumb2.cpp | 154 ++++++++++++++++++++++++------ 2 files changed, 135 insertions(+), 38 deletions(-) (limited to 'arch') diff --git a/arch/armv7/thumb2_disasm/disassembler.cpp b/arch/armv7/thumb2_disasm/disassembler.cpp index 8c7902b7..6910307f 100644 --- a/arch/armv7/thumb2_disasm/disassembler.cpp +++ b/arch/armv7/thumb2_disasm/disassembler.cpp @@ -317,15 +317,16 @@ std::string get_thumb_operation_name(struct decomp_result* result) contents += tlookup[tindex]; contents += slookup[sindex]; } - if (format->operationFlags & INSTR_FORMAT_FLAG_F16) { - contents += ".F16"; - } - if (format->operationFlags & INSTR_FORMAT_FLAG_F32) { - contents += ".F32"; - } - if (format->operationFlags & INSTR_FORMAT_FLAG_F64) { - contents += ".F64"; - } + // These are obviated by the type specifier being included in the instruction_format.operation field in spec.cpp + // if (format->operationFlags & INSTR_FORMAT_FLAG_F16) { + // contents += ".F16"; + // } + // if (format->operationFlags & INSTR_FORMAT_FLAG_F32) { + // contents += ".F32"; + // } + // if (format->operationFlags & INSTR_FORMAT_FLAG_F64) { + // contents += ".F64"; + // } if (format->operationFlags & INSTR_FORMAT_FLAG_WIDE) { contents += ".w"; diff --git a/arch/armv7/thumb2_disasm/il_thumb2.cpp b/arch/armv7/thumb2_disasm/il_thumb2.cpp index 48dcf4ac..a9205b39 100644 --- a/arch/armv7/thumb2_disasm/il_thumb2.cpp +++ b/arch/armv7/thumb2_disasm/il_thumb2.cpp @@ -1821,47 +1821,143 @@ bool GetLowLevelILForNEONInstruction(Architecture* arch, LowLevelILFunction& il, il.AddInstruction(WriteILOperand(il, instr, 0, ReadILOperand(il, instr, 1), GetRegisterSize(instr, 1))); break; case armv7::ARMV7_VCVT: - if (instr->format->operandCount == 3) + // if (instr->format->operandCount == 3) + if (IS_FIELD_PRESENT(instr, FIELD_to_fixed)) { - // TODO: Fixed point unsupported. + if (IS_FIELD_PRESENT(instr, FIELD_imm)) + { + // VCVT (between floating-point and fixed-point, Floating-point) + /* VCVT.F32.
,,# */ + /* VCVT.F64.
,
,# */ + /* VCVT.
,,# */ + /* VCVT.
,
,# */ + // TODO: fixed-point unsupported. + il.AddInstruction(il.Unimplemented()); + } + else if (IS_FIELD_PRESENT(instr, FIELD_fbits)) + { + // VCVT (between floating-point and fixed-point, Advanced SIMD) + /* VCVT.
,,# */ + /* VCVT.
,,# */ + // TODO: vector and fixed-point unsupported. + } + } + else if (IS_FIELD_PRESENT(instr, FIELD_half_to_single)) + { + // VCVT (between half-precision and single-precision, Advanced SIMD) + /* VCVT.F16.F32
, */ + /* VCVT.F32.F16 , */ + // TODO: vector and half-precision unsupported. il.AddInstruction(il.Unimplemented()); } - else if (instr->format->operationFlags & (INSTR_FORMAT_FLAG_F32 | INSTR_FORMAT_FLAG_F64)) + else if (IS_FIELD_PRESENT(instr, FIELD_double_to_single)) { - il.AddInstruction( - WriteILOperand(il, instr, 0, il.FloatConvert(GetRegisterSize(instr, 1), ReadILOperand(il, instr, 1)))); + // VCVT (between double-precision and single-precision) + /* VCVT.F64.F32
, */ + /* VCVT.F32.F64 , */ + il.AddInstruction(WriteILOperand( + il, instr, 0, il.FloatConvert(GetRegisterSize(instr, 1), ReadILOperand(il, instr, 1)))); + break; } - else if (IS_FIELD_PRESENT(instr, FIELD_td)) + else if (IS_FIELD_PRESENT(instr, FIELD_to_integer)) { - switch (instr->fields[FIELD_dt]) + if (IS_FIELD_PRESENT(instr, FIELD_td)) { - case VFP_DATA_SIZE_S32F32: - case VFP_DATA_SIZE_U32F32: - il.AddInstruction(WriteILOperand( - il, instr, 0, il.IntToFloat(GetRegisterSize(instr, 1), ReadILOperand(il, instr, 1)))); - break; - case VFP_DATA_SIZE_F32S32: - case VFP_DATA_SIZE_F32U32: - il.AddInstruction(WriteILOperand( - il, instr, 0, il.FloatToInt(GetRegisterSize(instr, 1), ReadILOperand(il, instr, 1)))); - break; - default: - il.AddInstruction(il.Unimplemented()); + // VCVT (between floating-point and integer, Advanced SIMD) + /* VCVT.
, */ // instr->fields[FIELD_regs] = 1 + /* VCVT.
, */ // instr->fields[FIELD_regs] = 2 + switch (instr->fields[FIELD_dt]) + { + case VFP_DATA_SIZE_S32F32: + case VFP_DATA_SIZE_U32F32: + // TODO: iterate over vector components + // il.AddInstruction(WriteILOperand( + // il, instr, 0, il.IntToFloat(GetRegisterSize(instr, 1), ReadILOperand(il, instr, 1)))); + // break; + case VFP_DATA_SIZE_F32S32: + case VFP_DATA_SIZE_F32U32: + // TODO: iterate over vector components + // il.AddInstruction(WriteILOperand( + // il, instr, 0, il.FloatToInt(GetRegisterSize(instr, 1), + // il.RoundToInt(GetRegisterSize(instr, 1), + // ReadILOperand(il, instr, 1))))); + // break; + default: + // TODO: vector unsupported. + il.AddInstruction(il.Unimplemented()); + } } - } - else - { - switch (instr->fields[FIELD_dt]) + else if (instr->format->operationFlags & (INSTR_FORMAT_FLAG_F32 | INSTR_FORMAT_FLAG_F64)) { - case VFP_DATA_SIZE_F32: - case VFP_DATA_SIZE_S32: + switch (instr->fields[FIELD_dt]) + { + case VFP_DATA_SIZE_S32: + il.AddInstruction(WriteILOperand( + il, instr, 0, il.IntToFloat(GetRegisterSize(instr, 0), + il.SignExtend(GetRegisterSize(instr, 0), + ReadILOperand(il, instr, 1))))); + break; + case VFP_DATA_SIZE_U32: + il.AddInstruction(WriteILOperand( + il, instr, 0, il.IntToFloat(GetRegisterSize(instr, 0), + il.ZeroExtend(GetRegisterSize(instr, 0), + ReadILOperand(il, instr, 1))))); + break; + } + // il.AddInstruction(WriteILOperand( + // il, instr, 0, il.IntToFloat(GetRegisterSize(instr, 0), ReadILOperand(il, instr, 1)))); + } + else + { + // VCVT, VCVTR (between floating-point and integer, Floating-point) + switch (instr->fields[FIELD_dt]) + { + case VFP_DATA_SIZE_S32F32: + il.AddInstruction(WriteILOperand( + il, instr, 0, il.SignExtend(GetRegisterSize(instr, 0), + il.FloatToInt(GetRegisterSize(instr, 0), + il.RoundToInt(GetRegisterSize(instr, 0), + ReadILOperand(il, instr, 1)))))); + break; + case VFP_DATA_SIZE_U32F32: + // case VFP_DATA_SIZE_S32F64: + // case VFP_DATA_SIZE_U32F64: il.AddInstruction(WriteILOperand( - il, instr, 0, il.FloatConvert(GetRegisterSize(instr, 1), ReadILOperand(il, instr, 1)))); - break; - default: - il.AddInstruction(il.Unimplemented()); + il, instr, 0, il.ZeroExtend(GetRegisterSize(instr, 0), + il.FloatToInt(GetRegisterSize(instr, 0), + il.RoundToInt(GetRegisterSize(instr, 0), + ReadILOperand(il, instr, 1)))))); + // il.AddInstruction(WriteILOperand( + // il, instr, 0, il.FloatToInt(GetRegisterSize(instr, 1), + // il.RoundToInt(GetRegisterSize(instr, 1), + // ReadILOperand(il, instr, 1))))); + break; + case VFP_DATA_SIZE_F32S32: + case VFP_DATA_SIZE_F32U32: + il.AddInstruction(WriteILOperand( + il, instr, 0, il.IntToFloat(GetRegisterSize(instr, 0), ReadILOperand(il, instr, 1)))); + break; + default: + // Invalid + il.AddInstruction(il.Unimplemented()); + } } } + // else if (IS_FIELD_PRESENT(instr, FIELD_dt)) + // { + // switch (instr->fields[FIELD_dt]) + // { + // case VFP_DATA_SIZE_F32: + // case VFP_DATA_SIZE_S32: + // il.AddInstruction(WriteILOperand( + // il, instr, 0, il.FloatConvert(GetRegisterSize(instr, 1), ReadILOperand(il, instr, 1)))); + // break; + // default: + // il.AddInstruction(il.Unimplemented()); + // } + // } + else + il.AddInstruction(il.Unimplemented()); break; case armv7::ARMV7_VMOV: if (instr->format->operandCount == 4) -- cgit v1.3.1