From 8552cffc732c86bd199ef2bf7deebdb0510f57a7 Mon Sep 17 00:00:00 2001 From: Aleksey Demakov Date: Sun, 23 Dec 2007 18:18:44 +0000 Subject: [PATCH] add x86 JIT_OP_NFLOAT_TO_INT and JIT_OP_NFLOAT_TO_LONG rules --- ChangeLog | 6 ++++++ jit/jit-gen-x86.h | 19 +++++++++++++++++ jit/jit-rules-x86.ins | 49 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+) diff --git a/ChangeLog b/ChangeLog index 866e030..14c1af7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2007-12-24 Aleksey Demakov + + * 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 * jit/jit-internal.h, jit/jit-context.c, jit/jit-function.c: diff --git a/jit/jit-gen-x86.h b/jit/jit-gen-x86.h index 5e6e9fd..d6a4dfa 100644 --- a/jit/jit-gen-x86.h +++ b/jit/jit-gen-x86.h @@ -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))) { \ diff --git a/jit/jit-rules-x86.ins b/jit/jit-rules-x86.ins index ad2c141..38c9384 100644 --- a/jit/jit-rules-x86.ins +++ b/jit/jit-rules-x86.ins @@ -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 } /*