/[pcre]/code/trunk/sljit/sljitNativeX86_common.c
ViewVC logotype

Diff of /code/trunk/sljit/sljitNativeX86_common.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 906 by zherczeg, Tue Jan 24 09:55:16 2012 UTC revision 955 by zherczeg, Tue Apr 3 15:32:36 2012 UTC
# Line 104  static SLJIT_CONST sljit_ub reg_lmap[SLJ Line 104  static SLJIT_CONST sljit_ub reg_lmap[SLJ
104  #else  #else
105  /* 1st passed in rcx, 2nd argument passed in rdx, 3rd in r8. */  /* 1st passed in rcx, 2nd argument passed in rdx, 3rd in r8. */
106  static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 4] = {  static SLJIT_CONST sljit_ub reg_map[SLJIT_NO_REGISTERS + 4] = {
107    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
108  };  };
109  /* low-map. reg_map & 0x7. */  /* low-map. reg_map & 0x7. */
110  static SLJIT_CONST sljit_ub reg_lmap[SLJIT_NO_REGISTERS + 4] = {  static SLJIT_CONST sljit_ub reg_lmap[SLJIT_NO_REGISTERS + 4] = {
111    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
112  };  };
113  #endif  #endif
114    
# Line 415  static SLJIT_INLINE int emit_save_flags( Line 415  static SLJIT_INLINE int emit_save_flags(
415          buf = (sljit_ub*)ensure_buf(compiler, 1 + 5);          buf = (sljit_ub*)ensure_buf(compiler, 1 + 5);
416          FAIL_IF(!buf);          FAIL_IF(!buf);
417          INC_SIZE(5);          INC_SIZE(5);
         *buf++ = 0x9c; /* pushfd */  
418  #else  #else
419          buf = (sljit_ub*)ensure_buf(compiler, 1 + 6);          buf = (sljit_ub*)ensure_buf(compiler, 1 + 6);
420          FAIL_IF(!buf);          FAIL_IF(!buf);
421          INC_SIZE(6);          INC_SIZE(6);
422          *buf++ = 0x9c; /* pushfq */          *buf++ = REX_W;
         *buf++ = 0x48;  
423  #endif  #endif
424          *buf++ = 0x8d; /* lea esp/rsp, [esp/rsp + sizeof(sljit_w)] */          *buf++ = 0x8d; /* lea esp/rsp, [esp/rsp + sizeof(sljit_w)] */
425          *buf++ = 0x64;          *buf++ = 0x64;
426          *buf++ = 0x24;          *buf++ = 0x24;
427          *buf++ = sizeof(sljit_w);          *buf++ = (sljit_ub)sizeof(sljit_w);
428            *buf++ = 0x9c; /* pushfd / pushfq */
429          compiler->flags_saved = 1;          compiler->flags_saved = 1;
430          return SLJIT_SUCCESS;          return SLJIT_SUCCESS;
431  }  }
# Line 439  static SLJIT_INLINE int emit_restore_fla Line 438  static SLJIT_INLINE int emit_restore_fla
438          buf = (sljit_ub*)ensure_buf(compiler, 1 + 5);          buf = (sljit_ub*)ensure_buf(compiler, 1 + 5);
439          FAIL_IF(!buf);          FAIL_IF(!buf);
440          INC_SIZE(5);          INC_SIZE(5);
441            *buf++ = 0x9d; /* popfd */
442  #else  #else
443          buf = (sljit_ub*)ensure_buf(compiler, 1 + 6);          buf = (sljit_ub*)ensure_buf(compiler, 1 + 6);
444          FAIL_IF(!buf);          FAIL_IF(!buf);
445          INC_SIZE(6);          INC_SIZE(6);
446          *buf++ = 0x48;          *buf++ = 0x9d; /* popfq */
447            *buf++ = REX_W;
448  #endif  #endif
449          *buf++ = 0x8d; /* lea esp/rsp, [esp/rsp - sizeof(sljit_w)] */          *buf++ = 0x8d; /* lea esp/rsp, [esp/rsp - sizeof(sljit_w)] */
450          *buf++ = 0x64;          *buf++ = 0x64;
451          *buf++ = 0x24;          *buf++ = 0x24;
452          *buf++ = (sljit_ub)-(int)sizeof(sljit_w);          *buf++ = (sljit_ub)-(int)sizeof(sljit_w);
         *buf++ = 0x9d; /* popfd / popfq */  
453          compiler->flags_saved = keep_flags;          compiler->flags_saved = keep_flags;
454          return SLJIT_SUCCESS;          return SLJIT_SUCCESS;
455  }  }
# Line 1050  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ Line 1050  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_
1050    
1051          CHECK_ERROR();          CHECK_ERROR();
1052          check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw);          check_sljit_emit_op1(compiler, op, dst, dstw, src, srcw);
1053            ADJUST_LOCAL_OFFSET(dst, dstw);
1054            ADJUST_LOCAL_OFFSET(src, srcw);
1055    
1056            CHECK_EXTRA_REGS(dst, dstw, dst_is_ereg = 1);
1057            CHECK_EXTRA_REGS(src, srcw, src_is_ereg = 1);
1058  #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)  #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1059          compiler->mode32 = op & SLJIT_INT_OP;          compiler->mode32 = op & SLJIT_INT_OP;
1060  #endif  #endif
         CHECK_EXTRA_REGS(dst, dstw, dst_is_ereg = 1);  
         CHECK_EXTRA_REGS(src, srcw, src_is_ereg = 1);  
1061    
1062          if (GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_MOVU_SI) {          if (GET_OPCODE(op) >= SLJIT_MOV && GET_OPCODE(op) <= SLJIT_MOVU_SI) {
1063                  op = GET_OPCODE(op);                  op = GET_OPCODE(op);
# Line 1558  static int emit_lea_binary(struct sljit_ Line 1560  static int emit_lea_binary(struct sljit_
1560          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;
1561    
1562          if (src1 >= SLJIT_TEMPORARY_REG1 && src1 <= SLJIT_NO_REGISTERS) {          if (src1 >= SLJIT_TEMPORARY_REG1 && src1 <= SLJIT_NO_REGISTERS) {
1563                  if (src2 >= SLJIT_TEMPORARY_REG1 && src2 <= SLJIT_NO_REGISTERS) {                  if ((src2 >= SLJIT_TEMPORARY_REG1 && src2 <= SLJIT_NO_REGISTERS) || src2 == TMP_REGISTER) {
1564                          /* It is not possible to be both SLJIT_LOCALS_REG. */                          code = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM2(src1, src2), 0);
1565                          if (src1 != SLJIT_LOCALS_REG || src2 != SLJIT_LOCALS_REG) {                          FAIL_IF(!code);
1566                                  code = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM2(src1, src2), 0);                          *code = 0x8d;
1567                                  FAIL_IF(!code);                          done = 1;
                                 *code = 0x8d;  
                                 done = 1;  
                         }  
1568                  }                  }
1569  #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)  #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1570                  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_compi Line 1830  static int emit_shift(struct sljit_compi
1830  #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)  #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1831                  EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_PREF_SHIFT_REG, 0);                  EMIT_MOV(compiler, TMP_REG2, 0, SLJIT_PREF_SHIFT_REG, 0);
1832  #else  #else
1833                  /* [esp - 4] is reserved for eflags. */                  /* [esp+0] contains the flags. */
1834                  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);
1835  #endif  #endif
1836                  EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src2, src2w);                  EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, src2, src2w);
1837                  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_compi Line 1840  static int emit_shift(struct sljit_compi
1840  #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)  #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1841                  EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REG2, 0);                  EMIT_MOV(compiler, SLJIT_PREF_SHIFT_REG, 0, TMP_REG2, 0);
1842  #else  #else
1843                  /* [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)));  
1844  #endif  #endif
1845                  EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0);                  EMIT_MOV(compiler, dst, dstw, TMP_REGISTER, 0);
1846          }          }
# Line 1892  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ Line 1890  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_
1890  {  {
1891          CHECK_ERROR();          CHECK_ERROR();
1892          check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w);          check_sljit_emit_op2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
1893            ADJUST_LOCAL_OFFSET(dst, dstw);
1894            ADJUST_LOCAL_OFFSET(src1, src1w);
1895            ADJUST_LOCAL_OFFSET(src2, src2w);
1896    
 #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)  
         compiler->mode32 = op & SLJIT_INT_OP;  
 #endif  
1897          CHECK_EXTRA_REGS(dst, dstw, (void)0);          CHECK_EXTRA_REGS(dst, dstw, (void)0);
1898          CHECK_EXTRA_REGS(src1, src1w, (void)0);          CHECK_EXTRA_REGS(src1, src1w, (void)0);
1899          CHECK_EXTRA_REGS(src2, src2w, (void)0);          CHECK_EXTRA_REGS(src2, src2w, (void)0);
1900    #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
1901            compiler->mode32 = op & SLJIT_INT_OP;
1902    #endif
1903    
1904          if (GET_OPCODE(op) >= SLJIT_MUL) {          if (GET_OPCODE(op) >= SLJIT_MUL) {
1905                  if (SLJIT_UNLIKELY(GET_FLAGS(op)))                  if (SLJIT_UNLIKELY(GET_FLAGS(op)))
# Line 1912  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ Line 1913  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_
1913                  if (!GET_FLAGS(op)) {                  if (!GET_FLAGS(op)) {
1914                          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)
1915                                  return compiler->error;                                  return compiler->error;
1916                  }                  }
1917                  else                  else
1918                          compiler->flags_saved = 0;                          compiler->flags_saved = 0;
1919                  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_ Line 2009  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_
2009  /*  Floating point operators                                             */  /*  Floating point operators                                             */
2010  /* --------------------------------------------------------------------- */  /* --------------------------------------------------------------------- */
2011    
 #if (defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)  
 static int sse2_available = 0;  
 #endif  
   
2012  #if (defined SLJIT_SSE2 && SLJIT_SSE2)  #if (defined SLJIT_SSE2 && SLJIT_SSE2)
2013    
2014  /* Alignment + 2 * 16 bytes. */  /* Alignment + 2 * 16 bytes. */
# Line 2020  static sljit_i *sse2_buffer; Line 2017  static sljit_i *sse2_buffer;
2017    
2018  static void init_compiler()  static void init_compiler()
2019  {  {
 #if (defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)  
         int features = 0;  
 #endif  
   
2020          sse2_buffer = (sljit_i*)(((sljit_uw)sse2_data + 15) & ~0xf);          sse2_buffer = (sljit_i*)(((sljit_uw)sse2_data + 15) & ~0xf);
2021          sse2_buffer[0] = 0;          sse2_buffer[0] = 0;
2022          sse2_buffer[1] = 0x80000000;          sse2_buffer[1] = 0x80000000;
2023          sse2_buffer[4] = 0xffffffff;          sse2_buffer[4] = 0xffffffff;
2024          sse2_buffer[5] = 0x7fffffff;          sse2_buffer[5] = 0x7fffffff;
2025    }
2026    
2027    #endif
2028    
2029    SLJIT_API_FUNC_ATTRIBUTE int sljit_is_fpu_available(void)
2030    {
2031    #if (defined SLJIT_SSE2 && SLJIT_SSE2)
2032    #if (defined SLJIT_DETECT_SSE2 && SLJIT_DETECT_SSE2)
2033            static int sse2_available = -1;
2034            int features;
2035    
2036            if (sse2_available != -1)
2037                    return sse2_available;
2038    
 #if (defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)  
2039  #ifdef __GNUC__  #ifdef __GNUC__
2040          /* AT&T syntax. */          /* AT&T syntax. */
2041          asm (          asm (
# Line 2053  static void init_compiler() Line 2058  static void init_compiler()
2058                  mov features, edx                  mov features, edx
2059          }          }
2060  #else  #else
2061          #error "SLJIT_SSE2_AUTO is not implemented for this C compiler"          #error "SLJIT_DETECT_SSE2 is not implemented for this C compiler"
2062  #endif  #endif
2063          sse2_available = (features >> 26) & 0x1;          sse2_available = (features >> 26) & 0x1;
2064            return sse2_available;
2065    #else
2066            return 1;
2067  #endif  #endif
2068  }  #else
2069            return 0;
2070  #endif  #endif
   
 SLJIT_API_FUNC_ATTRIBUTE int sljit_is_fpu_available(void)  
 {  
         /* Always available. */  
         return 1;  
2071  }  }
2072    
2073  #if (defined SLJIT_SSE2 && SLJIT_SSE2)  #if (defined SLJIT_SSE2 && SLJIT_SSE2)
# Line 2105  static SLJIT_INLINE int emit_sse2_store( Line 2108  static SLJIT_INLINE int emit_sse2_store(
2108          return emit_sse2(compiler, 0x11, src, dst, dstw);          return emit_sse2(compiler, 0x11, src, dst, dstw);
2109  }  }
2110    
 #if !(defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)  
2111  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  
2112          int dst, sljit_w dstw,          int dst, sljit_w dstw,
2113          int src, sljit_w srcw)          int src, sljit_w srcw)
2114  {  {
# Line 2167  static int sljit_emit_sse2_fop1(struct s Line 2166  static int sljit_emit_sse2_fop1(struct s
2166          return SLJIT_SUCCESS;          return SLJIT_SUCCESS;
2167  }  }
2168    
 #if !(defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)  
2169  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  
2170          int dst, sljit_w dstw,          int dst, sljit_w dstw,
2171          int src1, sljit_w src1w,          int src1, sljit_w src1w,
2172          int src2, sljit_w src2w)          int src2, sljit_w src2w)
# Line 2229  static int sljit_emit_sse2_fop2(struct s Line 2224  static int sljit_emit_sse2_fop2(struct s
2224          return SLJIT_SUCCESS;          return SLJIT_SUCCESS;
2225  }  }
2226    
2227  #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;  
 }  
2228    
 #if !(defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)  
2229  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  
2230          int dst, sljit_w dstw,          int dst, sljit_w dstw,
2231          int src, sljit_w srcw)          int src, sljit_w srcw)
2232  {  {
 #if !(defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)  
         sljit_ub *buf;  
 #endif  
   
2233          CHECK_ERROR();          CHECK_ERROR();
2234            /* Should cause an assertion fail. */
2235          check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw);          check_sljit_emit_fop1(compiler, op, dst, dstw, src, srcw);
2236            compiler->error = SLJIT_ERR_UNSUPPORTED;
2237  #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;  
2238  }  }
2239    
 #if !(defined SLJIT_SSE2_AUTO && SLJIT_SSE2_AUTO)  
2240  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  
2241          int dst, sljit_w dstw,          int dst, sljit_w dstw,
2242          int src1, sljit_w src1w,          int src1, sljit_w src1w,
2243          int src2, sljit_w src2w)          int src2, sljit_w src2w)
2244  {  {
2245          CHECK_ERROR();          CHECK_ERROR();
2246            /* Should cause an assertion fail. */
2247          check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w);          check_sljit_emit_fop2(compiler, op, dst, dstw, src1, src1w, src2, src2w);
2248            compiler->error = SLJIT_ERR_UNSUPPORTED;
2249  #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);  
2250  }  }
2251    
2252  #endif  #endif
# Line 2534  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ Line 2328  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_
2328    
2329          CHECK_ERROR();          CHECK_ERROR();
2330          check_sljit_emit_ijump(compiler, type, src, srcw);          check_sljit_emit_ijump(compiler, type, src, srcw);
2331            ADJUST_LOCAL_OFFSET(src, srcw);
2332    
2333          CHECK_EXTRA_REGS(src, srcw, (void)0);          CHECK_EXTRA_REGS(src, srcw, (void)0);
2334    
2335          if (SLJIT_UNLIKELY(compiler->flags_saved)) {          if (SLJIT_UNLIKELY(compiler->flags_saved)) {
2336                  if (type <= SLJIT_JUMP)                  if (type <= SLJIT_JUMP)
2337                          FAIL_IF(emit_restore_flags(compiler, 0));                          FAIL_IF(emit_restore_flags(compiler, 0));
# Line 2549  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ Line 2345  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_
2345                          EMIT_MOV(compiler, TMP_REGISTER, 0, src, 0);                          EMIT_MOV(compiler, TMP_REGISTER, 0, src, 0);
2346                          src = TMP_REGISTER;                          src = TMP_REGISTER;
2347                  }                  }
2348                  if ((src & SLJIT_MEM) && (src & 0xf) == SLJIT_LOCALS_REG && type >= SLJIT_CALL3) {                  if (src == SLJIT_MEM1(SLJIT_LOCALS_REG) && type >= SLJIT_CALL3)
2349                          if (src & 0xf0) {                          srcw += sizeof(sljit_w);
                                 EMIT_MOV(compiler, TMP_REGISTER, 0, src, srcw);  
                                 src = TMP_REGISTER;  
                         }  
                         else  
                                 srcw += sizeof(sljit_w);  
                 }  
2350  #else  #else
2351                  if ((src & SLJIT_MEM) && (src & 0xf) == SLJIT_LOCALS_REG) {                  if (src == SLJIT_MEM1(SLJIT_LOCALS_REG))
2352                          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);  
                 }  
2353  #endif  #endif
2354  #endif  #endif
2355  #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_ Line 2397  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_
2397  {  {
2398          sljit_ub *buf;          sljit_ub *buf;
2399          sljit_ub cond_set = 0;          sljit_ub cond_set = 0;
2400            int dst_save = dst;
2401            sljit_w dstw_save = dstw;
2402  #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)  #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
2403          int reg;          int reg;
2404  #endif  #endif
# Line 2623  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ Line 2409  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_
2409          if (dst == SLJIT_UNUSED)          if (dst == SLJIT_UNUSED)
2410                  return SLJIT_SUCCESS;                  return SLJIT_SUCCESS;
2411    
2412            ADJUST_LOCAL_OFFSET(dst, dstw);
2413          CHECK_EXTRA_REGS(dst, dstw, (void)0);          CHECK_EXTRA_REGS(dst, dstw, (void)0);
2414          if (SLJIT_UNLIKELY(compiler->flags_saved))          if (SLJIT_UNLIKELY(compiler->flags_saved))
2415                  FAIL_IF(emit_restore_flags(compiler, 0));                  FAIL_IF(emit_restore_flags(compiler, op & SLJIT_KEEP_FLAGS));
2416    
2417          switch (type) {          switch (type) {
2418          case SLJIT_C_EQUAL:          case SLJIT_C_EQUAL:
# Line 2718  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ Line 2505  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_
2505  #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)  #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
2506                          compiler->skip_checks = 1;                          compiler->skip_checks = 1;
2507  #endif  #endif
2508                          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);
2509                  }                  }
2510          }          }
2511  #else  #else
# Line 2790  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_ Line 2577  SLJIT_API_FUNC_ATTRIBUTE int sljit_emit_
2577  #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)  #if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) || (defined SLJIT_DEBUG && SLJIT_DEBUG)
2578                  compiler->skip_checks = 1;                  compiler->skip_checks = 1;
2579  #endif  #endif
2580                  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);
2581          }          }
2582  #endif  #endif
2583    
2584          return SLJIT_SUCCESS;          return SLJIT_SUCCESS;
2585  }  }
2586    
2587    SLJIT_API_FUNC_ATTRIBUTE int sljit_get_local_base(struct sljit_compiler *compiler, int dst, sljit_w dstw, sljit_w offset)
2588    {
2589            CHECK_ERROR();
2590            check_sljit_get_local_base(compiler, dst, dstw, offset);
2591            ADJUST_LOCAL_OFFSET(dst, dstw);
2592    
2593            CHECK_EXTRA_REGS(dst, dstw, (void)0);
2594    
2595    #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
2596            compiler->mode32 = 0;
2597    #endif
2598    
2599            ADJUST_LOCAL_OFFSET(SLJIT_MEM1(SLJIT_LOCALS_REG), offset);
2600    
2601    #if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
2602            if (NOT_HALFWORD(offset)) {
2603                    FAIL_IF(emit_load_imm64(compiler, TMP_REGISTER, offset));
2604    #if (defined SLJIT_DEBUG && SLJIT_DEBUG)
2605                    SLJIT_ASSERT(emit_lea_binary(compiler, dst, dstw, SLJIT_LOCALS_REG, 0, TMP_REGISTER, 0) != SLJIT_ERR_UNSUPPORTED);
2606                    return compiler->error;
2607    #else
2608                    return emit_lea_binary(compiler, dst, dstw, SLJIT_LOCALS_REG, 0, TMP_REGISTER, 0);
2609    #endif
2610            }
2611    #endif
2612    
2613            return emit_lea_binary(compiler, dst, dstw, SLJIT_LOCALS_REG, 0, SLJIT_IMM, offset);
2614    }
2615    
2616  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)
2617  {  {
2618          sljit_ub *buf;          sljit_ub *buf;
# Line 2807  SLJIT_API_FUNC_ATTRIBUTE struct sljit_co Line 2623  SLJIT_API_FUNC_ATTRIBUTE struct sljit_co
2623    
2624          CHECK_ERROR_PTR();          CHECK_ERROR_PTR();
2625          check_sljit_emit_const(compiler, dst, dstw, init_value);          check_sljit_emit_const(compiler, dst, dstw, init_value);
2626            ADJUST_LOCAL_OFFSET(dst, dstw);
2627    
2628          CHECK_EXTRA_REGS(dst, dstw, (void)0);          CHECK_EXTRA_REGS(dst, dstw, (void)0);
2629    

Legend:
Removed from v.906  
changed lines
  Added in v.955

  ViewVC Help
Powered by ViewVC 1.1.5