Diff for /embedaddon/pcre/sljit/sljitNativeX86_common.c between versions 1.1.1.2 and 1.1.1.3

version 1.1.1.2, 2012/02/21 23:50:25 version 1.1.1.3, 2012/10/09 09:19:18
Line 104  static SLJIT_CONST sljit_ub reg_lmap[SLJIT_NO_REGISTER Line 104  static SLJIT_CONST sljit_ub reg_lmap[SLJIT_NO_REGISTER
 #else  #else
 /* 1st passed in rcx, 2nd argument passed in rdx, 3rd in r8. */  /* 1st passed in rcx, 2nd argument passed in rdx, 3rd in r8. */
 static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 4] = {  static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 4] = {
  0, 0, 2, 1, 11, 13, 3, 6, 7, 14, 12, 15, 10, 8, 9  0, 0, 2, 1, 11, 13, 3, 6, 7, 14, 15, 4, 10, 8, 9
 };  };
 /* low-map. reg_map & 0x7. */  /* low-map. reg_map & 0x7. */
 static SLJIT_CONST sljit_ub reg_lmap[SLJIT_NO_REGISTERS + 4] = {  static SLJIT_CONST sljit_ub reg_lmap[SLJIT_NO_REGISTERS + 4] = {
  0, 0, 2, 1, 3,  5,  3, 6, 7,  6,  4,  7, 2,  0, 1  0, 0, 2, 1, 3,  5,  3, 6, 7,  6,  7, 4, 2,  0, 1
 };  };
 #endif  #endif
   
Line 415  static SLJIT_INLINE int emit_save_flags(struct sljit_c Line 415  static SLJIT_INLINE int emit_save_flags(struct sljit_c
         buf = (sljit_ub*)ensure_buf(compiler, 1 + 5);          buf = (sljit_ub*)ensure_buf(compiler, 1 + 5);
         FAIL_IF(!buf);          FAIL_IF(!buf);
         INC_SIZE(5);          INC_SIZE(5);
         *buf++ = 0x9c; /* pushfd */  
 #else  #else
         buf = (sljit_ub*)ensure_buf(compiler, 1 + 6);          buf = (sljit_ub*)ensure_buf(compiler, 1 + 6);
         FAIL_IF(!buf);          FAIL_IF(!buf);
         INC_SIZE(6);          INC_SIZE(6);
        *buf++ = 0x9c; /* pushfq */        *buf++ = REX_W;
        *buf++ = 0x48; 
 #endif  #endif
         *buf++ = 0x8d; /* lea esp/rsp, [esp/rsp + sizeof(sljit_w)] */          *buf++ = 0x8d; /* lea esp/rsp, [esp/rsp + sizeof(sljit_w)] */
         *buf++ = 0x64;          *buf++ = 0x64;
         *buf++ = 0x24;          *buf++ = 0x24;
        *buf++ = sizeof(sljit_w);        *buf++ = (sljit_ub)sizeof(sljit_w);
         *buf++ = 0x9c; /* pushfd / pushfq */
         compiler->flags_saved = 1;          compiler->flags_saved = 1;
         return SLJIT_SUCCESS;          return SLJIT_SUCCESS;
 }  }
Line 439  static SLJIT_INLINE int emit_restore_flags(struct slji Line 438  static SLJIT_INLINE int emit_restore_flags(struct slji
         buf = (sljit_ub*)ensure_buf(compiler, 1 + 5);          buf = (sljit_ub*)ensure_buf(compiler, 1 + 5);
         FAIL_IF(!buf);          FAIL_IF(!buf);
         INC_SIZE(5);          INC_SIZE(5);
           *buf++ = 0x9d; /* popfd */
 #else  #else
         buf = (sljit_ub*)ensure_buf(compiler, 1 + 6);          buf = (sljit_ub*)ensure_buf(compiler, 1 + 6);
         FAIL_IF(!buf);          FAIL_IF(!buf);
         INC_SIZE(6);          INC_SIZE(6);
        *buf++ = 0x48;        *buf++ = 0x9d; /* popfq */
         *buf++ = REX_W;
 #endif  #endif
         *buf++ = 0x8d; /* lea esp/rsp, [esp/rsp - sizeof(sljit_w)] */          *buf++ = 0x8d; /* lea esp/rsp, [esp/rsp - sizeof(sljit_w)] */
         *buf++ = 0x64;          *buf++ = 0x64;
         *buf++ = 0x24;          *buf++ = 0x24;
         *buf++ = (sljit_ub)-(int)sizeof(sljit_w);          *buf++ = (sljit_ub)-(int)sizeof(sljit_w);
         *buf++ = 0x9d; /* popfd / popfq */  
         compiler->flags_saved = keep_flags;          compiler->flags_saved = keep_flags;
         return SLJIT_SUCCESS;          return SLJIT_SUCCESS;
 }  }
Line 457  static SLJIT_INLINE int emit_restore_flags(struct slji Line 457  static SLJIT_INLINE int emit_restore_flags(struct slji
 #ifdef _WIN32  #ifdef _WIN32
 #include <malloc.h>  #include <malloc.h>
   
static void SLJIT_CALL sljit_touch_stack(sljit_w local_size)static void SLJIT_CALL sljit_grow_stack(sljit_w local_size)
 {  {
        /* Workaround for calling _chkstk. */        /* Workaround for calling the internal _chkstk() function on Windows.
         This function touches all 4k pages belongs to the requested stack space,
         which size is passed in local_size. This is necessary on Windows where
         the stack can only grow in 4k steps. However, this function just burn
         CPU cycles if the stack is large enough, but you don't know it in advance.
         I think this is a bad design even if it has some reasons. */
         alloca(local_size);          alloca(local_size);
 }  }
   
 #endif  #endif
   
 #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)  #if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
Line 1050  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op1(struct slj Line 1056  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op1(struct slj
   
         CHECK_ERROR();          CHECK_ERROR();
         check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw);          check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw);
           ADJUST_LOCAL_OFFSET(dst, dstw);
           ADJUST_LOCAL_OFFSET(src, srcw);
   
           CHECK_EXTRA_REGS(dst, dstw, dst_is_ereg = 1);
           CHECK_EXTRA_REGS(src, srcw, src_is_ereg = 1);
 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)  #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
         compiler->mode32 = op & SLJIT_INT_OP;          compiler->mode32 = op & SLJIT_INT_OP;
 #endif  #endif
         CHECK_EXTRA_REGS(dst, dstw, dst_is_ereg = 1);  
         CHECK_EXTRA_REGS(src, srcw, src_is_ereg = 1);  
   
         if (GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_MOVU_SI) {          if (GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_MOVU_SI) {
                 op = GET_OPCODE(op);                  op = GET_OPCODE(op);
Line 1558  static int emit_lea_binary(struct sljit_compiler *comp Line 1566  static int emit_lea_binary(struct sljit_compiler *comp
         dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REGISTER;          dst_r = (dst >= SLJIT_TEMPORARY_REG1 && dst <= SLJIT_NO_REGISTERS) ? dst : TMP_REGISTER;
   
         if (src1 >= SLJIT_TEMPORARY_REG1 && src1 <= SLJIT_NO_REGISTERS) {          if (src1 >= SLJIT_TEMPORARY_REG1 && src1 <= SLJIT_NO_REGISTERS) {
                if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= SLJIT_NO_REGISTERS) {                if ((src2 >= SLJIT_TEMPORARY_REG1 && src2 <= SLJIT_NO_REGISTERS) || src2 == TMP_REGISTER) {
                        /* It is not possible to be both SLJIT_LOCALS_REG. */                        code = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM2(src1, src2), 0);
                        if (src1 != SLJIT_LOCALS_REG || src2 != SLJIT_LOCALS_REG) {                        FAIL_IF(!code);
                                code = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM2(src1, src2), 0);                        *code = 0x8d;
                                FAIL_IF(!code);                        done = 1;
                                *code = 0x8d; 
                                done = 1; 
                        } 
                 }                  }
 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)  #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
                 if ((src2 & SLJIT_IMM) && (compiler->mode32 || IS_HALFWORD(src2w))) {                  if ((src2 & SLJIT_IMM) && (compiler->mode32 || IS_HALFWORD(src2w))) {
Line 1831  static int emit_shift(struct sljit_compiler *compiler, Line 1836  static int emit_shift(struct sljit_compiler *compiler,
 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)  #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
                 EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_PREF_SHIFT_REG, 0);                  EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_PREF_SHIFT_REG, 0);
 #else  #else
                /* [esp - 4] is reserved for eflags. */                /* [esp+0] contains the flags. */
                EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), -(int)(2 * sizeof(sljit_w)), SLJIT_PREF_SHIFT_REG, 0);                EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), sizeof(sljit_w), SLJIT_PREF_SHIFT_REG, 0);
 #endif  #endif
                 EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src2, src2w);                  EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src2, src2w);
                 code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0);                  code = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_PREF_SHIFT_REG, 0, TMP_REGISTER, 0);
Line 1841  static int emit_shift(struct sljit_compiler *compiler, Line 1846  static int emit_shift(struct sljit_compiler *compiler,
 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)  #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
                 EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REG2, 0);                  EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REG2, 0);
 #else  #else
                /* [esp - 4] is reserved for eflags. */                EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), sizeof(sljit_w));
                EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), -(int)(2 * sizeof(sljit_w))); 
 #endif  #endif
                 EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0);                  EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0);
         }          }
Line 1892  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op2(struct slj Line 1896  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op2(struct slj
 {  {
         CHECK_ERROR();          CHECK_ERROR();
         check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w);          check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
           ADJUST_LOCAL_OFFSET(dst, dstw);
           ADJUST_LOCAL_OFFSET(src1, src1w);
           ADJUST_LOCAL_OFFSET(src2, src2w);
   
 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)  
         compiler->mode32 = op & SLJIT_INT_OP;  
 #endif  
         CHECK_EXTRA_REGS(dst, dstw, (void)0);          CHECK_EXTRA_REGS(dst, dstw, (void)0);
         CHECK_EXTRA_REGS(src1, src1w, (void)0);          CHECK_EXTRA_REGS(src1, src1w, (void)0);
         CHECK_EXTRA_REGS(src2, src2w, (void)0);          CHECK_EXTRA_REGS(src2, src2w, (void)0);
   #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
           compiler->mode32 = op & SLJIT_INT_OP;
   #endif
   
         if (GET_OPCODE(op) >= SLJIT_MUL) {          if (GET_OPCODE(op) >= SLJIT_MUL) {
                 if (SLJIT_UNLIKELY(GET_FLAGS(op)))                  if (SLJIT_UNLIKELY(GET_FLAGS(op)))
Line 1912  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op2(struct slj Line 1919  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op2(struct slj
                 if (!GET_FLAGS(op)) {                  if (!GET_FLAGS(op)) {
                         if (emit_lea_binary(compiler, dst, dstw, src1, src1w, src2, src2w) != SLJIT_ERR_UNSUPPORTED)                          if (emit_lea_binary(compiler, dst, dstw, src1, src1w, src2, src2w) != SLJIT_ERR_UNSUPPORTED)
                                 return compiler->error;                                  return compiler->error;
                }                 }
                 else                  else
                         compiler->flags_saved = 0;                          compiler->flags_saved = 0;
                 if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS) && !compiler->flags_saved)                  if (SLJIT_UNLIKELY(op & SLJIT_KEEP_FLAGS) && !compiler->flags_saved)
Line 2008  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op_custom(stru Line 2015  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_op_custom(stru
 /*  Floating point operators                                             */  /*  Floating point operators                                             */
 /* --------------------------------------------------------------------- */  /* --------------------------------------------------------------------- */
   
 #if (defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)  
 static int sse2_available = 0;  
 #endif  
   
 #if (defined SLJIT_SSE2 && SLJIT_SSE2)  #if (defined SLJIT_SSE2 && SLJIT_SSE2)
   
 /* Alignment + 2 * 16 bytes. */  /* Alignment + 2 * 16 bytes. */
Line 2020  static sljit_i *sse2_buffer; Line 2023  static sljit_i *sse2_buffer;
   
 static void init_compiler()  static void init_compiler()
 {  {
 #if (defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)  
         int features = 0;  
 #endif  
   
         sse2_buffer = (sljit_i*)(((sljit_uw)sse2_data + 15) & ~0xf);          sse2_buffer = (sljit_i*)(((sljit_uw)sse2_data + 15) & ~0xf);
         sse2_buffer[0] = 0;          sse2_buffer[0] = 0;
         sse2_buffer[1] = 0x80000000;          sse2_buffer[1] = 0x80000000;
         sse2_buffer[4] = 0xffffffff;          sse2_buffer[4] = 0xffffffff;
         sse2_buffer[5] = 0x7fffffff;          sse2_buffer[5] = 0x7fffffff;
   }
   
#if (defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)#endif
 
 SLJIT_API_FUNC_ATTRIBUTE int sljit_is_fpu_available(void)
 {
 #if (defined SLJIT_SSE2 && SLJIT_SSE2)
 #if (defined SLJIT_DETECT_SSE2 && SLJIT_DETECT_SSE2)
         static int sse2_available = -1;
         int features;
 
         if (sse2_available != -1)
                 return sse2_available;
 
 #ifdef __GNUC__  #ifdef __GNUC__
         /* AT&T syntax. */          /* AT&T syntax. */
         asm (          asm (
Line 2053  static void init_compiler() Line 2064  static void init_compiler()
                 mov features, edx                  mov features, edx
         }          }
 #else  #else
        #error "SLJIT_SSE2_AUTO is not implemented for this C compiler"        #error "SLJIT_DETECT_SSE2 is not implemented for this C compiler"
 #endif  #endif
         sse2_available = (features >> 26) & 0x1;          sse2_available = (features >> 26) & 0x1;
           return sse2_available;
   #else
           return 1;
 #endif  #endif
}#else
        return 0;
 #endif  #endif
   
 SLJIT_API_FUNC_ATTRIBUTE int sljit_is_fpu_available(void)  
 {  
         /* Always available. */  
         return 1;  
 }  }
   
 #if (defined SLJIT_SSE2 && SLJIT_SSE2)  #if (defined SLJIT_SSE2 && SLJIT_SSE2)
Line 2105  static SLJIT_INLINE int emit_sse2_store(struct sljit_c Line 2114  static SLJIT_INLINE int emit_sse2_store(struct sljit_c
         return emit_sse2(compiler, 0x11, src, dst, dstw);          return emit_sse2(compiler, 0x11, src, dst, dstw);
 }  }
   
 #if !(defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)  
 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop1(struct sljit_compiler *compiler, int op,  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop1(struct sljit_compiler *compiler, int op,
 #else  
 static int sljit_emit_sse2_fop1(struct sljit_compiler *compiler, int op,  
 #endif  
         int dst, sljit_w dstw,          int dst, sljit_w dstw,
         int src, sljit_w srcw)          int src, sljit_w srcw)
 {  {
Line 2167  static int sljit_emit_sse2_fop1(struct sljit_compiler  Line 2172  static int sljit_emit_sse2_fop1(struct sljit_compiler 
         return SLJIT_SUCCESS;          return SLJIT_SUCCESS;
 }  }
   
 #if !(defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)  
 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sljit_compiler *compiler, int op,  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sljit_compiler *compiler, int op,
 #else  
 static int sljit_emit_sse2_fop2(struct sljit_compiler *compiler, int op,  
 #endif  
         int dst, sljit_w dstw,          int dst, sljit_w dstw,
         int src1, sljit_w src1w,          int src1, sljit_w src1w,
         int src2, sljit_w src2w)          int src2, sljit_w src2w)
Line 2229  static int sljit_emit_sse2_fop2(struct sljit_compiler  Line 2230  static int sljit_emit_sse2_fop2(struct sljit_compiler 
         return SLJIT_SUCCESS;          return SLJIT_SUCCESS;
 }  }
   
#endif#else
   
 #if (defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO) || !(defined SLJIT_SSE2 && SLJIT_SSE2)  
   
 static int emit_fld(struct sljit_compiler *compiler,  
         int src, sljit_w srcw)  
 {  
         sljit_ub *buf;  
   
         if (src >= SLJIT_FLOAT_REG1 && src <= SLJIT_FLOAT_REG4) {  
                 buf = (sljit_ub*)ensure_buf(compiler, 1 + 2);  
                 FAIL_IF(!buf);  
                 INC_SIZE(2);  
                 *buf++ = 0xd9;  
                 *buf = 0xc0 + src - 1;  
                 return SLJIT_SUCCESS;  
         }  
   
         buf = emit_x86_instruction(compiler, 1, 0, 0, src, srcw);  
         FAIL_IF(!buf);  
         *buf = 0xdd;  
         return SLJIT_SUCCESS;  
 }  
   
 static int emit_fop(struct sljit_compiler *compiler,  
         sljit_ub st_arg, sljit_ub st_arg2,  
         sljit_ub m64fp_arg, sljit_ub m64fp_arg2,  
         int src, sljit_w srcw)  
 {  
         sljit_ub *buf;  
   
         if (src >= SLJIT_FLOAT_REG1 && src <= SLJIT_FLOAT_REG4) {  
                 buf = (sljit_ub*)ensure_buf(compiler, 1 + 2);  
                 FAIL_IF(!buf);  
                 INC_SIZE(2);  
                 *buf++ = st_arg;  
                 *buf = st_arg2 + src;  
                 return SLJIT_SUCCESS;  
         }  
   
         buf = emit_x86_instruction(compiler, 1, 0, 0, src, srcw);  
         FAIL_IF(!buf);  
         *buf++ = m64fp_arg;  
         *buf |= m64fp_arg2;  
         return SLJIT_SUCCESS;  
 }  
   
 static int emit_fop_regs(struct sljit_compiler *compiler,  
         sljit_ub st_arg, sljit_ub st_arg2,  
         int src)  
 {  
         sljit_ub *buf;  
   
         buf = (sljit_ub*)ensure_buf(compiler, 1 + 2);  
         FAIL_IF(!buf);  
         INC_SIZE(2);  
         *buf++ = st_arg;  
         *buf = st_arg2 + src;  
         return SLJIT_SUCCESS;  
 }  
   
 #if !(defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)  
 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop1(struct sljit_compiler *compiler, int op,  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop1(struct sljit_compiler *compiler, int op,
 #else  
 static int sljit_emit_fpu_fop1(struct sljit_compiler *compiler, int op,  
 #endif  
         int dst, sljit_w dstw,          int dst, sljit_w dstw,
         int src, sljit_w srcw)          int src, sljit_w srcw)
 {  {
 #if !(defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)  
         sljit_ub *buf;  
 #endif  
   
         CHECK_ERROR();          CHECK_ERROR();
           /* Should cause an assertion fail. */
         check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw);          check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw);
        compiler->error = SLJIT_ERR_UNSUPPORTED;
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)        return SLJIT_ERR_UNSUPPORTED;
        compiler->mode32 = 1; 
#endif 
 
        if (GET_OPCODE(op) == SLJIT_FCMP) { 
                compiler->flags_saved = 0; 
#if !(defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) 
                FAIL_IF(emit_fld(compiler, dst, dstw)); 
                FAIL_IF(emit_fop(compiler, 0xd8, 0xd8, 0xdc, 0x3 << 3, src, srcw)); 
 
                /* Copy flags. */ 
                EMIT_MOV(compiler, TMP_REGISTER, 0, SLJIT_TEMPORARY_REG1, 0); 
                buf = (sljit_ub*)ensure_buf(compiler, 1 + 3); 
                FAIL_IF(!buf); 
                INC_SIZE(3); 
                *buf++ = 0xdf; 
                *buf++ = 0xe0; 
                /* Note: lahf is not supported on all x86-64 architectures. */ 
                *buf++ = 0x9e; 
                EMIT_MOV(compiler, SLJIT_TEMPORARY_REG1, 0, TMP_REGISTER, 0); 
#else 
                if (src >= SLJIT_FLOAT_REG1 && src <= SLJIT_FLOAT_REG4) { 
                        FAIL_IF(emit_fld(compiler, dst, dstw)); 
                        FAIL_IF(emit_fop_regs(compiler, 0xdf, 0xe8, src)); 
                } else { 
                        FAIL_IF(emit_fld(compiler, src, srcw)); 
                        FAIL_IF(emit_fld(compiler, dst + ((dst >= SLJIT_FLOAT_REG1 && dst <= SLJIT_FLOAT_REG4) ? 1 : 0), dstw)); 
                        FAIL_IF(emit_fop_regs(compiler, 0xdf, 0xe8, src)); 
                        FAIL_IF(emit_fop_regs(compiler, 0xdd, 0xd8, 0)); 
                } 
#endif 
                return SLJIT_SUCCESS; 
        } 
 
        FAIL_IF(emit_fld(compiler, src, srcw)); 
 
        switch (op) { 
        case SLJIT_FNEG: 
                FAIL_IF(emit_fop_regs(compiler, 0xd9, 0xe0, 0)); 
                break; 
        case SLJIT_FABS: 
                FAIL_IF(emit_fop_regs(compiler, 0xd9, 0xe1, 0)); 
                break; 
        } 
 
        FAIL_IF(emit_fop(compiler, 0xdd, 0xd8, 0xdd, 0x3 << 3, dst, dstw)); 
 
        return SLJIT_SUCCESS; 
 }  }
   
 #if !(defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)  
 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sljit_compiler *compiler, int op,  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sljit_compiler *compiler, int op,
 #else  
 static int sljit_emit_fpu_fop2(struct sljit_compiler *compiler, int op,  
 #endif  
         int dst, sljit_w dstw,          int dst, sljit_w dstw,
         int src1, sljit_w src1w,          int src1, sljit_w src1w,
         int src2, sljit_w src2w)          int src2, sljit_w src2w)
 {  {
         CHECK_ERROR();          CHECK_ERROR();
           /* Should cause an assertion fail. */
         check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w);          check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
        compiler->error = SLJIT_ERR_UNSUPPORTED;
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)        return SLJIT_ERR_UNSUPPORTED;
        compiler->mode32 = 1; 
#endif 
 
        if (src1 >= SLJIT_FLOAT_REG1 && src1 <= SLJIT_FLOAT_REG4 && dst == src1) { 
                FAIL_IF(emit_fld(compiler, src2, src2w)); 
 
                switch (op) { 
                case SLJIT_FADD: 
                        FAIL_IF(emit_fop_regs(compiler, 0xde, 0xc0, src1)); 
                        break; 
                case SLJIT_FSUB: 
                        FAIL_IF(emit_fop_regs(compiler, 0xde, 0xe8, src1)); 
                        break; 
                case SLJIT_FMUL: 
                        FAIL_IF(emit_fop_regs(compiler, 0xde, 0xc8, src1)); 
                        break; 
                case SLJIT_FDIV: 
                        FAIL_IF(emit_fop_regs(compiler, 0xde, 0xf8, src1)); 
                        break; 
                } 
                return SLJIT_SUCCESS; 
        } 
 
        FAIL_IF(emit_fld(compiler, src1, src1w)); 
 
        if (src2 >= SLJIT_FLOAT_REG1 && src2 <= SLJIT_FLOAT_REG4 && dst == src2) { 
                switch (op) { 
                case SLJIT_FADD: 
                        FAIL_IF(emit_fop_regs(compiler, 0xde, 0xc0, src2)); 
                        break; 
                case SLJIT_FSUB: 
                        FAIL_IF(emit_fop_regs(compiler, 0xde, 0xe0, src2)); 
                        break; 
                case SLJIT_FMUL: 
                        FAIL_IF(emit_fop_regs(compiler, 0xde, 0xc8, src2)); 
                        break; 
                case SLJIT_FDIV: 
                        FAIL_IF(emit_fop_regs(compiler, 0xde, 0xf0, src2)); 
                        break; 
                } 
                return SLJIT_SUCCESS; 
        } 
 
        switch (op) { 
        case SLJIT_FADD: 
                FAIL_IF(emit_fop(compiler, 0xd8, 0xc0, 0xdc, 0x0 << 3, src2, src2w)); 
                break; 
        case SLJIT_FSUB: 
                FAIL_IF(emit_fop(compiler, 0xd8, 0xe0, 0xdc, 0x4 << 3, src2, src2w)); 
                break; 
        case SLJIT_FMUL: 
                FAIL_IF(emit_fop(compiler, 0xd8, 0xc8, 0xdc, 0x1 << 3, src2, src2w)); 
                break; 
        case SLJIT_FDIV: 
                FAIL_IF(emit_fop(compiler, 0xd8, 0xf0, 0xdc, 0x6 << 3, src2, src2w)); 
                break; 
        } 
 
        FAIL_IF(emit_fop(compiler, 0xdd, 0xd8, 0xdd, 0x3 << 3, dst, dstw)); 
 
        return SLJIT_SUCCESS; 
 }  }
 #endif  
   
 #if (defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)  
   
 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop1(struct sljit_compiler *compiler, int op,  
         int dst, sljit_w dstw,  
         int src, sljit_w srcw)  
 {  
         if (sse2_available)  
                 return sljit_emit_sse2_fop1(compiler, op, dst, dstw, src, srcw);  
         else  
                 return sljit_emit_fpu_fop1(compiler, op, dst, dstw, src, srcw);  
 }  
   
 SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_fop2(struct sljit_compiler *compiler, int op,  
         int dst, sljit_w dstw,  
         int src1, sljit_w src1w,  
         int src2, sljit_w src2w)  
 {  
         if (sse2_available)  
                 return sljit_emit_sse2_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w);  
         else  
                 return sljit_emit_fpu_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w);  
 }  
   
 #endif  #endif
   
 /* --------------------------------------------------------------------- */  /* --------------------------------------------------------------------- */
Line 2534  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ijump(struct s Line 2334  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ijump(struct s
   
         CHECK_ERROR();          CHECK_ERROR();
         check_sljit_emit_ijump(compiler, type, src, srcw);          check_sljit_emit_ijump(compiler, type, src, srcw);
           ADJUST_LOCAL_OFFSET(src, srcw);
   
         CHECK_EXTRA_REGS(src, srcw, (void)0);          CHECK_EXTRA_REGS(src, srcw, (void)0);
   
         if (SLJIT_UNLIKELY(compiler->flags_saved)) {          if (SLJIT_UNLIKELY(compiler->flags_saved)) {
                 if (type <= SLJIT_JUMP)                  if (type <= SLJIT_JUMP)
                         FAIL_IF(emit_restore_flags(compiler, 0));                          FAIL_IF(emit_restore_flags(compiler, 0));
Line 2549  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ijump(struct s Line 2351  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ijump(struct s
                         EMIT_MOV(compiler, TMP_REGISTER, 0, src, 0);                          EMIT_MOV(compiler, TMP_REGISTER, 0, src, 0);
                         src = TMP_REGISTER;                          src = TMP_REGISTER;
                 }                  }
                if ((src & SLJIT_MEM) && (src & 0xf) == SLJIT_LOCALS_REG && type >= SLJIT_CALL3) {                if (src == SLJIT_MEM1(SLJIT_LOCALS_REG) && type >= SLJIT_CALL3)
                        if (src & 0xf0) {                        srcw += sizeof(sljit_w);
                                EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw); 
                                src = TMP_REGISTER; 
                        } 
                        else 
                                srcw += sizeof(sljit_w); 
                } 
 #else  #else
                if ((src & SLJIT_MEM) && (src & 0xf) == SLJIT_LOCALS_REG) {                if (src == SLJIT_MEM1(SLJIT_LOCALS_REG))
                        if (src & 0xf0) {                        srcw += sizeof(sljit_w) * (type - SLJIT_CALL0);
                                EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw); 
                                src = TMP_REGISTER; 
                        } 
                        else 
                                srcw += sizeof(sljit_w) * (type - SLJIT_CALL0); 
                } 
 #endif  #endif
 #endif  #endif
 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) && defined(_WIN64)  #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64) && defined(_WIN64)
Line 2613  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_cond_value(str Line 2403  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_cond_value(str
 {  {
         sljit_ub *buf;          sljit_ub *buf;
         sljit_ub cond_set = 0;          sljit_ub cond_set = 0;
           int dst_save = dst;
           sljit_w dstw_save = dstw;
 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)  #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
         int reg;          int reg;
 #endif  #endif
Line 2623  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_cond_value(str Line 2415  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_cond_value(str
         if (dst == SLJIT_UNUSED)          if (dst == SLJIT_UNUSED)
                 return SLJIT_SUCCESS;                  return SLJIT_SUCCESS;
   
           ADJUST_LOCAL_OFFSET(dst, dstw);
         CHECK_EXTRA_REGS(dst, dstw, (void)0);          CHECK_EXTRA_REGS(dst, dstw, (void)0);
         if (SLJIT_UNLIKELY(compiler->flags_saved))          if (SLJIT_UNLIKELY(compiler->flags_saved))
                FAIL_IF(emit_restore_flags(compiler, 0));                FAIL_IF(emit_restore_flags(compiler, op & SLJIT_KEEP_FLAGS));
   
         switch (type) {          switch (type) {
         case SLJIT_C_EQUAL:          case SLJIT_C_EQUAL:
Line 2718  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_cond_value(str Line 2511  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_cond_value(str
 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)  #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
                         compiler->skip_checks = 1;                          compiler->skip_checks = 1;
 #endif  #endif
                        return sljit_emit_op2(compiler, op, dst, dstw, dst, dstw, TMP_REGISTER, 0);                        return sljit_emit_op2(compiler, op, dst_save, dstw_save, dst_save, dstw_save, TMP_REGISTER, 0);
                 }                  }
         }          }
 #else  #else
Line 2790  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_cond_value(str Line 2583  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_cond_value(str
 #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)  #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
                 compiler->skip_checks = 1;                  compiler->skip_checks = 1;
 #endif  #endif
                return sljit_emit_op2(compiler, op, dst, dstw, dst, dstw, TMP_REGISTER, 0);                return sljit_emit_op2(compiler, op, dst_save, dstw_save, dst_save, dstw_save, TMP_REGISTER, 0);
         }          }
 #endif  #endif
   
         return SLJIT_SUCCESS;          return SLJIT_SUCCESS;
 }  }
   
   SLJIT_API_FUNC_ATTRIBUTE int sljit_get_local_base(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w offset)
   {
           CHECK_ERROR();
           check_sljit_get_local_base(compiler, dst, dstw, offset);
           ADJUST_LOCAL_OFFSET(dst, dstw);
   
           CHECK_EXTRA_REGS(dst, dstw, (void)0);
   
   #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
           compiler->mode32 = 0;
   #endif
   
           ADJUST_LOCAL_OFFSET(SLJIT_MEM1(SLJIT_LOCALS_REG), offset);
   
   #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
           if (NOT_HALFWORD(offset)) {
                   FAIL_IF(emit_load_imm64(compiler, TMP_REGISTER, offset));
   #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
                   SLJIT_ASSERT(emit_lea_binary(compiler, dst, dstw, SLJIT_LOCALS_REG, 0, TMP_REGISTER, 0) != SLJIT_ERR_UNSUPPORTED);
                   return compiler->error;
   #else
                   return emit_lea_binary(compiler, dst, dstw, SLJIT_LOCALS_REG, 0, TMP_REGISTER, 0);
   #endif
           }
   #endif
   
           if (offset != 0)
                   return emit_lea_binary(compiler, dst, dstw, SLJIT_LOCALS_REG, 0, SLJIT_IMM, offset);
           return emit_mov(compiler, dst, dstw, SLJIT_LOCALS_REG, 0);
   }
   
 SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w init_value)  SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w init_value)
 {  {
         sljit_ub *buf;          sljit_ub *buf;
Line 2807  SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emi Line 2631  SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emi
   
         CHECK_ERROR_PTR();          CHECK_ERROR_PTR();
         check_sljit_emit_const(compiler, dst, dstw, init_value);          check_sljit_emit_const(compiler, dst, dstw, init_value);
           ADJUST_LOCAL_OFFSET(dst, dstw);
   
         CHECK_EXTRA_REGS(dst, dstw, (void)0);          CHECK_EXTRA_REGS(dst, dstw, (void)0);
   

Removed from v.1.1.1.2  
changed lines
  Added in v.1.1.1.3


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>