about summary refs log tree commit diff stats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--miasm2/arch/x86/sem.py8
-rw-r--r--miasm2/ir/translators/C.py2
-rw-r--r--miasm2/jitter/vm_mngr.c23
-rw-r--r--miasm2/jitter/vm_mngr.h1
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);