about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAjax <commial@gmail.com>2018-07-10 14:10:39 +0200
committerAjax <commial@gmail.com>2018-07-10 14:14:35 +0200
commitd8dd49b1f56b83e992753bf3092f1c98abeda854 (patch)
treecd3e7073ba7657ec1e88d528e033db5bb62aa783
parenta5fd75194b2af753e16762c8ea08017e8ae6d5c8 (diff)
downloadmiasm-d8dd49b1f56b83e992753bf3092f1c98abeda854.tar.gz
miasm-d8dd49b1f56b83e992753bf3092f1c98abeda854.zip
Add the new float ops support for the C jitter
-rw-r--r--miasm2/ir/translators/C.py68
-rw-r--r--miasm2/jitter/op_semantics.c227
-rw-r--r--miasm2/jitter/op_semantics.h38
3 files changed, 195 insertions, 138 deletions
diff --git a/miasm2/ir/translators/C.py b/miasm2/ir/translators/C.py
index fed07a6d..f8fd4d3b 100644
--- a/miasm2/ir/translators/C.py
+++ b/miasm2/ir/translators/C.py
@@ -94,17 +94,70 @@ class TranslatorC(Translator):
                     self.from_expr(expr.args[0]),
                     self._size2mask(expr.args[0].size),
                 )
-            elif (expr.op.startswith("double_to_") or
-                  expr.op.endswith("_to_double")   or
-                  expr.op.startswith("access_")    or
+            elif expr.op in [
+                    "ftan", "frndint", "f2xm1", "fsin", "fsqrt", "fabs", "fcos",
+                    "fchs",
+            ]:
+                return "fpu_%s%d(%s)" % (
+                    expr.op,
+                    expr.size,
+                    self.from_expr(expr.args[0]),
+                )
+            elif (expr.op.startswith("access_")    or
                   expr.op.startswith("load_")      or
                   expr.op.startswith("fxam_c")     or
-                  expr.op in ["-", "ftan", "frndint", "f2xm1",
-                              "fsin", "fsqrt", "fabs", "fcos", "fchs"]):
+                  expr.op in ["-"]):
                 return "%s(%s)" % (
                     expr.op,
                     self.from_expr(expr.args[0])
                 )
+            elif expr.op.startswith("fpround_"):
+                return "%s_fp%d(%s)" % (
+                    expr.op,
+                    expr.size,
+                    self.from_expr(expr.args[0]),
+                )
+            elif expr.op.startswith("sint_to_fp"):
+                dest_size = expr.size
+                arg_size = expr.args[0].size
+                if (arg_size, dest_size) in [
+                        (32, 32), (64, 64), (32, 64),
+                ]:
+                    func = "sint%d_to_fp%d" % (arg_size, dest_size)
+                else:
+                    raise RuntimeError(
+                        "Unsupported size for sint_to_fp: %r to %r" % (
+                            arg_size,
+                            dest_size
+                        ))
+                return "%s(%s)" % (func, self.from_expr(expr.args[0]))
+            elif expr.op.startswith("fp_to_sint"):
+                dest_size = expr.size
+                arg_size = expr.args[0].size
+                if (arg_size, dest_size) in [
+                        (32, 32), (64, 64), (64, 32),
+                ]:
+                    func = "fp%d_to_sint%d" % (arg_size, dest_size)
+                else:
+                    raise RuntimeError(
+                        "Unsupported size for fp_to_sint: %r to %r" % (
+                            arg_size,
+                            dest_size
+                        ))
+                return "%s(%s)" % (func, self.from_expr(expr.args[0]))
+            elif expr.op.startswith("fpconvert_fp"):
+                dest_size = expr.size
+                arg_size = expr.args[0].size
+                if (arg_size, dest_size) in [
+                        (32, 64), (64, 32)
+                ]:
+                    func = "fp%d_to_fp%d" % (arg_size, dest_size)
+                else:
+                    raise RuntimeError(
+                        "Unsupported size for fpconvert: %r to %r" % (arg_size,
+                                                                      dest_size)
+                    )
+                return "%s(%s)" % (func, self.from_expr(expr.args[0]))
             else:
                 raise NotImplementedError('Unknown op: %r' % expr.op)
 
@@ -155,10 +208,11 @@ class TranslatorC(Translator):
             elif (expr.op.startswith("fcom")  or
                   expr.op in ["fadd", "fsub", "fdiv", 'fmul', "fscale",
                               "fprem", "fprem_lsb", "fyl2x", "fpatan"]):
-                return "fpu_%s(%s, %s)" % (
+                return "fpu_%s%d(%s, %s)" % (
                     expr.op,
+                    expr.size,
                     self.from_expr(expr.args[0]),
-                    self.from_expr(expr.args[1])
+                    self.from_expr(expr.args[1]),
                 )
             elif expr.op == "segm":
                 return "segm2addr(jitcpu, %s, %s)" % (
diff --git a/miasm2/jitter/op_semantics.c b/miasm2/jitter/op_semantics.c
index 0420532a..0bc3fcc5 100644
--- a/miasm2/jitter/op_semantics.c
+++ b/miasm2/jitter/op_semantics.c
@@ -355,147 +355,92 @@ void dump_float(void)
 	*/
 }
 
-double mem_32_to_double(unsigned int m)
+uint32_t fpu_fadd32(uint32_t a, uint32_t b)
 {
-	float f;
-	double d;
-
-	f = *((float*)&m);
-	d = f;
-#ifdef DEBUG_MIASM_DOUBLE
-	dump_float();
-	printf("%d float %e\n", m, d);
-#endif
-	return d;
-}
-
-
-double mem_64_to_double(uint64_t m)
-{
-	double d;
-	d = *((double*)&m);
+	float c;
+	c = *((float*)&a) + *((float*)&b);
 #ifdef DEBUG_MIASM_DOUBLE
 	dump_float();
-	printf("%"PRId64" double %e\n", m, d);
-#endif
-	return d;
-}
-
-double int_16_to_double(unsigned int m)
-{
-	double d;
-
-	d = (double)(m&0xffff);
-#ifdef DEBUG_MIASM_DOUBLE
-	dump_float();
-	printf("%d double %e\n", m, d);
-#endif
-	return d;
-}
-
-double int_32_to_double(unsigned int m)
-{
-	double d;
-
-	d = (double)m;
-#ifdef DEBUG_MIASM_DOUBLE
-	dump_float();
-	printf("%d double %e\n", m, d);
+	printf("%e + %e -> %e\n", a, b, c);
 #endif
-	return d;
+	return *((uint32_t*)&c);
 }
 
-double int_64_to_double(uint64_t m)
+uint64_t fpu_fadd64(uint64_t a, uint64_t b)
 {
-	double d;
-
-	d = (double)m;
+	double c;
+	c = *((double*)&a) + *((double*)&b);
 #ifdef DEBUG_MIASM_DOUBLE
 	dump_float();
-	printf("%"PRId64" double %e\n", m, d);
+	printf("%e + %e -> %e\n", a, b, c);
 #endif
-	return d;
+	return *((uint64_t*)&c);
 }
 
-int16_t double_to_int_16(double d)
+uint32_t fpu_fsub32(uint32_t a, uint32_t b)
 {
-	int16_t i;
-
-	i = (int16_t)d;
+	float c;
+	c = *((float*)&a) - *((float*)&b);
 #ifdef DEBUG_MIASM_DOUBLE
 	dump_float();
-	printf("%e int %d\n", d, i);
+	printf("%e + %e -> %e\n", a, b, c);
 #endif
-	return i;
+	return *((uint32_t*)&c);
 }
 
-int32_t double_to_int_32(double d)
+uint64_t fpu_fsub64(uint64_t a, uint64_t b)
 {
-	int32_t i;
-
-	i = (int32_t)d;
+	double c;
+	c = *((double*)&a) - *((double*)&b);
 #ifdef DEBUG_MIASM_DOUBLE
 	dump_float();
-	printf("%e int %d\n", d, i);
+	printf("%e + %e -> %e\n", a, b, c);
 #endif
-	return i;
+	return *((uint64_t*)&c);
 }
 
-int64_t double_to_int_64(double d)
+uint32_t fpu_fmul32(uint32_t a, uint32_t b)
 {
-	int64_t i;
-
-	i = (int64_t)d;
+	float c;
+	c = *((float*)&a) * *((float*)&b);
 #ifdef DEBUG_MIASM_DOUBLE
 	dump_float();
-	printf("%e int %"PRId64"\n", d, i);
+	printf("%e * %e -> %e\n", a, b, c);
 #endif
-	return i;
+	return *((uint32_t*)&c);
 }
 
-
-double fpu_fadd(double a, double b)
+uint64_t fpu_fmul64(uint64_t a, uint64_t b)
 {
 	double c;
-	c = a + b;
+	c = *((double*)&a) * *((double*)&b);
 #ifdef DEBUG_MIASM_DOUBLE
 	dump_float();
-	printf("%e + %e -> %e\n", a, b, c);
+	printf("%e * %e -> %e\n", a, b, c);
 #endif
-	return c;
+	return *((uint64_t*)&c);
 }
 
-double fpu_fsub(double a, double b)
+uint32_t fpu_fdiv32(uint32_t a, uint32_t b)
 {
-	double c;
-	c = a - b;
-#ifdef DEBUG_MIASM_DOUBLE
-	dump_float();
-	printf("%e - %e -> %e\n", a, b, c);
-#endif
-	return c;
-}
-
-double fpu_fmul(double a, double b)
-{
-	double c;
-	c = a * b;
+	float c;
+	c = *((float*)&a) / *((float*)&b);
 #ifdef DEBUG_MIASM_DOUBLE
 	dump_float();
 	printf("%e * %e -> %e\n", a, b, c);
 #endif
-	return c;
+	return *((uint32_t*)&c);
 }
 
-double fpu_fdiv(double a, double b)
+uint64_t fpu_fdiv64(uint64_t a, uint64_t b)
 {
 	double c;
-	c = a / b;
+	c = *((double*)&a) / *((double*)&b);
 #ifdef DEBUG_MIASM_DOUBLE
 	dump_float();
-	printf("%e / %e -> %e\n", a, b, c);
+	printf("%e * %e -> %e\n", a, b, c);
 #endif
-	return c;
+	return *((uint64_t*)&c);
 }
 
 double fpu_ftan(double a)
@@ -567,15 +512,26 @@ double fpu_f2xm1(double a)
 	return b;
 }
 
-double fpu_fsqrt(double a)
+uint32_t fpu_fsqrt32(uint32_t a)
+{
+	float b;
+	b = sqrtf(*((float*)&a));
+#ifdef DEBUG_MIASM_DOUBLE
+	dump_float();
+	printf("%e sqrt %e\n", a, b);
+#endif
+	return *((uint32_t*)&b);
+}
+
+uint64_t fpu_fsqrt64(uint64_t a)
 {
 	double b;
-	b = sqrt(a);
+	b = sqrt(*((double*)&a));
 #ifdef DEBUG_MIASM_DOUBLE
 	dump_float();
 	printf("%e sqrt %e\n", a, b);
 #endif
-	return b;
+	return *((uint64_t*)&b);
 }
 
 double fpu_fabs(double a)
@@ -751,30 +707,75 @@ unsigned int fpu_fxam_c3(double a)
 	}
 }
 
-unsigned int double_to_mem_32(double d)
+uint64_t sint64_to_fp64(int64_t a)
 {
-	unsigned int m;
-	float f;
-	f = d;
-	m = *((unsigned int*)&f);
-#ifdef DEBUG_MIASM_DOUBLE
-	dump_float();
-	printf("%d %e\n", m, d);
-#endif
-	return m;
+	double result = (double) a;
+	return *((uint64_t*)&result);
 }
 
-uint64_t double_to_mem_64(double d)
+uint32_t sint32_to_fp32(int32_t a)
 {
-	uint64_t m;
-	m = *((uint64_t*)&d);
-#ifdef DEBUG_MIASM_DOUBLE
-	dump_float();
-	printf("%"PRId64" %e\n", m, d);
-#endif
-	return m;
+	float result = (float) a;
+	return *((uint32_t*)&result);
+}
+
+uint64_t sint32_to_fp64(int32_t a)
+{
+	double result = (double) a;
+	return *((uint64_t*)&result);
 }
 
+int32_t fp32_to_sint32(uint32_t a)
+{
+	// Enforce nearbyint (IEEE-754 behavior)
+	float rounded = *((float*)&a);
+	rounded = nearbyintf(rounded);
+	return (int32_t) rounded;
+}
+
+int64_t fp64_to_sint64(uint64_t a)
+{
+	// Enforce nearbyint (IEEE-754 behavior)
+	double rounded = *((double*)&a);
+	rounded = nearbyint(rounded);
+	return (int64_t) rounded;
+}
+
+int32_t fp64_to_sint32(uint64_t a)
+{
+	// Enforce nearbyint (IEEE-754 behavior)
+	double rounded = *((double*)&a);
+	rounded = nearbyint(rounded);
+	return (int32_t) rounded;
+}
+
+uint32_t fp64_to_fp32(uint64_t a)
+{
+	float result = (float) *((double*)&a);
+	return *((uint32_t*)&result);
+}
+
+uint64_t fp32_to_fp64(uint32_t a)
+{
+	double result = (double) *((float*)&a);
+	return *((uint64_t*)&result);
+}
+
+uint32_t fpround_towardszero_fp32(uint32_t a)
+{
+	float rounded = *((float*)&a);
+	rounded = truncf(rounded);
+	return *((uint32_t*)&rounded);
+}
+
+uint64_t fpround_towardszero_fp64(uint64_t a)
+{
+	double rounded = *((float*)&a);
+	rounded = trunc(rounded);
+	return *((uint64_t*)&rounded);
+}
+
+
 UDIV(16)
 UDIV(32)
 UDIV(64)
diff --git a/miasm2/jitter/op_semantics.h b/miasm2/jitter/op_semantics.h
index 3eb81cff..f8042895 100644
--- a/miasm2/jitter/op_semantics.h
+++ b/miasm2/jitter/op_semantics.h
@@ -96,19 +96,23 @@ int16_t idiv16(int16_t a, int16_t b);
 int16_t imod16(int16_t a, int16_t b);
 
 unsigned int x86_cpuid(unsigned int a, unsigned int reg_num);
-double int2double(unsigned int m);
 
-double fpu_fadd(double a, double b);
-double fpu_fsub(double a, double b);
-double fpu_fmul(double a, double b);
-double fpu_fdiv(double a, double b);
+uint32_t fpu_fadd32(uint32_t a, uint32_t b);
+uint64_t fpu_fadd64(uint64_t a, uint64_t b);
+uint32_t fpu_fsub32(uint32_t a, uint32_t b);
+uint64_t fpu_fsub64(uint64_t a, uint64_t b);
+uint32_t fpu_fmul32(uint32_t a, uint32_t b);
+uint64_t fpu_fmul64(uint64_t a, uint64_t b);
+uint32_t fpu_fdiv32(uint32_t a, uint32_t b);
+uint64_t fpu_fdiv64(uint64_t a, uint64_t b);
 double fpu_ftan(double a);
 double fpu_frndint(double a);
 double fpu_fsin(double a);
 double fpu_fcos(double a);
 double fpu_fscale(double a, double b);
 double fpu_f2xm1(double a);
-double fpu_fsqrt(double a);
+uint32_t fpu_fsqrt32(uint32_t a);
+uint64_t fpu_fsqrt64(uint64_t a);
 double fpu_fabs(double a);
 double fpu_fprem(double a, double b);
 double fpu_fchs(double a);
@@ -124,18 +128,16 @@ unsigned int fpu_fxam_c1(double a);
 unsigned int fpu_fxam_c2(double a);
 unsigned int fpu_fxam_c3(double a);
 
-
-double mem_32_to_double(unsigned int m);
-double mem_64_to_double(uint64_t m);
-double int_16_to_double(unsigned int m);
-double int_32_to_double(unsigned int m);
-double int_64_to_double(uint64_t m);
-int16_t double_to_int_16(double d);
-int32_t double_to_int_32(double d);
-int64_t double_to_int_64(double d);
-unsigned int double_to_mem_32(double d);
-uint64_t double_to_mem_64(double d);
-
+uint64_t sint64_to_fp64(int64_t a);
+uint32_t sint32_to_fp32(int32_t a);
+uint64_t sint32_to_fp64(int32_t a);
+int32_t fp32_to_sint32(uint32_t a);
+int64_t fp64_to_sint64(uint64_t a);
+int32_t fp64_to_sint32(uint64_t a);
+uint32_t fp64_to_fp32(uint64_t a);
+uint64_t fp32_to_fp64(uint32_t a);
+uint32_t fpround_towardszero_fp32(uint32_t a);
+uint64_t fpround_towardszero_fp64(uint64_t a);
 
 #define SHIFT_RIGHT_ARITH(size, value, shift)				\
 	((uint ## size ## _t)((((uint64_t) (shift)) > ((size) - 1))?	\