diff options
| author | Galen Williamson <galen@vector35.com> | 2025-08-08 14:30:49 -0400 |
|---|---|---|
| committer | Galen Williamson <galen@vector35.com> | 2025-08-14 14:06:49 -0400 |
| commit | 2aa2a28a341a2290fe0328a46dbe8e3d7bb3ba4d (patch) | |
| tree | 54cb1a70bf0f99889fa18b2905b4f897d5460b6d /arch | |
| parent | 193450bcf90800753aec316322ee651c5520ea57 (diff) | |
Corrected python docstring for LowLevelILFunction.float_convert
[thumb2] removed redundant format suffixes from disassembly of VFP instruction
[thumb2] Corrected lifting of VCVT instruction
Diffstat (limited to 'arch')
| -rw-r--r-- | arch/armv7/thumb2_disasm/disassembler.cpp | 19 | ||||
| -rw-r--r-- | arch/armv7/thumb2_disasm/il_thumb2.cpp | 154 |
2 files changed, 135 insertions, 38 deletions
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<c>.F32.<dt> <Sd>,<Sd>,#<imm> */ + /* VCVT<c>.F64.<dt> <Dd>,<Dd>,#<imm> */ + /* VCVT<c>.<dt> <Sd>,<Sd>,#<imm> */ + /* VCVT<c>.<dt> <Dd>,<Dd>,#<imm> */ + // 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<c>.<dt> <Dd>,<Dm>,#<fbits> */ + /* VCVT<c>.<dt> <Qd>,<Qm>,#<fbits> */ + // 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<c>.F16.F32 <Dd>,<Qm> */ + /* VCVT<c>.F32.F16 <Qd>,<Dm> */ + // 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<c>.F64.F32 <Dd>,<Sm> */ + /* VCVT<c>.F32.F64 <Sd>,<Dm> */ + 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<c>.<dt> <Dd>,<Dm> */ // instr->fields[FIELD_regs] = 1 + /* VCVT<c>.<dt> <Qd>,<Qm> */ // 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) |
