Emulate C99 fenv.h on amd64 through the MXCSR.
authorTaylor R Campbell <campbell@mumble.net>
Fri, 6 Aug 2010 01:18:01 +0000 (01:18 +0000)
committerTaylor R Campbell <campbell@mumble.net>
Fri, 6 Aug 2010 01:18:01 +0000 (01:18 +0000)
src/microcode/cmpauxmd/x86-64.m4
src/microcode/cmpintmd/x86-64.h

index fedb3e2ea0f7621cefab4c8f9f11ce56de55bffc..ff2238c5711fa4e16fd6c78efb932e20e17496a1 100644 (file)
@@ -966,6 +966,20 @@ asm_fixnum_rsh_overflow_negative:
        OP(mov,q)       TW(IMM_DETAGGED_FIXNUM_MINUS_ONE,REG(rax))
        ret
 \f
+define_c_label(x86_64_read_mxcsr)
+       enter           IMM(8),IMM(0)
+       stmxcsr         IND(REG(rsp))
+       OP(mov,l)       TW(IND(REG(rsp)),REG(eax))
+       leave
+       ret
+
+define_c_label(x86_64_write_mxcsr)
+       enter           IMM(8),IMM(0)
+       OP(mov,l)       TW(REG(eax),IND(REG(rsp)))
+       ldmxcsr         IND(REG(rsp))
+       leave
+       ret
+\f
 IFDASM(`end')
 
 # Mark the stack nonexecutable.  If we ever put code (e.g.,
index 55090c9538ad683b1f3a7fd1f78740ab259e06d7..d2e3bc55be3d84803b87f015488a291016aaeb86 100644 (file)
@@ -239,6 +239,37 @@ extern void asm_trampoline_to_interface (void);
 extern insn_t * read_compiled_closure_target (insn_t *);
 extern insn_t * read_uuo_target (SCHEME_OBJECT *);
 extern void x86_64_reset_hook (void);
-
+extern int x86_64_read_mxcsr (void);
+extern void x86_64_write_mxcsr (int);
+
+#ifndef HAVE_FENV_H
+
+#  define FE_TONEAREST 0
+#  define FE_DOWNWARD 1
+#  define FE_UPWARD 2
+#  define FE_TOWARDZERO 3
+
+#  define HAVE_FEGETROUND
+#  define HAVE_FESETROUND
+
+static inline int
+fegetround (void)
+{
+  return (3 & ((x86_64_read_mxcsr ()) >> 13));
+}
+
+static inline void
+fesetround (int mode)
+{
+  switch (mode)
+    {
+    case 0: case 1: case 2: case 3: break;
+    default: return (1);
+    }
+  x86_64_write_mxcsr ((mode << 13) | (0xffff9fff & (x86_64_read_mxcsr ())));
+  return (0);
+}
+
+#endif /* HAVE_FENV_H */
 
 #endif /* !SCM_CMPINTMD_H_INCLUDED */