]> git.unchartedbackwaters.co.uk Git - francis/libjit.git/commitdiff
add x86 JIT_OP_NFLOAT_TO_INT and JIT_OP_NFLOAT_TO_LONG rules
authorAleksey Demakov <ademakov@gmail.com>
Sun, 23 Dec 2007 18:18:44 +0000 (18:18 +0000)
committerAleksey Demakov <ademakov@gmail.com>
Sun, 23 Dec 2007 18:18:44 +0000 (18:18 +0000)
ChangeLog
jit/jit-gen-x86.h
jit/jit-rules-x86.ins

index 866e0306c03deb0aacce9ec231701aa9a37bdf27..14c1af7d4e4c87c2011c8eddd42ff72159a83317 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2007-12-24  Aleksey Demakov  <ademakov@gmail.com>
+
+       * jit/jit-gen-x86.h (x86_alu_reg16_imm): add macro.
+       * jit/jit-rules-x86.ins: add JIT_OP_NFLOAT_TO_INT and
+       JIT_OP_NFLOAT_TO_LONG rules.
+
 2007-12-21  Aleksey Demakov  <ademakov@gmail.com>
 
        * jit/jit-internal.h, jit/jit-context.c, jit/jit-function.c: 
index 5e6e9fdac9150051d9faaf9383eb9613e1f508fd..d6a4dfab2cdc157632a0a3806448c1c499d08456 100644 (file)
@@ -540,6 +540,25 @@ typedef union {
                }       \
        } while (0)
 
+#define x86_alu_reg16_imm(inst,opc,reg,imm)    \
+       do {    \
+               *(inst)++ = (unsigned char)0x66;        \
+               if ((reg) == X86_EAX) { \
+                       *(inst)++ = (((unsigned char)(opc)) << 3) + 5;  \
+                       x86_imm_emit16 ((inst), (imm)); \
+                       break;  \
+               }       \
+               if (x86_is_imm8((imm))) {       \
+                       *(inst)++ = (unsigned char)0x83;        \
+                       x86_reg_emit ((inst), (opc), (reg));    \
+                       x86_imm_emit8 ((inst), (imm));  \
+               } else {        \
+                       *(inst)++ = (unsigned char)0x81;        \
+                       x86_reg_emit ((inst), (opc), (reg));    \
+                       x86_imm_emit16 ((inst), (imm)); \
+               }       \
+       } while (0)
+
 #define x86_alu_mem_imm(inst,opc,mem,imm)      \
        do {    \
                if (x86_is_imm8((imm))) {       \
index ad2c141208e91f30ba6ab3d151f9b88f5833c73b..38c9384b7f8c78e0ce4d6dce7ee9a67f59bf2a4e 100644 (file)
@@ -141,6 +141,49 @@ JIT_OP_EXPAND_UINT:
                x86_clear_reg(inst, %1);
        }
 
+JIT_OP_NFLOAT_TO_INT: stack
+       [=reg, freg] -> {
+               /* allocate space on the stack for 2 shorts and 1 int */
+               x86_alu_reg_imm(inst, X86_SUB, X86_ESP, 8);
+               /* store FPU control word */
+               x86_fnstcw_membase(inst, X86_ESP, 0);
+               /* set "round toward zero" mode */
+               x86_mov_reg_membase(inst, $1, X86_ESP, 0, 2);
+               x86_alu_reg16_imm(inst, X86_OR, $1, 0xc00);
+               x86_mov_membase_reg(inst, X86_ESP, 2, $1, 2);
+               x86_fldcw_membase(inst, X86_ESP, 2);
+               /* convert float to int */
+               x86_fist_pop_membase(inst, X86_ESP, 4, 0);
+               /* restore FPU control word */
+               x86_fldcw_membase(inst, X86_ESP, 0);
+               /* move result to the destination */
+               x86_mov_reg_membase(inst, $1, X86_ESP, 4, 4);
+               /* restore the stack */
+               x86_alu_reg_imm(inst, X86_ADD, X86_ESP, 8);
+       }
+
+JIT_OP_NFLOAT_TO_LONG: stack
+       [=lreg, freg] -> {
+               /* allocate space on the stack for 2 shorts and 1 long */
+               x86_alu_reg_imm(inst, X86_SUB, X86_ESP, 12);
+               /* store FPU control word */
+               x86_fnstcw_membase(inst, X86_ESP, 0);
+               /* set "round toward zero" mode */
+               x86_mov_reg_membase(inst, $1, X86_ESP, 0, 2);
+               x86_alu_reg16_imm(inst, X86_OR, $1, 0xc00);
+               x86_mov_membase_reg(inst, X86_ESP, 2, $1, 2);
+               x86_fldcw_membase(inst, X86_ESP, 2);
+               /* convert float to long */
+               x86_fist_pop_membase(inst, X86_ESP, 4, 1);
+               /* restore FPU control word */
+               x86_fldcw_membase(inst, X86_ESP, 0);
+               /* move result to the destination */
+               x86_mov_reg_membase(inst, $1, X86_ESP, 4, 4);
+               x86_mov_reg_membase(inst, %1, X86_ESP, 8, 4);
+               /* restore the stack */
+               x86_alu_reg_imm(inst, X86_ADD, X86_ESP, 12);
+       }
+
 JIT_OP_INT_TO_NFLOAT:
        [=freg, local] -> {
                x86_fild_membase(inst, X86_EBP, $2, 0);
@@ -1449,12 +1492,18 @@ JIT_OP_LSIGN:
 
 JIT_OP_CHECK_NULL: note
        [reg] -> {
+#if 0 && defined(JIT_USE_SIGNALS)
+               /* if $1 contains NULL this generates SEGV and the signal
+                  handler will throw the exception  */
+               x86_alu_reg_membase(inst, X86_CMP, $1, $1, 0);
+#else
                unsigned char *patch;
                x86_alu_reg_reg(inst, X86_OR, $1, $1);
                patch = inst;
                x86_branch8(inst, X86_CC_NE, 0, 0);
                inst = throw_builtin(inst, func, JIT_RESULT_NULL_REFERENCE);
                x86_patch(patch, inst);
+#endif
        }
 
 /*