From 98bb9490c8d733a6fbe5c8983ef619452a09a803 Mon Sep 17 00:00:00 2001 From: yrp Date: Sat, 25 May 2024 15:39:48 -0700 Subject: [PATCH] arm64: lift scvtf --- arch/arm64/arm64test.py | 8 ++++-- arch/arm64/il.cpp | 9 +++++++ arch/arm64/misc/neon_intrins.c | 22 ----------------- arch/arm64/neon_intrinsics.cpp | 45 ---------------------------------- 4 files changed, 15 insertions(+), 69 deletions(-) diff --git a/arch/arm64/arm64test.py b/arch/arm64/arm64test.py index 0d568f3893..5bed976296 100755 --- a/arch/arm64/arm64test.py +++ b/arch/arm64/arm64test.py @@ -564,8 +564,12 @@ ] tests_scvtf = [ - # scvtf d1, x15 SCVTF_D64_float2int - (b'\xe1\x01b\x9e', 'LLIL_INTRINSIC([d1],vcvtd_f64_s64,[LLIL_REG.q(x15)])') + # scvtf d1, x15 SCVTF_D64_float2int + (b'\xe1\x01b\x9e', 'LLIL_SET_REG.q(d1,LLIL_FLOAT_TO_INT.q(LLIL_REG.q(x15)))'), + # scvtf d0, d1 + (b'\x20\xd8\x61\x5e', 'LLIL_SET_REG.q(d0,LLIL_FLOAT_TO_INT.q(LLIL_REG.q(d1)))'), + # svctf d0, d1, #0xf + (b'\x20\xe4\x71\x5f', 'LLIL_SET_REG.q(,LLIL_FLOAT_TO_INT.q(LLIL_AND.q(LLIL_REG.q(d1),LLIL_CONST.q(0x7FFF))))'), ] tests_ret = [ diff --git a/arch/arm64/il.cpp b/arch/arm64/il.cpp index d3c3e94366..a6e3e45987 100644 --- a/arch/arm64/il.cpp +++ b/arch/arm64/il.cpp @@ -2189,6 +2189,15 @@ bool GetLowLevelILForInstruction( il.Const(1, (REGSZ_O(operand1) * 8) - IMM_O(operand4) - IMM_O(operand3))), il.Const(1, (REGSZ_O(operand1) * 8) - IMM_O(operand4))))); break; + case ARM64_SCVTF: + if (operand3.operandClass == NONE) { + il.AddInstruction(ILSETREG_O(operand1, il.FloatToInt(REGSZ_O(operand1), ILREG_O(operand2)))); + } else { + if (IMM_O(operand3) > (REGSZ_O(operand1) * 8)) + ABORT_LIFT; + il.AddInstruction(ILSETREG_O(operand1, il.FloatToInt(REGSZ_O(operand1), ExtractBits(il, operand2, IMM_O(operand3), 0)))); + } + break; case ARM64_SDIV: il.AddInstruction(ILSETREG_O( operand1, il.DivSigned(REGSZ_O(operand2), ILREG_O(operand2), ILREG_O(operand3)))); diff --git a/arch/arm64/misc/neon_intrins.c b/arch/arm64/misc/neon_intrins.c index ff0e5efc77..978d1c9d40 100644 --- a/arch/arm64/misc/neon_intrins.c +++ b/arch/arm64/misc/neon_intrins.c @@ -1241,29 +1241,17 @@ uint64x1_t vcvt_n_u64_f64(float64x1_t a, const int n); // FCVT uint64x2_t vcvtq_n_u64_f64(float64x2_t a, const int n); // FCVTZU Vd.2D,Vn.2D,#n int64_t vcvtd_n_s64_f64(float64_t a, const int n); // FCVTZS Dd,Dn,#n uint64_t vcvtd_n_u64_f64(float64_t a, const int n); // FCVTZU Dd,Dn,#n -float32x2_t vcvt_f32_s32(int32x2_t a); // SCVTF Vd.2S,Vn.2S -float32x4_t vcvtq_f32_s32(int32x4_t a); // SCVTF Vd.4S,Vn.4S float32x2_t vcvt_f32_u32(uint32x2_t a); // UCVTF Vd.2S,Vn.2S float32x4_t vcvtq_f32_u32(uint32x4_t a); // UCVTF Vd.4S,Vn.4S -float32_t vcvts_f32_s32(int32_t a); // SCVTF Sd,Sn float32_t vcvts_f32_u32(uint32_t a); // UCVTF Sd,Sn -float64x1_t vcvt_f64_s64(int64x1_t a); // SCVTF Dd,Dn -float64x2_t vcvtq_f64_s64(int64x2_t a); // SCVTF Vd.2D,Vn.2D float64x1_t vcvt_f64_u64(uint64x1_t a); // UCVTF Dd,Dn float64x2_t vcvtq_f64_u64(uint64x2_t a); // UCVTF Vd.2D,Vn.2D -float64_t vcvtd_f64_s64(int64_t a); // SCVTF Dd,Dn float64_t vcvtd_f64_u64(uint64_t a); // UCVTF Dd,Dn -float32x2_t vcvt_n_f32_s32(int32x2_t a, const int n); // SCVTF Vd.2S,Vn.2S,#n -float32x4_t vcvtq_n_f32_s32(int32x4_t a, const int n); // SCVTF Vd.4S,Vn.4S,#n float32x2_t vcvt_n_f32_u32(uint32x2_t a, const int n); // UCVTF Vd.2S,Vn.2S,#n float32x4_t vcvtq_n_f32_u32(uint32x4_t a, const int n); // UCVTF Vd.4S,Vn.4S,#n -float32_t vcvts_n_f32_s32(int32_t a, const int n); // SCVTF Sd,Sn,#n float32_t vcvts_n_f32_u32(uint32_t a, const int n); // UCVTF Sd,Sn,#n -float64x1_t vcvt_n_f64_s64(int64x1_t a, const int n); // SCVTF Dd,Dn,#n -float64x2_t vcvtq_n_f64_s64(int64x2_t a, const int n); // SCVTF Vd.2D,Vn.2D,#n float64x1_t vcvt_n_f64_u64(uint64x1_t a, const int n); // UCVTF Dd,Dn,#n float64x2_t vcvtq_n_f64_u64(uint64x2_t a, const int n); // UCVTF Vd.2D,Vn.2D,#n -float64_t vcvtd_n_f64_s64(int64_t a, const int n); // SCVTF Dd,Dn,#n float64_t vcvtd_n_f64_u64(uint64_t a, const int n); // UCVTF Dd,Dn,#n float16x4_t vcvt_f16_f32(float32x4_t a); // FCVTN Vd.4H,Vn.4S float16x8_t vcvt_high_f16_f32(float16x4_t r, float32x4_t a); // FCVTN2 Vd.8H,Vn.4S @@ -4284,9 +4272,6 @@ uint16_t vcgezh_f16(float16_t a); // FCMGE Hd uint16_t vcgtzh_f16(float16_t a); // FCMGT Hd,Hn,#0 uint16_t vclezh_f16(float16_t a); // FCMLE Hd,Hn,#0 uint16_t vcltzh_f16(float16_t a); // FCMLT Hd,Hn,#0 -float16_t vcvth_f16_s16(int16_t a); // SCVTF Hd,Hn -float16_t vcvth_f16_s32(int32_t a); // SCVTF Hd,Hn -float16_t vcvth_f16_s64(int64_t a); // SCVTF Hd,Hn float16_t vcvth_f16_u16(uint16_t a); // UCVTF Hd,Hn float16_t vcvth_f16_u32(uint32_t a); // UCVTF Hd,Hn float16_t vcvth_f16_u64(uint64_t a); // UCVTF Hd,Hn @@ -4343,9 +4328,6 @@ uint16_t vcgeh_f16(float16_t a, float16_t b); // FCMGE Hd uint16_t vcgth_f16(float16_t a, float16_t b); // FCMGT Hd,Hn,Hm uint16_t vcleh_f16(float16_t a, float16_t b); // FCMGE Hd,Hn,Hm uint16_t vclth_f16(float16_t a, float16_t b); // FCMGT Hd,Hn,Hm -float16_t vcvth_n_f16_s16(int16_t a, const int n); // SCVTF Hd,Hn,#n -float16_t vcvth_n_f16_s32(int32_t a, const int n); // SCVTF Hd,Hn,#n -float16_t vcvth_n_f16_s64(int64_t a, const int n); // SCVTF Hd,Hn,#n float16_t vcvth_n_f16_u16(uint16_t a, const int n); // UCVTF Hd,Hn,#n float16_t vcvth_n_f16_u32(uint32_t a, const int n); // UCVTF Hd,Hn,#n float16_t vcvth_n_f16_u64(uint64_t a, const int n); // UCVTF Hd,Hn,#n @@ -4379,8 +4361,6 @@ uint16x4_t vclez_f16(float16x4_t a); // FCMLE Vd uint16x8_t vclezq_f16(float16x8_t a); // FCMLE Vd.8H,Vn.8H,#0 uint16x4_t vcltz_f16(float16x4_t a); // FCMLT Vd.4H,Vn.4H,#0 uint16x8_t vcltzq_f16(float16x8_t a); // FCMLT Vd.8H,Vn.8H,#0 -float16x4_t vcvt_f16_s16(int16x4_t a); // SCVTF Vd.4H,Vn.4H,#0 -float16x8_t vcvtq_f16_s16(int16x8_t a); // SCVTF Vd.8H,Vn.8H,#0 float16x4_t vcvt_f16_u16(uint16x4_t a); // UCVTF Vd.4H,Vn.4H,#0 float16x8_t vcvtq_f16_u16(uint16x8_t a); // UCVTF Vd.8H,Vn.8H int16x4_t vcvt_s16_f16(float16x4_t a); // FCVTZS Vd.4H,Vn.4H @@ -4447,8 +4427,6 @@ uint16x4_t vcle_f16(float16x4_t a, float16x4_t b); // FCMGE Vd uint16x8_t vcleq_f16(float16x8_t a, float16x8_t b); // FCMGE Vd.8H,Vn.8H,Vm.8H uint16x4_t vclt_f16(float16x4_t a, float16x4_t b); // FCMGT Vd.4H,Vn.4H,Vm.4H uint16x8_t vcltq_f16(float16x8_t a, float16x8_t b); // FCMGT Vd.8H,Vn.8H,Vm.8H -float16x4_t vcvt_n_f16_s16(int16x4_t a, const int n); // SCVTF Vd.4H,Vn.4H,#n -float16x8_t vcvtq_n_f16_s16(int16x8_t a, const int n); // SCVTF Vd.8H,Vn.8H,#n float16x4_t vcvt_n_f16_u16(uint16x4_t a, const int n); // UCVTF Vd.4H,Vn.4H,#n float16x8_t vcvtq_n_f16_u16(uint16x8_t a, const int n); // UCVTF Vd.8H,Vn.8H,#n int16x4_t vcvt_n_s16_f16(float16x4_t a, const int n); // FCVTZS Vd.4H,Vn.4H,#n diff --git a/arch/arm64/neon_intrinsics.cpp b/arch/arm64/neon_intrinsics.cpp index 037fc1ae1c..a62e742af7 100644 --- a/arch/arm64/neon_intrinsics.cpp +++ b/arch/arm64/neon_intrinsics.cpp @@ -17594,51 +17594,6 @@ bool NeonGetLowLevelILForInstruction( add_input_reg(inputs, il, instr.operands[2]); add_output_reg(outputs, il, instr.operands[0]); break; - case ENC_SCVTF_D64_FLOAT2INT: - // Lift instruction such as `scvtf d3, x15` to vcvtd_f64_s64(int64_t) - intrin_id = ARM64_INTRIN_VCVTD_F64_S64; // SCVTF Dd,Dn - add_input_reg(inputs, il, instr.operands[1]); - add_output_reg(outputs, il, instr.operands[0]); - break; - case ENC_SCVTF_D32_FLOAT2INT: - intrin_id = ARM64_INTRIN_VCVT_F64_S64; // SCVTF Dd,Dn - add_input_reg(inputs, il, instr.operands[1]); - add_output_reg(outputs, il, instr.operands[0]); - break; - case ENC_SCVTF_S32_FLOAT2INT: - intrin_id = ARM64_INTRIN_VCVTS_F32_S32; // SCVTF Sd,Sn - add_input_reg(inputs, il, instr.operands[1]); - add_output_reg(outputs, il, instr.operands[0]); - break; - case ENC_SCVTF_ASIMDMISCFP16_R: - if (instr.operands[1].arrSpec == ARRSPEC_2SINGLES) - intrin_id = ARM64_INTRIN_VCVT_F32_S32; // SCVTF Vd.2S,Vn.2S - if (instr.operands[1].arrSpec == ARRSPEC_4SINGLES) - intrin_id = ARM64_INTRIN_VCVTQ_F32_S32; // SCVTF Vd.4S,Vn.4S - if (instr.operands[1].arrSpec == ARRSPEC_2DOUBLES) - intrin_id = ARM64_INTRIN_VCVTQ_F64_S64; // SCVTF Vd.2D,Vn.2D - if (instr.operands[1].arrSpec == ARRSPEC_2SINGLES) - intrin_id = ARM64_INTRIN_VCVT_N_F32_S32; // SCVTF Vd.2S,Vn.2S,#n - if (instr.operands[1].arrSpec == ARRSPEC_4SINGLES) - intrin_id = ARM64_INTRIN_VCVTQ_N_F32_S32; // SCVTF Vd.4S,Vn.4S,#n - if (instr.operands[1].arrSpec == ARRSPEC_2DOUBLES) - intrin_id = ARM64_INTRIN_VCVTQ_N_F64_S64; // SCVTF Vd.2D,Vn.2D,#n - if (instr.operands[1].arrSpec == ARRSPEC_4HALVES) - intrin_id = ARM64_INTRIN_VCVT_F16_S16; // SCVTF Vd.4H,Vn.4H,#0 - if (instr.operands[1].arrSpec == ARRSPEC_8HALVES) - intrin_id = ARM64_INTRIN_VCVTQ_F16_S16; // SCVTF Vd.8H,Vn.8H,#0 - if (instr.operands[1].arrSpec == ARRSPEC_4HALVES) - intrin_id = ARM64_INTRIN_VCVT_N_F16_S16; // SCVTF Vd.4H,Vn.4H,#n - if (instr.operands[1].arrSpec == ARRSPEC_8HALVES) - intrin_id = ARM64_INTRIN_VCVTQ_N_F16_S16; // SCVTF Vd.8H,Vn.8H,#n - add_input_reg(inputs, il, instr.operands[1]); - add_output_reg(outputs, il, instr.operands[0]); - break; - case ENC_SCVTF_ASISDMISCFP16_R: - intrin_id = ARM64_INTRIN_VCVTH_F16_S16; // SCVTF Hd,Hn - add_input_reg(inputs, il, instr.operands[1]); - add_output_reg(outputs, il, instr.operands[0]); - break; case ENC_SDOT_ASIMDELEM_D: if (instr.operands[0].arrSpec == ARRSPEC_2SINGLES) intrin_id = ARM64_INTRIN_VDOT_LANE_S32; // SDOT Vd.2S,Vn.8B,Vm.4B[lane]