diff options
| author | Ajax <commial@gmail.com> | 2015-11-10 16:19:00 +0100 |
|---|---|---|
| committer | Ajax <commial@gmail.com> | 2015-11-10 16:19:00 +0100 |
| commit | 79e35eb685ac191cb92c05c17fdd340322e8f65b (patch) | |
| tree | 3cc7e355d57eb019c4be61d72483ee57fd01a3e3 | |
| parent | 4892fd18de5dff99267f43e584717518d3003a0d (diff) | |
| download | miasm-79e35eb685ac191cb92c05c17fdd340322e8f65b.tar.gz miasm-79e35eb685ac191cb92c05c17fdd340322e8f65b.zip | |
x86: C0/C1/C2/C3 flags in `fprem`
Diffstat (limited to '')
| -rw-r--r-- | miasm2/arch/x86/sem.py | 8 | ||||
| -rw-r--r-- | miasm2/ir/translators/C.py | 2 | ||||
| -rw-r--r-- | miasm2/jitter/vm_mngr.c | 23 | ||||
| -rw-r--r-- | miasm2/jitter/vm_mngr.h | 1 |
4 files changed, 33 insertions, 1 deletions
diff --git a/miasm2/arch/x86/sem.py b/miasm2/arch/x86/sem.py index a51848a9..25861271 100644 --- a/miasm2/arch/x86/sem.py +++ b/miasm2/arch/x86/sem.py @@ -2131,6 +2131,14 @@ def fpatan(ir, instr): def fprem(ir, instr): e = [] e.append(m2_expr.ExprAff(float_st0, m2_expr.ExprOp('fprem', float_st0, float_st1))) + # Remaining bits (ex: used in argument reduction in tan) + remain = m2_expr.ExprOp('fprem_lsb', float_st0, float_st1) + e += [m2_expr.ExprAff(float_c0, remain[2:3]), + m2_expr.ExprAff(float_c3, remain[1:2]), + m2_expr.ExprAff(float_c1, remain[0:1]), + # Consider the reduction is always completed + m2_expr.ExprAff(float_c2, m2_expr.ExprInt1(0)), + ] e += set_float_cs_eip(instr) return e, [] diff --git a/miasm2/ir/translators/C.py b/miasm2/ir/translators/C.py index 51de5f1f..e9d799ca 100644 --- a/miasm2/ir/translators/C.py +++ b/miasm2/ir/translators/C.py @@ -104,7 +104,7 @@ class TranslatorC(Translator): elif (expr.op.startswith('cpuid') or expr.op.startswith("fcom") or expr.op in ["fadd", "fsub", "fdiv", 'fmul', "fscale", - "fprem", "fyl2x", "fpatan"]): + "fprem", "fprem_lsb", "fyl2x", "fpatan"]): return "%s(%s, %s)" % (expr.op, self.from_expr(expr.args[0]), self.from_expr(expr.args[1])) elif expr.op == "segm": diff --git a/miasm2/jitter/vm_mngr.c b/miasm2/jitter/vm_mngr.c index 16e0a56f..ee7a2826 100644 --- a/miasm2/jitter/vm_mngr.c +++ b/miasm2/jitter/vm_mngr.c @@ -1254,6 +1254,29 @@ double fprem(double a, double b) return c; } +unsigned int fprem_lsb(double a, double b) +{ + // Inspired from qemu/fpu_helper.c + double c; + signed long long int q; + c = a / b; /* ST0 / ST1 */ + /* round dblq towards zero */ + c = (c < 0.0) ? ceil(c) : floor(c); + + /* convert dblq to q by truncating towards zero */ + if (c < 0.0) { + q = (signed long long int)(-c); + } else { + q = (signed long long int)c; + } +#ifdef DEBUG_MIASM_DOUBLE + dump_float(); + printf("%e %% %e -> %d %d %d\n", a, b, q & 0x4, + q & 0x2, q & 0x1); +#endif + return q; +} + double fchs(double a) { double b; diff --git a/miasm2/jitter/vm_mngr.h b/miasm2/jitter/vm_mngr.h index a9f218b1..2a934d5a 100644 --- a/miasm2/jitter/vm_mngr.h +++ b/miasm2/jitter/vm_mngr.h @@ -374,6 +374,7 @@ double fprem(double a, double b); double fchs(double a); double fyl2x(double a, double b); double fpatan(double a, double b); +unsigned int fprem_lsb(double a, double b); unsigned int fcom_c0(double a, double b); unsigned int fcom_c1(double a, double b); unsigned int fcom_c2(double a, double b); |