diff options
| author | Ajax <commial@gmail.com> | 2018-07-10 14:10:39 +0200 |
|---|---|---|
| committer | Ajax <commial@gmail.com> | 2018-07-10 14:14:35 +0200 |
| commit | d8dd49b1f56b83e992753bf3092f1c98abeda854 (patch) | |
| tree | cd3e7073ba7657ec1e88d528e033db5bb62aa783 | |
| parent | a5fd75194b2af753e16762c8ea08017e8ae6d5c8 (diff) | |
| download | miasm-d8dd49b1f56b83e992753bf3092f1c98abeda854.tar.gz miasm-d8dd49b1f56b83e992753bf3092f1c98abeda854.zip | |
Add the new float ops support for the C jitter
| -rw-r--r-- | miasm2/ir/translators/C.py | 68 | ||||
| -rw-r--r-- | miasm2/jitter/op_semantics.c | 227 | ||||
| -rw-r--r-- | miasm2/jitter/op_semantics.h | 38 |
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))? \ |