librz/arch/x86: uplift scalar FP SSE/SSE2 insns to RzIL (#6517)
Co-authored-by: Anton Kochkov <anton.kochkov@gmail.com>
This commit is contained in:
parent
62bcb8f6fc
commit
880c8005f7
6 changed files with 372 additions and 0 deletions
231
librz/arch/isa/x86/il_sse_ops.inc
Normal file
231
librz/arch/isa/x86/il_sse_ops.inc
Normal file
|
|
@ -0,0 +1,231 @@
|
|||
// SPDX-FileCopyrightText: 2025 RizinOrg <info@rizin.re>
|
||||
// SPDX-License-Identifier: LGPL-3.0-only
|
||||
|
||||
/**
|
||||
* \file il_sse_ops.inc
|
||||
*
|
||||
* Contains the IL implementations for x86 SSE/SSE2 scalar floating point
|
||||
* instructions, i.e. the ones operating on the low element of an XMM register
|
||||
* (the `*sd` doubles and `*ss` singles) plus the scalar conversions between
|
||||
* integers and floats.
|
||||
*
|
||||
* The legacy (non-VEX) encodings leave the upper bits of the destination XMM
|
||||
* register unmodified, which is what these lifters emulate.
|
||||
*
|
||||
* Rounding follows the MXCSR default (round to nearest, ties to even). MXCSR is
|
||||
* not modelled here, so a different rounding mode programmed into MXCSR is not
|
||||
* reflected, the same way the rest of the x86 lifter does not model every
|
||||
* control register.
|
||||
*
|
||||
* References:
|
||||
* - Intel 64 and IA-32 Architectures Software Developer's Manual, Volume 2
|
||||
* (ADDSD, ADDSS, ..., CVTSI2SD, CVTTSD2SI, ...)
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include <rz_il/rz_il_opbuilder_begin.h>
|
||||
|
||||
/**
|
||||
* \brief Read operand \p op as a scalar float of format \p fmt.
|
||||
*
|
||||
* Handles XMM register operands (reinterpreting the low bits of the 128-bit
|
||||
* register as a float) and memory operands (loading the matching width).
|
||||
*/
|
||||
static RzILOpFloat *x86_il_get_scalar_floating_op(X86Op op, RzFloatFormat fmt, int bits, ut64 pc) {
|
||||
ut8 width = x86_format_to_width(fmt);
|
||||
if (op.type == X86_OP_REG) {
|
||||
/* XMM register: reinterpret the low `width` bits as a float */
|
||||
return BV2F(fmt, CAST(width, IL_FALSE, x86_il_get_reg_bits(op.reg.value, bits, pc)));
|
||||
}
|
||||
/* memory operand: load `width` bits and reinterpret them as a float */
|
||||
return BV2F(fmt, LOADW(width, x86_il_get_memaddr_bits(op.mem, bits, pc)));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Write the scalar float \p val (of format \p fmt) into the low bits of
|
||||
* the destination XMM register operand \p op, leaving the upper bits unmodified
|
||||
* (legacy SSE semantics).
|
||||
*/
|
||||
static RzILOpEffect *x86_il_set_scalar_floating_op(X86Op op, RZ_OWN RZ_NONNULL RzILOpFloat *val, RzFloatFormat fmt, int bits, ut64 pc) {
|
||||
ut8 width = x86_format_to_width(fmt);
|
||||
RzILOpBitVector *result = UNSIGNED(128, F2BV(val));
|
||||
RzILOpBitVector *old = x86_il_get_reg_bits(op.reg.value, bits, pc);
|
||||
/* Clear the low `width` bits of the old value while keeping the upper bits,
|
||||
* then merge in the freshly computed scalar. */
|
||||
RzILOpBitVector *upper = SHIFTL0(SHIFTR0(old, UN(8, width)), UN(8, width));
|
||||
return x86_il_set_reg_bits(op.reg.value, LOGOR(upper, result), bits);
|
||||
}
|
||||
|
||||
/* Scalar arithmetic: ADDSD, ADDSS, SUBSD, SUBSS, MULSD, MULSS, DIVSD, DIVSS */
|
||||
|
||||
/* dest[scalar] = dest[scalar] <il_op> src[scalar]; upper bits of dest preserved */
|
||||
#define SSE_SCALAR_ARITHMETIC(il_op, fmt) \
|
||||
do { \
|
||||
RzFloatFormat _fmt = (fmt); \
|
||||
RzILOpFloat *dst = x86_il_get_scalar_floating_op(ins->operands[0], _fmt, analysis->bits, pc); \
|
||||
RzILOpFloat *src = x86_il_get_scalar_floating_op(ins->operands[1], _fmt, analysis->bits, pc); \
|
||||
RzILOpFloat *res = il_op(RZ_FLOAT_RMODE_RNE, dst, src); \
|
||||
return x86_il_set_scalar_floating_op(ins->operands[0], res, _fmt, analysis->bits, pc); \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* ADDSD
|
||||
* Add the low double precision floating point values
|
||||
*/
|
||||
IL_LIFTER(addsd) {
|
||||
SSE_SCALAR_ARITHMETIC(FADD, RZ_FLOAT_IEEE754_BIN_64);
|
||||
}
|
||||
|
||||
/**
|
||||
* ADDSS
|
||||
* Add the low single precision floating point values
|
||||
*/
|
||||
IL_LIFTER(addss) {
|
||||
SSE_SCALAR_ARITHMETIC(FADD, RZ_FLOAT_IEEE754_BIN_32);
|
||||
}
|
||||
|
||||
/**
|
||||
* SUBSD
|
||||
* Subtract the low double precision floating point values
|
||||
*/
|
||||
IL_LIFTER(subsd) {
|
||||
SSE_SCALAR_ARITHMETIC(FSUB, RZ_FLOAT_IEEE754_BIN_64);
|
||||
}
|
||||
|
||||
/**
|
||||
* SUBSS
|
||||
* Subtract the low single precision floating point values
|
||||
*/
|
||||
IL_LIFTER(subss) {
|
||||
SSE_SCALAR_ARITHMETIC(FSUB, RZ_FLOAT_IEEE754_BIN_32);
|
||||
}
|
||||
|
||||
/**
|
||||
* MULSD
|
||||
* Multiply the low double precision floating point values
|
||||
*/
|
||||
IL_LIFTER(mulsd) {
|
||||
SSE_SCALAR_ARITHMETIC(FMUL, RZ_FLOAT_IEEE754_BIN_64);
|
||||
}
|
||||
|
||||
/**
|
||||
* MULSS
|
||||
* Multiply the low single precision floating point values
|
||||
*/
|
||||
IL_LIFTER(mulss) {
|
||||
SSE_SCALAR_ARITHMETIC(FMUL, RZ_FLOAT_IEEE754_BIN_32);
|
||||
}
|
||||
|
||||
/**
|
||||
* DIVSD
|
||||
* Divide the low double precision floating point values
|
||||
*/
|
||||
IL_LIFTER(divsd) {
|
||||
SSE_SCALAR_ARITHMETIC(FDIV, RZ_FLOAT_IEEE754_BIN_64);
|
||||
}
|
||||
|
||||
/**
|
||||
* DIVSS
|
||||
* Divide the low single precision floating point values
|
||||
*/
|
||||
IL_LIFTER(divss) {
|
||||
SSE_SCALAR_ARITHMETIC(FDIV, RZ_FLOAT_IEEE754_BIN_32);
|
||||
}
|
||||
|
||||
/* Integer to scalar float: CVTSI2SD, CVTSI2SS */
|
||||
|
||||
/* dest[scalar] = (float) signed_int(src); upper bits of dest preserved */
|
||||
#define SSE_CVT_SI2F(fmt) \
|
||||
do { \
|
||||
RzFloatFormat _fmt = (fmt); \
|
||||
RzILOpBitVector *int_val = x86_il_get_op(1); \
|
||||
RzILOpFloat *res = SINT2F(_fmt, RZ_FLOAT_RMODE_RNE, int_val); \
|
||||
return x86_il_set_scalar_floating_op(ins->operands[0], res, _fmt, analysis->bits, pc); \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* CVTSI2SD
|
||||
* Convert a signed integer to a double precision floating point value
|
||||
*/
|
||||
IL_LIFTER(cvtsi2sd) {
|
||||
SSE_CVT_SI2F(RZ_FLOAT_IEEE754_BIN_64);
|
||||
}
|
||||
|
||||
/**
|
||||
* CVTSI2SS
|
||||
* Convert a signed integer to a single precision floating point value
|
||||
*/
|
||||
IL_LIFTER(cvtsi2ss) {
|
||||
SSE_CVT_SI2F(RZ_FLOAT_IEEE754_BIN_32);
|
||||
}
|
||||
|
||||
/* Scalar float to integer: CVTSD2SI, CVTSS2SI, CVTTSD2SI, CVTTSS2SI */
|
||||
|
||||
/* dest = (signed int) src[scalar], rounded using \p rmode */
|
||||
#define SSE_CVT_F2SI(fmt, rmode) \
|
||||
do { \
|
||||
RzILOpFloat *f = x86_il_get_scalar_floating_op(ins->operands[1], (fmt), analysis->bits, pc); \
|
||||
ut32 width = ins->operands[0].size * BITS_PER_BYTE; \
|
||||
return x86_il_set_op(0, F2SINT(width, rmode, f)); \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* CVTSD2SI
|
||||
* Convert a double precision floating point value to a signed integer
|
||||
*/
|
||||
IL_LIFTER(cvtsd2si) {
|
||||
SSE_CVT_F2SI(RZ_FLOAT_IEEE754_BIN_64, RZ_FLOAT_RMODE_RNE);
|
||||
}
|
||||
|
||||
/**
|
||||
* CVTSS2SI
|
||||
* Convert a single precision floating point value to a signed integer
|
||||
*/
|
||||
IL_LIFTER(cvtss2si) {
|
||||
SSE_CVT_F2SI(RZ_FLOAT_IEEE754_BIN_32, RZ_FLOAT_RMODE_RNE);
|
||||
}
|
||||
|
||||
/**
|
||||
* CVTTSD2SI
|
||||
* Convert (with truncation) a double precision floating point value to a signed integer
|
||||
*/
|
||||
IL_LIFTER(cvttsd2si) {
|
||||
SSE_CVT_F2SI(RZ_FLOAT_IEEE754_BIN_64, RZ_FLOAT_RMODE_RTZ);
|
||||
}
|
||||
|
||||
/**
|
||||
* CVTTSS2SI
|
||||
* Convert (with truncation) a single precision floating point value to a signed integer
|
||||
*/
|
||||
IL_LIFTER(cvttss2si) {
|
||||
SSE_CVT_F2SI(RZ_FLOAT_IEEE754_BIN_32, RZ_FLOAT_RMODE_RTZ);
|
||||
}
|
||||
|
||||
/* Scalar float to scalar float: CVTSD2SS, CVTSS2SD */
|
||||
|
||||
/* dest[scalar] = convert(src[scalar]) from \p src_fmt to \p dst_fmt */
|
||||
#define SSE_CVT_F2F(src_fmt, dst_fmt) \
|
||||
do { \
|
||||
RzFloatFormat _dst = (dst_fmt); \
|
||||
RzILOpFloat *f = x86_il_get_scalar_floating_op(ins->operands[1], (src_fmt), analysis->bits, pc); \
|
||||
RzILOpFloat *res = FCONVERT(_dst, RZ_FLOAT_RMODE_RNE, f); \
|
||||
return x86_il_set_scalar_floating_op(ins->operands[0], res, _dst, analysis->bits, pc); \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* CVTSD2SS
|
||||
* Convert a double precision floating point value to a single precision floating point value
|
||||
*/
|
||||
IL_LIFTER(cvtsd2ss) {
|
||||
SSE_CVT_F2F(RZ_FLOAT_IEEE754_BIN_64, RZ_FLOAT_IEEE754_BIN_32);
|
||||
}
|
||||
|
||||
/**
|
||||
* CVTSS2SD
|
||||
* Convert a single precision floating point value to a double precision floating point value
|
||||
*/
|
||||
IL_LIFTER(cvtss2sd) {
|
||||
SSE_CVT_F2F(RZ_FLOAT_IEEE754_BIN_32, RZ_FLOAT_IEEE754_BIN_64);
|
||||
}
|
||||
|
||||
#include <rz_il/rz_il_opbuilder_end.h>
|
||||
|
|
@ -5,6 +5,7 @@
|
|||
#include "x86_il.h"
|
||||
#include "il_ops.inc"
|
||||
#include "il_fp_ops.inc"
|
||||
#include "il_sse_ops.inc"
|
||||
|
||||
#define COMMON_REGS \
|
||||
"cs", /* X86_REG_CS */ \
|
||||
|
|
@ -38,6 +39,17 @@
|
|||
"st6", /* X86_REG_ST6 */ \
|
||||
"st7" /* X86_REG_ST6 */
|
||||
|
||||
/* SSE registers (xmm0-xmm7 are the only ones present in the reg profile). */
|
||||
#define XMM_REGS \
|
||||
"xmm0", /* X86_REG_XMM0 */ \
|
||||
"xmm1", /* X86_REG_XMM1 */ \
|
||||
"xmm2", /* X86_REG_XMM2 */ \
|
||||
"xmm3", /* X86_REG_XMM3 */ \
|
||||
"xmm4", /* X86_REG_XMM4 */ \
|
||||
"xmm5", /* X86_REG_XMM5 */ \
|
||||
"xmm6", /* X86_REG_XMM6 */ \
|
||||
"xmm7" /* X86_REG_XMM7 */
|
||||
|
||||
/**
|
||||
* \brief All registers bound to IL variables for x86 16-bit
|
||||
*/
|
||||
|
|
@ -74,6 +86,7 @@ const char *x86_bound_regs_32[] = {
|
|||
"gs", /* X86_REG_GS */
|
||||
"cr0", /* X86_REG_CR0 */
|
||||
"dr0", /* X86_REG_DR0 */
|
||||
XMM_REGS,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
|
@ -106,6 +119,7 @@ const char *x86_bound_regs_64[] = {
|
|||
"cr0", /* X86_REG_CR0 */
|
||||
"dr0", /* X86_REG_DR0 */
|
||||
FPU_REGS,
|
||||
XMM_REGS,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
|
@ -311,6 +325,24 @@ x86_il_ins x86_ins[X86_INS_MAX_VALUE] = {
|
|||
[X86_INS_FNOP] = x86_il_fnop,
|
||||
[X86_INS_FISTTP] = x86_il_fisttp,
|
||||
|
||||
/* SSE/SSE2 scalar floating-point instructions */
|
||||
[X86_INS_ADDSD] = x86_il_addsd,
|
||||
[X86_INS_ADDSS] = x86_il_addss,
|
||||
[X86_INS_SUBSD] = x86_il_subsd,
|
||||
[X86_INS_SUBSS] = x86_il_subss,
|
||||
[X86_INS_MULSD] = x86_il_mulsd,
|
||||
[X86_INS_MULSS] = x86_il_mulss,
|
||||
[X86_INS_DIVSD] = x86_il_divsd,
|
||||
[X86_INS_DIVSS] = x86_il_divss,
|
||||
[X86_INS_CVTSI2SD] = x86_il_cvtsi2sd,
|
||||
[X86_INS_CVTSI2SS] = x86_il_cvtsi2ss,
|
||||
[X86_INS_CVTSD2SI] = x86_il_cvtsd2si,
|
||||
[X86_INS_CVTSS2SI] = x86_il_cvtss2si,
|
||||
[X86_INS_CVTTSD2SI] = x86_il_cvttsd2si,
|
||||
[X86_INS_CVTTSS2SI] = x86_il_cvttss2si,
|
||||
[X86_INS_CVTSD2SS] = x86_il_cvtsd2ss,
|
||||
[X86_INS_CVTSS2SD] = x86_il_cvtss2sd,
|
||||
|
||||
/* unimplemented instructions */
|
||||
[X86_INS_IRET] = x86_il_unimpl,
|
||||
[X86_INS_INSB] = x86_il_unimpl,
|
||||
|
|
|
|||
|
|
@ -458,6 +458,7 @@
|
|||
#define X86_INS_PADDQ ZYDIS_MNEMONIC_PADDQ
|
||||
#define X86_INS_DIVPS ZYDIS_MNEMONIC_DIVPS
|
||||
#define X86_INS_DIVSS ZYDIS_MNEMONIC_DIVSS
|
||||
#define X86_INS_DIVSD ZYDIS_MNEMONIC_DIVSD
|
||||
#define X86_INS_MAXPS ZYDIS_MNEMONIC_MAXPS
|
||||
#define X86_INS_MAXSS ZYDIS_MNEMONIC_MAXSS
|
||||
#define X86_INS_MINPS ZYDIS_MNEMONIC_MINPS
|
||||
|
|
@ -470,12 +471,15 @@
|
|||
#define X86_INS_SQRTSS ZYDIS_MNEMONIC_SQRTSS
|
||||
#define X86_INS_CVTPI2PS ZYDIS_MNEMONIC_CVTPI2PS
|
||||
#define X86_INS_CVTSS2SI ZYDIS_MNEMONIC_CVTSS2SI
|
||||
#define X86_INS_CVTTSS2SI ZYDIS_MNEMONIC_CVTTSS2SI
|
||||
#define X86_INS_CVTPS2PI ZYDIS_MNEMONIC_CVTPS2PI
|
||||
#define X86_INS_CVTSI2SS ZYDIS_MNEMONIC_CVTSI2SS
|
||||
#define X86_INS_CVTSI2SD ZYDIS_MNEMONIC_CVTSI2SD
|
||||
#define X86_INS_CVTTPD2DQ ZYDIS_MNEMONIC_CVTTPD2DQ
|
||||
#define X86_INS_CVTPD2PS ZYDIS_MNEMONIC_CVTPD2PS
|
||||
#define X86_INS_CVTPS2PD ZYDIS_MNEMONIC_CVTPS2PD
|
||||
#define X86_INS_CVTSD2SI ZYDIS_MNEMONIC_CVTSD2SI
|
||||
#define X86_INS_CVTTSD2SI ZYDIS_MNEMONIC_CVTTSD2SI
|
||||
#define X86_INS_CVTSD2SS ZYDIS_MNEMONIC_CVTSD2SS
|
||||
#define X86_INS_PMOVMSKB ZYDIS_MNEMONIC_PMOVMSKB
|
||||
#define X86_INS_PSHUFD ZYDIS_MNEMONIC_PSHUFD
|
||||
|
|
|
|||
|
|
@ -2326,3 +2326,19 @@ a "dec ebx" 4b
|
|||
a "dec ecx" 49
|
||||
a "dec edi" 4f
|
||||
a "dec edx" 4a
|
||||
d "addsd xmm0, xmm1" f20f58c1 0x0 (set xmm0 (| (<< (>> (var xmm0) (bv 8 0x40) false) (bv 8 0x40) false) (cast 128 false (fbits (+. rne (float 1 (cast 64 false (var xmm0)) ) (float 1 (cast 64 false (var xmm1)) ))))))
|
||||
d "addss xmm0, xmm1" f30f58c1 0x0 (set xmm0 (| (<< (>> (var xmm0) (bv 8 0x20) false) (bv 8 0x20) false) (cast 128 false (fbits (+. rne (float 0 (cast 32 false (var xmm0)) ) (float 0 (cast 32 false (var xmm1)) ))))))
|
||||
d "subsd xmm0, xmm1" f20f5cc1 0x0 (set xmm0 (| (<< (>> (var xmm0) (bv 8 0x40) false) (bv 8 0x40) false) (cast 128 false (fbits (-. rne (float 1 (cast 64 false (var xmm0)) ) (float 1 (cast 64 false (var xmm1)) ))))))
|
||||
d "subss xmm0, xmm1" f30f5cc1 0x0 (set xmm0 (| (<< (>> (var xmm0) (bv 8 0x20) false) (bv 8 0x20) false) (cast 128 false (fbits (-. rne (float 0 (cast 32 false (var xmm0)) ) (float 0 (cast 32 false (var xmm1)) ))))))
|
||||
d "mulsd xmm0, xmm1" f20f59c1 0x0 (set xmm0 (| (<< (>> (var xmm0) (bv 8 0x40) false) (bv 8 0x40) false) (cast 128 false (fbits (*. rne (float 1 (cast 64 false (var xmm0)) ) (float 1 (cast 64 false (var xmm1)) ))))))
|
||||
d "mulss xmm0, xmm1" f30f59c1 0x0 (set xmm0 (| (<< (>> (var xmm0) (bv 8 0x20) false) (bv 8 0x20) false) (cast 128 false (fbits (*. rne (float 0 (cast 32 false (var xmm0)) ) (float 0 (cast 32 false (var xmm1)) ))))))
|
||||
d "divsd xmm0, xmm1" f20f5ec1 0x0 (set xmm0 (| (<< (>> (var xmm0) (bv 8 0x40) false) (bv 8 0x40) false) (cast 128 false (fbits (/. rne (float 1 (cast 64 false (var xmm0)) ) (float 1 (cast 64 false (var xmm1)) ))))))
|
||||
d "divss xmm0, xmm1" f30f5ec1 0x0 (set xmm0 (| (<< (>> (var xmm0) (bv 8 0x20) false) (bv 8 0x20) false) (cast 128 false (fbits (/. rne (float 0 (cast 32 false (var xmm0)) ) (float 0 (cast 32 false (var xmm1)) ))))))
|
||||
d "cvtsi2sd xmm0, eax" f20f2ac0 0x0 (set xmm0 (| (<< (>> (var xmm0) (bv 8 0x40) false) (bv 8 0x40) false) (cast 128 false (fbits (fcast_sfloat ieee754-bin64 rne (var eax))))))
|
||||
d "cvtsi2ss xmm0, eax" f30f2ac0 0x0 (set xmm0 (| (<< (>> (var xmm0) (bv 8 0x20) false) (bv 8 0x20) false) (cast 128 false (fbits (fcast_sfloat ieee754-bin32 rne (var eax))))))
|
||||
d "cvtsd2si eax, xmm0" f20f2dc0 0x0 (set eax (fcast_sint 32 rne (float 1 (cast 64 false (var xmm0)) )))
|
||||
d "cvtss2si eax, xmm0" f30f2dc0 0x0 (set eax (fcast_sint 32 rne (float 0 (cast 32 false (var xmm0)) )))
|
||||
d "cvttsd2si eax, xmm0" f20f2cc0 0x0 (set eax (fcast_sint 32 rtz (float 1 (cast 64 false (var xmm0)) )))
|
||||
d "cvttss2si eax, xmm0" f30f2cc0 0x0 (set eax (fcast_sint 32 rtz (float 0 (cast 32 false (var xmm0)) )))
|
||||
d "cvtsd2ss xmm0, xmm1" f20f5ac1 0x0 (set xmm0 (| (<< (>> (var xmm0) (bv 8 0x20) false) (bv 8 0x20) false) (cast 128 false (fbits (fconvert ieee754-bin32 rne (float 1 (cast 64 false (var xmm1)) ))))))
|
||||
d "cvtss2sd xmm0, xmm1" f30f5ac1 0x0 (set xmm0 (| (<< (>> (var xmm0) (bv 8 0x40) false) (bv 8 0x40) false) (cast 128 false (fbits (fconvert ieee754-bin64 rne (float 0 (cast 32 false (var xmm1)) ))))))
|
||||
|
|
|
|||
|
|
@ -1118,3 +1118,25 @@ a "fnstsw ax" dfe0 0x0 (set rax (| (& (var rax) (~ (bv 64 0xffff))) (cast 64 fal
|
|||
a "fsave dword [rax]" 9bdd30
|
||||
a "fnsave dword [rax]" dd30
|
||||
aB "fnsave dword [rdi + rdi*8]" dd34ff
|
||||
d "addsd xmm0, xmm1" f20f58c1 0x0 (set xmm0 (| (<< (>> (var xmm0) (bv 8 0x40) false) (bv 8 0x40) false) (cast 128 false (fbits (+. rne (float 1 (cast 64 false (var xmm0)) ) (float 1 (cast 64 false (var xmm1)) ))))))
|
||||
d "addss xmm0, xmm1" f30f58c1 0x0 (set xmm0 (| (<< (>> (var xmm0) (bv 8 0x20) false) (bv 8 0x20) false) (cast 128 false (fbits (+. rne (float 0 (cast 32 false (var xmm0)) ) (float 0 (cast 32 false (var xmm1)) ))))))
|
||||
d "subsd xmm0, xmm1" f20f5cc1 0x0 (set xmm0 (| (<< (>> (var xmm0) (bv 8 0x40) false) (bv 8 0x40) false) (cast 128 false (fbits (-. rne (float 1 (cast 64 false (var xmm0)) ) (float 1 (cast 64 false (var xmm1)) ))))))
|
||||
d "subss xmm0, xmm1" f30f5cc1 0x0 (set xmm0 (| (<< (>> (var xmm0) (bv 8 0x20) false) (bv 8 0x20) false) (cast 128 false (fbits (-. rne (float 0 (cast 32 false (var xmm0)) ) (float 0 (cast 32 false (var xmm1)) ))))))
|
||||
d "mulsd xmm0, xmm1" f20f59c1 0x0 (set xmm0 (| (<< (>> (var xmm0) (bv 8 0x40) false) (bv 8 0x40) false) (cast 128 false (fbits (*. rne (float 1 (cast 64 false (var xmm0)) ) (float 1 (cast 64 false (var xmm1)) ))))))
|
||||
d "mulss xmm0, xmm1" f30f59c1 0x0 (set xmm0 (| (<< (>> (var xmm0) (bv 8 0x20) false) (bv 8 0x20) false) (cast 128 false (fbits (*. rne (float 0 (cast 32 false (var xmm0)) ) (float 0 (cast 32 false (var xmm1)) ))))))
|
||||
d "divsd xmm0, xmm1" f20f5ec1 0x0 (set xmm0 (| (<< (>> (var xmm0) (bv 8 0x40) false) (bv 8 0x40) false) (cast 128 false (fbits (/. rne (float 1 (cast 64 false (var xmm0)) ) (float 1 (cast 64 false (var xmm1)) ))))))
|
||||
d "divss xmm0, xmm1" f30f5ec1 0x0 (set xmm0 (| (<< (>> (var xmm0) (bv 8 0x20) false) (bv 8 0x20) false) (cast 128 false (fbits (/. rne (float 0 (cast 32 false (var xmm0)) ) (float 0 (cast 32 false (var xmm1)) ))))))
|
||||
d "cvtsi2sd xmm0, rax" f2480f2ac0 0x0 (set xmm0 (| (<< (>> (var xmm0) (bv 8 0x40) false) (bv 8 0x40) false) (cast 128 false (fbits (fcast_sfloat ieee754-bin64 rne (var rax))))))
|
||||
d "cvtsi2sd xmm0, eax" f20f2ac0 0x0 (set xmm0 (| (<< (>> (var xmm0) (bv 8 0x40) false) (bv 8 0x40) false) (cast 128 false (fbits (fcast_sfloat ieee754-bin64 rne (cast 32 false (var rax)))))))
|
||||
d "cvtsi2ss xmm0, rax" f3480f2ac0 0x0 (set xmm0 (| (<< (>> (var xmm0) (bv 8 0x20) false) (bv 8 0x20) false) (cast 128 false (fbits (fcast_sfloat ieee754-bin32 rne (var rax))))))
|
||||
d "cvtsi2ss xmm0, eax" f30f2ac0 0x0 (set xmm0 (| (<< (>> (var xmm0) (bv 8 0x20) false) (bv 8 0x20) false) (cast 128 false (fbits (fcast_sfloat ieee754-bin32 rne (cast 32 false (var rax)))))))
|
||||
d "cvtsd2si rax, xmm0" f2480f2dc0 0x0 (set rax (fcast_sint 64 rne (float 1 (cast 64 false (var xmm0)) )))
|
||||
d "cvtsd2si eax, xmm0" f20f2dc0 0x0 (set rax (cast 64 false (fcast_sint 32 rne (float 1 (cast 64 false (var xmm0)) ))))
|
||||
d "cvtss2si rax, xmm0" f3480f2dc0 0x0 (set rax (fcast_sint 64 rne (float 0 (cast 32 false (var xmm0)) )))
|
||||
d "cvtss2si eax, xmm0" f30f2dc0 0x0 (set rax (cast 64 false (fcast_sint 32 rne (float 0 (cast 32 false (var xmm0)) ))))
|
||||
d "cvttsd2si rax, xmm0" f2480f2cc0 0x0 (set rax (fcast_sint 64 rtz (float 1 (cast 64 false (var xmm0)) )))
|
||||
d "cvttsd2si eax, xmm0" f20f2cc0 0x0 (set rax (cast 64 false (fcast_sint 32 rtz (float 1 (cast 64 false (var xmm0)) ))))
|
||||
d "cvttss2si rax, xmm0" f3480f2cc0 0x0 (set rax (fcast_sint 64 rtz (float 0 (cast 32 false (var xmm0)) )))
|
||||
d "cvttss2si eax, xmm0" f30f2cc0 0x0 (set rax (cast 64 false (fcast_sint 32 rtz (float 0 (cast 32 false (var xmm0)) ))))
|
||||
d "cvtsd2ss xmm0, xmm1" f20f5ac1 0x0 (set xmm0 (| (<< (>> (var xmm0) (bv 8 0x20) false) (bv 8 0x20) false) (cast 128 false (fbits (fconvert ieee754-bin32 rne (float 1 (cast 64 false (var xmm1)) ))))))
|
||||
d "cvtss2sd xmm0, xmm1" f30f5ac1 0x0 (set xmm0 (| (<< (>> (var xmm0) (bv 8 0x40) false) (bv 8 0x40) false) (cast 128 false (fbits (fconvert ieee754-bin64 rne (float 0 (cast 32 false (var xmm1)) ))))))
|
||||
|
|
|
|||
|
|
@ -105,3 +105,70 @@ EOF
|
|||
EXPECT=Hello from RzIL!
|
||||
EXPECT_ERR=
|
||||
RUN
|
||||
|
||||
NAME=x86 SSE2 scalar floating-point IL
|
||||
FILE=malloc://0x100
|
||||
CMDS=<<EOF
|
||||
e asm.arch=x86
|
||||
e asm.bits=64
|
||||
e analysis.arch=x86
|
||||
e analysis.bits=64
|
||||
# IL generation for the instructions listed in the issue
|
||||
wx f2490f2accf2490f2ac0f20f5e442408f20f58c0
|
||||
ao 4~rzil
|
||||
# emulate the issue's sequence: r12=3, r8=20, [rsp+8]=2.0
|
||||
# -> xmm1=3.0, xmm0=((20.0)/2.0 + itself)=20.0
|
||||
s 0
|
||||
aezi
|
||||
ar r12=3
|
||||
ar r8=20
|
||||
ar rsp=0x40
|
||||
wv8 0x4000000000000000 @ 0x48
|
||||
aezsu 0x14
|
||||
ar xmm1
|
||||
ar xmm0
|
||||
# mulss: 3.0f * 2.0f = 6.0f
|
||||
wx f30f59c1 @ 0
|
||||
s 0
|
||||
aezi
|
||||
ar xmm0=0x40400000
|
||||
ar xmm1=0x40000000
|
||||
aezs
|
||||
ar xmm0
|
||||
# subsd: 5.0 - 1.0 = 4.0
|
||||
wx f20f5cc1 @ 0
|
||||
s 0
|
||||
aezi
|
||||
ar xmm0=0x4014000000000000
|
||||
ar xmm1=0x3ff0000000000000
|
||||
aezs
|
||||
ar xmm0
|
||||
# cvttsd2si: trunc(3.9) = 3
|
||||
wx f2480f2cc0 @ 0
|
||||
s 0
|
||||
aezi
|
||||
ar xmm0=0x400f333333333333
|
||||
aezs
|
||||
ar rax
|
||||
# cvtsd2ss: double 1.5 -> single 1.5, upper bits of dest preserved
|
||||
wx f20f5ac1 @ 0
|
||||
s 0
|
||||
aezi
|
||||
ar xmm0=0x4018000000000000
|
||||
ar xmm1=0x3ff8000000000000
|
||||
aezs
|
||||
ar xmm0
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
rzil: (set xmm1 (| (<< (>> (var xmm1) (bv 8 0x40) false) (bv 8 0x40) false) (cast 128 false (fbits (fcast_sfloat ieee754-bin64 rne (var r12))))))
|
||||
rzil: (set xmm0 (| (<< (>> (var xmm0) (bv 8 0x40) false) (bv 8 0x40) false) (cast 128 false (fbits (fcast_sfloat ieee754-bin64 rne (var r8))))))
|
||||
rzil: (set xmm0 (| (<< (>> (var xmm0) (bv 8 0x40) false) (bv 8 0x40) false) (cast 128 false (fbits (/. rne (float 1 (cast 64 false (var xmm0)) ) (float 1 (loadw 0 64 (+ (var rsp) (bv 64 0x8))) ))))))
|
||||
rzil: (set xmm0 (| (<< (>> (var xmm0) (bv 8 0x40) false) (bv 8 0x40) false) (cast 128 false (fbits (+. rne (float 1 (cast 64 false (var xmm0)) ) (float 1 (cast 64 false (var xmm0)) ))))))
|
||||
xmm1 = 0x00000000000000004008000000000000
|
||||
xmm0 = 0x00000000000000004034000000000000
|
||||
xmm0 = 0x00000000000000000000000040c00000
|
||||
xmm0 = 0x00000000000000004010000000000000
|
||||
rax = 0x0000000000000003
|
||||
xmm0 = 0x0000000000000000401800003fc00000
|
||||
EOF
|
||||
RUN
|
||||
|
|
|
|||
Loading…
Reference in a new issue